Merge branches 'clk-baikal', 'clk-broadcom', 'clk-vc5' and 'clk-versaclock' into...
authorStephen Boyd <sboyd@kernel.org>
Tue, 4 Oct 2022 17:54:34 +0000 (10:54 -0700)
committerStephen Boyd <sboyd@kernel.org>
Tue, 4 Oct 2022 17:54:34 +0000 (10:54 -0700)
 - Convert Baikal-T1 CCU driver to platform driver
 - Split reset support out of primary Baikal-T1 CCU driver
 - Add some missing clks required for RPiVid Video Decoder on RaspberryPi
 - Mark PLLC critical on bcm2835
 - Support for Renesas VersaClock7 clock generator family

* clk-baikal:
  clk: baikal-t1: Convert to platform device driver
  clk: baikal-t1: Add DDR/PCIe directly controlled resets support
  dt-bindings: clk: baikal-t1: Add DDR/PCIe reset IDs
  clk: baikal-t1: Move reset-controls code into a dedicated module
  clk: baikal-t1: Add SATA internal ref clock buffer
  clk: baikal-t1: Add shared xGMAC ref/ptp clocks internal parent
  clk: baikal-t1: Fix invalid xGMAC PTP clock divider
  clk: vc5: Fix 5P49V6901 outputs disabling when enabling FOD

* clk-broadcom:
  clk: bcm: rpi: Add support for VEC clock
  clk: bcm: rpi: Handle pixel clock in firmware
  clk: bcm: rpi: Add support HEVC clock
  clk: bcm2835: fix bcm2835_clock_rate_from_divisor declaration
  clk: bcm2835: Round UART input clock up
  clk: bcm2835: Make peripheral PLLC critical

* clk-vc5:
  clk: vc5: Add support for IDT/Renesas VersaClock 5P49V6975
  dt-bindings: clock: vc5: Add 5P49V6975
  clk: vc5: Use regmap_{set,clear}_bits() where appropriate
  clk: vc5: Check IO access results

* clk-versaclock:
  clk: Renesas versaclock7 ccf device driver
  dt-bindings: Renesas versaclock7 device tree bindings

734 files changed:
Documentation/atomic_bitops.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.yaml
Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml
Documentation/devicetree/bindings/clock/cirrus,cs2000-cp.yaml
Documentation/devicetree/bindings/clock/gpio-gate-clock.txt [deleted file]
Documentation/devicetree/bindings/clock/gpio-gate-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
Documentation/devicetree/bindings/clock/mediatek,apmixedsys.yaml
Documentation/devicetree/bindings/clock/mediatek,mt6795-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/mediatek,mt6795-sys-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/mediatek,mt8365-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/mediatek,mt8365-sys-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml
Documentation/devicetree/bindings/clock/microchip,mpfs-ccc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml [moved from Documentation/devicetree/bindings/clock/microchip,mpfs.yaml with 73% similarity]
Documentation/devicetree/bindings/clock/qcom,a53pll.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-apq8064.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-msm8660.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc-msm8909.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc-msm8916.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc-msm8976.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-msm8994.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-msm8996.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-msm8998.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-other.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-qcm2290.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sc7180.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sc7280.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sc8180x.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sc8280xp.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sdm845.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sdx55.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sdx65.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sm6115.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sm6125.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sm6350.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sm8150.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sm8250.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sm8350.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sm8450.yaml
Documentation/devicetree/bindings/clock/qcom,gpucc.yaml
Documentation/devicetree/bindings/clock/qcom,mmcc.yaml
Documentation/devicetree/bindings/clock/qcom,msm8996-apcc.yaml
Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml
Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml
Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscc.yaml
Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml
Documentation/devicetree/bindings/clock/qcom,sm6115-dispcc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,sm6375-gcc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,sm8450-dispcc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.yaml
Documentation/devicetree/bindings/clock/renesas,rzg2l-cpg.yaml
Documentation/devicetree/bindings/clock/renesas,versaclock7.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/rockchip,px30-cru.yaml
Documentation/devicetree/bindings/clock/rockchip,rk3036-cru.yaml
Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt [deleted file]
Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/rockchip,rk3228-cru.yaml
Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.yaml
Documentation/devicetree/bindings/clock/rockchip,rk3308-cru.yaml
Documentation/devicetree/bindings/clock/rockchip,rk3368-cru.yaml
Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml
Documentation/devicetree/bindings/clock/rockchip,rv1108-cru.yaml
Documentation/devicetree/bindings/clock/rockchip,rv1126-cru.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
Documentation/devicetree/bindings/clock/samsung,exynosautov9-clock.yaml
Documentation/devicetree/bindings/clock/samsung,s2mps11.yaml
Documentation/devicetree/bindings/clock/ti/gate.txt
Documentation/devicetree/bindings/clock/ti/interface.txt
Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml
Documentation/devicetree/bindings/mfd/cirrus,lochnagar.yaml
Documentation/devicetree/bindings/net/qcom-emac.txt
Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
Documentation/devicetree/bindings/spi/cdns,qspi-nor-peripheral-props.yaml
Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
Documentation/devicetree/bindings/thermal/rcar-thermal.yaml
Documentation/kbuild/kconfig-language.rst
Documentation/tools/rtla/rtla-timerlat-hist.rst
MAINTAINERS
Makefile
arch/Kconfig
arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi
arch/arm64/include/asm/kvm_host.h
arch/arm64/include/uapi/asm/kvm.h
arch/arm64/kvm/arm.c
arch/arm64/kvm/guest.c
arch/arm64/kvm/mmu.c
arch/arm64/kvm/sys_regs.c
arch/loongarch/include/asm/irq.h
arch/mips/include/asm/kvm_host.h
arch/mips/kvm/mmu.c
arch/nios2/include/asm/entry.h
arch/nios2/include/asm/ptrace.h
arch/nios2/kernel/entry.S
arch/nios2/kernel/signal.c
arch/nios2/kernel/syscall_table.c
arch/powerpc/include/asm/kvm_book3s_64.h
arch/powerpc/kernel/pci-common.c
arch/powerpc/kvm/book3s_64_mmu_host.c
arch/powerpc/kvm/book3s_64_mmu_hv.c
arch/powerpc/kvm/book3s_64_mmu_radix.c
arch/powerpc/kvm/book3s_hv_nested.c
arch/powerpc/kvm/book3s_hv_rm_mmu.c
arch/powerpc/kvm/e500_mmu_host.c
arch/riscv/kernel/cpufeature.c
arch/riscv/kvm/mmu.c
arch/s390/hypfs/hypfs_diag.c
arch/s390/hypfs/inode.c
arch/um/drivers/virtio_uml.c
arch/um/include/asm/cpufeature.h
arch/x86/Makefile
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/extable_fixup_types.h
arch/x86/include/asm/ibt.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/rmwcc.h
arch/x86/include/asm/word-at-a-time.h
arch/x86/kernel/kprobes/core.c
arch/x86/kvm/emulate.c
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/mmu/paging_tmpl.h
arch/x86/mm/extable.c
arch/x86/mm/init_64.c
block/blk-mq.c
drivers/ata/libata-eh.c
drivers/block/ublk_drv.c
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/at91/dt-compat.c
drivers/clk/at91/sama5d2.c
drivers/clk/baikal-t1/Kconfig
drivers/clk/baikal-t1/Makefile
drivers/clk/baikal-t1/ccu-div.c
drivers/clk/baikal-t1/ccu-div.h
drivers/clk/baikal-t1/ccu-pll.h
drivers/clk/baikal-t1/ccu-rst.c [new file with mode: 0644]
drivers/clk/baikal-t1/ccu-rst.h [new file with mode: 0644]
drivers/clk/baikal-t1/clk-ccu-div.c
drivers/clk/baikal-t1/clk-ccu-pll.c
drivers/clk/berlin/bg2.c
drivers/clk/berlin/bg2q.c
drivers/clk/clk-asm9260.c
drivers/clk/clk-ast2600.c
drivers/clk/clk-fixed-rate.c
drivers/clk/clk-lan966x.c
drivers/clk/clk-lochnagar.c
drivers/clk/clk-nomadik.c
drivers/clk/clk-npcm7xx.c
drivers/clk/clk-oxnas.c
drivers/clk/clk-qoriq.c
drivers/clk/clk-versaclock5.c
drivers/clk/clk-versaclock7.c [new file with mode: 0644]
drivers/clk/clk-xgene.c
drivers/clk/clk.c
drivers/clk/clkdev.c
drivers/clk/davinci/Makefile
drivers/clk/davinci/da8xx-cfgchip.c
drivers/clk/davinci/pll-dm644x.c [deleted file]
drivers/clk/davinci/pll-dm646x.c [deleted file]
drivers/clk/davinci/pll.c
drivers/clk/davinci/pll.h
drivers/clk/davinci/psc-dm644x.c [deleted file]
drivers/clk/davinci/psc-dm646x.c [deleted file]
drivers/clk/davinci/psc.c
drivers/clk/davinci/psc.h
drivers/clk/imx/Makefile
drivers/clk/imx/clk-composite-93.c
drivers/clk/imx/clk-gate-93.c [new file with mode: 0644]
drivers/clk/imx/clk-imx8mp.c
drivers/clk/imx/clk-imx93.c
drivers/clk/imx/clk-scu.c
drivers/clk/imx/clk.h
drivers/clk/mediatek/Kconfig
drivers/clk/mediatek/Makefile
drivers/clk/mediatek/clk-apmixed.c
drivers/clk/mediatek/clk-cpumux.c
drivers/clk/mediatek/clk-gate.c
drivers/clk/mediatek/clk-mt2701-bdp.c
drivers/clk/mediatek/clk-mt2701-img.c
drivers/clk/mediatek/clk-mt2701-vdec.c
drivers/clk/mediatek/clk-mt2712-bdp.c
drivers/clk/mediatek/clk-mt2712-img.c
drivers/clk/mediatek/clk-mt2712-jpgdec.c
drivers/clk/mediatek/clk-mt2712-mfg.c
drivers/clk/mediatek/clk-mt2712-vdec.c
drivers/clk/mediatek/clk-mt2712-venc.c
drivers/clk/mediatek/clk-mt6765-audio.c
drivers/clk/mediatek/clk-mt6765-cam.c
drivers/clk/mediatek/clk-mt6765-img.c
drivers/clk/mediatek/clk-mt6765-mipi0a.c
drivers/clk/mediatek/clk-mt6765-mm.c
drivers/clk/mediatek/clk-mt6765-vcodec.c
drivers/clk/mediatek/clk-mt6779-aud.c
drivers/clk/mediatek/clk-mt6779-cam.c
drivers/clk/mediatek/clk-mt6779-img.c
drivers/clk/mediatek/clk-mt6779-ipe.c
drivers/clk/mediatek/clk-mt6779-mfg.c
drivers/clk/mediatek/clk-mt6779-vdec.c
drivers/clk/mediatek/clk-mt6779-venc.c
drivers/clk/mediatek/clk-mt6795-apmixedsys.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6795-infracfg.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6795-mfg.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6795-mm.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6795-pericfg.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6795-topckgen.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6795-vdecsys.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6795-vencsys.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6797-img.c
drivers/clk/mediatek/clk-mt6797-vdec.c
drivers/clk/mediatek/clk-mt6797-venc.c
drivers/clk/mediatek/clk-mt8183-cam.c
drivers/clk/mediatek/clk-mt8183-img.c
drivers/clk/mediatek/clk-mt8183-ipu0.c
drivers/clk/mediatek/clk-mt8183-ipu1.c
drivers/clk/mediatek/clk-mt8183-ipu_adl.c
drivers/clk/mediatek/clk-mt8183-ipu_conn.c
drivers/clk/mediatek/clk-mt8183-mfgcfg.c
drivers/clk/mediatek/clk-mt8183-vdec.c
drivers/clk/mediatek/clk-mt8183-venc.c
drivers/clk/mediatek/clk-mt8183.c
drivers/clk/mediatek/clk-mt8192-cam.c
drivers/clk/mediatek/clk-mt8192-img.c
drivers/clk/mediatek/clk-mt8192-imp_iic_wrap.c
drivers/clk/mediatek/clk-mt8192-ipe.c
drivers/clk/mediatek/clk-mt8192-mdp.c
drivers/clk/mediatek/clk-mt8192-mfg.c
drivers/clk/mediatek/clk-mt8192-msdc.c
drivers/clk/mediatek/clk-mt8192-scp_adsp.c
drivers/clk/mediatek/clk-mt8192-vdec.c
drivers/clk/mediatek/clk-mt8192-venc.c
drivers/clk/mediatek/clk-mt8192.c
drivers/clk/mediatek/clk-mt8195-infra_ao.c
drivers/clk/mediatek/clk-mt8195-mfg.c
drivers/clk/mediatek/clk-mt8195-topckgen.c
drivers/clk/mediatek/clk-mt8195-vdo0.c
drivers/clk/mediatek/clk-mt8195-vdo1.c
drivers/clk/mediatek/clk-mt8365-apu.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8365-cam.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8365-mfg.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8365-mm.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8365-vdec.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8365-venc.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8365.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mtk.c
drivers/clk/mediatek/clk-mtk.h
drivers/clk/mediatek/clk-mux.c
drivers/clk/mediatek/clk-mux.h
drivers/clk/mediatek/reset.c
drivers/clk/meson/meson-aoclk.c
drivers/clk/meson/meson-eeclk.c
drivers/clk/meson/meson8b.c
drivers/clk/microchip/Kconfig
drivers/clk/microchip/Makefile
drivers/clk/microchip/clk-mpfs-ccc.c [new file with mode: 0644]
drivers/clk/microchip/clk-mpfs.c
drivers/clk/mmp/clk-of-pxa168.c
drivers/clk/mvebu/armada-37xx-tbg.c
drivers/clk/mvebu/dove-divider.c
drivers/clk/nxp/clk-lpc18xx-cgu.c
drivers/clk/pistachio/clk.h
drivers/clk/pxa/clk-pxa.c
drivers/clk/qcom/Kconfig
drivers/clk/qcom/Makefile
drivers/clk/qcom/a53-pll.c
drivers/clk/qcom/apss-ipq-pll.c
drivers/clk/qcom/apss-ipq6018.c
drivers/clk/qcom/clk-alpha-pll.c
drivers/clk/qcom/clk-alpha-pll.h
drivers/clk/qcom/clk-cpu-8996.c
drivers/clk/qcom/clk-rcg.h
drivers/clk/qcom/clk-rcg2.c
drivers/clk/qcom/clk-rpmh.c
drivers/clk/qcom/clk-smd-rpm.c
drivers/clk/qcom/dispcc-sm6115.c [new file with mode: 0644]
drivers/clk/qcom/dispcc-sm8450.c [new file with mode: 0644]
drivers/clk/qcom/gcc-msm8660.c
drivers/clk/qcom/gcc-msm8909.c [new file with mode: 0644]
drivers/clk/qcom/gcc-msm8916.c
drivers/clk/qcom/gcc-msm8939.c
drivers/clk/qcom/gcc-msm8960.c
drivers/clk/qcom/gcc-qcm2290.c
drivers/clk/qcom/gcc-sc7180.c
drivers/clk/qcom/gcc-sc7280.c
drivers/clk/qcom/gcc-sc8280xp.c
drivers/clk/qcom/gcc-sdm660.c
drivers/clk/qcom/gcc-sdm845.c
drivers/clk/qcom/gcc-sm6115.c
drivers/clk/qcom/gcc-sm6350.c
drivers/clk/qcom/gcc-sm6375.c [new file with mode: 0644]
drivers/clk/qcom/gdsc.c
drivers/clk/qcom/gdsc.h
drivers/clk/qcom/gpucc-sc8280xp.c [new file with mode: 0644]
drivers/clk/qcom/kpss-xcc.c
drivers/clk/qcom/lcc-ipq806x.c
drivers/clk/qcom/lcc-msm8960.c
drivers/clk/qcom/lpassaudiocc-sc7280.c
drivers/clk/qcom/lpasscc-sc7280.c
drivers/clk/qcom/lpasscorecc-sc7280.c
drivers/clk/qcom/mmcc-msm8960.c
drivers/clk/qcom/reset.c
drivers/clk/qcom/reset.h
drivers/clk/renesas/r8a779f0-cpg-mssr.c
drivers/clk/renesas/r8a779g0-cpg-mssr.c
drivers/clk/renesas/r9a07g044-cpg.c
drivers/clk/renesas/r9a09g011-cpg.c
drivers/clk/rockchip/Kconfig
drivers/clk/rockchip/Makefile
drivers/clk/rockchip/clk-rv1126.c [new file with mode: 0644]
drivers/clk/rockchip/clk.c
drivers/clk/rockchip/clk.h
drivers/clk/samsung/clk-exynos-clkout.c
drivers/clk/samsung/clk-exynos7885.c
drivers/clk/samsung/clk-exynos850.c
drivers/clk/samsung/clk-exynosautov9.c
drivers/clk/sprd/Kconfig
drivers/clk/sprd/Makefile
drivers/clk/sprd/common.c
drivers/clk/sprd/ums512-clk.c [new file with mode: 0644]
drivers/clk/st/clkgen-fsyn.c
drivers/clk/st/clkgen-mux.c
drivers/clk/sunxi-ng/ccu-sun20i-d1.c
drivers/clk/sunxi-ng/ccu-sun8i-de2.c
drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c
drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c
drivers/clk/tegra/clk-bpmp.c
drivers/clk/tegra/clk-tegra114.c
drivers/clk/tegra/clk-tegra124.c
drivers/clk/tegra/clk-tegra20.c
drivers/clk/tegra/clk-tegra210.c
drivers/clk/tegra/clk-tegra30.c
drivers/clk/ti/clk-dra7-atl.c
drivers/clk/ti/clk.c
drivers/clk/xilinx/Kconfig
drivers/clk/xilinx/Makefile
drivers/clk/xilinx/clk-xlnx-clock-wizard.c [moved from drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c with 94% similarity]
drivers/clk/zynqmp/clkc.c
drivers/clk/zynqmp/divider.c
drivers/clk/zynqmp/pll.c
drivers/gpu/drm/amd/amdgpu/aldebaran.c
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
drivers/gpu/drm/amd/amdgpu/athub_v3_0.c
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c
drivers/gpu/drm/amd/amdgpu/ih_v6_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c
drivers/gpu/drm/amd/amdgpu/navi10_ih.c
drivers/gpu/drm/amd/amdgpu/psp_v12_0.c
drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
drivers/gpu/drm/amd/amdgpu/soc21.c
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
drivers/gpu/drm/amd/amdgpu/vega10_ih.c
drivers/gpu/drm/amd/amdgpu/vega20_ih.c
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
drivers/gpu/drm/amd/amdkfd/kfd_device.c
drivers/gpu/drm/amd/amdkfd/kfd_events.c
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
drivers/gpu/drm/amd/amdkfd/kfd_svm.c
drivers/gpu/drm/amd/amdkfd/kfd_svm.h
drivers/gpu/drm/amd/amdkfd/kfd_topology.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
drivers/gpu/drm/amd/display/dc/basics/conversion.c
drivers/gpu/drm/amd/display/dc/basics/conversion.h
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.h
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_smu.h
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
drivers/gpu/drm/amd/display/dc/dc_link.h
drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c
drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.h
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h
drivers/gpu/drm/amd/display/dc/dcn314/Makefile
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.h
drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h
drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
drivers/gpu/drm/amd/display/dc/dml/Makefile
drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c
drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c
drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h
drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
drivers/gpu/drm/amd/display/include/dal_asic_id.h
drivers/gpu/drm/amd/display/include/logger_types.h
drivers/gpu/drm/amd/display/modules/freesync/freesync.c
drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_4.h
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
drivers/gpu/drm/bridge/lvds-codec.c
drivers/gpu/drm/i915/gem/i915_gem_object.c
drivers/gpu/drm/i915/gem/i915_gem_object_types.h
drivers/gpu/drm/i915/gem/i915_gem_pages.c
drivers/gpu/drm/i915/gt/intel_gt.c
drivers/gpu/drm/i915/gt/intel_gt.h
drivers/gpu/drm/i915/gt/intel_gt_pm.h
drivers/gpu/drm/i915/gt/intel_gt_types.h
drivers/gpu/drm/i915/gt/intel_migrate.c
drivers/gpu/drm/i915/gt/intel_ppgtt.c
drivers/gpu/drm/i915/gt/intel_region_lmem.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_vma.c
drivers/gpu/drm/i915/i915_vma.h
drivers/gpu/drm/i915/i915_vma_resource.c
drivers/gpu/drm/i915/i915_vma_resource.h
drivers/gpu/drm/imx/dcss/dcss-kms.c
drivers/gpu/drm/meson/meson_drv.c
drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-scmi.c
drivers/infiniband/core/umem_dmabuf.c
drivers/infiniband/hw/cxgb4/cm.c
drivers/infiniband/hw/erdma/erdma_qp.c
drivers/infiniband/hw/erdma/erdma_verbs.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/ulp/iser/iser_initiator.c
drivers/iommu/hyperv-iommu.c
drivers/irqchip/irq-loongarch-cpu.c
drivers/irqchip/irq-loongson-eiointc.c
drivers/irqchip/irq-loongson-liointc.c
drivers/irqchip/irq-loongson-pch-msi.c
drivers/irqchip/irq-loongson-pch-pic.c
drivers/mmc/host/meson-gx-mmc.c
drivers/mmc/host/mtk-sd.c
drivers/mmc/host/pxamci.c
drivers/mmc/host/sdhci-of-dwcmshc.c
drivers/net/dsa/microchip/ksz9477.c
drivers/net/dsa/mv88e6060.c
drivers/net/dsa/ocelot/felix_vsc9959.c
drivers/net/dsa/ocelot/seville_vsc9953.c
drivers/net/dsa/sja1105/sja1105_devlink.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
drivers/net/ethernet/freescale/fec_ptp.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/iavf/iavf_adminq.c
drivers/net/ethernet/intel/iavf/iavf_main.c
drivers/net/ethernet/intel/ice/ice_fltr.c
drivers/net/ethernet/intel/ice/ice_lib.c
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_switch.c
drivers/net/ethernet/intel/ice/ice_vf_lib.c
drivers/net/ethernet/intel/ice/ice_virtchnl.c
drivers/net/ethernet/intel/igb/igb.h
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/mediatek/mtk_eth_soc.c
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.h
drivers/net/ethernet/microchip/lan966x/lan966x_main.c
drivers/net/ethernet/moxa/moxart_ether.c
drivers/net/ethernet/mscc/ocelot.c
drivers/net/ethernet/mscc/ocelot_net.c
drivers/net/ethernet/mscc/ocelot_vsc7514.c
drivers/net/ethernet/mscc/vsc7514_regs.c
drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
drivers/net/fddi/skfp/h/hwmtm.h
drivers/net/ipa/ipa_reg.h
drivers/net/virtio_net.c
drivers/perf/riscv_pmu_legacy.c
drivers/platform/mellanox/mlxbf-tmfifo.c
drivers/platform/x86/serial-multi-instantiate.c
drivers/regulator/core.c
drivers/remoteproc/remoteproc_virtio.c
drivers/reset/Kconfig
drivers/reset/Makefile
drivers/reset/reset-mpfs.c [new file with mode: 0644]
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/ap_bus.h
drivers/s390/virtio/virtio_ccw.c
drivers/spi/spi-meson-spicc.c
drivers/spi/spi.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/clocking-wizard/Kconfig [deleted file]
drivers/staging/clocking-wizard/Makefile [deleted file]
drivers/staging/clocking-wizard/TODO [deleted file]
drivers/staging/clocking-wizard/dt-binding.txt [deleted file]
drivers/tee/tee_shm.c
drivers/virtio/virtio_mmio.c
drivers/virtio/virtio_pci_common.c
drivers/virtio/virtio_pci_common.h
drivers/virtio/virtio_pci_legacy.c
drivers/virtio/virtio_pci_modern.c
drivers/virtio/virtio_ring.c
drivers/virtio/virtio_vdpa.c
fs/btrfs/block-group.c
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/disk-io.h
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/locking.c
fs/btrfs/locking.h
fs/btrfs/relocation.c
fs/btrfs/tree-checker.c
fs/btrfs/tree-log.c
fs/cifs/cifs_debug.c
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/cifsroot.c
fs/cifs/connect.c
fs/cifs/misc.c
fs/cifs/netmisc.c
fs/cifs/readdir.c
fs/cifs/smb2file.c
fs/cifs/smb2misc.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2proto.h
fs/dcache.c
fs/exec.c
fs/ksmbd/ksmbd_netlink.h
fs/ksmbd/mgmt/share_config.c
fs/ksmbd/mgmt/share_config.h
fs/ksmbd/mgmt/tree_connect.c
fs/ksmbd/smb2pdu.c
fs/ntfs3/attrib.c
fs/ntfs3/bitmap.c
fs/ntfs3/file.c
fs/ntfs3/frecord.c
fs/ntfs3/fslog.c
fs/ntfs3/fsntfs.c
fs/ntfs3/index.c
fs/ntfs3/inode.c
fs/ntfs3/namei.c
fs/ntfs3/ntfs_fs.h
fs/ntfs3/record.c
fs/ntfs3/run.c
fs/ntfs3/super.c
fs/ntfs3/xattr.c
include/asm-generic/bitops/atomic.h
include/dt-bindings/clock/exynos850.h
include/dt-bindings/clock/imx8mm-clock.h
include/dt-bindings/clock/imx93-clock.h
include/dt-bindings/clock/lochnagar.h [moved from include/dt-bindings/clk/lochnagar.h with 100% similarity]
include/dt-bindings/clock/marvell,pxa168.h
include/dt-bindings/clock/mediatek,mt6795-clk.h [new file with mode: 0644]
include/dt-bindings/clock/mediatek,mt8365-clk.h [new file with mode: 0644]
include/dt-bindings/clock/microchip,mpfs-clock.h
include/dt-bindings/clock/mt8195-clk.h
include/dt-bindings/clock/qcom,gcc-msm8909.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,gcc-sdm845.h
include/dt-bindings/clock/qcom,gpucc-sc8280xp.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,lcc-ipq806x.h
include/dt-bindings/clock/qcom,lpassaudiocc-sc7280.h
include/dt-bindings/clock/qcom,lpasscorecc-sc7280.h
include/dt-bindings/clock/qcom,rpmcc.h
include/dt-bindings/clock/qcom,sm6115-dispcc.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,sm6375-gcc.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,sm8450-dispcc.h [new file with mode: 0644]
include/dt-bindings/clock/rockchip,rv1126-cru.h [new file with mode: 0644]
include/dt-bindings/clock/samsung,exynosautov9.h
include/dt-bindings/clock/versaclock.h [moved from include/dt-bindings/clk/versaclock.h with 100% similarity]
include/dt-bindings/reset/bt1-ccu.h
include/dt-bindings/reset/mediatek,mt6795-resets.h [new file with mode: 0644]
include/dt-bindings/reset/mt8195-resets.h
include/linux/blk-mq.h
include/linux/clk-provider.h
include/linux/clk/davinci.h
include/linux/clkdev.h
include/linux/cpumask.h
include/linux/kvm_host.h
include/linux/libata.h
include/linux/soc/qcom/smd-rpm.h
include/linux/virtio.h
include/linux/virtio_config.h
include/net/neighbour.h
include/net/netns/conntrack.h
include/net/sock.h
include/soc/microchip/mpfs.h
include/soc/mscc/ocelot.h
include/uapi/linux/virtio_ring.h
init/Kconfig
io_uring/net.c
io_uring/notif.h
kernel/bpf/reuseport_array.c
kernel/trace/ftrace.c
kernel/trace/trace_eprobe.c
kernel/trace/trace_event_perf.c
kernel/trace/trace_events.c
kernel/trace/trace_probe.c
lib/Makefile
lib/cpumask.c
net/core/gen_stats.c
net/core/neighbour.c
net/core/rtnetlink.c
net/core/skmsg.c
net/dsa/port.c
net/ipv4/tcp.c
net/ipv6/ip6_tunnel.c
net/ipv6/ndisc.c
net/netfilter/Kconfig
net/netfilter/nf_conntrack_ftp.c
net/netfilter/nf_conntrack_h323_main.c
net/netfilter/nf_conntrack_irc.c
net/netfilter/nf_conntrack_sane.c
net/netfilter/nf_tables_api.c
net/netfilter/nfnetlink.c
net/netlink/genetlink.c
net/netlink/policy.c
net/qrtr/mhi.c
net/rds/ib_recv.c
net/sched/cls_route.c
net/sunrpc/sysfs.c
net/tls/tls_sw.c
scripts/Makefile.extrawarn
scripts/Makefile.gcc-plugins
scripts/clang-tools/run-clang-tools.py
scripts/dummy-tools/gcc
scripts/gcc-goto.sh [deleted file]
scripts/mod/modpost.c
security/loadpin/loadpin.c
sound/core/info.c
sound/pci/hda/cs35l41_hda.c
sound/pci/hda/patch_cs8409-tables.c
sound/pci/hda/patch_realtek.c
sound/soc/amd/yc/acp6x-mach.c
sound/soc/codecs/rt5640.c
sound/soc/codecs/tas2770.c
sound/soc/codecs/tas2770.h
sound/soc/codecs/tlv320aic32x4.c
sound/soc/intel/avs/pcm.c
sound/soc/intel/boards/sof_es8336.c
sound/soc/sh/rz-ssi.c
sound/soc/soc-pcm.c
sound/soc/sof/debug.c
sound/soc/sof/intel/hda.c
sound/soc/sof/ipc3-topology.c
tools/arch/s390/include/uapi/asm/kvm.h
tools/arch/x86/include/asm/cpufeatures.h
tools/arch/x86/include/asm/msr-index.h
tools/arch/x86/include/asm/rmwcc.h
tools/arch/x86/include/uapi/asm/kvm.h
tools/arch/x86/include/uapi/asm/vmx.h
tools/include/uapi/drm/i915_drm.h
tools/include/uapi/linux/fscrypt.h
tools/include/uapi/linux/kvm.h
tools/include/uapi/linux/perf_event.h
tools/include/uapi/linux/vhost.h
tools/lib/perf/cpumap.c
tools/lib/perf/evsel.c
tools/lib/perf/include/perf/cpumap.h
tools/lib/perf/include/perf/event.h
tools/lib/perf/include/perf/evsel.h
tools/lib/perf/tests/test-evsel.c
tools/objtool/check.c
tools/perf/tests/cpumap.c
tools/perf/tests/sample-parsing.c
tools/perf/trace/beauty/include/linux/socket.h
tools/perf/util/cpumap.c
tools/perf/util/cpumap.h
tools/perf/util/event.h
tools/perf/util/evsel.c
tools/perf/util/scripting-engines/trace-event-python.c
tools/perf/util/session.c
tools/perf/util/synthetic-events.c
tools/perf/util/synthetic-events.h
tools/testing/selftests/landlock/Makefile
tools/testing/selftests/netfilter/nft_flowtable.sh
tools/testing/selftests/powerpc/pmu/event_code_tests/.gitignore [new file with mode: 0644]
tools/testing/selftests/powerpc/pmu/sampling_tests/.gitignore
tools/tracing/rtla/Makefile
tools/tracing/rtla/src/timerlat_hist.c
tools/tracing/rtla/src/timerlat_top.c
virt/kvm/kvm_main.c
virt/kvm/pfncache.c

index 093cdae..d8b101c 100644 (file)
@@ -59,7 +59,7 @@ Like with atomic_t, the rule of thumb is:
  - RMW operations that have a return value are fully ordered.
 
  - RMW operations that are conditional are unordered on FAILURE,
-   otherwise the above rules apply. In the case of test_and_{}_bit() operations,
+   otherwise the above rules apply. In the case of test_and_set_bit_lock(),
    if the bit in memory is unchanged by the operation then it is deemed to have
    failed.
 
index 8681b78..1d7c837 100644 (file)
@@ -23,6 +23,7 @@ properties:
               - mediatek,mt2701-infracfg
               - mediatek,mt2712-infracfg
               - mediatek,mt6765-infracfg
+              - mediatek,mt6795-infracfg
               - mediatek,mt6779-infracfg_ao
               - mediatek,mt6797-infracfg
               - mediatek,mt7622-infracfg
@@ -60,6 +61,7 @@ if:
         enum:
           - mediatek,mt2701-infracfg
           - mediatek,mt2712-infracfg
+          - mediatek,mt6795-infracfg
           - mediatek,mt7622-infracfg
           - mediatek,mt7986-infracfg
           - mediatek,mt8135-infracfg
index 6ad023e..597ef18 100644 (file)
@@ -25,6 +25,7 @@ properties:
               - mediatek,mt2712-mmsys
               - mediatek,mt6765-mmsys
               - mediatek,mt6779-mmsys
+              - mediatek,mt6795-mmsys
               - mediatek,mt6797-mmsys
               - mediatek,mt8167-mmsys
               - mediatek,mt8173-mmsys
index 8585f6f..ef62cbb 100644 (file)
@@ -21,6 +21,7 @@ properties:
               - mediatek,mt2701-pericfg
               - mediatek,mt2712-pericfg
               - mediatek,mt6765-pericfg
+              - mediatek,mt6795-pericfg
               - mediatek,mt7622-pericfg
               - mediatek,mt7629-pericfg
               - mediatek,mt8135-pericfg
index 0abd6ba..8283608 100644 (file)
@@ -23,7 +23,6 @@ properties:
   clocks:
     description:
       Common clock binding for CLK_IN, XTI/REF_CLK
-    minItems: 2
     maxItems: 2
 
   clock-names:
diff --git a/Documentation/devicetree/bindings/clock/gpio-gate-clock.txt b/Documentation/devicetree/bindings/clock/gpio-gate-clock.txt
deleted file mode 100644 (file)
index d3379ff..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-Binding for simple gpio gated clock.
-
-This binding uses the common clock binding[1].
-
-[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
-
-Required properties:
-- compatible : shall be "gpio-gate-clock".
-- #clock-cells : from common clock binding; shall be set to 0.
-- enable-gpios : GPIO reference for enabling and disabling the clock.
-
-Optional properties:
-- clocks: Maximum of one parent clock is supported.
-
-Example:
-       clock {
-               compatible = "gpio-gate-clock";
-               clocks = <&parentclk>;
-               #clock-cells = <0>;
-               enable-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
-       };
diff --git a/Documentation/devicetree/bindings/clock/gpio-gate-clock.yaml b/Documentation/devicetree/bindings/clock/gpio-gate-clock.yaml
new file mode 100644 (file)
index 0000000..d09d0e3
--- /dev/null
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/gpio-gate-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Simple GPIO clock gate
+
+maintainers:
+  - Jyri Sarha <jsarha@ti.com>
+
+properties:
+  compatible:
+    const: gpio-gate-clock
+
+  clocks:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 0
+
+  enable-gpios:
+    description: GPIO reference for enabling and disabling the clock.
+    maxItems: 1
+
+required:
+  - compatible
+  - '#clock-cells'
+  - enable-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    clock {
+        compatible = "gpio-gate-clock";
+        clocks = <&parentclk>;
+        #clock-cells = <0>;
+        enable-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
+    };
index 7c331bf..f9ba986 100644 (file)
@@ -56,6 +56,7 @@ properties:
       - idt,5p49v5935
       - idt,5p49v6901
       - idt,5p49v6965
+      - idt,5p49v6975
 
   reg:
     description: I2C device address
@@ -108,7 +109,7 @@ patternProperties:
     properties:
       idt,mode:
         description:
-          The output drive mode. Values defined in dt-bindings/clk/versaclock.h
+          The output drive mode. Values defined in dt-bindings/clock/versaclock.h
         $ref: /schemas/types.yaml#/definitions/uint32
         minimum: 0
         maximum: 6
@@ -134,6 +135,7 @@ allOf:
           enum:
             - idt,5p49v5933
             - idt,5p49v5935
+            - idt,5p49v6975
     then:
       # Devices with builtin crystal + optional external input
       properties:
@@ -151,7 +153,7 @@ additionalProperties: false
 
 examples:
   - |
-    #include <dt-bindings/clk/versaclock.h>
+    #include <dt-bindings/clock/versaclock.h>
 
     /* 25MHz reference crystal */
     ref25: ref25m {
index 7705461..731bfe0 100644 (file)
@@ -34,6 +34,7 @@ properties:
               - mediatek,mt2712-apmixedsys
               - mediatek,mt6765-apmixedsys
               - mediatek,mt6779-apmixedsys
+              - mediatek,mt6795-apmixedsys
               - mediatek,mt7629-apmixedsys
               - mediatek,mt8167-apmixedsys
               - mediatek,mt8183-apmixedsys
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt6795-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt6795-clock.yaml
new file mode 100644 (file)
index 0000000..04469ea
--- /dev/null
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mediatek,mt6795-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek Functional Clock Controller for MT6795
+
+maintainers:
+  - AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+  - Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+description: |
+  The clock architecture in MediaTek like below
+  PLLs -->
+          dividers -->
+                      muxes
+                           -->
+                              clock gate
+
+  The devices provide clock gate control in different IP blocks.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt6795-mfgcfg
+      - mediatek,mt6795-vdecsys
+      - mediatek,mt6795-vencsys
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        mfgcfg: clock-controller@13000000 {
+            compatible = "mediatek,mt6795-mfgcfg";
+            reg = <0 0x13000000 0 0x1000>;
+            #clock-cells = <1>;
+        };
+
+        vdecsys: clock-controller@16000000 {
+            compatible = "mediatek,mt6795-vdecsys";
+            reg = <0 0x16000000 0 0x1000>;
+            #clock-cells = <1>;
+        };
+
+        vencsys: clock-controller@18000000 {
+            compatible = "mediatek,mt6795-vencsys";
+            reg = <0 0x18000000 0 0x1000>;
+            #clock-cells = <1>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt6795-sys-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt6795-sys-clock.yaml
new file mode 100644 (file)
index 0000000..378b761
--- /dev/null
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mediatek,mt6795-sys-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek System Clock Controller for MT6795
+
+maintainers:
+  - AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+  - Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+description:
+  The Mediatek system clock controller provides various clocks and system
+  configuration like reset and bus protection on MT6795.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt6795-apmixedsys
+          - mediatek,mt6795-infracfg
+          - mediatek,mt6795-pericfg
+          - mediatek,mt6795-topckgen
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        topckgen: clock-controller@10000000 {
+            compatible = "mediatek,mt6795-topckgen", "syscon";
+            reg = <0 0x10000000 0 0x1000>;
+            #clock-cells = <1>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8365-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8365-clock.yaml
new file mode 100644 (file)
index 0000000..b327ecb
--- /dev/null
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mediatek,mt8365-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek Functional Clock Controller for MT8365
+
+maintainers:
+  - Markus Schneider-Pargmann <msp@baylibre.com>
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt8365-apu
+          - mediatek,mt8365-imgsys
+          - mediatek,mt8365-mfgcfg
+          - mediatek,mt8365-vdecsys
+          - mediatek,mt8365-vencsys
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    apu: clock-controller@19020000 {
+        compatible = "mediatek,mt8365-apu", "syscon";
+        reg = <0x19020000 0x1000>;
+        #clock-cells = <1>;
+    };
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8365-sys-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8365-sys-clock.yaml
new file mode 100644 (file)
index 0000000..643f846
--- /dev/null
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mediatek,mt8365-sys-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek System Clock Controller for MT8365
+
+maintainers:
+  - Markus Schneider-Pargmann <msp@baylibre.com>
+
+description:
+  The apmixedsys module provides most of PLLs which generated from SoC 26m.
+  The topckgen provides dividers and muxes which provides the clock source to other IP blocks.
+  The infracfg_ao and pericfg_ao provides clock gate in peripheral and infrastructure IP blocks.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt8365-topckgen
+          - mediatek,mt8365-infracfg
+          - mediatek,mt8365-apmixedsys
+          - mediatek,mt8365-pericfg
+          - mediatek,mt8365-mcucfg
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    topckgen: clock-controller@10000000 {
+        compatible = "mediatek,mt8365-topckgen", "syscon";
+        reg = <0x10000000 0x1000>;
+        #clock-cells = <1>;
+    };
index 5b8b37a..81531b5 100644 (file)
@@ -33,6 +33,7 @@ properties:
               - mediatek,mt2712-topckgen
               - mediatek,mt6765-topckgen
               - mediatek,mt6779-topckgen
+              - mediatek,mt6795-topckgen
               - mediatek,mt7629-topckgen
               - mediatek,mt7986-topckgen
               - mediatek,mt8167-topckgen
diff --git a/Documentation/devicetree/bindings/clock/microchip,mpfs-ccc.yaml b/Documentation/devicetree/bindings/clock/microchip,mpfs-ccc.yaml
new file mode 100644 (file)
index 0000000..f177036
--- /dev/null
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/microchip,mpfs-ccc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip PolarFire SoC Fabric Clock Conditioning Circuitry
+
+maintainers:
+  - Conor Dooley <conor.dooley@microchip.com>
+
+description: |
+  Microchip PolarFire SoC has 4 Clock Conditioning Circuitry blocks. Each of
+  these blocks contains two PLLs and 2 DLLs & are located in the four corners of
+  the FPGA. For more information see "PolarFire SoC FPGA Clocking Resources" at:
+  https://onlinedocs.microchip.com/pr/GUID-8F0CC4C0-0317-4262-89CA-CE7773ED1931-en-US-1/index.html
+
+properties:
+  compatible:
+    const: microchip,mpfs-ccc
+
+  reg:
+    items:
+      - description: PLL0's control registers
+      - description: PLL1's control registers
+      - description: DLL0's control registers
+      - description: DLL1's control registers
+
+  clocks:
+    description:
+      The CCC PLL's have two input clocks. It is required that even if the input
+      clocks are identical that both are provided.
+    minItems: 2
+    items:
+      - description: PLL0's refclk0
+      - description: PLL0's refclk1
+      - description: PLL1's refclk0
+      - description: PLL1's refclk1
+      - description: DLL0's refclk
+      - description: DLL1's refclk
+
+  clock-names:
+    minItems: 2
+    items:
+      - const: pll0_ref0
+      - const: pll0_ref1
+      - const: pll1_ref0
+      - const: pll1_ref1
+      - const: dll0_ref
+      - const: dll1_ref
+
+  '#clock-cells':
+    const: 1
+    description: |
+      The clock consumer should specify the desired clock by having the clock
+      ID in its "clocks" phandle cell.
+      See include/dt-bindings/clock/microchip,mpfs-clock.h for the full list of
+      PolarFire clock IDs.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller@38100000 {
+        compatible = "microchip,mpfs-ccc";
+        reg = <0x38010000 0x1000>, <0x38020000 0x1000>,
+              <0x39010000 0x1000>, <0x39020000 0x1000>;
+        #clock-cells = <1>;
+        clocks = <&refclk_ccc>, <&refclk_ccc>, <&refclk_ccc>, <&refclk_ccc>,
+                  <&refclk_ccc>, <&refclk_ccc>;
+        clock-names = "pll0_ref0", "pll0_ref1", "pll1_ref0", "pll1_ref1",
+                      "dll0_ref", "dll1_ref";
+    };
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/clock/microchip,mpfs.yaml#
+$id: http://devicetree.org/schemas/clock/microchip,mpfs-clkcfg.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Microchip PolarFire Clock Control Module Binding
@@ -40,8 +40,21 @@ properties:
     const: 1
     description: |
       The clock consumer should specify the desired clock by having the clock
-      ID in its "clocks" phandle cell. See include/dt-bindings/clock/microchip,mpfs-clock.h
-      for the full list of PolarFire clock IDs.
+      ID in its "clocks" phandle cell.
+      See include/dt-bindings/clock/microchip,mpfs-clock.h for the full list of
+      PolarFire clock IDs.
+
+  resets:
+    maxItems: 1
+
+  '#reset-cells':
+    description:
+      The AHB/AXI peripherals on the PolarFire SoC have reset support, so from
+      CLK_ENVM to CLK_CFM. The reset consumer should specify the desired
+      peripheral via the clock ID in its "resets" phandle cell.
+      See include/dt-bindings/clock/microchip,mpfs-clock.h for the full list of
+      PolarFire clock IDs.
+    const: 1
 
 required:
   - compatible
index fbd7584..fe6ca4f 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Qualcomm A53 PLL Binding
 
 maintainers:
-  - Sivaprakash Murugesan <sivaprak@codeaurora.org>
+  - Bjorn Andersson <andersson@kernel.org>
 
 description:
   The A53 PLL on few Qualcomm platforms is the main CPU PLL used used for
@@ -17,6 +17,7 @@ properties:
   compatible:
     enum:
       - qcom,ipq6018-a53pll
+      - qcom,ipq8074-a53pll
       - qcom,msm8916-a53pll
       - qcom,msm8939-a53pll
 
index 3cf404c..6b4efd6 100644 (file)
@@ -38,6 +38,15 @@ properties:
     description: child tsens device
     $ref: /schemas/thermal/qcom-tsens.yaml#
 
+  clocks:
+    maxItems: 3
+
+  clock-names:
+    items:
+      - const: cxo
+      - const: pxo
+      - const: pll4
+
   nvmem-cells:
     minItems: 1
     maxItems: 2
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8660.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8660.yaml
new file mode 100644 (file)
index 0000000..09b2ea6
--- /dev/null
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,gcc-msm8660.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller Binding for MSM8660
+
+maintainers:
+  - Stephen Boyd <sboyd@kernel.org>
+  - Taniya Das <quic_tdas@quicinc.com>
+
+description: |
+  Qualcomm global clock control module which supports the clocks and resets on
+  MSM8660
+
+  See also:
+  - dt-bindings/clock/qcom,gcc-msm8660.h
+  - dt-bindings/reset/qcom,gcc-msm8660.h
+
+allOf:
+  - $ref: "qcom,gcc.yaml#"
+
+properties:
+  compatible:
+    enum:
+      - qcom,gcc-msm8660
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: pxo
+      - const: cxo
+
+required:
+  - compatible
+
+unevaluatedProperties: false
+
+examples:
+  # Example for GCC for MSM8974:
+  - |
+    clock-controller@900000 {
+      compatible = "qcom,gcc-msm8660";
+      reg = <0x900000 0x4000>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+      clocks = <&pxo_board>, <&cxo_board>;
+      clock-names = "pxo", "cxo";
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8909.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8909.yaml
new file mode 100644 (file)
index 0000000..2272ea5
--- /dev/null
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,gcc-msm8909.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller Binding for MSM8909
+
+maintainers:
+  - Stephan Gerhold <stephan@gerhold.net>
+
+description: |
+  Qualcomm global clock control module which supports the clocks, resets and
+  power domains on MSM8909.
+
+  See also:
+  - dt-bindings/clock/qcom,gcc-msm8909.h
+
+properties:
+  compatible:
+    const: qcom,gcc-msm8909
+
+  clocks:
+    items:
+      - description: XO source
+      - description: Sleep clock source
+      - description: DSI phy instance 0 dsi clock
+      - description: DSI phy instance 0 byte clock
+
+  clock-names:
+    items:
+      - const: xo
+      - const: sleep_clk
+      - const: dsi0pll
+      - const: dsi0pllbyte
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    gcc: clock-controller@1800000 {
+      compatible = "qcom,gcc-msm8909";
+      reg = <0x01800000 0x80000>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+      clocks = <&xo_board>, <&sleep_clk>, <&dsi0_phy 1>, <&dsi0_phy 0>;
+      clock-names = "xo", "sleep_clk", "dsi0pll", "dsi0pllbyte";
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8916.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8916.yaml
new file mode 100644 (file)
index 0000000..2ceb1e5
--- /dev/null
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,gcc-msm8916.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller Binding for MSM8916 and MSM8939
+
+maintainers:
+  - Stephen Boyd <sboyd@kernel.org>
+  - Taniya Das <quic_tdas@quicinc.com>
+
+description: |
+  Qualcomm global clock control module which supports the clocks, resets and
+  power domains on MSM8916 or MSM8939.
+
+  See also:
+  - dt-bindings/clock/qcom,gcc-msm8916.h
+  - dt-bindings/clock/qcom,gcc-msm8939.h
+  - dt-bindings/reset/qcom,gcc-msm8916.h
+  - dt-bindings/reset/qcom,gcc-msm8939.h
+
+properties:
+  compatible:
+    enum:
+      - qcom,gcc-msm8916
+      - qcom,gcc-msm8939
+
+  clocks:
+    items:
+      - description: XO source
+      - description: Sleep clock source
+      - description: DSI phy instance 0 dsi clock
+      - description: DSI phy instance 0 byte clock
+      - description: External MCLK clock
+      - description: External Primary I2S clock
+      - description: External Secondary I2S clock
+
+  clock-names:
+    items:
+      - const: xo
+      - const: sleep_clk
+      - const: dsi0pll
+      - const: dsi0pllbyte
+      - const: ext_mclk
+      - const: ext_pri_i2s
+      - const: ext_sec_i2s
+
+required:
+  - compatible
+
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    clock-controller@300000 {
+      compatible = "qcom,gcc-msm8916";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+      reg = <0x300000 0x90000>;
+    };
+...
index f3430b1..4b7d695 100644 (file)
@@ -45,29 +45,16 @@ properties:
     description:
       Phandle to voltage regulator providing power to the GX domain.
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
 required:
   - compatible
-  - reg
   - clocks
   - clock-names
   - vdd_gfx-supply
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index 22e67b2..7b9fef6 100644 (file)
@@ -32,28 +32,15 @@ properties:
       - const: xo
       - const: sleep
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
 required:
   - compatible
   - clocks
   - clock-names
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index 005e0ed..dfc5165 100644 (file)
@@ -49,30 +49,13 @@ properties:
       - const: ufs_rx_symbol_1_clk_src
       - const: ufs_tx_symbol_0_clk_src
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
-  protected-clocks:
-    description:
-      Protected clock specifier list as per common clock binding.
-
 required:
   - compatible
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index 8151c0a..544a233 100644 (file)
@@ -37,32 +37,15 @@ properties:
       - const: core_bi_pll_test_se # Optional clock
     minItems: 2
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
-  protected-clocks:
-    description:
-      Protected clock specifier list as per common clock binding.
-
 required:
   - compatible
   - clocks
   - clock-names
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index 6c78df0..76988e0 100644 (file)
@@ -18,11 +18,7 @@ description: |
   - dt-bindings/clock/qcom,gcc-ipq4019.h
   - dt-bindings/clock/qcom,gcc-ipq6018.h
   - dt-bindings/reset/qcom,gcc-ipq6018.h
-  - dt-bindings/clock/qcom,gcc-msm8939.h
   - dt-bindings/clock/qcom,gcc-msm8953.h
-  - dt-bindings/reset/qcom,gcc-msm8939.h
-  - dt-bindings/clock/qcom,gcc-msm8660.h
-  - dt-bindings/reset/qcom,gcc-msm8660.h
   - dt-bindings/clock/qcom,gcc-msm8974.h (qcom,gcc-msm8226 and qcom,gcc-msm8974)
   - dt-bindings/reset/qcom,gcc-msm8974.h (qcom,gcc-msm8226 and qcom,gcc-msm8974)
   - dt-bindings/clock/qcom,gcc-mdm9607.h
@@ -40,9 +36,6 @@ properties:
       - qcom,gcc-ipq6018
       - qcom,gcc-mdm9607
       - qcom,gcc-msm8226
-      - qcom,gcc-msm8660
-      - qcom,gcc-msm8916
-      - qcom,gcc-msm8939
       - qcom,gcc-msm8953
       - qcom,gcc-msm8974
       - qcom,gcc-msm8974pro
index 5de9c82..aec37e3 100644 (file)
@@ -30,32 +30,15 @@ properties:
       - const: bi_tcxo
       - const: sleep_clk
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
-  protected-clocks:
-    description:
-      Protected clock specifier list as per common clock binding.
-
 required:
   - compatible
   - clocks
   - clock-names
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index a404c8f..e4d490e 100644 (file)
@@ -33,32 +33,15 @@ properties:
       - const: bi_tcxo_ao
       - const: sleep_clk
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
-  protected-clocks:
-    description:
-      Protected clock specifier list as per common clock binding.
-
 required:
   - compatible
   - clocks
   - clock-names
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index 5693b89..ea61367 100644 (file)
@@ -44,28 +44,15 @@ properties:
       - const: ufs_phy_tx_symbol_0_clk
       - const: usb3_phy_wrapper_gcc_usb30_pipe_clk
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
 required:
   - compatible
   - clocks
   - clock-names
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index f03ef96..30b5d12 100644 (file)
@@ -32,32 +32,15 @@ properties:
       - const: bi_tcxo_ao
       - const: sleep_clk
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
-  protected-clocks:
-    description:
-      Protected clock specifier list as per common clock binding.
-
 required:
   - compatible
   - clocks
   - clock-names
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index 0bcdc69..b1bf768 100644 (file)
@@ -33,7 +33,7 @@ properties:
       - description: Primary USB SuperSpeed pipe clock
       - description: USB4 PHY pipegmux clock source
       - description: USB4 PHY DP gmux clock source
-      - description: USB4 PHY sys piegmux clock source
+      - description: USB4 PHY sys pipegmux clock source
       - description: USB4 PHY PCIe pipe clock
       - description: USB4 PHY router max pipe clock
       - description: Primary USB4 RX0 clock
@@ -46,7 +46,7 @@ properties:
       - description: Second USB4 PHY router max pipe clock
       - description: Secondary USB4 RX0 clock
       - description: Secondary USB4 RX1 clock
-      - description: Multiport USB first SupserSpeed pipe clock
+      - description: Multiport USB first SuperSpeed pipe clock
       - description: Multiport USB second SuperSpeed pipe clock
       - description: PCIe 2a pipe clock
       - description: PCIe 2b pipe clock
@@ -56,30 +56,17 @@ properties:
       - description: First EMAC controller reference clock
       - description: Second EMAC controller reference clock
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
   protected-clocks:
     maxItems: 389
 
 required:
   - compatible
   - clocks
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index daf7906..e169d46 100644 (file)
@@ -19,51 +19,67 @@ description: |
 
 properties:
   compatible:
-    const: qcom,gcc-sdm845
+    enum:
+      - qcom,gcc-sdm670
+      - qcom,gcc-sdm845
 
   clocks:
-    items:
-      - description: Board XO source
-      - description: Board active XO source
-      - description: Sleep clock source
-      - description: PCIE 0 Pipe clock source
-      - description: PCIE 1 Pipe clock source
+    minItems: 3
+    maxItems: 5
 
   clock-names:
-    items:
-      - const: bi_tcxo
-      - const: bi_tcxo_ao
-      - const: sleep_clk
-      - const: pcie_0_pipe_clk
-      - const: pcie_1_pipe_clk
-
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
+    minItems: 3
+    maxItems: 5
 
   power-domains:
     maxItems: 1
 
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
-  protected-clocks:
-    description:
-      Protected clock specifier list as per common clock binding.
-
 required:
   - compatible
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: qcom,gcc-sdm670
+    then:
+      properties:
+        clocks:
+          items:
+            - description: Board XO source
+            - description: Board active XO source
+            - description: Sleep clock source
+        clock-names:
+          items:
+            - const: bi_tcxo
+            - const: bi_tcxo_ao
+            - const: sleep_clk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: qcom,gcc-sdm845
+    then:
+      properties:
+        clocks:
+          items:
+            - description: Board XO source
+            - description: Board active XO source
+            - description: Sleep clock source
+            - description: PCIE 0 Pipe clock source
+            - description: PCIE 1 Pipe clock source
+        clock-names:
+          items:
+            - const: bi_tcxo
+            - const: bi_tcxo_ao
+            - const: sleep_clk
+            - const: pcie_0_pipe_clk
+            - const: pcie_1_pipe_clk
+
+unevaluatedProperties: false
 
 examples:
   # Example for GCC for SDM845:
index b0d1c65..13ffa16 100644 (file)
@@ -35,28 +35,15 @@ properties:
       - const: core_bi_pll_test_se # Optional clock
     minItems: 2
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
 required:
   - compatible
   - clocks
   - clock-names
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index 16c4cdc..8a1419c 100644 (file)
@@ -20,9 +20,6 @@ properties:
   compatible:
     const: qcom,gcc-sdx65
 
-  reg:
-    maxItems: 1
-
   clocks:
     items:
       - description: Board XO source
@@ -43,25 +40,15 @@ properties:
       - const: core_bi_pll_test_se # Optional clock
     minItems: 5
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
 required:
   - compatible
-  - reg
   - clocks
   - clock-names
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index 26050da..bb81a27 100644 (file)
@@ -30,32 +30,15 @@ properties:
       - const: bi_tcxo
       - const: sleep_clk
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
-  protected-clocks:
-    description:
-      Protected clock specifier list as per common clock binding.
-
 required:
   - compatible
   - clocks
   - clock-names
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index ab12b39..03e84e1 100644 (file)
@@ -30,32 +30,15 @@ properties:
       - const: bi_tcxo
       - const: sleep_clk
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
-  protected-clocks:
-    description:
-      Protected clock specifier list as per common clock binding.
-
 required:
   - compatible
   - clocks
   - clock-names
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index 20926cd..cbe98c0 100644 (file)
@@ -32,32 +32,15 @@ properties:
       - const: bi_tcxo_ao
       - const: sleep_clk
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
-  protected-clocks:
-    description:
-      Protected clock specifier list as per common clock binding.
-
 required:
   - compatible
   - clocks
   - clock-names
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index 12766a8..0333ccb 100644 (file)
@@ -31,32 +31,15 @@ properties:
       - const: bi_tcxo
       - const: sleep_clk
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
-  protected-clocks:
-    description:
-      Protected clock specifier list as per common clock binding.
-
 required:
   - compatible
   - clocks
   - clock-names
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index 80bd6ca..4e2a9ca 100644 (file)
@@ -31,32 +31,15 @@ properties:
       - const: bi_tcxo
       - const: sleep_clk
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
-  protected-clocks:
-    description:
-      Protected clock specifier list as per common clock binding.
-
 required:
   - compatible
   - clocks
   - clock-names
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index 1122700..3edbeca 100644 (file)
@@ -54,28 +54,15 @@ properties:
       - const: usb3_uni_phy_sec_gcc_usb30_pipe_clk # Optional clock
     minItems: 2
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
 required:
   - compatible
   - clocks
   - clock-names
-  - reg
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index 58d98a7..102ce68 100644 (file)
@@ -46,28 +46,15 @@ properties:
       - const: usb3_phy_wrapper_gcc_usb30_pipe_clk # Optional clock
     minItems: 2
 
-  '#clock-cells':
-    const: 1
-
-  '#reset-cells':
-    const: 1
-
-  '#power-domain-cells':
-    const: 1
-
-  reg:
-    maxItems: 1
-
 required:
   - compatible
-  - reg
   - clocks
   - clock-names
-  - '#clock-cells'
-  - '#reset-cells'
-  - '#power-domain-cells'
 
-additionalProperties: false
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
 
 examples:
   - |
index 9ebcb19..a7d0af1 100644 (file)
@@ -17,6 +17,7 @@ description: |
     dt-bindings/clock/qcom,gpucc-sdm845.h
     dt-bindings/clock/qcom,gpucc-sc7180.h
     dt-bindings/clock/qcom,gpucc-sc7280.h
+    dt-bindings/clock/qcom,gpucc-sc8280xp.h
     dt-bindings/clock/qcom,gpucc-sm6350.h
     dt-bindings/clock/qcom,gpucc-sm8150.h
     dt-bindings/clock/qcom,gpucc-sm8250.h
@@ -28,6 +29,7 @@ properties:
       - qcom,sc7180-gpucc
       - qcom,sc7280-gpucc
       - qcom,sc8180x-gpucc
+      - qcom,sc8280xp-gpucc
       - qcom,sm6350-gpucc
       - qcom,sm8150-gpucc
       - qcom,sm8250-gpucc
index 32e8701..03faab5 100644 (file)
@@ -31,30 +31,12 @@ properties:
       - qcom,mmcc-sdm660
 
   clocks:
-    items:
-      - description: Board XO source
-      - description: Board sleep source
-      - description: Global PLL 0 clock
-      - description: DSI phy instance 0 dsi clock
-      - description: DSI phy instance 0 byte clock
-      - description: DSI phy instance 1 dsi clock
-      - description: DSI phy instance 1 byte clock
-      - description: HDMI phy PLL clock
-      - description: DisplayPort phy PLL vco clock
-      - description: DisplayPort phy PLL link clock
+    minItems: 8
+    maxItems: 10
 
   clock-names:
-    items:
-      - const: xo
-      - const: sleep
-      - const: gpll0
-      - const: dsi0dsi
-      - const: dsi0byte
-      - const: dsi1dsi
-      - const: dsi1byte
-      - const: hdmipll
-      - const: dpvco
-      - const: dplink
+    minItems: 8
+    maxItems: 10
 
   '#clock-cells':
     const: 1
@@ -85,16 +67,179 @@ required:
 
 additionalProperties: false
 
-if:
-  properties:
-    compatible:
-      contains:
-        const: qcom,mmcc-msm8998
-
-then:
-  required:
-    - clocks
-    - clock-names
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,mmcc-apq8064
+              - qcom,mmcc-msm8960
+    then:
+      properties:
+        clocks:
+          items:
+            - description: Board PXO source
+            - description: PLL 3 clock
+            - description: PLL 3 Vote clock
+            - description: DSI phy instance 1 dsi clock
+            - description: DSI phy instance 1 byte clock
+            - description: DSI phy instance 2 dsi clock
+            - description: DSI phy instance 2 byte clock
+            - description: HDMI phy PLL clock
+
+        clock-names:
+          items:
+            - const: pxo
+            - const: pll3
+            - const: pll8_vote
+            - const: dsi1pll
+            - const: dsi1pllbyte
+            - const: dsi2pll
+            - const: dsi2pllbyte
+            - const: hdmipll
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,mmcc-msm8994
+              - qcom,mmcc-msm8998
+              - qcom,mmcc-sdm630
+              - qcom,mmcc-sdm660
+    then:
+      required:
+        - clocks
+        - clock-names
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: qcom,mmcc-msm8994
+    then:
+      properties:
+        clocks:
+          items:
+            - description: Board XO source
+            - description: Global PLL 0 clock
+            - description: MMSS NoC AHB clock
+            - description: GFX3D clock
+            - description: DSI phy instance 0 dsi clock
+            - description: DSI phy instance 0 byte clock
+            - description: DSI phy instance 1 dsi clock
+            - description: DSI phy instance 1 byte clock
+            - description: HDMI phy PLL clock
+
+        clock-names:
+          items:
+            - const: xo
+            - const: gpll0
+            - const: mmssnoc_ahb
+            - const: oxili_gfx3d_clk_src
+            - const: dsi0pll
+            - const: dsi0pllbyte
+            - const: dsi1pll
+            - const: dsi1pllbyte
+            - const: hdmipll
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: qcom,mmcc-msm8996
+    then:
+      properties:
+        clocks:
+          items:
+            - description: Board XO source
+            - description: Global PLL 0 clock
+            - description: MMSS NoC AHB clock
+            - description: DSI phy instance 0 dsi clock
+            - description: DSI phy instance 0 byte clock
+            - description: DSI phy instance 1 dsi clock
+            - description: DSI phy instance 1 byte clock
+            - description: HDMI phy PLL clock
+
+        clock-names:
+          items:
+            - const: xo
+            - const: gpll0
+            - const: gcc_mmss_noc_cfg_ahb_clk
+            - const: dsi0pll
+            - const: dsi0pllbyte
+            - const: dsi1pll
+            - const: dsi1pllbyte
+            - const: hdmipll
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: qcom,mmcc-msm8998
+    then:
+      properties:
+        clocks:
+          items:
+            - description: Board XO source
+            - description: Global PLL 0 clock
+            - description: DSI phy instance 0 dsi clock
+            - description: DSI phy instance 0 byte clock
+            - description: DSI phy instance 1 dsi clock
+            - description: DSI phy instance 1 byte clock
+            - description: HDMI phy PLL clock
+            - description: DisplayPort phy PLL link clock
+            - description: DisplayPort phy PLL vco clock
+            - description: Test clock
+
+        clock-names:
+          items:
+            - const: xo
+            - const: gpll0
+            - const: dsi0dsi
+            - const: dsi0byte
+            - const: dsi1dsi
+            - const: dsi1byte
+            - const: hdmipll
+            - const: dplink
+            - const: dpvco
+            - const: core_bi_pll_test_se
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,mmcc-sdm630
+              - qcom,mmcc-sdm660
+    then:
+      properties:
+        clocks:
+          items:
+            - description: Board XO source
+            - description: Board sleep source
+            - description: Global PLL 0 clock
+            - description: Global PLL 0 DIV clock
+            - description: DSI phy instance 0 dsi clock
+            - description: DSI phy instance 0 byte clock
+            - description: DSI phy instance 1 dsi clock
+            - description: DSI phy instance 1 byte clock
+            - description: DisplayPort phy PLL link clock
+            - description: DisplayPort phy PLL vco clock
+
+        clock-names:
+          items:
+            - const: xo
+            - const: sleep_clk
+            - const: gpll0
+            - const: gpll0_div
+            - const: dsi0pll
+            - const: dsi0pllbyte
+            - const: dsi1pll
+            - const: dsi1pllbyte
+            - const: dp_link_2x_clk_divsel_five
+            - const: dp_vco_divided_clk_src_mux
 
 examples:
   # Example for MMCC for MSM8960:
index a20cb10..c497123 100644 (file)
@@ -26,22 +26,18 @@ properties:
 
   clocks:
     items:
-      - description: Primary PLL clock for power cluster (little)
-      - description: Primary PLL clock for perf cluster (big)
-      - description: Alternate PLL clock for power cluster (little)
-      - description: Alternate PLL clock for perf cluster (big)
+      - description: XO source
 
   clock-names:
     items:
-      - const: pwrcl_pll
-      - const: perfcl_pll
-      - const: pwrcl_alt_pll
-      - const: perfcl_alt_pll
+      - const: xo
 
 required:
   - compatible
   - reg
   - '#clock-cells'
+  - clocks
+  - clock-names
 
 additionalProperties: false
 
@@ -51,4 +47,7 @@ examples:
         compatible = "qcom,msm8996-apcc";
         reg = <0x6400000 0x90000>;
         #clock-cells = <1>;
+
+        clocks = <&xo_board>;
+        clock-names = "xo";
     };
index d63b45a..2a95bf8 100644 (file)
@@ -29,6 +29,7 @@ properties:
           - qcom,rpmcc-mdm9607
           - qcom,rpmcc-msm8226
           - qcom,rpmcc-msm8660
+          - qcom,rpmcc-msm8909
           - qcom,rpmcc-msm8916
           - qcom,rpmcc-msm8936
           - qcom,rpmcc-msm8953
@@ -43,6 +44,7 @@ properties:
           - qcom,rpmcc-sdm660
           - qcom,rpmcc-sm6115
           - qcom,rpmcc-sm6125
+          - qcom,rpmcc-sm6375
       - const: qcom,rpmcc
 
   '#clock-cells':
index 8fcaf41..437a34b 100644 (file)
@@ -21,6 +21,7 @@ properties:
       - qcom,sc7280-rpmh-clk
       - qcom,sc8180x-rpmh-clk
       - qcom,sc8280xp-rpmh-clk
+      - qcom,sdm670-rpmh-clk
       - qcom,sdm845-rpmh-clk
       - qcom,sdx55-rpmh-clk
       - qcom,sdx65-rpmh-clk
index 47028d7..633887d 100644 (file)
@@ -36,13 +36,11 @@ properties:
     items:
       - description: LPASS qdsp6ss register
       - description: LPASS top-cc register
-      - description: LPASS cc register
 
   reg-names:
     items:
       - const: qdsp6ss
       - const: top_cc
-      - const: cc
 
 required:
   - compatible
@@ -59,8 +57,8 @@ examples:
     #include <dt-bindings/clock/qcom,lpass-sc7280.h>
     clock-controller@3000000 {
       compatible = "qcom,sc7280-lpasscc";
-      reg = <0x03000000 0x40>, <0x03c04000 0x4>, <0x03389000 0x24>;
-      reg-names = "qdsp6ss", "top_cc", "cc";
+      reg = <0x03000000 0x40>, <0x03c04000 0x4>;
+      reg-names = "qdsp6ss", "top_cc";
       clocks = <&gcc GCC_CFG_NOC_LPASS_CLK>;
       clock-names = "iface";
       #clock-cells = <1>;
index bad9135..f50e284 100644 (file)
@@ -22,6 +22,8 @@ properties:
 
   clock-names: true
 
+  reg: true
+
   compatible:
     enum:
       - qcom,sc7280-lpassaoncc
@@ -38,8 +40,14 @@ properties:
   '#power-domain-cells':
     const: 1
 
-  reg:
-    maxItems: 1
+  '#reset-cells':
+    const: 1
+
+  qcom,adsp-pil-mode:
+    description:
+      Indicates if the LPASS would be brought out of reset using
+      peripheral loader.
+    type: boolean
 
 required:
   - compatible
@@ -69,6 +77,11 @@ allOf:
           items:
             - const: bi_tcxo
             - const: lpass_aon_cc_main_rcg_clk_src
+
+        reg:
+          items:
+            - description: lpass core cc register
+            - description: lpass audio csr register
   - if:
       properties:
         compatible:
@@ -90,6 +103,8 @@ allOf:
             - const: bi_tcxo_ao
             - const: iface
 
+        reg:
+          maxItems: 1
   - if:
       properties:
         compatible:
@@ -108,6 +123,8 @@ allOf:
           items:
             - const: bi_tcxo
 
+        reg:
+          maxItems: 1
 examples:
   - |
     #include <dt-bindings/clock/qcom,rpmh.h>
@@ -116,13 +133,15 @@ examples:
     #include <dt-bindings/clock/qcom,lpasscorecc-sc7280.h>
     lpass_audiocc: clock-controller@3300000 {
       compatible = "qcom,sc7280-lpassaudiocc";
-      reg = <0x3300000 0x30000>;
+      reg = <0x3300000 0x30000>,
+            <0x32a9000 0x1000>;
       clocks = <&rpmhcc RPMH_CXO_CLK>,
                <&lpass_aon LPASS_AON_CC_MAIN_RCG_CLK_SRC>;
       clock-names = "bi_tcxo", "lpass_aon_cc_main_rcg_clk_src";
       power-domains = <&lpass_aon LPASS_AON_CC_LPASS_AUDIO_HM_GDSC>;
       #clock-cells = <1>;
       #power-domain-cells = <1>;
+      #reset-cells = <1>;
     };
 
   - |
@@ -165,6 +184,7 @@ examples:
       clocks = <&rpmhcc RPMH_CXO_CLK>, <&rpmhcc RPMH_CXO_CLK_A>,
                <&lpasscore LPASS_CORE_CC_CORE_CLK>;
       clock-names = "bi_tcxo", "bi_tcxo_ao","iface";
+      qcom,adsp-pil-mode;
       #clock-cells = <1>;
       #power-domain-cells = <1>;
     };
diff --git a/Documentation/devicetree/bindings/clock/qcom,sm6115-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm6115-dispcc.yaml
new file mode 100644 (file)
index 0000000..6660ff1
--- /dev/null
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,sm6115-dispcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Display Clock Controller for SM6115
+
+maintainers:
+  - Bjorn Andersson <andersson@kernel.org>
+
+description: |
+  Qualcomm display clock control module which supports the clocks and
+  power domains on SM6115.
+
+  See also:
+    include/dt-bindings/clock/qcom,sm6115-dispcc.h
+
+properties:
+  compatible:
+    enum:
+      - qcom,sm6115-dispcc
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Board sleep clock
+      - description: Byte clock from DSI PHY0
+      - description: Pixel clock from DSI PHY0
+      - description: GPLL0 DISP DIV clock from GCC
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmcc.h>
+    #include <dt-bindings/clock/qcom,gcc-sm6115.h>
+    clock-controller@5f00000 {
+      compatible = "qcom,sm6115-dispcc";
+      reg = <0x5f00000 0x20000>;
+      clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+               <&sleep_clk>,
+               <&dsi0_phy 0>,
+               <&dsi0_phy 1>,
+               <&gcc GCC_DISP_GPLL0_DIV_CLK_SRC>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,sm6375-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm6375-gcc.yaml
new file mode 100644 (file)
index 0000000..3c573e1
--- /dev/null
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,sm6375-gcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller Binding for SM6375
+
+maintainers:
+  - Konrad Dybcio <konrad.dybcio@somainline.org>
+
+description: |
+  Qualcomm global clock control module which supports the clocks, resets and
+  power domains on SM6375
+
+  See also:
+  - dt-bindings/clock/qcom,sm6375-gcc.h
+
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+properties:
+  compatible:
+    const: qcom,sm6375-gcc
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Board XO Active-Only source
+      - description: Sleep clock source
+
+required:
+  - compatible
+  - clocks
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmcc.h>
+    clock-controller@1400000 {
+      compatible = "qcom,sm6375-gcc";
+      reg = <0x01400000 0x1f0000>;
+      clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+               <&rpmcc RPM_SMD_XO_A_CLK_SRC>,
+               <&sleep_clk>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-dispcc.yaml
new file mode 100644 (file)
index 0000000..1cc2457
--- /dev/null
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,sm8450-dispcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Display Clock & Reset Controller for SM8450
+
+maintainers:
+  - Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+description: |
+  Qualcomm display clock control module which supports the clocks, resets and
+  power domains on SM8450.
+
+  See also:
+    include/dt-bindings/clock/qcom,sm8450-dispcc.h
+
+properties:
+  compatible:
+    enum:
+      - qcom,sm8450-dispcc
+
+  clocks:
+    minItems: 3
+    items:
+      - description: Board XO source
+      - description: Board Always On XO source
+      - description: Display's AHB clock
+      - description: sleep clock
+      - description: Byte clock from DSI PHY0
+      - description: Pixel clock from DSI PHY0
+      - description: Byte clock from DSI PHY1
+      - description: Pixel clock from DSI PHY1
+      - description: Link clock from DP PHY0
+      - description: VCO DIV clock from DP PHY0
+      - description: Link clock from DP PHY1
+      - description: VCO DIV clock from DP PHY1
+      - description: Link clock from DP PHY2
+      - description: VCO DIV clock from DP PHY2
+      - description: Link clock from DP PHY3
+      - description: VCO DIV clock from DP PHY3
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    description:
+      A phandle and PM domain specifier for the MMCX power domain.
+    maxItems: 1
+
+  required-opps:
+    description:
+      A phandle to an OPP node describing required MMCX performance point.
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,gcc-sm8450.h>
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    #include <dt-bindings/power/qcom-rpmpd.h>
+    clock-controller@af00000 {
+      compatible = "qcom,sm8450-dispcc";
+      reg = <0x0af00000 0x10000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&rpmhcc RPMH_CXO_CLK_A>,
+               <&gcc GCC_DISP_AHB_CLK>,
+               <&sleep_clk>,
+               <&dsi0_phy 0>,
+               <&dsi0_phy 1>,
+               <&dsi1_phy 0>,
+               <&dsi1_phy 1>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+      power-domains = <&rpmhpd SM8450_MMCX>;
+      required-opps = <&rpmhpd_opp_low_svs>;
+    };
+...
index 6eaabb4..81f09df 100644 (file)
@@ -47,7 +47,6 @@ properties:
     maxItems: 1
 
   clocks:
-    minItems: 4
     maxItems: 4
 
   clock-names:
@@ -64,7 +63,6 @@ properties:
     maxItems: 1
 
   resets:
-    minItems: 2
     maxItems: 2
 
   reset-names:
index d036675..487f74c 100644 (file)
@@ -24,7 +24,7 @@ description: |
 properties:
   compatible:
     enum:
-      - renesas,r9a07g043-cpg # RZ/G2UL{Type-1,Type-2}
+      - renesas,r9a07g043-cpg # RZ/G2UL{Type-1,Type-2} and RZ/Five
       - renesas,r9a07g044-cpg # RZ/G2{L,LC}
       - renesas,r9a07g054-cpg # RZ/V2L
       - renesas,r9a09g011-cpg # RZ/V2M
diff --git a/Documentation/devicetree/bindings/clock/renesas,versaclock7.yaml b/Documentation/devicetree/bindings/clock/renesas,versaclock7.yaml
new file mode 100644 (file)
index 0000000..8d4eb44
--- /dev/null
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/renesas,versaclock7.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas Versaclock7 Programmable Clock Device Tree Bindings
+
+maintainers:
+  - Alex Helms <alexander.helms.jy@renesas.com>
+
+description: |
+  Renesas Versaclock7 is a family of configurable clock generator and
+  jitter attenuator ICs with fractional and integer dividers.
+
+properties:
+  '#clock-cells':
+    const: 1
+
+  compatible:
+    enum:
+      - renesas,rc21008a
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: External crystal or oscillator
+
+  clock-names:
+    items:
+      - const: xin
+
+required:
+  - '#clock-cells'
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    vc7_xin: clock {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <49152000>;
+    };
+
+    i2c@0 {
+        reg = <0x0 0x100>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        vc7: clock-controller@9 {
+            compatible = "renesas,rc21008a";
+            reg = <0x9>;
+            #clock-cells = <1>;
+            clocks = <&vc7_xin>;
+            clock-names = "xin";
+        };
+    };
index 3eec381..0f0f64b 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/clock/rockchip,px30-cru.yaml#
index 1376230..ba5b454 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/clock/rockchip,rk3036-cru.yaml#
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt
deleted file mode 100644 (file)
index 6f8744f..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-* Rockchip RK3126/RK3128 Clock and Reset Unit
-
-The RK3126/RK3128 clock controller generates and supplies clock to various
-controllers within the SoC and also implements a reset controller for SoC
-peripherals.
-
-Required Properties:
-
-- compatible: should be "rockchip,rk3126-cru" or "rockchip,rk3128-cru"
-  "rockchip,rk3126-cru" - controller compatible with RK3126 SoC.
-  "rockchip,rk3128-cru" - controller compatible with RK3128 SoC.
-- reg: physical base address of the controller and length of memory mapped
-  region.
-- #clock-cells: should be 1.
-- #reset-cells: should be 1.
-
-Optional Properties:
-
-- rockchip,grf: phandle to the syscon managing the "general register files"
-  If missing pll rates are not changeable, due to the missing pll lock status.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume. All available clocks are defined as
-preprocessor macros in the dt-bindings/clock/rk3128-cru.h headers and can be
-used in device tree sources. Similar macros exist for the reset sources in
-these files.
-
-External clocks:
-
-There are several clocks that are generated outside the SoC. It is expected
-that they are defined using standard clock bindings with following
-clock-output-names:
- - "xin24m" - crystal input - required,
- - "ext_i2s" - external I2S clock - optional,
- - "gmac_clkin" - external GMAC clock - optional
-
-Example: Clock controller node:
-
-       cru: cru@20000000 {
-               compatible = "rockchip,rk3128-cru";
-               reg = <0x20000000 0x1000>;
-               rockchip,grf = <&grf>;
-
-               #clock-cells = <1>;
-               #reset-cells = <1>;
-       };
-
-Example: UART controller node that consumes the clock generated by the clock
-  controller:
-
-       uart2: serial@20068000 {
-               compatible = "rockchip,serial";
-               reg = <0x20068000 0x100>;
-               interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
-               clock-frequency = <24000000>;
-               clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
-               clock-names = "sclk_uart", "pclk_uart";
-       };
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.yaml
new file mode 100644 (file)
index 0000000..b3d9c8e
--- /dev/null
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/rockchip,rk3128-cru.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3126/RK3128 Clock and Reset Unit (CRU)
+
+maintainers:
+  - Elaine Zhang <zhangqing@rock-chips.com>
+  - Heiko Stuebner <heiko@sntech.de>
+
+description: |
+  The RK3126/RK3128 clock controller generates and supplies clock to various
+  controllers within the SoC and also implements a reset controller for SoC
+  peripherals.
+  Each clock is assigned an identifier and client nodes can use this identifier
+  to specify the clock which they consume. All available clocks are defined as
+  preprocessor macros in the dt-bindings/clock/rk3128-cru.h headers and can be
+  used in device tree sources. Similar macros exist for the reset sources in
+  these files.
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk3126-cru
+      - rockchip,rk3128-cru
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+  clocks:
+    minItems: 1
+    maxItems: 3
+
+  clock-names:
+    minItems: 1
+    items:
+      - const: xin24m
+      - enum:
+          - ext_i2s
+          - gmac_clkin
+      - enum:
+          - ext_i2s
+          - gmac_clkin
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the syscon managing the "general register files" (GRF),
+      if missing pll rates are not changeable, due to the missing pll
+      lock status.
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    cru: clock-controller@20000000 {
+      compatible = "rockchip,rk3128-cru";
+      reg = <0x20000000 0x1000>;
+      rockchip,grf = <&grf>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
index cf7dc01..1050fff 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/clock/rockchip,rk3228-cru.yaml#
index 96bc057..6655e97 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/clock/rockchip,rk3288-cru.yaml#
index 523ee57..fec37f5 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/clock/rockchip,rk3308-cru.yaml#
index adb6787..90af242 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/clock/rockchip,rk3368-cru.yaml#
index 54da1e3..0b758e0 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0-only
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/clock/rockchip,rk3399-cru.yaml#
index 20421c2..4611d92 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/clock/rockchip,rv1108-cru.yaml#
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rv1126-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rv1126-cru.yaml
new file mode 100644 (file)
index 0000000..0998f8b
--- /dev/null
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/rockchip,rv1126-cru.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RV1126 Clock and Reset Unit
+
+maintainers:
+  - Jagan Teki <jagan@edgeble.ai>
+  - Finley Xiao <finley.xiao@rock-chips.com>
+  - Heiko Stuebner <heiko@sntech.de>
+
+description:
+  The RV1126 clock controller generates the clock and also implements a
+  reset controller for SoC peripherals.
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rv1126-cru
+      - rockchip,rv1126-pmucru
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: xin24m
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the syscon managing the "general register files" (GRF),
+      if missing pll rates are not changeable, due to the missing pll
+      lock status.
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    cru: clock-controller@ff490000 {
+      compatible = "rockchip,rv1126-cru";
+      reg = <0xff490000 0x1000>;
+      rockchip,grf = <&grf>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
index aa11815..141cf17 100644 (file)
@@ -33,10 +33,13 @@ properties:
     enum:
       - samsung,exynos850-cmu-top
       - samsung,exynos850-cmu-apm
+      - samsung,exynos850-cmu-aud
       - samsung,exynos850-cmu-cmgp
       - samsung,exynos850-cmu-core
       - samsung,exynos850-cmu-dpu
       - samsung,exynos850-cmu-hsi
+      - samsung,exynos850-cmu-is
+      - samsung,exynos850-cmu-mfcmscl
       - samsung,exynos850-cmu-peri
 
   clocks:
@@ -92,6 +95,24 @@ allOf:
       properties:
         compatible:
           contains:
+            const: samsung,exynos850-cmu-aud
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: AUD clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_aud
+
+  - if:
+      properties:
+        compatible:
+          contains:
             const: samsung,exynos850-cmu-cmgp
 
     then:
@@ -176,6 +197,54 @@ allOf:
       properties:
         compatible:
           contains:
+            const: samsung,exynos850-cmu-is
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_IS bus clock (from CMU_TOP)
+            - description: Image Texture Processing core clock (from CMU_TOP)
+            - description: Visual Recognition Accelerator clock (from CMU_TOP)
+            - description: Geometric Distortion Correction clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_is_bus
+            - const: dout_is_itp
+            - const: dout_is_vra
+            - const: dout_is_gdc
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-mfcmscl
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: Multi-Format Codec clock (from CMU_TOP)
+            - description: Memory to Memory Scaler clock (from CMU_TOP)
+            - description: Multi-Channel Scaler clock (from CMU_TOP)
+            - description: JPEG codec clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_mfcmscl_mfc
+            - const: dout_mfcmscl_m2m
+            - const: dout_mfcmscl_mcsc
+            - const: dout_mfcmscl_jpeg
+
+  - if:
+      properties:
+        compatible:
+          contains:
             const: samsung,exynos850-cmu-peri
 
     then:
index eafc715..2ab4642 100644 (file)
@@ -35,6 +35,8 @@ properties:
       - samsung,exynosautov9-cmu-top
       - samsung,exynosautov9-cmu-busmc
       - samsung,exynosautov9-cmu-core
+      - samsung,exynosautov9-cmu-fsys0
+      - samsung,exynosautov9-cmu-fsys1
       - samsung,exynosautov9-cmu-fsys2
       - samsung,exynosautov9-cmu-peric0
       - samsung,exynosautov9-cmu-peric1
@@ -111,6 +113,48 @@ allOf:
       properties:
         compatible:
           contains:
+            const: samsung,exynosautov9-cmu-fsys0
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_FSYS0 bus clock (from CMU_TOP)
+            - description: CMU_FSYS0 pcie clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_clkcmu_fsys0_bus
+            - const: dout_clkcmu_fsys0_pcie
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynosautov9-cmu-fsys1
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_FSYS1 bus clock (from CMU_TOP)
+            - description: CMU_FSYS1 mmc card clock (from CMU_TOP)
+            - description: CMU_FSYS1 usb clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_clkcmu_fsys1_bus
+            - const: dout_clkcmu_fsys1_mmc_card
+            - const: dout_clkcmu_fsys1_usbdrd
+
+  - if:
+      properties:
+        compatible:
+          contains:
             const: samsung,exynosautov9-cmu-fsys2
 
     then:
index 9248bfc..d5296e6 100644 (file)
@@ -34,7 +34,6 @@ properties:
     const: 1
 
   clock-output-names:
-    minItems: 3
     maxItems: 3
     description: Names for AP, CP and BT clocks.
 
index b4820b1..4982615 100644 (file)
@@ -10,7 +10,7 @@ will be controlled instead and the corresponding hw-ops for
 that is used.
 
 [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
-[2] Documentation/devicetree/bindings/clock/gpio-gate-clock.txt
+[2] Documentation/devicetree/bindings/clock/gpio-gate-clock.yaml
 [3] Documentation/devicetree/bindings/clock/ti/clockdomain.txt
 
 Required properties:
index 94ec77d..d3eb5ca 100644 (file)
@@ -9,7 +9,7 @@ companion clock finding (match corresponding functional gate
 clock) and hardware autoidle enable / disable.
 
 [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
-[2] Documentation/devicetree/bindings/clock/gpio-gate-clock.txt
+[2] Documentation/devicetree/bindings/clock/gpio-gate-clock.yaml
 
 Required properties:
 - compatible : shall be one of:
diff --git a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
new file mode 100644 (file)
index 0000000..634b7b9
--- /dev/null
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/clock/xlnx,clocking-wizard.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Xilinx clocking wizard
+
+maintainers:
+  - Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
+
+description:
+  The clocking wizard is a soft ip clocking block of Xilinx versal. It
+  reads required input clock frequencies from the devicetree and acts as clock
+  clock output.
+
+properties:
+  compatible:
+    enum:
+      - xlnx,clocking-wizard
+      - xlnx,clocking-wizard-v5.2
+      - xlnx,clocking-wizard-v6.0
+
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+  clocks:
+    items:
+      - description: clock input
+      - description: axi clock
+
+  clock-names:
+    items:
+      - const: clk_in1
+      - const: s_axi_aclk
+
+
+  xlnx,speed-grade:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1, 2, 3]
+    description:
+      Speed grade of the device. Higher the speed grade faster is the FPGA device.
+
+  xlnx,nr-outputs:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1
+    maximum: 8
+    description:
+      Number of outputs.
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - xlnx,speed-grade
+  - xlnx,nr-outputs
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller@b0000000  {
+        compatible = "xlnx,clocking-wizard";
+        reg = <0xb0000000 0x10000>;
+        #clock-cells = <1>;
+        xlnx,speed-grade = <1>;
+        xlnx,nr-outputs = <6>;
+        clock-names = "clk_in1", "s_axi_aclk";
+        clocks = <&clkc 15>, <&clkc 15>;
+    };
+...
index 4a92a4c..f816898 100644 (file)
@@ -233,6 +233,7 @@ allOf:
               - allwinner,sun8i-a83t-tcon-lcd
               - allwinner,sun8i-v3s-tcon
               - allwinner,sun9i-a80-tcon-lcd
+              - allwinner,sun20i-d1-tcon-lcd
 
     then:
       properties:
@@ -252,6 +253,7 @@ allOf:
               - allwinner,sun8i-a83t-tcon-tv
               - allwinner,sun8i-r40-tcon-tv
               - allwinner,sun9i-a80-tcon-tv
+              - allwinner,sun20i-d1-tcon-tv
 
     then:
       properties:
@@ -278,6 +280,7 @@ allOf:
               - allwinner,sun9i-a80-tcon-lcd
               - allwinner,sun4i-a10-tcon
               - allwinner,sun8i-a83t-tcon-lcd
+              - allwinner,sun20i-d1-tcon-lcd
 
     then:
       required:
@@ -294,6 +297,7 @@ allOf:
               - allwinner,sun8i-a23-tcon
               - allwinner,sun8i-a33-tcon
               - allwinner,sun8i-a83t-tcon-lcd
+              - allwinner,sun20i-d1-tcon-lcd
 
     then:
       properties:
index ad285cb..ef4814c 100644 (file)
@@ -261,7 +261,7 @@ additionalProperties: false
 
 examples:
   - |
-    #include <dt-bindings/clk/lochnagar.h>
+    #include <dt-bindings/clock/lochnagar.h>
     #include <dt-bindings/pinctrl/lochnagar.h>
     i2c@e0004000 {
         #address-cells = <1>;
index e6cb229..7ae8aa1 100644 (file)
@@ -14,7 +14,7 @@ MAC node:
 - mac-address : The 6-byte MAC address. If present, it is the default
        MAC address.
 - internal-phy : phandle to the internal PHY node
-- phy-handle : phandle the external PHY node
+- phy-handle : phandle to the external PHY node
 
 Internal PHY node:
 - compatible : Should be "qcom,fsm9900-emac-sgmii" or "qcom,qdf2432-emac-sgmii".
index b539781..835b533 100644 (file)
@@ -47,12 +47,6 @@ properties:
         description:
           Properties for single LDO regulator.
 
-        properties:
-          regulator-name:
-            pattern: "^LDO[1-5]$"
-            description:
-              should be "LDO1", ..., "LDO5"
-
         unevaluatedProperties: false
 
       "^BUCK[1-6]$":
@@ -62,11 +56,6 @@ properties:
           Properties for single BUCK regulator.
 
         properties:
-          regulator-name:
-            pattern: "^BUCK[1-6]$"
-            description:
-              should be "BUCK1", ..., "BUCK6"
-
           nxp,dvs-run-voltage:
             $ref: "/schemas/types.yaml#/definitions/uint32"
             minimum: 600000
index 553601a..510b82c 100644 (file)
@@ -10,7 +10,7 @@ description:
   See spi-peripheral-props.yaml for more info.
 
 maintainers:
-  - Pratyush Yadav <p.yadav@ti.com>
+  - Vaishnav Achath <vaishnav.a@ti.com>
 
 properties:
   # cdns,qspi-nor.yaml
index 0a537fa..4707294 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Cadence Quad SPI controller
 
 maintainers:
-  - Pratyush Yadav <p.yadav@ti.com>
+  - Vaishnav Achath <vaishnav.a@ti.com>
 
 allOf:
   - $ref: spi-controller.yaml#
index ce048e7..a4abe15 100644 (file)
@@ -16,7 +16,7 @@ description:
   their own separate schema that should be referenced from here.
 
 maintainers:
-  - Pratyush Yadav <p.yadav@ti.com>
+  - Mark Brown <broonie@kernel.org>
 
 properties:
   reg:
index 00dcbdd..119998d 100644 (file)
@@ -42,7 +42,7 @@ properties:
     description:
       Address ranges of the thermal registers. If more then one range is given
       the first one must be the common registers followed by each sensor
-      according the datasheet.
+      according to the datasheet.
     minItems: 1
     maxItems: 4
 
index 7fb3986..858ed5d 100644 (file)
@@ -525,8 +525,8 @@ followed by a test macro::
 If you need to expose a compiler capability to makefiles and/or C source files,
 `CC_HAS_` is the recommended prefix for the config option::
 
-  config CC_HAS_ASM_GOTO
-       def_bool $(success,$(srctree)/scripts/gcc-goto.sh $(CC))
+  config CC_HAS_FOO
+       def_bool $(success,$(srctree)/scripts/cc-check-foo.sh $(CC))
 
 Build as module only
 ~~~~~~~~~~~~~~~~~~~~
index e12eae1..6bf7f0c 100644 (file)
@@ -33,7 +33,7 @@ EXAMPLE
 =======
 In the example below, **rtla timerlat hist** is set to run for *10* minutes,
 in the cpus *0-4*, *skipping zero* only lines. Moreover, **rtla timerlat
-hist** will change the priority of the *timelat* threads to run under
+hist** will change the priority of the *timerlat* threads to run under
 *SCHED_DEADLINE* priority, with a *10us* runtime every *1ms* period. The
 *1ms* period is also passed to the *timerlat* tracer::
 
index 8a5012b..403c5f0 100644 (file)
@@ -2178,7 +2178,7 @@ M:        Jean-Marie Verdun <verdun@hpe.com>
 M:     Nick Hawkins <nick.hawkins@hpe.com>
 S:     Maintained
 F:     Documentation/devicetree/bindings/arm/hpe,gxp.yaml
-F:     Documentation/devicetree/bindings/spi/hpe,gxp-spi.yaml
+F:     Documentation/devicetree/bindings/spi/hpe,gxp-spifi.yaml
 F:     Documentation/devicetree/bindings/timer/hpe,gxp-timer.yaml
 F:     arch/arm/boot/dts/hpe-bmc*
 F:     arch/arm/boot/dts/hpe-gxp*
@@ -4957,7 +4957,7 @@ F:        drivers/hwmon/lochnagar-hwmon.c
 F:     drivers/mfd/lochnagar-i2c.c
 F:     drivers/pinctrl/cirrus/pinctrl-lochnagar.c
 F:     drivers/regulator/lochnagar-regulator.c
-F:     include/dt-bindings/clk/lochnagar.h
+F:     include/dt-bindings/clock/lochnagar.h
 F:     include/dt-bindings/pinctrl/lochnagar.h
 F:     include/linux/mfd/lochnagar*
 F:     sound/soc/codecs/lochnagar-sc.c
@@ -5145,6 +5145,7 @@ T:        git git://git.samba.org/sfrench/cifs-2.6.git
 F:     Documentation/admin-guide/cifs/
 F:     fs/cifs/
 F:     fs/smbfs_common/
+F:     include/uapi/linux/cifs
 
 COMPACTPCI HOTPLUG CORE
 M:     Scott Murray <scott@spiteful.org>
@@ -17441,6 +17442,12 @@ S:     Maintained
 F:     Documentation/devicetree/bindings/mtd/renesas-nandc.yaml
 F:     drivers/mtd/nand/raw/renesas-nand-controller.c
 
+RENESAS VERSACLOCK 7 CLOCK DRIVER
+M:     Alex Helms <alexander.helms.jy@renesas.com>
+S:     Maintained
+F:     Documentation/devicetree/bindings/clock/renesas,versaclock7.yaml
+F:     drivers/clk/clk-versaclock7.c
+
 RESET CONTROLLER FRAMEWORK
 M:     Philipp Zabel <p.zabel@pengutronix.de>
 S:     Maintained
@@ -17532,6 +17539,7 @@ F:      drivers/char/hw_random/mpfs-rng.c
 F:     drivers/clk/microchip/clk-mpfs.c
 F:     drivers/mailbox/mailbox-mpfs.c
 F:     drivers/pci/controller/pcie-microchip-host.c
+F:     drivers/reset/reset-mpfs.c
 F:     drivers/rtc/rtc-mpfs.c
 F:     drivers/soc/microchip/
 F:     drivers/spi/spi-microchip-core.c
@@ -18022,12 +18030,14 @@ Q:    https://patchwork.linuxtv.org/project/linux-media/list/
 F:     drivers/media/platform/samsung/exynos4-is/
 
 SAMSUNG SOC CLOCK DRIVERS
+M:     Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 M:     Sylwester Nawrocki <s.nawrocki@samsung.com>
 M:     Tomasz Figa <tomasz.figa@gmail.com>
 M:     Chanwoo Choi <cw00.choi@samsung.com>
 R:     Alim Akhtar <alim.akhtar@samsung.com>
 L:     linux-samsung-soc@vger.kernel.org
 S:     Supported
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
 F:     Documentation/devicetree/bindings/clock/samsung,*.yaml
 F:     Documentation/devicetree/bindings/clock/samsung,s3c*
@@ -20304,6 +20314,7 @@ R:      Sekhar Nori <nsekhar@ti.com>
 S:     Maintained
 F:     Documentation/devicetree/bindings/clock/ti/davinci/
 F:     drivers/clk/davinci/
+F:     include/linux/clk/davinci.h
 
 TI DAVINCI SERIES GPIO DRIVER
 M:     Keerthy <j-keerthy@ti.com>
index f09673b..c7705f7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 6
 PATCHLEVEL = 0
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME = Hurr durr I'ma ninja sloth
 
 # *DOCUMENTATION*
@@ -1113,13 +1113,11 @@ vmlinux-alldirs := $(sort $(vmlinux-dirs) Documentation \
                     $(patsubst %/,%,$(filter %/, $(core-) \
                        $(drivers-) $(libs-))))
 
-subdir-modorder := $(addsuffix modules.order,$(filter %/, \
-                       $(core-y) $(core-m) $(libs-y) $(libs-m) \
-                       $(drivers-y) $(drivers-m)))
-
 build-dirs     := $(vmlinux-dirs)
 clean-dirs     := $(vmlinux-alldirs)
 
+subdir-modorder := $(addsuffix /modules.order, $(build-dirs))
+
 # Externally visible symbols (used by link-vmlinux.sh)
 KBUILD_VMLINUX_OBJS := $(head-y) $(patsubst %/,%/built-in.a, $(core-y))
 KBUILD_VMLINUX_OBJS += $(addsuffix built-in.a, $(filter %/, $(libs-y)))
index f330410..5dbf11a 100644 (file)
@@ -53,7 +53,6 @@ config KPROBES
 config JUMP_LABEL
        bool "Optimize very unlikely/likely branches"
        depends on HAVE_ARCH_JUMP_LABEL
-       depends on CC_HAS_ASM_GOTO
        select OBJTOOL if HAVE_JUMP_LABEL_HACK
        help
         This option enables a transparent branch optimization that
@@ -1361,7 +1360,7 @@ config HAVE_PREEMPT_DYNAMIC_CALL
 
 config HAVE_PREEMPT_DYNAMIC_KEY
        bool
-       depends on HAVE_ARCH_JUMP_LABEL && CC_HAS_ASM_GOTO
+       depends on HAVE_ARCH_JUMP_LABEL
        select HAVE_PREEMPT_DYNAMIC
        help
           An architecture should select this if it can handle the preemption
index 63e7a39..8166e3c 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
-#include <dt-bindings/clk/versaclock.h>
+#include <dt-bindings/clock/versaclock.h>
 
 / {
        backlight_lvds: backlight-lvds {
index f5c1d74..d3fc8ff 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 #include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/clk/versaclock.h>
+#include <dt-bindings/clock/versaclock.h>
 
 / {
        memory@48000000 {
index f38ef29..e9c9388 100644 (file)
@@ -929,6 +929,10 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
        (system_supports_mte() &&                               \
         test_bit(KVM_ARCH_FLAG_MTE_ENABLED, &(kvm)->arch.flags))
 
+#define kvm_supports_32bit_el0()                               \
+       (system_supports_32bit_el0() &&                         \
+        !static_branch_unlikely(&arm64_mismatched_32bit_el0))
+
 int kvm_trng_call(struct kvm_vcpu *vcpu);
 #ifdef CONFIG_KVM
 extern phys_addr_t hyp_mem_base;
index 3bb1343..316917b 100644 (file)
@@ -75,9 +75,11 @@ struct kvm_regs {
 
 /* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
 #define KVM_ARM_DEVICE_TYPE_SHIFT      0
-#define KVM_ARM_DEVICE_TYPE_MASK       (0xffff << KVM_ARM_DEVICE_TYPE_SHIFT)
+#define KVM_ARM_DEVICE_TYPE_MASK       GENMASK(KVM_ARM_DEVICE_TYPE_SHIFT + 15, \
+                                               KVM_ARM_DEVICE_TYPE_SHIFT)
 #define KVM_ARM_DEVICE_ID_SHIFT                16
-#define KVM_ARM_DEVICE_ID_MASK         (0xffff << KVM_ARM_DEVICE_ID_SHIFT)
+#define KVM_ARM_DEVICE_ID_MASK         GENMASK(KVM_ARM_DEVICE_ID_SHIFT + 15, \
+                                               KVM_ARM_DEVICE_ID_SHIFT)
 
 /* Supported device IDs */
 #define KVM_ARM_DEVICE_VGIC_V2         0
index 986cee6..2ff0ef6 100644 (file)
@@ -757,8 +757,7 @@ static bool vcpu_mode_is_bad_32bit(struct kvm_vcpu *vcpu)
        if (likely(!vcpu_mode_is_32bit(vcpu)))
                return false;
 
-       return !system_supports_32bit_el0() ||
-               static_branch_unlikely(&arm64_mismatched_32bit_el0);
+       return !kvm_supports_32bit_el0();
 }
 
 /**
index 8c60719..f802a3b 100644 (file)
@@ -242,7 +242,7 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
                u64 mode = (*(u64 *)valp) & PSR_AA32_MODE_MASK;
                switch (mode) {
                case PSR_AA32_MODE_USR:
-                       if (!system_supports_32bit_el0())
+                       if (!kvm_supports_32bit_el0())
                                return -EINVAL;
                        break;
                case PSR_AA32_MODE_FIQ:
index 87f1cd0..c9a13e4 100644 (file)
@@ -993,7 +993,7 @@ transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,
                 * THP doesn't start to split while we are adjusting the
                 * refcounts.
                 *
-                * We are sure this doesn't happen, because mmu_notifier_retry
+                * We are sure this doesn't happen, because mmu_invalidate_retry
                 * was successful and we are holding the mmu_lock, so if this
                 * THP is trying to split, it will be blocked in the mmu
                 * notifier before touching any of the pages, specifically
@@ -1188,9 +1188,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
                        return ret;
        }
 
-       mmu_seq = vcpu->kvm->mmu_notifier_seq;
+       mmu_seq = vcpu->kvm->mmu_invalidate_seq;
        /*
-        * Ensure the read of mmu_notifier_seq happens before we call
+        * Ensure the read of mmu_invalidate_seq happens before we call
         * gfn_to_pfn_prot (which calls get_user_pages), so that we don't risk
         * the page we just got a reference to gets unmapped before we have a
         * chance to grab the mmu_lock, which ensure that if the page gets
@@ -1246,7 +1246,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
        else
                write_lock(&kvm->mmu_lock);
        pgt = vcpu->arch.hw_mmu->pgt;
-       if (mmu_notifier_retry(kvm, mmu_seq))
+       if (mmu_invalidate_retry(kvm, mmu_seq))
                goto out_unlock;
 
        /*
index c059b25..3234f50 100644 (file)
@@ -652,7 +652,7 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
         */
        val = ((pmcr & ~ARMV8_PMU_PMCR_MASK)
               | (ARMV8_PMU_PMCR_MASK & 0xdecafbad)) & (~ARMV8_PMU_PMCR_E);
-       if (!system_supports_32bit_el0())
+       if (!kvm_supports_32bit_el0())
                val |= ARMV8_PMU_PMCR_LC;
        __vcpu_sys_reg(vcpu, r->reg) = val;
 }
@@ -701,7 +701,7 @@ static bool access_pmcr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
                val = __vcpu_sys_reg(vcpu, PMCR_EL0);
                val &= ~ARMV8_PMU_PMCR_MASK;
                val |= p->regval & ARMV8_PMU_PMCR_MASK;
-               if (!system_supports_32bit_el0())
+               if (!kvm_supports_32bit_el0())
                        val |= ARMV8_PMU_PMCR_LC;
                __vcpu_sys_reg(vcpu, PMCR_EL0) = val;
                kvm_pmu_handle_pmcr(vcpu, val);
index 4b13019..d06d454 100644 (file)
@@ -81,7 +81,6 @@ extern struct acpi_vector_group msi_group[MAX_IO_PICS];
 #define GSI_MIN_PCH_IRQ                LOONGSON_PCH_IRQ_BASE
 #define GSI_MAX_PCH_IRQ                (LOONGSON_PCH_IRQ_BASE + 256 - 1)
 
-extern int find_pch_pic(u32 gsi);
 struct acpi_madt_lio_pic;
 struct acpi_madt_eio_pic;
 struct acpi_madt_ht_pic;
index 717716c..5cedb28 100644 (file)
@@ -84,8 +84,6 @@
 
 
 #define KVM_MAX_VCPUS          16
-/* memory slots that does not exposed to userspace */
-#define KVM_PRIVATE_MEM_SLOTS  0
 
 #define KVM_HALT_POLL_NS_DEFAULT 500000
 
index db17e87..74cd64a 100644 (file)
@@ -615,17 +615,17 @@ retry:
         * Used to check for invalidations in progress, of the pfn that is
         * returned by pfn_to_pfn_prot below.
         */
-       mmu_seq = kvm->mmu_notifier_seq;
+       mmu_seq = kvm->mmu_invalidate_seq;
        /*
-        * Ensure the read of mmu_notifier_seq isn't reordered with PTE reads in
-        * gfn_to_pfn_prot() (which calls get_user_pages()), so that we don't
+        * Ensure the read of mmu_invalidate_seq isn't reordered with PTE reads
+        * in gfn_to_pfn_prot() (which calls get_user_pages()), so that we don't
         * risk the page we get a reference to getting unmapped before we have a
-        * chance to grab the mmu_lock without mmu_notifier_retry() noticing.
+        * chance to grab the mmu_lock without mmu_invalidate_retry() noticing.
         *
         * This smp_rmb() pairs with the effective smp_wmb() of the combination
         * of the pte_unmap_unlock() after the PTE is zapped, and the
         * spin_lock() in kvm_mmu_notifier_invalidate_<page|range_end>() before
-        * mmu_notifier_seq is incremented.
+        * mmu_invalidate_seq is incremented.
         */
        smp_rmb();
 
@@ -638,7 +638,7 @@ retry:
 
        spin_lock(&kvm->mmu_lock);
        /* Check if an invalidation has taken place since we got pfn */
-       if (mmu_notifier_retry(kvm, mmu_seq)) {
+       if (mmu_invalidate_retry(kvm, mmu_seq)) {
                /*
                 * This can happen when mappings are changed asynchronously, but
                 * also synchronously if a COW is triggered by
index cf37f55..bafb7b2 100644 (file)
@@ -50,7 +50,8 @@
        stw     r13, PT_R13(sp)
        stw     r14, PT_R14(sp)
        stw     r15, PT_R15(sp)
-       stw     r2, PT_ORIG_R2(sp)
+       movi    r24, -1
+       stw     r24, PT_ORIG_R2(sp)
        stw     r7, PT_ORIG_R7(sp)
 
        stw     ra, PT_RA(sp)
index 6424621..9da34c3 100644 (file)
@@ -74,6 +74,8 @@ extern void show_regs(struct pt_regs *);
        ((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE)\
                - 1)
 
+#define force_successful_syscall_return() (current_pt_regs()->orig_r2 = -1)
+
 int do_syscall_trace_enter(void);
 void do_syscall_trace_exit(void);
 #endif /* __ASSEMBLY__ */
index 0794cd7..99f0a65 100644 (file)
@@ -185,6 +185,7 @@ ENTRY(handle_system_call)
        ldw     r5, PT_R5(sp)
 
 local_restart:
+       stw     r2, PT_ORIG_R2(sp)
        /* Check that the requested system call is within limits */
        movui   r1, __NR_syscalls
        bgeu    r2, r1, ret_invsyscall
@@ -192,7 +193,6 @@ local_restart:
        movhi   r11, %hiadj(sys_call_table)
        add     r1, r1, r11
        ldw     r1, %lo(sys_call_table)(r1)
-       beq     r1, r0, ret_invsyscall
 
        /* Check if we are being traced */
        GET_THREAD_INFO r11
@@ -213,6 +213,9 @@ local_restart:
 translate_rc_and_ret:
        movi    r1, 0
        bge     r2, zero, 3f
+       ldw     r1, PT_ORIG_R2(sp)
+       addi    r1, r1, 1
+       beq     r1, zero, 3f
        sub     r2, zero, r2
        movi    r1, 1
 3:
@@ -255,9 +258,9 @@ traced_system_call:
        ldw     r6, PT_R6(sp)
        ldw     r7, PT_R7(sp)
 
-       /* Fetch the syscall function, we don't need to check the boundaries
-        * since this is already done.
-        */
+       /* Fetch the syscall function. */
+       movui   r1, __NR_syscalls
+       bgeu    r2, r1, traced_invsyscall
        slli    r1, r2, 2
        movhi   r11,%hiadj(sys_call_table)
        add     r1, r1, r11
@@ -276,6 +279,9 @@ traced_system_call:
 translate_rc_and_ret2:
        movi    r1, 0
        bge     r2, zero, 4f
+       ldw     r1, PT_ORIG_R2(sp)
+       addi    r1, r1, 1
+       beq     r1, zero, 4f
        sub     r2, zero, r2
        movi    r1, 1
 4:
@@ -287,6 +293,11 @@ end_translate_rc_and_ret2:
        RESTORE_SWITCH_STACK
        br      ret_from_exception
 
+       /* If the syscall number was invalid return ENOSYS */
+traced_invsyscall:
+       movi    r2, -ENOSYS
+       br      translate_rc_and_ret2
+
 Luser_return:
        GET_THREAD_INFO r11                     /* get thread_info pointer */
        ldw     r10, TI_FLAGS(r11)              /* get thread_info->flags */
@@ -336,9 +347,6 @@ external_interrupt:
        /* skip if no interrupt is pending */
        beq     r12, r0, ret_from_interrupt
 
-       movi    r24, -1
-       stw     r24, PT_ORIG_R2(sp)
-
        /*
         * Process an external hardware interrupt.
         */
index cb0b915..a5b93a3 100644 (file)
@@ -242,7 +242,7 @@ static int do_signal(struct pt_regs *regs)
        /*
         * If we were from a system call, check for system call restarting...
         */
-       if (regs->orig_r2 >= 0) {
+       if (regs->orig_r2 >= 0 && regs->r1) {
                continue_addr = regs->ea;
                restart_addr = continue_addr - 4;
                retval = regs->r2;
@@ -264,6 +264,7 @@ static int do_signal(struct pt_regs *regs)
                        regs->ea = restart_addr;
                        break;
                }
+               regs->orig_r2 = -1;
        }
 
        if (get_signal(&ksig)) {
index 6176d63..c2875a6 100644 (file)
@@ -13,5 +13,6 @@
 #define __SYSCALL(nr, call) [nr] = (call),
 
 void *sys_call_table[__NR_syscalls] = {
+       [0 ... __NR_syscalls-1] = sys_ni_syscall,
 #include <asm/unistd.h>
 };
index 4def2bd..d49065a 100644 (file)
@@ -666,7 +666,7 @@ static inline pte_t *find_kvm_host_pte(struct kvm *kvm, unsigned long mmu_seq,
        VM_WARN(!spin_is_locked(&kvm->mmu_lock),
                "%s called with kvm mmu_lock not held \n", __func__);
 
-       if (mmu_notifier_retry(kvm, mmu_seq))
+       if (mmu_invalidate_retry(kvm, mmu_seq))
                return NULL;
 
        pte = __find_linux_pte(kvm->mm->pgd, ea, NULL, hshift);
index bdd3332..31de91c 100644 (file)
@@ -68,10 +68,6 @@ void __init set_pci_dma_ops(const struct dma_map_ops *dma_ops)
        pci_dma_ops = dma_ops;
 }
 
-/*
- * This function should run under locking protection, specifically
- * hose_spinlock.
- */
 static int get_phb_number(struct device_node *dn)
 {
        int ret, phb_id = -1;
@@ -108,15 +104,20 @@ static int get_phb_number(struct device_node *dn)
        if (!ret)
                phb_id = (int)(prop & (MAX_PHBS - 1));
 
+       spin_lock(&hose_spinlock);
+
        /* We need to be sure to not use the same PHB number twice. */
        if ((phb_id >= 0) && !test_and_set_bit(phb_id, phb_bitmap))
-               return phb_id;
+               goto out_unlock;
 
        /* If everything fails then fallback to dynamic PHB numbering. */
        phb_id = find_first_zero_bit(phb_bitmap, MAX_PHBS);
        BUG_ON(phb_id >= MAX_PHBS);
        set_bit(phb_id, phb_bitmap);
 
+out_unlock:
+       spin_unlock(&hose_spinlock);
+
        return phb_id;
 }
 
@@ -127,10 +128,13 @@ struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
        phb = zalloc_maybe_bootmem(sizeof(struct pci_controller), GFP_KERNEL);
        if (phb == NULL)
                return NULL;
-       spin_lock(&hose_spinlock);
+
        phb->global_number = get_phb_number(dev);
+
+       spin_lock(&hose_spinlock);
        list_add_tail(&phb->list_node, &hose_list);
        spin_unlock(&hose_spinlock);
+
        phb->dn = dev;
        phb->is_dynamic = slab_is_available();
 #ifdef CONFIG_PPC64
index 1ae0999..bc6a381 100644 (file)
@@ -90,7 +90,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte,
        unsigned long pfn;
 
        /* used to check for invalidations in progress */
-       mmu_seq = kvm->mmu_notifier_seq;
+       mmu_seq = kvm->mmu_invalidate_seq;
        smp_rmb();
 
        /* Get host physical address for gpa */
@@ -151,7 +151,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte,
        cpte = kvmppc_mmu_hpte_cache_next(vcpu);
 
        spin_lock(&kvm->mmu_lock);
-       if (!cpte || mmu_notifier_retry(kvm, mmu_seq)) {
+       if (!cpte || mmu_invalidate_retry(kvm, mmu_seq)) {
                r = -EAGAIN;
                goto out_unlock;
        }
index 514fd45..e9744b4 100644 (file)
@@ -578,7 +578,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_vcpu *vcpu,
                return -EFAULT;
 
        /* used to check for invalidations in progress */
-       mmu_seq = kvm->mmu_notifier_seq;
+       mmu_seq = kvm->mmu_invalidate_seq;
        smp_rmb();
 
        ret = -EFAULT;
@@ -693,7 +693,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_vcpu *vcpu,
 
        /* Check if we might have been invalidated; let the guest retry if so */
        ret = RESUME_GUEST;
-       if (mmu_notifier_retry(vcpu->kvm, mmu_seq)) {
+       if (mmu_invalidate_retry(vcpu->kvm, mmu_seq)) {
                unlock_rmap(rmap);
                goto out_unlock;
        }
index 9d4b3fe..5d5e12f 100644 (file)
@@ -640,7 +640,7 @@ int kvmppc_create_pte(struct kvm *kvm, pgd_t *pgtable, pte_t pte,
        /* Check if we might have been invalidated; let the guest retry if so */
        spin_lock(&kvm->mmu_lock);
        ret = -EAGAIN;
-       if (mmu_notifier_retry(kvm, mmu_seq))
+       if (mmu_invalidate_retry(kvm, mmu_seq))
                goto out_unlock;
 
        /* Now traverse again under the lock and change the tree */
@@ -830,7 +830,7 @@ int kvmppc_book3s_instantiate_page(struct kvm_vcpu *vcpu,
        bool large_enable;
 
        /* used to check for invalidations in progress */
-       mmu_seq = kvm->mmu_notifier_seq;
+       mmu_seq = kvm->mmu_invalidate_seq;
        smp_rmb();
 
        /*
@@ -1191,7 +1191,7 @@ void kvmppc_radix_flush_memslot(struct kvm *kvm,
         * Increase the mmu notifier sequence number to prevent any page
         * fault that read the memslot earlier from writing a PTE.
         */
-       kvm->mmu_notifier_seq++;
+       kvm->mmu_invalidate_seq++;
        spin_unlock(&kvm->mmu_lock);
 }
 
index be8249c..5a64a13 100644 (file)
@@ -1580,7 +1580,7 @@ static long int __kvmhv_nested_page_fault(struct kvm_vcpu *vcpu,
        /* 2. Find the host pte for this L1 guest real address */
 
        /* Used to check for invalidations in progress */
-       mmu_seq = kvm->mmu_notifier_seq;
+       mmu_seq = kvm->mmu_invalidate_seq;
        smp_rmb();
 
        /* See if can find translation in our partition scoped tables for L1 */
index 2257fb1..5a05953 100644 (file)
@@ -219,7 +219,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
        g_ptel = ptel;
 
        /* used later to detect if we might have been invalidated */
-       mmu_seq = kvm->mmu_notifier_seq;
+       mmu_seq = kvm->mmu_invalidate_seq;
        smp_rmb();
 
        /* Find the memslot (if any) for this address */
@@ -366,7 +366,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
                        rmap = real_vmalloc_addr(rmap);
                lock_rmap(rmap);
                /* Check for pending invalidations under the rmap chain lock */
-               if (mmu_notifier_retry(kvm, mmu_seq)) {
+               if (mmu_invalidate_retry(kvm, mmu_seq)) {
                        /* inval in progress, write a non-present HPTE */
                        pteh |= HPTE_V_ABSENT;
                        pteh &= ~HPTE_V_VALID;
@@ -932,7 +932,7 @@ static long kvmppc_do_h_page_init_zero(struct kvm_vcpu *vcpu,
        int i;
 
        /* Used later to detect if we might have been invalidated */
-       mmu_seq = kvm->mmu_notifier_seq;
+       mmu_seq = kvm->mmu_invalidate_seq;
        smp_rmb();
 
        arch_spin_lock(&kvm->mmu_lock.rlock.raw_lock);
@@ -960,7 +960,7 @@ static long kvmppc_do_h_page_init_copy(struct kvm_vcpu *vcpu,
        long ret = H_SUCCESS;
 
        /* Used later to detect if we might have been invalidated */
-       mmu_seq = kvm->mmu_notifier_seq;
+       mmu_seq = kvm->mmu_invalidate_seq;
        smp_rmb();
 
        arch_spin_lock(&kvm->mmu_lock.rlock.raw_lock);
index 7f16afc..05668e9 100644 (file)
@@ -339,7 +339,7 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
        unsigned long flags;
 
        /* used to check for invalidations in progress */
-       mmu_seq = kvm->mmu_notifier_seq;
+       mmu_seq = kvm->mmu_invalidate_seq;
        smp_rmb();
 
        /*
@@ -460,7 +460,7 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
        }
 
        spin_lock(&kvm->mmu_lock);
-       if (mmu_notifier_retry(kvm, mmu_seq)) {
+       if (mmu_invalidate_retry(kvm, mmu_seq)) {
                ret = -EAGAIN;
                goto out;
        }
index 553d755..3b5583d 100644 (file)
@@ -28,7 +28,7 @@ unsigned long elf_hwcap __read_mostly;
 /* Host ISA bitmap */
 static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly;
 
-__ro_after_init DEFINE_STATIC_KEY_ARRAY_FALSE(riscv_isa_ext_keys, RISCV_ISA_EXT_KEY_MAX);
+DEFINE_STATIC_KEY_ARRAY_FALSE(riscv_isa_ext_keys, RISCV_ISA_EXT_KEY_MAX);
 EXPORT_SYMBOL(riscv_isa_ext_keys);
 
 /**
index 3a35b2d..3620eca 100644 (file)
@@ -666,7 +666,7 @@ int kvm_riscv_gstage_map(struct kvm_vcpu *vcpu,
                return ret;
        }
 
-       mmu_seq = kvm->mmu_notifier_seq;
+       mmu_seq = kvm->mmu_invalidate_seq;
 
        hfn = gfn_to_pfn_prot(kvm, gfn, is_write, &writable);
        if (hfn == KVM_PFN_ERR_HWPOISON) {
@@ -686,7 +686,7 @@ int kvm_riscv_gstage_map(struct kvm_vcpu *vcpu,
 
        spin_lock(&kvm->mmu_lock);
 
-       if (mmu_notifier_retry(kvm, mmu_seq))
+       if (mmu_invalidate_retry(kvm, mmu_seq))
                goto out_unlock;
 
        if (writable) {
index f0bc4dc..6511d15 100644 (file)
@@ -437,7 +437,7 @@ __init int hypfs_diag_init(void)
        int rc;
 
        if (diag204_probe()) {
-               pr_err("The hardware system does not support hypfs\n");
+               pr_info("The hardware system does not support hypfs\n");
                return -ENODATA;
        }
 
index 5c97f48..ee919bf 100644 (file)
@@ -496,9 +496,9 @@ fail_hypfs_sprp_exit:
        hypfs_vm_exit();
 fail_hypfs_diag_exit:
        hypfs_diag_exit();
+       pr_err("Initialization of hypfs failed with rc=%i\n", rc);
 fail_dbfs_exit:
        hypfs_dbfs_exit();
-       pr_err("Initialization of hypfs failed with rc=%i\n", rc);
        return rc;
 }
 device_initcall(hypfs_init)
index 79e38af..e719af8 100644 (file)
@@ -1011,7 +1011,7 @@ error_kzalloc:
 
 static int vu_find_vqs(struct virtio_device *vdev, unsigned nvqs,
                       struct virtqueue *vqs[], vq_callback_t *callbacks[],
-                      const char * const names[], u32 sizes[], const bool *ctx,
+                      const char * const names[], const bool *ctx,
                       struct irq_affinity *desc)
 {
        struct virtio_uml_device *vu_dev = to_virtio_uml_device(vdev);
index 19cd7ed..4b6d1b5 100644 (file)
@@ -65,20 +65,6 @@ extern void setup_clear_cpu_cap(unsigned int bit);
 
 #define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit)
 
-#if defined(__clang__) && !defined(CONFIG_CC_HAS_ASM_GOTO)
-
-/*
- * Workaround for the sake of BPF compilation which utilizes kernel
- * headers, but clang does not support ASM GOTO and fails the build.
- */
-#ifndef __BPF_TRACING__
-#warning "Compiler lacks ASM_GOTO support. Add -D __BPF_TRACING__ to your compiler arguments"
-#endif
-
-#define static_cpu_has(bit)            boot_cpu_has(bit)
-
-#else
-
 /*
  * Static testing of CPU features. Used the same as boot_cpu_has(). It
  * statically patches the target code for additional performance. Use
@@ -137,7 +123,6 @@ t_no:
                boot_cpu_has(bit) :                             \
                _static_cpu_has(bit)                            \
 )
-#endif
 
 #define cpu_has_bug(c, bit)            cpu_has(c, (bit))
 #define set_cpu_bug(c, bit)            set_cpu_cap(c, (bit))
index 7854685..bafbd90 100644 (file)
@@ -286,10 +286,6 @@ vdso_install:
 
 archprepare: checkbin
 checkbin:
-ifndef CONFIG_CC_HAS_ASM_GOTO
-       @echo Compiler lacks asm-goto support.
-       @exit 1
-endif
 ifdef CONFIG_RETPOLINE
 ifeq ($(RETPOLINE_CFLAGS),)
        @echo "You are building kernel with non-retpoline compiler." >&2
index ea34cc3..1a85e1f 100644 (file)
@@ -155,20 +155,6 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);
 
 #define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit)
 
-#if defined(__clang__) && !defined(CONFIG_CC_HAS_ASM_GOTO)
-
-/*
- * Workaround for the sake of BPF compilation which utilizes kernel
- * headers, but clang does not support ASM GOTO and fails the build.
- */
-#ifndef __BPF_TRACING__
-#warning "Compiler lacks ASM_GOTO support. Add -D __BPF_TRACING__ to your compiler arguments"
-#endif
-
-#define static_cpu_has(bit)            boot_cpu_has(bit)
-
-#else
-
 /*
  * Static testing of CPU features. Used the same as boot_cpu_has(). It
  * statically patches the target code for additional performance. Use
@@ -208,7 +194,6 @@ t_no:
                boot_cpu_has(bit) :                             \
                _static_cpu_has(bit)                            \
 )
-#endif
 
 #define cpu_has_bug(c, bit)            cpu_has(c, (bit))
 #define set_cpu_bug(c, bit)            set_cpu_cap(c, (bit))
index 5036226..991e31c 100644 (file)
@@ -64,4 +64,6 @@
 #define        EX_TYPE_UCOPY_LEN4              (EX_TYPE_UCOPY_LEN | EX_DATA_IMM(4))
 #define        EX_TYPE_UCOPY_LEN8              (EX_TYPE_UCOPY_LEN | EX_DATA_IMM(8))
 
+#define EX_TYPE_ZEROPAD                        20 /* longword load with zeropad on fault */
+
 #endif
index 689880e..9b08082 100644 (file)
 
 #define __noendbr      __attribute__((nocf_check))
 
+/*
+ * Create a dummy function pointer reference to prevent objtool from marking
+ * the function as needing to be "sealed" (i.e. ENDBR converted to NOP by
+ * apply_ibt_endbr()).
+ */
+#define IBT_NOSEAL(fname)                              \
+       ".pushsection .discard.ibt_endbr_noseal\n\t"    \
+       _ASM_PTR fname "\n\t"                           \
+       ".popsection\n\t"
+
 static inline __attribute_const__ u32 gen_endbr(void)
 {
        u32 endbr;
@@ -84,6 +94,7 @@ extern __noendbr void ibt_restore(u64 save);
 #ifndef __ASSEMBLY__
 
 #define ASM_ENDBR
+#define IBT_NOSEAL(name)
 
 #define __noendbr
 
index 5ffa578..2c96c43 100644 (file)
@@ -53,7 +53,7 @@
 #define KVM_MAX_VCPU_IDS (KVM_MAX_VCPUS * KVM_VCPU_ID_RATIO)
 
 /* memory slots that are not exposed to userspace */
-#define KVM_PRIVATE_MEM_SLOTS 3
+#define KVM_INTERNAL_MEM_SLOTS 3
 
 #define KVM_HALT_POLL_NS_DEFAULT 200000
 
index 8a9eba1..7fa6112 100644 (file)
@@ -11,7 +11,7 @@
 
 #define __CLOBBERS_MEM(clb...) "memory", ## clb
 
-#if !defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(CONFIG_CC_HAS_ASM_GOTO)
+#ifndef __GCC_ASM_FLAG_OUTPUTS__
 
 /* Use asm goto */
 
@@ -27,7 +27,7 @@ cc_label:     c = true;                                               \
        c;                                                              \
 })
 
-#else /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CONFIG_CC_HAS_ASM_GOTO) */
+#else /* defined(__GCC_ASM_FLAG_OUTPUTS__) */
 
 /* Use flags output or a set instruction */
 
@@ -40,7 +40,7 @@ cc_label:     c = true;                                               \
        c;                                                              \
 })
 
-#endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CONFIG_CC_HAS_ASM_GOTO) */
+#endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) */
 
 #define GEN_UNARY_RMWcc_4(op, var, cc, arg0)                           \
        __GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM())
index 8338b04..46b4f1f 100644 (file)
@@ -77,58 +77,18 @@ static inline unsigned long find_zero(unsigned long mask)
  * and the next page not being mapped, take the exception and
  * return zeroes in the non-existing part.
  */
-#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
-
 static inline unsigned long load_unaligned_zeropad(const void *addr)
 {
-       unsigned long offset, data;
        unsigned long ret;
 
-       asm_volatile_goto(
+       asm volatile(
                "1:     mov %[mem], %[ret]\n"
-
-               _ASM_EXTABLE(1b, %l[do_exception])
-
-               : [ret] "=r" (ret)
-               : [mem] "m" (*(unsigned long *)addr)
-               : : do_exception);
-
-       return ret;
-
-do_exception:
-       offset = (unsigned long)addr & (sizeof(long) - 1);
-       addr = (void *)((unsigned long)addr & ~(sizeof(long) - 1));
-       data = *(unsigned long *)addr;
-       ret = data >> offset * 8;
-
-       return ret;
-}
-
-#else /* !CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
-
-static inline unsigned long load_unaligned_zeropad(const void *addr)
-{
-       unsigned long offset, data;
-       unsigned long ret, err = 0;
-
-       asm(    "1:     mov %[mem], %[ret]\n"
                "2:\n"
-
-               _ASM_EXTABLE_FAULT(1b, 2b)
-
-               : [ret] "=&r" (ret), "+a" (err)
+               _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_ZEROPAD)
+               : [ret] "=r" (ret)
                : [mem] "m" (*(unsigned long *)addr));
 
-       if (unlikely(err)) {
-               offset = (unsigned long)addr & (sizeof(long) - 1);
-               addr = (void *)((unsigned long)addr & ~(sizeof(long) - 1));
-               data = *(unsigned long *)addr;
-               ret = data >> offset * 8;
-       }
-
        return ret;
 }
 
-#endif /* CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
-
 #endif /* _ASM_WORD_AT_A_TIME_H */
index 74167dc..4c3c27b 100644 (file)
@@ -505,7 +505,7 @@ static void kprobe_emulate_jcc(struct kprobe *p, struct pt_regs *regs)
                match = ((regs->flags & X86_EFLAGS_SF) >> X86_EFLAGS_SF_BIT) ^
                        ((regs->flags & X86_EFLAGS_OF) >> X86_EFLAGS_OF_BIT);
                if (p->ainsn.jcc.type >= 0xe)
-                       match = match && (regs->flags & X86_EFLAGS_ZF);
+                       match = match || (regs->flags & X86_EFLAGS_ZF);
        }
        __kprobe_emulate_jmp(p, regs, (match && !invert) || (!match && invert));
 }
index b4eeb7c..d5ec3a2 100644 (file)
@@ -326,7 +326,8 @@ static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop);
        ".align " __stringify(FASTOP_SIZE) " \n\t" \
        ".type " name ", @function \n\t" \
        name ":\n\t" \
-       ASM_ENDBR
+       ASM_ENDBR \
+       IBT_NOSEAL(name)
 
 #define FOP_FUNC(name) \
        __FOP_FUNC(#name)
@@ -446,27 +447,12 @@ static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop);
        FOP_END
 
 /* Special case for SETcc - 1 instruction per cc */
-
-/*
- * Depending on .config the SETcc functions look like:
- *
- * ENDBR                       [4 bytes; CONFIG_X86_KERNEL_IBT]
- * SETcc %al                   [3 bytes]
- * RET | JMP __x86_return_thunk        [1,5 bytes; CONFIG_RETHUNK]
- * INT3                                [1 byte; CONFIG_SLS]
- */
-#define SETCC_ALIGN    16
-
 #define FOP_SETCC(op) \
-       ".align " __stringify(SETCC_ALIGN) " \n\t" \
-       ".type " #op ", @function \n\t" \
-       #op ": \n\t" \
-       ASM_ENDBR \
+       FOP_FUNC(op) \
        #op " %al \n\t" \
-       __FOP_RET(#op) \
-       ".skip " __stringify(SETCC_ALIGN) " - (.-" #op "), 0xcc \n\t"
+       FOP_RET(op)
 
-__FOP_START(setcc, SETCC_ALIGN)
+FOP_START(setcc)
 FOP_SETCC(seto)
 FOP_SETCC(setno)
 FOP_SETCC(setc)
@@ -493,7 +479,7 @@ FOP_END;
 
 /*
  * XXX: inoutclob user must know where the argument is being expanded.
- *      Relying on CONFIG_CC_HAS_ASM_GOTO would allow us to remove _fault.
+ *      Using asm goto would allow us to remove _fault.
  */
 #define asm_safe(insn, inoutclob...) \
 ({ \
@@ -1079,7 +1065,7 @@ static int em_bsr_c(struct x86_emulate_ctxt *ctxt)
 static __always_inline u8 test_cc(unsigned int condition, unsigned long flags)
 {
        u8 rc;
-       void (*fop)(void) = (void *)em_setcc + SETCC_ALIGN * (condition & 0xf);
+       void (*fop)(void) = (void *)em_setcc + FASTOP_SIZE * (condition & 0xf);
 
        flags = (flags & EFLAGS_MASK) | X86_EFLAGS_IF;
        asm("push %[flags]; popf; " CALL_NOSPEC
index eccddb1..126fa9a 100644 (file)
@@ -2914,7 +2914,7 @@ static void direct_pte_prefetch(struct kvm_vcpu *vcpu, u64 *sptep)
         * If addresses are being invalidated, skip prefetching to avoid
         * accidentally prefetching those addresses.
         */
-       if (unlikely(vcpu->kvm->mmu_notifier_count))
+       if (unlikely(vcpu->kvm->mmu_invalidate_in_progress))
                return;
 
        __direct_pte_prefetch(vcpu, sp, sptep);
@@ -2928,7 +2928,7 @@ static void direct_pte_prefetch(struct kvm_vcpu *vcpu, u64 *sptep)
  *
  * There are several ways to safely use this helper:
  *
- * - Check mmu_notifier_retry_hva() after grabbing the mapping level, before
+ * - Check mmu_invalidate_retry_hva() after grabbing the mapping level, before
  *   consuming it.  In this case, mmu_lock doesn't need to be held during the
  *   lookup, but it does need to be held while checking the MMU notifier.
  *
@@ -3056,7 +3056,7 @@ void kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
                return;
 
        /*
-        * mmu_notifier_retry() was successful and mmu_lock is held, so
+        * mmu_invalidate_retry() was successful and mmu_lock is held, so
         * the pmd can't be split from under us.
         */
        fault->goal_level = fault->req_level;
@@ -4203,7 +4203,7 @@ static bool is_page_fault_stale(struct kvm_vcpu *vcpu,
                return true;
 
        return fault->slot &&
-              mmu_notifier_retry_hva(vcpu->kvm, mmu_seq, fault->hva);
+              mmu_invalidate_retry_hva(vcpu->kvm, mmu_seq, fault->hva);
 }
 
 static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
@@ -4227,7 +4227,7 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
        if (r)
                return r;
 
-       mmu_seq = vcpu->kvm->mmu_notifier_seq;
+       mmu_seq = vcpu->kvm->mmu_invalidate_seq;
        smp_rmb();
 
        r = kvm_faultin_pfn(vcpu, fault);
@@ -6055,7 +6055,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end)
 
        write_lock(&kvm->mmu_lock);
 
-       kvm_inc_notifier_count(kvm, gfn_start, gfn_end);
+       kvm_mmu_invalidate_begin(kvm, gfn_start, gfn_end);
 
        flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end);
 
@@ -6069,7 +6069,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end)
                kvm_flush_remote_tlbs_with_address(kvm, gfn_start,
                                                   gfn_end - gfn_start);
 
-       kvm_dec_notifier_count(kvm, gfn_start, gfn_end);
+       kvm_mmu_invalidate_end(kvm, gfn_start, gfn_end);
 
        write_unlock(&kvm->mmu_lock);
 }
index f595807..39e0205 100644 (file)
@@ -589,7 +589,7 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw,
         * If addresses are being invalidated, skip prefetching to avoid
         * accidentally prefetching those addresses.
         */
-       if (unlikely(vcpu->kvm->mmu_notifier_count))
+       if (unlikely(vcpu->kvm->mmu_invalidate_in_progress))
                return;
 
        if (sp->role.direct)
@@ -838,7 +838,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
        else
                fault->max_level = walker.level;
 
-       mmu_seq = vcpu->kvm->mmu_notifier_seq;
+       mmu_seq = vcpu->kvm->mmu_invalidate_seq;
        smp_rmb();
 
        r = kvm_faultin_pfn(vcpu, fault);
index 331310c..60814e1 100644 (file)
@@ -41,6 +41,59 @@ static bool ex_handler_default(const struct exception_table_entry *e,
        return true;
 }
 
+/*
+ * This is the *very* rare case where we do a "load_unaligned_zeropad()"
+ * and it's a page crosser into a non-existent page.
+ *
+ * This happens when we optimistically load a pathname a word-at-a-time
+ * and the name is less than the full word and the  next page is not
+ * mapped. Typically that only happens for CONFIG_DEBUG_PAGEALLOC.
+ *
+ * NOTE! The faulting address is always a 'mov mem,reg' type instruction
+ * of size 'long', and the exception fixup must always point to right
+ * after the instruction.
+ */
+static bool ex_handler_zeropad(const struct exception_table_entry *e,
+                              struct pt_regs *regs,
+                              unsigned long fault_addr)
+{
+       struct insn insn;
+       const unsigned long mask = sizeof(long) - 1;
+       unsigned long offset, addr, next_ip, len;
+       unsigned long *reg;
+
+       next_ip = ex_fixup_addr(e);
+       len = next_ip - regs->ip;
+       if (len > MAX_INSN_SIZE)
+               return false;
+
+       if (insn_decode(&insn, (void *) regs->ip, len, INSN_MODE_KERN))
+               return false;
+       if (insn.length != len)
+               return false;
+
+       if (insn.opcode.bytes[0] != 0x8b)
+               return false;
+       if (insn.opnd_bytes != sizeof(long))
+               return false;
+
+       addr = (unsigned long) insn_get_addr_ref(&insn, regs);
+       if (addr == ~0ul)
+               return false;
+
+       offset = addr & mask;
+       addr = addr & ~mask;
+       if (fault_addr != addr + sizeof(long))
+               return false;
+
+       reg = insn_get_modrm_reg_ptr(&insn, regs);
+       if (!reg)
+               return false;
+
+       *reg = *(unsigned long *)addr >> (offset * 8);
+       return ex_handler_default(e, regs);
+}
+
 static bool ex_handler_fault(const struct exception_table_entry *fixup,
                             struct pt_regs *regs, int trapnr)
 {
@@ -217,6 +270,8 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,
                return ex_handler_sgx(e, regs, trapnr);
        case EX_TYPE_UCOPY_LEN:
                return ex_handler_ucopy_len(e, regs, trapnr, reg, imm);
+       case EX_TYPE_ZEROPAD:
+               return ex_handler_zeropad(e, regs, fault_addr);
        }
        BUG();
 }
index 39c5246..0fe690e 100644 (file)
@@ -645,7 +645,7 @@ phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end,
                        pages++;
                        spin_lock(&init_mm.page_table_lock);
 
-                       prot = __pgprot(pgprot_val(prot) | __PAGE_KERNEL_LARGE);
+                       prot = __pgprot(pgprot_val(prot) | _PAGE_PSE);
 
                        set_pte_init((pte_t *)pud,
                                     pfn_pte((paddr & PUD_MASK) >> PAGE_SHIFT,
index 5ee62b9..3c1e6b6 100644 (file)
@@ -2229,26 +2229,6 @@ void blk_mq_delay_run_hw_queues(struct request_queue *q, unsigned long msecs)
 }
 EXPORT_SYMBOL(blk_mq_delay_run_hw_queues);
 
-/**
- * blk_mq_queue_stopped() - check whether one or more hctxs have been stopped
- * @q: request queue.
- *
- * The caller is responsible for serializing this function against
- * blk_mq_{start,stop}_hw_queue().
- */
-bool blk_mq_queue_stopped(struct request_queue *q)
-{
-       struct blk_mq_hw_ctx *hctx;
-       unsigned long i;
-
-       queue_for_each_hw_ctx(q, hctx, i)
-               if (blk_mq_hctx_stopped(hctx))
-                       return true;
-
-       return false;
-}
-EXPORT_SYMBOL(blk_mq_queue_stopped);
-
 /*
  * This function is often used for pausing .queue_rq() by driver when
  * there isn't enough resource or some conditions aren't satisfied, and
@@ -2570,7 +2550,7 @@ static void blk_mq_plug_issue_direct(struct blk_plug *plug, bool from_schedule)
                        break;
                case BLK_STS_RESOURCE:
                case BLK_STS_DEV_RESOURCE:
-                       blk_mq_request_bypass_insert(rq, false, last);
+                       blk_mq_request_bypass_insert(rq, false, true);
                        blk_mq_commit_rqs(hctx, &queued, from_schedule);
                        return;
                default:
index ef4508d..7c128c8 100644 (file)
@@ -2122,6 +2122,7 @@ const char *ata_get_cmd_name(u8 command)
                { ATA_CMD_WRITE_QUEUED_FUA_EXT, "WRITE DMA QUEUED FUA EXT" },
                { ATA_CMD_FPDMA_READ,           "READ FPDMA QUEUED" },
                { ATA_CMD_FPDMA_WRITE,          "WRITE FPDMA QUEUED" },
+               { ATA_CMD_NCQ_NON_DATA,         "NCQ NON-DATA" },
                { ATA_CMD_FPDMA_SEND,           "SEND FPDMA QUEUED" },
                { ATA_CMD_FPDMA_RECV,           "RECEIVE FPDMA QUEUED" },
                { ATA_CMD_PIO_READ,             "READ SECTOR(S)" },
index 2b7d1db..6a4a94b 100644 (file)
@@ -555,7 +555,7 @@ static inline struct ublk_uring_cmd_pdu *ublk_get_uring_cmd_pdu(
        return (struct ublk_uring_cmd_pdu *)&ioucmd->pdu;
 }
 
-static bool ubq_daemon_is_dying(struct ublk_queue *ubq)
+static inline bool ubq_daemon_is_dying(struct ublk_queue *ubq)
 {
        return ubq->ubq_daemon->flags & PF_EXITING;
 }
@@ -605,8 +605,9 @@ static void ublk_complete_rq(struct request *req)
 }
 
 /*
- * __ublk_fail_req() may be called from abort context or ->ubq_daemon
- * context during exiting, so lock is required.
+ * Since __ublk_rq_task_work always fails requests immediately during
+ * exiting, __ublk_fail_req() is only called from abort context during
+ * exiting. So lock is unnecessary.
  *
  * Also aborting may not be started yet, keep in mind that one failed
  * request may be issued by block layer again.
@@ -644,8 +645,7 @@ static inline void __ublk_rq_task_work(struct request *req)
        struct ublk_device *ub = ubq->dev;
        int tag = req->tag;
        struct ublk_io *io = &ubq->ios[tag];
-       bool task_exiting = current != ubq->ubq_daemon ||
-               (current->flags & PF_EXITING);
+       bool task_exiting = current != ubq->ubq_daemon || ubq_daemon_is_dying(ubq);
        unsigned int mapped_bytes;
 
        pr_devel("%s: complete: op %d, qid %d tag %d io_flags %x addr %llx\n",
@@ -680,6 +680,11 @@ static inline void __ublk_rq_task_work(struct request *req)
                 * do the copy work.
                 */
                io->flags &= ~UBLK_IO_FLAG_NEED_GET_DATA;
+               /* update iod->addr because ublksrv may have passed a new io buffer */
+               ublk_get_iod(ubq, req->tag)->addr = io->addr;
+               pr_devel("%s: update iod->addr: op %d, qid %d tag %d io_flags %x addr %llx\n",
+                               __func__, io->cmd->cmd_op, ubq->q_id, req->tag, io->flags,
+                               ublk_get_iod(ubq, req->tag)->addr);
        }
 
        mapped_bytes = ublk_map_io(ubq, req, io);
@@ -751,9 +756,25 @@ static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx,
                if (task_work_add(ubq->ubq_daemon, &data->work, notify_mode))
                        goto fail;
        } else {
-               struct io_uring_cmd *cmd = ubq->ios[rq->tag].cmd;
+               struct ublk_io *io = &ubq->ios[rq->tag];
+               struct io_uring_cmd *cmd = io->cmd;
                struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
 
+               /*
+                * If the check pass, we know that this is a re-issued request aborted
+                * previously in monitor_work because the ubq_daemon(cmd's task) is
+                * PF_EXITING. We cannot call io_uring_cmd_complete_in_task() anymore
+                * because this ioucmd's io_uring context may be freed now if no inflight
+                * ioucmd exists. Otherwise we may cause null-deref in ctx->fallback_work.
+                *
+                * Note: monitor_work sets UBLK_IO_FLAG_ABORTED and ends this request(releasing
+                * the tag). Then the request is re-started(allocating the tag) and we are here.
+                * Since releasing/allocating a tag implies smp_mb(), finding UBLK_IO_FLAG_ABORTED
+                * guarantees that here is a re-issued request aborted previously.
+                */
+               if ((io->flags & UBLK_IO_FLAG_ABORTED))
+                       goto fail;
+
                pdu->req = rq;
                io_uring_cmd_complete_in_task(cmd, ublk_rq_task_work_cb);
        }
index 48f8f42..d79905f 100644 (file)
@@ -249,7 +249,7 @@ config COMMON_CLK_GEMINI
          platform, also known as SL3516 or CS3516.
 
 config COMMON_CLK_LAN966X
-       bool "Generic Clock Controller driver for LAN966X SoC"
+       tristate "Generic Clock Controller driver for LAN966X SoC"
        depends on HAS_IOMEM
        depends on OF
        depends on SOC_LAN966 || COMPILE_TEST
@@ -377,6 +377,15 @@ config COMMON_CLK_VC5
          This driver supports the IDT VersaClock 5 and VersaClock 6
          programmable clock generators.
 
+config COMMON_CLK_VC7
+       tristate "Clock driver for Renesas Versaclock 7 devices"
+       depends on I2C
+       depends on OF
+       select REGMAP_I2C
+       help
+         Renesas Versaclock7 is a family of configurable clock generator
+         and jitter attenuator ICs with fractional and integer dividers.
+
 config COMMON_CLK_STM32MP135
        def_bool COMMON_CLK && MACH_STM32MP13
        help
index d5db170..e3ca0d0 100644 (file)
@@ -73,6 +73,7 @@ obj-$(CONFIG_CLK_TWL6040)             += clk-twl6040.o
 obj-$(CONFIG_ARCH_VT8500)              += clk-vt8500.o
 obj-$(CONFIG_COMMON_CLK_RS9_PCIE)      += clk-renesas-pcie.o
 obj-$(CONFIG_COMMON_CLK_VC5)           += clk-versaclock5.o
+obj-$(CONFIG_COMMON_CLK_VC7)           += clk-versaclock7.o
 obj-$(CONFIG_COMMON_CLK_WM831X)                += clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_XGENE)         += clk-xgene.o
 
index 8ca8bca..85a964c 100644 (file)
@@ -33,8 +33,11 @@ static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np)
        const char *name = np->name;
        const char *parent_name;
        struct regmap *regmap;
+       struct device_node *parent_np;
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -56,8 +59,11 @@ static void __init of_sama5d2_clk_audio_pll_pad_setup(struct device_node *np)
        const char *name = np->name;
        const char *parent_name;
        struct regmap *regmap;
+       struct device_node *parent_np;
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -79,8 +85,11 @@ static void __init of_sama5d2_clk_audio_pll_pmc_setup(struct device_node *np)
        const char *name = np->name;
        const char *parent_name;
        struct regmap *regmap;
+       struct device_node *parent_np;
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -120,7 +129,7 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
        struct clk_hw *hw;
        unsigned int num_parents;
        const char *parent_names[GENERATED_SOURCE_MAX];
-       struct device_node *gcknp;
+       struct device_node *gcknp, *parent_np;
        struct clk_range range = CLK_RANGE(0, 0);
        struct regmap *regmap;
 
@@ -134,7 +143,9 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
        if (!num || num > PERIPHERAL_MAX)
                return;
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -180,8 +191,11 @@ static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
        const char *name = np->name;
        const char *parent_name;
        struct regmap *regmap;
+       struct device_node *parent_np;
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -243,12 +257,15 @@ static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
        const char *parent_name;
        struct regmap *regmap;
        bool bypass;
+       struct device_node *parent_np;
 
        of_property_read_string(np, "clock-output-names", &name);
        bypass = of_property_read_bool(np, "atmel,osc-bypass");
        parent_name = of_clk_get_parent_name(np, 0);
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -268,12 +285,15 @@ static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
        u32 accuracy = 0;
        const char *name = np->name;
        struct regmap *regmap;
+       struct device_node *parent_np;
 
        of_property_read_string(np, "clock-output-names", &name);
        of_property_read_u32(np, "clock-frequency", &frequency);
        of_property_read_u32(np, "clock-accuracy", &accuracy);
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -292,11 +312,14 @@ static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
        const char *parent_name;
        const char *name = np->name;
        struct regmap *regmap;
+       struct device_node *parent_np;
 
        parent_name = of_clk_get_parent_name(np, 0);
        of_property_read_string(np, "clock-output-names", &name);
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -316,13 +339,16 @@ static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
        unsigned int num_parents;
        const char *name = np->name;
        struct regmap *regmap;
+       struct device_node *parent_np;
 
        num_parents = of_clk_get_parent_count(np);
        if (num_parents == 0 || num_parents > 2)
                return;
 
        of_clk_parent_fill(np, parent_names, num_parents);
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -373,6 +399,7 @@ of_at91_clk_master_setup(struct device_node *np,
        const char *name = np->name;
        struct clk_master_characteristics *characteristics;
        struct regmap *regmap;
+       struct device_node *parent_np;
 
        num_parents = of_clk_get_parent_count(np);
        if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX)
@@ -386,7 +413,9 @@ of_at91_clk_master_setup(struct device_node *np,
        if (!characteristics)
                return;
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -433,6 +462,7 @@ of_at91_clk_periph_setup(struct device_node *np, u8 type)
        const char *name;
        struct device_node *periphclknp;
        struct regmap *regmap;
+       struct device_node *parent_np;
 
        parent_name = of_clk_get_parent_name(np, 0);
        if (!parent_name)
@@ -442,7 +472,9 @@ of_at91_clk_periph_setup(struct device_node *np, u8 type)
        if (!num || num > PERIPHERAL_MAX)
                return;
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -601,6 +633,7 @@ of_at91_clk_pll_setup(struct device_node *np,
        struct regmap *regmap;
        const char *parent_name;
        const char *name = np->name;
+       struct device_node *parent_np;
        struct clk_pll_characteristics *characteristics;
 
        if (of_property_read_u32(np, "reg", &id))
@@ -610,7 +643,9 @@ of_at91_clk_pll_setup(struct device_node *np,
 
        of_property_read_string(np, "clock-output-names", &name);
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -665,12 +700,15 @@ of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
        const char *parent_name;
        const char *name = np->name;
        struct regmap *regmap;
+       struct device_node *parent_np;
 
        parent_name = of_clk_get_parent_name(np, 0);
 
        of_property_read_string(np, "clock-output-names", &name);
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -694,7 +732,7 @@ of_at91_clk_prog_setup(struct device_node *np,
        unsigned int num_parents;
        const char *parent_names[PROG_SOURCE_MAX];
        const char *name;
-       struct device_node *progclknp;
+       struct device_node *progclknp, *parent_np;
        struct regmap *regmap;
 
        num_parents = of_clk_get_parent_count(np);
@@ -707,7 +745,9 @@ of_at91_clk_prog_setup(struct device_node *np,
        if (!num || num > (PROG_ID_MAX + 1))
                return;
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -756,13 +796,16 @@ static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
        unsigned int num_parents;
        const char *name = np->name;
        struct regmap *regmap;
+       struct device_node *parent_np;
 
        num_parents = of_clk_get_parent_count(np);
        if (num_parents != 2)
                return;
 
        of_clk_parent_fill(np, parent_names, num_parents);
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -788,6 +831,7 @@ static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
        const char *parent_names[SMD_SOURCE_MAX];
        const char *name = np->name;
        struct regmap *regmap;
+       struct device_node *parent_np;
 
        num_parents = of_clk_get_parent_count(np);
        if (num_parents == 0 || num_parents > SMD_SOURCE_MAX)
@@ -797,7 +841,9 @@ static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
 
        of_property_read_string(np, "clock-output-names", &name);
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -818,7 +864,7 @@ static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
        u32 id;
        struct clk_hw *hw;
        const char *name;
-       struct device_node *sysclknp;
+       struct device_node *sysclknp, *parent_np;
        const char *parent_name;
        struct regmap *regmap;
 
@@ -826,7 +872,9 @@ static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
        if (num > (SYSTEM_MAX_ID + 1))
                return;
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -859,6 +907,7 @@ static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
        const char *parent_names[USB_SOURCE_MAX];
        const char *name = np->name;
        struct regmap *regmap;
+       struct device_node *parent_np;
 
        num_parents = of_clk_get_parent_count(np);
        if (num_parents == 0 || num_parents > USB_SOURCE_MAX)
@@ -868,7 +917,9 @@ static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
 
        of_property_read_string(np, "clock-output-names", &name);
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -888,6 +939,7 @@ static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
        const char *parent_name;
        const char *name = np->name;
        struct regmap *regmap;
+       struct device_node *parent_np;
 
        parent_name = of_clk_get_parent_name(np, 0);
        if (!parent_name)
@@ -895,7 +947,9 @@ static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
 
        of_property_read_string(np, "clock-output-names", &name);
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
 
@@ -915,6 +969,7 @@ static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
        const char *name = np->name;
        u32 divisors[4] = {0, 0, 0, 0};
        struct regmap *regmap;
+       struct device_node *parent_np;
 
        parent_name = of_clk_get_parent_name(np, 0);
        if (!parent_name)
@@ -926,7 +981,9 @@ static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
 
        of_property_read_string(np, "clock-output-names", &name);
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap))
                return;
        hw = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
@@ -946,12 +1003,15 @@ static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
        const char *parent_name;
        const char *name = np->name;
        struct regmap *regmap_pmc, *regmap_sfr;
+       struct device_node *parent_np;
 
        parent_name = of_clk_get_parent_name(np, 0);
 
        of_property_read_string(np, "clock-output-names", &name);
 
-       regmap_pmc = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap_pmc = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap_pmc))
                return;
 
index cfd0f5e..84156dc 100644 (file)
@@ -120,6 +120,16 @@ static const struct {
        struct clk_range r;
        int chg_pid;
 } sama5d2_gck[] = {
+       { .n = "flx0_gclk",   .id = 19, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
+       { .n = "flx1_gclk",   .id = 20, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
+       { .n = "flx2_gclk",   .id = 21, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
+       { .n = "flx3_gclk",   .id = 22, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
+       { .n = "flx4_gclk",   .id = 23, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
+       { .n = "uart0_gclk",  .id = 24, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
+       { .n = "uart1_gclk",  .id = 25, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
+       { .n = "uart2_gclk",  .id = 26, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
+       { .n = "uart3_gclk",  .id = 27, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
+       { .n = "uart4_gclk",  .id = 28, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
        { .n = "sdmmc0_gclk", .id = 31, .chg_pid = INT_MIN, },
        { .n = "sdmmc1_gclk", .id = 32, .chg_pid = INT_MIN, },
        { .n = "tcb0_gclk",   .id = 35, .chg_pid = INT_MIN, .r = { .min = 0, .max = 83000000 }, },
index 03102f1..f0b1868 100644 (file)
@@ -29,7 +29,6 @@ config CLK_BT1_CCU_PLL
 
 config CLK_BT1_CCU_DIV
        bool "Baikal-T1 CCU Dividers support"
-       select RESET_CONTROLLER
        select MFD_SYSCON
        default MIPS_BAIKAL_T1
        help
@@ -39,4 +38,15 @@ config CLK_BT1_CCU_DIV
          either gateable or ungateable. Some of the CCU dividers can be as well
          used to reset the domains they're supplying clock to.
 
+config CLK_BT1_CCU_RST
+       bool "Baikal-T1 CCU Resets support"
+       select RESET_CONTROLLER
+       select MFD_SYSCON
+       default MIPS_BAIKAL_T1
+       help
+         Enable this to support the CCU reset blocks responsible for the
+         AXI-bus and some subsystems reset. These are mainly the
+         self-deasserted reset controls but there are several lines which
+         can be directly asserted/de-asserted (PCIe and DDR sub-domains).
+
 endif
index b3b9590..9c3637d 100644 (file)
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_CLK_BT1_CCU_PLL) += ccu-pll.o clk-ccu-pll.o
 obj-$(CONFIG_CLK_BT1_CCU_DIV) += ccu-div.o clk-ccu-div.o
+obj-$(CONFIG_CLK_BT1_CCU_RST) += ccu-rst.o
index 4062092..8d5fc71 100644 (file)
@@ -34,9 +34,9 @@
 #define CCU_DIV_CTL_CLKDIV_MASK(_width) \
        GENMASK((_width) + CCU_DIV_CTL_CLKDIV_FLD - 1, CCU_DIV_CTL_CLKDIV_FLD)
 #define CCU_DIV_CTL_LOCK_SHIFTED       BIT(27)
+#define CCU_DIV_CTL_GATE_REF_BUF       BIT(28)
 #define CCU_DIV_CTL_LOCK_NORMAL                BIT(31)
 
-#define CCU_DIV_RST_DELAY_US           1
 #define CCU_DIV_LOCK_CHECK_RETRIES     50
 
 #define CCU_DIV_CLKDIV_MIN             0
@@ -170,6 +170,40 @@ static int ccu_div_gate_is_enabled(struct clk_hw *hw)
        return !!(val & CCU_DIV_CTL_EN);
 }
 
+static int ccu_div_buf_enable(struct clk_hw *hw)
+{
+       struct ccu_div *div = to_ccu_div(hw);
+       unsigned long flags;
+
+       spin_lock_irqsave(&div->lock, flags);
+       regmap_update_bits(div->sys_regs, div->reg_ctl,
+                          CCU_DIV_CTL_GATE_REF_BUF, 0);
+       spin_unlock_irqrestore(&div->lock, flags);
+
+       return 0;
+}
+
+static void ccu_div_buf_disable(struct clk_hw *hw)
+{
+       struct ccu_div *div = to_ccu_div(hw);
+       unsigned long flags;
+
+       spin_lock_irqsave(&div->lock, flags);
+       regmap_update_bits(div->sys_regs, div->reg_ctl,
+                          CCU_DIV_CTL_GATE_REF_BUF, CCU_DIV_CTL_GATE_REF_BUF);
+       spin_unlock_irqrestore(&div->lock, flags);
+}
+
+static int ccu_div_buf_is_enabled(struct clk_hw *hw)
+{
+       struct ccu_div *div = to_ccu_div(hw);
+       u32 val = 0;
+
+       regmap_read(div->sys_regs, div->reg_ctl, &val);
+
+       return !(val & CCU_DIV_CTL_GATE_REF_BUF);
+}
+
 static unsigned long ccu_div_var_recalc_rate(struct clk_hw *hw,
                                             unsigned long parent_rate)
 {
@@ -288,24 +322,6 @@ static int ccu_div_fixed_set_rate(struct clk_hw *hw, unsigned long rate,
        return 0;
 }
 
-int ccu_div_reset_domain(struct ccu_div *div)
-{
-       unsigned long flags;
-
-       if (!div || !(div->features & CCU_DIV_RESET_DOMAIN))
-               return -EINVAL;
-
-       spin_lock_irqsave(&div->lock, flags);
-       regmap_update_bits(div->sys_regs, div->reg_ctl,
-                          CCU_DIV_CTL_RST, CCU_DIV_CTL_RST);
-       spin_unlock_irqrestore(&div->lock, flags);
-
-       /* The next delay must be enough to cover all the resets. */
-       udelay(CCU_DIV_RST_DELAY_US);
-
-       return 0;
-}
-
 #ifdef CONFIG_DEBUG_FS
 
 struct ccu_div_dbgfs_bit {
@@ -323,6 +339,7 @@ static const struct ccu_div_dbgfs_bit ccu_div_bits[] = {
        CCU_DIV_DBGFS_BIT_ATTR("div_en", CCU_DIV_CTL_EN),
        CCU_DIV_DBGFS_BIT_ATTR("div_rst", CCU_DIV_CTL_RST),
        CCU_DIV_DBGFS_BIT_ATTR("div_bypass", CCU_DIV_CTL_SET_CLKDIV),
+       CCU_DIV_DBGFS_BIT_ATTR("div_buf", CCU_DIV_CTL_GATE_REF_BUF),
        CCU_DIV_DBGFS_BIT_ATTR("div_lock", CCU_DIV_CTL_LOCK_NORMAL)
 };
 
@@ -441,6 +458,9 @@ static void ccu_div_var_debug_init(struct clk_hw *hw, struct dentry *dentry)
                        continue;
                }
 
+               if (!strcmp("div_buf", name))
+                       continue;
+
                bits[didx] = ccu_div_bits[bidx];
                bits[didx].div = div;
 
@@ -477,6 +497,21 @@ static void ccu_div_gate_debug_init(struct clk_hw *hw, struct dentry *dentry)
                                   &ccu_div_dbgfs_fixed_clkdiv_fops);
 }
 
+static void ccu_div_buf_debug_init(struct clk_hw *hw, struct dentry *dentry)
+{
+       struct ccu_div *div = to_ccu_div(hw);
+       struct ccu_div_dbgfs_bit *bit;
+
+       bit = kmalloc(sizeof(*bit), GFP_KERNEL);
+       if (!bit)
+               return;
+
+       *bit = ccu_div_bits[3];
+       bit->div = div;
+       debugfs_create_file_unsafe(bit->name, ccu_div_dbgfs_mode, dentry, bit,
+                                  &ccu_div_dbgfs_bit_fops);
+}
+
 static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry)
 {
        struct ccu_div *div = to_ccu_div(hw);
@@ -489,6 +524,7 @@ static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry)
 
 #define ccu_div_var_debug_init NULL
 #define ccu_div_gate_debug_init NULL
+#define ccu_div_buf_debug_init NULL
 #define ccu_div_fixed_debug_init NULL
 
 #endif /* !CONFIG_DEBUG_FS */
@@ -520,6 +556,13 @@ static const struct clk_ops ccu_div_gate_ops = {
        .debug_init = ccu_div_gate_debug_init
 };
 
+static const struct clk_ops ccu_div_buf_ops = {
+       .enable = ccu_div_buf_enable,
+       .disable = ccu_div_buf_disable,
+       .is_enabled = ccu_div_buf_is_enabled,
+       .debug_init = ccu_div_buf_debug_init
+};
+
 static const struct clk_ops ccu_div_fixed_ops = {
        .recalc_rate = ccu_div_fixed_recalc_rate,
        .round_rate = ccu_div_fixed_round_rate,
@@ -566,6 +609,8 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init)
        } else if (div_init->type == CCU_DIV_GATE) {
                hw_init.ops = &ccu_div_gate_ops;
                div->divider = div_init->divider;
+       } else if (div_init->type == CCU_DIV_BUF) {
+               hw_init.ops = &ccu_div_buf_ops;
        } else if (div_init->type == CCU_DIV_FIXED) {
                hw_init.ops = &ccu_div_fixed_ops;
                div->divider = div_init->divider;
@@ -579,6 +624,7 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init)
                goto err_free_div;
        }
        parent_data.fw_name = div_init->parent_name;
+       parent_data.name = div_init->parent_name;
        hw_init.parent_data = &parent_data;
        hw_init.num_parents = 1;
 
index 795665c..76d8ee4 100644 (file)
 #include <linux/of.h>
 
 /*
+ * CCU Divider private clock IDs
+ * @CCU_SYS_SATA_CLK: CCU SATA internal clock
+ * @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock
+ */
+#define CCU_SYS_SATA_CLK               -1
+#define CCU_SYS_XGMAC_CLK              -2
+
+/*
  * CCU Divider private flags
+ * @CCU_DIV_BASIC: Basic divider clock required by the kernel as early as
+ *                possible.
  * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1.
  *                   It can be 0 though, which is functionally the same.
  * @CCU_DIV_SKIP_ONE_TO_THREE: For some reason divider can't be within [1,3].
  *                            It can be either 0 or greater than 3.
  * @CCU_DIV_LOCK_SHIFTED: Find lock-bit at non-standard position.
- * @CCU_DIV_RESET_DOMAIN: Provide reset clock domain method.
+ * @CCU_DIV_RESET_DOMAIN: There is a clock domain reset handle.
  */
+#define CCU_DIV_BASIC                  BIT(0)
 #define CCU_DIV_SKIP_ONE               BIT(1)
 #define CCU_DIV_SKIP_ONE_TO_THREE      BIT(2)
 #define CCU_DIV_LOCK_SHIFTED           BIT(3)
  * enum ccu_div_type - CCU Divider types
  * @CCU_DIV_VAR: Clocks gate with variable divider.
  * @CCU_DIV_GATE: Clocks gate with fixed divider.
+ * @CCU_DIV_BUF: Clock gate with no divider.
  * @CCU_DIV_FIXED: Ungateable clock with fixed divider.
  */
 enum ccu_div_type {
        CCU_DIV_VAR,
        CCU_DIV_GATE,
+       CCU_DIV_BUF,
        CCU_DIV_FIXED
 };
 
@@ -105,6 +118,4 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *init);
 
 void ccu_div_hw_unregister(struct ccu_div *div);
 
-int ccu_div_reset_domain(struct ccu_div *div);
-
 #endif /* __CLK_BT1_CCU_DIV_H__ */
index 76cd913..a71bfd7 100644 (file)
 #include <linux/of.h>
 
 /*
+ * CCU PLL private flags
+ * @CCU_PLL_BASIC: Basic PLL required by the kernel as early as possible.
+ */
+#define CCU_PLL_BASIC          BIT(0)
+
+/*
  * struct ccu_pll_init_data - CCU PLL initialization data
  * @id: Clock private identifier.
  * @name: Clocks name.
@@ -22,6 +28,7 @@
  * @sys_regs: Baikal-T1 System Controller registers map.
  * @np: Pointer to the node describing the CCU PLLs.
  * @flags: PLL clock flags.
+ * @features: PLL private features.
  */
 struct ccu_pll_init_data {
        unsigned int id;
@@ -31,6 +38,7 @@ struct ccu_pll_init_data {
        struct regmap *sys_regs;
        struct device_node *np;
        unsigned long flags;
+       unsigned long features;
 };
 
 /*
diff --git a/drivers/clk/baikal-t1/ccu-rst.c b/drivers/clk/baikal-t1/ccu-rst.c
new file mode 100644 (file)
index 0000000..40023ea
--- /dev/null
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 BAIKAL ELECTRONICS, JSC
+ *
+ * Authors:
+ *   Serge Semin <Sergey.Semin@baikalelectronics.ru>
+ *
+ * Baikal-T1 CCU Resets interface driver
+ */
+
+#define pr_fmt(fmt) "bt1-ccu-rst: " fmt
+
+#include <linux/bits.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/printk.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/reset/bt1-ccu.h>
+
+#include "ccu-rst.h"
+
+#define CCU_AXI_MAIN_BASE              0x030
+#define CCU_AXI_DDR_BASE               0x034
+#define CCU_AXI_SATA_BASE              0x038
+#define CCU_AXI_GMAC0_BASE             0x03C
+#define CCU_AXI_GMAC1_BASE             0x040
+#define CCU_AXI_XGMAC_BASE             0x044
+#define CCU_AXI_PCIE_M_BASE            0x048
+#define CCU_AXI_PCIE_S_BASE            0x04C
+#define CCU_AXI_USB_BASE               0x050
+#define CCU_AXI_HWA_BASE               0x054
+#define CCU_AXI_SRAM_BASE              0x058
+
+#define CCU_SYS_DDR_BASE               0x02c
+#define CCU_SYS_SATA_REF_BASE          0x060
+#define CCU_SYS_APB_BASE               0x064
+#define CCU_SYS_PCIE_BASE              0x144
+
+#define CCU_RST_DELAY_US               1
+
+#define CCU_RST_TRIG(_base, _ofs)              \
+       {                                       \
+               .type = CCU_RST_TRIG,           \
+               .base = _base,                  \
+               .mask = BIT(_ofs),              \
+       }
+
+#define CCU_RST_DIR(_base, _ofs)               \
+       {                                       \
+               .type = CCU_RST_DIR,            \
+               .base = _base,                  \
+               .mask = BIT(_ofs),              \
+       }
+
+struct ccu_rst_info {
+       enum ccu_rst_type type;
+       unsigned int base;
+       unsigned int mask;
+};
+
+/*
+ * Each AXI-bus clock divider is equipped with the corresponding clock-consumer
+ * domain reset (it's self-deasserted reset control).
+ */
+static const struct ccu_rst_info axi_rst_info[] = {
+       [CCU_AXI_MAIN_RST] = CCU_RST_TRIG(CCU_AXI_MAIN_BASE, 1),
+       [CCU_AXI_DDR_RST] = CCU_RST_TRIG(CCU_AXI_DDR_BASE, 1),
+       [CCU_AXI_SATA_RST] = CCU_RST_TRIG(CCU_AXI_SATA_BASE, 1),
+       [CCU_AXI_GMAC0_RST] = CCU_RST_TRIG(CCU_AXI_GMAC0_BASE, 1),
+       [CCU_AXI_GMAC1_RST] = CCU_RST_TRIG(CCU_AXI_GMAC1_BASE, 1),
+       [CCU_AXI_XGMAC_RST] = CCU_RST_TRIG(CCU_AXI_XGMAC_BASE, 1),
+       [CCU_AXI_PCIE_M_RST] = CCU_RST_TRIG(CCU_AXI_PCIE_M_BASE, 1),
+       [CCU_AXI_PCIE_S_RST] = CCU_RST_TRIG(CCU_AXI_PCIE_S_BASE, 1),
+       [CCU_AXI_USB_RST] = CCU_RST_TRIG(CCU_AXI_USB_BASE, 1),
+       [CCU_AXI_HWA_RST] = CCU_RST_TRIG(CCU_AXI_HWA_BASE, 1),
+       [CCU_AXI_SRAM_RST] = CCU_RST_TRIG(CCU_AXI_SRAM_BASE, 1),
+};
+
+/*
+ * SATA reference clock domain and APB-bus domain are connected with the
+ * sefl-deasserted reset control, which can be activated via the corresponding
+ * clock divider register. DDR and PCIe sub-domains can be reset with directly
+ * controlled reset signals. Resetting the DDR controller though won't end up
+ * well while the Linux kernel is working.
+ */
+static const struct ccu_rst_info sys_rst_info[] = {
+       [CCU_SYS_SATA_REF_RST] = CCU_RST_TRIG(CCU_SYS_SATA_REF_BASE, 1),
+       [CCU_SYS_APB_RST] = CCU_RST_TRIG(CCU_SYS_APB_BASE, 1),
+       [CCU_SYS_DDR_FULL_RST] = CCU_RST_DIR(CCU_SYS_DDR_BASE, 1),
+       [CCU_SYS_DDR_INIT_RST] = CCU_RST_DIR(CCU_SYS_DDR_BASE, 2),
+       [CCU_SYS_PCIE_PCS_PHY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 0),
+       [CCU_SYS_PCIE_PIPE0_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 4),
+       [CCU_SYS_PCIE_CORE_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 8),
+       [CCU_SYS_PCIE_PWR_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 9),
+       [CCU_SYS_PCIE_STICKY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 10),
+       [CCU_SYS_PCIE_NSTICKY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 11),
+       [CCU_SYS_PCIE_HOT_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 12),
+};
+
+static int ccu_rst_reset(struct reset_controller_dev *rcdev, unsigned long idx)
+{
+       struct ccu_rst *rst = to_ccu_rst(rcdev);
+       const struct ccu_rst_info *info = &rst->rsts_info[idx];
+
+       if (info->type != CCU_RST_TRIG)
+               return -EOPNOTSUPP;
+
+       regmap_update_bits(rst->sys_regs, info->base, info->mask, info->mask);
+
+       /* The next delay must be enough to cover all the resets. */
+       udelay(CCU_RST_DELAY_US);
+
+       return 0;
+}
+
+static int ccu_rst_set(struct reset_controller_dev *rcdev,
+                      unsigned long idx, bool high)
+{
+       struct ccu_rst *rst = to_ccu_rst(rcdev);
+       const struct ccu_rst_info *info = &rst->rsts_info[idx];
+
+       if (info->type != CCU_RST_DIR)
+               return high ? -EOPNOTSUPP : 0;
+
+       return regmap_update_bits(rst->sys_regs, info->base,
+                                 info->mask, high ? info->mask : 0);
+}
+
+static int ccu_rst_assert(struct reset_controller_dev *rcdev,
+                         unsigned long idx)
+{
+       return ccu_rst_set(rcdev, idx, true);
+}
+
+static int ccu_rst_deassert(struct reset_controller_dev *rcdev,
+                           unsigned long idx)
+{
+       return ccu_rst_set(rcdev, idx, false);
+}
+
+static int ccu_rst_status(struct reset_controller_dev *rcdev,
+                         unsigned long idx)
+{
+       struct ccu_rst *rst = to_ccu_rst(rcdev);
+       const struct ccu_rst_info *info = &rst->rsts_info[idx];
+       u32 val;
+
+       if (info->type != CCU_RST_DIR)
+               return -EOPNOTSUPP;
+
+       regmap_read(rst->sys_regs, info->base, &val);
+
+       return !!(val & info->mask);
+}
+
+static const struct reset_control_ops ccu_rst_ops = {
+       .reset = ccu_rst_reset,
+       .assert = ccu_rst_assert,
+       .deassert = ccu_rst_deassert,
+       .status = ccu_rst_status,
+};
+
+struct ccu_rst *ccu_rst_hw_register(const struct ccu_rst_init_data *rst_init)
+{
+       struct ccu_rst *rst;
+       int ret;
+
+       if (!rst_init)
+               return ERR_PTR(-EINVAL);
+
+       rst = kzalloc(sizeof(*rst), GFP_KERNEL);
+       if (!rst)
+               return ERR_PTR(-ENOMEM);
+
+       rst->sys_regs = rst_init->sys_regs;
+       if (of_device_is_compatible(rst_init->np, "baikal,bt1-ccu-axi")) {
+               rst->rcdev.nr_resets = ARRAY_SIZE(axi_rst_info);
+               rst->rsts_info = axi_rst_info;
+       } else if (of_device_is_compatible(rst_init->np, "baikal,bt1-ccu-sys")) {
+               rst->rcdev.nr_resets = ARRAY_SIZE(sys_rst_info);
+               rst->rsts_info = sys_rst_info;
+       } else {
+               pr_err("Incompatible DT node '%s' specified\n",
+                      of_node_full_name(rst_init->np));
+               ret = -EINVAL;
+               goto err_kfree_rst;
+       }
+
+       rst->rcdev.owner = THIS_MODULE;
+       rst->rcdev.ops = &ccu_rst_ops;
+       rst->rcdev.of_node = rst_init->np;
+
+       ret = reset_controller_register(&rst->rcdev);
+       if (ret) {
+               pr_err("Couldn't register '%s' reset controller\n",
+                      of_node_full_name(rst_init->np));
+               goto err_kfree_rst;
+       }
+
+       return rst;
+
+err_kfree_rst:
+       kfree(rst);
+
+       return ERR_PTR(ret);
+}
+
+void ccu_rst_hw_unregister(struct ccu_rst *rst)
+{
+       reset_controller_unregister(&rst->rcdev);
+
+       kfree(rst);
+}
diff --git a/drivers/clk/baikal-t1/ccu-rst.h b/drivers/clk/baikal-t1/ccu-rst.h
new file mode 100644 (file)
index 0000000..d6e8b2f
--- /dev/null
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 BAIKAL ELECTRONICS, JSC
+ *
+ * Baikal-T1 CCU Resets interface driver
+ */
+#ifndef __CLK_BT1_CCU_RST_H__
+#define __CLK_BT1_CCU_RST_H__
+
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+struct ccu_rst_info;
+
+/*
+ * enum ccu_rst_type - CCU Reset types
+ * @CCU_RST_TRIG: Self-deasserted reset signal.
+ * @CCU_RST_DIR: Directly controlled reset signal.
+ */
+enum ccu_rst_type {
+       CCU_RST_TRIG,
+       CCU_RST_DIR,
+};
+
+/*
+ * struct ccu_rst_init_data - CCU Resets initialization data
+ * @sys_regs: Baikal-T1 System Controller registers map.
+ * @np: Pointer to the node with the System CCU block.
+ */
+struct ccu_rst_init_data {
+       struct regmap *sys_regs;
+       struct device_node *np;
+};
+
+/*
+ * struct ccu_rst - CCU Reset descriptor
+ * @rcdev: Reset controller descriptor.
+ * @sys_regs: Baikal-T1 System Controller registers map.
+ * @rsts_info: Reset flag info (base address and mask).
+ */
+struct ccu_rst {
+       struct reset_controller_dev rcdev;
+       struct regmap *sys_regs;
+       const struct ccu_rst_info *rsts_info;
+};
+#define to_ccu_rst(_rcdev) container_of(_rcdev, struct ccu_rst, rcdev)
+
+#ifdef CONFIG_CLK_BT1_CCU_RST
+
+struct ccu_rst *ccu_rst_hw_register(const struct ccu_rst_init_data *init);
+
+void ccu_rst_hw_unregister(struct ccu_rst *rst);
+
+#else
+
+static inline
+struct ccu_rst *ccu_rst_hw_register(const struct ccu_rst_init_data *init)
+{
+       return NULL;
+}
+
+static inline void ccu_rst_hw_unregister(struct ccu_rst *rst) {}
+
+#endif
+
+#endif /* __CLK_BT1_CCU_RST_H__ */
index f141fda..0e772e0 100644 (file)
@@ -12,6 +12,7 @@
 #define pr_fmt(fmt) "bt1-ccu-div: " fmt
 
 #include <linux/kernel.h>
+#include <linux/platform_device.h>
 #include <linux/printk.h>
 #include <linux/slab.h>
 #include <linux/clk-provider.h>
@@ -24,9 +25,9 @@
 #include <linux/regmap.h>
 
 #include <dt-bindings/clock/bt1-ccu.h>
-#include <dt-bindings/reset/bt1-ccu.h>
 
 #include "ccu-div.h"
+#include "ccu-rst.h"
 
 #define CCU_AXI_MAIN_BASE              0x030
 #define CCU_AXI_DDR_BASE               0x034
                .divider = _divider                             \
        }
 
+#define CCU_DIV_BUF_INFO(_id, _name, _pname, _base, _flags)    \
+       {                                                       \
+               .id = _id,                                      \
+               .name = _name,                                  \
+               .parent_name = _pname,                          \
+               .base = _base,                                  \
+               .type = CCU_DIV_BUF,                            \
+               .flags = _flags                                 \
+       }
+
 #define CCU_DIV_FIXED_INFO(_id, _name, _pname, _divider)       \
        {                                                       \
                .id = _id,                                      \
                .divider = _divider                             \
        }
 
-#define CCU_DIV_RST_MAP(_rst_id, _clk_id)      \
-       {                                       \
-               .rst_id = _rst_id,              \
-               .clk_id = _clk_id               \
-       }
-
 struct ccu_div_info {
        unsigned int id;
        const char *name;
@@ -105,11 +110,6 @@ struct ccu_div_info {
        unsigned long features;
 };
 
-struct ccu_div_rst_map {
-       unsigned int rst_id;
-       unsigned int clk_id;
-};
-
 struct ccu_div_data {
        struct device_node *np;
        struct regmap *sys_regs;
@@ -118,11 +118,8 @@ struct ccu_div_data {
        const struct ccu_div_info *divs_info;
        struct ccu_div **divs;
 
-       unsigned int rst_num;
-       const struct ccu_div_rst_map *rst_map;
-       struct reset_controller_dev rcdev;
+       struct ccu_rst *rsts;
 };
-#define to_ccu_div_data(_rcdev) container_of(_rcdev, struct ccu_div_data, rcdev)
 
 /*
  * AXI Main Interconnect (axi_main_clk) and DDR AXI-bus (axi_ddr_clk) clocks
@@ -169,33 +166,22 @@ static const struct ccu_div_info axi_info[] = {
                         CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN)
 };
 
-static const struct ccu_div_rst_map axi_rst_map[] = {
-       CCU_DIV_RST_MAP(CCU_AXI_MAIN_RST, CCU_AXI_MAIN_CLK),
-       CCU_DIV_RST_MAP(CCU_AXI_DDR_RST, CCU_AXI_DDR_CLK),
-       CCU_DIV_RST_MAP(CCU_AXI_SATA_RST, CCU_AXI_SATA_CLK),
-       CCU_DIV_RST_MAP(CCU_AXI_GMAC0_RST, CCU_AXI_GMAC0_CLK),
-       CCU_DIV_RST_MAP(CCU_AXI_GMAC1_RST, CCU_AXI_GMAC1_CLK),
-       CCU_DIV_RST_MAP(CCU_AXI_XGMAC_RST, CCU_AXI_XGMAC_CLK),
-       CCU_DIV_RST_MAP(CCU_AXI_PCIE_M_RST, CCU_AXI_PCIE_M_CLK),
-       CCU_DIV_RST_MAP(CCU_AXI_PCIE_S_RST, CCU_AXI_PCIE_S_CLK),
-       CCU_DIV_RST_MAP(CCU_AXI_USB_RST, CCU_AXI_USB_CLK),
-       CCU_DIV_RST_MAP(CCU_AXI_HWA_RST, CCU_AXI_HWA_CLK),
-       CCU_DIV_RST_MAP(CCU_AXI_SRAM_RST, CCU_AXI_SRAM_CLK)
-};
-
 /*
  * APB-bus clock is marked as critical since it's a main communication bus
  * for the SoC devices registers IO-operations.
  */
 static const struct ccu_div_info sys_info[] = {
-       CCU_DIV_VAR_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk",
+       CCU_DIV_VAR_INFO(CCU_SYS_SATA_CLK, "sys_sata_clk",
                         "sata_clk", CCU_SYS_SATA_REF_BASE, 4,
                         CLK_SET_RATE_GATE,
                         CCU_DIV_SKIP_ONE | CCU_DIV_LOCK_SHIFTED |
                         CCU_DIV_RESET_DOMAIN),
+       CCU_DIV_BUF_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk",
+                        "sys_sata_clk", CCU_SYS_SATA_REF_BASE,
+                        CLK_SET_RATE_PARENT),
        CCU_DIV_VAR_INFO(CCU_SYS_APB_CLK, "sys_apb_clk",
                         "pcie_clk", CCU_SYS_APB_BASE, 5,
-                        CLK_IS_CRITICAL, CCU_DIV_RESET_DOMAIN),
+                        CLK_IS_CRITICAL, CCU_DIV_BASIC | CCU_DIV_RESET_DOMAIN),
        CCU_DIV_GATE_INFO(CCU_SYS_GMAC0_TX_CLK, "sys_gmac0_tx_clk",
                          "eth_clk", CCU_SYS_GMAC0_BASE, 5),
        CCU_DIV_FIXED_INFO(CCU_SYS_GMAC0_PTP_CLK, "sys_gmac0_ptp_clk",
@@ -204,10 +190,12 @@ static const struct ccu_div_info sys_info[] = {
                          "eth_clk", CCU_SYS_GMAC1_BASE, 5),
        CCU_DIV_FIXED_INFO(CCU_SYS_GMAC1_PTP_CLK, "sys_gmac1_ptp_clk",
                           "eth_clk", 10),
-       CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk",
-                         "eth_clk", CCU_SYS_XGMAC_BASE, 8),
+       CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_CLK, "sys_xgmac_clk",
+                         "eth_clk", CCU_SYS_XGMAC_BASE, 1),
+       CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk",
+                          "sys_xgmac_clk", 8),
        CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_PTP_CLK, "sys_xgmac_ptp_clk",
-                          "eth_clk", 10),
+                          "sys_xgmac_clk", 8),
        CCU_DIV_GATE_INFO(CCU_SYS_USB_CLK, "sys_usb_clk",
                          "eth_clk", CCU_SYS_USB_BASE, 10),
        CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk",
@@ -227,74 +215,58 @@ static const struct ccu_div_info sys_info[] = {
                           "ref_clk", 25),
        CCU_DIV_VAR_INFO(CCU_SYS_TIMER0_CLK, "sys_timer0_clk",
                         "ref_clk", CCU_SYS_TIMER0_BASE, 17,
-                        CLK_SET_RATE_GATE, 0),
+                        CLK_SET_RATE_GATE, CCU_DIV_BASIC),
        CCU_DIV_VAR_INFO(CCU_SYS_TIMER1_CLK, "sys_timer1_clk",
                         "ref_clk", CCU_SYS_TIMER1_BASE, 17,
-                        CLK_SET_RATE_GATE, 0),
+                        CLK_SET_RATE_GATE, CCU_DIV_BASIC),
        CCU_DIV_VAR_INFO(CCU_SYS_TIMER2_CLK, "sys_timer2_clk",
                         "ref_clk", CCU_SYS_TIMER2_BASE, 17,
-                        CLK_SET_RATE_GATE, 0),
+                        CLK_SET_RATE_GATE, CCU_DIV_BASIC),
        CCU_DIV_VAR_INFO(CCU_SYS_WDT_CLK, "sys_wdt_clk",
                         "eth_clk", CCU_SYS_WDT_BASE, 17,
                         CLK_SET_RATE_GATE, CCU_DIV_SKIP_ONE_TO_THREE)
 };
 
-static const struct ccu_div_rst_map sys_rst_map[] = {
-       CCU_DIV_RST_MAP(CCU_SYS_SATA_REF_RST, CCU_SYS_SATA_REF_CLK),
-       CCU_DIV_RST_MAP(CCU_SYS_APB_RST, CCU_SYS_APB_CLK),
-};
+static struct ccu_div_data *axi_data;
+static struct ccu_div_data *sys_data;
 
-static struct ccu_div *ccu_div_find_desc(struct ccu_div_data *data,
-                                        unsigned int clk_id)
+static void ccu_div_set_data(struct ccu_div_data *data)
 {
-       struct ccu_div *div;
-       int idx;
-
-       for (idx = 0; idx < data->divs_num; ++idx) {
-               div = data->divs[idx];
-               if (div && div->id == clk_id)
-                       return div;
-       }
-
-       return ERR_PTR(-EINVAL);
+       struct device_node *np = data->np;
+
+       if (of_device_is_compatible(np, "baikal,bt1-ccu-axi"))
+               axi_data = data;
+       else if (of_device_is_compatible(np, "baikal,bt1-ccu-sys"))
+               sys_data = data;
+       else
+               pr_err("Invalid DT node '%s' specified\n", of_node_full_name(np));
 }
 
-static int ccu_div_reset(struct reset_controller_dev *rcdev,
-                        unsigned long rst_id)
+static struct ccu_div_data *ccu_div_get_data(struct device_node *np)
 {
-       struct ccu_div_data *data = to_ccu_div_data(rcdev);
-       const struct ccu_div_rst_map *map;
-       struct ccu_div *div;
-       int idx, ret;
+       if (of_device_is_compatible(np, "baikal,bt1-ccu-axi"))
+               return axi_data;
+       else if (of_device_is_compatible(np, "baikal,bt1-ccu-sys"))
+               return sys_data;
 
-       for (idx = 0, map = data->rst_map; idx < data->rst_num; ++idx, ++map) {
-               if (map->rst_id == rst_id)
-                       break;
-       }
-       if (idx == data->rst_num) {
-               pr_err("Invalid reset ID %lu specified\n", rst_id);
-               return -EINVAL;
-       }
+       pr_err("Invalid DT node '%s' specified\n", of_node_full_name(np));
 
-       div = ccu_div_find_desc(data, map->clk_id);
-       if (IS_ERR(div)) {
-               pr_err("Invalid clock ID %d in mapping\n", map->clk_id);
-               return PTR_ERR(div);
-       }
+       return NULL;
+}
 
-       ret = ccu_div_reset_domain(div);
-       if (ret) {
-               pr_err("Reset isn't supported by divider %s\n",
-                       clk_hw_get_name(ccu_div_get_clk_hw(div)));
+static struct ccu_div *ccu_div_find_desc(struct ccu_div_data *data,
+                                        unsigned int clk_id)
+{
+       int idx;
+
+       for (idx = 0; idx < data->divs_num; ++idx) {
+               if (data->divs_info[idx].id == clk_id)
+                       return data->divs[idx];
        }
 
-       return ret;
+       return ERR_PTR(-EINVAL);
 }
 
-static const struct reset_control_ops ccu_div_rst_ops = {
-       .reset = ccu_div_reset,
-};
-
 static struct ccu_div_data *ccu_div_create_data(struct device_node *np)
 {
        struct ccu_div_data *data;
@@ -308,13 +280,9 @@ static struct ccu_div_data *ccu_div_create_data(struct device_node *np)
        if (of_device_is_compatible(np, "baikal,bt1-ccu-axi")) {
                data->divs_num = ARRAY_SIZE(axi_info);
                data->divs_info = axi_info;
-               data->rst_num = ARRAY_SIZE(axi_rst_map);
-               data->rst_map = axi_rst_map;
        } else if (of_device_is_compatible(np, "baikal,bt1-ccu-sys")) {
                data->divs_num = ARRAY_SIZE(sys_info);
                data->divs_info = sys_info;
-               data->rst_num = ARRAY_SIZE(sys_rst_map);
-               data->rst_map = sys_rst_map;
        } else {
                pr_err("Incompatible DT node '%s' specified\n",
                        of_node_full_name(np));
@@ -365,14 +333,16 @@ static struct clk_hw *ccu_div_of_clk_hw_get(struct of_phandle_args *clkspec,
        clk_id = clkspec->args[0];
        div = ccu_div_find_desc(data, clk_id);
        if (IS_ERR(div)) {
-               pr_info("Invalid clock ID %d specified\n", clk_id);
+               if (div != ERR_PTR(-EPROBE_DEFER))
+                       pr_info("Invalid clock ID %d specified\n", clk_id);
+
                return ERR_CAST(div);
        }
 
        return ccu_div_get_clk_hw(div);
 }
 
-static int ccu_div_clk_register(struct ccu_div_data *data)
+static int ccu_div_clk_register(struct ccu_div_data *data, bool defer)
 {
        int idx, ret;
 
@@ -380,6 +350,13 @@ static int ccu_div_clk_register(struct ccu_div_data *data)
                const struct ccu_div_info *info = &data->divs_info[idx];
                struct ccu_div_init_data init = {0};
 
+               if (!!(info->features & CCU_DIV_BASIC) ^ defer) {
+                       if (!data->divs[idx])
+                               data->divs[idx] = ERR_PTR(-EPROBE_DEFER);
+
+                       continue;
+               }
+
                init.id = info->id;
                init.name = info->name;
                init.parent_name = info->parent_name;
@@ -396,6 +373,9 @@ static int ccu_div_clk_register(struct ccu_div_data *data)
                        init.base = info->base;
                        init.sys_regs = data->sys_regs;
                        init.divider = info->divider;
+               } else if (init.type == CCU_DIV_BUF) {
+                       init.base = info->base;
+                       init.sys_regs = data->sys_regs;
                } else {
                        init.divider = info->divider;
                }
@@ -409,49 +389,104 @@ static int ccu_div_clk_register(struct ccu_div_data *data)
                }
        }
 
-       ret = of_clk_add_hw_provider(data->np, ccu_div_of_clk_hw_get, data);
-       if (ret) {
-               pr_err("Couldn't register dividers '%s' clock provider\n",
-                       of_node_full_name(data->np));
-               goto err_hw_unregister;
-       }
-
        return 0;
 
 err_hw_unregister:
-       for (--idx; idx >= 0; --idx)
+       for (--idx; idx >= 0; --idx) {
+               if (!!(data->divs_info[idx].features & CCU_DIV_BASIC) ^ defer)
+                       continue;
+
                ccu_div_hw_unregister(data->divs[idx]);
+       }
 
        return ret;
 }
 
-static void ccu_div_clk_unregister(struct ccu_div_data *data)
+static void ccu_div_clk_unregister(struct ccu_div_data *data, bool defer)
 {
        int idx;
 
-       of_clk_del_provider(data->np);
+       /* Uninstall only the clocks registered on the specfied stage */
+       for (idx = 0; idx < data->divs_num; ++idx) {
+               if (!!(data->divs_info[idx].features & CCU_DIV_BASIC) ^ defer)
+                       continue;
 
-       for (idx = 0; idx < data->divs_num; ++idx)
                ccu_div_hw_unregister(data->divs[idx]);
+       }
 }
 
-static int ccu_div_rst_register(struct ccu_div_data *data)
+static int ccu_div_of_register(struct ccu_div_data *data)
 {
        int ret;
 
-       data->rcdev.ops = &ccu_div_rst_ops;
-       data->rcdev.of_node = data->np;
-       data->rcdev.nr_resets = data->rst_num;
+       ret = of_clk_add_hw_provider(data->np, ccu_div_of_clk_hw_get, data);
+       if (ret) {
+               pr_err("Couldn't register dividers '%s' clock provider\n",
+                      of_node_full_name(data->np));
+       }
+
+       return ret;
+}
 
-       ret = reset_controller_register(&data->rcdev);
-       if (ret)
+static int ccu_div_rst_register(struct ccu_div_data *data)
+{
+       struct ccu_rst_init_data init = {0};
+
+       init.sys_regs = data->sys_regs;
+       init.np = data->np;
+
+       data->rsts = ccu_rst_hw_register(&init);
+       if (IS_ERR(data->rsts)) {
                pr_err("Couldn't register divider '%s' reset controller\n",
                        of_node_full_name(data->np));
+               return PTR_ERR(data->rsts);
+       }
+
+       return 0;
+}
+
+static int ccu_div_probe(struct platform_device *pdev)
+{
+       struct ccu_div_data *data;
+       int ret;
+
+       data = ccu_div_get_data(dev_of_node(&pdev->dev));
+       if (!data)
+               return -EINVAL;
+
+       ret = ccu_div_clk_register(data, false);
+       if (ret)
+               return ret;
+
+       ret = ccu_div_rst_register(data);
+       if (ret)
+               goto err_clk_unregister;
+
+       return 0;
+
+err_clk_unregister:
+       ccu_div_clk_unregister(data, false);
 
        return ret;
 }
 
-static void ccu_div_init(struct device_node *np)
+static const struct of_device_id ccu_div_of_match[] = {
+       { .compatible = "baikal,bt1-ccu-axi" },
+       { .compatible = "baikal,bt1-ccu-sys" },
+       { }
+};
+
+static struct platform_driver ccu_div_driver = {
+       .probe  = ccu_div_probe,
+       .driver = {
+               .name = "clk-ccu-div",
+               .of_match_table = ccu_div_of_match,
+               .suppress_bind_attrs = true,
+       },
+};
+builtin_platform_driver(ccu_div_driver);
+
+static __init void ccu_div_init(struct device_node *np)
 {
        struct ccu_div_data *data;
        int ret;
@@ -464,22 +499,23 @@ static void ccu_div_init(struct device_node *np)
        if (ret)
                goto err_free_data;
 
-       ret = ccu_div_clk_register(data);
+       ret = ccu_div_clk_register(data, true);
        if (ret)
                goto err_free_data;
 
-       ret = ccu_div_rst_register(data);
+       ret = ccu_div_of_register(data);
        if (ret)
                goto err_clk_unregister;
 
+       ccu_div_set_data(data);
+
        return;
 
 err_clk_unregister:
-       ccu_div_clk_unregister(data);
+       ccu_div_clk_unregister(data, true);
 
 err_free_data:
        ccu_div_free_data(data);
 }
-
-CLK_OF_DECLARE(ccu_axi, "baikal,bt1-ccu-axi", ccu_div_init);
-CLK_OF_DECLARE(ccu_sys, "baikal,bt1-ccu-sys", ccu_div_init);
+CLK_OF_DECLARE_DRIVER(ccu_axi, "baikal,bt1-ccu-axi", ccu_div_init);
+CLK_OF_DECLARE_DRIVER(ccu_sys, "baikal,bt1-ccu-sys", ccu_div_init);
index 2445d4b..fce02ce 100644 (file)
@@ -12,6 +12,7 @@
 #define pr_fmt(fmt) "bt1-ccu-pll: " fmt
 
 #include <linux/kernel.h>
+#include <linux/platform_device.h>
 #include <linux/printk.h>
 #include <linux/slab.h>
 #include <linux/clk-provider.h>
 #define CCU_PCIE_PLL_BASE              0x018
 #define CCU_ETH_PLL_BASE               0x020
 
-#define CCU_PLL_INFO(_id, _name, _pname, _base, _flags)        \
-       {                                               \
-               .id = _id,                              \
-               .name = _name,                          \
-               .parent_name = _pname,                  \
-               .base = _base,                          \
-               .flags = _flags                         \
+#define CCU_PLL_INFO(_id, _name, _pname, _base, _flags, _features)     \
+       {                                                               \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .parent_name = _pname,                                  \
+               .base = _base,                                          \
+               .flags = _flags,                                        \
+               .features = _features,                                  \
        }
 
 #define CCU_PLL_NUM                    ARRAY_SIZE(pll_info)
@@ -48,6 +50,7 @@ struct ccu_pll_info {
        const char *parent_name;
        unsigned int base;
        unsigned long flags;
+       unsigned long features;
 };
 
 /*
@@ -61,15 +64,15 @@ struct ccu_pll_info {
  */
 static const struct ccu_pll_info pll_info[] = {
        CCU_PLL_INFO(CCU_CPU_PLL, "cpu_pll", "ref_clk", CCU_CPU_PLL_BASE,
-                    CLK_IS_CRITICAL),
+                    CLK_IS_CRITICAL, CCU_PLL_BASIC),
        CCU_PLL_INFO(CCU_SATA_PLL, "sata_pll", "ref_clk", CCU_SATA_PLL_BASE,
-                    CLK_IS_CRITICAL | CLK_SET_RATE_GATE),
+                    CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 0),
        CCU_PLL_INFO(CCU_DDR_PLL, "ddr_pll", "ref_clk", CCU_DDR_PLL_BASE,
-                    CLK_IS_CRITICAL | CLK_SET_RATE_GATE),
+                    CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 0),
        CCU_PLL_INFO(CCU_PCIE_PLL, "pcie_pll", "ref_clk", CCU_PCIE_PLL_BASE,
-                    CLK_IS_CRITICAL),
+                    CLK_IS_CRITICAL, CCU_PLL_BASIC),
        CCU_PLL_INFO(CCU_ETH_PLL, "eth_pll", "ref_clk", CCU_ETH_PLL_BASE,
-                    CLK_IS_CRITICAL | CLK_SET_RATE_GATE)
+                    CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 0)
 };
 
 struct ccu_pll_data {
@@ -78,16 +81,16 @@ struct ccu_pll_data {
        struct ccu_pll *plls[CCU_PLL_NUM];
 };
 
+static struct ccu_pll_data *pll_data;
+
 static struct ccu_pll *ccu_pll_find_desc(struct ccu_pll_data *data,
                                         unsigned int clk_id)
 {
-       struct ccu_pll *pll;
        int idx;
 
        for (idx = 0; idx < CCU_PLL_NUM; ++idx) {
-               pll = data->plls[idx];
-               if (pll && pll->id == clk_id)
-                       return pll;
+               if (pll_info[idx].id == clk_id)
+                       return data->plls[idx];
        }
 
        return ERR_PTR(-EINVAL);
@@ -133,14 +136,16 @@ static struct clk_hw *ccu_pll_of_clk_hw_get(struct of_phandle_args *clkspec,
        clk_id = clkspec->args[0];
        pll = ccu_pll_find_desc(data, clk_id);
        if (IS_ERR(pll)) {
-               pr_info("Invalid PLL clock ID %d specified\n", clk_id);
+               if (pll != ERR_PTR(-EPROBE_DEFER))
+                       pr_info("Invalid PLL clock ID %d specified\n", clk_id);
+
                return ERR_CAST(pll);
        }
 
        return ccu_pll_get_clk_hw(pll);
 }
 
-static int ccu_pll_clk_register(struct ccu_pll_data *data)
+static int ccu_pll_clk_register(struct ccu_pll_data *data, bool defer)
 {
        int idx, ret;
 
@@ -148,6 +153,14 @@ static int ccu_pll_clk_register(struct ccu_pll_data *data)
                const struct ccu_pll_info *info = &pll_info[idx];
                struct ccu_pll_init_data init = {0};
 
+               /* Defer non-basic PLLs allocation for the probe stage */
+               if (!!(info->features & CCU_PLL_BASIC) ^ defer) {
+                       if (!data->plls[idx])
+                               data->plls[idx] = ERR_PTR(-EPROBE_DEFER);
+
+                       continue;
+               }
+
                init.id = info->id;
                init.name = info->name;
                init.parent_name = info->parent_name;
@@ -155,6 +168,7 @@ static int ccu_pll_clk_register(struct ccu_pll_data *data)
                init.sys_regs = data->sys_regs;
                init.np = data->np;
                init.flags = info->flags;
+               init.features = info->features;
 
                data->plls[idx] = ccu_pll_hw_register(&init);
                if (IS_ERR(data->plls[idx])) {
@@ -165,22 +179,70 @@ static int ccu_pll_clk_register(struct ccu_pll_data *data)
                }
        }
 
+       return 0;
+
+err_hw_unregister:
+       for (--idx; idx >= 0; --idx) {
+               if (!!(pll_info[idx].features & CCU_PLL_BASIC) ^ defer)
+                       continue;
+
+               ccu_pll_hw_unregister(data->plls[idx]);
+       }
+
+       return ret;
+}
+
+static void ccu_pll_clk_unregister(struct ccu_pll_data *data, bool defer)
+{
+       int idx;
+
+       /* Uninstall only the clocks registered on the specfied stage */
+       for (idx = 0; idx < CCU_PLL_NUM; ++idx) {
+               if (!!(pll_info[idx].features & CCU_PLL_BASIC) ^ defer)
+                       continue;
+
+               ccu_pll_hw_unregister(data->plls[idx]);
+       }
+}
+
+static int ccu_pll_of_register(struct ccu_pll_data *data)
+{
+       int ret;
+
        ret = of_clk_add_hw_provider(data->np, ccu_pll_of_clk_hw_get, data);
        if (ret) {
                pr_err("Couldn't register PLL provider of '%s'\n",
                        of_node_full_name(data->np));
-               goto err_hw_unregister;
        }
 
-       return 0;
+       return ret;
+}
 
-err_hw_unregister:
-       for (--idx; idx >= 0; --idx)
-               ccu_pll_hw_unregister(data->plls[idx]);
+static int ccu_pll_probe(struct platform_device *pdev)
+{
+       struct ccu_pll_data *data = pll_data;
 
-       return ret;
+       if (!data)
+               return -EINVAL;
+
+       return ccu_pll_clk_register(data, false);
 }
 
+static const struct of_device_id ccu_pll_of_match[] = {
+       { .compatible = "baikal,bt1-ccu-pll" },
+       { }
+};
+
+static struct platform_driver ccu_pll_driver = {
+       .probe  = ccu_pll_probe,
+       .driver = {
+               .name = "clk-ccu-pll",
+               .of_match_table = ccu_pll_of_match,
+               .suppress_bind_attrs = true,
+       },
+};
+builtin_platform_driver(ccu_pll_driver);
+
 static __init void ccu_pll_init(struct device_node *np)
 {
        struct ccu_pll_data *data;
@@ -194,13 +256,22 @@ static __init void ccu_pll_init(struct device_node *np)
        if (ret)
                goto err_free_data;
 
-       ret = ccu_pll_clk_register(data);
+       ret = ccu_pll_clk_register(data, true);
        if (ret)
                goto err_free_data;
 
+       ret = ccu_pll_of_register(data);
+       if (ret)
+               goto err_clk_unregister;
+
+       pll_data = data;
+
        return;
 
+err_clk_unregister:
+       ccu_pll_clk_unregister(data, true);
+
 err_free_data:
        ccu_pll_free_data(data);
 }
-CLK_OF_DECLARE(ccu_pll, "baikal,bt1-ccu-pll", ccu_pll_init);
+CLK_OF_DECLARE_DRIVER(ccu_pll, "baikal,bt1-ccu-pll", ccu_pll_init);
index bccdfa0..67a9edb 100644 (file)
@@ -500,12 +500,15 @@ static void __init berlin2_clock_setup(struct device_node *np)
        int n, ret;
 
        clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL);
-       if (!clk_data)
+       if (!clk_data) {
+               of_node_put(parent_np);
                return;
+       }
        clk_data->num = MAX_CLKS;
        hws = clk_data->hws;
 
        gbase = of_iomap(parent_np, 0);
+       of_node_put(parent_np);
        if (!gbase)
                return;
 
index e9518d3..dd2784b 100644 (file)
@@ -286,19 +286,23 @@ static void __init berlin2q_clock_setup(struct device_node *np)
        int n, ret;
 
        clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL);
-       if (!clk_data)
+       if (!clk_data) {
+               of_node_put(parent_np);
                return;
+       }
        clk_data->num = MAX_CLKS;
        hws = clk_data->hws;
 
        gbase = of_iomap(parent_np, 0);
        if (!gbase) {
+               of_node_put(parent_np);
                pr_err("%pOF: Unable to map global base\n", np);
                return;
        }
 
        /* BG2Q CPU PLL is not part of global registers */
        cpupll_base = of_iomap(parent_np, 1);
+       of_node_put(parent_np);
        if (!cpupll_base) {
                pr_err("%pOF: Unable to map cpupll base\n", np);
                iounmap(gbase);
index bacebd4..8b3c059 100644 (file)
@@ -80,7 +80,7 @@ struct asm9260_mux_clock {
        u8                      mask;
        u32                     *table;
        const char              *name;
-       const char              **parent_names;
+       const struct clk_parent_data *parent_data;
        u8                      num_parents;
        unsigned long           offset;
        unsigned long           flags;
@@ -232,10 +232,10 @@ static const struct asm9260_gate_data asm9260_ahb_gates[] __initconst = {
                HW_AHBCLKCTRL1, 16 },
 };
 
-static const char __initdata *main_mux_p[] =   { NULL, NULL };
-static const char __initdata *i2s0_mux_p[] =   { NULL, NULL, "i2s0m_div"};
-static const char __initdata *i2s1_mux_p[] =   { NULL, NULL, "i2s1m_div"};
-static const char __initdata *clkout_mux_p[] = { NULL, NULL, "rtc"};
+static struct clk_parent_data __initdata main_mux_p[] =   { { .index = 0, }, { .name = "pll" } };
+static struct clk_parent_data __initdata i2s0_mux_p[] =   { { .index = 0, }, { .name = "pll" }, { .name = "i2s0m_div"} };
+static struct clk_parent_data __initdata i2s1_mux_p[] =   { { .index = 0, }, { .name = "pll" }, { .name = "i2s1m_div"} };
+static struct clk_parent_data __initdata clkout_mux_p[] = { { .index = 0, }, { .name = "pll" }, { .name = "rtc"} };
 static u32 three_mux_table[] = {0, 1, 3};
 
 static struct asm9260_mux_clock asm9260_mux_clks[] __initdata = {
@@ -255,9 +255,10 @@ static struct asm9260_mux_clock asm9260_mux_clks[] __initdata = {
 
 static void __init asm9260_acc_init(struct device_node *np)
 {
-       struct clk_hw *hw;
+       struct clk_hw *hw, *pll_hw;
        struct clk_hw **hws;
-       const char *ref_clk, *pll_clk = "pll";
+       const char *pll_clk = "pll";
+       struct clk_parent_data pll_parent_data = { .index = 0 };
        u32 rate;
        int n;
 
@@ -274,21 +275,15 @@ static void __init asm9260_acc_init(struct device_node *np)
        /* register pll */
        rate = (ioread32(base + HW_SYSPLLCTRL) & 0xffff) * 1000000;
 
-       /* TODO: Convert to DT parent scheme */
-       ref_clk = of_clk_get_parent_name(np, 0);
-       hw = __clk_hw_register_fixed_rate(NULL, NULL, pll_clk,
-                       ref_clk, NULL, NULL, 0, rate, 0,
-                       CLK_FIXED_RATE_PARENT_ACCURACY);
-
-       if (IS_ERR(hw))
+       pll_hw = clk_hw_register_fixed_rate_parent_accuracy(NULL, pll_clk, &pll_parent_data,
+                                                       0, rate);
+       if (IS_ERR(pll_hw))
                panic("%pOFn: can't register REFCLK. Check DT!", np);
 
        for (n = 0; n < ARRAY_SIZE(asm9260_mux_clks); n++) {
                const struct asm9260_mux_clock *mc = &asm9260_mux_clks[n];
 
-               mc->parent_names[0] = ref_clk;
-               mc->parent_names[1] = pll_clk;
-               hw = clk_hw_register_mux_table(NULL, mc->name, mc->parent_names,
+               hw = clk_hw_register_mux_table_parent_data(NULL, mc->name, mc->parent_data,
                                mc->num_parents, mc->flags, base + mc->offset,
                                0, mc->mask, 0, mc->table, &asm9260_clk_lock);
        }
index 24dab23..9c3305b 100644 (file)
@@ -622,7 +622,7 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev)
        regmap_write(map, 0x308, 0x12000); /* 3x3 = 9 */
 
        /* P-Bus (BCLK) clock divider */
-       hw = clk_hw_register_divider_table(dev, "bclk", "hpll", 0,
+       hw = clk_hw_register_divider_table(dev, "bclk", "epll", 0,
                        scu_g6_base + ASPEED_G6_CLK_SELECTION1, 20, 3, 0,
                        ast2600_div_table,
                        &aspeed_g6_clk_lock);
index ac68a6b..7d77595 100644 (file)
@@ -49,12 +49,24 @@ const struct clk_ops clk_fixed_rate_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
 
+static void devm_clk_hw_register_fixed_rate_release(struct device *dev, void *res)
+{
+       struct clk_fixed_rate *fix = res;
+
+       /*
+        * We can not use clk_hw_unregister_fixed_rate, since it will kfree()
+        * the hw, resulting in double free. Just unregister the hw and let
+        * devres code kfree() it.
+        */
+       clk_hw_unregister(&fix->hw);
+}
+
 struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev,
                struct device_node *np, const char *name,
                const char *parent_name, const struct clk_hw *parent_hw,
                const struct clk_parent_data *parent_data, unsigned long flags,
                unsigned long fixed_rate, unsigned long fixed_accuracy,
-               unsigned long clk_fixed_flags)
+               unsigned long clk_fixed_flags, bool devm)
 {
        struct clk_fixed_rate *fixed;
        struct clk_hw *hw;
@@ -62,7 +74,11 @@ struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev,
        int ret = -EINVAL;
 
        /* allocate fixed-rate clock */
-       fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
+       if (devm)
+               fixed = devres_alloc(devm_clk_hw_register_fixed_rate_release,
+                                    sizeof(*fixed), GFP_KERNEL);
+       else
+               fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
        if (!fixed)
                return ERR_PTR(-ENOMEM);
 
@@ -90,9 +106,13 @@ struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev,
        else
                ret = of_clk_hw_register(np, hw);
        if (ret) {
-               kfree(fixed);
+               if (devm)
+                       devres_free(fixed);
+               else
+                       kfree(fixed);
                hw = ERR_PTR(ret);
-       }
+       } else if (devm)
+               devres_add(dev, fixed);
 
        return hw;
 }
index 81cb909..460e721 100644 (file)
@@ -286,7 +286,7 @@ static struct platform_driver lan966x_clk_driver = {
                .of_match_table = lan966x_clk_dt_ids,
        },
 };
-builtin_platform_driver(lan966x_clk_driver);
+module_platform_driver(lan966x_clk_driver);
 
 MODULE_AUTHOR("Kavyasree Kotagiri <kavyasree.kotagiri@microchip.com>");
 MODULE_DESCRIPTION("LAN966X clock driver");
index 565bcd0..80944bf 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/mfd/lochnagar1_regs.h>
 #include <linux/mfd/lochnagar2_regs.h>
 
-#include <dt-bindings/clk/lochnagar.h>
+#include <dt-bindings/clock/lochnagar.h>
 
 #define LOCHNAGAR_NUM_CLOCKS   (LOCHNAGAR_SPDIF_CLKOUT + 1)
 
index bad2677..71fbe68 100644 (file)
@@ -99,7 +99,7 @@ static void __init nomadik_src_init(void)
        if (!src_base) {
                pr_err("%s: must have src parent node with REGS (%pOFn)\n",
                       __func__, np);
-               return;
+               goto out_put;
        }
 
        /* Set all timers to use the 2.4 MHz TIMCLK */
@@ -132,6 +132,9 @@ static void __init nomadik_src_init(void)
        }
        writel(val, src_base + SRC_XTALCR);
        register_reboot_notifier(&nomadik_clk_reboot_notifier);
+
+out_put:
+       of_node_put(np);
 }
 
 /**
index e677bb5..e319cfa 100644 (file)
@@ -129,20 +129,6 @@ npcm7xx_clk_register_pll(void __iomem *pllcon, const char *name,
 #define NPCM7XX_SECCNT          (0x68)
 #define NPCM7XX_CNTR25M         (0x6C)
 
-struct npcm7xx_clk_gate_data {
-       u32 reg;
-       u8 bit_idx;
-       const char *name;
-       const char *parent_name;
-       unsigned long flags;
-       /*
-        * If this clock is exported via DT, set onecell_idx to constant
-        * defined in include/dt-bindings/clock/nuvoton, NPCM7XX-clock.h for
-        * this specific clock.  Otherwise, set to -1.
-        */
-       int onecell_idx;
-};
-
 struct npcm7xx_clk_mux_data {
        u8 shift;
        u8 mask;
@@ -160,21 +146,6 @@ struct npcm7xx_clk_mux_data {
 
 };
 
-struct npcm7xx_clk_div_fixed_data {
-       u8 mult;
-       u8 div;
-       const char *name;
-       const char *parent_name;
-       u8 clk_divider_flags;
-       /*
-        * If this clock is exported via DT, set onecell_idx to constant
-        * defined in include/dt-bindings/clock/nuvoton, NPCM7XX-clock.h for
-        * this specific clock.  Otherwise, set to -1.
-        */
-       int onecell_idx;
-};
-
-
 struct npcm7xx_clk_div_data {
        u32 reg;
        u8 shift;
index cda5e25..584e293 100644 (file)
@@ -207,7 +207,7 @@ static const struct of_device_id oxnas_stdclk_dt_ids[] = {
 
 static int oxnas_stdclk_probe(struct platform_device *pdev)
 {
-       struct device_node *np = pdev->dev.of_node;
+       struct device_node *np = pdev->dev.of_node, *parent_np;
        const struct oxnas_stdclk_data *data;
        struct regmap *regmap;
        int ret;
@@ -215,7 +215,9 @@ static int oxnas_stdclk_probe(struct platform_device *pdev)
 
        data = of_device_get_match_data(&pdev->dev);
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       regmap = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(regmap)) {
                dev_err(&pdev->dev, "failed to have parent regmap\n");
                return PTR_ERR(regmap);
index 88898b9..5eddb9f 100644 (file)
@@ -1063,8 +1063,13 @@ static void __init _clockgen_init(struct device_node *np, bool legacy);
  */
 static void __init legacy_init_clockgen(struct device_node *np)
 {
-       if (!clockgen.node)
-               _clockgen_init(of_get_parent(np), true);
+       if (!clockgen.node) {
+               struct device_node *parent_np;
+
+               parent_np = of_get_parent(np);
+               _clockgen_init(parent_np, true);
+               of_node_put(parent_np);
+       }
 }
 
 /* Legacy node */
@@ -1159,6 +1164,7 @@ static struct clk * __init create_sysclk(const char *name)
        sysclk = of_get_child_by_name(clockgen.node, "sysclk");
        if (sysclk) {
                clk = sysclk_from_fixed(sysclk, name);
+               of_node_put(sysclk);
                if (!IS_ERR(clk))
                        return clk;
        }
index e7be3e5..2cf3e57 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/regmap.h>
 #include <linux/slab.h>
 
-#include <dt-bindings/clk/versaclock.h>
+#include <dt-bindings/clock/versaclock.h>
 
 /* VersaClock5 registers */
 #define VC5_OTP_CONTROL                                0x00
@@ -153,6 +153,7 @@ enum vc5_model {
        IDT_VC5_5P49V5935,
        IDT_VC6_5P49V6901,
        IDT_VC6_5P49V6965,
+       IDT_VC6_5P49V6975,
 };
 
 /* Structure to describe features of a particular VC5 model */
@@ -230,8 +231,12 @@ static unsigned char vc5_mux_get_parent(struct clk_hw *hw)
                container_of(hw, struct vc5_driver_data, clk_mux);
        const u8 mask = VC5_PRIM_SRC_SHDN_EN_XTAL | VC5_PRIM_SRC_SHDN_EN_CLKIN;
        unsigned int src;
+       int ret;
+
+       ret = regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &src);
+       if (ret)
+               return 0;
 
-       regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &src);
        src &= mask;
 
        if (src == VC5_PRIM_SRC_SHDN_EN_XTAL)
@@ -286,8 +291,12 @@ static unsigned long vc5_dbl_recalc_rate(struct clk_hw *hw,
        struct vc5_driver_data *vc5 =
                container_of(hw, struct vc5_driver_data, clk_mul);
        unsigned int premul;
+       int ret;
+
+       ret = regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &premul);
+       if (ret)
+               return 0;
 
-       regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &premul);
        if (premul & VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ)
                parent_rate *= 2;
 
@@ -315,11 +324,9 @@ static int vc5_dbl_set_rate(struct clk_hw *hw, unsigned long rate,
        else
                mask = 0;
 
-       regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN,
-                          VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ,
-                          mask);
-
-       return 0;
+       return regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN,
+                                 VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ,
+                                 mask);
 }
 
 static const struct clk_ops vc5_dbl_ops = {
@@ -334,14 +341,19 @@ static unsigned long vc5_pfd_recalc_rate(struct clk_hw *hw,
        struct vc5_driver_data *vc5 =
                container_of(hw, struct vc5_driver_data, clk_pfd);
        unsigned int prediv, div;
+       int ret;
 
-       regmap_read(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV, &prediv);
+       ret = regmap_read(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV, &prediv);
+       if (ret)
+               return 0;
 
        /* The bypass_prediv is set, PLL fed from Ref_in directly. */
        if (prediv & VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV)
                return parent_rate;
 
-       regmap_read(vc5->regmap, VC5_REF_DIVIDER, &div);
+       ret = regmap_read(vc5->regmap, VC5_REF_DIVIDER, &div);
+       if (ret)
+               return 0;
 
        /* The Sel_prediv2 is set, PLL fed from prediv2 (Ref_in / 2) */
        if (div & VC5_REF_DIVIDER_SEL_PREDIV2)
@@ -376,15 +388,17 @@ static int vc5_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
        struct vc5_driver_data *vc5 =
                container_of(hw, struct vc5_driver_data, clk_pfd);
        unsigned long idiv;
+       int ret;
        u8 div;
 
        /* CLKIN within range of PLL input, feed directly to PLL. */
        if (parent_rate <= 50000000) {
-               regmap_update_bits(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV,
-                                  VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV,
-                                  VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV);
-               regmap_update_bits(vc5->regmap, VC5_REF_DIVIDER, 0xff, 0x00);
-               return 0;
+               ret = regmap_set_bits(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV,
+                                     VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV);
+               if (ret)
+                       return ret;
+
+               return regmap_update_bits(vc5->regmap, VC5_REF_DIVIDER, 0xff, 0x00);
        }
 
        idiv = DIV_ROUND_UP(parent_rate, rate);
@@ -395,11 +409,12 @@ static int vc5_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
        else
                div = VC5_REF_DIVIDER_REF_DIV(idiv);
 
-       regmap_update_bits(vc5->regmap, VC5_REF_DIVIDER, 0xff, div);
-       regmap_update_bits(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV,
-                          VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV, 0);
+       ret = regmap_update_bits(vc5->regmap, VC5_REF_DIVIDER, 0xff, div);
+       if (ret)
+               return ret;
 
-       return 0;
+       return regmap_clear_bits(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV,
+                                VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV);
 }
 
 static const struct clk_ops vc5_pfd_ops = {
@@ -551,9 +566,12 @@ static int vc5_fod_set_rate(struct clk_hw *hw, unsigned long rate,
                hwdata->div_int >> 4, hwdata->div_int << 4,
                0
        };
+       int ret;
 
-       regmap_bulk_write(vc5->regmap, VC5_OUT_DIV_FRAC(hwdata->num, 0),
-                         data, 14);
+       ret = regmap_bulk_write(vc5->regmap, VC5_OUT_DIV_FRAC(hwdata->num, 0),
+                               data, 14);
+       if (ret)
+               return ret;
 
        /*
         * Toggle magic bit in undocumented register for unknown reason.
@@ -561,12 +579,13 @@ static int vc5_fod_set_rate(struct clk_hw *hw, unsigned long rate,
         * datasheet somewhat implies this is needed, but the register
         * and the bit is not documented.
         */
-       regmap_update_bits(vc5->regmap, VC5_GLOBAL_REGISTER,
-                          VC5_GLOBAL_REGISTER_GLOBAL_RESET, 0);
-       regmap_update_bits(vc5->regmap, VC5_GLOBAL_REGISTER,
-                          VC5_GLOBAL_REGISTER_GLOBAL_RESET,
-                          VC5_GLOBAL_REGISTER_GLOBAL_RESET);
-       return 0;
+       ret = regmap_clear_bits(vc5->regmap, VC5_GLOBAL_REGISTER,
+                               VC5_GLOBAL_REGISTER_GLOBAL_RESET);
+       if (ret)
+               return ret;
+
+       return regmap_set_bits(vc5->regmap, VC5_GLOBAL_REGISTER,
+                              VC5_GLOBAL_REGISTER_GLOBAL_RESET);
 }
 
 static const struct clk_ops vc5_fod_ops = {
@@ -594,10 +613,9 @@ static int vc5_clk_out_prepare(struct clk_hw *hw)
         * registers.
         */
        if (vc5->chip_info->flags & VC5_HAS_BYPASS_SYNC_BIT) {
-               ret = regmap_update_bits(vc5->regmap,
-                                        VC5_RESERVED_X0(hwdata->num),
-                                        VC5_RESERVED_X0_BYPASS_SYNC,
-                                        VC5_RESERVED_X0_BYPASS_SYNC);
+               ret = regmap_set_bits(vc5->regmap,
+                                     VC5_RESERVED_X0(hwdata->num),
+                                     VC5_RESERVED_X0_BYPASS_SYNC);
                if (ret)
                        return ret;
        }
@@ -606,7 +624,10 @@ static int vc5_clk_out_prepare(struct clk_hw *hw)
         * If the input mux is disabled, enable it first and
         * select source from matching FOD.
         */
-       regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
+       ret = regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
+       if (ret)
+               return ret;
+
        if ((src & mask) == 0) {
                src = VC5_OUT_DIV_CONTROL_RESET | VC5_OUT_DIV_CONTROL_EN_FOD;
                ret = regmap_update_bits(vc5->regmap,
@@ -617,18 +638,22 @@ static int vc5_clk_out_prepare(struct clk_hw *hw)
        }
 
        /* Enable the clock buffer */
-       regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
-                          VC5_CLK_OUTPUT_CFG1_EN_CLKBUF,
-                          VC5_CLK_OUTPUT_CFG1_EN_CLKBUF);
+       ret = regmap_set_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
+                             VC5_CLK_OUTPUT_CFG1_EN_CLKBUF);
+       if (ret)
+               return ret;
+
        if (hwdata->clk_output_cfg0_mask) {
                dev_dbg(&vc5->client->dev, "Update output %d mask 0x%0X val 0x%0X\n",
                        hwdata->num, hwdata->clk_output_cfg0_mask,
                        hwdata->clk_output_cfg0);
 
-               regmap_update_bits(vc5->regmap,
-                       VC5_CLK_OUTPUT_CFG(hwdata->num, 0),
-                       hwdata->clk_output_cfg0_mask,
-                       hwdata->clk_output_cfg0);
+               ret = regmap_update_bits(vc5->regmap,
+                                        VC5_CLK_OUTPUT_CFG(hwdata->num, 0),
+                                        hwdata->clk_output_cfg0_mask,
+                                        hwdata->clk_output_cfg0);
+               if (ret)
+                       return ret;
        }
 
        return 0;
@@ -640,8 +665,8 @@ static void vc5_clk_out_unprepare(struct clk_hw *hw)
        struct vc5_driver_data *vc5 = hwdata->vc5;
 
        /* Disable the clock buffer */
-       regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
-                          VC5_CLK_OUTPUT_CFG1_EN_CLKBUF, 0);
+       regmap_clear_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
+                         VC5_CLK_OUTPUT_CFG1_EN_CLKBUF);
 }
 
 static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw)
@@ -656,8 +681,12 @@ static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw)
        const u8 extclk = VC5_OUT_DIV_CONTROL_SELB_NORM |
                          VC5_OUT_DIV_CONTROL_SEL_EXT;
        unsigned int src;
+       int ret;
+
+       ret = regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
+       if (ret)
+               return 0;
 
-       regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
        src &= mask;
 
        if (src == 0)   /* Input mux set to DISABLED */
@@ -725,6 +754,7 @@ static int vc5_map_index_to_output(const enum vc5_model model,
        case IDT_VC5_5P49V5935:
        case IDT_VC6_5P49V6901:
        case IDT_VC6_5P49V6965:
+       case IDT_VC6_5P49V6975:
        default:
                return n;
        }
@@ -819,22 +849,27 @@ static int vc5_update_cap_load(struct device_node *node, struct vc5_driver_data
 {
        u32 value;
        int mapped_value;
+       int ret;
 
-       if (!of_property_read_u32(node, "idt,xtal-load-femtofarads", &value)) {
-               mapped_value = vc5_map_cap_value(value);
-               if (mapped_value < 0)
-                       return mapped_value;
-
-               /*
-                * The mapped_value is really the high 6 bits of
-                * VC5_XTAL_X1_LOAD_CAP and VC5_XTAL_X2_LOAD_CAP, so
-                * shift the value 2 places.
-                */
-               regmap_update_bits(vc5->regmap, VC5_XTAL_X1_LOAD_CAP, ~0x03, mapped_value << 2);
-               regmap_update_bits(vc5->regmap, VC5_XTAL_X2_LOAD_CAP, ~0x03, mapped_value << 2);
-       }
+       if (of_property_read_u32(node, "idt,xtal-load-femtofarads", &value))
+               return 0;
 
-       return 0;
+       mapped_value = vc5_map_cap_value(value);
+       if (mapped_value < 0)
+               return mapped_value;
+
+       /*
+        * The mapped_value is really the high 6 bits of
+        * VC5_XTAL_X1_LOAD_CAP and VC5_XTAL_X2_LOAD_CAP, so
+        * shift the value 2 places.
+        */
+       ret = regmap_update_bits(vc5->regmap, VC5_XTAL_X1_LOAD_CAP, ~0x03,
+                                mapped_value << 2);
+       if (ret)
+               return ret;
+
+       return regmap_update_bits(vc5->regmap, VC5_XTAL_X2_LOAD_CAP, ~0x03,
+                                 mapped_value << 2);
 }
 
 static int vc5_update_slew(struct device_node *np_output,
@@ -956,7 +991,10 @@ static int vc5_probe(struct i2c_client *client)
                                     "could not read idt,output-enable-active\n");
        }
 
-       regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, src_mask, src_val);
+       ret = regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, src_mask,
+                                src_val);
+       if (ret)
+               return ret;
 
        /* Register clock input mux */
        memset(&init, 0, sizeof(init));
@@ -1204,7 +1242,7 @@ static const struct vc5_chip_info idt_5p49v6901_info = {
        .model = IDT_VC6_5P49V6901,
        .clk_fod_cnt = 4,
        .clk_out_cnt = 5,
-       .flags = VC5_HAS_PFD_FREQ_DBL,
+       .flags = VC5_HAS_PFD_FREQ_DBL | VC5_HAS_BYPASS_SYNC_BIT,
 };
 
 static const struct vc5_chip_info idt_5p49v6965_info = {
@@ -1214,6 +1252,13 @@ static const struct vc5_chip_info idt_5p49v6965_info = {
        .flags = VC5_HAS_BYPASS_SYNC_BIT,
 };
 
+static const struct vc5_chip_info idt_5p49v6975_info = {
+       .model = IDT_VC6_5P49V6975,
+       .clk_fod_cnt = 4,
+       .clk_out_cnt = 5,
+       .flags = VC5_HAS_BYPASS_SYNC_BIT | VC5_HAS_INTERNAL_XTAL,
+};
+
 static const struct i2c_device_id vc5_id[] = {
        { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 },
        { "5p49v5925", .driver_data = IDT_VC5_5P49V5925 },
@@ -1221,6 +1266,7 @@ static const struct i2c_device_id vc5_id[] = {
        { "5p49v5935", .driver_data = IDT_VC5_5P49V5935 },
        { "5p49v6901", .driver_data = IDT_VC6_5P49V6901 },
        { "5p49v6965", .driver_data = IDT_VC6_5P49V6965 },
+       { "5p49v6975", .driver_data = IDT_VC6_5P49V6975 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, vc5_id);
@@ -1232,6 +1278,7 @@ static const struct of_device_id clk_vc5_of_match[] = {
        { .compatible = "idt,5p49v5935", .data = &idt_5p49v5935_info },
        { .compatible = "idt,5p49v6901", .data = &idt_5p49v6901_info },
        { .compatible = "idt,5p49v6965", .data = &idt_5p49v6965_info },
+       { .compatible = "idt,5p49v6975", .data = &idt_5p49v6975_info },
        { },
 };
 MODULE_DEVICE_TABLE(of, clk_vc5_of_match);
diff --git a/drivers/clk/clk-versaclock7.c b/drivers/clk/clk-versaclock7.c
new file mode 100644 (file)
index 0000000..050807c
--- /dev/null
@@ -0,0 +1,1311 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Common clock framework driver for the Versaclock7 family of timing devices.
+ *
+ * Copyright (c) 2022 Renesas Electronics Corporation
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/i2c.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/swab.h>
+
+/*
+ * 16-bit register address: the lower 8 bits of the register address come
+ * from the offset addr byte and the upper 8 bits come from the page register.
+ */
+#define VC7_PAGE_ADDR                  0xFD
+#define VC7_PAGE_WINDOW                        256
+#define VC7_MAX_REG                    0x364
+
+/* Maximum number of banks supported by VC7 */
+#define VC7_NUM_BANKS                  7
+
+/* Maximum number of FODs supported by VC7 */
+#define VC7_NUM_FOD                    3
+
+/* Maximum number of IODs supported by VC7 */
+#define VC7_NUM_IOD                    4
+
+/* Maximum number of outputs supported by VC7 */
+#define VC7_NUM_OUT                    12
+
+/* VCO valid range is 9.5 GHz to 10.7 GHz */
+#define VC7_APLL_VCO_MIN               9500000000UL
+#define VC7_APLL_VCO_MAX               10700000000UL
+
+/* APLL denominator is fixed at 2^27 */
+#define VC7_APLL_DENOMINATOR_BITS      27
+
+/* FOD 1st stage denominator is fixed 2^34 */
+#define VC7_FOD_DENOMINATOR_BITS       34
+
+/* IOD can operate between 1kHz and 650MHz */
+#define VC7_IOD_RATE_MIN               1000UL
+#define VC7_IOD_RATE_MAX               650000000UL
+#define VC7_IOD_MIN_DIVISOR            14
+#define VC7_IOD_MAX_DIVISOR            0x1ffffff /* 25-bit */
+
+#define VC7_FOD_RATE_MIN               1000UL
+#define VC7_FOD_RATE_MAX               650000000UL
+#define VC7_FOD_1ST_STAGE_RATE_MIN     33000000UL /* 33 MHz */
+#define VC7_FOD_1ST_STAGE_RATE_MAX     650000000UL /* 650 MHz */
+#define VC7_FOD_1ST_INT_MAX            324
+#define VC7_FOD_2ND_INT_MIN            2
+#define VC7_FOD_2ND_INT_MAX            0x1ffff /* 17-bit */
+
+/* VC7 Registers */
+
+#define VC7_REG_XO_CNFG                        0x2C
+#define VC7_REG_XO_CNFG_COUNT          4
+#define VC7_REG_XO_IB_H_DIV_SHIFT      24
+#define VC7_REG_XO_IB_H_DIV_MASK       GENMASK(28, VC7_REG_XO_IB_H_DIV_SHIFT)
+
+#define VC7_REG_APLL_FB_DIV_FRAC       0x120
+#define VC7_REG_APLL_FB_DIV_FRAC_COUNT 4
+#define VC7_REG_APLL_FB_DIV_FRAC_MASK  GENMASK(26, 0)
+
+#define VC7_REG_APLL_FB_DIV_INT                0x124
+#define VC7_REG_APLL_FB_DIV_INT_COUNT  2
+#define VC7_REG_APLL_FB_DIV_INT_MASK   GENMASK(9, 0)
+
+#define VC7_REG_APLL_CNFG              0x127
+#define VC7_REG_APLL_EN_DOUBLER                BIT(0)
+
+#define VC7_REG_OUT_BANK_CNFG(idx)     (0x280 + (0x4 * (idx)))
+#define VC7_REG_OUTPUT_BANK_SRC_MASK   GENMASK(2, 0)
+
+#define VC7_REG_FOD_INT_CNFG(idx)      (0x1E0 + (0x10 * (idx)))
+#define VC7_REG_FOD_INT_CNFG_COUNT     8
+#define VC7_REG_FOD_1ST_INT_MASK       GENMASK(8, 0)
+#define VC7_REG_FOD_2ND_INT_SHIFT      9
+#define VC7_REG_FOD_2ND_INT_MASK       GENMASK(25, VC7_REG_FOD_2ND_INT_SHIFT)
+#define VC7_REG_FOD_FRAC_SHIFT         26
+#define VC7_REG_FOD_FRAC_MASK          GENMASK_ULL(59, VC7_REG_FOD_FRAC_SHIFT)
+
+#define VC7_REG_IOD_INT_CNFG(idx)      (0x1C0 + (0x8 * (idx)))
+#define VC7_REG_IOD_INT_CNFG_COUNT     4
+#define VC7_REG_IOD_INT_MASK           GENMASK(24, 0)
+
+#define VC7_REG_ODRV_EN(idx)           (0x240 + (0x4 * (idx)))
+#define VC7_REG_OUT_DIS                        BIT(0)
+
+struct vc7_driver_data;
+static const struct regmap_config vc7_regmap_config;
+
+/* Supported Renesas VC7 models */
+enum vc7_model {
+       VC7_RC21008A,
+};
+
+struct vc7_chip_info {
+       const enum vc7_model model;
+       const unsigned int banks[VC7_NUM_BANKS];
+       const unsigned int num_banks;
+       const unsigned int outputs[VC7_NUM_OUT];
+       const unsigned int num_outputs;
+};
+
+/*
+ * Changing the APLL frequency is currently not supported.
+ * The APLL will consist of an opaque block between the XO and FOD/IODs and
+ * its frequency will be computed based on the current state of the device.
+ */
+struct vc7_apll_data {
+       struct clk *clk;
+       struct vc7_driver_data *vc7;
+       u8 xo_ib_h_div;
+       u8 en_doubler;
+       u16 apll_fb_div_int;
+       u32 apll_fb_div_frac;
+};
+
+struct vc7_fod_data {
+       struct clk_hw hw;
+       struct vc7_driver_data *vc7;
+       unsigned int num;
+       u32 fod_1st_int;
+       u32 fod_2nd_int;
+       u64 fod_frac;
+};
+
+struct vc7_iod_data {
+       struct clk_hw hw;
+       struct vc7_driver_data *vc7;
+       unsigned int num;
+       u32 iod_int;
+};
+
+struct vc7_out_data {
+       struct clk_hw hw;
+       struct vc7_driver_data *vc7;
+       unsigned int num;
+       unsigned int out_dis;
+};
+
+struct vc7_driver_data {
+       struct i2c_client *client;
+       struct regmap *regmap;
+       const struct vc7_chip_info *chip_info;
+
+       struct clk *pin_xin;
+       struct vc7_apll_data clk_apll;
+       struct vc7_fod_data clk_fod[VC7_NUM_FOD];
+       struct vc7_iod_data clk_iod[VC7_NUM_IOD];
+       struct vc7_out_data clk_out[VC7_NUM_OUT];
+};
+
+struct vc7_bank_src_map {
+       enum vc7_bank_src_type {
+               VC7_FOD,
+               VC7_IOD,
+       } type;
+       union _divider {
+               struct vc7_iod_data *iod;
+               struct vc7_fod_data *fod;
+       } src;
+};
+
+static struct clk_hw *vc7_of_clk_get(struct of_phandle_args *clkspec,
+                                    void *data)
+{
+       struct vc7_driver_data *vc7 = data;
+       unsigned int idx = clkspec->args[0];
+
+       if (idx >= vc7->chip_info->num_outputs)
+               return ERR_PTR(-EINVAL);
+
+       return &vc7->clk_out[idx].hw;
+}
+
+static const unsigned int RC21008A_index_to_output_mapping[] = {
+       1, 2, 3, 6, 7, 8, 10, 11
+};
+
+static int vc7_map_index_to_output(const enum vc7_model model, const unsigned int i)
+{
+       switch (model) {
+       case VC7_RC21008A:
+               return RC21008A_index_to_output_mapping[i];
+       default:
+               return i;
+       }
+}
+
+/* bank to output mapping, same across all variants */
+static const unsigned int output_bank_mapping[] = {
+       0, /* Output 0 */
+       1, /* Output 1 */
+       2, /* Output 2 */
+       2, /* Output 3 */
+       3, /* Output 4 */
+       3, /* Output 5 */
+       3, /* Output 6 */
+       3, /* Output 7 */
+       4, /* Output 8 */
+       4, /* Output 9 */
+       5, /* Output 10 */
+       6  /* Output 11 */
+};
+
+/**
+ * vc7_64_mul_64_to_128() - Multiply two u64 and return an unsigned 128-bit integer
+ * as an upper and lower part.
+ *
+ * @left: The left argument.
+ * @right: The right argument.
+ * @hi: The upper 64-bits of the 128-bit product.
+ * @lo: The lower 64-bits of the 128-bit product.
+ *
+ * From mul_64_64 in crypto/ecc.c:350 in the linux kernel, accessed in v5.17.2.
+ */
+static void vc7_64_mul_64_to_128(u64 left, u64 right, u64 *hi, u64 *lo)
+{
+       u64 a0 = left & 0xffffffffull;
+       u64 a1 = left >> 32;
+       u64 b0 = right & 0xffffffffull;
+       u64 b1 = right >> 32;
+       u64 m0 = a0 * b0;
+       u64 m1 = a0 * b1;
+       u64 m2 = a1 * b0;
+       u64 m3 = a1 * b1;
+
+       m2 += (m0 >> 32);
+       m2 += m1;
+
+       /* Overflow */
+       if (m2 < m1)
+               m3 += 0x100000000ull;
+
+       *lo = (m0 & 0xffffffffull) | (m2 << 32);
+       *hi = m3 + (m2 >> 32);
+}
+
+/**
+ * vc7_128_div_64_to_64() - Divides a 128-bit uint by a 64-bit divisor, return a 64-bit quotient.
+ *
+ * @numhi: The uppper 64-bits of the dividend.
+ * @numlo: The lower 64-bits of the dividend.
+ * @den: The denominator (divisor).
+ * @r: The remainder, pass NULL if the remainder is not needed.
+ *
+ * Originally from libdivide, modified to use kernel u64/u32 types.
+ *
+ * See https://github.com/ridiculousfish/libdivide/blob/master/libdivide.h#L471.
+ *
+ * Return: The 64-bit quotient of the division.
+ *
+ * In case of overflow of division by zero, max(u64) is returned.
+ */
+static u64 vc7_128_div_64_to_64(u64 numhi, u64 numlo, u64 den, u64 *r)
+{
+       /*
+        * We work in base 2**32.
+        * A uint32 holds a single digit. A uint64 holds two digits.
+        * Our numerator is conceptually [num3, num2, num1, num0].
+        * Our denominator is [den1, den0].
+        */
+       const u64 b = ((u64)1 << 32);
+
+       /* The high and low digits of our computed quotient. */
+       u32 q1, q0;
+
+       /* The normalization shift factor */
+       int shift;
+
+       /*
+        * The high and low digits of our denominator (after normalizing).
+        * Also the low 2 digits of our numerator (after normalizing).
+        */
+       u32 den1, den0, num1, num0;
+
+       /* A partial remainder; */
+       u64 rem;
+
+       /*
+        * The estimated quotient, and its corresponding remainder (unrelated
+        * to true remainder).
+        */
+       u64 qhat, rhat;
+
+       /* Variables used to correct the estimated quotient. */
+       u64 c1, c2;
+
+       /* Check for overflow and divide by 0. */
+       if (numhi >= den) {
+               if (r)
+                       *r = ~0ull;
+               return ~0ull;
+       }
+
+       /*
+        * Determine the normalization factor. We multiply den by this, so that
+        * its leading digit is at least half b. In binary this means just
+        * shifting left by the number of leading zeros, so that there's a 1 in
+        * the MSB.
+        *
+        * We also shift numer by the same amount. This cannot overflow because
+        * numhi < den.  The expression (-shift & 63) is the same as (64 -
+        * shift), except it avoids the UB of shifting by 64. The funny bitwise
+        * 'and' ensures that numlo does not get shifted into numhi if shift is
+        * 0. clang 11 has an x86 codegen bug here: see LLVM bug 50118. The
+        * sequence below avoids it.
+        */
+       shift = __builtin_clzll(den);
+       den <<= shift;
+       numhi <<= shift;
+       numhi |= (numlo >> (-shift & 63)) & (-(s64)shift >> 63);
+       numlo <<= shift;
+
+       /*
+        * Extract the low digits of the numerator and both digits of the
+        * denominator.
+        */
+       num1 = (u32)(numlo >> 32);
+       num0 = (u32)(numlo & 0xFFFFFFFFu);
+       den1 = (u32)(den >> 32);
+       den0 = (u32)(den & 0xFFFFFFFFu);
+
+       /*
+        * We wish to compute q1 = [n3 n2 n1] / [d1 d0].
+        * Estimate q1 as [n3 n2] / [d1], and then correct it.
+        * Note while qhat may be 2 digits, q1 is always 1 digit.
+        */
+       qhat = div64_u64_rem(numhi, den1, &rhat);
+       c1 = qhat * den0;
+       c2 = rhat * b + num1;
+       if (c1 > c2)
+               qhat -= (c1 - c2 > den) ? 2 : 1;
+       q1 = (u32)qhat;
+
+       /* Compute the true (partial) remainder. */
+       rem = numhi * b + num1 - q1 * den;
+
+       /*
+        * We wish to compute q0 = [rem1 rem0 n0] / [d1 d0].
+        * Estimate q0 as [rem1 rem0] / [d1] and correct it.
+        */
+       qhat = div64_u64_rem(rem, den1, &rhat);
+       c1 = qhat * den0;
+       c2 = rhat * b + num0;
+       if (c1 > c2)
+               qhat -= (c1 - c2 > den) ? 2 : 1;
+       q0 = (u32)qhat;
+
+       /* Return remainder if requested. */
+       if (r)
+               *r = (rem * b + num0 - q0 * den) >> shift;
+       return ((u64)q1 << 32) | q0;
+}
+
+static int vc7_get_bank_clk(struct vc7_driver_data *vc7,
+                           unsigned int bank_idx,
+                           unsigned int output_bank_src,
+                           struct vc7_bank_src_map *map)
+{
+       /* Mapping from Table 38 in datasheet */
+       if (bank_idx == 0 || bank_idx == 1) {
+               switch (output_bank_src) {
+               case 0:
+                       map->type = VC7_IOD,
+                       map->src.iod = &vc7->clk_iod[0];
+                       return 0;
+               case 1:
+                       map->type = VC7_IOD,
+                       map->src.iod = &vc7->clk_iod[1];
+                       return 0;
+               case 4:
+                       map->type = VC7_FOD,
+                       map->src.fod = &vc7->clk_fod[0];
+                       return 0;
+               case 5:
+                       map->type = VC7_FOD,
+                       map->src.fod = &vc7->clk_fod[1];
+                       return 0;
+               default:
+                       break;
+               }
+       } else if (bank_idx == 2) {
+               switch (output_bank_src) {
+               case 1:
+                       map->type = VC7_IOD,
+                       map->src.iod = &vc7->clk_iod[1];
+                       return 0;
+               case 4:
+                       map->type = VC7_FOD,
+                       map->src.fod = &vc7->clk_fod[0];
+                       return 0;
+               case 5:
+                       map->type = VC7_FOD,
+                       map->src.fod = &vc7->clk_fod[1];
+                       return 0;
+               default:
+                       break;
+               }
+       } else if (bank_idx == 3) {
+               switch (output_bank_src) {
+               case 4:
+                       map->type = VC7_FOD,
+                       map->src.fod = &vc7->clk_fod[0];
+                       return 0;
+               case 5:
+                       map->type = VC7_FOD,
+                       map->src.fod = &vc7->clk_fod[1];
+                       return 0;
+               case 6:
+                       map->type = VC7_FOD,
+                       map->src.fod = &vc7->clk_fod[2];
+                       return 0;
+               default:
+                       break;
+               }
+       } else if (bank_idx == 4) {
+               switch (output_bank_src) {
+               case 0:
+                       /* CLKIN1 not supported in this driver */
+                       break;
+               case 2:
+                       map->type = VC7_IOD,
+                       map->src.iod = &vc7->clk_iod[2];
+                       return 0;
+               case 5:
+                       map->type = VC7_FOD,
+                       map->src.fod = &vc7->clk_fod[1];
+                       return 0;
+               case 6:
+                       map->type = VC7_FOD,
+                       map->src.fod = &vc7->clk_fod[2];
+                       return 0;
+               case 7:
+                       /* CLKIN0 not supported in this driver */
+                       break;
+               default:
+                       break;
+               }
+       } else if (bank_idx == 5) {
+               switch (output_bank_src) {
+               case 0:
+                       /* CLKIN1 not supported in this driver */
+                       break;
+               case 1:
+                       /* XIN_REFIN not supported in this driver */
+                       break;
+               case 2:
+                       map->type = VC7_IOD,
+                       map->src.iod = &vc7->clk_iod[2];
+                       return 0;
+               case 3:
+                       map->type = VC7_IOD,
+                       map->src.iod = &vc7->clk_iod[3];
+                       return 0;
+               case 5:
+                       map->type = VC7_FOD,
+                       map->src.fod = &vc7->clk_fod[1];
+                       return 0;
+               case 6:
+                       map->type = VC7_FOD,
+                       map->src.fod = &vc7->clk_fod[2];
+                       return 0;
+               case 7:
+                       /* CLKIN0 not supported in this driver */
+                       break;
+               default:
+                       break;
+               }
+       } else if (bank_idx == 6) {
+               switch (output_bank_src) {
+               case 0:
+                       /* CLKIN1 not supported in this driver */
+                       break;
+               case 2:
+                       map->type = VC7_IOD,
+                       map->src.iod = &vc7->clk_iod[2];
+                       return 0;
+               case 3:
+                       map->type = VC7_IOD,
+                       map->src.iod = &vc7->clk_iod[3];
+                       return 0;
+               case 5:
+                       map->type = VC7_FOD,
+                       map->src.fod = &vc7->clk_fod[1];
+                       return 0;
+               case 6:
+                       map->type = VC7_FOD,
+                       map->src.fod = &vc7->clk_fod[2];
+                       return 0;
+               case 7:
+                       /* CLKIN0 not supported in this driver */
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       pr_warn("bank_src%d = %d is not supported\n", bank_idx, output_bank_src);
+       return -1;
+}
+
+static int vc7_read_apll(struct vc7_driver_data *vc7)
+{
+       int err;
+       u32 val32;
+       u16 val16;
+
+       err = regmap_bulk_read(vc7->regmap,
+                              VC7_REG_XO_CNFG,
+                              (u32 *)&val32,
+                              VC7_REG_XO_CNFG_COUNT);
+       if (err) {
+               dev_err(&vc7->client->dev, "failed to read XO_CNFG\n");
+               return err;
+       }
+
+       vc7->clk_apll.xo_ib_h_div = (val32 & VC7_REG_XO_IB_H_DIV_MASK)
+               >> VC7_REG_XO_IB_H_DIV_SHIFT;
+
+       err = regmap_read(vc7->regmap,
+                         VC7_REG_APLL_CNFG,
+                         &val32);
+       if (err) {
+               dev_err(&vc7->client->dev, "failed to read APLL_CNFG\n");
+               return err;
+       }
+
+       vc7->clk_apll.en_doubler = val32 & VC7_REG_APLL_EN_DOUBLER;
+
+       err = regmap_bulk_read(vc7->regmap,
+                              VC7_REG_APLL_FB_DIV_FRAC,
+                              (u32 *)&val32,
+                              VC7_REG_APLL_FB_DIV_FRAC_COUNT);
+       if (err) {
+               dev_err(&vc7->client->dev, "failed to read APLL_FB_DIV_FRAC\n");
+               return err;
+       }
+
+       vc7->clk_apll.apll_fb_div_frac = val32 & VC7_REG_APLL_FB_DIV_FRAC_MASK;
+
+       err = regmap_bulk_read(vc7->regmap,
+                              VC7_REG_APLL_FB_DIV_INT,
+                              (u16 *)&val16,
+                              VC7_REG_APLL_FB_DIV_INT_COUNT);
+       if (err) {
+               dev_err(&vc7->client->dev, "failed to read APLL_FB_DIV_INT\n");
+               return err;
+       }
+
+       vc7->clk_apll.apll_fb_div_int = val16 & VC7_REG_APLL_FB_DIV_INT_MASK;
+
+       return 0;
+}
+
+static int vc7_read_fod(struct vc7_driver_data *vc7, unsigned int idx)
+{
+       int err;
+       u64 val;
+
+       err = regmap_bulk_read(vc7->regmap,
+                              VC7_REG_FOD_INT_CNFG(idx),
+                              (u64 *)&val,
+                              VC7_REG_FOD_INT_CNFG_COUNT);
+       if (err) {
+               dev_err(&vc7->client->dev, "failed to read FOD%d\n", idx);
+               return err;
+       }
+
+       vc7->clk_fod[idx].fod_1st_int = (val & VC7_REG_FOD_1ST_INT_MASK);
+       vc7->clk_fod[idx].fod_2nd_int =
+           (val & VC7_REG_FOD_2ND_INT_MASK) >> VC7_REG_FOD_2ND_INT_SHIFT;
+       vc7->clk_fod[idx].fod_frac = (val & VC7_REG_FOD_FRAC_MASK)
+               >> VC7_REG_FOD_FRAC_SHIFT;
+
+       return 0;
+}
+
+static int vc7_write_fod(struct vc7_driver_data *vc7, unsigned int idx)
+{
+       int err;
+       u64 val;
+
+       /*
+        * FOD dividers are part of an atomic group where fod_1st_int,
+        * fod_2nd_int, and fod_frac must be written together. The new divider
+        * is applied when the MSB of fod_frac is written.
+        */
+
+       err = regmap_bulk_read(vc7->regmap,
+                              VC7_REG_FOD_INT_CNFG(idx),
+                              (u64 *)&val,
+                              VC7_REG_FOD_INT_CNFG_COUNT);
+       if (err) {
+               dev_err(&vc7->client->dev, "failed to read FOD%d\n", idx);
+               return err;
+       }
+
+       val = u64_replace_bits(val,
+                              vc7->clk_fod[idx].fod_1st_int,
+                              VC7_REG_FOD_1ST_INT_MASK);
+       val = u64_replace_bits(val,
+                              vc7->clk_fod[idx].fod_2nd_int,
+                              VC7_REG_FOD_2ND_INT_MASK);
+       val = u64_replace_bits(val,
+                              vc7->clk_fod[idx].fod_frac,
+                              VC7_REG_FOD_FRAC_MASK);
+
+       err = regmap_bulk_write(vc7->regmap,
+                               VC7_REG_FOD_INT_CNFG(idx),
+                               (u64 *)&val,
+                               sizeof(u64));
+       if (err) {
+               dev_err(&vc7->client->dev, "failed to write FOD%d\n", idx);
+               return err;
+       }
+
+       return 0;
+}
+
+static int vc7_read_iod(struct vc7_driver_data *vc7, unsigned int idx)
+{
+       int err;
+       u32 val;
+
+       err = regmap_bulk_read(vc7->regmap,
+                              VC7_REG_IOD_INT_CNFG(idx),
+                              (u32 *)&val,
+                              VC7_REG_IOD_INT_CNFG_COUNT);
+       if (err) {
+               dev_err(&vc7->client->dev, "failed to read IOD%d\n", idx);
+               return err;
+       }
+
+       vc7->clk_iod[idx].iod_int = (val & VC7_REG_IOD_INT_MASK);
+
+       return 0;
+}
+
+static int vc7_write_iod(struct vc7_driver_data *vc7, unsigned int idx)
+{
+       int err;
+       u32 val;
+
+       /*
+        * IOD divider field is atomic and all bits must be written.
+        * The new divider is applied when the MSB of iod_int is written.
+        */
+
+       err = regmap_bulk_read(vc7->regmap,
+                              VC7_REG_IOD_INT_CNFG(idx),
+                              (u32 *)&val,
+                              VC7_REG_IOD_INT_CNFG_COUNT);
+       if (err) {
+               dev_err(&vc7->client->dev, "failed to read IOD%d\n", idx);
+               return err;
+       }
+
+       val = u32_replace_bits(val,
+                              vc7->clk_iod[idx].iod_int,
+                              VC7_REG_IOD_INT_MASK);
+
+       err = regmap_bulk_write(vc7->regmap,
+                               VC7_REG_IOD_INT_CNFG(idx),
+                               (u32 *)&val,
+                               sizeof(u32));
+       if (err) {
+               dev_err(&vc7->client->dev, "failed to write IOD%d\n", idx);
+               return err;
+       }
+
+       return 0;
+}
+
+static int vc7_read_output(struct vc7_driver_data *vc7, unsigned int idx)
+{
+       int err;
+       unsigned int val, out_num;
+
+       out_num = vc7_map_index_to_output(vc7->chip_info->model, idx);
+       err = regmap_read(vc7->regmap,
+                         VC7_REG_ODRV_EN(out_num),
+                         &val);
+       if (err) {
+               dev_err(&vc7->client->dev, "failed to read ODRV_EN[%d]\n", idx);
+               return err;
+       }
+
+       vc7->clk_out[idx].out_dis = val & VC7_REG_OUT_DIS;
+
+       return 0;
+}
+
+static int vc7_write_output(struct vc7_driver_data *vc7, unsigned int idx)
+{
+       int err;
+       unsigned int out_num;
+
+       out_num = vc7_map_index_to_output(vc7->chip_info->model, idx);
+       err = regmap_write_bits(vc7->regmap,
+                               VC7_REG_ODRV_EN(out_num),
+                               VC7_REG_OUT_DIS,
+                               vc7->clk_out[idx].out_dis);
+
+       if (err) {
+               dev_err(&vc7->client->dev, "failed to write ODRV_EN[%d]\n", idx);
+               return err;
+       }
+
+       return 0;
+}
+
+static unsigned long vc7_get_apll_rate(struct vc7_driver_data *vc7)
+{
+       int err;
+       unsigned long xtal_rate;
+       u64 refin_div, apll_rate;
+
+       xtal_rate = clk_get_rate(vc7->pin_xin);
+       err = vc7_read_apll(vc7);
+       if (err) {
+               dev_err(&vc7->client->dev, "unable to read apll\n");
+               return err;
+       }
+
+       /* 0 is bypassed, 1 is reserved */
+       if (vc7->clk_apll.xo_ib_h_div < 2)
+               refin_div = xtal_rate;
+       else
+               refin_div = div64_u64(xtal_rate, vc7->clk_apll.xo_ib_h_div);
+
+       if (vc7->clk_apll.en_doubler)
+               refin_div *= 2;
+
+       /* divider = int + (frac / 2^27) */
+       apll_rate = (refin_div * vc7->clk_apll.apll_fb_div_int) +
+                   ((refin_div * vc7->clk_apll.apll_fb_div_frac) >> VC7_APLL_DENOMINATOR_BITS);
+
+       pr_debug("%s - xo_ib_h_div: %u, apll_fb_div_int: %u, apll_fb_div_frac: %u\n",
+                __func__, vc7->clk_apll.xo_ib_h_div, vc7->clk_apll.apll_fb_div_int,
+                vc7->clk_apll.apll_fb_div_frac);
+       pr_debug("%s - refin_div: %llu, apll rate: %llu\n",
+                __func__, refin_div, apll_rate);
+
+       return apll_rate;
+}
+
+static void vc7_calc_iod_divider(unsigned long rate, unsigned long parent_rate,
+                                u32 *divider)
+{
+       *divider = DIV_ROUND_UP(parent_rate, rate);
+       if (*divider < VC7_IOD_MIN_DIVISOR)
+               *divider = VC7_IOD_MIN_DIVISOR;
+       if (*divider > VC7_IOD_MAX_DIVISOR)
+               *divider = VC7_IOD_MAX_DIVISOR;
+}
+
+static void vc7_calc_fod_1st_stage(unsigned long rate, unsigned long parent_rate,
+                                  u32 *div_int, u64 *div_frac)
+{
+       u64 rem;
+
+       *div_int = (u32)div64_u64_rem(parent_rate, rate, &rem);
+       *div_frac = div64_u64(rem << VC7_FOD_DENOMINATOR_BITS, rate);
+}
+
+static unsigned long vc7_calc_fod_1st_stage_rate(unsigned long parent_rate,
+                                                u32 fod_1st_int, u64 fod_frac)
+{
+       u64 numer, denom, hi, lo, divisor;
+
+       numer = fod_frac;
+       denom = BIT_ULL(VC7_FOD_DENOMINATOR_BITS);
+
+       if (fod_frac) {
+               vc7_64_mul_64_to_128(parent_rate, denom, &hi, &lo);
+               divisor = ((u64)fod_1st_int * denom) + numer;
+               return vc7_128_div_64_to_64(hi, lo, divisor, NULL);
+       }
+
+       return div64_u64(parent_rate, fod_1st_int);
+}
+
+static unsigned long vc7_calc_fod_2nd_stage_rate(unsigned long parent_rate,
+                                                u32 fod_1st_int, u32 fod_2nd_int, u64 fod_frac)
+{
+       unsigned long fod_1st_stage_rate;
+
+       fod_1st_stage_rate = vc7_calc_fod_1st_stage_rate(parent_rate, fod_1st_int, fod_frac);
+
+       if (fod_2nd_int < 2)
+               return fod_1st_stage_rate;
+
+       /*
+        * There is a div-by-2 preceding the 2nd stage integer divider
+        * (not shown on block diagram) so the actual 2nd stage integer
+        * divisor is 2 * N.
+        */
+       return div64_u64(fod_1st_stage_rate >> 1, fod_2nd_int);
+}
+
+static void vc7_calc_fod_divider(unsigned long rate, unsigned long parent_rate,
+                                u32 *fod_1st_int, u32 *fod_2nd_int, u64 *fod_frac)
+{
+       unsigned int allow_frac, i, best_frac_i;
+       unsigned long first_stage_rate;
+
+       vc7_calc_fod_1st_stage(rate, parent_rate, fod_1st_int, fod_frac);
+       first_stage_rate = vc7_calc_fod_1st_stage_rate(parent_rate, *fod_1st_int, *fod_frac);
+
+       *fod_2nd_int = 0;
+
+       /* Do we need the second stage integer divider? */
+       if (first_stage_rate < VC7_FOD_1ST_STAGE_RATE_MIN) {
+               allow_frac = 0;
+               best_frac_i = VC7_FOD_2ND_INT_MIN;
+
+               for (i = VC7_FOD_2ND_INT_MIN; i <= VC7_FOD_2ND_INT_MAX; i++) {
+                       /*
+                        * 1) There is a div-by-2 preceding the 2nd stage integer divider
+                        *    (not shown on block diagram) so the actual 2nd stage integer
+                        *    divisor is 2 * N.
+                        * 2) Attempt to find an integer solution first. This means stepping
+                        *    through each 2nd stage integer and recalculating the 1st stage
+                        *    until the 1st stage frequency is out of bounds. If no integer
+                        *    solution is found, use the best fractional solution.
+                        */
+                       vc7_calc_fod_1st_stage(parent_rate, rate * 2 * i, fod_1st_int, fod_frac);
+                       first_stage_rate = vc7_calc_fod_1st_stage_rate(parent_rate,
+                                                                      *fod_1st_int,
+                                                                      *fod_frac);
+
+                       /* Remember the first viable fractional solution */
+                       if (best_frac_i == VC7_FOD_2ND_INT_MIN &&
+                           first_stage_rate > VC7_FOD_1ST_STAGE_RATE_MIN) {
+                               best_frac_i = i;
+                       }
+
+                       /* Is the divider viable? Prefer integer solutions over fractional. */
+                       if (*fod_1st_int < VC7_FOD_1ST_INT_MAX &&
+                           first_stage_rate >= VC7_FOD_1ST_STAGE_RATE_MIN &&
+                           (allow_frac || *fod_frac == 0)) {
+                               *fod_2nd_int = i;
+                               break;
+                       }
+
+                       /* Ran out of divisors or the 1st stage frequency is out of range */
+                       if (i >= VC7_FOD_2ND_INT_MAX ||
+                           first_stage_rate > VC7_FOD_1ST_STAGE_RATE_MAX) {
+                               allow_frac = 1;
+                               i = best_frac_i;
+
+                               /* Restore the best frac and rerun the loop for the last time */
+                               if (best_frac_i != VC7_FOD_2ND_INT_MIN)
+                                       i--;
+
+                               continue;
+                       }
+               }
+       }
+}
+
+static unsigned long vc7_fod_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+       struct vc7_fod_data *fod = container_of(hw, struct vc7_fod_data, hw);
+       struct vc7_driver_data *vc7 = fod->vc7;
+       int err;
+       unsigned long fod_rate;
+
+       err = vc7_read_fod(vc7, fod->num);
+       if (err) {
+               dev_err(&vc7->client->dev, "error reading registers for %s\n",
+                       clk_hw_get_name(hw));
+               return err;
+       }
+
+       pr_debug("%s - %s: parent_rate: %lu\n", __func__, clk_hw_get_name(hw), parent_rate);
+
+       fod_rate = vc7_calc_fod_2nd_stage_rate(parent_rate, fod->fod_1st_int,
+                                              fod->fod_2nd_int, fod->fod_frac);
+
+       pr_debug("%s - %s: fod_1st_int: %u, fod_2nd_int: %u, fod_frac: %llu\n",
+                __func__, clk_hw_get_name(hw),
+                fod->fod_1st_int, fod->fod_2nd_int, fod->fod_frac);
+       pr_debug("%s - %s rate: %lu\n", __func__, clk_hw_get_name(hw), fod_rate);
+
+       return fod_rate;
+}
+
+static long vc7_fod_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate)
+{
+       struct vc7_fod_data *fod = container_of(hw, struct vc7_fod_data, hw);
+       unsigned long fod_rate;
+
+       pr_debug("%s - %s: requested rate: %lu, parent_rate: %lu\n",
+                __func__, clk_hw_get_name(hw), rate, *parent_rate);
+
+       vc7_calc_fod_divider(rate, *parent_rate,
+                            &fod->fod_1st_int, &fod->fod_2nd_int, &fod->fod_frac);
+       fod_rate = vc7_calc_fod_2nd_stage_rate(*parent_rate, fod->fod_1st_int,
+                                              fod->fod_2nd_int, fod->fod_frac);
+
+       pr_debug("%s - %s: fod_1st_int: %u, fod_2nd_int: %u, fod_frac: %llu\n",
+                __func__, clk_hw_get_name(hw),
+                fod->fod_1st_int, fod->fod_2nd_int, fod->fod_frac);
+       pr_debug("%s - %s rate: %lu\n", __func__, clk_hw_get_name(hw), fod_rate);
+
+       return fod_rate;
+}
+
+static int vc7_fod_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
+{
+       struct vc7_fod_data *fod = container_of(hw, struct vc7_fod_data, hw);
+       struct vc7_driver_data *vc7 = fod->vc7;
+       unsigned long fod_rate;
+
+       pr_debug("%s - %s: rate: %lu, parent_rate: %lu\n",
+                __func__, clk_hw_get_name(hw), rate, parent_rate);
+
+       if (rate < VC7_FOD_RATE_MIN || rate > VC7_FOD_RATE_MAX) {
+               dev_err(&vc7->client->dev,
+                       "requested frequency %lu Hz for %s is out of range\n",
+                       rate, clk_hw_get_name(hw));
+               return -EINVAL;
+       }
+
+       vc7_write_fod(vc7, fod->num);
+
+       fod_rate = vc7_calc_fod_2nd_stage_rate(parent_rate, fod->fod_1st_int,
+                                              fod->fod_2nd_int, fod->fod_frac);
+
+       pr_debug("%s - %s: fod_1st_int: %u, fod_2nd_int: %u, fod_frac: %llu\n",
+                __func__, clk_hw_get_name(hw),
+                fod->fod_1st_int, fod->fod_2nd_int, fod->fod_frac);
+       pr_debug("%s - %s rate: %lu\n", __func__, clk_hw_get_name(hw), fod_rate);
+
+       return 0;
+}
+
+static const struct clk_ops vc7_fod_ops = {
+       .recalc_rate = vc7_fod_recalc_rate,
+       .round_rate = vc7_fod_round_rate,
+       .set_rate = vc7_fod_set_rate,
+};
+
+static unsigned long vc7_iod_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+       struct vc7_iod_data *iod = container_of(hw, struct vc7_iod_data, hw);
+       struct vc7_driver_data *vc7 = iod->vc7;
+       int err;
+       unsigned long iod_rate;
+
+       err = vc7_read_iod(vc7, iod->num);
+       if (err) {
+               dev_err(&vc7->client->dev, "error reading registers for %s\n",
+                       clk_hw_get_name(hw));
+               return err;
+       }
+
+       iod_rate = div64_u64(parent_rate, iod->iod_int);
+
+       pr_debug("%s - %s: iod_int: %u\n", __func__, clk_hw_get_name(hw), iod->iod_int);
+       pr_debug("%s - %s rate: %lu\n", __func__, clk_hw_get_name(hw), iod_rate);
+
+       return iod_rate;
+}
+
+static long vc7_iod_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate)
+{
+       struct vc7_iod_data *iod = container_of(hw, struct vc7_iod_data, hw);
+       unsigned long iod_rate;
+
+       pr_debug("%s - %s: requested rate: %lu, parent_rate: %lu\n",
+                __func__, clk_hw_get_name(hw), rate, *parent_rate);
+
+       vc7_calc_iod_divider(rate, *parent_rate, &iod->iod_int);
+       iod_rate = div64_u64(*parent_rate, iod->iod_int);
+
+       pr_debug("%s - %s: iod_int: %u\n", __func__, clk_hw_get_name(hw), iod->iod_int);
+       pr_debug("%s - %s rate: %ld\n", __func__, clk_hw_get_name(hw), iod_rate);
+
+       return iod_rate;
+}
+
+static int vc7_iod_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
+{
+       struct vc7_iod_data *iod = container_of(hw, struct vc7_iod_data, hw);
+       struct vc7_driver_data *vc7 = iod->vc7;
+       unsigned long iod_rate;
+
+       pr_debug("%s - %s: rate: %lu, parent_rate: %lu\n",
+                __func__, clk_hw_get_name(hw), rate, parent_rate);
+
+       if (rate < VC7_IOD_RATE_MIN || rate > VC7_IOD_RATE_MAX) {
+               dev_err(&vc7->client->dev,
+                       "requested frequency %lu Hz for %s is out of range\n",
+                       rate, clk_hw_get_name(hw));
+               return -EINVAL;
+       }
+
+       vc7_write_iod(vc7, iod->num);
+
+       iod_rate = div64_u64(parent_rate, iod->iod_int);
+
+       pr_debug("%s - %s: iod_int: %u\n", __func__, clk_hw_get_name(hw), iod->iod_int);
+       pr_debug("%s - %s rate: %ld\n", __func__, clk_hw_get_name(hw), iod_rate);
+
+       return 0;
+}
+
+static const struct clk_ops vc7_iod_ops = {
+       .recalc_rate = vc7_iod_recalc_rate,
+       .round_rate = vc7_iod_round_rate,
+       .set_rate = vc7_iod_set_rate,
+};
+
+static int vc7_clk_out_prepare(struct clk_hw *hw)
+{
+       struct vc7_out_data *out = container_of(hw, struct vc7_out_data, hw);
+       struct vc7_driver_data *vc7 = out->vc7;
+       int err;
+
+       out->out_dis = 0;
+
+       err = vc7_write_output(vc7, out->num);
+       if (err) {
+               dev_err(&vc7->client->dev, "error writing registers for %s\n",
+                       clk_hw_get_name(hw));
+               return err;
+       }
+
+       pr_debug("%s - %s: clk prepared\n", __func__, clk_hw_get_name(hw));
+
+       return 0;
+}
+
+static void vc7_clk_out_unprepare(struct clk_hw *hw)
+{
+       struct vc7_out_data *out = container_of(hw, struct vc7_out_data, hw);
+       struct vc7_driver_data *vc7 = out->vc7;
+       int err;
+
+       out->out_dis = 1;
+
+       err = vc7_write_output(vc7, out->num);
+       if (err) {
+               dev_err(&vc7->client->dev, "error writing registers for %s\n",
+                       clk_hw_get_name(hw));
+               return;
+       }
+
+       pr_debug("%s - %s: clk unprepared\n", __func__, clk_hw_get_name(hw));
+}
+
+static int vc7_clk_out_is_enabled(struct clk_hw *hw)
+{
+       struct vc7_out_data *out = container_of(hw, struct vc7_out_data, hw);
+       struct vc7_driver_data *vc7 = out->vc7;
+       int err, is_enabled;
+
+       err = vc7_read_output(vc7, out->num);
+       if (err) {
+               dev_err(&vc7->client->dev, "error reading registers for %s\n",
+                       clk_hw_get_name(hw));
+               return err;
+       }
+
+       is_enabled = !out->out_dis;
+
+       pr_debug("%s - %s: is_enabled=%d\n", __func__, clk_hw_get_name(hw), is_enabled);
+
+       return is_enabled;
+}
+
+static const struct clk_ops vc7_clk_out_ops = {
+       .prepare = vc7_clk_out_prepare,
+       .unprepare = vc7_clk_out_unprepare,
+       .is_enabled = vc7_clk_out_is_enabled,
+};
+
+static int vc7_probe(struct i2c_client *client)
+{
+       struct vc7_driver_data *vc7;
+       struct clk_init_data clk_init;
+       struct vc7_bank_src_map bank_src_map;
+       const char *node_name, *apll_name;
+       const char *parent_names[1];
+       unsigned int i, val, bank_idx, out_num;
+       unsigned long apll_rate;
+       int ret;
+
+       vc7 = devm_kzalloc(&client->dev, sizeof(*vc7), GFP_KERNEL);
+       if (!vc7)
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, vc7);
+       vc7->client = client;
+       vc7->chip_info = of_device_get_match_data(&client->dev);
+
+       vc7->pin_xin = devm_clk_get(&client->dev, "xin");
+       if (PTR_ERR(vc7->pin_xin) == -EPROBE_DEFER) {
+               return dev_err_probe(&client->dev, -EPROBE_DEFER,
+                                    "xin not specified\n");
+       }
+
+       vc7->regmap = devm_regmap_init_i2c(client, &vc7_regmap_config);
+       if (IS_ERR(vc7->regmap)) {
+               return dev_err_probe(&client->dev, PTR_ERR(vc7->regmap),
+                                    "failed to allocate register map\n");
+       }
+
+       if (of_property_read_string(client->dev.of_node, "clock-output-names",
+                                   &node_name))
+               node_name = client->dev.of_node->name;
+
+       /* Register APLL */
+       apll_rate = vc7_get_apll_rate(vc7);
+       apll_name = kasprintf(GFP_KERNEL, "%s_apll", node_name);
+       vc7->clk_apll.clk = clk_register_fixed_rate(&client->dev, apll_name,
+                                                   __clk_get_name(vc7->pin_xin),
+                                                   0, apll_rate);
+       kfree(apll_name); /* ccf made a copy of the name */
+       if (IS_ERR(vc7->clk_apll.clk)) {
+               return dev_err_probe(&client->dev, PTR_ERR(vc7->clk_apll.clk),
+                                    "failed to register apll\n");
+       }
+
+       /* Register FODs */
+       for (i = 0; i < VC7_NUM_FOD; i++) {
+               memset(&clk_init, 0, sizeof(clk_init));
+               clk_init.name = kasprintf(GFP_KERNEL, "%s_fod%d", node_name, i);
+               clk_init.ops = &vc7_fod_ops;
+               clk_init.parent_names = parent_names;
+               parent_names[0] = __clk_get_name(vc7->clk_apll.clk);
+               clk_init.num_parents = 1;
+               vc7->clk_fod[i].num = i;
+               vc7->clk_fod[i].vc7 = vc7;
+               vc7->clk_fod[i].hw.init = &clk_init;
+               ret = devm_clk_hw_register(&client->dev, &vc7->clk_fod[i].hw);
+               if (ret)
+                       goto err_clk_register;
+               kfree(clk_init.name); /* ccf made a copy of the name */
+       }
+
+       /* Register IODs */
+       for (i = 0; i < VC7_NUM_IOD; i++) {
+               memset(&clk_init, 0, sizeof(clk_init));
+               clk_init.name = kasprintf(GFP_KERNEL, "%s_iod%d", node_name, i);
+               clk_init.ops = &vc7_iod_ops;
+               clk_init.parent_names = parent_names;
+               parent_names[0] = __clk_get_name(vc7->clk_apll.clk);
+               clk_init.num_parents = 1;
+               vc7->clk_iod[i].num = i;
+               vc7->clk_iod[i].vc7 = vc7;
+               vc7->clk_iod[i].hw.init = &clk_init;
+               ret = devm_clk_hw_register(&client->dev, &vc7->clk_iod[i].hw);
+               if (ret)
+                       goto err_clk_register;
+               kfree(clk_init.name); /* ccf made a copy of the name */
+       }
+
+       /* Register outputs */
+       for (i = 0; i < vc7->chip_info->num_outputs; i++) {
+               out_num = vc7_map_index_to_output(vc7->chip_info->model, i);
+
+               /*
+                * This driver does not support remapping FOD/IOD to banks.
+                * The device state is read and the driver is setup to match
+                * the device's existing mapping.
+                */
+               bank_idx = output_bank_mapping[out_num];
+
+               regmap_read(vc7->regmap, VC7_REG_OUT_BANK_CNFG(bank_idx), &val);
+               val &= VC7_REG_OUTPUT_BANK_SRC_MASK;
+
+               memset(&bank_src_map, 0, sizeof(bank_src_map));
+               ret = vc7_get_bank_clk(vc7, bank_idx, val, &bank_src_map);
+               if (ret) {
+                       dev_err_probe(&client->dev, ret,
+                                     "unable to register output %d\n", i);
+                       return ret;
+               }
+
+               switch (bank_src_map.type) {
+               case VC7_FOD:
+                       parent_names[0] = clk_hw_get_name(&bank_src_map.src.fod->hw);
+                       break;
+               case VC7_IOD:
+                       parent_names[0] = clk_hw_get_name(&bank_src_map.src.iod->hw);
+                       break;
+               }
+
+               memset(&clk_init, 0, sizeof(clk_init));
+               clk_init.name = kasprintf(GFP_KERNEL, "%s_out%d", node_name, i);
+               clk_init.ops = &vc7_clk_out_ops;
+               clk_init.flags = CLK_SET_RATE_PARENT;
+               clk_init.parent_names = parent_names;
+               clk_init.num_parents = 1;
+               vc7->clk_out[i].num = i;
+               vc7->clk_out[i].vc7 = vc7;
+               vc7->clk_out[i].hw.init = &clk_init;
+               ret = devm_clk_hw_register(&client->dev, &vc7->clk_out[i].hw);
+               if (ret)
+                       goto err_clk_register;
+               kfree(clk_init.name); /* ccf made a copy of the name */
+       }
+
+       ret = of_clk_add_hw_provider(client->dev.of_node, vc7_of_clk_get, vc7);
+       if (ret) {
+               dev_err_probe(&client->dev, ret, "unable to add clk provider\n");
+               goto err_clk;
+       }
+
+       return ret;
+
+err_clk_register:
+       dev_err_probe(&client->dev, ret,
+                     "unable to register %s\n", clk_init.name);
+       kfree(clk_init.name); /* ccf made a copy of the name */
+err_clk:
+       clk_unregister_fixed_rate(vc7->clk_apll.clk);
+       return ret;
+}
+
+static int vc7_remove(struct i2c_client *client)
+{
+       struct vc7_driver_data *vc7 = i2c_get_clientdata(client);
+
+       of_clk_del_provider(client->dev.of_node);
+       clk_unregister_fixed_rate(vc7->clk_apll.clk);
+
+       return 0;
+}
+
+static bool vc7_volatile_reg(struct device *dev, unsigned int reg)
+{
+       if (reg == VC7_PAGE_ADDR)
+               return false;
+
+       return true;
+}
+
+static const struct vc7_chip_info vc7_rc21008a_info = {
+       .model = VC7_RC21008A,
+       .num_banks = 6,
+       .num_outputs = 8,
+};
+
+static struct regmap_range_cfg vc7_range_cfg[] = {
+{
+       .range_min = 0,
+       .range_max = VC7_MAX_REG,
+       .selector_reg = VC7_PAGE_ADDR,
+       .selector_mask = 0xFF,
+       .selector_shift = 0,
+       .window_start = 0,
+       .window_len = VC7_PAGE_WINDOW,
+}};
+
+static const struct regmap_config vc7_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = VC7_MAX_REG,
+       .ranges = vc7_range_cfg,
+       .num_ranges = ARRAY_SIZE(vc7_range_cfg),
+       .volatile_reg = vc7_volatile_reg,
+       .cache_type = REGCACHE_RBTREE,
+       .can_multi_write = true,
+       .reg_format_endian = REGMAP_ENDIAN_LITTLE,
+       .val_format_endian = REGMAP_ENDIAN_LITTLE,
+};
+
+static const struct i2c_device_id vc7_i2c_id[] = {
+       { "rc21008a", VC7_RC21008A },
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, vc7_i2c_id);
+
+static const struct of_device_id vc7_of_match[] = {
+       { .compatible = "renesas,rc21008a", .data = &vc7_rc21008a_info },
+       {}
+};
+MODULE_DEVICE_TABLE(of, vc7_of_match);
+
+static struct i2c_driver vc7_i2c_driver = {
+       .driver = {
+               .name = "vc7",
+               .of_match_table = vc7_of_match,
+       },
+       .probe_new = vc7_probe,
+       .remove = vc7_remove,
+       .id_table = vc7_i2c_id,
+};
+module_i2c_driver(vc7_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alex Helms <alexander.helms.jy@renesas.com");
+MODULE_DESCRIPTION("Renesas Versaclock7 common clock framework driver");
index 857217c..0c3d0ce 100644 (file)
@@ -522,10 +522,10 @@ static int xgene_clk_is_enabled(struct clk_hw *hw)
                pr_debug("%s clock is %s\n", clk_hw_get_name(hw),
                        data & pclk->param.reg_clk_mask ? "enabled" :
                                                        "disabled");
+       } else {
+               return 1;
        }
 
-       if (!pclk->param.csr_reg)
-               return 1;
        return data & pclk->param.reg_clk_mask ? 1 : 0;
 }
 
index 7fc191c..3c86919 100644 (file)
@@ -2189,7 +2189,7 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
 {
        struct clk_core *top, *fail_clk;
        unsigned long rate;
-       int ret = 0;
+       int ret;
 
        if (!core)
                return 0;
@@ -3462,7 +3462,7 @@ static void clk_core_reparent_orphans_nolock(void)
 
                /*
                 * We need to use __clk_set_parent_before() and _after() to
-                * to properly migrate any prepare/enable count of the orphan
+                * properly migrate any prepare/enable count of the orphan
                 * clock. This is important for CLK_IS_CRITICAL clocks, which
                 * are enabled during init but might not have a parent yet.
                 */
@@ -3672,7 +3672,6 @@ static int __clk_core_init(struct clk_core *core)
 
        clk_core_reparent_orphans_nolock();
 
-
        kref_init(&core->ref);
 out:
        clk_pm_runtime_put(core);
@@ -4751,32 +4750,6 @@ void of_clk_del_provider(struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_clk_del_provider);
 
-static int devm_clk_provider_match(struct device *dev, void *res, void *data)
-{
-       struct device_node **np = res;
-
-       if (WARN_ON(!np || !*np))
-               return 0;
-
-       return *np == data;
-}
-
-/**
- * devm_of_clk_del_provider() - Remove clock provider registered using devm
- * @dev: Device to whose lifetime the clock provider was bound
- */
-void devm_of_clk_del_provider(struct device *dev)
-{
-       int ret;
-       struct device_node *np = get_clk_provider_node(dev);
-
-       ret = devres_release(dev, devm_of_clk_release_provider,
-                            devm_clk_provider_match, np);
-
-       WARN_ON(ret);
-}
-EXPORT_SYMBOL(devm_of_clk_del_provider);
-
 /**
  * of_parse_clkspec() - Parse a DT clock specifier for a given device node
  * @np: device node to parse clock specifier from
index 67f601a..ee37d0b 100644 (file)
@@ -165,7 +165,7 @@ vclkdev_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt,
 
        cla->cl.clk_hw = hw;
        if (con_id) {
-               strlcpy(cla->con_id, con_id, sizeof(cla->con_id));
+               strscpy(cla->con_id, con_id, sizeof(cla->con_id));
                cla->cl.con_id = cla->con_id;
        }
 
@@ -346,46 +346,12 @@ int clk_hw_register_clkdev(struct clk_hw *hw, const char *con_id,
 }
 EXPORT_SYMBOL(clk_hw_register_clkdev);
 
-static void devm_clkdev_release(struct device *dev, void *res)
+static void devm_clkdev_release(void *res)
 {
-       clkdev_drop(*(struct clk_lookup **)res);
-}
-
-static int devm_clk_match_clkdev(struct device *dev, void *res, void *data)
-{
-       struct clk_lookup **l = res;
-
-       return *l == data;
+       clkdev_drop(res);
 }
 
 /**
- * devm_clk_release_clkdev - Resource managed clkdev lookup release
- * @dev: device this lookup is bound
- * @con_id: connection ID string on device
- * @dev_id: format string describing device name
- *
- * Drop the clkdev lookup created with devm_clk_hw_register_clkdev.
- * Normally this function will not need to be called and the resource
- * management code will ensure that the resource is freed.
- */
-void devm_clk_release_clkdev(struct device *dev, const char *con_id,
-                            const char *dev_id)
-{
-       struct clk_lookup *cl;
-       int rval;
-
-       mutex_lock(&clocks_mutex);
-       cl = clk_find(dev_id, con_id);
-       mutex_unlock(&clocks_mutex);
-
-       WARN_ON(!cl);
-       rval = devres_release(dev, devm_clkdev_release,
-                             devm_clk_match_clkdev, cl);
-       WARN_ON(rval);
-}
-EXPORT_SYMBOL(devm_clk_release_clkdev);
-
-/**
  * devm_clk_hw_register_clkdev - managed clk lookup registration for clk_hw
  * @dev: device this lookup is bound
  * @hw: struct clk_hw to associate with all clk_lookups
@@ -403,17 +369,13 @@ EXPORT_SYMBOL(devm_clk_release_clkdev);
 int devm_clk_hw_register_clkdev(struct device *dev, struct clk_hw *hw,
                                const char *con_id, const char *dev_id)
 {
-       int rval = -ENOMEM;
-       struct clk_lookup **cl;
-
-       cl = devres_alloc(devm_clkdev_release, sizeof(*cl), GFP_KERNEL);
-       if (cl) {
-               rval = do_clk_register_clkdev(hw, cl, con_id, dev_id);
-               if (!rval)
-                       devres_add(dev, cl);
-               else
-                       devres_free(cl);
-       }
-       return rval;
+       struct clk_lookup *cl;
+       int rval;
+
+       rval = do_clk_register_clkdev(hw, &cl, con_id, dev_id);
+       if (rval)
+               return rval;
+
+       return devm_add_action_or_reset(dev, devm_clkdev_release, cl);
 }
 EXPORT_SYMBOL(devm_clk_hw_register_clkdev);
index 11178b7..be6f55d 100644 (file)
@@ -8,14 +8,10 @@ obj-$(CONFIG_ARCH_DAVINCI_DA830)      += pll-da830.o
 obj-$(CONFIG_ARCH_DAVINCI_DA850)       += pll-da850.o
 obj-$(CONFIG_ARCH_DAVINCI_DM355)       += pll-dm355.o
 obj-$(CONFIG_ARCH_DAVINCI_DM365)       += pll-dm365.o
-obj-$(CONFIG_ARCH_DAVINCI_DM644x)      += pll-dm644x.o
-obj-$(CONFIG_ARCH_DAVINCI_DM646x)      += pll-dm646x.o
 
 obj-y += psc.o
 obj-$(CONFIG_ARCH_DAVINCI_DA830)       += psc-da830.o
 obj-$(CONFIG_ARCH_DAVINCI_DA850)       += psc-da850.o
 obj-$(CONFIG_ARCH_DAVINCI_DM355)       += psc-dm355.o
 obj-$(CONFIG_ARCH_DAVINCI_DM365)       += psc-dm365.o
-obj-$(CONFIG_ARCH_DAVINCI_DM644x)      += psc-dm644x.o
-obj-$(CONFIG_ARCH_DAVINCI_DM646x)      += psc-dm646x.o
 endif
index 77d1827..4103d60 100644 (file)
@@ -510,8 +510,7 @@ da8xx_cfgchip_register_usb0_clk48(struct device *dev,
 
        fck_clk = devm_clk_get(dev, "fck");
        if (IS_ERR(fck_clk)) {
-               if (PTR_ERR(fck_clk) != -EPROBE_DEFER)
-                       dev_err(dev, "Missing fck clock\n");
+               dev_err_probe(dev, PTR_ERR(fck_clk), "Missing fck clock\n");
                return ERR_CAST(fck_clk);
        }
 
diff --git a/drivers/clk/davinci/pll-dm644x.c b/drivers/clk/davinci/pll-dm644x.c
deleted file mode 100644 (file)
index 7650fad..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * PLL clock descriptions for TI DM644X
- *
- * Copyright (C) 2018 David Lechner <david@lechnology.com>
- */
-
-#include <linux/bitops.h>
-#include <linux/clk/davinci.h>
-#include <linux/clkdev.h>
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include "pll.h"
-
-static const struct davinci_pll_clk_info dm644x_pll1_info = {
-       .name = "pll1",
-       .pllm_mask = GENMASK(4, 0),
-       .pllm_min = 1,
-       .pllm_max = 32,
-       .pllout_min_rate = 400000000,
-       .pllout_max_rate = 600000000, /* 810MHz @ 1.3V, -810 only */
-       .flags = PLL_HAS_CLKMODE | PLL_HAS_POSTDIV,
-};
-
-SYSCLK(1, pll1_sysclk1, pll1_pllen, 4, SYSCLK_FIXED_DIV);
-SYSCLK(2, pll1_sysclk2, pll1_pllen, 4, SYSCLK_FIXED_DIV);
-SYSCLK(3, pll1_sysclk3, pll1_pllen, 4, SYSCLK_FIXED_DIV);
-SYSCLK(5, pll1_sysclk5, pll1_pllen, 4, SYSCLK_FIXED_DIV);
-
-int dm644x_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
-{
-       struct clk *clk;
-
-       davinci_pll_clk_register(dev, &dm644x_pll1_info, "ref_clk", base, cfgchip);
-
-       clk = davinci_pll_sysclk_register(dev, &pll1_sysclk1, base);
-       clk_register_clkdev(clk, "pll1_sysclk1", "dm644x-psc");
-
-       clk = davinci_pll_sysclk_register(dev, &pll1_sysclk2, base);
-       clk_register_clkdev(clk, "pll1_sysclk2", "dm644x-psc");
-
-       clk = davinci_pll_sysclk_register(dev, &pll1_sysclk3, base);
-       clk_register_clkdev(clk, "pll1_sysclk3", "dm644x-psc");
-
-       clk = davinci_pll_sysclk_register(dev, &pll1_sysclk5, base);
-       clk_register_clkdev(clk, "pll1_sysclk5", "dm644x-psc");
-
-       clk = davinci_pll_auxclk_register(dev, "pll1_auxclk", base);
-       clk_register_clkdev(clk, "pll1_auxclk", "dm644x-psc");
-
-       davinci_pll_sysclkbp_clk_register(dev, "pll1_sysclkbp", base);
-
-       return 0;
-}
-
-static const struct davinci_pll_clk_info dm644x_pll2_info = {
-       .name = "pll2",
-       .pllm_mask = GENMASK(4, 0),
-       .pllm_min = 1,
-       .pllm_max = 32,
-       .pllout_min_rate = 400000000,
-       .pllout_max_rate = 900000000,
-       .flags = PLL_HAS_POSTDIV | PLL_POSTDIV_FIXED_DIV,
-};
-
-SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, 0);
-SYSCLK(2, pll2_sysclk2, pll2_pllen, 4, 0);
-
-int dm644x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
-{
-       davinci_pll_clk_register(dev, &dm644x_pll2_info, "oscin", base, cfgchip);
-
-       davinci_pll_sysclk_register(dev, &pll2_sysclk1, base);
-
-       davinci_pll_sysclk_register(dev, &pll2_sysclk2, base);
-
-       davinci_pll_sysclkbp_clk_register(dev, "pll2_sysclkbp", base);
-
-       return 0;
-}
diff --git a/drivers/clk/davinci/pll-dm646x.c b/drivers/clk/davinci/pll-dm646x.c
deleted file mode 100644 (file)
index 2698297..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * PLL clock descriptions for TI DM646X
- *
- * Copyright (C) 2018 David Lechner <david@lechnology.com>
- */
-
-#include <linux/clk-provider.h>
-#include <linux/clk/davinci.h>
-#include <linux/clkdev.h>
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include "pll.h"
-
-static const struct davinci_pll_clk_info dm646x_pll1_info = {
-       .name = "pll1",
-       .pllm_mask = GENMASK(4, 0),
-       .pllm_min = 14,
-       .pllm_max = 32,
-       .flags = PLL_HAS_CLKMODE,
-};
-
-SYSCLK(1, pll1_sysclk1, pll1_pllen, 4, SYSCLK_FIXED_DIV);
-SYSCLK(2, pll1_sysclk2, pll1_pllen, 4, SYSCLK_FIXED_DIV);
-SYSCLK(3, pll1_sysclk3, pll1_pllen, 4, SYSCLK_FIXED_DIV);
-SYSCLK(4, pll1_sysclk4, pll1_pllen, 4, 0);
-SYSCLK(5, pll1_sysclk5, pll1_pllen, 4, 0);
-SYSCLK(6, pll1_sysclk6, pll1_pllen, 4, 0);
-SYSCLK(8, pll1_sysclk8, pll1_pllen, 4, 0);
-SYSCLK(9, pll1_sysclk9, pll1_pllen, 4, 0);
-
-int dm646x_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
-{
-       struct clk *clk;
-
-       davinci_pll_clk_register(dev, &dm646x_pll1_info, "ref_clk", base, cfgchip);
-
-       clk = davinci_pll_sysclk_register(dev, &pll1_sysclk1, base);
-       clk_register_clkdev(clk, "pll1_sysclk1", "dm646x-psc");
-
-       clk = davinci_pll_sysclk_register(dev, &pll1_sysclk2, base);
-       clk_register_clkdev(clk, "pll1_sysclk2", "dm646x-psc");
-
-       clk = davinci_pll_sysclk_register(dev, &pll1_sysclk3, base);
-       clk_register_clkdev(clk, "pll1_sysclk3", "dm646x-psc");
-       clk_register_clkdev(clk, NULL, "davinci-wdt");
-
-       clk = davinci_pll_sysclk_register(dev, &pll1_sysclk4, base);
-       clk_register_clkdev(clk, "pll1_sysclk4", "dm646x-psc");
-
-       clk = davinci_pll_sysclk_register(dev, &pll1_sysclk5, base);
-       clk_register_clkdev(clk, "pll1_sysclk5", "dm646x-psc");
-
-       davinci_pll_sysclk_register(dev, &pll1_sysclk6, base);
-
-       davinci_pll_sysclk_register(dev, &pll1_sysclk8, base);
-
-       davinci_pll_sysclk_register(dev, &pll1_sysclk9, base);
-
-       davinci_pll_sysclkbp_clk_register(dev, "pll1_sysclkbp", base);
-
-       davinci_pll_auxclk_register(dev, "pll1_auxclk", base);
-
-       return 0;
-}
-
-static const struct davinci_pll_clk_info dm646x_pll2_info = {
-       .name = "pll2",
-       .pllm_mask = GENMASK(4, 0),
-       .pllm_min = 14,
-       .pllm_max = 32,
-       .flags = 0,
-};
-
-SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, SYSCLK_ALWAYS_ENABLED);
-
-int dm646x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip)
-{
-       davinci_pll_clk_register(dev, &dm646x_pll2_info, "oscin", base, cfgchip);
-
-       davinci_pll_sysclk_register(dev, &pll2_sysclk1, base);
-
-       return 0;
-}
index 0d75043..f862f5e 100644 (file)
@@ -98,7 +98,7 @@
  * @hw: clk_hw for the pll
  * @base: Base memory address
  * @pllm_min: The minimum allowable PLLM[PLLM] value
- * @pllm_max: The maxiumum allowable PLLM[PLLM] value
+ * @pllm_max: The maximum allowable PLLM[PLLM] value
  * @pllm_mask: Bitmask for PLLM[PLLM] value
  */
 struct davinci_pll_clk {
@@ -890,14 +890,6 @@ static const struct platform_device_id davinci_pll_id_table[] = {
        { .name = "dm365-pll1",  .driver_data = (kernel_ulong_t)dm365_pll1_init  },
        { .name = "dm365-pll2",  .driver_data = (kernel_ulong_t)dm365_pll2_init  },
 #endif
-#ifdef CONFIG_ARCH_DAVINCI_DM644x
-       { .name = "dm644x-pll1", .driver_data = (kernel_ulong_t)dm644x_pll1_init },
-       { .name = "dm644x-pll2", .driver_data = (kernel_ulong_t)dm644x_pll2_init },
-#endif
-#ifdef CONFIG_ARCH_DAVINCI_DM646x
-       { .name = "dm646x-pll1", .driver_data = (kernel_ulong_t)dm646x_pll1_init },
-       { .name = "dm646x-pll2", .driver_data = (kernel_ulong_t)dm646x_pll2_init },
-#endif
        { }
 };
 
index c2a453c..1773277 100644 (file)
@@ -130,11 +130,5 @@ int of_da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cf
 #ifdef CONFIG_ARCH_DAVINCI_DM355
 int dm355_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip);
 #endif
-#ifdef CONFIG_ARCH_DAVINCI_DM644x
-int dm644x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip);
-#endif
-#ifdef CONFIG_ARCH_DAVINCI_DM646x
-int dm646x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip);
-#endif
 
 #endif /* __CLK_DAVINCI_PLL_H___ */
diff --git a/drivers/clk/davinci/psc-dm644x.c b/drivers/clk/davinci/psc-dm644x.c
deleted file mode 100644 (file)
index 0cea6e0..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * PSC clock descriptions for TI DaVinci DM644x
- *
- * Copyright (C) 2018 David Lechner <david@lechnology.com>
- */
-
-#include <linux/clk-provider.h>
-#include <linux/clk/davinci.h>
-#include <linux/clk.h>
-#include <linux/clkdev.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-#include "psc.h"
-
-LPSC_CLKDEV1(vpss_master_clkdev,       "master",       "vpss");
-LPSC_CLKDEV1(vpss_slave_clkdev,                "slave",        "vpss");
-LPSC_CLKDEV2(emac_clkdev,              NULL,           "davinci_emac.1",
-                                       "fck",          "davinci_mdio.0");
-LPSC_CLKDEV1(usb_clkdev,               "usb",          NULL);
-LPSC_CLKDEV1(ide_clkdev,               NULL,           "palm_bk3710");
-LPSC_CLKDEV2(aemif_clkdev,             "aemif",        NULL,
-                                       NULL,           "ti-aemif");
-LPSC_CLKDEV1(mmcsd_clkdev,             NULL,           "dm6441-mmc.0");
-LPSC_CLKDEV1(asp0_clkdev,              NULL,           "davinci-mcbsp");
-LPSC_CLKDEV1(i2c_clkdev,               NULL,           "i2c_davinci.1");
-LPSC_CLKDEV1(uart0_clkdev,             NULL,           "serial8250.0");
-LPSC_CLKDEV1(uart1_clkdev,             NULL,           "serial8250.1");
-LPSC_CLKDEV1(uart2_clkdev,             NULL,           "serial8250.2");
-/* REVISIT: gpio-davinci.c should be modified to drop con_id */
-LPSC_CLKDEV1(gpio_clkdev,              "gpio",         NULL);
-LPSC_CLKDEV1(timer0_clkdev,            "timer0",       NULL);
-LPSC_CLKDEV1(timer2_clkdev,            NULL,           "davinci-wdt");
-
-static const struct davinci_lpsc_clk_info dm644x_psc_info[] = {
-       LPSC(0,  0, vpss_master, pll1_sysclk3, vpss_master_clkdev, 0),
-       LPSC(1,  0, vpss_slave,  pll1_sysclk3, vpss_slave_clkdev,  0),
-       LPSC(6,  0, emac,        pll1_sysclk5, emac_clkdev,        0),
-       LPSC(9,  0, usb,         pll1_sysclk5, usb_clkdev,         0),
-       LPSC(10, 0, ide,         pll1_sysclk5, ide_clkdev,         0),
-       LPSC(11, 0, vlynq,       pll1_sysclk5, NULL,               0),
-       LPSC(14, 0, aemif,       pll1_sysclk5, aemif_clkdev,       0),
-       LPSC(15, 0, mmcsd,       pll1_sysclk5, mmcsd_clkdev,       0),
-       LPSC(17, 0, asp0,        pll1_sysclk5, asp0_clkdev,        0),
-       LPSC(18, 0, i2c,         pll1_auxclk,  i2c_clkdev,         0),
-       LPSC(19, 0, uart0,       pll1_auxclk,  uart0_clkdev,       0),
-       LPSC(20, 0, uart1,       pll1_auxclk,  uart1_clkdev,       0),
-       LPSC(21, 0, uart2,       pll1_auxclk,  uart2_clkdev,       0),
-       LPSC(22, 0, spi,         pll1_sysclk5, NULL,               0),
-       LPSC(23, 0, pwm0,        pll1_auxclk,  NULL,               0),
-       LPSC(24, 0, pwm1,        pll1_auxclk,  NULL,               0),
-       LPSC(25, 0, pwm2,        pll1_auxclk,  NULL,               0),
-       LPSC(26, 0, gpio,        pll1_sysclk5, gpio_clkdev,        0),
-       LPSC(27, 0, timer0,      pll1_auxclk,  timer0_clkdev,      LPSC_ALWAYS_ENABLED),
-       LPSC(28, 0, timer1,      pll1_auxclk,  NULL,               0),
-       /* REVISIT: why can't this be disabled? */
-       LPSC(29, 0, timer2,      pll1_auxclk,  timer2_clkdev,      LPSC_ALWAYS_ENABLED),
-       LPSC(31, 0, arm,         pll1_sysclk2, NULL,               LPSC_ALWAYS_ENABLED),
-       /* REVISIT how to disable? */
-       LPSC(39, 1, dsp,         pll1_sysclk1, NULL,               LPSC_ALWAYS_ENABLED),
-       /* REVISIT how to disable? */
-       LPSC(40, 1, vicp,        pll1_sysclk2, NULL,               LPSC_ALWAYS_ENABLED),
-       { }
-};
-
-int dm644x_psc_init(struct device *dev, void __iomem *base)
-{
-       return davinci_psc_register_clocks(dev, dm644x_psc_info, 41, base);
-}
-
-static struct clk_bulk_data dm644x_psc_parent_clks[] = {
-       { .id = "pll1_sysclk1" },
-       { .id = "pll1_sysclk2" },
-       { .id = "pll1_sysclk3" },
-       { .id = "pll1_sysclk5" },
-       { .id = "pll1_auxclk"  },
-};
-
-const struct davinci_psc_init_data dm644x_psc_init_data = {
-       .parent_clks            = dm644x_psc_parent_clks,
-       .num_parent_clks        = ARRAY_SIZE(dm644x_psc_parent_clks),
-       .psc_init               = &dm644x_psc_init,
-};
diff --git a/drivers/clk/davinci/psc-dm646x.c b/drivers/clk/davinci/psc-dm646x.c
deleted file mode 100644 (file)
index 20012dc..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * PSC clock descriptions for TI DaVinci DM646x
- *
- * Copyright (C) 2018 David Lechner <david@lechnology.com>
- */
-
-#include <linux/clk-provider.h>
-#include <linux/clk/davinci.h>
-#include <linux/clk.h>
-#include <linux/clkdev.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-#include "psc.h"
-
-LPSC_CLKDEV1(ide_clkdev,       NULL,           "palm_bk3710");
-LPSC_CLKDEV2(emac_clkdev,      NULL,           "davinci_emac.1",
-                               "fck",          "davinci_mdio.0");
-LPSC_CLKDEV2(aemif_clkdev,     "aemif",        NULL,
-                               NULL,           "ti-aemif");
-LPSC_CLKDEV1(mcasp0_clkdev,    NULL,           "davinci-mcasp.0");
-LPSC_CLKDEV1(mcasp1_clkdev,    NULL,           "davinci-mcasp.1");
-LPSC_CLKDEV1(uart0_clkdev,     NULL,           "serial8250.0");
-LPSC_CLKDEV1(uart1_clkdev,     NULL,           "serial8250.1");
-LPSC_CLKDEV1(uart2_clkdev,     NULL,           "serial8250.2");
-LPSC_CLKDEV1(i2c_clkdev,       NULL,           "i2c_davinci.1");
-/* REVISIT: gpio-davinci.c should be modified to drop con_id */
-LPSC_CLKDEV1(gpio_clkdev,      "gpio",         NULL);
-LPSC_CLKDEV1(timer0_clkdev,    "timer0",        NULL);
-
-static const struct davinci_lpsc_clk_info dm646x_psc_info[] = {
-       LPSC(0,  0, arm,      pll1_sysclk2, NULL,          LPSC_ALWAYS_ENABLED),
-       /* REVISIT how to disable? */
-       LPSC(1,  0, dsp,      pll1_sysclk1, NULL,          LPSC_ALWAYS_ENABLED),
-       LPSC(4,  0, edma_cc,  pll1_sysclk2, NULL,          LPSC_ALWAYS_ENABLED),
-       LPSC(5,  0, edma_tc0, pll1_sysclk2, NULL,          LPSC_ALWAYS_ENABLED),
-       LPSC(6,  0, edma_tc1, pll1_sysclk2, NULL,          LPSC_ALWAYS_ENABLED),
-       LPSC(7,  0, edma_tc2, pll1_sysclk2, NULL,          LPSC_ALWAYS_ENABLED),
-       LPSC(8,  0, edma_tc3, pll1_sysclk2, NULL,          LPSC_ALWAYS_ENABLED),
-       LPSC(10, 0, ide,      pll1_sysclk4, ide_clkdev,    0),
-       LPSC(14, 0, emac,     pll1_sysclk3, emac_clkdev,   0),
-       LPSC(16, 0, vpif0,    ref_clk,      NULL,          LPSC_ALWAYS_ENABLED),
-       LPSC(17, 0, vpif1,    ref_clk,      NULL,          LPSC_ALWAYS_ENABLED),
-       LPSC(21, 0, aemif,    pll1_sysclk3, aemif_clkdev,  LPSC_ALWAYS_ENABLED),
-       LPSC(22, 0, mcasp0,   pll1_sysclk3, mcasp0_clkdev, 0),
-       LPSC(23, 0, mcasp1,   pll1_sysclk3, mcasp1_clkdev, 0),
-       LPSC(26, 0, uart0,    aux_clkin,    uart0_clkdev,  0),
-       LPSC(27, 0, uart1,    aux_clkin,    uart1_clkdev,  0),
-       LPSC(28, 0, uart2,    aux_clkin,    uart2_clkdev,  0),
-       /* REVIST: disabling hangs system */
-       LPSC(29, 0, pwm0,     pll1_sysclk3, NULL,          LPSC_ALWAYS_ENABLED),
-       /* REVIST: disabling hangs system */
-       LPSC(30, 0, pwm1,     pll1_sysclk3, NULL,          LPSC_ALWAYS_ENABLED),
-       LPSC(31, 0, i2c,      pll1_sysclk3, i2c_clkdev,    0),
-       LPSC(33, 0, gpio,     pll1_sysclk3, gpio_clkdev,   0),
-       LPSC(34, 0, timer0,   pll1_sysclk3, timer0_clkdev, LPSC_ALWAYS_ENABLED),
-       LPSC(35, 0, timer1,   pll1_sysclk3, NULL,          0),
-       { }
-};
-
-int dm646x_psc_init(struct device *dev, void __iomem *base)
-{
-       return davinci_psc_register_clocks(dev, dm646x_psc_info, 46, base);
-}
-
-static struct clk_bulk_data dm646x_psc_parent_clks[] = {
-       { .id = "ref_clk"      },
-       { .id = "aux_clkin"    },
-       { .id = "pll1_sysclk1" },
-       { .id = "pll1_sysclk2" },
-       { .id = "pll1_sysclk3" },
-       { .id = "pll1_sysclk4" },
-       { .id = "pll1_sysclk5" },
-};
-
-const struct davinci_psc_init_data dm646x_psc_init_data = {
-       .parent_clks            = dm646x_psc_parent_clks,
-       .num_parent_clks        = ARRAY_SIZE(dm646x_psc_parent_clks),
-       .psc_init               = &dm646x_psc_init,
-};
index 7387e7f..42a59db 100644 (file)
@@ -517,12 +517,6 @@ static const struct platform_device_id davinci_psc_id_table[] = {
 #ifdef CONFIG_ARCH_DAVINCI_DM365
        { .name = "dm365-psc",  .driver_data = (kernel_ulong_t)&dm365_psc_init_data  },
 #endif
-#ifdef CONFIG_ARCH_DAVINCI_DM644x
-       { .name = "dm644x-psc", .driver_data = (kernel_ulong_t)&dm644x_psc_init_data },
-#endif
-#ifdef CONFIG_ARCH_DAVINCI_DM646x
-       { .name = "dm646x-psc", .driver_data = (kernel_ulong_t)&dm646x_psc_init_data },
-#endif
        { }
 };
 
index 69070f8..5e382b6 100644 (file)
@@ -110,11 +110,5 @@ extern const struct davinci_psc_init_data dm355_psc_init_data;
 #ifdef CONFIG_ARCH_DAVINCI_DM365
 extern const struct davinci_psc_init_data dm365_psc_init_data;
 #endif
-#ifdef CONFIG_ARCH_DAVINCI_DM644x
-extern const struct davinci_psc_init_data dm644x_psc_init_data;
-#endif
-#ifdef CONFIG_ARCH_DAVINCI_DM646x
-extern const struct davinci_psc_init_data dm646x_psc_init_data;
-#endif
 
 #endif /* __CLK_DAVINCI_PSC_H__ */
index 88b9b92..e8aacb0 100644 (file)
@@ -12,6 +12,7 @@ mxc-clk-objs += clk-fixup-div.o
 mxc-clk-objs += clk-fixup-mux.o
 mxc-clk-objs += clk-frac-pll.o
 mxc-clk-objs += clk-gate2.o
+mxc-clk-objs += clk-gate-93.o
 mxc-clk-objs += clk-gate-exclusive.o
 mxc-clk-objs += clk-pfd.o
 mxc-clk-objs += clk-pfdv2.o
index b44619a..74a66b0 100644 (file)
 #include <linux/errno.h>
 #include <linux/export.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/slab.h>
 
 #include "clk.h"
 
+#define TIMEOUT_US     500U
+
 #define CCM_DIV_SHIFT  0
 #define CCM_DIV_WIDTH  8
 #define CCM_MUX_SHIFT  8
 #define CCM_MUX_MASK   3
 #define CCM_OFF_SHIFT  24
+#define CCM_BUSY_SHIFT 28
 
+#define STAT_OFFSET    0x4
 #define AUTHEN_OFFSET  0x30
 #define TZ_NS_SHIFT    9
 #define TZ_NS_MASK     BIT(9)
 
+#define WHITE_LIST_SHIFT       16
+
+static int imx93_clk_composite_wait_ready(struct clk_hw *hw, void __iomem *reg)
+{
+       int ret;
+       u32 val;
+
+       ret = readl_poll_timeout_atomic(reg + STAT_OFFSET, val, !(val & BIT(CCM_BUSY_SHIFT)),
+                                       0, TIMEOUT_US);
+       if (ret)
+               pr_err("Slice[%s] busy timeout\n", clk_hw_get_name(hw));
+
+       return ret;
+}
+
+static void imx93_clk_composite_gate_endisable(struct clk_hw *hw, int enable)
+{
+       struct clk_gate *gate = to_clk_gate(hw);
+       unsigned long flags;
+       u32 reg;
+
+       if (gate->lock)
+               spin_lock_irqsave(gate->lock, flags);
+
+       reg = readl(gate->reg);
+
+       if (enable)
+               reg &= ~BIT(gate->bit_idx);
+       else
+               reg |= BIT(gate->bit_idx);
+
+       writel(reg, gate->reg);
+
+       imx93_clk_composite_wait_ready(hw, gate->reg);
+
+       if (gate->lock)
+               spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static int imx93_clk_composite_gate_enable(struct clk_hw *hw)
+{
+       imx93_clk_composite_gate_endisable(hw, 1);
+
+       return 0;
+}
+
+static void imx93_clk_composite_gate_disable(struct clk_hw *hw)
+{
+       imx93_clk_composite_gate_endisable(hw, 0);
+}
+
+static const struct clk_ops imx93_clk_composite_gate_ops = {
+       .enable = imx93_clk_composite_gate_enable,
+       .disable = imx93_clk_composite_gate_disable,
+       .is_enabled = clk_gate_is_enabled,
+};
+
+static unsigned long
+imx93_clk_composite_divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+       return clk_divider_ops.recalc_rate(hw, parent_rate);
+}
+
+static long
+imx93_clk_composite_divider_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate)
+{
+       return clk_divider_ops.round_rate(hw, rate, prate);
+}
+
+static int
+imx93_clk_composite_divider_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+       return clk_divider_ops.determine_rate(hw, req);
+}
+
+static int imx93_clk_composite_divider_set_rate(struct clk_hw *hw, unsigned long rate,
+                                               unsigned long parent_rate)
+{
+       struct clk_divider *divider = to_clk_divider(hw);
+       int value;
+       unsigned long flags = 0;
+       u32 val;
+       int ret;
+
+       value = divider_get_val(rate, parent_rate, divider->table, divider->width, divider->flags);
+       if (value < 0)
+               return value;
+
+       if (divider->lock)
+               spin_lock_irqsave(divider->lock, flags);
+
+       val = readl(divider->reg);
+       val &= ~(clk_div_mask(divider->width) << divider->shift);
+       val |= (u32)value << divider->shift;
+       writel(val, divider->reg);
+
+       ret = imx93_clk_composite_wait_ready(hw, divider->reg);
+
+       if (divider->lock)
+               spin_unlock_irqrestore(divider->lock, flags);
+
+       return ret;
+}
+
+static const struct clk_ops imx93_clk_composite_divider_ops = {
+       .recalc_rate = imx93_clk_composite_divider_recalc_rate,
+       .round_rate = imx93_clk_composite_divider_round_rate,
+       .determine_rate = imx93_clk_composite_divider_determine_rate,
+       .set_rate = imx93_clk_composite_divider_set_rate,
+};
+
+static u8 imx93_clk_composite_mux_get_parent(struct clk_hw *hw)
+{
+       return clk_mux_ops.get_parent(hw);
+}
+
+static int imx93_clk_composite_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct clk_mux *mux = to_clk_mux(hw);
+       u32 val = clk_mux_index_to_val(mux->table, mux->flags, index);
+       unsigned long flags = 0;
+       u32 reg;
+       int ret;
+
+       if (mux->lock)
+               spin_lock_irqsave(mux->lock, flags);
+
+       reg = readl(mux->reg);
+       reg &= ~(mux->mask << mux->shift);
+       val = val << mux->shift;
+       reg |= val;
+       writel(reg, mux->reg);
+
+       ret = imx93_clk_composite_wait_ready(hw, mux->reg);
+
+       if (mux->lock)
+               spin_unlock_irqrestore(mux->lock, flags);
+
+       return ret;
+}
+
+static int
+imx93_clk_composite_mux_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+       return clk_mux_ops.determine_rate(hw, req);
+}
+
+static const struct clk_ops imx93_clk_composite_mux_ops = {
+       .get_parent = imx93_clk_composite_mux_get_parent,
+       .set_parent = imx93_clk_composite_mux_set_parent,
+       .determine_rate = imx93_clk_composite_mux_determine_rate,
+};
+
 struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *parent_names,
-                                        int num_parents, void __iomem *reg,
+                                        int num_parents, void __iomem *reg, u32 domain_id,
                                         unsigned long flags)
 {
        struct clk_hw *hw = ERR_PTR(-ENOMEM), *mux_hw;
@@ -33,6 +191,7 @@ struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *p
        struct clk_gate *gate = NULL;
        struct clk_mux *mux = NULL;
        bool clk_ro = false;
+       u32 authen;
 
        mux = kzalloc(sizeof(*mux), GFP_KERNEL);
        if (!mux)
@@ -55,7 +214,8 @@ struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *p
        div->lock = &imx_ccm_lock;
        div->flags = CLK_DIVIDER_ROUND_CLOSEST;
 
-       if (!(readl(reg + AUTHEN_OFFSET) & TZ_NS_MASK))
+       authen = readl(reg + AUTHEN_OFFSET);
+       if (!(authen & TZ_NS_MASK) || !(authen & BIT(WHITE_LIST_SHIFT + domain_id)))
                clk_ro = true;
 
        if (clk_ro) {
@@ -74,9 +234,10 @@ struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *p
                gate->flags = CLK_GATE_SET_TO_DISABLE;
 
                hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
-                                              mux_hw, &clk_mux_ops, div_hw,
-                                              &clk_divider_ops, gate_hw,
-                                              &clk_gate_ops, flags | CLK_SET_RATE_NO_REPARENT);
+                                              mux_hw, &imx93_clk_composite_mux_ops, div_hw,
+                                              &imx93_clk_composite_divider_ops, gate_hw,
+                                              &imx93_clk_composite_gate_ops,
+                                              flags | CLK_SET_RATE_NO_REPARENT);
        }
 
        if (IS_ERR(hw))
diff --git a/drivers/clk/imx/clk-gate-93.c b/drivers/clk/imx/clk-gate-93.c
new file mode 100644 (file)
index 0000000..ceb56b2
--- /dev/null
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2022 NXP
+ *
+ * Peng Fan <peng.fan@nxp.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/slab.h>
+
+#include "clk.h"
+
+#define DIRECT_OFFSET          0x0
+
+/*
+ * 0b000 - LPCG will be OFF in any CPU mode.
+ * 0b100 - LPCG will be ON in any CPU mode.
+ */
+#define LPM_SETTING_OFF                0x0
+#define LPM_SETTING_ON         0x4
+
+#define LPM_CUR_OFFSET         0x1c
+
+#define AUTHEN_OFFSET          0x30
+#define CPULPM_EN              BIT(2)
+#define TZ_NS_SHIFT            9
+#define TZ_NS_MASK             BIT(9)
+
+#define WHITE_LIST_SHIFT       16
+
+struct imx93_clk_gate {
+       struct clk_hw hw;
+       void __iomem    *reg;
+       u32             bit_idx;
+       u32             val;
+       u32             mask;
+       spinlock_t      *lock;
+       unsigned int    *share_count;
+};
+
+#define to_imx93_clk_gate(_hw) container_of(_hw, struct imx93_clk_gate, hw)
+
+static void imx93_clk_gate_do_hardware(struct clk_hw *hw, bool enable)
+{
+       struct imx93_clk_gate *gate = to_imx93_clk_gate(hw);
+       u32 val;
+
+       val = readl(gate->reg + AUTHEN_OFFSET);
+       if (val & CPULPM_EN) {
+               val = enable ? LPM_SETTING_ON : LPM_SETTING_OFF;
+               writel(val, gate->reg + LPM_CUR_OFFSET);
+       } else {
+               val = readl(gate->reg + DIRECT_OFFSET);
+               val &= ~(gate->mask << gate->bit_idx);
+               if (enable)
+                       val |= (gate->val & gate->mask) << gate->bit_idx;
+               writel(val, gate->reg + DIRECT_OFFSET);
+       }
+}
+
+static int imx93_clk_gate_enable(struct clk_hw *hw)
+{
+       struct imx93_clk_gate *gate = to_imx93_clk_gate(hw);
+       unsigned long flags;
+
+       spin_lock_irqsave(gate->lock, flags);
+
+       if (gate->share_count && (*gate->share_count)++ > 0)
+               goto out;
+
+       imx93_clk_gate_do_hardware(hw, true);
+out:
+       spin_unlock_irqrestore(gate->lock, flags);
+
+       return 0;
+}
+
+static void imx93_clk_gate_disable(struct clk_hw *hw)
+{
+       struct imx93_clk_gate *gate = to_imx93_clk_gate(hw);
+       unsigned long flags;
+
+       spin_lock_irqsave(gate->lock, flags);
+
+       if (gate->share_count) {
+               if (WARN_ON(*gate->share_count == 0))
+                       goto out;
+               else if (--(*gate->share_count) > 0)
+                       goto out;
+       }
+
+       imx93_clk_gate_do_hardware(hw, false);
+out:
+       spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static int imx93_clk_gate_reg_is_enabled(struct imx93_clk_gate *gate)
+{
+       u32 val = readl(gate->reg + AUTHEN_OFFSET);
+
+       if (val & CPULPM_EN) {
+               val = readl(gate->reg + LPM_CUR_OFFSET);
+               if (val == LPM_SETTING_ON)
+                       return 1;
+       } else {
+               val = readl(gate->reg);
+               if (((val >> gate->bit_idx) & gate->mask) == gate->val)
+                       return 1;
+       }
+
+       return 0;
+}
+
+static int imx93_clk_gate_is_enabled(struct clk_hw *hw)
+{
+       struct imx93_clk_gate *gate = to_imx93_clk_gate(hw);
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(gate->lock, flags);
+
+       ret = imx93_clk_gate_reg_is_enabled(gate);
+
+       spin_unlock_irqrestore(gate->lock, flags);
+
+       return ret;
+}
+
+static void imx93_clk_gate_disable_unused(struct clk_hw *hw)
+{
+       struct imx93_clk_gate *gate = to_imx93_clk_gate(hw);
+       unsigned long flags;
+
+       spin_lock_irqsave(gate->lock, flags);
+
+       if (!gate->share_count || *gate->share_count == 0)
+               imx93_clk_gate_do_hardware(hw, false);
+
+       spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static const struct clk_ops imx93_clk_gate_ops = {
+       .enable = imx93_clk_gate_enable,
+       .disable = imx93_clk_gate_disable,
+       .disable_unused = imx93_clk_gate_disable_unused,
+       .is_enabled = imx93_clk_gate_is_enabled,
+};
+
+static const struct clk_ops imx93_clk_gate_ro_ops = {
+       .is_enabled = imx93_clk_gate_is_enabled,
+};
+
+struct clk_hw *imx93_clk_gate(struct device *dev, const char *name, const char *parent_name,
+                             unsigned long flags, void __iomem *reg, u32 bit_idx, u32 val,
+                             u32 mask, u32 domain_id, unsigned int *share_count)
+{
+       struct imx93_clk_gate *gate;
+       struct clk_hw *hw;
+       struct clk_init_data init;
+       int ret;
+       u32 authen;
+
+       gate = kzalloc(sizeof(struct imx93_clk_gate), GFP_KERNEL);
+       if (!gate)
+               return ERR_PTR(-ENOMEM);
+
+       gate->reg = reg;
+       gate->lock = &imx_ccm_lock;
+       gate->bit_idx = bit_idx;
+       gate->val = val;
+       gate->mask = mask;
+       gate->share_count = share_count;
+
+       init.name = name;
+       init.ops = &imx93_clk_gate_ops;
+       init.flags = flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE;
+       init.parent_names = parent_name ? &parent_name : NULL;
+       init.num_parents = parent_name ? 1 : 0;
+
+       gate->hw.init = &init;
+       hw = &gate->hw;
+
+       authen = readl(reg + AUTHEN_OFFSET);
+       if (!(authen & TZ_NS_MASK) || !(authen & BIT(WHITE_LIST_SHIFT + domain_id)))
+               init.ops = &imx93_clk_gate_ro_ops;
+
+       ret = clk_hw_register(dev, hw);
+       if (ret) {
+               kfree(gate);
+               return ERR_PTR(ret);
+       }
+
+       return hw;
+}
+EXPORT_SYMBOL_GPL(imx93_clk_gate);
index e89db56..652ae58 100644 (file)
@@ -665,8 +665,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
        hws[IMX8MP_CLK_CAN1_ROOT] = imx_clk_hw_gate2("can1_root_clk", "can1", ccm_base + 0x4350, 0);
        hws[IMX8MP_CLK_CAN2_ROOT] = imx_clk_hw_gate2("can2_root_clk", "can2", ccm_base + 0x4360, 0);
        hws[IMX8MP_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_root_clk", "ipg_root", ccm_base + 0x43a0, 0);
-       hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0);
        hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0);
+       hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0);
        hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_core", ccm_base + 0x4450, 0);
        hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core", ccm_base + 0x4460, 0);
        hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0);
index f5c9fa4..f6a9e77 100644 (file)
@@ -28,6 +28,11 @@ enum clk_sel {
        MAX_SEL
 };
 
+static u32 share_count_sai1;
+static u32 share_count_sai2;
+static u32 share_count_sai3;
+static u32 share_count_mub;
+
 static const char *parent_names[MAX_SEL][4] = {
        {"osc_24m", "sys_pll_pfd0_div2", "sys_pll_pfd1_div2", "video_pll"},
        {"osc_24m", "sys_pll_pfd0_div2", "sys_pll_pfd1_div2", "sys_pll_pfd2_div2"},
@@ -146,6 +151,7 @@ static const struct imx93_clk_ccgr {
        char *parent_name;
        u32 off;
        unsigned long flags;
+       u32 *shared_count;
 } ccgr_array[] = {
        { IMX93_CLK_A55_GATE,           "a55",          "a55_root",             0x8000, },
        /* M33 critical clk for system run */
@@ -158,8 +164,10 @@ static const struct imx93_clk_ccgr {
        { IMX93_CLK_WDOG5_GATE,         "wdog5",        "osc_24m",              0x8400, },
        { IMX93_CLK_SEMA1_GATE,         "sema1",        "bus_aon_root",         0x8440, },
        { IMX93_CLK_SEMA2_GATE,         "sema2",        "bus_wakeup_root",      0x8480, },
-       { IMX93_CLK_MU_A_GATE,          "mu_a",         "bus_aon_root",         0x84c0, },
-       { IMX93_CLK_MU_B_GATE,          "mu_b",         "bus_aon_root",         0x8500, },
+       { IMX93_CLK_MU1_A_GATE,         "mu1_a",        "bus_aon_root",         0x84c0, CLK_IGNORE_UNUSED },
+       { IMX93_CLK_MU2_A_GATE,         "mu2_a",        "bus_wakeup_root",      0x84c0, CLK_IGNORE_UNUSED },
+       { IMX93_CLK_MU1_B_GATE,         "mu1_b",        "bus_aon_root",         0x8500, 0, &share_count_mub },
+       { IMX93_CLK_MU2_B_GATE,         "mu2_b",        "bus_wakeup_root",      0x8500, 0, &share_count_mub },
        { IMX93_CLK_EDMA1_GATE,         "edma1",        "m33_root",             0x8540, },
        { IMX93_CLK_EDMA2_GATE,         "edma2",        "wakeup_axi_root",      0x8580, },
        { IMX93_CLK_FLEXSPI1_GATE,      "flexspi",      "flexspi_root",         0x8640, },
@@ -210,9 +218,12 @@ static const struct imx93_clk_ccgr {
        { IMX93_CLK_USDHC1_GATE,        "usdhc1",       "usdhc1_root",          0x9380, },
        { IMX93_CLK_USDHC2_GATE,        "usdhc2",       "usdhc2_root",          0x93c0, },
        { IMX93_CLK_USDHC3_GATE,        "usdhc3",       "usdhc3_root",          0x9400, },
-       { IMX93_CLK_SAI1_GATE,          "sai1",         "sai1_root",            0x9440, },
-       { IMX93_CLK_SAI2_GATE,          "sai2",         "sai2_root",            0x9480, },
-       { IMX93_CLK_SAI3_GATE,          "sai3",         "sai3_root",            0x94c0, },
+       { IMX93_CLK_SAI1_GATE,          "sai1",         "sai1_root",            0x9440, 0, &share_count_sai1},
+       { IMX93_CLK_SAI1_IPG,           "sai1_ipg_clk", "bus_aon_root",         0x9440, 0, &share_count_sai1},
+       { IMX93_CLK_SAI2_GATE,          "sai2",         "sai2_root",            0x9480, 0, &share_count_sai2},
+       { IMX93_CLK_SAI2_IPG,           "sai2_ipg_clk", "bus_wakeup_root",      0x9480, 0, &share_count_sai2},
+       { IMX93_CLK_SAI3_GATE,          "sai3",         "sai3_root",            0x94c0, 0, &share_count_sai3},
+       { IMX93_CLK_SAI3_IPG,           "sai3_ipg_clk", "bus_wakeup_root",      0x94c0, 0, &share_count_sai3},
        { IMX93_CLK_MIPI_CSI_GATE,      "mipi_csi",     "media_apb_root",       0x9580, },
        { IMX93_CLK_MIPI_DSI_GATE,      "mipi_dsi",     "media_apb_root",       0x95c0, },
        { IMX93_CLK_LVDS_GATE,          "lvds",         "media_ldb_root",       0x9600, },
@@ -293,16 +304,15 @@ static int imx93_clocks_probe(struct platform_device *pdev)
                root = &root_array[i];
                clks[root->clk] = imx93_clk_composite_flags(root->name,
                                                            parent_names[root->sel],
-                                                           4, base + root->off,
+                                                           4, base + root->off, 3,
                                                            root->flags);
        }
 
        for (i = 0; i < ARRAY_SIZE(ccgr_array); i++) {
                ccgr = &ccgr_array[i];
-               clks[ccgr->clk] = imx_clk_hw_gate4_flags(ccgr->name,
-                                                        ccgr->parent_name,
-                                                        base + ccgr->off, 0,
-                                                        ccgr->flags);
+               clks[ccgr->clk] = imx93_clk_gate(NULL, ccgr->name, ccgr->parent_name,
+                                                ccgr->flags, base + ccgr->off, 0, 1, 1, 3,
+                                                ccgr->shared_count);
        }
 
        imx_check_clk_hws(clks, IMX93_CLK_END);
index c56e406..1e6870f 100644 (file)
@@ -695,7 +695,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
                pr_warn("%s: failed to attached the power domain %d\n",
                        name, ret);
 
-       platform_device_add(pdev);
+       ret = platform_device_add(pdev);
+       if (ret) {
+               platform_device_put(pdev);
+               return ERR_PTR(ret);
+       }
 
        /* For API backwards compatiblilty, simply return NULL for success */
        return NULL;
index 5061a06..dd49f90 100644 (file)
@@ -445,11 +445,16 @@ struct clk_hw *imx93_clk_composite_flags(const char *name,
                                         const char * const *parent_names,
                                         int num_parents,
                                         void __iomem *reg,
+                                        u32 domain_id,
                                         unsigned long flags);
-#define imx93_clk_composite(name, parent_names, num_parents, reg) \
-       imx93_clk_composite_flags(name, parent_names, num_parents, reg, \
+#define imx93_clk_composite(name, parent_names, num_parents, reg, domain_id) \
+       imx93_clk_composite_flags(name, parent_names, num_parents, reg, domain_id \
                                  CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
 
+struct clk_hw *imx93_clk_gate(struct device *dev, const char *name, const char *parent_name,
+                             unsigned long flags, void __iomem *reg, u32 bit_idx, u32 val,
+                             u32 mask, u32 domain_id, unsigned int *share_count);
+
 struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name,
                unsigned long flags, void __iomem *reg, u8 shift, u8 width,
                u8 clk_divider_flags, const struct clk_div_table *table,
index d5936cf..843cea0 100644 (file)
@@ -259,6 +259,43 @@ config COMMON_CLK_MT6779_AUDSYS
        help
          This driver supports Mediatek MT6779 audsys clocks.
 
+config COMMON_CLK_MT6795
+       tristate "Clock driver for MediaTek MT6795"
+       depends on ARCH_MEDIATEK || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK
+       help
+         This driver supports MediaTek MT6795 basic clocks and clocks
+         required for various peripherals found on MediaTek.
+
+config COMMON_CLK_MT6795_MFGCFG
+       tristate "Clock driver for MediaTek MT6795 mfgcfg"
+       depends on COMMON_CLK_MT6795
+       default COMMON_CLK_MT6795
+       help
+         This driver supports MediaTek MT6795 mfgcfg clocks.
+
+config COMMON_CLK_MT6795_MMSYS
+       tristate "Clock driver for MediaTek MT6795 mmsys"
+       depends on COMMON_CLK_MT6795
+       default COMMON_CLK_MT6795
+       help
+         This driver supports MediaTek MT6795 mmsys clocks.
+
+config COMMON_CLK_MT6795_VDECSYS
+       tristate "Clock driver for MediaTek MT6795 VDECSYS"
+       depends on COMMON_CLK_MT6795
+       default COMMON_CLK_MT6795
+       help
+         This driver supports MediaTek MT6795 vdecsys clocks.
+
+config COMMON_CLK_MT6795_VENCSYS
+       tristate "Clock driver for MediaTek MT6795 VENCSYS"
+       depends on COMMON_CLK_MT6795
+       default COMMON_CLK_MT6795
+       help
+         This driver supports MediaTek MT6795 vencsys clocks.
+
 config COMMON_CLK_MT6797
        bool "Clock driver for MediaTek MT6797"
        depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
@@ -608,6 +645,56 @@ config COMMON_CLK_MT8195
         help
           This driver supports MediaTek MT8195 clocks.
 
+config COMMON_CLK_MT8365
+       tristate "Clock driver for MediaTek MT8365"
+       depends on ARCH_MEDIATEK || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK && ARM64
+       help
+         This driver supports MediaTek MT8365 basic clocks.
+
+config COMMON_CLK_MT8365_APU
+       tristate "Clock driver for MediaTek MT8365 apu"
+       depends on COMMON_CLK_MT8365
+       default COMMON_CLK_MT8365
+       help
+         This driver supports MediaTek MT8365 apu clocks.
+
+config COMMON_CLK_MT8365_CAM
+       tristate "Clock driver for MediaTek MT8365 cam"
+       depends on COMMON_CLK_MT8365
+       default COMMON_CLK_MT8365
+       help
+         This driver supports MediaTek MT8365 cam clocks.
+
+config COMMON_CLK_MT8365_MFG
+       tristate "Clock driver for MediaTek MT8365 mfg"
+       depends on COMMON_CLK_MT8365
+       default COMMON_CLK_MT8365
+       help
+         This driver supports MediaTek MT8365 mfg clocks.
+
+config COMMON_CLK_MT8365_MMSYS
+       tristate "Clock driver for MediaTek MT8365 mmsys"
+       depends on COMMON_CLK_MT8365
+       default COMMON_CLK_MT8365
+       help
+         This driver supports MediaTek MT8365 mmsys clocks.
+
+config COMMON_CLK_MT8365_VDEC
+       tristate "Clock driver for MediaTek MT8365 vdec"
+       depends on COMMON_CLK_MT8365
+       default COMMON_CLK_MT8365
+       help
+         This driver supports MediaTek MT8365 vdec clocks.
+
+config COMMON_CLK_MT8365_VENC
+       tristate "Clock driver for MediaTek MT8365 venc"
+       depends on COMMON_CLK_MT8365
+       default COMMON_CLK_MT8365
+       help
+         This driver supports MediaTek MT8365 venc clocks.
+
 config COMMON_CLK_MT8516
        bool "Clock driver for MediaTek MT8516"
        depends on ARCH_MEDIATEK || COMPILE_TEST
index caf2ce9..ea3b732 100644 (file)
@@ -17,6 +17,12 @@ obj-$(CONFIG_COMMON_CLK_MT6779_VDECSYS) += clk-mt6779-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT6779_VENCSYS) += clk-mt6779-venc.o
 obj-$(CONFIG_COMMON_CLK_MT6779_MFGCFG) += clk-mt6779-mfg.o
 obj-$(CONFIG_COMMON_CLK_MT6779_AUDSYS) += clk-mt6779-aud.o
+obj-$(CONFIG_COMMON_CLK_MT6795) += clk-mt6795-apmixedsys.o clk-mt6795-infracfg.o \
+                                  clk-mt6795-pericfg.o clk-mt6795-topckgen.o
+obj-$(CONFIG_COMMON_CLK_MT6795_MFGCFG) += clk-mt6795-mfg.o
+obj-$(CONFIG_COMMON_CLK_MT6795_MMSYS) += clk-mt6795-mm.o
+obj-$(CONFIG_COMMON_CLK_MT6795_VDECSYS) += clk-mt6795-vdecsys.o
+obj-$(CONFIG_COMMON_CLK_MT6795_VENCSYS) += clk-mt6795-vencsys.o
 obj-$(CONFIG_COMMON_CLK_MT6797) += clk-mt6797.o
 obj-$(CONFIG_COMMON_CLK_MT6797_IMGSYS) += clk-mt6797-img.o
 obj-$(CONFIG_COMMON_CLK_MT6797_MMSYS) += clk-mt6797-mm.o
@@ -97,5 +103,12 @@ obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o
                                   clk-mt8195-venc.o clk-mt8195-vpp0.o clk-mt8195-vpp1.o \
                                   clk-mt8195-wpe.o clk-mt8195-imp_iic_wrap.o \
                                   clk-mt8195-apusys_pll.o
+obj-$(CONFIG_COMMON_CLK_MT8365) += clk-mt8365.o
+obj-$(CONFIG_COMMON_CLK_MT8365_APU) += clk-mt8365-apu.o
+obj-$(CONFIG_COMMON_CLK_MT8365_CAM) += clk-mt8365-cam.o
+obj-$(CONFIG_COMMON_CLK_MT8365_MFG) += clk-mt8365-mfg.o
+obj-$(CONFIG_COMMON_CLK_MT8365_MMSYS) += clk-mt8365-mm.o
+obj-$(CONFIG_COMMON_CLK_MT8365_VDEC) += clk-mt8365-vdec.o
+obj-$(CONFIG_COMMON_CLK_MT8365_VENC) += clk-mt8365-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
index fc3d414..60e34f1 100644 (file)
@@ -70,7 +70,7 @@ static const struct clk_ops mtk_ref2usb_tx_ops = {
        .unprepare      = mtk_ref2usb_tx_unprepare,
 };
 
-struct clk_hw * __init mtk_clk_register_ref2usb_tx(const char *name,
+struct clk_hw *mtk_clk_register_ref2usb_tx(const char *name,
                        const char *parent_name, void __iomem *reg)
 {
        struct mtk_ref2usb_tx *tx;
@@ -98,5 +98,15 @@ struct clk_hw * __init mtk_clk_register_ref2usb_tx(const char *name,
 
        return &tx->hw;
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_ref2usb_tx);
+
+void mtk_clk_unregister_ref2usb_tx(struct clk_hw *hw)
+{
+       struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
+
+       clk_hw_unregister(hw);
+       kfree(tx);
+}
+EXPORT_SYMBOL_GPL(mtk_clk_unregister_ref2usb_tx);
 
 MODULE_LICENSE("GPL");
index 2b5d485..25618ef 100644 (file)
@@ -150,6 +150,7 @@ err:
 
        return PTR_ERR(hw);
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_cpumuxes);
 
 void mtk_clk_unregister_cpumuxes(const struct mtk_composite *clks, int num,
                                 struct clk_hw_onecell_data *clk_data)
@@ -166,5 +167,6 @@ void mtk_clk_unregister_cpumuxes(const struct mtk_composite *clks, int num,
                clk_data->hws[mux->id] = ERR_PTR(-ENOENT);
        }
 }
+EXPORT_SYMBOL_GPL(mtk_clk_unregister_cpumuxes);
 
 MODULE_LICENSE("GPL");
index 4218062..0c86713 100644 (file)
@@ -261,6 +261,7 @@ err:
 
        return PTR_ERR(hw);
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_gates_with_dev);
 
 int mtk_clk_register_gates(struct device_node *node,
                           const struct mtk_gate *clks, int num,
index 662a8ab..435ed48 100644 (file)
@@ -94,33 +94,23 @@ static const struct mtk_gate bdp_clks[] = {
        GATE_BDP1(CLK_BDP_HDMI_MON, "hdmi_mon", "hdmi_0_pll340m", 16),
 };
 
-static const struct of_device_id of_match_clk_mt2701_bdp[] = {
-       { .compatible = "mediatek,mt2701-bdpsys", },
-       {}
+static const struct mtk_clk_desc bdp_desc = {
+       .clks = bdp_clks,
+       .num_clks = ARRAY_SIZE(bdp_clks),
 };
 
-static int clk_mt2701_bdp_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_BDP_NR);
-
-       mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks),
-                                               clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-       if (r)
-               dev_err(&pdev->dev,
-                       "could not register clock provider: %s: %d\n",
-                       pdev->name, r);
-
-       return r;
-}
+static const struct of_device_id of_match_clk_mt2701_bdp[] = {
+       {
+               .compatible = "mediatek,mt2701-bdpsys",
+               .data = &bdp_desc,
+       }, {
+               /* sentinel */
+       }
+};
 
 static struct platform_driver clk_mt2701_bdp_drv = {
-       .probe = clk_mt2701_bdp_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt2701-bdp",
                .of_match_table = of_match_clk_mt2701_bdp,
index c4f3cd2..7e53deb 100644 (file)
@@ -36,33 +36,23 @@ static const struct mtk_gate img_clks[] = {
        GATE_IMG(CLK_IMG_VENC, "img_venc", "mm_sel", 9),
 };
 
-static const struct of_device_id of_match_clk_mt2701_img[] = {
-       { .compatible = "mediatek,mt2701-imgsys", },
-       {}
+static const struct mtk_clk_desc img_desc = {
+       .clks = img_clks,
+       .num_clks = ARRAY_SIZE(img_clks),
 };
 
-static int clk_mt2701_img_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_IMG_NR);
-
-       mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
-                                               clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-       if (r)
-               dev_err(&pdev->dev,
-                       "could not register clock provider: %s: %d\n",
-                       pdev->name, r);
-
-       return r;
-}
+static const struct of_device_id of_match_clk_mt2701_img[] = {
+       {
+               .compatible = "mediatek,mt2701-imgsys",
+               .data = &img_desc,
+       }, {
+               /* sentinel */
+       }
+};
 
 static struct platform_driver clk_mt2701_img_drv = {
-       .probe = clk_mt2701_img_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt2701-img",
                .of_match_table = of_match_clk_mt2701_img,
index a2f1811..d3089da 100644 (file)
@@ -47,33 +47,23 @@ static const struct mtk_gate vdec_clks[] = {
        GATE_VDEC1(CLK_VDEC_LARB, "vdec_larb_cken", "mm_sel", 0),
 };
 
-static const struct of_device_id of_match_clk_mt2701_vdec[] = {
-       { .compatible = "mediatek,mt2701-vdecsys", },
-       {}
+static const struct mtk_clk_desc vdec_desc = {
+       .clks = vdec_clks,
+       .num_clks = ARRAY_SIZE(vdec_clks),
 };
 
-static int clk_mt2701_vdec_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_VDEC_NR);
-
-       mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
-                                               clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-       if (r)
-               dev_err(&pdev->dev,
-                       "could not register clock provider: %s: %d\n",
-                       pdev->name, r);
-
-       return r;
-}
+static const struct of_device_id of_match_clk_mt2701_vdec[] = {
+       {
+               .compatible = "mediatek,mt2701-vdecsys",
+               .data = &vdec_desc,
+       }, {
+               /* sentinel */
+       }
+};
 
 static struct platform_driver clk_mt2701_vdec_drv = {
-       .probe = clk_mt2701_vdec_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt2701-vdec",
                .of_match_table = of_match_clk_mt2701_vdec,
index 9acab43..684d03e 100644 (file)
@@ -58,33 +58,23 @@ static const struct mtk_gate bdp_clks[] = {
        GATE_BDP(CLK_BDP_TVD_CBUS, "bdp_tvd_cbus", "mm_sel", 30),
 };
 
-static int clk_mt2712_bdp_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_BDP_NR_CLK);
-
-       mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks),
-                       clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
-       if (r != 0)
-               pr_err("%s(): could not register clock provider: %d\n",
-                       __func__, r);
-
-       return r;
-}
+static const struct mtk_clk_desc bdp_desc = {
+       .clks = bdp_clks,
+       .num_clks = ARRAY_SIZE(bdp_clks),
+};
 
 static const struct of_device_id of_match_clk_mt2712_bdp[] = {
-       { .compatible = "mediatek,mt2712-bdpsys", },
-       {}
+       {
+               .compatible = "mediatek,mt2712-bdpsys",
+               .data = &bdp_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt2712_bdp_drv = {
-       .probe = clk_mt2712_bdp_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt2712-bdp",
                .of_match_table = of_match_clk_mt2712_bdp,
index 5cc143e..335049c 100644 (file)
@@ -36,33 +36,23 @@ static const struct mtk_gate img_clks[] = {
        GATE_IMG(CLK_IMG_CAM_SV2_EN, "img_cam_sv2_en", "mm_sel", 11),
 };
 
-static int clk_mt2712_img_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
-
-       mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
-                       clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
-       if (r != 0)
-               pr_err("%s(): could not register clock provider: %d\n",
-                       __func__, r);
-
-       return r;
-}
+static const struct mtk_clk_desc img_desc = {
+       .clks = img_clks,
+       .num_clks = ARRAY_SIZE(img_clks),
+};
 
 static const struct of_device_id of_match_clk_mt2712_img[] = {
-       { .compatible = "mediatek,mt2712-imgsys", },
-       {}
+       {
+               .compatible = "mediatek,mt2712-imgsys",
+               .data = &img_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt2712_img_drv = {
-       .probe = clk_mt2712_img_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt2712-img",
                .of_match_table = of_match_clk_mt2712_img,
index 31fc303..07ba7c5 100644 (file)
@@ -32,33 +32,23 @@ static const struct mtk_gate jpgdec_clks[] = {
        GATE_JPGDEC(CLK_JPGDEC_JPGDEC, "jpgdec_jpgdec", "jpgdec_sel", 4),
 };
 
-static int clk_mt2712_jpgdec_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_JPGDEC_NR_CLK);
-
-       mtk_clk_register_gates(node, jpgdec_clks, ARRAY_SIZE(jpgdec_clks),
-                       clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
-       if (r != 0)
-               pr_err("%s(): could not register clock provider: %d\n",
-                       __func__, r);
-
-       return r;
-}
+static const struct mtk_clk_desc jpgdec_desc = {
+       .clks = jpgdec_clks,
+       .num_clks = ARRAY_SIZE(jpgdec_clks),
+};
 
 static const struct of_device_id of_match_clk_mt2712_jpgdec[] = {
-       { .compatible = "mediatek,mt2712-jpgdecsys", },
-       {}
+       {
+               .compatible = "mediatek,mt2712-jpgdecsys",
+               .data = &jpgdec_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt2712_jpgdec_drv = {
-       .probe = clk_mt2712_jpgdec_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt2712-jpgdec",
                .of_match_table = of_match_clk_mt2712_jpgdec,
index a4d0967..42f8cf3 100644 (file)
@@ -31,33 +31,23 @@ static const struct mtk_gate mfg_clks[] = {
        GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0),
 };
 
-static int clk_mt2712_mfg_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_MFG_NR_CLK);
-
-       mtk_clk_register_gates(node, mfg_clks, ARRAY_SIZE(mfg_clks),
-                       clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
-       if (r != 0)
-               pr_err("%s(): could not register clock provider: %d\n",
-                       __func__, r);
-
-       return r;
-}
+static const struct mtk_clk_desc mfg_desc = {
+       .clks = mfg_clks,
+       .num_clks = ARRAY_SIZE(mfg_clks),
+};
 
 static const struct of_device_id of_match_clk_mt2712_mfg[] = {
-       { .compatible = "mediatek,mt2712-mfgcfg", },
-       {}
+       {
+               .compatible = "mediatek,mt2712-mfgcfg",
+               .data = &mfg_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt2712_mfg_drv = {
-       .probe = clk_mt2712_mfg_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt2712-mfg",
                .of_match_table = of_match_clk_mt2712_mfg,
index af13f43..6296ed5 100644 (file)
@@ -50,33 +50,23 @@ static const struct mtk_gate vdec_clks[] = {
        GATE_VDEC1(CLK_VDEC_IMGRZ_CKEN, "vdec_imgrz_cken", "vdec_sel", 1),
 };
 
-static int clk_mt2712_vdec_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_VDEC_NR_CLK);
-
-       mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
-                       clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
-       if (r != 0)
-               pr_err("%s(): could not register clock provider: %d\n",
-                       __func__, r);
-
-       return r;
-}
+static const struct mtk_clk_desc vdec_desc = {
+       .clks = vdec_clks,
+       .num_clks = ARRAY_SIZE(vdec_clks),
+};
 
 static const struct of_device_id of_match_clk_mt2712_vdec[] = {
-       { .compatible = "mediatek,mt2712-vdecsys", },
-       {}
+       {
+               .compatible = "mediatek,mt2712-vdecsys",
+               .data = &vdec_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt2712_vdec_drv = {
-       .probe = clk_mt2712_vdec_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt2712-vdec",
                .of_match_table = of_match_clk_mt2712_vdec,
index abc08a0..b9bfc35 100644 (file)
@@ -33,33 +33,23 @@ static const struct mtk_gate venc_clks[] = {
        GATE_VENC(CLK_VENC_SMI_LARB6, "venc_smi_larb6", "jpgdec_sel", 12),
 };
 
-static int clk_mt2712_venc_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK);
-
-       mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
-                       clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
-       if (r != 0)
-               pr_err("%s(): could not register clock provider: %d\n",
-                       __func__, r);
-
-       return r;
-}
+static const struct mtk_clk_desc venc_desc = {
+       .clks = venc_clks,
+       .num_clks = ARRAY_SIZE(venc_clks),
+};
 
 static const struct of_device_id of_match_clk_mt2712_venc[] = {
-       { .compatible = "mediatek,mt2712-vencsys", },
-       {}
+       {
+               .compatible = "mediatek,mt2712-vencsys",
+               .data = &venc_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt2712_venc_drv = {
-       .probe = clk_mt2712_venc_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt2712-venc",
                .of_match_table = of_match_clk_mt2712_venc,
index 9c6e9ca..0aa6c0d 100644 (file)
@@ -64,33 +64,23 @@ static const struct mtk_gate audio_clks[] = {
                    "audio_ck", 7),
 };
 
-static int clk_mt6765_audio_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_AUDIO_NR_CLK);
-
-       mtk_clk_register_gates(node, audio_clks,
-                              ARRAY_SIZE(audio_clks), clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
-       if (r)
-               pr_err("%s(): could not register clock provider: %d\n",
-                      __func__, r);
-
-       return r;
-}
+static const struct mtk_clk_desc audio_desc = {
+       .clks = audio_clks,
+       .num_clks = ARRAY_SIZE(audio_clks),
+};
 
 static const struct of_device_id of_match_clk_mt6765_audio[] = {
-       { .compatible = "mediatek,mt6765-audsys", },
-       {}
+       {
+               .compatible = "mediatek,mt6765-audsys",
+               .data = &audio_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt6765_audio_drv = {
-       .probe = clk_mt6765_audio_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6765-audio",
                .of_match_table = of_match_clk_mt6765_audio,
index 2586d3a..25f2bef 100644 (file)
@@ -39,32 +39,23 @@ static const struct mtk_gate cam_clks[] = {
        GATE_CAM(CLK_CAM_CCU, "cam_ccu", "mm_ck", 12),
 };
 
-static int clk_mt6765_cam_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_CAM_NR_CLK);
-
-       mtk_clk_register_gates(node, cam_clks, ARRAY_SIZE(cam_clks), clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
-       if (r)
-               pr_err("%s(): could not register clock provider: %d\n",
-                      __func__, r);
-
-       return r;
-}
+static const struct mtk_clk_desc cam_desc = {
+       .clks = cam_clks,
+       .num_clks = ARRAY_SIZE(cam_clks),
+};
 
 static const struct of_device_id of_match_clk_mt6765_cam[] = {
-       { .compatible = "mediatek,mt6765-camsys", },
-       {}
+       {
+               .compatible = "mediatek,mt6765-camsys",
+               .data = &cam_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt6765_cam_drv = {
-       .probe = clk_mt6765_cam_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6765-cam",
                .of_match_table = of_match_clk_mt6765_cam,
index 8cc95b9..a62303e 100644 (file)
@@ -35,32 +35,23 @@ static const struct mtk_gate img_clks[] = {
        GATE_IMG(CLK_IMG_RSC, "img_rsc", "mm_ck", 5),
 };
 
-static int clk_mt6765_img_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
-
-       mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks), clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
-       if (r)
-               pr_err("%s(): could not register clock provider: %d\n",
-                      __func__, r);
-
-       return r;
-}
+static const struct mtk_clk_desc img_desc = {
+       .clks = img_clks,
+       .num_clks = ARRAY_SIZE(img_clks),
+};
 
 static const struct of_device_id of_match_clk_mt6765_img[] = {
-       { .compatible = "mediatek,mt6765-imgsys", },
-       {}
+       {
+               .compatible = "mediatek,mt6765-imgsys",
+               .data = &img_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt6765_img_drv = {
-       .probe = clk_mt6765_img_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6765-img",
                .of_match_table = of_match_clk_mt6765_img,
index c816e26..25c829f 100644 (file)
@@ -32,33 +32,23 @@ static const struct mtk_gate mipi0a_clks[] = {
                    "mipi0a_csr_0a", "f_fseninf_ck", 1),
 };
 
-static int clk_mt6765_mipi0a_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_MIPI0A_NR_CLK);
-
-       mtk_clk_register_gates(node, mipi0a_clks,
-                              ARRAY_SIZE(mipi0a_clks), clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
-       if (r)
-               pr_err("%s(): could not register clock provider: %d\n",
-                      __func__, r);
-
-       return r;
-}
+static const struct mtk_clk_desc mipi0a_desc = {
+       .clks = mipi0a_clks,
+       .num_clks = ARRAY_SIZE(mipi0a_clks),
+};
 
 static const struct of_device_id of_match_clk_mt6765_mipi0a[] = {
-       { .compatible = "mediatek,mt6765-mipi0a", },
-       {}
+       {
+               .compatible = "mediatek,mt6765-mipi0a",
+               .data = &mipi0a_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt6765_mipi0a_drv = {
-       .probe = clk_mt6765_mipi0a_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6765-mipi0a",
                .of_match_table = of_match_clk_mt6765_mipi0a,
index ee6d3b8..bda7746 100644 (file)
@@ -61,32 +61,23 @@ static const struct mtk_gate mm_clks[] = {
        GATE_MM(CLK_MM_F26M_HRTWT, "mm_hrtwt", "f_f26m_ck", 29),
 };
 
-static int clk_mt6765_mm_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
-
-       mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks), clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
-       if (r)
-               pr_err("%s(): could not register clock provider: %d\n",
-                      __func__, r);
-
-       return r;
-}
+static const struct mtk_clk_desc mm_desc = {
+       .clks = mm_clks,
+       .num_clks = ARRAY_SIZE(mm_clks),
+};
 
 static const struct of_device_id of_match_clk_mt6765_mm[] = {
-       { .compatible = "mediatek,mt6765-mmsys", },
-       {}
+       {
+               .compatible = "mediatek,mt6765-mmsys",
+               .data = &mm_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt6765_mm_drv = {
-       .probe = clk_mt6765_mm_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6765-mm",
                .of_match_table = of_match_clk_mt6765_mm,
index d804597..2bc1fbd 100644 (file)
@@ -34,33 +34,23 @@ static const struct mtk_gate venc_clks[] = {
        GATE_VENC(CLK_VENC_SET3_VDEC, "venc_set3_vdec", "mm_ck", 12),
 };
 
-static int clk_mt6765_vcodec_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK);
-
-       mtk_clk_register_gates(node, venc_clks,
-                              ARRAY_SIZE(venc_clks), clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
-       if (r)
-               pr_err("%s(): could not register clock provider: %d\n",
-                      __func__, r);
-
-       return r;
-}
+static const struct mtk_clk_desc venc_desc = {
+       .clks = venc_clks,
+       .num_clks = ARRAY_SIZE(venc_clks),
+};
 
 static const struct of_device_id of_match_clk_mt6765_vcodec[] = {
-       { .compatible = "mediatek,mt6765-vcodecsys", },
-       {}
+       {
+               .compatible = "mediatek,mt6765-vcodecsys",
+               .data = &venc_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt6765_vcodec_drv = {
-       .probe = clk_mt6765_vcodec_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6765-vcodec",
                .of_match_table = of_match_clk_mt6765_vcodec,
index 97e44ab..6e473ae 100644 (file)
@@ -89,26 +89,23 @@ static const struct mtk_gate audio_clks[] = {
                    "audio_h_sel", 31),
 };
 
-static const struct of_device_id of_match_clk_mt6779_aud[] = {
-       { .compatible = "mediatek,mt6779-audio", },
-       {}
+static const struct mtk_clk_desc audio_desc = {
+       .clks = audio_clks,
+       .num_clks = ARRAY_SIZE(audio_clks),
 };
 
-static int clk_mt6779_aud_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_AUD_NR_CLK);
-
-       mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks),
-                              clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct of_device_id of_match_clk_mt6779_aud[] = {
+       {
+               .compatible = "mediatek,mt6779-audio",
+               .data = &audio_desc,
+       }, {
+               /* sentinel */
+       }
+};
 
 static struct platform_driver clk_mt6779_aud_drv = {
-       .probe = clk_mt6779_aud_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6779-aud",
                .of_match_table = of_match_clk_mt6779_aud,
index 9c5117a..7be3db9 100644 (file)
@@ -38,26 +38,23 @@ static const struct mtk_gate cam_clks[] = {
        GATE_CAM(CLK_CAM_FAKE_ENG, "camsys_fake_eng", "cam_sel", 14),
 };
 
-static const struct of_device_id of_match_clk_mt6779_cam[] = {
-       { .compatible = "mediatek,mt6779-camsys", },
-       {}
+static const struct mtk_clk_desc cam_desc = {
+       .clks = cam_clks,
+       .num_clks = ARRAY_SIZE(cam_clks),
 };
 
-static int clk_mt6779_cam_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_CAM_NR_CLK);
-
-       mtk_clk_register_gates(node, cam_clks, ARRAY_SIZE(cam_clks),
-                              clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct of_device_id of_match_clk_mt6779_cam[] = {
+       {
+               .compatible = "mediatek,mt6779-camsys",
+               .data = &cam_desc,
+       }, {
+               /* sentinel */
+       }
+};
 
 static struct platform_driver clk_mt6779_cam_drv = {
-       .probe = clk_mt6779_cam_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6779-cam",
                .of_match_table = of_match_clk_mt6779_cam,
index 8012714..9bc51fc 100644 (file)
@@ -30,26 +30,23 @@ static const struct mtk_gate img_clks[] = {
        GATE_IMG(CLK_IMG_WPE_A, "imgsys_wpe_a", "img_sel", 7),
 };
 
-static const struct of_device_id of_match_clk_mt6779_img[] = {
-       { .compatible = "mediatek,mt6779-imgsys", },
-       {}
+static const struct mtk_clk_desc img_desc = {
+       .clks = img_clks,
+       .num_clks = ARRAY_SIZE(img_clks),
 };
 
-static int clk_mt6779_img_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
-
-       mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
-                              clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct of_device_id of_match_clk_mt6779_img[] = {
+       {
+               .compatible = "mediatek,mt6779-imgsys",
+               .data = &img_desc,
+       }, {
+               /* sentinel */
+       }
+};
 
 static struct platform_driver clk_mt6779_img_drv = {
-       .probe = clk_mt6779_img_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6779-img",
                .of_match_table = of_match_clk_mt6779_img,
index f67814c..92e9d1a 100644 (file)
@@ -32,26 +32,23 @@ static const struct mtk_gate ipe_clks[] = {
        GATE_IPE(CLK_IPE_DPE, "ipe_dpe", "ipe_sel", 6),
 };
 
-static const struct of_device_id of_match_clk_mt6779_ipe[] = {
-       { .compatible = "mediatek,mt6779-ipesys", },
-       {}
+static const struct mtk_clk_desc ipe_desc = {
+       .clks = ipe_clks,
+       .num_clks = ARRAY_SIZE(ipe_clks),
 };
 
-static int clk_mt6779_ipe_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_IPE_NR_CLK);
-
-       mtk_clk_register_gates(node, ipe_clks, ARRAY_SIZE(ipe_clks),
-                              clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct of_device_id of_match_clk_mt6779_ipe[] = {
+       {
+               .compatible = "mediatek,mt6779-ipesys",
+               .data = &ipe_desc,
+       }, {
+               /* sentinel */
+       }
+};
 
 static struct platform_driver clk_mt6779_ipe_drv = {
-       .probe = clk_mt6779_ipe_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6779-ipe",
                .of_match_table = of_match_clk_mt6779_ipe,
index fc7387b..efc793a 100644 (file)
@@ -27,26 +27,23 @@ static const struct mtk_gate mfg_clks[] = {
        GATE_MFG(CLK_MFGCFG_BG3D, "mfg_bg3d", "mfg_sel", 0),
 };
 
-static int clk_mt6779_mfg_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_MFGCFG_NR_CLK);
-
-       mtk_clk_register_gates(node, mfg_clks, ARRAY_SIZE(mfg_clks),
-                              clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct mtk_clk_desc mfg_desc = {
+       .clks = mfg_clks,
+       .num_clks = ARRAY_SIZE(mfg_clks),
+};
 
 static const struct of_device_id of_match_clk_mt6779_mfg[] = {
-       { .compatible = "mediatek,mt6779-mfgcfg", },
-       {}
+       {
+               .compatible = "mediatek,mt6779-mfgcfg",
+               .data = &mfg_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt6779_mfg_drv = {
-       .probe = clk_mt6779_mfg_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6779-mfg",
                .of_match_table = of_match_clk_mt6779_mfg,
index 7e195b0..3209a65 100644 (file)
@@ -39,26 +39,23 @@ static const struct mtk_gate vdec_clks[] = {
        GATE_VDEC1_I(CLK_VDEC_LARB1, "vdec_larb1_cken", "vdec_sel", 0),
 };
 
-static const struct of_device_id of_match_clk_mt6779_vdec[] = {
-       { .compatible = "mediatek,mt6779-vdecsys", },
-       {}
+static const struct mtk_clk_desc vdec_desc = {
+       .clks = vdec_clks,
+       .num_clks = ARRAY_SIZE(vdec_clks),
 };
 
-static int clk_mt6779_vdec_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_VDEC_GCON_NR_CLK);
-
-       mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
-                              clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct of_device_id of_match_clk_mt6779_vdec[] = {
+       {
+               .compatible = "mediatek,mt6779-vdecsys",
+               .data = &vdec_desc,
+       }, {
+               /* sentinel */
+       }
+};
 
 static struct platform_driver clk_mt6779_vdec_drv = {
-       .probe = clk_mt6779_vdec_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6779-vdec",
                .of_match_table = of_match_clk_mt6779_vdec,
index 573efa8..c25035c 100644 (file)
@@ -30,26 +30,23 @@ static const struct mtk_gate venc_clks[] = {
        GATE_VENC_I(CLK_VENC_GCON_GALS, "venc_gals", "venc_sel", 28),
 };
 
-static const struct of_device_id of_match_clk_mt6779_venc[] = {
-       { .compatible = "mediatek,mt6779-vencsys", },
-       {}
+static const struct mtk_clk_desc venc_desc = {
+       .clks = venc_clks,
+       .num_clks = ARRAY_SIZE(venc_clks),
 };
 
-static int clk_mt6779_venc_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_VENC_GCON_NR_CLK);
-
-       mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
-                              clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct of_device_id of_match_clk_mt6779_venc[] = {
+       {
+               .compatible = "mediatek,mt6779-vencsys",
+               .data = &venc_desc,
+       }, {
+               /* sentinel */
+       }
+};
 
 static struct platform_driver clk_mt6779_venc_drv = {
-       .probe = clk_mt6779_venc_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6779-venc",
                .of_match_table = of_match_clk_mt6779_venc,
diff --git a/drivers/clk/mediatek/clk-mt6795-apmixedsys.c b/drivers/clk/mediatek/clk-mt6795-apmixedsys.c
new file mode 100644 (file)
index 0000000..59761c7
--- /dev/null
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Collabora Ltd.
+ * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#include <dt-bindings/clock/mediatek,mt6795-clk.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "clk-mtk.h"
+#include "clk-pll.h"
+
+#define REG_REF2USB            0x8
+#define REG_AP_PLL_CON7                0x1c
+ #define MD1_MTCMOS_OFF                BIT(0)
+ #define MD1_MEM_OFF           BIT(1)
+ #define MD1_CLK_OFF           BIT(4)
+ #define MD1_ISO_OFF           BIT(8)
+
+#define MT6795_PLL_FMAX                (3000UL * MHZ)
+#define MT6795_CON0_EN         BIT(0)
+#define MT6795_CON0_RST_BAR    BIT(24)
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,    \
+           _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) {     \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .reg = _reg,                                            \
+               .pwr_reg = _pwr_reg,                                    \
+               .en_mask = MT6795_CON0_EN | _en_mask,                   \
+               .flags = _flags,                                        \
+               .rst_bar_mask = MT6795_CON0_RST_BAR,                    \
+               .fmax = MT6795_PLL_FMAX,                                \
+               .pcwbits = _pcwbits,                                    \
+               .pd_reg = _pd_reg,                                      \
+               .pd_shift = _pd_shift,                                  \
+               .tuner_reg = _tuner_reg,                                \
+               .pcw_reg = _pcw_reg,                                    \
+               .pcw_shift = _pcw_shift,                                \
+               .div_table = NULL,                                      \
+               .pll_en_bit = 0,                                        \
+       }
+
+static const struct mtk_pll_data plls[] = {
+       PLL(CLK_APMIXED_ARMCA53PLL, "armca53pll", 0x200, 0x20c, 0, PLL_AO,
+           21, 0x204, 24, 0x0, 0x204, 0),
+       PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x220, 0x22c, 0xf0000101, HAVE_RST_BAR,
+           21, 0x220, 4, 0x0, 0x224, 0),
+       PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x230, 0x23c, 0xfe000101, HAVE_RST_BAR,
+           7, 0x230, 4, 0x0, 0x234, 14),
+       PLL(CLK_APMIXED_MMPLL, "mmpll", 0x240, 0x24c, 0, 0, 21, 0x244, 24, 0x0, 0x244, 0),
+       PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x250, 0x25c, 0, 0, 21, 0x250, 4, 0x0, 0x254, 0),
+       PLL(CLK_APMIXED_VENCPLL, "vencpll", 0x260, 0x26c, 0, 0, 21, 0x260, 4, 0x0, 0x264, 0),
+       PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x270, 0x27c, 0, 0, 21, 0x270, 4, 0x0, 0x274, 0),
+       PLL(CLK_APMIXED_MPLL, "mpll", 0x280, 0x28c, 0, 0, 21, 0x280, 4, 0x0, 0x284, 0),
+       PLL(CLK_APMIXED_VCODECPLL, "vcodecpll", 0x290, 0x29c, 0, 0, 21, 0x290, 4, 0x0, 0x294, 0),
+       PLL(CLK_APMIXED_APLL1, "apll1", 0x2a0, 0x2b0, 0, 0, 31, 0x2a0, 4, 0x2a8, 0x2a4, 0),
+       PLL(CLK_APMIXED_APLL2, "apll2", 0x2b4, 0x2c4, 0, 0, 31, 0x2b4, 4, 0x2bc, 0x2b8, 0),
+};
+
+static void clk_mt6795_apmixed_setup_md1(void __iomem *base)
+{
+       void __iomem *reg = base + REG_AP_PLL_CON7;
+
+       /* Turn on MD1 internal clock */
+       writel(readl(reg) & ~MD1_CLK_OFF, reg);
+
+       /* Unlock MD1's MTCMOS power path */
+       writel(readl(reg) & ~MD1_MTCMOS_OFF, reg);
+
+       /* Turn on ISO */
+       writel(readl(reg) & ~MD1_ISO_OFF, reg);
+
+       /* Turn on memory */
+       writel(readl(reg) & ~MD1_MEM_OFF, reg);
+}
+
+static const struct of_device_id of_match_clk_mt6795_apmixed[] = {
+       { .compatible = "mediatek,mt6795-apmixedsys" },
+       { /* sentinel */ }
+};
+
+static int clk_mt6795_apmixed_probe(struct platform_device *pdev)
+{
+       struct clk_hw_onecell_data *clk_data;
+       struct device *dev = &pdev->dev;
+       struct device_node *node = dev->of_node;
+       void __iomem *base;
+       struct clk_hw *hw;
+       int ret;
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+       if (ret)
+               goto free_clk_data;
+
+       hw = mtk_clk_register_ref2usb_tx("ref2usb_tx", "clk26m", base + REG_REF2USB);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               dev_err(dev, "Failed to register ref2usb_tx: %d\n", ret);
+               goto unregister_plls;
+       }
+       clk_data->hws[CLK_APMIXED_REF2USB_TX] = hw;
+
+       ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (ret) {
+               dev_err(dev, "Cannot register clock provider: %d\n", ret);
+               goto unregister_ref2usb;
+       }
+
+       /* Setup MD1 to avoid random crashes */
+       dev_dbg(dev, "Performing initial setup for MD1\n");
+       clk_mt6795_apmixed_setup_md1(base);
+
+       return 0;
+
+unregister_ref2usb:
+       mtk_clk_unregister_ref2usb_tx(clk_data->hws[CLK_APMIXED_REF2USB_TX]);
+unregister_plls:
+       mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
+free_clk_data:
+       mtk_free_clk_data(clk_data);
+       return ret;
+}
+
+static int clk_mt6795_apmixed_remove(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev);
+
+       of_clk_del_provider(node);
+       mtk_clk_unregister_ref2usb_tx(clk_data->hws[CLK_APMIXED_REF2USB_TX]);
+       mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
+       mtk_free_clk_data(clk_data);
+
+       return 0;
+}
+
+static struct platform_driver clk_mt6795_apmixed_drv = {
+       .probe = clk_mt6795_apmixed_probe,
+       .remove = clk_mt6795_apmixed_remove,
+       .driver = {
+               .name = "clk-mt6795-apmixed",
+               .of_match_table = of_match_clk_mt6795_apmixed,
+       },
+};
+module_platform_driver(clk_mt6795_apmixed_drv);
+
+MODULE_DESCRIPTION("MediaTek MT6795 apmixed clocks driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6795-infracfg.c b/drivers/clk/mediatek/clk-mt6795-infracfg.c
new file mode 100644 (file)
index 0000000..df7eed6
--- /dev/null
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Collabora Ltd.
+ * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#include <dt-bindings/clock/mediatek,mt6795-clk.h>
+#include <dt-bindings/reset/mediatek,mt6795-resets.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "clk-cpumux.h"
+#include "clk-gate.h"
+#include "clk-mtk.h"
+#include "reset.h"
+
+#define GATE_ICG(_id, _name, _parent, _shift)                  \
+               GATE_MTK(_id, _name, _parent, &infra_cg_regs,   \
+                        _shift, &mtk_clk_gate_ops_no_setclr)
+
+static const struct mtk_gate_regs infra_cg_regs = {
+       .set_ofs = 0x0040,
+       .clr_ofs = 0x0044,
+       .sta_ofs = 0x0048,
+};
+
+static const char * const ca53_c0_parents[] = {
+       "clk26m",
+       "armca53pll",
+       "mainpll",
+       "univpll"
+};
+
+static const char * const ca53_c1_parents[] = {
+       "clk26m",
+       "armca53pll",
+       "mainpll",
+       "univpll"
+};
+
+static const struct mtk_composite cpu_muxes[] = {
+       MUX(CLK_INFRA_CA53_C0_SEL, "infra_ca53_c0_sel", ca53_c0_parents, 0x00, 0, 2),
+       MUX(CLK_INFRA_CA53_C1_SEL, "infra_ca53_c1_sel", ca53_c1_parents, 0x00, 2, 2),
+};
+
+static const struct mtk_gate infra_gates[] = {
+       GATE_ICG(CLK_INFRA_DBGCLK, "infra_dbgclk", "axi_sel", 0),
+       GATE_ICG(CLK_INFRA_SMI, "infra_smi", "mm_sel", 1),
+       GATE_ICG(CLK_INFRA_AUDIO, "infra_audio", "aud_intbus_sel", 5),
+       GATE_ICG(CLK_INFRA_GCE, "infra_gce", "axi_sel", 6),
+       GATE_ICG(CLK_INFRA_L2C_SRAM, "infra_l2c_sram", "axi_sel", 7),
+       GATE_ICG(CLK_INFRA_M4U, "infra_m4u", "mem_sel", 8),
+       GATE_ICG(CLK_INFRA_MD1MCU, "infra_md1mcu", "clk26m", 9),
+       GATE_ICG(CLK_INFRA_MD1BUS, "infra_md1bus", "axi_sel", 10),
+       GATE_ICG(CLK_INFRA_MD1DBB, "infra_dbb", "axi_sel", 11),
+       GATE_ICG(CLK_INFRA_DEVICE_APC, "infra_devapc", "clk26m", 12),
+       GATE_ICG(CLK_INFRA_TRNG, "infra_trng", "axi_sel", 13),
+       GATE_ICG(CLK_INFRA_MD1LTE, "infra_md1lte", "axi_sel", 14),
+       GATE_ICG(CLK_INFRA_CPUM, "infra_cpum", "cpum_ck", 15),
+       GATE_ICG(CLK_INFRA_KP, "infra_kp", "axi_sel", 16),
+};
+
+static u16 infra_ao_rst_ofs[] = { 0x30, 0x34 };
+
+static u16 infra_ao_idx_map[] = {
+       [MT6795_INFRA_RST0_SCPSYS_RST]    = 0 * RST_NR_PER_BANK + 5,
+       [MT6795_INFRA_RST0_PMIC_WRAP_RST] = 0 * RST_NR_PER_BANK + 7,
+       [MT6795_INFRA_RST1_MIPI_DSI_RST]  = 1 * RST_NR_PER_BANK + 4,
+       [MT6795_INFRA_RST1_MIPI_CSI_RST]  = 1 * RST_NR_PER_BANK + 7,
+       [MT6795_INFRA_RST1_MM_IOMMU_RST]  = 1 * RST_NR_PER_BANK + 15,
+};
+
+static const struct mtk_clk_rst_desc clk_rst_desc = {
+       .version = MTK_RST_SET_CLR,
+       .rst_bank_ofs = infra_ao_rst_ofs,
+       .rst_bank_nr = ARRAY_SIZE(infra_ao_rst_ofs),
+       .rst_idx_map = infra_ao_idx_map,
+       .rst_idx_map_nr = ARRAY_SIZE(infra_ao_idx_map),
+};
+
+static const struct of_device_id of_match_clk_mt6795_infracfg[] = {
+       { .compatible = "mediatek,mt6795-infracfg" },
+       { /* sentinel */ }
+};
+
+static int clk_mt6795_infracfg_probe(struct platform_device *pdev)
+{
+       struct clk_hw_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       void __iomem *base;
+       int ret;
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       ret = mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
+       if (ret)
+               goto free_clk_data;
+
+       ret = mtk_clk_register_gates(node, infra_gates, ARRAY_SIZE(infra_gates), clk_data);
+       if (ret)
+               goto free_clk_data;
+
+       ret = mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes), clk_data);
+       if (ret)
+               goto unregister_gates;
+
+       ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (ret)
+               goto unregister_cpumuxes;
+
+       return 0;
+
+unregister_cpumuxes:
+       mtk_clk_unregister_cpumuxes(cpu_muxes, ARRAY_SIZE(cpu_muxes), clk_data);
+unregister_gates:
+       mtk_clk_unregister_gates(infra_gates, ARRAY_SIZE(infra_gates), clk_data);
+free_clk_data:
+       mtk_free_clk_data(clk_data);
+       return ret;
+}
+
+static int clk_mt6795_infracfg_remove(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev);
+
+       of_clk_del_provider(node);
+       mtk_clk_unregister_cpumuxes(cpu_muxes, ARRAY_SIZE(cpu_muxes), clk_data);
+       mtk_clk_unregister_gates(infra_gates, ARRAY_SIZE(infra_gates), clk_data);
+       mtk_free_clk_data(clk_data);
+
+       return 0;
+}
+
+static struct platform_driver clk_mt6795_infracfg_drv = {
+       .driver = {
+               .name = "clk-mt6795-infracfg",
+               .of_match_table = of_match_clk_mt6795_infracfg,
+       },
+       .probe = clk_mt6795_infracfg_probe,
+       .remove = clk_mt6795_infracfg_remove,
+};
+module_platform_driver(clk_mt6795_infracfg_drv);
+
+MODULE_DESCRIPTION("MediaTek MT6795 infracfg clocks driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6795-mfg.c b/drivers/clk/mediatek/clk-mt6795-mfg.c
new file mode 100644 (file)
index 0000000..ee7aab2
--- /dev/null
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Collabora Ltd.
+ * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#include <dt-bindings/clock/mediatek,mt6795-clk.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+static const struct mtk_gate_regs mfg_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_MFG(_id, _name, _parent, _shift)                  \
+       GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate mfg_clks[] = {
+       GATE_MFG(CLK_MFG_BAXI, "mfg_baxi", "axi_mfg_in_sel", 0),
+       GATE_MFG(CLK_MFG_BMEM, "mfg_bmem", "mem_mfg_in_sel", 1),
+       GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 2),
+       GATE_MFG(CLK_MFG_B26M, "mfg_b26m", "clk26m", 3),
+};
+
+static const struct mtk_clk_desc mfg_desc = {
+       .clks = mfg_clks,
+       .num_clks = ARRAY_SIZE(mfg_clks),
+};
+
+static const struct of_device_id of_match_clk_mt6795_mfg[] = {
+       { .compatible = "mediatek,mt6795-mfgcfg", .data = &mfg_desc },
+       { /* sentinel */ }
+};
+
+static struct platform_driver clk_mt6795_mfg_drv = {
+       .driver = {
+               .name = "clk-mt6795-mfg",
+               .of_match_table = of_match_clk_mt6795_mfg,
+       },
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
+};
+module_platform_driver(clk_mt6795_mfg_drv);
+
+MODULE_DESCRIPTION("MediaTek MT6795 mfg clocks driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6795-mm.c b/drivers/clk/mediatek/clk-mt6795-mm.c
new file mode 100644 (file)
index 0000000..fd73f20
--- /dev/null
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Collabora Ltd.
+ * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#include <dt-bindings/clock/mediatek,mt6795-clk.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#define GATE_MM0(_id, _name, _parent, _shift)  \
+       GATE_MTK(_id, _name, _parent, &mm0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_MM1(_id, _name, _parent, _shift)  \
+       GATE_MTK(_id, _name, _parent, &mm1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate_regs mm0_cg_regs = {
+       .set_ofs = 0x0104,
+       .clr_ofs = 0x0108,
+       .sta_ofs = 0x0100,
+};
+
+static const struct mtk_gate_regs mm1_cg_regs = {
+       .set_ofs = 0x0114,
+       .clr_ofs = 0x0118,
+       .sta_ofs = 0x0110,
+};
+
+static const struct mtk_gate mm_gates[] = {
+       /* MM0 */
+       GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
+       GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
+       GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 2),
+       GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 3),
+       GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 4),
+       GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 5),
+       GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 6),
+       GATE_MM0(CLK_MM_MDP_RSZ2, "mm_mdp_rsz2", "mm_sel", 7),
+       GATE_MM0(CLK_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_sel", 8),
+       GATE_MM0(CLK_MM_MDP_TDSHP1, "mm_mdp_tdshp1", "mm_sel", 9),
+       GATE_MM0(CLK_MM_MDP_CROP, "mm_mdp_crop", "mm_sel", 10),
+       GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11),
+       GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 12),
+       GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 13),
+       GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 14),
+       GATE_MM0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "clk32k", 15),
+       GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 16),
+       GATE_MM0(CLK_MM_DISP_OVL1, "mm_disp_ovl1", "mm_sel", 17),
+       GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 18),
+       GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19),
+       GATE_MM0(CLK_MM_DISP_RDMA2, "mm_disp_rdma2", "mm_sel", 20),
+       GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 21),
+       GATE_MM0(CLK_MM_DISP_WDMA1, "mm_disp_wdma1", "mm_sel", 22),
+       GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 23),
+       GATE_MM0(CLK_MM_DISP_COLOR1, "mm_disp_color1", "mm_sel", 24),
+       GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "mm_sel", 25),
+       GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "mm_sel", 26),
+       GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 27),
+       GATE_MM0(CLK_MM_DISP_SPLIT0, "mm_disp_split0", "mm_sel", 28),
+       GATE_MM0(CLK_MM_DISP_SPLIT1, "mm_disp_split1", "mm_sel", 29),
+       GATE_MM0(CLK_MM_DISP_MERGE, "mm_disp_merge", "mm_sel", 30),
+       GATE_MM0(CLK_MM_DISP_OD, "mm_disp_od", "mm_sel", 31),
+
+       /* MM1 */
+       GATE_MM1(CLK_MM_DISP_PWM0MM, "mm_disp_pwm0mm", "mm_sel", 0),
+       GATE_MM1(CLK_MM_DISP_PWM026M, "mm_disp_pwm026m", "pwm_sel", 1),
+       GATE_MM1(CLK_MM_DISP_PWM1MM, "mm_disp_pwm1mm", "mm_sel", 2),
+       GATE_MM1(CLK_MM_DISP_PWM126M, "mm_disp_pwm126m", "pwm_sel", 3),
+       GATE_MM1(CLK_MM_DSI0_ENGINE, "mm_dsi0_engine", "mm_sel", 4),
+       GATE_MM1(CLK_MM_DSI0_DIGITAL, "mm_dsi0_digital", "dsi0_dig", 5),
+       GATE_MM1(CLK_MM_DSI1_ENGINE, "mm_dsi1_engine", "mm_sel", 6),
+       GATE_MM1(CLK_MM_DSI1_DIGITAL, "mm_dsi1_digital", "dsi1_dig", 7),
+       GATE_MM1(CLK_MM_DPI_PIXEL, "mm_dpi_pixel", "dpi0_sel", 8),
+       GATE_MM1(CLK_MM_DPI_ENGINE, "mm_dpi_engine", "mm_sel", 9),
+};
+
+static int clk_mt6795_mm_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *node = dev->parent->of_node;
+       struct clk_hw_onecell_data *clk_data;
+       int ret;
+
+       clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       ret = mtk_clk_register_gates(node, mm_gates, ARRAY_SIZE(mm_gates), clk_data);
+       if (ret)
+               goto free_clk_data;
+
+       ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (ret)
+               goto unregister_gates;
+
+       platform_set_drvdata(pdev, clk_data);
+
+       return 0;
+
+unregister_gates:
+       mtk_clk_unregister_gates(mm_gates, ARRAY_SIZE(mm_gates), clk_data);
+free_clk_data:
+       mtk_free_clk_data(clk_data);
+       return ret;
+}
+
+static int clk_mt6795_mm_remove(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *node = dev->parent->of_node;
+       struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev);
+
+       of_clk_del_provider(node);
+       mtk_clk_unregister_gates(mm_gates, ARRAY_SIZE(mm_gates), clk_data);
+       mtk_free_clk_data(clk_data);
+
+       return 0;
+}
+
+static struct platform_driver clk_mt6795_mm_drv = {
+       .driver = {
+               .name = "clk-mt6795-mm",
+       },
+       .probe = clk_mt6795_mm_probe,
+       .remove = clk_mt6795_mm_remove,
+};
+module_platform_driver(clk_mt6795_mm_drv);
+
+MODULE_DESCRIPTION("MediaTek MT6795 MultiMedia clocks driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6795-pericfg.c b/drivers/clk/mediatek/clk-mt6795-pericfg.c
new file mode 100644 (file)
index 0000000..cb28d35
--- /dev/null
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Collabora Ltd.
+ * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#include <dt-bindings/clock/mediatek,mt6795-clk.h>
+#include <dt-bindings/reset/mediatek,mt6795-resets.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "clk-gate.h"
+#include "clk-mtk.h"
+#include "reset.h"
+
+#define GATE_PERI(_id, _name, _parent, _shift)                 \
+               GATE_MTK(_id, _name, _parent, &peri_cg_regs,    \
+                        _shift, &mtk_clk_gate_ops_setclr)
+
+static DEFINE_SPINLOCK(mt6795_peri_clk_lock);
+
+static const struct mtk_gate_regs peri_cg_regs = {
+       .set_ofs = 0x0008,
+       .clr_ofs = 0x0010,
+       .sta_ofs = 0x0018,
+};
+
+static const char * const uart_ck_sel_parents[] = {
+       "clk26m",
+       "uart_sel",
+};
+
+static const struct mtk_composite peri_clks[] = {
+       MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, 0x40c, 0, 1),
+       MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, 0x40c, 1, 1),
+       MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, 0x40c, 2, 1),
+       MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1),
+};
+
+static const struct mtk_gate peri_gates[] = {
+       GATE_PERI(CLK_PERI_NFI, "peri_nfi", "axi_sel", 0),
+       GATE_PERI(CLK_PERI_THERM, "peri_therm", "axi_sel", 1),
+       GATE_PERI(CLK_PERI_PWM1, "peri_pwm1", "axi_sel", 2),
+       GATE_PERI(CLK_PERI_PWM2, "peri_pwm2", "axi_sel", 3),
+       GATE_PERI(CLK_PERI_PWM3, "peri_pwm3", "axi_sel", 4),
+       GATE_PERI(CLK_PERI_PWM4, "peri_pwm4", "axi_sel", 5),
+       GATE_PERI(CLK_PERI_PWM5, "peri_pwm5", "axi_sel", 6),
+       GATE_PERI(CLK_PERI_PWM6, "peri_pwm6", "axi_sel", 7),
+       GATE_PERI(CLK_PERI_PWM7, "peri_pwm7", "axi_sel", 8),
+       GATE_PERI(CLK_PERI_PWM, "peri_pwm", "axi_sel", 9),
+       GATE_PERI(CLK_PERI_USB0, "peri_usb0", "usb30_sel", 10),
+       GATE_PERI(CLK_PERI_USB1, "peri_usb1", "usb20_sel", 11),
+       GATE_PERI(CLK_PERI_AP_DMA, "peri_ap_dma", "axi_sel", 12),
+       GATE_PERI(CLK_PERI_MSDC30_0, "peri_msdc30_0", "msdc50_0_sel", 13),
+       GATE_PERI(CLK_PERI_MSDC30_1, "peri_msdc30_1", "msdc30_1_sel", 14),
+       GATE_PERI(CLK_PERI_MSDC30_2, "peri_msdc30_2", "msdc30_2_sel", 15),
+       GATE_PERI(CLK_PERI_MSDC30_3, "peri_msdc30_3", "msdc30_3_sel", 16),
+       GATE_PERI(CLK_PERI_NLI_ARB, "peri_nli_arb", "axi_sel", 17),
+       GATE_PERI(CLK_PERI_IRDA, "peri_irda", "irda_sel", 18),
+       GATE_PERI(CLK_PERI_UART0, "peri_uart0", "axi_sel", 19),
+       GATE_PERI(CLK_PERI_UART1, "peri_uart1", "axi_sel", 20),
+       GATE_PERI(CLK_PERI_UART2, "peri_uart2", "axi_sel", 21),
+       GATE_PERI(CLK_PERI_UART3, "peri_uart3", "axi_sel", 22),
+       GATE_PERI(CLK_PERI_I2C0, "peri_i2c0", "axi_sel", 23),
+       GATE_PERI(CLK_PERI_I2C1, "peri_i2c1", "axi_sel", 24),
+       GATE_PERI(CLK_PERI_I2C2, "peri_i2c2", "axi_sel", 25),
+       GATE_PERI(CLK_PERI_I2C3, "peri_i2c3", "axi_sel", 26),
+       GATE_PERI(CLK_PERI_I2C4, "peri_i2c4", "axi_sel", 27),
+       GATE_PERI(CLK_PERI_AUXADC, "peri_auxadc", "clk26m", 28),
+       GATE_PERI(CLK_PERI_SPI0, "peri_spi0", "spi_sel", 29),
+};
+
+static u16 peri_rst_ofs[] = { 0x0 };
+
+static u16 peri_idx_map[] = {
+       [MT6795_PERI_NFI_SW_RST]   = 14,
+       [MT6795_PERI_THERM_SW_RST] = 16,
+       [MT6795_PERI_MSDC1_SW_RST] = 20,
+};
+
+static const struct mtk_clk_rst_desc clk_rst_desc = {
+       .version = MTK_RST_SIMPLE,
+       .rst_bank_ofs = peri_rst_ofs,
+       .rst_bank_nr = ARRAY_SIZE(peri_rst_ofs),
+       .rst_idx_map = peri_idx_map,
+       .rst_idx_map_nr = ARRAY_SIZE(peri_idx_map),
+};
+
+static const struct of_device_id of_match_clk_mt6795_pericfg[] = {
+       { .compatible = "mediatek,mt6795-pericfg" },
+       { /* sentinel */ }
+};
+
+static int clk_mt6795_pericfg_probe(struct platform_device *pdev)
+{
+       struct clk_hw_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       void __iomem *base;
+       int ret;
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       ret = mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
+       if (ret)
+               goto free_clk_data;
+
+       ret = mtk_clk_register_gates(node, peri_gates, ARRAY_SIZE(peri_gates), clk_data);
+       if (ret)
+               goto free_clk_data;
+
+       ret = mtk_clk_register_composites(peri_clks, ARRAY_SIZE(peri_clks), base,
+                                         &mt6795_peri_clk_lock, clk_data);
+       if (ret)
+               goto unregister_gates;
+
+       ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (ret)
+               goto unregister_composites;
+
+       return 0;
+
+unregister_composites:
+       mtk_clk_unregister_composites(peri_clks, ARRAY_SIZE(peri_clks), clk_data);
+unregister_gates:
+       mtk_clk_unregister_gates(peri_gates, ARRAY_SIZE(peri_gates), clk_data);
+free_clk_data:
+       mtk_free_clk_data(clk_data);
+       return ret;
+}
+
+static int clk_mt6795_pericfg_remove(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev);
+
+       of_clk_del_provider(node);
+       mtk_clk_unregister_composites(peri_clks, ARRAY_SIZE(peri_clks), clk_data);
+       mtk_clk_unregister_gates(peri_gates, ARRAY_SIZE(peri_gates), clk_data);
+       mtk_free_clk_data(clk_data);
+
+       return 0;
+}
+
+static struct platform_driver clk_mt6795_pericfg_drv = {
+       .driver = {
+               .name = "clk-mt6795-pericfg",
+               .of_match_table = of_match_clk_mt6795_pericfg,
+       },
+       .probe = clk_mt6795_pericfg_probe,
+       .remove = clk_mt6795_pericfg_remove,
+};
+module_platform_driver(clk_mt6795_pericfg_drv);
+
+MODULE_DESCRIPTION("MediaTek MT6795 pericfg clocks driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6795-topckgen.c b/drivers/clk/mediatek/clk-mt6795-topckgen.c
new file mode 100644 (file)
index 0000000..2948dd1
--- /dev/null
@@ -0,0 +1,610 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Collabora Ltd.
+ * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#include <dt-bindings/clock/mediatek,mt6795-clk.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "clk-gate.h"
+#include "clk-mtk.h"
+#include "clk-mux.h"
+
+/*
+ * For some clocks, we don't care what their actual rates are. And these
+ * clocks may change their rate on different products or different scenarios.
+ * So we model these clocks' rate as 0, to denote it's not an actual rate.
+ */
+#define DUMMY_RATE     0
+
+#define TOP_MUX_GATE_NOSR(_id, _name, _parents, _reg, _shift, _width, _gate, _flags) \
+               MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _reg,          \
+                       (_reg + 0x4), (_reg + 0x8), _shift, _width,             \
+                       _gate, 0, -1, _flags)
+
+#define TOP_MUX_GATE(_id, _name, _parents, _reg, _shift, _width, _gate, _flags)        \
+               TOP_MUX_GATE_NOSR(_id, _name, _parents, _reg, _shift, _width,   \
+                                 _gate, CLK_SET_RATE_PARENT | _flags)
+
+static DEFINE_SPINLOCK(mt6795_top_clk_lock);
+
+static const char * const aud_1_parents[] = {
+       "clk26m",
+       "apll1_ck",
+       "univpll2_d4",
+       "univpll2_d8"
+};
+
+static const char * const aud_2_parents[] = {
+       "clk26m",
+       "apll2_ck",
+       "univpll2_d4",
+       "univpll2_d8"
+};
+
+static const char * const aud_intbus_parents[] = {
+       "clk26m",
+       "syspll1_d4",
+       "syspll4_d2",
+       "univpll3_d2",
+       "univpll2_d8",
+       "dmpll_d4",
+       "dmpll_d8"
+};
+
+static const char * const audio_parents[] = {
+       "clk26m",
+       "syspll3_d4",
+       "syspll4_d4",
+       "syspll1_d16"
+};
+
+static const char * const axi_mfg_in_parents[] = {
+       "clk26m",
+       "axi_sel",
+       "dmpll_d2"
+};
+
+static const char * const axi_parents[] = {
+       "clk26m",
+       "syspll1_d2",
+       "syspll_d5",
+       "syspll1_d4",
+       "univpll_d5",
+       "univpll2_d2",
+       "dmpll_d2",
+       "dmpll_d4"
+};
+
+static const char * const camtg_parents[] = {
+       "clk26m",
+       "univpll_d26",
+       "univpll2_d2",
+       "syspll3_d2",
+       "syspll3_d4",
+       "univpll1_d4",
+       "dmpll_d8"
+};
+
+static const char * const cci400_parents[] = {
+       "clk26m",
+       "vencpll_ck",
+       "clk26m",
+       "clk26m",
+       "univpll_d2",
+       "syspll_d2",
+       "msdcpll_ck",
+       "dmpll_ck"
+};
+
+static const char * const ddrphycfg_parents[] = {
+       "clk26m",
+       "syspll1_d8"
+};
+
+static const char * const dpi0_parents[] = {
+       "clk26m",
+       "tvdpll_d2",
+       "tvdpll_d4",
+       "clk26m",
+       "clk26m",
+       "tvdpll_d8",
+       "tvdpll_d16"
+};
+
+static const char * const i2s0_m_ck_parents[] = {
+       "apll1_div1",
+       "apll2_div1"
+};
+
+static const char * const i2s1_m_ck_parents[] = {
+       "apll1_div2",
+       "apll2_div2"
+};
+
+static const char * const i2s2_m_ck_parents[] = {
+       "apll1_div3",
+       "apll2_div3"
+};
+
+static const char * const i2s3_m_ck_parents[] = {
+       "apll1_div4",
+       "apll2_div4"
+};
+
+static const char * const i2s3_b_ck_parents[] = {
+       "apll1_div5",
+       "apll2_div5"
+};
+
+static const char * const irda_parents[] = {
+       "clk26m",
+       "univpll2_d4",
+       "syspll2_d4",
+       "dmpll_d8",
+};
+
+static const char * const mem_mfg_in_parents[] = {
+       "clk26m",
+       "mmpll_ck",
+       "dmpll_ck"
+};
+
+static const char * const mem_parents[] = {
+       "clk26m",
+       "dmpll_ck"
+};
+
+static const char * const mfg_parents[] = {
+       "clk26m",
+       "mmpll_ck",
+       "dmpll_ck",
+       "clk26m",
+       "clk26m",
+       "clk26m",
+       "clk26m",
+       "clk26m",
+       "clk26m",
+       "syspll_d3",
+       "syspll1_d2",
+       "syspll_d5",
+       "univpll_d3",
+       "univpll1_d2",
+       "univpll_d5",
+       "univpll2_d2"
+};
+
+static const char * const mm_parents[] = {
+       "clk26m",
+       "vencpll_d2",
+       "syspll_d3",
+       "syspll1_d2",
+       "syspll_d5",
+       "syspll1_d4",
+       "univpll1_d2",
+       "univpll2_d2",
+       "dmpll_d2"
+};
+
+static const char * const mjc_parents[] = {
+       "clk26m",
+       "univpll_d3",
+       "vcodecpll_ck",
+       "tvdpll_445p5m",
+       "vencpll_d2",
+       "syspll_d3",
+       "univpll1_d2",
+       "syspll_d5",
+       "syspll1_d2",
+       "univpll_d5",
+       "univpll2_d2",
+       "dmpll_ck"
+};
+
+static const char * const msdc50_0_h_parents[] = {
+       "clk26m",
+       "syspll1_d2",
+       "syspll2_d2",
+       "syspll4_d2",
+       "univpll_d5",
+       "univpll1_d4"
+};
+
+static const char * const msdc50_0_parents[] = {
+       "clk26m",
+       "msdcpll_ck",
+       "msdcpll_d2",
+       "univpll1_d4",
+       "syspll2_d2",
+       "syspll_d7",
+       "msdcpll_d4",
+       "vencpll_d4",
+       "tvdpll_ck",
+       "univpll_d2",
+       "univpll1_d2",
+       "mmpll_ck"
+};
+
+static const char * const msdc30_1_parents[] = {
+       "clk26m",
+       "univpll2_d2",
+       "msdcpll_d4",
+       "univpll1_d4",
+       "syspll2_d2",
+       "syspll_d7",
+       "univpll_d7",
+       "vencpll_d4"
+};
+
+static const char * const msdc30_2_parents[] = {
+       "clk26m",
+       "univpll2_d2",
+       "msdcpll_d4",
+       "univpll1_d4",
+       "syspll2_d2",
+       "syspll_d7",
+       "univpll_d7",
+       "vencpll_d2"
+};
+
+static const char * const msdc30_3_parents[] = {
+       "clk26m",
+       "univpll2_d2",
+       "msdcpll_d4",
+       "univpll1_d4",
+       "syspll2_d2",
+       "syspll_d7",
+       "univpll_d7",
+       "vencpll_d4"
+};
+
+static const char * const pmicspi_parents[] = {
+       "clk26m",
+       "syspll1_d8",
+       "syspll3_d4",
+       "syspll1_d16",
+       "univpll3_d4",
+       "univpll_d26",
+       "dmpll_d8",
+       "dmpll_d16"
+};
+
+static const char * const pwm_parents[] = {
+       "clk26m",
+       "univpll2_d4",
+       "univpll3_d2",
+       "univpll1_d4"
+};
+
+static const char * const scam_parents[] = {
+       "clk26m",
+       "syspll3_d2",
+       "univpll2_d4",
+       "dmpll_d4"
+};
+
+static const char * const scp_parents[] = {
+       "clk26m",
+       "syspll1_d2",
+       "univpll_d5",
+       "syspll_d5",
+       "dmpll_d2",
+       "dmpll_d4"
+};
+
+static const char * const spi_parents[] = {
+       "clk26m",
+       "syspll3_d2",
+       "syspll1_d4",
+       "syspll4_d2",
+       "univpll3_d2",
+       "univpll2_d4",
+       "univpll1_d8"
+};
+
+static const char * const uart_parents[] = {
+       "clk26m",
+       "univpll2_d8"
+};
+
+static const char * const usb20_parents[] = {
+       "clk26m",
+       "univpll1_d8",
+       "univpll3_d4"
+};
+
+static const char * const usb30_parents[] = {
+       "clk26m",
+       "univpll3_d2",
+       "usb_syspll_125m",
+       "univpll2_d4"
+};
+
+static const char * const vdec_parents[] = {
+       "clk26m",
+       "vcodecpll_ck",
+       "tvdpll_445p5m",
+       "univpll_d3",
+       "vencpll_d2",
+       "syspll_d3",
+       "univpll1_d2",
+       "mmpll_d2",
+       "dmpll_d2",
+       "dmpll_d4"
+};
+
+static const char * const venc_parents[] = {
+       "clk26m",
+       "vcodecpll_ck",
+       "tvdpll_445p5m",
+       "univpll_d3",
+       "vencpll_d2",
+       "syspll_d3",
+       "univpll1_d2",
+       "univpll2_d2",
+       "dmpll_d2",
+       "dmpll_d4"
+};
+
+static const struct mtk_fixed_clk fixed_clks[] = {
+       FIXED_CLK(CLK_TOP_ADSYS_26M, "adsys_26m", "clk26m", 26 * MHZ),
+       FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", DUMMY_RATE),
+       FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
+       FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", DUMMY_RATE),
+       FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", DUMMY_RATE),
+};
+
+static const struct mtk_fixed_factor top_divs[] = {
+       FACTOR(CLK_TOP_ARMCA53PLL_754M, "armca53pll_754m", "clk26m", 1, 2),
+       FACTOR(CLK_TOP_ARMCA53PLL_502M, "armca53pll_502m", "clk26m", 1, 3),
+
+       FACTOR(CLK_TOP_MAIN_H546M, "main_h546m", "mainpll", 1, 2),
+       FACTOR(CLK_TOP_MAIN_H364M, "main_h364m", "mainpll", 1, 3),
+       FACTOR(CLK_TOP_MAIN_H218P4M, "main_h218p4m", "mainpll", 1, 5),
+       FACTOR(CLK_TOP_MAIN_H156M, "main_h156m", "mainpll", 1, 7),
+
+       FACTOR(CLK_TOP_TVDPLL_445P5M, "tvdpll_445p5m", "tvdpll", 1, 4),
+       FACTOR(CLK_TOP_TVDPLL_594M, "tvdpll_594m", "tvdpll", 1, 3),
+
+       FACTOR(CLK_TOP_UNIV_624M, "univ_624m", "univpll", 1, 2),
+       FACTOR(CLK_TOP_UNIV_416M, "univ_416m", "univpll", 1, 3),
+       FACTOR(CLK_TOP_UNIV_249P6M, "univ_249p6m", "univpll", 1, 5),
+       FACTOR(CLK_TOP_UNIV_178P3M, "univ_178p3m", "univpll", 1, 7),
+       FACTOR(CLK_TOP_UNIV_48M, "univ_48m", "univpll", 1, 26),
+
+       FACTOR(CLK_TOP_CLKRTC_EXT, "clkrtc_ext", "clk32k", 1, 1),
+       FACTOR(CLK_TOP_CLKRTC_INT, "clkrtc_int", "clk26m", 1, 793),
+       FACTOR(CLK_TOP_FPC, "fpc_ck", "clk26m", 1, 1),
+
+       FACTOR(CLK_TOP_HDMITXPLL_D2, "hdmitxpll_d2", "clk26m", 1, 2),
+       FACTOR(CLK_TOP_HDMITXPLL_D3, "hdmitxpll_d3", "clk26m", 1, 3),
+
+       FACTOR(CLK_TOP_ARMCA53PLL_D2, "armca53pll_d2", "clk26m", 1, 1),
+       FACTOR(CLK_TOP_ARMCA53PLL_D3, "armca53pll_d3", "clk26m", 1, 1),
+
+       FACTOR(CLK_TOP_APLL1, "apll1_ck", "apll1", 1, 1),
+       FACTOR(CLK_TOP_APLL2, "apll2_ck", "apll2", 1, 1),
+
+       FACTOR(CLK_TOP_DMPLL, "dmpll_ck", "clkph_mck_o", 1, 1),
+       FACTOR(CLK_TOP_DMPLL_D2, "dmpll_d2", "clkph_mck_o", 1, 2),
+       FACTOR(CLK_TOP_DMPLL_D4, "dmpll_d4", "clkph_mck_o", 1, 4),
+       FACTOR(CLK_TOP_DMPLL_D8, "dmpll_d8", "clkph_mck_o", 1, 8),
+       FACTOR(CLK_TOP_DMPLL_D16, "dmpll_d16", "clkph_mck_o", 1, 16),
+
+       FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, 1),
+       FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
+
+       FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1),
+       FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
+       FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4),
+       FACTOR(CLK_TOP_MSDCPLL2, "msdcpll2_ck", "msdcpll2", 1, 1),
+       FACTOR(CLK_TOP_MSDCPLL2_D2, "msdcpll2_d2", "msdcpll2", 1, 2),
+       FACTOR(CLK_TOP_MSDCPLL2_D4, "msdcpll2_d4", "msdcpll2", 1, 4),
+
+       FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "main_h546m", 1, 1),
+       FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "main_h546m", 1, 2),
+       FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "main_h546m", 1, 4),
+       FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "main_h546m", 1, 8),
+       FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "main_h546m", 1, 16),
+       FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "main_h364m", 1, 1),
+       FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "main_h364m", 1, 2),
+       FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "main_h364m", 1, 4),
+       FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "main_h218p4m", 1, 1),
+       FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "main_h218p4m", 1, 2),
+       FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "main_h218p4m", 1, 4),
+       FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "main_h156m", 1, 1),
+       FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "main_h156m", 1, 2),
+       FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "main_h156m", 1, 4),
+
+       FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll_594m", 1, 1),
+       FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_594m", 1, 2),
+       FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll_594m", 1, 4),
+       FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll_594m", 1, 8),
+       FACTOR(CLK_TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll_594m", 1, 16),
+
+       FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univ_624m", 1, 1),
+       FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univ_624m", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univ_624m", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univ_624m", 1, 8),
+       FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univ_416m", 1, 1),
+       FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univ_416m", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univ_416m", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univ_416m", 1, 8),
+       FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univ_249p6m", 1, 1),
+       FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univ_249p6m", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univ_249p6m", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univ_249p6m", 1, 8),
+       FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univ_178p3m", 1, 1),
+       FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univ_48m", 1, 1),
+       FACTOR(CLK_TOP_UNIVPLL_D52, "univpll_d52", "univ_48m", 1, 2),
+
+       FACTOR(CLK_TOP_VCODECPLL, "vcodecpll_ck", "vcodecpll", 1, 3),
+       FACTOR(CLK_TOP_VCODECPLL_370P5, "vcodecpll_370p5", "vcodecpll", 1, 4),
+
+       FACTOR(CLK_TOP_VENCPLL, "vencpll_ck", "vencpll", 1, 1),
+       FACTOR(CLK_TOP_VENCPLL_D2, "vencpll_d2", "vencpll", 1, 2),
+       FACTOR(CLK_TOP_VENCPLL_D4, "vencpll_d4", "vencpll", 1, 4),
+};
+
+static const struct mtk_mux top_muxes[] = {
+       /* CLK_CFG_0 */
+       TOP_MUX_GATE_NOSR(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
+                         0x40, 0, 3, 7, CLK_IS_CRITICAL),
+       TOP_MUX_GATE_NOSR(CLK_TOP_MEM_SEL, "mem_sel", mem_parents,
+                         0x40, 8, 1, 15, CLK_IS_CRITICAL),
+       TOP_MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents,
+                    0x40, 16, 1, 23, CLK_IS_CRITICAL),
+       TOP_MUX_GATE(CLK_TOP_MM_SEL, "mm_sel", mm_parents, 0x40, 24, 3, 31, 0),
+       /* CLK_CFG_1 */
+       TOP_MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x50, 0, 2, 7, 0),
+       TOP_MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x50, 8, 4, 15, 0),
+       TOP_MUX_GATE(CLK_TOP_VENC_SEL, "venc_sel", venc_parents, 0x50, 16, 4, 23, 0),
+       TOP_MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x50, 24, 4, 31, 0),
+       /* CLK_CFG_2 */
+       TOP_MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x60, 0, 3, 7, 0),
+       TOP_MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x60, 8, 1, 15, 0),
+       TOP_MUX_GATE(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x60, 16, 3, 23, 0),
+       TOP_MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x60, 24, 2, 31, 0),
+       /* CLK_CFG_3 */
+       TOP_MUX_GATE(CLK_TOP_USB30_SEL, "usb30_sel", usb30_parents, 0x70, 0, 2, 7, 0),
+       TOP_MUX_GATE(CLK_TOP_MSDC50_0_H_SEL, "msdc50_0_h_sel", msdc50_0_h_parents,
+                    0x70, 8, 3, 15, 0),
+       TOP_MUX_GATE(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel", msdc50_0_parents, 0x70, 16, 4, 23, 0),
+       TOP_MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_1_parents, 0x70, 24, 3, 31, 0),
+       /* CLK_CFG_4 */
+       TOP_MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_2_parents, 0x80, 0, 3, 7, 0),
+       TOP_MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_3_parents, 0x80, 8, 3, 15, 0),
+       TOP_MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x80, 16, 2, 23, 0),
+       TOP_MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
+                    0x80, 24, 3, 31, 0),
+       /* CLK_CFG_5 */
+       TOP_MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x90, 0, 3, 5, 0),
+       TOP_MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, 0x90, 8, 3, 15, 0),
+       TOP_MUX_GATE(CLK_TOP_MJC_SEL, "mjc_sel", mjc_parents, 0x90, 24, 4, 31, 0),
+       /* CLK_CFG_6 */
+       /*
+        * The dpi0_sel clock should not propagate rate changes to its parent
+        * clock so the dpi driver can have full control over PLL and divider.
+        */
+       TOP_MUX_GATE_NOSR(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 0xa0, 0, 3, 7, 0),
+       TOP_MUX_GATE(CLK_TOP_IRDA_SEL, "irda_sel", irda_parents, 0xa0, 8, 2, 15, 0),
+       TOP_MUX_GATE(CLK_TOP_CCI400_SEL, "cci400_sel", cci400_parents,
+                    0xa0, 16, 3, 23, CLK_IS_CRITICAL),
+       TOP_MUX_GATE(CLK_TOP_AUD_1_SEL, "aud_1_sel", aud_1_parents, 0xa0, 24, 2, 31, 0),
+       /* CLK_CFG_7 */
+       TOP_MUX_GATE(CLK_TOP_AUD_2_SEL, "aud_2_sel", aud_2_parents, 0xb0, 0, 2, 7, 0),
+       TOP_MUX_GATE(CLK_TOP_MEM_MFG_IN_SEL, "mem_mfg_in_sel", mem_mfg_in_parents,
+                    0xb0, 8, 2, 15, 0),
+       TOP_MUX_GATE(CLK_TOP_AXI_MFG_IN_SEL, "axi_mfg_in_sel", axi_mfg_in_parents,
+                    0xb0, 16, 2, 23, 0),
+       TOP_MUX_GATE(CLK_TOP_SCAM_SEL, "scam_sel", scam_parents, 0xb0, 24, 2, 31, 0),
+};
+
+static struct mtk_composite top_aud_divs[] = {
+       MUX(CLK_TOP_I2S0_M_SEL, "i2s0_m_ck_sel", i2s0_m_ck_parents, 0x120, 4, 1),
+       MUX(CLK_TOP_I2S1_M_SEL, "i2s1_m_ck_sel", i2s1_m_ck_parents, 0x120, 5, 1),
+       MUX(CLK_TOP_I2S2_M_SEL, "i2s2_m_ck_sel", i2s2_m_ck_parents, 0x120, 6, 1),
+       MUX(CLK_TOP_I2S3_M_SEL, "i2s3_m_ck_sel", i2s3_m_ck_parents, 0x120, 7, 1),
+       MUX(CLK_TOP_I2S3_B_SEL, "i2s3_b_ck_sel", i2s3_b_ck_parents, 0x120, 8, 1),
+
+       DIV_GATE(CLK_TOP_APLL1_DIV0, "apll1_div0", "aud_1_sel", 0x12c, 8, 0x120, 4, 24),
+       DIV_GATE(CLK_TOP_APLL1_DIV1, "apll1_div1", "aud_1_sel", 0x12c, 9, 0x124, 8, 0),
+       DIV_GATE(CLK_TOP_APLL1_DIV2, "apll1_div2", "aud_1_sel", 0x12c, 10, 0x124, 8, 8),
+       DIV_GATE(CLK_TOP_APLL1_DIV3, "apll1_div3", "aud_1_sel", 0x12c, 11, 0x124, 8, 16),
+       DIV_GATE(CLK_TOP_APLL1_DIV4, "apll1_div4", "aud_1_sel", 0x12c, 12, 0x124, 8, 24),
+       DIV_GATE(CLK_TOP_APLL1_DIV5, "apll1_div5", "apll1_div4", 0x12c, 13, 0x12c, 4, 0),
+
+       DIV_GATE(CLK_TOP_APLL2_DIV0, "apll2_div0", "aud_2_sel", 0x12c, 16, 0x120, 4, 28),
+       DIV_GATE(CLK_TOP_APLL2_DIV1, "apll2_div1", "aud_2_sel", 0x12c, 17, 0x128, 8, 0),
+       DIV_GATE(CLK_TOP_APLL2_DIV2, "apll2_div2", "aud_2_sel", 0x12c, 18, 0x128, 8, 8),
+       DIV_GATE(CLK_TOP_APLL2_DIV3, "apll2_div3", "aud_2_sel", 0x12c, 19, 0x128, 8, 16),
+       DIV_GATE(CLK_TOP_APLL2_DIV4, "apll2_div4", "aud_2_sel", 0x12c, 20, 0x128, 8, 24),
+       DIV_GATE(CLK_TOP_APLL2_DIV5, "apll2_div5", "apll2_div4", 0x12c, 21, 0x12c, 4, 4),
+};
+
+
+static const struct of_device_id of_match_clk_mt6795_topckgen[] = {
+       { .compatible = "mediatek,mt6795-topckgen" },
+       { /* sentinel */ }
+};
+
+static int clk_mt6795_topckgen_probe(struct platform_device *pdev)
+{
+       struct clk_hw_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       void __iomem *base;
+       int ret;
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       ret = mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), clk_data);
+       if (ret)
+               goto free_clk_data;
+
+       ret = mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+       if (ret)
+               goto unregister_fixed_clks;
+
+       ret = mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), node,
+                                    &mt6795_top_clk_lock, clk_data);
+       if (ret)
+               goto unregister_factors;
+
+       ret = mtk_clk_register_composites(top_aud_divs, ARRAY_SIZE(top_aud_divs), base,
+                                         &mt6795_top_clk_lock, clk_data);
+       if (ret)
+               goto unregister_muxes;
+
+       ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (ret)
+               goto unregister_composites;
+
+       return 0;
+
+unregister_composites:
+       mtk_clk_unregister_composites(top_aud_divs, ARRAY_SIZE(top_aud_divs), clk_data);
+unregister_muxes:
+       mtk_clk_unregister_muxes(top_muxes, ARRAY_SIZE(top_muxes), clk_data);
+unregister_factors:
+       mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+unregister_fixed_clks:
+       mtk_clk_unregister_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), clk_data);
+free_clk_data:
+       mtk_free_clk_data(clk_data);
+       return ret;
+}
+
+static int clk_mt6795_topckgen_remove(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev);
+
+       of_clk_del_provider(node);
+       mtk_clk_unregister_composites(top_aud_divs, ARRAY_SIZE(top_aud_divs), clk_data);
+       mtk_clk_unregister_muxes(top_muxes, ARRAY_SIZE(top_muxes), clk_data);
+       mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+       mtk_clk_unregister_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), clk_data);
+       mtk_free_clk_data(clk_data);
+
+       return 0;
+}
+
+static struct platform_driver clk_mt6795_topckgen_drv = {
+       .driver = {
+               .name = "clk-mt6795-topckgen",
+               .of_match_table = of_match_clk_mt6795_topckgen,
+       },
+       .probe = clk_mt6795_topckgen_probe,
+       .remove = clk_mt6795_topckgen_remove,
+};
+module_platform_driver(clk_mt6795_topckgen_drv);
+
+MODULE_DESCRIPTION("MediaTek MT6795 topckgen clocks driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6795-vdecsys.c b/drivers/clk/mediatek/clk-mt6795-vdecsys.c
new file mode 100644 (file)
index 0000000..d85d04e
--- /dev/null
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Collabora Ltd.
+ * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#include <dt-bindings/clock/mediatek,mt6795-clk.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#define GATE_VDEC(_id, _name, _parent, _regs)                  \
+               GATE_MTK(_id, _name, _parent, _regs, 0,         \
+                        &mtk_clk_gate_ops_setclr_inv)
+
+static const struct mtk_gate_regs vdec0_cg_regs = {
+       .set_ofs = 0x0000,
+       .clr_ofs = 0x0004,
+       .sta_ofs = 0x0000,
+};
+
+static const struct mtk_gate_regs vdec1_cg_regs = {
+       .set_ofs = 0x0008,
+       .clr_ofs = 0x000c,
+       .sta_ofs = 0x0008,
+};
+
+static const struct mtk_gate vdec_clks[] = {
+       GATE_VDEC(CLK_VDEC_CKEN, "vdec_cken", "vdec_sel", &vdec0_cg_regs),
+       GATE_VDEC(CLK_VDEC_LARB_CKEN, "vdec_larb_cken", "mm_sel", &vdec1_cg_regs),
+};
+
+static const struct mtk_clk_desc vdec_desc = {
+       .clks = vdec_clks,
+       .num_clks = ARRAY_SIZE(vdec_clks),
+};
+
+static const struct of_device_id of_match_clk_mt6795_vdecsys[] = {
+       { .compatible = "mediatek,mt6795-vdecsys", .data = &vdec_desc },
+       { /* sentinel */ }
+};
+
+static struct platform_driver clk_mt6795_vdecsys_drv = {
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
+       .driver = {
+               .name = "clk-mt6795-vdecsys",
+               .of_match_table = of_match_clk_mt6795_vdecsys,
+       },
+};
+module_platform_driver(clk_mt6795_vdecsys_drv);
+
+MODULE_DESCRIPTION("MediaTek MT6795 vdecsys clocks driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6795-vencsys.c b/drivers/clk/mediatek/clk-mt6795-vencsys.c
new file mode 100644 (file)
index 0000000..de40a98
--- /dev/null
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Collabora Ltd.
+ * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#include <dt-bindings/clock/mediatek,mt6795-clk.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+static const struct mtk_gate_regs venc_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_VENC(_id, _name, _parent, _shift)                 \
+       GATE_MTK(_id, _name, _parent, &venc_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+static const struct mtk_gate venc_clks[] = {
+       GATE_VENC(CLK_VENC_LARB, "venc_larb", "venc_sel", 0),
+       GATE_VENC(CLK_VENC_VENC, "venc_venc", "venc_sel", 4),
+       GATE_VENC(CLK_VENC_JPGENC, "venc_jpgenc", "venc_sel", 8),
+       GATE_VENC(CLK_VENC_JPGDEC, "venc_jpgdec", "venc_sel", 12),
+};
+
+static const struct mtk_clk_desc venc_desc = {
+       .clks = venc_clks,
+       .num_clks = ARRAY_SIZE(venc_clks),
+};
+
+static const struct of_device_id of_match_clk_mt6795_vencsys[] = {
+       { .compatible = "mediatek,mt6795-vencsys", .data = &venc_desc },
+       { /* sentinel */ }
+};
+
+static struct platform_driver clk_mt6795_vencsys_drv = {
+       .driver = {
+               .name = "clk-mt6795-vencsys",
+               .of_match_table = of_match_clk_mt6795_vencsys,
+       },
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
+};
+module_platform_driver(clk_mt6795_vencsys_drv);
+
+MODULE_DESCRIPTION("MediaTek MT6795 vdecsys clocks driver");
+MODULE_LICENSE("GPL");
index 25d17db..7c6a53f 100644 (file)
@@ -32,33 +32,23 @@ static const struct mtk_gate img_clks[] = {
        GATE_IMG(CLK_IMG_LARB6, "img_larb6", "mm_sel", 0),
 };
 
-static const struct of_device_id of_match_clk_mt6797_img[] = {
-       { .compatible = "mediatek,mt6797-imgsys", },
-       {}
+static const struct mtk_clk_desc img_desc = {
+       .clks = img_clks,
+       .num_clks = ARRAY_SIZE(img_clks),
 };
 
-static int clk_mt6797_img_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_IMG_NR);
-
-       mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
-                              clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-       if (r)
-               dev_err(&pdev->dev,
-                       "could not register clock provider: %s: %d\n",
-                       pdev->name, r);
-
-       return r;
-}
+static const struct of_device_id of_match_clk_mt6797_img[] = {
+       {
+               .compatible = "mediatek,mt6797-imgsys",
+               .data = &img_desc,
+       }, {
+               /* sentinel */
+       }
+};
 
 static struct platform_driver clk_mt6797_img_drv = {
-       .probe = clk_mt6797_img_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6797-img",
                .of_match_table = of_match_clk_mt6797_img,
index de85789..6120fcc 100644 (file)
@@ -49,33 +49,23 @@ static const struct mtk_gate vdec_clks[] = {
        GATE_VDEC1(CLK_VDEC_LARB1_CKEN, "vdec_larb1_cken", "mm_sel", 0),
 };
 
-static const struct of_device_id of_match_clk_mt6797_vdec[] = {
-       { .compatible = "mediatek,mt6797-vdecsys", },
-       {}
+static const struct mtk_clk_desc vdec_desc = {
+       .clks = vdec_clks,
+       .num_clks = ARRAY_SIZE(vdec_clks),
 };
 
-static int clk_mt6797_vdec_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_VDEC_NR);
-
-       mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
-                              clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-       if (r)
-               dev_err(&pdev->dev,
-                       "could not register clock provider: %s: %d\n",
-                       pdev->name, r);
-
-       return r;
-}
+static const struct of_device_id of_match_clk_mt6797_vdec[] = {
+       {
+               .compatible = "mediatek,mt6797-vdecsys",
+               .data = &vdec_desc,
+       }, {
+               /* sentinel */
+       }
+};
 
 static struct platform_driver clk_mt6797_vdec_drv = {
-       .probe = clk_mt6797_vdec_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6797-vdec",
                .of_match_table = of_match_clk_mt6797_vdec,
index 78b7ed5..834d383 100644 (file)
@@ -34,33 +34,23 @@ static const struct mtk_gate venc_clks[] = {
        GATE_VENC(CLK_VENC_3, "venc_3", "venc_sel", 12),
 };
 
-static const struct of_device_id of_match_clk_mt6797_venc[] = {
-       { .compatible = "mediatek,mt6797-vencsys", },
-       {}
+static const struct mtk_clk_desc venc_desc = {
+       .clks = venc_clks,
+       .num_clks = ARRAY_SIZE(venc_clks),
 };
 
-static int clk_mt6797_venc_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       int r;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_VENC_NR);
-
-       mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
-                              clk_data);
-
-       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-       if (r)
-               dev_err(&pdev->dev,
-                       "could not register clock provider: %s: %d\n",
-                       pdev->name, r);
-
-       return r;
-}
+static const struct of_device_id of_match_clk_mt6797_venc[] = {
+       {
+               .compatible = "mediatek,mt6797-vencsys",
+               .data = &venc_desc,
+       }, {
+               /* sentinel */
+       }
+};
 
 static struct platform_driver clk_mt6797_venc_drv = {
-       .probe = clk_mt6797_venc_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt6797-venc",
                .of_match_table = of_match_clk_mt6797_venc,
index fcc598a..6907b1a 100644 (file)
@@ -34,26 +34,23 @@ static const struct mtk_gate cam_clks[] = {
        GATE_CAM(CLK_CAM_CCU, "cam_ccu", "cam_sel", 12),
 };
 
-static int clk_mt8183_cam_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_CAM_NR_CLK);
-
-       mtk_clk_register_gates(node, cam_clks, ARRAY_SIZE(cam_clks),
-                       clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct mtk_clk_desc cam_desc = {
+       .clks = cam_clks,
+       .num_clks = ARRAY_SIZE(cam_clks),
+};
 
 static const struct of_device_id of_match_clk_mt8183_cam[] = {
-       { .compatible = "mediatek,mt8183-camsys", },
-       {}
+       {
+               .compatible = "mediatek,mt8183-camsys",
+               .data = &cam_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt8183_cam_drv = {
-       .probe = clk_mt8183_cam_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8183-cam",
                .of_match_table = of_match_clk_mt8183_cam,
index eb2def2..8d88442 100644 (file)
@@ -34,26 +34,23 @@ static const struct mtk_gate img_clks[] = {
        GATE_IMG(CLK_IMG_OWE, "img_owe", "img_sel", 9),
 };
 
-static int clk_mt8183_img_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
-
-       mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
-                       clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct mtk_clk_desc img_desc = {
+       .clks = img_clks,
+       .num_clks = ARRAY_SIZE(img_clks),
+};
 
 static const struct of_device_id of_match_clk_mt8183_img[] = {
-       { .compatible = "mediatek,mt8183-imgsys", },
-       {}
+       {
+               .compatible = "mediatek,mt8183-imgsys",
+               .data = &img_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt8183_img_drv = {
-       .probe = clk_mt8183_img_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8183-img",
                .of_match_table = of_match_clk_mt8183_img,
index b30fc9f..953a8a3 100644 (file)
@@ -27,26 +27,23 @@ static const struct mtk_gate ipu_core0_clks[] = {
        GATE_IPU_CORE0(CLK_IPU_CORE0_IPU, "ipu_core0_ipu", "dsp_sel", 2),
 };
 
-static int clk_mt8183_ipu_core0_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_IPU_CORE0_NR_CLK);
-
-       mtk_clk_register_gates(node, ipu_core0_clks, ARRAY_SIZE(ipu_core0_clks),
-                       clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct mtk_clk_desc ipu_core0_desc = {
+       .clks = ipu_core0_clks,
+       .num_clks = ARRAY_SIZE(ipu_core0_clks),
+};
 
 static const struct of_device_id of_match_clk_mt8183_ipu_core0[] = {
-       { .compatible = "mediatek,mt8183-ipu_core0", },
-       {}
+       {
+               .compatible = "mediatek,mt8183-ipu_core0",
+               .data = &ipu_core0_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt8183_ipu_core0_drv = {
-       .probe = clk_mt8183_ipu_core0_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8183-ipu_core0",
                .of_match_table = of_match_clk_mt8183_ipu_core0,
index b378957..221d122 100644 (file)
@@ -27,26 +27,23 @@ static const struct mtk_gate ipu_core1_clks[] = {
        GATE_IPU_CORE1(CLK_IPU_CORE1_IPU, "ipu_core1_ipu", "dsp_sel", 2),
 };
 
-static int clk_mt8183_ipu_core1_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_IPU_CORE1_NR_CLK);
-
-       mtk_clk_register_gates(node, ipu_core1_clks, ARRAY_SIZE(ipu_core1_clks),
-                       clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct mtk_clk_desc ipu_core1_desc = {
+       .clks = ipu_core1_clks,
+       .num_clks = ARRAY_SIZE(ipu_core1_clks),
+};
 
 static const struct of_device_id of_match_clk_mt8183_ipu_core1[] = {
-       { .compatible = "mediatek,mt8183-ipu_core1", },
-       {}
+       {
+               .compatible = "mediatek,mt8183-ipu_core1",
+               .data = &ipu_core1_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt8183_ipu_core1_drv = {
-       .probe = clk_mt8183_ipu_core1_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8183-ipu_core1",
                .of_match_table = of_match_clk_mt8183_ipu_core1,
index 941b43a..8c4fd96 100644 (file)
@@ -25,26 +25,23 @@ static const struct mtk_gate ipu_adl_clks[] = {
        GATE_IPU_ADL_I(CLK_IPU_ADL_CABGEN, "ipu_adl_cabgen", "dsp_sel", 24),
 };
 
-static int clk_mt8183_ipu_adl_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_IPU_ADL_NR_CLK);
-
-       mtk_clk_register_gates(node, ipu_adl_clks, ARRAY_SIZE(ipu_adl_clks),
-                       clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct mtk_clk_desc ipu_adl_desc = {
+       .clks = ipu_adl_clks,
+       .num_clks = ARRAY_SIZE(ipu_adl_clks),
+};
 
 static const struct of_device_id of_match_clk_mt8183_ipu_adl[] = {
-       { .compatible = "mediatek,mt8183-ipu_adl", },
-       {}
+       {
+               .compatible = "mediatek,mt8183-ipu_adl",
+               .data = &ipu_adl_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt8183_ipu_adl_drv = {
-       .probe = clk_mt8183_ipu_adl_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8183-ipu_adl",
                .of_match_table = of_match_clk_mt8183_ipu_adl,
index ae82c2e..14a4c3f 100644 (file)
@@ -94,26 +94,23 @@ static const struct mtk_gate ipu_conn_clks[] = {
                "ipu_conn_cab3to1_slice", "dsp1_sel", 17),
 };
 
-static int clk_mt8183_ipu_conn_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_IPU_CONN_NR_CLK);
-
-       mtk_clk_register_gates(node, ipu_conn_clks, ARRAY_SIZE(ipu_conn_clks),
-                       clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct mtk_clk_desc ipu_conn_desc = {
+       .clks = ipu_conn_clks,
+       .num_clks = ARRAY_SIZE(ipu_conn_clks),
+};
 
 static const struct of_device_id of_match_clk_mt8183_ipu_conn[] = {
-       { .compatible = "mediatek,mt8183-ipu_conn", },
-       {}
+       {
+               .compatible = "mediatek,mt8183-ipu_conn",
+               .data = &ipu_conn_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt8183_ipu_conn_drv = {
-       .probe = clk_mt8183_ipu_conn_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8183-ipu_conn",
                .of_match_table = of_match_clk_mt8183_ipu_conn,
index d774eda..730c9ae 100644 (file)
@@ -18,36 +18,31 @@ static const struct mtk_gate_regs mfg_cg_regs = {
        .sta_ofs = 0x0,
 };
 
-#define GATE_MFG(_id, _name, _parent, _shift)                  \
-       GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift,     \
-               &mtk_clk_gate_ops_setclr)
+#define GATE_MFG(_id, _name, _parent, _shift)                          \
+       GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs, _shift,       \
+                      &mtk_clk_gate_ops_setclr, CLK_SET_RATE_PARENT)
 
 static const struct mtk_gate mfg_clks[] = {
        GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0)
 };
 
-static int clk_mt8183_mfg_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       pm_runtime_enable(&pdev->dev);
-
-       clk_data = mtk_alloc_clk_data(CLK_MFG_NR_CLK);
-
-       mtk_clk_register_gates_with_dev(node, mfg_clks, ARRAY_SIZE(mfg_clks),
-                       clk_data, &pdev->dev);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct mtk_clk_desc mfg_desc = {
+       .clks = mfg_clks,
+       .num_clks = ARRAY_SIZE(mfg_clks),
+};
 
 static const struct of_device_id of_match_clk_mt8183_mfg[] = {
-       { .compatible = "mediatek,mt8183-mfgcfg", },
-       {}
+       {
+               .compatible = "mediatek,mt8183-mfgcfg",
+               .data = &mfg_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt8183_mfg_drv = {
-       .probe = clk_mt8183_mfg_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8183-mfg",
                .of_match_table = of_match_clk_mt8183_mfg,
index 0548cde..c294e50 100644 (file)
@@ -38,26 +38,23 @@ static const struct mtk_gate vdec_clks[] = {
        GATE_VDEC1_I(CLK_VDEC_LARB1, "vdec_larb1", "mm_sel", 0),
 };
 
-static int clk_mt8183_vdec_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_VDEC_NR_CLK);
-
-       mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
-                       clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct mtk_clk_desc vdec_desc = {
+       .clks = vdec_clks,
+       .num_clks = ARRAY_SIZE(vdec_clks),
+};
 
 static const struct of_device_id of_match_clk_mt8183_vdec[] = {
-       { .compatible = "mediatek,mt8183-vdecsys", },
-       {}
+       {
+               .compatible = "mediatek,mt8183-vdecsys",
+               .data = &vdec_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt8183_vdec_drv = {
-       .probe = clk_mt8183_vdec_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8183-vdec",
                .of_match_table = of_match_clk_mt8183_vdec,
index f86ec60..0051c5d 100644 (file)
@@ -30,26 +30,23 @@ static const struct mtk_gate venc_clks[] = {
                "mm_sel", 8),
 };
 
-static int clk_mt8183_venc_probe(struct platform_device *pdev)
-{
-       struct clk_hw_onecell_data *clk_data;
-       struct device_node *node = pdev->dev.of_node;
-
-       clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK);
-
-       mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
-                       clk_data);
-
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-}
+static const struct mtk_clk_desc venc_desc = {
+       .clks = venc_clks,
+       .num_clks = ARRAY_SIZE(venc_clks),
+};
 
 static const struct of_device_id of_match_clk_mt8183_venc[] = {
-       { .compatible = "mediatek,mt8183-vencsys", },
-       {}
+       {
+               .compatible = "mediatek,mt8183-vencsys",
+               .data = &venc_desc,
+       }, {
+               /* sentinel */
+       }
 };
 
 static struct platform_driver clk_mt8183_venc_drv = {
-       .probe = clk_mt8183_venc_probe,
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8183-venc",
                .of_match_table = of_match_clk_mt8183_venc,
index 8512101..1860a35 100644 (file)
@@ -1198,10 +1198,33 @@ static void clk_mt8183_top_init_early(struct device_node *node)
 CLK_OF_DECLARE_DRIVER(mt8183_topckgen, "mediatek,mt8183-topckgen",
                        clk_mt8183_top_init_early);
 
+/* Register mux notifier for MFG mux */
+static int clk_mt8183_reg_mfg_mux_notifier(struct device *dev, struct clk *clk)
+{
+       struct mtk_mux_nb *mfg_mux_nb;
+       int i;
+
+       mfg_mux_nb = devm_kzalloc(dev, sizeof(*mfg_mux_nb), GFP_KERNEL);
+       if (!mfg_mux_nb)
+               return -ENOMEM;
+
+       for (i = 0; i < ARRAY_SIZE(top_muxes); i++)
+               if (top_muxes[i].id == CLK_TOP_MUX_MFG)
+                       break;
+       if (i == ARRAY_SIZE(top_muxes))
+               return -EINVAL;
+
+       mfg_mux_nb->ops = top_muxes[i].ops;
+       mfg_mux_nb->bypass_index = 0; /* Bypass to 26M crystal */
+
+       return devm_mtk_clk_mux_notifier_register(dev, clk, mfg_mux_nb);
+}
+
 static int clk_mt8183_top_probe(struct platform_device *pdev)
 {
        void __iomem *base;
        struct device_node *node = pdev->dev.of_node;
+       int ret;
 
        base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(base))
@@ -1227,6 +1250,11 @@ static int clk_mt8183_top_probe(struct platform_device *pdev)
        mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
                top_clk_data);
 
+       ret = clk_mt8183_reg_mfg_mux_notifier(&pdev->dev,
+                                             top_clk_data->hws[CLK_TOP_MUX_MFG]->clk);
+       if (ret)
+               return ret;
+
        return of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
                                      top_clk_data);
 }
index fc74cd8..90b57d4 100644 (file)
@@ -98,6 +98,7 @@ static const struct of_device_id of_match_clk_mt8192_cam[] = {
 
 static struct platform_driver clk_mt8192_cam_drv = {
        .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8192-cam",
                .of_match_table = of_match_clk_mt8192_cam,
index 7ce3abe..da82d65 100644 (file)
@@ -61,6 +61,7 @@ static const struct of_device_id of_match_clk_mt8192_img[] = {
 
 static struct platform_driver clk_mt8192_img_drv = {
        .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8192-img",
                .of_match_table = of_match_clk_mt8192_img,
index 700356a..ff8e20b 100644 (file)
@@ -110,6 +110,7 @@ static const struct of_device_id of_match_clk_mt8192_imp_iic_wrap[] = {
 
 static struct platform_driver clk_mt8192_imp_iic_wrap_drv = {
        .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8192-imp_iic_wrap",
                .of_match_table = of_match_clk_mt8192_imp_iic_wrap,
index 730d91b..0225abe 100644 (file)
@@ -48,6 +48,7 @@ static const struct of_device_id of_match_clk_mt8192_ipe[] = {
 
 static struct platform_driver clk_mt8192_ipe_drv = {
        .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8192-ipe",
                .of_match_table = of_match_clk_mt8192_ipe,
index 93c87ae..4675788 100644 (file)
@@ -73,6 +73,7 @@ static const struct of_device_id of_match_clk_mt8192_mdp[] = {
 
 static struct platform_driver clk_mt8192_mdp_drv = {
        .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8192-mdp",
                .of_match_table = of_match_clk_mt8192_mdp,
index 3bbc746..ec5b44f 100644 (file)
@@ -18,8 +18,10 @@ static const struct mtk_gate_regs mfg_cg_regs = {
        .sta_ofs = 0x0,
 };
 
-#define GATE_MFG(_id, _name, _parent, _shift)  \
-       GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+#define GATE_MFG(_id, _name, _parent, _shift)                  \
+       GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs,       \
+                      _shift, &mtk_clk_gate_ops_setclr,        \
+                      CLK_SET_RATE_PARENT)
 
 static const struct mtk_gate mfg_clks[] = {
        GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_pll_sel", 0),
@@ -41,6 +43,7 @@ static const struct of_device_id of_match_clk_mt8192_mfg[] = {
 
 static struct platform_driver clk_mt8192_mfg_drv = {
        .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8192-mfg",
                .of_match_table = of_match_clk_mt8192_mfg,
index 635f7a0..a72e1b7 100644 (file)
@@ -55,6 +55,7 @@ static const struct of_device_id of_match_clk_mt8192_msdc[] = {
 
 static struct platform_driver clk_mt8192_msdc_drv = {
        .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8192-msdc",
                .of_match_table = of_match_clk_mt8192_msdc,
index 58725d7..18a8679 100644 (file)
@@ -41,6 +41,7 @@ static const struct of_device_id of_match_clk_mt8192_scp_adsp[] = {
 
 static struct platform_driver clk_mt8192_scp_adsp_drv = {
        .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8192-scp_adsp",
                .of_match_table = of_match_clk_mt8192_scp_adsp,
index b1d95cf..e149962 100644 (file)
@@ -85,6 +85,7 @@ static const struct of_device_id of_match_clk_mt8192_vdec[] = {
 
 static struct platform_driver clk_mt8192_vdec_drv = {
        .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8192-vdec",
                .of_match_table = of_match_clk_mt8192_vdec,
index c0d867b..80b8bb1 100644 (file)
@@ -44,6 +44,7 @@ static const struct of_device_id of_match_clk_mt8192_venc[] = {
 
 static struct platform_driver clk_mt8192_venc_drv = {
        .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
        .driver = {
                .name = "clk-mt8192-venc",
                .of_match_table = of_match_clk_mt8192_venc,
index ebbd279..d0f2269 100644 (file)
@@ -167,22 +167,7 @@ static const char * const mdp_parents[] = {
        "mmpll_d5_d2"
 };
 
-static const char * const img1_parents[] = {
-       "clk26m",
-       "univpll_d4",
-       "tvdpll_ck",
-       "mainpll_d4",
-       "univpll_d5",
-       "mmpll_d6",
-       "univpll_d6",
-       "mainpll_d6",
-       "mmpll_d4_d2",
-       "mainpll_d4_d2",
-       "mmpll_d6_d2",
-       "mmpll_d5_d2"
-};
-
-static const char * const img2_parents[] = {
+static const char * const img_parents[] = {
        "clk26m",
        "univpll_d4",
        "tvdpll_ck",
@@ -280,61 +265,6 @@ static const char * const camtg_parents[] = {
        "univpll_192m_d32"
 };
 
-static const char * const camtg2_parents[] = {
-       "clk26m",
-       "univpll_192m_d8",
-       "univpll_d6_d8",
-       "univpll_192m_d4",
-       "univpll_d6_d16",
-       "csw_f26m_d2",
-       "univpll_192m_d16",
-       "univpll_192m_d32"
-};
-
-static const char * const camtg3_parents[] = {
-       "clk26m",
-       "univpll_192m_d8",
-       "univpll_d6_d8",
-       "univpll_192m_d4",
-       "univpll_d6_d16",
-       "csw_f26m_d2",
-       "univpll_192m_d16",
-       "univpll_192m_d32"
-};
-
-static const char * const camtg4_parents[] = {
-       "clk26m",
-       "univpll_192m_d8",
-       "univpll_d6_d8",
-       "univpll_192m_d4",
-       "univpll_d6_d16",
-       "csw_f26m_d2",
-       "univpll_192m_d16",
-       "univpll_192m_d32"
-};
-
-static const char * const camtg5_parents[] = {
-       "clk26m",
-       "univpll_192m_d8",
-       "univpll_d6_d8",
-       "univpll_192m_d4",
-       "univpll_d6_d16",
-       "csw_f26m_d2",
-       "univpll_192m_d16",
-       "univpll_192m_d32"
-};
-
-static const char * const camtg6_parents[] = {
-       "clk26m",
-       "univpll_192m_d8",
-       "univpll_d6_d8",
-       "univpll_192m_d4",
-       "univpll_d6_d16",
-       "csw_f26m_d2",
-       "univpll_192m_d16",
-       "univpll_192m_d32"
-};
-
 static const char * const uart_parents[] = {
        "clk26m",
        "univpll_d6_d8"
@@ -362,15 +292,7 @@ static const char * const msdc50_0_parents[] = {
        "univpll_d4_d2"
 };
 
-static const char * const msdc30_1_parents[] = {
-       "clk26m",
-       "univpll_d6_d2",
-       "mainpll_d6_d2",
-       "mainpll_d7_d2",
-       "msdcpll_d2"
-};
-
-static const char * const msdc30_2_parents[] = {
+static const char * const msdc30_parents[] = {
        "clk26m",
        "univpll_d6_d2",
        "mainpll_d6_d2",
@@ -457,39 +379,6 @@ static const char * const seninf_parents[] = {
        "univpll_d5"
 };
 
-static const char * const seninf1_parents[] = {
-       "clk26m",
-       "univpll_d4_d4",
-       "univpll_d6_d2",
-       "univpll_d4_d2",
-       "univpll_d7",
-       "univpll_d6",
-       "mmpll_d6",
-       "univpll_d5"
-};
-
-static const char * const seninf2_parents[] = {
-       "clk26m",
-       "univpll_d4_d4",
-       "univpll_d6_d2",
-       "univpll_d4_d2",
-       "univpll_d7",
-       "univpll_d6",
-       "mmpll_d6",
-       "univpll_d5"
-};
-
-static const char * const seninf3_parents[] = {
-       "clk26m",
-       "univpll_d4_d4",
-       "univpll_d6_d2",
-       "univpll_d4_d2",
-       "univpll_d7",
-       "univpll_d6",
-       "mmpll_d6",
-       "univpll_d5"
-};
-
 static const char * const tl_parents[] = {
        "clk26m",
        "univpll_192m_d2",
@@ -649,52 +538,7 @@ static const char * const sflash_parents[] = {
        "univpll_d5_d8"
 };
 
-static const char * const apll_i2s0_m_parents[] = {
-       "aud_1_sel",
-       "aud_2_sel"
-};
-
-static const char * const apll_i2s1_m_parents[] = {
-       "aud_1_sel",
-       "aud_2_sel"
-};
-
-static const char * const apll_i2s2_m_parents[] = {
-       "aud_1_sel",
-       "aud_2_sel"
-};
-
-static const char * const apll_i2s3_m_parents[] = {
-       "aud_1_sel",
-       "aud_2_sel"
-};
-
-static const char * const apll_i2s4_m_parents[] = {
-       "aud_1_sel",
-       "aud_2_sel"
-};
-
-static const char * const apll_i2s5_m_parents[] = {
-       "aud_1_sel",
-       "aud_2_sel"
-};
-
-static const char * const apll_i2s6_m_parents[] = {
-       "aud_1_sel",
-       "aud_2_sel"
-};
-
-static const char * const apll_i2s7_m_parents[] = {
-       "aud_1_sel",
-       "aud_2_sel"
-};
-
-static const char * const apll_i2s8_m_parents[] = {
-       "aud_1_sel",
-       "aud_2_sel"
-};
-
-static const char * const apll_i2s9_m_parents[] = {
+static const char * const apll_i2s_m_parents[] = {
        "aud_1_sel",
        "aud_2_sel"
 };
@@ -724,9 +568,9 @@ static const struct mtk_mux top_mtk_muxes[] = {
        MUX_GATE_CLR_SET_UPD(CLK_TOP_MDP_SEL, "mdp_sel",
                             mdp_parents, 0x020, 0x024, 0x028, 8, 4, 15, 0x004, 5),
        MUX_GATE_CLR_SET_UPD(CLK_TOP_IMG1_SEL, "img1_sel",
-                            img1_parents, 0x020, 0x024, 0x028, 16, 4, 23, 0x004, 6),
+                            img_parents, 0x020, 0x024, 0x028, 16, 4, 23, 0x004, 6),
        MUX_GATE_CLR_SET_UPD(CLK_TOP_IMG2_SEL, "img2_sel",
-                            img2_parents, 0x020, 0x024, 0x028, 24, 4, 31, 0x004, 7),
+                            img_parents, 0x020, 0x024, 0x028, 24, 4, 31, 0x004, 7),
        /* CLK_CFG_2 */
        MUX_GATE_CLR_SET_UPD(CLK_TOP_IPE_SEL, "ipe_sel",
                             ipe_parents, 0x030, 0x034, 0x038, 0, 4, 7, 0x004, 8),
@@ -747,16 +591,16 @@ static const struct mtk_mux top_mtk_muxes[] = {
                             camtg_parents, 0x050, 0x054, 0x058, 24, 3, 31, 0x004, 19),
        /* CLK_CFG_5 */
        MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG2_SEL, "camtg2_sel",
-                            camtg2_parents, 0x060, 0x064, 0x068, 0, 3, 7, 0x004, 20),
+                            camtg_parents, 0x060, 0x064, 0x068, 0, 3, 7, 0x004, 20),
        MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG3_SEL, "camtg3_sel",
-                            camtg3_parents, 0x060, 0x064, 0x068, 8, 3, 15, 0x004, 21),
+                            camtg_parents, 0x060, 0x064, 0x068, 8, 3, 15, 0x004, 21),
        MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG4_SEL, "camtg4_sel",
-                            camtg4_parents, 0x060, 0x064, 0x068, 16, 3, 23, 0x004, 22),
+                            camtg_parents, 0x060, 0x064, 0x068, 16, 3, 23, 0x004, 22),
        MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG5_SEL, "camtg5_sel",
-                            camtg5_parents, 0x060, 0x064, 0x068, 24, 3, 31, 0x004, 23),
+                            camtg_parents, 0x060, 0x064, 0x068, 24, 3, 31, 0x004, 23),
        /* CLK_CFG_6 */
        MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG6_SEL, "camtg6_sel",
-                            camtg6_parents, 0x070, 0x074, 0x078, 0, 3, 7, 0x004, 24),
+                            camtg_parents, 0x070, 0x074, 0x078, 0, 3, 7, 0x004, 24),
        MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel",
                             uart_parents, 0x070, 0x074, 0x078, 8, 1, 15, 0x004, 25),
        MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel",
@@ -767,9 +611,9 @@ static const struct mtk_mux top_mtk_muxes[] = {
        MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel",
                             msdc50_0_parents, 0x080, 0x084, 0x088, 0, 3, 7, 0x004, 28),
        MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel",
-                            msdc30_1_parents, 0x080, 0x084, 0x088, 8, 3, 15, 0x004, 29),
+                            msdc30_parents, 0x080, 0x084, 0x088, 8, 3, 15, 0x004, 29),
        MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel",
-                            msdc30_2_parents, 0x080, 0x084, 0x088, 16, 3, 23, 0x004, 30),
+                            msdc30_parents, 0x080, 0x084, 0x088, 16, 3, 23, 0x004, 30),
        MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_SEL, "audio_sel",
                             audio_parents, 0x080, 0x084, 0x088, 24, 2, 31, 0x008, 0),
        /* CLK_CFG_8 */
@@ -796,12 +640,12 @@ static const struct mtk_mux top_mtk_muxes[] = {
        MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF_SEL, "seninf_sel",
                             seninf_parents, 0x0b0, 0x0b4, 0x0b8, 16, 3, 23, 0x008, 11),
        MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF1_SEL, "seninf1_sel",
-                            seninf1_parents, 0x0b0, 0x0b4, 0x0b8, 24, 3, 31, 0x008, 12),
+                            seninf_parents, 0x0b0, 0x0b4, 0x0b8, 24, 3, 31, 0x008, 12),
        /* CLK_CFG_11 */
        MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF2_SEL, "seninf2_sel",
-                            seninf2_parents, 0x0c0, 0x0c4, 0x0c8, 0, 3, 7, 0x008, 13),
+                            seninf_parents, 0x0c0, 0x0c4, 0x0c8, 0, 3, 7, 0x008, 13),
        MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF3_SEL, "seninf3_sel",
-                            seninf3_parents, 0x0c0, 0x0c4, 0x0c8, 8, 3, 15, 0x008, 14),
+                            seninf_parents, 0x0c0, 0x0c4, 0x0c8, 8, 3, 15, 0x008, 14),
        MUX_GATE_CLR_SET_UPD(CLK_TOP_TL_SEL, "tl_sel",
                             tl_parents, 0x0c0, 0x0c4, 0x0c8, 16, 2, 23, 0x008, 15),
        MUX_GATE_CLR_SET_UPD(CLK_TOP_DXCC_SEL, "dxcc_sel",
@@ -847,16 +691,16 @@ static const struct mtk_mux top_mtk_muxes[] = {
 
 static struct mtk_composite top_muxes[] = {
        /* CLK_AUDDIV_0 */
-       MUX(CLK_TOP_APLL_I2S0_M_SEL, "apll_i2s0_m_sel", apll_i2s0_m_parents, 0x320, 16, 1),
-       MUX(CLK_TOP_APLL_I2S1_M_SEL, "apll_i2s1_m_sel", apll_i2s1_m_parents, 0x320, 17, 1),
-       MUX(CLK_TOP_APLL_I2S2_M_SEL, "apll_i2s2_m_sel", apll_i2s2_m_parents, 0x320, 18, 1),
-       MUX(CLK_TOP_APLL_I2S3_M_SEL, "apll_i2s3_m_sel", apll_i2s3_m_parents, 0x320, 19, 1),
-       MUX(CLK_TOP_APLL_I2S4_M_SEL, "apll_i2s4_m_sel", apll_i2s4_m_parents, 0x320, 20, 1),
-       MUX(CLK_TOP_APLL_I2S5_M_SEL, "apll_i2s5_m_sel", apll_i2s5_m_parents, 0x320, 21, 1),
-       MUX(CLK_TOP_APLL_I2S6_M_SEL, "apll_i2s6_m_sel", apll_i2s6_m_parents, 0x320, 22, 1),
-       MUX(CLK_TOP_APLL_I2S7_M_SEL, "apll_i2s7_m_sel", apll_i2s7_m_parents, 0x320, 23, 1),
-       MUX(CLK_TOP_APLL_I2S8_M_SEL, "apll_i2s8_m_sel", apll_i2s8_m_parents, 0x320, 24, 1),
-       MUX(CLK_TOP_APLL_I2S9_M_SEL, "apll_i2s9_m_sel", apll_i2s9_m_parents, 0x320, 25, 1),
+       MUX(CLK_TOP_APLL_I2S0_M_SEL, "apll_i2s0_m_sel", apll_i2s_m_parents, 0x320, 16, 1),
+       MUX(CLK_TOP_APLL_I2S1_M_SEL, "apll_i2s1_m_sel", apll_i2s_m_parents, 0x320, 17, 1),
+       MUX(CLK_TOP_APLL_I2S2_M_SEL, "apll_i2s2_m_sel", apll_i2s_m_parents, 0x320, 18, 1),
+       MUX(CLK_TOP_APLL_I2S3_M_SEL, "apll_i2s3_m_sel", apll_i2s_m_parents, 0x320, 19, 1),
+       MUX(CLK_TOP_APLL_I2S4_M_SEL, "apll_i2s4_m_sel", apll_i2s_m_parents, 0x320, 20, 1),
+       MUX(CLK_TOP_APLL_I2S5_M_SEL, "apll_i2s5_m_sel", apll_i2s_m_parents, 0x320, 21, 1),
+       MUX(CLK_TOP_APLL_I2S6_M_SEL, "apll_i2s6_m_sel", apll_i2s_m_parents, 0x320, 22, 1),
+       MUX(CLK_TOP_APLL_I2S7_M_SEL, "apll_i2s7_m_sel", apll_i2s_m_parents, 0x320, 23, 1),
+       MUX(CLK_TOP_APLL_I2S8_M_SEL, "apll_i2s8_m_sel", apll_i2s_m_parents, 0x320, 24, 1),
+       MUX(CLK_TOP_APLL_I2S9_M_SEL, "apll_i2s9_m_sel", apll_i2s_m_parents, 0x320, 25, 1),
 };
 
 static const struct mtk_composite top_adj_divs[] = {
@@ -1224,6 +1068,28 @@ static void clk_mt8192_top_init_early(struct device_node *node)
 CLK_OF_DECLARE_DRIVER(mt8192_topckgen, "mediatek,mt8192-topckgen",
                      clk_mt8192_top_init_early);
 
+/* Register mux notifier for MFG mux */
+static int clk_mt8192_reg_mfg_mux_notifier(struct device *dev, struct clk *clk)
+{
+       struct mtk_mux_nb *mfg_mux_nb;
+       int i;
+
+       mfg_mux_nb = devm_kzalloc(dev, sizeof(*mfg_mux_nb), GFP_KERNEL);
+       if (!mfg_mux_nb)
+               return -ENOMEM;
+
+       for (i = 0; i < ARRAY_SIZE(top_mtk_muxes); i++)
+               if (top_mtk_muxes[i].id == CLK_TOP_MFG_PLL_SEL)
+                       break;
+       if (i == ARRAY_SIZE(top_mtk_muxes))
+               return -EINVAL;
+
+       mfg_mux_nb->ops = top_mtk_muxes[i].ops;
+       mfg_mux_nb->bypass_index = 0; /* Bypass to 26M crystal */
+
+       return devm_mtk_clk_mux_notifier_register(dev, clk, mfg_mux_nb);
+}
+
 static int clk_mt8192_top_probe(struct platform_device *pdev)
 {
        struct device_node *node = pdev->dev.of_node;
@@ -1247,6 +1113,12 @@ static int clk_mt8192_top_probe(struct platform_device *pdev)
        if (r)
                return r;
 
+       r = clk_mt8192_reg_mfg_mux_notifier(&pdev->dev,
+                                           top_clk_data->hws[CLK_TOP_MFG_PLL_SEL]->clk);
+       if (r)
+               return r;
+
+
        return of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
                                      top_clk_data);
 }
index 97657f2..fcd4104 100644 (file)
@@ -55,8 +55,12 @@ static const struct mtk_gate_regs infra_ao4_cg_regs = {
 #define GATE_INFRA_AO1(_id, _name, _parent, _shift)    \
        GATE_INFRA_AO1_FLAGS(_id, _name, _parent, _shift, 0)
 
+#define GATE_INFRA_AO2_FLAGS(_id, _name, _parent, _shift, _flag)       \
+       GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao2_cg_regs, _shift, \
+                      &mtk_clk_gate_ops_setclr, _flag)
+
 #define GATE_INFRA_AO2(_id, _name, _parent, _shift)                    \
-       GATE_MTK(_id, _name, _parent, &infra_ao2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+       GATE_INFRA_AO2_FLAGS(_id, _name, _parent, _shift, 0)
 
 #define GATE_INFRA_AO3_FLAGS(_id, _name, _parent, _shift, _flag)               \
        GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao3_cg_regs, _shift, \
@@ -136,8 +140,11 @@ static const struct mtk_gate infra_ao_clks[] = {
        GATE_INFRA_AO2(CLK_INFRA_AO_UNIPRO_SYS, "infra_ao_unipro_sys", "top_ufs", 11),
        GATE_INFRA_AO2(CLK_INFRA_AO_UNIPRO_TICK, "infra_ao_unipro_tick", "top_ufs_tick1us", 12),
        GATE_INFRA_AO2(CLK_INFRA_AO_UFS_MP_SAP_B, "infra_ao_ufs_mp_sap_b", "top_ufs_mp_sap_cfg", 13),
-       GATE_INFRA_AO2(CLK_INFRA_AO_PWRMCU, "infra_ao_pwrmcu", "top_pwrmcu", 15),
-       GATE_INFRA_AO2(CLK_INFRA_AO_PWRMCU_BUS_H, "infra_ao_pwrmcu_bus_h", "top_axi", 17),
+       /* pwrmcu is used by ATF for platform PM: clocks must never be disabled by the kernel */
+       GATE_INFRA_AO2_FLAGS(CLK_INFRA_AO_PWRMCU, "infra_ao_pwrmcu", "top_pwrmcu", 15,
+                            CLK_IS_CRITICAL),
+       GATE_INFRA_AO2_FLAGS(CLK_INFRA_AO_PWRMCU_BUS_H, "infra_ao_pwrmcu_bus_h", "top_axi", 17,
+                            CLK_IS_CRITICAL),
        GATE_INFRA_AO2(CLK_INFRA_AO_APDMA_B, "infra_ao_apdma_b", "top_axi", 18),
        GATE_INFRA_AO2(CLK_INFRA_AO_SPI4, "infra_ao_spi4", "top_spi", 25),
        GATE_INFRA_AO2(CLK_INFRA_AO_SPI5, "infra_ao_spi5", "top_spi", 26),
@@ -193,6 +200,9 @@ static u16 infra_ao_rst_ofs[] = {
 
 static u16 infra_ao_idx_map[] = {
        [MT8195_INFRA_RST0_THERM_CTRL_SWRST] = 0 * RST_NR_PER_BANK + 0,
+       [MT8195_INFRA_RST2_USBSIF_P1_SWRST] = 2 * RST_NR_PER_BANK + 18,
+       [MT8195_INFRA_RST2_PCIE_P0_SWRST] = 2 * RST_NR_PER_BANK + 26,
+       [MT8195_INFRA_RST2_PCIE_P1_SWRST] = 2 * RST_NR_PER_BANK + 27,
        [MT8195_INFRA_RST3_THERM_CTRL_PTP_SWRST] = 3 * RST_NR_PER_BANK + 5,
        [MT8195_INFRA_RST4_THERM_CTRL_MCU_SWRST] = 4 * RST_NR_PER_BANK + 10,
 };
index 9411c55..c94cb71 100644 (file)
@@ -17,10 +17,12 @@ static const struct mtk_gate_regs mfg_cg_regs = {
 };
 
 #define GATE_MFG(_id, _name, _parent, _shift)                  \
-       GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+       GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs,       \
+                      _shift, &mtk_clk_gate_ops_setclr,        \
+                      CLK_SET_RATE_PARENT)
 
 static const struct mtk_gate mfg_clks[] = {
-       GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "top_mfg_core_tmp", 0),
+       GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_ck_fast_ref", 0),
 };
 
 static const struct mtk_clk_desc mfg_desc = {
index ec70e1f..8cbab5c 100644 (file)
@@ -298,11 +298,14 @@ static const char * const ipu_if_parents[] = {
        "mmpll_d4"
 };
 
+/*
+ * MFG can be also parented to "univpll_d6" and "univpll_d7":
+ * these have been removed from the parents list to let us
+ * achieve GPU DVFS without any special clock handlers.
+ */
 static const char * const mfg_parents[] = {
        "clk26m",
-       "mainpll_d5_d2",
-       "univpll_d6",
-       "univpll_d7"
+       "mainpll_d5_d2"
 };
 
 static const char * const camtg_parents[] = {
@@ -1149,11 +1152,6 @@ static const struct mtk_mux top_mtk_muxes[] = {
         */
 };
 
-static struct mtk_composite top_muxes[] = {
-       /* CLK_MISC_CFG_3 */
-       MUX(CLK_TOP_MFG_CK_FAST_REF, "mfg_ck_fast_ref", mfg_fast_parents, 0x0250, 8, 1),
-};
-
 static const struct mtk_composite top_adj_divs[] = {
        DIV_GATE(CLK_TOP_APLL12_DIV0, "apll12_div0", "top_i2si1_mck", 0x0320, 0, 0x0328, 8, 0),
        DIV_GATE(CLK_TOP_APLL12_DIV1, "apll12_div1", "top_i2si2_mck", 0x0320, 1, 0x0328, 8, 8),
@@ -1222,10 +1220,26 @@ static const struct of_device_id of_match_clk_mt8195_topck[] = {
        {}
 };
 
+/* Register mux notifier for MFG mux */
+static int clk_mt8195_reg_mfg_mux_notifier(struct device *dev, struct clk *clk)
+{
+       struct mtk_mux_nb *mfg_mux_nb;
+
+       mfg_mux_nb = devm_kzalloc(dev, sizeof(*mfg_mux_nb), GFP_KERNEL);
+       if (!mfg_mux_nb)
+               return -ENOMEM;
+
+       mfg_mux_nb->ops = &clk_mux_ops;
+       mfg_mux_nb->bypass_index = 0; /* Bypass to TOP_MFG_CORE_TMP */
+
+       return devm_mtk_clk_mux_notifier_register(dev, clk, mfg_mux_nb);
+}
+
 static int clk_mt8195_topck_probe(struct platform_device *pdev)
 {
        struct clk_hw_onecell_data *top_clk_data;
        struct device_node *node = pdev->dev.of_node;
+       struct clk_hw *hw;
        int r;
        void __iomem *base;
 
@@ -1253,15 +1267,22 @@ static int clk_mt8195_topck_probe(struct platform_device *pdev)
        if (r)
                goto unregister_factors;
 
-       r = mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
-                                       &mt8195_clk_lock, top_clk_data);
+       hw = devm_clk_hw_register_mux(&pdev->dev, "mfg_ck_fast_ref", mfg_fast_parents,
+                                     ARRAY_SIZE(mfg_fast_parents), CLK_SET_RATE_PARENT,
+                                     (base + 0x250), 8, 1, 0, &mt8195_clk_lock);
+       if (IS_ERR(hw))
+               goto unregister_muxes;
+       top_clk_data->hws[CLK_TOP_MFG_CK_FAST_REF] = hw;
+
+       r = clk_mt8195_reg_mfg_mux_notifier(&pdev->dev,
+                                           top_clk_data->hws[CLK_TOP_MFG_CK_FAST_REF]->clk);
        if (r)
                goto unregister_muxes;
 
        r = mtk_clk_register_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
                                        &mt8195_clk_lock, top_clk_data);
        if (r)
-               goto unregister_composite_muxes;
+               goto unregister_muxes;
 
        r = mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), top_clk_data);
        if (r)
@@ -1279,8 +1300,6 @@ unregister_gates:
        mtk_clk_unregister_gates(top_clks, ARRAY_SIZE(top_clks), top_clk_data);
 unregister_composite_divs:
        mtk_clk_unregister_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), top_clk_data);
-unregister_composite_muxes:
-       mtk_clk_unregister_composites(top_muxes, ARRAY_SIZE(top_muxes), top_clk_data);
 unregister_muxes:
        mtk_clk_unregister_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), top_clk_data);
 unregister_factors:
@@ -1300,7 +1319,6 @@ static int clk_mt8195_topck_remove(struct platform_device *pdev)
        of_clk_del_provider(node);
        mtk_clk_unregister_gates(top_clks, ARRAY_SIZE(top_clks), top_clk_data);
        mtk_clk_unregister_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), top_clk_data);
-       mtk_clk_unregister_composites(top_muxes, ARRAY_SIZE(top_muxes), top_clk_data);
        mtk_clk_unregister_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), top_clk_data);
        mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
        mtk_clk_unregister_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), top_clk_data);
index 261a7f7..07b46bf 100644 (file)
@@ -37,6 +37,10 @@ static const struct mtk_gate_regs vdo0_2_cg_regs = {
 #define GATE_VDO0_2(_id, _name, _parent, _shift)                       \
        GATE_MTK(_id, _name, _parent, &vdo0_2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
 
+#define GATE_VDO0_2_FLAGS(_id, _name, _parent, _shift, _flags)         \
+       GATE_MTK_FLAGS(_id, _name, _parent, &vdo0_2_cg_regs, _shift,    \
+                      &mtk_clk_gate_ops_setclr, _flags)
+
 static const struct mtk_gate vdo0_clks[] = {
        /* VDO0_0 */
        GATE_VDO0_0(CLK_VDO0_DISP_OVL0, "vdo0_disp_ovl0", "top_vpp", 0),
@@ -85,7 +89,8 @@ static const struct mtk_gate vdo0_clks[] = {
        /* VDO0_2 */
        GATE_VDO0_2(CLK_VDO0_DSI0_DSI, "vdo0_dsi0_dsi", "top_dsi_occ", 0),
        GATE_VDO0_2(CLK_VDO0_DSI1_DSI, "vdo0_dsi1_dsi", "top_dsi_occ", 8),
-       GATE_VDO0_2(CLK_VDO0_DP_INTF0_DP_INTF, "vdo0_dp_intf0_dp_intf", "top_edp", 16),
+       GATE_VDO0_2_FLAGS(CLK_VDO0_DP_INTF0_DP_INTF, "vdo0_dp_intf0_dp_intf",
+                         "top_edp", 16, CLK_SET_RATE_PARENT),
 };
 
 static int clk_mt8195_vdo0_probe(struct platform_device *pdev)
index 3378487..835335b 100644 (file)
@@ -34,6 +34,12 @@ static const struct mtk_gate_regs vdo1_3_cg_regs = {
        .sta_ofs = 0x140,
 };
 
+static const struct mtk_gate_regs vdo1_4_cg_regs = {
+       .set_ofs = 0x400,
+       .clr_ofs = 0x400,
+       .sta_ofs = 0x400,
+};
+
 #define GATE_VDO1_0(_id, _name, _parent, _shift)                       \
        GATE_MTK(_id, _name, _parent, &vdo1_0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
 
@@ -43,9 +49,16 @@ static const struct mtk_gate_regs vdo1_3_cg_regs = {
 #define GATE_VDO1_2(_id, _name, _parent, _shift)                       \
        GATE_MTK(_id, _name, _parent, &vdo1_2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
 
+#define GATE_VDO1_2_FLAGS(_id, _name, _parent, _shift, _flags)         \
+       GATE_MTK_FLAGS(_id, _name, _parent, &vdo1_2_cg_regs, _shift,    \
+                      &mtk_clk_gate_ops_setclr, _flags)
+
 #define GATE_VDO1_3(_id, _name, _parent, _shift)                       \
        GATE_MTK(_id, _name, _parent, &vdo1_3_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
 
+#define GATE_VDO1_4(_id, _name, _parent, _shift)                       \
+       GATE_MTK(_id, _name, _parent, &vdo1_4_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
 static const struct mtk_gate vdo1_clks[] = {
        /* VDO1_0 */
        GATE_VDO1_0(CLK_VDO1_SMI_LARB2, "vdo1_smi_larb2", "top_vpp", 0),
@@ -99,10 +112,12 @@ static const struct mtk_gate vdo1_clks[] = {
        GATE_VDO1_2(CLK_VDO1_DISP_MONITOR_DPI0, "vdo1_disp_monitor_dpi0", "top_vpp", 1),
        GATE_VDO1_2(CLK_VDO1_DPI1, "vdo1_dpi1", "top_vpp", 8),
        GATE_VDO1_2(CLK_VDO1_DISP_MONITOR_DPI1, "vdo1_disp_monitor_dpi1", "top_vpp", 9),
-       GATE_VDO1_2(CLK_VDO1_DPINTF, "vdo1_dpintf", "top_vpp", 16),
+       GATE_VDO1_2_FLAGS(CLK_VDO1_DPINTF, "vdo1_dpintf", "top_dp", 16, CLK_SET_RATE_PARENT),
        GATE_VDO1_2(CLK_VDO1_DISP_MONITOR_DPINTF, "vdo1_disp_monitor_dpintf", "top_vpp", 17),
        /* VDO1_3 */
        GATE_VDO1_3(CLK_VDO1_26M_SLOW, "vdo1_26m_slow", "clk26m", 8),
+       /* VDO1_4 */
+       GATE_VDO1_4(CLK_VDO1_DPI1_HDMI, "vdo1_dpi1_hdmi", "hdmi_txpll", 0),
 };
 
 static int clk_mt8195_vdo1_probe(struct platform_device *pdev)
diff --git a/drivers/clk/mediatek/clk-mt8365-apu.c b/drivers/clk/mediatek/clk-mt8365-apu.c
new file mode 100644 (file)
index 0000000..91ffe89
--- /dev/null
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ */
+
+#include <dt-bindings/clock/mediatek,mt8365-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+static const struct mtk_gate_regs apu_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_APU(_id, _name, _parent, _shift) \
+               GATE_MTK(_id, _name, _parent, &apu_cg_regs, _shift, \
+                        &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate apu_clks[] = {
+       GATE_APU(CLK_APU_AHB, "apu_ahb", "ifr_apu_axi", 5),
+       GATE_APU(CLK_APU_EDMA, "apu_edma", "apu_sel", 4),
+       GATE_APU(CLK_APU_IF_CK, "apu_if_ck", "apu_if_sel", 3),
+       GATE_APU(CLK_APU_JTAG, "apu_jtag", "clk26m", 2),
+       GATE_APU(CLK_APU_AXI, "apu_axi", "apu_sel", 1),
+       GATE_APU(CLK_APU_IPU_CK, "apu_ck", "apu_sel", 0),
+};
+
+static const struct mtk_clk_desc apu_desc = {
+       .clks = apu_clks,
+       .num_clks = ARRAY_SIZE(apu_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8365_apu[] = {
+       {
+               .compatible = "mediatek,mt8365-apu",
+               .data = &apu_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8365_apu_drv = {
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
+       .driver = {
+               .name = "clk-mt8365-apu",
+               .of_match_table = of_match_clk_mt8365_apu,
+       },
+};
+builtin_platform_driver(clk_mt8365_apu_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8365-cam.c b/drivers/clk/mediatek/clk-mt8365-cam.c
new file mode 100644 (file)
index 0000000..31d5b5c
--- /dev/null
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ */
+
+#include <dt-bindings/clock/mediatek,mt8365-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+static const struct mtk_gate_regs cam_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_CAM(_id, _name, _parent, _shift) \
+               GATE_MTK(_id, _name, _parent, &cam_cg_regs, _shift, \
+                        &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate cam_clks[] = {
+       GATE_CAM(CLK_CAM_LARB2, "cam_larb2", "mm_sel", 0),
+       GATE_CAM(CLK_CAM, "cam", "mm_sel", 6),
+       GATE_CAM(CLK_CAMTG, "camtg", "mm_sel", 7),
+       GATE_CAM(CLK_CAM_SENIF, "cam_senif", "mm_sel", 8),
+       GATE_CAM(CLK_CAMSV0, "camsv0", "mm_sel", 9),
+       GATE_CAM(CLK_CAMSV1, "camsv1", "mm_sel", 10),
+       GATE_CAM(CLK_CAM_FDVT, "cam_fdvt", "mm_sel", 11),
+       GATE_CAM(CLK_CAM_WPE, "cam_wpe", "mm_sel", 12),
+};
+
+static const struct mtk_clk_desc cam_desc = {
+       .clks = cam_clks,
+       .num_clks = ARRAY_SIZE(cam_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8365_cam[] = {
+       {
+               .compatible = "mediatek,mt8365-imgsys",
+               .data = &cam_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8365_cam_drv = {
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
+       .driver = {
+               .name = "clk-mt8365-cam",
+               .of_match_table = of_match_clk_mt8365_cam,
+       },
+};
+builtin_platform_driver(clk_mt8365_cam_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8365-mfg.c b/drivers/clk/mediatek/clk-mt8365-mfg.c
new file mode 100644 (file)
index 0000000..587b491
--- /dev/null
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ */
+
+#include <dt-bindings/clock/mediatek,mt8365-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+static const struct mtk_gate_regs mfg0_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs mfg1_cg_regs = {
+       .set_ofs = 0x280,
+       .clr_ofs = 0x280,
+       .sta_ofs = 0x280,
+};
+
+#define GATE_MFG0(_id, _name, _parent, _shift) \
+               GATE_MTK(_id, _name, _parent, &mfg0_cg_regs, _shift, \
+                        &mtk_clk_gate_ops_setclr)
+
+#define GATE_MFG1(_id, _name, _parent, _shift) \
+               GATE_MTK(_id, _name, _parent, &mfg1_cg_regs, _shift, \
+                        &mtk_clk_gate_ops_no_setclr)
+
+static const struct mtk_gate mfg_clks[] = {
+       /* MFG0 */
+       GATE_MFG0(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0),
+       /* MFG1 */
+       GATE_MFG1(CLK_MFG_MBIST_DIAG, "mfg_mbist_diag", "mbist_diag_sel", 24),
+};
+
+static const struct mtk_clk_desc mfg_desc = {
+       .clks = mfg_clks,
+       .num_clks = ARRAY_SIZE(mfg_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8365_mfg[] = {
+       {
+               .compatible = "mediatek,mt8365-mfgcfg",
+               .data = &mfg_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8365_mfg_drv = {
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
+       .driver = {
+               .name = "clk-mt8365-mfg",
+               .of_match_table = of_match_clk_mt8365_mfg,
+       },
+};
+builtin_platform_driver(clk_mt8365_mfg_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8365-mm.c b/drivers/clk/mediatek/clk-mt8365-mm.c
new file mode 100644 (file)
index 0000000..5c8bf18
--- /dev/null
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Copyright (c) 2022 BayLibre, SAS
+ */
+
+#include <dt-bindings/clock/mediatek,mt8365-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+static const struct mtk_gate_regs mm0_cg_regs = {
+       .set_ofs = 0x104,
+       .clr_ofs = 0x108,
+       .sta_ofs = 0x100,
+};
+
+static const struct mtk_gate_regs mm1_cg_regs = {
+       .set_ofs = 0x114,
+       .clr_ofs = 0x118,
+       .sta_ofs = 0x110,
+};
+
+#define GATE_MM0(_id, _name, _parent, _shift) \
+               GATE_MTK(_id, _name, _parent, &mm0_cg_regs, _shift, \
+                        &mtk_clk_gate_ops_setclr)
+
+#define GATE_MM1(_id, _name, _parent, _shift) \
+               GATE_MTK(_id, _name, _parent, &mm1_cg_regs, _shift, \
+                        &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate mm_clks[] = {
+       /* MM0 */
+       GATE_MM0(CLK_MM_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 0),
+       GATE_MM0(CLK_MM_MM_MDP_CCORR0, "mm_mdp_ccorr0", "mm_sel", 1),
+       GATE_MM0(CLK_MM_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 2),
+       GATE_MM0(CLK_MM_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 3),
+       GATE_MM0(CLK_MM_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_sel", 4),
+       GATE_MM0(CLK_MM_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 5),
+       GATE_MM0(CLK_MM_MM_MDP_WDMA0, "mm_mdp_wdma0", "mm_sel", 6),
+       GATE_MM0(CLK_MM_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 7),
+       GATE_MM0(CLK_MM_MM_DISP_OVL0_2L, "mm_disp_ovl0_2l", "mm_sel", 8),
+       GATE_MM0(CLK_MM_MM_DISP_RSZ0, "mm_disp_rsz0", "mm_sel", 9),
+       GATE_MM0(CLK_MM_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 10),
+       GATE_MM0(CLK_MM_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 11),
+       GATE_MM0(CLK_MM_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 12),
+       GATE_MM0(CLK_MM_MM_DISP_CCORR0, "mm_disp_ccorr0", "mm_sel", 13),
+       GATE_MM0(CLK_MM_MM_DISP_AAL0, "mm_disp_aal0", "mm_sel", 14),
+       GATE_MM0(CLK_MM_MM_DISP_GAMMA0, "mm_disp_gamma0", "mm_sel", 15),
+       GATE_MM0(CLK_MM_MM_DISP_DITHER0, "mm_disp_dither0", "mm_sel", 16),
+       GATE_MM0(CLK_MM_MM_DSI0, "mm_dsi0", "mm_sel", 17),
+       GATE_MM0(CLK_MM_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 18),
+       GATE_MM0(CLK_MM_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 19),
+       GATE_MM0(CLK_MM_DPI0_DPI0, "mm_dpi0_dpi0", "vpll_dpix", 20),
+       GATE_MM0(CLK_MM_MM_FAKE, "mm_fake", "mm_sel", 21),
+       GATE_MM0(CLK_MM_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 22),
+       GATE_MM0(CLK_MM_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 23),
+       GATE_MM0(CLK_MM_MM_SMI_COMM0, "mm_smi_comm0", "mm_sel", 24),
+       GATE_MM0(CLK_MM_MM_SMI_COMM1, "mm_smi_comm1", "mm_sel", 25),
+       GATE_MM0(CLK_MM_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 26),
+       GATE_MM0(CLK_MM_MM_SMI_IMG, "mm_smi_img", "mm_sel", 27),
+       GATE_MM0(CLK_MM_MM_SMI_CAM, "mm_smi_cam", "mm_sel", 28),
+       GATE_MM0(CLK_MM_IMG_IMG_DL_RELAY, "mm_dl_relay", "mm_sel", 29),
+       GATE_MM0(CLK_MM_IMG_IMG_DL_ASYNC_TOP, "mm_dl_async_top", "mm_sel", 30),
+       GATE_MM0(CLK_MM_DSI0_DIG_DSI, "mm_dsi0_dig_dsi", "dsi0_lntc_dsick", 31),
+       /* MM1 */
+       GATE_MM1(CLK_MM_26M_HRTWT, "mm_f26m_hrtwt", "clk26m", 0),
+       GATE_MM1(CLK_MM_MM_DPI0, "mm_dpi0", "mm_sel", 1),
+       GATE_MM1(CLK_MM_LVDSTX_PXL, "mm_flvdstx_pxl", "vpll_dpix", 2),
+       GATE_MM1(CLK_MM_LVDSTX_CTS, "mm_flvdstx_cts", "lvdstx_dig_cts", 3),
+};
+
+static int clk_mt8365_mm_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *node = dev->parent->of_node;
+       struct clk_hw_onecell_data *clk_data;
+       int ret;
+
+       clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
+
+       ret = mtk_clk_register_gates_with_dev(node, mm_clks,
+                                             ARRAY_SIZE(mm_clks), clk_data,
+                                             dev);
+       if (ret)
+               goto err_free_clk_data;
+
+       ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (ret)
+               goto err_unregister_gates;
+
+       return 0;
+
+err_unregister_gates:
+       mtk_clk_unregister_gates(mm_clks, ARRAY_SIZE(mm_clks), clk_data);
+
+err_free_clk_data:
+       mtk_free_clk_data(clk_data);
+
+       return ret;
+}
+
+static struct platform_driver clk_mt8365_mm_drv = {
+       .probe = clk_mt8365_mm_probe,
+       .driver = {
+               .name = "clk-mt8365-mm",
+       },
+};
+builtin_platform_driver(clk_mt8365_mm_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8365-vdec.c b/drivers/clk/mediatek/clk-mt8365-vdec.c
new file mode 100644 (file)
index 0000000..cdc678e
--- /dev/null
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ */
+
+#include <dt-bindings/clock/mediatek,mt8365-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+static const struct mtk_gate_regs vdec0_cg_regs = {
+       .set_ofs = 0x0,
+       .clr_ofs = 0x4,
+       .sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs vdec1_cg_regs = {
+       .set_ofs = 0x8,
+       .clr_ofs = 0xc,
+       .sta_ofs = 0x8,
+};
+
+#define GATE_VDEC0(_id, _name, _parent, _shift) \
+               GATE_MTK(_id, _name, _parent, &vdec0_cg_regs, _shift, \
+                        &mtk_clk_gate_ops_setclr_inv)
+
+#define GATE_VDEC1(_id, _name, _parent, _shift) \
+               GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, \
+                        &mtk_clk_gate_ops_setclr_inv)
+
+static const struct mtk_gate vdec_clks[] = {
+       /* VDEC0 */
+       GATE_VDEC0(CLK_VDEC_VDEC, "vdec_fvdec_ck", "mm_sel", 0),
+       /* VDEC1 */
+       GATE_VDEC1(CLK_VDEC_LARB1, "vdec_flarb1_ck", "mm_sel", 0),
+};
+
+static const struct mtk_clk_desc vdec_desc = {
+       .clks = vdec_clks,
+       .num_clks = ARRAY_SIZE(vdec_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8365_vdec[] = {
+       {
+               .compatible = "mediatek,mt8365-vdecsys",
+               .data = &vdec_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8365_vdec_drv = {
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
+       .driver = {
+               .name = "clk-mt8365-vdec",
+               .of_match_table = of_match_clk_mt8365_vdec,
+       },
+};
+builtin_platform_driver(clk_mt8365_vdec_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8365-venc.c b/drivers/clk/mediatek/clk-mt8365-venc.c
new file mode 100644 (file)
index 0000000..0e080c2
--- /dev/null
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ */
+
+#include <dt-bindings/clock/mediatek,mt8365-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+static const struct mtk_gate_regs venc_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_VENC(_id, _name, _parent, _shift) \
+               GATE_MTK(_id, _name, _parent, &venc_cg_regs, _shift, \
+                        &mtk_clk_gate_ops_setclr_inv)
+
+static const struct mtk_gate venc_clks[] = {
+       /* VENC */
+       GATE_VENC(CLK_VENC, "venc_fvenc_ck", "mm_sel", 4),
+       GATE_VENC(CLK_VENC_JPGENC, "venc_jpgenc_ck", "mm_sel", 8),
+};
+
+static const struct mtk_clk_desc venc_desc = {
+       .clks = venc_clks,
+       .num_clks = ARRAY_SIZE(venc_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8365_venc[] = {
+       {
+               .compatible = "mediatek,mt8365-vencsys",
+               .data = &venc_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8365_venc_drv = {
+       .probe = mtk_clk_simple_probe,
+       .remove = mtk_clk_simple_remove,
+       .driver = {
+               .name = "clk-mt8365-venc",
+               .of_match_table = of_match_clk_mt8365_venc,
+       },
+};
+builtin_platform_driver(clk_mt8365_venc_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8365.c b/drivers/clk/mediatek/clk-mt8365.c
new file mode 100644 (file)
index 0000000..adfecb6
--- /dev/null
@@ -0,0 +1,1155 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ */
+
+#include <dt-bindings/clock/mediatek,mt8365-clk.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+#include "clk-mux.h"
+#include "clk-pll.h"
+
+static DEFINE_SPINLOCK(mt8365_clk_lock);
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+       FIXED_CLK(CLK_TOP_I2S0_BCK, "i2s0_bck", NULL, 26000000),
+       FIXED_CLK(CLK_TOP_DSI0_LNTC_DSICK, "dsi0_lntc_dsick", "clk26m",
+                 75000000),
+       FIXED_CLK(CLK_TOP_VPLL_DPIX, "vpll_dpix", "clk26m", 75000000),
+       FIXED_CLK(CLK_TOP_LVDSTX_CLKDIG_CTS, "lvdstx_dig_cts", "clk26m",
+                 52500000),
+};
+
+static const struct mtk_fixed_factor top_divs[] = {
+       FACTOR(CLK_TOP_SYS_26M_D2, "sys_26m_d2", "clk26m", 1, 2),
+       FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2),
+       FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "mainpll", 1, 4),
+       FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "mainpll", 1, 8),
+       FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "mainpll", 1, 16),
+       FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "mainpll", 1, 32),
+       FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3),
+       FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "mainpll", 1, 6),
+       FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "mainpll", 1, 12),
+       FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "mainpll", 1, 24),
+       FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5),
+       FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "mainpll", 1, 10),
+       FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "mainpll", 1, 20),
+       FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7),
+       FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "mainpll", 1, 14),
+       FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "mainpll", 1, 28),
+       FACTOR(CLK_TOP_UNIVPLL, "univpll", "univ_en", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll", 1, 8),
+       FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
+       FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll", 1, 6),
+       FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll", 1, 12),
+       FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll", 1, 24),
+       FACTOR(CLK_TOP_UNIVPLL2_D32, "univpll2_d32", "univpll", 1, 96),
+       FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
+       FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll", 1, 10),
+       FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll", 1, 20),
+       FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, 1),
+       FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
+       FACTOR(CLK_TOP_MFGPLL, "mfgpll_ck", "mfgpll", 1, 1),
+       FACTOR(CLK_TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2),
+       FACTOR(CLK_TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4),
+       FACTOR(CLK_TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8),
+       FACTOR(CLK_TOP_LVDSPLL_D16, "lvdspll_d16", "lvdspll", 1, 16),
+       FACTOR(CLK_TOP_USB20_192M, "usb20_192m_ck", "usb20_en", 1, 13),
+       FACTOR(CLK_TOP_USB20_192M_D4, "usb20_192m_d4", "usb20_192m_ck", 1, 4),
+       FACTOR(CLK_TOP_USB20_192M_D8, "usb20_192m_d8", "usb20_192m_ck", 1, 8),
+       FACTOR(CLK_TOP_USB20_192M_D16, "usb20_192m_d16", "usb20_192m_ck",
+              1, 16),
+       FACTOR(CLK_TOP_USB20_192M_D32, "usb20_192m_d32", "usb20_192m_ck",
+              1, 32),
+       FACTOR(CLK_TOP_APLL1, "apll1_ck", "apll1", 1, 1),
+       FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1_ck", 1, 2),
+       FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "apll1_ck", 1, 4),
+       FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "apll1_ck", 1, 8),
+       FACTOR(CLK_TOP_APLL2, "apll2_ck", "apll2", 1, 1),
+       FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2_ck", 1, 2),
+       FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2_ck", 1, 4),
+       FACTOR(CLK_TOP_APLL2_D8, "apll2_d8", "apll2_ck", 1, 8),
+       FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1),
+       FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
+       FACTOR(CLK_TOP_DSPPLL, "dsppll_ck", "dsppll", 1, 1),
+       FACTOR(CLK_TOP_DSPPLL_D2, "dsppll_d2", "dsppll", 1, 2),
+       FACTOR(CLK_TOP_DSPPLL_D4, "dsppll_d4", "dsppll", 1, 4),
+       FACTOR(CLK_TOP_DSPPLL_D8, "dsppll_d8", "dsppll", 1, 8),
+       FACTOR(CLK_TOP_APUPLL, "apupll_ck", "apupll", 1, 1),
+       FACTOR(CLK_TOP_CLK26M_D52, "clk26m_d52", "clk26m", 1, 52),
+};
+
+static const char * const axi_parents[] = {
+       "clk26m",
+       "syspll_d7",
+       "syspll1_d4",
+       "syspll3_d2"
+};
+
+static const char * const mem_parents[] = {
+       "clk26m",
+       "mmpll_ck",
+       "syspll_d3",
+       "syspll1_d2"
+};
+
+static const char * const mm_parents[] = {
+       "clk26m",
+       "mmpll_ck",
+       "syspll1_d2",
+       "syspll_d5",
+       "syspll1_d4",
+       "univpll_d5",
+       "univpll1_d2",
+       "mmpll_d2"
+};
+
+static const char * const scp_parents[] = {
+       "clk26m",
+       "syspll4_d2",
+       "univpll2_d2",
+       "syspll1_d2",
+       "univpll1_d2",
+       "syspll_d3",
+       "univpll_d3"
+};
+
+static const char * const mfg_parents[] = {
+       "clk26m",
+       "mfgpll_ck",
+       "syspll_d3",
+       "univpll_d3"
+};
+
+static const char * const atb_parents[] = {
+       "clk26m",
+       "syspll1_d4",
+       "syspll1_d2"
+};
+
+static const char * const camtg_parents[] = {
+       "clk26m",
+       "usb20_192m_d8",
+       "univpll2_d8",
+       "usb20_192m_d4",
+       "univpll2_d32",
+       "usb20_192m_d16",
+       "usb20_192m_d32"
+};
+
+static const char * const uart_parents[] = {
+       "clk26m",
+       "univpll2_d8"
+};
+
+static const char * const spi_parents[] = {
+       "clk26m",
+       "univpll2_d2",
+       "univpll2_d4",
+       "univpll2_d8"
+};
+
+static const char * const msdc50_0_hc_parents[] = {
+       "clk26m",
+       "syspll1_d2",
+       "univpll1_d4",
+       "syspll2_d2"
+};
+
+static const char * const msdc50_0_parents[] = {
+       "clk26m",
+       "msdcpll_ck",
+       "univpll1_d2",
+       "syspll1_d2",
+       "univpll_d5",
+       "syspll2_d2",
+       "univpll1_d4",
+       "syspll4_d2"
+};
+
+static const char * const msdc50_2_parents[] = {
+       "clk26m",
+       "msdcpll_ck",
+       "univpll_d3",
+       "univpll1_d2",
+       "syspll1_d2",
+       "univpll2_d2",
+       "syspll2_d2",
+       "univpll1_d4"
+};
+
+static const char * const msdc30_1_parents[] = {
+       "clk26m",
+       "msdcpll_d2",
+       "univpll2_d2",
+       "syspll2_d2",
+       "univpll1_d4",
+       "syspll1_d4",
+       "syspll2_d4",
+       "univpll2_d8"
+};
+
+static const char * const audio_parents[] = {
+       "clk26m",
+       "syspll3_d4",
+       "syspll4_d4",
+       "syspll1_d16"
+};
+
+static const char * const aud_intbus_parents[] = {
+       "clk26m",
+       "syspll1_d4",
+       "syspll4_d2"
+};
+
+static const char * const aud_1_parents[] = {
+       "clk26m",
+       "apll1_ck"
+};
+
+static const char * const aud_2_parents[] = {
+       "clk26m",
+       "apll2_ck"
+};
+
+static const char * const aud_engen1_parents[] = {
+       "clk26m",
+       "apll1_d2",
+       "apll1_d4",
+       "apll1_d8"
+};
+
+static const char * const aud_engen2_parents[] = {
+       "clk26m",
+       "apll2_d2",
+       "apll2_d4",
+       "apll2_d8"
+};
+
+static const char * const aud_spdif_parents[] = {
+       "clk26m",
+       "univpll_d2"
+};
+
+static const char * const disp_pwm_parents[] = {
+       "clk26m",
+       "univpll2_d4"
+};
+
+static const char * const dxcc_parents[] = {
+       "clk26m",
+       "syspll1_d2",
+       "syspll1_d4",
+       "syspll1_d8"
+};
+
+static const char * const ssusb_sys_parents[] = {
+       "clk26m",
+       "univpll3_d4",
+       "univpll2_d4",
+       "univpll3_d2"
+};
+
+static const char * const spm_parents[] = {
+       "clk26m",
+       "syspll1_d8"
+};
+
+static const char * const i2c_parents[] = {
+       "clk26m",
+       "univpll3_d4",
+       "univpll3_d2",
+       "syspll1_d8",
+       "syspll2_d8"
+};
+
+static const char * const pwm_parents[] = {
+       "clk26m",
+       "univpll3_d4",
+       "syspll1_d8"
+};
+
+static const char * const senif_parents[] = {
+       "clk26m",
+       "univpll1_d4",
+       "univpll1_d2",
+       "univpll2_d2"
+};
+
+static const char * const aes_fde_parents[] = {
+       "clk26m",
+       "msdcpll_ck",
+       "univpll_d3",
+       "univpll2_d2",
+       "univpll1_d2",
+       "syspll1_d2"
+};
+
+static const char * const dpi0_parents[] = {
+       "clk26m",
+       "lvdspll_d2",
+       "lvdspll_d4",
+       "lvdspll_d8",
+       "lvdspll_d16"
+};
+
+static const char * const dsp_parents[] = {
+       "clk26m",
+       "sys_26m_d2",
+       "dsppll_ck",
+       "dsppll_d2",
+       "dsppll_d4",
+       "dsppll_d8"
+};
+
+static const char * const nfi2x_parents[] = {
+       "clk26m",
+       "syspll2_d2",
+       "syspll_d7",
+       "syspll_d3",
+       "syspll2_d4",
+       "msdcpll_d2",
+       "univpll1_d2",
+       "univpll_d5"
+};
+
+static const char * const nfiecc_parents[] = {
+       "clk26m",
+       "syspll4_d2",
+       "univpll2_d4",
+       "syspll_d7",
+       "univpll1_d2",
+       "syspll1_d2",
+       "univpll2_d2",
+       "syspll_d5"
+};
+
+static const char * const ecc_parents[] = {
+       "clk26m",
+       "univpll2_d2",
+       "univpll1_d2",
+       "univpll_d3",
+       "syspll_d2"
+};
+
+static const char * const eth_parents[] = {
+       "clk26m",
+       "univpll2_d8",
+       "syspll4_d4",
+       "syspll1_d8",
+       "syspll4_d2"
+};
+
+static const char * const gcpu_parents[] = {
+       "clk26m",
+       "univpll_d3",
+       "univpll2_d2",
+       "syspll_d3",
+       "syspll2_d2"
+};
+
+static const char * const gcpu_cpm_parents[] = {
+       "clk26m",
+       "univpll2_d2",
+       "syspll2_d2"
+};
+
+static const char * const apu_parents[] = {
+       "clk26m",
+       "univpll_d2",
+       "apupll_ck",
+       "mmpll_ck",
+       "syspll_d3",
+       "univpll1_d2",
+       "syspll1_d2",
+       "syspll1_d4"
+};
+
+static const char * const mbist_diag_parents[] = {
+       "clk26m",
+       "syspll4_d4",
+       "univpll2_d8"
+};
+
+static const char * const apll_i2s0_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static struct mtk_composite top_misc_mux_gates[] = {
+       /* CLK_CFG_11 */
+       MUX_GATE(CLK_TOP_MBIST_DIAG_SEL, "mbist_diag_sel", mbist_diag_parents,
+                0x0ec, 0, 2, 7),
+};
+
+struct mt8365_clk_audio_mux {
+       int id;
+       const char *name;
+       u8 shift;
+};
+
+static struct mt8365_clk_audio_mux top_misc_muxes[] = {
+       { CLK_TOP_APLL_I2S0_SEL, "apll_i2s0_sel", 11},
+       { CLK_TOP_APLL_I2S1_SEL, "apll_i2s1_sel", 12},
+       { CLK_TOP_APLL_I2S2_SEL, "apll_i2s2_sel", 13},
+       { CLK_TOP_APLL_I2S3_SEL, "apll_i2s3_sel", 14},
+       { CLK_TOP_APLL_TDMOUT_SEL, "apll_tdmout_sel", 15},
+       { CLK_TOP_APLL_TDMIN_SEL, "apll_tdmin_sel", 16},
+       { CLK_TOP_APLL_SPDIF_SEL, "apll_spdif_sel", 17},
+};
+
+#define CLK_CFG_UPDATE 0x004
+#define CLK_CFG_UPDATE1 0x008
+
+static const struct mtk_mux top_muxes[] = {
+       /* CLK_CFG_0 */
+       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
+                                  0x040, 0x044, 0x048, 0, 2, 7, CLK_CFG_UPDATE,
+                                  0, CLK_IS_CRITICAL),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x040,
+                            0x044, 0x048, 8, 2, 15, CLK_CFG_UPDATE, 1),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MM_SEL, "mm_sel", mm_parents, 0x040, 0x044,
+                            0x048, 16, 3, 23, CLK_CFG_UPDATE, 2),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, 0x040,
+                            0x044, 0x048, 24, 3, 31, CLK_CFG_UPDATE, 3),
+       /* CLK_CFG_1 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x050,
+                            0x054, 0x058, 0, 2, 7, CLK_CFG_UPDATE, 4),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_ATB_SEL, "atb_sel", atb_parents, 0x050,
+                            0x054, 0x058, 8, 2, 15, CLK_CFG_UPDATE, 5),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents,
+                            0x050, 0x054, 0x058, 16, 3, 23, CLK_CFG_UPDATE, 6),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG1_SEL, "camtg1_sel", camtg_parents,
+                            0x050, 0x054, 0x058, 24, 3, 31, CLK_CFG_UPDATE, 7),
+       /* CLK_CFG_2 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x060,
+                            0x064, 0x068, 0, 1, 7, CLK_CFG_UPDATE, 8),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x060,
+                            0x064, 0x068, 8, 2, 15, CLK_CFG_UPDATE, 9),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_HC_SEL, "msdc50_0_hc_sel",
+                            msdc50_0_hc_parents, 0x060, 0x064, 0x068, 16, 2,
+                            23, CLK_CFG_UPDATE, 10),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC2_2_HC_SEL, "msdc2_2_hc_sel",
+                            msdc50_0_hc_parents, 0x060, 0x064, 0x068, 24, 2,
+                            31, CLK_CFG_UPDATE, 11),
+       /* CLK_CFG_3 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel",
+                            msdc50_0_parents, 0x070, 0x074, 0x078, 0, 3, 7,
+                            CLK_CFG_UPDATE, 12),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_2_SEL, "msdc50_2_sel",
+                            msdc50_2_parents, 0x070, 0x074, 0x078, 8, 3, 15,
+                            CLK_CFG_UPDATE, 13),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel",
+                            msdc30_1_parents, 0x070, 0x074, 0x078, 16, 3, 23,
+                            CLK_CFG_UPDATE, 14),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents,
+                            0x070, 0x074, 0x078, 24, 2, 31, CLK_CFG_UPDATE,
+                            15),
+       /* CLK_CFG_4 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel",
+                            aud_intbus_parents, 0x080, 0x084, 0x088, 0, 2, 7,
+                            CLK_CFG_UPDATE, 16),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_1_SEL, "aud_1_sel", aud_1_parents,
+                            0x080, 0x084, 0x088, 8, 1, 15, CLK_CFG_UPDATE, 17),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_2_SEL, "aud_2_sel", aud_2_parents,
+                            0x080, 0x084, 0x088, 16, 1, 23, CLK_CFG_UPDATE,
+                            18),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENGEN1_SEL, "aud_engen1_sel",
+                            aud_engen1_parents, 0x080, 0x084, 0x088, 24, 2, 31,
+                            CLK_CFG_UPDATE, 19),
+       /* CLK_CFG_5 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENGEN2_SEL, "aud_engen2_sel",
+                            aud_engen2_parents, 0x090, 0x094, 0x098, 0, 2, 7,
+                            CLK_CFG_UPDATE, 20),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_SPDIF_SEL, "aud_spdif_sel",
+                            aud_spdif_parents, 0x090, 0x094, 0x098, 8, 1, 15,
+                            CLK_CFG_UPDATE, 21),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_PWM_SEL, "disp_pwm_sel",
+                            disp_pwm_parents, 0x090, 0x094, 0x098, 16, 2, 23,
+                            CLK_CFG_UPDATE, 22),
+       /* CLK_CFG_6 */
+       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DXCC_SEL, "dxcc_sel", dxcc_parents,
+                                  0x0a0, 0x0a4, 0x0a8, 0, 2, 7, CLK_CFG_UPDATE,
+                                  24, CLK_IS_CRITICAL),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_SYS_SEL, "ssusb_sys_sel",
+                            ssusb_sys_parents, 0x0a0, 0x0a4, 0x0a8, 8, 2, 15,
+                            CLK_CFG_UPDATE, 25),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI_SEL, "ssusb_xhci_sel",
+                            ssusb_sys_parents, 0x0a0, 0x0a4, 0x0a8, 16, 2, 23,
+                            CLK_CFG_UPDATE, 26),
+       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SPM_SEL, "spm_sel", spm_parents,
+                                  0x0a0, 0x0a4, 0x0a8, 24, 1, 31,
+                                  CLK_CFG_UPDATE, 27, CLK_IS_CRITICAL),
+       /* CLK_CFG_7 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x0b0,
+                            0x0b4, 0x0b8, 0, 3, 7, CLK_CFG_UPDATE, 28),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x0b0,
+                            0x0b4, 0x0b8, 8, 2, 15, CLK_CFG_UPDATE, 29),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SENIF_SEL, "senif_sel", senif_parents,
+                            0x0b0, 0x0b4, 0x0b8, 16, 2, 23, CLK_CFG_UPDATE,
+                            30),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_FDE_SEL, "aes_fde_sel",
+                            aes_fde_parents, 0x0b0, 0x0b4, 0x0b8, 24, 3, 31,
+                            CLK_CFG_UPDATE, 31),
+       /* CLK_CFG_8 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTM_SEL, "camtm_sel", senif_parents,
+                            0x0c0, 0x0c4, 0x0c8, 0, 2, 7, CLK_CFG_UPDATE1, 0),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 0x0c0,
+                            0x0c4, 0x0c8, 8, 3, 15, CLK_CFG_UPDATE1, 1),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi0_parents, 0x0c0,
+                            0x0c4, 0x0c8, 16, 3, 23, CLK_CFG_UPDATE1, 2),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP_SEL, "dsp_sel", dsp_parents, 0x0c0,
+                            0x0c4, 0x0c8, 24, 3, 31, CLK_CFG_UPDATE1, 3),
+       /* CLK_CFG_9 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_NFI2X_SEL, "nfi2x_sel", nfi2x_parents,
+                            0x0d0, 0x0d4, 0x0d8, 0, 3, 7, CLK_CFG_UPDATE1, 4),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_NFIECC_SEL, "nfiecc_sel", nfiecc_parents,
+                            0x0d0, 0x0d4, 0x0d8, 8, 3, 15, CLK_CFG_UPDATE1, 5),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_ECC_SEL, "ecc_sel", ecc_parents, 0x0d0,
+                            0x0d4, 0x0d8, 16, 3, 23, CLK_CFG_UPDATE1, 6),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_SEL, "eth_sel", eth_parents, 0x0d0,
+                            0x0d4, 0x0d8, 24, 3, 31, CLK_CFG_UPDATE1, 7),
+       /* CLK_CFG_10 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_GCPU_SEL, "gcpu_sel", gcpu_parents, 0x0e0,
+                            0x0e4, 0x0e8, 0, 3, 7, CLK_CFG_UPDATE1, 8),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_GCPU_CPM_SEL, "gcpu_cpm_sel",
+                            gcpu_cpm_parents, 0x0e0, 0x0e4, 0x0e8, 8, 2, 15,
+                            CLK_CFG_UPDATE1, 9),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_APU_SEL, "apu_sel", apu_parents, 0x0e0,
+                            0x0e4, 0x0e8, 16, 3, 23, CLK_CFG_UPDATE1, 10),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_APU_IF_SEL, "apu_if_sel", apu_parents,
+                            0x0e0, 0x0e4, 0x0e8, 24, 3, 31, CLK_CFG_UPDATE1,
+                            11),
+};
+
+static const char * const mcu_bus_parents[] = {
+       "clk26m",
+       "armpll",
+       "mainpll",
+       "univpll_d2"
+};
+
+static struct mtk_composite mcu_muxes[] = {
+       /* bus_pll_divider_cfg */
+       MUX_GATE_FLAGS(CLK_MCU_BUS_SEL, "mcu_bus_sel", mcu_bus_parents, 0x7C0,
+                      9, 2, -1, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
+};
+
+#define DIV_ADJ_F(_id, _name, _parent, _reg, _shift, _width, _flags) { \
+               .id = _id,                                      \
+               .name = _name,                                  \
+               .parent_name = _parent,                         \
+               .div_reg = _reg,                                \
+               .div_shift = _shift,                            \
+               .div_width = _width,                            \
+               .clk_divider_flags = _flags,                    \
+}
+
+static const struct mtk_clk_divider top_adj_divs[] = {
+       DIV_ADJ_F(CLK_TOP_APLL12_CK_DIV0, "apll12_ck_div0", "apll_i2s0_sel",
+                 0x324, 0, 8, CLK_DIVIDER_ROUND_CLOSEST),
+       DIV_ADJ_F(CLK_TOP_APLL12_CK_DIV1, "apll12_ck_div1", "apll_i2s1_sel",
+                 0x324, 8, 8, CLK_DIVIDER_ROUND_CLOSEST),
+       DIV_ADJ_F(CLK_TOP_APLL12_CK_DIV2, "apll12_ck_div2", "apll_i2s2_sel",
+                 0x324, 16, 8, CLK_DIVIDER_ROUND_CLOSEST),
+       DIV_ADJ_F(CLK_TOP_APLL12_CK_DIV3, "apll12_ck_div3", "apll_i2s3_sel",
+                 0x324, 24, 8, CLK_DIVIDER_ROUND_CLOSEST),
+       DIV_ADJ_F(CLK_TOP_APLL12_CK_DIV6, "apll12_ck_div6", "apll_spdif_sel",
+                 0x32c, 0, 8, CLK_DIVIDER_ROUND_CLOSEST),
+};
+
+struct mtk_simple_gate {
+       int id;
+       const char *name;
+       const char *parent;
+       u32 reg;
+       u8 shift;
+       unsigned long gate_flags;
+};
+
+static const struct mtk_simple_gate top_clk_gates[] = {
+       { CLK_TOP_CONN_32K, "conn_32k", "clk32k", 0x0, 10, CLK_GATE_SET_TO_DISABLE },
+       { CLK_TOP_CONN_26M, "conn_26m", "clk26m", 0x0, 11, CLK_GATE_SET_TO_DISABLE },
+       { CLK_TOP_DSP_32K, "dsp_32k", "clk32k", 0x0, 16, CLK_GATE_SET_TO_DISABLE },
+       { CLK_TOP_DSP_26M, "dsp_26m", "clk26m", 0x0, 17, CLK_GATE_SET_TO_DISABLE },
+       { CLK_TOP_USB20_48M_EN, "usb20_48m_en", "usb20_192m_d4", 0x104, 8, 0 },
+       { CLK_TOP_UNIVPLL_48M_EN, "univpll_48m_en", "usb20_192m_d4", 0x104, 9, 0 },
+       { CLK_TOP_LVDSTX_CLKDIG_EN, "lvdstx_dig_en", "lvdstx_dig_cts", 0x104, 20, 0 },
+       { CLK_TOP_VPLL_DPIX_EN, "vpll_dpix_en", "vpll_dpix", 0x104, 21, 0 },
+       { CLK_TOP_SSUSB_TOP_CK_EN, "ssusb_top_ck_en", NULL, 0x104, 22, 0 },
+       { CLK_TOP_SSUSB_PHY_CK_EN, "ssusb_phy_ck_en", NULL, 0x104, 23, 0 },
+       { CLK_TOP_AUD_I2S0_M, "aud_i2s0_m_ck", "apll12_ck_div0", 0x320, 0, 0 },
+       { CLK_TOP_AUD_I2S1_M, "aud_i2s1_m_ck", "apll12_ck_div1", 0x320, 1, 0 },
+       { CLK_TOP_AUD_I2S2_M, "aud_i2s2_m_ck", "apll12_ck_div2", 0x320, 2, 0 },
+       { CLK_TOP_AUD_I2S3_M, "aud_i2s3_m_ck", "apll12_ck_div3", 0x320, 3, 0 },
+       { CLK_TOP_AUD_TDMOUT_M, "aud_tdmout_m_ck", "apll12_ck_div4", 0x320, 4, 0 },
+       { CLK_TOP_AUD_TDMOUT_B, "aud_tdmout_b_ck", "apll12_ck_div4b", 0x320, 5, 0 },
+       { CLK_TOP_AUD_TDMIN_M, "aud_tdmin_m_ck", "apll12_ck_div5", 0x320, 6, 0 },
+       { CLK_TOP_AUD_TDMIN_B, "aud_tdmin_b_ck", "apll12_ck_div5b", 0x320, 7, 0 },
+       { CLK_TOP_AUD_SPDIF_M, "aud_spdif_m_ck", "apll12_ck_div6", 0x320, 8, 0 },
+};
+
+static const struct mtk_gate_regs ifr2_cg_regs = {
+       .set_ofs = 0x80,
+       .clr_ofs = 0x84,
+       .sta_ofs = 0x90,
+};
+
+static const struct mtk_gate_regs ifr3_cg_regs = {
+       .set_ofs = 0x88,
+       .clr_ofs = 0x8c,
+       .sta_ofs = 0x94,
+};
+
+static const struct mtk_gate_regs ifr4_cg_regs = {
+       .set_ofs = 0xa4,
+       .clr_ofs = 0xa8,
+       .sta_ofs = 0xac,
+};
+
+static const struct mtk_gate_regs ifr5_cg_regs = {
+       .set_ofs = 0xc0,
+       .clr_ofs = 0xc4,
+       .sta_ofs = 0xc8,
+};
+
+static const struct mtk_gate_regs ifr6_cg_regs = {
+       .set_ofs = 0xd0,
+       .clr_ofs = 0xd4,
+       .sta_ofs = 0xd8,
+};
+
+#define GATE_IFR2(_id, _name, _parent, _shift) {       \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &ifr2_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+#define GATE_IFR3(_id, _name, _parent, _shift) {       \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &ifr3_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+#define GATE_IFR4(_id, _name, _parent, _shift) {       \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &ifr4_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+#define GATE_IFR5(_id, _name, _parent, _shift) {       \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &ifr5_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+#define GATE_IFR6(_id, _name, _parent, _shift) {       \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &ifr6_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+static const struct mtk_gate ifr_clks[] = {
+       /* IFR2 */
+       GATE_IFR2(CLK_IFR_PMIC_TMR, "ifr_pmic_tmr", "clk26m", 0),
+       GATE_IFR2(CLK_IFR_PMIC_AP, "ifr_pmic_ap", "clk26m", 1),
+       GATE_IFR2(CLK_IFR_PMIC_MD, "ifr_pmic_md", "clk26m", 2),
+       GATE_IFR2(CLK_IFR_PMIC_CONN, "ifr_pmic_conn", "clk26m", 3),
+       GATE_IFR2(CLK_IFR_ICUSB, "ifr_icusb", "axi_sel", 8),
+       GATE_IFR2(CLK_IFR_GCE, "ifr_gce", "axi_sel", 9),
+       GATE_IFR2(CLK_IFR_THERM, "ifr_therm", "axi_sel", 10),
+       GATE_IFR2(CLK_IFR_PWM_HCLK, "ifr_pwm_hclk", "axi_sel", 15),
+       GATE_IFR2(CLK_IFR_PWM1, "ifr_pwm1", "pwm_sel", 16),
+       GATE_IFR2(CLK_IFR_PWM2, "ifr_pwm2", "pwm_sel", 17),
+       GATE_IFR2(CLK_IFR_PWM3, "ifr_pwm3", "pwm_sel", 18),
+       GATE_IFR2(CLK_IFR_PWM4, "ifr_pwm4", "pwm_sel", 19),
+       GATE_IFR2(CLK_IFR_PWM5, "ifr_pwm5", "pwm_sel", 20),
+       GATE_IFR2(CLK_IFR_PWM, "ifr_pwm", "pwm_sel", 21),
+       GATE_IFR2(CLK_IFR_UART0, "ifr_uart0", "uart_sel", 22),
+       GATE_IFR2(CLK_IFR_UART1, "ifr_uart1", "uart_sel", 23),
+       GATE_IFR2(CLK_IFR_UART2, "ifr_uart2", "uart_sel", 24),
+       GATE_IFR2(CLK_IFR_DSP_UART, "ifr_dsp_uart", "uart_sel", 26),
+       GATE_IFR2(CLK_IFR_GCE_26M, "ifr_gce_26m", "clk26m", 27),
+       GATE_IFR2(CLK_IFR_CQ_DMA_FPC, "ifr_cq_dma_fpc", "axi_sel", 28),
+       GATE_IFR2(CLK_IFR_BTIF, "ifr_btif", "axi_sel", 31),
+       /* IFR3 */
+       GATE_IFR3(CLK_IFR_SPI0, "ifr_spi0", "spi_sel", 1),
+       GATE_IFR3(CLK_IFR_MSDC0_HCLK, "ifr_msdc0", "msdc50_0_hc_sel", 2),
+       GATE_IFR3(CLK_IFR_MSDC2_HCLK, "ifr_msdc2", "msdc2_2_hc_sel", 3),
+       GATE_IFR3(CLK_IFR_MSDC1_HCLK, "ifr_msdc1", "axi_sel", 4),
+       GATE_IFR3(CLK_IFR_DVFSRC, "ifr_dvfsrc", "clk26m", 7),
+       GATE_IFR3(CLK_IFR_GCPU, "ifr_gcpu", "axi_sel", 8),
+       GATE_IFR3(CLK_IFR_TRNG, "ifr_trng", "axi_sel", 9),
+       GATE_IFR3(CLK_IFR_AUXADC, "ifr_auxadc", "clk26m", 10),
+       GATE_IFR3(CLK_IFR_AUXADC_MD, "ifr_auxadc_md", "clk26m", 14),
+       GATE_IFR3(CLK_IFR_AP_DMA, "ifr_ap_dma", "axi_sel", 18),
+       GATE_IFR3(CLK_IFR_DEBUGSYS, "ifr_debugsys", "axi_sel", 24),
+       GATE_IFR3(CLK_IFR_AUDIO, "ifr_audio", "axi_sel", 25),
+       /* IFR4 */
+       GATE_IFR4(CLK_IFR_PWM_FBCLK6, "ifr_pwm_fbclk6", "pwm_sel", 0),
+       GATE_IFR4(CLK_IFR_DISP_PWM, "ifr_disp_pwm", "disp_pwm_sel", 2),
+       GATE_IFR4(CLK_IFR_AUD_26M_BK, "ifr_aud_26m_bk", "clk26m", 4),
+       GATE_IFR4(CLK_IFR_CQ_DMA, "ifr_cq_dma", "axi_sel", 27),
+       /* IFR5 */
+       GATE_IFR5(CLK_IFR_MSDC0_SF, "ifr_msdc0_sf", "msdc50_0_sel", 0),
+       GATE_IFR5(CLK_IFR_MSDC1_SF, "ifr_msdc1_sf", "msdc50_0_sel", 1),
+       GATE_IFR5(CLK_IFR_MSDC2_SF, "ifr_msdc2_sf", "msdc50_0_sel", 2),
+       GATE_IFR5(CLK_IFR_AP_MSDC0, "ifr_ap_msdc0", "msdc50_0_sel", 7),
+       GATE_IFR5(CLK_IFR_MD_MSDC0, "ifr_md_msdc0", "msdc50_0_sel", 8),
+       GATE_IFR5(CLK_IFR_MSDC0_SRC, "ifr_msdc0_src", "msdc50_0_sel", 9),
+       GATE_IFR5(CLK_IFR_MSDC1_SRC, "ifr_msdc1_src", "msdc30_1_sel", 10),
+       GATE_IFR5(CLK_IFR_MSDC2_SRC, "ifr_msdc2_src", "msdc50_2_sel", 11),
+       GATE_IFR5(CLK_IFR_PWRAP_TMR, "ifr_pwrap_tmr", "clk26m", 12),
+       GATE_IFR5(CLK_IFR_PWRAP_SPI, "ifr_pwrap_spi", "clk26m", 13),
+       GATE_IFR5(CLK_IFR_PWRAP_SYS, "ifr_pwrap_sys", "clk26m", 14),
+       GATE_IFR5(CLK_IFR_IRRX_26M, "ifr_irrx_26m", "clk26m", 22),
+       GATE_IFR5(CLK_IFR_IRRX_32K, "ifr_irrx_32k", "clk32k", 23),
+       GATE_IFR5(CLK_IFR_I2C0_AXI, "ifr_i2c0_axi", "i2c_sel", 24),
+       GATE_IFR5(CLK_IFR_I2C1_AXI, "ifr_i2c1_axi", "i2c_sel", 25),
+       GATE_IFR5(CLK_IFR_I2C2_AXI, "ifr_i2c2_axi", "i2c_sel", 26),
+       GATE_IFR5(CLK_IFR_I2C3_AXI, "ifr_i2c3_axi", "i2c_sel", 27),
+       GATE_IFR5(CLK_IFR_NIC_AXI, "ifr_nic_axi", "axi_sel", 28),
+       GATE_IFR5(CLK_IFR_NIC_SLV_AXI, "ifr_nic_slv_axi", "axi_sel", 29),
+       GATE_IFR5(CLK_IFR_APU_AXI, "ifr_apu_axi", "axi_sel", 30),
+       /* IFR6 */
+       GATE_IFR6(CLK_IFR_NFIECC, "ifr_nfiecc", "nfiecc_sel", 0),
+       GATE_IFR6(CLK_IFR_NFI1X_BK, "ifr_nfi1x_bk", "nfi2x_sel", 1),
+       GATE_IFR6(CLK_IFR_NFIECC_BK, "ifr_nfiecc_bk", "nfi2x_sel", 2),
+       GATE_IFR6(CLK_IFR_NFI_BK, "ifr_nfi_bk", "axi_sel", 3),
+       GATE_IFR6(CLK_IFR_MSDC2_AP_BK, "ifr_msdc2_ap_bk", "axi_sel", 4),
+       GATE_IFR6(CLK_IFR_MSDC2_MD_BK, "ifr_msdc2_md_bk", "axi_sel", 5),
+       GATE_IFR6(CLK_IFR_MSDC2_BK, "ifr_msdc2_bk", "axi_sel", 6),
+       GATE_IFR6(CLK_IFR_SUSB_133_BK, "ifr_susb_133_bk", "axi_sel", 7),
+       GATE_IFR6(CLK_IFR_SUSB_66_BK, "ifr_susb_66_bk", "axi_sel", 8),
+       GATE_IFR6(CLK_IFR_SSUSB_SYS, "ifr_ssusb_sys", "ssusb_sys_sel", 9),
+       GATE_IFR6(CLK_IFR_SSUSB_REF, "ifr_ssusb_ref", "ssusb_sys_sel", 10),
+       GATE_IFR6(CLK_IFR_SSUSB_XHCI, "ifr_ssusb_xhci", "ssusb_xhci_sel", 11),
+};
+
+static const struct mtk_simple_gate peri_clks[] = {
+       { CLK_PERIAXI, "periaxi", "axi_sel", 0x20c, 31, 0 },
+};
+
+#define MT8365_PLL_FMAX                (3800UL * MHZ)
+#define MT8365_PLL_FMIN                (1500UL * MHZ)
+#define CON0_MT8365_RST_BAR    BIT(23)
+
+#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,  \
+               _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg,          \
+               _tuner_en_bit,  _pcw_reg, _pcw_shift, _div_table,       \
+               _rst_bar_mask, _pcw_chg_reg) {                          \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .reg = _reg,                                            \
+               .pwr_reg = _pwr_reg,                                    \
+               .en_mask = _en_mask,                                    \
+               .flags = _flags,                                        \
+               .rst_bar_mask = _rst_bar_mask,                          \
+               .fmax = MT8365_PLL_FMAX,                                \
+               .fmin = MT8365_PLL_FMIN,                                \
+               .pcwbits = _pcwbits,                                    \
+               .pcwibits = 8,                                          \
+               .pd_reg = _pd_reg,                                      \
+               .pd_shift = _pd_shift,                                  \
+               .tuner_reg = _tuner_reg,                                \
+               .tuner_en_reg = _tuner_en_reg,                          \
+               .tuner_en_bit = _tuner_en_bit,                          \
+               .pcw_reg = _pcw_reg,                                    \
+               .pcw_shift = _pcw_shift,                                \
+               .pcw_chg_reg = _pcw_chg_reg,                            \
+               .div_table = _div_table,                                \
+       }
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,    \
+                       _pd_reg, _pd_shift, _tuner_reg,                 \
+                       _tuner_en_reg, _tuner_en_bit, _pcw_reg,         \
+                       _pcw_shift, _rst_bar_mask, _pcw_chg_reg)        \
+               PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags,     \
+                       _pcwbits, _pd_reg, _pd_shift,                   \
+                       _tuner_reg, _tuner_en_reg, _tuner_en_bit,       \
+                       _pcw_reg, _pcw_shift, NULL, _rst_bar_mask,      \
+                       _pcw_chg_reg)                                   \
+
+static const struct mtk_pll_div_table armpll_div_table[] = {
+       { .div = 0, .freq = MT8365_PLL_FMAX },
+       { .div = 1, .freq = 1500 * MHZ },
+       { .div = 2, .freq = 750 * MHZ },
+       { .div = 3, .freq = 375 * MHZ },
+       { .div = 4, .freq = 182500000 },
+       { } /* sentinel */
+};
+
+static const struct mtk_pll_div_table mfgpll_div_table[] = {
+       { .div = 0, .freq = MT8365_PLL_FMAX },
+       { .div = 1, .freq = 1600 * MHZ },
+       { .div = 2, .freq = 800 * MHZ },
+       { .div = 3, .freq = 400 * MHZ },
+       { .div = 4, .freq = 200 * MHZ },
+       { } /* sentinel */
+};
+
+static const struct mtk_pll_div_table dsppll_div_table[] = {
+       { .div = 0, .freq = MT8365_PLL_FMAX },
+       { .div = 1, .freq = 1600 * MHZ },
+       { .div = 2, .freq = 600 * MHZ },
+       { .div = 3, .freq = 400 * MHZ },
+       { .div = 4, .freq = 200 * MHZ },
+       { } /* sentinel */
+};
+
+static const struct mtk_pll_data plls[] = {
+       PLL_B(CLK_APMIXED_ARMPLL, "armpll", 0x030C, 0x0318, 0x00000001, PLL_AO,
+             22, 0x0310, 24, 0, 0, 0, 0x0310, 0, armpll_div_table, 0, 0),
+       PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0228, 0x0234, 0xFF000001,
+           HAVE_RST_BAR, 22, 0x022C, 24, 0, 0, 0, 0x022C, 0,
+           CON0_MT8365_RST_BAR, 0),
+       PLL(CLK_APMIXED_UNIVPLL, "univpll2", 0x0208, 0x0214, 0xFF000001,
+           HAVE_RST_BAR, 22, 0x020C, 24, 0, 0, 0, 0x020C, 0,
+           CON0_MT8365_RST_BAR, 0),
+       PLL_B(CLK_APMIXED_MFGPLL, "mfgpll", 0x0218, 0x0224, 0x00000001, 0, 22,
+             0x021C, 24, 0, 0, 0, 0x021C, 0, mfgpll_div_table, 0, 0),
+       PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0350, 0x035C, 0x00000001, 0, 22,
+           0x0354, 24, 0, 0, 0, 0x0354, 0, 0, 0),
+       PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0330, 0x033C, 0x00000001, 0, 22,
+           0x0334, 24, 0, 0, 0, 0x0334, 0, 0, 0),
+       PLL(CLK_APMIXED_APLL1, "apll1", 0x031C, 0x032C, 0x00000001, 0, 32,
+           0x0320, 24, 0x0040, 0x000C, 0, 0x0324, 0, 0, 0x0320),
+       PLL(CLK_APMIXED_APLL2, "apll2", 0x0360, 0x0370, 0x00000001, 0, 32,
+           0x0364, 24, 0x004C, 0x000C, 5, 0x0368, 0, 0, 0x0364),
+       PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x0374, 0x0380, 0x00000001, 0, 22,
+           0x0378, 24, 0, 0, 0, 0x0378, 0, 0, 0),
+       PLL_B(CLK_APMIXED_DSPPLL, "dsppll", 0x0390, 0x039C, 0x00000001, 0, 22,
+             0x0394, 24, 0, 0, 0, 0x0394, 0, dsppll_div_table, 0, 0),
+       PLL(CLK_APMIXED_APUPLL, "apupll", 0x03A0, 0x03AC, 0x00000001, 0, 22,
+           0x03A4, 24, 0, 0, 0, 0x03A4, 0, 0, 0),
+};
+
+static int clk_mt8365_apmixed_probe(struct platform_device *pdev)
+{
+       void __iomem *base;
+       struct clk_hw_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       struct device *dev = &pdev->dev;
+       struct clk_hw *hw;
+       int ret;
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       clk_data = mtk_devm_alloc_clk_data(dev, CLK_APMIXED_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       hw = devm_clk_hw_register_gate(dev, "univ_en", "univpll2", 0,
+                                      base + 0x204, 0, 0, NULL);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       clk_data->hws[CLK_APMIXED_UNIV_EN] = hw;
+
+       hw = devm_clk_hw_register_gate(dev, "usb20_en", "univ_en", 0,
+                                      base + 0x204, 1, 0, NULL);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       clk_data->hws[CLK_APMIXED_USB20_EN] = hw;
+
+       ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+       if (ret)
+               return ret;
+
+       ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (ret)
+               goto unregister_plls;
+
+       return 0;
+
+unregister_plls:
+       mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
+
+       return ret;
+}
+
+static int
+clk_mt8365_register_mtk_simple_gates(struct device *dev, void __iomem *base,
+                                    struct clk_hw_onecell_data *clk_data,
+                                    const struct mtk_simple_gate *gates,
+                                    unsigned int num_gates)
+{
+       unsigned int i;
+
+       for (i = 0; i != num_gates; ++i) {
+               const struct mtk_simple_gate *gate = &gates[i];
+               struct clk_hw *hw;
+
+               hw = devm_clk_hw_register_gate(dev, gate->name, gate->parent, 0,
+                                              base + gate->reg, gate->shift,
+                                              gate->gate_flags, NULL);
+               if (IS_ERR(hw))
+                       return PTR_ERR(hw);
+
+               clk_data->hws[gate->id] = hw;
+       }
+
+       return 0;
+}
+
+static int clk_mt8365_top_probe(struct platform_device *pdev)
+{
+       void __iomem *base;
+       struct clk_hw_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       struct device *dev = &pdev->dev;
+       int ret;
+       int i;
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       ret = mtk_clk_register_fixed_clks(top_fixed_clks,
+                                         ARRAY_SIZE(top_fixed_clks), clk_data);
+       if (ret)
+               goto free_clk_data;
+
+       ret = mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs),
+                                      clk_data);
+       if (ret)
+               goto unregister_fixed_clks;
+
+       ret = mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), node,
+                                    &mt8365_clk_lock, clk_data);
+       if (ret)
+               goto unregister_factors;
+
+       ret = mtk_clk_register_composites(top_misc_mux_gates,
+                                         ARRAY_SIZE(top_misc_mux_gates), base,
+                                         &mt8365_clk_lock, clk_data);
+       if (ret)
+               goto unregister_muxes;
+
+       for (i = 0; i != ARRAY_SIZE(top_misc_muxes); ++i) {
+               struct mt8365_clk_audio_mux *mux = &top_misc_muxes[i];
+               struct clk_hw *hw;
+
+               hw = devm_clk_hw_register_mux(dev, mux->name, apll_i2s0_parents,
+                                             ARRAY_SIZE(apll_i2s0_parents),
+                                             CLK_SET_RATE_PARENT, base + 0x320,
+                                             mux->shift, 1, 0, NULL);
+               if (IS_ERR(hw)) {
+                       ret = PTR_ERR(hw);
+                       goto unregister_composites;
+               }
+
+               clk_data->hws[mux->id] = hw;
+       }
+
+       ret = mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
+                                       base, &mt8365_clk_lock, clk_data);
+       if (ret)
+               goto unregister_composites;
+
+       ret = clk_mt8365_register_mtk_simple_gates(dev, base, clk_data,
+                                                  top_clk_gates,
+                                                  ARRAY_SIZE(top_clk_gates));
+       if (ret)
+               goto unregister_dividers;
+
+       ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (ret)
+               goto unregister_dividers;
+
+       return 0;
+unregister_dividers:
+       mtk_clk_unregister_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
+                                   clk_data);
+unregister_composites:
+       mtk_clk_unregister_composites(top_misc_mux_gates,
+                                     ARRAY_SIZE(top_misc_mux_gates), clk_data);
+unregister_muxes:
+       mtk_clk_unregister_muxes(top_muxes, ARRAY_SIZE(top_muxes), clk_data);
+unregister_factors:
+       mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+unregister_fixed_clks:
+       mtk_clk_unregister_fixed_clks(top_fixed_clks,
+                                     ARRAY_SIZE(top_fixed_clks), clk_data);
+free_clk_data:
+       mtk_free_clk_data(clk_data);
+
+       return ret;
+}
+
+static int clk_mt8365_infra_probe(struct platform_device *pdev)
+{
+       struct clk_hw_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int ret;
+
+       clk_data = mtk_alloc_clk_data(CLK_IFR_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       ret = mtk_clk_register_gates(node, ifr_clks, ARRAY_SIZE(ifr_clks),
+                                    clk_data);
+       if (ret)
+               goto free_clk_data;
+
+       ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (ret)
+               goto unregister_gates;
+
+       return 0;
+
+unregister_gates:
+       mtk_clk_unregister_gates(ifr_clks, ARRAY_SIZE(ifr_clks), clk_data);
+free_clk_data:
+       mtk_free_clk_data(clk_data);
+
+       return ret;
+}
+
+static int clk_mt8365_peri_probe(struct platform_device *pdev)
+{
+       void __iomem *base;
+       struct clk_hw_onecell_data *clk_data;
+       struct device *dev = &pdev->dev;
+       struct device_node *node = dev->of_node;
+       int ret;
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       clk_data = mtk_devm_alloc_clk_data(dev, CLK_PERI_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       ret = clk_mt8365_register_mtk_simple_gates(dev, base, clk_data,
+                                                  peri_clks,
+                                                  ARRAY_SIZE(peri_clks));
+       if (ret)
+               return ret;
+
+       ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+
+       return ret;
+}
+
+static int clk_mt8365_mcu_probe(struct platform_device *pdev)
+{
+       struct clk_hw_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       void __iomem *base;
+       int ret;
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       clk_data = mtk_alloc_clk_data(CLK_MCU_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       ret = mtk_clk_register_composites(mcu_muxes, ARRAY_SIZE(mcu_muxes),
+                                         base, &mt8365_clk_lock, clk_data);
+       if (ret)
+               goto free_clk_data;
+
+       ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (ret)
+               goto unregister_composites;
+
+       return 0;
+
+unregister_composites:
+       mtk_clk_unregister_composites(mcu_muxes, ARRAY_SIZE(mcu_muxes),
+                                     clk_data);
+free_clk_data:
+       mtk_free_clk_data(clk_data);
+
+       return ret;
+}
+
+static const struct of_device_id of_match_clk_mt8365[] = {
+       {
+               .compatible = "mediatek,mt8365-apmixedsys",
+               .data = clk_mt8365_apmixed_probe,
+       }, {
+               .compatible = "mediatek,mt8365-topckgen",
+               .data = clk_mt8365_top_probe,
+       }, {
+               .compatible = "mediatek,mt8365-infracfg",
+               .data = clk_mt8365_infra_probe,
+       }, {
+               .compatible = "mediatek,mt8365-pericfg",
+               .data = clk_mt8365_peri_probe,
+       }, {
+               .compatible = "mediatek,mt8365-mcucfg",
+               .data = clk_mt8365_mcu_probe,
+       }, {
+               /* sentinel */
+       }
+};
+
+static int clk_mt8365_probe(struct platform_device *pdev)
+{
+       int (*clk_probe)(struct platform_device *pdev);
+       int ret;
+
+       clk_probe = of_device_get_match_data(&pdev->dev);
+       if (!clk_probe)
+               return -EINVAL;
+
+       ret = clk_probe(pdev);
+       if (ret)
+               dev_err(&pdev->dev,
+                       "%s: could not register clock provider: %d\n",
+                       pdev->name, ret);
+
+       return ret;
+}
+
+static struct platform_driver clk_mt8365_drv = {
+       .probe = clk_mt8365_probe,
+       .driver = {
+               .name = "clk-mt8365",
+               .of_match_table = of_match_clk_mt8365,
+       },
+};
+
+static int __init clk_mt8365_init(void)
+{
+       return platform_driver_register(&clk_mt8365_drv);
+}
+arch_initcall(clk_mt8365_init);
+MODULE_LICENSE("GPL");
index 05a188c..d31f01d 100644 (file)
 #include "clk-mtk.h"
 #include "clk-gate.h"
 
-struct clk_hw_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
+static void mtk_init_clk_data(struct clk_hw_onecell_data *clk_data,
+                             unsigned int clk_num)
 {
        int i;
+
+       clk_data->num = clk_num;
+
+       for (i = 0; i < clk_num; i++)
+               clk_data->hws[i] = ERR_PTR(-ENOENT);
+}
+
+struct clk_hw_onecell_data *mtk_devm_alloc_clk_data(struct device *dev,
+                                                   unsigned int clk_num)
+{
        struct clk_hw_onecell_data *clk_data;
 
-       clk_data = kzalloc(struct_size(clk_data, hws, clk_num), GFP_KERNEL);
+       clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, clk_num),
+                               GFP_KERNEL);
        if (!clk_data)
                return NULL;
 
-       clk_data->num = clk_num;
+       mtk_init_clk_data(clk_data, clk_num);
 
-       for (i = 0; i < clk_num; i++)
-               clk_data->hws[i] = ERR_PTR(-ENOENT);
+       return clk_data;
+}
+EXPORT_SYMBOL_GPL(mtk_devm_alloc_clk_data);
+
+struct clk_hw_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
+{
+       struct clk_hw_onecell_data *clk_data;
+
+       clk_data = kzalloc(struct_size(clk_data, hws, clk_num), GFP_KERNEL);
+       if (!clk_data)
+               return NULL;
+
+       mtk_init_clk_data(clk_data, clk_num);
 
        return clk_data;
 }
@@ -80,7 +103,7 @@ err:
                if (IS_ERR_OR_NULL(clk_data->hws[rc->id]))
                        continue;
 
-               clk_unregister_fixed_rate(clk_data->hws[rc->id]->clk);
+               clk_hw_unregister_fixed_rate(clk_data->hws[rc->id]);
                clk_data->hws[rc->id] = ERR_PTR(-ENOENT);
        }
 
@@ -102,7 +125,7 @@ void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,
                if (IS_ERR_OR_NULL(clk_data->hws[rc->id]))
                        continue;
 
-               clk_unregister_fixed_rate(clk_data->hws[rc->id]->clk);
+               clk_hw_unregister_fixed_rate(clk_data->hws[rc->id]);
                clk_data->hws[rc->id] = ERR_PTR(-ENOENT);
        }
 }
@@ -146,7 +169,7 @@ err:
                if (IS_ERR_OR_NULL(clk_data->hws[ff->id]))
                        continue;
 
-               clk_unregister_fixed_factor(clk_data->hws[ff->id]->clk);
+               clk_hw_unregister_fixed_factor(clk_data->hws[ff->id]);
                clk_data->hws[ff->id] = ERR_PTR(-ENOENT);
        }
 
@@ -168,7 +191,7 @@ void mtk_clk_unregister_factors(const struct mtk_fixed_factor *clks, int num,
                if (IS_ERR_OR_NULL(clk_data->hws[ff->id]))
                        continue;
 
-               clk_unregister_fixed_factor(clk_data->hws[ff->id]->clk);
+               clk_hw_unregister_fixed_factor(clk_data->hws[ff->id]);
                clk_data->hws[ff->id] = ERR_PTR(-ENOENT);
        }
 }
@@ -393,12 +416,13 @@ err:
                if (IS_ERR_OR_NULL(clk_data->hws[mcd->id]))
                        continue;
 
-               mtk_clk_unregister_composite(clk_data->hws[mcd->id]);
+               clk_hw_unregister_divider(clk_data->hws[mcd->id]);
                clk_data->hws[mcd->id] = ERR_PTR(-ENOENT);
        }
 
        return PTR_ERR(hw);
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_dividers);
 
 void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,
                                 struct clk_hw_onecell_data *clk_data)
@@ -414,10 +438,11 @@ void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,
                if (IS_ERR_OR_NULL(clk_data->hws[mcd->id]))
                        continue;
 
-               clk_unregister_divider(clk_data->hws[mcd->id]->clk);
+               clk_hw_unregister_divider(clk_data->hws[mcd->id]);
                clk_data->hws[mcd->id] = ERR_PTR(-ENOENT);
        }
 }
+EXPORT_SYMBOL_GPL(mtk_clk_unregister_dividers);
 
 int mtk_clk_simple_probe(struct platform_device *pdev)
 {
@@ -434,7 +459,8 @@ int mtk_clk_simple_probe(struct platform_device *pdev)
        if (!clk_data)
                return -ENOMEM;
 
-       r = mtk_clk_register_gates(node, mcd->clks, mcd->num_clks, clk_data);
+       r = mtk_clk_register_gates_with_dev(node, mcd->clks, mcd->num_clks,
+                                           clk_data, &pdev->dev);
        if (r)
                goto free_data;
 
@@ -459,6 +485,7 @@ free_data:
        mtk_free_clk_data(clk_data);
        return r;
 }
+EXPORT_SYMBOL_GPL(mtk_clk_simple_probe);
 
 int mtk_clk_simple_remove(struct platform_device *pdev)
 {
@@ -472,5 +499,6 @@ int mtk_clk_simple_remove(struct platform_device *pdev)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_clk_simple_remove);
 
 MODULE_LICENSE("GPL");
index 1b95c48..63ae794 100644 (file)
@@ -184,10 +184,13 @@ void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,
                                 struct clk_hw_onecell_data *clk_data);
 
 struct clk_hw_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
+struct clk_hw_onecell_data *mtk_devm_alloc_clk_data(struct device *dev,
+                                                   unsigned int clk_num);
 void mtk_free_clk_data(struct clk_hw_onecell_data *clk_data);
 
 struct clk_hw *mtk_clk_register_ref2usb_tx(const char *name,
                        const char *parent_name, void __iomem *reg);
+void mtk_clk_unregister_ref2usb_tx(struct clk_hw *hw);
 
 struct mtk_clk_desc {
        const struct mtk_gate *clks;
index cd5f9fd..4421e48 100644 (file)
@@ -4,6 +4,7 @@
  * Author: Owen Chen <owen.chen@mediatek.com>
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/compiler_types.h>
 #include <linux/container_of.h>
@@ -259,4 +260,41 @@ void mtk_clk_unregister_muxes(const struct mtk_mux *muxes, int num,
 }
 EXPORT_SYMBOL_GPL(mtk_clk_unregister_muxes);
 
+/*
+ * This clock notifier is called when the frequency of the parent
+ * PLL clock is to be changed. The idea is to switch the parent to a
+ * stable clock, such as the main oscillator, while the PLL frequency
+ * stabilizes.
+ */
+static int mtk_clk_mux_notifier_cb(struct notifier_block *nb,
+                                  unsigned long event, void *_data)
+{
+       struct clk_notifier_data *data = _data;
+       struct clk_hw *hw = __clk_get_hw(data->clk);
+       struct mtk_mux_nb *mux_nb = to_mtk_mux_nb(nb);
+       int ret = 0;
+
+       switch (event) {
+       case PRE_RATE_CHANGE:
+               mux_nb->original_index = mux_nb->ops->get_parent(hw);
+               ret = mux_nb->ops->set_parent(hw, mux_nb->bypass_index);
+               break;
+       case POST_RATE_CHANGE:
+       case ABORT_RATE_CHANGE:
+               ret = mux_nb->ops->set_parent(hw, mux_nb->original_index);
+               break;
+       }
+
+       return notifier_from_errno(ret);
+}
+
+int devm_mtk_clk_mux_notifier_register(struct device *dev, struct clk *clk,
+                                      struct mtk_mux_nb *mux_nb)
+{
+       mux_nb->nb.notifier_call = mtk_clk_mux_notifier_cb;
+
+       return devm_clk_notifier_register(dev, clk, &mux_nb->nb);
+}
+EXPORT_SYMBOL_GPL(devm_mtk_clk_mux_notifier_register);
+
 MODULE_LICENSE("GPL");
index 6539c58..83ff420 100644 (file)
@@ -7,12 +7,14 @@
 #ifndef __DRV_CLK_MTK_MUX_H
 #define __DRV_CLK_MTK_MUX_H
 
+#include <linux/notifier.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 
 struct clk;
 struct clk_hw_onecell_data;
 struct clk_ops;
+struct device;
 struct device_node;
 
 struct mtk_mux {
@@ -89,4 +91,17 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
 void mtk_clk_unregister_muxes(const struct mtk_mux *muxes, int num,
                              struct clk_hw_onecell_data *clk_data);
 
+struct mtk_mux_nb {
+       struct notifier_block   nb;
+       const struct clk_ops    *ops;
+
+       u8      bypass_index;   /* Which parent to temporarily use */
+       u8      original_index; /* Set by notifier callback */
+};
+
+#define to_mtk_mux_nb(_nb)     container_of(_nb, struct mtk_mux_nb, nb)
+
+int devm_mtk_clk_mux_notifier_register(struct device *dev, struct clk *clk,
+                                      struct mtk_mux_nb *mux_nb);
+
 #endif /* __DRV_CLK_MTK_MUX_H */
index 1795055..290ceda 100644 (file)
@@ -228,5 +228,6 @@ int mtk_register_reset_controller_with_dev(struct device *dev,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_register_reset_controller_with_dev);
 
 MODULE_LICENSE("GPL");
index 27cd2c1..434cd8f 100644 (file)
@@ -38,6 +38,7 @@ int meson_aoclkc_probe(struct platform_device *pdev)
        struct meson_aoclk_reset_controller *rstc;
        struct meson_aoclk_data *data;
        struct device *dev = &pdev->dev;
+       struct device_node *np;
        struct regmap *regmap;
        int ret, clkid;
 
@@ -49,7 +50,9 @@ int meson_aoclkc_probe(struct platform_device *pdev)
        if (!rstc)
                return -ENOMEM;
 
-       regmap = syscon_node_to_regmap(of_get_parent(dev->of_node));
+       np = of_get_parent(dev->of_node);
+       regmap = syscon_node_to_regmap(np);
+       of_node_put(np);
        if (IS_ERR(regmap)) {
                dev_err(dev, "failed to get regmap\n");
                return PTR_ERR(regmap);
index 8d5a5da..0e5e6b5 100644 (file)
@@ -18,6 +18,7 @@ int meson_eeclkc_probe(struct platform_device *pdev)
 {
        const struct meson_eeclkc_data *data;
        struct device *dev = &pdev->dev;
+       struct device_node *np;
        struct regmap *map;
        int ret, i;
 
@@ -26,7 +27,9 @@ int meson_eeclkc_probe(struct platform_device *pdev)
                return -EINVAL;
 
        /* Get the hhi system controller node */
-       map = syscon_node_to_regmap(of_get_parent(dev->of_node));
+       np = of_get_parent(dev->of_node);
+       map = syscon_node_to_regmap(np);
+       of_node_put(np);
        if (IS_ERR(map)) {
                dev_err(dev,
                        "failed to get HHI regmap\n");
index 8f3b7a9..827e78f 100644 (file)
@@ -3792,12 +3792,15 @@ static void __init meson8b_clkc_init_common(struct device_node *np,
                        struct clk_hw_onecell_data *clk_hw_onecell_data)
 {
        struct meson8b_clk_reset *rstc;
+       struct device_node *parent_np;
        const char *notifier_clk_name;
        struct clk *notifier_clk;
        struct regmap *map;
        int i, ret;
 
-       map = syscon_node_to_regmap(of_get_parent(np));
+       parent_np = of_get_parent(np);
+       map = syscon_node_to_regmap(parent_np);
+       of_node_put(parent_np);
        if (IS_ERR(map)) {
                pr_err("failed to get HHI regmap - Trying obsolete regs\n");
                return;
index a5a9987..b46e864 100644 (file)
@@ -6,5 +6,6 @@ config COMMON_CLK_PIC32
 config MCHP_CLK_MPFS
        bool "Clk driver for PolarFire SoC"
        depends on (RISCV && SOC_MICROCHIP_POLARFIRE) || COMPILE_TEST
+       select AUXILIARY_BUS
        help
          Supports Clock Configuration for PolarFire SoC
index 5fa6dcf..13250e0 100644 (file)
@@ -2,3 +2,4 @@
 obj-$(CONFIG_COMMON_CLK_PIC32) += clk-core.o
 obj-$(CONFIG_PIC32MZDA) += clk-pic32mzda.o
 obj-$(CONFIG_MCHP_CLK_MPFS) += clk-mpfs.o
+obj-$(CONFIG_MCHP_CLK_MPFS) += clk-mpfs-ccc.o
diff --git a/drivers/clk/microchip/clk-mpfs-ccc.c b/drivers/clk/microchip/clk-mpfs-ccc.c
new file mode 100644 (file)
index 0000000..7be028d
--- /dev/null
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Author: Conor Dooley <conor.dooley@microchip.com>
+ *
+ * Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries
+ */
+#include "asm-generic/errno-base.h"
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/microchip,mpfs-clock.h>
+
+/* address offset of control registers */
+#define MPFS_CCC_PLL_CR                        0x04u
+#define MPFS_CCC_REF_CR                        0x08u
+#define MPFS_CCC_SSCG_2_CR             0x2Cu
+#define MPFS_CCC_POSTDIV01_CR          0x10u
+#define MPFS_CCC_POSTDIV23_CR          0x14u
+
+#define MPFS_CCC_FBDIV_SHIFT           0x00u
+#define MPFS_CCC_FBDIV_WIDTH           0x0Cu
+#define MPFS_CCC_POSTDIV0_SHIFT                0x08u
+#define MPFS_CCC_POSTDIV1_SHIFT                0x18u
+#define MPFS_CCC_POSTDIV2_SHIFT                MPFS_CCC_POSTDIV0_SHIFT
+#define MPFS_CCC_POSTDIV3_SHIFT                MPFS_CCC_POSTDIV1_SHIFT
+#define MPFS_CCC_POSTDIV_WIDTH         0x06u
+#define MPFS_CCC_REFCLK_SEL            BIT(6)
+#define MPFS_CCC_REFDIV_SHIFT          0x08u
+#define MPFS_CCC_REFDIV_WIDTH          0x06u
+
+#define MPFS_CCC_FIXED_DIV             4
+#define MPFS_CCC_OUTPUTS_PER_PLL       4
+#define MPFS_CCC_REFS_PER_PLL          2
+
+struct mpfs_ccc_data {
+       void __iomem **pll_base;
+       struct device *dev;
+       struct clk_hw_onecell_data hw_data;
+};
+
+struct mpfs_ccc_pll_hw_clock {
+       void __iomem *base;
+       const char *name;
+       const struct clk_parent_data *parents;
+       unsigned int id;
+       u32 reg_offset;
+       u32 shift;
+       u32 width;
+       u32 flags;
+       struct clk_hw hw;
+       struct clk_init_data init;
+};
+
+#define to_mpfs_ccc_clk(_hw) container_of(_hw, struct mpfs_ccc_pll_hw_clock, hw)
+
+/*
+ * mpfs_ccc_lock prevents anything else from writing to a fabric ccc
+ * while a software locked register is being written.
+ */
+static DEFINE_SPINLOCK(mpfs_ccc_lock);
+
+static const struct clk_parent_data mpfs_ccc_pll0_refs[] = {
+       { .fw_name = "pll0_ref0" },
+       { .fw_name = "pll0_ref1" },
+};
+
+static const struct clk_parent_data mpfs_ccc_pll1_refs[] = {
+       { .fw_name = "pll1_ref0" },
+       { .fw_name = "pll1_ref1" },
+};
+
+static unsigned long mpfs_ccc_pll_recalc_rate(struct clk_hw *hw, unsigned long prate)
+{
+       struct mpfs_ccc_pll_hw_clock *ccc_hw = to_mpfs_ccc_clk(hw);
+       void __iomem *mult_addr = ccc_hw->base + ccc_hw->reg_offset;
+       void __iomem *ref_div_addr = ccc_hw->base + MPFS_CCC_REF_CR;
+       u32 mult, ref_div;
+
+       mult = readl_relaxed(mult_addr) >> MPFS_CCC_FBDIV_SHIFT;
+       mult &= clk_div_mask(MPFS_CCC_FBDIV_WIDTH);
+       ref_div = readl_relaxed(ref_div_addr) >> MPFS_CCC_REFDIV_SHIFT;
+       ref_div &= clk_div_mask(MPFS_CCC_REFDIV_WIDTH);
+
+       return prate * mult / (ref_div * MPFS_CCC_FIXED_DIV);
+}
+
+static u8 mpfs_ccc_pll_get_parent(struct clk_hw *hw)
+{
+       struct mpfs_ccc_pll_hw_clock *ccc_hw = to_mpfs_ccc_clk(hw);
+       void __iomem *pll_cr_addr = ccc_hw->base + MPFS_CCC_PLL_CR;
+
+       return !!(readl_relaxed(pll_cr_addr) & MPFS_CCC_REFCLK_SEL);
+}
+
+static const struct clk_ops mpfs_ccc_pll_ops = {
+       .recalc_rate = mpfs_ccc_pll_recalc_rate,
+       .get_parent = mpfs_ccc_pll_get_parent,
+};
+
+#define CLK_CCC_PLL(_id, _parents, _shift, _width, _flags, _offset) {  \
+       .id = _id,                                                      \
+       .shift = _shift,                                                \
+       .width = _width,                                                \
+       .reg_offset = _offset,                                          \
+       .flags = _flags,                                                \
+       .parents = _parents,                                            \
+}
+
+static struct mpfs_ccc_pll_hw_clock mpfs_ccc_pll_clks[] = {
+       CLK_CCC_PLL(CLK_CCC_PLL0, mpfs_ccc_pll0_refs, MPFS_CCC_FBDIV_SHIFT,
+                   MPFS_CCC_FBDIV_WIDTH, 0, MPFS_CCC_SSCG_2_CR),
+       CLK_CCC_PLL(CLK_CCC_PLL1, mpfs_ccc_pll1_refs, MPFS_CCC_FBDIV_SHIFT,
+                   MPFS_CCC_FBDIV_WIDTH, 0, MPFS_CCC_SSCG_2_CR),
+};
+
+struct mpfs_ccc_out_hw_clock {
+       struct clk_divider divider;
+       struct clk_init_data init;
+       unsigned int id;
+       u32 reg_offset;
+};
+
+#define CLK_CCC_OUT(_id, _shift, _width, _flags, _offset) {    \
+       .id = _id,                                              \
+       .divider.shift = _shift,                                \
+       .divider.width = _width,                                \
+       .reg_offset = _offset,                                  \
+       .divider.flags = _flags,                                \
+       .divider.lock = &mpfs_ccc_lock,                         \
+}
+
+static struct mpfs_ccc_out_hw_clock mpfs_ccc_pll0out_clks[] = {
+       CLK_CCC_OUT(CLK_CCC_PLL0_OUT0, MPFS_CCC_POSTDIV0_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
+                   CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV01_CR),
+       CLK_CCC_OUT(CLK_CCC_PLL0_OUT1, MPFS_CCC_POSTDIV1_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
+                   CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV01_CR),
+       CLK_CCC_OUT(CLK_CCC_PLL0_OUT2, MPFS_CCC_POSTDIV2_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
+                   CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV23_CR),
+       CLK_CCC_OUT(CLK_CCC_PLL0_OUT3, MPFS_CCC_POSTDIV3_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
+                   CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV23_CR),
+};
+
+static struct mpfs_ccc_out_hw_clock mpfs_ccc_pll1out_clks[] = {
+       CLK_CCC_OUT(CLK_CCC_PLL1_OUT0, MPFS_CCC_POSTDIV0_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
+                   CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV01_CR),
+       CLK_CCC_OUT(CLK_CCC_PLL1_OUT1, MPFS_CCC_POSTDIV1_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
+                   CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV01_CR),
+       CLK_CCC_OUT(CLK_CCC_PLL1_OUT2, MPFS_CCC_POSTDIV2_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
+                   CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV23_CR),
+       CLK_CCC_OUT(CLK_CCC_PLL1_OUT3, MPFS_CCC_POSTDIV3_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
+                   CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV23_CR),
+};
+
+static struct mpfs_ccc_out_hw_clock *mpfs_ccc_pllout_clks[] = {
+       mpfs_ccc_pll0out_clks, mpfs_ccc_pll1out_clks
+};
+
+static int mpfs_ccc_register_outputs(struct device *dev, struct mpfs_ccc_out_hw_clock *out_hws,
+                                    unsigned int num_clks, struct mpfs_ccc_data *data,
+                                    struct mpfs_ccc_pll_hw_clock *parent)
+{
+       int ret;
+
+       for (unsigned int i = 0; i < num_clks; i++) {
+               struct mpfs_ccc_out_hw_clock *out_hw = &out_hws[i];
+               char *name = devm_kzalloc(dev, 23, GFP_KERNEL);
+
+               snprintf(name, 23, "%s_out%u", parent->name, i);
+               out_hw->divider.hw.init = CLK_HW_INIT_HW(name, &parent->hw, &clk_divider_ops, 0);
+               out_hw->divider.reg = data->pll_base[i / MPFS_CCC_OUTPUTS_PER_PLL] +
+                       out_hw->reg_offset;
+
+               ret = devm_clk_hw_register(dev, &out_hw->divider.hw);
+               if (ret)
+                       return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
+                                            out_hw->id);
+
+               data->hw_data.hws[out_hw->id] = &out_hw->divider.hw;
+       }
+
+       return 0;
+}
+
+#define CLK_HW_INIT_PARENTS_DATA_FIXED_SIZE(_name, _parents, _ops, _flags)     \
+       (&(struct clk_init_data) {                                              \
+               .flags          = _flags,                                       \
+               .name           = _name,                                        \
+               .parent_data    = _parents,                                     \
+               .num_parents    = MPFS_CCC_REFS_PER_PLL,                        \
+               .ops            = _ops,                                         \
+       })
+
+static int mpfs_ccc_register_plls(struct device *dev, struct mpfs_ccc_pll_hw_clock *pll_hws,
+                                 unsigned int num_clks, struct mpfs_ccc_data *data)
+{
+       int ret;
+
+       for (unsigned int i = 0; i < num_clks; i++) {
+               struct mpfs_ccc_pll_hw_clock *pll_hw = &pll_hws[i];
+               char *name = devm_kzalloc(dev, 18, GFP_KERNEL);
+
+               pll_hw->base = data->pll_base[i];
+               snprintf(name, 18, "ccc%s_pll%u", strchrnul(dev->of_node->full_name, '@'), i);
+               pll_hw->name = (const char *)name;
+               pll_hw->hw.init = CLK_HW_INIT_PARENTS_DATA_FIXED_SIZE(pll_hw->name,
+                                                                     pll_hw->parents,
+                                                                     &mpfs_ccc_pll_ops, 0);
+
+               ret = devm_clk_hw_register(dev, &pll_hw->hw);
+               if (ret)
+                       return dev_err_probe(dev, ret, "failed to register ccc id: %d\n",
+                                            pll_hw->id);
+
+               data->hw_data.hws[pll_hw->id] = &pll_hw->hw;
+
+               ret = mpfs_ccc_register_outputs(dev, mpfs_ccc_pllout_clks[i],
+                                               MPFS_CCC_OUTPUTS_PER_PLL, data, pll_hw);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int mpfs_ccc_probe(struct platform_device *pdev)
+{
+       struct mpfs_ccc_data *clk_data;
+       void __iomem *pll_base[ARRAY_SIZE(mpfs_ccc_pll_clks)];
+       unsigned int num_clks;
+       int ret;
+
+       num_clks = ARRAY_SIZE(mpfs_ccc_pll_clks) + ARRAY_SIZE(mpfs_ccc_pll0out_clks) +
+                  ARRAY_SIZE(mpfs_ccc_pll1out_clks);
+
+       clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hw_data.hws, num_clks),
+                               GFP_KERNEL);
+       if (!clk_data)
+               return -ENOMEM;
+
+       pll_base[0] = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(pll_base[0]))
+               return PTR_ERR(pll_base[0]);
+
+       pll_base[1] = devm_platform_ioremap_resource(pdev, 1);
+       if (IS_ERR(pll_base[1]))
+               return PTR_ERR(pll_base[1]);
+
+       clk_data->pll_base = pll_base;
+       clk_data->hw_data.num = num_clks;
+       clk_data->dev = &pdev->dev;
+
+       ret = mpfs_ccc_register_plls(clk_data->dev, mpfs_ccc_pll_clks,
+                                    ARRAY_SIZE(mpfs_ccc_pll_clks), clk_data);
+       if (ret)
+               return ret;
+
+       return devm_of_clk_add_hw_provider(clk_data->dev, of_clk_hw_onecell_get,
+                                          &clk_data->hw_data);
+}
+
+static const struct of_device_id mpfs_ccc_of_match_table[] = {
+       { .compatible = "microchip,mpfs-ccc", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, mpfs_ccc_of_match_table);
+
+static struct platform_driver mpfs_ccc_driver = {
+       .probe = mpfs_ccc_probe,
+       .driver = {
+               .name = "microchip-mpfs-ccc",
+               .of_match_table = mpfs_ccc_of_match_table,
+       },
+};
+
+static int __init clk_ccc_init(void)
+{
+       return platform_driver_register(&mpfs_ccc_driver);
+}
+core_initcall(clk_ccc_init);
+
+static void __exit clk_ccc_exit(void)
+{
+       platform_driver_unregister(&mpfs_ccc_driver);
+}
+module_exit(clk_ccc_exit);
+
+MODULE_DESCRIPTION("Microchip PolarFire SoC Clock Conditioning Circuitry Driver");
+MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
+MODULE_LICENSE("GPL");
index 070c3b8..4f0a19d 100644 (file)
@@ -1,14 +1,17 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Daire McNamara,<daire.mcnamara@microchip.com>
- * Copyright (C) 2020 Microchip Technology Inc.  All rights reserved.
+ * PolarFire SoC MSS/core complex clock control
+ *
+ * Copyright (C) 2020-2022 Microchip Technology Inc. All rights reserved.
  */
+#include <linux/auxiliary_bus.h>
 #include <linux/clk-provider.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <dt-bindings/clock/microchip,mpfs-clock.h>
+#include <soc/microchip/mpfs.h>
 
 /* address offset of control registers */
 #define REG_MSSPLL_REF_CR      0x08u
@@ -28,6 +31,7 @@
 #define MSSPLL_FIXED_DIV       4u
 
 struct mpfs_clock_data {
+       struct device *dev;
        void __iomem *base;
        void __iomem *msspll_base;
        struct clk_hw_onecell_data hw_data;
@@ -46,37 +50,18 @@ struct mpfs_msspll_hw_clock {
 
 #define to_mpfs_msspll_clk(_hw) container_of(_hw, struct mpfs_msspll_hw_clock, hw)
 
-struct mpfs_cfg_clock {
-       const struct clk_div_table *table;
-       unsigned int id;
-       u32 reg_offset;
-       u8 shift;
-       u8 width;
-       u8 flags;
-};
-
 struct mpfs_cfg_hw_clock {
-       struct mpfs_cfg_clock cfg;
-       void __iomem *sys_base;
-       struct clk_hw hw;
+       struct clk_divider cfg;
        struct clk_init_data init;
-};
-
-#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw)
-
-struct mpfs_periph_clock {
        unsigned int id;
-       u8 shift;
+       u32 reg_offset;
 };
 
 struct mpfs_periph_hw_clock {
-       struct mpfs_periph_clock periph;
-       void __iomem *sys_base;
-       struct clk_hw hw;
+       struct clk_gate periph;
+       unsigned int id;
 };
 
-#define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw)
-
 /*
  * mpfs_clk_lock prevents anything else from writing to the
  * mpfs clk block while a software locked register is being written.
@@ -126,8 +111,62 @@ static unsigned long mpfs_clk_msspll_recalc_rate(struct clk_hw *hw, unsigned lon
        return prate * mult / (ref_div * MSSPLL_FIXED_DIV * postdiv);
 }
 
+static long mpfs_clk_msspll_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate)
+{
+       struct mpfs_msspll_hw_clock *msspll_hw = to_mpfs_msspll_clk(hw);
+       void __iomem *mult_addr = msspll_hw->base + msspll_hw->reg_offset;
+       void __iomem *ref_div_addr = msspll_hw->base + REG_MSSPLL_REF_CR;
+       u32 mult, ref_div;
+       unsigned long rate_before_ctrl;
+
+       mult = readl_relaxed(mult_addr) >> MSSPLL_FBDIV_SHIFT;
+       mult &= clk_div_mask(MSSPLL_FBDIV_WIDTH);
+       ref_div = readl_relaxed(ref_div_addr) >> MSSPLL_REFDIV_SHIFT;
+       ref_div &= clk_div_mask(MSSPLL_REFDIV_WIDTH);
+
+       rate_before_ctrl = rate * (ref_div * MSSPLL_FIXED_DIV) / mult;
+
+       return divider_round_rate(hw, rate_before_ctrl, prate, NULL, MSSPLL_POSTDIV_WIDTH,
+                                 msspll_hw->flags);
+}
+
+static int mpfs_clk_msspll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
+{
+       struct mpfs_msspll_hw_clock *msspll_hw = to_mpfs_msspll_clk(hw);
+       void __iomem *mult_addr = msspll_hw->base + msspll_hw->reg_offset;
+       void __iomem *ref_div_addr = msspll_hw->base + REG_MSSPLL_REF_CR;
+       void __iomem *postdiv_addr = msspll_hw->base + REG_MSSPLL_POSTDIV_CR;
+       u32 mult, ref_div, postdiv;
+       int divider_setting;
+       unsigned long rate_before_ctrl, flags;
+
+       mult = readl_relaxed(mult_addr) >> MSSPLL_FBDIV_SHIFT;
+       mult &= clk_div_mask(MSSPLL_FBDIV_WIDTH);
+       ref_div = readl_relaxed(ref_div_addr) >> MSSPLL_REFDIV_SHIFT;
+       ref_div &= clk_div_mask(MSSPLL_REFDIV_WIDTH);
+
+       rate_before_ctrl = rate * (ref_div * MSSPLL_FIXED_DIV) / mult;
+       divider_setting = divider_get_val(rate_before_ctrl, prate, NULL, MSSPLL_POSTDIV_WIDTH,
+                                         msspll_hw->flags);
+
+       if (divider_setting < 0)
+               return divider_setting;
+
+       spin_lock_irqsave(&mpfs_clk_lock, flags);
+
+       postdiv = readl_relaxed(postdiv_addr);
+       postdiv &= ~(clk_div_mask(MSSPLL_POSTDIV_WIDTH) << MSSPLL_POSTDIV_SHIFT);
+       writel_relaxed(postdiv, postdiv_addr);
+
+       spin_unlock_irqrestore(&mpfs_clk_lock, flags);
+
+       return 0;
+}
+
 static const struct clk_ops mpfs_clk_msspll_ops = {
        .recalc_rate = mpfs_clk_msspll_recalc_rate,
+       .round_rate = mpfs_clk_msspll_round_rate,
+       .set_rate = mpfs_clk_msspll_set_rate,
 };
 
 #define CLK_PLL(_id, _name, _parent, _shift, _width, _flags, _offset) {                        \
@@ -144,25 +183,17 @@ static struct mpfs_msspll_hw_clock mpfs_msspll_clks[] = {
                MSSPLL_FBDIV_WIDTH, 0, REG_MSSPLL_SSCG_2_CR),
 };
 
-static int mpfs_clk_register_msspll(struct device *dev, struct mpfs_msspll_hw_clock *msspll_hw,
-                                   void __iomem *base)
-{
-       msspll_hw->base = base;
-
-       return devm_clk_hw_register(dev, &msspll_hw->hw);
-}
-
 static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_clock *msspll_hws,
                                     unsigned int num_clks, struct mpfs_clock_data *data)
 {
-       void __iomem *base = data->msspll_base;
        unsigned int i;
        int ret;
 
        for (i = 0; i < num_clks; i++) {
                struct mpfs_msspll_hw_clock *msspll_hw = &msspll_hws[i];
 
-               ret = mpfs_clk_register_msspll(dev, msspll_hw, base);
+               msspll_hw->base = data->msspll_base;
+               ret = devm_clk_hw_register(dev, &msspll_hw->hw);
                if (ret)
                        return dev_err_probe(dev, ret, "failed to register msspll id: %d\n",
                                             CLK_MSSPLL);
@@ -177,68 +208,22 @@ static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_c
  * "CFG" clocks
  */
 
-static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long prate)
-{
-       struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
-       struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
-       void __iomem *base_addr = cfg_hw->sys_base;
-       u32 val;
-
-       val = readl_relaxed(base_addr + cfg->reg_offset) >> cfg->shift;
-       val &= clk_div_mask(cfg->width);
-
-       return divider_recalc_rate(hw, prate, val, cfg->table, cfg->flags, cfg->width);
-}
-
-static long mpfs_cfg_clk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate)
-{
-       struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
-       struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
-
-       return divider_round_rate(hw, rate, prate, cfg->table, cfg->width, 0);
-}
-
-static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
-{
-       struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
-       struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
-       void __iomem *base_addr = cfg_hw->sys_base;
-       unsigned long flags;
-       u32 val;
-       int divider_setting;
-
-       divider_setting = divider_get_val(rate, prate, cfg->table, cfg->width, 0);
-
-       if (divider_setting < 0)
-               return divider_setting;
-
-       spin_lock_irqsave(&mpfs_clk_lock, flags);
-       val = readl_relaxed(base_addr + cfg->reg_offset);
-       val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift);
-       val |= divider_setting << cfg->shift;
-       writel_relaxed(val, base_addr + cfg->reg_offset);
-
-       spin_unlock_irqrestore(&mpfs_clk_lock, flags);
-
-       return 0;
-}
-
-static const struct clk_ops mpfs_clk_cfg_ops = {
-       .recalc_rate = mpfs_cfg_clk_recalc_rate,
-       .round_rate = mpfs_cfg_clk_round_rate,
-       .set_rate = mpfs_cfg_clk_set_rate,
-};
-
 #define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) {                \
-       .cfg.id = _id,                                                                  \
+       .id = _id,                                                                      \
        .cfg.shift = _shift,                                                            \
        .cfg.width = _width,                                                            \
        .cfg.table = _table,                                                            \
-       .cfg.reg_offset = _offset,                                                      \
+       .reg_offset = _offset,                                                          \
        .cfg.flags = _flags,                                                            \
-       .hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_cfg_ops, 0),                   \
+       .cfg.hw.init = CLK_HW_INIT(_name, _parent, &clk_divider_ops, 0),                \
+       .cfg.lock = &mpfs_clk_lock,                                                     \
 }
 
+#define CLK_CPU_OFFSET         0u
+#define CLK_AXI_OFFSET         1u
+#define CLK_AHB_OFFSET         2u
+#define CLK_RTCREF_OFFSET      3u
+
 static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
        CLK_CFG(CLK_CPU, "clk_cpu", "clk_msspll", 0, 2, mpfs_div_cpu_axi_table, 0,
                REG_CLOCK_CONFIG_CR),
@@ -247,42 +232,34 @@ static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
        CLK_CFG(CLK_AHB, "clk_ahb", "clk_msspll", 4, 2, mpfs_div_ahb_table, 0,
                REG_CLOCK_CONFIG_CR),
        {
-               .cfg.id = CLK_RTCREF,
+               .id = CLK_RTCREF,
                .cfg.shift = 0,
                .cfg.width = 12,
                .cfg.table = mpfs_div_rtcref_table,
-               .cfg.reg_offset = REG_RTC_CLOCK_CR,
+               .reg_offset = REG_RTC_CLOCK_CR,
                .cfg.flags = CLK_DIVIDER_ONE_BASED,
-               .hw.init =
-                       CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &mpfs_clk_cfg_ops, 0),
+               .cfg.hw.init =
+                       CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &clk_divider_ops, 0),
        }
 };
 
-static int mpfs_clk_register_cfg(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hw,
-                                void __iomem *sys_base)
-{
-       cfg_hw->sys_base = sys_base;
-
-       return devm_clk_hw_register(dev, &cfg_hw->hw);
-}
-
 static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hws,
                                  unsigned int num_clks, struct mpfs_clock_data *data)
 {
-       void __iomem *sys_base = data->base;
        unsigned int i, id;
        int ret;
 
        for (i = 0; i < num_clks; i++) {
                struct mpfs_cfg_hw_clock *cfg_hw = &cfg_hws[i];
 
-               ret = mpfs_clk_register_cfg(dev, cfg_hw, sys_base);
+               cfg_hw->cfg.reg = data->base + cfg_hw->reg_offset;
+               ret = devm_clk_hw_register(dev, &cfg_hw->cfg.hw);
                if (ret)
                        return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
-                                            cfg_hw->cfg.id);
+                                            cfg_hw->id);
 
-               id = cfg_hw->cfg.id;
-               data->hw_data.hws[id] = &cfg_hw->hw;
+               id = cfg_hw->id;
+               data->hw_data.hws[id] = &cfg_hw->cfg.hw;
        }
 
        return 0;
@@ -292,77 +269,15 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *
  * peripheral clocks - devices connected to axi or ahb buses.
  */
 
-static int mpfs_periph_clk_enable(struct clk_hw *hw)
-{
-       struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
-       struct mpfs_periph_clock *periph = &periph_hw->periph;
-       void __iomem *base_addr = periph_hw->sys_base;
-       u32 reg, val;
-       unsigned long flags;
-
-       spin_lock_irqsave(&mpfs_clk_lock, flags);
-
-       reg = readl_relaxed(base_addr + REG_SUBBLK_RESET_CR);
-       val = reg & ~(1u << periph->shift);
-       writel_relaxed(val, base_addr + REG_SUBBLK_RESET_CR);
-
-       reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
-       val = reg | (1u << periph->shift);
-       writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR);
-
-       spin_unlock_irqrestore(&mpfs_clk_lock, flags);
-
-       return 0;
-}
-
-static void mpfs_periph_clk_disable(struct clk_hw *hw)
-{
-       struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
-       struct mpfs_periph_clock *periph = &periph_hw->periph;
-       void __iomem *base_addr = periph_hw->sys_base;
-       u32 reg, val;
-       unsigned long flags;
-
-       spin_lock_irqsave(&mpfs_clk_lock, flags);
-
-       reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
-       val = reg & ~(1u << periph->shift);
-       writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR);
-
-       spin_unlock_irqrestore(&mpfs_clk_lock, flags);
-}
-
-static int mpfs_periph_clk_is_enabled(struct clk_hw *hw)
-{
-       struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
-       struct mpfs_periph_clock *periph = &periph_hw->periph;
-       void __iomem *base_addr = periph_hw->sys_base;
-       u32 reg;
-
-       reg = readl_relaxed(base_addr + REG_SUBBLK_RESET_CR);
-       if ((reg & (1u << periph->shift)) == 0u) {
-               reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
-               if (reg & (1u << periph->shift))
-                       return 1;
-       }
-
-       return 0;
-}
-
-static const struct clk_ops mpfs_periph_clk_ops = {
-       .enable = mpfs_periph_clk_enable,
-       .disable = mpfs_periph_clk_disable,
-       .is_enabled = mpfs_periph_clk_is_enabled,
-};
-
 #define CLK_PERIPH(_id, _name, _parent, _shift, _flags) {                      \
-       .periph.id = _id,                                                       \
-       .periph.shift = _shift,                                                 \
-       .hw.init = CLK_HW_INIT_HW(_name, _parent, &mpfs_periph_clk_ops,         \
+       .id = _id,                                                              \
+       .periph.bit_idx = _shift,                                               \
+       .periph.hw.init = CLK_HW_INIT_HW(_name, _parent, &clk_gate_ops,         \
                                  _flags),                                      \
+       .periph.lock = &mpfs_clk_lock,                                          \
 }
 
-#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].hw)
+#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFFSET].cfg.hw)
 
 /*
  * Critical clocks:
@@ -370,6 +285,8 @@ static const struct clk_ops mpfs_periph_clk_ops = {
  *   trap handler
  * - CLK_MMUART0: reserved by the hss
  * - CLK_DDRC: provides clock to the ddr subsystem
+ * - CLK_RTC: the onboard RTC's AHB bus clock must be kept running as the rtc will stop
+ *   if the AHB interface clock is disabled
  * - CLK_FICx: these provide the processor side clocks to the "FIC" (Fabric InterConnect)
  *   clock domain crossers which provide the interface to the FPGA fabric. Disabling them
  *   causes the FPGA fabric to go into reset.
@@ -394,7 +311,7 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
        CLK_PERIPH(CLK_CAN0, "clk_periph_can0", PARENT_CLK(AHB), 14, 0),
        CLK_PERIPH(CLK_CAN1, "clk_periph_can1", PARENT_CLK(AHB), 15, 0),
        CLK_PERIPH(CLK_USB, "clk_periph_usb", PARENT_CLK(AHB), 16, 0),
-       CLK_PERIPH(CLK_RTC, "clk_periph_rtc", PARENT_CLK(AHB), 18, 0),
+       CLK_PERIPH(CLK_RTC, "clk_periph_rtc", PARENT_CLK(AHB), 18, CLK_IS_CRITICAL),
        CLK_PERIPH(CLK_QSPI, "clk_periph_qspi", PARENT_CLK(AHB), 19, 0),
        CLK_PERIPH(CLK_GPIO0, "clk_periph_gpio0", PARENT_CLK(AHB), 20, 0),
        CLK_PERIPH(CLK_GPIO1, "clk_periph_gpio1", PARENT_CLK(AHB), 21, 0),
@@ -408,36 +325,116 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
        CLK_PERIPH(CLK_CFM, "clk_periph_cfm", PARENT_CLK(AHB), 29, 0),
 };
 
-static int mpfs_clk_register_periph(struct device *dev, struct mpfs_periph_hw_clock *periph_hw,
-                                   void __iomem *sys_base)
-{
-       periph_hw->sys_base = sys_base;
-
-       return devm_clk_hw_register(dev, &periph_hw->hw);
-}
-
 static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_clock *periph_hws,
                                     int num_clks, struct mpfs_clock_data *data)
 {
-       void __iomem *sys_base = data->base;
        unsigned int i, id;
        int ret;
 
        for (i = 0; i < num_clks; i++) {
                struct mpfs_periph_hw_clock *periph_hw = &periph_hws[i];
 
-               ret = mpfs_clk_register_periph(dev, periph_hw, sys_base);
+               periph_hw->periph.reg = data->base + REG_SUBBLK_CLOCK_CR;
+               ret = devm_clk_hw_register(dev, &periph_hw->periph.hw);
                if (ret)
                        return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
-                                            periph_hw->periph.id);
+                                            periph_hw->id);
 
-               id = periph_hws[i].periph.id;
-               data->hw_data.hws[id] = &periph_hw->hw;
+               id = periph_hws[i].id;
+               data->hw_data.hws[id] = &periph_hw->periph.hw;
        }
 
        return 0;
 }
 
+/*
+ * Peripheral clock resets
+ */
+
+#if IS_ENABLED(CONFIG_RESET_CONTROLLER)
+
+u32 mpfs_reset_read(struct device *dev)
+{
+       struct mpfs_clock_data *clock_data = dev_get_drvdata(dev->parent);
+
+       return readl_relaxed(clock_data->base + REG_SUBBLK_RESET_CR);
+}
+EXPORT_SYMBOL_NS_GPL(mpfs_reset_read, MCHP_CLK_MPFS);
+
+void mpfs_reset_write(struct device *dev, u32 val)
+{
+       struct mpfs_clock_data *clock_data = dev_get_drvdata(dev->parent);
+
+       writel_relaxed(val, clock_data->base + REG_SUBBLK_RESET_CR);
+}
+EXPORT_SYMBOL_NS_GPL(mpfs_reset_write, MCHP_CLK_MPFS);
+
+static void mpfs_reset_unregister_adev(void *_adev)
+{
+       struct auxiliary_device *adev = _adev;
+
+       auxiliary_device_delete(adev);
+}
+
+static void mpfs_reset_adev_release(struct device *dev)
+{
+       struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+       auxiliary_device_uninit(adev);
+
+       kfree(adev);
+}
+
+static struct auxiliary_device *mpfs_reset_adev_alloc(struct mpfs_clock_data *clk_data)
+{
+       struct auxiliary_device *adev;
+       int ret;
+
+       adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+       if (!adev)
+               return ERR_PTR(-ENOMEM);
+
+       adev->name = "reset-mpfs";
+       adev->dev.parent = clk_data->dev;
+       adev->dev.release = mpfs_reset_adev_release;
+       adev->id = 666u;
+
+       ret = auxiliary_device_init(adev);
+       if (ret) {
+               kfree(adev);
+               return ERR_PTR(ret);
+       }
+
+       return adev;
+}
+
+static int mpfs_reset_controller_register(struct mpfs_clock_data *clk_data)
+{
+       struct auxiliary_device *adev;
+       int ret;
+
+       adev = mpfs_reset_adev_alloc(clk_data);
+       if (IS_ERR(adev))
+               return PTR_ERR(adev);
+
+       ret = auxiliary_device_add(adev);
+       if (ret) {
+               auxiliary_device_uninit(adev);
+               return ret;
+       }
+
+       return devm_add_action_or_reset(clk_data->dev, mpfs_reset_unregister_adev, adev);
+}
+
+#else /* !CONFIG_RESET_CONTROLLER */
+
+static int mpfs_reset_controller_register(struct mpfs_clock_data *clk_data)
+{
+       return 0;
+}
+
+#endif /* !CONFIG_RESET_CONTROLLER */
+
 static int mpfs_clk_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -462,6 +459,8 @@ static int mpfs_clk_probe(struct platform_device *pdev)
                return PTR_ERR(clk_data->msspll_base);
 
        clk_data->hw_data.num = num_clks;
+       clk_data->dev = dev;
+       dev_set_drvdata(dev, clk_data);
 
        ret = mpfs_clk_register_mssplls(dev, mpfs_msspll_clks, ARRAY_SIZE(mpfs_msspll_clks),
                                        clk_data);
@@ -481,14 +480,14 @@ static int mpfs_clk_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       return ret;
+       return mpfs_reset_controller_register(clk_data);
 }
 
 static const struct of_device_id mpfs_clk_of_match_table[] = {
        { .compatible = "microchip,mpfs-clkcfg", },
        {}
 };
-MODULE_DEVICE_TABLE(of, mpfs_clk_match_table);
+MODULE_DEVICE_TABLE(of, mpfs_clk_of_match_table);
 
 static struct platform_driver mpfs_clk_driver = {
        .probe = mpfs_clk_probe,
@@ -511,4 +510,7 @@ static void __exit clk_mpfs_exit(void)
 module_exit(clk_mpfs_exit);
 
 MODULE_DESCRIPTION("Microchip PolarFire SoC Clock Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Padmarao Begari <padmarao.begari@microchip.com>");
+MODULE_AUTHOR("Daire McNamara <daire.mcnamara@microchip.com>");
+MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
+MODULE_LICENSE("GPL");
index 48dfb18..130d1a7 100644 (file)
@@ -19,9 +19,6 @@
 #include "clk.h"
 #include "reset.h"
 
-#define APBC_RTC       0x28
-#define APBC_TWSI0     0x2c
-#define APBC_KPC       0x30
 #define APBC_UART0     0x0
 #define APBC_UART1     0x4
 #define APBC_GPIO      0x8
 #define APBC_PWM1      0x10
 #define APBC_PWM2      0x14
 #define APBC_PWM3      0x18
+#define APBC_RTC       0x28
+#define APBC_TWSI0     0x2c
+#define APBC_KPC       0x30
 #define APBC_TIMER     0x34
+#define APBC_AIB       0x3c
+#define APBC_SW_JTAG   0x40
+#define APBC_ONEWIRE   0x48
+#define APBC_TWSI1     0x6c
+#define APBC_UART2     0x70
+#define APBC_AC97      0x84
 #define APBC_SSP0      0x81c
 #define APBC_SSP1      0x820
 #define APBC_SSP2      0x84c
 #define APBC_SSP3      0x858
 #define APBC_SSP4      0x85c
-#define APBC_TWSI1     0x6c
-#define APBC_UART2     0x70
+#define APMU_DISP0     0x4c
+#define APMU_CCIC0     0x50
 #define APMU_SDH0      0x54
 #define APMU_SDH1      0x58
 #define APMU_USB       0x5c
-#define APMU_DISP0     0x4c
-#define APMU_CCIC0     0x50
 #define APMU_DFC       0x60
+#define APMU_DMA       0x64
+#define APMU_BUS       0x6c
+#define APMU_GC                0xcc
+#define APMU_SMC       0xd4
+#define APMU_XD                0xdc
+#define APMU_SDH2      0xe0
+#define APMU_SDH3      0xe4
+#define APMU_CF                0xf0
+#define APMU_MSP       0xf4
+#define APMU_CMU       0xf8
+#define APMU_FE                0xfc
+#define APMU_PCIE      0x100
+#define APMU_EPD       0x104
 #define MPMU_UART_PLL  0x14
 
 struct pxa168_clk_unit {
@@ -71,9 +88,12 @@ static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
        {PXA168_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0},
        {PXA168_CLK_PLL1_192, "pll1_192", "pll1_96", 1, 2, 0},
        {PXA168_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0},
-       {PXA168_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0},
-       {PXA168_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0},
+       {PXA168_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 1, 5, 0},
+       {PXA168_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 1, 5, 0},
        {PXA168_CLK_PLL1_3_16, "pll1_3_16", "pll1", 3, 16, 0},
+       {PXA168_CLK_PLL1_2_1_10, "pll1_2_1_10", "pll1_2", 1, 10, 0},
+       {PXA168_CLK_PLL1_2_3_16, "pll1_2_3_16", "pll1_2", 3, 16, 0},
+       {PXA168_CLK_CLK32_2, "clk32_2", "clk32", 1, 2, 0},
 };
 
 static struct mmp_clk_factor_masks uart_factor_masks = {
@@ -107,24 +127,44 @@ static void pxa168_pll_init(struct pxa168_clk_unit *pxa_unit)
        mmp_clk_add(unit, PXA168_CLK_UART_PLL, clk);
 }
 
+static DEFINE_SPINLOCK(twsi0_lock);
+static DEFINE_SPINLOCK(twsi1_lock);
+static const char * const twsi_parent_names[] = {"pll1_2_1_10", "pll1_2_1_5"};
+
+static DEFINE_SPINLOCK(kpc_lock);
+static const char * const kpc_parent_names[] = {"clk32", "clk32_2", "pll1_24"};
+
+static DEFINE_SPINLOCK(pwm0_lock);
+static DEFINE_SPINLOCK(pwm1_lock);
+static DEFINE_SPINLOCK(pwm2_lock);
+static DEFINE_SPINLOCK(pwm3_lock);
+static const char * const pwm_parent_names[] = {"pll1_48", "clk32"};
+
 static DEFINE_SPINLOCK(uart0_lock);
 static DEFINE_SPINLOCK(uart1_lock);
 static DEFINE_SPINLOCK(uart2_lock);
-static const char *uart_parent_names[] = {"pll1_3_16", "uart_pll"};
+static const char * const uart_parent_names[] = {"pll1_2_3_16", "uart_pll"};
 
 static DEFINE_SPINLOCK(ssp0_lock);
 static DEFINE_SPINLOCK(ssp1_lock);
 static DEFINE_SPINLOCK(ssp2_lock);
 static DEFINE_SPINLOCK(ssp3_lock);
 static DEFINE_SPINLOCK(ssp4_lock);
-static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"};
+static const char * const ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"};
 
 static DEFINE_SPINLOCK(timer_lock);
-static const char *timer_parent_names[] = {"pll1_48", "clk32", "pll1_96", "pll1_192"};
+static const char * const timer_parent_names[] = {"pll1_48", "clk32", "pll1_96", "pll1_192"};
 
 static DEFINE_SPINLOCK(reset_lock);
 
 static struct mmp_param_mux_clk apbc_mux_clks[] = {
+       {0, "twsi0_mux", twsi_parent_names, ARRAY_SIZE(twsi_parent_names), CLK_SET_RATE_PARENT, APBC_TWSI0, 4, 3, 0, &twsi0_lock},
+       {0, "twsi1_mux", twsi_parent_names, ARRAY_SIZE(twsi_parent_names), CLK_SET_RATE_PARENT, APBC_TWSI1, 4, 3, 0, &twsi1_lock},
+       {0, "kpc_mux", kpc_parent_names, ARRAY_SIZE(kpc_parent_names), CLK_SET_RATE_PARENT, APBC_KPC, 4, 3, 0, &kpc_lock},
+       {0, "pwm0_mux", pwm_parent_names, ARRAY_SIZE(pwm_parent_names), CLK_SET_RATE_PARENT, APBC_PWM0, 4, 3, 0, &pwm0_lock},
+       {0, "pwm1_mux", pwm_parent_names, ARRAY_SIZE(pwm_parent_names), CLK_SET_RATE_PARENT, APBC_PWM1, 4, 3, 0, &pwm1_lock},
+       {0, "pwm2_mux", pwm_parent_names, ARRAY_SIZE(pwm_parent_names), CLK_SET_RATE_PARENT, APBC_PWM2, 4, 3, 0, &pwm2_lock},
+       {0, "pwm3_mux", pwm_parent_names, ARRAY_SIZE(pwm_parent_names), CLK_SET_RATE_PARENT, APBC_PWM3, 4, 3, 0, &pwm3_lock},
        {0, "uart0_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART0, 4, 3, 0, &uart0_lock},
        {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART1, 4, 3, 0, &uart1_lock},
        {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART2, 4, 3, 0, &uart2_lock},
@@ -137,16 +177,15 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = {
 };
 
 static struct mmp_param_gate_clk apbc_gate_clks[] = {
-       {PXA168_CLK_TWSI0, "twsi0_clk", "pll1_13_1_5", CLK_SET_RATE_PARENT, APBC_TWSI0, 0x3, 0x3, 0x0, 0, &reset_lock},
-       {PXA168_CLK_TWSI1, "twsi1_clk", "pll1_13_1_5", CLK_SET_RATE_PARENT, APBC_TWSI1, 0x3, 0x3, 0x0, 0, &reset_lock},
-       {PXA168_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_GPIO, 0x3, 0x3, 0x0, 0, &reset_lock},
-       {PXA168_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_KPC, 0x3, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL},
+       {PXA168_CLK_TWSI0, "twsi0_clk", "twsi0_mux", CLK_SET_RATE_PARENT, APBC_TWSI0, 0x3, 0x3, 0x0, 0, &twsi0_lock},
+       {PXA168_CLK_TWSI1, "twsi1_clk", "twsi1_mux", CLK_SET_RATE_PARENT, APBC_TWSI1, 0x3, 0x3, 0x0, 0, &twsi1_lock},
+       {PXA168_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_GPIO, 0x1, 0x1, 0x0, 0, &reset_lock},
+       {PXA168_CLK_KPC, "kpc_clk", "kpc_mux", CLK_SET_RATE_PARENT, APBC_KPC, 0x3, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, &kpc_lock},
        {PXA168_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_RTC, 0x83, 0x83, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL},
-       {PXA168_CLK_PWM0, "pwm0_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM0, 0x3, 0x3, 0x0, 0, &reset_lock},
-       {PXA168_CLK_PWM1, "pwm1_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM1, 0x3, 0x3, 0x0, 0, &reset_lock},
-       {PXA168_CLK_PWM2, "pwm2_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM2, 0x3, 0x3, 0x0, 0, &reset_lock},
-       {PXA168_CLK_PWM3, "pwm3_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM3, 0x3, 0x3, 0x0, 0, &reset_lock},
-       /* The gate clocks has mux parent. */
+       {PXA168_CLK_PWM0, "pwm0_clk", "pwm0_mux", CLK_SET_RATE_PARENT, APBC_PWM0, 0x3, 0x3, 0x0, 0, &pwm0_lock},
+       {PXA168_CLK_PWM1, "pwm1_clk", "pwm1_mux", CLK_SET_RATE_PARENT, APBC_PWM1, 0x3, 0x3, 0x0, 0, &pwm1_lock},
+       {PXA168_CLK_PWM2, "pwm2_clk", "pwm2_mux", CLK_SET_RATE_PARENT, APBC_PWM2, 0x3, 0x3, 0x0, 0, &pwm2_lock},
+       {PXA168_CLK_PWM3, "pwm3_clk", "pwm3_mux", CLK_SET_RATE_PARENT, APBC_PWM3, 0x3, 0x3, 0x0, 0, &pwm3_lock},
        {PXA168_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, APBC_UART0, 0x3, 0x3, 0x0, 0, &uart0_lock},
        {PXA168_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x3, 0x3, 0x0, 0, &uart1_lock},
        {PXA168_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, APBC_UART2, 0x3, 0x3, 0x0, 0, &uart2_lock},
@@ -170,22 +209,30 @@ static void pxa168_apb_periph_clk_init(struct pxa168_clk_unit *pxa_unit)
 
 }
 
+static DEFINE_SPINLOCK(dfc_lock);
+static const char * const dfc_parent_names[] = {"pll1_4", "pll1_8"};
+
 static DEFINE_SPINLOCK(sdh0_lock);
 static DEFINE_SPINLOCK(sdh1_lock);
-static const char *sdh_parent_names[] = {"pll1_12", "pll1_13"};
+static DEFINE_SPINLOCK(sdh2_lock);
+static DEFINE_SPINLOCK(sdh3_lock);
+static const char * const sdh_parent_names[] = {"pll1_13", "pll1_12", "pll1_8"};
 
 static DEFINE_SPINLOCK(usb_lock);
 
 static DEFINE_SPINLOCK(disp0_lock);
-static const char *disp_parent_names[] = {"pll1_2", "pll1_12"};
+static const char * const disp_parent_names[] = {"pll1", "pll1_2"};
 
 static DEFINE_SPINLOCK(ccic0_lock);
-static const char *ccic_parent_names[] = {"pll1_2", "pll1_12"};
-static const char *ccic_phy_parent_names[] = {"pll1_6", "pll1_12"};
+static const char * const ccic_parent_names[] = {"pll1_4", "pll1_8"};
+static const char * const ccic_phy_parent_names[] = {"pll1_6", "pll1_12"};
 
 static struct mmp_param_mux_clk apmu_mux_clks[] = {
-       {0, "sdh0_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH0, 6, 1, 0, &sdh0_lock},
-       {0, "sdh1_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH1, 6, 1, 0, &sdh1_lock},
+       {0, "dfc_mux", dfc_parent_names, ARRAY_SIZE(dfc_parent_names), CLK_SET_RATE_PARENT, APMU_DFC, 6, 1, 0, &dfc_lock},
+       {0, "sdh0_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH0, 6, 2, 0, &sdh0_lock},
+       {0, "sdh1_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH1, 6, 2, 0, &sdh1_lock},
+       {0, "sdh2_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH2, 6, 2, 0, &sdh2_lock},
+       {0, "sdh3_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH3, 6, 2, 0, &sdh3_lock},
        {0, "disp0_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP0, 6, 1, 0, &disp0_lock},
        {0, "ccic0_mux", ccic_parent_names, ARRAY_SIZE(ccic_parent_names), CLK_SET_RATE_PARENT, APMU_CCIC0, 6, 1, 0, &ccic0_lock},
        {0, "ccic0_phy_mux", ccic_phy_parent_names, ARRAY_SIZE(ccic_phy_parent_names), CLK_SET_RATE_PARENT, APMU_CCIC0, 7, 1, 0, &ccic0_lock},
@@ -196,12 +243,16 @@ static struct mmp_param_div_clk apmu_div_clks[] = {
 };
 
 static struct mmp_param_gate_clk apmu_gate_clks[] = {
-       {PXA168_CLK_DFC, "dfc_clk", "pll1_4", CLK_SET_RATE_PARENT, APMU_DFC, 0x19b, 0x19b, 0x0, 0, NULL},
+       {PXA168_CLK_DFC, "dfc_clk", "dfc_mux", CLK_SET_RATE_PARENT, APMU_DFC, 0x19b, 0x19b, 0x0, 0, &dfc_lock},
        {PXA168_CLK_USB, "usb_clk", "usb_pll", 0, APMU_USB, 0x9, 0x9, 0x0, 0, &usb_lock},
        {PXA168_CLK_SPH, "sph_clk", "usb_pll", 0, APMU_USB, 0x12, 0x12, 0x0, 0, &usb_lock},
-       /* The gate clocks has mux parent. */
-       {PXA168_CLK_SDH0, "sdh0_clk", "sdh0_mux", CLK_SET_RATE_PARENT, APMU_SDH0, 0x1b, 0x1b, 0x0, 0, &sdh0_lock},
-       {PXA168_CLK_SDH1, "sdh1_clk", "sdh1_mux", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh1_lock},
+       {PXA168_CLK_SDH0, "sdh0_clk", "sdh0_mux", CLK_SET_RATE_PARENT, APMU_SDH0, 0x12, 0x12, 0x0, 0, &sdh0_lock},
+       {PXA168_CLK_SDH1, "sdh1_clk", "sdh1_mux", CLK_SET_RATE_PARENT, APMU_SDH1, 0x12, 0x12, 0x0, 0, &sdh1_lock},
+       {PXA168_CLK_SDH2, "sdh2_clk", "sdh2_mux", CLK_SET_RATE_PARENT, APMU_SDH2, 0x12, 0x12, 0x0, 0, &sdh2_lock},
+       {PXA168_CLK_SDH3, "sdh3_clk", "sdh3_mux", CLK_SET_RATE_PARENT, APMU_SDH3, 0x12, 0x12, 0x0, 0, &sdh3_lock},
+       /* SDH0/1 and 2/3 AXI clocks are also gated by common bits in SDH0 and SDH2 registers */
+       {PXA168_CLK_SDH01_AXI, "sdh01_axi_clk", NULL, CLK_SET_RATE_PARENT, APMU_SDH0, 0x9, 0x9, 0x0, 0, &sdh0_lock},
+       {PXA168_CLK_SDH23_AXI, "sdh23_axi_clk", NULL, CLK_SET_RATE_PARENT, APMU_SDH2, 0x9, 0x9, 0x0, 0, &sdh2_lock},
        {PXA168_CLK_DISP0, "disp0_clk", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock},
        {PXA168_CLK_CCIC0, "ccic0_clk", "ccic0_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock},
        {PXA168_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_phy_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock},
index 585a02e..fc403ad 100644 (file)
@@ -87,7 +87,7 @@ static int armada_3700_tbg_clock_probe(struct platform_device *pdev)
        struct resource *res;
        struct clk *parent;
        void __iomem *reg;
-       int i, ret;
+       int i;
 
        hw_tbg_data = devm_kzalloc(&pdev->dev,
                                   struct_size(hw_tbg_data, hws, NUM_TBG),
@@ -123,9 +123,7 @@ static int armada_3700_tbg_clock_probe(struct platform_device *pdev)
                        dev_err(dev, "Can't register TBG clock %s\n", name);
        }
 
-       ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, hw_tbg_data);
-
-       return ret;
+       return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, hw_tbg_data);
 }
 
 static int armada_3700_tbg_clock_remove(struct platform_device *pdev)
index 7e35c89..0a90452 100644 (file)
@@ -170,7 +170,7 @@ static struct clk *clk_register_dove_divider(struct device *dev,
                .num_parents = num_parents,
        };
 
-       strlcpy(name, dc->name, sizeof(name));
+       strscpy(name, dc->name, sizeof(name));
 
        dc->hw.init = &init;
        dc->base = base;
index f253ef1..69ebf65 100644 (file)
@@ -606,7 +606,7 @@ static void __init lpc18xx_cgu_register_source_clks(struct device_node *np,
        if (IS_ERR(clk))
                pr_warn("%s: failed to register irc clk\n", __func__);
 
-       /* Register crystal oscillator controlller */
+       /* Register crystal oscillator controller */
        parents[0] = of_clk_get_parent_name(np, 0);
        clk = clk_register_gate(NULL, clk_src_names[CLK_SRC_OSC], parents[0],
                                0, base + LPC18XX_CGU_XTAL_OSC_CTRL,
index f9c31e3..2f4ffbd 100644 (file)
@@ -31,10 +31,10 @@ struct pistachio_mux {
        unsigned int shift;
        unsigned int num_parents;
        const char *name;
-       const char **parents;
+       const char *const *parents;
 };
 
-#define PNAME(x) static const char *x[] __initconst
+#define PNAME(x) static const char *const x[] __initconst
 
 #define MUX(_id, _name, _pnames, _reg, _shift)                 \
        {                                                       \
index 03de634..374098e 100644 (file)
@@ -104,6 +104,8 @@ int __init clk_pxa_cken_init(const struct desc_clk_cken *clks,
 
        for (i = 0; i < nb_clks; i++) {
                pxa_clk = kzalloc(sizeof(*pxa_clk), GFP_KERNEL);
+               if (!pxa_clk)
+                       return -ENOMEM;
                pxa_clk->is_in_low_power = clks[i].is_in_low_power;
                pxa_clk->lp = clks[i].lp;
                pxa_clk->hp = clks[i].hp;
index 1cf1ef7..76e6dee 100644 (file)
@@ -180,6 +180,14 @@ config MSM_GCC_8660
          Say Y if you want to use peripheral devices such as UART, SPI,
          i2c, USB, SD/eMMC, etc.
 
+config MSM_GCC_8909
+       tristate "MSM8909 Global Clock Controller"
+       select QCOM_GDSC
+       help
+         Support for the global clock controller on msm8909 devices.
+         Say Y if you want to use devices such as UART, SPI, I2C, USB,
+         SD/eMMC, display, graphics, camera etc.
+
 config MSM_GCC_8916
        tristate "MSM8916 Global Clock Controller"
        select QCOM_GDSC
@@ -445,6 +453,14 @@ config SC_GPUCC_7280
          Say Y if you want to support graphics controller devices and
          functionality such as 3D graphics.
 
+config SC_GPUCC_8280XP
+       tristate "SC8280XP Graphics Clock Controller"
+       select SC_GCC_8280XP
+       help
+         Support for the graphics clock controller on SC8280XP devices.
+         Say Y if you want to support graphics controller devices and
+         functionality such as 3D graphics.
+
 config SC_LPASSCC_7280
        tristate "SC7280 Low Power Audio Subsystem (LPASS) Clock Controller"
        select SC_GCC_7280
@@ -545,10 +561,10 @@ config QCS_Q6SSTOP_404
          controller to reset the Q6SSTOP subsystem.
 
 config SDM_GCC_845
-       tristate "SDM845 Global Clock Controller"
+       tristate "SDM845/SDM670 Global Clock Controller"
        select QCOM_GDSC
        help
-         Support for the global clock controller on SDM845 devices.
+         Support for the global clock controller on SDM845 and SDM670 devices.
          Say Y if you want to use peripheral devices such as UART, SPI,
          i2C, USB, UFS, SDDC, PCIe, etc.
 
@@ -616,6 +632,15 @@ config SM_CAMCC_8450
          Support for the camera clock controller on SM8450 devices.
          Say Y if you want to support camera devices and camera functionality.
 
+config SM_DISPCC_6115
+       tristate "SM6115 Display Clock Controller"
+       depends on SM_GCC_6115
+       help
+         Support for the display clock controller on Qualcomm Technologies, Inc
+         SM6115/SM4250 devices.
+         Say Y if you want to support display devices and functionality such as
+         splash screen
+
 config SM_DISPCC_6125
        tristate "SM6125 Display Clock Controller"
        depends on SM_GCC_6125
@@ -643,8 +668,18 @@ config SM_DISPCC_6350
          Say Y if you want to support display devices and functionality such as
          splash screen.
 
+config SM_DISPCC_8450
+       tristate "SM8450 Display Clock Controller"
+       depends on SM_GCC_8450
+       help
+         Support for the display clock controller on Qualcomm Technologies, Inc
+         SM8450 devices.
+         Say Y if you want to support display devices and functionality such as
+         splash screen.
+
 config SM_GCC_6115
        tristate "SM6115 and SM4250 Global Clock Controller"
+       select QCOM_GDSC
        help
          Support for the global clock controller on SM6115 and SM4250 devices.
          Say Y if you want to use peripheral devices such as UART, SPI,
@@ -665,6 +700,14 @@ config SM_GCC_6350
          Say Y if you want to use peripheral devices such as UART,
          SPI, I2C, USB, SD/UFS, PCIe etc.
 
+config SM_GCC_6375
+       tristate "SM6375 Global Clock Controller"
+       select QCOM_GDSC
+       help
+         Support for the global clock controller on SM6375 devices.
+         Say Y if you want to use peripheral devices such as UART,
+         SPI, I2C, USB, SD/UFS etc.
+
 config SM_GCC_8150
        tristate "SM8150 Global Clock Controller"
        help
index fbcf040..e6cecf9 100644 (file)
@@ -32,6 +32,7 @@ obj-$(CONFIG_MDM_GCC_9607) += gcc-mdm9607.o
 obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o
 obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o
 obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
+obj-$(CONFIG_MSM_GCC_8909) += gcc-msm8909.o
 obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o
 obj-$(CONFIG_MSM_GCC_8939) += gcc-msm8939.o
 obj-$(CONFIG_MSM_GCC_8953) += gcc-msm8953.o
@@ -71,6 +72,7 @@ obj-$(CONFIG_SC_GCC_8180X) += gcc-sc8180x.o
 obj-$(CONFIG_SC_GCC_8280XP) += gcc-sc8280xp.o
 obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o
 obj-$(CONFIG_SC_GPUCC_7280) += gpucc-sc7280.o
+obj-$(CONFIG_SC_GPUCC_8280XP) += gpucc-sc8280xp.o
 obj-$(CONFIG_SC_LPASSCC_7280) += lpasscc-sc7280.o
 obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o
 obj-$(CONFIG_SC_LPASS_CORECC_7280) += lpasscorecc-sc7280.o lpassaudiocc-sc7280.o
@@ -90,12 +92,15 @@ obj-$(CONFIG_SDX_GCC_55) += gcc-sdx55.o
 obj-$(CONFIG_SDX_GCC_65) += gcc-sdx65.o
 obj-$(CONFIG_SM_CAMCC_8250) += camcc-sm8250.o
 obj-$(CONFIG_SM_CAMCC_8450) += camcc-sm8450.o
+obj-$(CONFIG_SM_DISPCC_6115) += dispcc-sm6115.o
 obj-$(CONFIG_SM_DISPCC_6125) += dispcc-sm6125.o
 obj-$(CONFIG_SM_DISPCC_6350) += dispcc-sm6350.o
 obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o
+obj-$(CONFIG_SM_DISPCC_8450) += dispcc-sm8450.o
 obj-$(CONFIG_SM_GCC_6115) += gcc-sm6115.o
 obj-$(CONFIG_SM_GCC_6125) += gcc-sm6125.o
 obj-$(CONFIG_SM_GCC_6350) += gcc-sm6350.o
+obj-$(CONFIG_SM_GCC_6375) += gcc-sm6375.o
 obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o
 obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o
 obj-$(CONFIG_SM_GCC_8350) += gcc-sm8350.o
index 329d2c5..f9c5e29 100644 (file)
@@ -127,7 +127,9 @@ static int qcom_a53pll_probe(struct platform_device *pdev)
        if (!init.name)
                return -ENOMEM;
 
-       init.parent_names = (const char *[]){ "xo" };
+       init.parent_data = &(const struct clk_parent_data){
+               .fw_name = "xo", .name = "xo_board",
+       };
        init.num_parents = 1;
        init.ops = &clk_pll_sr2_ops;
        pll->clkr.hw.init = &init;
index bef7899..a5aea27 100644 (file)
@@ -2,6 +2,7 @@
 // Copyright (c) 2018, The Linux Foundation. All rights reserved.
 #include <linux/clk-provider.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
@@ -36,12 +37,28 @@ static struct clk_alpha_pll ipq_pll = {
        },
 };
 
-static const struct alpha_pll_config ipq_pll_config = {
+static const struct alpha_pll_config ipq6018_pll_config = {
        .l = 0x37,
-       .config_ctl_val = 0x04141200,
-       .config_ctl_hi_val = 0x0,
+       .config_ctl_val = 0x240d4828,
+       .config_ctl_hi_val = 0x6,
        .early_output_mask = BIT(3),
+       .aux2_output_mask = BIT(2),
+       .aux_output_mask = BIT(1),
        .main_output_mask = BIT(0),
+       .test_ctl_val = 0x1c0000C0,
+       .test_ctl_hi_val = 0x4000,
+};
+
+static const struct alpha_pll_config ipq8074_pll_config = {
+       .l = 0x48,
+       .config_ctl_val = 0x200d4828,
+       .config_ctl_hi_val = 0x6,
+       .early_output_mask = BIT(3),
+       .aux2_output_mask = BIT(2),
+       .aux_output_mask = BIT(1),
+       .main_output_mask = BIT(0),
+       .test_ctl_val = 0x1c000000,
+       .test_ctl_hi_val = 0x4000,
 };
 
 static const struct regmap_config ipq_pll_regmap_config = {
@@ -54,6 +71,7 @@ static const struct regmap_config ipq_pll_regmap_config = {
 
 static int apss_ipq_pll_probe(struct platform_device *pdev)
 {
+       const struct alpha_pll_config *ipq_pll_config;
        struct device *dev = &pdev->dev;
        struct regmap *regmap;
        void __iomem *base;
@@ -67,7 +85,11 @@ static int apss_ipq_pll_probe(struct platform_device *pdev)
        if (IS_ERR(regmap))
                return PTR_ERR(regmap);
 
-       clk_alpha_pll_configure(&ipq_pll, regmap, &ipq_pll_config);
+       ipq_pll_config = of_device_get_match_data(&pdev->dev);
+       if (!ipq_pll_config)
+               return -ENODEV;
+
+       clk_alpha_pll_configure(&ipq_pll, regmap, ipq_pll_config);
 
        ret = devm_clk_register_regmap(dev, &ipq_pll.clkr);
        if (ret)
@@ -78,7 +100,8 @@ static int apss_ipq_pll_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id apss_ipq_pll_match_table[] = {
-       { .compatible = "qcom,ipq6018-a53pll" },
+       { .compatible = "qcom,ipq6018-a53pll", .data = &ipq6018_pll_config },
+       { .compatible = "qcom,ipq8074-a53pll", .data = &ipq8074_pll_config },
        { }
 };
 MODULE_DEVICE_TABLE(of, apss_ipq_pll_match_table);
index d78ff2f..f2f502e 100644 (file)
@@ -16,7 +16,7 @@
 #include "clk-regmap.h"
 #include "clk-branch.h"
 #include "clk-alpha-pll.h"
-#include "clk-regmap-mux.h"
+#include "clk-rcg.h"
 
 enum {
        P_XO,
@@ -33,16 +33,15 @@ static const struct parent_map parents_apcs_alias0_clk_src_map[] = {
        { P_APSS_PLL_EARLY, 5 },
 };
 
-static struct clk_regmap_mux apcs_alias0_clk_src = {
-       .reg = 0x0050,
-       .width = 3,
-       .shift = 7,
+static struct clk_rcg2 apcs_alias0_clk_src = {
+       .cmd_rcgr = 0x0050,
+       .hid_width = 5,
        .parent_map = parents_apcs_alias0_clk_src_map,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "apcs_alias0_clk_src",
                .parent_data = parents_apcs_alias0_clk_src,
-               .num_parents = 2,
-               .ops = &clk_regmap_mux_closest_ops,
+               .num_parents = ARRAY_SIZE(parents_apcs_alias0_clk_src),
+               .ops = &clk_rcg2_mux_closest_ops,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -57,7 +56,7 @@ static struct clk_branch apcs_alias0_core_clk = {
                        .parent_hws = (const struct clk_hw *[]){
                                &apcs_alias0_clk_src.clkr.hw },
                        .num_parents = 1,
-                       .flags = CLK_SET_RATE_PARENT,
+                       .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
                        .ops = &clk_branch2_ops,
                },
        },
index b426847..1973d79 100644 (file)
@@ -27,6 +27,7 @@
 # define PLL_VOTE_FSM_RESET    BIT(21)
 # define PLL_UPDATE            BIT(22)
 # define PLL_UPDATE_BYPASS     BIT(23)
+# define PLL_FSM_LEGACY_MODE   BIT(24)
 # define PLL_OFFLINE_ACK       BIT(28)
 # define ALPHA_PLL_ACK_LATCH   BIT(29)
 # define PLL_ACTIVE_FLAG       BIT(30)
@@ -166,6 +167,27 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
                [PLL_OFF_TEST_CTL] = 0x28,
                [PLL_OFF_TEST_CTL_U] = 0x2c,
        },
+       [CLK_ALPHA_PLL_TYPE_DEFAULT_EVO] =  {
+               [PLL_OFF_L_VAL] = 0x04,
+               [PLL_OFF_ALPHA_VAL] = 0x08,
+               [PLL_OFF_ALPHA_VAL_U] = 0x0c,
+               [PLL_OFF_TEST_CTL] = 0x10,
+               [PLL_OFF_TEST_CTL_U] = 0x14,
+               [PLL_OFF_USER_CTL] = 0x18,
+               [PLL_OFF_USER_CTL_U] = 0x1c,
+               [PLL_OFF_CONFIG_CTL] = 0x20,
+               [PLL_OFF_STATUS] = 0x24,
+       },
+       [CLK_ALPHA_PLL_TYPE_BRAMMO_EVO] =  {
+               [PLL_OFF_L_VAL] = 0x04,
+               [PLL_OFF_ALPHA_VAL] = 0x08,
+               [PLL_OFF_ALPHA_VAL_U] = 0x0c,
+               [PLL_OFF_TEST_CTL] = 0x10,
+               [PLL_OFF_TEST_CTL_U] = 0x14,
+               [PLL_OFF_USER_CTL] = 0x18,
+               [PLL_OFF_CONFIG_CTL] = 0x1C,
+               [PLL_OFF_STATUS] = 0x20,
+       },
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
 
@@ -1102,6 +1124,10 @@ void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
                regmap_update_bits(regmap, PLL_USER_CTL(pll), mask, val);
        }
 
+       if (pll->flags & SUPPORTS_FSM_LEGACY_MODE)
+               regmap_update_bits(regmap, PLL_MODE(pll), PLL_FSM_LEGACY_MODE,
+                                                       PLL_FSM_LEGACY_MODE);
+
        regmap_update_bits(regmap, PLL_MODE(pll), PLL_UPDATE_BYPASS,
                                                        PLL_UPDATE_BYPASS);
 
@@ -2088,7 +2114,7 @@ static int alpha_pll_lucid_evo_enable(struct clk_hw *hw)
        return ret;
 }
 
-static void alpha_pll_lucid_evo_disable(struct clk_hw *hw)
+static void _alpha_pll_lucid_evo_disable(struct clk_hw *hw, bool reset)
 {
        struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
        struct regmap *regmap = pll->clkr.regmap;
@@ -2117,9 +2143,12 @@ static void alpha_pll_lucid_evo_disable(struct clk_hw *hw)
 
        /* Place the PLL mode in STANDBY */
        regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
+
+       if (reset)
+               regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, 0);
 }
 
-static int alpha_pll_lucid_evo_prepare(struct clk_hw *hw)
+static int _alpha_pll_lucid_evo_prepare(struct clk_hw *hw, bool reset)
 {
        struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
        struct clk_hw *p;
@@ -2139,11 +2168,31 @@ static int alpha_pll_lucid_evo_prepare(struct clk_hw *hw)
        if (ret)
                return ret;
 
-       alpha_pll_lucid_evo_disable(hw);
+       _alpha_pll_lucid_evo_disable(hw, reset);
 
        return 0;
 }
 
+static void alpha_pll_lucid_evo_disable(struct clk_hw *hw)
+{
+       _alpha_pll_lucid_evo_disable(hw, false);
+}
+
+static int alpha_pll_lucid_evo_prepare(struct clk_hw *hw)
+{
+       return _alpha_pll_lucid_evo_prepare(hw, false);
+}
+
+static void alpha_pll_reset_lucid_evo_disable(struct clk_hw *hw)
+{
+       _alpha_pll_lucid_evo_disable(hw, true);
+}
+
+static int alpha_pll_reset_lucid_evo_prepare(struct clk_hw *hw)
+{
+       return _alpha_pll_lucid_evo_prepare(hw, true);
+}
+
 static unsigned long alpha_pll_lucid_evo_recalc_rate(struct clk_hw *hw,
                                                     unsigned long parent_rate)
 {
@@ -2191,6 +2240,17 @@ const struct clk_ops clk_alpha_pll_lucid_evo_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_evo_ops);
 
+const struct clk_ops clk_alpha_pll_reset_lucid_evo_ops = {
+       .prepare = alpha_pll_reset_lucid_evo_prepare,
+       .enable = alpha_pll_lucid_evo_enable,
+       .disable = alpha_pll_reset_lucid_evo_disable,
+       .is_enabled = clk_trion_pll_is_enabled,
+       .recalc_rate = alpha_pll_lucid_evo_recalc_rate,
+       .round_rate = clk_alpha_pll_round_rate,
+       .set_rate = alpha_pll_lucid_5lpe_set_rate,
+};
+EXPORT_SYMBOL_GPL(clk_alpha_pll_reset_lucid_evo_ops);
+
 void clk_rivian_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
                                  const struct alpha_pll_config *config)
 {
index 447efb8..f9524b3 100644 (file)
@@ -19,6 +19,8 @@ enum {
        CLK_ALPHA_PLL_TYPE_ZONDA,
        CLK_ALPHA_PLL_TYPE_LUCID_EVO,
        CLK_ALPHA_PLL_TYPE_RIVIAN_EVO,
+       CLK_ALPHA_PLL_TYPE_DEFAULT_EVO,
+       CLK_ALPHA_PLL_TYPE_BRAMMO_EVO,
        CLK_ALPHA_PLL_TYPE_MAX,
 };
 
@@ -70,9 +72,10 @@ struct clk_alpha_pll {
 
        const struct pll_vco *vco_table;
        size_t num_vco;
-#define SUPPORTS_OFFLINE_REQ   BIT(0)
-#define SUPPORTS_FSM_MODE      BIT(2)
+#define SUPPORTS_OFFLINE_REQ           BIT(0)
+#define SUPPORTS_FSM_MODE              BIT(2)
 #define SUPPORTS_DYNAMIC_UPDATE        BIT(3)
+#define SUPPORTS_FSM_LEGACY_MODE       BIT(4)
        u8 flags;
 
        struct clk_regmap clkr;
@@ -155,6 +158,7 @@ extern const struct clk_ops clk_alpha_pll_zonda_ops;
 #define clk_alpha_pll_postdiv_zonda_ops clk_alpha_pll_postdiv_fabia_ops
 
 extern const struct clk_ops clk_alpha_pll_lucid_evo_ops;
+extern const struct clk_ops clk_alpha_pll_reset_lucid_evo_ops;
 extern const struct clk_ops clk_alpha_pll_fixed_lucid_evo_ops;
 extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops;
 
index 4a4fde8..ee76ef9 100644 (file)
@@ -49,6 +49,7 @@
  * detect voltage droops.
  */
 
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/io.h>
 
 #include "clk-alpha-pll.h"
 #include "clk-regmap.h"
+#include "clk-regmap-mux.h"
 
 enum _pmux_input {
-       DIV_2_INDEX = 0,
+       SMUX_INDEX = 0,
        PLL_INDEX,
        ACD_INDEX,
        ALT_INDEX,
@@ -75,6 +77,8 @@ enum _pmux_input {
 #define ALT_PLL_OFFSET 0x100
 #define SSSCTL_OFFSET 0x160
 
+#define PMUX_MASK      0x3
+
 static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
        [PLL_OFF_L_VAL] = 0x04,
        [PLL_OFF_ALPHA_VAL] = 0x08,
@@ -111,30 +115,90 @@ static const struct alpha_pll_config hfpll_config = {
        .early_output_mask = BIT(3),
 };
 
-static struct clk_alpha_pll perfcl_pll = {
-       .offset = PERFCL_REG_OFFSET,
+static const struct clk_parent_data pll_parent[] = {
+       { .fw_name = "xo" },
+};
+
+static struct clk_alpha_pll pwrcl_pll = {
+       .offset = PWRCL_REG_OFFSET,
        .regs = prim_pll_regs,
        .flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
        .clkr.hw.init = &(struct clk_init_data){
-               .name = "perfcl_pll",
-               .parent_names = (const char *[]){ "xo" },
-               .num_parents = 1,
+               .name = "pwrcl_pll",
+               .parent_data = pll_parent,
+               .num_parents = ARRAY_SIZE(pll_parent),
                .ops = &clk_alpha_pll_huayra_ops,
        },
 };
 
-static struct clk_alpha_pll pwrcl_pll = {
-       .offset = PWRCL_REG_OFFSET,
+static struct clk_alpha_pll perfcl_pll = {
+       .offset = PERFCL_REG_OFFSET,
        .regs = prim_pll_regs,
        .flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
        .clkr.hw.init = &(struct clk_init_data){
-               .name = "pwrcl_pll",
-               .parent_names = (const char *[]){ "xo" },
-               .num_parents = 1,
+               .name = "perfcl_pll",
+               .parent_data = pll_parent,
+               .num_parents = ARRAY_SIZE(pll_parent),
                .ops = &clk_alpha_pll_huayra_ops,
        },
 };
 
+static struct clk_fixed_factor pwrcl_pll_postdiv = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "pwrcl_pll_postdiv",
+               .parent_data = &(const struct clk_parent_data){
+                       .hw = &pwrcl_pll.clkr.hw
+               },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_fixed_factor perfcl_pll_postdiv = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "perfcl_pll_postdiv",
+               .parent_data = &(const struct clk_parent_data){
+                       .hw = &perfcl_pll.clkr.hw
+               },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_fixed_factor perfcl_pll_acd = {
+       .mult = 1,
+       .div = 1,
+       .hw.init = &(struct clk_init_data){
+               .name = "perfcl_pll_acd",
+               .parent_data = &(const struct clk_parent_data){
+                       .hw = &perfcl_pll.clkr.hw
+               },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_fixed_factor pwrcl_pll_acd = {
+       .mult = 1,
+       .div = 1,
+       .hw.init = &(struct clk_init_data){
+               .name = "pwrcl_pll_acd",
+               .parent_data = &(const struct clk_parent_data){
+                       .hw = &pwrcl_pll.clkr.hw
+               },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
 static const struct pll_vco alt_pll_vco_modes[] = {
        VCO(3,  250000000,  500000000),
        VCO(2,  500000000,  750000000),
@@ -153,93 +217,87 @@ static const struct alpha_pll_config altpll_config = {
        .early_output_mask = BIT(3),
 };
 
-static struct clk_alpha_pll perfcl_alt_pll = {
-       .offset = PERFCL_REG_OFFSET + ALT_PLL_OFFSET,
+static struct clk_alpha_pll pwrcl_alt_pll = {
+       .offset = PWRCL_REG_OFFSET + ALT_PLL_OFFSET,
        .regs = alt_pll_regs,
        .vco_table = alt_pll_vco_modes,
        .num_vco = ARRAY_SIZE(alt_pll_vco_modes),
        .flags = SUPPORTS_OFFLINE_REQ | SUPPORTS_FSM_MODE,
        .clkr.hw.init = &(struct clk_init_data) {
-               .name = "perfcl_alt_pll",
-               .parent_names = (const char *[]){ "xo" },
-               .num_parents = 1,
+               .name = "pwrcl_alt_pll",
+               .parent_data = pll_parent,
+               .num_parents = ARRAY_SIZE(pll_parent),
                .ops = &clk_alpha_pll_hwfsm_ops,
        },
 };
 
-static struct clk_alpha_pll pwrcl_alt_pll = {
-       .offset = PWRCL_REG_OFFSET + ALT_PLL_OFFSET,
+static struct clk_alpha_pll perfcl_alt_pll = {
+       .offset = PERFCL_REG_OFFSET + ALT_PLL_OFFSET,
        .regs = alt_pll_regs,
        .vco_table = alt_pll_vco_modes,
        .num_vco = ARRAY_SIZE(alt_pll_vco_modes),
        .flags = SUPPORTS_OFFLINE_REQ | SUPPORTS_FSM_MODE,
        .clkr.hw.init = &(struct clk_init_data) {
-               .name = "pwrcl_alt_pll",
-               .parent_names = (const char *[]){ "xo" },
-               .num_parents = 1,
+               .name = "perfcl_alt_pll",
+               .parent_data = pll_parent,
+               .num_parents = ARRAY_SIZE(pll_parent),
                .ops = &clk_alpha_pll_hwfsm_ops,
        },
 };
 
-struct clk_cpu_8996_mux {
+struct clk_cpu_8996_pmux {
        u32     reg;
-       u8      shift;
-       u8      width;
        struct notifier_block nb;
-       struct clk_hw   *pll;
-       struct clk_hw   *pll_div_2;
        struct clk_regmap clkr;
 };
 
 static int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
                               void *data);
 
-#define to_clk_cpu_8996_mux_nb(_nb) \
-       container_of(_nb, struct clk_cpu_8996_mux, nb)
+#define to_clk_cpu_8996_pmux_nb(_nb) \
+       container_of(_nb, struct clk_cpu_8996_pmux, nb)
 
-static inline struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
+static inline struct clk_cpu_8996_pmux *to_clk_cpu_8996_pmux_hw(struct clk_hw *hw)
 {
-       return container_of(to_clk_regmap(hw), struct clk_cpu_8996_mux, clkr);
+       return container_of(to_clk_regmap(hw), struct clk_cpu_8996_pmux, clkr);
 }
 
-static u8 clk_cpu_8996_mux_get_parent(struct clk_hw *hw)
+static u8 clk_cpu_8996_pmux_get_parent(struct clk_hw *hw)
 {
        struct clk_regmap *clkr = to_clk_regmap(hw);
-       struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
-       u32 mask = GENMASK(cpuclk->width - 1, 0);
+       struct clk_cpu_8996_pmux *cpuclk = to_clk_cpu_8996_pmux_hw(hw);
        u32 val;
 
        regmap_read(clkr->regmap, cpuclk->reg, &val);
-       val >>= cpuclk->shift;
 
-       return val & mask;
+       return FIELD_GET(PMUX_MASK, val);
 }
 
-static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
+static int clk_cpu_8996_pmux_set_parent(struct clk_hw *hw, u8 index)
 {
        struct clk_regmap *clkr = to_clk_regmap(hw);
-       struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
-       u32 mask = GENMASK(cpuclk->width + cpuclk->shift - 1, cpuclk->shift);
+       struct clk_cpu_8996_pmux *cpuclk = to_clk_cpu_8996_pmux_hw(hw);
        u32 val;
 
-       val = index;
-       val <<= cpuclk->shift;
+       val = FIELD_PREP(PMUX_MASK, index);
 
-       return regmap_update_bits(clkr->regmap, cpuclk->reg, mask, val);
+       return regmap_update_bits(clkr->regmap, cpuclk->reg, PMUX_MASK, val);
 }
 
-static int clk_cpu_8996_mux_determine_rate(struct clk_hw *hw,
+static int clk_cpu_8996_pmux_determine_rate(struct clk_hw *hw,
                                           struct clk_rate_request *req)
 {
-       struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
-       struct clk_hw *parent = cpuclk->pll;
+       struct clk_hw *parent;
 
-       if (cpuclk->pll_div_2 && req->rate < DIV_2_THRESHOLD) {
-               if (req->rate < (DIV_2_THRESHOLD / 2))
-                       return -EINVAL;
+       if (req->rate < (DIV_2_THRESHOLD / 2))
+               return -EINVAL;
 
-               parent = cpuclk->pll_div_2;
-       }
+       if (req->rate < DIV_2_THRESHOLD)
+               parent = clk_hw_get_parent_by_index(hw, SMUX_INDEX);
+       else
+               parent = clk_hw_get_parent_by_index(hw, ACD_INDEX);
+       if (!parent)
+               return -EINVAL;
 
        req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
        req->best_parent_hw = parent;
@@ -247,83 +305,83 @@ static int clk_cpu_8996_mux_determine_rate(struct clk_hw *hw,
        return 0;
 }
 
-static const struct clk_ops clk_cpu_8996_mux_ops = {
-       .set_parent = clk_cpu_8996_mux_set_parent,
-       .get_parent = clk_cpu_8996_mux_get_parent,
-       .determine_rate = clk_cpu_8996_mux_determine_rate,
+static const struct clk_ops clk_cpu_8996_pmux_ops = {
+       .set_parent = clk_cpu_8996_pmux_set_parent,
+       .get_parent = clk_cpu_8996_pmux_get_parent,
+       .determine_rate = clk_cpu_8996_pmux_determine_rate,
+};
+
+static const struct clk_parent_data pwrcl_smux_parents[] = {
+       { .fw_name = "xo" },
+       { .hw = &pwrcl_pll_postdiv.hw },
 };
 
-static struct clk_cpu_8996_mux pwrcl_smux = {
+static const struct clk_parent_data perfcl_smux_parents[] = {
+       { .fw_name = "xo" },
+       { .hw = &perfcl_pll_postdiv.hw },
+};
+
+static struct clk_regmap_mux pwrcl_smux = {
        .reg = PWRCL_REG_OFFSET + MUX_OFFSET,
        .shift = 2,
        .width = 2,
        .clkr.hw.init = &(struct clk_init_data) {
                .name = "pwrcl_smux",
-               .parent_names = (const char *[]){
-                       "xo",
-                       "pwrcl_pll_main",
-               },
-               .num_parents = 2,
-               .ops = &clk_cpu_8996_mux_ops,
+               .parent_data = pwrcl_smux_parents,
+               .num_parents = ARRAY_SIZE(pwrcl_smux_parents),
+               .ops = &clk_regmap_mux_closest_ops,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static struct clk_cpu_8996_mux perfcl_smux = {
+static struct clk_regmap_mux perfcl_smux = {
        .reg = PERFCL_REG_OFFSET + MUX_OFFSET,
        .shift = 2,
        .width = 2,
        .clkr.hw.init = &(struct clk_init_data) {
                .name = "perfcl_smux",
-               .parent_names = (const char *[]){
-                       "xo",
-                       "perfcl_pll_main",
-               },
-               .num_parents = 2,
-               .ops = &clk_cpu_8996_mux_ops,
+               .parent_data = perfcl_smux_parents,
+               .num_parents = ARRAY_SIZE(perfcl_smux_parents),
+               .ops = &clk_regmap_mux_closest_ops,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static struct clk_cpu_8996_mux pwrcl_pmux = {
+static const struct clk_hw *pwrcl_pmux_parents[] = {
+       [SMUX_INDEX] = &pwrcl_smux.clkr.hw,
+       [PLL_INDEX] = &pwrcl_pll.clkr.hw,
+       [ACD_INDEX] = &pwrcl_pll_acd.hw,
+       [ALT_INDEX] = &pwrcl_alt_pll.clkr.hw,
+};
+
+static const struct clk_hw *perfcl_pmux_parents[] = {
+       [SMUX_INDEX] = &perfcl_smux.clkr.hw,
+       [PLL_INDEX] = &perfcl_pll.clkr.hw,
+       [ACD_INDEX] = &perfcl_pll_acd.hw,
+       [ALT_INDEX] = &perfcl_alt_pll.clkr.hw,
+};
+
+static struct clk_cpu_8996_pmux pwrcl_pmux = {
        .reg = PWRCL_REG_OFFSET + MUX_OFFSET,
-       .shift = 0,
-       .width = 2,
-       .pll = &pwrcl_pll.clkr.hw,
-       .pll_div_2 = &pwrcl_smux.clkr.hw,
        .nb.notifier_call = cpu_clk_notifier_cb,
        .clkr.hw.init = &(struct clk_init_data) {
                .name = "pwrcl_pmux",
-               .parent_names = (const char *[]){
-                       "pwrcl_smux",
-                       "pwrcl_pll",
-                       "pwrcl_pll_acd",
-                       "pwrcl_alt_pll",
-               },
-               .num_parents = 4,
-               .ops = &clk_cpu_8996_mux_ops,
+               .parent_hws = pwrcl_pmux_parents,
+               .num_parents = ARRAY_SIZE(pwrcl_pmux_parents),
+               .ops = &clk_cpu_8996_pmux_ops,
                /* CPU clock is critical and should never be gated */
                .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
        },
 };
 
-static struct clk_cpu_8996_mux perfcl_pmux = {
+static struct clk_cpu_8996_pmux perfcl_pmux = {
        .reg = PERFCL_REG_OFFSET + MUX_OFFSET,
-       .shift = 0,
-       .width = 2,
-       .pll = &perfcl_pll.clkr.hw,
-       .pll_div_2 = &perfcl_smux.clkr.hw,
        .nb.notifier_call = cpu_clk_notifier_cb,
        .clkr.hw.init = &(struct clk_init_data) {
                .name = "perfcl_pmux",
-               .parent_names = (const char *[]){
-                       "perfcl_smux",
-                       "perfcl_pll",
-                       "perfcl_pll_acd",
-                       "perfcl_alt_pll",
-               },
-               .num_parents = 4,
-               .ops = &clk_cpu_8996_mux_ops,
+               .parent_hws = perfcl_pmux_parents,
+               .num_parents = ARRAY_SIZE(perfcl_pmux_parents),
+               .ops = &clk_cpu_8996_pmux_ops,
                /* CPU clock is critical and should never be gated */
                .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
        },
@@ -338,15 +396,22 @@ static const struct regmap_config cpu_msm8996_regmap_config = {
        .val_format_endian      = REGMAP_ENDIAN_LITTLE,
 };
 
+static struct clk_hw *cpu_msm8996_hw_clks[] = {
+       &pwrcl_pll_postdiv.hw,
+       &perfcl_pll_postdiv.hw,
+       &pwrcl_pll_acd.hw,
+       &perfcl_pll_acd.hw,
+};
+
 static struct clk_regmap *cpu_msm8996_clks[] = {
-       &perfcl_pll.clkr,
        &pwrcl_pll.clkr,
-       &perfcl_alt_pll.clkr,
+       &perfcl_pll.clkr,
        &pwrcl_alt_pll.clkr,
-       &perfcl_smux.clkr,
+       &perfcl_alt_pll.clkr,
        &pwrcl_smux.clkr,
-       &perfcl_pmux.clkr,
+       &perfcl_smux.clkr,
        &pwrcl_pmux.clkr,
+       &perfcl_pmux.clkr,
 };
 
 static int qcom_cpu_clk_msm8996_register_clks(struct device *dev,
@@ -354,67 +419,33 @@ static int qcom_cpu_clk_msm8996_register_clks(struct device *dev,
 {
        int i, ret;
 
-       perfcl_smux.pll = clk_hw_register_fixed_factor(dev, "perfcl_pll_main",
-                                                      "perfcl_pll",
-                                                      CLK_SET_RATE_PARENT,
-                                                      1, 2);
-       if (IS_ERR(perfcl_smux.pll)) {
-               dev_err(dev, "Failed to initialize perfcl_pll_main\n");
-               return PTR_ERR(perfcl_smux.pll);
-       }
-
-       pwrcl_smux.pll = clk_hw_register_fixed_factor(dev, "pwrcl_pll_main",
-                                                     "pwrcl_pll",
-                                                     CLK_SET_RATE_PARENT,
-                                                     1, 2);
-       if (IS_ERR(pwrcl_smux.pll)) {
-               dev_err(dev, "Failed to initialize pwrcl_pll_main\n");
-               clk_hw_unregister(perfcl_smux.pll);
-               return PTR_ERR(pwrcl_smux.pll);
+       for (i = 0; i < ARRAY_SIZE(cpu_msm8996_hw_clks); i++) {
+               ret = devm_clk_hw_register(dev, cpu_msm8996_hw_clks[i]);
+               if (ret)
+                       return ret;
        }
 
        for (i = 0; i < ARRAY_SIZE(cpu_msm8996_clks); i++) {
                ret = devm_clk_register_regmap(dev, cpu_msm8996_clks[i]);
-               if (ret) {
-                       clk_hw_unregister(perfcl_smux.pll);
-                       clk_hw_unregister(pwrcl_smux.pll);
+               if (ret)
                        return ret;
-               }
        }
 
-       clk_alpha_pll_configure(&perfcl_pll, regmap, &hfpll_config);
        clk_alpha_pll_configure(&pwrcl_pll, regmap, &hfpll_config);
-       clk_alpha_pll_configure(&perfcl_alt_pll, regmap, &altpll_config);
+       clk_alpha_pll_configure(&perfcl_pll, regmap, &hfpll_config);
        clk_alpha_pll_configure(&pwrcl_alt_pll, regmap, &altpll_config);
+       clk_alpha_pll_configure(&perfcl_alt_pll, regmap, &altpll_config);
 
        /* Enable alt PLLs */
        clk_prepare_enable(pwrcl_alt_pll.clkr.hw.clk);
        clk_prepare_enable(perfcl_alt_pll.clkr.hw.clk);
 
-       clk_notifier_register(pwrcl_pmux.clkr.hw.clk, &pwrcl_pmux.nb);
-       clk_notifier_register(perfcl_pmux.clkr.hw.clk, &perfcl_pmux.nb);
+       devm_clk_notifier_register(dev, pwrcl_pmux.clkr.hw.clk, &pwrcl_pmux.nb);
+       devm_clk_notifier_register(dev, perfcl_pmux.clkr.hw.clk, &perfcl_pmux.nb);
 
        return ret;
 }
 
-static int qcom_cpu_clk_msm8996_unregister_clks(void)
-{
-       int ret = 0;
-
-       ret = clk_notifier_unregister(pwrcl_pmux.clkr.hw.clk, &pwrcl_pmux.nb);
-       if (ret)
-               return ret;
-
-       ret = clk_notifier_unregister(perfcl_pmux.clkr.hw.clk, &perfcl_pmux.nb);
-       if (ret)
-               return ret;
-
-       clk_hw_unregister(perfcl_smux.pll);
-       clk_hw_unregister(pwrcl_smux.pll);
-
-       return 0;
-}
-
 #define CPU_AFINITY_MASK 0xFFF
 #define PWRCL_CPU_REG_MASK 0x3
 #define PERFCL_CPU_REG_MASK 0x103
@@ -456,22 +487,22 @@ static void qcom_cpu_clk_msm8996_acd_init(void __iomem *base)
 static int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
                               void *data)
 {
-       struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+       struct clk_cpu_8996_pmux *cpuclk = to_clk_cpu_8996_pmux_nb(nb);
        struct clk_notifier_data *cnd = data;
        int ret;
 
        switch (event) {
        case PRE_RATE_CHANGE:
-               ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
+               ret = clk_cpu_8996_pmux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
                qcom_cpu_clk_msm8996_acd_init(base);
                break;
        case POST_RATE_CHANGE:
                if (cnd->new_rate < DIV_2_THRESHOLD)
-                       ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
-                                                         DIV_2_INDEX);
+                       ret = clk_cpu_8996_pmux_set_parent(&cpuclk->clkr.hw,
+                                                          SMUX_INDEX);
                else
-                       ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
-                                                         ACD_INDEX);
+                       ret = clk_cpu_8996_pmux_set_parent(&cpuclk->clkr.hw,
+                                                          ACD_INDEX);
                break;
        default:
                ret = 0;
@@ -513,11 +544,6 @@ static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
        return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, data);
 }
 
-static int qcom_cpu_clk_msm8996_driver_remove(struct platform_device *pdev)
-{
-       return qcom_cpu_clk_msm8996_unregister_clks();
-}
-
 static const struct of_device_id qcom_cpu_clk_msm8996_match_table[] = {
        { .compatible = "qcom,msm8996-apcc" },
        {}
@@ -526,7 +552,6 @@ MODULE_DEVICE_TABLE(of, qcom_cpu_clk_msm8996_match_table);
 
 static struct platform_driver qcom_cpu_clk_msm8996_driver = {
        .probe = qcom_cpu_clk_msm8996_driver_probe,
-       .remove = qcom_cpu_clk_msm8996_driver_remove,
        .driver = {
                .name = "qcom-msm8996-apcc",
                .of_match_table = qcom_cpu_clk_msm8996_match_table,
index 012e745..01581f4 100644 (file)
@@ -167,6 +167,7 @@ struct clk_rcg2_gfx3d {
 
 extern const struct clk_ops clk_rcg2_ops;
 extern const struct clk_ops clk_rcg2_floor_ops;
+extern const struct clk_ops clk_rcg2_mux_closest_ops;
 extern const struct clk_ops clk_edp_pixel_ops;
 extern const struct clk_ops clk_byte_ops;
 extern const struct clk_ops clk_byte2_ops;
index 28019ed..609c10f 100644 (file)
@@ -509,6 +509,13 @@ const struct clk_ops clk_rcg2_floor_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_rcg2_floor_ops);
 
+const struct clk_ops clk_rcg2_mux_closest_ops = {
+       .determine_rate = __clk_mux_determine_rate_closest,
+       .get_parent = clk_rcg2_get_parent,
+       .set_parent = clk_rcg2_set_parent,
+};
+EXPORT_SYMBOL_GPL(clk_rcg2_mux_closest_ops);
+
 struct frac_entry {
        int num;
        int den;
index c07cab6..0471bab 100644 (file)
@@ -195,10 +195,6 @@ static int clk_rpmh_aggregate_state_send_command(struct clk_rpmh *c,
 {
        int ret;
 
-       /* Nothing required to be done if already off or on */
-       if (enable == c->state)
-               return 0;
-
        c->state = enable ? c->valid_state_mask : 0;
        c->aggr_state = c->state | c->peer->state;
        c->peer->aggr_state = c->aggr_state;
@@ -382,6 +378,26 @@ static const struct clk_rpmh_desc clk_rpmh_sdm845 = {
        .num_clks = ARRAY_SIZE(sdm845_rpmh_clocks),
 };
 
+static struct clk_hw *sdm670_rpmh_clocks[] = {
+       [RPMH_CXO_CLK]          = &sdm845_bi_tcxo.hw,
+       [RPMH_CXO_CLK_A]        = &sdm845_bi_tcxo_ao.hw,
+       [RPMH_LN_BB_CLK2]       = &sdm845_ln_bb_clk2.hw,
+       [RPMH_LN_BB_CLK2_A]     = &sdm845_ln_bb_clk2_ao.hw,
+       [RPMH_LN_BB_CLK3]       = &sdm845_ln_bb_clk3.hw,
+       [RPMH_LN_BB_CLK3_A]     = &sdm845_ln_bb_clk3_ao.hw,
+       [RPMH_RF_CLK1]          = &sdm845_rf_clk1.hw,
+       [RPMH_RF_CLK1_A]        = &sdm845_rf_clk1_ao.hw,
+       [RPMH_RF_CLK2]          = &sdm845_rf_clk2.hw,
+       [RPMH_RF_CLK2_A]        = &sdm845_rf_clk2_ao.hw,
+       [RPMH_IPA_CLK]          = &sdm845_ipa.hw,
+       [RPMH_CE_CLK]           = &sdm845_ce.hw,
+};
+
+static const struct clk_rpmh_desc clk_rpmh_sdm670 = {
+       .clks = sdm670_rpmh_clocks,
+       .num_clks = ARRAY_SIZE(sdm670_rpmh_clocks),
+};
+
 DEFINE_CLK_RPMH_VRM(sdx55, rf_clk1, rf_clk1_ao, "rfclkd1", 1);
 DEFINE_CLK_RPMH_VRM(sdx55, rf_clk2, rf_clk2_ao, "rfclkd2", 1);
 DEFINE_CLK_RPMH_BCM(sdx55, qpic_clk, "QP0");
@@ -715,6 +731,7 @@ static const struct of_device_id clk_rpmh_match_table[] = {
        { .compatible = "qcom,sc8180x-rpmh-clk", .data = &clk_rpmh_sc8180x},
        { .compatible = "qcom,sc8280xp-rpmh-clk", .data = &clk_rpmh_sc8280xp},
        { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845},
+       { .compatible = "qcom,sdm670-rpmh-clk", .data = &clk_rpmh_sdm670},
        { .compatible = "qcom,sdx55-rpmh-clk",  .data = &clk_rpmh_sdx55},
        { .compatible = "qcom,sdx65-rpmh-clk",  .data = &clk_rpmh_sdx65},
        { .compatible = "qcom,sm6350-rpmh-clk", .data = &clk_rpmh_sm6350},
index 10b4e6d..fea5058 100644 (file)
@@ -417,6 +417,7 @@ DEFINE_CLK_SMD_RPM_BRANCH(sdm660, bi_tcxo, bi_tcxo_a, QCOM_SMD_RPM_MISC_CLK, 0,
 DEFINE_CLK_SMD_RPM(msm8916, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
 DEFINE_CLK_SMD_RPM(msm8916, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
 DEFINE_CLK_SMD_RPM(msm8916, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
+DEFINE_CLK_SMD_RPM(qcs404, qpic_clk, qpic_a_clk, QCOM_SMD_RPM_QPIC_CLK, 0);
 DEFINE_CLK_SMD_RPM_QDSS(msm8916, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1);
 DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, bb_clk1, bb_clk1_a, 1, 19200000);
 DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, bb_clk2, bb_clk2_a, 2, 19200000);
@@ -427,6 +428,40 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, bb_clk2_pin, bb_clk2_a_pin, 2, 192
 DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, rf_clk1_pin, rf_clk1_a_pin, 4, 19200000);
 DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, rf_clk2_pin, rf_clk2_a_pin, 5, 19200000);
 
+static struct clk_smd_rpm *msm8909_clks[] = {
+       [RPM_SMD_PCNOC_CLK]             = &msm8916_pcnoc_clk,
+       [RPM_SMD_PCNOC_A_CLK]           = &msm8916_pcnoc_a_clk,
+       [RPM_SMD_SNOC_CLK]              = &msm8916_snoc_clk,
+       [RPM_SMD_SNOC_A_CLK]            = &msm8916_snoc_a_clk,
+       [RPM_SMD_BIMC_CLK]              = &msm8916_bimc_clk,
+       [RPM_SMD_BIMC_A_CLK]            = &msm8916_bimc_a_clk,
+       [RPM_SMD_QPIC_CLK]              = &qcs404_qpic_clk,
+       [RPM_SMD_QPIC_CLK_A]            = &qcs404_qpic_a_clk,
+       [RPM_SMD_QDSS_CLK]              = &msm8916_qdss_clk,
+       [RPM_SMD_QDSS_A_CLK]            = &msm8916_qdss_a_clk,
+       [RPM_SMD_BB_CLK1]               = &msm8916_bb_clk1,
+       [RPM_SMD_BB_CLK1_A]             = &msm8916_bb_clk1_a,
+       [RPM_SMD_BB_CLK2]               = &msm8916_bb_clk2,
+       [RPM_SMD_BB_CLK2_A]             = &msm8916_bb_clk2_a,
+       [RPM_SMD_RF_CLK1]               = &msm8916_rf_clk1,
+       [RPM_SMD_RF_CLK1_A]             = &msm8916_rf_clk1_a,
+       [RPM_SMD_RF_CLK2]               = &msm8916_rf_clk2,
+       [RPM_SMD_RF_CLK2_A]             = &msm8916_rf_clk2_a,
+       [RPM_SMD_BB_CLK1_PIN]           = &msm8916_bb_clk1_pin,
+       [RPM_SMD_BB_CLK1_A_PIN]         = &msm8916_bb_clk1_a_pin,
+       [RPM_SMD_BB_CLK2_PIN]           = &msm8916_bb_clk2_pin,
+       [RPM_SMD_BB_CLK2_A_PIN]         = &msm8916_bb_clk2_a_pin,
+       [RPM_SMD_RF_CLK1_PIN]           = &msm8916_rf_clk1_pin,
+       [RPM_SMD_RF_CLK1_A_PIN]         = &msm8916_rf_clk1_a_pin,
+       [RPM_SMD_RF_CLK2_PIN]           = &msm8916_rf_clk2_pin,
+       [RPM_SMD_RF_CLK2_A_PIN]         = &msm8916_rf_clk2_a_pin,
+};
+
+static const struct rpm_smd_clk_desc rpm_clk_msm8909 = {
+       .clks = msm8909_clks,
+       .num_clks = ARRAY_SIZE(msm8909_clks),
+};
+
 static struct clk_smd_rpm *msm8916_clks[] = {
        [RPM_SMD_PCNOC_CLK]             = &msm8916_pcnoc_clk,
        [RPM_SMD_PCNOC_A_CLK]           = &msm8916_pcnoc_a_clk,
@@ -787,7 +822,6 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8996 = {
 };
 
 DEFINE_CLK_SMD_RPM(qcs404, bimc_gpu_clk, bimc_gpu_a_clk, QCOM_SMD_RPM_MEM_CLK, 2);
-DEFINE_CLK_SMD_RPM(qcs404, qpic_clk, qpic_a_clk, QCOM_SMD_RPM_QPIC_CLK, 0);
 DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(qcs404, ln_bb_clk_pin, ln_bb_clk_a_pin, 8, 19200000);
 
 static struct clk_smd_rpm *qcs404_clks[] = {
@@ -1085,13 +1119,54 @@ static const struct rpm_smd_clk_desc rpm_clk_sm6115 = {
        .num_clks = ARRAY_SIZE(sm6115_clks),
 };
 
+/* SM6375 */
+DEFINE_CLK_SMD_RPM(sm6375, mmnrt_clk, mmnrt_a_clk, QCOM_SMD_RPM_MMXI_CLK, 0);
+DEFINE_CLK_SMD_RPM(sm6375, mmrt_clk, mmrt_a_clk, QCOM_SMD_RPM_MMXI_CLK, 1);
+DEFINE_CLK_SMD_RPM(qcm2290, hwkm_clk, hwkm_a_clk, QCOM_SMD_RPM_HWKM_CLK, 0);
+DEFINE_CLK_SMD_RPM(qcm2290, pka_clk, pka_a_clk, QCOM_SMD_RPM_PKA_CLK, 0);
+DEFINE_CLK_SMD_RPM_BRANCH(sm6375, bimc_freq_log, bimc_freq_log_a, QCOM_SMD_RPM_MISC_CLK, 4, 1);
+static struct clk_smd_rpm *sm6375_clks[] = {
+       [RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo,
+       [RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a,
+       [RPM_SMD_SNOC_CLK] = &sm6125_snoc_clk,
+       [RPM_SMD_SNOC_A_CLK] = &sm6125_snoc_a_clk,
+       [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk,
+       [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk,
+       [RPM_SMD_QDSS_CLK] = &sm6125_qdss_clk,
+       [RPM_SMD_QDSS_A_CLK] = &sm6125_qdss_a_clk,
+       [RPM_SMD_CNOC_CLK] = &sm6125_cnoc_clk,
+       [RPM_SMD_CNOC_A_CLK] = &sm6125_cnoc_a_clk,
+       [RPM_SMD_IPA_CLK] = &msm8976_ipa_clk,
+       [RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk,
+       [RPM_SMD_QUP_CLK] = &sm6125_qup_clk,
+       [RPM_SMD_QUP_A_CLK] = &sm6125_qup_a_clk,
+       [RPM_SMD_MMRT_CLK] = &sm6375_mmrt_clk,
+       [RPM_SMD_MMRT_A_CLK] = &sm6375_mmrt_a_clk,
+       [RPM_SMD_MMNRT_CLK] = &sm6375_mmnrt_clk,
+       [RPM_SMD_MMNRT_A_CLK] = &sm6375_mmnrt_a_clk,
+       [RPM_SMD_SNOC_PERIPH_CLK] = &sm6125_snoc_periph_clk,
+       [RPM_SMD_SNOC_PERIPH_A_CLK] = &sm6125_snoc_periph_a_clk,
+       [RPM_SMD_SNOC_LPASS_CLK] = &sm6125_snoc_lpass_clk,
+       [RPM_SMD_SNOC_LPASS_A_CLK] = &sm6125_snoc_lpass_a_clk,
+       [RPM_SMD_CE1_CLK] = &msm8992_ce1_clk,
+       [RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk,
+       [RPM_SMD_HWKM_CLK] = &qcm2290_hwkm_clk,
+       [RPM_SMD_HWKM_A_CLK] = &qcm2290_hwkm_a_clk,
+       [RPM_SMD_PKA_CLK] = &qcm2290_pka_clk,
+       [RPM_SMD_PKA_A_CLK] = &qcm2290_pka_a_clk,
+       [RPM_SMD_BIMC_FREQ_LOG] = &sm6375_bimc_freq_log,
+};
+
+static const struct rpm_smd_clk_desc rpm_clk_sm6375 = {
+       .clks = sm6375_clks,
+       .num_clks = ARRAY_SIZE(sm6375_clks),
+};
+
 /* QCM2290 */
 DEFINE_CLK_SMD_RPM_XO_BUFFER(qcm2290, ln_bb_clk2, ln_bb_clk2_a, 0x2, 19200000);
 DEFINE_CLK_SMD_RPM_XO_BUFFER(qcm2290, rf_clk3, rf_clk3_a, 6, 38400000);
 
 DEFINE_CLK_SMD_RPM(qcm2290, qpic_clk, qpic_a_clk, QCOM_SMD_RPM_QPIC_CLK, 0);
-DEFINE_CLK_SMD_RPM(qcm2290, hwkm_clk, hwkm_a_clk, QCOM_SMD_RPM_HWKM_CLK, 0);
-DEFINE_CLK_SMD_RPM(qcm2290, pka_clk, pka_a_clk, QCOM_SMD_RPM_PKA_CLK, 0);
 DEFINE_CLK_SMD_RPM(qcm2290, cpuss_gnoc_clk, cpuss_gnoc_a_clk,
                   QCOM_SMD_RPM_MEM_CLK, 1);
 DEFINE_CLK_SMD_RPM(qcm2290, bimc_gpu_clk, bimc_gpu_a_clk,
@@ -1146,6 +1221,7 @@ static const struct rpm_smd_clk_desc rpm_clk_qcm2290 = {
 static const struct of_device_id rpm_smd_clk_match_table[] = {
        { .compatible = "qcom,rpmcc-mdm9607", .data = &rpm_clk_mdm9607 },
        { .compatible = "qcom,rpmcc-msm8226", .data = &rpm_clk_msm8974 },
+       { .compatible = "qcom,rpmcc-msm8909", .data = &rpm_clk_msm8909 },
        { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 },
        { .compatible = "qcom,rpmcc-msm8936", .data = &rpm_clk_msm8936 },
        { .compatible = "qcom,rpmcc-msm8953", .data = &rpm_clk_msm8953 },
@@ -1160,6 +1236,7 @@ static const struct of_device_id rpm_smd_clk_match_table[] = {
        { .compatible = "qcom,rpmcc-sdm660",  .data = &rpm_clk_sdm660  },
        { .compatible = "qcom,rpmcc-sm6115",  .data = &rpm_clk_sm6115  },
        { .compatible = "qcom,rpmcc-sm6125",  .data = &rpm_clk_sm6125  },
+       { .compatible = "qcom,rpmcc-sm6375",  .data = &rpm_clk_sm6375  },
        { }
 };
 MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table);
diff --git a/drivers/clk/qcom/dispcc-sm6115.c b/drivers/clk/qcom/dispcc-sm6115.c
new file mode 100644 (file)
index 0000000..818bb8f
--- /dev/null
@@ -0,0 +1,608 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Based on dispcc-qcm2290.c
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021, Linaro Ltd.
+ */
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,sm6115-dispcc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "common.h"
+#include "gdsc.h"
+
+enum {
+       DT_BI_TCXO,
+       DT_SLEEP_CLK,
+       DT_DSI0_PHY_PLL_OUT_BYTECLK,
+       DT_DSI0_PHY_PLL_OUT_DSICLK,
+       DT_GPLL0_DISP_DIV,
+};
+
+enum {
+       P_BI_TCXO,
+       P_DISP_CC_PLL0_OUT_MAIN,
+       P_DSI0_PHY_PLL_OUT_BYTECLK,
+       P_DSI0_PHY_PLL_OUT_DSICLK,
+       P_GPLL0_OUT_MAIN,
+       P_SLEEP_CLK,
+};
+
+static const struct clk_parent_data parent_data_tcxo = { .index = DT_BI_TCXO };
+
+static const struct pll_vco spark_vco[] = {
+       { 500000000, 1000000000, 2 },
+};
+
+/* 768MHz configuration */
+static const struct alpha_pll_config disp_cc_pll0_config = {
+       .l = 0x28,
+       .alpha = 0x0,
+       .alpha_en_mask = BIT(24),
+       .vco_val = 0x2 << 20,
+       .vco_mask = GENMASK(21, 20),
+       .main_output_mask = BIT(0),
+       .config_ctl_val = 0x4001055B,
+};
+
+static struct clk_alpha_pll disp_cc_pll0 = {
+       .offset = 0x0,
+       .vco_table = spark_vco,
+       .num_vco = ARRAY_SIZE(spark_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_pll0",
+                       .parent_data = &parent_data_tcxo,
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_disp_cc_pll0_out_main[] = {
+       { 0x0, 1 },
+       { }
+};
+static struct clk_alpha_pll_postdiv disp_cc_pll0_out_main = {
+       .offset = 0x0,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_disp_cc_pll0_out_main,
+       .num_post_div = ARRAY_SIZE(post_div_table_disp_cc_pll0_out_main),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_pll0_out_main",
+               .parent_hws = (const struct clk_hw*[]){
+                       &disp_cc_pll0.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_alpha_pll_postdiv_ops,
+       },
+};
+
+static const struct parent_map disp_cc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+       { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_0[] = {
+       { .index = DT_BI_TCXO },
+       { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
+};
+
+static const struct parent_map disp_cc_parent_map_1[] = {
+       { P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_1[] = {
+       { .index = DT_BI_TCXO },
+};
+
+static const struct parent_map disp_cc_parent_map_2[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 4 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_2[] = {
+       { .index = DT_BI_TCXO },
+       { .index = DT_GPLL0_DISP_DIV },
+};
+
+static const struct parent_map disp_cc_parent_map_3[] = {
+       { P_BI_TCXO, 0 },
+       { P_DISP_CC_PLL0_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_3[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &disp_cc_pll0_out_main.clkr.hw },
+};
+
+static const struct parent_map disp_cc_parent_map_4[] = {
+       { P_BI_TCXO, 0 },
+       { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_4[] = {
+       { .index = DT_BI_TCXO },
+       { .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
+};
+
+static const struct parent_map disp_cc_parent_map_5[] = {
+       { P_SLEEP_CLK, 0 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_5[] = {
+       { .index = DT_SLEEP_CLK, },
+};
+
+static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
+       .cmd_rcgr = 0x20bc,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_0,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_byte0_clk_src",
+               .parent_data = disp_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+               /* For set_rate and set_parent to succeed, parent(s) must be enabled */
+               .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE | CLK_GET_RATE_NOCACHE,
+               .ops = &clk_byte2_ops,
+       },
+};
+
+static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
+       .reg = 0x20d4,
+       .shift = 0,
+       .width = 2,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_byte0_div_clk_src",
+               .parent_hws = (const struct clk_hw*[]){
+                       &disp_cc_mdss_byte0_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_regmap_div_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(37500000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(75000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
+       .cmd_rcgr = 0x2154,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_2,
+       .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_ahb_clk_src",
+               .parent_data = disp_cc_parent_data_2,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
+       .cmd_rcgr = 0x20d8,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_0,
+       .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_esc0_clk_src",
+               .parent_data = disp_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),
+       F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+       F(307200000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
+       F(384000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
+       .cmd_rcgr = 0x2074,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_3,
+       .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_mdp_clk_src",
+               .parent_data = disp_cc_parent_data_3,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
+       .cmd_rcgr = 0x205c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_4,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_pclk0_clk_src",
+               .parent_data = disp_cc_parent_data_4,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
+               /* For set_rate and set_parent to succeed, parent(s) must be enabled */
+               .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE | CLK_GET_RATE_NOCACHE,
+               .ops = &clk_pixel_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),
+       F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+       F(307200000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
+       .cmd_rcgr = 0x208c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_3,
+       .freq_tbl = ftbl_disp_cc_mdss_rot_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_rot_clk_src",
+               .parent_data = disp_cc_parent_data_3,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
+       .cmd_rcgr = 0x20a4,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_vsync_clk_src",
+               .parent_data = disp_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = {
+       F(32764, P_SLEEP_CLK, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_sleep_clk_src = {
+       .cmd_rcgr = 0x6050,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_5,
+       .freq_tbl = ftbl_disp_cc_sleep_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_sleep_clk_src",
+               .parent_data = disp_cc_parent_data_5,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch disp_cc_mdss_ahb_clk = {
+       .halt_reg = 0x2044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_byte0_clk = {
+       .halt_reg = 0x2024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_byte0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_byte0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
+       .halt_reg = 0x2028,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_byte0_intf_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_byte0_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_esc0_clk = {
+       .halt_reg = 0x202c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x202c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_esc0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_esc0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_mdp_clk = {
+       .halt_reg = 0x2008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_mdp_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_mdp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
+       .halt_reg = 0x2018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x2018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_mdp_lut_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_mdp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
+       .halt_reg = 0x4004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_non_gdsc_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_pclk0_clk = {
+       .halt_reg = 0x2004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_pclk0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_pclk0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_rot_clk = {
+       .halt_reg = 0x2010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_rot_clk",
+                       .parent_names = (const char *[]){
+                               "disp_cc_mdss_rot_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_vsync_clk = {
+       .halt_reg = 0x2020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_vsync_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_vsync_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_sleep_clk = {
+       .halt_reg = 0x6068,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6068,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_sleep_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_sleep_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc mdss_gdsc = {
+       .gdscr = 0x3000,
+       .pd = {
+               .name = "mdss_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = HW_CTRL,
+};
+
+static struct gdsc *disp_cc_sm6115_gdscs[] = {
+       [MDSS_GDSC] = &mdss_gdsc,
+};
+
+static struct clk_regmap *disp_cc_sm6115_clocks[] = {
+       [DISP_CC_PLL0] = &disp_cc_pll0.clkr,
+       [DISP_CC_PLL0_OUT_MAIN] = &disp_cc_pll0_out_main.clkr,
+       [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
+       [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
+       [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
+       [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
+       [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
+       [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
+       [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
+       [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
+       [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
+       [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
+       [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
+       [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
+       [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
+       [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
+       [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
+       [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
+       [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
+       [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
+       [DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr,
+       [DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr,
+};
+
+static const struct regmap_config disp_cc_sm6115_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = 0x10000,
+       .fast_io = true,
+};
+
+static const struct qcom_cc_desc disp_cc_sm6115_desc = {
+       .config = &disp_cc_sm6115_regmap_config,
+       .clks = disp_cc_sm6115_clocks,
+       .num_clks = ARRAY_SIZE(disp_cc_sm6115_clocks),
+       .gdscs = disp_cc_sm6115_gdscs,
+       .num_gdscs = ARRAY_SIZE(disp_cc_sm6115_gdscs),
+};
+
+static const struct of_device_id disp_cc_sm6115_match_table[] = {
+       { .compatible = "qcom,sm6115-dispcc" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, disp_cc_sm6115_match_table);
+
+static int disp_cc_sm6115_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+       int ret;
+
+       regmap = qcom_cc_map(pdev, &disp_cc_sm6115_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       clk_alpha_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
+
+       /* Keep DISP_CC_XO_CLK always-ON */
+       regmap_update_bits(regmap, 0x604c, BIT(0), BIT(0));
+
+       ret = qcom_cc_really_probe(pdev, &disp_cc_sm6115_desc, regmap);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to register DISP CC clocks\n");
+               return ret;
+       }
+
+       return ret;
+}
+
+static struct platform_driver disp_cc_sm6115_driver = {
+       .probe = disp_cc_sm6115_probe,
+       .driver = {
+               .name = "dispcc-sm6115",
+               .of_match_table = disp_cc_sm6115_match_table,
+       },
+};
+
+module_platform_driver(disp_cc_sm6115_driver);
+MODULE_DESCRIPTION("Qualcomm SM6115 Display Clock controller");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/qcom/dispcc-sm8450.c b/drivers/clk/qcom/dispcc-sm8450.c
new file mode 100644 (file)
index 0000000..0cd7ebe
--- /dev/null
@@ -0,0 +1,1829 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022, Linaro Ltd.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/pm_runtime.h>
+
+#include <dt-bindings/clock/qcom,sm8450-dispcc.h>
+
+#include "common.h"
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "reset.h"
+#include "gdsc.h"
+
+/* Need to match the order of clocks in DT binding */
+enum {
+       DT_BI_TCXO,
+       DT_BI_TCXO_AO,
+       DT_AHB_CLK,
+       DT_SLEEP_CLK,
+
+       DT_DSI0_PHY_PLL_OUT_BYTECLK,
+       DT_DSI0_PHY_PLL_OUT_DSICLK,
+       DT_DSI1_PHY_PLL_OUT_BYTECLK,
+       DT_DSI1_PHY_PLL_OUT_DSICLK,
+
+       DT_DP0_PHY_PLL_LINK_CLK,
+       DT_DP0_PHY_PLL_VCO_DIV_CLK,
+       DT_DP1_PHY_PLL_LINK_CLK,
+       DT_DP1_PHY_PLL_VCO_DIV_CLK,
+       DT_DP2_PHY_PLL_LINK_CLK,
+       DT_DP2_PHY_PLL_VCO_DIV_CLK,
+       DT_DP3_PHY_PLL_LINK_CLK,
+       DT_DP3_PHY_PLL_VCO_DIV_CLK,
+};
+
+#define DISP_CC_MISC_CMD       0xF000
+
+enum {
+       P_BI_TCXO,
+       P_DISP_CC_PLL0_OUT_MAIN,
+       P_DISP_CC_PLL1_OUT_EVEN,
+       P_DISP_CC_PLL1_OUT_MAIN,
+       P_DP0_PHY_PLL_LINK_CLK,
+       P_DP0_PHY_PLL_VCO_DIV_CLK,
+       P_DP1_PHY_PLL_LINK_CLK,
+       P_DP1_PHY_PLL_VCO_DIV_CLK,
+       P_DP2_PHY_PLL_LINK_CLK,
+       P_DP2_PHY_PLL_VCO_DIV_CLK,
+       P_DP3_PHY_PLL_LINK_CLK,
+       P_DP3_PHY_PLL_VCO_DIV_CLK,
+       P_DSI0_PHY_PLL_OUT_BYTECLK,
+       P_DSI0_PHY_PLL_OUT_DSICLK,
+       P_DSI1_PHY_PLL_OUT_BYTECLK,
+       P_DSI1_PHY_PLL_OUT_DSICLK,
+       P_SLEEP_CLK,
+};
+
+static struct pll_vco lucid_evo_vco[] = {
+       { 249600000, 2000000000, 0 },
+};
+
+static const struct alpha_pll_config disp_cc_pll0_config = {
+       .l = 0xD,
+       .alpha = 0x6492,
+       .config_ctl_val = 0x20485699,
+       .config_ctl_hi_val = 0x00182261,
+       .config_ctl_hi1_val = 0x32AA299C,
+       .user_ctl_val = 0x00000000,
+       .user_ctl_hi_val = 0x00000805,
+};
+
+static struct clk_alpha_pll disp_cc_pll0 = {
+       .offset = 0x0,
+       .vco_table = lucid_evo_vco,
+       .num_vco = ARRAY_SIZE(lucid_evo_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+       .clkr = {
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_pll0",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .index = DT_BI_TCXO,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_reset_lucid_evo_ops,
+               },
+       },
+};
+
+static const struct alpha_pll_config disp_cc_pll1_config = {
+       .l = 0x1F,
+       .alpha = 0x4000,
+       .config_ctl_val = 0x20485699,
+       .config_ctl_hi_val = 0x00182261,
+       .config_ctl_hi1_val = 0x32AA299C,
+       .user_ctl_val = 0x00000000,
+       .user_ctl_hi_val = 0x00000805,
+};
+
+static struct clk_alpha_pll disp_cc_pll1 = {
+       .offset = 0x1000,
+       .vco_table = lucid_evo_vco,
+       .num_vco = ARRAY_SIZE(lucid_evo_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+       .clkr = {
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_pll1",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .index = DT_BI_TCXO,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_reset_lucid_evo_ops,
+               },
+       },
+};
+
+static const struct parent_map disp_cc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+       { P_DP0_PHY_PLL_LINK_CLK, 1 },
+       { P_DP0_PHY_PLL_VCO_DIV_CLK, 2 },
+       { P_DP3_PHY_PLL_VCO_DIV_CLK, 3 },
+       { P_DP1_PHY_PLL_VCO_DIV_CLK, 4 },
+       { P_DP2_PHY_PLL_VCO_DIV_CLK, 6 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_0[] = {
+       { .index = DT_BI_TCXO },
+       { .index = DT_DP0_PHY_PLL_LINK_CLK },
+       { .index = DT_DP0_PHY_PLL_VCO_DIV_CLK },
+       { .index = DT_DP3_PHY_PLL_VCO_DIV_CLK },
+       { .index = DT_DP1_PHY_PLL_VCO_DIV_CLK },
+       { .index = DT_DP2_PHY_PLL_VCO_DIV_CLK },
+};
+
+static const struct parent_map disp_cc_parent_map_1[] = {
+       { P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_1[] = {
+       { .index = DT_BI_TCXO },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_1_ao[] = {
+       { .index = DT_BI_TCXO_AO },
+};
+
+static const struct parent_map disp_cc_parent_map_2[] = {
+       { P_BI_TCXO, 0 },
+       { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+       { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
+       { P_DSI1_PHY_PLL_OUT_DSICLK, 3 },
+       { P_DSI1_PHY_PLL_OUT_BYTECLK, 4 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_2[] = {
+       { .index = DT_BI_TCXO },
+       { .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
+       { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
+       { .index = DT_DSI1_PHY_PLL_OUT_DSICLK },
+       { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK },
+};
+
+static const struct parent_map disp_cc_parent_map_3[] = {
+       { P_BI_TCXO, 0 },
+       { P_DP0_PHY_PLL_LINK_CLK, 1 },
+       { P_DP1_PHY_PLL_LINK_CLK, 2 },
+       { P_DP2_PHY_PLL_LINK_CLK, 3 },
+       { P_DP3_PHY_PLL_LINK_CLK, 4 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_3[] = {
+       { .index = DT_BI_TCXO },
+       { .index = DT_DP0_PHY_PLL_LINK_CLK },
+       { .index = DT_DP1_PHY_PLL_LINK_CLK },
+       { .index = DT_DP2_PHY_PLL_LINK_CLK },
+       { .index = DT_DP3_PHY_PLL_LINK_CLK },
+};
+
+static const struct parent_map disp_cc_parent_map_4[] = {
+       { P_BI_TCXO, 0 },
+       { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
+       { P_DSI1_PHY_PLL_OUT_BYTECLK, 4 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_4[] = {
+       { .index = DT_BI_TCXO },
+       { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
+       { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK },
+};
+
+static const struct parent_map disp_cc_parent_map_5[] = {
+       { P_BI_TCXO, 0 },
+       { P_DISP_CC_PLL0_OUT_MAIN, 1 },
+       { P_DISP_CC_PLL1_OUT_MAIN, 4 },
+       { P_DISP_CC_PLL1_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_5[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &disp_cc_pll0.clkr.hw },
+       { .hw = &disp_cc_pll1.clkr.hw },
+       { .hw = &disp_cc_pll1.clkr.hw },
+};
+
+static const struct parent_map disp_cc_parent_map_6[] = {
+       { P_BI_TCXO, 0 },
+       { P_DISP_CC_PLL1_OUT_MAIN, 4 },
+       { P_DISP_CC_PLL1_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_6[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &disp_cc_pll1.clkr.hw },
+       { .hw = &disp_cc_pll1.clkr.hw },
+};
+
+static const struct parent_map disp_cc_parent_map_7[] = {
+       { P_SLEEP_CLK, 0 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_7[] = {
+       { .index = DT_SLEEP_CLK },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(37500000, P_DISP_CC_PLL1_OUT_MAIN, 16, 0, 0),
+       F(75000000, P_DISP_CC_PLL1_OUT_MAIN, 8, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
+       .cmd_rcgr = 0x8324,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_6,
+       .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_ahb_clk_src",
+               .parent_data = disp_cc_parent_data_6,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_6),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_byte0_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
+       .cmd_rcgr = 0x8134,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_2,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_byte0_clk_src",
+               .parent_data = disp_cc_parent_data_2,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_byte2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = {
+       .cmd_rcgr = 0x8150,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_2,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_byte1_clk_src",
+               .parent_data = disp_cc_parent_data_2,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_byte2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx0_aux_clk_src = {
+       .cmd_rcgr = 0x81ec,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx0_aux_clk_src",
+               .parent_data = disp_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_dptx0_link_clk_src[] = {
+       F(162000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
+       F(270000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
+       F(540000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
+       F(810000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = {
+       .cmd_rcgr = 0x819c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_3,
+       .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx0_link_clk_src",
+               .parent_data = disp_cc_parent_data_3,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx0_pixel0_clk_src = {
+       .cmd_rcgr = 0x81bc,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_0,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx0_pixel0_clk_src",
+               .parent_data = disp_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_dp_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx0_pixel1_clk_src = {
+       .cmd_rcgr = 0x81d4,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_0,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx0_pixel1_clk_src",
+               .parent_data = disp_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_dp_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx1_aux_clk_src = {
+       .cmd_rcgr = 0x8254,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx1_aux_clk_src",
+               .parent_data = disp_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_dp_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx1_link_clk_src = {
+       .cmd_rcgr = 0x8234,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_3,
+       .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx1_link_clk_src",
+               .parent_data = disp_cc_parent_data_3,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx1_pixel0_clk_src = {
+       .cmd_rcgr = 0x8204,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_0,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx1_pixel0_clk_src",
+               .parent_data = disp_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_dp_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx1_pixel1_clk_src = {
+       .cmd_rcgr = 0x821c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_0,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx1_pixel1_clk_src",
+               .parent_data = disp_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_dp_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx2_aux_clk_src = {
+       .cmd_rcgr = 0x82bc,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx2_aux_clk_src",
+               .parent_data = disp_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx2_link_clk_src = {
+       .cmd_rcgr = 0x826c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_3,
+       .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx2_link_clk_src",
+               .parent_data = disp_cc_parent_data_3,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx2_pixel0_clk_src = {
+       .cmd_rcgr = 0x828c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_0,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx2_pixel0_clk_src",
+               .parent_data = disp_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_dp_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx2_pixel1_clk_src = {
+       .cmd_rcgr = 0x82a4,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_0,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx2_pixel1_clk_src",
+               .parent_data = disp_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_dp_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx3_aux_clk_src = {
+       .cmd_rcgr = 0x8308,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx3_aux_clk_src",
+               .parent_data = disp_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx3_link_clk_src = {
+       .cmd_rcgr = 0x82ec,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_3,
+       .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx3_link_clk_src",
+               .parent_data = disp_cc_parent_data_3,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx3_pixel0_clk_src = {
+       .cmd_rcgr = 0x82d4,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_0,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx3_pixel0_clk_src",
+               .parent_data = disp_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_dp_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
+       .cmd_rcgr = 0x816c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_4,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_esc0_clk_src",
+               .parent_data = disp_cc_parent_data_4,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = {
+       .cmd_rcgr = 0x8184,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_4,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_esc1_clk_src",
+               .parent_data = disp_cc_parent_data_4,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(85714286, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+       F(100000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+       F(150000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+       F(172000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+       F(200000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+       F(325000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+       F(375000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+       F(500000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
+       .cmd_rcgr = 0x80ec,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_5,
+       .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_mdp_clk_src",
+               .parent_data = disp_cc_parent_data_5,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
+       .cmd_rcgr = 0x80bc,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_2,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_pclk0_clk_src",
+               .parent_data = disp_cc_parent_data_2,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_pixel_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = {
+       .cmd_rcgr = 0x80d4,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_2,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_pclk1_clk_src",
+               .parent_data = disp_cc_parent_data_2,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_pixel_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(150000000, P_DISP_CC_PLL1_OUT_MAIN, 4, 0, 0),
+       F(200000000, P_DISP_CC_PLL1_OUT_MAIN, 3, 0, 0),
+       F(300000000, P_DISP_CC_PLL1_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
+       .cmd_rcgr = 0x8104,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_5,
+       .freq_tbl = ftbl_disp_cc_mdss_rot_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_rot_clk_src",
+               .parent_data = disp_cc_parent_data_5,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
+       .cmd_rcgr = 0x811c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_vsync_clk_src",
+               .parent_data = disp_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = {
+       F(32000, P_SLEEP_CLK, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_sleep_clk_src = {
+       .cmd_rcgr = 0xe060,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_7,
+       .freq_tbl = ftbl_disp_cc_sleep_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_sleep_clk_src",
+               .parent_data = disp_cc_parent_data_7,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_7),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_xo_clk_src = {
+       .cmd_rcgr = 0xe044,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_xo_clk_src",
+               .parent_data = disp_cc_parent_data_1_ao,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_1_ao),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
+       .reg = 0x814c,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_byte0_div_clk_src",
+               .parent_data = &(const struct clk_parent_data) {
+                       .hw = &disp_cc_mdss_byte0_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_regmap_div_ops,
+       },
+};
+
+static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = {
+       .reg = 0x8168,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_byte1_div_clk_src",
+               .parent_data = &(const struct clk_parent_data) {
+                       .hw = &disp_cc_mdss_byte1_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_regmap_div_ops,
+       },
+};
+
+static struct clk_regmap_div disp_cc_mdss_dptx0_link_div_clk_src = {
+       .reg = 0x81b4,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx0_link_div_clk_src",
+               .parent_data = &(const struct clk_parent_data) {
+                       .hw = &disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_regmap_div disp_cc_mdss_dptx1_link_div_clk_src = {
+       .reg = 0x824c,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx1_link_div_clk_src",
+               .parent_data = &(const struct clk_parent_data) {
+                       .hw = &disp_cc_mdss_dptx1_link_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_regmap_div disp_cc_mdss_dptx2_link_div_clk_src = {
+       .reg = 0x8284,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx2_link_div_clk_src",
+               .parent_data = &(const struct clk_parent_data) {
+                       .hw = &disp_cc_mdss_dptx2_link_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_regmap_div disp_cc_mdss_dptx3_link_div_clk_src = {
+       .reg = 0x8304,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dptx3_link_div_clk_src",
+               .parent_data = &(const struct clk_parent_data) {
+                       .hw = &disp_cc_mdss_dptx3_link_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_branch disp_cc_mdss_ahb1_clk = {
+       .halt_reg = 0xa020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xa020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_ahb1_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_ahb_clk = {
+       .halt_reg = 0x80a4,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x80a4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_ahb_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_byte0_clk = {
+       .halt_reg = 0x8028,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_byte0_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_byte0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
+       .halt_reg = 0x802c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x802c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_byte0_intf_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_byte0_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_byte1_clk = {
+       .halt_reg = 0x8030,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_byte1_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_byte1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_byte1_intf_clk = {
+       .halt_reg = 0x8034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_byte1_intf_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_byte1_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx0_aux_clk = {
+       .halt_reg = 0x8058,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx0_aux_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx0_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx0_crypto_clk = {
+       .halt_reg = 0x804c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x804c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx0_crypto_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx0_link_clk = {
+       .halt_reg = 0x8040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx0_link_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx0_link_intf_clk = {
+       .halt_reg = 0x8048,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx0_link_intf_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx0_pixel0_clk = {
+       .halt_reg = 0x8050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx0_pixel0_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx0_pixel0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx0_pixel1_clk = {
+       .halt_reg = 0x8054,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx0_pixel1_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx0_pixel1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx0_usb_router_link_intf_clk = {
+       .halt_reg = 0x8044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx0_usb_router_link_intf_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx1_aux_clk = {
+       .halt_reg = 0x8074,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8074,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx1_aux_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx1_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx1_crypto_clk = {
+       .halt_reg = 0x8070,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8070,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx1_crypto_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx1_link_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx1_link_clk = {
+       .halt_reg = 0x8064,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8064,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx1_link_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx1_link_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx1_link_intf_clk = {
+       .halt_reg = 0x806c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x806c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx1_link_intf_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx1_pixel0_clk = {
+       .halt_reg = 0x805c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x805c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx1_pixel0_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx1_pixel0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx1_pixel1_clk = {
+       .halt_reg = 0x8060,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8060,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx1_pixel1_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx1_pixel1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx1_usb_router_link_intf_clk = {
+       .halt_reg = 0x8068,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8068,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx1_usb_router_link_intf_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx2_aux_clk = {
+       .halt_reg = 0x808c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x808c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx2_aux_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx2_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx2_crypto_clk = {
+       .halt_reg = 0x8088,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8088,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx2_crypto_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx2_link_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx2_link_clk = {
+       .halt_reg = 0x8080,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx2_link_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx2_link_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx2_link_intf_clk = {
+       .halt_reg = 0x8084,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8084,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx2_link_intf_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx2_link_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx2_pixel0_clk = {
+       .halt_reg = 0x8078,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8078,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx2_pixel0_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx2_pixel0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx2_pixel1_clk = {
+       .halt_reg = 0x807c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x807c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx2_pixel1_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx2_pixel1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx3_aux_clk = {
+       .halt_reg = 0x809c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x809c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx3_aux_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx3_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx3_crypto_clk = {
+       .halt_reg = 0x80a0,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x80a0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx3_crypto_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx3_link_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx3_link_clk = {
+       .halt_reg = 0x8094,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8094,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx3_link_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx3_link_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx3_link_intf_clk = {
+       .halt_reg = 0x8098,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8098,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx3_link_intf_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx3_link_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dptx3_pixel0_clk = {
+       .halt_reg = 0x8090,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8090,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_dptx3_pixel0_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_dptx3_pixel0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_esc0_clk = {
+       .halt_reg = 0x8038,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_esc0_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_esc0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_esc1_clk = {
+       .halt_reg = 0x803c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x803c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_esc1_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_esc1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_mdp1_clk = {
+       .halt_reg = 0xa004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xa004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_mdp1_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_mdp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_mdp_clk = {
+       .halt_reg = 0x800c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x800c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_mdp_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_mdp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_mdp_lut1_clk = {
+       .halt_reg = 0xa014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xa014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_mdp_lut1_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_mdp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
+       .halt_reg = 0x801c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x801c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_mdp_lut_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_mdp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
+       .halt_reg = 0xc004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0xc004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_non_gdsc_ahb_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_pclk0_clk = {
+       .halt_reg = 0x8004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_pclk0_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_pclk0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_pclk1_clk = {
+       .halt_reg = 0x8008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_pclk1_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_pclk1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_rot1_clk = {
+       .halt_reg = 0xa00c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xa00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_rot1_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_rot_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_rot_clk = {
+       .halt_reg = 0x8014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_rot_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_rot_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
+       .halt_reg = 0xc00c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xc00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_rscc_ahb_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
+       .halt_reg = 0xc008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xc008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_rscc_vsync_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_vsync_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_vsync1_clk = {
+       .halt_reg = 0xa01c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xa01c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_vsync1_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_vsync_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_vsync_clk = {
+       .halt_reg = 0x8024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_mdss_vsync_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_mdss_vsync_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_sleep_clk = {
+       .halt_reg = 0xe078,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xe078,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "disp_cc_sleep_clk",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .hw = &disp_cc_sleep_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc mdss_gdsc = {
+       .gdscr = 0x9000,
+       .pd = {
+               .name = "mdss_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = HW_CTRL | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc mdss_int2_gdsc = {
+       .gdscr = 0xb000,
+       .pd = {
+               .name = "mdss_int2_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = HW_CTRL | RETAIN_FF_ENABLE,
+};
+
+static struct clk_regmap *disp_cc_sm8450_clocks[] = {
+       [DISP_CC_MDSS_AHB1_CLK] = &disp_cc_mdss_ahb1_clk.clkr,
+       [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
+       [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
+       [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
+       [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
+       [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
+       [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
+       [DISP_CC_MDSS_BYTE1_CLK] = &disp_cc_mdss_byte1_clk.clkr,
+       [DISP_CC_MDSS_BYTE1_CLK_SRC] = &disp_cc_mdss_byte1_clk_src.clkr,
+       [DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = &disp_cc_mdss_byte1_div_clk_src.clkr,
+       [DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr,
+       [DISP_CC_MDSS_DPTX0_AUX_CLK] = &disp_cc_mdss_dptx0_aux_clk.clkr,
+       [DISP_CC_MDSS_DPTX0_AUX_CLK_SRC] = &disp_cc_mdss_dptx0_aux_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX0_CRYPTO_CLK] = &disp_cc_mdss_dptx0_crypto_clk.clkr,
+       [DISP_CC_MDSS_DPTX0_LINK_CLK] = &disp_cc_mdss_dptx0_link_clk.clkr,
+       [DISP_CC_MDSS_DPTX0_LINK_CLK_SRC] = &disp_cc_mdss_dptx0_link_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx0_link_div_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX0_LINK_INTF_CLK] = &disp_cc_mdss_dptx0_link_intf_clk.clkr,
+       [DISP_CC_MDSS_DPTX0_PIXEL0_CLK] = &disp_cc_mdss_dptx0_pixel0_clk.clkr,
+       [DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx0_pixel0_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX0_PIXEL1_CLK] = &disp_cc_mdss_dptx0_pixel1_clk.clkr,
+       [DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx0_pixel1_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK] =
+               &disp_cc_mdss_dptx0_usb_router_link_intf_clk.clkr,
+       [DISP_CC_MDSS_DPTX1_AUX_CLK] = &disp_cc_mdss_dptx1_aux_clk.clkr,
+       [DISP_CC_MDSS_DPTX1_AUX_CLK_SRC] = &disp_cc_mdss_dptx1_aux_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX1_CRYPTO_CLK] = &disp_cc_mdss_dptx1_crypto_clk.clkr,
+       [DISP_CC_MDSS_DPTX1_LINK_CLK] = &disp_cc_mdss_dptx1_link_clk.clkr,
+       [DISP_CC_MDSS_DPTX1_LINK_CLK_SRC] = &disp_cc_mdss_dptx1_link_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx1_link_div_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX1_LINK_INTF_CLK] = &disp_cc_mdss_dptx1_link_intf_clk.clkr,
+       [DISP_CC_MDSS_DPTX1_PIXEL0_CLK] = &disp_cc_mdss_dptx1_pixel0_clk.clkr,
+       [DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx1_pixel0_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX1_PIXEL1_CLK] = &disp_cc_mdss_dptx1_pixel1_clk.clkr,
+       [DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx1_pixel1_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK] =
+               &disp_cc_mdss_dptx1_usb_router_link_intf_clk.clkr,
+       [DISP_CC_MDSS_DPTX2_AUX_CLK] = &disp_cc_mdss_dptx2_aux_clk.clkr,
+       [DISP_CC_MDSS_DPTX2_AUX_CLK_SRC] = &disp_cc_mdss_dptx2_aux_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX2_CRYPTO_CLK] = &disp_cc_mdss_dptx2_crypto_clk.clkr,
+       [DISP_CC_MDSS_DPTX2_LINK_CLK] = &disp_cc_mdss_dptx2_link_clk.clkr,
+       [DISP_CC_MDSS_DPTX2_LINK_CLK_SRC] = &disp_cc_mdss_dptx2_link_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX2_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx2_link_div_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX2_LINK_INTF_CLK] = &disp_cc_mdss_dptx2_link_intf_clk.clkr,
+       [DISP_CC_MDSS_DPTX2_PIXEL0_CLK] = &disp_cc_mdss_dptx2_pixel0_clk.clkr,
+       [DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx2_pixel0_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX2_PIXEL1_CLK] = &disp_cc_mdss_dptx2_pixel1_clk.clkr,
+       [DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx2_pixel1_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX3_AUX_CLK] = &disp_cc_mdss_dptx3_aux_clk.clkr,
+       [DISP_CC_MDSS_DPTX3_AUX_CLK_SRC] = &disp_cc_mdss_dptx3_aux_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX3_CRYPTO_CLK] = &disp_cc_mdss_dptx3_crypto_clk.clkr,
+       [DISP_CC_MDSS_DPTX3_LINK_CLK] = &disp_cc_mdss_dptx3_link_clk.clkr,
+       [DISP_CC_MDSS_DPTX3_LINK_CLK_SRC] = &disp_cc_mdss_dptx3_link_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX3_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx3_link_div_clk_src.clkr,
+       [DISP_CC_MDSS_DPTX3_LINK_INTF_CLK] = &disp_cc_mdss_dptx3_link_intf_clk.clkr,
+       [DISP_CC_MDSS_DPTX3_PIXEL0_CLK] = &disp_cc_mdss_dptx3_pixel0_clk.clkr,
+       [DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx3_pixel0_clk_src.clkr,
+       [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
+       [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
+       [DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr,
+       [DISP_CC_MDSS_ESC1_CLK_SRC] = &disp_cc_mdss_esc1_clk_src.clkr,
+       [DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr,
+       [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
+       [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
+       [DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr,
+       [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
+       [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
+       [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
+       [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
+       [DISP_CC_MDSS_PCLK1_CLK] = &disp_cc_mdss_pclk1_clk.clkr,
+       [DISP_CC_MDSS_PCLK1_CLK_SRC] = &disp_cc_mdss_pclk1_clk_src.clkr,
+       [DISP_CC_MDSS_ROT1_CLK] = &disp_cc_mdss_rot1_clk.clkr,
+       [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
+       [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
+       [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
+       [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
+       [DISP_CC_MDSS_VSYNC1_CLK] = &disp_cc_mdss_vsync1_clk.clkr,
+       [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
+       [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
+       [DISP_CC_PLL0] = &disp_cc_pll0.clkr,
+       [DISP_CC_PLL1] = &disp_cc_pll1.clkr,
+       [DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr,
+       [DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr,
+       [DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr,
+};
+
+static const struct qcom_reset_map disp_cc_sm8450_resets[] = {
+       [DISP_CC_MDSS_CORE_BCR] = { 0x8000 },
+       [DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 },
+       [DISP_CC_MDSS_RSCC_BCR] = { 0xc000 },
+};
+
+static struct gdsc *disp_cc_sm8450_gdscs[] = {
+       [MDSS_GDSC] = &mdss_gdsc,
+       [MDSS_INT2_GDSC] = &mdss_int2_gdsc,
+};
+
+static const struct regmap_config disp_cc_sm8450_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = 0x11008,
+       .fast_io = true,
+};
+
+static struct qcom_cc_desc disp_cc_sm8450_desc = {
+       .config = &disp_cc_sm8450_regmap_config,
+       .clks = disp_cc_sm8450_clocks,
+       .num_clks = ARRAY_SIZE(disp_cc_sm8450_clocks),
+       .resets = disp_cc_sm8450_resets,
+       .num_resets = ARRAY_SIZE(disp_cc_sm8450_resets),
+       .gdscs = disp_cc_sm8450_gdscs,
+       .num_gdscs = ARRAY_SIZE(disp_cc_sm8450_gdscs),
+};
+
+static const struct of_device_id disp_cc_sm8450_match_table[] = {
+       { .compatible = "qcom,sm8450-dispcc" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, disp_cc_sm8450_match_table);
+
+static void disp_cc_sm8450_pm_runtime_disable(void *data)
+{
+       pm_runtime_disable(data);
+}
+
+static int disp_cc_sm8450_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+       int ret;
+
+       pm_runtime_enable(&pdev->dev);
+
+       ret = devm_add_action_or_reset(&pdev->dev, disp_cc_sm8450_pm_runtime_disable, &pdev->dev);
+       if (ret)
+               return ret;
+
+       ret = pm_runtime_resume_and_get(&pdev->dev);
+       if (ret)
+               return ret;
+
+       regmap = qcom_cc_map(pdev, &disp_cc_sm8450_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       clk_lucid_evo_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
+       clk_lucid_evo_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll1_config);
+
+       /* Enable clock gating for MDP clocks */
+       regmap_update_bits(regmap, DISP_CC_MISC_CMD, 0x10, 0x10);
+
+       /*
+        * Keep clocks always enabled:
+        *      disp_cc_xo_clk
+        */
+       regmap_update_bits(regmap, 0xe05c, BIT(0), BIT(0));
+
+       ret = qcom_cc_really_probe(pdev, &disp_cc_sm8450_desc, regmap);
+
+       pm_runtime_put(&pdev->dev);
+
+       return ret;
+}
+
+static struct platform_driver disp_cc_sm8450_driver = {
+       .probe = disp_cc_sm8450_probe,
+       .driver = {
+               .name = "disp_cc-sm8450",
+               .of_match_table = disp_cc_sm8450_match_table,
+       },
+};
+
+static int __init disp_cc_sm8450_init(void)
+{
+       return platform_driver_register(&disp_cc_sm8450_driver);
+}
+subsys_initcall(disp_cc_sm8450_init);
+
+static void __exit disp_cc_sm8450_exit(void)
+{
+       platform_driver_unregister(&disp_cc_sm8450_driver);
+}
+module_exit(disp_cc_sm8450_exit);
+
+MODULE_DESCRIPTION("QTI DISPCC SM8450 Driver");
+MODULE_LICENSE("GPL");
index 94ea2d8..657e115 100644 (file)
@@ -34,7 +34,9 @@ static struct clk_pll pll8 = {
        .status_bit = 16,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pll8",
-               .parent_names = (const char *[]){ "pxo" },
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "pxo", .name = "pxo_board",
+               },
                .num_parents = 1,
                .ops = &clk_pll_ops,
        },
@@ -45,7 +47,9 @@ static struct clk_regmap pll8_vote = {
        .enable_mask = BIT(8),
        .hw.init = &(struct clk_init_data){
                .name = "pll8_vote",
-               .parent_names = (const char *[]){ "pll8" },
+               .parent_hws = (const struct clk_hw*[]){
+                       &pll8.clkr.hw
+               },
                .num_parents = 1,
                .ops = &clk_pll_vote_ops,
        },
@@ -62,9 +66,9 @@ static const struct parent_map gcc_pxo_pll8_map[] = {
        { P_PLL8, 3 }
 };
 
-static const char * const gcc_pxo_pll8[] = {
-       "pxo",
-       "pll8_vote",
+static const struct clk_parent_data gcc_pxo_pll8[] = {
+       { .fw_name = "pxo", .name = "pxo_board" },
+       { .hw = &pll8_vote.hw },
 };
 
 static const struct parent_map gcc_pxo_pll8_cxo_map[] = {
@@ -73,10 +77,10 @@ static const struct parent_map gcc_pxo_pll8_cxo_map[] = {
        { P_CXO, 5 }
 };
 
-static const char * const gcc_pxo_pll8_cxo[] = {
-       "pxo",
-       "pll8_vote",
-       "cxo",
+static const struct clk_parent_data gcc_pxo_pll8_cxo[] = {
+       { .fw_name = "pxo", .name = "pxo_board" },
+       { .hw = &pll8_vote.hw },
+       { .fw_name = "cxo", .name = "cxo_board" },
 };
 
 static struct freq_tbl clk_tbl_gsbi_uart[] = {
@@ -122,8 +126,8 @@ static struct clk_rcg gsbi1_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi1_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -138,8 +142,8 @@ static struct clk_branch gsbi1_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi1_uart_clk",
-                       .parent_names = (const char *[]){
-                               "gsbi1_uart_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi1_uart_src.clkr.hw
                        },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
@@ -173,8 +177,8 @@ static struct clk_rcg gsbi2_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi2_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -189,8 +193,8 @@ static struct clk_branch gsbi2_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi2_uart_clk",
-                       .parent_names = (const char *[]){
-                               "gsbi2_uart_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi2_uart_src.clkr.hw
                        },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
@@ -224,8 +228,8 @@ static struct clk_rcg gsbi3_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi3_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -240,8 +244,8 @@ static struct clk_branch gsbi3_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi3_uart_clk",
-                       .parent_names = (const char *[]){
-                               "gsbi3_uart_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi3_uart_src.clkr.hw
                        },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
@@ -275,8 +279,8 @@ static struct clk_rcg gsbi4_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi4_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -291,8 +295,8 @@ static struct clk_branch gsbi4_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi4_uart_clk",
-                       .parent_names = (const char *[]){
-                               "gsbi4_uart_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi4_uart_src.clkr.hw
                        },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
@@ -326,8 +330,8 @@ static struct clk_rcg gsbi5_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi5_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -342,8 +346,8 @@ static struct clk_branch gsbi5_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi5_uart_clk",
-                       .parent_names = (const char *[]){
-                               "gsbi5_uart_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi5_uart_src.clkr.hw
                        },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
@@ -377,8 +381,8 @@ static struct clk_rcg gsbi6_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi6_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -393,8 +397,8 @@ static struct clk_branch gsbi6_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi6_uart_clk",
-                       .parent_names = (const char *[]){
-                               "gsbi6_uart_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi6_uart_src.clkr.hw
                        },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
@@ -428,8 +432,8 @@ static struct clk_rcg gsbi7_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi7_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -444,8 +448,8 @@ static struct clk_branch gsbi7_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi7_uart_clk",
-                       .parent_names = (const char *[]){
-                               "gsbi7_uart_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi7_uart_src.clkr.hw
                        },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
@@ -479,8 +483,8 @@ static struct clk_rcg gsbi8_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi8_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -495,7 +499,9 @@ static struct clk_branch gsbi8_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi8_uart_clk",
-                       .parent_names = (const char *[]){ "gsbi8_uart_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi8_uart_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -528,8 +534,8 @@ static struct clk_rcg gsbi9_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi9_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -544,7 +550,9 @@ static struct clk_branch gsbi9_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi9_uart_clk",
-                       .parent_names = (const char *[]){ "gsbi9_uart_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi9_uart_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -577,8 +585,8 @@ static struct clk_rcg gsbi10_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi10_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -593,7 +601,9 @@ static struct clk_branch gsbi10_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi10_uart_clk",
-                       .parent_names = (const char *[]){ "gsbi10_uart_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi10_uart_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -626,8 +636,8 @@ static struct clk_rcg gsbi11_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi11_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -642,7 +652,9 @@ static struct clk_branch gsbi11_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi11_uart_clk",
-                       .parent_names = (const char *[]){ "gsbi11_uart_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi11_uart_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -675,8 +687,8 @@ static struct clk_rcg gsbi12_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi12_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -691,7 +703,9 @@ static struct clk_branch gsbi12_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi12_uart_clk",
-                       .parent_names = (const char *[]){ "gsbi12_uart_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi12_uart_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -737,8 +751,8 @@ static struct clk_rcg gsbi1_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi1_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -753,7 +767,9 @@ static struct clk_branch gsbi1_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi1_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi1_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi1_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -786,8 +802,8 @@ static struct clk_rcg gsbi2_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi2_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -802,7 +818,9 @@ static struct clk_branch gsbi2_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi2_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi2_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi2_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -835,8 +853,8 @@ static struct clk_rcg gsbi3_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi3_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -851,7 +869,9 @@ static struct clk_branch gsbi3_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi3_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi3_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi3_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -884,8 +904,8 @@ static struct clk_rcg gsbi4_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi4_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -900,7 +920,9 @@ static struct clk_branch gsbi4_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi4_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi4_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi4_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -933,8 +955,8 @@ static struct clk_rcg gsbi5_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi5_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -949,7 +971,9 @@ static struct clk_branch gsbi5_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi5_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi5_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi5_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -982,8 +1006,8 @@ static struct clk_rcg gsbi6_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi6_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -998,7 +1022,9 @@ static struct clk_branch gsbi6_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi6_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi6_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi6_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1031,8 +1057,8 @@ static struct clk_rcg gsbi7_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi7_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1047,7 +1073,9 @@ static struct clk_branch gsbi7_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi7_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi7_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi7_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1080,8 +1108,8 @@ static struct clk_rcg gsbi8_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi8_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1096,7 +1124,9 @@ static struct clk_branch gsbi8_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi8_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi8_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi8_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1129,8 +1159,8 @@ static struct clk_rcg gsbi9_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi9_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1145,7 +1175,9 @@ static struct clk_branch gsbi9_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi9_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi9_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi9_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1178,8 +1210,8 @@ static struct clk_rcg gsbi10_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi10_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1194,7 +1226,9 @@ static struct clk_branch gsbi10_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi10_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi10_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi10_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1227,8 +1261,8 @@ static struct clk_rcg gsbi11_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi11_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1243,7 +1277,9 @@ static struct clk_branch gsbi11_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi11_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi11_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi11_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1276,8 +1312,8 @@ static struct clk_rcg gsbi12_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi12_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1292,7 +1328,9 @@ static struct clk_branch gsbi12_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi12_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi12_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi12_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1338,8 +1376,8 @@ static struct clk_rcg gp0_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gp0_src",
-                       .parent_names = gcc_pxo_pll8_cxo,
-                       .num_parents = 3,
+                       .parent_data = gcc_pxo_pll8_cxo,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8_cxo),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1354,7 +1392,9 @@ static struct clk_branch gp0_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gp0_clk",
-                       .parent_names = (const char *[]){ "gp0_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp0_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1387,8 +1427,8 @@ static struct clk_rcg gp1_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gp1_src",
-                       .parent_names = gcc_pxo_pll8_cxo,
-                       .num_parents = 3,
+                       .parent_data = gcc_pxo_pll8_cxo,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8_cxo),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
@@ -1403,7 +1443,9 @@ static struct clk_branch gp1_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gp1_clk",
-                       .parent_names = (const char *[]){ "gp1_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp1_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1436,8 +1478,8 @@ static struct clk_rcg gp2_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gp2_src",
-                       .parent_names = gcc_pxo_pll8_cxo,
-                       .num_parents = 3,
+                       .parent_data = gcc_pxo_pll8_cxo,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8_cxo),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
@@ -1452,7 +1494,9 @@ static struct clk_branch gp2_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gp2_clk",
-                       .parent_names = (const char *[]){ "gp2_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp2_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1488,8 +1532,8 @@ static struct clk_rcg prng_src = {
        .clkr.hw = {
                .init = &(struct clk_init_data){
                        .name = "prng_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                },
        },
@@ -1504,7 +1548,9 @@ static struct clk_branch prng_clk = {
                .enable_mask = BIT(10),
                .hw.init = &(struct clk_init_data){
                        .name = "prng_clk",
-                       .parent_names = (const char *[]){ "prng_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &prng_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                },
@@ -1547,8 +1593,8 @@ static struct clk_rcg sdc1_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc1_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                },
        }
@@ -1562,7 +1608,9 @@ static struct clk_branch sdc1_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc1_clk",
-                       .parent_names = (const char *[]){ "sdc1_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdc1_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1595,8 +1643,8 @@ static struct clk_rcg sdc2_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc2_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                },
        }
@@ -1610,7 +1658,9 @@ static struct clk_branch sdc2_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc2_clk",
-                       .parent_names = (const char *[]){ "sdc2_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdc2_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1643,8 +1693,8 @@ static struct clk_rcg sdc3_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc3_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                },
        }
@@ -1658,7 +1708,9 @@ static struct clk_branch sdc3_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc3_clk",
-                       .parent_names = (const char *[]){ "sdc3_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdc3_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1691,8 +1743,8 @@ static struct clk_rcg sdc4_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc4_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                },
        }
@@ -1706,7 +1758,9 @@ static struct clk_branch sdc4_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc4_clk",
-                       .parent_names = (const char *[]){ "sdc4_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdc4_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1739,8 +1793,8 @@ static struct clk_rcg sdc5_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc5_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                },
        }
@@ -1754,7 +1808,9 @@ static struct clk_branch sdc5_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc5_clk",
-                       .parent_names = (const char *[]){ "sdc5_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdc5_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1792,8 +1848,8 @@ static struct clk_rcg tsif_ref_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "tsif_ref_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
@@ -1808,7 +1864,9 @@ static struct clk_branch tsif_ref_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "tsif_ref_clk",
-                       .parent_names = (const char *[]){ "tsif_ref_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &tsif_ref_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1846,8 +1904,8 @@ static struct clk_rcg usb_hs1_xcvr_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_hs1_xcvr_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
@@ -1862,7 +1920,9 @@ static struct clk_branch usb_hs1_xcvr_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_hs1_xcvr_clk",
-                       .parent_names = (const char *[]){ "usb_hs1_xcvr_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_hs1_xcvr_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1895,16 +1955,14 @@ static struct clk_rcg usb_fs1_xcvr_fs_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_fs1_xcvr_fs_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
        }
 };
 
-static const char * const usb_fs1_xcvr_fs_src_p[] = { "usb_fs1_xcvr_fs_src" };
-
 static struct clk_branch usb_fs1_xcvr_fs_clk = {
        .halt_reg = 0x2fcc,
        .halt_bit = 15,
@@ -1913,7 +1971,9 @@ static struct clk_branch usb_fs1_xcvr_fs_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_fs1_xcvr_fs_clk",
-                       .parent_names = usb_fs1_xcvr_fs_src_p,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_fs1_xcvr_fs_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1928,7 +1988,9 @@ static struct clk_branch usb_fs1_system_clk = {
                .enable_reg = 0x296c,
                .enable_mask = BIT(4),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = usb_fs1_xcvr_fs_src_p,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_fs1_xcvr_fs_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .name = "usb_fs1_system_clk",
                        .ops = &clk_branch_ops,
@@ -1962,16 +2024,14 @@ static struct clk_rcg usb_fs2_xcvr_fs_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_fs2_xcvr_fs_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
        }
 };
 
-static const char * const usb_fs2_xcvr_fs_src_p[] = { "usb_fs2_xcvr_fs_src" };
-
 static struct clk_branch usb_fs2_xcvr_fs_clk = {
        .halt_reg = 0x2fcc,
        .halt_bit = 12,
@@ -1980,7 +2040,9 @@ static struct clk_branch usb_fs2_xcvr_fs_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_fs2_xcvr_fs_clk",
-                       .parent_names = usb_fs2_xcvr_fs_src_p,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_fs2_xcvr_fs_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1996,7 +2058,9 @@ static struct clk_branch usb_fs2_system_clk = {
                .enable_mask = BIT(4),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_fs2_system_clk",
-                       .parent_names = usb_fs2_xcvr_fs_src_p,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_fs2_xcvr_fs_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
diff --git a/drivers/clk/qcom/gcc-msm8909.c b/drivers/clk/qcom/gcc-msm8909.c
new file mode 100644 (file)
index 0000000..2a00b11
--- /dev/null
@@ -0,0 +1,2731 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022 Kernkonzept GmbH.
+ *
+ * Based on gcc-msm8916.c:
+ *   Copyright 2015 Linaro Limited
+ * adapted with data from clock-gcc-8909.c in Qualcomm's msm-3.18 release:
+ *   Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/clock/qcom,gcc-msm8909.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+/* Need to match the order of clocks in DT binding */
+enum {
+       DT_XO,
+       DT_SLEEP_CLK,
+       DT_DSI0PLL,
+       DT_DSI0PLL_BYTE,
+};
+
+enum {
+       P_XO,
+       P_SLEEP_CLK,
+       P_GPLL0,
+       P_GPLL1,
+       P_GPLL2,
+       P_BIMC,
+       P_DSI0PLL,
+       P_DSI0PLL_BYTE,
+};
+
+static const struct parent_map gcc_xo_map[] = {
+       { P_XO, 0 },
+};
+
+static const struct clk_parent_data gcc_xo_data[] = {
+       { .index = DT_XO },
+};
+
+static const struct clk_parent_data gcc_sleep_clk_data[] = {
+       { .index = DT_SLEEP_CLK },
+};
+
+static struct clk_alpha_pll gpll0_early = {
+       .offset = 0x21000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x45000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gpll0_early",
+                       .parent_data = gcc_xo_data,
+                       .num_parents = ARRAY_SIZE(gcc_xo_data),
+                       /* Avoid rate changes for shared clock */
+                       .ops = &clk_alpha_pll_fixed_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll0 = {
+       .offset = 0x21000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gpll0",
+               .parent_hws = (const struct clk_hw*[]) {
+                       &gpll0_early.clkr.hw,
+               },
+               .num_parents = 1,
+               /* Avoid rate changes for shared clock */
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+       },
+};
+
+static struct clk_pll gpll1 = {
+       .l_reg = 0x20004,
+       .m_reg = 0x20008,
+       .n_reg = 0x2000c,
+       .config_reg = 0x20010,
+       .mode_reg = 0x20000,
+       .status_reg = 0x2001c,
+       .status_bit = 17,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gpll1",
+               .parent_data = gcc_xo_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_data),
+               .ops = &clk_pll_ops,
+       },
+};
+
+static struct clk_regmap gpll1_vote = {
+       .enable_reg = 0x45000,
+       .enable_mask = BIT(1),
+       .hw.init = &(struct clk_init_data) {
+               .name = "gpll1_vote",
+               .parent_hws = (const struct clk_hw*[]) {
+                       &gpll1.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll2_early = {
+       .offset = 0x25000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x45000,
+               .enable_mask = BIT(3),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gpll2_early",
+                       .parent_data = gcc_xo_data,
+                       .num_parents = ARRAY_SIZE(gcc_xo_data),
+                       /* Avoid rate changes for shared clock */
+                       .ops = &clk_alpha_pll_fixed_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll2 = {
+       .offset = 0x25000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gpll2",
+               .parent_hws = (const struct clk_hw*[]) {
+                       &gpll2_early.clkr.hw,
+               },
+               .num_parents = 1,
+               /* Avoid rate changes for shared clock */
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+       },
+};
+
+static struct clk_alpha_pll bimc_pll_early = {
+       .offset = 0x23000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x45000,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "bimc_pll_early",
+                       .parent_data = gcc_xo_data,
+                       .num_parents = ARRAY_SIZE(gcc_xo_data),
+                       /* Avoid rate changes for shared clock */
+                       .ops = &clk_alpha_pll_fixed_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv bimc_pll = {
+       .offset = 0x23000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "bimc_pll",
+               .parent_hws = (const struct clk_hw*[]) {
+                       &bimc_pll_early.clkr.hw,
+               },
+               .num_parents = 1,
+               /* Avoid rate changes for shared clock */
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+       },
+};
+
+static const struct parent_map gcc_xo_gpll0_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_data[] = {
+       { .index = DT_XO },
+       { .hw = &gpll0.clkr.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_bimc_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_BIMC, 2 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_bimc_data[] = {
+       { .index = DT_XO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &bimc_pll.clkr.hw },
+};
+
+static const struct freq_tbl ftbl_apss_ahb_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 apss_ahb_clk_src = {
+       .cmd_rcgr = 0x46000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_apss_ahb_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "apss_ahb_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 bimc_ddr_clk_src = {
+       .cmd_rcgr = 0x32004,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_bimc_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "bimc_ddr_clk_src",
+               .parent_data = gcc_xo_gpll0_bimc_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc_data),
+               .ops = &clk_rcg2_ops,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_rcg2 bimc_gpu_clk_src = {
+       .cmd_rcgr = 0x31028,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_bimc_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "bimc_gpu_clk_src",
+               .parent_data = gcc_xo_gpll0_bimc_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc_data),
+               .ops = &clk_rcg2_ops,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp_i2c_apps_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x0200c,
+       .hid_width = 5,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup1_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x03000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup2_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x04000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup3_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x05000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup4_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x06000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup5_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x07000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup6_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_blsp_spi_apps_clk_src[] = {
+       F(960000, P_XO, 10, 1, 2),
+       F(4800000, P_XO, 4, 0, 0),
+       F(9600000, P_XO, 2, 0, 0),
+       F(16000000, P_GPLL0, 10, 1, 5),
+       F(19200000, P_XO, 1, 0, 0),
+       F(25000000, P_GPLL0, 16, 1, 2),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
+       .cmd_rcgr = 0x02024,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup1_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
+       .cmd_rcgr = 0x03014,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup2_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
+       .cmd_rcgr = 0x04024,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup3_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
+       .cmd_rcgr = 0x05024,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup4_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = {
+       .cmd_rcgr = 0x06024,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup5_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = {
+       .cmd_rcgr = 0x07024,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup6_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_blsp_uart_apps_clk_src[] = {
+       F(3686400, P_GPLL0, 1, 72, 15625),
+       F(7372800, P_GPLL0, 1, 144, 15625),
+       F(14745600, P_GPLL0, 1, 288, 15625),
+       F(16000000, P_GPLL0, 10, 1, 5),
+       F(19200000, P_XO, 1, 0, 0),
+       F(24000000, P_GPLL0, 1, 3, 100),
+       F(25000000, P_GPLL0, 16, 1, 2),
+       F(32000000, P_GPLL0, 1, 1, 25),
+       F(40000000, P_GPLL0, 1, 1, 20),
+       F(46400000, P_GPLL0, 1, 29, 500),
+       F(48000000, P_GPLL0, 1, 3, 50),
+       F(51200000, P_GPLL0, 1, 8, 125),
+       F(56000000, P_GPLL0, 1, 7, 100),
+       F(58982400, P_GPLL0, 1, 1152, 15625),
+       F(60000000, P_GPLL0, 1, 3, 40),
+       { }
+};
+
+static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
+       .cmd_rcgr = 0x02044,
+       .hid_width = 5,
+       .mnd_width = 16,
+       .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_uart1_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
+       .cmd_rcgr = 0x03034,
+       .hid_width = 5,
+       .mnd_width = 16,
+       .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_uart2_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_byte0_map[] = {
+       { P_XO, 0 },
+       { P_DSI0PLL_BYTE, 1 },
+};
+
+static const struct clk_parent_data gcc_byte_data[] = {
+       { .index = DT_XO },
+       { .index = DT_DSI0PLL_BYTE },
+};
+
+static struct clk_rcg2 byte0_clk_src = {
+       .cmd_rcgr = 0x4d044,
+       .hid_width = 5,
+       .parent_map = gcc_byte0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "byte0_clk_src",
+               .parent_data = gcc_byte_data,
+               .num_parents = ARRAY_SIZE(gcc_byte_data),
+               .ops = &clk_byte2_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       }
+};
+
+static const struct freq_tbl ftbl_camss_gp_clk_src[] = {
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 camss_gp0_clk_src = {
+       .cmd_rcgr = 0x54000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_camss_gp_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "camss_gp0_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 camss_gp1_clk_src = {
+       .cmd_rcgr = 0x55000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_camss_gp_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "camss_gp1_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_camss_top_ahb_clk_src[] = {
+       F(40000000, P_GPLL0, 10, 1, 2),
+       F(80000000, P_GPLL0, 10, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 camss_top_ahb_clk_src = {
+       .cmd_rcgr = 0x5a000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_camss_top_ahb_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "camss_top_ahb_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_crypto_clk_src[] = {
+       F(50000000, P_GPLL0, 16, 0, 0),
+       F(80000000, P_GPLL0, 10, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(160000000, P_GPLL0, 5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 crypto_clk_src = {
+       .cmd_rcgr = 0x16004,
+       .hid_width = 5,
+       .freq_tbl = ftbl_crypto_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "crypto_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_csi_clk_src[] = {
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi0_clk_src = {
+       .cmd_rcgr = 0x4e020,
+       .hid_width = 5,
+       .freq_tbl = ftbl_csi_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "csi0_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_map),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 csi1_clk_src = {
+       .cmd_rcgr = 0x4f020,
+       .hid_width = 5,
+       .freq_tbl = ftbl_csi_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "csi1_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_csi_phytimer_clk_src[] = {
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi0phytimer_clk_src = {
+       .cmd_rcgr = 0x4e000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_csi_phytimer_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "csi0phytimer_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_esc0_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 esc0_clk_src = {
+       .cmd_rcgr = 0x4d05c,
+       .hid_width = 5,
+       .freq_tbl = ftbl_esc0_clk_src,
+       .parent_map = gcc_xo_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "esc0_clk_src",
+               .parent_data = gcc_xo_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_gfx3d_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL1, 2 },
+};
+
+static const struct clk_parent_data gcc_gfx3d_data[] = {
+       { .index = DT_XO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll1_vote.hw },
+};
+
+static const struct freq_tbl ftbl_gfx3d_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       F(80000000, P_GPLL0, 10, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(160000000, P_GPLL0, 5, 0, 0),
+       F(177780000, P_GPLL0, 4.5, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(266670000, P_GPLL0, 3, 0, 0),
+       F(307200000, P_GPLL1, 4, 0, 0),
+       F(409600000, P_GPLL1, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gfx3d_clk_src = {
+       .cmd_rcgr = 0x59000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_gfx3d_clk_src,
+       .parent_map = gcc_gfx3d_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gfx3d_clk_src",
+               .parent_data = gcc_gfx3d_data,
+               .num_parents = ARRAY_SIZE(gcc_gfx3d_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_gp_clk_src[] = {
+       F(150000, P_XO, 1, 1, 128),
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gp1_clk_src = {
+       .cmd_rcgr = 0x08004,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_gp_clk_src,
+       .parent_map = gcc_xo_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gp1_clk_src",
+               .parent_data = gcc_xo_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 gp2_clk_src = {
+       .cmd_rcgr = 0x09004,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_gp_clk_src,
+       .parent_map = gcc_xo_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gp2_clk_src",
+               .parent_data = gcc_xo_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 gp3_clk_src = {
+       .cmd_rcgr = 0x0a004,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_gp_clk_src,
+       .parent_map = gcc_xo_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gp3_clk_src",
+               .parent_data = gcc_xo_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_mclk_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL2, 3 },
+};
+
+static const struct clk_parent_data gcc_mclk_data[] = {
+       { .index = DT_XO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll2.clkr.hw },
+};
+
+static const struct freq_tbl ftbl_mclk_clk_src[] = {
+       F(24000000, P_GPLL2, 1, 1, 33),
+       F(66667000, P_GPLL0, 12, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 mclk0_clk_src = {
+       .cmd_rcgr = 0x52000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_mclk_clk_src,
+       .parent_map = gcc_mclk_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "mclk0_clk_src",
+               .parent_data = gcc_mclk_data,
+               .num_parents = ARRAY_SIZE(gcc_mclk_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 mclk1_clk_src = {
+       .cmd_rcgr = 0x53000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_mclk_clk_src,
+       .parent_map = gcc_mclk_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "mclk1_clk_src",
+               .parent_data = gcc_mclk_data,
+               .num_parents = ARRAY_SIZE(gcc_mclk_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_mdp_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL1, 3 },
+};
+
+static const struct clk_parent_data gcc_mdp_data[] = {
+       { .index = DT_XO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll1_vote.hw },
+};
+
+static const struct freq_tbl ftbl_mdp_clk_src[] = {
+       F(50000000, P_GPLL0, 16, 0, 0),
+       F(80000000, P_GPLL0, 10, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(160000000, P_GPLL0, 5, 0, 0),
+       F(177780000, P_GPLL0, 4.5, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(266670000, P_GPLL0, 3, 0, 0),
+       F(307200000, P_GPLL1, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 mdp_clk_src = {
+       .cmd_rcgr = 0x4d014,
+       .hid_width = 5,
+       .freq_tbl = ftbl_mdp_clk_src,
+       .parent_map = gcc_mdp_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "mdp_clk_src",
+               .parent_data = gcc_mdp_data,
+               .num_parents = ARRAY_SIZE(gcc_mdp_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_pclk0_map[] = {
+       { P_XO, 0 },
+       { P_DSI0PLL, 1 },
+};
+
+static const struct clk_parent_data gcc_pclk_data[] = {
+       { .index = DT_XO },
+       { .index = DT_DSI0PLL },
+};
+
+static struct clk_rcg2 pclk0_clk_src = {
+       .cmd_rcgr = 0x4d000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .parent_map = gcc_pclk0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "pclk0_clk_src",
+               .parent_data = gcc_pclk_data,
+               .num_parents = ARRAY_SIZE(gcc_pclk_data),
+               .ops = &clk_pixel_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       }
+};
+
+static struct clk_rcg2 pcnoc_bfdcd_clk_src = {
+       .cmd_rcgr = 0x27000,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_bimc_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "pcnoc_bfdcd_clk_src",
+               .parent_data = gcc_xo_gpll0_bimc_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc_data),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_pdm2_clk_src[] = {
+       F(64000000, P_GPLL0, 12.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 pdm2_clk_src = {
+       .cmd_rcgr = 0x44010,
+       .hid_width = 5,
+       .freq_tbl = ftbl_pdm2_clk_src,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "pdm2_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_2_apps_clk[] = {
+       F(144000, P_XO, 16, 3, 25),
+       F(400000, P_XO, 12, 1, 4),
+       F(20000000, P_GPLL0, 10, 1, 4),
+       F(25000000, P_GPLL0, 16, 1, 2),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(177770000, P_GPLL0, 4.5, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 sdcc1_apps_clk_src = {
+       .cmd_rcgr = 0x42004,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_gcc_sdcc1_2_apps_clk,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "sdcc1_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_floor_ops,
+       }
+};
+
+static struct clk_rcg2 sdcc2_apps_clk_src = {
+       .cmd_rcgr = 0x43004,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_gcc_sdcc1_2_apps_clk,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "sdcc2_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_floor_ops,
+       }
+};
+
+static struct clk_rcg2 system_noc_bfdcd_clk_src = {
+       .cmd_rcgr = 0x26004,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_bimc_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "system_noc_bfdcd_clk_src",
+               .parent_data = gcc_xo_gpll0_bimc_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc_data),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
+       F(57140000, P_GPLL0, 14, 0, 0),
+       F(80000000, P_GPLL0, 10, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 usb_hs_system_clk_src = {
+       .cmd_rcgr = 0x41010,
+       .hid_width = 5,
+       .freq_tbl = ftbl_gcc_usb_hs_system_clk,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "usb_hs_system_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_vcodec0_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL1, 3 },
+};
+
+static const struct clk_parent_data gcc_vcodec0_data[] = {
+       { .index = DT_XO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll1_vote.hw },
+};
+
+static const struct freq_tbl ftbl_vcodec0_clk_src[] = {
+       F(133330000, P_GPLL0, 6, 0, 0),
+       F(266670000, P_GPLL0, 3, 0, 0),
+       F(307200000, P_GPLL1, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vcodec0_clk_src = {
+       .cmd_rcgr = 0x4c000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_vcodec0_clk_src,
+       .parent_map = gcc_vcodec0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "vcodec0_clk_src",
+               .parent_data = gcc_vcodec0_data,
+               .num_parents = ARRAY_SIZE(gcc_vcodec0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_gcc_camss_vfe0_clk[] = {
+       F(50000000, P_GPLL0, 16, 0, 0),
+       F(80000000, P_GPLL0, 10, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(133330000, P_GPLL0, 6, 0, 0),
+       F(160000000, P_GPLL0, 5, 0, 0),
+       F(177780000, P_GPLL0, 4.5, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(266670000, P_GPLL0, 3, 0, 0),
+       F(320000000, P_GPLL0, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vfe0_clk_src = {
+       .cmd_rcgr = 0x58000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_gcc_camss_vfe0_clk,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "vfe0_clk_src",
+               .parent_data = gcc_xo_gpll0_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_vsync_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vsync_clk_src = {
+       .cmd_rcgr = 0x4d02c,
+       .hid_width = 5,
+       .freq_tbl = ftbl_vsync_clk_src,
+       .parent_map = gcc_xo_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "vsync_clk_src",
+               .parent_data = gcc_xo_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_branch gcc_apss_tcu_clk = {
+       .halt_reg = 0x12018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_apss_tcu_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &bimc_ddr_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_ahb_clk = {
+       .halt_reg = 0x01008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_sleep_clk = {
+       .halt_reg = 0x01004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_sleep_clk",
+                       .parent_data = gcc_sleep_clk_data,
+                       .num_parents = ARRAY_SIZE(gcc_sleep_clk_data),
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+       .halt_reg = 0x1300c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_boot_rom_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_crypto_clk = {
+       .halt_reg = 0x1601c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_crypto_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &crypto_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_crypto_ahb_clk = {
+       .halt_reg = 0x16024,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_crypto_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_crypto_axi_clk = {
+       .halt_reg = 0x16020,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_crypto_axi_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_gfx_tbu_clk = {
+       .halt_reg = 0x12010,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(3),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_gfx_tbu_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &bimc_ddr_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_gfx_tcu_clk = {
+       .halt_reg = 0x12020,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_gfx_tcu_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &bimc_ddr_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_gtcu_ahb_clk = {
+       .halt_reg = 0x12044,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_gtcu_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdp_tbu_clk = {
+       .halt_reg = 0x1201c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdp_tbu_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &system_noc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+       .halt_reg = 0x13004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_prng_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_smmu_cfg_clk = {
+       .halt_reg = 0x12038,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(12),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_smmu_cfg_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_venus_tbu_clk = {
+       .halt_reg = 0x12014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(5),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus_tbu_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &system_noc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_vfe_tbu_clk = {
+       .halt_reg = 0x1203c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_vfe_tbu_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &system_noc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_bimc_gfx_clk = {
+       .halt_reg = 0x31024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x31024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_bimc_gfx_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &bimc_gpu_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_bimc_gpu_clk = {
+       .halt_reg = 0x31040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x31040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_bimc_gpu_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &bimc_gpu_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
+       .halt_reg = 0x02008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x02008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup1_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup1_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
+       .halt_reg = 0x03010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x03010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup2_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup2_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
+       .halt_reg = 0x04020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x04020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup3_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup3_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
+       .halt_reg = 0x05020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x05020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup4_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup4_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = {
+       .halt_reg = 0x06020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x06020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup5_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup5_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = {
+       .halt_reg = 0x07020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x07020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup6_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup6_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
+       .halt_reg = 0x02004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x02004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup1_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup1_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
+       .halt_reg = 0x0300c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0300c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup2_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup2_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
+       .halt_reg = 0x0401c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0401c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup3_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup3_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
+       .halt_reg = 0x0501c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0501c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup4_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup4_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = {
+       .halt_reg = 0x0601c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0601c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup5_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup5_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = {
+       .halt_reg = 0x0701c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0701c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup6_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup6_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_uart1_apps_clk = {
+       .halt_reg = 0x0203c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0203c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_uart1_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_uart1_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_uart2_apps_clk = {
+       .halt_reg = 0x0302c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0302c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_uart2_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_uart2_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_ahb_clk = {
+       .halt_reg = 0x5a014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5a014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi0_clk = {
+       .halt_reg = 0x4e03c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &csi0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi0_ahb_clk = {
+       .halt_reg = 0x4e040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi0phy_clk = {
+       .halt_reg = 0x4e048,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0phy_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &csi0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi0phytimer_clk = {
+       .halt_reg = 0x4e01c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e01c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0phytimer_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &csi0phytimer_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi0pix_clk = {
+       .halt_reg = 0x4e058,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0pix_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &csi0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi0rdi_clk = {
+       .halt_reg = 0x4e050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0rdi_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &csi0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi1_clk = {
+       .halt_reg = 0x4f03c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4f03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &csi1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi1_ahb_clk = {
+       .halt_reg = 0x4f040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4f040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi1phy_clk = {
+       .halt_reg = 0x4f048,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4f048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1phy_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &csi1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi1pix_clk = {
+       .halt_reg = 0x4f058,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4f058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1pix_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &csi1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi1rdi_clk = {
+       .halt_reg = 0x4f050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4f050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1rdi_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &csi1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi_vfe0_clk = {
+       .halt_reg = 0x58050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi_vfe0_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &vfe0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_gp0_clk = {
+       .halt_reg = 0x54018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x54018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_gp0_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &camss_gp0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_gp1_clk = {
+       .halt_reg = 0x55018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x55018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_gp1_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &camss_gp1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_ispif_ahb_clk = {
+       .halt_reg = 0x50004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x50004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_ispif_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_mclk0_clk = {
+       .halt_reg = 0x52018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x52018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_mclk0_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &mclk0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_mclk1_clk = {
+       .halt_reg = 0x53018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x53018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_mclk1_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &mclk1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_top_ahb_clk = {
+       .halt_reg = 0x56004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x56004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_top_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_vfe0_clk = {
+       .halt_reg = 0x58038,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe0_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &vfe0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_vfe_ahb_clk = {
+       .halt_reg = 0x58044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_vfe_axi_clk = {
+       .halt_reg = 0x58048,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe_axi_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &system_noc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_gp1_clk = {
+       .halt_reg = 0x08000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x08000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_gp1_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &gp1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_gp2_clk = {
+       .halt_reg = 0x09000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x09000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_gp2_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &gp2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_gp3_clk = {
+       .halt_reg = 0x0a000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0a000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_gp3_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &gp3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_ahb_clk = {
+       .halt_reg = 0x4d07c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d07c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_axi_clk = {
+       .halt_reg = 0x4d080,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_axi_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &system_noc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_byte0_clk = {
+       .halt_reg = 0x4d094,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d094,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_byte0_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &byte0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_esc0_clk = {
+       .halt_reg = 0x4d098,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d098,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_esc0_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &esc0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_mdp_clk = {
+       .halt_reg = 0x4d088,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d088,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_mdp_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &mdp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_pclk0_clk = {
+       .halt_reg = 0x4d084,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d084,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_pclk0_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pclk0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_vsync_clk = {
+       .halt_reg = 0x4d090,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d090,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_vsync_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &vsync_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_mss_cfg_ahb_clk = {
+       .halt_reg = 0x49000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x49000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mss_cfg_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
+       .halt_reg = 0x49004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x49004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mss_q6_bimc_axi_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &bimc_ddr_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_oxili_ahb_clk = {
+       .halt_reg = 0x59028,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_oxili_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_oxili_gfx3d_clk = {
+       .halt_reg = 0x59020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_oxili_gfx3d_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &gfx3d_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+       .halt_reg = 0x4400c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4400c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_pdm2_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pdm2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_pdm_ahb_clk = {
+       .halt_reg = 0x44004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x44004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_pdm_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+       .halt_reg = 0x4201c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4201c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc1_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+       .halt_reg = 0x42018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x42018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc1_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &sdcc1_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_sdcc2_ahb_clk = {
+       .halt_reg = 0x4301c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4301c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc2_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_sdcc2_apps_clk = {
+       .halt_reg = 0x43018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x43018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc2_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &sdcc2_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_usb2a_phy_sleep_clk = {
+       .halt_reg = 0x4102c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4102c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb2a_phy_sleep_clk",
+                       .parent_data = gcc_sleep_clk_data,
+                       .num_parents = ARRAY_SIZE(gcc_sleep_clk_data),
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_usb_hs_ahb_clk = {
+       .halt_reg = 0x41008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x41008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb_hs_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_usb_hs_phy_cfg_ahb_clk = {
+       .halt_reg = 0x41030,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x41030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb_hs_phy_cfg_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_usb_hs_system_clk = {
+       .halt_reg = 0x41004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x41004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb_hs_system_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &usb_hs_system_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_venus0_ahb_clk = {
+       .halt_reg = 0x4c020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4c020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus0_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_venus0_axi_clk = {
+       .halt_reg = 0x4c024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4c024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus0_axi_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &system_noc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_venus0_core0_vcodec0_clk = {
+       .halt_reg = 0x4c02c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4c02c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus0_core0_vcodec0_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &vcodec0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_venus0_vcodec0_clk = {
+       .halt_reg = 0x4c01c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4c01c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus0_vcodec0_clk",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &vcodec0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct gdsc mdss_gdsc = {
+       .gdscr = 0x4d078,
+       .cxcs = (unsigned int []) { 0x4d080, 0x4d088 },
+       .cxc_count = 2,
+       .pd = {
+               .name = "mdss_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxili_gdsc = {
+       .gdscr = 0x5901c,
+       .cxcs = (unsigned int []) { 0x59020 },
+       .cxc_count = 1,
+       .pd = {
+               .name = "oxili_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus_gdsc = {
+       .gdscr = 0x4c018,
+       .cxcs = (unsigned int []) { 0x4c024, 0x4c01c },
+       .cxc_count = 2,
+       .pd = {
+               .name = "venus_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus_core0_gdsc = {
+       .gdscr = 0x4c028,
+       .cxcs = (unsigned int []) { 0x4c02c },
+       .cxc_count = 1,
+       .pd = {
+               .name = "venus_core0_gdsc",
+       },
+       .flags = HW_CTRL,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc vfe_gdsc = {
+       .gdscr = 0x58034,
+       .cxcs = (unsigned int []) { 0x58038, 0x58048, 0x58050 },
+       .cxc_count = 3,
+       .pd = {
+               .name = "vfe_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct clk_regmap *gcc_msm8909_clocks[] = {
+       [GPLL0_EARLY] = &gpll0_early.clkr,
+       [GPLL0] = &gpll0.clkr,
+       [GPLL1] = &gpll1.clkr,
+       [GPLL1_VOTE] = &gpll1_vote,
+       [GPLL2_EARLY] = &gpll2_early.clkr,
+       [GPLL2] = &gpll2.clkr,
+       [BIMC_PLL_EARLY] = &bimc_pll_early.clkr,
+       [BIMC_PLL] = &bimc_pll.clkr,
+       [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr,
+       [BIMC_DDR_CLK_SRC] = &bimc_ddr_clk_src.clkr,
+       [BIMC_GPU_CLK_SRC] = &bimc_gpu_clk_src.clkr,
+       [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
+       [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
+       [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr,
+       [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr,
+       [BLSP1_QUP5_I2C_APPS_CLK_SRC] = &blsp1_qup5_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP5_SPI_APPS_CLK_SRC] = &blsp1_qup5_spi_apps_clk_src.clkr,
+       [BLSP1_QUP6_I2C_APPS_CLK_SRC] = &blsp1_qup6_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP6_SPI_APPS_CLK_SRC] = &blsp1_qup6_spi_apps_clk_src.clkr,
+       [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
+       [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
+       [BYTE0_CLK_SRC] = &byte0_clk_src.clkr,
+       [CAMSS_GP0_CLK_SRC] = &camss_gp0_clk_src.clkr,
+       [CAMSS_GP1_CLK_SRC] = &camss_gp1_clk_src.clkr,
+       [CAMSS_TOP_AHB_CLK_SRC] = &camss_top_ahb_clk_src.clkr,
+       [CRYPTO_CLK_SRC] = &crypto_clk_src.clkr,
+       [CSI0_CLK_SRC] = &csi0_clk_src.clkr,
+       [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr,
+       [CSI1_CLK_SRC] = &csi1_clk_src.clkr,
+       [ESC0_CLK_SRC] = &esc0_clk_src.clkr,
+       [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr,
+       [GP1_CLK_SRC] = &gp1_clk_src.clkr,
+       [GP2_CLK_SRC] = &gp2_clk_src.clkr,
+       [GP3_CLK_SRC] = &gp3_clk_src.clkr,
+       [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr,
+       [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr,
+       [MDP_CLK_SRC] = &mdp_clk_src.clkr,
+       [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr,
+       [PCNOC_BFDCD_CLK_SRC] = &pcnoc_bfdcd_clk_src.clkr,
+       [PDM2_CLK_SRC] = &pdm2_clk_src.clkr,
+       [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr,
+       [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr,
+       [SYSTEM_NOC_BFDCD_CLK_SRC] = &system_noc_bfdcd_clk_src.clkr,
+       [USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr,
+       [VCODEC0_CLK_SRC] = &vcodec0_clk_src.clkr,
+       [VFE0_CLK_SRC] = &vfe0_clk_src.clkr,
+       [VSYNC_CLK_SRC] = &vsync_clk_src.clkr,
+       [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr,
+       [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
+       [GCC_BLSP1_SLEEP_CLK] = &gcc_blsp1_sleep_clk.clkr,
+       [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+       [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr,
+       [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr,
+       [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr,
+       [GCC_GFX_TBU_CLK] = &gcc_gfx_tbu_clk.clkr,
+       [GCC_GFX_TCU_CLK] = &gcc_gfx_tcu_clk.clkr,
+       [GCC_GTCU_AHB_CLK] = &gcc_gtcu_ahb_clk.clkr,
+       [GCC_MDP_TBU_CLK] = &gcc_mdp_tbu_clk.clkr,
+       [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+       [GCC_SMMU_CFG_CLK] = &gcc_smmu_cfg_clk.clkr,
+       [GCC_VENUS_TBU_CLK] = &gcc_venus_tbu_clk.clkr,
+       [GCC_VFE_TBU_CLK] = &gcc_vfe_tbu_clk.clkr,
+       [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr,
+       [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr,
+       [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP5_I2C_APPS_CLK] = &gcc_blsp1_qup5_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP5_SPI_APPS_CLK] = &gcc_blsp1_qup5_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP6_I2C_APPS_CLK] = &gcc_blsp1_qup6_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP6_SPI_APPS_CLK] = &gcc_blsp1_qup6_spi_apps_clk.clkr,
+       [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
+       [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
+       [GCC_CAMSS_AHB_CLK] = &gcc_camss_ahb_clk.clkr,
+       [GCC_CAMSS_CSI0_CLK] = &gcc_camss_csi0_clk.clkr,
+       [GCC_CAMSS_CSI0_AHB_CLK] = &gcc_camss_csi0_ahb_clk.clkr,
+       [GCC_CAMSS_CSI0PHY_CLK] = &gcc_camss_csi0phy_clk.clkr,
+       [GCC_CAMSS_CSI0PHYTIMER_CLK] = &gcc_camss_csi0phytimer_clk.clkr,
+       [GCC_CAMSS_CSI0PIX_CLK] = &gcc_camss_csi0pix_clk.clkr,
+       [GCC_CAMSS_CSI0RDI_CLK] = &gcc_camss_csi0rdi_clk.clkr,
+       [GCC_CAMSS_CSI1_CLK] = &gcc_camss_csi1_clk.clkr,
+       [GCC_CAMSS_CSI1_AHB_CLK] = &gcc_camss_csi1_ahb_clk.clkr,
+       [GCC_CAMSS_CSI1PHY_CLK] = &gcc_camss_csi1phy_clk.clkr,
+       [GCC_CAMSS_CSI1PIX_CLK] = &gcc_camss_csi1pix_clk.clkr,
+       [GCC_CAMSS_CSI1RDI_CLK] = &gcc_camss_csi1rdi_clk.clkr,
+       [GCC_CAMSS_CSI_VFE0_CLK] = &gcc_camss_csi_vfe0_clk.clkr,
+       [GCC_CAMSS_GP0_CLK] = &gcc_camss_gp0_clk.clkr,
+       [GCC_CAMSS_GP1_CLK] = &gcc_camss_gp1_clk.clkr,
+       [GCC_CAMSS_ISPIF_AHB_CLK] = &gcc_camss_ispif_ahb_clk.clkr,
+       [GCC_CAMSS_MCLK0_CLK] = &gcc_camss_mclk0_clk.clkr,
+       [GCC_CAMSS_MCLK1_CLK] = &gcc_camss_mclk1_clk.clkr,
+       [GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr,
+       [GCC_CAMSS_VFE0_CLK] = &gcc_camss_vfe0_clk.clkr,
+       [GCC_CAMSS_VFE_AHB_CLK] = &gcc_camss_vfe_ahb_clk.clkr,
+       [GCC_CAMSS_VFE_AXI_CLK] = &gcc_camss_vfe_axi_clk.clkr,
+       [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+       [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+       [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+       [GCC_MDSS_AHB_CLK] = &gcc_mdss_ahb_clk.clkr,
+       [GCC_MDSS_AXI_CLK] = &gcc_mdss_axi_clk.clkr,
+       [GCC_MDSS_BYTE0_CLK] = &gcc_mdss_byte0_clk.clkr,
+       [GCC_MDSS_ESC0_CLK] = &gcc_mdss_esc0_clk.clkr,
+       [GCC_MDSS_MDP_CLK] = &gcc_mdss_mdp_clk.clkr,
+       [GCC_MDSS_PCLK0_CLK] = &gcc_mdss_pclk0_clk.clkr,
+       [GCC_MDSS_VSYNC_CLK] = &gcc_mdss_vsync_clk.clkr,
+       [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
+       [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr,
+       [GCC_OXILI_AHB_CLK] = &gcc_oxili_ahb_clk.clkr,
+       [GCC_OXILI_GFX3D_CLK] = &gcc_oxili_gfx3d_clk.clkr,
+       [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+       [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+       [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+       [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+       [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
+       [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
+       [GCC_USB2A_PHY_SLEEP_CLK] = &gcc_usb2a_phy_sleep_clk.clkr,
+       [GCC_USB_HS_AHB_CLK] = &gcc_usb_hs_ahb_clk.clkr,
+       [GCC_USB_HS_PHY_CFG_AHB_CLK] = &gcc_usb_hs_phy_cfg_ahb_clk.clkr,
+       [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr,
+       [GCC_VENUS0_AHB_CLK] = &gcc_venus0_ahb_clk.clkr,
+       [GCC_VENUS0_AXI_CLK] = &gcc_venus0_axi_clk.clkr,
+       [GCC_VENUS0_CORE0_VCODEC0_CLK] = &gcc_venus0_core0_vcodec0_clk.clkr,
+       [GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr,
+};
+
+static struct gdsc *gcc_msm8909_gdscs[] = {
+       [MDSS_GDSC] = &mdss_gdsc,
+       [OXILI_GDSC] = &oxili_gdsc,
+       [VENUS_GDSC] = &venus_gdsc,
+       [VENUS_CORE0_GDSC] = &venus_core0_gdsc,
+       [VFE_GDSC] = &vfe_gdsc,
+};
+
+static const struct qcom_reset_map gcc_msm8909_resets[] = {
+       [GCC_AUDIO_CORE_BCR] = { 0x1c008 },
+       [GCC_BLSP1_BCR] = { 0x01000 },
+       [GCC_BLSP1_QUP1_BCR] = { 0x02000 },
+       [GCC_BLSP1_QUP2_BCR] = { 0x03008 },
+       [GCC_BLSP1_QUP3_BCR] = { 0x04018 },
+       [GCC_BLSP1_QUP4_BCR] = { 0x05018 },
+       [GCC_BLSP1_QUP5_BCR] = { 0x06018 },
+       [GCC_BLSP1_QUP6_BCR] = { 0x07018 },
+       [GCC_BLSP1_UART1_BCR] = { 0x02038 },
+       [GCC_BLSP1_UART2_BCR] = { 0x03028 },
+       [GCC_CAMSS_CSI0_BCR] = { 0x4e038 },
+       [GCC_CAMSS_CSI0PHY_BCR] = { 0x4e044 },
+       [GCC_CAMSS_CSI0PIX_BCR] = { 0x4e054 },
+       [GCC_CAMSS_CSI0RDI_BCR] = { 0x4e04c },
+       [GCC_CAMSS_CSI1_BCR] = { 0x4f038 },
+       [GCC_CAMSS_CSI1PHY_BCR] = { 0x4f044 },
+       [GCC_CAMSS_CSI1PIX_BCR] = { 0x4f054 },
+       [GCC_CAMSS_CSI1RDI_BCR] = { 0x4f04c },
+       [GCC_CAMSS_CSI_VFE0_BCR] = { 0x5804c },
+       [GCC_CAMSS_GP0_BCR] = { 0x54014 },
+       [GCC_CAMSS_GP1_BCR] = { 0x55014 },
+       [GCC_CAMSS_ISPIF_BCR] = { 0x50000 },
+       [GCC_CAMSS_MCLK0_BCR] = { 0x52014 },
+       [GCC_CAMSS_MCLK1_BCR] = { 0x53014 },
+       [GCC_CAMSS_PHY0_BCR] = { 0x4e018 },
+       [GCC_CAMSS_TOP_BCR] = { 0x56000 },
+       [GCC_CAMSS_TOP_AHB_BCR] = { 0x5a018 },
+       [GCC_CAMSS_VFE_BCR] = { 0x58030 },
+       [GCC_CRYPTO_BCR] = { 0x16000 },
+       [GCC_MDSS_BCR] = { 0x4d074 },
+       [GCC_OXILI_BCR] = { 0x59018 },
+       [GCC_PDM_BCR] = { 0x44000 },
+       [GCC_PRNG_BCR] = { 0x13000 },
+       [GCC_QUSB2_PHY_BCR] = { 0x4103c },
+       [GCC_SDCC1_BCR] = { 0x42000 },
+       [GCC_SDCC2_BCR] = { 0x43000 },
+       [GCC_ULT_AUDIO_BCR] = { 0x1c0b4 },
+       [GCC_USB2A_PHY_BCR] = { 0x41028 },
+       [GCC_USB2_HS_PHY_ONLY_BCR] = { .reg = 0x41034, .udelay = 15 },
+       [GCC_USB_HS_BCR] = { 0x41000 },
+       [GCC_VENUS0_BCR] = { 0x4c014 },
+       /* Subsystem Restart */
+       [GCC_MSS_RESTART] = { 0x3e000 },
+};
+
+static const struct regmap_config gcc_msm8909_regmap_config = {
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0x80000,
+       .fast_io        = true,
+};
+
+static const struct qcom_cc_desc gcc_msm8909_desc = {
+       .config = &gcc_msm8909_regmap_config,
+       .clks = gcc_msm8909_clocks,
+       .num_clks = ARRAY_SIZE(gcc_msm8909_clocks),
+       .resets = gcc_msm8909_resets,
+       .num_resets = ARRAY_SIZE(gcc_msm8909_resets),
+       .gdscs = gcc_msm8909_gdscs,
+       .num_gdscs = ARRAY_SIZE(gcc_msm8909_gdscs),
+};
+
+static const struct of_device_id gcc_msm8909_match_table[] = {
+       { .compatible = "qcom,gcc-msm8909" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gcc_msm8909_match_table);
+
+static int gcc_msm8909_probe(struct platform_device *pdev)
+{
+       return qcom_cc_probe(pdev, &gcc_msm8909_desc);
+}
+
+static struct platform_driver gcc_msm8909_driver = {
+       .probe          = gcc_msm8909_probe,
+       .driver         = {
+               .name   = "gcc-msm8909",
+               .of_match_table = gcc_msm8909_match_table,
+       },
+};
+
+static int __init gcc_msm8909_init(void)
+{
+       return platform_driver_register(&gcc_msm8909_driver);
+}
+core_initcall(gcc_msm8909_init);
+
+static void __exit gcc_msm8909_exit(void)
+{
+       platform_driver_unregister(&gcc_msm8909_driver);
+}
+module_exit(gcc_msm8909_exit);
+
+MODULE_DESCRIPTION("Qualcomm GCC MSM8909 Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:gcc-msm8909");
index 9a46794..0c8fe19 100644 (file)
@@ -42,14 +42,138 @@ enum {
        P_EXT_MCLK,
 };
 
+static struct clk_pll gpll0 = {
+       .l_reg = 0x21004,
+       .m_reg = 0x21008,
+       .n_reg = 0x2100c,
+       .config_reg = 0x21010,
+       .mode_reg = 0x21000,
+       .status_reg = 0x2101c,
+       .status_bit = 17,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo", .name = "xo_board",
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_ops,
+       },
+};
+
+static struct clk_regmap gpll0_vote = {
+       .enable_reg = 0x45000,
+       .enable_mask = BIT(0),
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll0_vote",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll0.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
+static struct clk_pll gpll1 = {
+       .l_reg = 0x20004,
+       .m_reg = 0x20008,
+       .n_reg = 0x2000c,
+       .config_reg = 0x20010,
+       .mode_reg = 0x20000,
+       .status_reg = 0x2001c,
+       .status_bit = 17,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll1",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo", .name = "xo_board",
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_ops,
+       },
+};
+
+static struct clk_regmap gpll1_vote = {
+       .enable_reg = 0x45000,
+       .enable_mask = BIT(1),
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll1_vote",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll1.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
+static struct clk_pll gpll2 = {
+       .l_reg = 0x4a004,
+       .m_reg = 0x4a008,
+       .n_reg = 0x4a00c,
+       .config_reg = 0x4a010,
+       .mode_reg = 0x4a000,
+       .status_reg = 0x4a01c,
+       .status_bit = 17,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll2",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo", .name = "xo_board",
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_ops,
+       },
+};
+
+static struct clk_regmap gpll2_vote = {
+       .enable_reg = 0x45000,
+       .enable_mask = BIT(2),
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll2_vote",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll2.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
+static struct clk_pll bimc_pll = {
+       .l_reg = 0x23004,
+       .m_reg = 0x23008,
+       .n_reg = 0x2300c,
+       .config_reg = 0x23010,
+       .mode_reg = 0x23000,
+       .status_reg = 0x2301c,
+       .status_bit = 17,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "bimc_pll",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo", .name = "xo_board",
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_ops,
+       },
+};
+
+static struct clk_regmap bimc_pll_vote = {
+       .enable_reg = 0x45000,
+       .enable_mask = BIT(3),
+       .hw.init = &(struct clk_init_data){
+               .name = "bimc_pll_vote",
+               .parent_hws = (const struct clk_hw*[]){
+                       &bimc_pll.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
 static const struct parent_map gcc_xo_gpll0_map[] = {
        { P_XO, 0 },
        { P_GPLL0, 1 },
 };
 
-static const char * const gcc_xo_gpll0[] = {
-       "xo",
-       "gpll0_vote",
+static const struct clk_parent_data gcc_xo_gpll0[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll0_vote.hw },
 };
 
 static const struct parent_map gcc_xo_gpll0_bimc_map[] = {
@@ -58,10 +182,10 @@ static const struct parent_map gcc_xo_gpll0_bimc_map[] = {
        { P_BIMC, 2 },
 };
 
-static const char * const gcc_xo_gpll0_bimc[] = {
-       "xo",
-       "gpll0_vote",
-       "bimc_pll_vote",
+static const struct clk_parent_data gcc_xo_gpll0_bimc[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll0_vote.hw },
+       { .hw = &bimc_pll_vote.hw },
 };
 
 static const struct parent_map gcc_xo_gpll0a_gpll1_gpll2a_map[] = {
@@ -71,11 +195,11 @@ static const struct parent_map gcc_xo_gpll0a_gpll1_gpll2a_map[] = {
        { P_GPLL2_AUX, 2 },
 };
 
-static const char * const gcc_xo_gpll0a_gpll1_gpll2a[] = {
-       "xo",
-       "gpll0_vote",
-       "gpll1_vote",
-       "gpll2_vote",
+static const struct clk_parent_data gcc_xo_gpll0a_gpll1_gpll2a[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll0_vote.hw },
+       { .hw = &gpll1_vote.hw },
+       { .hw = &gpll2_vote.hw },
 };
 
 static const struct parent_map gcc_xo_gpll0_gpll2_map[] = {
@@ -84,10 +208,10 @@ static const struct parent_map gcc_xo_gpll0_gpll2_map[] = {
        { P_GPLL2, 2 },
 };
 
-static const char * const gcc_xo_gpll0_gpll2[] = {
-       "xo",
-       "gpll0_vote",
-       "gpll2_vote",
+static const struct clk_parent_data gcc_xo_gpll0_gpll2[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll0_vote.hw },
+       { .hw = &gpll2_vote.hw },
 };
 
 static const struct parent_map gcc_xo_gpll0a_map[] = {
@@ -95,9 +219,9 @@ static const struct parent_map gcc_xo_gpll0a_map[] = {
        { P_GPLL0_AUX, 2 },
 };
 
-static const char * const gcc_xo_gpll0a[] = {
-       "xo",
-       "gpll0_vote",
+static const struct clk_parent_data gcc_xo_gpll0a[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll0_vote.hw },
 };
 
 static const struct parent_map gcc_xo_gpll0_gpll1a_sleep_map[] = {
@@ -107,11 +231,11 @@ static const struct parent_map gcc_xo_gpll0_gpll1a_sleep_map[] = {
        { P_SLEEP_CLK, 6 },
 };
 
-static const char * const gcc_xo_gpll0_gpll1a_sleep[] = {
-       "xo",
-       "gpll0_vote",
-       "gpll1_vote",
-       "sleep_clk",
+static const struct clk_parent_data gcc_xo_gpll0_gpll1a_sleep[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll0_vote.hw },
+       { .hw = &gpll1_vote.hw },
+       { .fw_name = "sleep_clk", .name = "sleep_clk" },
 };
 
 static const struct parent_map gcc_xo_gpll0_gpll1a_map[] = {
@@ -120,10 +244,10 @@ static const struct parent_map gcc_xo_gpll0_gpll1a_map[] = {
        { P_GPLL1_AUX, 2 },
 };
 
-static const char * const gcc_xo_gpll0_gpll1a[] = {
-       "xo",
-       "gpll0_vote",
-       "gpll1_vote",
+static const struct clk_parent_data gcc_xo_gpll0_gpll1a[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll0_vote.hw },
+       { .hw = &gpll1_vote.hw },
 };
 
 static const struct parent_map gcc_xo_dsibyte_map[] = {
@@ -131,9 +255,9 @@ static const struct parent_map gcc_xo_dsibyte_map[] = {
        { P_DSI0_PHYPLL_BYTE, 2 },
 };
 
-static const char * const gcc_xo_dsibyte[] = {
-       "xo",
-       "dsi0pllbyte",
+static const struct clk_parent_data gcc_xo_dsibyte[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .fw_name = "dsi0pllbyte", .name = "dsi0pllbyte" },
 };
 
 static const struct parent_map gcc_xo_gpll0a_dsibyte_map[] = {
@@ -142,10 +266,10 @@ static const struct parent_map gcc_xo_gpll0a_dsibyte_map[] = {
        { P_DSI0_PHYPLL_BYTE, 1 },
 };
 
-static const char * const gcc_xo_gpll0a_dsibyte[] = {
-       "xo",
-       "gpll0_vote",
-       "dsi0pllbyte",
+static const struct clk_parent_data gcc_xo_gpll0a_dsibyte[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll0_vote.hw },
+       { .fw_name = "dsi0pllbyte", .name = "dsi0pllbyte" },
 };
 
 static const struct parent_map gcc_xo_gpll0_dsiphy_map[] = {
@@ -154,10 +278,10 @@ static const struct parent_map gcc_xo_gpll0_dsiphy_map[] = {
        { P_DSI0_PHYPLL_DSI, 2 },
 };
 
-static const char * const gcc_xo_gpll0_dsiphy[] = {
-       "xo",
-       "gpll0_vote",
-       "dsi0pll",
+static const struct clk_parent_data gcc_xo_gpll0_dsiphy[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll0_vote.hw },
+       { .fw_name = "dsi0pll", .name = "dsi0pll" },
 };
 
 static const struct parent_map gcc_xo_gpll0a_dsiphy_map[] = {
@@ -166,10 +290,10 @@ static const struct parent_map gcc_xo_gpll0a_dsiphy_map[] = {
        { P_DSI0_PHYPLL_DSI, 1 },
 };
 
-static const char * const gcc_xo_gpll0a_dsiphy[] = {
-       "xo",
-       "gpll0_vote",
-       "dsi0pll",
+static const struct clk_parent_data gcc_xo_gpll0a_dsiphy[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll0_vote.hw },
+       { .fw_name = "dsi0pll", .name = "dsi0pll" },
 };
 
 static const struct parent_map gcc_xo_gpll0a_gpll1_gpll2_map[] = {
@@ -179,11 +303,11 @@ static const struct parent_map gcc_xo_gpll0a_gpll1_gpll2_map[] = {
        { P_GPLL2, 2 },
 };
 
-static const char * const gcc_xo_gpll0a_gpll1_gpll2[] = {
-       "xo",
-       "gpll0_vote",
-       "gpll1_vote",
-       "gpll2_vote",
+static const struct clk_parent_data gcc_xo_gpll0a_gpll1_gpll2[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll0_vote.hw },
+       { .hw = &gpll1_vote.hw },
+       { .hw = &gpll2_vote.hw },
 };
 
 static const struct parent_map gcc_xo_gpll0_gpll1_sleep_map[] = {
@@ -193,11 +317,11 @@ static const struct parent_map gcc_xo_gpll0_gpll1_sleep_map[] = {
        { P_SLEEP_CLK, 6 }
 };
 
-static const char * const gcc_xo_gpll0_gpll1_sleep[] = {
-       "xo",
-       "gpll0_vote",
-       "gpll1_vote",
-       "sleep_clk",
+static const struct clk_parent_data gcc_xo_gpll0_gpll1_sleep[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll0_vote.hw },
+       { .hw = &gpll1_vote.hw },
+       { .fw_name = "sleep_clk", .name = "sleep_clk" },
 };
 
 static const struct parent_map gcc_xo_gpll1_epi2s_emclk_sleep_map[] = {
@@ -208,12 +332,12 @@ static const struct parent_map gcc_xo_gpll1_epi2s_emclk_sleep_map[] = {
        { P_SLEEP_CLK, 6 }
 };
 
-static const char * const gcc_xo_gpll1_epi2s_emclk_sleep[] = {
-       "xo",
-       "gpll1_vote",
-       "ext_pri_i2s",
-       "ext_mclk",
-       "sleep_clk",
+static const struct clk_parent_data gcc_xo_gpll1_epi2s_emclk_sleep[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll1_vote.hw },
+       { .fw_name = "ext_pri_i2s", .name = "ext_pri_i2s" },
+       { .fw_name = "ext_mclk", .name = "ext_mclk" },
+       { .fw_name = "sleep_clk", .name = "sleep_clk" },
 };
 
 static const struct parent_map gcc_xo_gpll1_esi2s_emclk_sleep_map[] = {
@@ -224,12 +348,12 @@ static const struct parent_map gcc_xo_gpll1_esi2s_emclk_sleep_map[] = {
        { P_SLEEP_CLK, 6 }
 };
 
-static const char * const gcc_xo_gpll1_esi2s_emclk_sleep[] = {
-       "xo",
-       "gpll1_vote",
-       "ext_sec_i2s",
-       "ext_mclk",
-       "sleep_clk",
+static const struct clk_parent_data gcc_xo_gpll1_esi2s_emclk_sleep[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll1_vote.hw },
+       { .fw_name = "ext_sec_i2s", .name = "ext_sec_i2s" },
+       { .fw_name = "ext_mclk", .name = "ext_mclk" },
+       { .fw_name = "sleep_clk", .name = "sleep_clk" },
 };
 
 static const struct parent_map gcc_xo_sleep_map[] = {
@@ -237,9 +361,9 @@ static const struct parent_map gcc_xo_sleep_map[] = {
        { P_SLEEP_CLK, 6 }
 };
 
-static const char * const gcc_xo_sleep[] = {
-       "xo",
-       "sleep_clk",
+static const struct clk_parent_data gcc_xo_sleep[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .fw_name = "sleep_clk", .name = "sleep_clk" },
 };
 
 static const struct parent_map gcc_xo_gpll1_emclk_sleep_map[] = {
@@ -249,119 +373,11 @@ static const struct parent_map gcc_xo_gpll1_emclk_sleep_map[] = {
        { P_SLEEP_CLK, 6 }
 };
 
-static const char * const gcc_xo_gpll1_emclk_sleep[] = {
-       "xo",
-       "gpll1_vote",
-       "ext_mclk",
-       "sleep_clk",
-};
-
-static struct clk_pll gpll0 = {
-       .l_reg = 0x21004,
-       .m_reg = 0x21008,
-       .n_reg = 0x2100c,
-       .config_reg = 0x21010,
-       .mode_reg = 0x21000,
-       .status_reg = 0x2101c,
-       .status_bit = 17,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gpll0",
-               .parent_names = (const char *[]){ "xo" },
-               .num_parents = 1,
-               .ops = &clk_pll_ops,
-       },
-};
-
-static struct clk_regmap gpll0_vote = {
-       .enable_reg = 0x45000,
-       .enable_mask = BIT(0),
-       .hw.init = &(struct clk_init_data){
-               .name = "gpll0_vote",
-               .parent_names = (const char *[]){ "gpll0" },
-               .num_parents = 1,
-               .ops = &clk_pll_vote_ops,
-       },
-};
-
-static struct clk_pll gpll1 = {
-       .l_reg = 0x20004,
-       .m_reg = 0x20008,
-       .n_reg = 0x2000c,
-       .config_reg = 0x20010,
-       .mode_reg = 0x20000,
-       .status_reg = 0x2001c,
-       .status_bit = 17,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gpll1",
-               .parent_names = (const char *[]){ "xo" },
-               .num_parents = 1,
-               .ops = &clk_pll_ops,
-       },
-};
-
-static struct clk_regmap gpll1_vote = {
-       .enable_reg = 0x45000,
-       .enable_mask = BIT(1),
-       .hw.init = &(struct clk_init_data){
-               .name = "gpll1_vote",
-               .parent_names = (const char *[]){ "gpll1" },
-               .num_parents = 1,
-               .ops = &clk_pll_vote_ops,
-       },
-};
-
-static struct clk_pll gpll2 = {
-       .l_reg = 0x4a004,
-       .m_reg = 0x4a008,
-       .n_reg = 0x4a00c,
-       .config_reg = 0x4a010,
-       .mode_reg = 0x4a000,
-       .status_reg = 0x4a01c,
-       .status_bit = 17,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gpll2",
-               .parent_names = (const char *[]){ "xo" },
-               .num_parents = 1,
-               .ops = &clk_pll_ops,
-       },
-};
-
-static struct clk_regmap gpll2_vote = {
-       .enable_reg = 0x45000,
-       .enable_mask = BIT(2),
-       .hw.init = &(struct clk_init_data){
-               .name = "gpll2_vote",
-               .parent_names = (const char *[]){ "gpll2" },
-               .num_parents = 1,
-               .ops = &clk_pll_vote_ops,
-       },
-};
-
-static struct clk_pll bimc_pll = {
-       .l_reg = 0x23004,
-       .m_reg = 0x23008,
-       .n_reg = 0x2300c,
-       .config_reg = 0x23010,
-       .mode_reg = 0x23000,
-       .status_reg = 0x2301c,
-       .status_bit = 17,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "bimc_pll",
-               .parent_names = (const char *[]){ "xo" },
-               .num_parents = 1,
-               .ops = &clk_pll_ops,
-       },
-};
-
-static struct clk_regmap bimc_pll_vote = {
-       .enable_reg = 0x45000,
-       .enable_mask = BIT(3),
-       .hw.init = &(struct clk_init_data){
-               .name = "bimc_pll_vote",
-               .parent_names = (const char *[]){ "bimc_pll" },
-               .num_parents = 1,
-               .ops = &clk_pll_vote_ops,
-       },
+static const struct clk_parent_data gcc_xo_gpll1_emclk_sleep[] = {
+       { .fw_name = "xo", .name = "xo_board" },
+       { .hw = &gpll1_vote.hw },
+       { .fw_name = "ext_mclk", .name = "ext_mclk" },
+       { .fw_name = "sleep_clk", .name = "sleep_clk" },
 };
 
 static struct clk_rcg2 pcnoc_bfdcd_clk_src = {
@@ -370,8 +386,8 @@ static struct clk_rcg2 pcnoc_bfdcd_clk_src = {
        .parent_map = gcc_xo_gpll0_bimc_map,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pcnoc_bfdcd_clk_src",
-               .parent_names = gcc_xo_gpll0_bimc,
-               .num_parents = 3,
+               .parent_data = gcc_xo_gpll0_bimc,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -382,8 +398,8 @@ static struct clk_rcg2 system_noc_bfdcd_clk_src = {
        .parent_map = gcc_xo_gpll0_bimc_map,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "system_noc_bfdcd_clk_src",
-               .parent_names = gcc_xo_gpll0_bimc,
-               .num_parents = 3,
+               .parent_data = gcc_xo_gpll0_bimc,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -402,8 +418,8 @@ static struct clk_rcg2 camss_ahb_clk_src = {
        .freq_tbl = ftbl_gcc_camss_ahb_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "camss_ahb_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -423,8 +439,8 @@ static struct clk_rcg2 apss_ahb_clk_src = {
        .freq_tbl = ftbl_apss_ahb_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "apss_ahb_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -442,8 +458,8 @@ static struct clk_rcg2 csi0_clk_src = {
        .freq_tbl = ftbl_gcc_camss_csi0_1_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "csi0_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -455,8 +471,8 @@ static struct clk_rcg2 csi1_clk_src = {
        .freq_tbl = ftbl_gcc_camss_csi0_1_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "csi1_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -483,8 +499,8 @@ static struct clk_rcg2 gfx3d_clk_src = {
        .freq_tbl = ftbl_gcc_oxili_gfx3d_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gfx3d_clk_src",
-               .parent_names = gcc_xo_gpll0a_gpll1_gpll2a,
-               .num_parents = 4,
+               .parent_data = gcc_xo_gpll0a_gpll1_gpll2a,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_gpll1_gpll2a),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -510,8 +526,8 @@ static struct clk_rcg2 vfe0_clk_src = {
        .freq_tbl = ftbl_gcc_camss_vfe0_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "vfe0_clk_src",
-               .parent_names = gcc_xo_gpll0_gpll2,
-               .num_parents = 3,
+               .parent_data = gcc_xo_gpll0_gpll2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll2),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -529,8 +545,8 @@ static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
        .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup1_i2c_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -558,8 +574,8 @@ static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
        .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup1_spi_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -571,8 +587,8 @@ static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
        .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup2_i2c_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -585,8 +601,8 @@ static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
        .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup2_spi_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -598,8 +614,8 @@ static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
        .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup3_i2c_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -612,8 +628,8 @@ static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
        .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup3_spi_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -625,8 +641,8 @@ static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
        .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup4_i2c_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -639,8 +655,8 @@ static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
        .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup4_spi_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -652,8 +668,8 @@ static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = {
        .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup5_i2c_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -666,8 +682,8 @@ static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = {
        .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup5_spi_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -679,8 +695,8 @@ static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = {
        .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup6_i2c_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -693,8 +709,8 @@ static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = {
        .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup6_spi_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -726,8 +742,8 @@ static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
        .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_uart1_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -740,8 +756,8 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
        .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_uart2_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -759,8 +775,8 @@ static struct clk_rcg2 cci_clk_src = {
        .freq_tbl = ftbl_gcc_camss_cci_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "cci_clk_src",
-               .parent_names = gcc_xo_gpll0a,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0a,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0a),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -792,8 +808,8 @@ static struct clk_rcg2 camss_gp0_clk_src = {
        .freq_tbl = ftbl_gcc_camss_gp0_1_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "camss_gp0_clk_src",
-               .parent_names = gcc_xo_gpll0_gpll1a_sleep,
-               .num_parents = 4,
+               .parent_data = gcc_xo_gpll0_gpll1a_sleep,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -806,8 +822,8 @@ static struct clk_rcg2 camss_gp1_clk_src = {
        .freq_tbl = ftbl_gcc_camss_gp0_1_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "camss_gp1_clk_src",
-               .parent_names = gcc_xo_gpll0_gpll1a_sleep,
-               .num_parents = 4,
+               .parent_data = gcc_xo_gpll0_gpll1a_sleep,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -826,8 +842,8 @@ static struct clk_rcg2 jpeg0_clk_src = {
        .freq_tbl = ftbl_gcc_camss_jpeg0_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "jpeg0_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -847,8 +863,8 @@ static struct clk_rcg2 mclk0_clk_src = {
        .freq_tbl = ftbl_gcc_camss_mclk0_1_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "mclk0_clk_src",
-               .parent_names = gcc_xo_gpll0_gpll1a_sleep,
-               .num_parents = 4,
+               .parent_data = gcc_xo_gpll0_gpll1a_sleep,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -861,8 +877,8 @@ static struct clk_rcg2 mclk1_clk_src = {
        .freq_tbl = ftbl_gcc_camss_mclk0_1_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "mclk1_clk_src",
-               .parent_names = gcc_xo_gpll0_gpll1a_sleep,
-               .num_parents = 4,
+               .parent_data = gcc_xo_gpll0_gpll1a_sleep,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -880,8 +896,8 @@ static struct clk_rcg2 csi0phytimer_clk_src = {
        .freq_tbl = ftbl_gcc_camss_csi0_1phytimer_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "csi0phytimer_clk_src",
-               .parent_names = gcc_xo_gpll0_gpll1a,
-               .num_parents = 3,
+               .parent_data = gcc_xo_gpll0_gpll1a,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -893,8 +909,8 @@ static struct clk_rcg2 csi1phytimer_clk_src = {
        .freq_tbl = ftbl_gcc_camss_csi0_1phytimer_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "csi1phytimer_clk_src",
-               .parent_names = gcc_xo_gpll0_gpll1a,
-               .num_parents = 3,
+               .parent_data = gcc_xo_gpll0_gpll1a,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -913,8 +929,8 @@ static struct clk_rcg2 cpp_clk_src = {
        .freq_tbl = ftbl_gcc_camss_cpp_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "cpp_clk_src",
-               .parent_names = gcc_xo_gpll0_gpll2,
-               .num_parents = 3,
+               .parent_data = gcc_xo_gpll0_gpll2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll2),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -934,8 +950,8 @@ static struct clk_rcg2 crypto_clk_src = {
        .freq_tbl = ftbl_gcc_crypto_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "crypto_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -975,8 +991,8 @@ static struct clk_rcg2 gp1_clk_src = {
        .freq_tbl = ftbl_gcc_gp1_3_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gp1_clk_src",
-               .parent_names = gcc_xo_gpll0_gpll1a_sleep,
-               .num_parents = 3,
+               .parent_data = gcc_xo_gpll0_gpll1a_sleep,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -989,8 +1005,8 @@ static struct clk_rcg2 gp2_clk_src = {
        .freq_tbl = ftbl_gcc_gp1_3_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gp2_clk_src",
-               .parent_names = gcc_xo_gpll0_gpll1a_sleep,
-               .num_parents = 3,
+               .parent_data = gcc_xo_gpll0_gpll1a_sleep,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1003,8 +1019,8 @@ static struct clk_rcg2 gp3_clk_src = {
        .freq_tbl = ftbl_gcc_gp1_3_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gp3_clk_src",
-               .parent_names = gcc_xo_gpll0_gpll1a_sleep,
-               .num_parents = 3,
+               .parent_data = gcc_xo_gpll0_gpll1a_sleep,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1015,8 +1031,8 @@ static struct clk_rcg2 byte0_clk_src = {
        .parent_map = gcc_xo_gpll0a_dsibyte_map,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "byte0_clk_src",
-               .parent_names = gcc_xo_gpll0a_dsibyte,
-               .num_parents = 3,
+               .parent_data = gcc_xo_gpll0a_dsibyte,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_dsibyte),
                .ops = &clk_byte2_ops,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1034,8 +1050,8 @@ static struct clk_rcg2 esc0_clk_src = {
        .freq_tbl = ftbl_gcc_mdss_esc0_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "esc0_clk_src",
-               .parent_names = gcc_xo_dsibyte,
-               .num_parents = 2,
+               .parent_data = gcc_xo_dsibyte,
+               .num_parents = ARRAY_SIZE(gcc_xo_dsibyte),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1059,8 +1075,8 @@ static struct clk_rcg2 mdp_clk_src = {
        .freq_tbl = ftbl_gcc_mdss_mdp_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "mdp_clk_src",
-               .parent_names = gcc_xo_gpll0_dsiphy,
-               .num_parents = 3,
+               .parent_data = gcc_xo_gpll0_dsiphy,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_dsiphy),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1072,8 +1088,8 @@ static struct clk_rcg2 pclk0_clk_src = {
        .parent_map = gcc_xo_gpll0a_dsiphy_map,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pclk0_clk_src",
-               .parent_names = gcc_xo_gpll0a_dsiphy,
-               .num_parents = 3,
+               .parent_data = gcc_xo_gpll0a_dsiphy,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_dsiphy),
                .ops = &clk_pixel_ops,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1091,8 +1107,8 @@ static struct clk_rcg2 vsync_clk_src = {
        .freq_tbl = ftbl_gcc_mdss_vsync_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "vsync_clk_src",
-               .parent_names = gcc_xo_gpll0a,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0a,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0a),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1109,8 +1125,8 @@ static struct clk_rcg2 pdm2_clk_src = {
        .freq_tbl = ftbl_gcc_pdm2_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pdm2_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1134,8 +1150,8 @@ static struct clk_rcg2 sdcc1_apps_clk_src = {
        .freq_tbl = ftbl_gcc_sdcc1_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "sdcc1_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_floor_ops,
        },
 };
@@ -1159,8 +1175,8 @@ static struct clk_rcg2 sdcc2_apps_clk_src = {
        .freq_tbl = ftbl_gcc_sdcc2_apps_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "sdcc2_apps_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_floor_ops,
        },
 };
@@ -1179,8 +1195,8 @@ static struct clk_rcg2 apss_tcu_clk_src = {
        .freq_tbl = ftbl_gcc_apss_tcu_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "apss_tcu_clk_src",
-               .parent_names = gcc_xo_gpll0a_gpll1_gpll2,
-               .num_parents = 4,
+               .parent_data = gcc_xo_gpll0a_gpll1_gpll2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_gpll1_gpll2),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1202,8 +1218,8 @@ static struct clk_rcg2 bimc_gpu_clk_src = {
        .freq_tbl = ftbl_gcc_bimc_gpu_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "bimc_gpu_clk_src",
-               .parent_names = gcc_xo_gpll0_bimc,
-               .num_parents = 3,
+               .parent_data = gcc_xo_gpll0_bimc,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc),
                .flags = CLK_GET_RATE_NOCACHE,
                .ops = &clk_rcg2_ops,
        },
@@ -1221,8 +1237,8 @@ static struct clk_rcg2 usb_hs_system_clk_src = {
        .freq_tbl = ftbl_gcc_usb_hs_system_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "usb_hs_system_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1247,8 +1263,8 @@ static struct clk_rcg2 ultaudio_ahbfabric_clk_src = {
        .freq_tbl = ftbl_gcc_ultaudio_ahb_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "ultaudio_ahbfabric_clk_src",
-               .parent_names = gcc_xo_gpll0_gpll1_sleep,
-               .num_parents = 4,
+               .parent_data = gcc_xo_gpll0_gpll1_sleep,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1_sleep),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1260,8 +1276,8 @@ static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_ahbfabric_ixfabric_clk",
-                       .parent_names = (const char *[]){
-                               "ultaudio_ahbfabric_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ultaudio_ahbfabric_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1277,8 +1293,8 @@ static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_lpm_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_ahbfabric_ixfabric_lpm_clk",
-                       .parent_names = (const char *[]){
-                               "ultaudio_ahbfabric_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ultaudio_ahbfabric_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1326,8 +1342,8 @@ static struct clk_rcg2 ultaudio_lpaif_pri_i2s_clk_src = {
        .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "ultaudio_lpaif_pri_i2s_clk_src",
-               .parent_names = gcc_xo_gpll1_epi2s_emclk_sleep,
-               .num_parents = 5,
+               .parent_data = gcc_xo_gpll1_epi2s_emclk_sleep,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll1_epi2s_emclk_sleep),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1339,8 +1355,8 @@ static struct clk_branch gcc_ultaudio_lpaif_pri_i2s_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_lpaif_pri_i2s_clk",
-                       .parent_names = (const char *[]){
-                               "ultaudio_lpaif_pri_i2s_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ultaudio_lpaif_pri_i2s_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1357,8 +1373,8 @@ static struct clk_rcg2 ultaudio_lpaif_sec_i2s_clk_src = {
        .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "ultaudio_lpaif_sec_i2s_clk_src",
-               .parent_names = gcc_xo_gpll1_esi2s_emclk_sleep,
-               .num_parents = 5,
+               .parent_data = gcc_xo_gpll1_esi2s_emclk_sleep,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll1_esi2s_emclk_sleep),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1370,8 +1386,8 @@ static struct clk_branch gcc_ultaudio_lpaif_sec_i2s_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_lpaif_sec_i2s_clk",
-                       .parent_names = (const char *[]){
-                               "ultaudio_lpaif_sec_i2s_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ultaudio_lpaif_sec_i2s_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1388,8 +1404,8 @@ static struct clk_rcg2 ultaudio_lpaif_aux_i2s_clk_src = {
        .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "ultaudio_lpaif_aux_i2s_clk_src",
-               .parent_names = gcc_xo_gpll1_esi2s_emclk_sleep,
-               .num_parents = 5,
+               .parent_data = gcc_xo_gpll1_esi2s_emclk_sleep,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll1_esi2s_emclk_sleep),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1401,8 +1417,8 @@ static struct clk_branch gcc_ultaudio_lpaif_aux_i2s_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_lpaif_aux_i2s_clk",
-                       .parent_names = (const char *[]){
-                               "ultaudio_lpaif_aux_i2s_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ultaudio_lpaif_aux_i2s_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1423,8 +1439,8 @@ static struct clk_rcg2 ultaudio_xo_clk_src = {
        .freq_tbl = ftbl_gcc_ultaudio_xo_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "ultaudio_xo_clk_src",
-               .parent_names = gcc_xo_sleep,
-               .num_parents = 2,
+               .parent_data = gcc_xo_sleep,
+               .num_parents = ARRAY_SIZE(gcc_xo_sleep),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1436,8 +1452,8 @@ static struct clk_branch gcc_ultaudio_avsync_xo_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_avsync_xo_clk",
-                       .parent_names = (const char *[]){
-                               "ultaudio_xo_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ultaudio_xo_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1453,8 +1469,8 @@ static struct clk_branch gcc_ultaudio_stc_xo_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_stc_xo_clk",
-                       .parent_names = (const char *[]){
-                               "ultaudio_xo_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ultaudio_xo_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1479,8 +1495,8 @@ static struct clk_rcg2 codec_digcodec_clk_src = {
        .freq_tbl = ftbl_codec_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "codec_digcodec_clk_src",
-               .parent_names = gcc_xo_gpll1_emclk_sleep,
-               .num_parents = 4,
+               .parent_data = gcc_xo_gpll1_emclk_sleep,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll1_emclk_sleep),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1492,8 +1508,8 @@ static struct clk_branch gcc_codec_digcodec_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_codec_digcodec_clk",
-                       .parent_names = (const char *[]){
-                               "codec_digcodec_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &codec_digcodec_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1509,8 +1525,8 @@ static struct clk_branch gcc_ultaudio_pcnoc_mport_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_pcnoc_mport_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1525,8 +1541,8 @@ static struct clk_branch gcc_ultaudio_pcnoc_sway_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_pcnoc_sway_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1549,8 +1565,8 @@ static struct clk_rcg2 vcodec0_clk_src = {
        .freq_tbl = ftbl_gcc_venus0_vcodec0_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "vcodec0_clk_src",
-               .parent_names = gcc_xo_gpll0,
-               .num_parents = 2,
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1563,8 +1579,8 @@ static struct clk_branch gcc_blsp1_ahb_clk = {
                .enable_mask = BIT(10),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1579,8 +1595,8 @@ static struct clk_branch gcc_blsp1_sleep_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_sleep_clk",
-                       .parent_names = (const char *[]){
-                               "sleep_clk_src",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "sleep_clk", .name = "sleep_clk_src",
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1596,8 +1612,8 @@ static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup1_i2c_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup1_i2c_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup1_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1613,8 +1629,8 @@ static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup1_spi_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup1_spi_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup1_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1630,8 +1646,8 @@ static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup2_i2c_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup2_i2c_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup2_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1647,8 +1663,8 @@ static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup2_spi_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup2_spi_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup2_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1664,8 +1680,8 @@ static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup3_i2c_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup3_i2c_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup3_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1681,8 +1697,8 @@ static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup3_spi_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup3_spi_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup3_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1698,8 +1714,8 @@ static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup4_i2c_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup4_i2c_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup4_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1715,8 +1731,8 @@ static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup4_spi_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup4_spi_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup4_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1732,8 +1748,8 @@ static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup5_i2c_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup5_i2c_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup5_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1749,8 +1765,8 @@ static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup5_spi_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup5_spi_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup5_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1766,8 +1782,8 @@ static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup6_i2c_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup6_i2c_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup6_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1783,8 +1799,8 @@ static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup6_spi_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup6_spi_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup6_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1800,8 +1816,8 @@ static struct clk_branch gcc_blsp1_uart1_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_uart1_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_uart1_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_uart1_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1817,8 +1833,8 @@ static struct clk_branch gcc_blsp1_uart2_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_uart2_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_uart2_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_uart2_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1835,8 +1851,8 @@ static struct clk_branch gcc_boot_rom_ahb_clk = {
                .enable_mask = BIT(7),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_boot_rom_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1851,8 +1867,8 @@ static struct clk_branch gcc_camss_cci_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_cci_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "camss_ahb_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1868,8 +1884,8 @@ static struct clk_branch gcc_camss_cci_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_cci_clk",
-                       .parent_names = (const char *[]){
-                               "cci_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &cci_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1885,8 +1901,8 @@ static struct clk_branch gcc_camss_csi0_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi0_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "camss_ahb_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1902,8 +1918,8 @@ static struct clk_branch gcc_camss_csi0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi0_clk",
-                       .parent_names = (const char *[]){
-                               "csi0_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1919,8 +1935,8 @@ static struct clk_branch gcc_camss_csi0phy_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi0phy_clk",
-                       .parent_names = (const char *[]){
-                               "csi0_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1936,8 +1952,8 @@ static struct clk_branch gcc_camss_csi0pix_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi0pix_clk",
-                       .parent_names = (const char *[]){
-                               "csi0_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1953,8 +1969,8 @@ static struct clk_branch gcc_camss_csi0rdi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi0rdi_clk",
-                       .parent_names = (const char *[]){
-                               "csi0_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1970,8 +1986,8 @@ static struct clk_branch gcc_camss_csi1_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi1_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "camss_ahb_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1987,8 +2003,8 @@ static struct clk_branch gcc_camss_csi1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi1_clk",
-                       .parent_names = (const char *[]){
-                               "csi1_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2004,8 +2020,8 @@ static struct clk_branch gcc_camss_csi1phy_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi1phy_clk",
-                       .parent_names = (const char *[]){
-                               "csi1_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2021,8 +2037,8 @@ static struct clk_branch gcc_camss_csi1pix_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi1pix_clk",
-                       .parent_names = (const char *[]){
-                               "csi1_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2038,8 +2054,8 @@ static struct clk_branch gcc_camss_csi1rdi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi1rdi_clk",
-                       .parent_names = (const char *[]){
-                               "csi1_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2055,8 +2071,8 @@ static struct clk_branch gcc_camss_csi_vfe0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi_vfe0_clk",
-                       .parent_names = (const char *[]){
-                               "vfe0_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vfe0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2072,8 +2088,8 @@ static struct clk_branch gcc_camss_gp0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_gp0_clk",
-                       .parent_names = (const char *[]){
-                               "camss_gp0_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_gp0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2089,8 +2105,8 @@ static struct clk_branch gcc_camss_gp1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_gp1_clk",
-                       .parent_names = (const char *[]){
-                               "camss_gp1_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_gp1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2106,8 +2122,8 @@ static struct clk_branch gcc_camss_ispif_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_ispif_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "camss_ahb_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2123,8 +2139,8 @@ static struct clk_branch gcc_camss_jpeg0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_jpeg0_clk",
-                       .parent_names = (const char *[]){
-                               "jpeg0_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &jpeg0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2140,8 +2156,8 @@ static struct clk_branch gcc_camss_jpeg_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_jpeg_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "camss_ahb_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2157,8 +2173,8 @@ static struct clk_branch gcc_camss_jpeg_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_jpeg_axi_clk",
-                       .parent_names = (const char *[]){
-                               "system_noc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2174,8 +2190,8 @@ static struct clk_branch gcc_camss_mclk0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_mclk0_clk",
-                       .parent_names = (const char *[]){
-                               "mclk0_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &mclk0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2191,8 +2207,8 @@ static struct clk_branch gcc_camss_mclk1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_mclk1_clk",
-                       .parent_names = (const char *[]){
-                               "mclk1_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &mclk1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2208,8 +2224,8 @@ static struct clk_branch gcc_camss_micro_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_micro_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "camss_ahb_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2225,8 +2241,8 @@ static struct clk_branch gcc_camss_csi0phytimer_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi0phytimer_clk",
-                       .parent_names = (const char *[]){
-                               "csi0phytimer_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0phytimer_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2242,8 +2258,8 @@ static struct clk_branch gcc_camss_csi1phytimer_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi1phytimer_clk",
-                       .parent_names = (const char *[]){
-                               "csi1phytimer_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1phytimer_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2259,8 +2275,8 @@ static struct clk_branch gcc_camss_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "camss_ahb_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2276,8 +2292,8 @@ static struct clk_branch gcc_camss_top_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_top_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2293,8 +2309,8 @@ static struct clk_branch gcc_camss_cpp_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_cpp_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "camss_ahb_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2310,8 +2326,8 @@ static struct clk_branch gcc_camss_cpp_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_cpp_clk",
-                       .parent_names = (const char *[]){
-                               "cpp_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &cpp_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2327,8 +2343,8 @@ static struct clk_branch gcc_camss_vfe0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_vfe0_clk",
-                       .parent_names = (const char *[]){
-                               "vfe0_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vfe0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2344,8 +2360,8 @@ static struct clk_branch gcc_camss_vfe_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_vfe_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "camss_ahb_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2361,8 +2377,8 @@ static struct clk_branch gcc_camss_vfe_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_vfe_axi_clk",
-                       .parent_names = (const char *[]){
-                               "system_noc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2379,8 +2395,8 @@ static struct clk_branch gcc_crypto_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_crypto_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2397,8 +2413,8 @@ static struct clk_branch gcc_crypto_axi_clk = {
                .enable_mask = BIT(1),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_crypto_axi_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2415,8 +2431,8 @@ static struct clk_branch gcc_crypto_clk = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_crypto_clk",
-                       .parent_names = (const char *[]){
-                               "crypto_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &crypto_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2432,8 +2448,8 @@ static struct clk_branch gcc_oxili_gmem_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_oxili_gmem_clk",
-                       .parent_names = (const char *[]){
-                               "gfx3d_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gfx3d_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2449,8 +2465,8 @@ static struct clk_branch gcc_gp1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gp1_clk",
-                       .parent_names = (const char *[]){
-                               "gp1_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2466,8 +2482,8 @@ static struct clk_branch gcc_gp2_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gp2_clk",
-                       .parent_names = (const char *[]){
-                               "gp2_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp2_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2483,8 +2499,8 @@ static struct clk_branch gcc_gp3_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gp3_clk",
-                       .parent_names = (const char *[]){
-                               "gp3_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp3_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2500,8 +2516,8 @@ static struct clk_branch gcc_mdss_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2517,8 +2533,8 @@ static struct clk_branch gcc_mdss_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_axi_clk",
-                       .parent_names = (const char *[]){
-                               "system_noc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2534,8 +2550,8 @@ static struct clk_branch gcc_mdss_byte0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_byte0_clk",
-                       .parent_names = (const char *[]){
-                               "byte0_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &byte0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2551,8 +2567,8 @@ static struct clk_branch gcc_mdss_esc0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_esc0_clk",
-                       .parent_names = (const char *[]){
-                               "esc0_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &esc0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2568,8 +2584,8 @@ static struct clk_branch gcc_mdss_mdp_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_mdp_clk",
-                       .parent_names = (const char *[]){
-                               "mdp_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &mdp_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2585,8 +2601,8 @@ static struct clk_branch gcc_mdss_pclk0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_pclk0_clk",
-                       .parent_names = (const char *[]){
-                               "pclk0_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pclk0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2602,8 +2618,8 @@ static struct clk_branch gcc_mdss_vsync_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_vsync_clk",
-                       .parent_names = (const char *[]){
-                               "vsync_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vsync_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2619,25 +2635,8 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mss_cfg_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
-                       },
-                       .num_parents = 1,
-                       .flags = CLK_SET_RATE_PARENT,
-                       .ops = &clk_branch2_ops,
-               },
-       },
-};
-
-static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
-       .halt_reg = 0x49004,
-       .clkr = {
-               .enable_reg = 0x49004,
-               .enable_mask = BIT(0),
-               .hw.init = &(struct clk_init_data){
-                       .name = "gcc_mss_q6_bimc_axi_clk",
-                       .parent_names = (const char *[]){
-                               "bimc_ddr_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2653,8 +2652,8 @@ static struct clk_branch gcc_oxili_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_oxili_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2670,8 +2669,8 @@ static struct clk_branch gcc_oxili_gfx3d_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_oxili_gfx3d_clk",
-                       .parent_names = (const char *[]){
-                               "gfx3d_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gfx3d_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2687,8 +2686,8 @@ static struct clk_branch gcc_pdm2_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_pdm2_clk",
-                       .parent_names = (const char *[]){
-                               "pdm2_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pdm2_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2704,8 +2703,8 @@ static struct clk_branch gcc_pdm_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_pdm_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2722,8 +2721,8 @@ static struct clk_branch gcc_prng_ahb_clk = {
                .enable_mask = BIT(8),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_prng_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -2738,8 +2737,8 @@ static struct clk_branch gcc_sdcc1_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc1_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2755,8 +2754,8 @@ static struct clk_branch gcc_sdcc1_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc1_apps_clk",
-                       .parent_names = (const char *[]){
-                               "sdcc1_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdcc1_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2772,8 +2771,8 @@ static struct clk_branch gcc_sdcc2_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc2_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2789,8 +2788,8 @@ static struct clk_branch gcc_sdcc2_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc2_apps_clk",
-                       .parent_names = (const char *[]){
-                               "sdcc2_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdcc2_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2805,13 +2804,30 @@ static struct clk_rcg2 bimc_ddr_clk_src = {
        .parent_map = gcc_xo_gpll0_bimc_map,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "bimc_ddr_clk_src",
-               .parent_names = gcc_xo_gpll0_bimc,
-               .num_parents = 3,
+               .parent_data = gcc_xo_gpll0_bimc,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc),
                .ops = &clk_rcg2_ops,
                .flags = CLK_GET_RATE_NOCACHE,
        },
 };
 
+static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
+       .halt_reg = 0x49004,
+       .clkr = {
+               .enable_reg = 0x49004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_q6_bimc_axi_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &bimc_ddr_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_branch gcc_apss_tcu_clk = {
        .halt_reg = 0x12018,
        .clkr = {
@@ -2819,8 +2835,8 @@ static struct clk_branch gcc_apss_tcu_clk = {
                .enable_mask = BIT(1),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_apss_tcu_clk",
-                       .parent_names = (const char *[]){
-                               "bimc_ddr_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &bimc_ddr_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -2835,8 +2851,8 @@ static struct clk_branch gcc_gfx_tcu_clk = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gfx_tcu_clk",
-                       .parent_names = (const char *[]){
-                               "bimc_ddr_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &bimc_ddr_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -2851,8 +2867,8 @@ static struct clk_branch gcc_gtcu_ahb_clk = {
                .enable_mask = BIT(13),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gtcu_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2868,8 +2884,8 @@ static struct clk_branch gcc_bimc_gfx_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_bimc_gfx_clk",
-                       .parent_names = (const char *[]){
-                               "bimc_gpu_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &bimc_gpu_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2885,8 +2901,8 @@ static struct clk_branch gcc_bimc_gpu_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_bimc_gpu_clk",
-                       .parent_names = (const char *[]){
-                               "bimc_gpu_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &bimc_gpu_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2902,8 +2918,8 @@ static struct clk_branch gcc_jpeg_tbu_clk = {
                .enable_mask = BIT(10),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_jpeg_tbu_clk",
-                       .parent_names = (const char *[]){
-                               "system_noc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2919,8 +2935,8 @@ static struct clk_branch gcc_mdp_tbu_clk = {
                .enable_mask = BIT(4),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdp_tbu_clk",
-                       .parent_names = (const char *[]){
-                               "system_noc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2936,8 +2952,8 @@ static struct clk_branch gcc_smmu_cfg_clk = {
                .enable_mask = BIT(12),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_smmu_cfg_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2953,8 +2969,8 @@ static struct clk_branch gcc_venus_tbu_clk = {
                .enable_mask = BIT(5),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_venus_tbu_clk",
-                       .parent_names = (const char *[]){
-                               "system_noc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2970,8 +2986,8 @@ static struct clk_branch gcc_vfe_tbu_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_vfe_tbu_clk",
-                       .parent_names = (const char *[]){
-                               "system_noc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2987,8 +3003,8 @@ static struct clk_branch gcc_usb2a_phy_sleep_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb2a_phy_sleep_clk",
-                       .parent_names = (const char *[]){
-                               "sleep_clk_src",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "sleep_clk", .name = "sleep_clk_src",
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3004,8 +3020,8 @@ static struct clk_branch gcc_usb_hs_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb_hs_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3021,8 +3037,8 @@ static struct clk_branch gcc_usb_hs_system_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb_hs_system_clk",
-                       .parent_names = (const char *[]){
-                               "usb_hs_system_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_hs_system_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3038,8 +3054,8 @@ static struct clk_branch gcc_venus0_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_venus0_ahb_clk",
-                       .parent_names = (const char *[]){
-                               "pcnoc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3055,8 +3071,8 @@ static struct clk_branch gcc_venus0_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_venus0_axi_clk",
-                       .parent_names = (const char *[]){
-                               "system_noc_bfdcd_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3072,8 +3088,8 @@ static struct clk_branch gcc_venus0_vcodec0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_venus0_vcodec0_clk",
-                       .parent_names = (const char *[]){
-                               "vcodec0_clk_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vcodec0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
index 8e2d9fb..af608f1 100644 (file)
@@ -614,7 +614,7 @@ static struct clk_rcg2 pcnoc_bfdcd_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pcnoc_bfdcd_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -626,7 +626,7 @@ static struct clk_rcg2 system_noc_bfdcd_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "system_noc_bfdcd_clk_src",
                .parent_data = gcc_xo_gpll0_gpll6a_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll6a_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -638,7 +638,7 @@ static struct clk_rcg2 bimc_ddr_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "bimc_ddr_clk_src",
                .parent_data = gcc_xo_gpll0_bimc_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc_parent_data),
                .ops = &clk_rcg2_ops,
                .flags = CLK_GET_RATE_NOCACHE,
        },
@@ -651,7 +651,7 @@ static struct clk_rcg2 system_mm_noc_bfdcd_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "system_mm_noc_bfdcd_clk_src",
                .parent_data = gcc_xo_gpll0_gpll6a_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll6a_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -671,7 +671,7 @@ static struct clk_rcg2 camss_ahb_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "camss_ahb_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -692,7 +692,7 @@ static struct clk_rcg2 apss_ahb_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "apss_ahb_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -711,7 +711,7 @@ static struct clk_rcg2 csi0_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "csi0_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -724,7 +724,7 @@ static struct clk_rcg2 csi1_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "csi1_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -753,7 +753,7 @@ static struct clk_rcg2 gfx3d_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gfx3d_clk_src",
                .parent_data = gcc_xo_gpll0_gpll2a_gpll3_gpll6a_parent_data,
-               .num_parents = 5,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll2a_gpll3_gpll6a_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -782,7 +782,7 @@ static struct clk_rcg2 vfe0_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "vfe0_clk_src",
                .parent_data = gcc_xo_gpll0_gpll2_gpll4_parent_data,
-               .num_parents = 4,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll2_gpll4_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -801,7 +801,7 @@ static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup1_i2c_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -826,7 +826,7 @@ static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup1_spi_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -839,7 +839,7 @@ static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup2_i2c_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -853,7 +853,7 @@ static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup2_spi_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -866,7 +866,7 @@ static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup3_i2c_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -880,7 +880,7 @@ static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup3_spi_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -893,7 +893,7 @@ static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup4_i2c_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -907,7 +907,7 @@ static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup4_spi_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -920,7 +920,7 @@ static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup5_i2c_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -934,7 +934,7 @@ static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup5_spi_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -947,7 +947,7 @@ static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup6_i2c_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -961,7 +961,7 @@ static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup6_spi_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -994,7 +994,7 @@ static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_uart1_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1008,7 +1008,7 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_uart2_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1028,7 +1028,7 @@ static struct clk_rcg2 cci_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "cci_clk_src",
                .parent_data = gcc_xo_gpll0a_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1048,7 +1048,7 @@ static struct clk_rcg2 camss_gp0_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "camss_gp0_clk_src",
                .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
-               .num_parents = 4,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1062,7 +1062,7 @@ static struct clk_rcg2 camss_gp1_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "camss_gp1_clk_src",
                .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
-               .num_parents = 4,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1082,7 +1082,7 @@ static struct clk_rcg2 jpeg0_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "jpeg0_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1102,7 +1102,7 @@ static struct clk_rcg2 mclk0_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "mclk0_clk_src",
                .parent_data = gcc_xo_gpll0_gpll1a_gpll6_sleep_parent_data,
-               .num_parents = 5,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_gpll6_sleep_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1116,7 +1116,7 @@ static struct clk_rcg2 mclk1_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "mclk1_clk_src",
                .parent_data = gcc_xo_gpll0_gpll1a_gpll6_sleep_parent_data,
-               .num_parents = 5,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_gpll6_sleep_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1135,7 +1135,7 @@ static struct clk_rcg2 csi0phytimer_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "csi0phytimer_clk_src",
                .parent_data = gcc_xo_gpll0_gpll1a_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1148,7 +1148,7 @@ static struct clk_rcg2 csi1phytimer_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "csi1phytimer_clk_src",
                .parent_data = gcc_xo_gpll0_gpll1a_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1171,7 +1171,7 @@ static struct clk_rcg2 cpp_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "cpp_clk_src",
                .parent_data = gcc_xo_gpll0_gpll2_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll2_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1193,7 +1193,7 @@ static struct clk_rcg2 crypto_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "crypto_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1212,7 +1212,7 @@ static struct clk_rcg2 gp1_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gp1_clk_src",
                .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1226,7 +1226,7 @@ static struct clk_rcg2 gp2_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gp2_clk_src",
                .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1240,7 +1240,7 @@ static struct clk_rcg2 gp3_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gp3_clk_src",
                .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1252,7 +1252,7 @@ static struct clk_rcg2 byte0_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "byte0_clk_src",
                .parent_data = gcc_xo_gpll0a_dsibyte_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_dsibyte_parent_data),
                .ops = &clk_byte2_ops,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1265,7 +1265,7 @@ static struct clk_rcg2 byte1_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "byte1_clk_src",
                .parent_data = gcc_xo_gpll0a_dsibyte_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_dsibyte_parent_data),
                .ops = &clk_byte2_ops,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1284,7 +1284,7 @@ static struct clk_rcg2 esc0_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "esc0_clk_src",
                .parent_data = gcc_xo_dsibyte_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_dsibyte_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1297,7 +1297,7 @@ static struct clk_rcg2 esc1_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "esc1_clk_src",
                .parent_data = gcc_xo_dsibyte_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_dsibyte_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1325,7 +1325,7 @@ static struct clk_rcg2 mdp_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "mdp_clk_src",
                .parent_data = gcc_xo_gpll1_dsiphy_gpll6_gpll3a_gpll0a_parent_data,
-               .num_parents = 6,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll1_dsiphy_gpll6_gpll3a_gpll0a_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1338,7 +1338,7 @@ static struct clk_rcg2 pclk0_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pclk0_clk_src",
                .parent_data = gcc_xo_gpll0a_dsiphy_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_dsiphy_parent_data),
                .ops = &clk_pixel_ops,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1352,7 +1352,7 @@ static struct clk_rcg2 pclk1_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pclk1_clk_src",
                .parent_data = gcc_xo_gpll0a_dsiphy_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_dsiphy_parent_data),
                .ops = &clk_pixel_ops,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1371,7 +1371,7 @@ static struct clk_rcg2 vsync_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "vsync_clk_src",
                .parent_data = gcc_xo_gpll0a_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1390,7 +1390,7 @@ static struct clk_rcg2 pdm2_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pdm2_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1416,7 +1416,7 @@ static struct clk_rcg2 sdcc1_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "sdcc1_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_floor_ops,
        },
 };
@@ -1430,7 +1430,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "sdcc2_apps_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_floor_ops,
        },
 };
@@ -1450,7 +1450,7 @@ static struct clk_rcg2 apss_tcu_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "apss_tcu_clk_src",
                .parent_data = gcc_xo_gpll0_gpll5a_gpll6_bimc_parent_data,
-               .num_parents = 5,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll5a_gpll6_bimc_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1473,7 +1473,7 @@ static struct clk_rcg2 bimc_gpu_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "bimc_gpu_clk_src",
                .parent_data = gcc_xo_gpll0_gpll5a_gpll6_bimc_parent_data,
-               .num_parents = 5,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll5a_gpll6_bimc_parent_data),
                .flags = CLK_GET_RATE_NOCACHE,
                .ops = &clk_rcg2_ops,
        },
@@ -1494,7 +1494,7 @@ static struct clk_rcg2 usb_hs_system_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "usb_hs_system_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1512,7 +1512,7 @@ static struct clk_rcg2 usb_fs_system_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "usb_fs_system_clk_src",
                .parent_data = gcc_xo_gpll6_gpll0_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll6_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1530,7 +1530,7 @@ static struct clk_rcg2 usb_fs_ic_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "usb_fs_ic_clk_src",
                .parent_data = gcc_xo_gpll6_gpll0a_parent_data,
-               .num_parents = 3,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll6_gpll0a_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1556,7 +1556,7 @@ static struct clk_rcg2 ultaudio_ahbfabric_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "ultaudio_ahbfabric_clk_src",
                .parent_data = gcc_xo_gpll0_gpll1_sleep_parent_data,
-               .num_parents = 4,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1_sleep_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1568,8 +1568,8 @@ static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_ahbfabric_ixfabric_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &ultaudio_ahbfabric_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ultaudio_ahbfabric_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1585,8 +1585,8 @@ static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_lpm_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_ahbfabric_ixfabric_lpm_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &ultaudio_ahbfabric_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ultaudio_ahbfabric_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1635,7 +1635,7 @@ static struct clk_rcg2 ultaudio_lpaif_pri_i2s_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "ultaudio_lpaif_pri_i2s_clk_src",
                .parent_data = gcc_xo_gpll1_epi2s_emclk_sleep_parent_data,
-               .num_parents = 5,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll1_epi2s_emclk_sleep_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1647,8 +1647,8 @@ static struct clk_branch gcc_ultaudio_lpaif_pri_i2s_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_lpaif_pri_i2s_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &ultaudio_lpaif_pri_i2s_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ultaudio_lpaif_pri_i2s_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1666,7 +1666,7 @@ static struct clk_rcg2 ultaudio_lpaif_sec_i2s_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "ultaudio_lpaif_sec_i2s_clk_src",
                .parent_data = gcc_xo_gpll1_esi2s_emclk_sleep_parent_data,
-               .num_parents = 5,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll1_esi2s_emclk_sleep_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1678,8 +1678,8 @@ static struct clk_branch gcc_ultaudio_lpaif_sec_i2s_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_lpaif_sec_i2s_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &ultaudio_lpaif_sec_i2s_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ultaudio_lpaif_sec_i2s_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1697,7 +1697,7 @@ static struct clk_rcg2 ultaudio_lpaif_aux_i2s_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "ultaudio_lpaif_aux_i2s_clk_src",
                .parent_data = gcc_xo_gpll1_esi2s_emclk_sleep_parent_data,
-               .num_parents = 5,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll1_esi2s_emclk_sleep_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1709,8 +1709,8 @@ static struct clk_branch gcc_ultaudio_lpaif_aux_i2s_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_lpaif_aux_i2s_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &ultaudio_lpaif_aux_i2s_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ultaudio_lpaif_aux_i2s_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1732,7 +1732,7 @@ static struct clk_rcg2 ultaudio_xo_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "ultaudio_xo_clk_src",
                .parent_data = gcc_xo_sleep_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_sleep_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1744,8 +1744,8 @@ static struct clk_branch gcc_ultaudio_avsync_xo_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_avsync_xo_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &ultaudio_xo_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ultaudio_xo_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1761,8 +1761,8 @@ static struct clk_branch gcc_ultaudio_stc_xo_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_stc_xo_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &ultaudio_xo_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ultaudio_xo_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1788,7 +1788,7 @@ static struct clk_rcg2 codec_digcodec_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "codec_digcodec_clk_src",
                .parent_data = gcc_xo_gpll1_emclk_sleep_parent_data,
-               .num_parents = 4,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll1_emclk_sleep_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1800,8 +1800,8 @@ static struct clk_branch gcc_codec_digcodec_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_codec_digcodec_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &codec_digcodec_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &codec_digcodec_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1817,8 +1817,8 @@ static struct clk_branch gcc_ultaudio_pcnoc_mport_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_pcnoc_mport_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1833,8 +1833,8 @@ static struct clk_branch gcc_ultaudio_pcnoc_sway_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ultaudio_pcnoc_sway_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1858,7 +1858,7 @@ static struct clk_rcg2 vcodec0_clk_src = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "vcodec0_clk_src",
                .parent_data = gcc_xo_gpll0_parent_data,
-               .num_parents = 2,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
                .ops = &clk_rcg2_ops,
        },
 };
@@ -1871,8 +1871,8 @@ static struct clk_branch gcc_blsp1_ahb_clk = {
                .enable_mask = BIT(10),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1899,8 +1899,8 @@ static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup1_i2c_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &blsp1_qup1_i2c_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup1_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1916,8 +1916,8 @@ static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup1_spi_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &blsp1_qup1_spi_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup1_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1933,8 +1933,8 @@ static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup2_i2c_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &blsp1_qup2_i2c_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup2_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1950,8 +1950,8 @@ static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup2_spi_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &blsp1_qup2_spi_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup2_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1967,8 +1967,8 @@ static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup3_i2c_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &blsp1_qup3_i2c_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup3_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1984,8 +1984,8 @@ static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup3_spi_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &blsp1_qup3_spi_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup3_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2001,8 +2001,8 @@ static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup4_i2c_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &blsp1_qup4_i2c_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup4_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2018,8 +2018,8 @@ static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup4_spi_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &blsp1_qup4_spi_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup4_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2035,8 +2035,8 @@ static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup5_i2c_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &blsp1_qup5_i2c_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup5_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2052,8 +2052,8 @@ static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup5_spi_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &blsp1_qup5_spi_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup5_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2069,8 +2069,8 @@ static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup6_i2c_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &blsp1_qup6_i2c_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup6_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2086,8 +2086,8 @@ static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup6_spi_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &blsp1_qup6_spi_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup6_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2103,8 +2103,8 @@ static struct clk_branch gcc_blsp1_uart1_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_uart1_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &blsp1_uart1_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_uart1_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2120,8 +2120,8 @@ static struct clk_branch gcc_blsp1_uart2_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_uart2_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &blsp1_uart2_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_uart2_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2138,8 +2138,8 @@ static struct clk_branch gcc_boot_rom_ahb_clk = {
                .enable_mask = BIT(7),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_boot_rom_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -2154,8 +2154,8 @@ static struct clk_branch gcc_camss_cci_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_cci_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &camss_ahb_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2171,8 +2171,8 @@ static struct clk_branch gcc_camss_cci_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_cci_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &cci_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &cci_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2188,8 +2188,8 @@ static struct clk_branch gcc_camss_csi0_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi0_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &camss_ahb_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2205,8 +2205,8 @@ static struct clk_branch gcc_camss_csi0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi0_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &csi0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2222,8 +2222,8 @@ static struct clk_branch gcc_camss_csi0phy_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi0phy_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &csi0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2239,8 +2239,8 @@ static struct clk_branch gcc_camss_csi0pix_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi0pix_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &csi0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2256,8 +2256,8 @@ static struct clk_branch gcc_camss_csi0rdi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi0rdi_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &csi0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2273,8 +2273,8 @@ static struct clk_branch gcc_camss_csi1_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi1_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &camss_ahb_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2290,8 +2290,8 @@ static struct clk_branch gcc_camss_csi1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi1_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &csi1_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2307,8 +2307,8 @@ static struct clk_branch gcc_camss_csi1phy_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi1phy_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &csi1_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2324,8 +2324,8 @@ static struct clk_branch gcc_camss_csi1pix_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi1pix_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &csi1_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2341,8 +2341,8 @@ static struct clk_branch gcc_camss_csi1rdi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi1rdi_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &csi1_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2358,8 +2358,8 @@ static struct clk_branch gcc_camss_csi_vfe0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi_vfe0_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &vfe0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vfe0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2375,8 +2375,8 @@ static struct clk_branch gcc_camss_gp0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_gp0_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &camss_gp0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_gp0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2392,8 +2392,8 @@ static struct clk_branch gcc_camss_gp1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_gp1_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &camss_gp1_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_gp1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2409,8 +2409,8 @@ static struct clk_branch gcc_camss_ispif_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_ispif_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &camss_ahb_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2426,8 +2426,8 @@ static struct clk_branch gcc_camss_jpeg0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_jpeg0_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &jpeg0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &jpeg0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2443,8 +2443,8 @@ static struct clk_branch gcc_camss_jpeg_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_jpeg_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &camss_ahb_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2460,8 +2460,8 @@ static struct clk_branch gcc_camss_jpeg_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_jpeg_axi_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_mm_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2477,8 +2477,8 @@ static struct clk_branch gcc_camss_mclk0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_mclk0_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &mclk0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &mclk0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2494,8 +2494,8 @@ static struct clk_branch gcc_camss_mclk1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_mclk1_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &mclk1_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &mclk1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2511,8 +2511,8 @@ static struct clk_branch gcc_camss_micro_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_micro_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &camss_ahb_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2528,8 +2528,8 @@ static struct clk_branch gcc_camss_csi0phytimer_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi0phytimer_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &csi0phytimer_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0phytimer_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2545,8 +2545,8 @@ static struct clk_branch gcc_camss_csi1phytimer_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_csi1phytimer_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &csi1phytimer_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1phytimer_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2562,8 +2562,8 @@ static struct clk_branch gcc_camss_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &camss_ahb_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2579,8 +2579,8 @@ static struct clk_branch gcc_camss_top_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_top_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2596,8 +2596,8 @@ static struct clk_branch gcc_camss_cpp_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_cpp_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &camss_ahb_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2613,8 +2613,8 @@ static struct clk_branch gcc_camss_cpp_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_cpp_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &cpp_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &cpp_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2630,8 +2630,8 @@ static struct clk_branch gcc_camss_vfe0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_vfe0_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &vfe0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vfe0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2647,8 +2647,8 @@ static struct clk_branch gcc_camss_vfe_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_vfe_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &camss_ahb_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_ahb_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2664,8 +2664,8 @@ static struct clk_branch gcc_camss_vfe_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_camss_vfe_axi_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_mm_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2682,8 +2682,8 @@ static struct clk_branch gcc_crypto_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_crypto_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2700,8 +2700,8 @@ static struct clk_branch gcc_crypto_axi_clk = {
                .enable_mask = BIT(1),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_crypto_axi_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2718,8 +2718,8 @@ static struct clk_branch gcc_crypto_clk = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_crypto_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &crypto_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &crypto_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2735,8 +2735,8 @@ static struct clk_branch gcc_oxili_gmem_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_oxili_gmem_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &gfx3d_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gfx3d_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2752,8 +2752,8 @@ static struct clk_branch gcc_gp1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gp1_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &gp1_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2769,8 +2769,8 @@ static struct clk_branch gcc_gp2_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gp2_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &gp2_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp2_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2786,8 +2786,8 @@ static struct clk_branch gcc_gp3_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gp3_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &gp3_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp3_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2803,8 +2803,8 @@ static struct clk_branch gcc_mdss_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2820,8 +2820,8 @@ static struct clk_branch gcc_mdss_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_axi_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_mm_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2837,8 +2837,8 @@ static struct clk_branch gcc_mdss_byte0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_byte0_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &byte0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &byte0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2854,8 +2854,8 @@ static struct clk_branch gcc_mdss_byte1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_byte1_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &byte1_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &byte1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2871,8 +2871,8 @@ static struct clk_branch gcc_mdss_esc0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_esc0_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &esc0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &esc0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2888,8 +2888,8 @@ static struct clk_branch gcc_mdss_esc1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_esc1_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &esc1_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &esc1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2905,8 +2905,8 @@ static struct clk_branch gcc_mdss_mdp_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_mdp_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &mdp_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &mdp_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2922,8 +2922,8 @@ static struct clk_branch gcc_mdss_pclk0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_pclk0_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pclk0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pclk0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2939,8 +2939,8 @@ static struct clk_branch gcc_mdss_pclk1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_pclk1_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pclk1_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pclk1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2956,8 +2956,8 @@ static struct clk_branch gcc_mdss_vsync_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdss_vsync_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &vsync_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vsync_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2973,8 +2973,8 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mss_cfg_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2990,8 +2990,8 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mss_q6_bimc_axi_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &bimc_ddr_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &bimc_ddr_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3007,8 +3007,8 @@ static struct clk_branch gcc_oxili_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_oxili_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3024,8 +3024,8 @@ static struct clk_branch gcc_oxili_gfx3d_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_oxili_gfx3d_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &gfx3d_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gfx3d_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3041,8 +3041,8 @@ static struct clk_branch gcc_pdm2_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_pdm2_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pdm2_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pdm2_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3058,8 +3058,8 @@ static struct clk_branch gcc_pdm_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_pdm_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3076,8 +3076,8 @@ static struct clk_branch gcc_prng_ahb_clk = {
                .enable_mask = BIT(8),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_prng_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -3092,8 +3092,8 @@ static struct clk_branch gcc_sdcc1_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc1_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3109,8 +3109,8 @@ static struct clk_branch gcc_sdcc1_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc1_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &sdcc1_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdcc1_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3126,8 +3126,8 @@ static struct clk_branch gcc_sdcc2_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc2_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3143,8 +3143,8 @@ static struct clk_branch gcc_sdcc2_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc2_apps_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &sdcc2_apps_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdcc2_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3161,8 +3161,8 @@ static struct clk_branch gcc_apss_tcu_clk = {
                .enable_mask = BIT(1),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_apss_tcu_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &bimc_ddr_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &bimc_ddr_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -3178,8 +3178,8 @@ static struct clk_branch gcc_gfx_tcu_clk = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gfx_tcu_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &bimc_ddr_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &bimc_ddr_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -3195,8 +3195,8 @@ static struct clk_branch gcc_gfx_tbu_clk = {
                .enable_mask = BIT(3),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gfx_tbu_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &bimc_ddr_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &bimc_ddr_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -3212,8 +3212,8 @@ static struct clk_branch gcc_mdp_tbu_clk = {
                .enable_mask = BIT(4),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdp_tbu_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_mm_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3230,8 +3230,8 @@ static struct clk_branch gcc_venus_tbu_clk = {
                .enable_mask = BIT(5),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_venus_tbu_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_mm_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3248,8 +3248,8 @@ static struct clk_branch gcc_vfe_tbu_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_vfe_tbu_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_mm_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3266,8 +3266,8 @@ static struct clk_branch gcc_jpeg_tbu_clk = {
                .enable_mask = BIT(10),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_jpeg_tbu_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_mm_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3284,8 +3284,8 @@ static struct clk_branch gcc_smmu_cfg_clk = {
                .enable_mask = BIT(12),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_smmu_cfg_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3302,8 +3302,8 @@ static struct clk_branch gcc_gtcu_ahb_clk = {
                .enable_mask = BIT(13),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gtcu_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3320,8 +3320,8 @@ static struct clk_branch gcc_cpp_tbu_clk = {
                .enable_mask = BIT(14),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_cpp_tbu_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3338,8 +3338,8 @@ static struct clk_branch gcc_mdp_rt_tbu_clk = {
                .enable_mask = BIT(15),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mdp_rt_tbu_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3355,8 +3355,8 @@ static struct clk_branch gcc_bimc_gfx_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_bimc_gfx_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &bimc_gpu_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &bimc_gpu_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3372,8 +3372,8 @@ static struct clk_branch gcc_bimc_gpu_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_bimc_gpu_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &bimc_gpu_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &bimc_gpu_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3401,8 +3401,8 @@ static struct clk_branch gcc_usb_fs_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb_fs_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3418,8 +3418,8 @@ static struct clk_branch gcc_usb_fs_ic_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb_fs_ic_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &usb_fs_ic_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_fs_ic_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3435,8 +3435,8 @@ static struct clk_branch gcc_usb_fs_system_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb_fs_system_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &usb_fs_system_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_fs_system_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3452,8 +3452,8 @@ static struct clk_branch gcc_usb_hs_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb_hs_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3469,8 +3469,8 @@ static struct clk_branch gcc_usb_hs_system_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb_hs_system_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &usb_hs_system_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_hs_system_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3486,8 +3486,8 @@ static struct clk_branch gcc_venus0_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_venus0_ahb_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcnoc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3503,8 +3503,8 @@ static struct clk_branch gcc_venus0_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_venus0_axi_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &system_mm_noc_bfdcd_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3520,8 +3520,8 @@ static struct clk_branch gcc_venus0_vcodec0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_venus0_vcodec0_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &vcodec0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vcodec0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3537,8 +3537,8 @@ static struct clk_branch gcc_venus0_core0_vcodec0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_venus0_core0_vcodec0_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &vcodec0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vcodec0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -3554,8 +3554,8 @@ static struct clk_branch gcc_venus0_core1_vcodec0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_venus0_core1_vcodec0_clk",
-                       .parent_data = &(const struct clk_parent_data){
-                               .hw = &vcodec0_clk_src.clkr.hw,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vcodec0_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
index a6e13b9..9dd4e7f 100644 (file)
@@ -35,7 +35,9 @@ static struct clk_pll pll3 = {
        .status_bit = 16,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pll3",
-               .parent_names = (const char *[]){ "pxo" },
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "pxo", .name = "pxo_board",
+               },
                .num_parents = 1,
                .ops = &clk_pll_ops,
        },
@@ -46,7 +48,9 @@ static struct clk_regmap pll4_vote = {
        .enable_mask = BIT(4),
        .hw.init = &(struct clk_init_data){
                .name = "pll4_vote",
-               .parent_names = (const char *[]){ "pll4" },
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "pll4", .name = "pll4",
+               },
                .num_parents = 1,
                .ops = &clk_pll_vote_ops,
        },
@@ -62,7 +66,9 @@ static struct clk_pll pll8 = {
        .status_bit = 16,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pll8",
-               .parent_names = (const char *[]){ "pxo" },
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "pxo", .name = "pxo_board",
+               },
                .num_parents = 1,
                .ops = &clk_pll_ops,
        },
@@ -73,7 +79,9 @@ static struct clk_regmap pll8_vote = {
        .enable_mask = BIT(8),
        .hw.init = &(struct clk_init_data){
                .name = "pll8_vote",
-               .parent_names = (const char *[]){ "pll8" },
+               .parent_hws = (const struct clk_hw*[]){
+                       &pll8.clkr.hw
+               },
                .num_parents = 1,
                .ops = &clk_pll_vote_ops,
        },
@@ -96,7 +104,9 @@ static struct hfpll_data hfpll0_data = {
 static struct clk_hfpll hfpll0 = {
        .d = &hfpll0_data,
        .clkr.hw.init = &(struct clk_init_data){
-               .parent_names = (const char *[]){ "pxo" },
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "pxo", .name = "pxo_board",
+               },
                .num_parents = 1,
                .name = "hfpll0",
                .ops = &clk_ops_hfpll,
@@ -136,7 +146,9 @@ static struct hfpll_data hfpll1_data = {
 static struct clk_hfpll hfpll1 = {
        .d = &hfpll1_data,
        .clkr.hw.init = &(struct clk_init_data){
-               .parent_names = (const char *[]){ "pxo" },
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "pxo", .name = "pxo_board",
+               },
                .num_parents = 1,
                .name = "hfpll1",
                .ops = &clk_ops_hfpll,
@@ -162,7 +174,9 @@ static struct hfpll_data hfpll2_data = {
 static struct clk_hfpll hfpll2 = {
        .d = &hfpll2_data,
        .clkr.hw.init = &(struct clk_init_data){
-               .parent_names = (const char *[]){ "pxo" },
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "pxo", .name = "pxo_board",
+               },
                .num_parents = 1,
                .name = "hfpll2",
                .ops = &clk_ops_hfpll,
@@ -188,7 +202,9 @@ static struct hfpll_data hfpll3_data = {
 static struct clk_hfpll hfpll3 = {
        .d = &hfpll3_data,
        .clkr.hw.init = &(struct clk_init_data){
-               .parent_names = (const char *[]){ "pxo" },
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "pxo", .name = "pxo_board",
+               },
                .num_parents = 1,
                .name = "hfpll3",
                .ops = &clk_ops_hfpll,
@@ -228,7 +244,9 @@ static struct hfpll_data hfpll_l2_data = {
 static struct clk_hfpll hfpll_l2 = {
        .d = &hfpll_l2_data,
        .clkr.hw.init = &(struct clk_init_data){
-               .parent_names = (const char *[]){ "pxo" },
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "pxo", .name = "pxo_board",
+               },
                .num_parents = 1,
                .name = "hfpll_l2",
                .ops = &clk_ops_hfpll,
@@ -247,7 +265,9 @@ static struct clk_pll pll14 = {
        .status_bit = 16,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pll14",
-               .parent_names = (const char *[]){ "pxo" },
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "pxo", .name = "pxo_board",
+               },
                .num_parents = 1,
                .ops = &clk_pll_ops,
        },
@@ -258,7 +278,9 @@ static struct clk_regmap pll14_vote = {
        .enable_mask = BIT(14),
        .hw.init = &(struct clk_init_data){
                .name = "pll14_vote",
-               .parent_names = (const char *[]){ "pll14" },
+               .parent_hws = (const struct clk_hw*[]){
+                       &pll14.clkr.hw
+               },
                .num_parents = 1,
                .ops = &clk_pll_vote_ops,
        },
@@ -276,9 +298,9 @@ static const struct parent_map gcc_pxo_pll8_map[] = {
        { P_PLL8, 3 }
 };
 
-static const char * const gcc_pxo_pll8[] = {
-       "pxo",
-       "pll8_vote",
+static const struct clk_parent_data gcc_pxo_pll8[] = {
+       { .fw_name = "pxo", .name = "pxo_board" },
+       { .hw = &pll8_vote.hw },
 };
 
 static const struct parent_map gcc_pxo_pll8_cxo_map[] = {
@@ -287,10 +309,10 @@ static const struct parent_map gcc_pxo_pll8_cxo_map[] = {
        { P_CXO, 5 }
 };
 
-static const char * const gcc_pxo_pll8_cxo[] = {
-       "pxo",
-       "pll8_vote",
-       "cxo",
+static const struct clk_parent_data gcc_pxo_pll8_cxo[] = {
+       { .fw_name = "pxo", .name = "pxo_board" },
+       { .hw = &pll8_vote.hw },
+       { .fw_name = "cxo", .name = "cxo_board" },
 };
 
 static const struct parent_map gcc_pxo_pll8_pll3_map[] = {
@@ -299,10 +321,10 @@ static const struct parent_map gcc_pxo_pll8_pll3_map[] = {
        { P_PLL3, 6 }
 };
 
-static const char * const gcc_pxo_pll8_pll3[] = {
-       "pxo",
-       "pll8_vote",
-       "pll3",
+static const struct clk_parent_data gcc_pxo_pll8_pll3[] = {
+       { .fw_name = "pxo", .name = "pxo_board" },
+       { .hw = &pll8_vote.hw },
+       { .hw = &pll3.clkr.hw },
 };
 
 static struct freq_tbl clk_tbl_gsbi_uart[] = {
@@ -348,8 +370,8 @@ static struct clk_rcg gsbi1_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi1_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -364,8 +386,8 @@ static struct clk_branch gsbi1_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi1_uart_clk",
-                       .parent_names = (const char *[]){
-                               "gsbi1_uart_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi1_uart_src.clkr.hw
                        },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
@@ -399,8 +421,8 @@ static struct clk_rcg gsbi2_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi2_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -415,8 +437,8 @@ static struct clk_branch gsbi2_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi2_uart_clk",
-                       .parent_names = (const char *[]){
-                               "gsbi2_uart_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi2_uart_src.clkr.hw
                        },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
@@ -450,8 +472,8 @@ static struct clk_rcg gsbi3_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi3_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -466,8 +488,8 @@ static struct clk_branch gsbi3_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi3_uart_clk",
-                       .parent_names = (const char *[]){
-                               "gsbi3_uart_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi3_uart_src.clkr.hw
                        },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
@@ -501,8 +523,8 @@ static struct clk_rcg gsbi4_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi4_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -517,8 +539,8 @@ static struct clk_branch gsbi4_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi4_uart_clk",
-                       .parent_names = (const char *[]){
-                               "gsbi4_uart_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi4_uart_src.clkr.hw
                        },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
@@ -552,8 +574,8 @@ static struct clk_rcg gsbi5_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi5_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -568,8 +590,8 @@ static struct clk_branch gsbi5_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi5_uart_clk",
-                       .parent_names = (const char *[]){
-                               "gsbi5_uart_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi5_uart_src.clkr.hw
                        },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
@@ -603,8 +625,8 @@ static struct clk_rcg gsbi6_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi6_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -619,8 +641,8 @@ static struct clk_branch gsbi6_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi6_uart_clk",
-                       .parent_names = (const char *[]){
-                               "gsbi6_uart_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi6_uart_src.clkr.hw
                        },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
@@ -654,8 +676,8 @@ static struct clk_rcg gsbi7_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi7_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -670,8 +692,8 @@ static struct clk_branch gsbi7_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi7_uart_clk",
-                       .parent_names = (const char *[]){
-                               "gsbi7_uart_src",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi7_uart_src.clkr.hw
                        },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
@@ -705,8 +727,8 @@ static struct clk_rcg gsbi8_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi8_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -721,7 +743,9 @@ static struct clk_branch gsbi8_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi8_uart_clk",
-                       .parent_names = (const char *[]){ "gsbi8_uart_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi8_uart_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -754,8 +778,8 @@ static struct clk_rcg gsbi9_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi9_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -770,7 +794,9 @@ static struct clk_branch gsbi9_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi9_uart_clk",
-                       .parent_names = (const char *[]){ "gsbi9_uart_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi9_uart_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -803,8 +829,8 @@ static struct clk_rcg gsbi10_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi10_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -819,7 +845,9 @@ static struct clk_branch gsbi10_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi10_uart_clk",
-                       .parent_names = (const char *[]){ "gsbi10_uart_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi10_uart_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -852,8 +880,8 @@ static struct clk_rcg gsbi11_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi11_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -868,7 +896,9 @@ static struct clk_branch gsbi11_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi11_uart_clk",
-                       .parent_names = (const char *[]){ "gsbi11_uart_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi11_uart_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -901,8 +931,8 @@ static struct clk_rcg gsbi12_uart_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi12_uart_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -917,7 +947,9 @@ static struct clk_branch gsbi12_uart_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi12_uart_clk",
-                       .parent_names = (const char *[]){ "gsbi12_uart_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi12_uart_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -963,8 +995,8 @@ static struct clk_rcg gsbi1_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi1_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -979,7 +1011,9 @@ static struct clk_branch gsbi1_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi1_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi1_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi1_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1012,8 +1046,8 @@ static struct clk_rcg gsbi2_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi2_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1028,7 +1062,9 @@ static struct clk_branch gsbi2_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi2_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi2_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi2_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1061,8 +1097,8 @@ static struct clk_rcg gsbi3_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi3_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1077,7 +1113,9 @@ static struct clk_branch gsbi3_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi3_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi3_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi3_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1110,8 +1148,8 @@ static struct clk_rcg gsbi4_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi4_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1126,7 +1164,9 @@ static struct clk_branch gsbi4_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi4_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi4_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi4_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1159,8 +1199,8 @@ static struct clk_rcg gsbi5_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi5_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1175,7 +1215,9 @@ static struct clk_branch gsbi5_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi5_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi5_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi5_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1208,8 +1250,8 @@ static struct clk_rcg gsbi6_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi6_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1224,7 +1266,9 @@ static struct clk_branch gsbi6_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi6_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi6_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi6_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1257,8 +1301,8 @@ static struct clk_rcg gsbi7_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi7_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1273,7 +1317,9 @@ static struct clk_branch gsbi7_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi7_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi7_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi7_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1306,8 +1352,8 @@ static struct clk_rcg gsbi8_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi8_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1322,7 +1368,9 @@ static struct clk_branch gsbi8_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi8_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi8_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi8_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1355,8 +1403,8 @@ static struct clk_rcg gsbi9_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi9_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1371,7 +1419,9 @@ static struct clk_branch gsbi9_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi9_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi9_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi9_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1404,8 +1454,8 @@ static struct clk_rcg gsbi10_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi10_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1420,7 +1470,9 @@ static struct clk_branch gsbi10_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi10_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi10_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi10_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1453,8 +1505,8 @@ static struct clk_rcg gsbi11_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi11_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1469,7 +1521,9 @@ static struct clk_branch gsbi11_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi11_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi11_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi11_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1502,8 +1556,8 @@ static struct clk_rcg gsbi12_qup_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi12_qup_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1518,7 +1572,9 @@ static struct clk_branch gsbi12_qup_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gsbi12_qup_clk",
-                       .parent_names = (const char *[]){ "gsbi12_qup_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gsbi12_qup_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1564,8 +1620,8 @@ static struct clk_rcg gp0_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gp0_src",
-                       .parent_names = gcc_pxo_pll8_cxo,
-                       .num_parents = 3,
+                       .parent_data = gcc_pxo_pll8_cxo,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8_cxo),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_PARENT_GATE,
                },
@@ -1580,7 +1636,9 @@ static struct clk_branch gp0_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gp0_clk",
-                       .parent_names = (const char *[]){ "gp0_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp0_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1613,8 +1671,8 @@ static struct clk_rcg gp1_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gp1_src",
-                       .parent_names = gcc_pxo_pll8_cxo,
-                       .num_parents = 3,
+                       .parent_data = gcc_pxo_pll8_cxo,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8_cxo),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
@@ -1629,7 +1687,9 @@ static struct clk_branch gp1_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gp1_clk",
-                       .parent_names = (const char *[]){ "gp1_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp1_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1662,8 +1722,8 @@ static struct clk_rcg gp2_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "gp2_src",
-                       .parent_names = gcc_pxo_pll8_cxo,
-                       .num_parents = 3,
+                       .parent_data = gcc_pxo_pll8_cxo,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8_cxo),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
@@ -1678,7 +1738,9 @@ static struct clk_branch gp2_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "gp2_clk",
-                       .parent_names = (const char *[]){ "gp2_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp2_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1714,8 +1776,8 @@ static struct clk_rcg prng_src = {
        .clkr = {
                .hw.init = &(struct clk_init_data){
                        .name = "prng_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                },
        },
@@ -1730,7 +1792,9 @@ static struct clk_branch prng_clk = {
                .enable_mask = BIT(10),
                .hw.init = &(struct clk_init_data){
                        .name = "prng_clk",
-                       .parent_names = (const char *[]){ "prng_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &prng_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                },
@@ -1776,8 +1840,8 @@ static struct clk_rcg sdc1_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc1_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                },
        }
@@ -1791,7 +1855,9 @@ static struct clk_branch sdc1_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc1_clk",
-                       .parent_names = (const char *[]){ "sdc1_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdc1_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1824,8 +1890,8 @@ static struct clk_rcg sdc2_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc2_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                },
        }
@@ -1839,7 +1905,9 @@ static struct clk_branch sdc2_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc2_clk",
-                       .parent_names = (const char *[]){ "sdc2_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdc2_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1872,8 +1940,8 @@ static struct clk_rcg sdc3_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc3_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                },
        }
@@ -1887,7 +1955,9 @@ static struct clk_branch sdc3_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc3_clk",
-                       .parent_names = (const char *[]){ "sdc3_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdc3_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1920,8 +1990,8 @@ static struct clk_rcg sdc4_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc4_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                },
        }
@@ -1935,7 +2005,9 @@ static struct clk_branch sdc4_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc4_clk",
-                       .parent_names = (const char *[]){ "sdc4_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdc4_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1968,8 +2040,8 @@ static struct clk_rcg sdc5_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc5_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                },
        }
@@ -1983,7 +2055,9 @@ static struct clk_branch sdc5_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "sdc5_clk",
-                       .parent_names = (const char *[]){ "sdc5_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdc5_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2021,8 +2095,8 @@ static struct clk_rcg tsif_ref_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "tsif_ref_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
@@ -2037,7 +2111,9 @@ static struct clk_branch tsif_ref_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "tsif_ref_clk",
-                       .parent_names = (const char *[]){ "tsif_ref_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &tsif_ref_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2075,8 +2151,8 @@ static struct clk_rcg usb_hs1_xcvr_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_hs1_xcvr_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
@@ -2091,7 +2167,9 @@ static struct clk_branch usb_hs1_xcvr_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_hs1_xcvr_clk",
-                       .parent_names = (const char *[]){ "usb_hs1_xcvr_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_hs1_xcvr_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2124,8 +2202,8 @@ static struct clk_rcg usb_hs3_xcvr_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_hs3_xcvr_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
@@ -2140,7 +2218,9 @@ static struct clk_branch usb_hs3_xcvr_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_hs3_xcvr_clk",
-                       .parent_names = (const char *[]){ "usb_hs3_xcvr_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_hs3_xcvr_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2173,8 +2253,8 @@ static struct clk_rcg usb_hs4_xcvr_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_hs4_xcvr_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
@@ -2189,7 +2269,9 @@ static struct clk_branch usb_hs4_xcvr_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_hs4_xcvr_clk",
-                       .parent_names = (const char *[]){ "usb_hs4_xcvr_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_hs4_xcvr_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2222,16 +2304,14 @@ static struct clk_rcg usb_hsic_xcvr_fs_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_hsic_xcvr_fs_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
        }
 };
 
-static const char * const usb_hsic_xcvr_fs_src_p[] = { "usb_hsic_xcvr_fs_src" };
-
 static struct clk_branch usb_hsic_xcvr_fs_clk = {
        .halt_reg = 0x2fc8,
        .halt_bit = 2,
@@ -2240,7 +2320,9 @@ static struct clk_branch usb_hsic_xcvr_fs_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_hsic_xcvr_fs_clk",
-                       .parent_names = usb_hsic_xcvr_fs_src_p,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_hsic_xcvr_fs_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2255,7 +2337,9 @@ static struct clk_branch usb_hsic_system_clk = {
                .enable_reg = 0x292c,
                .enable_mask = BIT(4),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = usb_hsic_xcvr_fs_src_p,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_hsic_xcvr_fs_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .name = "usb_hsic_system_clk",
                        .ops = &clk_branch_ops,
@@ -2271,7 +2355,9 @@ static struct clk_branch usb_hsic_hsic_clk = {
                .enable_reg = 0x2b44,
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = (const char *[]){ "pll14_vote" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pll14_vote.hw
+                       },
                        .num_parents = 1,
                        .name = "usb_hsic_hsic_clk",
                        .ops = &clk_branch_ops,
@@ -2317,16 +2403,14 @@ static struct clk_rcg usb_fs1_xcvr_fs_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_fs1_xcvr_fs_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
        }
 };
 
-static const char * const usb_fs1_xcvr_fs_src_p[] = { "usb_fs1_xcvr_fs_src" };
-
 static struct clk_branch usb_fs1_xcvr_fs_clk = {
        .halt_reg = 0x2fcc,
        .halt_bit = 15,
@@ -2335,7 +2419,9 @@ static struct clk_branch usb_fs1_xcvr_fs_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_fs1_xcvr_fs_clk",
-                       .parent_names = usb_fs1_xcvr_fs_src_p,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_fs1_xcvr_fs_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2350,7 +2436,9 @@ static struct clk_branch usb_fs1_system_clk = {
                .enable_reg = 0x296c,
                .enable_mask = BIT(4),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = usb_fs1_xcvr_fs_src_p,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_fs1_xcvr_fs_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .name = "usb_fs1_system_clk",
                        .ops = &clk_branch_ops,
@@ -2384,16 +2472,14 @@ static struct clk_rcg usb_fs2_xcvr_fs_src = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_fs2_xcvr_fs_src",
-                       .parent_names = gcc_pxo_pll8,
-                       .num_parents = 2,
+                       .parent_data = gcc_pxo_pll8,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
        }
 };
 
-static const char * const usb_fs2_xcvr_fs_src_p[] = { "usb_fs2_xcvr_fs_src" };
-
 static struct clk_branch usb_fs2_xcvr_fs_clk = {
        .halt_reg = 0x2fcc,
        .halt_bit = 12,
@@ -2402,7 +2488,9 @@ static struct clk_branch usb_fs2_xcvr_fs_clk = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_fs2_xcvr_fs_clk",
-                       .parent_names = usb_fs2_xcvr_fs_src_p,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_fs2_xcvr_fs_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2418,7 +2506,9 @@ static struct clk_branch usb_fs2_system_clk = {
                .enable_mask = BIT(4),
                .hw.init = &(struct clk_init_data){
                        .name = "usb_fs2_system_clk",
-                       .parent_names = usb_fs2_xcvr_fs_src_p,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb_fs2_xcvr_fs_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2872,8 +2962,8 @@ static struct clk_rcg ce3_src = {
                .enable_mask = BIT(7),
                .hw.init = &(struct clk_init_data){
                        .name = "ce3_src",
-                       .parent_names = gcc_pxo_pll8_pll3,
-                       .num_parents = 3,
+                       .parent_data = gcc_pxo_pll8_pll3,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8_pll3),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
@@ -2888,7 +2978,9 @@ static struct clk_branch ce3_core_clk = {
                .enable_mask = BIT(4),
                .hw.init = &(struct clk_init_data){
                        .name = "ce3_core_clk",
-                       .parent_names = (const char *[]){ "ce3_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ce3_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2904,7 +2996,9 @@ static struct clk_branch ce3_h_clk = {
                .enable_mask = BIT(4),
                .hw.init = &(struct clk_init_data){
                        .name = "ce3_h_clk",
-                       .parent_names = (const char *[]){ "ce3_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ce3_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2934,8 +3028,8 @@ static struct clk_rcg sata_clk_src = {
                .enable_mask = BIT(7),
                .hw.init = &(struct clk_init_data){
                        .name = "sata_clk_src",
-                       .parent_names = gcc_pxo_pll8_pll3,
-                       .num_parents = 3,
+                       .parent_data = gcc_pxo_pll8_pll3,
+                       .num_parents = ARRAY_SIZE(gcc_pxo_pll8_pll3),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
@@ -2950,7 +3044,9 @@ static struct clk_branch sata_rxoob_clk = {
                .enable_mask = BIT(4),
                .hw.init = &(struct clk_init_data){
                        .name = "sata_rxoob_clk",
-                       .parent_names = (const char *[]){ "sata_clk_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sata_clk_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2966,7 +3062,9 @@ static struct clk_branch sata_pmalive_clk = {
                .enable_mask = BIT(4),
                .hw.init = &(struct clk_init_data){
                        .name = "sata_pmalive_clk",
-                       .parent_names = (const char *[]){ "sata_clk_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sata_clk_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2982,7 +3080,9 @@ static struct clk_branch sata_phy_ref_clk = {
                .enable_mask = BIT(4),
                .hw.init = &(struct clk_init_data){
                        .name = "sata_phy_ref_clk",
-                       .parent_names = (const char *[]){ "pxo" },
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "pxo", .name = "pxo_board",
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                },
index b6fa7b8..7792b8f 100644 (file)
@@ -54,33 +54,9 @@ static const struct pll_vco spark_vco[] = {
        { 750000000, 1500000000, 1 },
 };
 
-static const u8 clk_alpha_pll_regs_offset[][PLL_OFF_MAX_REGS] = {
-       [CLK_ALPHA_PLL_TYPE_DEFAULT] =  {
-               [PLL_OFF_L_VAL] = 0x04,
-               [PLL_OFF_ALPHA_VAL] = 0x08,
-               [PLL_OFF_ALPHA_VAL_U] = 0x0c,
-               [PLL_OFF_TEST_CTL] = 0x10,
-               [PLL_OFF_TEST_CTL_U] = 0x14,
-               [PLL_OFF_USER_CTL] = 0x18,
-               [PLL_OFF_USER_CTL_U] = 0x1C,
-               [PLL_OFF_CONFIG_CTL] = 0x20,
-               [PLL_OFF_STATUS] = 0x24,
-       },
-       [CLK_ALPHA_PLL_TYPE_BRAMMO] =  {
-               [PLL_OFF_L_VAL] = 0x04,
-               [PLL_OFF_ALPHA_VAL] = 0x08,
-               [PLL_OFF_ALPHA_VAL_U] = 0x0c,
-               [PLL_OFF_TEST_CTL] = 0x10,
-               [PLL_OFF_TEST_CTL_U] = 0x14,
-               [PLL_OFF_USER_CTL] = 0x18,
-               [PLL_OFF_CONFIG_CTL] = 0x1C,
-               [PLL_OFF_STATUS] = 0x20,
-       },
-};
-
 static struct clk_alpha_pll gpll0 = {
        .offset = 0x0,
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(0),
@@ -106,7 +82,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_aux2 = {
        .post_div_table = post_div_table_gpll0_out_aux2,
        .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_aux2),
        .width = 4,
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll0_out_aux2",
                .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
@@ -117,7 +93,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_aux2 = {
 
 static struct clk_alpha_pll gpll1 = {
        .offset = 0x1000,
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(1),
@@ -147,7 +123,7 @@ static struct clk_alpha_pll gpll10 = {
        .offset = 0xa000,
        .vco_table = spark_vco,
        .num_vco = ARRAY_SIZE(spark_vco),
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(10),
@@ -179,7 +155,7 @@ static struct clk_alpha_pll gpll11 = {
        .offset = 0xb000,
        .vco_table = default_vco,
        .num_vco = ARRAY_SIZE(default_vco),
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .flags = SUPPORTS_DYNAMIC_UPDATE,
        .clkr = {
                .enable_reg = 0x79000,
@@ -197,7 +173,7 @@ static struct clk_alpha_pll gpll11 = {
 
 static struct clk_alpha_pll gpll3 = {
        .offset = 0x3000,
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(3),
@@ -223,7 +199,7 @@ static struct clk_alpha_pll_postdiv gpll3_out_main = {
        .post_div_table = post_div_table_gpll3_out_main,
        .num_post_div = ARRAY_SIZE(post_div_table_gpll3_out_main),
        .width = 4,
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll3_out_main",
                .parent_hws = (const struct clk_hw *[]){ &gpll3.clkr.hw },
@@ -234,7 +210,7 @@ static struct clk_alpha_pll_postdiv gpll3_out_main = {
 
 static struct clk_alpha_pll gpll4 = {
        .offset = 0x4000,
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(4),
@@ -251,7 +227,7 @@ static struct clk_alpha_pll gpll4 = {
 
 static struct clk_alpha_pll gpll5 = {
        .offset = 0x5000,
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(5),
@@ -268,7 +244,7 @@ static struct clk_alpha_pll gpll5 = {
 
 static struct clk_alpha_pll gpll6 = {
        .offset = 0x6000,
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(6),
@@ -294,7 +270,7 @@ static struct clk_alpha_pll_postdiv gpll6_out_main = {
        .post_div_table = post_div_table_gpll6_out_main,
        .num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_main),
        .width = 4,
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll6_out_main",
                .parent_hws = (const struct clk_hw *[]){ &gpll6.clkr.hw },
@@ -305,7 +281,7 @@ static struct clk_alpha_pll_postdiv gpll6_out_main = {
 
 static struct clk_alpha_pll gpll7 = {
        .offset = 0x7000,
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(7),
@@ -340,7 +316,7 @@ static struct clk_alpha_pll gpll8 = {
        .offset = 0x8000,
        .vco_table = default_vco,
        .num_vco = ARRAY_SIZE(default_vco),
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .flags = SUPPORTS_DYNAMIC_UPDATE,
        .clkr = {
                .enable_reg = 0x79000,
@@ -367,7 +343,7 @@ static struct clk_alpha_pll_postdiv gpll8_out_main = {
        .post_div_table = post_div_table_gpll8_out_main,
        .num_post_div = ARRAY_SIZE(post_div_table_gpll8_out_main),
        .width = 4,
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll8_out_main",
                .parent_hws = (const struct clk_hw *[]){ &gpll8.clkr.hw },
@@ -393,7 +369,7 @@ static struct clk_alpha_pll gpll9 = {
        .offset = 0x9000,
        .vco_table = brammo_vco,
        .num_vco = ARRAY_SIZE(brammo_vco),
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_BRAMMO],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(9),
@@ -419,7 +395,7 @@ static struct clk_alpha_pll_postdiv gpll9_out_main = {
        .post_div_table = post_div_table_gpll9_out_main,
        .num_post_div = ARRAY_SIZE(post_div_table_gpll9_out_main),
        .width = 2,
-       .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_BRAMMO],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO_EVO],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll9_out_main",
                .parent_hws = (const struct clk_hw *[]){ &gpll9.clkr.hw },
index c2ea099..2d39802 100644 (file)
@@ -2224,7 +2224,7 @@ static struct gdsc usb30_prim_gdsc = {
        .pd = {
                .name = "usb30_prim_gdsc",
        },
-       .pwrsts = PWRSTS_OFF_ON,
+       .pwrsts = PWRSTS_RET_ON,
 };
 
 static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = {
index 7ff64d4..8afb757 100644 (file)
@@ -3108,7 +3108,7 @@ static struct gdsc gcc_pcie_1_gdsc = {
        .pd = {
                .name = "gcc_pcie_1_gdsc",
        },
-       .pwrsts = PWRSTS_OFF_ON,
+       .pwrsts = PWRSTS_RET_ON,
        .flags = VOTABLE,
 };
 
@@ -3126,7 +3126,7 @@ static struct gdsc gcc_usb30_prim_gdsc = {
        .pd = {
                .name = "gcc_usb30_prim_gdsc",
        },
-       .pwrsts = PWRSTS_OFF_ON,
+       .pwrsts = PWRSTS_RET_ON,
        .flags = VOTABLE,
 };
 
@@ -3135,7 +3135,7 @@ static struct gdsc gcc_usb30_sec_gdsc = {
        .pd = {
                .name = "gcc_usb30_sec_gdsc",
        },
-       .pwrsts = PWRSTS_OFF_ON,
+       .pwrsts = PWRSTS_RET_ON,
        .flags = VOTABLE,
 };
 
index a2f3ffc..a18ed88 100644 (file)
@@ -6768,6 +6768,10 @@ static struct gdsc pcie_1_tunnel_gdsc = {
        .flags = VOTABLE,
 };
 
+/*
+ * The Qualcomm PCIe driver does not yet implement suspend so to keep the
+ * PCIe power domains always-on for now.
+ */
 static struct gdsc pcie_2a_gdsc = {
        .gdscr = 0x9d004,
        .collapse_ctrl = 0x52128,
@@ -6776,7 +6780,7 @@ static struct gdsc pcie_2a_gdsc = {
                .name = "pcie_2a_gdsc",
        },
        .pwrsts = PWRSTS_OFF_ON,
-       .flags = VOTABLE,
+       .flags = VOTABLE | ALWAYS_ON,
 };
 
 static struct gdsc pcie_2b_gdsc = {
@@ -6787,7 +6791,7 @@ static struct gdsc pcie_2b_gdsc = {
                .name = "pcie_2b_gdsc",
        },
        .pwrsts = PWRSTS_OFF_ON,
-       .flags = VOTABLE,
+       .flags = VOTABLE | ALWAYS_ON,
 };
 
 static struct gdsc pcie_3a_gdsc = {
@@ -6798,7 +6802,7 @@ static struct gdsc pcie_3a_gdsc = {
                .name = "pcie_3a_gdsc",
        },
        .pwrsts = PWRSTS_OFF_ON,
-       .flags = VOTABLE,
+       .flags = VOTABLE | ALWAYS_ON,
 };
 
 static struct gdsc pcie_3b_gdsc = {
@@ -6809,7 +6813,7 @@ static struct gdsc pcie_3b_gdsc = {
                .name = "pcie_3b_gdsc",
        },
        .pwrsts = PWRSTS_OFF_ON,
-       .flags = VOTABLE,
+       .flags = VOTABLE | ALWAYS_ON,
 };
 
 static struct gdsc pcie_4_gdsc = {
@@ -6820,7 +6824,7 @@ static struct gdsc pcie_4_gdsc = {
                .name = "pcie_4_gdsc",
        },
        .pwrsts = PWRSTS_OFF_ON,
-       .flags = VOTABLE,
+       .flags = VOTABLE | ALWAYS_ON,
 };
 
 static struct gdsc ufs_card_gdsc = {
@@ -6844,7 +6848,7 @@ static struct gdsc usb30_mp_gdsc = {
        .pd = {
                .name = "usb30_mp_gdsc",
        },
-       .pwrsts = PWRSTS_OFF_ON,
+       .pwrsts = PWRSTS_RET_ON,
 };
 
 static struct gdsc usb30_prim_gdsc = {
@@ -6852,7 +6856,7 @@ static struct gdsc usb30_prim_gdsc = {
        .pd = {
                .name = "usb30_prim_gdsc",
        },
-       .pwrsts = PWRSTS_OFF_ON,
+       .pwrsts = PWRSTS_RET_ON,
 };
 
 static struct gdsc usb30_sec_gdsc = {
@@ -6860,7 +6864,7 @@ static struct gdsc usb30_sec_gdsc = {
        .pd = {
                .name = "usb30_sec_gdsc",
        },
-       .pwrsts = PWRSTS_OFF_ON,
+       .pwrsts = PWRSTS_RET_ON,
 };
 
 static struct clk_regmap *gcc_sc8280xp_clocks[] = {
index 9b97425..db918c9 100644 (file)
@@ -757,7 +757,7 @@ static struct clk_rcg2 sdcc1_apps_clk_src = {
                .name = "sdcc1_apps_clk_src",
                .parent_data = gcc_parent_data_xo_gpll0_gpll4_gpll0_early_div,
                .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll4_gpll0_early_div),
-               .ops = &clk_rcg2_ops,
+               .ops = &clk_rcg2_floor_ops,
        },
 };
 
index 58aa3ec..6af08e0 100644 (file)
@@ -31,6 +31,7 @@ enum {
        P_GPLL0_OUT_EVEN,
        P_GPLL0_OUT_MAIN,
        P_GPLL4_OUT_MAIN,
+       P_GPLL6_OUT_MAIN,
        P_SLEEP_CLK,
 };
 
@@ -68,6 +69,23 @@ static struct clk_alpha_pll gpll4 = {
        },
 };
 
+static struct clk_alpha_pll gpll6 = {
+       .offset = 0x13000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(6),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll6",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo", .name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_fabia_ops,
+               },
+       },
+};
+
 static const struct clk_div_table post_div_table_fabia_even[] = {
        { 0x0, 1 },
        { 0x1, 2 },
@@ -194,6 +212,19 @@ static const struct clk_parent_data gcc_parent_data_10[] = {
        { .hw = &gpll0_out_even.clkr.hw },
 };
 
+static const struct parent_map gcc_parent_map_11[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL6_OUT_MAIN, 2 },
+       { P_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_11[] = {
+       { .fw_name = "bi_tcxo", .name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+};
 
 static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = {
        F(19200000, P_BI_TCXO, 1, 0, 0),
@@ -233,6 +264,26 @@ static struct clk_rcg2 gcc_cpuss_rbcpr_clk_src = {
        },
 };
 
+static const struct freq_tbl ftbl_gcc_sdm670_cpuss_rbcpr_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdm670_cpuss_rbcpr_clk_src = {
+       .cmd_rcgr = 0x4815c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_gcc_sdm670_cpuss_rbcpr_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_cpuss_rbcpr_clk_src",
+               .parent_data = gcc_parent_data_8_ao,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_8_ao),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
 static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = {
        F(19200000, P_BI_TCXO, 1, 0, 0),
        F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
@@ -656,6 +707,54 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {
        .clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_src_init,
 };
 
+static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = {
+       F(144000, P_BI_TCXO, 16, 3, 25),
+       F(400000, P_BI_TCXO, 12, 1, 4),
+       F(20000000, P_GPLL0_OUT_EVEN, 5, 1, 3),
+       F(25000000, P_GPLL0_OUT_EVEN, 6, 1, 2),
+       F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(192000000, P_GPLL6_OUT_MAIN, 2, 0, 0),
+       F(384000000, P_GPLL6_OUT_MAIN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc1_apps_clk_src = {
+       .cmd_rcgr = 0x26028,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_11,
+       .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc1_apps_clk_src",
+               .parent_data = gcc_parent_data_11,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_11),
+               .ops = &clk_rcg2_floor_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = {
+       F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = {
+       .cmd_rcgr = 0x26010,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc1_ice_core_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
 static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
        F(400000, P_BI_TCXO, 12, 1, 4),
        F(9600000, P_BI_TCXO, 2, 0, 0),
@@ -705,6 +804,31 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = {
        },
 };
 
+static const struct freq_tbl ftbl_gcc_sdm670_sdcc4_apps_clk_src[] = {
+       F(400000, P_BI_TCXO, 12, 1, 4),
+       F(9600000, P_BI_TCXO, 2, 0, 0),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(33333333, P_GPLL0_OUT_EVEN, 9, 0, 0),
+       F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdm670_sdcc4_apps_clk_src = {
+       .cmd_rcgr = 0x1600c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_sdm670_sdcc4_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc4_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .ops = &clk_rcg2_floor_ops,
+       },
+};
+
 static const struct freq_tbl ftbl_gcc_tsif_ref_clk_src[] = {
        F(105495, P_BI_TCXO, 2, 1, 91),
        { }
@@ -1283,6 +1407,28 @@ static struct clk_branch gcc_cpuss_rbcpr_clk = {
        },
 };
 
+/*
+ * The source clock frequencies are different for SDM670; define a child clock
+ * pointing to the source clock that uses SDM670 frequencies.
+ */
+static struct clk_branch gcc_sdm670_cpuss_rbcpr_clk = {
+       .halt_reg = 0x48008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x48008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cpuss_rbcpr_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_sdm670_cpuss_rbcpr_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_branch gcc_ddrss_gpu_axi_clk = {
        .halt_reg = 0x44038,
        .halt_check = BRANCH_VOTED,
@@ -2353,6 +2499,55 @@ static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = {
        },
 };
 
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+       .halt_reg = 0x26008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x26008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+       .halt_reg = 0x26004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x26004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_sdcc1_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ice_core_clk = {
+       .halt_reg = 0x2600c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2600c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ice_core_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_sdcc1_ice_core_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_branch gcc_sdcc2_ahb_clk = {
        .halt_reg = 0x14008,
        .halt_check = BRANCH_HALT,
@@ -2415,6 +2610,28 @@ static struct clk_branch gcc_sdcc4_apps_clk = {
        },
 };
 
+/*
+ * The source clock frequencies are different for SDM670; define a child clock
+ * pointing to the source clock that uses SDM670 frequencies.
+ */
+static struct clk_branch gcc_sdm670_sdcc4_apps_clk = {
+       .halt_reg = 0x16004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x16004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc4_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_sdm670_sdcc4_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = {
        .halt_reg = 0x414c,
        .halt_check = BRANCH_HALT_VOTED,
@@ -3308,6 +3525,155 @@ static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = {
        .flags = VOTABLE,
 };
 
+static struct clk_regmap *gcc_sdm670_clocks[] = {
+       [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr,
+       [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr,
+       [GCC_APC_VS_CLK] = &gcc_apc_vs_clk.clkr,
+       [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+       [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr,
+       [GCC_CAMERA_AXI_CLK] = &gcc_camera_axi_clk.clkr,
+       [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr,
+       [GCC_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr,
+       [GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr,
+       [GCC_CE1_CLK] = &gcc_ce1_clk.clkr,
+       [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr,
+       [GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr,
+       [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr,
+       [GCC_CPUSS_RBCPR_CLK] = &gcc_sdm670_cpuss_rbcpr_clk.clkr,
+       [GCC_CPUSS_RBCPR_CLK_SRC] = &gcc_sdm670_cpuss_rbcpr_clk_src.clkr,
+       [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr,
+       [GCC_DISP_AHB_CLK] = &gcc_disp_ahb_clk.clkr,
+       [GCC_DISP_AXI_CLK] = &gcc_disp_axi_clk.clkr,
+       [GCC_DISP_GPLL0_CLK_SRC] = &gcc_disp_gpll0_clk_src.clkr,
+       [GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr,
+       [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr,
+       [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+       [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr,
+       [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+       [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr,
+       [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+       [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr,
+       [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr,
+       [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr,
+       [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr,
+       [GCC_GPU_IREF_CLK] = &gcc_gpu_iref_clk.clkr,
+       [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr,
+       [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr,
+       [GCC_GPU_VS_CLK] = &gcc_gpu_vs_clk.clkr,
+       [GCC_MSS_AXIS2_CLK] = &gcc_mss_axis2_clk.clkr,
+       [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
+       [GCC_MSS_GPLL0_DIV_CLK_SRC] = &gcc_mss_gpll0_div_clk_src.clkr,
+       [GCC_MSS_MFAB_AXIS_CLK] = &gcc_mss_mfab_axis_clk.clkr,
+       [GCC_MSS_Q6_MEMNOC_AXI_CLK] = &gcc_mss_q6_memnoc_axi_clk.clkr,
+       [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
+       [GCC_MSS_VS_CLK] = &gcc_mss_vs_clk.clkr,
+       [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+       [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr,
+       [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+       [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr,
+       [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+       [GCC_QMIP_CAMERA_AHB_CLK] = &gcc_qmip_camera_ahb_clk.clkr,
+       [GCC_QMIP_DISP_AHB_CLK] = &gcc_qmip_disp_ahb_clk.clkr,
+       [GCC_QMIP_VIDEO_AHB_CLK] = &gcc_qmip_video_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr,
+       [GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr,
+       [GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr,
+       [GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr,
+       [GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr,
+       [GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr,
+       [GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S6_CLK] = &gcc_qupv3_wrap0_s6_clk.clkr,
+       [GCC_QUPV3_WRAP0_S6_CLK_SRC] = &gcc_qupv3_wrap0_s6_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S7_CLK] = &gcc_qupv3_wrap0_s7_clk.clkr,
+       [GCC_QUPV3_WRAP0_S7_CLK_SRC] = &gcc_qupv3_wrap0_s7_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr,
+       [GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr,
+       [GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr,
+       [GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr,
+       [GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr,
+       [GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr,
+       [GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S6_CLK] = &gcc_qupv3_wrap1_s6_clk.clkr,
+       [GCC_QUPV3_WRAP1_S6_CLK_SRC] = &gcc_qupv3_wrap1_s6_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S7_CLK] = &gcc_qupv3_wrap1_s7_clk.clkr,
+       [GCC_QUPV3_WRAP1_S7_CLK_SRC] = &gcc_qupv3_wrap1_s7_clk_src.clkr,
+       [GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_1_M_AHB_CLK] = &gcc_qupv3_wrap_1_m_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr,
+       [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+       [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+       [GCC_SDCC1_APPS_CLK_SRC] = &gcc_sdcc1_apps_clk_src.clkr,
+       [GCC_SDCC1_ICE_CORE_CLK_SRC] = &gcc_sdcc1_ice_core_clk_src.clkr,
+       [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr,
+       [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
+       [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
+       [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr,
+       [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr,
+       [GCC_SDCC4_APPS_CLK] = &gcc_sdm670_sdcc4_apps_clk.clkr,
+       [GCC_SDCC4_APPS_CLK_SRC] = &gcc_sdm670_sdcc4_apps_clk_src.clkr,
+       [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr,
+       [GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr,
+       [GCC_TSIF_INACTIVITY_TIMERS_CLK] =
+                                       &gcc_tsif_inactivity_timers_clk.clkr,
+       [GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr,
+       [GCC_TSIF_REF_CLK_SRC] = &gcc_tsif_ref_clk_src.clkr,
+       [GCC_UFS_MEM_CLKREF_CLK] = &gcc_ufs_mem_clkref_clk.clkr,
+       [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr,
+       [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr,
+       [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr,
+       [GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr,
+       [GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr,
+       [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr,
+       [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr,
+       [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr,
+       [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr,
+       [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr,
+       [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] =
+                                       &gcc_ufs_phy_unipro_core_clk_src.clkr,
+       [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr,
+       [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr,
+       [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr,
+       [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] =
+                                       &gcc_usb30_prim_mock_utmi_clk_src.clkr,
+       [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr,
+       [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr,
+       [GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr,
+       [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr,
+       [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr,
+       [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr,
+       [GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr,
+       [GCC_VDDA_VS_CLK] = &gcc_vdda_vs_clk.clkr,
+       [GCC_VDDCX_VS_CLK] = &gcc_vddcx_vs_clk.clkr,
+       [GCC_VDDMX_VS_CLK] = &gcc_vddmx_vs_clk.clkr,
+       [GCC_VIDEO_AHB_CLK] = &gcc_video_ahb_clk.clkr,
+       [GCC_VIDEO_AXI_CLK] = &gcc_video_axi_clk.clkr,
+       [GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr,
+       [GCC_VS_CTRL_AHB_CLK] = &gcc_vs_ctrl_ahb_clk.clkr,
+       [GCC_VS_CTRL_CLK] = &gcc_vs_ctrl_clk.clkr,
+       [GCC_VS_CTRL_CLK_SRC] = &gcc_vs_ctrl_clk_src.clkr,
+       [GCC_VSENSOR_CLK_SRC] = &gcc_vsensor_clk_src.clkr,
+       [GPLL0] = &gpll0.clkr,
+       [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr,
+       [GPLL4] = &gpll4.clkr,
+       [GPLL6] = &gpll6.clkr,
+       [GCC_CPUSS_DVM_BUS_CLK] = &gcc_cpuss_dvm_bus_clk.clkr,
+       [GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr,
+       [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr,
+       [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr,
+       [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr,
+};
+
 static struct clk_regmap *gcc_sdm845_clocks[] = {
        [GCC_AGGRE_NOC_PCIE_TBU_CLK] = &gcc_aggre_noc_pcie_tbu_clk.clkr,
        [GCC_AGGRE_UFS_CARD_AXI_CLK] = &gcc_aggre_ufs_card_axi_clk.clkr,
@@ -3533,6 +3899,22 @@ static const struct qcom_reset_map gcc_sdm845_resets[] = {
        [GCC_PCIE_1_PHY_BCR] = { 0x8e01c },
 };
 
+static struct gdsc *gcc_sdm670_gdscs[] = {
+       [UFS_PHY_GDSC] = &ufs_phy_gdsc,
+       [USB30_PRIM_GDSC] = &usb30_prim_gdsc,
+       [HLOS1_VOTE_AGGRE_NOC_MMU_AUDIO_TBU_GDSC] =
+                       &hlos1_vote_aggre_noc_mmu_audio_tbu_gdsc,
+       [HLOS1_VOTE_AGGRE_NOC_MMU_TBU1_GDSC] =
+                       &hlos1_vote_aggre_noc_mmu_tbu1_gdsc,
+       [HLOS1_VOTE_AGGRE_NOC_MMU_TBU2_GDSC] =
+                       &hlos1_vote_aggre_noc_mmu_tbu2_gdsc,
+       [HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC] =
+                       &hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc,
+       [HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC] =
+                       &hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc,
+       [HLOS1_VOTE_MMNOC_MMU_TBU_SF_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_sf_gdsc,
+};
+
 static struct gdsc *gcc_sdm845_gdscs[] = {
        [PCIE_0_GDSC] = &pcie_0_gdsc,
        [PCIE_1_GDSC] = &pcie_1_gdsc,
@@ -3563,6 +3945,17 @@ static const struct regmap_config gcc_sdm845_regmap_config = {
        .fast_io        = true,
 };
 
+static const struct qcom_cc_desc gcc_sdm670_desc = {
+       .config = &gcc_sdm845_regmap_config,
+       .clks = gcc_sdm670_clocks,
+       .num_clks = ARRAY_SIZE(gcc_sdm670_clocks),
+       /* Snapdragon 670 can function without its own exclusive resets. */
+       .resets = gcc_sdm845_resets,
+       .num_resets = ARRAY_SIZE(gcc_sdm845_resets),
+       .gdscs = gcc_sdm670_gdscs,
+       .num_gdscs = ARRAY_SIZE(gcc_sdm670_gdscs),
+};
+
 static const struct qcom_cc_desc gcc_sdm845_desc = {
        .config = &gcc_sdm845_regmap_config,
        .clks = gcc_sdm845_clocks,
@@ -3574,7 +3967,8 @@ static const struct qcom_cc_desc gcc_sdm845_desc = {
 };
 
 static const struct of_device_id gcc_sdm845_match_table[] = {
-       { .compatible = "qcom,gcc-sdm845" },
+       { .compatible = "qcom,gcc-sdm670", .data = &gcc_sdm670_desc },
+       { .compatible = "qcom,gcc-sdm845", .data = &gcc_sdm845_desc },
        { }
 };
 MODULE_DEVICE_TABLE(of, gcc_sdm845_match_table);
@@ -3600,6 +3994,7 @@ static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
 
 static int gcc_sdm845_probe(struct platform_device *pdev)
 {
+       const struct qcom_cc_desc *gcc_desc;
        struct regmap *regmap;
        int ret;
 
@@ -3616,7 +4011,8 @@ static int gcc_sdm845_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       return qcom_cc_really_probe(pdev, &gcc_sdm845_desc, regmap);
+       gcc_desc = of_device_get_match_data(&pdev->dev);
+       return qcom_cc_really_probe(pdev, gcc_desc, regmap);
 }
 
 static struct platform_driver gcc_sdm845_driver = {
index 68fe9f6..565f991 100644 (file)
@@ -57,7 +57,7 @@ static struct clk_alpha_pll gpll0 = {
        .offset = 0x0,
        .vco_table = default_vco,
        .num_vco = ARRAY_SIZE(default_vco),
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(0),
@@ -83,7 +83,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_aux2 = {
        .post_div_table = post_div_table_gpll0_out_aux2,
        .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_aux2),
        .width = 4,
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll0_out_aux2",
                .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
@@ -92,18 +92,6 @@ static struct clk_alpha_pll_postdiv gpll0_out_aux2 = {
        },
 };
 
-/* listed as BRAMMO, but it doesn't really match */
-static const u8 clk_gpll9_regs[PLL_OFF_MAX_REGS] = {
-       [PLL_OFF_L_VAL] = 0x04,
-       [PLL_OFF_ALPHA_VAL] = 0x08,
-       [PLL_OFF_ALPHA_VAL_U] = 0x0c,
-       [PLL_OFF_TEST_CTL] = 0x10,
-       [PLL_OFF_TEST_CTL_U] = 0x14,
-       [PLL_OFF_USER_CTL] = 0x18,
-       [PLL_OFF_CONFIG_CTL] = 0x1C,
-       [PLL_OFF_STATUS] = 0x20,
-};
-
 static const struct clk_div_table post_div_table_gpll0_out_main[] = {
        { 0x0, 1 },
        { }
@@ -115,7 +103,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_main = {
        .post_div_table = post_div_table_gpll0_out_main,
        .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_main),
        .width = 4,
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll0_out_main",
                .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
@@ -137,7 +125,7 @@ static struct clk_alpha_pll gpll10 = {
        .offset = 0xa000,
        .vco_table = gpll10_vco,
        .num_vco = ARRAY_SIZE(gpll10_vco),
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(10),
@@ -163,7 +151,7 @@ static struct clk_alpha_pll_postdiv gpll10_out_main = {
        .post_div_table = post_div_table_gpll10_out_main,
        .num_post_div = ARRAY_SIZE(post_div_table_gpll10_out_main),
        .width = 4,
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll10_out_main",
                .parent_hws = (const struct clk_hw *[]){ &gpll10.clkr.hw },
@@ -189,7 +177,7 @@ static struct clk_alpha_pll gpll11 = {
        .vco_table = default_vco,
        .num_vco = ARRAY_SIZE(default_vco),
        .flags = SUPPORTS_DYNAMIC_UPDATE,
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(11),
@@ -215,7 +203,7 @@ static struct clk_alpha_pll_postdiv gpll11_out_main = {
        .post_div_table = post_div_table_gpll11_out_main,
        .num_post_div = ARRAY_SIZE(post_div_table_gpll11_out_main),
        .width = 4,
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll11_out_main",
                .parent_hws = (const struct clk_hw *[]){ &gpll11.clkr.hw },
@@ -229,7 +217,7 @@ static struct clk_alpha_pll gpll3 = {
        .offset = 0x3000,
        .vco_table = default_vco,
        .num_vco = ARRAY_SIZE(default_vco),
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(3),
@@ -248,7 +236,7 @@ static struct clk_alpha_pll gpll4 = {
        .offset = 0x4000,
        .vco_table = default_vco,
        .num_vco = ARRAY_SIZE(default_vco),
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(4),
@@ -274,7 +262,7 @@ static struct clk_alpha_pll_postdiv gpll4_out_main = {
        .post_div_table = post_div_table_gpll4_out_main,
        .num_post_div = ARRAY_SIZE(post_div_table_gpll4_out_main),
        .width = 4,
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll4_out_main",
                .parent_hws = (const struct clk_hw *[]){ &gpll4.clkr.hw },
@@ -287,7 +275,7 @@ static struct clk_alpha_pll gpll6 = {
        .offset = 0x6000,
        .vco_table = default_vco,
        .num_vco = ARRAY_SIZE(default_vco),
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(6),
@@ -313,7 +301,7 @@ static struct clk_alpha_pll_postdiv gpll6_out_main = {
        .post_div_table = post_div_table_gpll6_out_main,
        .num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_main),
        .width = 4,
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll6_out_main",
                .parent_hws = (const struct clk_hw *[]){ &gpll6.clkr.hw },
@@ -326,7 +314,7 @@ static struct clk_alpha_pll gpll7 = {
        .offset = 0x7000,
        .vco_table = default_vco,
        .num_vco = ARRAY_SIZE(default_vco),
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(7),
@@ -352,7 +340,7 @@ static struct clk_alpha_pll_postdiv gpll7_out_main = {
        .post_div_table = post_div_table_gpll7_out_main,
        .num_post_div = ARRAY_SIZE(post_div_table_gpll7_out_main),
        .width = 4,
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll7_out_main",
                .parent_hws = (const struct clk_hw *[]){ &gpll7.clkr.hw },
@@ -380,7 +368,7 @@ static struct clk_alpha_pll gpll8 = {
        .offset = 0x8000,
        .vco_table = default_vco,
        .num_vco = ARRAY_SIZE(default_vco),
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .flags = SUPPORTS_DYNAMIC_UPDATE,
        .clkr = {
                .enable_reg = 0x79000,
@@ -407,7 +395,7 @@ static struct clk_alpha_pll_postdiv gpll8_out_main = {
        .post_div_table = post_div_table_gpll8_out_main,
        .num_post_div = ARRAY_SIZE(post_div_table_gpll8_out_main),
        .width = 4,
-       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll8_out_main",
                .parent_hws = (const struct clk_hw *[]){ &gpll8.clkr.hw },
@@ -431,7 +419,7 @@ static struct clk_alpha_pll gpll9 = {
        .offset = 0x9000,
        .vco_table = gpll9_vco,
        .num_vco = ARRAY_SIZE(gpll9_vco),
-       .regs = clk_gpll9_regs,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO_EVO],
        .clkr = {
                .enable_reg = 0x79000,
                .enable_mask = BIT(9),
@@ -457,7 +445,7 @@ static struct clk_alpha_pll_postdiv gpll9_out_main = {
        .post_div_table = post_div_table_gpll9_out_main,
        .num_post_div = ARRAY_SIZE(post_div_table_gpll9_out_main),
        .width = 2,
-       .regs = clk_gpll9_regs,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO_EVO],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll9_out_main",
                .parent_hws = (const struct clk_hw *[]){ &gpll9.clkr.hw },
index 6941240..9b4e4bb 100644 (file)
@@ -2316,7 +2316,7 @@ static struct gdsc usb30_prim_gdsc = {
        .pd = {
                .name = "usb30_prim_gdsc",
        },
-       .pwrsts = PWRSTS_OFF_ON,
+       .pwrsts = PWRSTS_RET_ON,
 };
 
 static struct gdsc ufs_phy_gdsc = {
diff --git a/drivers/clk/qcom/gcc-sm6375.c b/drivers/clk/qcom/gcc-sm6375.c
new file mode 100644 (file)
index 0000000..89a1cc9
--- /dev/null
@@ -0,0 +1,3919 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022, Konrad Dybcio <konrad.dybcio@somainline.org>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,sm6375-gcc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "clk-regmap-phy-mux.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+       DT_BI_TCXO,
+       DT_BI_TCXO_AO,
+       DT_SLEEP_CLK
+};
+
+enum {
+       P_BI_TCXO,
+       P_GPLL0_OUT_EVEN,
+       P_GPLL0_OUT_MAIN,
+       P_GPLL0_OUT_ODD,
+       P_GPLL10_OUT_EVEN,
+       P_GPLL11_OUT_EVEN,
+       P_GPLL11_OUT_ODD,
+       P_GPLL3_OUT_EVEN,
+       P_GPLL3_OUT_MAIN,
+       P_GPLL4_OUT_EVEN,
+       P_GPLL5_OUT_EVEN,
+       P_GPLL6_OUT_EVEN,
+       P_GPLL6_OUT_MAIN,
+       P_GPLL7_OUT_EVEN,
+       P_GPLL8_OUT_EVEN,
+       P_GPLL8_OUT_MAIN,
+       P_GPLL9_OUT_EARLY,
+       P_GPLL9_OUT_MAIN,
+       P_SLEEP_CLK,
+};
+
+static struct pll_vco lucid_vco[] = {
+       { 249600000, 2000000000, 0 },
+};
+
+static struct pll_vco zonda_vco[] = {
+       { 595200000, 3600000000UL, 0 },
+};
+
+static struct clk_alpha_pll gpll0 = {
+       .offset = 0x0,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll0",
+                       .parent_data = &(const struct clk_parent_data){
+                               .index = DT_BI_TCXO,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_lucid_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll0_out_even[] = {
+       { 0x1, 2 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll0_out_even = {
+       .offset = 0x0,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll0_out_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0_out_even",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll0.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_lucid_ops,
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll0_out_odd[] = {
+       { 0x3, 3 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll0_out_odd = {
+       .offset = 0x0,
+       .post_div_shift = 12,
+       .post_div_table = post_div_table_gpll0_out_odd,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_odd),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0_out_odd",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll0.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_lucid_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll1 = {
+       .offset = 0x1000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll1",
+                       .parent_data = &(const struct clk_parent_data){
+                               .index = DT_BI_TCXO,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_lucid_ops,
+               },
+       },
+};
+
+/* 1152MHz Configuration */
+static const struct alpha_pll_config gpll10_config = {
+       .l = 0x3c,
+       .alpha = 0x0,
+       .config_ctl_val = 0x20485699,
+       .config_ctl_hi_val = 0x00002261,
+       .config_ctl_hi1_val = 0x329a299c,
+       .user_ctl_val = 0x00000001,
+       .user_ctl_hi_val = 0x00000805,
+       .user_ctl_hi1_val = 0x00000000,
+};
+
+static struct clk_alpha_pll gpll10 = {
+       .offset = 0xa000,
+       .vco_table = lucid_vco,
+       .num_vco = ARRAY_SIZE(lucid_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .flags = SUPPORTS_FSM_LEGACY_MODE,
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll10",
+                       .parent_data = &(const struct clk_parent_data){
+                               .index = DT_BI_TCXO,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_lucid_ops,
+               },
+       },
+};
+
+/* 532MHz Configuration */
+static const struct alpha_pll_config gpll11_config = {
+       .l = 0x1b,
+       .alpha = 0xb555,
+       .config_ctl_val = 0x20485699,
+       .config_ctl_hi_val = 0x00002261,
+       .config_ctl_hi1_val = 0x329a299c,
+       .user_ctl_val = 0x00000001,
+       .user_ctl_hi_val = 0x00000805,
+       .user_ctl_hi1_val = 0x00000000,
+};
+
+static struct clk_alpha_pll gpll11 = {
+       .offset = 0xb000,
+       .vco_table = lucid_vco,
+       .num_vco = ARRAY_SIZE(lucid_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .flags = SUPPORTS_FSM_LEGACY_MODE,
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll11",
+                       .parent_data = &(const struct clk_parent_data){
+                               .index = DT_BI_TCXO,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_lucid_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll gpll3 = {
+       .offset = 0x3000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(3),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll3",
+                       .parent_data = &(const struct clk_parent_data){
+                               .index = DT_BI_TCXO,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_lucid_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll3_out_even[] = {
+       { 0x1, 2 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll3_out_even = {
+       .offset = 0x3000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll3_out_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll3_out_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll3_out_even",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll3.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_lucid_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll4 = {
+       .offset = 0x4000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll4",
+                       .parent_data = &(const struct clk_parent_data){
+                               .index = DT_BI_TCXO,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_lucid_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll gpll5 = {
+       .offset = 0x5000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(5),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll5",
+                       .parent_data = &(const struct clk_parent_data){
+                               .index = DT_BI_TCXO,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_lucid_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll gpll6 = {
+       .offset = 0x6000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(6),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll6",
+                       .parent_data = &(const struct clk_parent_data){
+                               .index = DT_BI_TCXO,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_lucid_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll6_out_even[] = {
+       { 0x1, 2 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll6_out_even = {
+       .offset = 0x6000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll6_out_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll6_out_even",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll6.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_lucid_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll7 = {
+       .offset = 0x7000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll7",
+                       .parent_data = &(const struct clk_parent_data){
+                               .index = DT_BI_TCXO,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_lucid_ops,
+               },
+       },
+};
+
+/* 400MHz Configuration */
+static const struct alpha_pll_config gpll8_config = {
+       .l = 0x14,
+       .alpha = 0xd555,
+       .config_ctl_val = 0x20485699,
+       .config_ctl_hi_val = 0x00002261,
+       .config_ctl_hi1_val = 0x329a299c,
+       .user_ctl_val = 0x00000101,
+       .user_ctl_hi_val = 0x00000805,
+       .user_ctl_hi1_val = 0x00000000,
+};
+
+static struct clk_alpha_pll gpll8 = {
+       .offset = 0x8000,
+       .vco_table = lucid_vco,
+       .num_vco = ARRAY_SIZE(lucid_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .flags = SUPPORTS_FSM_LEGACY_MODE,
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll8",
+                       .parent_data = &(const struct clk_parent_data){
+                               .index = DT_BI_TCXO,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_lucid_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll8_out_even[] = {
+       { 0x1, 2 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll8_out_even = {
+       .offset = 0x8000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll8_out_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll8_out_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll8_out_even",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll8.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_alpha_pll_postdiv_lucid_ops,
+       },
+};
+
+/* 1440MHz Configuration */
+static const struct alpha_pll_config gpll9_config = {
+       .l = 0x4b,
+       .alpha = 0x0,
+       .config_ctl_val = 0x08200800,
+       .config_ctl_hi_val = 0x05022011,
+       .config_ctl_hi1_val = 0x08000000,
+       .user_ctl_val = 0x00000301,
+};
+
+static struct clk_alpha_pll gpll9 = {
+       .offset = 0x9000,
+       .vco_table = zonda_vco,
+       .num_vco = ARRAY_SIZE(zonda_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll9",
+                       .parent_data = &(const struct clk_parent_data){
+                               .index = DT_BI_TCXO,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_zonda_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll9_out_main[] = {
+       { 0x3, 4 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll9_out_main = {
+       .offset = 0x9000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll9_out_main,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll9_out_main),
+       .width = 2,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll9_out_main",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll9.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_alpha_pll_postdiv_zonda_ops,
+       },
+};
+
+static const struct parent_map gcc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL0_OUT_EVEN, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_0[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_1[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL0_OUT_EVEN, 2 },
+       { P_GPLL6_OUT_EVEN, 4 },
+};
+
+static const struct clk_parent_data gcc_parent_data_1[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+       { .hw = &gpll6_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_2[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL0_OUT_EVEN, 2 },
+       { P_GPLL0_OUT_ODD, 4 },
+};
+
+static const struct clk_parent_data gcc_parent_data_2[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+       { .hw = &gpll0_out_odd.clkr.hw },
+};
+
+static const struct clk_parent_data gcc_parent_data_2_ao[] = {
+       { .index = DT_BI_TCXO_AO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+       { .hw = &gpll0_out_odd.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_3[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL9_OUT_EARLY, 2 },
+       { P_GPLL10_OUT_EVEN, 3 },
+       { P_GPLL9_OUT_MAIN, 4 },
+       { P_GPLL3_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_3[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll9.clkr.hw },
+       { .hw = &gpll10.clkr.hw },
+       { .hw = &gpll9_out_main.clkr.hw },
+       { .hw = &gpll3_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_4[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL0_OUT_EVEN, 2 },
+       { P_GPLL0_OUT_ODD, 4 },
+       { P_GPLL4_OUT_EVEN, 5 },
+       { P_GPLL3_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_4[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+       { .hw = &gpll0_out_odd.clkr.hw },
+       { .hw = &gpll4.clkr.hw },
+       { .hw = &gpll3_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_5[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL8_OUT_MAIN, 2 },
+       { P_GPLL10_OUT_EVEN, 3 },
+       { P_GPLL9_OUT_MAIN, 4 },
+       { P_GPLL8_OUT_EVEN, 5 },
+       { P_GPLL3_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_5[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll8.clkr.hw },
+       { .hw = &gpll10.clkr.hw },
+       { .hw = &gpll9_out_main.clkr.hw },
+       { .hw = &gpll8_out_even.clkr.hw },
+       { .hw = &gpll3_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_6[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL8_OUT_MAIN, 2 },
+       { P_GPLL5_OUT_EVEN, 3 },
+       { P_GPLL9_OUT_MAIN, 4 },
+       { P_GPLL8_OUT_EVEN, 5 },
+       { P_GPLL3_OUT_MAIN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_6[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll8.clkr.hw },
+       { .hw = &gpll5.clkr.hw },
+       { .hw = &gpll9_out_main.clkr.hw },
+       { .hw = &gpll8_out_even.clkr.hw },
+       { .hw = &gpll3.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_7[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL0_OUT_EVEN, 2 },
+       { P_GPLL0_OUT_ODD, 4 },
+       { P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data gcc_parent_data_7[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+       { .hw = &gpll0_out_odd.clkr.hw },
+       { .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map gcc_parent_map_8[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL0_OUT_EVEN, 2 },
+       { P_GPLL10_OUT_EVEN, 3 },
+       { P_GPLL4_OUT_EVEN, 5 },
+       { P_GPLL3_OUT_MAIN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_8[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+       { .hw = &gpll10.clkr.hw },
+       { .hw = &gpll4.clkr.hw },
+       { .hw = &gpll3.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_9[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL0_OUT_EVEN, 2 },
+       { P_GPLL10_OUT_EVEN, 3 },
+       { P_GPLL9_OUT_MAIN, 4 },
+       { P_GPLL8_OUT_EVEN, 5 },
+       { P_GPLL3_OUT_MAIN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_9[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+       { .hw = &gpll10.clkr.hw },
+       { .hw = &gpll9_out_main.clkr.hw },
+       { .hw = &gpll8_out_even.clkr.hw },
+       { .hw = &gpll3.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_10[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL8_OUT_MAIN, 2 },
+       { P_GPLL10_OUT_EVEN, 3 },
+       { P_GPLL9_OUT_MAIN, 4 },
+       { P_GPLL8_OUT_EVEN, 5 },
+       { P_GPLL3_OUT_MAIN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_10[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll8.clkr.hw },
+       { .hw = &gpll10.clkr.hw },
+       { .hw = &gpll9_out_main.clkr.hw },
+       { .hw = &gpll8_out_even.clkr.hw },
+       { .hw = &gpll3.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_11[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL8_OUT_MAIN, 2 },
+       { P_GPLL10_OUT_EVEN, 3 },
+       { P_GPLL6_OUT_MAIN, 4 },
+       { P_GPLL3_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_11[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll8.clkr.hw },
+       { .hw = &gpll10.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll3_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_12[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL0_OUT_EVEN, 2 },
+       { P_GPLL7_OUT_EVEN, 3 },
+       { P_GPLL4_OUT_EVEN, 5 },
+};
+
+static const struct clk_parent_data gcc_parent_data_12[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+       { .hw = &gpll7.clkr.hw },
+       { .hw = &gpll4.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_13[] = {
+       { P_BI_TCXO, 0 },
+       { P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data gcc_parent_data_13[] = {
+       { .index = DT_BI_TCXO },
+       { .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map gcc_parent_map_14[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL11_OUT_ODD, 2 },
+       { P_GPLL11_OUT_EVEN, 3 },
+};
+
+static const struct clk_parent_data gcc_parent_data_14[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpll11.clkr.hw },
+       { .hw = &gpll11.clkr.hw },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_axi_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0),
+       F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       F(300000000, P_GPLL0_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_axi_clk_src = {
+       .cmd_rcgr = 0x5802c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_gcc_camss_axi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_axi_clk_src",
+               .parent_data = gcc_parent_data_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_8),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_cci_0_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_cci_0_clk_src = {
+       .cmd_rcgr = 0x56000,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_9,
+       .freq_tbl = ftbl_gcc_camss_cci_0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_cci_0_clk_src",
+               .parent_data = gcc_parent_data_9,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_9),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_cci_1_clk_src = {
+       .cmd_rcgr = 0x5c000,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_9,
+       .freq_tbl = ftbl_gcc_camss_cci_0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_cci_1_clk_src",
+               .parent_data = gcc_parent_data_9,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_9),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_csi0phytimer_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(100000000, P_GPLL0_OUT_ODD, 2, 0, 0),
+       F(300000000, P_GPLL0_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_csi0phytimer_clk_src = {
+       .cmd_rcgr = 0x59000,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_gcc_camss_csi0phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_csi0phytimer_clk_src",
+               .parent_data = gcc_parent_data_4,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_csi1phytimer_clk_src = {
+       .cmd_rcgr = 0x5901c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_gcc_camss_csi0phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_csi1phytimer_clk_src",
+               .parent_data = gcc_parent_data_4,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_csi2phytimer_clk_src = {
+       .cmd_rcgr = 0x59038,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_gcc_camss_csi0phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_csi2phytimer_clk_src",
+               .parent_data = gcc_parent_data_4,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_csi3phytimer_clk_src = {
+       .cmd_rcgr = 0x59054,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_gcc_camss_csi0phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_csi3phytimer_clk_src",
+               .parent_data = gcc_parent_data_4,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_mclk0_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(24000000, P_GPLL9_OUT_MAIN, 1, 1, 15),
+       F(65454545, P_GPLL9_OUT_EARLY, 11, 1, 2),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_mclk0_clk_src = {
+       .cmd_rcgr = 0x51000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_gcc_camss_mclk0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_mclk0_clk_src",
+               .parent_data = gcc_parent_data_3,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_3),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_mclk1_clk_src = {
+       .cmd_rcgr = 0x5101c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_gcc_camss_mclk0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_mclk1_clk_src",
+               .parent_data = gcc_parent_data_3,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_3),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_mclk2_clk_src = {
+       .cmd_rcgr = 0x51038,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_gcc_camss_mclk0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_mclk2_clk_src",
+               .parent_data = gcc_parent_data_3,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_3),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_mclk3_clk_src = {
+       .cmd_rcgr = 0x51054,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_gcc_camss_mclk0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_mclk3_clk_src",
+               .parent_data = gcc_parent_data_3,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_3),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_mclk4_clk_src = {
+       .cmd_rcgr = 0x51070,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_gcc_camss_mclk0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_mclk4_clk_src",
+               .parent_data = gcc_parent_data_3,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_3),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_ope_ahb_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
+       F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_ope_ahb_clk_src = {
+       .cmd_rcgr = 0x55024,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_10,
+       .freq_tbl = ftbl_gcc_camss_ope_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_ope_ahb_clk_src",
+               .parent_data = gcc_parent_data_10,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_10),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_ope_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(200000000, P_GPLL8_OUT_EVEN, 1, 0, 0),
+       F(266600000, P_GPLL8_OUT_EVEN, 1, 0, 0),
+       F(480000000, P_GPLL8_OUT_EVEN, 1, 0, 0),
+       F(580000000, P_GPLL8_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_ope_clk_src = {
+       .cmd_rcgr = 0x55004,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_10,
+       .freq_tbl = ftbl_gcc_camss_ope_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_ope_clk_src",
+               .parent_data = gcc_parent_data_10,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_10),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_tfe_0_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(120000000, P_GPLL0_OUT_MAIN, 5, 0, 0),
+       F(133333333, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       F(144000000, P_GPLL9_OUT_MAIN, 2.5, 0, 0),
+       F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
+       F(180000000, P_GPLL9_OUT_MAIN, 2, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+       F(329142857, P_GPLL10_OUT_EVEN, 3.5, 0, 0),
+       F(384000000, P_GPLL10_OUT_EVEN, 3, 0, 0),
+       F(460800000, P_GPLL10_OUT_EVEN, 2.5, 0, 0),
+       F(576000000, P_GPLL10_OUT_EVEN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_tfe_0_clk_src = {
+       .cmd_rcgr = 0x52004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_5,
+       .freq_tbl = ftbl_gcc_camss_tfe_0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_tfe_0_clk_src",
+               .parent_data = gcc_parent_data_5,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_5),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_tfe_0_csid_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(120000000, P_GPLL0_OUT_MAIN, 5, 0, 0),
+       F(266571429, P_GPLL5_OUT_EVEN, 3.5, 0, 0),
+       F(426400000, P_GPLL3_OUT_MAIN, 2.5, 0, 0),
+       F(466500000, P_GPLL5_OUT_EVEN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_tfe_0_csid_clk_src = {
+       .cmd_rcgr = 0x52094,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_6,
+       .freq_tbl = ftbl_gcc_camss_tfe_0_csid_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_tfe_0_csid_clk_src",
+               .parent_data = gcc_parent_data_6,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_6),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_tfe_1_clk_src = {
+       .cmd_rcgr = 0x52024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_5,
+       .freq_tbl = ftbl_gcc_camss_tfe_0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_tfe_1_clk_src",
+               .parent_data = gcc_parent_data_5,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_5),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_tfe_1_csid_clk_src = {
+       .cmd_rcgr = 0x520b4,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_6,
+       .freq_tbl = ftbl_gcc_camss_tfe_0_csid_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_tfe_1_csid_clk_src",
+               .parent_data = gcc_parent_data_6,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_6),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_tfe_2_clk_src = {
+       .cmd_rcgr = 0x52044,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_5,
+       .freq_tbl = ftbl_gcc_camss_tfe_0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_tfe_2_clk_src",
+               .parent_data = gcc_parent_data_5,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_5),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_tfe_2_csid_clk_src = {
+       .cmd_rcgr = 0x520d4,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_6,
+       .freq_tbl = ftbl_gcc_camss_tfe_0_csid_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_tfe_2_csid_clk_src",
+               .parent_data = gcc_parent_data_6,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_6),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_tfe_cphy_rx_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(256000000, P_GPLL6_OUT_MAIN, 3, 0, 0),
+       F(384000000, P_GPLL6_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_tfe_cphy_rx_clk_src = {
+       .cmd_rcgr = 0x52064,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_11,
+       .freq_tbl = ftbl_gcc_camss_tfe_cphy_rx_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_tfe_cphy_rx_clk_src",
+               .parent_data = gcc_parent_data_11,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_11),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_top_ahb_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(40000000, P_GPLL0_OUT_EVEN, 7.5, 0, 0),
+       F(80000000, P_GPLL0_OUT_MAIN, 7.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_top_ahb_clk_src = {
+       .cmd_rcgr = 0x58010,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_gcc_camss_top_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_top_ahb_clk_src",
+               .parent_data = gcc_parent_data_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_8),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(50000000, P_GPLL0_OUT_ODD, 4, 0, 0),
+       F(100000000, P_GPLL0_OUT_ODD, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_cpuss_ahb_clk_src = {
+       .cmd_rcgr = 0x2b13c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_cpuss_ahb_clk_src",
+               .parent_data = gcc_parent_data_2_ao,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_2_ao),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = {
+       F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(50000000, P_GPLL0_OUT_ODD, 4, 0, 0),
+       F(100000000, P_GPLL0_OUT_ODD, 2, 0, 0),
+       F(200000000, P_GPLL0_OUT_ODD, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_gp1_clk_src = {
+       .cmd_rcgr = 0x4d004,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_7,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp1_clk_src",
+               .parent_data = gcc_parent_data_7,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_7),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_gp2_clk_src = {
+       .cmd_rcgr = 0x4e004,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_7,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp2_clk_src",
+               .parent_data = gcc_parent_data_7,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_7),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_gp3_clk_src = {
+       .cmd_rcgr = 0x4f004,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_7,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp3_clk_src",
+               .parent_data = gcc_parent_data_7,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_7),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(60000000, P_GPLL0_OUT_EVEN, 5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_pdm2_clk_src = {
+       .cmd_rcgr = 0x20010,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_pdm2_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_pdm2_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+       F(7372800, P_GPLL0_OUT_EVEN, 1, 384, 15625),
+       F(14745600, P_GPLL0_OUT_EVEN, 1, 768, 15625),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(29491200, P_GPLL0_OUT_EVEN, 1, 1536, 15625),
+       F(32000000, P_GPLL0_OUT_EVEN, 1, 8, 75),
+       F(48000000, P_GPLL0_OUT_EVEN, 1, 4, 25),
+       F(64000000, P_GPLL0_OUT_EVEN, 1, 16, 75),
+       F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(80000000, P_GPLL0_OUT_EVEN, 1, 4, 15),
+       F(96000000, P_GPLL0_OUT_EVEN, 1, 8, 25),
+       F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0),
+       F(102400000, P_GPLL0_OUT_EVEN, 1, 128, 375),
+       F(112000000, P_GPLL0_OUT_EVEN, 1, 28, 75),
+       F(117964800, P_GPLL0_OUT_EVEN, 1, 6144, 15625),
+       F(120000000, P_GPLL0_OUT_EVEN, 2.5, 0, 0),
+       F(128000000, P_GPLL6_OUT_EVEN, 3, 0, 0),
+       { }
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s0_clk_src",
+       .parent_data = gcc_parent_data_1,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+       .ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
+       .cmd_rcgr = 0x1f148,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s1_clk_src",
+       .parent_data = gcc_parent_data_1,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+       .ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
+       .cmd_rcgr = 0x1f278,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s2_clk_src",
+       .parent_data = gcc_parent_data_1,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+       .ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
+       .cmd_rcgr = 0x1f3a8,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s3_clk_src",
+       .parent_data = gcc_parent_data_1,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+       .ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
+       .cmd_rcgr = 0x1f4d8,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s4_clk_src",
+       .parent_data = gcc_parent_data_1,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+       .ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
+       .cmd_rcgr = 0x1f608,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s5_clk_src",
+       .parent_data = gcc_parent_data_1,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+       .ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
+       .cmd_rcgr = 0x1f738,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
+       .name = "gcc_qupv3_wrap1_s0_clk_src",
+       .parent_data = gcc_parent_data_1,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+       .ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
+       .cmd_rcgr = 0x5301c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
+       .name = "gcc_qupv3_wrap1_s1_clk_src",
+       .parent_data = gcc_parent_data_1,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+       .ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
+       .cmd_rcgr = 0x5314c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
+       .name = "gcc_qupv3_wrap1_s2_clk_src",
+       .parent_data = gcc_parent_data_1,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+       .ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
+       .cmd_rcgr = 0x5327c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
+       .name = "gcc_qupv3_wrap1_s3_clk_src",
+       .parent_data = gcc_parent_data_1,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+       .ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
+       .cmd_rcgr = 0x533ac,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
+       .name = "gcc_qupv3_wrap1_s4_clk_src",
+       .parent_data = gcc_parent_data_1,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+       .ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
+       .cmd_rcgr = 0x534dc,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
+       .name = "gcc_qupv3_wrap1_s5_clk_src",
+       .parent_data = gcc_parent_data_1,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+       .ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
+       .cmd_rcgr = 0x5360c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = {
+       F(144000, P_BI_TCXO, 16, 3, 25),
+       F(400000, P_BI_TCXO, 12, 1, 4),
+       F(20000000, P_GPLL0_OUT_EVEN, 5, 1, 3),
+       F(25000000, P_GPLL0_OUT_EVEN, 6, 1, 2),
+       F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
+       F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0),
+       F(192000000, P_GPLL6_OUT_EVEN, 2, 0, 0),
+       F(384000000, P_GPLL6_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc1_apps_clk_src = {
+       .cmd_rcgr = 0x38028,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc1_apps_clk_src",
+               .parent_data = gcc_parent_data_1,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = {
+       F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0),
+       F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       F(300000000, P_GPLL0_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = {
+       .cmd_rcgr = 0x38010,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc1_ice_core_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
+       F(400000, P_BI_TCXO, 12, 1, 4),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
+       F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0),
+       F(202000000, P_GPLL7_OUT_EVEN, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
+       .cmd_rcgr = 0x1e00c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_12,
+       .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc2_apps_clk_src",
+               .parent_data = gcc_parent_data_12,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_12),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+       F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(50000000, P_GPLL0_OUT_ODD, 4, 0, 0),
+       F(100000000, P_GPLL0_OUT_ODD, 2, 0, 0),
+       F(200000000, P_GPLL0_OUT_ODD, 1, 0, 0),
+       F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = {
+       .cmd_rcgr = 0x45020,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_axi_clk_src",
+               .parent_data = gcc_parent_data_2,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_2),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+       F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0),
+       F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0),
+       F(300000000, P_GPLL0_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = {
+       .cmd_rcgr = 0x45048,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_ice_core_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = {
+       F(9600000, P_BI_TCXO, 2, 0, 0),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = {
+       .cmd_rcgr = 0x4507c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_phy_aux_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
+       F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0),
+       F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = {
+       .cmd_rcgr = 0x45060,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_phy_unipro_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_unipro_core_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
+       F(66666667, P_GPLL0_OUT_EVEN, 4.5, 0, 0),
+       F(133333333, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       F(200000000, P_GPLL0_OUT_ODD, 1, 0, 0),
+       F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_usb30_prim_master_clk_src = {
+       .cmd_rcgr = 0x1a01c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb30_prim_master_clk_src",
+               .parent_data = gcc_parent_data_2,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_2),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_mock_utmi_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = {
+       .cmd_rcgr = 0x1a034,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb30_prim_mock_utmi_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = {
+       .cmd_rcgr = 0x1a060,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_13,
+       .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb3_prim_phy_aux_clk_src",
+               .parent_data = gcc_parent_data_13,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_13),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_video_venus_clk_src[] = {
+       F(133000000, P_GPLL11_OUT_EVEN, 4, 0, 0),
+       F(240000000, P_GPLL11_OUT_EVEN, 2.5, 0, 0),
+       F(300000000, P_GPLL11_OUT_EVEN, 2, 0, 0),
+       F(384000000, P_GPLL11_OUT_EVEN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_video_venus_clk_src = {
+       .cmd_rcgr = 0x58060,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_14,
+       .freq_tbl = ftbl_gcc_video_venus_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_video_venus_clk_src",
+               .parent_data = gcc_parent_data_14,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_14),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_regmap_div gcc_cpuss_ahb_postdiv_clk_src = {
+       .reg = 0x2b154,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gcc_cpuss_ahb_postdiv_clk_src",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gcc_cpuss_ahb_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_regmap_div gcc_usb30_prim_mock_utmi_postdiv_clk_src = {
+       .reg = 0x1a04c,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gcc_usb30_prim_mock_utmi_postdiv_clk_src",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_branch gcc_ahb2phy_csi_clk = {
+       .halt_reg = 0x1d004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x1d004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1d004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ahb2phy_csi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ahb2phy_usb_clk = {
+       .halt_reg = 0x1d008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x1d008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1d008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ahb2phy_usb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_bimc_gpu_axi_clk = {
+       .halt_reg = 0x71154,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x71154,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x71154,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_bimc_gpu_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+       .halt_reg = 0x23004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x23004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_boot_rom_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cam_throttle_nrt_clk = {
+       .halt_reg = 0x17070,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17070,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(27),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cam_throttle_nrt_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cam_throttle_rt_clk = {
+       .halt_reg = 0x1706c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x1706c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(26),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cam_throttle_rt_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camera_ahb_clk = {
+       .halt_reg = 0x17008,
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0x17008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camera_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_axi_clk = {
+       .halt_reg = 0x58044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_axi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_axi_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cci_0_clk = {
+       .halt_reg = 0x56018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x56018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_cci_0_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_cci_0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cci_1_clk = {
+       .halt_reg = 0x5c018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5c018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_cci_1_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_cci_1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cphy_0_clk = {
+       .halt_reg = 0x52088,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x52088,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_cphy_0_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cphy_1_clk = {
+       .halt_reg = 0x5208c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5208c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_cphy_1_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cphy_2_clk = {
+       .halt_reg = 0x52090,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x52090,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_cphy_2_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cphy_3_clk = {
+       .halt_reg = 0x520f8,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x520f8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_cphy_3_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi0phytimer_clk = {
+       .halt_reg = 0x59018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_csi0phytimer_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_csi0phytimer_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi1phytimer_clk = {
+       .halt_reg = 0x59034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_csi1phytimer_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_csi1phytimer_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi2phytimer_clk = {
+       .halt_reg = 0x59050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_csi2phytimer_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_csi2phytimer_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi3phytimer_clk = {
+       .halt_reg = 0x5906c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5906c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_csi3phytimer_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_csi3phytimer_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_mclk0_clk = {
+       .halt_reg = 0x51018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x51018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_mclk0_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_mclk0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_mclk1_clk = {
+       .halt_reg = 0x51034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x51034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_mclk1_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_mclk1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_mclk2_clk = {
+       .halt_reg = 0x51050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x51050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_mclk2_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_mclk2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_mclk3_clk = {
+       .halt_reg = 0x5106c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5106c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_mclk3_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_mclk3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_mclk4_clk = {
+       .halt_reg = 0x51088,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x51088,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_mclk4_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_mclk4_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_nrt_axi_clk = {
+       .halt_reg = 0x58054,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_nrt_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_ope_ahb_clk = {
+       .halt_reg = 0x5503c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5503c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_ope_ahb_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_ope_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_ope_clk = {
+       .halt_reg = 0x5501c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5501c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_ope_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_ope_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_rt_axi_clk = {
+       .halt_reg = 0x5805c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5805c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_rt_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_0_clk = {
+       .halt_reg = 0x5201c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5201c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_0_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_tfe_0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_0_cphy_rx_clk = {
+       .halt_reg = 0x5207c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5207c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_0_cphy_rx_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_0_csid_clk = {
+       .halt_reg = 0x520ac,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x520ac,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_0_csid_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_tfe_0_csid_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_1_clk = {
+       .halt_reg = 0x5203c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5203c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_1_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_tfe_1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_1_cphy_rx_clk = {
+       .halt_reg = 0x52080,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x52080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_1_cphy_rx_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_1_csid_clk = {
+       .halt_reg = 0x520cc,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x520cc,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_1_csid_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_tfe_1_csid_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_2_clk = {
+       .halt_reg = 0x5205c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5205c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_2_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_tfe_2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_2_cphy_rx_clk = {
+       .halt_reg = 0x52084,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x52084,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_2_cphy_rx_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_2_csid_clk = {
+       .halt_reg = 0x520ec,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x520ec,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_2_csid_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_tfe_2_csid_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_top_ahb_clk = {
+       .halt_reg = 0x58028,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_top_ahb_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = {
+       .halt_reg = 0x1a084,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x1a084,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1a084,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cfg_noc_usb3_prim_axi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_usb30_prim_master_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_ahb_clk = {
+       .halt_reg = 0x1700c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x1700c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1700c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_regmap_div gcc_disp_gpll0_clk_src = {
+       .reg = 0x17058,
+       .shift = 0,
+       .width = 2,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gcc_disp_gpll0_clk_src",
+               .parent_names =
+                       (const char *[]){ "gpll0" },
+               .num_parents = 1,
+               .ops = &clk_regmap_div_ops,
+       },
+};
+
+static struct clk_branch gcc_disp_gpll0_div_clk_src = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(20),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_gpll0_div_clk_src",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_disp_gpll0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_hf_axi_clk = {
+       .halt_reg = 0x17020,
+       .halt_check = BRANCH_VOTED,
+       .hwcg_reg = 0x17020,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_hf_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_sleep_clk = {
+       .halt_reg = 0x17074,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17074,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17074,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_throttle_core_clk = {
+       .halt_reg = 0x17064,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17064,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(5),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_throttle_core_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp1_clk = {
+       .halt_reg = 0x4d000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp1_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_gp1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp2_clk = {
+       .halt_reg = 0x4e000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp2_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_gp2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp3_clk = {
+       .halt_reg = 0x4f000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4f000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp3_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_gp3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_cfg_ahb_clk = {
+       .halt_reg = 0x36004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x36004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x36004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_cfg_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_gpll0_clk_src = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_gpll0_clk_src",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gpll0.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_gpll0_div_clk_src = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(16),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_gpll0_div_clk_src",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gpll0_out_even.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_memnoc_gfx_clk = {
+       .halt_reg = 0x3600c,
+       .halt_check = BRANCH_VOTED,
+       .hwcg_reg = 0x3600c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3600c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_memnoc_gfx_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = {
+       .halt_reg = 0x36018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x36018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_snoc_dvm_gfx_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_throttle_core_clk = {
+       .halt_reg = 0x36048,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x36048,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(31),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_throttle_core_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+       .halt_reg = 0x2000c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2000c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm2_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_pdm2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm_ahb_clk = {
+       .halt_reg = 0x20004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x20004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x20004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm_xo4_clk = {
+       .halt_reg = 0x20008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x20008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm_xo4_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+       .halt_reg = 0x21004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x21004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_prng_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = {
+       .halt_reg = 0x17014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_camera_nrt_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_camera_rt_ahb_clk = {
+       .halt_reg = 0x17060,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17060,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_camera_rt_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_disp_ahb_clk = {
+       .halt_reg = 0x17018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17018,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_disp_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_gpu_cfg_ahb_clk = {
+       .halt_reg = 0x36040,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x36040,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_gpu_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = {
+       .halt_reg = 0x17010,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(25),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_video_vcodec_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_core_2x_clk = {
+       .halt_reg = 0x1f014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_core_2x_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_core_clk = {
+       .halt_reg = 0x1f00c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_core_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s0_clk = {
+       .halt_reg = 0x1f144,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s0_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_qupv3_wrap0_s0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s1_clk = {
+       .halt_reg = 0x1f274,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s1_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_qupv3_wrap0_s1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s2_clk = {
+       .halt_reg = 0x1f3a4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(12),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s2_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_qupv3_wrap0_s2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s3_clk = {
+       .halt_reg = 0x1f4d4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s3_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_qupv3_wrap0_s3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s4_clk = {
+       .halt_reg = 0x1f604,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(14),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s4_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_qupv3_wrap0_s4_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s5_clk = {
+       .halt_reg = 0x1f734,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s5_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_qupv3_wrap0_s5_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = {
+       .halt_reg = 0x53014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(20),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_core_2x_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_core_clk = {
+       .halt_reg = 0x5300c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(19),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_core_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s0_clk = {
+       .halt_reg = 0x53018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(21),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s0_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_qupv3_wrap1_s0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s1_clk = {
+       .halt_reg = 0x53148,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(22),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s1_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_qupv3_wrap1_s1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s2_clk = {
+       .halt_reg = 0x53278,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(23),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s2_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_qupv3_wrap1_s2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s3_clk = {
+       .halt_reg = 0x533a8,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(24),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s3_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_qupv3_wrap1_s3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s4_clk = {
+       .halt_reg = 0x534d8,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(25),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s4_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_qupv3_wrap1_s4_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s5_clk = {
+       .halt_reg = 0x53608,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(26),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s5_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_qupv3_wrap1_s5_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = {
+       .halt_reg = 0x1f004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x1f004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(6),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_0_m_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = {
+       .halt_reg = 0x1f008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x1f008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_0_s_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_1_m_ahb_clk = {
+       .halt_reg = 0x53004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x53004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(17),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_1_m_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = {
+       .halt_reg = 0x53008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x53008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(18),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_1_s_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+       .halt_reg = 0x38008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x38008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+       .halt_reg = 0x38004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x38004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_sdcc1_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ice_core_clk = {
+       .halt_reg = 0x3800c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x3800c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3800c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ice_core_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_sdcc1_ice_core_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc2_ahb_clk = {
+       .halt_reg = 0x1e008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1e008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc2_apps_clk = {
+       .halt_reg = 0x1e004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1e004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_sdcc2_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = {
+       .halt_reg = 0x2b06c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x2b06c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sys_noc_cpuss_ahb_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_cpuss_ahb_postdiv_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sys_noc_ufs_phy_axi_clk = {
+       .halt_reg = 0x45098,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x45098,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sys_noc_ufs_phy_axi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_ufs_phy_axi_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sys_noc_usb3_prim_axi_clk = {
+       .halt_reg = 0x1a080,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x1a080,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1a080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sys_noc_usb3_prim_axi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_usb30_prim_master_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_ahb_clk = {
+       .halt_reg = 0x45014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x45014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x45014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_axi_clk = {
+       .halt_reg = 0x45010,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x45010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x45010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_axi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_ufs_phy_axi_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_ice_core_clk = {
+       .halt_reg = 0x45044,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x45044,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x45044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_ice_core_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_ufs_phy_ice_core_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_phy_aux_clk = {
+       .halt_reg = 0x45078,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x45078,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x45078,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_phy_aux_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_ufs_phy_phy_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = {
+       .halt_reg = 0x4501c,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x4501c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_rx_symbol_0_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = {
+       .halt_reg = 0x45018,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x45018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_tx_symbol_0_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_unipro_core_clk = {
+       .halt_reg = 0x45040,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x45040,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x45040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_unipro_core_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_ufs_phy_unipro_core_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_prim_master_clk = {
+       .halt_reg = 0x1a010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_prim_master_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_usb30_prim_master_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_prim_mock_utmi_clk = {
+       .halt_reg = 0x1a018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_prim_mock_utmi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_prim_sleep_clk = {
+       .halt_reg = 0x1a014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_prim_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_mem_clkref_clk = {
+       .halt_reg = 0x8c000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8c000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_mem_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_rx5_pcie_clkref_en_clk = {
+       .halt_reg = 0x8c00c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8c00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_rx5_pcie_clkref_en_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_clkref_clk = {
+       .halt_reg = 0x8c010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8c010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = {
+       .halt_reg = 0x1a054,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_phy_com_aux_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_usb3_prim_phy_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_phy_pipe_clk = {
+       .halt_reg = 0x1a058,
+       .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0x1a058,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1a058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_phy_pipe_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_vcodec0_axi_clk = {
+       .halt_reg = 0x6e008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6e008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_vcodec0_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_venus_ahb_clk = {
+       .halt_reg = 0x6e010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6e010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_venus_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_venus_ctl_axi_clk = {
+       .halt_reg = 0x6e004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6e004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_venus_ctl_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_ahb_clk = {
+       .halt_reg = 0x17004,
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0x17004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_axi0_clk = {
+       .halt_reg = 0x1701c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x1701c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1701c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_axi0_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_throttle_core_clk = {
+       .halt_reg = 0x17068,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17068,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(28),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_throttle_core_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_vcodec0_sys_clk = {
+       .halt_reg = 0x580a4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x580a4,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x580a4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_vcodec0_sys_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_video_venus_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_venus_ctl_clk = {
+       .halt_reg = 0x5808c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5808c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_venus_ctl_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_video_venus_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_xo_clk = {
+       .halt_reg = 0x17024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x17024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_xo_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc usb30_prim_gdsc = {
+       .gdscr = 0x1a004,
+       .pd = {
+               .name = "usb30_prim_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc ufs_phy_gdsc = {
+       .gdscr = 0x45004,
+       .pd = {
+               .name = "ufs_phy_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_top_gdsc = {
+       .gdscr = 0x58004,
+       .pd = {
+               .name = "camss_top_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus_gdsc = {
+       .gdscr = 0x5807c,
+       .pd = {
+               .name = "venus_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc vcodec0_gdsc = {
+       .gdscr = 0x58098,
+       .pd = {
+               .name = "vcodec0_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = HW_CTRL,
+};
+
+static struct gdsc hlos1_vote_mm_snoc_mmu_tbu_rt_gdsc = {
+       .gdscr = 0x7d074,
+       .pd = {
+               .name = "hlos1_vote_mm_snoc_mmu_tbu_rt_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct gdsc hlos1_vote_mm_snoc_mmu_tbu_nrt_gdsc = {
+       .gdscr = 0x7d078,
+       .pd = {
+               .name = "hlos1_vote_mm_snoc_mmu_tbu_nrt_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct gdsc hlos1_vote_turing_mmu_tbu1_gdsc = {
+       .gdscr = 0x7d060,
+       .pd = {
+               .name = "hlos1_vote_turing_mmu_tbu1_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct gdsc hlos1_vote_turing_mmu_tbu0_gdsc = {
+       .gdscr = 0x7d07c,
+       .pd = {
+               .name = "hlos1_vote_turing_mmu_tbu0_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct clk_regmap *gcc_sm6375_clocks[] = {
+       [GCC_AHB2PHY_CSI_CLK] = &gcc_ahb2phy_csi_clk.clkr,
+       [GCC_AHB2PHY_USB_CLK] = &gcc_ahb2phy_usb_clk.clkr,
+       [GCC_BIMC_GPU_AXI_CLK] = &gcc_bimc_gpu_axi_clk.clkr,
+       [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+       [GCC_CAM_THROTTLE_NRT_CLK] = &gcc_cam_throttle_nrt_clk.clkr,
+       [GCC_CAM_THROTTLE_RT_CLK] = &gcc_cam_throttle_rt_clk.clkr,
+       [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr,
+       [GCC_CAMSS_AXI_CLK] = &gcc_camss_axi_clk.clkr,
+       [GCC_CAMSS_AXI_CLK_SRC] = &gcc_camss_axi_clk_src.clkr,
+       [GCC_CAMSS_CCI_0_CLK] = &gcc_camss_cci_0_clk.clkr,
+       [GCC_CAMSS_CCI_0_CLK_SRC] = &gcc_camss_cci_0_clk_src.clkr,
+       [GCC_CAMSS_CCI_1_CLK] = &gcc_camss_cci_1_clk.clkr,
+       [GCC_CAMSS_CCI_1_CLK_SRC] = &gcc_camss_cci_1_clk_src.clkr,
+       [GCC_CAMSS_CPHY_0_CLK] = &gcc_camss_cphy_0_clk.clkr,
+       [GCC_CAMSS_CPHY_1_CLK] = &gcc_camss_cphy_1_clk.clkr,
+       [GCC_CAMSS_CPHY_2_CLK] = &gcc_camss_cphy_2_clk.clkr,
+       [GCC_CAMSS_CPHY_3_CLK] = &gcc_camss_cphy_3_clk.clkr,
+       [GCC_CAMSS_CSI0PHYTIMER_CLK] = &gcc_camss_csi0phytimer_clk.clkr,
+       [GCC_CAMSS_CSI0PHYTIMER_CLK_SRC] = &gcc_camss_csi0phytimer_clk_src.clkr,
+       [GCC_CAMSS_CSI1PHYTIMER_CLK] = &gcc_camss_csi1phytimer_clk.clkr,
+       [GCC_CAMSS_CSI1PHYTIMER_CLK_SRC] = &gcc_camss_csi1phytimer_clk_src.clkr,
+       [GCC_CAMSS_CSI2PHYTIMER_CLK] = &gcc_camss_csi2phytimer_clk.clkr,
+       [GCC_CAMSS_CSI2PHYTIMER_CLK_SRC] = &gcc_camss_csi2phytimer_clk_src.clkr,
+       [GCC_CAMSS_CSI3PHYTIMER_CLK] = &gcc_camss_csi3phytimer_clk.clkr,
+       [GCC_CAMSS_CSI3PHYTIMER_CLK_SRC] = &gcc_camss_csi3phytimer_clk_src.clkr,
+       [GCC_CAMSS_MCLK0_CLK] = &gcc_camss_mclk0_clk.clkr,
+       [GCC_CAMSS_MCLK0_CLK_SRC] = &gcc_camss_mclk0_clk_src.clkr,
+       [GCC_CAMSS_MCLK1_CLK] = &gcc_camss_mclk1_clk.clkr,
+       [GCC_CAMSS_MCLK1_CLK_SRC] = &gcc_camss_mclk1_clk_src.clkr,
+       [GCC_CAMSS_MCLK2_CLK] = &gcc_camss_mclk2_clk.clkr,
+       [GCC_CAMSS_MCLK2_CLK_SRC] = &gcc_camss_mclk2_clk_src.clkr,
+       [GCC_CAMSS_MCLK3_CLK] = &gcc_camss_mclk3_clk.clkr,
+       [GCC_CAMSS_MCLK3_CLK_SRC] = &gcc_camss_mclk3_clk_src.clkr,
+       [GCC_CAMSS_MCLK4_CLK] = &gcc_camss_mclk4_clk.clkr,
+       [GCC_CAMSS_MCLK4_CLK_SRC] = &gcc_camss_mclk4_clk_src.clkr,
+       [GCC_CAMSS_NRT_AXI_CLK] = &gcc_camss_nrt_axi_clk.clkr,
+       [GCC_CAMSS_OPE_AHB_CLK] = &gcc_camss_ope_ahb_clk.clkr,
+       [GCC_CAMSS_OPE_AHB_CLK_SRC] = &gcc_camss_ope_ahb_clk_src.clkr,
+       [GCC_CAMSS_OPE_CLK] = &gcc_camss_ope_clk.clkr,
+       [GCC_CAMSS_OPE_CLK_SRC] = &gcc_camss_ope_clk_src.clkr,
+       [GCC_CAMSS_RT_AXI_CLK] = &gcc_camss_rt_axi_clk.clkr,
+       [GCC_CAMSS_TFE_0_CLK] = &gcc_camss_tfe_0_clk.clkr,
+       [GCC_CAMSS_TFE_0_CLK_SRC] = &gcc_camss_tfe_0_clk_src.clkr,
+       [GCC_CAMSS_TFE_0_CPHY_RX_CLK] = &gcc_camss_tfe_0_cphy_rx_clk.clkr,
+       [GCC_CAMSS_TFE_0_CSID_CLK] = &gcc_camss_tfe_0_csid_clk.clkr,
+       [GCC_CAMSS_TFE_0_CSID_CLK_SRC] = &gcc_camss_tfe_0_csid_clk_src.clkr,
+       [GCC_CAMSS_TFE_1_CLK] = &gcc_camss_tfe_1_clk.clkr,
+       [GCC_CAMSS_TFE_1_CLK_SRC] = &gcc_camss_tfe_1_clk_src.clkr,
+       [GCC_CAMSS_TFE_1_CPHY_RX_CLK] = &gcc_camss_tfe_1_cphy_rx_clk.clkr,
+       [GCC_CAMSS_TFE_1_CSID_CLK] = &gcc_camss_tfe_1_csid_clk.clkr,
+       [GCC_CAMSS_TFE_1_CSID_CLK_SRC] = &gcc_camss_tfe_1_csid_clk_src.clkr,
+       [GCC_CAMSS_TFE_2_CLK] = &gcc_camss_tfe_2_clk.clkr,
+       [GCC_CAMSS_TFE_2_CLK_SRC] = &gcc_camss_tfe_2_clk_src.clkr,
+       [GCC_CAMSS_TFE_2_CPHY_RX_CLK] = &gcc_camss_tfe_2_cphy_rx_clk.clkr,
+       [GCC_CAMSS_TFE_2_CSID_CLK] = &gcc_camss_tfe_2_csid_clk.clkr,
+       [GCC_CAMSS_TFE_2_CSID_CLK_SRC] = &gcc_camss_tfe_2_csid_clk_src.clkr,
+       [GCC_CAMSS_TFE_CPHY_RX_CLK_SRC] = &gcc_camss_tfe_cphy_rx_clk_src.clkr,
+       [GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr,
+       [GCC_CAMSS_TOP_AHB_CLK_SRC] = &gcc_camss_top_ahb_clk_src.clkr,
+       [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr,
+       [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr,
+       [GCC_CPUSS_AHB_POSTDIV_CLK_SRC] = &gcc_cpuss_ahb_postdiv_clk_src.clkr,
+       [GCC_DISP_AHB_CLK] = &gcc_disp_ahb_clk.clkr,
+       [GCC_DISP_GPLL0_CLK_SRC] = &gcc_disp_gpll0_clk_src.clkr,
+       [GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr,
+       [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr,
+       [GCC_DISP_SLEEP_CLK] = &gcc_disp_sleep_clk.clkr,
+       [GCC_DISP_THROTTLE_CORE_CLK] = &gcc_disp_throttle_core_clk.clkr,
+       [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+       [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr,
+       [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+       [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr,
+       [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+       [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr,
+       [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr,
+       [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr,
+       [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr,
+       [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr,
+       [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr,
+       [GCC_GPU_THROTTLE_CORE_CLK] = &gcc_gpu_throttle_core_clk.clkr,
+       [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+       [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr,
+       [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+       [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr,
+       [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+       [GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr,
+       [GCC_QMIP_CAMERA_RT_AHB_CLK] = &gcc_qmip_camera_rt_ahb_clk.clkr,
+       [GCC_QMIP_DISP_AHB_CLK] = &gcc_qmip_disp_ahb_clk.clkr,
+       [GCC_QMIP_GPU_CFG_AHB_CLK] = &gcc_qmip_gpu_cfg_ahb_clk.clkr,
+       [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP0_CORE_2X_CLK] = &gcc_qupv3_wrap0_core_2x_clk.clkr,
+       [GCC_QUPV3_WRAP0_CORE_CLK] = &gcc_qupv3_wrap0_core_clk.clkr,
+       [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr,
+       [GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr,
+       [GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr,
+       [GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr,
+       [GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr,
+       [GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr,
+       [GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_CORE_2X_CLK] = &gcc_qupv3_wrap1_core_2x_clk.clkr,
+       [GCC_QUPV3_WRAP1_CORE_CLK] = &gcc_qupv3_wrap1_core_clk.clkr,
+       [GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr,
+       [GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr,
+       [GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr,
+       [GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr,
+       [GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr,
+       [GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr,
+       [GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr,
+       [GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_1_M_AHB_CLK] = &gcc_qupv3_wrap_1_m_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr,
+       [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+       [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+       [GCC_SDCC1_APPS_CLK_SRC] = &gcc_sdcc1_apps_clk_src.clkr,
+       [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr,
+       [GCC_SDCC1_ICE_CORE_CLK_SRC] = &gcc_sdcc1_ice_core_clk_src.clkr,
+       [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
+       [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
+       [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr,
+       [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr,
+       [GCC_SYS_NOC_UFS_PHY_AXI_CLK] = &gcc_sys_noc_ufs_phy_axi_clk.clkr,
+       [GCC_SYS_NOC_USB3_PRIM_AXI_CLK] = &gcc_sys_noc_usb3_prim_axi_clk.clkr,
+       [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr,
+       [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr,
+       [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr,
+       [GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr,
+       [GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr,
+       [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr,
+       [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr,
+       [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr,
+       [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr,
+       [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr,
+       [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = &gcc_ufs_phy_unipro_core_clk_src.clkr,
+       [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr,
+       [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr,
+       [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr,
+       [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = &gcc_usb30_prim_mock_utmi_clk_src.clkr,
+       [GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr,
+       [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr,
+       [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr,
+       [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr,
+       [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr,
+       [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr,
+       [GCC_VCODEC0_AXI_CLK] = &gcc_vcodec0_axi_clk.clkr,
+       [GCC_VENUS_AHB_CLK] = &gcc_venus_ahb_clk.clkr,
+       [GCC_VENUS_CTL_AXI_CLK] = &gcc_venus_ctl_axi_clk.clkr,
+       [GCC_VIDEO_AHB_CLK] = &gcc_video_ahb_clk.clkr,
+       [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr,
+       [GCC_VIDEO_THROTTLE_CORE_CLK] = &gcc_video_throttle_core_clk.clkr,
+       [GCC_VIDEO_VCODEC0_SYS_CLK] = &gcc_video_vcodec0_sys_clk.clkr,
+       [GCC_VIDEO_VENUS_CLK_SRC] = &gcc_video_venus_clk_src.clkr,
+       [GCC_VIDEO_VENUS_CTL_CLK] = &gcc_video_venus_ctl_clk.clkr,
+       [GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr,
+       [GCC_UFS_MEM_CLKREF_CLK] = &gcc_ufs_mem_clkref_clk.clkr,
+       [GCC_RX5_PCIE_CLKREF_EN_CLK] = &gcc_rx5_pcie_clkref_en_clk.clkr,
+       [GPLL0] = &gpll0.clkr,
+       [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr,
+       [GPLL0_OUT_ODD] = &gpll0_out_odd.clkr,
+       [GPLL1] = &gpll1.clkr,
+       [GPLL10] = &gpll10.clkr,
+       [GPLL11] = &gpll11.clkr,
+       [GPLL3] = &gpll3.clkr,
+       [GPLL3_OUT_EVEN] = &gpll3_out_even.clkr,
+       [GPLL4] = &gpll4.clkr,
+       [GPLL5] = &gpll5.clkr,
+       [GPLL6] = &gpll6.clkr,
+       [GPLL6_OUT_EVEN] = &gpll6_out_even.clkr,
+       [GPLL7] = &gpll7.clkr,
+       [GPLL8] = &gpll8.clkr,
+       [GPLL8_OUT_EVEN] = &gpll8_out_even.clkr,
+       [GPLL9] = &gpll9.clkr,
+       [GPLL9_OUT_MAIN] = &gpll9_out_main.clkr,
+};
+
+static const struct qcom_reset_map gcc_sm6375_resets[] = {
+       [GCC_MMSS_BCR] = { 0x17000 },
+       [GCC_USB30_PRIM_BCR] = { 0x1a000 },
+       [GCC_USB3_PHY_PRIM_SP0_BCR] = { 0x1b000 },
+       [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x1b020 },
+       [GCC_QUSB2PHY_PRIM_BCR] = { 0x1c000 },
+       [GCC_QUSB2PHY_SEC_BCR] = { 0x1c004 },
+       [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x1d000 },
+       [GCC_SDCC2_BCR] = { 0x1e000 },
+       [GCC_QUPV3_WRAPPER_0_BCR] = { 0x1f000 },
+       [GCC_PDM_BCR] = { 0x20000 },
+       [GCC_GPU_BCR] = { 0x36000 },
+       [GCC_SDCC1_BCR] = { 0x38000 },
+       [GCC_UFS_PHY_BCR] = { 0x45000 },
+       [GCC_CAMSS_TFE_BCR] = { 0x52000 },
+       [GCC_QUPV3_WRAPPER_1_BCR] = { 0x53000 },
+       [GCC_CAMSS_OPE_BCR] = { 0x55000 },
+       [GCC_CAMSS_TOP_BCR] = { 0x58000 },
+       [GCC_VENUS_BCR] = { 0x58078 },
+       [GCC_VCODEC0_BCR] = { 0x58094 },
+       [GCC_VIDEO_INTERFACE_BCR] = { 0x6e000 },
+};
+
+
+static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src),
+};
+
+static struct gdsc *gcc_sm6375_gdscs[] = {
+       [USB30_PRIM_GDSC] = &usb30_prim_gdsc,
+       [UFS_PHY_GDSC] = &ufs_phy_gdsc,
+       [CAMSS_TOP_GDSC] = &camss_top_gdsc,
+       [VENUS_GDSC] = &venus_gdsc,
+       [VCODEC0_GDSC] = &vcodec0_gdsc,
+       [HLOS1_VOTE_MM_SNOC_MMU_TBU_NRT_GDSC] = &hlos1_vote_mm_snoc_mmu_tbu_nrt_gdsc,
+       [HLOS1_VOTE_MM_SNOC_MMU_TBU_RT_GDSC] = &hlos1_vote_mm_snoc_mmu_tbu_rt_gdsc,
+       [HLOS1_VOTE_TURING_MMU_TBU0_GDSC] = &hlos1_vote_turing_mmu_tbu0_gdsc,
+       [HLOS1_VOTE_TURING_MMU_TBU1_GDSC] = &hlos1_vote_turing_mmu_tbu1_gdsc,
+};
+
+static const struct regmap_config gcc_sm6375_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = 0xc7000,
+       .fast_io = true,
+};
+
+static const struct qcom_cc_desc gcc_sm6375_desc = {
+       .config = &gcc_sm6375_regmap_config,
+       .clks = gcc_sm6375_clocks,
+       .num_clks = ARRAY_SIZE(gcc_sm6375_clocks),
+       .resets = gcc_sm6375_resets,
+       .num_resets = ARRAY_SIZE(gcc_sm6375_resets),
+       .gdscs = gcc_sm6375_gdscs,
+       .num_gdscs = ARRAY_SIZE(gcc_sm6375_gdscs),
+};
+
+static const struct of_device_id gcc_sm6375_match_table[] = {
+       { .compatible = "qcom,sm6375-gcc" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gcc_sm6375_match_table);
+
+static int gcc_sm6375_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+       int ret;
+
+       regmap = qcom_cc_map(pdev, &gcc_sm6375_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, ARRAY_SIZE(gcc_dfs_clocks));
+       if (ret)
+               return ret;
+
+       /*
+        * Keep the following clocks always on:
+        * GCC_CAMERA_XO_CLK, GCC_CPUSS_GNOC_CLK, GCC_DISP_XO_CLK
+        */
+       regmap_update_bits(regmap, 0x17028, BIT(0), BIT(0));
+       regmap_update_bits(regmap, 0x2b004, BIT(0), BIT(0));
+       regmap_update_bits(regmap, 0x1702c, BIT(0), BIT(0));
+
+       clk_lucid_pll_configure(&gpll10, regmap, &gpll10_config);
+       clk_lucid_pll_configure(&gpll11, regmap, &gpll11_config);
+       clk_lucid_pll_configure(&gpll8, regmap, &gpll8_config);
+       clk_zonda_pll_configure(&gpll9, regmap, &gpll9_config);
+
+       return qcom_cc_really_probe(pdev, &gcc_sm6375_desc, regmap);
+}
+
+static struct platform_driver gcc_sm6375_driver = {
+       .probe = gcc_sm6375_probe,
+       .driver = {
+               .name = "gcc-sm6375",
+               .of_match_table = gcc_sm6375_match_table,
+       },
+};
+
+static int __init gcc_sm6375_init(void)
+{
+       return platform_driver_register(&gcc_sm6375_driver);
+}
+subsys_initcall(gcc_sm6375_init);
+
+static void __exit gcc_sm6375_exit(void)
+{
+       platform_driver_unregister(&gcc_sm6375_driver);
+}
+module_exit(gcc_sm6375_exit);
+
+MODULE_DESCRIPTION("QTI GCC SM6375 Driver");
+MODULE_LICENSE("GPL");
index d324400..7cf5e13 100644 (file)
@@ -368,6 +368,16 @@ static int _gdsc_disable(struct gdsc *sc)
        if (sc->pwrsts & PWRSTS_OFF)
                gdsc_clear_mem_on(sc);
 
+       /*
+        * If the GDSC supports only a Retention state, apart from ON,
+        * leave it in ON state.
+        * There is no SW control to transition the GDSC into
+        * Retention state. This happens in HW when the parent
+        * domain goes down to a Low power state
+        */
+       if (sc->pwrsts == PWRSTS_RET_ON)
+               return 0;
+
        ret = gdsc_toggle_logic(sc, GDSC_OFF);
        if (ret)
                return ret;
@@ -439,11 +449,8 @@ static int gdsc_init(struct gdsc *sc)
 
                /* ...and the power-domain */
                ret = gdsc_pm_runtime_get(sc);
-               if (ret) {
-                       if (sc->rsupply)
-                               regulator_disable(sc->rsupply);
-                       return ret;
-               }
+               if (ret)
+                       goto err_disable_supply;
 
                /*
                 * Votable GDSCs can be ON due to Vote from other masters.
@@ -452,14 +459,14 @@ static int gdsc_init(struct gdsc *sc)
                if (sc->flags & VOTABLE) {
                        ret = gdsc_update_collapse_bit(sc, false);
                        if (ret)
-                               return ret;
+                               goto err_put_rpm;
                }
 
                /* Turn on HW trigger mode if supported */
                if (sc->flags & HW_CTRL) {
                        ret = gdsc_hwctrl(sc, true);
                        if (ret < 0)
-                               return ret;
+                               goto err_put_rpm;
                }
 
                /*
@@ -486,9 +493,21 @@ static int gdsc_init(struct gdsc *sc)
                sc->pd.power_off = gdsc_disable;
        if (!sc->pd.power_on)
                sc->pd.power_on = gdsc_enable;
-       pm_genpd_init(&sc->pd, NULL, !on);
+
+       ret = pm_genpd_init(&sc->pd, NULL, !on);
+       if (ret)
+               goto err_put_rpm;
 
        return 0;
+
+err_put_rpm:
+       if (on)
+               gdsc_pm_runtime_put(sc);
+err_disable_supply:
+       if (on && sc->rsupply)
+               regulator_disable(sc->rsupply);
+
+       return ret;
 }
 
 int gdsc_register(struct gdsc_desc *desc,
index 5de48c9..981a12c 100644 (file)
@@ -49,6 +49,11 @@ struct gdsc {
        const u8                        pwrsts;
 /* Powerdomain allowable state bitfields */
 #define PWRSTS_OFF             BIT(0)
+/*
+ * There is no SW control to transition a GDSC into
+ * PWRSTS_RET. This happens in HW when the parent
+ * domain goes down to a low power state
+ */
 #define PWRSTS_RET             BIT(1)
 #define PWRSTS_ON              BIT(2)
 #define PWRSTS_OFF_ON          (PWRSTS_OFF | PWRSTS_ON)
diff --git a/drivers/clk/qcom/gpucc-sc8280xp.c b/drivers/clk/qcom/gpucc-sc8280xp.c
new file mode 100644 (file)
index 0000000..ea1e950
--- /dev/null
@@ -0,0 +1,461 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,gpucc-sc8280xp.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap-divider.h"
+#include "common.h"
+#include "reset.h"
+#include "gdsc.h"
+
+/* Need to match the order of clocks in DT binding */
+enum {
+       DT_BI_TCXO,
+       DT_GCC_GPU_GPLL0_CLK_SRC,
+       DT_GCC_GPU_GPLL0_DIV_CLK_SRC,
+};
+
+enum {
+       P_BI_TCXO,
+       P_GCC_GPU_GPLL0_CLK_SRC,
+       P_GCC_GPU_GPLL0_DIV_CLK_SRC,
+       P_GPU_CC_PLL0_OUT_MAIN,
+       P_GPU_CC_PLL1_OUT_MAIN,
+};
+
+static const struct clk_parent_data parent_data_tcxo = { .index = DT_BI_TCXO };
+
+static const struct pll_vco lucid_5lpe_vco[] = {
+       { 249600000, 1800000000, 0 },
+};
+
+static struct alpha_pll_config gpu_cc_pll0_config = {
+       .l = 0x1c,
+       .alpha = 0xa555,
+       .config_ctl_val = 0x20485699,
+       .config_ctl_hi_val = 0x00002261,
+       .config_ctl_hi1_val = 0x2a9a699c,
+       .test_ctl_val = 0x00000000,
+       .test_ctl_hi_val = 0x00000000,
+       .test_ctl_hi1_val = 0x01800000,
+       .user_ctl_val = 0x00000000,
+       .user_ctl_hi_val = 0x00000805,
+       .user_ctl_hi1_val = 0x00000000,
+};
+
+static struct clk_alpha_pll gpu_cc_pll0 = {
+       .offset = 0x0,
+       .vco_table = lucid_5lpe_vco,
+       .num_vco = ARRAY_SIZE(lucid_5lpe_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr = {
+               .hw.init = &(const struct clk_init_data){
+                       .name = "gpu_cc_pll0",
+                       .parent_data = &parent_data_tcxo,
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_lucid_5lpe_ops,
+               },
+       },
+};
+
+static struct alpha_pll_config gpu_cc_pll1_config = {
+       .l = 0x1A,
+       .alpha = 0xaaa,
+       .config_ctl_val = 0x20485699,
+       .config_ctl_hi_val = 0x00002261,
+       .config_ctl_hi1_val = 0x2a9a699c,
+       .test_ctl_val = 0x00000000,
+       .test_ctl_hi_val = 0x00000000,
+       .test_ctl_hi1_val = 0x01800000,
+       .user_ctl_val = 0x00000000,
+       .user_ctl_hi_val = 0x00000805,
+       .user_ctl_hi1_val = 0x00000000,
+};
+
+static struct clk_alpha_pll gpu_cc_pll1 = {
+       .offset = 0x100,
+       .vco_table = lucid_5lpe_vco,
+       .num_vco = ARRAY_SIZE(lucid_5lpe_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr = {
+               .hw.init = &(const struct clk_init_data){
+                       .name = "gpu_cc_pll1",
+                       .parent_data = &parent_data_tcxo,
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_lucid_5lpe_ops,
+               },
+       },
+};
+
+static const struct parent_map gpu_cc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPU_CC_PLL0_OUT_MAIN, 1 },
+       { P_GPU_CC_PLL1_OUT_MAIN, 3 },
+       { P_GCC_GPU_GPLL0_CLK_SRC, 5 },
+       { P_GCC_GPU_GPLL0_DIV_CLK_SRC, 6 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_0[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpu_cc_pll0.clkr.hw },
+       { .hw = &gpu_cc_pll1.clkr.hw },
+       { .index = DT_GCC_GPU_GPLL0_CLK_SRC },
+       { .index = DT_GCC_GPU_GPLL0_DIV_CLK_SRC },
+};
+
+static const struct parent_map gpu_cc_parent_map_1[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPU_CC_PLL1_OUT_MAIN, 3 },
+       { P_GCC_GPU_GPLL0_CLK_SRC, 5 },
+       { P_GCC_GPU_GPLL0_DIV_CLK_SRC, 6 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_1[] = {
+       { .index = DT_BI_TCXO },
+       { .hw = &gpu_cc_pll1.clkr.hw },
+       { .index = DT_GCC_GPU_GPLL0_CLK_SRC },
+       { .index = DT_GCC_GPU_GPLL0_DIV_CLK_SRC },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(200000000, P_GCC_GPU_GPLL0_DIV_CLK_SRC, 1.5, 0, 0),
+       F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gpu_cc_gmu_clk_src = {
+       .cmd_rcgr = 0x1120,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gpu_cc_parent_map_0,
+       .freq_tbl = ftbl_gpu_cc_gmu_clk_src,
+       .clkr.hw.init = &(const struct clk_init_data){
+               .name = "gpu_cc_gmu_clk_src",
+               .parent_data = gpu_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = {
+       F(200000000, P_GCC_GPU_GPLL0_CLK_SRC, 3, 0, 0),
+       F(300000000, P_GCC_GPU_GPLL0_CLK_SRC, 2, 0, 0),
+       F(400000000, P_GCC_GPU_GPLL0_CLK_SRC, 1.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gpu_cc_hub_clk_src = {
+       .cmd_rcgr = 0x117c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gpu_cc_parent_map_1,
+       .freq_tbl = ftbl_gpu_cc_hub_clk_src,
+       .clkr.hw.init = &(const struct clk_init_data){
+               .name = "gpu_cc_hub_clk_src",
+               .parent_data = gpu_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_regmap_div gpu_cc_hub_ahb_div_clk_src = {
+       .reg = 0x11c0,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(const struct clk_init_data) {
+               .name = "gpu_cc_hub_ahb_div_clk_src",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpu_cc_hub_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_regmap_div gpu_cc_hub_cx_int_div_clk_src = {
+       .reg = 0x11bc,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(const struct clk_init_data) {
+               .name = "gpu_cc_hub_cx_int_div_clk_src",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpu_cc_hub_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_branch gpu_cc_ahb_clk = {
+       .halt_reg = 0x1078,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x1078,
+               .enable_mask = BIT(0),
+               .hw.init = &(const struct clk_init_data){
+                       .name = "gpu_cc_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpu_cc_hub_ahb_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_crc_ahb_clk = {
+       .halt_reg = 0x107c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x107c,
+               .enable_mask = BIT(0),
+               .hw.init = &(const struct clk_init_data){
+                       .name = "gpu_cc_crc_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpu_cc_hub_ahb_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_cx_gmu_clk = {
+       .halt_reg = 0x1098,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1098,
+               .enable_mask = BIT(0),
+               .hw.init = &(const struct clk_init_data){
+                       .name = "gpu_cc_cx_gmu_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpu_cc_gmu_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_aon_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
+       .halt_reg = 0x108c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x108c,
+               .enable_mask = BIT(0),
+               .hw.init = &(const struct clk_init_data){
+                       .name = "gpu_cc_cx_snoc_dvm_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_cxo_aon_clk = {
+       .halt_reg = 0x1004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x1004,
+               .enable_mask = BIT(0),
+               .hw.init = &(const struct clk_init_data){
+                       .name = "gpu_cc_cxo_aon_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_gx_gmu_clk = {
+       .halt_reg = 0x1064,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1064,
+               .enable_mask = BIT(0),
+               .hw.init = &(const struct clk_init_data){
+                       .name = "gpu_cc_gx_gmu_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpu_cc_gmu_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = {
+       .halt_reg = 0x5000,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5000,
+               .enable_mask = BIT(0),
+               .hw.init = &(const struct clk_init_data){
+                       .name = "gpu_cc_hlos1_vote_gpu_smmu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_hub_aon_clk = {
+       .halt_reg = 0x1178,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1178,
+               .enable_mask = BIT(0),
+               .hw.init = &(const struct clk_init_data){
+                       .name = "gpu_cc_hub_aon_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpu_cc_hub_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_aon_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_hub_cx_int_clk = {
+       .halt_reg = 0x1204,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1204,
+               .enable_mask = BIT(0),
+               .hw.init = &(const struct clk_init_data){
+                       .name = "gpu_cc_hub_cx_int_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpu_cc_hub_cx_int_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_aon_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_sleep_clk = {
+       .halt_reg = 0x1090,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x1090,
+               .enable_mask = BIT(0),
+               .hw.init = &(const struct clk_init_data){
+                       .name = "gpu_cc_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_regmap *gpu_cc_sc8280xp_clocks[] = {
+       [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
+       [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
+       [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
+       [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
+       [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
+       [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
+       [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
+       [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr,
+       [GPU_CC_HUB_AHB_DIV_CLK_SRC] = &gpu_cc_hub_ahb_div_clk_src.clkr,
+       [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr,
+       [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr,
+       [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr,
+       [GPU_CC_HUB_CX_INT_DIV_CLK_SRC] = &gpu_cc_hub_cx_int_div_clk_src.clkr,
+       [GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
+       [GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
+       [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr,
+};
+
+static struct gdsc cx_gdsc = {
+       .gdscr = 0x106c,
+       .gds_hw_ctrl = 0x1540,
+       .pd = {
+               .name = "cx_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc gx_gdsc = {
+       .gdscr = 0x100c,
+       .clamp_io_ctrl = 0x1508,
+       .pd = {
+               .name = "gx_gdsc",
+               .power_on = gdsc_gx_do_nothing_enable,
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = CLAMP_IO | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc *gpu_cc_sc8280xp_gdscs[] = {
+       [GPU_CC_CX_GDSC] = &cx_gdsc,
+       [GPU_CC_GX_GDSC] = &gx_gdsc,
+};
+
+static const struct regmap_config gpu_cc_sc8280xp_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = 0x8030,
+       .fast_io = true,
+};
+
+static struct qcom_cc_desc gpu_cc_sc8280xp_desc = {
+       .config = &gpu_cc_sc8280xp_regmap_config,
+       .clks = gpu_cc_sc8280xp_clocks,
+       .num_clks = ARRAY_SIZE(gpu_cc_sc8280xp_clocks),
+       .gdscs = gpu_cc_sc8280xp_gdscs,
+       .num_gdscs = ARRAY_SIZE(gpu_cc_sc8280xp_gdscs),
+};
+
+static int gpu_cc_sc8280xp_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+
+       regmap = qcom_cc_map(pdev, &gpu_cc_sc8280xp_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       clk_lucid_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
+       clk_lucid_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
+
+       /*
+        * Keep the clocks always-ON
+        * GPU_CC_CB_CLK, GPU_CC_CXO_CLK
+        */
+       regmap_update_bits(regmap, 0x1170, BIT(0), BIT(0));
+       regmap_update_bits(regmap, 0x109c, BIT(0), BIT(0));
+
+       return qcom_cc_really_probe(pdev, &gpu_cc_sc8280xp_desc, regmap);
+}
+
+static const struct of_device_id gpu_cc_sc8280xp_match_table[] = {
+       { .compatible = "qcom,sc8280xp-gpucc" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gpu_cc_sc8280xp_match_table);
+
+static struct platform_driver gpu_cc_sc8280xp_driver = {
+       .probe = gpu_cc_sc8280xp_probe,
+       .driver = {
+               .name = "gpu_cc-sc8280xp",
+               .of_match_table = gpu_cc_sc8280xp_match_table,
+       },
+};
+module_platform_driver(gpu_cc_sc8280xp_driver);
+
+MODULE_DESCRIPTION("Qualcomm SC8280XP GPU clock controller");
+MODULE_LICENSE("GPL");
index 88d4b33..b1b3702 100644 (file)
@@ -12,9 +12,9 @@
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 
-static const char *aux_parents[] = {
-       "pll8_vote",
-       "pxo",
+static const struct clk_parent_data aux_parents[] = {
+       { .fw_name = "pll8_vote", .name = "pll8_vote" },
+       { .fw_name = "pxo", .name = "pxo_board" },
 };
 
 static const u32 aux_parent_map[] = {
@@ -32,8 +32,8 @@ MODULE_DEVICE_TABLE(of, kpss_xcc_match_table);
 static int kpss_xcc_driver_probe(struct platform_device *pdev)
 {
        const struct of_device_id *id;
-       struct clk *clk;
        void __iomem *base;
+       struct clk_hw *hw;
        const char *name;
 
        id = of_match_device(kpss_xcc_match_table, &pdev->dev);
@@ -55,24 +55,16 @@ static int kpss_xcc_driver_probe(struct platform_device *pdev)
                base += 0x28;
        }
 
-       clk = clk_register_mux_table(&pdev->dev, name, aux_parents,
-                                    ARRAY_SIZE(aux_parents), 0, base, 0, 0x3,
-                                    0, aux_parent_map, NULL);
+       hw = devm_clk_hw_register_mux_parent_data_table(&pdev->dev, name, aux_parents,
+                                                       ARRAY_SIZE(aux_parents), 0,
+                                                       base, 0, 0x3,
+                                                       0, aux_parent_map, NULL);
 
-       platform_set_drvdata(pdev, clk);
-
-       return PTR_ERR_OR_ZERO(clk);
-}
-
-static int kpss_xcc_driver_remove(struct platform_device *pdev)
-{
-       clk_unregister_mux(platform_get_drvdata(pdev));
-       return 0;
+       return PTR_ERR_OR_ZERO(hw);
 }
 
 static struct platform_driver kpss_xcc_driver = {
        .probe = kpss_xcc_driver_probe,
-       .remove = kpss_xcc_driver_remove,
        .driver = {
                .name = "kpss-xcc",
                .of_match_table = kpss_xcc_match_table,
index 1a2be4a..81a44a9 100644 (file)
@@ -22,6 +22,7 @@
 #include "clk-branch.h"
 #include "clk-regmap-divider.h"
 #include "clk-regmap-mux.h"
+#include "reset.h"
 
 static struct clk_pll pll4 = {
        .l_reg = 0x4,
@@ -33,7 +34,9 @@ static struct clk_pll pll4 = {
        .status_bit = 16,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pll4",
-               .parent_names = (const char *[]){ "pxo" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "pxo", .name = "pxo_board",
+               },
                .num_parents = 1,
                .ops = &clk_pll_ops,
        },
@@ -63,9 +66,9 @@ static const struct parent_map lcc_pxo_pll4_map[] = {
        { P_PLL4, 2 }
 };
 
-static const char * const lcc_pxo_pll4[] = {
-       "pxo",
-       "pll4_vote",
+static const struct clk_parent_data lcc_pxo_pll4[] = {
+       { .fw_name = "pxo", .name = "pxo_board" },
+       { .fw_name = "pll4_vote", .name = "pll4_vote" },
 };
 
 static struct freq_tbl clk_tbl_aif_mi2s[] = {
@@ -130,18 +133,14 @@ static struct clk_rcg mi2s_osr_src = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "mi2s_osr_src",
-                       .parent_names = lcc_pxo_pll4,
-                       .num_parents = 2,
+                       .parent_data = lcc_pxo_pll4,
+                       .num_parents = ARRAY_SIZE(lcc_pxo_pll4),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
        },
 };
 
-static const char * const lcc_mi2s_parents[] = {
-       "mi2s_osr_src",
-};
-
 static struct clk_branch mi2s_osr_clk = {
        .halt_reg = 0x50,
        .halt_bit = 1,
@@ -151,7 +150,9 @@ static struct clk_branch mi2s_osr_clk = {
                .enable_mask = BIT(17),
                .hw.init = &(struct clk_init_data){
                        .name = "mi2s_osr_clk",
-                       .parent_names = lcc_mi2s_parents,
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &mi2s_osr_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -166,7 +167,9 @@ static struct clk_regmap_div mi2s_div_clk = {
        .clkr = {
                .hw.init = &(struct clk_init_data){
                        .name = "mi2s_div_clk",
-                       .parent_names = lcc_mi2s_parents,
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &mi2s_osr_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_regmap_div_ops,
                },
@@ -182,7 +185,9 @@ static struct clk_branch mi2s_bit_div_clk = {
                .enable_mask = BIT(15),
                .hw.init = &(struct clk_init_data){
                        .name = "mi2s_bit_div_clk",
-                       .parent_names = (const char *[]){ "mi2s_div_clk" },
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &mi2s_div_clk.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -190,6 +195,10 @@ static struct clk_branch mi2s_bit_div_clk = {
        },
 };
 
+static const struct clk_parent_data lcc_mi2s_bit_div_codec_clk[] = {
+       { .hw = &mi2s_bit_div_clk.clkr.hw, },
+       { .fw_name = "mi2s_codec", .name = "mi2s_codec_clk" },
+};
 
 static struct clk_regmap_mux mi2s_bit_clk = {
        .reg = 0x48,
@@ -198,11 +207,8 @@ static struct clk_regmap_mux mi2s_bit_clk = {
        .clkr = {
                .hw.init = &(struct clk_init_data){
                        .name = "mi2s_bit_clk",
-                       .parent_names = (const char *[]){
-                               "mi2s_bit_div_clk",
-                               "mi2s_codec_clk",
-                       },
-                       .num_parents = 2,
+                       .parent_data = lcc_mi2s_bit_div_codec_clk,
+                       .num_parents = ARRAY_SIZE(lcc_mi2s_bit_div_codec_clk),
                        .ops = &clk_regmap_mux_closest_ops,
                        .flags = CLK_SET_RATE_PARENT,
                },
@@ -244,8 +250,8 @@ static struct clk_rcg pcm_src = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "pcm_src",
-                       .parent_names = lcc_pxo_pll4,
-                       .num_parents = 2,
+                       .parent_data = lcc_pxo_pll4,
+                       .num_parents = ARRAY_SIZE(lcc_pxo_pll4),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
@@ -261,7 +267,9 @@ static struct clk_branch pcm_clk_out = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "pcm_clk_out",
-                       .parent_names = (const char *[]){ "pcm_src" },
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pcm_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -269,6 +277,11 @@ static struct clk_branch pcm_clk_out = {
        },
 };
 
+static const struct clk_parent_data lcc_pcm_clk_out_codec_clk[] = {
+       { .hw = &pcm_clk_out.clkr.hw, },
+       { .fw_name = "pcm_codec_clk", .name = "pcm_codec_clk" },
+};
+
 static struct clk_regmap_mux pcm_clk = {
        .reg = 0x54,
        .shift = 10,
@@ -276,11 +289,8 @@ static struct clk_regmap_mux pcm_clk = {
        .clkr = {
                .hw.init = &(struct clk_init_data){
                        .name = "pcm_clk",
-                       .parent_names = (const char *[]){
-                               "pcm_clk_out",
-                               "pcm_codec_clk",
-                       },
-                       .num_parents = 2,
+                       .parent_data = lcc_pcm_clk_out_codec_clk,
+                       .num_parents = ARRAY_SIZE(lcc_pcm_clk_out_codec_clk),
                        .ops = &clk_regmap_mux_closest_ops,
                        .flags = CLK_SET_RATE_PARENT,
                },
@@ -324,18 +334,14 @@ static struct clk_rcg spdif_src = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "spdif_src",
-                       .parent_names = lcc_pxo_pll4,
-                       .num_parents = 2,
+                       .parent_data = lcc_pxo_pll4,
+                       .num_parents = ARRAY_SIZE(lcc_pxo_pll4),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
        },
 };
 
-static const char * const lcc_spdif_parents[] = {
-       "spdif_src",
-};
-
 static struct clk_branch spdif_clk = {
        .halt_reg = 0xd4,
        .halt_bit = 1,
@@ -345,7 +351,9 @@ static struct clk_branch spdif_clk = {
                .enable_mask = BIT(12),
                .hw.init = &(struct clk_init_data){
                        .name = "spdif_clk",
-                       .parent_names = lcc_spdif_parents,
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &spdif_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -383,8 +391,8 @@ static struct clk_rcg ahbix_clk = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "ahbix",
-                       .parent_names = lcc_pxo_pll4,
-                       .num_parents = 2,
+                       .parent_data = lcc_pxo_pll4,
+                       .num_parents = ARRAY_SIZE(lcc_pxo_pll4),
                        .ops = &clk_rcg_lcc_ops,
                },
        },
@@ -405,6 +413,10 @@ static struct clk_regmap *lcc_ipq806x_clks[] = {
        [AHBIX_CLK] = &ahbix_clk.clkr,
 };
 
+static const struct qcom_reset_map lcc_ipq806x_resets[] = {
+       [LCC_PCM_RESET] = { 0x54, 13 },
+};
+
 static const struct regmap_config lcc_ipq806x_regmap_config = {
        .reg_bits       = 32,
        .reg_stride     = 4,
@@ -417,6 +429,8 @@ static const struct qcom_cc_desc lcc_ipq806x_desc = {
        .config = &lcc_ipq806x_regmap_config,
        .clks = lcc_ipq806x_clks,
        .num_clks = ARRAY_SIZE(lcc_ipq806x_clks),
+       .resets = lcc_ipq806x_resets,
+       .num_resets = ARRAY_SIZE(lcc_ipq806x_resets),
 };
 
 static const struct of_device_id lcc_ipq806x_match_table[] = {
index 84817cf..3926184 100644 (file)
@@ -33,7 +33,9 @@ static struct clk_pll pll4 = {
        .status_bit = 16,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pll4",
-               .parent_names = (const char *[]){ "pxo" },
+               .parent_data = (const struct clk_parent_data[]){
+                       { .fw_name = "pxo", .name = "pxo_board" },
+               },
                .num_parents = 1,
                .ops = &clk_pll_ops,
        },
@@ -49,9 +51,9 @@ static const struct parent_map lcc_pxo_pll4_map[] = {
        { P_PLL4, 2 }
 };
 
-static const char * const lcc_pxo_pll4[] = {
-       "pxo",
-       "pll4_vote",
+static const struct clk_parent_data lcc_pxo_pll4[] = {
+       { .fw_name = "pxo", .name = "pxo_board" },
+       { .fw_name = "pll4_vote", .name = "pll4_vote" },
 };
 
 static struct freq_tbl clk_tbl_aif_osr_492[] = {
@@ -86,112 +88,7 @@ static struct freq_tbl clk_tbl_aif_osr_393[] = {
        { }
 };
 
-static struct clk_rcg mi2s_osr_src = {
-       .ns_reg = 0x48,
-       .md_reg = 0x4c,
-       .mn = {
-               .mnctr_en_bit = 8,
-               .mnctr_reset_bit = 7,
-               .mnctr_mode_shift = 5,
-               .n_val_shift = 24,
-               .m_val_shift = 8,
-               .width = 8,
-       },
-       .p = {
-               .pre_div_shift = 3,
-               .pre_div_width = 2,
-       },
-       .s = {
-               .src_sel_shift = 0,
-               .parent_map = lcc_pxo_pll4_map,
-       },
-       .freq_tbl = clk_tbl_aif_osr_393,
-       .clkr = {
-               .enable_reg = 0x48,
-               .enable_mask = BIT(9),
-               .hw.init = &(struct clk_init_data){
-                       .name = "mi2s_osr_src",
-                       .parent_names = lcc_pxo_pll4,
-                       .num_parents = 2,
-                       .ops = &clk_rcg_ops,
-                       .flags = CLK_SET_RATE_GATE,
-               },
-       },
-};
-
-static const char * const lcc_mi2s_parents[] = {
-       "mi2s_osr_src",
-};
-
-static struct clk_branch mi2s_osr_clk = {
-       .halt_reg = 0x50,
-       .halt_bit = 1,
-       .halt_check = BRANCH_HALT_ENABLE,
-       .clkr = {
-               .enable_reg = 0x48,
-               .enable_mask = BIT(17),
-               .hw.init = &(struct clk_init_data){
-                       .name = "mi2s_osr_clk",
-                       .parent_names = lcc_mi2s_parents,
-                       .num_parents = 1,
-                       .ops = &clk_branch_ops,
-                       .flags = CLK_SET_RATE_PARENT,
-               },
-       },
-};
-
-static struct clk_regmap_div mi2s_div_clk = {
-       .reg = 0x48,
-       .shift = 10,
-       .width = 4,
-       .clkr = {
-               .enable_reg = 0x48,
-               .enable_mask = BIT(15),
-               .hw.init = &(struct clk_init_data){
-                       .name = "mi2s_div_clk",
-                       .parent_names = lcc_mi2s_parents,
-                       .num_parents = 1,
-                       .ops = &clk_regmap_div_ops,
-               },
-       },
-};
-
-static struct clk_branch mi2s_bit_div_clk = {
-       .halt_reg = 0x50,
-       .halt_bit = 0,
-       .halt_check = BRANCH_HALT_ENABLE,
-       .clkr = {
-               .enable_reg = 0x48,
-               .enable_mask = BIT(15),
-               .hw.init = &(struct clk_init_data){
-                       .name = "mi2s_bit_div_clk",
-                       .parent_names = (const char *[]){ "mi2s_div_clk" },
-                       .num_parents = 1,
-                       .ops = &clk_branch_ops,
-                       .flags = CLK_SET_RATE_PARENT,
-               },
-       },
-};
-
-static struct clk_regmap_mux mi2s_bit_clk = {
-       .reg = 0x48,
-       .shift = 14,
-       .width = 1,
-       .clkr = {
-               .hw.init = &(struct clk_init_data){
-                       .name = "mi2s_bit_clk",
-                       .parent_names = (const char *[]){
-                               "mi2s_bit_div_clk",
-                               "mi2s_codec_clk",
-                       },
-                       .num_parents = 2,
-                       .ops = &clk_regmap_mux_closest_ops,
-                       .flags = CLK_SET_RATE_PARENT,
-               },
-       },
-};
-
-#define CLK_AIF_OSR_DIV(prefix, _ns, _md, hr)                  \
+#define CLK_AIF_OSR_SRC(prefix, _ns, _md)                      \
 static struct clk_rcg prefix##_osr_src = {                     \
        .ns_reg = _ns,                                          \
        .md_reg = _md,                                          \
@@ -217,85 +114,103 @@ static struct clk_rcg prefix##_osr_src = {                       \
                .enable_mask = BIT(9),                          \
                .hw.init = &(struct clk_init_data){             \
                        .name = #prefix "_osr_src",             \
-                       .parent_names = lcc_pxo_pll4,           \
-                       .num_parents = 2,                       \
+                       .parent_data = lcc_pxo_pll4,            \
+                       .num_parents = ARRAY_SIZE(lcc_pxo_pll4), \
                        .ops = &clk_rcg_ops,                    \
                        .flags = CLK_SET_RATE_GATE,             \
                },                                              \
        },                                                      \
 };                                                             \
-                                                               \
-static const char * const lcc_##prefix##_parents[] = {         \
-       #prefix "_osr_src",                                     \
-};                                                             \
-                                                               \
+
+#define CLK_AIF_OSR_CLK(prefix, _ns, hr, en_bit)               \
 static struct clk_branch prefix##_osr_clk = {                  \
        .halt_reg = hr,                                         \
        .halt_bit = 1,                                          \
        .halt_check = BRANCH_HALT_ENABLE,                       \
        .clkr = {                                               \
                .enable_reg = _ns,                              \
-               .enable_mask = BIT(21),                         \
+               .enable_mask = BIT(en_bit),                     \
                .hw.init = &(struct clk_init_data){             \
                        .name = #prefix "_osr_clk",             \
-                       .parent_names = lcc_##prefix##_parents, \
+                       .parent_hws = (const struct clk_hw*[]){ \
+                               &prefix##_osr_src.clkr.hw,      \
+                       },                                      \
                        .num_parents = 1,                       \
                        .ops = &clk_branch_ops,                 \
                        .flags = CLK_SET_RATE_PARENT,           \
                },                                              \
        },                                                      \
 };                                                             \
-                                                               \
+
+#define CLK_AIF_OSR_DIV_CLK(prefix, _ns, _width)               \
 static struct clk_regmap_div prefix##_div_clk = {              \
        .reg = _ns,                                             \
        .shift = 10,                                            \
-       .width = 8,                                             \
+       .width = _width,                                        \
        .clkr = {                                               \
                .hw.init = &(struct clk_init_data){             \
                        .name = #prefix "_div_clk",             \
-                       .parent_names = lcc_##prefix##_parents, \
+                       .parent_hws = (const struct clk_hw*[]){ \
+                               &prefix##_osr_src.clkr.hw,      \
+                       },                                      \
                        .num_parents = 1,                       \
                        .ops = &clk_regmap_div_ops,             \
                },                                              \
        },                                                      \
 };                                                             \
-                                                               \
+
+#define CLK_AIF_OSR_BIT_DIV_CLK(prefix, _ns, hr, en_bit)       \
 static struct clk_branch prefix##_bit_div_clk = {              \
        .halt_reg = hr,                                         \
        .halt_bit = 0,                                          \
        .halt_check = BRANCH_HALT_ENABLE,                       \
        .clkr = {                                               \
                .enable_reg = _ns,                              \
-               .enable_mask = BIT(19),                         \
+               .enable_mask = BIT(en_bit),                     \
                .hw.init = &(struct clk_init_data){             \
                        .name = #prefix "_bit_div_clk",         \
-                       .parent_names = (const char *[]){       \
-                               #prefix "_div_clk"              \
-                       },                                      \
+                       .parent_hws = (const struct clk_hw*[]){ \
+                               &prefix##_div_clk.clkr.hw,      \
+                       },                                      \
                        .num_parents = 1,                       \
                        .ops = &clk_branch_ops,                 \
                        .flags = CLK_SET_RATE_PARENT,           \
                },                                              \
        },                                                      \
 };                                                             \
-                                                               \
+
+#define CLK_AIF_OSR_BIT_CLK(prefix, _ns, _shift)               \
 static struct clk_regmap_mux prefix##_bit_clk = {              \
        .reg = _ns,                                             \
-       .shift = 18,                                            \
+       .shift = _shift,                                        \
        .width = 1,                                             \
        .clkr = {                                               \
                .hw.init = &(struct clk_init_data){             \
                        .name = #prefix "_bit_clk",             \
-                       .parent_names = (const char *[]){       \
-                               #prefix "_bit_div_clk",         \
-                               #prefix "_codec_clk",           \
+                       .parent_data = (const struct clk_parent_data[]){ \
+                               { .hw = &prefix##_bit_div_clk.clkr.hw, }, \
+                               { .fw_name = #prefix "_codec_clk", \
+                                 .name = #prefix "_codec_clk", }, \
                        },                                      \
                        .num_parents = 2,                       \
                        .ops = &clk_regmap_mux_closest_ops,     \
                        .flags = CLK_SET_RATE_PARENT,           \
                },                                              \
        },                                                      \
-}
+};
+
+CLK_AIF_OSR_SRC(mi2s, 0x48, 0x4c)
+CLK_AIF_OSR_CLK(mi2s, 0x48, 0x50, 17)
+CLK_AIF_OSR_DIV_CLK(mi2s, 0x48, 4)
+CLK_AIF_OSR_BIT_DIV_CLK(mi2s, 0x48, 0x50, 15)
+CLK_AIF_OSR_BIT_CLK(mi2s, 0x48, 14)
+
+#define CLK_AIF_OSR_DIV(prefix, _ns, _md, hr)                  \
+       CLK_AIF_OSR_SRC(prefix, _ns, _md)                       \
+       CLK_AIF_OSR_CLK(prefix, _ns, hr, 21)                    \
+       CLK_AIF_OSR_DIV_CLK(prefix, _ns, 8)                     \
+       CLK_AIF_OSR_BIT_DIV_CLK(prefix, _ns, hr, 19)            \
+       CLK_AIF_OSR_BIT_CLK(prefix, _ns, 18)
 
 CLK_AIF_OSR_DIV(codec_i2s_mic, 0x60, 0x64, 0x68);
 CLK_AIF_OSR_DIV(spare_i2s_mic, 0x78, 0x7c, 0x80);
@@ -361,8 +276,8 @@ static struct clk_rcg pcm_src = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "pcm_src",
-                       .parent_names = lcc_pxo_pll4,
-                       .num_parents = 2,
+                       .parent_data = lcc_pxo_pll4,
+                       .num_parents = ARRAY_SIZE(lcc_pxo_pll4),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
@@ -378,7 +293,9 @@ static struct clk_branch pcm_clk_out = {
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
                        .name = "pcm_clk_out",
-                       .parent_names = (const char *[]){ "pcm_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pcm_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -393,9 +310,9 @@ static struct clk_regmap_mux pcm_clk = {
        .clkr = {
                .hw.init = &(struct clk_init_data){
                        .name = "pcm_clk",
-                       .parent_names = (const char *[]){
-                               "pcm_clk_out",
-                               "pcm_codec_clk",
+                       .parent_data = (const struct clk_parent_data[]){
+                               { .hw = &pcm_clk_out.clkr.hw },
+                               { .fw_name = "pcm_codec_clk", .name = "pcm_codec_clk" },
                        },
                        .num_parents = 2,
                        .ops = &clk_regmap_mux_closest_ops,
@@ -429,18 +346,14 @@ static struct clk_rcg slimbus_src = {
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
                        .name = "slimbus_src",
-                       .parent_names = lcc_pxo_pll4,
-                       .num_parents = 2,
+                       .parent_data = lcc_pxo_pll4,
+                       .num_parents = ARRAY_SIZE(lcc_pxo_pll4),
                        .ops = &clk_rcg_ops,
                        .flags = CLK_SET_RATE_GATE,
                },
        },
 };
 
-static const char * const lcc_slimbus_parents[] = {
-       "slimbus_src",
-};
-
 static struct clk_branch audio_slimbus_clk = {
        .halt_reg = 0xd4,
        .halt_bit = 0,
@@ -450,7 +363,9 @@ static struct clk_branch audio_slimbus_clk = {
                .enable_mask = BIT(10),
                .hw.init = &(struct clk_init_data){
                        .name = "audio_slimbus_clk",
-                       .parent_names = lcc_slimbus_parents,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &slimbus_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -467,7 +382,9 @@ static struct clk_branch sps_slimbus_clk = {
                .enable_mask = BIT(12),
                .hw.init = &(struct clk_init_data){
                        .name = "sps_slimbus_clk",
-                       .parent_names = lcc_slimbus_parents,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &slimbus_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
index 6ab6e5a..063e036 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 
+#include <dt-bindings/clock/qcom,lpass-sc7280.h>
 #include <dt-bindings/clock/qcom,lpassaudiocc-sc7280.h>
 
 #include "clk-alpha-pll.h"
@@ -22,6 +23,7 @@
 #include "clk-regmap-mux.h"
 #include "common.h"
 #include "gdsc.h"
+#include "reset.h"
 
 enum {
        P_BI_TCXO,
@@ -38,6 +40,32 @@ static const struct pll_vco zonda_vco[] = {
        { 595200000UL, 3600000000UL, 0 },
 };
 
+static struct clk_branch lpass_q6ss_ahbm_clk = {
+       .halt_reg = 0x901c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x901c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                               .name = "lpass_q6ss_ahbm_clk",
+                               .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch lpass_q6ss_ahbs_clk = {
+       .halt_reg = 0x9020,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x9020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "lpass_q6ss_ahbs_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 /* 1128.96MHz configuration */
 static const struct alpha_pll_config lpass_audio_cc_pll_config = {
        .l = 0x3a,
@@ -221,7 +249,7 @@ static struct clk_rcg2 lpass_aon_cc_main_rcg_clk_src = {
                .parent_data = lpass_aon_cc_parent_data_0,
                .num_parents = ARRAY_SIZE(lpass_aon_cc_parent_data_0),
                .flags = CLK_OPS_PARENT_ENABLE,
-               .ops = &clk_rcg2_ops,
+               .ops = &clk_rcg2_shared_ops,
        },
 };
 
@@ -614,6 +642,11 @@ static struct gdsc lpass_aon_cc_lpass_audio_hm_gdsc = {
        .flags = RETAIN_FF_ENABLE,
 };
 
+static struct clk_regmap *lpass_cc_sc7280_clocks[] = {
+       [LPASS_Q6SS_AHBM_CLK] = &lpass_q6ss_ahbm_clk.clkr,
+       [LPASS_Q6SS_AHBS_CLK] = &lpass_q6ss_ahbs_clk.clkr,
+};
+
 static struct clk_regmap *lpass_aon_cc_sc7280_clocks[] = {
        [LPASS_AON_CC_AUDIO_HM_H_CLK] = &lpass_aon_cc_audio_hm_h_clk.clkr,
        [LPASS_AON_CC_VA_MEM0_CLK] = &lpass_aon_cc_va_mem0_clk.clkr,
@@ -659,12 +692,30 @@ static struct regmap_config lpass_audio_cc_sc7280_regmap_config = {
        .fast_io = true,
 };
 
+static const struct qcom_cc_desc lpass_cc_sc7280_desc = {
+       .config = &lpass_audio_cc_sc7280_regmap_config,
+       .clks = lpass_cc_sc7280_clocks,
+       .num_clks = ARRAY_SIZE(lpass_cc_sc7280_clocks),
+};
+
 static const struct qcom_cc_desc lpass_audio_cc_sc7280_desc = {
        .config = &lpass_audio_cc_sc7280_regmap_config,
        .clks = lpass_audio_cc_sc7280_clocks,
        .num_clks = ARRAY_SIZE(lpass_audio_cc_sc7280_clocks),
 };
 
+static const struct qcom_reset_map lpass_audio_cc_sc7280_resets[] = {
+       [LPASS_AUDIO_SWR_RX_CGCR] =  { 0xa0, 1 },
+       [LPASS_AUDIO_SWR_TX_CGCR] =  { 0xa8, 1 },
+       [LPASS_AUDIO_SWR_WSA_CGCR] = { 0xb0, 1 },
+};
+
+static const struct qcom_cc_desc lpass_audio_cc_reset_sc7280_desc = {
+       .config = &lpass_audio_cc_sc7280_regmap_config,
+       .resets = lpass_audio_cc_sc7280_resets,
+       .num_resets = ARRAY_SIZE(lpass_audio_cc_sc7280_resets),
+};
+
 static const struct of_device_id lpass_audio_cc_sc7280_match_table[] = {
        { .compatible = "qcom,sc7280-lpassaudiocc" },
        { }
@@ -741,6 +792,13 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev)
                return ret;
        }
 
+       ret = qcom_cc_probe_by_index(pdev, 1, &lpass_audio_cc_reset_sc7280_desc);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC Resets\n");
+               pm_runtime_disable(&pdev->dev);
+               return ret;
+       }
+
        pm_runtime_mark_last_busy(&pdev->dev);
        pm_runtime_put_autosuspend(&pdev->dev);
        pm_runtime_put_sync(&pdev->dev);
@@ -785,6 +843,12 @@ static int lpass_aon_cc_sc7280_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
+       if (of_property_read_bool(pdev->dev.of_node, "qcom,adsp-pil-mode")) {
+               lpass_audio_cc_sc7280_regmap_config.name = "cc";
+               desc = &lpass_cc_sc7280_desc;
+               return qcom_cc_probe(pdev, desc);
+       }
+
        lpass_audio_cc_sc7280_regmap_config.name = "lpasscc_aon";
        lpass_audio_cc_sc7280_regmap_config.max_register = 0xa0008;
        desc = &lpass_aon_cc_sc7280_desc;
index b39ee1c..5c1e17b 100644 (file)
 #include "clk-branch.h"
 #include "common.h"
 
-static struct clk_branch lpass_q6ss_ahbm_clk = {
-       .halt_reg = 0x1c,
-       .halt_check = BRANCH_HALT,
-       .clkr = {
-               .enable_reg = 0x1c,
-               .enable_mask = BIT(0),
-               .hw.init = &(struct clk_init_data){
-                       .name = "lpass_q6ss_ahbm_clk",
-                       .ops = &clk_branch2_ops,
-               },
-       },
-};
-
-static struct clk_branch lpass_q6ss_ahbs_clk = {
-       .halt_reg = 0x20,
-       .halt_check = BRANCH_HALT_VOTED,
-       .clkr = {
-               .enable_reg = 0x20,
-               .enable_mask = BIT(0),
-               .hw.init = &(struct clk_init_data){
-                       .name = "lpass_q6ss_ahbs_clk",
-                       .ops = &clk_branch2_ops,
-               },
-       },
-};
-
 static struct clk_branch lpass_top_cc_lpi_q6_axim_hs_clk = {
        .halt_reg = 0x0,
        .halt_check = BRANCH_HALT,
@@ -105,17 +79,6 @@ static struct regmap_config lpass_regmap_config = {
        .fast_io        = true,
 };
 
-static struct clk_regmap *lpass_cc_sc7280_clocks[] = {
-       [LPASS_Q6SS_AHBM_CLK] = &lpass_q6ss_ahbm_clk.clkr,
-       [LPASS_Q6SS_AHBS_CLK] = &lpass_q6ss_ahbs_clk.clkr,
-};
-
-static const struct qcom_cc_desc lpass_cc_sc7280_desc = {
-       .config = &lpass_regmap_config,
-       .clks = lpass_cc_sc7280_clocks,
-       .num_clks = ARRAY_SIZE(lpass_cc_sc7280_clocks),
-};
-
 static struct clk_regmap *lpass_cc_top_sc7280_clocks[] = {
        [LPASS_TOP_CC_LPI_Q6_AXIM_HS_CLK] =
                                &lpass_top_cc_lpi_q6_axim_hs_clk.clkr,
@@ -169,13 +132,6 @@ static int lpass_cc_sc7280_probe(struct platform_device *pdev)
        if (ret)
                goto destroy_pm_clk;
 
-       lpass_regmap_config.name = "cc";
-       desc = &lpass_cc_sc7280_desc;
-
-       ret = qcom_cc_probe_by_index(pdev, 2, desc);
-       if (ret)
-               goto destroy_pm_clk;
-
        return 0;
 
 destroy_pm_clk:
index 1f1f1bd..6ad19b0 100644 (file)
@@ -190,6 +190,19 @@ static struct clk_rcg2 lpass_core_cc_ext_if1_clk_src = {
        },
 };
 
+static struct clk_rcg2 lpass_core_cc_ext_mclk0_clk_src = {
+       .cmd_rcgr = 0x20000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = lpass_core_cc_parent_map_0,
+       .freq_tbl = ftbl_lpass_core_cc_ext_if0_clk_src,
+       .clkr.hw.init = &(const struct clk_init_data){
+               .name = "lpass_core_cc_ext_mclk0_clk_src",
+               .parent_data = lpass_core_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(lpass_core_cc_parent_data_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
 
 static struct clk_branch lpass_core_cc_core_clk = {
        .halt_reg = 0x1f000,
@@ -283,6 +296,24 @@ static struct clk_branch lpass_core_cc_lpm_mem0_core_clk = {
        },
 };
 
+static struct clk_branch lpass_core_cc_ext_mclk0_clk = {
+       .halt_reg = 0x20014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x20014,
+               .enable_mask = BIT(0),
+               .hw.init = &(const struct clk_init_data){
+                       .name = "lpass_core_cc_ext_mclk0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &lpass_core_cc_ext_mclk0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_branch lpass_core_cc_sysnoc_mport_core_clk = {
        .halt_reg = 0x23000,
        .halt_check = BRANCH_HALT_VOTED,
@@ -326,6 +357,8 @@ static struct clk_regmap *lpass_core_cc_sc7280_clocks[] = {
        [LPASS_CORE_CC_LPM_CORE_CLK] = &lpass_core_cc_lpm_core_clk.clkr,
        [LPASS_CORE_CC_LPM_MEM0_CORE_CLK] = &lpass_core_cc_lpm_mem0_core_clk.clkr,
        [LPASS_CORE_CC_SYSNOC_MPORT_CORE_CLK] = &lpass_core_cc_sysnoc_mport_core_clk.clkr,
+       [LPASS_CORE_CC_EXT_MCLK0_CLK] = &lpass_core_cc_ext_mclk0_clk.clkr,
+       [LPASS_CORE_CC_EXT_MCLK0_CLK_SRC] = &lpass_core_cc_ext_mclk0_clk_src.clkr,
 };
 
 static struct regmap_config lpass_core_cc_sc7280_regmap_config = {
index aaaad65..6bf908a 100644 (file)
@@ -41,70 +41,6 @@ enum {
 
 #define F_MN(f, s, _m, _n) { .freq = f, .src = s, .m = _m, .n = _n }
 
-static const struct parent_map mmcc_pxo_pll8_pll2_map[] = {
-       { P_PXO, 0 },
-       { P_PLL8, 2 },
-       { P_PLL2, 1 }
-};
-
-static const char * const mmcc_pxo_pll8_pll2[] = {
-       "pxo",
-       "pll8_vote",
-       "pll2",
-};
-
-static const struct parent_map mmcc_pxo_pll8_pll2_pll3_map[] = {
-       { P_PXO, 0 },
-       { P_PLL8, 2 },
-       { P_PLL2, 1 },
-       { P_PLL3, 3 }
-};
-
-static const char * const mmcc_pxo_pll8_pll2_pll15[] = {
-       "pxo",
-       "pll8_vote",
-       "pll2",
-       "pll15",
-};
-
-static const struct parent_map mmcc_pxo_pll8_pll2_pll15_map[] = {
-       { P_PXO, 0 },
-       { P_PLL8, 2 },
-       { P_PLL2, 1 },
-       { P_PLL15, 3 }
-};
-
-static const char * const mmcc_pxo_pll8_pll2_pll3[] = {
-       "pxo",
-       "pll8_vote",
-       "pll2",
-       "pll3",
-};
-
-static const struct parent_map mmcc_pxo_dsi2_dsi1_map[] = {
-       { P_PXO, 0 },
-       { P_DSI2_PLL_DSICLK, 1 },
-       { P_DSI1_PLL_DSICLK, 3 },
-};
-
-static const char * const mmcc_pxo_dsi2_dsi1[] = {
-       "pxo",
-       "dsi2pll",
-       "dsi1pll",
-};
-
-static const struct parent_map mmcc_pxo_dsi1_dsi2_byte_map[] = {
-       { P_PXO, 0 },
-       { P_DSI1_PLL_BYTECLK, 1 },
-       { P_DSI2_PLL_BYTECLK, 2 },
-};
-
-static const char * const mmcc_pxo_dsi1_dsi2_byte[] = {
-       "pxo",
-       "dsi1pllbyte",
-       "dsi2pllbyte",
-};
-
 static struct clk_pll pll2 = {
        .l_reg = 0x320,
        .m_reg = 0x324,
@@ -115,7 +51,9 @@ static struct clk_pll pll2 = {
        .status_bit = 16,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pll2",
-               .parent_names = (const char *[]){ "pxo" },
+               .parent_data = (const struct clk_parent_data[]){
+                       { .fw_name = "pxo", .name = "pxo_board" },
+               },
                .num_parents = 1,
                .ops = &clk_pll_ops,
        },
@@ -131,7 +69,9 @@ static struct clk_pll pll15 = {
        .status_bit = 16,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pll15",
-               .parent_names = (const char *[]){ "pxo" },
+               .parent_data = (const struct clk_parent_data[]){
+                       { .fw_name = "pxo", .name = "pxo_board" },
+               },
                .num_parents = 1,
                .ops = &clk_pll_ops,
        },
@@ -151,6 +91,70 @@ static const struct pll_config pll15_config = {
        .main_output_mask = BIT(23),
 };
 
+static const struct parent_map mmcc_pxo_pll8_pll2_map[] = {
+       { P_PXO, 0 },
+       { P_PLL8, 2 },
+       { P_PLL2, 1 }
+};
+
+static const struct clk_parent_data mmcc_pxo_pll8_pll2[] = {
+       { .fw_name = "pxo", .name = "pxo_board" },
+       { .fw_name = "pll8_vote", .name = "pll8_vote" },
+       { .hw = &pll2.clkr.hw },
+};
+
+static const struct parent_map mmcc_pxo_pll8_pll2_pll3_map[] = {
+       { P_PXO, 0 },
+       { P_PLL8, 2 },
+       { P_PLL2, 1 },
+       { P_PLL3, 3 }
+};
+
+static const struct clk_parent_data mmcc_pxo_pll8_pll2_pll15[] = {
+       { .fw_name = "pxo", .name = "pxo_board" },
+       { .fw_name = "pll8_vote", .name = "pll8_vote" },
+       { .hw = &pll2.clkr.hw },
+       { .hw = &pll15.clkr.hw },
+};
+
+static const struct parent_map mmcc_pxo_pll8_pll2_pll15_map[] = {
+       { P_PXO, 0 },
+       { P_PLL8, 2 },
+       { P_PLL2, 1 },
+       { P_PLL15, 3 }
+};
+
+static const struct clk_parent_data mmcc_pxo_pll8_pll2_pll3[] = {
+       { .fw_name = "pxo", .name = "pxo_board" },
+       { .fw_name = "pll8_vote", .name = "pll8_vote" },
+       { .hw = &pll2.clkr.hw },
+       { .fw_name = "pll3", .name = "pll3" },
+};
+
+static const struct parent_map mmcc_pxo_dsi2_dsi1_map[] = {
+       { P_PXO, 0 },
+       { P_DSI2_PLL_DSICLK, 1 },
+       { P_DSI1_PLL_DSICLK, 3 },
+};
+
+static const struct clk_parent_data mmcc_pxo_dsi2_dsi1[] = {
+       { .fw_name = "pxo", .name = "pxo_board" },
+       { .fw_name = "dsi2pll", .name = "dsi2pll" },
+       { .fw_name = "dsi1pll", .name = "dsi1pll" },
+};
+
+static const struct parent_map mmcc_pxo_dsi1_dsi2_byte_map[] = {
+       { P_PXO, 0 },
+       { P_DSI1_PLL_BYTECLK, 1 },
+       { P_DSI2_PLL_BYTECLK, 2 },
+};
+
+static const struct clk_parent_data mmcc_pxo_dsi1_dsi2_byte[] = {
+       { .fw_name = "pxo", .name = "pxo_board" },
+       { .fw_name = "dsi1pllbyte", .name = "dsi1pllbyte" },
+       { .fw_name = "dsi2pllbyte", .name = "dsi2pllbyte" },
+};
+
 static struct freq_tbl clk_tbl_cam[] = {
        {   6000000, P_PLL8, 4, 1, 16 },
        {   8000000, P_PLL8, 4, 1, 12 },
@@ -192,8 +196,8 @@ static struct clk_rcg camclk0_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "camclk0_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_rcg_ops,
                },
        },
@@ -207,7 +211,9 @@ static struct clk_branch camclk0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "camclk0_clk",
-                       .parent_names = (const char *[]){ "camclk0_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camclk0_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                },
@@ -241,8 +247,8 @@ static struct clk_rcg camclk1_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "camclk1_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_rcg_ops,
                },
        },
@@ -256,7 +262,9 @@ static struct clk_branch camclk1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "camclk1_clk",
-                       .parent_names = (const char *[]){ "camclk1_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camclk1_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                },
@@ -290,8 +298,8 @@ static struct clk_rcg camclk2_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "camclk2_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_rcg_ops,
                },
        },
@@ -305,7 +313,9 @@ static struct clk_branch camclk2_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "camclk2_clk",
-                       .parent_names = (const char *[]){ "camclk2_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camclk2_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                },
@@ -345,8 +355,8 @@ static struct clk_rcg csi0_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "csi0_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_rcg_ops,
                },
        },
@@ -359,7 +369,9 @@ static struct clk_branch csi0_clk = {
                .enable_reg = 0x0040,
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = (const char *[]){ "csi0_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .name = "csi0_clk",
                        .ops = &clk_branch_ops,
@@ -375,7 +387,9 @@ static struct clk_branch csi0_phy_clk = {
                .enable_reg = 0x0040,
                .enable_mask = BIT(8),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = (const char *[]){ "csi0_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .name = "csi0_phy_clk",
                        .ops = &clk_branch_ops,
@@ -409,8 +423,8 @@ static struct clk_rcg csi1_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "csi1_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_rcg_ops,
                },
        },
@@ -423,7 +437,9 @@ static struct clk_branch csi1_clk = {
                .enable_reg = 0x0024,
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = (const char *[]){ "csi1_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .name = "csi1_clk",
                        .ops = &clk_branch_ops,
@@ -439,7 +455,9 @@ static struct clk_branch csi1_phy_clk = {
                .enable_reg = 0x0024,
                .enable_mask = BIT(8),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = (const char *[]){ "csi1_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .name = "csi1_phy_clk",
                        .ops = &clk_branch_ops,
@@ -473,8 +491,8 @@ static struct clk_rcg csi2_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "csi2_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_rcg_ops,
                },
        },
@@ -487,7 +505,9 @@ static struct clk_branch csi2_clk = {
                .enable_reg = 0x022c,
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = (const char *[]){ "csi2_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi2_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .name = "csi2_clk",
                        .ops = &clk_branch_ops,
@@ -503,7 +523,9 @@ static struct clk_branch csi2_phy_clk = {
                .enable_reg = 0x022c,
                .enable_mask = BIT(8),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = (const char *[]){ "csi2_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi2_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .name = "csi2_phy_clk",
                        .ops = &clk_branch_ops,
@@ -602,10 +624,10 @@ static const struct clk_ops clk_ops_pix_rdi = {
        .determine_rate = __clk_mux_determine_rate,
 };
 
-static const char * const pix_rdi_parents[] = {
-       "csi0_clk",
-       "csi1_clk",
-       "csi2_clk",
+static const struct clk_hw *pix_rdi_parents[] = {
+       &csi0_clk.clkr.hw,
+       &csi1_clk.clkr.hw,
+       &csi2_clk.clkr.hw,
 };
 
 static struct clk_pix_rdi csi_pix_clk = {
@@ -618,8 +640,8 @@ static struct clk_pix_rdi csi_pix_clk = {
                .enable_mask = BIT(26),
                .hw.init = &(struct clk_init_data){
                        .name = "csi_pix_clk",
-                       .parent_names = pix_rdi_parents,
-                       .num_parents = 3,
+                       .parent_hws = pix_rdi_parents,
+                       .num_parents = ARRAY_SIZE(pix_rdi_parents),
                        .ops = &clk_ops_pix_rdi,
                },
        },
@@ -635,8 +657,8 @@ static struct clk_pix_rdi csi_pix1_clk = {
                .enable_mask = BIT(10),
                .hw.init = &(struct clk_init_data){
                        .name = "csi_pix1_clk",
-                       .parent_names = pix_rdi_parents,
-                       .num_parents = 3,
+                       .parent_hws = pix_rdi_parents,
+                       .num_parents = ARRAY_SIZE(pix_rdi_parents),
                        .ops = &clk_ops_pix_rdi,
                },
        },
@@ -652,8 +674,8 @@ static struct clk_pix_rdi csi_rdi_clk = {
                .enable_mask = BIT(13),
                .hw.init = &(struct clk_init_data){
                        .name = "csi_rdi_clk",
-                       .parent_names = pix_rdi_parents,
-                       .num_parents = 3,
+                       .parent_hws = pix_rdi_parents,
+                       .num_parents = ARRAY_SIZE(pix_rdi_parents),
                        .ops = &clk_ops_pix_rdi,
                },
        },
@@ -669,8 +691,8 @@ static struct clk_pix_rdi csi_rdi1_clk = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "csi_rdi1_clk",
-                       .parent_names = pix_rdi_parents,
-                       .num_parents = 3,
+                       .parent_hws = pix_rdi_parents,
+                       .num_parents = ARRAY_SIZE(pix_rdi_parents),
                        .ops = &clk_ops_pix_rdi,
                },
        },
@@ -686,8 +708,8 @@ static struct clk_pix_rdi csi_rdi2_clk = {
                .enable_mask = BIT(6),
                .hw.init = &(struct clk_init_data){
                        .name = "csi_rdi2_clk",
-                       .parent_names = pix_rdi_parents,
-                       .num_parents = 3,
+                       .parent_hws = pix_rdi_parents,
+                       .num_parents = ARRAY_SIZE(pix_rdi_parents),
                        .ops = &clk_ops_pix_rdi,
                },
        },
@@ -725,15 +747,13 @@ static struct clk_rcg csiphytimer_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "csiphytimer_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_rcg_ops,
                },
        },
 };
 
-static const char * const csixphy_timer_src[] = { "csiphytimer_src" };
-
 static struct clk_branch csiphy0_timer_clk = {
        .halt_reg = 0x01e8,
        .halt_bit = 17,
@@ -741,7 +761,9 @@ static struct clk_branch csiphy0_timer_clk = {
                .enable_reg = 0x0160,
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = csixphy_timer_src,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csiphytimer_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .name = "csiphy0_timer_clk",
                        .ops = &clk_branch_ops,
@@ -757,7 +779,9 @@ static struct clk_branch csiphy1_timer_clk = {
                .enable_reg = 0x0160,
                .enable_mask = BIT(9),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = csixphy_timer_src,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csiphytimer_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .name = "csiphy1_timer_clk",
                        .ops = &clk_branch_ops,
@@ -773,7 +797,9 @@ static struct clk_branch csiphy2_timer_clk = {
                .enable_reg = 0x0160,
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = csixphy_timer_src,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csiphytimer_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .name = "csiphy2_timer_clk",
                        .ops = &clk_branch_ops,
@@ -835,8 +861,8 @@ static struct clk_dyn_rcg gfx2d0_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "gfx2d0_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_dyn_rcg_ops,
                },
        },
@@ -850,7 +876,9 @@ static struct clk_branch gfx2d0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gfx2d0_clk",
-                       .parent_names = (const char *[]){ "gfx2d0_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gfx2d0_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -895,8 +923,8 @@ static struct clk_dyn_rcg gfx2d1_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "gfx2d1_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_dyn_rcg_ops,
                },
        },
@@ -910,7 +938,9 @@ static struct clk_branch gfx2d1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gfx2d1_clk",
-                       .parent_names = (const char *[]){ "gfx2d1_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gfx2d1_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -996,8 +1026,8 @@ static struct clk_dyn_rcg gfx3d_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "gfx3d_src",
-                       .parent_names = mmcc_pxo_pll8_pll2_pll3,
-                       .num_parents = 4,
+                       .parent_data = mmcc_pxo_pll8_pll2_pll3,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2_pll3),
                        .ops = &clk_dyn_rcg_ops,
                },
        },
@@ -1005,8 +1035,8 @@ static struct clk_dyn_rcg gfx3d_src = {
 
 static const struct clk_init_data gfx3d_8064_init = {
        .name = "gfx3d_src",
-       .parent_names = mmcc_pxo_pll8_pll2_pll15,
-       .num_parents = 4,
+       .parent_data = mmcc_pxo_pll8_pll2_pll15,
+       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2_pll15),
        .ops = &clk_dyn_rcg_ops,
 };
 
@@ -1018,7 +1048,9 @@ static struct clk_branch gfx3d_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gfx3d_clk",
-                       .parent_names = (const char *[]){ "gfx3d_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gfx3d_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1074,8 +1106,8 @@ static struct clk_dyn_rcg vcap_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "vcap_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_dyn_rcg_ops,
                },
        },
@@ -1089,7 +1121,9 @@ static struct clk_branch vcap_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "vcap_clk",
-                       .parent_names = (const char *[]){ "vcap_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vcap_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1105,7 +1139,9 @@ static struct clk_branch vcap_npl_clk = {
                .enable_mask = BIT(13),
                .hw.init = &(struct clk_init_data){
                        .name = "vcap_npl_clk",
-                       .parent_names = (const char *[]){ "vcap_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vcap_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1153,8 +1189,8 @@ static struct clk_rcg ijpeg_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "ijpeg_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_rcg_ops,
                },
        },
@@ -1168,7 +1204,9 @@ static struct clk_branch ijpeg_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "ijpeg_clk",
-                       .parent_names = (const char *[]){ "ijpeg_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &ijpeg_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1201,8 +1239,8 @@ static struct clk_rcg jpegd_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "jpegd_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_rcg_ops,
                },
        },
@@ -1216,7 +1254,9 @@ static struct clk_branch jpegd_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "jpegd_clk",
-                       .parent_names = (const char *[]){ "jpegd_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &jpegd_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1281,8 +1321,8 @@ static struct clk_dyn_rcg mdp_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "mdp_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_dyn_rcg_ops,
                },
        },
@@ -1296,7 +1336,9 @@ static struct clk_branch mdp_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "mdp_clk",
-                       .parent_names = (const char *[]){ "mdp_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &mdp_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1311,7 +1353,9 @@ static struct clk_branch mdp_lut_clk = {
                .enable_reg = 0x016c,
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = (const char *[]){ "mdp_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &mdp_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .name = "mdp_lut_clk",
                        .ops = &clk_branch_ops,
@@ -1328,7 +1372,9 @@ static struct clk_branch mdp_vsync_clk = {
                .enable_mask = BIT(6),
                .hw.init = &(struct clk_init_data){
                        .name = "mdp_vsync_clk",
-                       .parent_names = (const char *[]){ "pxo" },
+                       .parent_data = (const struct clk_parent_data[]){
+                               { .fw_name = "pxo", .name = "pxo_board" },
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops
                },
@@ -1380,8 +1426,8 @@ static struct clk_dyn_rcg rot_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "rot_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_dyn_rcg_ops,
                },
        },
@@ -1395,7 +1441,9 @@ static struct clk_branch rot_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "rot_clk",
-                       .parent_names = (const char *[]){ "rot_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &rot_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1408,9 +1456,9 @@ static const struct parent_map mmcc_pxo_hdmi_map[] = {
        { P_HDMI_PLL, 3 }
 };
 
-static const char * const mmcc_pxo_hdmi[] = {
-       "pxo",
-       "hdmi_pll",
+static const struct clk_parent_data mmcc_pxo_hdmi[] = {
+       { .fw_name = "pxo", .name = "pxo_board" },
+       { .fw_name = "hdmipll", .name = "hdmi_pll" },
 };
 
 static struct freq_tbl clk_tbl_tv[] = {
@@ -1443,16 +1491,14 @@ static struct clk_rcg tv_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "tv_src",
-                       .parent_names = mmcc_pxo_hdmi,
-                       .num_parents = 2,
+                       .parent_data = mmcc_pxo_hdmi,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_hdmi),
                        .ops = &clk_rcg_bypass_ops,
                        .flags = CLK_SET_RATE_PARENT,
                },
        },
 };
 
-static const char * const tv_src_name[] = { "tv_src" };
-
 static struct clk_branch tv_enc_clk = {
        .halt_reg = 0x01d4,
        .halt_bit = 9,
@@ -1460,7 +1506,9 @@ static struct clk_branch tv_enc_clk = {
                .enable_reg = 0x00ec,
                .enable_mask = BIT(8),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = tv_src_name,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &tv_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .name = "tv_enc_clk",
                        .ops = &clk_branch_ops,
@@ -1476,7 +1524,9 @@ static struct clk_branch tv_dac_clk = {
                .enable_reg = 0x00ec,
                .enable_mask = BIT(10),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = tv_src_name,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &tv_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .name = "tv_dac_clk",
                        .ops = &clk_branch_ops,
@@ -1492,7 +1542,9 @@ static struct clk_branch mdp_tv_clk = {
                .enable_reg = 0x00ec,
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = tv_src_name,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &tv_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .name = "mdp_tv_clk",
                        .ops = &clk_branch_ops,
@@ -1508,7 +1560,9 @@ static struct clk_branch hdmi_tv_clk = {
                .enable_reg = 0x00ec,
                .enable_mask = BIT(12),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = tv_src_name,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &tv_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .name = "hdmi_tv_clk",
                        .ops = &clk_branch_ops,
@@ -1524,7 +1578,9 @@ static struct clk_branch rgb_tv_clk = {
                .enable_reg = 0x0124,
                .enable_mask = BIT(14),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = tv_src_name,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &tv_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .name = "rgb_tv_clk",
                        .ops = &clk_branch_ops,
@@ -1540,7 +1596,9 @@ static struct clk_branch npl_tv_clk = {
                .enable_reg = 0x0124,
                .enable_mask = BIT(16),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = tv_src_name,
+                       .parent_hws = (const struct clk_hw*[]){
+                               &tv_src.clkr.hw,
+                       },
                        .num_parents = 1,
                        .name = "npl_tv_clk",
                        .ops = &clk_branch_ops,
@@ -1556,7 +1614,9 @@ static struct clk_branch hdmi_app_clk = {
                .enable_reg = 0x005c,
                .enable_mask = BIT(11),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = (const char *[]){ "pxo" },
+                       .parent_data = (const struct clk_parent_data[]){
+                               { .fw_name = "pxo", .name = "pxo_board" },
+                       },
                        .num_parents = 1,
                        .name = "hdmi_app_clk",
                        .ops = &clk_branch_ops,
@@ -1614,8 +1674,8 @@ static struct clk_dyn_rcg vcodec_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "vcodec_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_dyn_rcg_ops,
                },
        },
@@ -1629,7 +1689,9 @@ static struct clk_branch vcodec_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "vcodec_clk",
-                       .parent_names = (const char *[]){ "vcodec_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vcodec_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1665,8 +1727,8 @@ static struct clk_rcg vpe_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "vpe_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_rcg_ops,
                },
        },
@@ -1680,7 +1742,9 @@ static struct clk_branch vpe_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "vpe_clk",
-                       .parent_names = (const char *[]){ "vpe_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vpe_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1733,8 +1797,8 @@ static struct clk_rcg vfe_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "vfe_src",
-                       .parent_names = mmcc_pxo_pll8_pll2,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_pll8_pll2,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_pll8_pll2),
                        .ops = &clk_rcg_ops,
                },
        },
@@ -1748,7 +1812,9 @@ static struct clk_branch vfe_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "vfe_clk",
-                       .parent_names = (const char *[]){ "vfe_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vfe_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1763,7 +1829,9 @@ static struct clk_branch vfe_csi_clk = {
                .enable_reg = 0x0104,
                .enable_mask = BIT(12),
                .hw.init = &(struct clk_init_data){
-                       .parent_names = (const char *[]){ "vfe_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vfe_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .name = "vfe_csi_clk",
                        .ops = &clk_branch_ops,
@@ -2067,8 +2135,8 @@ static struct clk_rcg dsi1_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "dsi1_src",
-                       .parent_names = mmcc_pxo_dsi2_dsi1,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_dsi2_dsi1,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_dsi2_dsi1),
                        .ops = &clk_rcg_bypass2_ops,
                        .flags = CLK_SET_RATE_PARENT,
                },
@@ -2083,7 +2151,9 @@ static struct clk_branch dsi1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "dsi1_clk",
-                       .parent_names = (const char *[]){ "dsi1_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &dsi1_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2115,8 +2185,8 @@ static struct clk_rcg dsi2_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "dsi2_src",
-                       .parent_names = mmcc_pxo_dsi2_dsi1,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_dsi2_dsi1,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_dsi2_dsi1),
                        .ops = &clk_rcg_bypass2_ops,
                        .flags = CLK_SET_RATE_PARENT,
                },
@@ -2131,7 +2201,9 @@ static struct clk_branch dsi2_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "dsi2_clk",
-                       .parent_names = (const char *[]){ "dsi2_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &dsi2_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2154,8 +2226,8 @@ static struct clk_rcg dsi1_byte_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "dsi1_byte_src",
-                       .parent_names = mmcc_pxo_dsi1_dsi2_byte,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_dsi1_dsi2_byte,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_dsi1_dsi2_byte),
                        .ops = &clk_rcg_bypass2_ops,
                        .flags = CLK_SET_RATE_PARENT,
                },
@@ -2170,7 +2242,9 @@ static struct clk_branch dsi1_byte_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "dsi1_byte_clk",
-                       .parent_names = (const char *[]){ "dsi1_byte_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &dsi1_byte_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2193,8 +2267,8 @@ static struct clk_rcg dsi2_byte_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "dsi2_byte_src",
-                       .parent_names = mmcc_pxo_dsi1_dsi2_byte,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_dsi1_dsi2_byte,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_dsi1_dsi2_byte),
                        .ops = &clk_rcg_bypass2_ops,
                        .flags = CLK_SET_RATE_PARENT,
                },
@@ -2209,7 +2283,9 @@ static struct clk_branch dsi2_byte_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "dsi2_byte_clk",
-                       .parent_names = (const char *[]){ "dsi2_byte_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &dsi2_byte_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2232,8 +2308,8 @@ static struct clk_rcg dsi1_esc_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "dsi1_esc_src",
-                       .parent_names = mmcc_pxo_dsi1_dsi2_byte,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_dsi1_dsi2_byte,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_dsi1_dsi2_byte),
                        .ops = &clk_rcg_esc_ops,
                },
        },
@@ -2247,7 +2323,9 @@ static struct clk_branch dsi1_esc_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "dsi1_esc_clk",
-                       .parent_names = (const char *[]){ "dsi1_esc_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &dsi1_esc_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2270,8 +2348,8 @@ static struct clk_rcg dsi2_esc_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "dsi2_esc_src",
-                       .parent_names = mmcc_pxo_dsi1_dsi2_byte,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_dsi1_dsi2_byte,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_dsi1_dsi2_byte),
                        .ops = &clk_rcg_esc_ops,
                },
        },
@@ -2285,7 +2363,9 @@ static struct clk_branch dsi2_esc_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "dsi2_esc_clk",
-                       .parent_names = (const char *[]){ "dsi2_esc_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &dsi2_esc_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2317,8 +2397,8 @@ static struct clk_rcg dsi1_pixel_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "dsi1_pixel_src",
-                       .parent_names = mmcc_pxo_dsi2_dsi1,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_dsi2_dsi1,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_dsi2_dsi1),
                        .ops = &clk_rcg_pixel_ops,
                },
        },
@@ -2332,7 +2412,9 @@ static struct clk_branch dsi1_pixel_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "mdp_pclk1_clk",
-                       .parent_names = (const char *[]){ "dsi1_pixel_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &dsi1_pixel_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2364,8 +2446,8 @@ static struct clk_rcg dsi2_pixel_src = {
                .enable_mask = BIT(2),
                .hw.init = &(struct clk_init_data){
                        .name = "dsi2_pixel_src",
-                       .parent_names = mmcc_pxo_dsi2_dsi1,
-                       .num_parents = 3,
+                       .parent_data = mmcc_pxo_dsi2_dsi1,
+                       .num_parents = ARRAY_SIZE(mmcc_pxo_dsi2_dsi1),
                        .ops = &clk_rcg_pixel_ops,
                },
        },
@@ -2379,7 +2461,9 @@ static struct clk_branch dsi2_pixel_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "mdp_pclk2_clk",
-                       .parent_names = (const char *[]){ "dsi2_pixel_src" },
+                       .parent_hws = (const struct clk_hw*[]){
+                               &dsi2_pixel_src.clkr.hw
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch_ops,
                        .flags = CLK_SET_RATE_PARENT,
index 819d194..2a16adb 100644 (file)
 
 static int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id)
 {
+       struct qcom_reset_controller *rst = to_qcom_reset_controller(rcdev);
+
        rcdev->ops->assert(rcdev, id);
-       udelay(1);
+       udelay(rst->reset_map[id].udelay ?: 1); /* use 1 us as default */
        rcdev->ops->deassert(rcdev, id);
        return 0;
 }
index 2a08b5e..b8c1135 100644 (file)
@@ -11,6 +11,7 @@
 struct qcom_reset_map {
        unsigned int reg;
        u8 bit;
+       u8 udelay;
 };
 
 struct regmap;
index cd80b60..4baf355 100644 (file)
@@ -108,7 +108,13 @@ static const struct cpg_core_clk r8a779f0_core_clks[] __initconst = {
        DEF_FIXED("cbfusa",     R8A779F0_CLK_CBFUSA,    CLK_EXTAL,      2, 1),
        DEF_FIXED("cpex",       R8A779F0_CLK_CPEX,      CLK_EXTAL,      2, 1),
 
-       DEF_GEN4_SD("sd0",      R8A779F0_CLK_SD0,       CLK_SDSRC,      0x870),
+       DEF_FIXED("sasyncrt",   R8A779F0_CLK_SASYNCRT,  CLK_PLL5_DIV4,  48, 1),
+       DEF_FIXED("sasyncperd1", R8A779F0_CLK_SASYNCPERD1, CLK_PLL5_DIV4, 3, 1),
+       DEF_FIXED("sasyncperd2", R8A779F0_CLK_SASYNCPERD2, R8A779F0_CLK_SASYNCPERD1, 2, 1),
+       DEF_FIXED("sasyncperd4", R8A779F0_CLK_SASYNCPERD4, R8A779F0_CLK_SASYNCPERD1, 4, 1),
+
+       DEF_GEN4_SDH("sdh0",    R8A779F0_CLK_SD0H,      CLK_SDSRC,         0x870),
+       DEF_GEN4_SD("sd0",      R8A779F0_CLK_SD0,       R8A779F0_CLK_SD0H, 0x870),
 
        DEF_BASE("rpc",         R8A779F0_CLK_RPC,       CLK_TYPE_GEN4_RPC, CLK_RPCSRC),
        DEF_BASE("rpcd2",       R8A779F0_CLK_RPCD2,     CLK_TYPE_GEN4_RPCD2, R8A779F0_CLK_RPC),
@@ -130,6 +136,10 @@ static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = {
        DEF_MOD("i2c3",         521,    R8A779F0_CLK_S0D6_PER),
        DEF_MOD("i2c4",         522,    R8A779F0_CLK_S0D6_PER),
        DEF_MOD("i2c5",         523,    R8A779F0_CLK_S0D6_PER),
+       DEF_MOD("msiof0",       618,    R8A779F0_CLK_MSO),
+       DEF_MOD("msiof1",       619,    R8A779F0_CLK_MSO),
+       DEF_MOD("msiof2",       620,    R8A779F0_CLK_MSO),
+       DEF_MOD("msiof3",       621,    R8A779F0_CLK_MSO),
        DEF_MOD("pcie0",        624,    R8A779F0_CLK_S0D2),
        DEF_MOD("pcie1",        625,    R8A779F0_CLK_S0D2),
        DEF_MOD("scif0",        702,    R8A779F0_CLK_S0D12_PER),
@@ -139,7 +149,16 @@ static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = {
        DEF_MOD("sdhi0",        706,    R8A779F0_CLK_SD0),
        DEF_MOD("sys-dmac0",    709,    R8A779F0_CLK_S0D3_PER),
        DEF_MOD("sys-dmac1",    710,    R8A779F0_CLK_S0D3_PER),
+       DEF_MOD("tmu0",         713,    R8A779F0_CLK_SASYNCRT),
+       DEF_MOD("tmu1",         714,    R8A779F0_CLK_SASYNCPERD2),
+       DEF_MOD("tmu2",         715,    R8A779F0_CLK_SASYNCPERD2),
+       DEF_MOD("tmu3",         716,    R8A779F0_CLK_SASYNCPERD2),
+       DEF_MOD("tmu4",         717,    R8A779F0_CLK_SASYNCPERD2),
        DEF_MOD("wdt",          907,    R8A779F0_CLK_R),
+       DEF_MOD("cmt0",         910,    R8A779F0_CLK_R),
+       DEF_MOD("cmt1",         911,    R8A779F0_CLK_R),
+       DEF_MOD("cmt2",         912,    R8A779F0_CLK_R),
+       DEF_MOD("cmt3",         913,    R8A779F0_CLK_R),
        DEF_MOD("pfc0",         915,    R8A779F0_CLK_CL16M),
        DEF_MOD("tsc",          919,    R8A779F0_CLK_CL16M),
        DEF_MOD("ufs",          1514,   R8A779F0_CLK_S0D4_HSC),
index 3fc4233..9641122 100644 (file)
@@ -150,10 +150,24 @@ static const struct cpg_core_clk r8a779g0_core_clks[] __initconst = {
 };
 
 static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = {
+       DEF_MOD("avb0",         211,    R8A779G0_CLK_S0D4_HSC),
+       DEF_MOD("avb1",         212,    R8A779G0_CLK_S0D4_HSC),
+       DEF_MOD("avb2",         213,    R8A779G0_CLK_S0D4_HSC),
        DEF_MOD("hscif0",       514,    R8A779G0_CLK_S0D3_PER),
        DEF_MOD("hscif1",       515,    R8A779G0_CLK_S0D3_PER),
        DEF_MOD("hscif2",       516,    R8A779G0_CLK_S0D3_PER),
        DEF_MOD("hscif3",       517,    R8A779G0_CLK_S0D3_PER),
+       DEF_MOD("i2c0",         518,    R8A779G0_CLK_S0D6_PER),
+       DEF_MOD("i2c1",         519,    R8A779G0_CLK_S0D6_PER),
+       DEF_MOD("i2c2",         520,    R8A779G0_CLK_S0D6_PER),
+       DEF_MOD("i2c3",         521,    R8A779G0_CLK_S0D6_PER),
+       DEF_MOD("i2c4",         522,    R8A779G0_CLK_S0D6_PER),
+       DEF_MOD("i2c5",         523,    R8A779G0_CLK_S0D6_PER),
+       DEF_MOD("wdt1:wdt0",    907,    R8A779G0_CLK_R),
+       DEF_MOD("pfc0",         915,    R8A779G0_CLK_CL16M),
+       DEF_MOD("pfc1",         916,    R8A779G0_CLK_CL16M),
+       DEF_MOD("pfc2",         917,    R8A779G0_CLK_CL16M),
+       DEF_MOD("pfc3",         918,    R8A779G0_CLK_CL16M),
 };
 
 /*
index fd7c4ee..02a4fc4 100644 (file)
@@ -414,6 +414,7 @@ static const unsigned int r9a07g044_crit_mod_clks[] __initconst = {
        MOD_CLK_BASE + R9A07G044_DMAC_ACLK,
 };
 
+#ifdef CONFIG_CLK_R9A07G044
 const struct rzg2l_cpg_info r9a07g044_cpg_info = {
        /* Core Clocks */
        .core_clks = core_clks.common,
@@ -436,6 +437,7 @@ const struct rzg2l_cpg_info r9a07g044_cpg_info = {
 
        .has_clk_mon_regs = true,
 };
+#endif
 
 #ifdef CONFIG_CLK_R9A07G054
 const struct rzg2l_cpg_info r9a07g054_cpg_info = {
index b21915c..fbef1b3 100644 (file)
@@ -132,6 +132,8 @@ static const struct rzg2l_mod_clk r9a09g011_mod_clks[] __initconst = {
        DEF_COUPLED("eth_chi",  R9A09G011_ETH0_CLK_CHI,  CLK_PLL2_100, 0x40c, 8),
        DEF_MOD("eth_clk_gptp", R9A09G011_ETH0_GPTP_EXT, CLK_PLL2_100, 0x40c, 9),
        DEF_MOD("syc_cnt_clk",  R9A09G011_SYC_CNT_CLK,   CLK_MAIN_24,  0x41c, 12),
+       DEF_MOD("iic_pclk0",    R9A09G011_IIC_PCLK0,     CLK_SEL_E,    0x420, 12),
+       DEF_MOD("iic_pclk1",    R9A09G011_IIC_PCLK1,     CLK_SEL_E,    0x424, 12),
        DEF_MOD("wdt0_pclk",    R9A09G011_WDT0_PCLK,     CLK_SEL_E,    0x428, 12),
        DEF_MOD("wdt0_clk",     R9A09G011_WDT0_CLK,      CLK_MAIN,     0x428, 13),
        DEF_MOD("urt_pclk",     R9A09G011_URT_PCLK,      CLK_SEL_E,    0x438, 4),
@@ -143,6 +145,8 @@ static const struct rzg2l_reset r9a09g011_resets[] = {
        DEF_RST(R9A09G011_PFC_PRESETN,          0x600, 2),
        DEF_RST_MON(R9A09G011_ETH0_RST_HW_N,    0x608, 11, 11),
        DEF_RST_MON(R9A09G011_SYC_RST_N,        0x610, 9,  13),
+       DEF_RST(R9A09G011_IIC_GPA_PRESETN,      0x614, 8),
+       DEF_RST(R9A09G011_IIC_GPB_PRESETN,      0x614, 9),
        DEF_RST_MON(R9A09G011_WDT0_PRESETN,     0x614, 12, 19),
 };
 
index 3067bdb..345a5d2 100644 (file)
@@ -23,6 +23,13 @@ config CLK_RV110X
        help
          Build the driver for RV110x Clock Driver.
 
+config CLK_RV1126
+       bool "Rockchip RV1126 clock controller support"
+       depends on ARM || COMPILE_TEST
+       default y
+       help
+         Build the driver for RV1126 Clock Driver.
+
 config CLK_RK3036
        bool "Rockchip RK3036 clock controller support"
        depends on ARM || COMPILE_TEST
index 2b78f12..e854387 100644 (file)
@@ -17,6 +17,7 @@ clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
 
 obj-$(CONFIG_CLK_PX30)          += clk-px30.o
 obj-$(CONFIG_CLK_RV110X)        += clk-rv1108.o
+obj-$(CONFIG_CLK_RV1126)        += clk-rv1126.o
 obj-$(CONFIG_CLK_RK3036)        += clk-rk3036.o
 obj-$(CONFIG_CLK_RK312X)        += clk-rk3128.o
 obj-$(CONFIG_CLK_RK3188)        += clk-rk3188.o
diff --git a/drivers/clk/rockchip/clk-rv1126.c b/drivers/clk/rockchip/clk-rv1126.c
new file mode 100644 (file)
index 0000000..c18790f
--- /dev/null
@@ -0,0 +1,1138 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Rockchip Electronics Co. Ltd.
+ * Author: Finley Xiao <finley.xiao@rock-chips.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/rockchip,rv1126-cru.h>
+#include "clk.h"
+
+#define RV1126_GMAC_CON                        0x460
+#define RV1126_GRF_IOFUNC_CON1         0x10264
+#define RV1126_GRF_SOC_STATUS0         0x10
+
+#define RV1126_FRAC_MAX_PRATE          1200000000
+#define RV1126_CSIOUT_FRAC_MAX_PRATE   300000000
+
+enum rv1126_pmu_plls {
+       gpll,
+};
+
+enum rv1126_plls {
+       apll, dpll, cpll, hpll,
+};
+
+static struct rockchip_pll_rate_table rv1126_pll_rates[] = {
+       /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+       RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1584000000, 1, 132, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1560000000, 1, 130, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1536000000, 1, 128, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1512000000, 1, 126, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1488000000, 1, 124, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1464000000, 1, 122, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1440000000, 1, 120, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1400000000, 3, 350, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1392000000, 1, 116, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1368000000, 1, 114, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1344000000, 1, 112, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1320000000, 1, 110, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1272000000, 1, 106, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1248000000, 1, 104, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1100000000, 3, 275, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
+       RK3036_PLL_RATE(984000000, 1, 82, 2, 1, 1, 0),
+       RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0),
+       RK3036_PLL_RATE(936000000, 1, 78, 2, 1, 1, 0),
+       RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
+       RK3036_PLL_RATE(900000000, 1, 75, 2, 1, 1, 0),
+       RK3036_PLL_RATE(888000000, 1, 74, 2, 1, 1, 0),
+       RK3036_PLL_RATE(864000000, 1, 72, 2, 1, 1, 0),
+       RK3036_PLL_RATE(840000000, 1, 70, 2, 1, 1, 0),
+       RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+       RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0),
+       RK3036_PLL_RATE(700000000, 3, 350, 4, 1, 1, 0),
+       RK3036_PLL_RATE(696000000, 1, 116, 4, 1, 1, 0),
+       RK3036_PLL_RATE(624000000, 1, 104, 4, 1, 1, 0),
+       RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
+       RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
+       RK3036_PLL_RATE(504000000, 1, 84, 4, 1, 1, 0),
+       RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
+       RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
+       RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
+       RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
+       RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0),
+       { /* sentinel */ },
+};
+
+#define RV1126_DIV_ACLK_CORE_MASK      0xf
+#define RV1126_DIV_ACLK_CORE_SHIFT     4
+#define RV1126_DIV_PCLK_DBG_MASK       0x7
+#define RV1126_DIV_PCLK_DBG_SHIFT      0
+
+#define RV1126_CLKSEL1(_aclk_core, _pclk_dbg)                          \
+{                                                                      \
+       .reg = RV1126_CLKSEL_CON(1),                                    \
+       .val = HIWORD_UPDATE(_aclk_core, RV1126_DIV_ACLK_CORE_MASK,     \
+                            RV1126_DIV_ACLK_CORE_SHIFT) |              \
+              HIWORD_UPDATE(_pclk_dbg, RV1126_DIV_PCLK_DBG_MASK,       \
+                            RV1126_DIV_PCLK_DBG_SHIFT),                \
+}
+
+#define RV1126_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg)              \
+{                                                                      \
+       .prate = _prate,                                                \
+       .divs = {                                                       \
+               RV1126_CLKSEL1(_aclk_core, _pclk_dbg),                  \
+       },                                                              \
+}
+
+static struct rockchip_cpuclk_rate_table rv1126_cpuclk_rates[] __initdata = {
+       RV1126_CPUCLK_RATE(1608000000, 1, 7),
+       RV1126_CPUCLK_RATE(1584000000, 1, 7),
+       RV1126_CPUCLK_RATE(1560000000, 1, 7),
+       RV1126_CPUCLK_RATE(1536000000, 1, 7),
+       RV1126_CPUCLK_RATE(1512000000, 1, 7),
+       RV1126_CPUCLK_RATE(1488000000, 1, 5),
+       RV1126_CPUCLK_RATE(1464000000, 1, 5),
+       RV1126_CPUCLK_RATE(1440000000, 1, 5),
+       RV1126_CPUCLK_RATE(1416000000, 1, 5),
+       RV1126_CPUCLK_RATE(1392000000, 1, 5),
+       RV1126_CPUCLK_RATE(1368000000, 1, 5),
+       RV1126_CPUCLK_RATE(1344000000, 1, 5),
+       RV1126_CPUCLK_RATE(1320000000, 1, 5),
+       RV1126_CPUCLK_RATE(1296000000, 1, 5),
+       RV1126_CPUCLK_RATE(1272000000, 1, 5),
+       RV1126_CPUCLK_RATE(1248000000, 1, 5),
+       RV1126_CPUCLK_RATE(1224000000, 1, 5),
+       RV1126_CPUCLK_RATE(1200000000, 1, 5),
+       RV1126_CPUCLK_RATE(1104000000, 1, 5),
+       RV1126_CPUCLK_RATE(1008000000, 1, 5),
+       RV1126_CPUCLK_RATE(912000000, 1, 5),
+       RV1126_CPUCLK_RATE(816000000, 1, 3),
+       RV1126_CPUCLK_RATE(696000000, 1, 3),
+       RV1126_CPUCLK_RATE(600000000, 1, 3),
+       RV1126_CPUCLK_RATE(408000000, 1, 1),
+       RV1126_CPUCLK_RATE(312000000, 1, 1),
+       RV1126_CPUCLK_RATE(216000000,  1, 1),
+       RV1126_CPUCLK_RATE(96000000, 1, 1),
+};
+
+static const struct rockchip_cpuclk_reg_data rv1126_cpuclk_data = {
+       .core_reg[0] = RV1126_CLKSEL_CON(0),
+       .div_core_shift[0] = 0,
+       .div_core_mask[0] = 0x1f,
+       .num_cores = 1,
+       .mux_core_alt = 0,
+       .mux_core_main = 2,
+       .mux_core_shift = 6,
+       .mux_core_mask = 0x3,
+};
+
+PNAME(mux_pll_p)                       = { "xin24m" };
+PNAME(mux_rtc32k_p)                    = { "clk_pmupvtm_divout", "xin32k", "clk_osc0_div32k" };
+PNAME(mux_wifi_p)                      = { "clk_wifi_osc0", "clk_wifi_div" };
+PNAME(mux_gpll_usb480m_cpll_xin24m_p)  = { "gpll", "usb480m", "cpll", "xin24m" };
+PNAME(mux_uart1_p)                     = { "sclk_uart1_div", "sclk_uart1_fracdiv", "xin24m" };
+PNAME(mux_xin24m_gpll_p)               = { "xin24m", "gpll" };
+PNAME(mux_gpll_xin24m_p)               = { "gpll", "xin24m" };
+PNAME(mux_xin24m_32k_p)                        = { "xin24m", "clk_rtc32k" };
+PNAME(mux_usbphy_otg_ref_p)            = { "clk_ref12m", "xin_osc0_div2_usbphyref_otg" };
+PNAME(mux_usbphy_host_ref_p)           = { "clk_ref12m", "xin_osc0_div2_usbphyref_host" };
+PNAME(mux_mipidsiphy_ref_p)            = { "clk_ref24m", "xin_osc0_mipiphyref" };
+PNAME(mux_usb480m_p)                   = { "xin24m", "usb480m_phy", "clk_rtc32k" };
+PNAME(mux_armclk_p)                    = { "gpll", "cpll", "apll" };
+PNAME(mux_gpll_cpll_dpll_p)            = { "gpll", "cpll", "dummy_dpll" };
+PNAME(mux_gpll_cpll_p)                 = { "gpll", "cpll" };
+PNAME(mux_hclk_pclk_pdbus_p)           = { "gpll", "dummy_cpll" };
+PNAME(mux_gpll_cpll_usb480m_xin24m_p)  = { "gpll", "cpll", "usb480m", "xin24m" };
+PNAME(mux_uart0_p)                     = { "sclk_uart0_div", "sclk_uart0_frac", "xin24m" };
+PNAME(mux_uart2_p)                     = { "sclk_uart2_div", "sclk_uart2_frac", "xin24m" };
+PNAME(mux_uart3_p)                     = { "sclk_uart3_div", "sclk_uart3_frac", "xin24m" };
+PNAME(mux_uart4_p)                     = { "sclk_uart4_div", "sclk_uart4_frac", "xin24m" };
+PNAME(mux_uart5_p)                     = { "sclk_uart5_div", "sclk_uart5_frac", "xin24m" };
+PNAME(mux_cpll_gpll_p)                 = { "cpll", "gpll" };
+PNAME(mux_i2s0_tx_p)                   = { "mclk_i2s0_tx_div", "mclk_i2s0_tx_fracdiv", "i2s0_mclkin", "xin12m" };
+PNAME(mux_i2s0_rx_p)                   = { "mclk_i2s0_rx_div", "mclk_i2s0_rx_fracdiv", "i2s0_mclkin", "xin12m" };
+PNAME(mux_i2s0_tx_out2io_p)            = { "mclk_i2s0_tx", "xin12m" };
+PNAME(mux_i2s0_rx_out2io_p)            = { "mclk_i2s0_rx", "xin12m" };
+PNAME(mux_i2s1_p)                      = { "mclk_i2s1_div", "mclk_i2s1_fracdiv", "i2s1_mclkin", "xin12m" };
+PNAME(mux_i2s1_out2io_p)               = { "mclk_i2s1", "xin12m" };
+PNAME(mux_i2s2_p)                      = { "mclk_i2s2_div", "mclk_i2s2_fracdiv", "i2s2_mclkin", "xin12m" };
+PNAME(mux_i2s2_out2io_p)               = { "mclk_i2s2", "xin12m" };
+PNAME(mux_gpll_cpll_xin24m_p)          = { "gpll", "cpll", "xin24m" };
+PNAME(mux_audpwm_p)                    = { "sclk_audpwm_div", "sclk_audpwm_fracdiv", "xin24m" };
+PNAME(mux_usb480m_gpll_p)              = { "usb480m", "gpll" };
+PNAME(clk_gmac_src_m0_p)               = { "clk_gmac_div", "clk_gmac_rgmii_m0" };
+PNAME(clk_gmac_src_m1_p)               = { "clk_gmac_div", "clk_gmac_rgmii_m1" };
+PNAME(mux_clk_gmac_src_p)              = { "clk_gmac_src_m0", "clk_gmac_src_m1" };
+PNAME(mux_rgmii_clk_p)                 = { "clk_gmac_tx_div50", "clk_gmac_tx_div5", "clk_gmac_tx_src", "clk_gmac_tx_src"};
+PNAME(mux_rmii_clk_p)                  = { "clk_gmac_rx_div20", "clk_gmac_rx_div2" };
+PNAME(mux_gmac_tx_rx_p)                        = { "rgmii_mode_clk", "rmii_mode_clk" };
+PNAME(mux_dpll_gpll_p)                 = { "dpll", "gpll" };
+
+static u32 rgmii_mux_idx[]             = { 2, 3, 0, 1 };
+
+static struct rockchip_pll_clock rv1126_pmu_pll_clks[] __initdata = {
+       [gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll",  mux_pll_p,
+                    0, RV1126_PMU_PLL_CON(0),
+                    RV1126_PMU_MODE, 0, 3, 0, rv1126_pll_rates),
+};
+
+static struct rockchip_pll_clock rv1126_pll_clks[] __initdata = {
+       [apll] = PLL(pll_rk3328, PLL_APLL, "apll", mux_pll_p,
+                    0, RV1126_PLL_CON(0),
+                    RV1126_MODE_CON, 0, 0, 0, rv1126_pll_rates),
+       [dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p,
+                    0, RV1126_PLL_CON(8),
+                    RV1126_MODE_CON, 2, 1, 0, NULL),
+       [cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p,
+                    0, RV1126_PLL_CON(16),
+                    RV1126_MODE_CON, 4, 2, 0, rv1126_pll_rates),
+       [hpll] = PLL(pll_rk3328, PLL_HPLL, "hpll", mux_pll_p,
+                    0, RV1126_PLL_CON(24),
+                    RV1126_MODE_CON, 6, 4, 0, rv1126_pll_rates),
+};
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_clk_branch rv1126_rtc32k_fracmux __initdata =
+       MUX(CLK_RTC32K, "clk_rtc32k", mux_rtc32k_p, CLK_SET_RATE_PARENT,
+                       RV1126_PMU_CLKSEL_CON(0), 7, 2, MFLAGS);
+
+static struct rockchip_clk_branch rv1126_uart1_fracmux __initdata =
+       MUX(SCLK_UART1_MUX, "sclk_uart1_mux", mux_uart1_p, CLK_SET_RATE_PARENT,
+                       RV1126_PMU_CLKSEL_CON(4), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch rv1126_uart0_fracmux __initdata =
+       MUX(SCLK_UART0_MUX, "sclk_uart0_mux", mux_uart0_p, CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(10), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch rv1126_uart2_fracmux __initdata =
+       MUX(SCLK_UART2_MUX, "sclk_uart2_mux", mux_uart2_p, CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(12), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch rv1126_uart3_fracmux __initdata =
+       MUX(SCLK_UART3_MUX, "sclk_uart3_mux", mux_uart3_p, CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(14), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch rv1126_uart4_fracmux __initdata =
+       MUX(SCLK_UART4_MUX, "sclk_uart4_mux", mux_uart4_p, CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(16), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch rv1126_uart5_fracmux __initdata =
+       MUX(SCLK_UART5_MUX, "sclk_uart5_mux", mux_uart5_p, CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(18), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch rv1126_i2s0_tx_fracmux __initdata =
+       MUX(MCLK_I2S0_TX_MUX, "mclk_i2s0_tx_mux", mux_i2s0_tx_p, CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(30), 0, 2, MFLAGS);
+
+static struct rockchip_clk_branch rv1126_i2s0_rx_fracmux __initdata =
+       MUX(MCLK_I2S0_RX_MUX, "mclk_i2s0_rx_mux", mux_i2s0_rx_p, CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(30), 2, 2, MFLAGS);
+
+static struct rockchip_clk_branch rv1126_i2s1_fracmux __initdata =
+       MUX(MCLK_I2S1_MUX, "mclk_i2s1_mux", mux_i2s1_p, CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(31), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rv1126_i2s2_fracmux __initdata =
+       MUX(MCLK_I2S2_MUX, "mclk_i2s2_mux", mux_i2s2_p, CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(33), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rv1126_audpwm_fracmux __initdata =
+       MUX(SCLK_AUDPWM_MUX, "mclk_audpwm_mux", mux_audpwm_p, CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(36), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rv1126_clk_pmu_branches[] __initdata = {
+       /*
+        * Clock-Architecture Diagram 2
+        */
+       /* PD_PMU */
+       COMPOSITE_NOMUX(PCLK_PDPMU, "pclk_pdpmu", "gpll", CLK_IGNORE_UNUSED,
+                       RV1126_PMU_CLKSEL_CON(1), 0, 5, DFLAGS,
+                       RV1126_PMU_CLKGATE_CON(0), 0, GFLAGS),
+
+       COMPOSITE_FRACMUX(CLK_OSC0_DIV32K, "clk_osc0_div32k", "xin24m", CLK_IGNORE_UNUSED,
+                       RV1126_PMU_CLKSEL_CON(13), 0,
+                       RV1126_PMU_CLKGATE_CON(2), 9, GFLAGS,
+                       &rv1126_rtc32k_fracmux),
+
+       COMPOSITE_NOMUX(CLK_WIFI_DIV, "clk_wifi_div", "gpll", 0,
+                       RV1126_PMU_CLKSEL_CON(12), 0, 6, DFLAGS,
+                       RV1126_PMU_CLKGATE_CON(2), 10, GFLAGS),
+       GATE(CLK_WIFI_OSC0, "clk_wifi_osc0", "xin24m", 0,
+                       RV1126_PMU_CLKGATE_CON(2), 11, GFLAGS),
+       MUX(CLK_WIFI, "clk_wifi", mux_wifi_p, CLK_SET_RATE_PARENT,
+                       RV1126_PMU_CLKSEL_CON(12), 8, 1, MFLAGS),
+
+       GATE(PCLK_PMU, "pclk_pmu", "pclk_pdpmu", CLK_IGNORE_UNUSED,
+                       RV1126_PMU_CLKGATE_CON(0), 1, GFLAGS),
+
+       GATE(PCLK_UART1, "pclk_uart1", "pclk_pdpmu", 0,
+                       RV1126_PMU_CLKGATE_CON(0), 11, GFLAGS),
+       COMPOSITE(SCLK_UART1_DIV, "sclk_uart1_div", mux_gpll_usb480m_cpll_xin24m_p, 0,
+                       RV1126_PMU_CLKSEL_CON(4), 8, 2, MFLAGS, 0, 7, DFLAGS,
+                       RV1126_PMU_CLKGATE_CON(0), 12, GFLAGS),
+       COMPOSITE_FRACMUX(SCLK_UART1_FRACDIV, "sclk_uart1_fracdiv", "sclk_uart1_div",
+                       CLK_SET_RATE_PARENT,
+                       RV1126_PMU_CLKSEL_CON(5), 0,
+                       RV1126_PMU_CLKGATE_CON(0), 13, GFLAGS,
+                       &rv1126_uart1_fracmux),
+       GATE(SCLK_UART1, "sclk_uart1", "sclk_uart1_mux", 0,
+                       RV1126_PMU_CLKGATE_CON(0), 14, GFLAGS),
+
+       GATE(PCLK_I2C0, "pclk_i2c0", "pclk_pdpmu", 0,
+                       RV1126_PMU_CLKGATE_CON(0), 5, GFLAGS),
+       COMPOSITE_NOMUX(CLK_I2C0, "clk_i2c0", "gpll", 0,
+                       RV1126_PMU_CLKSEL_CON(2), 0, 7, DFLAGS,
+                       RV1126_PMU_CLKGATE_CON(0), 6, GFLAGS),
+       GATE(PCLK_I2C2, "pclk_i2c2", "pclk_pdpmu", 0,
+                       RV1126_PMU_CLKGATE_CON(0), 9, GFLAGS),
+       COMPOSITE_NOMUX(CLK_I2C2, "clk_i2c2", "gpll", 0,
+                       RV1126_PMU_CLKSEL_CON(3), 0, 7, DFLAGS,
+                       RV1126_PMU_CLKGATE_CON(0), 10, GFLAGS),
+
+       GATE(CLK_CAPTURE_PWM0, "clk_capture_pwm0", "xin24m", 0,
+                       RV1126_PMU_CLKGATE_CON(1), 2, GFLAGS),
+       GATE(PCLK_PWM0, "pclk_pwm0", "pclk_pdpmu", 0,
+                       RV1126_PMU_CLKGATE_CON(1), 0, GFLAGS),
+       COMPOSITE(CLK_PWM0, "clk_pwm0", mux_xin24m_gpll_p, 0,
+                       RV1126_PMU_CLKSEL_CON(6), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RV1126_PMU_CLKGATE_CON(1), 1, GFLAGS),
+       GATE(CLK_CAPTURE_PWM1, "clk_capture_pwm1", "xin24m", 0,
+                       RV1126_PMU_CLKGATE_CON(1), 5, GFLAGS),
+       GATE(PCLK_PWM1, "pclk_pwm1", "pclk_pdpmu", 0,
+                       RV1126_PMU_CLKGATE_CON(1), 3, GFLAGS),
+       COMPOSITE(CLK_PWM1, "clk_pwm1", mux_xin24m_gpll_p, 0,
+                       RV1126_PMU_CLKSEL_CON(6), 15, 1, MFLAGS, 8, 7, DFLAGS,
+                       RV1126_PMU_CLKGATE_CON(1), 4, GFLAGS),
+
+       GATE(PCLK_SPI0, "pclk_spi0", "pclk_pdpmu", 0,
+                       RV1126_PMU_CLKGATE_CON(1), 11, GFLAGS),
+       COMPOSITE(CLK_SPI0, "clk_spi0", mux_gpll_xin24m_p, 0,
+                       RV1126_PMU_CLKSEL_CON(9), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RV1126_PMU_CLKGATE_CON(1), 12, GFLAGS),
+
+       GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pdpmu", 0,
+                       RV1126_PMU_CLKGATE_CON(1), 9, GFLAGS),
+       COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", mux_xin24m_32k_p, 0,
+                       RV1126_PMU_CLKSEL_CON(8), 15, 1, MFLAGS,
+                       RV1126_PMU_CLKGATE_CON(1), 10, GFLAGS),
+
+       GATE(PCLK_PMUPVTM, "pclk_pmupvtm", "pclk_pdpmu", 0,
+                       RV1126_PMU_CLKGATE_CON(2), 6, GFLAGS),
+       GATE(CLK_PMUPVTM, "clk_pmupvtm", "xin24m", 0,
+                       RV1126_PMU_CLKGATE_CON(2), 5, GFLAGS),
+       GATE(CLK_CORE_PMUPVTM, "clk_core_pmupvtm", "xin24m", 0,
+                       RV1126_PMU_CLKGATE_CON(2), 7, GFLAGS),
+
+       COMPOSITE_NOMUX(CLK_REF12M, "clk_ref12m", "gpll", 0,
+                       RV1126_PMU_CLKSEL_CON(7), 8, 7, DFLAGS,
+                       RV1126_PMU_CLKGATE_CON(1), 15, GFLAGS),
+       GATE(0, "xin_osc0_usbphyref_otg", "xin24m", 0,
+                       RV1126_PMU_CLKGATE_CON(1), 6, GFLAGS),
+       GATE(0, "xin_osc0_usbphyref_host", "xin24m", 0,
+                       RV1126_PMU_CLKGATE_CON(1), 7, GFLAGS),
+       FACTOR(0, "xin_osc0_div2_usbphyref_otg", "xin_osc0_usbphyref_otg", 0, 1, 2),
+       FACTOR(0, "xin_osc0_div2_usbphyref_host", "xin_osc0_usbphyref_host", 0, 1, 2),
+       MUX(CLK_USBPHY_OTG_REF, "clk_usbphy_otg_ref", mux_usbphy_otg_ref_p, CLK_SET_RATE_PARENT,
+                       RV1126_PMU_CLKSEL_CON(7), 6, 1, MFLAGS),
+       MUX(CLK_USBPHY_HOST_REF, "clk_usbphy_host_ref", mux_usbphy_host_ref_p, CLK_SET_RATE_PARENT,
+                       RV1126_PMU_CLKSEL_CON(7), 7, 1, MFLAGS),
+
+       COMPOSITE_NOMUX(CLK_REF24M, "clk_ref24m", "gpll", 0,
+                       RV1126_PMU_CLKSEL_CON(7), 0, 6, DFLAGS,
+                       RV1126_PMU_CLKGATE_CON(1), 14, GFLAGS),
+       GATE(0, "xin_osc0_mipiphyref", "xin24m", 0,
+                       RV1126_PMU_CLKGATE_CON(1), 8, GFLAGS),
+       MUX(CLK_MIPIDSIPHY_REF, "clk_mipidsiphy_ref", mux_mipidsiphy_ref_p, CLK_SET_RATE_PARENT,
+                       RV1126_PMU_CLKSEL_CON(7), 15, 1, MFLAGS),
+
+       GATE(CLK_PMU, "clk_pmu", "xin24m", CLK_IGNORE_UNUSED,
+                       RV1126_PMU_CLKGATE_CON(0), 15, GFLAGS),
+
+       GATE(PCLK_PMUSGRF, "pclk_pmusgrf", "pclk_pdpmu", CLK_IGNORE_UNUSED,
+                       RV1126_PMU_CLKGATE_CON(0), 4, GFLAGS),
+       GATE(PCLK_PMUGRF, "pclk_pmugrf", "pclk_pdpmu", CLK_IGNORE_UNUSED,
+                       RV1126_PMU_CLKGATE_CON(1), 13, GFLAGS),
+       GATE(PCLK_PMUCRU, "pclk_pmucru", "pclk_pdpmu", CLK_IGNORE_UNUSED,
+                       RV1126_PMU_CLKGATE_CON(2), 4, GFLAGS),
+       GATE(PCLK_CHIPVEROTP, "pclk_chipverotp", "pclk_pdpmu", CLK_IGNORE_UNUSED,
+                       RV1126_PMU_CLKGATE_CON(2), 0, GFLAGS),
+       GATE(PCLK_PDPMU_NIU, "pclk_pdpmu_niu", "pclk_pdpmu", CLK_IGNORE_UNUSED,
+                       RV1126_PMU_CLKGATE_CON(0), 2, GFLAGS),
+
+       GATE(PCLK_SCRKEYGEN, "pclk_scrkeygen", "pclk_pdpmu", 0,
+                       RV1126_PMU_CLKGATE_CON(0), 7, GFLAGS),
+};
+
+static struct rockchip_clk_branch rv1126_clk_branches[] __initdata = {
+       /*
+        * Clock-Architecture Diagram 1
+        */
+       MUX(USB480M, "usb480m", mux_usb480m_p, CLK_SET_RATE_PARENT,
+                       RV1126_MODE_CON, 10, 2, MFLAGS),
+       FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
+
+       /*
+        * Clock-Architecture Diagram 3
+        */
+       /* PD_CORE */
+       COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED,
+                       RV1126_CLKSEL_CON(1), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
+                       RV1126_CLKGATE_CON(0), 6, GFLAGS),
+       GATE(CLK_CORE_CPUPVTM, "clk_core_cpupvtm", "armclk", 0,
+                       RV1126_CLKGATE_CON(0), 12, GFLAGS),
+       GATE(PCLK_CPUPVTM, "pclk_cpupvtm", "pclk_dbg", 0,
+                       RV1126_CLKGATE_CON(0), 10, GFLAGS),
+       GATE(CLK_CPUPVTM, "clk_cpupvtm", "xin24m", 0,
+                       RV1126_CLKGATE_CON(0), 11, GFLAGS),
+       COMPOSITE_NOMUX(HCLK_PDCORE_NIU, "hclk_pdcore_niu", "gpll", CLK_IGNORE_UNUSED,
+                       RV1126_CLKSEL_CON(0), 8, 5, DFLAGS,
+                       RV1126_CLKGATE_CON(0), 8, GFLAGS),
+
+       /*
+        * Clock-Architecture Diagram 4
+        */
+       /* PD_BUS */
+       COMPOSITE(0, "aclk_pdbus_pre", mux_gpll_cpll_dpll_p, CLK_IGNORE_UNUSED,
+                       RV1126_CLKSEL_CON(2), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RV1126_CLKGATE_CON(2), 0, GFLAGS),
+       GATE(ACLK_PDBUS, "aclk_pdbus", "aclk_pdbus_pre", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(2), 11, GFLAGS),
+       COMPOSITE(0, "hclk_pdbus_pre", mux_hclk_pclk_pdbus_p, CLK_IGNORE_UNUSED,
+                       RV1126_CLKSEL_CON(2), 15, 1, MFLAGS, 8, 5, DFLAGS,
+                       RV1126_CLKGATE_CON(2), 1, GFLAGS),
+       GATE(HCLK_PDBUS, "hclk_pdbus", "hclk_pdbus_pre", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(2), 12, GFLAGS),
+       COMPOSITE(0, "pclk_pdbus_pre", mux_hclk_pclk_pdbus_p, CLK_IGNORE_UNUSED,
+                       RV1126_CLKSEL_CON(3), 7, 1, MFLAGS, 0, 5, DFLAGS,
+                       RV1126_CLKGATE_CON(2), 2, GFLAGS),
+       GATE(PCLK_PDBUS, "pclk_pdbus", "pclk_pdbus_pre", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(2), 13, GFLAGS),
+       /* aclk_dmac is controlled by sgrf_clkgat_con. */
+       SGRF_GATE(ACLK_DMAC, "aclk_dmac", "hclk_pdbus"),
+       GATE(ACLK_DCF, "aclk_dcf", "hclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(3), 6, GFLAGS),
+       GATE(PCLK_DCF, "pclk_dcf", "pclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(3), 7, GFLAGS),
+       GATE(PCLK_WDT, "pclk_wdt", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(6), 14, GFLAGS),
+       GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(7), 10, GFLAGS),
+
+       COMPOSITE(CLK_SCR1, "clk_scr1", mux_gpll_cpll_p, 0,
+                       RV1126_CLKSEL_CON(3), 15, 1, MFLAGS, 8, 5, DFLAGS,
+                       RV1126_CLKGATE_CON(4), 7, GFLAGS),
+       GATE(0, "clk_scr1_niu", "clk_scr1", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(2), 14, GFLAGS),
+       GATE(CLK_SCR1_CORE, "clk_scr1_core", "clk_scr1", 0,
+                       RV1126_CLKGATE_CON(4), 8, GFLAGS),
+       GATE(CLK_SCR1_RTC, "clk_scr1_rtc", "xin24m", 0,
+                       RV1126_CLKGATE_CON(4), 9, GFLAGS),
+       GATE(CLK_SCR1_JTAG, "clk_scr1_jtag", "clk_scr1_jtag_io", 0,
+                       RV1126_CLKGATE_CON(4), 10, GFLAGS),
+
+       GATE(PCLK_UART0, "pclk_uart0", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(5), 0, GFLAGS),
+       COMPOSITE(SCLK_UART0_DIV, "sclk_uart0_div", mux_gpll_cpll_usb480m_xin24m_p, 0,
+                       RV1126_CLKSEL_CON(10), 8, 2, MFLAGS, 0, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(5), 1, GFLAGS),
+       COMPOSITE_FRACMUX(SCLK_UART0_FRAC, "sclk_uart0_frac", "sclk_uart0_div", CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(11), 0,
+                       RV1126_CLKGATE_CON(5), 2, GFLAGS,
+                       &rv1126_uart0_fracmux),
+       GATE(SCLK_UART0, "sclk_uart0", "sclk_uart0_mux", 0,
+                       RV1126_CLKGATE_CON(5), 3, GFLAGS),
+       GATE(PCLK_UART2, "pclk_uart2", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(5), 4, GFLAGS),
+       COMPOSITE(SCLK_UART2_DIV, "sclk_uart2_div", mux_gpll_cpll_usb480m_xin24m_p, 0,
+                       RV1126_CLKSEL_CON(12), 8, 2, MFLAGS, 0, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(5), 5, GFLAGS),
+       COMPOSITE_FRACMUX(SCLK_UART2_FRAC, "sclk_uart2_frac", "sclk_uart2_div", CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(13), 0,
+                       RV1126_CLKGATE_CON(5), 6, GFLAGS,
+                       &rv1126_uart2_fracmux),
+       GATE(SCLK_UART2, "sclk_uart2", "sclk_uart2_mux", 0,
+                       RV1126_CLKGATE_CON(5), 7, GFLAGS),
+       GATE(PCLK_UART3, "pclk_uart3", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(5), 8, GFLAGS),
+       COMPOSITE(SCLK_UART3_DIV, "sclk_uart3_div", mux_gpll_cpll_usb480m_xin24m_p, 0,
+                       RV1126_CLKSEL_CON(14), 8, 2, MFLAGS, 0, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(5), 9, GFLAGS),
+       COMPOSITE_FRACMUX(SCLK_UART3_FRAC, "sclk_uart3_frac", "sclk_uart3_div", CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(15), 0,
+                       RV1126_CLKGATE_CON(5), 10, GFLAGS,
+                       &rv1126_uart3_fracmux),
+       GATE(SCLK_UART3, "sclk_uart3", "sclk_uart3_mux", 0,
+                       RV1126_CLKGATE_CON(5), 11, GFLAGS),
+       GATE(PCLK_UART4, "pclk_uart4", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(5), 12, GFLAGS),
+       COMPOSITE(SCLK_UART4_DIV, "sclk_uart4_div", mux_gpll_cpll_usb480m_xin24m_p, 0,
+                       RV1126_CLKSEL_CON(16), 8, 2, MFLAGS, 0, 7,
+                       DFLAGS, RV1126_CLKGATE_CON(5), 13, GFLAGS),
+       COMPOSITE_FRACMUX(SCLK_UART4_FRAC, "sclk_uart4_frac", "sclk_uart4_div", CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(17), 0,
+                       RV1126_CLKGATE_CON(5), 14, GFLAGS,
+                       &rv1126_uart4_fracmux),
+       GATE(SCLK_UART4, "sclk_uart4", "sclk_uart4_mux", 0,
+                       RV1126_CLKGATE_CON(5), 15, GFLAGS),
+       GATE(PCLK_UART5, "pclk_uart5", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(6), 0, GFLAGS),
+       COMPOSITE(SCLK_UART5_DIV, "sclk_uart5_div", mux_gpll_cpll_usb480m_xin24m_p, 0,
+                       RV1126_CLKSEL_CON(18), 8, 2, MFLAGS, 0, 7,
+                       DFLAGS, RV1126_CLKGATE_CON(6), 1, GFLAGS),
+       COMPOSITE_FRACMUX(SCLK_UART5_FRAC, "sclk_uart5_frac", "sclk_uart5_div", CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(19), 0,
+                       RV1126_CLKGATE_CON(6), 2, GFLAGS,
+                       &rv1126_uart5_fracmux),
+       GATE(SCLK_UART5, "sclk_uart5", "sclk_uart5_mux", 0,
+                       RV1126_CLKGATE_CON(6), 3, GFLAGS),
+
+       GATE(PCLK_I2C1, "pclk_i2c1", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(3), 10, GFLAGS),
+       COMPOSITE_NOMUX(CLK_I2C1, "clk_i2c1", "gpll", 0,
+                       RV1126_CLKSEL_CON(5), 0, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(3), 11, GFLAGS),
+       GATE(PCLK_I2C3, "pclk_i2c3", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(3), 12, GFLAGS),
+       COMPOSITE_NOMUX(CLK_I2C3, "clk_i2c3", "gpll", 0,
+                       RV1126_CLKSEL_CON(5), 8, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(3), 13, GFLAGS),
+       GATE(PCLK_I2C4, "pclk_i2c4", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(3), 14, GFLAGS),
+       COMPOSITE_NOMUX(CLK_I2C4, "clk_i2c4", "gpll", 0,
+                       RV1126_CLKSEL_CON(6), 0, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(3), 15, GFLAGS),
+       GATE(PCLK_I2C5, "pclk_i2c5", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(4), 0, GFLAGS),
+       COMPOSITE_NOMUX(CLK_I2C5, "clk_i2c5", "gpll", 0,
+                       RV1126_CLKSEL_CON(6), 8, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(4), 1, GFLAGS),
+
+       GATE(PCLK_SPI1, "pclk_spi1", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(4), 2, GFLAGS),
+       COMPOSITE(CLK_SPI1, "clk_spi1", mux_gpll_xin24m_p, 0,
+                       RV1126_CLKSEL_CON(8), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(4), 3, GFLAGS),
+
+       GATE(CLK_CAPTURE_PWM2, "clk_capture_pwm2", "xin24m", 0,
+                       RV1126_CLKGATE_CON(4), 6, GFLAGS),
+       GATE(PCLK_PWM2, "pclk_pwm2", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(4), 4, GFLAGS),
+       COMPOSITE(CLK_PWM2, "clk_pwm2", mux_xin24m_gpll_p, 0,
+                       RV1126_CLKSEL_CON(9), 15, 1, MFLAGS, 8, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(4), 5, GFLAGS),
+
+       GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(7), 0, GFLAGS),
+       COMPOSITE_NODIV(DBCLK_GPIO1, "dbclk_gpio1", mux_xin24m_32k_p, 0,
+                       RV1126_CLKSEL_CON(21), 15, 1, MFLAGS,
+                       RV1126_CLKGATE_CON(7), 1, GFLAGS),
+       GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(7), 2, GFLAGS),
+       COMPOSITE_NODIV(DBCLK_GPIO2, "dbclk_gpio2", mux_xin24m_32k_p, 0,
+                       RV1126_CLKSEL_CON(22), 15, 1, MFLAGS,
+                       RV1126_CLKGATE_CON(7), 3, GFLAGS),
+       GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(7), 4, GFLAGS),
+       COMPOSITE_NODIV(DBCLK_GPIO3, "dbclk_gpio3", mux_xin24m_32k_p, 0,
+                       RV1126_CLKSEL_CON(23), 15, 1, MFLAGS,
+                       RV1126_CLKGATE_CON(7), 5, GFLAGS),
+       GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(7), 6, GFLAGS),
+       COMPOSITE_NODIV(DBCLK_GPIO4, "dbclk_gpio4", mux_xin24m_32k_p, 0,
+                       RV1126_CLKSEL_CON(24), 15, 1, MFLAGS,
+                       RV1126_CLKGATE_CON(7), 7, GFLAGS),
+
+       GATE(PCLK_SARADC, "pclk_saradc", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(6), 4, GFLAGS),
+       COMPOSITE_NOMUX(CLK_SARADC, "clk_saradc", "xin24m", 0,
+                       RV1126_CLKSEL_CON(20), 0, 11, DFLAGS,
+                       RV1126_CLKGATE_CON(6), 5, GFLAGS),
+
+       GATE(PCLK_TIMER, "pclk_timer", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(6), 7, GFLAGS),
+       GATE(CLK_TIMER0, "clk_timer0", "xin24m", 0,
+                       RV1126_CLKGATE_CON(6), 8, GFLAGS),
+       GATE(CLK_TIMER1, "clk_timer1", "xin24m", 0,
+                       RV1126_CLKGATE_CON(6), 9, GFLAGS),
+       GATE(CLK_TIMER2, "clk_timer2", "xin24m", 0,
+                       RV1126_CLKGATE_CON(6), 10, GFLAGS),
+       GATE(CLK_TIMER3, "clk_timer3", "xin24m", 0,
+                       RV1126_CLKGATE_CON(6), 11, GFLAGS),
+       GATE(CLK_TIMER4, "clk_timer4", "xin24m", 0,
+                       RV1126_CLKGATE_CON(6), 12, GFLAGS),
+       GATE(CLK_TIMER5, "clk_timer5", "xin24m", 0,
+                       RV1126_CLKGATE_CON(6), 13, GFLAGS),
+
+       GATE(ACLK_SPINLOCK, "aclk_spinlock", "hclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(6), 6, GFLAGS),
+
+       GATE(ACLK_DECOM, "aclk_decom", "aclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(7), 11, GFLAGS),
+       GATE(PCLK_DECOM, "pclk_decom", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(7), 12, GFLAGS),
+       COMPOSITE(DCLK_DECOM, "dclk_decom", mux_gpll_cpll_p, 0,
+                       RV1126_CLKSEL_CON(25), 15, 1, MFLAGS, 8, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(7), 13, GFLAGS),
+
+       GATE(PCLK_CAN, "pclk_can", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(7), 8, GFLAGS),
+       COMPOSITE(CLK_CAN, "clk_can", mux_gpll_xin24m_p, 0,
+                       RV1126_CLKSEL_CON(25), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(7), 9, GFLAGS),
+       /* pclk_otp and clk_otp are controlled by sgrf_clkgat_con. */
+       SGRF_GATE(CLK_OTP, "clk_otp", "xin24m"),
+       SGRF_GATE(PCLK_OTP, "pclk_otp", "pclk_pdbus"),
+
+       GATE(PCLK_NPU_TSADC, "pclk_npu_tsadc", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(24), 3, GFLAGS),
+       COMPOSITE_NOMUX(CLK_NPU_TSADC, "clk_npu_tsadc", "xin24m", 0,
+                       RV1126_CLKSEL_CON(71), 0, 11, DFLAGS,
+                       RV1126_CLKGATE_CON(24), 4, GFLAGS),
+       GATE(CLK_NPU_TSADCPHY, "clk_npu_tsadcphy", "clk_npu_tsadc", 0,
+                       RV1126_CLKGATE_CON(24), 5, GFLAGS),
+       GATE(PCLK_CPU_TSADC, "pclk_cpu_tsadc", "pclk_pdbus", 0,
+                       RV1126_CLKGATE_CON(24), 0, GFLAGS),
+       COMPOSITE_NOMUX(CLK_CPU_TSADC, "clk_cpu_tsadc", "xin24m", 0,
+                       RV1126_CLKSEL_CON(70), 0, 11, DFLAGS,
+                       RV1126_CLKGATE_CON(24), 1, GFLAGS),
+       GATE(CLK_CPU_TSADCPHY, "clk_cpu_tsadcphy", "clk_cpu_tsadc", 0,
+                       RV1126_CLKGATE_CON(24), 2, GFLAGS),
+
+       /*
+        * Clock-Architecture Diagram 6
+        */
+       /* PD_AUDIO */
+       COMPOSITE_NOMUX(HCLK_PDAUDIO, "hclk_pdaudio", "gpll", 0,
+                       RV1126_CLKSEL_CON(26), 0, 5, DFLAGS,
+                       RV1126_CLKGATE_CON(9), 0, GFLAGS),
+
+       GATE(HCLK_I2S0, "hclk_i2s0", "hclk_pdaudio", 0,
+                       RV1126_CLKGATE_CON(9), 4, GFLAGS),
+       COMPOSITE(MCLK_I2S0_TX_DIV, "mclk_i2s0_tx_div", mux_cpll_gpll_p, 0,
+                       RV1126_CLKSEL_CON(27), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(9), 5, GFLAGS),
+       COMPOSITE_FRACMUX(MCLK_I2S0_TX_FRACDIV, "mclk_i2s0_tx_fracdiv", "mclk_i2s0_tx_div",
+                       CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(28), 0,
+                       RV1126_CLKGATE_CON(9), 6, GFLAGS,
+                       &rv1126_i2s0_tx_fracmux),
+       GATE(MCLK_I2S0_TX, "mclk_i2s0_tx", "mclk_i2s0_tx_mux", 0,
+                       RV1126_CLKGATE_CON(9), 9, GFLAGS),
+       COMPOSITE(MCLK_I2S0_RX_DIV, "mclk_i2s0_rx_div", mux_cpll_gpll_p, 0,
+                       RV1126_CLKSEL_CON(27), 15, 1, MFLAGS, 8, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(9), 7, GFLAGS),
+       COMPOSITE_FRACMUX(MCLK_I2S0_RX_FRACDIV, "mclk_i2s0_rx_fracdiv", "mclk_i2s0_rx_div",
+                       CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(29), 0,
+                       RV1126_CLKGATE_CON(9), 8, GFLAGS,
+                       &rv1126_i2s0_rx_fracmux),
+       GATE(MCLK_I2S0_RX, "mclk_i2s0_rx", "mclk_i2s0_rx_mux", 0,
+                       RV1126_CLKGATE_CON(9), 10, GFLAGS),
+       COMPOSITE_NODIV(MCLK_I2S0_TX_OUT2IO, "mclk_i2s0_tx_out2io", mux_i2s0_tx_out2io_p, 0,
+                       RV1126_CLKSEL_CON(30), 6, 1, MFLAGS,
+                       RV1126_CLKGATE_CON(9), 13, GFLAGS),
+       COMPOSITE_NODIV(MCLK_I2S0_RX_OUT2IO, "mclk_i2s0_rx_out2io", mux_i2s0_rx_out2io_p, 0,
+                       RV1126_CLKSEL_CON(30), 8, 1, MFLAGS,
+                       RV1126_CLKGATE_CON(9), 14, GFLAGS),
+
+       GATE(HCLK_I2S1, "hclk_i2s1", "hclk_pdaudio", 0,
+                       RV1126_CLKGATE_CON(10), 0, GFLAGS),
+       COMPOSITE(MCLK_I2S1_DIV, "mclk_i2s1_div", mux_cpll_gpll_p, 0,
+                       RV1126_CLKSEL_CON(31), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(10), 1, GFLAGS),
+       COMPOSITE_FRACMUX(MCLK_I2S1_FRACDIV, "mclk_i2s1_fracdiv", "mclk_i2s1_div",
+                       CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(32), 0,
+                       RV1126_CLKGATE_CON(10), 2, GFLAGS,
+                       &rv1126_i2s1_fracmux),
+       GATE(MCLK_I2S1, "mclk_i2s1", "mclk_i2s1_mux", 0,
+                       RV1126_CLKGATE_CON(10), 3, GFLAGS),
+       COMPOSITE_NODIV(MCLK_I2S1_OUT2IO, "mclk_i2s1_out2io", mux_i2s1_out2io_p, 0,
+                       RV1126_CLKSEL_CON(31), 12, 1, MFLAGS,
+                       RV1126_CLKGATE_CON(10), 4, GFLAGS),
+       GATE(HCLK_I2S2, "hclk_i2s2", "hclk_pdaudio", 0,
+                       RV1126_CLKGATE_CON(10), 5, GFLAGS),
+       COMPOSITE(MCLK_I2S2_DIV, "mclk_i2s2_div", mux_cpll_gpll_p, 0,
+                       RV1126_CLKSEL_CON(33), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(10), 6, GFLAGS),
+       COMPOSITE_FRACMUX(MCLK_I2S2_FRACDIV, "mclk_i2s2_fracdiv", "mclk_i2s2_div",
+                       CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(34), 0,
+                       RV1126_CLKGATE_CON(10), 7, GFLAGS,
+                       &rv1126_i2s2_fracmux),
+       GATE(MCLK_I2S2, "mclk_i2s2", "mclk_i2s2_mux", 0,
+                       RV1126_CLKGATE_CON(10), 8, GFLAGS),
+       COMPOSITE_NODIV(MCLK_I2S2_OUT2IO, "mclk_i2s2_out2io", mux_i2s2_out2io_p, 0,
+                       RV1126_CLKSEL_CON(33), 10, 1, MFLAGS,
+                       RV1126_CLKGATE_CON(10), 9, GFLAGS),
+
+       GATE(HCLK_PDM, "hclk_pdm", "hclk_pdaudio", 0,
+                       RV1126_CLKGATE_CON(10), 10, GFLAGS),
+       COMPOSITE(MCLK_PDM, "mclk_pdm", mux_gpll_cpll_xin24m_p, 0,
+                       RV1126_CLKSEL_CON(35), 8, 2, MFLAGS, 0, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(10), 11, GFLAGS),
+
+       GATE(HCLK_AUDPWM, "hclk_audpwm", "hclk_pdaudio", 0,
+                       RV1126_CLKGATE_CON(10), 12, GFLAGS),
+       COMPOSITE(SCLK_ADUPWM_DIV, "sclk_audpwm_div", mux_gpll_cpll_p, 0,
+                       RV1126_CLKSEL_CON(36), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(10), 13, GFLAGS),
+       COMPOSITE_FRACMUX(SCLK_AUDPWM_FRACDIV, "sclk_audpwm_fracdiv", "sclk_audpwm_div",
+                       CLK_SET_RATE_PARENT,
+                       RV1126_CLKSEL_CON(37), 0,
+                       RV1126_CLKGATE_CON(10), 14, GFLAGS,
+                       &rv1126_audpwm_fracmux),
+       GATE(SCLK_AUDPWM, "sclk_audpwm", "mclk_audpwm_mux", 0,
+                       RV1126_CLKGATE_CON(10), 15, GFLAGS),
+
+       GATE(PCLK_ACDCDIG, "pclk_acdcdig", "hclk_pdaudio", 0,
+                       RV1126_CLKGATE_CON(11), 0, GFLAGS),
+       GATE(CLK_ACDCDIG_ADC, "clk_acdcdig_adc", "mclk_i2s0_rx", 0,
+                       RV1126_CLKGATE_CON(11), 2, GFLAGS),
+       GATE(CLK_ACDCDIG_DAC, "clk_acdcdig_dac", "mclk_i2s0_tx", 0,
+                       RV1126_CLKGATE_CON(11), 3, GFLAGS),
+       COMPOSITE(CLK_ACDCDIG_I2C, "clk_acdcdig_i2c", mux_gpll_xin24m_p, 0,
+                       RV1126_CLKSEL_CON(72), 8, 1, MFLAGS, 0, 7, DFLAGS,
+                       RV1126_CLKGATE_CON(11), 1, GFLAGS),
+
+       /*
+        * Clock-Architecture Diagram 12
+        */
+       /* PD_PHP */
+       COMPOSITE(ACLK_PDPHP, "aclk_pdphp", mux_gpll_cpll_p, CLK_IGNORE_UNUSED,
+                       RV1126_CLKSEL_CON(53), 7, 1, MFLAGS, 0, 5, DFLAGS,
+                       RV1126_CLKGATE_CON(17), 0, GFLAGS),
+       COMPOSITE_NOMUX(HCLK_PDPHP, "hclk_pdphp", "gpll", CLK_IGNORE_UNUSED,
+                       RV1126_CLKSEL_CON(53), 8, 5, DFLAGS,
+                       RV1126_CLKGATE_CON(17), 1, GFLAGS),
+       /* PD_SDCARD */
+       GATE(HCLK_PDSDMMC, "hclk_pdsdmmc", "hclk_pdphp", 0,
+                       RV1126_CLKGATE_CON(17), 6, GFLAGS),
+       GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_pdsdmmc", 0,
+                       RV1126_CLKGATE_CON(18), 4, GFLAGS),
+       COMPOSITE(CLK_SDMMC, "clk_sdmmc", mux_gpll_cpll_xin24m_p, 0,
+                       RV1126_CLKSEL_CON(55), 14, 2, MFLAGS, 0, 8,
+                       DFLAGS, RV1126_CLKGATE_CON(18), 5, GFLAGS),
+       MMC(SCLK_SDMMC_DRV,     "sdmmc_drv",    "clk_sdmmc", RV1126_SDMMC_CON0, 1),
+       MMC(SCLK_SDMMC_SAMPLE,  "sdmmc_sample", "clk_sdmmc", RV1126_SDMMC_CON1, 1),
+
+       /* PD_SDIO */
+       GATE(HCLK_PDSDIO, "hclk_pdsdio", "hclk_pdphp", 0,
+                       RV1126_CLKGATE_CON(17), 8, GFLAGS),
+       GATE(HCLK_SDIO, "hclk_sdio", "hclk_pdsdio", 0,
+                       RV1126_CLKGATE_CON(18), 6, GFLAGS),
+       COMPOSITE(CLK_SDIO, "clk_sdio", mux_gpll_cpll_xin24m_p, 0,
+                       RV1126_CLKSEL_CON(56), 14, 2, MFLAGS, 0, 8, DFLAGS,
+                       RV1126_CLKGATE_CON(18), 7, GFLAGS),
+       MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio", RV1126_SDIO_CON0, 1),
+       MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio", RV1126_SDIO_CON1, 1),
+
+       /* PD_NVM */
+       GATE(HCLK_PDNVM, "hclk_pdnvm", "hclk_pdphp", 0,
+                       RV1126_CLKGATE_CON(18), 1, GFLAGS),
+       GATE(HCLK_EMMC, "hclk_emmc", "hclk_pdnvm", 0,
+                       RV1126_CLKGATE_CON(18), 8, GFLAGS),
+       COMPOSITE(CLK_EMMC, "clk_emmc", mux_gpll_cpll_xin24m_p, 0,
+                       RV1126_CLKSEL_CON(57), 14, 2, MFLAGS, 0, 8, DFLAGS,
+                       RV1126_CLKGATE_CON(18), 9, GFLAGS),
+       GATE(HCLK_NANDC, "hclk_nandc", "hclk_pdnvm", 0,
+                       RV1126_CLKGATE_CON(18), 13, GFLAGS),
+       COMPOSITE(CLK_NANDC, "clk_nandc", mux_gpll_cpll_p, 0,
+                       RV1126_CLKSEL_CON(59), 15, 1, MFLAGS, 0, 8, DFLAGS,
+                       RV1126_CLKGATE_CON(18), 14, GFLAGS),
+       GATE(HCLK_SFC, "hclk_sfc", "hclk_pdnvm", 0,
+                       RV1126_CLKGATE_CON(18), 10, GFLAGS),
+       GATE(HCLK_SFCXIP, "hclk_sfcxip", "hclk_pdnvm", 0,
+                       RV1126_CLKGATE_CON(18), 11, GFLAGS),
+       COMPOSITE(SCLK_SFC, "sclk_sfc", mux_cpll_gpll_p, 0,
+                       RV1126_CLKSEL_CON(58), 15, 1, MFLAGS, 0, 8, DFLAGS,
+                       RV1126_CLKGATE_CON(18), 12, GFLAGS),
+       MMC(SCLK_EMMC_DRV, "emmc_drv", "clk_emmc", RV1126_EMMC_CON0, 1),
+       MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "clk_emmc", RV1126_EMMC_CON1, 1),
+
+       /* PD_USB */
+       GATE(ACLK_PDUSB, "aclk_pdusb", "aclk_pdphp", 0,
+                       RV1126_CLKGATE_CON(19), 0, GFLAGS),
+       GATE(HCLK_PDUSB, "hclk_pdusb", "hclk_pdphp", 0,
+                       RV1126_CLKGATE_CON(19), 1, GFLAGS),
+       GATE(HCLK_USBHOST, "hclk_usbhost", "hclk_pdusb", 0,
+                       RV1126_CLKGATE_CON(19), 4, GFLAGS),
+       GATE(HCLK_USBHOST_ARB, "hclk_usbhost_arb", "hclk_pdusb", 0,
+                       RV1126_CLKGATE_CON(19), 5, GFLAGS),
+       COMPOSITE(CLK_USBHOST_UTMI_OHCI, "clk_usbhost_utmi_ohci", mux_usb480m_gpll_p, 0,
+                       RV1126_CLKSEL_CON(61), 7, 1, MFLAGS, 0, 5, DFLAGS,
+                       RV1126_CLKGATE_CON(19), 6, GFLAGS),
+       GATE(ACLK_USBOTG, "aclk_usbotg", "aclk_pdusb", 0,
+                       RV1126_CLKGATE_CON(19), 7, GFLAGS),
+       GATE(CLK_USBOTG_REF, "clk_usbotg_ref", "xin24m", 0,
+                       RV1126_CLKGATE_CON(19), 8, GFLAGS),
+       /* PD_GMAC */
+       GATE(ACLK_PDGMAC, "aclk_pdgmac", "aclk_pdphp", 0,
+                       RV1126_CLKGATE_CON(20), 0, GFLAGS),
+       COMPOSITE_NOMUX(PCLK_PDGMAC, "pclk_pdgmac", "aclk_pdgmac", 0,
+                       RV1126_CLKSEL_CON(63), 8, 5, DFLAGS,
+                       RV1126_CLKGATE_CON(20), 1, GFLAGS),
+       GATE(ACLK_GMAC, "aclk_gmac", "aclk_pdgmac", 0,
+                       RV1126_CLKGATE_CON(20), 4, GFLAGS),
+       GATE(PCLK_GMAC, "pclk_gmac", "pclk_pdgmac", 0,
+                       RV1126_CLKGATE_CON(20), 5, GFLAGS),
+
+       COMPOSITE(CLK_GMAC_DIV, "clk_gmac_div", mux_cpll_gpll_p, 0,
+                       RV1126_CLKSEL_CON(63), 7, 1, MFLAGS, 0, 5, DFLAGS,
+                       RV1126_CLKGATE_CON(20), 6, GFLAGS),
+       GATE(CLK_GMAC_RGMII_M0, "clk_gmac_rgmii_m0", "clk_gmac_rgmii_clkin_m0", 0,
+                       RV1126_CLKGATE_CON(20), 12, GFLAGS),
+       MUX(CLK_GMAC_SRC_M0, "clk_gmac_src_m0", clk_gmac_src_m0_p, CLK_SET_RATE_PARENT,
+                       RV1126_GMAC_CON, 0, 1, MFLAGS),
+       GATE(CLK_GMAC_RGMII_M1, "clk_gmac_rgmii_m1", "clk_gmac_rgmii_clkin_m1", 0,
+                       RV1126_CLKGATE_CON(20), 13, GFLAGS),
+       MUX(CLK_GMAC_SRC_M1, "clk_gmac_src_m1", clk_gmac_src_m1_p, CLK_SET_RATE_PARENT,
+                       RV1126_GMAC_CON, 5, 1, MFLAGS),
+       MUXGRF(CLK_GMAC_SRC, "clk_gmac_src", mux_clk_gmac_src_p, CLK_SET_RATE_PARENT |
+                       CLK_SET_RATE_NO_REPARENT,
+                       RV1126_GRF_IOFUNC_CON1, 12, 1, MFLAGS),
+
+       GATE(CLK_GMAC_REF, "clk_gmac_ref", "clk_gmac_src", 0,
+                       RV1126_CLKGATE_CON(20), 7, GFLAGS),
+
+       GATE(CLK_GMAC_TX_SRC, "clk_gmac_tx_src", "clk_gmac_src", 0,
+                       RV1126_CLKGATE_CON(20), 9, GFLAGS),
+       FACTOR(CLK_GMAC_TX_DIV5, "clk_gmac_tx_div5", "clk_gmac_tx_src", 0, 1, 5),
+       FACTOR(CLK_GMAC_TX_DIV50, "clk_gmac_tx_div50", "clk_gmac_tx_src", 0, 1, 50),
+       MUXTBL(RGMII_MODE_CLK, "rgmii_mode_clk", mux_rgmii_clk_p, CLK_SET_RATE_PARENT,
+                       RV1126_GMAC_CON, 2, 2, MFLAGS, rgmii_mux_idx),
+       GATE(CLK_GMAC_RX_SRC, "clk_gmac_rx_src", "clk_gmac_src", 0,
+                       RV1126_CLKGATE_CON(20), 8, GFLAGS),
+       FACTOR(CLK_GMAC_RX_DIV2, "clk_gmac_rx_div2", "clk_gmac_rx_src", 0, 1, 2),
+       FACTOR(CLK_GMAC_RX_DIV20, "clk_gmac_rx_div20", "clk_gmac_rx_src", 0, 1, 20),
+       MUX(RMII_MODE_CLK, "rmii_mode_clk", mux_rmii_clk_p, CLK_SET_RATE_PARENT,
+                       RV1126_GMAC_CON, 1, 1, MFLAGS),
+       MUX(CLK_GMAC_TX_RX, "clk_gmac_tx_rx", mux_gmac_tx_rx_p, CLK_SET_RATE_PARENT |
+                       CLK_SET_RATE_NO_REPARENT,
+                       RV1126_GMAC_CON, 4, 1, MFLAGS),
+
+       GATE(CLK_GMAC_PTPREF, "clk_gmac_ptpref", "xin24m", 0,
+                       RV1126_CLKGATE_CON(20), 10, GFLAGS),
+       COMPOSITE(CLK_GMAC_ETHERNET_OUT, "clk_gmac_ethernet_out2io", mux_cpll_gpll_p, 0,
+                       RV1126_CLKSEL_CON(61), 15, 1, MFLAGS, 8, 5, DFLAGS,
+                       RV1126_CLKGATE_CON(20), 11, GFLAGS),
+
+       /*
+        * Clock-Architecture Diagram 15
+        */
+       GATE(PCLK_PDTOP, "pclk_pdtop", "pclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(23), 8, GFLAGS),
+       GATE(PCLK_DSIPHY, "pclk_dsiphy", "pclk_pdtop", 0,
+                       RV1126_CLKGATE_CON(23), 4, GFLAGS),
+       GATE(PCLK_CSIPHY0, "pclk_csiphy0", "pclk_pdtop", 0,
+                       RV1126_CLKGATE_CON(23), 2, GFLAGS),
+       GATE(PCLK_CSIPHY1, "pclk_csiphy1", "pclk_pdtop", 0,
+                       RV1126_CLKGATE_CON(23), 3, GFLAGS),
+       GATE(PCLK_USBPHY_HOST, "pclk_usbphy_host", "pclk_pdtop", 0,
+                       RV1126_CLKGATE_CON(19), 13, GFLAGS),
+       GATE(PCLK_USBPHY_OTG, "pclk_usbphy_otg", "pclk_pdtop", 0,
+                       RV1126_CLKGATE_CON(19), 12, GFLAGS),
+
+       /*
+        * Clock-Architecture Diagram 3
+        */
+       /* PD_CORE */
+       COMPOSITE_NOMUX(0, "aclk_core", "armclk", CLK_IGNORE_UNUSED,
+                       RV1126_CLKSEL_CON(1), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+                       RV1126_CLKGATE_CON(0), 2, GFLAGS),
+       GATE(0, "pclk_dbg_daplite", "pclk_dbg", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(0), 5, GFLAGS),
+       GATE(0, "clk_a7_jtag", "clk_jtag_ori", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(0), 9, GFLAGS),
+       GATE(0, "aclk_core_niu", "aclk_core", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(0), 3, GFLAGS),
+       GATE(0, "pclk_dbg_niu", "pclk_dbg", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(0), 4, GFLAGS),
+       /*
+        * Clock-Architecture Diagram 4
+        */
+       /* PD_BUS */
+       GATE(0, "aclk_pdbus_hold_niu1", "aclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(2), 10, GFLAGS),
+       GATE(0, "aclk_pdbus_niu1", "aclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(2), 3, GFLAGS),
+       GATE(0, "hclk_pdbus_niu1", "hclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(2), 4, GFLAGS),
+       GATE(0, "pclk_pdbus_niu1", "pclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(2), 5, GFLAGS),
+       GATE(0, "aclk_pdbus_niu2", "aclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(2), 6, GFLAGS),
+       GATE(0, "hclk_pdbus_niu2", "hclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(2), 7, GFLAGS),
+       GATE(0, "aclk_pdbus_niu3", "aclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(2), 8, GFLAGS),
+       GATE(0, "hclk_pdbus_niu3", "hclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(2), 9, GFLAGS),
+       GATE(0, "pclk_grf", "pclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(6), 15, GFLAGS),
+       GATE(0, "pclk_sgrf", "pclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(8), 4, GFLAGS),
+       GATE(0, "aclk_sysram", "hclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(3), 9, GFLAGS),
+       GATE(0, "pclk_intmux", "pclk_pdbus", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(7), 14, GFLAGS),
+
+       /*
+        * Clock-Architecture Diagram 6
+        */
+       /* PD_AUDIO */
+       GATE(0, "hclk_pdaudio_niu", "hclk_pdaudio", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(9), 2, GFLAGS),
+       GATE(0, "pclk_pdaudio_niu", "hclk_pdaudio", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(9), 3, GFLAGS),
+
+       /*
+        * Clock-Architecture Diagram 12
+        */
+       /* PD_PHP */
+       GATE(0, "aclk_pdphpmid", "aclk_pdphp", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(17), 2, GFLAGS),
+       GATE(0, "hclk_pdphpmid", "hclk_pdphp", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(17), 3, GFLAGS),
+       GATE(0, "aclk_pdphpmid_niu", "aclk_pdphpmid", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(17), 4, GFLAGS),
+       GATE(0, "hclk_pdphpmid_niu", "hclk_pdphpmid", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(17), 5, GFLAGS),
+
+       /* PD_SDCARD */
+       GATE(0, "hclk_pdsdmmc_niu", "hclk_pdsdmmc", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(17), 7, GFLAGS),
+
+       /* PD_SDIO */
+       GATE(0, "hclk_pdsdio_niu", "hclk_pdsdio", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(17), 9, GFLAGS),
+
+       /* PD_NVM */
+       GATE(0, "hclk_pdnvm_niu", "hclk_pdnvm", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(18), 3, GFLAGS),
+
+       /* PD_USB */
+       GATE(0, "aclk_pdusb_niu", "aclk_pdusb", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(19), 2, GFLAGS),
+       GATE(0, "hclk_pdusb_niu", "hclk_pdusb", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(19), 3, GFLAGS),
+
+       /* PD_GMAC */
+       GATE(0, "aclk_pdgmac_niu", "aclk_pdgmac", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(20), 2, GFLAGS),
+       GATE(0, "pclk_pdgmac_niu", "pclk_pdgmac", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(20), 3, GFLAGS),
+
+       /*
+        * Clock-Architecture Diagram 13
+        */
+       /* PD_DDR */
+       COMPOSITE_NOMUX(0, "pclk_pdddr_pre", "gpll", CLK_IGNORE_UNUSED,
+                       RV1126_CLKSEL_CON(64), 0, 5, DFLAGS,
+                       RV1126_CLKGATE_CON(21), 0, GFLAGS),
+       GATE(PCLK_PDDDR, "pclk_pdddr", "pclk_pdddr_pre", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(21), 15, GFLAGS),
+       GATE(0, "pclk_ddr_msch", "pclk_pdddr", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(21), 6, GFLAGS),
+       COMPOSITE_NOGATE(SCLK_DDRCLK, "sclk_ddrc", mux_dpll_gpll_p, CLK_IGNORE_UNUSED,
+                        RV1126_CLKSEL_CON(64), 15, 1, MFLAGS, 8, 5, DFLAGS |
+                        CLK_DIVIDER_POWER_OF_TWO),
+       COMPOSITE(CLK_DDRPHY, "clk_ddrphy", mux_dpll_gpll_p, CLK_IGNORE_UNUSED,
+                       RV1126_CLKSEL_CON(64), 15, 1, MFLAGS, 8, 5, DFLAGS,
+                       RV1126_CLKGATE_CON(21), 8, GFLAGS),
+       GATE(0, "clk1x_phy", "clk_ddrphy", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(23), 1, GFLAGS),
+       GATE(0, "clk_ddr_msch", "clk_ddrphy", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(21), 10, GFLAGS),
+       GATE(0, "pclk_ddr_dfictl", "pclk_pdddr", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(21), 2, GFLAGS),
+       GATE(0, "clk_ddr_dfictl", "clk_ddrphy", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(21), 13, GFLAGS),
+       GATE(0, "pclk_ddr_standby", "pclk_pdddr", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(21), 4, GFLAGS),
+       GATE(0, "clk_ddr_standby", "clk_ddrphy", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(21), 14, GFLAGS),
+       GATE(0, "aclk_ddr_split", "clk_ddrphy", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(21), 9, GFLAGS),
+       GATE(0, "pclk_ddr_grf", "pclk_pdddr", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(21), 5, GFLAGS),
+       GATE(PCLK_DDR_MON, "pclk_ddr_mon", "pclk_pdddr", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(21), 3, GFLAGS),
+       GATE(CLK_DDR_MON, "clk_ddr_mon", "clk_ddrphy", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(20), 15, GFLAGS),
+       GATE(TMCLK_DDR_MON, "tmclk_ddr_mon", "xin24m", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(21), 7, GFLAGS),
+
+       /*
+        * Clock-Architecture Diagram 15
+        */
+       GATE(0, "pclk_topniu", "pclk_pdtop", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(23), 9, GFLAGS),
+       GATE(PCLK_TOPCRU, "pclk_topcru", "pclk_pdtop", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(23), 10, GFLAGS),
+       GATE(PCLK_TOPGRF, "pclk_topgrf", "pclk_pdtop", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(23), 11, GFLAGS),
+       GATE(PCLK_CPUEMADET, "pclk_cpuemadet", "pclk_pdtop", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(23), 12, GFLAGS),
+       GATE(PCLK_DDRPHY, "pclk_ddrphy", "pclk_pdtop", CLK_IGNORE_UNUSED,
+                       RV1126_CLKGATE_CON(23), 0, GFLAGS),
+};
+
+static const char *const rv1126_cru_critical_clocks[] __initconst = {
+       "gpll",
+       "cpll",
+       "hpll",
+       "armclk",
+       "pclk_dbg",
+       "pclk_pdpmu",
+       "aclk_pdbus",
+       "hclk_pdbus",
+       "pclk_pdbus",
+       "aclk_pdphp",
+       "hclk_pdphp",
+       "clk_ddrphy",
+       "pclk_pdddr",
+       "pclk_pdtop",
+       "clk_usbhost_utmi_ohci",
+       "aclk_pdjpeg_niu",
+       "hclk_pdjpeg_niu",
+       "aclk_pdvdec_niu",
+       "hclk_pdvdec_niu",
+};
+
+static void __init rv1126_pmu_clk_init(struct device_node *np)
+{
+       struct rockchip_clk_provider *ctx;
+       void __iomem *reg_base;
+
+       reg_base = of_iomap(np, 0);
+       if (!reg_base) {
+               pr_err("%s: could not map cru pmu region\n", __func__);
+               return;
+       }
+
+       ctx = rockchip_clk_init(np, reg_base, CLKPMU_NR_CLKS);
+       if (IS_ERR(ctx)) {
+               pr_err("%s: rockchip pmu clk init failed\n", __func__);
+               return;
+       }
+
+       rockchip_clk_register_plls(ctx, rv1126_pmu_pll_clks,
+                                  ARRAY_SIZE(rv1126_pmu_pll_clks),
+                                  RV1126_GRF_SOC_STATUS0);
+
+       rockchip_clk_register_branches(ctx, rv1126_clk_pmu_branches,
+                                      ARRAY_SIZE(rv1126_clk_pmu_branches));
+
+       rockchip_register_softrst(np, 2, reg_base + RV1126_PMU_SOFTRST_CON(0),
+                                 ROCKCHIP_SOFTRST_HIWORD_MASK);
+
+       rockchip_clk_of_add_provider(np, ctx);
+}
+
+static void __init rv1126_clk_init(struct device_node *np)
+{
+       struct rockchip_clk_provider *ctx;
+       void __iomem *reg_base;
+
+       reg_base = of_iomap(np, 0);
+       if (!reg_base) {
+               pr_err("%s: could not map cru region\n", __func__);
+               return;
+       }
+
+       ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+       if (IS_ERR(ctx)) {
+               pr_err("%s: rockchip clk init failed\n", __func__);
+               iounmap(reg_base);
+               return;
+       }
+
+       rockchip_clk_register_plls(ctx, rv1126_pll_clks,
+                                  ARRAY_SIZE(rv1126_pll_clks),
+                                  RV1126_GRF_SOC_STATUS0);
+
+       rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
+                                    mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
+                                    &rv1126_cpuclk_data, rv1126_cpuclk_rates,
+                                    ARRAY_SIZE(rv1126_cpuclk_rates));
+
+       rockchip_clk_register_branches(ctx, rv1126_clk_branches,
+                                      ARRAY_SIZE(rv1126_clk_branches));
+
+       rockchip_register_softrst(np, 15, reg_base + RV1126_SOFTRST_CON(0),
+                                 ROCKCHIP_SOFTRST_HIWORD_MASK);
+
+       rockchip_register_restart_notifier(ctx, RV1126_GLB_SRST_FST, NULL);
+
+       rockchip_clk_protect_critical(rv1126_cru_critical_clocks,
+                                     ARRAY_SIZE(rv1126_cru_critical_clocks));
+
+       rockchip_clk_of_add_provider(np, ctx);
+}
+
+struct clk_rv1126_inits {
+       void (*inits)(struct device_node *np);
+};
+
+static const struct clk_rv1126_inits clk_rv1126_pmucru_init = {
+       .inits = rv1126_pmu_clk_init,
+};
+
+static const struct clk_rv1126_inits clk_rv1126_cru_init = {
+       .inits = rv1126_clk_init,
+};
+
+static const struct of_device_id clk_rv1126_match_table[] = {
+       {
+               .compatible = "rockchip,rv1126-cru",
+               .data = &clk_rv1126_cru_init,
+       },  {
+               .compatible = "rockchip,rv1126-pmucru",
+               .data = &clk_rv1126_pmucru_init,
+       },
+       { }
+};
+
+static int __init clk_rv1126_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       const struct clk_rv1126_inits *init_data;
+
+       init_data = (struct clk_rv1126_inits *)of_device_get_match_data(&pdev->dev);
+       if (!init_data)
+               return -EINVAL;
+
+       if (init_data->inits)
+               init_data->inits(np);
+
+       return 0;
+}
+
+static struct platform_driver clk_rv1126_driver = {
+       .driver         = {
+               .name   = "clk-rv1126",
+               .of_match_table = clk_rv1126_match_table,
+               .suppress_bind_attrs = true,
+       },
+};
+builtin_platform_driver_probe(clk_rv1126_driver, clk_rv1126_probe);
index bb8a844..e63d4f2 100644 (file)
@@ -40,6 +40,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
                const char *const *parent_names, u8 num_parents,
                void __iomem *base,
                int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags,
+               u32 *mux_table,
                int div_offset, u8 div_shift, u8 div_width, u8 div_flags,
                struct clk_div_table *div_table, int gate_offset,
                u8 gate_shift, u8 gate_flags, unsigned long flags,
@@ -62,6 +63,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
                mux->shift = mux_shift;
                mux->mask = BIT(mux_width) - 1;
                mux->flags = mux_flags;
+               mux->table = mux_table;
                mux->lock = lock;
                mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops
                                                        : &clk_mux_ops;
@@ -270,6 +272,8 @@ static struct clk *rockchip_clk_register_frac_branch(
                frac_mux->shift = child->mux_shift;
                frac_mux->mask = BIT(child->mux_width) - 1;
                frac_mux->flags = child->mux_flags;
+               if (child->mux_table)
+                       frac_mux->table = child->mux_table;
                frac_mux->lock = lock;
                frac_mux->hw.init = &init;
 
@@ -444,11 +448,21 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
                /* catch simple muxes */
                switch (list->branch_type) {
                case branch_mux:
-                       clk = clk_register_mux(NULL, list->name,
-                               list->parent_names, list->num_parents,
-                               flags, ctx->reg_base + list->muxdiv_offset,
-                               list->mux_shift, list->mux_width,
-                               list->mux_flags, &ctx->lock);
+                       if (list->mux_table)
+                               clk = clk_register_mux_table(NULL, list->name,
+                                       list->parent_names, list->num_parents,
+                                       flags,
+                                       ctx->reg_base + list->muxdiv_offset,
+                                       list->mux_shift, list->mux_width,
+                                       list->mux_flags, list->mux_table,
+                                       &ctx->lock);
+                       else
+                               clk = clk_register_mux(NULL, list->name,
+                                       list->parent_names, list->num_parents,
+                                       flags,
+                                       ctx->reg_base + list->muxdiv_offset,
+                                       list->mux_shift, list->mux_width,
+                                       list->mux_flags, &ctx->lock);
                        break;
                case branch_muxgrf:
                        clk = rockchip_clk_register_muxgrf(list->name,
@@ -506,7 +520,8 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
                                ctx->reg_base, list->muxdiv_offset,
                                list->mux_shift,
                                list->mux_width, list->mux_flags,
-                               list->div_offset, list->div_shift, list->div_width,
+                               list->mux_table, list->div_offset,
+                               list->div_shift, list->div_width,
                                list->div_flags, list->div_table,
                                list->gate_offset, list->gate_shift,
                                list->gate_flags, flags, &ctx->lock);
index 7aa45cc..ee01739 100644 (file)
@@ -79,6 +79,25 @@ struct clk;
 #define RV1108_EMMC_CON0               0x1e8
 #define RV1108_EMMC_CON1               0x1ec
 
+#define RV1126_PMU_MODE                        0x0
+#define RV1126_PMU_PLL_CON(x)          ((x) * 0x4 + 0x10)
+#define RV1126_PMU_CLKSEL_CON(x)       ((x) * 0x4 + 0x100)
+#define RV1126_PMU_CLKGATE_CON(x)      ((x) * 0x4 + 0x180)
+#define RV1126_PMU_SOFTRST_CON(x)      ((x) * 0x4 + 0x200)
+#define RV1126_PLL_CON(x)              ((x) * 0x4)
+#define RV1126_MODE_CON                        0x90
+#define RV1126_CLKSEL_CON(x)           ((x) * 0x4 + 0x100)
+#define RV1126_CLKGATE_CON(x)          ((x) * 0x4 + 0x280)
+#define RV1126_SOFTRST_CON(x)          ((x) * 0x4 + 0x300)
+#define RV1126_GLB_SRST_FST            0x408
+#define RV1126_GLB_SRST_SND            0x40c
+#define RV1126_SDMMC_CON0              0x440
+#define RV1126_SDMMC_CON1              0x444
+#define RV1126_SDIO_CON0               0x448
+#define RV1126_SDIO_CON1               0x44c
+#define RV1126_EMMC_CON0               0x450
+#define RV1126_EMMC_CON1               0x454
+
 #define RK2928_PLL_CON(x)              ((x) * 0x4)
 #define RK2928_MODE_CON                0x40
 #define RK2928_CLKSEL_CON(x)   ((x) * 0x4 + 0x44)
@@ -448,6 +467,7 @@ struct rockchip_clk_branch {
        u8                              mux_shift;
        u8                              mux_width;
        u8                              mux_flags;
+       u32                             *mux_table;
        int                             div_offset;
        u8                              div_shift;
        u8                              div_width;
@@ -680,6 +700,22 @@ struct rockchip_clk_branch {
                .gate_offset    = -1,                           \
        }
 
+#define MUXTBL(_id, cname, pnames, f, o, s, w, mf, mt)         \
+       {                                                       \
+               .id             = _id,                          \
+               .branch_type    = branch_mux,                   \
+               .name           = cname,                        \
+               .parent_names   = pnames,                       \
+               .num_parents    = ARRAY_SIZE(pnames),           \
+               .flags          = f,                            \
+               .muxdiv_offset  = o,                            \
+               .mux_shift      = s,                            \
+               .mux_width      = w,                            \
+               .mux_flags      = mf,                           \
+               .gate_offset    = -1,                           \
+               .mux_table      = mt,                           \
+       }
+
 #define MUXGRF(_id, cname, pnames, f, o, s, w, mf)             \
        {                                                       \
                .id             = _id,                          \
index e6d6cbf..273f77d 100644 (file)
@@ -81,19 +81,17 @@ MODULE_DEVICE_TABLE(of, exynos_clkout_ids);
 static int exynos_clkout_match_parent_dev(struct device *dev, u32 *mux_mask)
 {
        const struct exynos_clkout_variant *variant;
-       const struct of_device_id *match;
 
        if (!dev->parent) {
                dev_err(dev, "not instantiated from MFD\n");
                return -EINVAL;
        }
 
-       match = of_match_device(exynos_clkout_ids, dev->parent);
-       if (!match) {
+       variant = of_device_get_match_data(dev->parent);
+       if (!variant) {
                dev_err(dev, "cannot match parent device\n");
                return -EINVAL;
        }
-       variant = match->data;
 
        *mux_mask = variant->mux_mask;
 
index a7b1063..62ce681 100644 (file)
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS                0x1014
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI                0x1018
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_G3D                0x101c
+#define CLK_CON_MUX_MUX_CLKCMU_FSYS_BUS                0x1028
+#define CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_CARD   0x102c
+#define CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_EMBD   0x1030
+#define CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_SDIO   0x1034
+#define CLK_CON_MUX_MUX_CLKCMU_FSYS_USB30DRD   0x1038
 #define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS                0x1058
 #define CLK_CON_MUX_MUX_CLKCMU_PERI_SPI0       0x105c
 #define CLK_CON_MUX_MUX_CLKCMU_PERI_SPI1       0x1060
 #define CLK_CON_DIV_CLKCMU_CORE_BUS            0x181c
 #define CLK_CON_DIV_CLKCMU_CORE_CCI            0x1820
 #define CLK_CON_DIV_CLKCMU_CORE_G3D            0x1824
+#define CLK_CON_DIV_CLKCMU_FSYS_BUS            0x1844
+#define CLK_CON_DIV_CLKCMU_FSYS_MMC_CARD       0x1848
+#define CLK_CON_DIV_CLKCMU_FSYS_MMC_EMBD       0x184c
+#define CLK_CON_DIV_CLKCMU_FSYS_MMC_SDIO       0x1850
+#define CLK_CON_DIV_CLKCMU_FSYS_USB30DRD       0x1854
 #define CLK_CON_DIV_CLKCMU_PERI_BUS            0x1874
 #define CLK_CON_DIV_CLKCMU_PERI_SPI0           0x1878
 #define CLK_CON_DIV_CLKCMU_PERI_SPI1           0x187c
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS       0x201c
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI       0x2020
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_G3D       0x2024
+#define CLK_CON_GAT_GATE_CLKCMU_FSYS_BUS       0x2044
+#define CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_CARD  0x2048
+#define CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_EMBD  0x204c
+#define CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_SDIO  0x2050
+#define CLK_CON_GAT_GATE_CLKCMU_FSYS_USB30DRD  0x2054
 #define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS       0x207c
 #define CLK_CON_GAT_GATE_CLKCMU_PERI_SPI0      0x2080
 #define CLK_CON_GAT_GATE_CLKCMU_PERI_SPI1      0x2084
@@ -76,6 +91,11 @@ static const unsigned long top_clk_regs[] __initconst = {
        CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
        CLK_CON_MUX_MUX_CLKCMU_CORE_CCI,
        CLK_CON_MUX_MUX_CLKCMU_CORE_G3D,
+       CLK_CON_MUX_MUX_CLKCMU_FSYS_BUS,
+       CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_CARD,
+       CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_EMBD,
+       CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_SDIO,
+       CLK_CON_MUX_MUX_CLKCMU_FSYS_USB30DRD,
        CLK_CON_MUX_MUX_CLKCMU_PERI_BUS,
        CLK_CON_MUX_MUX_CLKCMU_PERI_SPI0,
        CLK_CON_MUX_MUX_CLKCMU_PERI_SPI1,
@@ -88,6 +108,11 @@ static const unsigned long top_clk_regs[] __initconst = {
        CLK_CON_DIV_CLKCMU_CORE_BUS,
        CLK_CON_DIV_CLKCMU_CORE_CCI,
        CLK_CON_DIV_CLKCMU_CORE_G3D,
+       CLK_CON_DIV_CLKCMU_FSYS_BUS,
+       CLK_CON_DIV_CLKCMU_FSYS_MMC_CARD,
+       CLK_CON_DIV_CLKCMU_FSYS_MMC_EMBD,
+       CLK_CON_DIV_CLKCMU_FSYS_MMC_SDIO,
+       CLK_CON_DIV_CLKCMU_FSYS_USB30DRD,
        CLK_CON_DIV_CLKCMU_PERI_BUS,
        CLK_CON_DIV_CLKCMU_PERI_SPI0,
        CLK_CON_DIV_CLKCMU_PERI_SPI1,
@@ -108,6 +133,11 @@ static const unsigned long top_clk_regs[] __initconst = {
        CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
        CLK_CON_GAT_GATE_CLKCMU_CORE_CCI,
        CLK_CON_GAT_GATE_CLKCMU_CORE_G3D,
+       CLK_CON_GAT_GATE_CLKCMU_FSYS_BUS,
+       CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_CARD,
+       CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_EMBD,
+       CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_SDIO,
+       CLK_CON_GAT_GATE_CLKCMU_FSYS_USB30DRD,
        CLK_CON_GAT_GATE_CLKCMU_PERI_BUS,
        CLK_CON_GAT_GATE_CLKCMU_PERI_SPI0,
        CLK_CON_GAT_GATE_CLKCMU_PERI_SPI1,
@@ -146,6 +176,13 @@ PNAME(mout_peri_usi0_p)            = { "oscclk", "dout_shared0_div4" };
 PNAME(mout_peri_usi1_p)                = { "oscclk", "dout_shared0_div4" };
 PNAME(mout_peri_usi2_p)                = { "oscclk", "dout_shared0_div4" };
 
+/* List of parent clocks for Muxes in CMU_TOP: for CMU_FSYS */
+PNAME(mout_fsys_bus_p)         = { "dout_shared0_div2", "dout_shared1_div2" };
+PNAME(mout_fsys_mmc_card_p)    = { "dout_shared0_div2", "dout_shared1_div2" };
+PNAME(mout_fsys_mmc_embd_p)    = { "dout_shared0_div2", "dout_shared1_div2" };
+PNAME(mout_fsys_mmc_sdio_p)    = { "dout_shared0_div2", "dout_shared1_div2" };
+PNAME(mout_fsys_usb30drd_p)    = { "dout_shared0_div4", "dout_shared1_div4" };
+
 static const struct samsung_mux_clock top_mux_clks[] __initconst = {
        /* CORE */
        MUX(CLK_MOUT_CORE_BUS, "mout_core_bus", mout_core_bus_p,
@@ -174,6 +211,18 @@ static const struct samsung_mux_clock top_mux_clks[] __initconst = {
            CLK_CON_MUX_MUX_CLKCMU_PERI_USI1, 0, 1),
        MUX(CLK_MOUT_PERI_USI2, "mout_peri_usi2", mout_peri_usi2_p,
            CLK_CON_MUX_MUX_CLKCMU_PERI_USI2, 0, 1),
+
+       /* FSYS */
+       MUX(CLK_MOUT_FSYS_BUS, "mout_fsys_bus", mout_fsys_bus_p,
+           CLK_CON_MUX_MUX_CLKCMU_FSYS_BUS, 0, 1),
+       MUX(CLK_MOUT_FSYS_MMC_CARD, "mout_fsys_mmc_card", mout_fsys_mmc_card_p,
+           CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_CARD, 0, 1),
+       MUX(CLK_MOUT_FSYS_MMC_EMBD, "mout_fsys_mmc_embd", mout_fsys_mmc_embd_p,
+           CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_EMBD, 0, 1),
+       MUX(CLK_MOUT_FSYS_MMC_SDIO, "mout_fsys_mmc_sdio", mout_fsys_mmc_sdio_p,
+           CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_SDIO, 0, 1),
+       MUX(CLK_MOUT_FSYS_USB30DRD, "mout_fsys_usb30drd", mout_fsys_usb30drd_p,
+           CLK_CON_MUX_MUX_CLKCMU_FSYS_USB30DRD, 0, 1),
 };
 
 static const struct samsung_div_clock top_div_clks[] __initconst = {
@@ -220,6 +269,18 @@ static const struct samsung_div_clock top_div_clks[] __initconst = {
            CLK_CON_DIV_CLKCMU_PERI_USI1, 0, 4),
        DIV(CLK_DOUT_PERI_USI2, "dout_peri_usi2", "gout_peri_usi2",
            CLK_CON_DIV_CLKCMU_PERI_USI2, 0, 4),
+
+       /* FSYS */
+       DIV(CLK_DOUT_FSYS_BUS, "dout_fsys_bus", "gout_fsys_bus",
+           CLK_CON_DIV_CLKCMU_FSYS_BUS, 0, 4),
+       DIV(CLK_DOUT_FSYS_MMC_CARD, "dout_fsys_mmc_card", "gout_fsys_mmc_card",
+           CLK_CON_DIV_CLKCMU_FSYS_MMC_CARD, 0, 9),
+       DIV(CLK_DOUT_FSYS_MMC_EMBD, "dout_fsys_mmc_embd", "gout_fsys_mmc_embd",
+           CLK_CON_DIV_CLKCMU_FSYS_MMC_EMBD, 0, 9),
+       DIV(CLK_DOUT_FSYS_MMC_SDIO, "dout_fsys_mmc_sdio", "gout_fsys_mmc_sdio",
+           CLK_CON_DIV_CLKCMU_FSYS_MMC_SDIO, 0, 9),
+       DIV(CLK_DOUT_FSYS_USB30DRD, "dout_fsys_usb30drd", "gout_fsys_usb30drd",
+           CLK_CON_DIV_CLKCMU_FSYS_USB30DRD, 0, 4),
 };
 
 static const struct samsung_gate_clock top_gate_clks[] __initconst = {
@@ -250,6 +311,18 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
             CLK_CON_GAT_GATE_CLKCMU_PERI_USI1, 21, 0, 0),
        GATE(CLK_GOUT_PERI_USI2, "gout_peri_usi2", "mout_peri_usi2",
             CLK_CON_GAT_GATE_CLKCMU_PERI_USI2, 21, 0, 0),
+
+       /* FSYS */
+       GATE(CLK_GOUT_FSYS_BUS, "gout_fsys_bus", "mout_fsys_bus",
+            CLK_CON_GAT_GATE_CLKCMU_FSYS_BUS, 21, 0, 0),
+       GATE(CLK_GOUT_FSYS_MMC_CARD, "gout_fsys_mmc_card", "mout_fsys_mmc_card",
+            CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_CARD, 21, 0, 0),
+       GATE(CLK_GOUT_FSYS_MMC_EMBD, "gout_fsys_mmc_embd", "mout_fsys_mmc_embd",
+            CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_EMBD, 21, 0, 0),
+       GATE(CLK_GOUT_FSYS_MMC_SDIO, "gout_fsys_mmc_sdio", "mout_fsys_mmc_sdio",
+            CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_SDIO, 21, 0, 0),
+       GATE(CLK_GOUT_FSYS_USB30DRD, "gout_fsys_usb30drd", "mout_fsys_usb30drd",
+            CLK_CON_GAT_GATE_CLKCMU_FSYS_USB30DRD, 21, 0, 0),
 };
 
 static const struct samsung_cmu_info top_cmu_info __initconst = {
@@ -498,13 +571,20 @@ CLK_OF_DECLARE(exynos7885_cmu_peri, "samsung,exynos7885-cmu-peri",
 /* ---- CMU_CORE ------------------------------------------------------------ */
 
 /* Register Offset definitions for CMU_CORE (0x12000000) */
-#define PLL_CON0_MUX_CLKCMU_CORE_BUS_USER      0x0100
-#define PLL_CON0_MUX_CLKCMU_CORE_CCI_USER      0x0120
-#define PLL_CON0_MUX_CLKCMU_CORE_G3D_USER      0x0140
-#define CLK_CON_MUX_MUX_CLK_CORE_GIC           0x1000
-#define CLK_CON_DIV_DIV_CLK_CORE_BUSP          0x1800
-#define CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK     0x2054
-#define CLK_CON_GAT_GOUT_CORE_GIC400_CLK       0x2058
+#define PLL_CON0_MUX_CLKCMU_CORE_BUS_USER              0x0100
+#define PLL_CON0_MUX_CLKCMU_CORE_CCI_USER              0x0120
+#define PLL_CON0_MUX_CLKCMU_CORE_G3D_USER              0x0140
+#define CLK_CON_MUX_MUX_CLK_CORE_GIC                   0x1000
+#define CLK_CON_DIV_DIV_CLK_CORE_BUSP                  0x1800
+#define CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK             0x2054
+#define CLK_CON_GAT_GOUT_CORE_GIC400_CLK               0x2058
+#define CLK_CON_GAT_GOUT_CORE_TREX_D_CORE_ACLK         0x215c
+#define CLK_CON_GAT_GOUT_CORE_TREX_D_CORE_GCLK         0x2160
+#define CLK_CON_GAT_GOUT_CORE_TREX_D_CORE_PCLK         0x2164
+#define CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_ACLK_P_CORE  0x2168
+#define CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_CCLK_P_CORE  0x216c
+#define CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_PCLK         0x2170
+#define CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_PCLK_P_CORE  0x2174
 
 static const unsigned long core_clk_regs[] __initconst = {
        PLL_CON0_MUX_CLKCMU_CORE_BUS_USER,
@@ -514,6 +594,13 @@ static const unsigned long core_clk_regs[] __initconst = {
        CLK_CON_DIV_DIV_CLK_CORE_BUSP,
        CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK,
        CLK_CON_GAT_GOUT_CORE_GIC400_CLK,
+       CLK_CON_GAT_GOUT_CORE_TREX_D_CORE_ACLK,
+       CLK_CON_GAT_GOUT_CORE_TREX_D_CORE_GCLK,
+       CLK_CON_GAT_GOUT_CORE_TREX_D_CORE_PCLK,
+       CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_ACLK_P_CORE,
+       CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_CCLK_P_CORE,
+       CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_PCLK,
+       CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_PCLK_P_CORE,
 };
 
 /* List of parent clocks for Muxes in CMU_CORE */
@@ -545,6 +632,27 @@ static const struct samsung_gate_clock core_gate_clks[] __initconst = {
        /* GIC (interrupt controller) clock must be always running */
        GATE(CLK_GOUT_GIC400_CLK, "gout_gic400_clk", "mout_core_gic",
             CLK_CON_GAT_GOUT_CORE_GIC400_CLK, 21, CLK_IS_CRITICAL, 0),
+       /*
+        * TREX D and P Core (seems to be related to "bus traffic shaper")
+        * clocks must always be running
+        */
+       GATE(CLK_GOUT_TREX_D_CORE_ACLK, "gout_trex_d_core_aclk", "mout_core_bus_user",
+            CLK_CON_GAT_GOUT_CORE_TREX_D_CORE_ACLK, 21, CLK_IS_CRITICAL, 0),
+       GATE(CLK_GOUT_TREX_D_CORE_GCLK, "gout_trex_d_core_gclk", "mout_core_g3d_user",
+            CLK_CON_GAT_GOUT_CORE_TREX_D_CORE_GCLK, 21, CLK_IS_CRITICAL, 0),
+       GATE(CLK_GOUT_TREX_D_CORE_PCLK, "gout_trex_d_core_pclk", "dout_core_busp",
+            CLK_CON_GAT_GOUT_CORE_TREX_D_CORE_PCLK, 21, CLK_IS_CRITICAL, 0),
+       GATE(CLK_GOUT_TREX_P_CORE_ACLK_P_CORE, "gout_trex_p_core_aclk_p_core",
+            "mout_core_bus_user", CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_ACLK_P_CORE, 21,
+            CLK_IS_CRITICAL, 0),
+       GATE(CLK_GOUT_TREX_P_CORE_CCLK_P_CORE, "gout_trex_p_core_cclk_p_core",
+            "mout_core_cci_user", CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_CCLK_P_CORE, 21,
+            CLK_IS_CRITICAL, 0),
+       GATE(CLK_GOUT_TREX_P_CORE_PCLK, "gout_trex_p_core_pclk", "dout_core_busp",
+            CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_PCLK, 21, CLK_IS_CRITICAL, 0),
+       GATE(CLK_GOUT_TREX_P_CORE_PCLK_P_CORE, "gout_trex_p_core_pclk_p_core",
+            "dout_core_busp", CLK_CON_GAT_GOUT_CORE_TREX_P_CORE_PCLK_P_CORE, 21,
+            CLK_IS_CRITICAL, 0),
 };
 
 static const struct samsung_cmu_info core_cmu_info __initconst = {
@@ -560,6 +668,88 @@ static const struct samsung_cmu_info core_cmu_info __initconst = {
        .clk_name               = "dout_core_bus",
 };
 
+/* ---- CMU_FSYS ------------------------------------------------------------ */
+
+/* Register Offset definitions for CMU_FSYS (0x13400000) */
+#define PLL_CON0_MUX_CLKCMU_FSYS_BUS_USER      0x0100
+#define PLL_CON0_MUX_CLKCMU_FSYS_MMC_CARD_USER 0x0120
+#define PLL_CON0_MUX_CLKCMU_FSYS_MMC_EMBD_USER 0x0140
+#define PLL_CON0_MUX_CLKCMU_FSYS_MMC_SDIO_USER 0x0160
+#define PLL_CON0_MUX_CLKCMU_FSYS_USB30DRD_USER 0x0180
+#define CLK_CON_GAT_GOUT_FSYS_MMC_CARD_I_ACLK  0x2030
+#define CLK_CON_GAT_GOUT_FSYS_MMC_CARD_SDCLKIN 0x2034
+#define CLK_CON_GAT_GOUT_FSYS_MMC_EMBD_I_ACLK  0x2038
+#define CLK_CON_GAT_GOUT_FSYS_MMC_EMBD_SDCLKIN 0x203c
+#define CLK_CON_GAT_GOUT_FSYS_MMC_SDIO_I_ACLK  0x2040
+#define CLK_CON_GAT_GOUT_FSYS_MMC_SDIO_SDCLKIN 0x2044
+
+static const unsigned long fsys_clk_regs[] __initconst = {
+       PLL_CON0_MUX_CLKCMU_FSYS_BUS_USER,
+       PLL_CON0_MUX_CLKCMU_FSYS_MMC_CARD_USER,
+       PLL_CON0_MUX_CLKCMU_FSYS_MMC_EMBD_USER,
+       PLL_CON0_MUX_CLKCMU_FSYS_MMC_SDIO_USER,
+       PLL_CON0_MUX_CLKCMU_FSYS_USB30DRD_USER,
+       CLK_CON_GAT_GOUT_FSYS_MMC_CARD_I_ACLK,
+       CLK_CON_GAT_GOUT_FSYS_MMC_CARD_SDCLKIN,
+       CLK_CON_GAT_GOUT_FSYS_MMC_EMBD_I_ACLK,
+       CLK_CON_GAT_GOUT_FSYS_MMC_EMBD_SDCLKIN,
+       CLK_CON_GAT_GOUT_FSYS_MMC_SDIO_I_ACLK,
+       CLK_CON_GAT_GOUT_FSYS_MMC_SDIO_SDCLKIN,
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS */
+PNAME(mout_fsys_bus_user_p)            = { "oscclk", "dout_fsys_bus" };
+PNAME(mout_fsys_mmc_card_user_p)       = { "oscclk", "dout_fsys_mmc_card" };
+PNAME(mout_fsys_mmc_embd_user_p)       = { "oscclk", "dout_fsys_mmc_embd" };
+PNAME(mout_fsys_mmc_sdio_user_p)       = { "oscclk", "dout_fsys_mmc_sdio" };
+PNAME(mout_fsys_usb30drd_user_p)       = { "oscclk", "dout_fsys_usb30drd" };
+
+static const struct samsung_mux_clock fsys_mux_clks[] __initconst = {
+       MUX(CLK_MOUT_FSYS_BUS_USER, "mout_fsys_bus_user", mout_fsys_bus_user_p,
+           PLL_CON0_MUX_CLKCMU_FSYS_BUS_USER, 4, 1),
+       MUX_F(CLK_MOUT_FSYS_MMC_CARD_USER, "mout_fsys_mmc_card_user",
+             mout_fsys_mmc_card_user_p, PLL_CON0_MUX_CLKCMU_FSYS_MMC_CARD_USER,
+             4, 1, CLK_SET_RATE_PARENT, 0),
+       MUX_F(CLK_MOUT_FSYS_MMC_EMBD_USER, "mout_fsys_mmc_embd_user",
+             mout_fsys_mmc_embd_user_p, PLL_CON0_MUX_CLKCMU_FSYS_MMC_EMBD_USER,
+             4, 1, CLK_SET_RATE_PARENT, 0),
+       MUX_F(CLK_MOUT_FSYS_MMC_SDIO_USER, "mout_fsys_mmc_sdio_user",
+             mout_fsys_mmc_sdio_user_p, PLL_CON0_MUX_CLKCMU_FSYS_MMC_SDIO_USER,
+             4, 1, CLK_SET_RATE_PARENT, 0),
+       MUX_F(CLK_MOUT_FSYS_USB30DRD_USER, "mout_fsys_usb30drd_user",
+             mout_fsys_usb30drd_user_p, PLL_CON0_MUX_CLKCMU_FSYS_USB30DRD_USER,
+             4, 1, CLK_SET_RATE_PARENT, 0),
+};
+
+static const struct samsung_gate_clock fsys_gate_clks[] __initconst = {
+       GATE(CLK_GOUT_MMC_CARD_ACLK, "gout_mmc_card_aclk", "mout_fsys_bus_user",
+            CLK_CON_GAT_GOUT_FSYS_MMC_CARD_I_ACLK, 21, 0, 0),
+       GATE(CLK_GOUT_MMC_CARD_SDCLKIN, "gout_mmc_card_sdclkin",
+            "mout_fsys_mmc_card_user", CLK_CON_GAT_GOUT_FSYS_MMC_CARD_SDCLKIN,
+            21, CLK_SET_RATE_PARENT, 0),
+       GATE(CLK_GOUT_MMC_EMBD_ACLK, "gout_mmc_embd_aclk", "mout_fsys_bus_user",
+            CLK_CON_GAT_GOUT_FSYS_MMC_EMBD_I_ACLK, 21, 0, 0),
+       GATE(CLK_GOUT_MMC_EMBD_SDCLKIN, "gout_mmc_embd_sdclkin",
+            "mout_fsys_mmc_embd_user", CLK_CON_GAT_GOUT_FSYS_MMC_EMBD_SDCLKIN,
+            21, CLK_SET_RATE_PARENT, 0),
+       GATE(CLK_GOUT_MMC_SDIO_ACLK, "gout_mmc_sdio_aclk", "mout_fsys_bus_user",
+            CLK_CON_GAT_GOUT_FSYS_MMC_SDIO_I_ACLK, 21, 0, 0),
+       GATE(CLK_GOUT_MMC_SDIO_SDCLKIN, "gout_mmc_sdio_sdclkin",
+            "mout_fsys_mmc_sdio_user", CLK_CON_GAT_GOUT_FSYS_MMC_SDIO_SDCLKIN,
+            21, CLK_SET_RATE_PARENT, 0),
+};
+
+static const struct samsung_cmu_info fsys_cmu_info __initconst = {
+       .mux_clks               = fsys_mux_clks,
+       .nr_mux_clks            = ARRAY_SIZE(fsys_mux_clks),
+       .gate_clks              = fsys_gate_clks,
+       .nr_gate_clks           = ARRAY_SIZE(fsys_gate_clks),
+       .nr_clk_ids             = FSYS_NR_CLK,
+       .clk_regs               = fsys_clk_regs,
+       .nr_clk_regs            = ARRAY_SIZE(fsys_clk_regs),
+       .clk_name               = "dout_fsys_bus",
+};
+
 /* ---- platform_driver ----------------------------------------------------- */
 
 static int __init exynos7885_cmu_probe(struct platform_device *pdev)
@@ -578,6 +768,9 @@ static const struct of_device_id exynos7885_cmu_of_match[] = {
                .compatible = "samsung,exynos7885-cmu-core",
                .data = &core_cmu_info,
        }, {
+               .compatible = "samsung,exynos7885-cmu-fsys",
+               .data = &fsys_cmu_info,
+       }, {
        },
 };
 
index cd9725f..541761e 100644 (file)
@@ -30,6 +30,7 @@
 #define PLL_CON0_PLL_SHARED1                   0x0180
 #define PLL_CON3_PLL_SHARED1                   0x018c
 #define CLK_CON_MUX_MUX_CLKCMU_APM_BUS         0x1000
+#define CLK_CON_MUX_MUX_CLKCMU_AUD             0x1004
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS                0x1014
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI                0x1018
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD   0x101c
 #define CLK_CON_MUX_MUX_CLKCMU_HSI_BUS         0x103c
 #define CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD    0x1040
 #define CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD    0x1044
+#define CLK_CON_MUX_MUX_CLKCMU_IS_BUS          0x1048
+#define CLK_CON_MUX_MUX_CLKCMU_IS_GDC          0x104c
+#define CLK_CON_MUX_MUX_CLKCMU_IS_ITP          0x1050
+#define CLK_CON_MUX_MUX_CLKCMU_IS_VRA          0x1054
+#define CLK_CON_MUX_MUX_CLKCMU_MFCMSCL_JPEG    0x1058
+#define CLK_CON_MUX_MUX_CLKCMU_MFCMSCL_M2M     0x105c
+#define CLK_CON_MUX_MUX_CLKCMU_MFCMSCL_MCSC    0x1060
+#define CLK_CON_MUX_MUX_CLKCMU_MFCMSCL_MFC     0x1064
 #define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS                0x1070
 #define CLK_CON_MUX_MUX_CLKCMU_PERI_IP         0x1074
 #define CLK_CON_MUX_MUX_CLKCMU_PERI_UART       0x1078
 #define CLK_CON_DIV_CLKCMU_APM_BUS             0x180c
+#define CLK_CON_DIV_CLKCMU_AUD                 0x1810
 #define CLK_CON_DIV_CLKCMU_CORE_BUS            0x1820
 #define CLK_CON_DIV_CLKCMU_CORE_CCI            0x1824
 #define CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD       0x1828
 #define CLK_CON_DIV_CLKCMU_HSI_BUS             0x1848
 #define CLK_CON_DIV_CLKCMU_HSI_MMC_CARD                0x184c
 #define CLK_CON_DIV_CLKCMU_HSI_USB20DRD                0x1850
+#define CLK_CON_DIV_CLKCMU_IS_BUS              0x1854
+#define CLK_CON_DIV_CLKCMU_IS_GDC              0x1858
+#define CLK_CON_DIV_CLKCMU_IS_ITP              0x185c
+#define CLK_CON_DIV_CLKCMU_IS_VRA              0x1860
+#define CLK_CON_DIV_CLKCMU_MFCMSCL_JPEG                0x1864
+#define CLK_CON_DIV_CLKCMU_MFCMSCL_M2M         0x1868
+#define CLK_CON_DIV_CLKCMU_MFCMSCL_MCSC                0x186c
+#define CLK_CON_DIV_CLKCMU_MFCMSCL_MFC         0x1870
 #define CLK_CON_DIV_CLKCMU_PERI_BUS            0x187c
 #define CLK_CON_DIV_CLKCMU_PERI_IP             0x1880
 #define CLK_CON_DIV_CLKCMU_PERI_UART           0x1884
@@ -60,6 +78,7 @@
 #define CLK_CON_DIV_PLL_SHARED1_DIV3           0x189c
 #define CLK_CON_DIV_PLL_SHARED1_DIV4           0x18a0
 #define CLK_CON_GAT_GATE_CLKCMU_APM_BUS                0x2008
+#define CLK_CON_GAT_GATE_CLKCMU_AUD            0x200c
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS       0x201c
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI       0x2020
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD  0x2024
 #define CLK_CON_GAT_GATE_CLKCMU_HSI_BUS                0x2044
 #define CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD   0x2048
 #define CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD   0x204c
+#define CLK_CON_GAT_GATE_CLKCMU_IS_BUS         0x2050
+#define CLK_CON_GAT_GATE_CLKCMU_IS_GDC         0x2054
+#define CLK_CON_GAT_GATE_CLKCMU_IS_ITP         0x2058
+#define CLK_CON_GAT_GATE_CLKCMU_IS_VRA         0x205c
+#define CLK_CON_GAT_GATE_CLKCMU_MFCMSCL_JPEG   0x2060
+#define CLK_CON_GAT_GATE_CLKCMU_MFCMSCL_M2M    0x2064
+#define CLK_CON_GAT_GATE_CLKCMU_MFCMSCL_MCSC   0x2068
+#define CLK_CON_GAT_GATE_CLKCMU_MFCMSCL_MFC    0x206c
 #define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS       0x2080
 #define CLK_CON_GAT_GATE_CLKCMU_PERI_IP                0x2084
 #define CLK_CON_GAT_GATE_CLKCMU_PERI_UART      0x2088
@@ -83,6 +110,7 @@ static const unsigned long top_clk_regs[] __initconst = {
        PLL_CON0_PLL_SHARED1,
        PLL_CON3_PLL_SHARED1,
        CLK_CON_MUX_MUX_CLKCMU_APM_BUS,
+       CLK_CON_MUX_MUX_CLKCMU_AUD,
        CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
        CLK_CON_MUX_MUX_CLKCMU_CORE_CCI,
        CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD,
@@ -91,10 +119,19 @@ static const unsigned long top_clk_regs[] __initconst = {
        CLK_CON_MUX_MUX_CLKCMU_HSI_BUS,
        CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD,
        CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD,
+       CLK_CON_MUX_MUX_CLKCMU_IS_BUS,
+       CLK_CON_MUX_MUX_CLKCMU_IS_GDC,
+       CLK_CON_MUX_MUX_CLKCMU_IS_ITP,
+       CLK_CON_MUX_MUX_CLKCMU_IS_VRA,
+       CLK_CON_MUX_MUX_CLKCMU_MFCMSCL_JPEG,
+       CLK_CON_MUX_MUX_CLKCMU_MFCMSCL_M2M,
+       CLK_CON_MUX_MUX_CLKCMU_MFCMSCL_MCSC,
+       CLK_CON_MUX_MUX_CLKCMU_MFCMSCL_MFC,
        CLK_CON_MUX_MUX_CLKCMU_PERI_BUS,
        CLK_CON_MUX_MUX_CLKCMU_PERI_IP,
        CLK_CON_MUX_MUX_CLKCMU_PERI_UART,
        CLK_CON_DIV_CLKCMU_APM_BUS,
+       CLK_CON_DIV_CLKCMU_AUD,
        CLK_CON_DIV_CLKCMU_CORE_BUS,
        CLK_CON_DIV_CLKCMU_CORE_CCI,
        CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD,
@@ -103,6 +140,14 @@ static const unsigned long top_clk_regs[] __initconst = {
        CLK_CON_DIV_CLKCMU_HSI_BUS,
        CLK_CON_DIV_CLKCMU_HSI_MMC_CARD,
        CLK_CON_DIV_CLKCMU_HSI_USB20DRD,
+       CLK_CON_DIV_CLKCMU_IS_BUS,
+       CLK_CON_DIV_CLKCMU_IS_GDC,
+       CLK_CON_DIV_CLKCMU_IS_ITP,
+       CLK_CON_DIV_CLKCMU_IS_VRA,
+       CLK_CON_DIV_CLKCMU_MFCMSCL_JPEG,
+       CLK_CON_DIV_CLKCMU_MFCMSCL_M2M,
+       CLK_CON_DIV_CLKCMU_MFCMSCL_MCSC,
+       CLK_CON_DIV_CLKCMU_MFCMSCL_MFC,
        CLK_CON_DIV_CLKCMU_PERI_BUS,
        CLK_CON_DIV_CLKCMU_PERI_IP,
        CLK_CON_DIV_CLKCMU_PERI_UART,
@@ -113,6 +158,7 @@ static const unsigned long top_clk_regs[] __initconst = {
        CLK_CON_DIV_PLL_SHARED1_DIV3,
        CLK_CON_DIV_PLL_SHARED1_DIV4,
        CLK_CON_GAT_GATE_CLKCMU_APM_BUS,
+       CLK_CON_GAT_GATE_CLKCMU_AUD,
        CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
        CLK_CON_GAT_GATE_CLKCMU_CORE_CCI,
        CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD,
@@ -121,6 +167,14 @@ static const unsigned long top_clk_regs[] __initconst = {
        CLK_CON_GAT_GATE_CLKCMU_HSI_BUS,
        CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD,
        CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD,
+       CLK_CON_GAT_GATE_CLKCMU_IS_BUS,
+       CLK_CON_GAT_GATE_CLKCMU_IS_GDC,
+       CLK_CON_GAT_GATE_CLKCMU_IS_ITP,
+       CLK_CON_GAT_GATE_CLKCMU_IS_VRA,
+       CLK_CON_GAT_GATE_CLKCMU_MFCMSCL_JPEG,
+       CLK_CON_GAT_GATE_CLKCMU_MFCMSCL_M2M,
+       CLK_CON_GAT_GATE_CLKCMU_MFCMSCL_MCSC,
+       CLK_CON_GAT_GATE_CLKCMU_MFCMSCL_MFC,
        CLK_CON_GAT_GATE_CLKCMU_PERI_BUS,
        CLK_CON_GAT_GATE_CLKCMU_PERI_IP,
        CLK_CON_GAT_GATE_CLKCMU_PERI_UART,
@@ -148,6 +202,9 @@ PNAME(mout_shared1_pll_p)   = { "oscclk", "fout_shared1_pll" };
 PNAME(mout_mmc_pll_p)          = { "oscclk", "fout_mmc_pll" };
 /* List of parent clocks for Muxes in CMU_TOP: for CMU_APM */
 PNAME(mout_clkcmu_apm_bus_p)   = { "dout_shared0_div4", "pll_shared1_div4" };
+/* List of parent clocks for Muxes in CMU_TOP: for CMU_AUD */
+PNAME(mout_aud_p)              = { "fout_shared1_pll", "dout_shared0_div2",
+                                   "dout_shared1_div2", "dout_shared0_div3" };
 /* List of parent clocks for Muxes in CMU_TOP: for CMU_CORE */
 PNAME(mout_core_bus_p)         = { "dout_shared1_div2", "dout_shared0_div3",
                                    "dout_shared1_div3", "dout_shared0_div4" };
@@ -167,13 +224,30 @@ PNAME(mout_hsi_mmc_card_p)        = { "oscclk", "dout_shared0_div2",
                                    "oscclk", "oscclk" };
 PNAME(mout_hsi_usb20drd_p)     = { "oscclk", "dout_shared0_div4",
                                    "dout_shared1_div4", "oscclk" };
+/* List of parent clocks for Muxes in CMU_TOP: for CMU_IS */
+PNAME(mout_is_bus_p)           = { "dout_shared0_div2", "dout_shared1_div2",
+                                   "dout_shared0_div3", "dout_shared1_div3" };
+PNAME(mout_is_itp_p)           = { "dout_shared0_div2", "dout_shared1_div2",
+                                   "dout_shared0_div3", "dout_shared1_div3" };
+PNAME(mout_is_vra_p)           = { "dout_shared0_div2", "dout_shared1_div2",
+                                   "dout_shared0_div3", "dout_shared1_div3" };
+PNAME(mout_is_gdc_p)           = { "dout_shared0_div2", "dout_shared1_div2",
+                                   "dout_shared0_div3", "dout_shared1_div3" };
+/* List of parent clocks for Muxes in CMU_TOP: for CMU_MFCMSCL */
+PNAME(mout_mfcmscl_mfc_p)      = { "dout_shared1_div2", "dout_shared0_div3",
+                                   "dout_shared1_div3", "dout_shared0_div4" };
+PNAME(mout_mfcmscl_m2m_p)      = { "dout_shared1_div2", "dout_shared0_div3",
+                                   "dout_shared1_div3", "dout_shared0_div4" };
+PNAME(mout_mfcmscl_mcsc_p)     = { "dout_shared1_div2", "dout_shared0_div3",
+                                   "dout_shared1_div3", "dout_shared0_div4" };
+PNAME(mout_mfcmscl_jpeg_p)     = { "dout_shared0_div3", "dout_shared1_div3",
+                                   "dout_shared0_div4", "dout_shared1_div4" };
 /* List of parent clocks for Muxes in CMU_TOP: for CMU_PERI */
 PNAME(mout_peri_bus_p)         = { "dout_shared0_div4", "dout_shared1_div4" };
 PNAME(mout_peri_uart_p)                = { "oscclk", "dout_shared0_div4",
                                    "dout_shared1_div4", "oscclk" };
 PNAME(mout_peri_ip_p)          = { "oscclk", "dout_shared0_div4",
                                    "dout_shared1_div4", "oscclk" };
-
 /* List of parent clocks for Muxes in CMU_TOP: for CMU_DPU */
 PNAME(mout_dpu_p)              = { "dout_shared0_div3", "dout_shared1_div3",
                                    "dout_shared0_div4", "dout_shared1_div4" };
@@ -191,6 +265,10 @@ static const struct samsung_mux_clock top_mux_clks[] __initconst = {
        MUX(CLK_MOUT_CLKCMU_APM_BUS, "mout_clkcmu_apm_bus",
            mout_clkcmu_apm_bus_p, CLK_CON_MUX_MUX_CLKCMU_APM_BUS, 0, 1),
 
+       /* AUD */
+       MUX(CLK_MOUT_AUD, "mout_aud", mout_aud_p,
+           CLK_CON_MUX_MUX_CLKCMU_AUD, 0, 2),
+
        /* CORE */
        MUX(CLK_MOUT_CORE_BUS, "mout_core_bus", mout_core_bus_p,
            CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 2),
@@ -213,6 +291,26 @@ static const struct samsung_mux_clock top_mux_clks[] __initconst = {
        MUX(CLK_MOUT_HSI_USB20DRD, "mout_hsi_usb20drd", mout_hsi_usb20drd_p,
            CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD, 0, 2),
 
+       /* IS */
+       MUX(CLK_MOUT_IS_BUS, "mout_is_bus", mout_is_bus_p,
+           CLK_CON_MUX_MUX_CLKCMU_IS_BUS, 0, 2),
+       MUX(CLK_MOUT_IS_ITP, "mout_is_itp", mout_is_itp_p,
+           CLK_CON_MUX_MUX_CLKCMU_IS_ITP, 0, 2),
+       MUX(CLK_MOUT_IS_VRA, "mout_is_vra", mout_is_vra_p,
+           CLK_CON_MUX_MUX_CLKCMU_IS_VRA, 0, 2),
+       MUX(CLK_MOUT_IS_GDC, "mout_is_gdc", mout_is_gdc_p,
+           CLK_CON_MUX_MUX_CLKCMU_IS_GDC, 0, 2),
+
+       /* MFCMSCL */
+       MUX(CLK_MOUT_MFCMSCL_MFC, "mout_mfcmscl_mfc", mout_mfcmscl_mfc_p,
+           CLK_CON_MUX_MUX_CLKCMU_MFCMSCL_MFC, 0, 2),
+       MUX(CLK_MOUT_MFCMSCL_M2M, "mout_mfcmscl_m2m", mout_mfcmscl_m2m_p,
+           CLK_CON_MUX_MUX_CLKCMU_MFCMSCL_M2M, 0, 2),
+       MUX(CLK_MOUT_MFCMSCL_MCSC, "mout_mfcmscl_mcsc", mout_mfcmscl_mcsc_p,
+           CLK_CON_MUX_MUX_CLKCMU_MFCMSCL_MCSC, 0, 2),
+       MUX(CLK_MOUT_MFCMSCL_JPEG, "mout_mfcmscl_jpeg", mout_mfcmscl_jpeg_p,
+           CLK_CON_MUX_MUX_CLKCMU_MFCMSCL_JPEG, 0, 2),
+
        /* PERI */
        MUX(CLK_MOUT_PERI_BUS, "mout_peri_bus", mout_peri_bus_p,
            CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, 0, 1),
@@ -241,6 +339,10 @@ static const struct samsung_div_clock top_div_clks[] __initconst = {
        DIV(CLK_DOUT_CLKCMU_APM_BUS, "dout_clkcmu_apm_bus",
            "gout_clkcmu_apm_bus", CLK_CON_DIV_CLKCMU_APM_BUS, 0, 3),
 
+       /* AUD */
+       DIV(CLK_DOUT_AUD, "dout_aud", "gout_aud",
+           CLK_CON_DIV_CLKCMU_AUD, 0, 4),
+
        /* CORE */
        DIV(CLK_DOUT_CORE_BUS, "dout_core_bus", "gout_core_bus",
            CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 4),
@@ -263,6 +365,26 @@ static const struct samsung_div_clock top_div_clks[] __initconst = {
        DIV(CLK_DOUT_HSI_USB20DRD, "dout_hsi_usb20drd", "gout_hsi_usb20drd",
            CLK_CON_DIV_CLKCMU_HSI_USB20DRD, 0, 4),
 
+       /* IS */
+       DIV(CLK_DOUT_IS_BUS, "dout_is_bus", "gout_is_bus",
+           CLK_CON_DIV_CLKCMU_IS_BUS, 0, 4),
+       DIV(CLK_DOUT_IS_ITP, "dout_is_itp", "gout_is_itp",
+           CLK_CON_DIV_CLKCMU_IS_ITP, 0, 4),
+       DIV(CLK_DOUT_IS_VRA, "dout_is_vra", "gout_is_vra",
+           CLK_CON_DIV_CLKCMU_IS_VRA, 0, 4),
+       DIV(CLK_DOUT_IS_GDC, "dout_is_gdc", "gout_is_gdc",
+           CLK_CON_DIV_CLKCMU_IS_GDC, 0, 4),
+
+       /* MFCMSCL */
+       DIV(CLK_DOUT_MFCMSCL_MFC, "dout_mfcmscl_mfc", "gout_mfcmscl_mfc",
+           CLK_CON_DIV_CLKCMU_MFCMSCL_MFC, 0, 4),
+       DIV(CLK_DOUT_MFCMSCL_M2M, "dout_mfcmscl_m2m", "gout_mfcmscl_m2m",
+           CLK_CON_DIV_CLKCMU_MFCMSCL_M2M, 0, 4),
+       DIV(CLK_DOUT_MFCMSCL_MCSC, "dout_mfcmscl_mcsc", "gout_mfcmscl_mcsc",
+           CLK_CON_DIV_CLKCMU_MFCMSCL_MCSC, 0, 4),
+       DIV(CLK_DOUT_MFCMSCL_JPEG, "dout_mfcmscl_jpeg", "gout_mfcmscl_jpeg",
+           CLK_CON_DIV_CLKCMU_MFCMSCL_JPEG, 0, 4),
+
        /* PERI */
        DIV(CLK_DOUT_PERI_BUS, "dout_peri_bus", "gout_peri_bus",
            CLK_CON_DIV_CLKCMU_PERI_BUS, 0, 4),
@@ -287,6 +409,10 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
        GATE(CLK_GOUT_CLKCMU_APM_BUS, "gout_clkcmu_apm_bus",
             "mout_clkcmu_apm_bus", CLK_CON_GAT_GATE_CLKCMU_APM_BUS, 21, 0, 0),
 
+       /* AUD */
+       GATE(CLK_GOUT_AUD, "gout_aud", "mout_aud",
+            CLK_CON_GAT_GATE_CLKCMU_AUD, 21, 0, 0),
+
        /* DPU */
        GATE(CLK_GOUT_DPU, "gout_dpu", "mout_dpu",
             CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0),
@@ -299,6 +425,28 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
        GATE(CLK_GOUT_HSI_USB20DRD, "gout_hsi_usb20drd", "mout_hsi_usb20drd",
             CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD, 21, 0, 0),
 
+       /* IS */
+       /* TODO: These clocks have to be always enabled to access CMU_IS regs */
+       GATE(CLK_GOUT_IS_BUS, "gout_is_bus", "mout_is_bus",
+            CLK_CON_GAT_GATE_CLKCMU_IS_BUS, 21, CLK_IS_CRITICAL, 0),
+       GATE(CLK_GOUT_IS_ITP, "gout_is_itp", "mout_is_itp",
+            CLK_CON_GAT_GATE_CLKCMU_IS_ITP, 21, CLK_IS_CRITICAL, 0),
+       GATE(CLK_GOUT_IS_VRA, "gout_is_vra", "mout_is_vra",
+            CLK_CON_GAT_GATE_CLKCMU_IS_VRA, 21, CLK_IS_CRITICAL, 0),
+       GATE(CLK_GOUT_IS_GDC, "gout_is_gdc", "mout_is_gdc",
+            CLK_CON_GAT_GATE_CLKCMU_IS_GDC, 21, CLK_IS_CRITICAL, 0),
+
+       /* MFCMSCL */
+       /* TODO: These have to be always enabled to access CMU_MFCMSCL regs */
+       GATE(CLK_GOUT_MFCMSCL_MFC, "gout_mfcmscl_mfc", "mout_mfcmscl_mfc",
+            CLK_CON_GAT_GATE_CLKCMU_MFCMSCL_MFC, 21, CLK_IS_CRITICAL, 0),
+       GATE(CLK_GOUT_MFCMSCL_M2M, "gout_mfcmscl_m2m", "mout_mfcmscl_m2m",
+            CLK_CON_GAT_GATE_CLKCMU_MFCMSCL_M2M, 21, CLK_IS_CRITICAL, 0),
+       GATE(CLK_GOUT_MFCMSCL_MCSC, "gout_mfcmscl_mcsc", "mout_mfcmscl_mcsc",
+            CLK_CON_GAT_GATE_CLKCMU_MFCMSCL_MCSC, 21, CLK_IS_CRITICAL, 0),
+       GATE(CLK_GOUT_MFCMSCL_JPEG, "gout_mfcmscl_jpeg", "mout_mfcmscl_jpeg",
+            CLK_CON_GAT_GATE_CLKCMU_MFCMSCL_JPEG, 21, CLK_IS_CRITICAL, 0),
+
        /* PERI */
        GATE(CLK_GOUT_PERI_BUS, "gout_peri_bus", "mout_peri_bus",
             CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, 21, 0, 0),
@@ -463,6 +611,284 @@ static const struct samsung_cmu_info apm_cmu_info __initconst = {
        .clk_name               = "dout_clkcmu_apm_bus",
 };
 
+/* ---- CMU_AUD ------------------------------------------------------------- */
+
+#define PLL_LOCKTIME_PLL_AUD                   0x0000
+#define PLL_CON0_PLL_AUD                       0x0100
+#define PLL_CON3_PLL_AUD                       0x010c
+#define PLL_CON0_MUX_CLKCMU_AUD_CPU_USER       0x0600
+#define PLL_CON0_MUX_TICK_USB_USER             0x0610
+#define CLK_CON_MUX_MUX_CLK_AUD_CPU            0x1000
+#define CLK_CON_MUX_MUX_CLK_AUD_CPU_HCH                0x1004
+#define CLK_CON_MUX_MUX_CLK_AUD_FM             0x1008
+#define CLK_CON_MUX_MUX_CLK_AUD_UAIF0          0x100c
+#define CLK_CON_MUX_MUX_CLK_AUD_UAIF1          0x1010
+#define CLK_CON_MUX_MUX_CLK_AUD_UAIF2          0x1014
+#define CLK_CON_MUX_MUX_CLK_AUD_UAIF3          0x1018
+#define CLK_CON_MUX_MUX_CLK_AUD_UAIF4          0x101c
+#define CLK_CON_MUX_MUX_CLK_AUD_UAIF5          0x1020
+#define CLK_CON_MUX_MUX_CLK_AUD_UAIF6          0x1024
+#define CLK_CON_DIV_DIV_CLK_AUD_MCLK           0x1800
+#define CLK_CON_DIV_DIV_CLK_AUD_AUDIF          0x1804
+#define CLK_CON_DIV_DIV_CLK_AUD_BUSD           0x1808
+#define CLK_CON_DIV_DIV_CLK_AUD_BUSP           0x180c
+#define CLK_CON_DIV_DIV_CLK_AUD_CNT            0x1810
+#define CLK_CON_DIV_DIV_CLK_AUD_CPU            0x1814
+#define CLK_CON_DIV_DIV_CLK_AUD_CPU_ACLK       0x1818
+#define CLK_CON_DIV_DIV_CLK_AUD_CPU_PCLKDBG    0x181c
+#define CLK_CON_DIV_DIV_CLK_AUD_FM             0x1820
+#define CLK_CON_DIV_DIV_CLK_AUD_FM_SPDY                0x1824
+#define CLK_CON_DIV_DIV_CLK_AUD_UAIF0          0x1828
+#define CLK_CON_DIV_DIV_CLK_AUD_UAIF1          0x182c
+#define CLK_CON_DIV_DIV_CLK_AUD_UAIF2          0x1830
+#define CLK_CON_DIV_DIV_CLK_AUD_UAIF3          0x1834
+#define CLK_CON_DIV_DIV_CLK_AUD_UAIF4          0x1838
+#define CLK_CON_DIV_DIV_CLK_AUD_UAIF5          0x183c
+#define CLK_CON_DIV_DIV_CLK_AUD_UAIF6          0x1840
+#define CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_CNT     0x2000
+#define CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF0   0x2004
+#define CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF1   0x2008
+#define CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF2   0x200c
+#define CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF3   0x2010
+#define CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF4   0x2014
+#define CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF5   0x2018
+#define CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF6   0x201c
+#define CLK_CON_GAT_GOUT_AUD_ABOX_ACLK         0x2048
+#define CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_SPDY    0x204c
+#define CLK_CON_GAT_GOUT_AUD_ABOX_CCLK_ASB     0x2050
+#define CLK_CON_GAT_GOUT_AUD_ABOX_CCLK_CA32    0x2054
+#define CLK_CON_GAT_GOUT_AUD_ABOX_CCLK_DAP     0x2058
+#define CLK_CON_GAT_GOUT_AUD_CODEC_MCLK                0x206c
+#define CLK_CON_GAT_GOUT_AUD_TZPC_PCLK         0x2070
+#define CLK_CON_GAT_GOUT_AUD_GPIO_PCLK         0x2074
+#define CLK_CON_GAT_GOUT_AUD_PPMU_ACLK         0x2088
+#define CLK_CON_GAT_GOUT_AUD_PPMU_PCLK         0x208c
+#define CLK_CON_GAT_GOUT_AUD_SYSMMU_CLK_S1     0x20b4
+#define CLK_CON_GAT_GOUT_AUD_SYSREG_PCLK       0x20b8
+#define CLK_CON_GAT_GOUT_AUD_WDT_PCLK          0x20bc
+
+static const unsigned long aud_clk_regs[] __initconst = {
+       PLL_LOCKTIME_PLL_AUD,
+       PLL_CON0_PLL_AUD,
+       PLL_CON3_PLL_AUD,
+       PLL_CON0_MUX_CLKCMU_AUD_CPU_USER,
+       PLL_CON0_MUX_TICK_USB_USER,
+       CLK_CON_MUX_MUX_CLK_AUD_CPU,
+       CLK_CON_MUX_MUX_CLK_AUD_CPU_HCH,
+       CLK_CON_MUX_MUX_CLK_AUD_FM,
+       CLK_CON_MUX_MUX_CLK_AUD_UAIF0,
+       CLK_CON_MUX_MUX_CLK_AUD_UAIF1,
+       CLK_CON_MUX_MUX_CLK_AUD_UAIF2,
+       CLK_CON_MUX_MUX_CLK_AUD_UAIF3,
+       CLK_CON_MUX_MUX_CLK_AUD_UAIF4,
+       CLK_CON_MUX_MUX_CLK_AUD_UAIF5,
+       CLK_CON_MUX_MUX_CLK_AUD_UAIF6,
+       CLK_CON_DIV_DIV_CLK_AUD_MCLK,
+       CLK_CON_DIV_DIV_CLK_AUD_AUDIF,
+       CLK_CON_DIV_DIV_CLK_AUD_BUSD,
+       CLK_CON_DIV_DIV_CLK_AUD_BUSP,
+       CLK_CON_DIV_DIV_CLK_AUD_CNT,
+       CLK_CON_DIV_DIV_CLK_AUD_CPU,
+       CLK_CON_DIV_DIV_CLK_AUD_CPU_ACLK,
+       CLK_CON_DIV_DIV_CLK_AUD_CPU_PCLKDBG,
+       CLK_CON_DIV_DIV_CLK_AUD_FM,
+       CLK_CON_DIV_DIV_CLK_AUD_FM_SPDY,
+       CLK_CON_DIV_DIV_CLK_AUD_UAIF0,
+       CLK_CON_DIV_DIV_CLK_AUD_UAIF1,
+       CLK_CON_DIV_DIV_CLK_AUD_UAIF2,
+       CLK_CON_DIV_DIV_CLK_AUD_UAIF3,
+       CLK_CON_DIV_DIV_CLK_AUD_UAIF4,
+       CLK_CON_DIV_DIV_CLK_AUD_UAIF5,
+       CLK_CON_DIV_DIV_CLK_AUD_UAIF6,
+       CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_CNT,
+       CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF0,
+       CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF1,
+       CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF2,
+       CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF3,
+       CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF4,
+       CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF5,
+       CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF6,
+       CLK_CON_GAT_GOUT_AUD_ABOX_ACLK,
+       CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_SPDY,
+       CLK_CON_GAT_GOUT_AUD_ABOX_CCLK_ASB,
+       CLK_CON_GAT_GOUT_AUD_ABOX_CCLK_CA32,
+       CLK_CON_GAT_GOUT_AUD_ABOX_CCLK_DAP,
+       CLK_CON_GAT_GOUT_AUD_CODEC_MCLK,
+       CLK_CON_GAT_GOUT_AUD_TZPC_PCLK,
+       CLK_CON_GAT_GOUT_AUD_GPIO_PCLK,
+       CLK_CON_GAT_GOUT_AUD_PPMU_ACLK,
+       CLK_CON_GAT_GOUT_AUD_PPMU_PCLK,
+       CLK_CON_GAT_GOUT_AUD_SYSMMU_CLK_S1,
+       CLK_CON_GAT_GOUT_AUD_SYSREG_PCLK,
+       CLK_CON_GAT_GOUT_AUD_WDT_PCLK,
+};
+
+/* List of parent clocks for Muxes in CMU_AUD */
+PNAME(mout_aud_pll_p)          = { "oscclk", "fout_aud_pll" };
+PNAME(mout_aud_cpu_user_p)     = { "oscclk", "dout_aud" };
+PNAME(mout_aud_cpu_p)          = { "dout_aud_cpu", "mout_aud_cpu_user" };
+PNAME(mout_aud_cpu_hch_p)      = { "mout_aud_cpu", "oscclk" };
+PNAME(mout_aud_uaif0_p)                = { "dout_aud_uaif0", "ioclk_audiocdclk0" };
+PNAME(mout_aud_uaif1_p)                = { "dout_aud_uaif1", "ioclk_audiocdclk1" };
+PNAME(mout_aud_uaif2_p)                = { "dout_aud_uaif2", "ioclk_audiocdclk2" };
+PNAME(mout_aud_uaif3_p)                = { "dout_aud_uaif3", "ioclk_audiocdclk3" };
+PNAME(mout_aud_uaif4_p)                = { "dout_aud_uaif4", "ioclk_audiocdclk4" };
+PNAME(mout_aud_uaif5_p)                = { "dout_aud_uaif5", "ioclk_audiocdclk5" };
+PNAME(mout_aud_uaif6_p)                = { "dout_aud_uaif6", "ioclk_audiocdclk6" };
+PNAME(mout_aud_tick_usb_user_p)        = { "oscclk", "tick_usb" };
+PNAME(mout_aud_fm_p)           = { "oscclk", "dout_aud_fm_spdy" };
+
+/*
+ * Do not provide PLL table to PLL_AUD, as MANUAL_PLL_CTRL bit is not set
+ * for that PLL by default, so set_rate operation would fail.
+ */
+static const struct samsung_pll_clock aud_pll_clks[] __initconst = {
+       PLL(pll_0831x, CLK_FOUT_AUD_PLL, "fout_aud_pll", "oscclk",
+           PLL_LOCKTIME_PLL_AUD, PLL_CON3_PLL_AUD, NULL),
+};
+
+static const struct samsung_fixed_rate_clock aud_fixed_clks[] __initconst = {
+       FRATE(IOCLK_AUDIOCDCLK0, "ioclk_audiocdclk0", NULL, 0, 25000000),
+       FRATE(IOCLK_AUDIOCDCLK1, "ioclk_audiocdclk1", NULL, 0, 25000000),
+       FRATE(IOCLK_AUDIOCDCLK2, "ioclk_audiocdclk2", NULL, 0, 25000000),
+       FRATE(IOCLK_AUDIOCDCLK3, "ioclk_audiocdclk3", NULL, 0, 25000000),
+       FRATE(IOCLK_AUDIOCDCLK4, "ioclk_audiocdclk4", NULL, 0, 25000000),
+       FRATE(IOCLK_AUDIOCDCLK5, "ioclk_audiocdclk5", NULL, 0, 25000000),
+       FRATE(IOCLK_AUDIOCDCLK6, "ioclk_audiocdclk6", NULL, 0, 25000000),
+       FRATE(TICK_USB, "tick_usb", NULL, 0, 60000000),
+};
+
+static const struct samsung_mux_clock aud_mux_clks[] __initconst = {
+       MUX(CLK_MOUT_AUD_PLL, "mout_aud_pll", mout_aud_pll_p,
+           PLL_CON0_PLL_AUD, 4, 1),
+       MUX(CLK_MOUT_AUD_CPU_USER, "mout_aud_cpu_user", mout_aud_cpu_user_p,
+           PLL_CON0_MUX_CLKCMU_AUD_CPU_USER, 4, 1),
+       MUX(CLK_MOUT_AUD_TICK_USB_USER, "mout_aud_tick_usb_user",
+           mout_aud_tick_usb_user_p,
+           PLL_CON0_MUX_TICK_USB_USER, 4, 1),
+       MUX(CLK_MOUT_AUD_CPU, "mout_aud_cpu", mout_aud_cpu_p,
+           CLK_CON_MUX_MUX_CLK_AUD_CPU, 0, 1),
+       MUX(CLK_MOUT_AUD_CPU_HCH, "mout_aud_cpu_hch", mout_aud_cpu_hch_p,
+           CLK_CON_MUX_MUX_CLK_AUD_CPU_HCH, 0, 1),
+       MUX(CLK_MOUT_AUD_UAIF0, "mout_aud_uaif0", mout_aud_uaif0_p,
+           CLK_CON_MUX_MUX_CLK_AUD_UAIF0, 0, 1),
+       MUX(CLK_MOUT_AUD_UAIF1, "mout_aud_uaif1", mout_aud_uaif1_p,
+           CLK_CON_MUX_MUX_CLK_AUD_UAIF1, 0, 1),
+       MUX(CLK_MOUT_AUD_UAIF2, "mout_aud_uaif2", mout_aud_uaif2_p,
+           CLK_CON_MUX_MUX_CLK_AUD_UAIF2, 0, 1),
+       MUX(CLK_MOUT_AUD_UAIF3, "mout_aud_uaif3", mout_aud_uaif3_p,
+           CLK_CON_MUX_MUX_CLK_AUD_UAIF3, 0, 1),
+       MUX(CLK_MOUT_AUD_UAIF4, "mout_aud_uaif4", mout_aud_uaif4_p,
+           CLK_CON_MUX_MUX_CLK_AUD_UAIF4, 0, 1),
+       MUX(CLK_MOUT_AUD_UAIF5, "mout_aud_uaif5", mout_aud_uaif5_p,
+           CLK_CON_MUX_MUX_CLK_AUD_UAIF5, 0, 1),
+       MUX(CLK_MOUT_AUD_UAIF6, "mout_aud_uaif6", mout_aud_uaif6_p,
+           CLK_CON_MUX_MUX_CLK_AUD_UAIF6, 0, 1),
+       MUX(CLK_MOUT_AUD_FM, "mout_aud_fm", mout_aud_fm_p,
+           CLK_CON_MUX_MUX_CLK_AUD_FM, 0, 1),
+};
+
+static const struct samsung_div_clock aud_div_clks[] __initconst = {
+       DIV(CLK_DOUT_AUD_CPU, "dout_aud_cpu", "mout_aud_pll",
+           CLK_CON_DIV_DIV_CLK_AUD_CPU, 0, 4),
+       DIV(CLK_DOUT_AUD_BUSD, "dout_aud_busd", "mout_aud_pll",
+           CLK_CON_DIV_DIV_CLK_AUD_BUSD, 0, 4),
+       DIV(CLK_DOUT_AUD_BUSP, "dout_aud_busp", "mout_aud_pll",
+           CLK_CON_DIV_DIV_CLK_AUD_BUSP, 0, 4),
+       DIV(CLK_DOUT_AUD_AUDIF, "dout_aud_audif", "mout_aud_pll",
+           CLK_CON_DIV_DIV_CLK_AUD_AUDIF, 0, 9),
+       DIV(CLK_DOUT_AUD_CPU_ACLK, "dout_aud_cpu_aclk", "mout_aud_cpu_hch",
+           CLK_CON_DIV_DIV_CLK_AUD_CPU_ACLK, 0, 3),
+       DIV(CLK_DOUT_AUD_CPU_PCLKDBG, "dout_aud_cpu_pclkdbg",
+           "mout_aud_cpu_hch",
+           CLK_CON_DIV_DIV_CLK_AUD_CPU_PCLKDBG, 0, 3),
+       DIV(CLK_DOUT_AUD_MCLK, "dout_aud_mclk", "dout_aud_audif",
+           CLK_CON_DIV_DIV_CLK_AUD_MCLK, 0, 2),
+       DIV(CLK_DOUT_AUD_CNT, "dout_aud_cnt", "dout_aud_audif",
+           CLK_CON_DIV_DIV_CLK_AUD_CNT, 0, 10),
+       DIV(CLK_DOUT_AUD_UAIF0, "dout_aud_uaif0", "dout_aud_audif",
+           CLK_CON_DIV_DIV_CLK_AUD_UAIF0, 0, 10),
+       DIV(CLK_DOUT_AUD_UAIF1, "dout_aud_uaif1", "dout_aud_audif",
+           CLK_CON_DIV_DIV_CLK_AUD_UAIF1, 0, 10),
+       DIV(CLK_DOUT_AUD_UAIF2, "dout_aud_uaif2", "dout_aud_audif",
+           CLK_CON_DIV_DIV_CLK_AUD_UAIF2, 0, 10),
+       DIV(CLK_DOUT_AUD_UAIF3, "dout_aud_uaif3", "dout_aud_audif",
+           CLK_CON_DIV_DIV_CLK_AUD_UAIF3, 0, 10),
+       DIV(CLK_DOUT_AUD_UAIF4, "dout_aud_uaif4", "dout_aud_audif",
+           CLK_CON_DIV_DIV_CLK_AUD_UAIF4, 0, 10),
+       DIV(CLK_DOUT_AUD_UAIF5, "dout_aud_uaif5", "dout_aud_audif",
+           CLK_CON_DIV_DIV_CLK_AUD_UAIF5, 0, 10),
+       DIV(CLK_DOUT_AUD_UAIF6, "dout_aud_uaif6", "dout_aud_audif",
+           CLK_CON_DIV_DIV_CLK_AUD_UAIF6, 0, 10),
+       DIV(CLK_DOUT_AUD_FM_SPDY, "dout_aud_fm_spdy", "mout_aud_tick_usb_user",
+           CLK_CON_DIV_DIV_CLK_AUD_FM_SPDY, 0, 1),
+       DIV(CLK_DOUT_AUD_FM, "dout_aud_fm", "mout_aud_fm",
+           CLK_CON_DIV_DIV_CLK_AUD_FM, 0, 10),
+};
+
+static const struct samsung_gate_clock aud_gate_clks[] __initconst = {
+       GATE(CLK_GOUT_AUD_CA32_CCLK, "gout_aud_ca32_cclk", "mout_aud_cpu_hch",
+            CLK_CON_GAT_GOUT_AUD_ABOX_CCLK_CA32, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_ASB_CCLK, "gout_aud_asb_cclk", "dout_aud_cpu_aclk",
+            CLK_CON_GAT_GOUT_AUD_ABOX_CCLK_ASB, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_DAP_CCLK, "gout_aud_dap_cclk", "dout_aud_cpu_pclkdbg",
+            CLK_CON_GAT_GOUT_AUD_ABOX_CCLK_DAP, 21, 0, 0),
+       /* TODO: Should be enabled in ABOX driver (or made CLK_IS_CRITICAL) */
+       GATE(CLK_GOUT_AUD_ABOX_ACLK, "gout_aud_abox_aclk", "dout_aud_busd",
+            CLK_CON_GAT_GOUT_AUD_ABOX_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+       GATE(CLK_GOUT_AUD_GPIO_PCLK, "gout_aud_gpio_pclk", "dout_aud_busd",
+            CLK_CON_GAT_GOUT_AUD_GPIO_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_PPMU_ACLK, "gout_aud_ppmu_aclk", "dout_aud_busd",
+            CLK_CON_GAT_GOUT_AUD_PPMU_ACLK, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_PPMU_PCLK, "gout_aud_ppmu_pclk", "dout_aud_busd",
+            CLK_CON_GAT_GOUT_AUD_PPMU_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_SYSMMU_CLK, "gout_aud_sysmmu_clk", "dout_aud_busd",
+            CLK_CON_GAT_GOUT_AUD_SYSMMU_CLK_S1, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_SYSREG_PCLK, "gout_aud_sysreg_pclk", "dout_aud_busd",
+            CLK_CON_GAT_GOUT_AUD_SYSREG_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_WDT_PCLK, "gout_aud_wdt_pclk", "dout_aud_busd",
+            CLK_CON_GAT_GOUT_AUD_WDT_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_TZPC_PCLK, "gout_aud_tzpc_pclk", "dout_aud_busp",
+            CLK_CON_GAT_GOUT_AUD_TZPC_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_CODEC_MCLK, "gout_aud_codec_mclk", "dout_aud_mclk",
+            CLK_CON_GAT_GOUT_AUD_CODEC_MCLK, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_CNT_BCLK, "gout_aud_cnt_bclk", "dout_aud_cnt",
+            CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_CNT, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_UAIF0_BCLK, "gout_aud_uaif0_bclk", "mout_aud_uaif0",
+            CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF0, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_UAIF1_BCLK, "gout_aud_uaif1_bclk", "mout_aud_uaif1",
+            CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF1, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_UAIF2_BCLK, "gout_aud_uaif2_bclk", "mout_aud_uaif2",
+            CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF2, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_UAIF3_BCLK, "gout_aud_uaif3_bclk", "mout_aud_uaif3",
+            CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF3, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_UAIF4_BCLK, "gout_aud_uaif4_bclk", "mout_aud_uaif4",
+            CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF4, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_UAIF5_BCLK, "gout_aud_uaif5_bclk", "mout_aud_uaif5",
+            CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF5, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_UAIF6_BCLK, "gout_aud_uaif6_bclk", "mout_aud_uaif6",
+            CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF6, 21, 0, 0),
+       GATE(CLK_GOUT_AUD_SPDY_BCLK, "gout_aud_spdy_bclk", "dout_aud_fm",
+            CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_SPDY, 21, 0, 0),
+};
+
+static const struct samsung_cmu_info aud_cmu_info __initconst = {
+       .pll_clks               = aud_pll_clks,
+       .nr_pll_clks            = ARRAY_SIZE(aud_pll_clks),
+       .mux_clks               = aud_mux_clks,
+       .nr_mux_clks            = ARRAY_SIZE(aud_mux_clks),
+       .div_clks               = aud_div_clks,
+       .nr_div_clks            = ARRAY_SIZE(aud_div_clks),
+       .gate_clks              = aud_gate_clks,
+       .nr_gate_clks           = ARRAY_SIZE(aud_gate_clks),
+       .fixed_clks             = aud_fixed_clks,
+       .nr_fixed_clks          = ARRAY_SIZE(aud_fixed_clks),
+       .nr_clk_ids             = AUD_NR_CLK,
+       .clk_regs               = aud_clk_regs,
+       .nr_clk_regs            = ARRAY_SIZE(aud_clk_regs),
+       .clk_name               = "dout_aud",
+};
+
 /* ---- CMU_CMGP ------------------------------------------------------------ */
 
 /* Register Offset definitions for CMU_CMGP (0x11c00000) */
@@ -599,7 +1025,7 @@ static const unsigned long hsi_clk_regs[] __initconst = {
        CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY,
 };
 
-/* List of parent clocks for Muxes in CMU_PERI */
+/* List of parent clocks for Muxes in CMU_HSI */
 PNAME(mout_hsi_bus_user_p)     = { "oscclk", "dout_hsi_bus" };
 PNAME(mout_hsi_mmc_card_user_p)        = { "oscclk", "dout_hsi_mmc_card" };
 PNAME(mout_hsi_usb20drd_user_p)        = { "oscclk", "dout_hsi_usb20drd" };
@@ -654,6 +1080,247 @@ static const struct samsung_cmu_info hsi_cmu_info __initconst = {
        .clk_name               = "dout_hsi_bus",
 };
 
+/* ---- CMU_IS -------------------------------------------------------------- */
+
+#define PLL_CON0_MUX_CLKCMU_IS_BUS_USER                0x0600
+#define PLL_CON0_MUX_CLKCMU_IS_GDC_USER                0x0610
+#define PLL_CON0_MUX_CLKCMU_IS_ITP_USER                0x0620
+#define PLL_CON0_MUX_CLKCMU_IS_VRA_USER                0x0630
+#define CLK_CON_DIV_DIV_CLK_IS_BUSP            0x1800
+#define CLK_CON_GAT_CLK_IS_CMU_IS_PCLK         0x2000
+#define CLK_CON_GAT_GOUT_IS_CSIS0_ACLK         0x2040
+#define CLK_CON_GAT_GOUT_IS_CSIS1_ACLK         0x2044
+#define CLK_CON_GAT_GOUT_IS_CSIS2_ACLK         0x2048
+#define CLK_CON_GAT_GOUT_IS_TZPC_PCLK          0x204c
+#define CLK_CON_GAT_GOUT_IS_CLK_CSIS_DMA       0x2050
+#define CLK_CON_GAT_GOUT_IS_CLK_GDC            0x2054
+#define CLK_CON_GAT_GOUT_IS_CLK_IPP            0x2058
+#define CLK_CON_GAT_GOUT_IS_CLK_ITP            0x205c
+#define CLK_CON_GAT_GOUT_IS_CLK_MCSC           0x2060
+#define CLK_CON_GAT_GOUT_IS_CLK_VRA            0x2064
+#define CLK_CON_GAT_GOUT_IS_PPMU_IS0_ACLK      0x2074
+#define CLK_CON_GAT_GOUT_IS_PPMU_IS0_PCLK      0x2078
+#define CLK_CON_GAT_GOUT_IS_PPMU_IS1_ACLK      0x207c
+#define CLK_CON_GAT_GOUT_IS_PPMU_IS1_PCLK      0x2080
+#define CLK_CON_GAT_GOUT_IS_SYSMMU_IS0_CLK_S1  0x2098
+#define CLK_CON_GAT_GOUT_IS_SYSMMU_IS1_CLK_S1  0x209c
+#define CLK_CON_GAT_GOUT_IS_SYSREG_PCLK                0x20a0
+
+static const unsigned long is_clk_regs[] __initconst = {
+       PLL_CON0_MUX_CLKCMU_IS_BUS_USER,
+       PLL_CON0_MUX_CLKCMU_IS_GDC_USER,
+       PLL_CON0_MUX_CLKCMU_IS_ITP_USER,
+       PLL_CON0_MUX_CLKCMU_IS_VRA_USER,
+       CLK_CON_DIV_DIV_CLK_IS_BUSP,
+       CLK_CON_GAT_CLK_IS_CMU_IS_PCLK,
+       CLK_CON_GAT_GOUT_IS_CSIS0_ACLK,
+       CLK_CON_GAT_GOUT_IS_CSIS1_ACLK,
+       CLK_CON_GAT_GOUT_IS_CSIS2_ACLK,
+       CLK_CON_GAT_GOUT_IS_TZPC_PCLK,
+       CLK_CON_GAT_GOUT_IS_CLK_CSIS_DMA,
+       CLK_CON_GAT_GOUT_IS_CLK_GDC,
+       CLK_CON_GAT_GOUT_IS_CLK_IPP,
+       CLK_CON_GAT_GOUT_IS_CLK_ITP,
+       CLK_CON_GAT_GOUT_IS_CLK_MCSC,
+       CLK_CON_GAT_GOUT_IS_CLK_VRA,
+       CLK_CON_GAT_GOUT_IS_PPMU_IS0_ACLK,
+       CLK_CON_GAT_GOUT_IS_PPMU_IS0_PCLK,
+       CLK_CON_GAT_GOUT_IS_PPMU_IS1_ACLK,
+       CLK_CON_GAT_GOUT_IS_PPMU_IS1_PCLK,
+       CLK_CON_GAT_GOUT_IS_SYSMMU_IS0_CLK_S1,
+       CLK_CON_GAT_GOUT_IS_SYSMMU_IS1_CLK_S1,
+       CLK_CON_GAT_GOUT_IS_SYSREG_PCLK,
+};
+
+/* List of parent clocks for Muxes in CMU_IS */
+PNAME(mout_is_bus_user_p)      = { "oscclk", "dout_is_bus" };
+PNAME(mout_is_itp_user_p)      = { "oscclk", "dout_is_itp" };
+PNAME(mout_is_vra_user_p)      = { "oscclk", "dout_is_vra" };
+PNAME(mout_is_gdc_user_p)      = { "oscclk", "dout_is_gdc" };
+
+static const struct samsung_mux_clock is_mux_clks[] __initconst = {
+       MUX(CLK_MOUT_IS_BUS_USER, "mout_is_bus_user", mout_is_bus_user_p,
+           PLL_CON0_MUX_CLKCMU_IS_BUS_USER, 4, 1),
+       MUX(CLK_MOUT_IS_ITP_USER, "mout_is_itp_user", mout_is_itp_user_p,
+           PLL_CON0_MUX_CLKCMU_IS_ITP_USER, 4, 1),
+       MUX(CLK_MOUT_IS_VRA_USER, "mout_is_vra_user", mout_is_vra_user_p,
+           PLL_CON0_MUX_CLKCMU_IS_VRA_USER, 4, 1),
+       MUX(CLK_MOUT_IS_GDC_USER, "mout_is_gdc_user", mout_is_gdc_user_p,
+           PLL_CON0_MUX_CLKCMU_IS_GDC_USER, 4, 1),
+};
+
+static const struct samsung_div_clock is_div_clks[] __initconst = {
+       DIV(CLK_DOUT_IS_BUSP, "dout_is_busp", "mout_is_bus_user",
+           CLK_CON_DIV_DIV_CLK_IS_BUSP, 0, 2),
+};
+
+static const struct samsung_gate_clock is_gate_clks[] __initconst = {
+       /* TODO: Should be enabled in IS driver */
+       GATE(CLK_GOUT_IS_CMU_IS_PCLK, "gout_is_cmu_is_pclk", "dout_is_busp",
+            CLK_CON_GAT_CLK_IS_CMU_IS_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+       GATE(CLK_GOUT_IS_CSIS0_ACLK, "gout_is_csis0_aclk", "mout_is_bus_user",
+            CLK_CON_GAT_GOUT_IS_CSIS0_ACLK, 21, 0, 0),
+       GATE(CLK_GOUT_IS_CSIS1_ACLK, "gout_is_csis1_aclk", "mout_is_bus_user",
+            CLK_CON_GAT_GOUT_IS_CSIS1_ACLK, 21, 0, 0),
+       GATE(CLK_GOUT_IS_CSIS2_ACLK, "gout_is_csis2_aclk", "mout_is_bus_user",
+            CLK_CON_GAT_GOUT_IS_CSIS2_ACLK, 21, 0, 0),
+       GATE(CLK_GOUT_IS_TZPC_PCLK, "gout_is_tzpc_pclk", "dout_is_busp",
+            CLK_CON_GAT_GOUT_IS_TZPC_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_IS_CSIS_DMA_CLK, "gout_is_csis_dma_clk",
+            "mout_is_bus_user",
+            CLK_CON_GAT_GOUT_IS_CLK_CSIS_DMA, 21, 0, 0),
+       GATE(CLK_GOUT_IS_GDC_CLK, "gout_is_gdc_clk", "mout_is_gdc_user",
+            CLK_CON_GAT_GOUT_IS_CLK_GDC, 21, 0, 0),
+       GATE(CLK_GOUT_IS_IPP_CLK, "gout_is_ipp_clk", "mout_is_bus_user",
+            CLK_CON_GAT_GOUT_IS_CLK_IPP, 21, 0, 0),
+       GATE(CLK_GOUT_IS_ITP_CLK, "gout_is_itp_clk", "mout_is_itp_user",
+            CLK_CON_GAT_GOUT_IS_CLK_ITP, 21, 0, 0),
+       GATE(CLK_GOUT_IS_MCSC_CLK, "gout_is_mcsc_clk", "mout_is_itp_user",
+            CLK_CON_GAT_GOUT_IS_CLK_MCSC, 21, 0, 0),
+       GATE(CLK_GOUT_IS_VRA_CLK, "gout_is_vra_clk", "mout_is_vra_user",
+            CLK_CON_GAT_GOUT_IS_CLK_VRA, 21, 0, 0),
+       GATE(CLK_GOUT_IS_PPMU_IS0_ACLK, "gout_is_ppmu_is0_aclk",
+            "mout_is_bus_user",
+            CLK_CON_GAT_GOUT_IS_PPMU_IS0_ACLK, 21, 0, 0),
+       GATE(CLK_GOUT_IS_PPMU_IS0_PCLK, "gout_is_ppmu_is0_pclk", "dout_is_busp",
+            CLK_CON_GAT_GOUT_IS_PPMU_IS0_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_IS_PPMU_IS1_ACLK, "gout_is_ppmu_is1_aclk",
+            "mout_is_itp_user",
+            CLK_CON_GAT_GOUT_IS_PPMU_IS1_ACLK, 21, 0, 0),
+       GATE(CLK_GOUT_IS_PPMU_IS1_PCLK, "gout_is_ppmu_is1_pclk", "dout_is_busp",
+            CLK_CON_GAT_GOUT_IS_PPMU_IS1_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_IS_SYSMMU_IS0_CLK, "gout_is_sysmmu_is0_clk",
+            "mout_is_bus_user",
+            CLK_CON_GAT_GOUT_IS_SYSMMU_IS0_CLK_S1, 21, 0, 0),
+       GATE(CLK_GOUT_IS_SYSMMU_IS1_CLK, "gout_is_sysmmu_is1_clk",
+            "mout_is_itp_user",
+            CLK_CON_GAT_GOUT_IS_SYSMMU_IS1_CLK_S1, 21, 0, 0),
+       GATE(CLK_GOUT_IS_SYSREG_PCLK, "gout_is_sysreg_pclk", "dout_is_busp",
+            CLK_CON_GAT_GOUT_IS_SYSREG_PCLK, 21, 0, 0),
+};
+
+static const struct samsung_cmu_info is_cmu_info __initconst = {
+       .mux_clks               = is_mux_clks,
+       .nr_mux_clks            = ARRAY_SIZE(is_mux_clks),
+       .div_clks               = is_div_clks,
+       .nr_div_clks            = ARRAY_SIZE(is_div_clks),
+       .gate_clks              = is_gate_clks,
+       .nr_gate_clks           = ARRAY_SIZE(is_gate_clks),
+       .nr_clk_ids             = IS_NR_CLK,
+       .clk_regs               = is_clk_regs,
+       .nr_clk_regs            = ARRAY_SIZE(is_clk_regs),
+       .clk_name               = "dout_is_bus",
+};
+
+/* ---- CMU_MFCMSCL --------------------------------------------------------- */
+
+#define PLL_CON0_MUX_CLKCMU_MFCMSCL_JPEG_USER          0x0600
+#define PLL_CON0_MUX_CLKCMU_MFCMSCL_M2M_USER           0x0610
+#define PLL_CON0_MUX_CLKCMU_MFCMSCL_MCSC_USER          0x0620
+#define PLL_CON0_MUX_CLKCMU_MFCMSCL_MFC_USER           0x0630
+#define CLK_CON_DIV_DIV_CLK_MFCMSCL_BUSP               0x1800
+#define CLK_CON_GAT_CLK_MFCMSCL_CMU_MFCMSCL_PCLK       0x2000
+#define CLK_CON_GAT_GOUT_MFCMSCL_TZPC_PCLK             0x2038
+#define CLK_CON_GAT_GOUT_MFCMSCL_JPEG_ACLK             0x203c
+#define CLK_CON_GAT_GOUT_MFCMSCL_M2M_ACLK              0x2048
+#define CLK_CON_GAT_GOUT_MFCMSCL_MCSC_I_CLK            0x204c
+#define CLK_CON_GAT_GOUT_MFCMSCL_MFC_ACLK              0x2050
+#define CLK_CON_GAT_GOUT_MFCMSCL_PPMU_ACLK             0x2054
+#define CLK_CON_GAT_GOUT_MFCMSCL_PPMU_PCLK             0x2058
+#define CLK_CON_GAT_GOUT_MFCMSCL_SYSMMU_CLK_S1         0x2074
+#define CLK_CON_GAT_GOUT_MFCMSCL_SYSREG_PCLK           0x2078
+
+static const unsigned long mfcmscl_clk_regs[] __initconst = {
+       PLL_CON0_MUX_CLKCMU_MFCMSCL_JPEG_USER,
+       PLL_CON0_MUX_CLKCMU_MFCMSCL_M2M_USER,
+       PLL_CON0_MUX_CLKCMU_MFCMSCL_MCSC_USER,
+       PLL_CON0_MUX_CLKCMU_MFCMSCL_MFC_USER,
+       CLK_CON_DIV_DIV_CLK_MFCMSCL_BUSP,
+       CLK_CON_GAT_CLK_MFCMSCL_CMU_MFCMSCL_PCLK,
+       CLK_CON_GAT_GOUT_MFCMSCL_TZPC_PCLK,
+       CLK_CON_GAT_GOUT_MFCMSCL_JPEG_ACLK,
+       CLK_CON_GAT_GOUT_MFCMSCL_M2M_ACLK,
+       CLK_CON_GAT_GOUT_MFCMSCL_MCSC_I_CLK,
+       CLK_CON_GAT_GOUT_MFCMSCL_MFC_ACLK,
+       CLK_CON_GAT_GOUT_MFCMSCL_PPMU_ACLK,
+       CLK_CON_GAT_GOUT_MFCMSCL_PPMU_PCLK,
+       CLK_CON_GAT_GOUT_MFCMSCL_SYSMMU_CLK_S1,
+       CLK_CON_GAT_GOUT_MFCMSCL_SYSREG_PCLK,
+};
+
+/* List of parent clocks for Muxes in CMU_MFCMSCL */
+PNAME(mout_mfcmscl_mfc_user_p) = { "oscclk", "dout_mfcmscl_mfc" };
+PNAME(mout_mfcmscl_m2m_user_p) = { "oscclk", "dout_mfcmscl_m2m" };
+PNAME(mout_mfcmscl_mcsc_user_p)        = { "oscclk", "dout_mfcmscl_mcsc" };
+PNAME(mout_mfcmscl_jpeg_user_p)        = { "oscclk", "dout_mfcmscl_jpeg" };
+
+static const struct samsung_mux_clock mfcmscl_mux_clks[] __initconst = {
+       MUX(CLK_MOUT_MFCMSCL_MFC_USER, "mout_mfcmscl_mfc_user",
+           mout_mfcmscl_mfc_user_p,
+           PLL_CON0_MUX_CLKCMU_MFCMSCL_MFC_USER, 4, 1),
+       MUX(CLK_MOUT_MFCMSCL_M2M_USER, "mout_mfcmscl_m2m_user",
+           mout_mfcmscl_m2m_user_p,
+           PLL_CON0_MUX_CLKCMU_MFCMSCL_M2M_USER, 4, 1),
+       MUX(CLK_MOUT_MFCMSCL_MCSC_USER, "mout_mfcmscl_mcsc_user",
+           mout_mfcmscl_mcsc_user_p,
+           PLL_CON0_MUX_CLKCMU_MFCMSCL_MCSC_USER, 4, 1),
+       MUX(CLK_MOUT_MFCMSCL_JPEG_USER, "mout_mfcmscl_jpeg_user",
+           mout_mfcmscl_jpeg_user_p,
+           PLL_CON0_MUX_CLKCMU_MFCMSCL_JPEG_USER, 4, 1),
+};
+
+static const struct samsung_div_clock mfcmscl_div_clks[] __initconst = {
+       DIV(CLK_DOUT_MFCMSCL_BUSP, "dout_mfcmscl_busp", "mout_mfcmscl_mfc_user",
+           CLK_CON_DIV_DIV_CLK_MFCMSCL_BUSP, 0, 3),
+};
+
+static const struct samsung_gate_clock mfcmscl_gate_clks[] __initconst = {
+       /* TODO: Should be enabled in MFC driver */
+       GATE(CLK_GOUT_MFCMSCL_CMU_MFCMSCL_PCLK, "gout_mfcmscl_cmu_mfcmscl_pclk",
+            "dout_mfcmscl_busp", CLK_CON_GAT_CLK_MFCMSCL_CMU_MFCMSCL_PCLK,
+            21, CLK_IGNORE_UNUSED, 0),
+       GATE(CLK_GOUT_MFCMSCL_TZPC_PCLK, "gout_mfcmscl_tzpc_pclk",
+            "dout_mfcmscl_busp", CLK_CON_GAT_GOUT_MFCMSCL_TZPC_PCLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_MFCMSCL_JPEG_ACLK, "gout_mfcmscl_jpeg_aclk",
+            "mout_mfcmscl_jpeg_user", CLK_CON_GAT_GOUT_MFCMSCL_JPEG_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_MFCMSCL_M2M_ACLK, "gout_mfcmscl_m2m_aclk",
+            "mout_mfcmscl_m2m_user", CLK_CON_GAT_GOUT_MFCMSCL_M2M_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_MFCMSCL_MCSC_CLK, "gout_mfcmscl_mcsc_clk",
+            "mout_mfcmscl_mcsc_user", CLK_CON_GAT_GOUT_MFCMSCL_MCSC_I_CLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_MFCMSCL_MFC_ACLK, "gout_mfcmscl_mfc_aclk",
+            "mout_mfcmscl_mfc_user", CLK_CON_GAT_GOUT_MFCMSCL_MFC_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_MFCMSCL_PPMU_ACLK, "gout_mfcmscl_ppmu_aclk",
+            "mout_mfcmscl_mfc_user", CLK_CON_GAT_GOUT_MFCMSCL_PPMU_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_MFCMSCL_PPMU_PCLK, "gout_mfcmscl_ppmu_pclk",
+            "dout_mfcmscl_busp", CLK_CON_GAT_GOUT_MFCMSCL_PPMU_PCLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_MFCMSCL_SYSMMU_CLK, "gout_mfcmscl_sysmmu_clk",
+            "mout_mfcmscl_mfc_user", CLK_CON_GAT_GOUT_MFCMSCL_SYSMMU_CLK_S1,
+            21, 0, 0),
+       GATE(CLK_GOUT_MFCMSCL_SYSREG_PCLK, "gout_mfcmscl_sysreg_pclk",
+            "dout_mfcmscl_busp", CLK_CON_GAT_GOUT_MFCMSCL_SYSREG_PCLK,
+            21, 0, 0),
+};
+
+static const struct samsung_cmu_info mfcmscl_cmu_info __initconst = {
+       .mux_clks               = mfcmscl_mux_clks,
+       .nr_mux_clks            = ARRAY_SIZE(mfcmscl_mux_clks),
+       .div_clks               = mfcmscl_div_clks,
+       .nr_div_clks            = ARRAY_SIZE(mfcmscl_div_clks),
+       .gate_clks              = mfcmscl_gate_clks,
+       .nr_gate_clks           = ARRAY_SIZE(mfcmscl_gate_clks),
+       .nr_clk_ids             = MFCMSCL_NR_CLK,
+       .clk_regs               = mfcmscl_clk_regs,
+       .nr_clk_regs            = ARRAY_SIZE(mfcmscl_clk_regs),
+       .clk_name               = "dout_mfcmscl_mfc",
+};
+
 /* ---- CMU_PERI ------------------------------------------------------------ */
 
 /* Register Offset definitions for CMU_PERI (0x10030000) */
@@ -963,7 +1630,7 @@ static const unsigned long dpu_clk_regs[] __initconst = {
        CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK,
 };
 
-/* List of parent clocks for Muxes in CMU_CORE */
+/* List of parent clocks for Muxes in CMU_DPU */
 PNAME(mout_dpu_user_p)         = { "oscclk", "dout_dpu" };
 
 static const struct samsung_mux_clock dpu_mux_clks[] __initconst = {
@@ -1028,12 +1695,21 @@ static const struct of_device_id exynos850_cmu_of_match[] = {
                .compatible = "samsung,exynos850-cmu-apm",
                .data = &apm_cmu_info,
        }, {
+               .compatible = "samsung,exynos850-cmu-aud",
+               .data = &aud_cmu_info,
+       }, {
                .compatible = "samsung,exynos850-cmu-cmgp",
                .data = &cmgp_cmu_info,
        }, {
                .compatible = "samsung,exynos850-cmu-hsi",
                .data = &hsi_cmu_info,
        }, {
+               .compatible = "samsung,exynos850-cmu-is",
+               .data = &is_cmu_info,
+       }, {
+               .compatible = "samsung,exynos850-cmu-mfcmscl",
+               .data = &mfcmscl_cmu_info,
+       }, {
                .compatible = "samsung,exynos850-cmu-core",
                .data = &core_cmu_info,
        }, {
index d9e1f8e..7b16320 100644 (file)
@@ -1067,6 +1067,373 @@ static const struct samsung_cmu_info core_cmu_info __initconst = {
        .clk_name               = "dout_clkcmu_core_bus",
 };
 
+/* ---- CMU_FSYS0 ---------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_FSYS2 (0x17700000) */
+#define PLL_CON0_MUX_CLKCMU_FSYS0_BUS_USER     0x0600
+#define PLL_CON0_MUX_CLKCMU_FSYS0_PCIE_USER    0x0610
+#define CLK_CON_GAT_CLK_BLK_FSYS0_UID_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK   0x2000
+
+#define CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_2L0_X1_PHY_REFCLK_IN   0x2004
+#define CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_2L0_X2_PHY_REFCLK_IN   0x2008
+#define CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_2L1_X1_PHY_REFCLK_IN   0x200c
+#define CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_2L1_X2_PHY_REFCLK_IN   0x2010
+#define CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_4L_X2_PHY_REFCLK_IN    0x2014
+#define CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_4L_X4_PHY_REFCLK_IN    0x2018
+
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X1_DBI_ACLK       0x205c
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X1_MSTR_ACLK      0x2060
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X1_SLV_ACLK       0x2064
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X2_DBI_ACLK       0x206c
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X2_MSTR_ACLK      0x2070
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X2_SLV_ACLK       0x2074
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X2_PIPE_CLK       0x207c
+
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X1_DBI_ACLK       0x2084
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X1_MSTR_ACLK      0x2088
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X1_SLV_ACLK       0x208c
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X2_DBI_ACLK       0x2094
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X2_MSTR_ACLK      0x2098
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X2_SLV_ACLK       0x209c
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X2_PIPE_CLK       0x20a4
+
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X2_DBI_ACLK                0x20ac
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X2_MSTR_ACLK       0x20b0
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X2_SLV_ACLK                0x20b4
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X4_DBI_ACLK                0x20bc
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X4_MSTR_ACLK       0x20c0
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X4_SLV_ACLK                0x20c4
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X4_PIPE_CLK                0x20cc
+
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3A_2L0_CLK              0x20d4
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3A_2L1_CLK              0x20d8
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3A_4L_CLK               0x20dc
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3B_2L0_CLK              0x20e0
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3B_2L1_CLK              0x20e4
+#define CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3B_4L_CLK               0x20e8
+
+
+static const unsigned long fsys0_clk_regs[] __initconst = {
+       PLL_CON0_MUX_CLKCMU_FSYS0_BUS_USER,
+       PLL_CON0_MUX_CLKCMU_FSYS0_PCIE_USER,
+       CLK_CON_GAT_CLK_BLK_FSYS0_UID_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK,
+       CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_2L0_X1_PHY_REFCLK_IN,
+       CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_2L0_X2_PHY_REFCLK_IN,
+       CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_2L1_X1_PHY_REFCLK_IN,
+       CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_2L1_X2_PHY_REFCLK_IN,
+       CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_4L_X2_PHY_REFCLK_IN,
+       CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_4L_X4_PHY_REFCLK_IN,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X1_DBI_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X1_MSTR_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X1_SLV_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X2_DBI_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X2_MSTR_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X2_SLV_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X2_PIPE_CLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X1_DBI_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X1_MSTR_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X1_SLV_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X2_DBI_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X2_MSTR_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X2_SLV_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X2_PIPE_CLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X2_DBI_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X2_MSTR_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X2_SLV_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X4_DBI_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X4_MSTR_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X4_SLV_ACLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X4_PIPE_CLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3A_2L0_CLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3A_2L1_CLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3A_4L_CLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3B_2L0_CLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3B_2L1_CLK,
+       CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3B_4L_CLK,
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS0 */
+PNAME(mout_fsys0_bus_user_p) = { "oscclk", "dout_clkcmu_fsys0_bus" };
+PNAME(mout_fsys0_pcie_user_p) = { "oscclk", "dout_clkcmu_fsys0_pcie" };
+
+static const struct samsung_mux_clock fsys0_mux_clks[] __initconst = {
+       MUX(CLK_MOUT_FSYS0_BUS_USER, "mout_fsys0_bus_user",
+           mout_fsys0_bus_user_p, PLL_CON0_MUX_CLKCMU_FSYS0_BUS_USER, 4, 1),
+       MUX(CLK_MOUT_FSYS0_PCIE_USER, "mout_fsys0_pcie_user",
+           mout_fsys0_pcie_user_p, PLL_CON0_MUX_CLKCMU_FSYS0_PCIE_USER, 4, 1),
+};
+
+static const struct samsung_gate_clock fsys0_gate_clks[] __initconst = {
+       GATE(CLK_GOUT_FSYS0_BUS_PCLK, "gout_fsys0_bus_pclk",
+            "mout_fsys0_bus_user",
+            CLK_CON_GAT_CLK_BLK_FSYS0_UID_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK,
+            21, CLK_IGNORE_UNUSED, 0),
+
+       /* Gen3 2L0 */
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X1_REFCLK,
+            "gout_fsys0_pcie_gen3_2l0_x1_refclk", "mout_fsys0_pcie_user",
+            CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_2L0_X1_PHY_REFCLK_IN,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X2_REFCLK,
+            "gout_fsys0_pcie_gen3_2l0_x2_refclk", "mout_fsys0_pcie_user",
+            CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_2L0_X2_PHY_REFCLK_IN,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X1_DBI_ACLK,
+            "gout_fsys0_pcie_gen3_2l0_x1_dbi_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X1_DBI_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X1_MSTR_ACLK,
+            "gout_fsys0_pcie_gen3_2l0_x1_mstr_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X1_MSTR_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X1_SLV_ACLK,
+            "gout_fsys0_pcie_gen3_2l0_x1_slv_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X1_SLV_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X2_DBI_ACLK,
+            "gout_fsys0_pcie_gen3_2l0_x2_dbi_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X2_DBI_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X2_MSTR_ACLK,
+            "gout_fsys0_pcie_gen3_2l0_x2_mstr_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X2_MSTR_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X2_SLV_ACLK,
+            "gout_fsys0_pcie_gen3_2l0_x2_slv_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L0_X2_SLV_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3A_2L0_CLK,
+            "gout_fsys0_pcie_gen3a_2l0_clk", "mout_fsys0_pcie_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3A_2L0_CLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3B_2L0_CLK,
+            "gout_fsys0_pcie_gen3b_2l0_clk", "mout_fsys0_pcie_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3B_2L0_CLK,
+            21, 0, 0),
+
+       /* Gen3 2L1 */
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X1_REFCLK,
+            "gout_fsys0_pcie_gen3_2l1_x1_refclk", "mout_fsys0_pcie_user",
+            CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_2L1_X1_PHY_REFCLK_IN,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X2_REFCLK,
+            "gout_fsys0_pcie_gen3_2l1_x2_refclk", "mout_fsys0_pcie_user",
+            CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_2L1_X2_PHY_REFCLK_IN,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X1_DBI_ACLK,
+            "gout_fsys0_pcie_gen3_2l1_x1_dbi_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X1_DBI_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X1_MSTR_ACLK,
+            "gout_fsys0_pcie_gen3_2l1_x1_mstr_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X1_MSTR_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X1_SLV_ACLK,
+            "gout_fsys0_pcie_gen3_2l1_x1_slv_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X1_SLV_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X2_DBI_ACLK,
+            "gout_fsys0_pcie_gen3_2l1_x2_dbi_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X2_DBI_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X2_MSTR_ACLK,
+            "gout_fsys0_pcie_gen3_2l1_x2_mstr_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X2_MSTR_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X2_SLV_ACLK,
+            "gout_fsys0_pcie_gen3_2l1_x2_slv_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_2L1_X2_SLV_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3A_2L1_CLK,
+            "gout_fsys0_pcie_gen3a_2l1_clk", "mout_fsys0_pcie_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3A_2L1_CLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3B_2L1_CLK,
+            "gout_fsys0_pcie_gen3b_2l1_clk", "mout_fsys0_pcie_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3B_2L1_CLK,
+            21, 0, 0),
+
+       /* Gen3 4L */
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_4L_X2_REFCLK,
+            "gout_fsys0_pcie_gen3_4l_x2_refclk", "mout_fsys0_pcie_user",
+            CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_4L_X2_PHY_REFCLK_IN,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_4L_X4_REFCLK,
+            "gout_fsys0_pcie_gen3_4l_x4_refclk", "mout_fsys0_pcie_user",
+            CLK_CON_GAT_CLK_BLK_FSYS0_UID_PCIE_GEN3_4L_X4_PHY_REFCLK_IN,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_4L_X2_DBI_ACLK,
+            "gout_fsys0_pcie_gen3_4l_x2_dbi_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X2_DBI_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_4L_X2_MSTR_ACLK,
+            "gout_fsys0_pcie_gen3_4l_x2_mstr_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X2_MSTR_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_4L_X2_SLV_ACLK,
+            "gout_fsys0_pcie_gen3_4l_x2_slv_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X2_SLV_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_4L_X4_DBI_ACLK,
+            "gout_fsys0_pcie_gen3_4l_x4_dbi_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X4_DBI_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_4L_X4_MSTR_ACLK,
+            "gout_fsys0_pcie_gen3_4l_x4_mstr_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X4_MSTR_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3_4L_X4_SLV_ACLK,
+            "gout_fsys0_pcie_gen3_4l_x4_slv_aclk", "mout_fsys0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3_4L_X4_SLV_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3A_4L_CLK,
+            "gout_fsys0_pcie_gen3a_4l_clk", "mout_fsys0_pcie_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3A_4L_CLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS0_PCIE_GEN3B_4L_CLK,
+            "gout_fsys0_pcie_gen3b_4l_clk", "mout_fsys0_pcie_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS0_UID_PCIE_GEN3B_4L_CLK,
+            21, 0, 0),
+};
+
+static const struct samsung_cmu_info fsys0_cmu_info __initconst = {
+       .mux_clks               = fsys0_mux_clks,
+       .nr_mux_clks            = ARRAY_SIZE(fsys0_mux_clks),
+       .gate_clks              = fsys0_gate_clks,
+       .nr_gate_clks           = ARRAY_SIZE(fsys0_gate_clks),
+       .nr_clk_ids             = FSYS0_NR_CLK,
+       .clk_regs               = fsys0_clk_regs,
+       .nr_clk_regs            = ARRAY_SIZE(fsys0_clk_regs),
+       .clk_name               = "dout_clkcmu_fsys0_bus",
+};
+
+/* ---- CMU_FSYS1 ---------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_FSYS1 (0x17040000) */
+#define PLL_LOCKTIME_PLL_MMC                   0x0000
+#define PLL_CON0_PLL_MMC                       0x0100
+#define PLL_CON3_PLL_MMC                       0x010c
+#define PLL_CON0_MUX_CLKCMU_FSYS1_BUS_USER     0x0600
+#define PLL_CON0_MUX_CLKCMU_FSYS1_MMC_CARD_USER        0x0610
+#define PLL_CON0_MUX_CLKCMU_FSYS1_USBDRD_USER  0x0620
+
+#define CLK_CON_MUX_MUX_CLK_FSYS1_MMC_CARD     0x1000
+#define CLK_CON_DIV_DIV_CLK_FSYS1_MMC_CARD     0x1800
+
+#define CLK_CON_GAT_GOUT_BLK_FSYS1_UID_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK  0x2018
+#define CLK_CON_GAT_GOUT_BLK_FSYS1_UID_MMC_CARD_IPCLKPORT_SDCLKIN      0x202c
+#define CLK_CON_GAT_GOUT_BLK_FSYS1_UID_MMC_CARD_IPCLKPORT_I_ACLK       0x2028
+
+#define CLK_CON_GAT_GOUT_BLK_FSYS1_UID_USB20DRD_0_REF_CLK_40           0x204c
+#define CLK_CON_GAT_GOUT_BLK_FSYS1_UID_USB20DRD_1_REF_CLK_40           0x2058
+#define CLK_CON_GAT_GOUT_BLK_FSYS1_UID_USB30DRD_0_REF_CLK_40           0x2064
+#define CLK_CON_GAT_GOUT_BLK_FSYS1_UID_USB30DRD_1_REF_CLK_40           0x2070
+
+#define CLK_CON_GAT_GOUT_BLK_FSYS1_UID_US_D_USB2_0_IPCLKPORT_ACLK      0x2074
+#define CLK_CON_GAT_GOUT_BLK_FSYS1_UID_US_D_USB2_1_IPCLKPORT_ACLK      0x2078
+#define CLK_CON_GAT_GOUT_BLK_FSYS1_UID_US_D_USB3_0_IPCLKPORT_ACLK      0x207c
+#define CLK_CON_GAT_GOUT_BLK_FSYS1_UID_US_D_USB3_1_IPCLKPORT_ACLK      0x2080
+
+static const unsigned long fsys1_clk_regs[] __initconst = {
+       PLL_CON0_MUX_CLKCMU_FSYS1_BUS_USER,
+};
+
+static const struct samsung_pll_clock fsys1_pll_clks[] __initconst = {
+       PLL(pll_0831x, FOUT_MMC_PLL, "fout_mmc_pll", "oscclk",
+           PLL_LOCKTIME_PLL_MMC, PLL_CON3_PLL_MMC, NULL),
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS1 */
+PNAME(mout_fsys1_bus_user_p) = { "oscclk", "dout_clkcmu_fsys1_bus" };
+PNAME(mout_fsys1_mmc_pll_p) = { "oscclk", "fout_mmc_pll" };
+PNAME(mout_fsys1_mmc_card_user_p) = { "oscclk", "gout_clkcmu_fsys1_mmc_card" };
+PNAME(mout_fsys1_usbdrd_user_p) = { "oscclk", "dout_clkcmu_fsys1_usbdrd" };
+PNAME(mout_fsys1_mmc_card_p) = { "mout_fsys1_mmc_card_user",
+                                "mout_fsys1_mmc_pll" };
+
+static const struct samsung_mux_clock fsys1_mux_clks[] __initconst = {
+       MUX(CLK_MOUT_FSYS1_BUS_USER, "mout_fsys1_bus_user",
+           mout_fsys1_bus_user_p, PLL_CON0_MUX_CLKCMU_FSYS1_BUS_USER, 4, 1),
+       MUX(CLK_MOUT_FSYS1_MMC_PLL, "mout_fsys1_mmc_pll", mout_fsys1_mmc_pll_p,
+           PLL_CON0_PLL_MMC, 4, 1),
+       MUX(CLK_MOUT_FSYS1_MMC_CARD_USER, "mout_fsys1_mmc_card_user",
+           mout_fsys1_mmc_card_user_p, PLL_CON0_MUX_CLKCMU_FSYS1_MMC_CARD_USER,
+           4, 1),
+       MUX(CLK_MOUT_FSYS1_USBDRD_USER, "mout_fsys1_usbdrd_user",
+           mout_fsys1_usbdrd_user_p, PLL_CON0_MUX_CLKCMU_FSYS1_USBDRD_USER,
+           4, 1),
+       MUX(CLK_MOUT_FSYS1_MMC_CARD, "mout_fsys1_mmc_card",
+           mout_fsys1_mmc_card_p, CLK_CON_MUX_MUX_CLK_FSYS1_MMC_CARD,
+           0, 1),
+};
+
+static const struct samsung_div_clock fsys1_div_clks[] __initconst = {
+       DIV(CLK_DOUT_FSYS1_MMC_CARD, "dout_fsys1_mmc_card",
+           "mout_fsys1_mmc_card",
+           CLK_CON_DIV_DIV_CLK_FSYS1_MMC_CARD, 0, 9),
+};
+
+static const struct samsung_gate_clock fsys1_gate_clks[] __initconst = {
+       GATE(CLK_GOUT_FSYS1_PCLK, "gout_fsys1_pclk", "mout_fsys1_bus_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS1_UID_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK,
+            21, CLK_IGNORE_UNUSED, 0),
+       GATE(CLK_GOUT_FSYS1_MMC_CARD_SDCLKIN, "gout_fsys1_mmc_card_sdclkin",
+            "dout_fsys1_mmc_card",
+            CLK_CON_GAT_GOUT_BLK_FSYS1_UID_MMC_CARD_IPCLKPORT_SDCLKIN,
+            21, CLK_SET_RATE_PARENT, 0),
+       GATE(CLK_GOUT_FSYS1_MMC_CARD_ACLK, "gout_fsys1_mmc_card_aclk",
+            "dout_fsys1_mmc_card",
+            CLK_CON_GAT_GOUT_BLK_FSYS1_UID_MMC_CARD_IPCLKPORT_I_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS1_USB20DRD_0_REFCLK, "gout_fsys1_usb20drd_0_refclk",
+            "mout_fsys1_usbdrd_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS1_UID_USB20DRD_0_REF_CLK_40,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS1_USB20DRD_1_REFCLK, "gout_fsys1_usb20drd_1_refclk",
+            "mout_fsys1_usbdrd_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS1_UID_USB20DRD_1_REF_CLK_40,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS1_USB30DRD_0_REFCLK, "gout_fsys1_usb30drd_0_refclk",
+            "mout_fsys1_usbdrd_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS1_UID_USB30DRD_0_REF_CLK_40,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS1_USB30DRD_1_REFCLK, "gout_fsys1_usb30drd_1_refclk",
+            "mout_fsys1_usbdrd_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS1_UID_USB30DRD_1_REF_CLK_40,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS1_USB20_0_ACLK, "gout_fsys1_usb20_0_aclk",
+            "mout_fsys1_usbdrd_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS1_UID_US_D_USB2_0_IPCLKPORT_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS1_USB20_1_ACLK, "gout_fsys1_usb20_1_aclk",
+            "mout_fsys1_usbdrd_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS1_UID_US_D_USB2_1_IPCLKPORT_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS1_USB30_0_ACLK, "gout_fsys1_usb30_0_aclk",
+            "mout_fsys1_usbdrd_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS1_UID_US_D_USB3_0_IPCLKPORT_ACLK,
+            21, 0, 0),
+       GATE(CLK_GOUT_FSYS1_USB30_1_ACLK, "gout_fsys1_usb30_1_aclk",
+            "mout_fsys1_usbdrd_user",
+            CLK_CON_GAT_GOUT_BLK_FSYS1_UID_US_D_USB3_1_IPCLKPORT_ACLK,
+            21, 0, 0),
+};
+
+static const struct samsung_cmu_info fsys1_cmu_info __initconst = {
+       .pll_clks               = fsys1_pll_clks,
+       .nr_pll_clks            = ARRAY_SIZE(fsys1_pll_clks),
+       .mux_clks               = fsys1_mux_clks,
+       .nr_mux_clks            = ARRAY_SIZE(fsys1_mux_clks),
+       .div_clks               = fsys1_div_clks,
+       .nr_div_clks            = ARRAY_SIZE(fsys1_div_clks),
+       .gate_clks              = fsys1_gate_clks,
+       .nr_gate_clks           = ARRAY_SIZE(fsys1_gate_clks),
+       .nr_clk_ids             = FSYS1_NR_CLK,
+       .clk_regs               = fsys1_clk_regs,
+       .nr_clk_regs            = ARRAY_SIZE(fsys1_clk_regs),
+       .clk_name               = "dout_clkcmu_fsys1_bus",
+};
+
 /* ---- CMU_FSYS2 ---------------------------------------------------------- */
 
 /* Register Offset definitions for CMU_FSYS2 (0x17c00000) */
@@ -1170,9 +1537,9 @@ static const struct samsung_cmu_info fsys2_cmu_info __initconst = {
 #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_2   0x2058
 #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_3   0x205c
 #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_4   0x2060
-#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_7   0x206c
 #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_5   0x2064
 #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_6   0x2068
+#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_7   0x206c
 #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_8   0x2070
 #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_9   0x2074
 #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_10  0x204c
@@ -1330,6 +1697,10 @@ static const struct samsung_gate_clock peric0_gate_clks[] __initconst = {
             "mout_peric0_bus_user",
             CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_0,
             21, 0, 0),
+       GATE(CLK_GOUT_PERIC0_PCLK_1, "gout_peric0_pclk_1",
+            "mout_peric0_bus_user",
+            CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_1,
+            21, 0, 0),
        GATE(CLK_GOUT_PERIC0_PCLK_2, "gout_peric0_pclk_2",
             "mout_peric0_bus_user",
             CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_2,
@@ -1418,14 +1789,14 @@ static const struct samsung_cmu_info peric0_cmu_info __initconst = {
 #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_11 0x2020
 #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_0   0x2044
 #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_1   0x2048
-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_2   0x2058
-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_3   0x205c
-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4   0x2060
-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_7   0x206c
-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_5   0x2064
-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_6   0x2068
-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_8   0x2070
-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_9   0x2074
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_2   0x2054
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_3   0x2058
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4   0x205c
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_5   0x2060
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_6   0x2064
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_7   0x2068
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_8   0x206c
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_9   0x2070
 #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_10  0x204c
 #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_11  0x2050
 
@@ -1463,9 +1834,9 @@ static const unsigned long peric1_clk_regs[] __initconst = {
        CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_2,
        CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_3,
        CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4,
-       CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_7,
        CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_5,
        CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_6,
+       CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_7,
        CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_8,
        CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_9,
        CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_10,
@@ -1581,6 +1952,10 @@ static const struct samsung_gate_clock peric1_gate_clks[] __initconst = {
             "mout_peric1_bus_user",
             CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_0,
             21, 0, 0),
+       GATE(CLK_GOUT_PERIC1_PCLK_1, "gout_peric1_pclk_1",
+            "mout_peric1_bus_user",
+            CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_1,
+            21, 0, 0),
        GATE(CLK_GOUT_PERIC1_PCLK_2, "gout_peric1_pclk_2",
             "mout_peric1_bus_user",
             CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_2,
@@ -1702,6 +2077,12 @@ static const struct of_device_id exynosautov9_cmu_of_match[] = {
                .compatible = "samsung,exynosautov9-cmu-core",
                .data = &core_cmu_info,
        }, {
+               .compatible = "samsung,exynosautov9-cmu-fsys0",
+               .data = &fsys0_cmu_info,
+       }, {
+               .compatible = "samsung,exynosautov9-cmu-fsys1",
+               .data = &fsys1_cmu_info,
+       }, {
                .compatible = "samsung,exynosautov9-cmu-fsys2",
                .data = &fsys2_cmu_info,
        }, {
index e18c80f..c744bd9 100644 (file)
@@ -21,4 +21,10 @@ config SPRD_SC9863A_CLK
        help
          Support for the global clock controller on sc9863a devices.
          Say Y if you want to use peripheral devices on sc9863a SoC.
+
+config SPRD_UMS512_CLK
+       tristate "Support for the Spreadtrum UMS512 clocks"
+       help
+         Support for the global clock controller on ums512 devices.
+         Say Y if you want to use peripheral devices on ums512 SoC.
 endif
index 41d90e0..f25b2c3 100644 (file)
@@ -11,3 +11,4 @@ clk-sprd-y    += pll.o
 ## SoC support
 obj-$(CONFIG_SPRD_SC9860_CLK)  += sc9860-clk.o
 obj-$(CONFIG_SPRD_SC9863A_CLK) += sc9863a-clk.o
+obj-$(CONFIG_SPRD_UMS512_CLK)  += ums512-clk.o
index d620bbb..ce81e40 100644 (file)
@@ -41,7 +41,7 @@ int sprd_clk_regmap_init(struct platform_device *pdev,
 {
        void __iomem *base;
        struct device *dev = &pdev->dev;
-       struct device_node *node = dev->of_node;
+       struct device_node *node = dev->of_node, *np;
        struct regmap *regmap;
 
        if (of_find_property(node, "sprd,syscon", NULL)) {
@@ -50,9 +50,10 @@ int sprd_clk_regmap_init(struct platform_device *pdev,
                        pr_err("%s: failed to get syscon regmap\n", __func__);
                        return PTR_ERR(regmap);
                }
-       } else if (of_device_is_compatible(of_get_parent(dev->of_node),
-                          "syscon")) {
-               regmap = device_node_to_regmap(of_get_parent(dev->of_node));
+       } else if (of_device_is_compatible(np = of_get_parent(node), "syscon") ||
+                  (of_node_put(np), 0)) {
+               regmap = device_node_to_regmap(np);
+               of_node_put(np);
                if (IS_ERR(regmap)) {
                        dev_err(dev, "failed to get regmap from its parent.\n");
                        return PTR_ERR(regmap);
diff --git a/drivers/clk/sprd/ums512-clk.c b/drivers/clk/sprd/ums512-clk.c
new file mode 100644 (file)
index 0000000..fc25bdd
--- /dev/null
@@ -0,0 +1,2202 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Unisoc UMS512 clock driver
+ *
+ * Copyright (C) 2022 Unisoc, Inc.
+ * Author: Xiaolong Zhang <xiaolong.zhang@unisoc.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/sprd,ums512-clk.h>
+
+#include "common.h"
+#include "composite.h"
+#include "div.h"
+#include "gate.h"
+#include "mux.h"
+#include "pll.h"
+
+#define UMS512_MUX_FLAG        \
+       (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT)
+
+/* pll gate clock */
+/* some pll clocks configure CLK_IGNORE_UNUSED because hw dvfs does not call
+ * clock interface. hw dvfs can not gate the pll clock.
+ */
+static CLK_FIXED_FACTOR_FW_NAME(clk_26m_aud, "clk-26m-aud", "ext-26m", 1, 1, 0);
+static CLK_FIXED_FACTOR_FW_NAME(clk_13m, "clk-13m", "ext-26m", 2, 1, 0);
+static CLK_FIXED_FACTOR_FW_NAME(clk_6m5, "clk-6m5", "ext-26m", 4, 1, 0);
+static CLK_FIXED_FACTOR_FW_NAME(clk_4m3, "clk-4m3", "ext-26m", 6, 1, 0);
+static CLK_FIXED_FACTOR_FW_NAME(clk_2m, "clk-2m", "ext-26m", 13, 1, 0);
+static CLK_FIXED_FACTOR_FW_NAME(clk_1m, "clk-1m", "ext-26m", 26, 1, 0);
+static CLK_FIXED_FACTOR_FW_NAME(clk_250k, "clk-250k", "ext-26m", 104, 1, 0);
+static CLK_FIXED_FACTOR_FW_NAME(rco_25m, "rco-25m", "rco-100m", 4, 1, 0);
+static CLK_FIXED_FACTOR_FW_NAME(rco_4m, "rco-4m", "rco-100m", 25, 1, 0);
+static CLK_FIXED_FACTOR_FW_NAME(rco_2m, "rco-2m", "rco-100m", 50, 1, 0);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(isppll_gate, "isppll-gate", "ext-26m", 0x8c,
+                                   0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll0_gate, "dpll0-gate", "ext-26m", 0x98,
+                                   0x1000, BIT(0), 0, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll1_gate, "dpll1-gate", "ext-26m", 0x9c,
+                                   0x1000, BIT(0), 0, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(lpll_gate, "lpll-gate", "ext-26m", 0xa0,
+                                   0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(twpll_gate, "twpll-gate", "ext-26m", 0xa4,
+                                   0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(gpll_gate, "gpll-gate", "ext-26m", 0xa8,
+                                   0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(rpll_gate, "rpll-gate", "ext-26m", 0xac,
+                                   0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(cppll_gate, "cppll-gate", "ext-26m", 0xe4,
+                                   0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll0_gate, "mpll0-gate", "ext-26m", 0x190,
+                                   0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll1_gate, "mpll1-gate", "ext-26m", 0x194,
+                                   0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll2_gate, "mpll2-gate", "ext-26m", 0x198,
+                                   0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
+
+static struct sprd_clk_common *ums512_pmu_gate_clks[] = {
+       /* address base is 0x327e0000 */
+       &isppll_gate.common,
+       &dpll0_gate.common,
+       &dpll1_gate.common,
+       &lpll_gate.common,
+       &twpll_gate.common,
+       &gpll_gate.common,
+       &rpll_gate.common,
+       &cppll_gate.common,
+       &mpll0_gate.common,
+       &mpll1_gate.common,
+       &mpll2_gate.common,
+};
+
+static struct clk_hw_onecell_data ums512_pmu_gate_hws = {
+       .hws    = {
+               [CLK_26M_AUD]           = &clk_26m_aud.hw,
+               [CLK_13M]               = &clk_13m.hw,
+               [CLK_6M5]               = &clk_6m5.hw,
+               [CLK_4M3]               = &clk_4m3.hw,
+               [CLK_2M]                = &clk_2m.hw,
+               [CLK_1M]                = &clk_1m.hw,
+               [CLK_250K]              = &clk_250k.hw,
+               [CLK_RCO_25M]           = &rco_25m.hw,
+               [CLK_RCO_4M]            = &rco_4m.hw,
+               [CLK_RCO_2M]            = &rco_2m.hw,
+               [CLK_ISPPLL_GATE]       = &isppll_gate.common.hw,
+               [CLK_DPLL0_GATE]        = &dpll0_gate.common.hw,
+               [CLK_DPLL1_GATE]        = &dpll1_gate.common.hw,
+               [CLK_LPLL_GATE]         = &lpll_gate.common.hw,
+               [CLK_TWPLL_GATE]        = &twpll_gate.common.hw,
+               [CLK_GPLL_GATE]         = &gpll_gate.common.hw,
+               [CLK_RPLL_GATE]         = &rpll_gate.common.hw,
+               [CLK_CPPLL_GATE]        = &cppll_gate.common.hw,
+               [CLK_MPLL0_GATE]        = &mpll0_gate.common.hw,
+               [CLK_MPLL1_GATE]        = &mpll1_gate.common.hw,
+               [CLK_MPLL2_GATE]        = &mpll2_gate.common.hw,
+       },
+       .num = CLK_PMU_GATE_NUM,
+};
+
+static struct sprd_clk_desc ums512_pmu_gate_desc = {
+       .clk_clks       = ums512_pmu_gate_clks,
+       .num_clk_clks   = ARRAY_SIZE(ums512_pmu_gate_clks),
+       .hw_clks        = &ums512_pmu_gate_hws,
+};
+
+/* pll clock at g0 */
+static const u64 itable_dpll0[7] = { 6, 0, 0,
+                       1173000000ULL, 1475000000ULL,
+                       1855000000ULL, 1866000000ULL };
+
+static struct clk_bit_field f_dpll0[PLL_FACT_MAX] = {
+       { .shift = 18,  .width = 1 },   /* lock_done    */
+       { .shift = 0,   .width = 1 },   /* div_s        */
+       { .shift = 67,  .width = 1 },   /* mod_en       */
+       { .shift = 1,   .width = 1 },   /* sdm_en       */
+       { .shift = 0,   .width = 0 },   /* refin        */
+       { .shift = 4,   .width = 3 },   /* icp          */
+       { .shift = 7,   .width = 11 },  /* n            */
+       { .shift = 55,  .width = 7 },   /* nint         */
+       { .shift = 32,  .width = 23},   /* kint         */
+       { .shift = 0,   .width = 0 },   /* prediv       */
+       { .shift = 0,   .width = 0 },   /* postdiv      */
+};
+static SPRD_PLL_HW(dpll0, "dpll0", &dpll0_gate.common.hw, 0x4, 3,
+                  itable_dpll0, f_dpll0, 240, 1000, 1000, 0, 0);
+static CLK_FIXED_FACTOR_HW(dpll0_58m31, "dpll0-58m31", &dpll0.common.hw,
+                          32, 1, 0);
+
+static struct sprd_clk_common *ums512_g0_pll_clks[] = {
+       /* address base is 0x32390000 */
+       &dpll0.common,
+};
+
+static struct clk_hw_onecell_data ums512_g0_pll_hws = {
+       .hws    = {
+               [CLK_DPLL0]             = &dpll0.common.hw,
+               [CLK_DPLL0_58M31]       = &dpll0_58m31.hw,
+       },
+       .num    = CLK_ANLG_PHY_G0_NUM,
+};
+
+static struct sprd_clk_desc ums512_g0_pll_desc = {
+       .clk_clks       = ums512_g0_pll_clks,
+       .num_clk_clks   = ARRAY_SIZE(ums512_g0_pll_clks),
+       .hw_clks        = &ums512_g0_pll_hws,
+};
+
+/* pll clock at g2 */
+static const u64 itable_mpll[8] = { 7, 0,
+                       1400000000ULL, 1600000000ULL,
+                       1800000000ULL, 2000000000ULL,
+                       2200000000ULL, 2500000000ULL };
+
+static struct clk_bit_field f_mpll[PLL_FACT_MAX] = {
+       { .shift = 17,  .width = 1 },   /* lock_done    */
+       { .shift = 0,   .width = 1 },   /* div_s        */
+       { .shift = 67,  .width = 1 },   /* mod_en       */
+       { .shift = 1,   .width = 1 },   /* sdm_en       */
+       { .shift = 0,   .width = 0 },   /* refin        */
+       { .shift = 2,   .width = 3 },   /* icp          */
+       { .shift = 5,   .width = 11 },  /* n            */
+       { .shift = 55,  .width = 7 },   /* nint         */
+       { .shift = 32,  .width = 23},   /* kint         */
+       { .shift = 0,   .width = 0 },   /* prediv       */
+       { .shift = 77,  .width = 1 },   /* postdiv      */
+};
+static SPRD_PLL_HW(mpll1, "mpll1", &mpll1_gate.common.hw, 0x0, 3,
+                  itable_mpll, f_mpll, 240, 1000, 1000, 1, 1200000000);
+static CLK_FIXED_FACTOR_HW(mpll1_63m38, "mpll1-63m38", &mpll1.common.hw,
+                          32, 1, 0);
+
+static struct sprd_clk_common *ums512_g2_pll_clks[] = {
+       /* address base is 0x323B0000 */
+       &mpll1.common,
+};
+
+static struct clk_hw_onecell_data ums512_g2_pll_hws = {
+       .hws    = {
+               [CLK_MPLL1]             = &mpll1.common.hw,
+               [CLK_MPLL1_63M38]       = &mpll1_63m38.hw,
+       },
+       .num    = CLK_ANLG_PHY_G2_NUM,
+};
+
+static struct sprd_clk_desc ums512_g2_pll_desc = {
+       .clk_clks       = ums512_g2_pll_clks,
+       .num_clk_clks   = ARRAY_SIZE(ums512_g2_pll_clks),
+       .hw_clks        = &ums512_g2_pll_hws,
+};
+
+/* pll at g3 */
+static const u64 itable[8] = { 7, 0, 0,
+                       900000000ULL, 1100000000ULL,
+                       1300000000ULL, 1500000000ULL,
+                       1600000000ULL };
+
+static struct clk_bit_field f_pll[PLL_FACT_MAX] = {
+       { .shift = 18,  .width = 1 },   /* lock_done    */
+       { .shift = 0,   .width = 1 },   /* div_s        */
+       { .shift = 67,  .width = 1 },   /* mod_en       */
+       { .shift = 1,   .width = 1 },   /* sdm_en       */
+       { .shift = 0,   .width = 0 },   /* refin        */
+       { .shift = 2,   .width = 3 },   /* icp          */
+       { .shift = 5,   .width = 11 },  /* n            */
+       { .shift = 55,  .width = 7 },   /* nint         */
+       { .shift = 32,  .width = 23},   /* kint         */
+       { .shift = 0,   .width = 0 },   /* prediv       */
+       { .shift = 77,  .width = 1 },   /* postdiv      */
+};
+
+static SPRD_PLL_FW_NAME(rpll, "rpll", "ext-26m", 0x0, 3,
+                       itable, f_pll, 240, 1000, 1000, 1, 750000000);
+
+static SPRD_SC_GATE_CLK_FW_NAME(audio_gate, "audio-gate", "ext-26m", 0x24,
+                               0x1000, BIT(1), CLK_IGNORE_UNUSED, 0);
+
+static struct clk_bit_field f_mpll2[PLL_FACT_MAX] = {
+       { .shift = 16,  .width = 1 },   /* lock_done    */
+       { .shift = 0,   .width = 1 },   /* div_s        */
+       { .shift = 67,  .width = 1 },   /* mod_en       */
+       { .shift = 1,   .width = 1 },   /* sdm_en       */
+       { .shift = 0,   .width = 0 },   /* refin        */
+       { .shift = 2,   .width = 3 },   /* icp          */
+       { .shift = 5,   .width = 11 },  /* n            */
+       { .shift = 55,  .width = 7 },   /* nint         */
+       { .shift = 32,  .width = 23},   /* kint         */
+       { .shift = 0,   .width = 0 },   /* prediv       */
+       { .shift = 77,  .width = 1 },   /* postdiv      */
+};
+static SPRD_PLL_HW(mpll0, "mpll0", &mpll0_gate.common.hw, 0x54, 3,
+                  itable_mpll, f_mpll, 240, 1000, 1000, 1, 1200000000);
+static CLK_FIXED_FACTOR_HW(mpll0_56m88, "mpll0-56m88", &mpll0.common.hw,
+                          32, 1, 0);
+
+static const u64 itable_mpll2[6] = { 5,
+                       1200000000ULL, 1400000000ULL,
+                       1600000000ULL, 1800000000ULL,
+                       2000000000ULL };
+
+static SPRD_PLL_HW(mpll2, "mpll2", &mpll2_gate.common.hw, 0x9c, 3,
+                  itable_mpll2, f_mpll2, 240, 1000, 1000, 1, 1000000000);
+static CLK_FIXED_FACTOR_HW(mpll2_47m13, "mpll2-47m13", &mpll2.common.hw,
+                          32, 1, 0);
+
+static struct sprd_clk_common *ums512_g3_pll_clks[] = {
+       /* address base is 0x323c0000 */
+       &rpll.common,
+       &audio_gate.common,
+       &mpll0.common,
+       &mpll2.common,
+};
+
+static struct clk_hw_onecell_data ums512_g3_pll_hws = {
+       .hws    = {
+               [CLK_RPLL]              = &rpll.common.hw,
+               [CLK_AUDIO_GATE]        = &audio_gate.common.hw,
+               [CLK_MPLL0]             = &mpll0.common.hw,
+               [CLK_MPLL0_56M88]       = &mpll0_56m88.hw,
+               [CLK_MPLL2]             = &mpll2.common.hw,
+               [CLK_MPLL2_47M13]       = &mpll2_47m13.hw,
+       },
+       .num    = CLK_ANLG_PHY_G3_NUM,
+};
+
+static struct sprd_clk_desc ums512_g3_pll_desc = {
+       .clk_clks       = ums512_g3_pll_clks,
+       .num_clk_clks   = ARRAY_SIZE(ums512_g3_pll_clks),
+       .hw_clks        = &ums512_g3_pll_hws,
+};
+
+/* pll clock at gc */
+static SPRD_PLL_FW_NAME(twpll, "twpll", "ext-26m", 0x0, 3,
+                       itable, f_pll, 240, 1000, 1000, 1, 750000000);
+static CLK_FIXED_FACTOR_HW(twpll_768m, "twpll-768m", &twpll.common.hw,
+                          2, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_384m, "twpll-384m", &twpll.common.hw,
+                          4, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_192m, "twpll-192m", &twpll.common.hw,
+                          8, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_96m, "twpll-96m", &twpll.common.hw,
+                          16, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_48m, "twpll-48m", &twpll.common.hw,
+                          32, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_24m, "twpll-24m", &twpll.common.hw,
+                          64, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_12m, "twpll-12m", &twpll.common.hw,
+                          128, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_512m, "twpll-512m", &twpll.common.hw,
+                          3, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_256m, "twpll-256m", &twpll.common.hw,
+                          6, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_128m, "twpll-128m", &twpll.common.hw,
+                          12, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_64m, "twpll-64m", &twpll.common.hw,
+                          24, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_307m2, "twpll-307m2", &twpll.common.hw,
+                          5, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_219m4, "twpll-219m4", &twpll.common.hw,
+                          7, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_170m6, "twpll-170m6", &twpll.common.hw,
+                          9, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_153m6, "twpll-153m6", &twpll.common.hw,
+                          10, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_76m8, "twpll-76m8", &twpll.common.hw,
+                          20, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_51m2, "twpll-51m2", &twpll.common.hw,
+                          30, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_38m4, "twpll-38m4", &twpll.common.hw,
+                          40, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_19m2, "twpll-19m2", &twpll.common.hw,
+                          80, 1, 0);
+static CLK_FIXED_FACTOR_HW(twpll_12m29, "twpll-12m29", &twpll.common.hw,
+                          125, 1, 0);
+
+static SPRD_PLL_FW_NAME(lpll, "lpll", "ext-26m", 0x18, 3,
+                       itable, f_pll, 240, 1000, 1000, 1, 750000000);
+static CLK_FIXED_FACTOR_HW(lpll_614m4, "lpll-614m4", &lpll.common.hw,
+                          2, 1, 0);
+static CLK_FIXED_FACTOR_HW(lpll_409m6, "lpll-409m6", &lpll.common.hw,
+                          3, 1, 0);
+static CLK_FIXED_FACTOR_HW(lpll_245m76, "lpll-245m76", &lpll.common.hw,
+                          5, 1, 0);
+static CLK_FIXED_FACTOR_HW(lpll_30m72, "lpll-30m72", &lpll.common.hw,
+                          40, 1, 0);
+
+static SPRD_PLL_FW_NAME(isppll, "isppll", "ext-26m", 0x30, 3,
+                       itable, f_pll, 240, 1000, 1000, 1, 750000000);
+static CLK_FIXED_FACTOR_HW(isppll_468m, "isppll-468m", &isppll.common.hw,
+                          2, 1, 0);
+static CLK_FIXED_FACTOR_HW(isppll_78m, "isppll-78m", &isppll.common.hw,
+                          12, 1, 0);
+
+static SPRD_PLL_HW(gpll, "gpll", &gpll_gate.common.hw, 0x48, 3,
+                  itable, f_pll, 240, 1000, 1000, 1, 750000000);
+static CLK_FIXED_FACTOR_HW(gpll_40m, "gpll-40m", &gpll.common.hw,
+                          20, 1, 0);
+
+static SPRD_PLL_HW(cppll, "cppll", &cppll_gate.common.hw, 0x60, 3,
+                  itable, f_pll, 240, 1000, 1000, 1, 750000000);
+static CLK_FIXED_FACTOR_HW(cppll_39m32, "cppll-39m32", &cppll.common.hw,
+                          26, 1, 0);
+
+static struct sprd_clk_common *ums512_gc_pll_clks[] = {
+       /* address base is 0x323e0000 */
+       &twpll.common,
+       &lpll.common,
+       &isppll.common,
+       &gpll.common,
+       &cppll.common,
+};
+
+static struct clk_hw_onecell_data ums512_gc_pll_hws = {
+       .hws    = {
+               [CLK_TWPLL]             = &twpll.common.hw,
+               [CLK_TWPLL_768M]        = &twpll_768m.hw,
+               [CLK_TWPLL_384M]        = &twpll_384m.hw,
+               [CLK_TWPLL_192M]        = &twpll_192m.hw,
+               [CLK_TWPLL_96M]         = &twpll_96m.hw,
+               [CLK_TWPLL_48M]         = &twpll_48m.hw,
+               [CLK_TWPLL_24M]         = &twpll_24m.hw,
+               [CLK_TWPLL_12M]         = &twpll_12m.hw,
+               [CLK_TWPLL_512M]        = &twpll_512m.hw,
+               [CLK_TWPLL_256M]        = &twpll_256m.hw,
+               [CLK_TWPLL_128M]        = &twpll_128m.hw,
+               [CLK_TWPLL_64M]         = &twpll_64m.hw,
+               [CLK_TWPLL_307M2]       = &twpll_307m2.hw,
+               [CLK_TWPLL_219M4]       = &twpll_219m4.hw,
+               [CLK_TWPLL_170M6]       = &twpll_170m6.hw,
+               [CLK_TWPLL_153M6]       = &twpll_153m6.hw,
+               [CLK_TWPLL_76M8]        = &twpll_76m8.hw,
+               [CLK_TWPLL_51M2]        = &twpll_51m2.hw,
+               [CLK_TWPLL_38M4]        = &twpll_38m4.hw,
+               [CLK_TWPLL_19M2]        = &twpll_19m2.hw,
+               [CLK_TWPLL_12M29]       = &twpll_12m29.hw,
+               [CLK_LPLL]              = &lpll.common.hw,
+               [CLK_LPLL_614M4]        = &lpll_614m4.hw,
+               [CLK_LPLL_409M6]        = &lpll_409m6.hw,
+               [CLK_LPLL_245M76]       = &lpll_245m76.hw,
+               [CLK_LPLL_30M72]        = &lpll_30m72.hw,
+               [CLK_ISPPLL]            = &isppll.common.hw,
+               [CLK_ISPPLL_468M]       = &isppll_468m.hw,
+               [CLK_ISPPLL_78M]        = &isppll_78m.hw,
+               [CLK_GPLL]              = &gpll.common.hw,
+               [CLK_GPLL_40M]          = &gpll_40m.hw,
+               [CLK_CPPLL]             = &cppll.common.hw,
+               [CLK_CPPLL_39M32]       = &cppll_39m32.hw,
+       },
+       .num    = CLK_ANLG_PHY_GC_NUM,
+};
+
+static struct sprd_clk_desc ums512_gc_pll_desc = {
+       .clk_clks       = ums512_gc_pll_clks,
+       .num_clk_clks   = ARRAY_SIZE(ums512_gc_pll_clks),
+       .hw_clks        = &ums512_gc_pll_hws,
+};
+
+/* ap ahb gates */
+static SPRD_SC_GATE_CLK_FW_NAME(dsi_eb, "dsi-eb", "ext-26m",
+                               0x0, 0x1000, BIT(0), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(dispc_eb, "dispc-eb", "ext-26m",
+                               0x0, 0x1000, BIT(1), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(vsp_eb, "vsp-eb", "ext-26m",
+                               0x0, 0x1000, BIT(2), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(vdma_eb, "vdma-eb", "ext-26m",
+                               0x0, 0x1000, BIT(3), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(dma_pub_eb, "dma-pub-eb", "ext-26m",
+                               0x0, 0x1000, BIT(4), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(dma_sec_eb, "dma-sec-eb", "ext-26m",
+                               0x0, 0x1000, BIT(5), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ipi_eb, "ipi-eb", "ext-26m",
+                               0x0, 0x1000, BIT(6), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ahb_ckg_eb, "ahb-ckg-eb", "ext-26m",
+                               0x0, 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(bm_clk_eb, "bm-clk-eb", "ext-26m",
+                               0x0, 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0);
+
+static struct sprd_clk_common *ums512_apahb_gate[] = {
+       /* address base is 0x20100000 */
+       &dsi_eb.common,
+       &dispc_eb.common,
+       &vsp_eb.common,
+       &vdma_eb.common,
+       &dma_pub_eb.common,
+       &dma_sec_eb.common,
+       &ipi_eb.common,
+       &ahb_ckg_eb.common,
+       &bm_clk_eb.common,
+};
+
+static struct clk_hw_onecell_data ums512_apahb_gate_hws = {
+       .hws    = {
+               [CLK_DSI_EB]            = &dsi_eb.common.hw,
+               [CLK_DISPC_EB]          = &dispc_eb.common.hw,
+               [CLK_VSP_EB]            = &vsp_eb.common.hw,
+               [CLK_VDMA_EB]           = &vdma_eb.common.hw,
+               [CLK_DMA_PUB_EB]        = &dma_pub_eb.common.hw,
+               [CLK_DMA_SEC_EB]        = &dma_sec_eb.common.hw,
+               [CLK_IPI_EB]            = &ipi_eb.common.hw,
+               [CLK_AHB_CKG_EB]        = &ahb_ckg_eb.common.hw,
+               [CLK_BM_CLK_EB]         = &bm_clk_eb.common.hw,
+       },
+       .num    = CLK_AP_AHB_GATE_NUM,
+};
+
+static struct sprd_clk_desc ums512_apahb_gate_desc = {
+       .clk_clks       = ums512_apahb_gate,
+       .num_clk_clks   = ARRAY_SIZE(ums512_apahb_gate),
+       .hw_clks        = &ums512_apahb_gate_hws,
+};
+
+/* ap clks */
+static const struct clk_parent_data ap_apb_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_64m.hw  },
+       { .hw = &twpll_96m.hw  },
+       { .hw = &twpll_128m.hw  },
+};
+static SPRD_MUX_CLK_DATA(ap_apb_clk, "ap-apb-clk", ap_apb_parents,
+                        0x20, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data ipi_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_64m.hw  },
+       { .hw = &twpll_96m.hw  },
+       { .hw = &twpll_128m.hw  },
+};
+static SPRD_MUX_CLK_DATA(ipi_clk, "ipi-clk", ipi_parents,
+                        0x24, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data ap_uart_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_48m.hw  },
+       { .hw = &twpll_51m2.hw  },
+       { .hw = &twpll_96m.hw  },
+};
+static SPRD_COMP_CLK_DATA(ap_uart0_clk, "ap-uart0-clk", ap_uart_parents,
+                         0x28, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK_DATA(ap_uart1_clk, "ap-uart1-clk", ap_uart_parents,
+                         0x2c, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK_DATA(ap_uart2_clk, "ap-uart2-clk", ap_uart_parents,
+                         0x30, 0, 2, 8, 3, 0);
+
+static const struct clk_parent_data i2c_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_48m.hw  },
+       { .hw = &twpll_51m2.hw  },
+       { .hw = &twpll_153m6.hw  },
+};
+static SPRD_COMP_CLK_DATA(ap_i2c0_clk, "ap-i2c0-clk", i2c_parents,
+                         0x34, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK_DATA(ap_i2c1_clk, "ap-i2c1-clk", i2c_parents,
+                         0x38, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK_DATA(ap_i2c2_clk, "ap-i2c2-clk", i2c_parents,
+                         0x3c, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK_DATA(ap_i2c3_clk, "ap-i2c3-clk", i2c_parents,
+                         0x40, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK_DATA(ap_i2c4_clk, "ap-i2c4-clk", i2c_parents,
+                         0x44, 0, 2, 8, 3, 0);
+
+static const struct clk_parent_data spi_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_128m.hw  },
+       { .hw = &twpll_153m6.hw  },
+       { .hw = &twpll_192m.hw  },
+};
+static SPRD_COMP_CLK_DATA(ap_spi0_clk, "ap-spi0-clk", spi_parents,
+                         0x48, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK_DATA(ap_spi1_clk, "ap-spi1-clk", spi_parents,
+                         0x4c, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK_DATA(ap_spi2_clk, "ap-spi2-clk", spi_parents,
+                         0x50, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK_DATA(ap_spi3_clk, "ap-spi3-clk", spi_parents,
+                         0x54, 0, 2, 8, 3, 0);
+
+static const struct clk_parent_data iis_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_128m.hw  },
+       { .hw = &twpll_153m6.hw  },
+};
+static SPRD_COMP_CLK_DATA(ap_iis0_clk, "ap-iis0-clk", iis_parents,
+                         0x58, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK_DATA(ap_iis1_clk, "ap-iis1-clk", iis_parents,
+                         0x5c, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK_DATA(ap_iis2_clk, "ap-iis2-clk", iis_parents,
+                         0x60, 0, 2, 8, 3, 0);
+
+static const struct clk_parent_data sim_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_51m2.hw  },
+       { .hw = &twpll_64m.hw  },
+       { .hw = &twpll_96m.hw  },
+       { .hw = &twpll_128m.hw  },
+};
+static SPRD_COMP_CLK_DATA(ap_sim_clk, "ap-sim-clk", sim_parents,
+                         0x64, 0, 3, 8, 3, 0);
+
+static const struct clk_parent_data ap_ce_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_96m.hw  },
+       { .hw = &twpll_192m.hw  },
+       { .hw = &twpll_256m.hw  },
+};
+static SPRD_MUX_CLK_DATA(ap_ce_clk, "ap-ce-clk", ap_ce_parents,
+                        0x68, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data sdio_parents[] = {
+       { .hw = &clk_1m.hw  },
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_307m2.hw  },
+       { .hw = &twpll_384m.hw  },
+       { .hw = &rpll.common.hw  },
+       { .hw = &lpll_409m6.hw  },
+};
+static SPRD_MUX_CLK_DATA(sdio0_2x_clk, "sdio0-2x", sdio_parents,
+                        0x80, 0, 3, UMS512_MUX_FLAG);
+static SPRD_MUX_CLK_DATA(sdio1_2x_clk, "sdio1-2x", sdio_parents,
+                        0x88, 0, 3, UMS512_MUX_FLAG);
+static SPRD_MUX_CLK_DATA(emmc_2x_clk, "emmc-2x", sdio_parents,
+                        0x90, 0, 3, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data vsp_parents[] = {
+       { .hw = &twpll_256m.hw  },
+       { .hw = &twpll_307m2.hw  },
+       { .hw = &twpll_384m.hw  },
+};
+static SPRD_MUX_CLK_DATA(vsp_clk, "vsp-clk", vsp_parents,
+                        0x98, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data dispc0_parents[] = {
+       { .hw = &twpll_153m6.hw  },
+       { .hw = &twpll_192m.hw  },
+       { .hw = &twpll_256m.hw  },
+       { .hw = &twpll_307m2.hw  },
+       { .hw = &twpll_384m.hw  },
+};
+static SPRD_MUX_CLK_DATA(dispc0_clk, "dispc0-clk", dispc0_parents,
+                        0x9c, 0, 3, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data dispc0_dpi_parents[] = {
+       { .hw = &twpll_96m.hw  },
+       { .hw = &twpll_128m.hw  },
+       { .hw = &twpll_153m6.hw  },
+       { .hw = &twpll_192m.hw  },
+};
+static SPRD_COMP_CLK_DATA(dispc0_dpi_clk, "dispc0-dpi-clk", dispc0_dpi_parents,
+                         0xa0, 0, 3, 8, 4, 0);
+
+static const struct clk_parent_data dsi_apb_parents[] = {
+       { .hw = &twpll_96m.hw  },
+       { .hw = &twpll_128m.hw  },
+       { .hw = &twpll_153m6.hw  },
+       { .hw = &twpll_192m.hw  },
+};
+static SPRD_MUX_CLK_DATA(dsi_apb_clk, "dsi-apb-clk", dsi_apb_parents,
+                        0xa4, 0, 2, UMS512_MUX_FLAG);
+
+static SPRD_GATE_CLK_FW_NAME(dsi_rxesc, "dsi-rxesc", "ext-26m",
+                            0xa8, BIT(16), 0, 0);
+
+static SPRD_GATE_CLK_FW_NAME(dsi_lanebyte, "dsi-lanebyte", "ext-26m",
+                            0xac, BIT(16), 0, 0);
+
+static const struct clk_parent_data vdsp_parents[] = {
+       { .hw = &twpll_256m.hw  },
+       { .hw = &twpll_384m.hw  },
+       { .hw = &twpll_512m.hw  },
+       { .hw = &lpll_614m4.hw  },
+       { .hw = &twpll_768m.hw  },
+       { .hw = &isppll.common.hw  },
+};
+static SPRD_MUX_CLK_DATA(vdsp_clk, "vdsp-clk", vdsp_parents,
+                        0xb0, 0, 3, UMS512_MUX_FLAG);
+static SPRD_DIV_CLK_HW(vdsp_m_clk, "vdsp-m-clk", &vdsp_clk.common.hw,
+                      0xb4, 8, 2, 0);
+
+static struct sprd_clk_common *ums512_ap_clks[] = {
+       /* address base is 0x20200000 */
+       &ap_apb_clk.common,
+       &ipi_clk.common,
+       &ap_uart0_clk.common,
+       &ap_uart1_clk.common,
+       &ap_uart2_clk.common,
+       &ap_i2c0_clk.common,
+       &ap_i2c1_clk.common,
+       &ap_i2c2_clk.common,
+       &ap_i2c3_clk.common,
+       &ap_i2c4_clk.common,
+       &ap_spi0_clk.common,
+       &ap_spi1_clk.common,
+       &ap_spi2_clk.common,
+       &ap_spi3_clk.common,
+       &ap_iis0_clk.common,
+       &ap_iis1_clk.common,
+       &ap_iis2_clk.common,
+       &ap_sim_clk.common,
+       &ap_ce_clk.common,
+       &sdio0_2x_clk.common,
+       &sdio1_2x_clk.common,
+       &emmc_2x_clk.common,
+       &vsp_clk.common,
+       &dispc0_clk.common,
+       &dispc0_dpi_clk.common,
+       &dsi_apb_clk.common,
+       &dsi_rxesc.common,
+       &dsi_lanebyte.common,
+       &vdsp_clk.common,
+       &vdsp_m_clk.common,
+
+};
+
+static struct clk_hw_onecell_data ums512_ap_clk_hws = {
+       .hws    = {
+               [CLK_AP_APB]            = &ap_apb_clk.common.hw,
+               [CLK_IPI]               = &ipi_clk.common.hw,
+               [CLK_AP_UART0]          = &ap_uart0_clk.common.hw,
+               [CLK_AP_UART1]          = &ap_uart1_clk.common.hw,
+               [CLK_AP_UART2]          = &ap_uart2_clk.common.hw,
+               [CLK_AP_I2C0]           = &ap_i2c0_clk.common.hw,
+               [CLK_AP_I2C1]           = &ap_i2c1_clk.common.hw,
+               [CLK_AP_I2C2]           = &ap_i2c2_clk.common.hw,
+               [CLK_AP_I2C3]           = &ap_i2c3_clk.common.hw,
+               [CLK_AP_I2C4]           = &ap_i2c4_clk.common.hw,
+               [CLK_AP_SPI0]           = &ap_spi0_clk.common.hw,
+               [CLK_AP_SPI1]           = &ap_spi1_clk.common.hw,
+               [CLK_AP_SPI2]           = &ap_spi2_clk.common.hw,
+               [CLK_AP_SPI3]           = &ap_spi3_clk.common.hw,
+               [CLK_AP_IIS0]           = &ap_iis0_clk.common.hw,
+               [CLK_AP_IIS1]           = &ap_iis1_clk.common.hw,
+               [CLK_AP_IIS2]           = &ap_iis2_clk.common.hw,
+               [CLK_AP_SIM]            = &ap_sim_clk.common.hw,
+               [CLK_AP_CE]             = &ap_ce_clk.common.hw,
+               [CLK_SDIO0_2X]          = &sdio0_2x_clk.common.hw,
+               [CLK_SDIO1_2X]          = &sdio1_2x_clk.common.hw,
+               [CLK_EMMC_2X]           = &emmc_2x_clk.common.hw,
+               [CLK_VSP]               = &vsp_clk.common.hw,
+               [CLK_DISPC0]            = &dispc0_clk.common.hw,
+               [CLK_DISPC0_DPI]        = &dispc0_dpi_clk.common.hw,
+               [CLK_DSI_APB]           = &dsi_apb_clk.common.hw,
+               [CLK_DSI_RXESC]         = &dsi_rxesc.common.hw,
+               [CLK_DSI_LANEBYTE]      = &dsi_lanebyte.common.hw,
+               [CLK_VDSP]              = &vdsp_clk.common.hw,
+               [CLK_VDSP_M]            = &vdsp_m_clk.common.hw,
+       },
+       .num    = CLK_AP_CLK_NUM,
+};
+
+static struct sprd_clk_desc ums512_ap_clk_desc = {
+       .clk_clks       = ums512_ap_clks,
+       .num_clk_clks   = ARRAY_SIZE(ums512_ap_clks),
+       .hw_clks        = &ums512_ap_clk_hws,
+};
+
+/* aon apb clks */
+static const struct clk_parent_data aon_apb_parents[] = {
+       { .hw = &rco_4m.hw  },
+       { .fw_name = "ext-4m"  },
+       { .hw = &clk_13m.hw  },
+       { .hw = &rco_25m.hw  },
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_96m.hw  },
+       { .fw_name = "rco-100m" },
+       { .hw = &twpll_128m.hw  },
+};
+static SPRD_COMP_CLK_DATA(aon_apb_clk, "aon-apb-clk", aon_apb_parents,
+                         0x220, 0, 3, 8, 2, 0);
+
+
+static const struct clk_parent_data adi_parents[] = {
+       { .hw = &rco_4m.hw  },
+       { .fw_name = "ext-26m" },
+       { .hw = &rco_25m.hw  },
+       { .hw = &twpll_38m4.hw  },
+       { .hw = &twpll_51m2.hw  },
+};
+static SPRD_MUX_CLK_DATA(adi_clk, "adi-clk", adi_parents,
+                        0x224, 0, 3, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data aux_parents[] = {
+       { .fw_name = "ext-32k" },
+       { .fw_name = "ext-26m" },
+       { .hw = &clk_26m_aud.hw  },
+       { .hw = &rco_25m.hw  },
+       { .hw = &cppll_39m32.hw  },
+       { .hw = &mpll0_56m88.hw  },
+       { .hw = &mpll1_63m38.hw  },
+       { .hw = &mpll2_47m13.hw  },
+       { .hw = &dpll0_58m31.hw  },
+       { .hw = &gpll_40m.hw  },
+       { .hw = &twpll_48m.hw  },
+};
+static const struct clk_parent_data aux1_parents[] = {
+       { .fw_name = "ext-32k" },
+       { .fw_name = "ext-26m" },
+       { .hw = &clk_26m_aud.hw  },
+       { .hw = &rco_25m.hw  },
+       { .hw = &cppll_39m32.hw  },
+       { .hw = &mpll0_56m88.hw  },
+       { .hw = &mpll1_63m38.hw  },
+       { .hw = &mpll2_47m13.hw  },
+       { .hw = &dpll0_58m31.hw  },
+       { .hw = &gpll_40m.hw  },
+       { .hw = &twpll_19m2.hw  },
+       { .hw = &lpll_30m72.hw  },
+       { .hw = &rpll.common.hw  },
+       { .hw = &twpll_12m29.hw  },
+
+};
+static SPRD_COMP_CLK_DATA(aux0_clk, "aux0-clk", aux_parents,
+                         0x228, 0, 5, 8, 4, 0);
+static SPRD_COMP_CLK_DATA(aux1_clk, "aux1-clk", aux1_parents,
+                         0x22c, 0, 5, 8, 4, 0);
+static SPRD_COMP_CLK_DATA(aux2_clk, "aux2-clk", aux_parents,
+                         0x230, 0, 5, 8, 4, 0);
+static SPRD_COMP_CLK_DATA(probe_clk, "probe-clk", aux_parents,
+                         0x234, 0, 5, 8, 4, 0);
+
+static const struct clk_parent_data pwm_parents[] = {
+       { .fw_name = "ext-32k" },
+       { .fw_name = "ext-26m" },
+       { .hw = &rco_4m.hw  },
+       { .hw = &rco_25m.hw  },
+       { .hw = &twpll_48m.hw  },
+};
+static SPRD_MUX_CLK_DATA(pwm0_clk, "pwm0-clk", pwm_parents,
+                        0x238, 0, 3, UMS512_MUX_FLAG);
+static SPRD_MUX_CLK_DATA(pwm1_clk, "pwm1-clk", pwm_parents,
+                        0x23c, 0, 3, UMS512_MUX_FLAG);
+static SPRD_MUX_CLK_DATA(pwm2_clk, "pwm2-clk", pwm_parents,
+                        0x240, 0, 3, UMS512_MUX_FLAG);
+static SPRD_MUX_CLK_DATA(pwm3_clk, "pwm3-clk", pwm_parents,
+                        0x244, 0, 3, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data efuse_parents[] = {
+       { .hw = &rco_25m.hw  },
+       { .fw_name = "ext-26m" },
+};
+static SPRD_MUX_CLK_DATA(efuse_clk, "efuse-clk", efuse_parents,
+                        0x248, 0, 1, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data uart_parents[] = {
+       { .hw = &rco_4m.hw  },
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_48m.hw  },
+       { .hw = &twpll_51m2.hw  },
+       { .hw = &twpll_96m.hw  },
+       { .fw_name = "rco-100m" },
+       { .hw = &twpll_128m.hw  },
+};
+static SPRD_MUX_CLK_DATA(uart0_clk, "uart0-clk", uart_parents,
+                        0x24c, 0, 3, UMS512_MUX_FLAG);
+static SPRD_MUX_CLK_DATA(uart1_clk, "uart1-clk", uart_parents,
+                        0x250, 0, 3, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data thm_parents[] = {
+       { .fw_name = "ext-32m" },
+       { .hw = &clk_250k.hw  },
+};
+static SPRD_MUX_CLK_DATA(thm0_clk, "thm0-clk", thm_parents,
+                        0x260, 0, 1, UMS512_MUX_FLAG);
+static SPRD_MUX_CLK_DATA(thm1_clk, "thm1-clk", thm_parents,
+                        0x264, 0, 1, UMS512_MUX_FLAG);
+static SPRD_MUX_CLK_DATA(thm2_clk, "thm2-clk", thm_parents,
+                        0x268, 0, 1, UMS512_MUX_FLAG);
+static SPRD_MUX_CLK_DATA(thm3_clk, "thm3-clk", thm_parents,
+                        0x26c, 0, 1, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data aon_i2c_parents[] = {
+       { .hw = &rco_4m.hw  },
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_48m.hw  },
+       { .hw = &twpll_51m2.hw  },
+       { .fw_name = "rco-100m" },
+       { .hw = &twpll_153m6.hw  },
+};
+static SPRD_MUX_CLK_DATA(aon_i2c_clk, "aon-i2c-clk", aon_i2c_parents,
+                        0x27c, 0, 3, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data aon_iis_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_128m.hw  },
+       { .hw = &twpll_153m6.hw  },
+};
+static SPRD_MUX_CLK_DATA(aon_iis_clk, "aon-iis-clk", aon_iis_parents,
+                        0x280, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data scc_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_48m.hw  },
+       { .hw = &twpll_51m2.hw  },
+       { .hw = &twpll_96m.hw  },
+};
+static SPRD_MUX_CLK_DATA(scc_clk, "scc-clk", scc_parents,
+                        0x284, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data apcpu_dap_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &rco_4m.hw  },
+       { .hw = &twpll_76m8.hw  },
+       { .fw_name = "rco-100m" },
+       { .hw = &twpll_128m.hw  },
+       { .hw = &twpll_153m6.hw  },
+};
+static SPRD_MUX_CLK_DATA(apcpu_dap_clk, "apcpu-dap-clk", apcpu_dap_parents,
+                        0x288, 0, 3, UMS512_MUX_FLAG);
+
+static SPRD_GATE_CLK_FW_NAME(apcpu_dap_mtck, "apcpu-dap-mtck", "ext-26m",
+                            0x28c, BIT(16), 0, 0);
+
+static const struct clk_parent_data apcpu_ts_parents[] = {
+       { .fw_name = "ext-32m" },
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_128m.hw  },
+       { .hw = &twpll_153m6.hw  },
+};
+static SPRD_MUX_CLK_DATA(apcpu_ts_clk, "apcpu-ts-clk", apcpu_ts_parents,
+                        0x290, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data debug_ts_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_76m8.hw  },
+       { .hw = &twpll_128m.hw  },
+       { .hw = &twpll_192m.hw  },
+};
+static SPRD_MUX_CLK_DATA(debug_ts_clk, "debug-ts-clk", debug_ts_parents,
+                        0x294, 0, 2, UMS512_MUX_FLAG);
+
+static SPRD_GATE_CLK_FW_NAME(dsi_test_s, "dsi-test-s", "ext-26m",
+                            0x298, BIT(16), 0, 0);
+
+static const struct clk_parent_data djtag_tck_parents[] = {
+       { .hw = &rco_4m.hw  },
+       { .fw_name = "ext-26m" },
+};
+static SPRD_MUX_CLK_DATA(djtag_tck_clk, "djtag-tck-clk", djtag_tck_parents,
+                        0x2b4, 0, 1, UMS512_MUX_FLAG);
+
+static SPRD_GATE_CLK_FW_NAME(djtag_tck_hw, "djtag-tck-hw", "ext-26m",
+                            0x2b8, BIT(16), 0, 0);
+
+static const struct clk_parent_data aon_tmr_parents[] = {
+       { .hw = &rco_4m.hw  },
+       { .hw = &rco_25m.hw  },
+       { .fw_name = "ext-26m" },
+};
+static SPRD_MUX_CLK_DATA(aon_tmr_clk, "aon-tmr-clk", aon_tmr_parents,
+                        0x2c0, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data aon_pmu_parents[] = {
+       { .fw_name = "ext-32k" },
+       { .hw = &rco_4m.hw  },
+       { .fw_name = "ext-4m" },
+};
+static SPRD_MUX_CLK_DATA(aon_pmu_clk, "aon-pmu-clk", aon_pmu_parents,
+                        0x2c8, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data debounce_parents[] = {
+       { .fw_name = "ext-32k" },
+       { .hw = &rco_4m.hw  },
+       { .hw = &rco_25m.hw  },
+       { .fw_name = "ext-26m" },
+};
+static SPRD_MUX_CLK_DATA(debounce_clk, "debounce-clk", debounce_parents,
+                        0x2cc, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data apcpu_pmu_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_76m8.hw  },
+       { .fw_name = "rco-100m" },
+       { .hw = &twpll_128m.hw  },
+};
+static SPRD_MUX_CLK_DATA(apcpu_pmu_clk, "apcpu-pmu-clk", apcpu_pmu_parents,
+                        0x2d0, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data top_dvfs_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_96m.hw  },
+       { .fw_name = "rco-100m" },
+       { .hw = &twpll_128m.hw  },
+};
+static SPRD_MUX_CLK_DATA(top_dvfs_clk, "top-dvfs-clk", top_dvfs_parents,
+                        0x2d8, 0, 2, UMS512_MUX_FLAG);
+
+static SPRD_GATE_CLK_FW_NAME(otg_utmi, "otg-utmi", "ext-26m", 0x2dc,
+                               BIT(16), 0, 0);
+
+static const struct clk_parent_data otg_ref_parents[] = {
+       { .hw = &twpll_12m.hw  },
+       { .fw_name = "ext-26m" },
+};
+static SPRD_MUX_CLK_DATA(otg_ref_clk, "otg-ref-clk", otg_ref_parents,
+                        0x2e0, 0, 1, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data cssys_parents[] = {
+       { .hw = &rco_25m.hw  },
+       { .fw_name = "ext-26m" },
+       { .fw_name = "rco-100m" },
+       { .hw = &twpll_153m6.hw  },
+       { .hw = &twpll_384m.hw  },
+       { .hw = &twpll_512m.hw  },
+};
+static SPRD_COMP_CLK_DATA(cssys_clk, "cssys-clk", cssys_parents,
+                         0x2e4, 0, 3, 8, 2, 0);
+static SPRD_DIV_CLK_HW(cssys_pub_clk, "cssys-pub-clk", &cssys_clk.common.hw,
+                      0x2e8, 8, 2, 0);
+static SPRD_DIV_CLK_HW(cssys_apb_clk, "cssys-apb-clk", &cssys_clk.common.hw,
+                      0x2ec, 8, 3, 0);
+
+static const struct clk_parent_data ap_axi_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_76m8.hw  },
+       { .hw = &twpll_128m.hw  },
+       { .hw = &twpll_256m.hw  },
+};
+static SPRD_MUX_CLK_DATA(ap_axi_clk, "ap-axi-clk", ap_axi_parents,
+                        0x2f0, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data ap_mm_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_96m.hw  },
+       { .hw = &twpll_128m.hw  },
+       { .hw = &twpll_153m6.hw  },
+};
+static SPRD_MUX_CLK_DATA(ap_mm_clk, "ap-mm-clk", ap_mm_parents,
+                        0x2f4, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data sdio2_2x_parents[] = {
+       { .hw = &clk_1m.hw  },
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_307m2.hw  },
+       { .hw = &twpll_384m.hw  },
+       { .hw = &rpll.common.hw  },
+       { .hw = &lpll_409m6.hw  },
+};
+static SPRD_MUX_CLK_DATA(sdio2_2x_clk, "sdio2-2x-clk", sdio2_2x_parents,
+                        0x2f8, 0, 3, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data analog_io_apb_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_48m.hw  },
+};
+static SPRD_COMP_CLK_DATA(analog_io_apb, "analog-io-apb", analog_io_apb_parents,
+                         0x300, 0, 1, 8, 2, 0);
+
+static const struct clk_parent_data dmc_ref_parents[] = {
+       { .hw = &clk_6m5.hw  },
+       { .hw = &clk_13m.hw  },
+       { .fw_name = "ext-26m" },
+};
+static SPRD_MUX_CLK_DATA(dmc_ref_clk, "dmc-ref-clk", dmc_ref_parents,
+                        0x304, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data emc_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_384m.hw  },
+       { .hw = &twpll_512m.hw  },
+       { .hw = &twpll_768m.hw  },
+};
+static SPRD_MUX_CLK_DATA(emc_clk, "emc-clk", emc_parents,
+                        0x30c, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data usb_parents[] = {
+       { .hw = &rco_25m.hw  },
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_192m.hw  },
+       { .hw = &twpll_96m.hw  },
+       { .fw_name = "rco-100m" },
+       { .hw = &twpll_128m.hw  },
+};
+static SPRD_COMP_CLK_DATA(usb_clk, "usb-clk", usb_parents,
+                         0x310, 0, 3, 8, 2, 0);
+
+static const struct clk_parent_data pmu_26m_parents[] = {
+       { .hw = &rco_25m.hw  },
+       { .fw_name = "ext-26m" },
+};
+static SPRD_MUX_CLK_DATA(pmu_26m_clk, "26m-pmu-clk", pmu_26m_parents,
+                        0x318, 0, 1, UMS512_MUX_FLAG);
+
+static struct sprd_clk_common *ums512_aon_apb[] = {
+       /* address base is 0x32080200 */
+       &aon_apb_clk.common,
+       &adi_clk.common,
+       &aux0_clk.common,
+       &aux1_clk.common,
+       &aux2_clk.common,
+       &probe_clk.common,
+       &pwm0_clk.common,
+       &pwm1_clk.common,
+       &pwm2_clk.common,
+       &pwm3_clk.common,
+       &efuse_clk.common,
+       &uart0_clk.common,
+       &uart1_clk.common,
+       &thm0_clk.common,
+       &thm1_clk.common,
+       &thm2_clk.common,
+       &thm3_clk.common,
+       &aon_i2c_clk.common,
+       &aon_iis_clk.common,
+       &scc_clk.common,
+       &apcpu_dap_clk.common,
+       &apcpu_dap_mtck.common,
+       &apcpu_ts_clk.common,
+       &debug_ts_clk.common,
+       &dsi_test_s.common,
+       &djtag_tck_clk.common,
+       &djtag_tck_hw.common,
+       &aon_tmr_clk.common,
+       &aon_pmu_clk.common,
+       &debounce_clk.common,
+       &apcpu_pmu_clk.common,
+       &top_dvfs_clk.common,
+       &otg_utmi.common,
+       &otg_ref_clk.common,
+       &cssys_clk.common,
+       &cssys_pub_clk.common,
+       &cssys_apb_clk.common,
+       &ap_axi_clk.common,
+       &ap_mm_clk.common,
+       &sdio2_2x_clk.common,
+       &analog_io_apb.common,
+       &dmc_ref_clk.common,
+       &emc_clk.common,
+       &usb_clk.common,
+       &pmu_26m_clk.common,
+};
+
+static struct clk_hw_onecell_data ums512_aon_apb_hws = {
+       .hws    = {
+               [CLK_AON_APB]           = &aon_apb_clk.common.hw,
+               [CLK_ADI]               = &adi_clk.common.hw,
+               [CLK_AUX0]              = &aux0_clk.common.hw,
+               [CLK_AUX1]              = &aux1_clk.common.hw,
+               [CLK_AUX2]              = &aux2_clk.common.hw,
+               [CLK_PROBE]             = &probe_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_EFUSE]             = &efuse_clk.common.hw,
+               [CLK_UART0]             = &uart0_clk.common.hw,
+               [CLK_UART1]             = &uart1_clk.common.hw,
+               [CLK_THM0]              = &thm0_clk.common.hw,
+               [CLK_THM1]              = &thm1_clk.common.hw,
+               [CLK_THM2]              = &thm2_clk.common.hw,
+               [CLK_THM3]              = &thm3_clk.common.hw,
+               [CLK_AON_I2C]           = &aon_i2c_clk.common.hw,
+               [CLK_AON_IIS]           = &aon_iis_clk.common.hw,
+               [CLK_SCC]               = &scc_clk.common.hw,
+               [CLK_APCPU_DAP]         = &apcpu_dap_clk.common.hw,
+               [CLK_APCPU_DAP_MTCK]    = &apcpu_dap_mtck.common.hw,
+               [CLK_APCPU_TS]          = &apcpu_ts_clk.common.hw,
+               [CLK_DEBUG_TS]          = &debug_ts_clk.common.hw,
+               [CLK_DSI_TEST_S]        = &dsi_test_s.common.hw,
+               [CLK_DJTAG_TCK]         = &djtag_tck_clk.common.hw,
+               [CLK_DJTAG_TCK_HW]      = &djtag_tck_hw.common.hw,
+               [CLK_AON_TMR]           = &aon_tmr_clk.common.hw,
+               [CLK_AON_PMU]           = &aon_pmu_clk.common.hw,
+               [CLK_DEBOUNCE]          = &debounce_clk.common.hw,
+               [CLK_APCPU_PMU]         = &apcpu_pmu_clk.common.hw,
+               [CLK_TOP_DVFS]          = &top_dvfs_clk.common.hw,
+               [CLK_OTG_UTMI]          = &otg_utmi.common.hw,
+               [CLK_OTG_REF]           = &otg_ref_clk.common.hw,
+               [CLK_CSSYS]             = &cssys_clk.common.hw,
+               [CLK_CSSYS_PUB]         = &cssys_pub_clk.common.hw,
+               [CLK_CSSYS_APB]         = &cssys_apb_clk.common.hw,
+               [CLK_AP_AXI]            = &ap_axi_clk.common.hw,
+               [CLK_AP_MM]             = &ap_mm_clk.common.hw,
+               [CLK_SDIO2_2X]          = &sdio2_2x_clk.common.hw,
+               [CLK_ANALOG_IO_APB]     = &analog_io_apb.common.hw,
+               [CLK_DMC_REF_CLK]       = &dmc_ref_clk.common.hw,
+               [CLK_EMC]               = &emc_clk.common.hw,
+               [CLK_USB]               = &usb_clk.common.hw,
+               [CLK_26M_PMU]           = &pmu_26m_clk.common.hw,
+       },
+       .num    = CLK_AON_APB_NUM,
+};
+
+static struct sprd_clk_desc ums512_aon_apb_desc = {
+       .clk_clks       = ums512_aon_apb,
+       .num_clk_clks   = ARRAY_SIZE(ums512_aon_apb),
+       .hw_clks        = &ums512_aon_apb_hws,
+};
+
+/* aon apb gates */
+static SPRD_SC_GATE_CLK_FW_NAME(rc100m_cal_eb, "rc100m-cal-eb", "ext-26m",
+                               0x0, 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(djtag_tck_eb, "djtag-tck-eb", "ext-26m",
+                               0x0, 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(djtag_eb, "djtag-eb", "ext-26m",
+                               0x0, 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(aux0_eb, "aux0-eb", "ext-26m",
+                               0x0, 0x1000, BIT(4), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(aux1_eb, "aux1-eb", "ext-26m",
+                               0x0, 0x1000, BIT(5), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(aux2_eb, "aux2-eb", "ext-26m",
+                               0x0, 0x1000, BIT(6), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(probe_eb, "probe-eb", "ext-26m",
+                               0x0, 0x1000, BIT(7), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(mm_eb, "mm-eb", "ext-26m",
+                               0x0, 0x1000, BIT(9), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(gpu_eb, "gpu-eb", "ext-26m",
+                               0x0, 0x1000, BIT(11), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(mspi_eb, "mspi-eb", "ext-26m",
+                               0x0, 0x1000, BIT(12), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(apcpu_dap_eb, "apcpu-dap-eb", "ext-26m",
+                               0x0, 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(aon_cssys_eb, "aon-cssys-eb", "ext-26m",
+                               0x0, 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(cssys_apb_eb, "cssys-apb-eb", "ext-26m",
+                               0x0, 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(cssys_pub_eb, "cssys-pub-eb", "ext-26m",
+                               0x0, 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sdphy_cfg_eb, "sdphy-cfg-eb", "ext-26m",
+                               0x0, 0x1000, BIT(19), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sdphy_ref_eb, "sdphy-ref-eb", "ext-26m",
+                               0x0, 0x1000, BIT(20), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(efuse_eb, "efuse-eb", "ext-26m",
+                               0x4, 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(gpio_eb, "gpio-eb", "ext-26m",
+                               0x4, 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(mbox_eb, "mbox-eb", "ext-26m",
+                               0x4, 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(kpd_eb, "kpd-eb", "ext-26m",
+                               0x4, 0x1000, BIT(3), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(aon_syst_eb, "aon-syst-eb", "ext-26m",
+                               0x4, 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_syst_eb, "ap-syst-eb", "ext-26m",
+                               0x4, 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(aon_tmr_eb, "aon-tmr-eb", "ext-26m",
+                               0x4, 0x1000, BIT(6), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(otg_utmi_eb, "otg-utmi-eb", "ext-26m",
+                               0x4, 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(otg_phy_eb, "otg-phy-eb", "ext-26m",
+                               0x4, 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(splk_eb, "splk-eb", "ext-26m",
+                               0x4, 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(pin_eb, "pin-eb", "ext-26m",
+                               0x4, 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ana_eb, "ana-eb", "ext-26m",
+                               0x4, 0x1000, BIT(12), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(apcpu_ts0_eb, "apcpu-ts0-eb", "ext-26m",
+                               0x4, 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(apb_busmon_eb, "apb-busmon-eb", "ext-26m",
+                               0x4, 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(aon_iis_eb, "aon-iis-eb", "ext-26m",
+                               0x4, 0x1000, BIT(19), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(scc_eb, "scc-eb", "ext-26m",
+                               0x4, 0x1000, BIT(20), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(thm0_eb, "thm0-eb", "ext-26m",
+                               0x8, 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(thm1_eb, "thm1-eb", "ext-26m",
+                               0x8, 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(thm2_eb, "thm2-eb", "ext-26m",
+                               0x8, 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(asim_top_eb, "asim-top", "ext-26m",
+                               0x8, 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(i2c_eb, "i2c-eb", "ext-26m",
+                               0x8, 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(pmu_eb, "pmu-eb", "ext-26m",
+                               0x8, 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(adi_eb, "adi-eb", "ext-26m",
+                               0x8, 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(eic_eb, "eic-eb", "ext-26m",
+                               0x8, 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_intc0_eb, "ap-intc0-eb", "ext-26m",
+                               0x8, 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_intc1_eb, "ap-intc1-eb", "ext-26m",
+                               0x8, 0x1000, BIT(12), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_intc2_eb, "ap-intc2-eb", "ext-26m",
+                               0x8, 0x1000, BIT(13), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_intc3_eb, "ap-intc3-eb", "ext-26m",
+                               0x8, 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_intc4_eb, "ap-intc4-eb", "ext-26m",
+                               0x8, 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_intc5_eb, "ap-intc5-eb", "ext-26m",
+                               0x8, 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(audcp_intc_eb, "audcp-intc-eb", "ext-26m",
+                               0x8, 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_tmr0_eb, "ap-tmr0-eb", "ext-26m",
+                               0x8, 0x1000, BIT(22), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_tmr1_eb, "ap-tmr1-eb", "ext-26m",
+                               0x8, 0x1000, BIT(23), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_tmr2_eb, "ap-tmr2-eb", "ext-26m",
+                               0x8, 0x1000, BIT(24), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(pwm0_eb, "pwm0-eb", "ext-26m",
+                               0x8, 0x1000, BIT(25), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(pwm1_eb, "pwm1-eb", "ext-26m",
+                               0x8, 0x1000, BIT(26), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(pwm2_eb, "pwm2-eb", "ext-26m",
+                               0x8, 0x1000, BIT(27), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(pwm3_eb, "pwm3-eb", "ext-26m",
+                               0x8, 0x1000, BIT(28), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_wdg_eb, "ap-wdg-eb", "ext-26m",
+                               0x8, 0x1000, BIT(29), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(apcpu_wdg_eb, "apcpu-wdg-eb", "ext-26m",
+                               0x8, 0x1000, BIT(30), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(serdes_eb, "serdes-eb", "ext-26m",
+                               0x8, 0x1000, BIT(31), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(arch_rtc_eb, "arch-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(kpd_rtc_eb, "kpd-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(aon_syst_rtc_eb, "aon-syst-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_syst_rtc_eb, "ap-syst-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(aon_tmr_rtc_eb, "aon-tmr-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(eic_rtc_eb, "eic-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(eic_rtcdv5_eb, "eic-rtcdv5-eb", "ext-26m",
+                               0x18, 0x1000, BIT(6), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_wdg_rtc_eb, "ap-wdg-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ac_wdg_rtc_eb, "ac-wdg-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_tmr0_rtc_eb, "ap-tmr0-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_tmr1_rtc_eb, "ap-tmr1-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_tmr2_rtc_eb, "ap-tmr2-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(dcxo_lc_rtc_eb, "dcxo-lc-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(12), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(bb_cal_rtc_eb, "bb-cal-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(13), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_emmc_rtc_eb, "ap-emmc-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_sdio0_rtc_eb, "ap-sdio0-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_sdio1_rtc_eb, "ap-sdio1-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_sdio2_rtc_eb, "ap-sdio2-rtc-eb", "ext-26m",
+                               0x18, 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(dsi_csi_test_eb, "dsi-csi-test-eb", "ext-26m",
+                               0x138, 0x1000, BIT(8), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(djtag_tck_en, "djtag-tck-en", "ext-26m",
+                               0x138, 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(dphy_ref_eb, "dphy-ref-eb", "ext-26m",
+                               0x138, 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(dmc_ref_eb, "dmc-ref-eb", "ext-26m",
+                               0x138, 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(otg_ref_eb, "otg-ref-eb", "ext-26m",
+                               0x138, 0x1000, BIT(12), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(tsen_eb, "tsen-eb", "ext-26m",
+                               0x138, 0x1000, BIT(13), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(tmr_eb, "tmr-eb", "ext-26m",
+                               0x138, 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(rc100m_ref_eb, "rc100m-ref-eb", "ext-26m",
+                               0x138, 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(rc100m_fdk_eb, "rc100m-fdk-eb", "ext-26m",
+                               0x138, 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(debounce_eb, "debounce-eb", "ext-26m",
+                               0x138, 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(det_32k_eb, "det-32k-eb", "ext-26m",
+                               0x138, 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(top_cssys_en, "top-cssys-en", "ext-26m",
+                               0x13c, 0x1000, BIT(0), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(ap_axi_en, "ap-axi-en", "ext-26m",
+                               0x13c, 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sdio0_2x_en, "sdio0-2x-en", "ext-26m",
+                               0x13c, 0x1000, BIT(2), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sdio0_1x_en, "sdio0-1x-en", "ext-26m",
+                               0x13c, 0x1000, BIT(3), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sdio1_2x_en, "sdio1-2x-en", "ext-26m",
+                               0x13c, 0x1000, BIT(4), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sdio1_1x_en, "sdio1-1x-en", "ext-26m",
+                               0x13c, 0x1000, BIT(5), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sdio2_2x_en, "sdio2-2x-en", "ext-26m",
+                               0x13c, 0x1000, BIT(6), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sdio2_1x_en, "sdio2-1x-en", "ext-26m",
+                               0x13c, 0x1000, BIT(7), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(emmc_2x_en, "emmc-2x-en", "ext-26m",
+                               0x13c, 0x1000, BIT(8), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(emmc_1x_en, "emmc-1x-en", "ext-26m",
+                               0x13c, 0x1000, BIT(9), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(pll_test_en, "pll-test-en", "ext-26m",
+                               0x13c, 0x1000, BIT(14), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(cphy_cfg_en, "cphy-cfg-en", "ext-26m",
+                               0x13c, 0x1000, BIT(15), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(debug_ts_en, "debug-ts-en", "ext-26m",
+                               0x13c, 0x1000, BIT(18), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(access_aud_en, "access-aud-en",
+                               "ext-26m", 0x14c, 0x1000, BIT(0), 0, 0);
+
+static struct sprd_clk_common *ums512_aon_gate[] = {
+       /* address base is 0x327d0000 */
+       &rc100m_cal_eb.common,
+       &djtag_tck_eb.common,
+       &djtag_eb.common,
+       &aux0_eb.common,
+       &aux1_eb.common,
+       &aux2_eb.common,
+       &probe_eb.common,
+       &mm_eb.common,
+       &gpu_eb.common,
+       &mspi_eb.common,
+       &apcpu_dap_eb.common,
+       &aon_cssys_eb.common,
+       &cssys_apb_eb.common,
+       &cssys_pub_eb.common,
+       &sdphy_cfg_eb.common,
+       &sdphy_ref_eb.common,
+       &efuse_eb.common,
+       &gpio_eb.common,
+       &mbox_eb.common,
+       &kpd_eb.common,
+       &aon_syst_eb.common,
+       &ap_syst_eb.common,
+       &aon_tmr_eb.common,
+       &otg_utmi_eb.common,
+       &otg_phy_eb.common,
+       &splk_eb.common,
+       &pin_eb.common,
+       &ana_eb.common,
+       &apcpu_ts0_eb.common,
+       &apb_busmon_eb.common,
+       &aon_iis_eb.common,
+       &scc_eb.common,
+       &thm0_eb.common,
+       &thm1_eb.common,
+       &thm2_eb.common,
+       &asim_top_eb.common,
+       &i2c_eb.common,
+       &pmu_eb.common,
+       &adi_eb.common,
+       &eic_eb.common,
+       &ap_intc0_eb.common,
+       &ap_intc1_eb.common,
+       &ap_intc2_eb.common,
+       &ap_intc3_eb.common,
+       &ap_intc4_eb.common,
+       &ap_intc5_eb.common,
+       &audcp_intc_eb.common,
+       &ap_tmr0_eb.common,
+       &ap_tmr1_eb.common,
+       &ap_tmr2_eb.common,
+       &pwm0_eb.common,
+       &pwm1_eb.common,
+       &pwm2_eb.common,
+       &pwm3_eb.common,
+       &ap_wdg_eb.common,
+       &apcpu_wdg_eb.common,
+       &serdes_eb.common,
+       &arch_rtc_eb.common,
+       &kpd_rtc_eb.common,
+       &aon_syst_rtc_eb.common,
+       &ap_syst_rtc_eb.common,
+       &aon_tmr_rtc_eb.common,
+       &eic_rtc_eb.common,
+       &eic_rtcdv5_eb.common,
+       &ap_wdg_rtc_eb.common,
+       &ac_wdg_rtc_eb.common,
+       &ap_tmr0_rtc_eb.common,
+       &ap_tmr1_rtc_eb.common,
+       &ap_tmr2_rtc_eb.common,
+       &dcxo_lc_rtc_eb.common,
+       &bb_cal_rtc_eb.common,
+       &ap_emmc_rtc_eb.common,
+       &ap_sdio0_rtc_eb.common,
+       &ap_sdio1_rtc_eb.common,
+       &ap_sdio2_rtc_eb.common,
+       &dsi_csi_test_eb.common,
+       &djtag_tck_en.common,
+       &dphy_ref_eb.common,
+       &dmc_ref_eb.common,
+       &otg_ref_eb.common,
+       &tsen_eb.common,
+       &tmr_eb.common,
+       &rc100m_ref_eb.common,
+       &rc100m_fdk_eb.common,
+       &debounce_eb.common,
+       &det_32k_eb.common,
+       &top_cssys_en.common,
+       &ap_axi_en.common,
+       &sdio0_2x_en.common,
+       &sdio0_1x_en.common,
+       &sdio1_2x_en.common,
+       &sdio1_1x_en.common,
+       &sdio2_2x_en.common,
+       &sdio2_1x_en.common,
+       &emmc_2x_en.common,
+       &emmc_1x_en.common,
+       &pll_test_en.common,
+       &cphy_cfg_en.common,
+       &debug_ts_en.common,
+       &access_aud_en.common,
+};
+
+static struct clk_hw_onecell_data ums512_aon_gate_hws = {
+       .hws    = {
+               [CLK_RC100M_CAL_EB]     = &rc100m_cal_eb.common.hw,
+               [CLK_DJTAG_TCK_EB]      = &djtag_tck_eb.common.hw,
+               [CLK_DJTAG_EB]          = &djtag_eb.common.hw,
+               [CLK_AUX0_EB]           = &aux0_eb.common.hw,
+               [CLK_AUX1_EB]           = &aux1_eb.common.hw,
+               [CLK_AUX2_EB]           = &aux2_eb.common.hw,
+               [CLK_PROBE_EB]          = &probe_eb.common.hw,
+               [CLK_MM_EB]             = &mm_eb.common.hw,
+               [CLK_GPU_EB]            = &gpu_eb.common.hw,
+               [CLK_MSPI_EB]           = &mspi_eb.common.hw,
+               [CLK_APCPU_DAP_EB]      = &apcpu_dap_eb.common.hw,
+               [CLK_AON_CSSYS_EB]      = &aon_cssys_eb.common.hw,
+               [CLK_CSSYS_APB_EB]      = &cssys_apb_eb.common.hw,
+               [CLK_CSSYS_PUB_EB]      = &cssys_pub_eb.common.hw,
+               [CLK_SDPHY_CFG_EB]      = &sdphy_cfg_eb.common.hw,
+               [CLK_SDPHY_REF_EB]      = &sdphy_ref_eb.common.hw,
+               [CLK_EFUSE_EB]          = &efuse_eb.common.hw,
+               [CLK_GPIO_EB]           = &gpio_eb.common.hw,
+               [CLK_MBOX_EB]           = &mbox_eb.common.hw,
+               [CLK_KPD_EB]            = &kpd_eb.common.hw,
+               [CLK_AON_SYST_EB]       = &aon_syst_eb.common.hw,
+               [CLK_AP_SYST_EB]        = &ap_syst_eb.common.hw,
+               [CLK_AON_TMR_EB]        = &aon_tmr_eb.common.hw,
+               [CLK_OTG_UTMI_EB]       = &otg_utmi_eb.common.hw,
+               [CLK_OTG_PHY_EB]        = &otg_phy_eb.common.hw,
+               [CLK_SPLK_EB]           = &splk_eb.common.hw,
+               [CLK_PIN_EB]            = &pin_eb.common.hw,
+               [CLK_ANA_EB]            = &ana_eb.common.hw,
+               [CLK_APCPU_TS0_EB]      = &apcpu_ts0_eb.common.hw,
+               [CLK_APB_BUSMON_EB]     = &apb_busmon_eb.common.hw,
+               [CLK_AON_IIS_EB]        = &aon_iis_eb.common.hw,
+               [CLK_SCC_EB]            = &scc_eb.common.hw,
+               [CLK_THM0_EB]           = &thm0_eb.common.hw,
+               [CLK_THM1_EB]           = &thm1_eb.common.hw,
+               [CLK_THM2_EB]           = &thm2_eb.common.hw,
+               [CLK_ASIM_TOP_EB]       = &asim_top_eb.common.hw,
+               [CLK_I2C_EB]            = &i2c_eb.common.hw,
+               [CLK_PMU_EB]            = &pmu_eb.common.hw,
+               [CLK_ADI_EB]            = &adi_eb.common.hw,
+               [CLK_EIC_EB]            = &eic_eb.common.hw,
+               [CLK_AP_INTC0_EB]       = &ap_intc0_eb.common.hw,
+               [CLK_AP_INTC1_EB]       = &ap_intc1_eb.common.hw,
+               [CLK_AP_INTC2_EB]       = &ap_intc2_eb.common.hw,
+               [CLK_AP_INTC3_EB]       = &ap_intc3_eb.common.hw,
+               [CLK_AP_INTC4_EB]       = &ap_intc4_eb.common.hw,
+               [CLK_AP_INTC5_EB]       = &ap_intc5_eb.common.hw,
+               [CLK_AUDCP_INTC_EB]     = &audcp_intc_eb.common.hw,
+               [CLK_AP_TMR0_EB]        = &ap_tmr0_eb.common.hw,
+               [CLK_AP_TMR1_EB]        = &ap_tmr1_eb.common.hw,
+               [CLK_AP_TMR2_EB]        = &ap_tmr2_eb.common.hw,
+               [CLK_PWM0_EB]           = &pwm0_eb.common.hw,
+               [CLK_PWM1_EB]           = &pwm1_eb.common.hw,
+               [CLK_PWM2_EB]           = &pwm2_eb.common.hw,
+               [CLK_PWM3_EB]           = &pwm3_eb.common.hw,
+               [CLK_AP_WDG_EB]         = &ap_wdg_eb.common.hw,
+               [CLK_APCPU_WDG_EB]      = &apcpu_wdg_eb.common.hw,
+               [CLK_SERDES_EB]         = &serdes_eb.common.hw,
+               [CLK_ARCH_RTC_EB]       = &arch_rtc_eb.common.hw,
+               [CLK_KPD_RTC_EB]        = &kpd_rtc_eb.common.hw,
+               [CLK_AON_SYST_RTC_EB]   = &aon_syst_rtc_eb.common.hw,
+               [CLK_AP_SYST_RTC_EB]    = &ap_syst_rtc_eb.common.hw,
+               [CLK_AON_TMR_RTC_EB]    = &aon_tmr_rtc_eb.common.hw,
+               [CLK_EIC_RTC_EB]        = &eic_rtc_eb.common.hw,
+               [CLK_EIC_RTCDV5_EB]     = &eic_rtcdv5_eb.common.hw,
+               [CLK_AP_WDG_RTC_EB]     = &ap_wdg_rtc_eb.common.hw,
+               [CLK_AC_WDG_RTC_EB]     = &ac_wdg_rtc_eb.common.hw,
+               [CLK_AP_TMR0_RTC_EB]    = &ap_tmr0_rtc_eb.common.hw,
+               [CLK_AP_TMR1_RTC_EB]    = &ap_tmr1_rtc_eb.common.hw,
+               [CLK_AP_TMR2_RTC_EB]    = &ap_tmr2_rtc_eb.common.hw,
+               [CLK_DCXO_LC_RTC_EB]    = &dcxo_lc_rtc_eb.common.hw,
+               [CLK_BB_CAL_RTC_EB]     = &bb_cal_rtc_eb.common.hw,
+               [CLK_AP_EMMC_RTC_EB]    = &ap_emmc_rtc_eb.common.hw,
+               [CLK_AP_SDIO0_RTC_EB]   = &ap_sdio0_rtc_eb.common.hw,
+               [CLK_AP_SDIO1_RTC_EB]   = &ap_sdio1_rtc_eb.common.hw,
+               [CLK_AP_SDIO2_RTC_EB]   = &ap_sdio2_rtc_eb.common.hw,
+               [CLK_DSI_CSI_TEST_EB]   = &dsi_csi_test_eb.common.hw,
+               [CLK_DJTAG_TCK_EN]      = &djtag_tck_en.common.hw,
+               [CLK_DPHY_REF_EB]       = &dphy_ref_eb.common.hw,
+               [CLK_DMC_REF_EB]        = &dmc_ref_eb.common.hw,
+               [CLK_OTG_REF_EB]        = &otg_ref_eb.common.hw,
+               [CLK_TSEN_EB]           = &tsen_eb.common.hw,
+               [CLK_TMR_EB]            = &tmr_eb.common.hw,
+               [CLK_RC100M_REF_EB]     = &rc100m_ref_eb.common.hw,
+               [CLK_RC100M_FDK_EB]     = &rc100m_fdk_eb.common.hw,
+               [CLK_DEBOUNCE_EB]       = &debounce_eb.common.hw,
+               [CLK_DET_32K_EB]        = &det_32k_eb.common.hw,
+               [CLK_TOP_CSSYS_EB]      = &top_cssys_en.common.hw,
+               [CLK_AP_AXI_EN]         = &ap_axi_en.common.hw,
+               [CLK_SDIO0_2X_EN]       = &sdio0_2x_en.common.hw,
+               [CLK_SDIO0_1X_EN]       = &sdio0_1x_en.common.hw,
+               [CLK_SDIO1_2X_EN]       = &sdio1_2x_en.common.hw,
+               [CLK_SDIO1_1X_EN]       = &sdio1_1x_en.common.hw,
+               [CLK_SDIO2_2X_EN]       = &sdio2_2x_en.common.hw,
+               [CLK_SDIO2_1X_EN]       = &sdio2_1x_en.common.hw,
+               [CLK_EMMC_2X_EN]        = &emmc_2x_en.common.hw,
+               [CLK_EMMC_1X_EN]        = &emmc_1x_en.common.hw,
+               [CLK_PLL_TEST_EN]       = &pll_test_en.common.hw,
+               [CLK_CPHY_CFG_EN]       = &cphy_cfg_en.common.hw,
+               [CLK_DEBUG_TS_EN]       = &debug_ts_en.common.hw,
+               [CLK_ACCESS_AUD_EN]     = &access_aud_en.common.hw,
+       },
+       .num    = CLK_AON_APB_GATE_NUM,
+};
+
+static struct sprd_clk_desc ums512_aon_gate_desc = {
+       .clk_clks       = ums512_aon_gate,
+       .num_clk_clks   = ARRAY_SIZE(ums512_aon_gate),
+       .hw_clks        = &ums512_aon_gate_hws,
+};
+
+/* audcp apb gates */
+/* Audcp apb clocks configure CLK_IGNORE_UNUSED because these clocks may be
+ * controlled by audcp sys at the same time. It may be cause an execption if
+ * kernel gates these clock.
+ */
+static SPRD_SC_GATE_CLK_HW(audcp_wdg_eb, "audcp-wdg-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(1),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_rtc_wdg_eb, "audcp-rtc-wdg-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(2),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_tmr0_eb, "audcp-tmr0-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(5),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_tmr1_eb, "audcp-tmr1-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(6),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+
+static struct sprd_clk_common *ums512_audcpapb_gate[] = {
+       /* address base is 0x3350d000 */
+       &audcp_wdg_eb.common,
+       &audcp_rtc_wdg_eb.common,
+       &audcp_tmr0_eb.common,
+       &audcp_tmr1_eb.common,
+};
+
+static struct clk_hw_onecell_data ums512_audcpapb_gate_hws = {
+       .hws    = {
+               [CLK_AUDCP_WDG_EB]      = &audcp_wdg_eb.common.hw,
+               [CLK_AUDCP_RTC_WDG_EB]  = &audcp_rtc_wdg_eb.common.hw,
+               [CLK_AUDCP_TMR0_EB]     = &audcp_tmr0_eb.common.hw,
+               [CLK_AUDCP_TMR1_EB]     = &audcp_tmr1_eb.common.hw,
+       },
+       .num    = CLK_AUDCP_APB_GATE_NUM,
+};
+
+static const struct sprd_clk_desc ums512_audcpapb_gate_desc = {
+       .clk_clks       = ums512_audcpapb_gate,
+       .num_clk_clks   = ARRAY_SIZE(ums512_audcpapb_gate),
+       .hw_clks        = &ums512_audcpapb_gate_hws,
+};
+
+/* audcp ahb gates */
+/* Audcp aphb clocks configure CLK_IGNORE_UNUSED because these clocks may be
+ * controlled by audcp sys at the same time. It may be cause an execption if
+ * kernel gates these clock.
+ */
+static SPRD_SC_GATE_CLK_HW(audcp_iis0_eb, "audcp-iis0-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(0),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_iis1_eb, "audcp-iis1-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(1),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_iis2_eb, "audcp-iis2-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(2),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_uart_eb, "audcp-uart-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(4),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_dma_cp_eb, "audcp-dma-cp-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(5),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_dma_ap_eb, "audcp-dma-ap-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(6),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_src48k_eb, "audcp-src48k-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(10),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_mcdt_eb, "audcp-mcdt-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(12),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_vbcifd_eb, "audcp-vbcifd-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(13),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_vbc_eb, "audcp-vbc-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(14),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_splk_eb,  "audcp-splk-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(15),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_icu_eb, "audcp-icu-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(16),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(dma_ap_ashb_eb, "dma-ap-ashb-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(17),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(dma_cp_ashb_eb, "dma-cp-ashb-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(18),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_aud_eb, "audcp-aud-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(19),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_vbc_24m_eb, "audcp-vbc-24m-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(21),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_tmr_26m_eb, "audcp-tmr-26m-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(22),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+static SPRD_SC_GATE_CLK_HW(audcp_dvfs_ashb_eb, "audcp-dvfs-ashb-eb",
+                          &access_aud_en.common.hw, 0x0, 0x100, BIT(23),
+                          CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON);
+
+static struct sprd_clk_common *ums512_audcpahb_gate[] = {
+       /* address base is 0x335e0000 */
+       &audcp_iis0_eb.common,
+       &audcp_iis1_eb.common,
+       &audcp_iis2_eb.common,
+       &audcp_uart_eb.common,
+       &audcp_dma_cp_eb.common,
+       &audcp_dma_ap_eb.common,
+       &audcp_src48k_eb.common,
+       &audcp_mcdt_eb.common,
+       &audcp_vbcifd_eb.common,
+       &audcp_vbc_eb.common,
+       &audcp_splk_eb.common,
+       &audcp_icu_eb.common,
+       &dma_ap_ashb_eb.common,
+       &dma_cp_ashb_eb.common,
+       &audcp_aud_eb.common,
+       &audcp_vbc_24m_eb.common,
+       &audcp_tmr_26m_eb.common,
+       &audcp_dvfs_ashb_eb.common,
+};
+
+static struct clk_hw_onecell_data ums512_audcpahb_gate_hws = {
+       .hws    = {
+               [CLK_AUDCP_IIS0_EB]             = &audcp_iis0_eb.common.hw,
+               [CLK_AUDCP_IIS1_EB]             = &audcp_iis1_eb.common.hw,
+               [CLK_AUDCP_IIS2_EB]             = &audcp_iis2_eb.common.hw,
+               [CLK_AUDCP_UART_EB]             = &audcp_uart_eb.common.hw,
+               [CLK_AUDCP_DMA_CP_EB]           = &audcp_dma_cp_eb.common.hw,
+               [CLK_AUDCP_DMA_AP_EB]           = &audcp_dma_ap_eb.common.hw,
+               [CLK_AUDCP_SRC48K_EB]           = &audcp_src48k_eb.common.hw,
+               [CLK_AUDCP_MCDT_EB]             = &audcp_mcdt_eb.common.hw,
+               [CLK_AUDCP_VBCIFD_EB]           = &audcp_vbcifd_eb.common.hw,
+               [CLK_AUDCP_VBC_EB]              = &audcp_vbc_eb.common.hw,
+               [CLK_AUDCP_SPLK_EB]             = &audcp_splk_eb.common.hw,
+               [CLK_AUDCP_ICU_EB]              = &audcp_icu_eb.common.hw,
+               [CLK_AUDCP_DMA_AP_ASHB_EB]      = &dma_ap_ashb_eb.common.hw,
+               [CLK_AUDCP_DMA_CP_ASHB_EB]      = &dma_cp_ashb_eb.common.hw,
+               [CLK_AUDCP_AUD_EB]              = &audcp_aud_eb.common.hw,
+               [CLK_AUDCP_VBC_24M_EB]          = &audcp_vbc_24m_eb.common.hw,
+               [CLK_AUDCP_TMR_26M_EB]          = &audcp_tmr_26m_eb.common.hw,
+               [CLK_AUDCP_DVFS_ASHB_EB]        = &audcp_dvfs_ashb_eb.common.hw,
+       },
+       .num    = CLK_AUDCP_AHB_GATE_NUM,
+};
+
+static const struct sprd_clk_desc ums512_audcpahb_gate_desc = {
+       .clk_clks       = ums512_audcpahb_gate,
+       .num_clk_clks   = ARRAY_SIZE(ums512_audcpahb_gate),
+       .hw_clks        = &ums512_audcpahb_gate_hws,
+};
+
+/* gpu clocks */
+static SPRD_GATE_CLK_HW(gpu_core_gate, "gpu-core-gate", &gpu_eb.common.hw,
+                       0x4, BIT(0), 0, 0);
+
+static const struct clk_parent_data gpu_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_384m.hw  },
+       { .hw = &twpll_512m.hw  },
+       { .hw = &lpll_614m4.hw  },
+       { .hw = &twpll_768m.hw  },
+       { .hw = &gpll.common.hw  },
+};
+
+static SPRD_COMP_CLK_DATA(gpu_core_clk, "gpu-core-clk", gpu_parents,
+                         0x4, 4, 3, 8, 3, 0);
+
+static SPRD_GATE_CLK_HW(gpu_mem_gate, "gpu-mem-gate", &gpu_eb.common.hw,
+                       0x8, BIT(0), 0, 0);
+
+static SPRD_COMP_CLK_DATA(gpu_mem_clk, "gpu-mem-clk", gpu_parents,
+                         0x8, 4, 3, 8, 3, 0);
+
+static SPRD_GATE_CLK_HW(gpu_sys_gate, "gpu-sys-gate", &gpu_eb.common.hw,
+                       0xc, BIT(0), 0, 0);
+
+static SPRD_DIV_CLK_HW(gpu_sys_clk, "gpu-sys-clk", &gpu_eb.common.hw,
+                      0xc, 4, 3, 0);
+
+static struct sprd_clk_common *ums512_gpu_clk[] = {
+       /* address base is 0x60100000 */
+       &gpu_core_gate.common,
+       &gpu_core_clk.common,
+       &gpu_mem_gate.common,
+       &gpu_mem_clk.common,
+       &gpu_sys_gate.common,
+       &gpu_sys_clk.common,
+};
+
+static struct clk_hw_onecell_data ums512_gpu_clk_hws = {
+       .hws    = {
+               [CLK_GPU_CORE_EB]       = &gpu_core_gate.common.hw,
+               [CLK_GPU_CORE]          = &gpu_core_clk.common.hw,
+               [CLK_GPU_MEM_EB]        = &gpu_mem_gate.common.hw,
+               [CLK_GPU_MEM]           = &gpu_mem_clk.common.hw,
+               [CLK_GPU_SYS_EB]        = &gpu_sys_gate.common.hw,
+               [CLK_GPU_SYS]           = &gpu_sys_clk.common.hw,
+       },
+       .num    = CLK_GPU_CLK_NUM,
+};
+
+static struct sprd_clk_desc ums512_gpu_clk_desc = {
+       .clk_clks       = ums512_gpu_clk,
+       .num_clk_clks   = ARRAY_SIZE(ums512_gpu_clk),
+       .hw_clks        = &ums512_gpu_clk_hws,
+};
+
+/* mm clocks */
+static const struct clk_parent_data mm_ahb_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_96m.hw  },
+       { .hw = &twpll_128m.hw  },
+       { .hw = &twpll_153m6.hw  },
+};
+static SPRD_MUX_CLK_DATA(mm_ahb_clk, "mm-ahb-clk", mm_ahb_parents,
+                        0x20, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data mm_mtx_parents[] = {
+       { .hw = &twpll_76m8.hw  },
+       { .hw = &twpll_128m.hw  },
+       { .hw = &twpll_256m.hw  },
+       { .hw = &twpll_307m2.hw  },
+       { .hw = &twpll_384m.hw  },
+       { .hw = &isppll_468m.hw  },
+       { .hw = &twpll_512m.hw  },
+};
+static SPRD_MUX_CLK_DATA(mm_mtx_clk, "mm-mtx-clk", mm_mtx_parents,
+                        0x24, 0, 3, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data sensor_parents[] = {
+       { .fw_name = "ext-26m" },
+       { .hw = &twpll_48m.hw  },
+       { .hw = &twpll_76m8.hw  },
+       { .hw = &twpll_96m.hw  },
+};
+static SPRD_COMP_CLK_DATA(sensor0_clk, "sensor0-clk", sensor_parents,
+                         0x28, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK_DATA(sensor1_clk, "sensor1-clk", sensor_parents,
+                         0x2c, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK_DATA(sensor2_clk, "sensor2-clk", sensor_parents,
+                         0x30, 0, 2, 8, 3, 0);
+
+static const struct clk_parent_data cpp_parents[] = {
+       { .hw = &twpll_76m8.hw  },
+       { .hw = &twpll_128m.hw  },
+       { .hw = &twpll_256m.hw  },
+       { .hw = &twpll_384m.hw  },
+};
+static SPRD_MUX_CLK_DATA(cpp_clk, "cpp-clk", cpp_parents,
+                        0x34, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data jpg_parents[] = {
+       { .hw = &twpll_76m8.hw  },
+       { .hw = &twpll_128m.hw  },
+       { .hw = &twpll_256m.hw  },
+       { .hw = &twpll_384m.hw  },
+};
+static SPRD_MUX_CLK_DATA(jpg_clk, "jpg-clk", jpg_parents,
+                        0x38, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data fd_parents[] = {
+       { .hw = &twpll_76m8.hw  },
+       { .hw = &twpll_192m.hw  },
+       { .hw = &twpll_307m2.hw  },
+       { .hw = &twpll_384m.hw  },
+};
+static SPRD_MUX_CLK_DATA(fd_clk, "fd-clk", fd_parents,
+                        0x3c, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data dcam_if_parents[] = {
+       { .hw = &twpll_192m.hw  },
+       { .hw = &twpll_256m.hw  },
+       { .hw = &twpll_307m2.hw  },
+       { .hw = &twpll_384m.hw  },
+       { .hw = &isppll_468m.hw  },
+};
+static SPRD_MUX_CLK_DATA(dcam_if_clk, "dcam-if-clk", dcam_if_parents,
+                        0x40, 0, 3, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data dcam_axi_parents[] = {
+       { .hw = &twpll_256m.hw  },
+       { .hw = &twpll_307m2.hw  },
+       { .hw = &twpll_384m.hw  },
+       { .hw = &isppll_468m.hw  },
+};
+static SPRD_MUX_CLK_DATA(dcam_axi_clk, "dcam-axi-clk", dcam_axi_parents,
+                        0x44, 0, 2, UMS512_MUX_FLAG);
+
+static const struct clk_parent_data isp_parents[] = {
+       { .hw = &twpll_256m.hw  },
+       { .hw = &twpll_307m2.hw  },
+       { .hw = &twpll_384m.hw  },
+       { .hw = &isppll_468m.hw  },
+       { .hw = &twpll_512m.hw  },
+};
+static SPRD_MUX_CLK_DATA(isp_clk, "isp-clk", isp_parents,
+                        0x48, 0, 3, UMS512_MUX_FLAG);
+
+static SPRD_GATE_CLK_HW(mipi_csi0, "mipi-csi0", &mm_eb.common.hw,
+                       0x4c, BIT(16), CLK_IGNORE_UNUSED, 0);
+
+static SPRD_GATE_CLK_HW(mipi_csi1, "mipi-csi1", &mm_eb.common.hw,
+                       0x50, BIT(16), CLK_IGNORE_UNUSED, 0);
+
+static SPRD_GATE_CLK_HW(mipi_csi2, "mipi-csi2", &mm_eb.common.hw,
+                       0x54, BIT(16), CLK_IGNORE_UNUSED, 0);
+
+static struct sprd_clk_common *ums512_mm_clk[] = {
+       /* address base is 0x62100000 */
+       &mm_ahb_clk.common,
+       &mm_mtx_clk.common,
+       &sensor0_clk.common,
+       &sensor1_clk.common,
+       &sensor2_clk.common,
+       &cpp_clk.common,
+       &jpg_clk.common,
+       &fd_clk.common,
+       &dcam_if_clk.common,
+       &dcam_axi_clk.common,
+       &isp_clk.common,
+       &mipi_csi0.common,
+       &mipi_csi1.common,
+       &mipi_csi2.common,
+};
+
+static struct clk_hw_onecell_data ums512_mm_clk_hws = {
+       .hws    = {
+               [CLK_MM_AHB]    = &mm_ahb_clk.common.hw,
+               [CLK_MM_MTX]    = &mm_mtx_clk.common.hw,
+               [CLK_SENSOR0]   = &sensor0_clk.common.hw,
+               [CLK_SENSOR1]   = &sensor1_clk.common.hw,
+               [CLK_SENSOR2]   = &sensor2_clk.common.hw,
+               [CLK_CPP]       = &cpp_clk.common.hw,
+               [CLK_JPG]       = &jpg_clk.common.hw,
+               [CLK_FD]        = &fd_clk.common.hw,
+               [CLK_DCAM_IF]   = &dcam_if_clk.common.hw,
+               [CLK_DCAM_AXI]  = &dcam_axi_clk.common.hw,
+               [CLK_ISP]       = &isp_clk.common.hw,
+               [CLK_MIPI_CSI0] = &mipi_csi0.common.hw,
+               [CLK_MIPI_CSI1] = &mipi_csi1.common.hw,
+               [CLK_MIPI_CSI2] = &mipi_csi2.common.hw,
+       },
+       .num    = CLK_MM_CLK_NUM,
+};
+
+static struct sprd_clk_desc ums512_mm_clk_desc = {
+       .clk_clks       = ums512_mm_clk,
+       .num_clk_clks   = ARRAY_SIZE(ums512_mm_clk),
+       .hw_clks        = &ums512_mm_clk_hws,
+};
+
+/* mm gate clocks */
+static SPRD_SC_GATE_CLK_HW(mm_cpp_eb, "mm-cpp-eb", &mm_eb.common.hw,
+                          0x0, 0x1000, BIT(0), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_jpg_eb, "mm-jpg-eb", &mm_eb.common.hw,
+                          0x0, 0x1000, BIT(1), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_dcam_eb, "mm-dcam-eb", &mm_eb.common.hw,
+                          0x0, 0x1000, BIT(2), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_isp_eb, "mm-isp-eb", &mm_eb.common.hw,
+                          0x0, 0x1000, BIT(3), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_csi2_eb, "mm-csi2-eb", &mm_eb.common.hw,
+                          0x0, 0x1000, BIT(4), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_csi1_eb, "mm-csi1-eb", &mm_eb.common.hw,
+                          0x0, 0x1000, BIT(5), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_csi0_eb, "mm-csi0-eb", &mm_eb.common.hw,
+                          0x0, 0x1000, BIT(6), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_ckg_eb, "mm-ckg-eb", &mm_eb.common.hw,
+                          0x0, 0x1000, BIT(7), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_isp_ahb_eb, "mm-isp-ahb-eb", &mm_eb.common.hw,
+                          0x0, 0x1000, BIT(8), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_dvfs_eb, "mm-dvfs-eb", &mm_eb.common.hw,
+                          0x0, 0x1000, BIT(9), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_fd_eb, "mm-fd-eb", &mm_eb.common.hw,
+                          0x0, 0x1000, BIT(10), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_sensor2_en, "mm-sensor2-en", &mm_eb.common.hw,
+                          0x8, 0x1000, BIT(0), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_sensor1_en, "mm-sensor1-en", &mm_eb.common.hw,
+                          0x8, 0x1000, BIT(1), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_sensor0_en, "mm-sensor0-en", &mm_eb.common.hw,
+                          0x8, 0x1000, BIT(2), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_mipi_csi2_en, "mm-mipi-csi2-en", &mm_eb.common.hw,
+                          0x8, 0x1000, BIT(3), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_mipi_csi1_en, "mm-mipi-csi1-en", &mm_eb.common.hw,
+                          0x8, 0x1000, BIT(4), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_mipi_csi0_en, "mm-mipi-csi0-en", &mm_eb.common.hw,
+                          0x8, 0x1000, BIT(5), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_dcam_axi_en, "mm-dcam-axi-en", &mm_eb.common.hw,
+                          0x8, 0x1000, BIT(6), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_isp_axi_en, "mm-isp-axi-en", &mm_eb.common.hw,
+                          0x8, 0x1000, BIT(7), 0, 0);
+static SPRD_SC_GATE_CLK_HW(mm_cphy_en, "mm-cphy-en", &mm_eb.common.hw,
+                          0x8, 0x1000, BIT(8), 0, 0);
+
+static struct sprd_clk_common *ums512_mm_gate_clk[] = {
+       /* address base is 0x62200000 */
+       &mm_cpp_eb.common,
+       &mm_jpg_eb.common,
+       &mm_dcam_eb.common,
+       &mm_isp_eb.common,
+       &mm_csi2_eb.common,
+       &mm_csi1_eb.common,
+       &mm_csi0_eb.common,
+       &mm_ckg_eb.common,
+       &mm_isp_ahb_eb.common,
+       &mm_dvfs_eb.common,
+       &mm_fd_eb.common,
+       &mm_sensor2_en.common,
+       &mm_sensor1_en.common,
+       &mm_sensor0_en.common,
+       &mm_mipi_csi2_en.common,
+       &mm_mipi_csi1_en.common,
+       &mm_mipi_csi0_en.common,
+       &mm_dcam_axi_en.common,
+       &mm_isp_axi_en.common,
+       &mm_cphy_en.common,
+};
+
+static struct clk_hw_onecell_data ums512_mm_gate_clk_hws = {
+       .hws    = {
+               [CLK_MM_CPP_EB]         = &mm_cpp_eb.common.hw,
+               [CLK_MM_JPG_EB]         = &mm_jpg_eb.common.hw,
+               [CLK_MM_DCAM_EB]        = &mm_dcam_eb.common.hw,
+               [CLK_MM_ISP_EB]         = &mm_isp_eb.common.hw,
+               [CLK_MM_CSI2_EB]        = &mm_csi2_eb.common.hw,
+               [CLK_MM_CSI1_EB]        = &mm_csi1_eb.common.hw,
+               [CLK_MM_CSI0_EB]        = &mm_csi0_eb.common.hw,
+               [CLK_MM_CKG_EB]         = &mm_ckg_eb.common.hw,
+               [CLK_ISP_AHB_EB]        = &mm_isp_ahb_eb.common.hw,
+               [CLK_MM_DVFS_EB]        = &mm_dvfs_eb.common.hw,
+               [CLK_MM_FD_EB]          = &mm_fd_eb.common.hw,
+               [CLK_MM_SENSOR2_EB]     = &mm_sensor2_en.common.hw,
+               [CLK_MM_SENSOR1_EB]     = &mm_sensor1_en.common.hw,
+               [CLK_MM_SENSOR0_EB]     = &mm_sensor0_en.common.hw,
+               [CLK_MM_MIPI_CSI2_EB]   = &mm_mipi_csi2_en.common.hw,
+               [CLK_MM_MIPI_CSI1_EB]   = &mm_mipi_csi1_en.common.hw,
+               [CLK_MM_MIPI_CSI0_EB]   = &mm_mipi_csi0_en.common.hw,
+               [CLK_DCAM_AXI_EB]       = &mm_dcam_axi_en.common.hw,
+               [CLK_ISP_AXI_EB]        = &mm_isp_axi_en.common.hw,
+               [CLK_MM_CPHY_EB]        = &mm_cphy_en.common.hw,
+       },
+       .num    = CLK_MM_GATE_CLK_NUM,
+};
+
+static struct sprd_clk_desc ums512_mm_gate_clk_desc = {
+       .clk_clks       = ums512_mm_gate_clk,
+       .num_clk_clks   = ARRAY_SIZE(ums512_mm_gate_clk),
+       .hw_clks        = &ums512_mm_gate_clk_hws,
+};
+
+/* ap apb gates */
+static SPRD_SC_GATE_CLK_FW_NAME(sim0_eb, "sim0-eb", "ext-26m",
+                               0x0, 0x1000, BIT(0), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(iis0_eb, "iis0-eb", "ext-26m",
+                               0x0, 0x1000, BIT(1), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(iis1_eb, "iis1-eb", "ext-26m",
+                               0x0, 0x1000, BIT(2), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(iis2_eb, "iis2-eb", "ext-26m",
+                               0x0, 0x1000, BIT(3), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(apb_reg_eb, "apb-reg-eb", "ext-26m",
+                               0x0, 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(spi0_eb, "spi0-eb", "ext-26m",
+                               0x0, 0x1000, BIT(5), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(spi1_eb, "spi1-eb", "ext-26m",
+                               0x0, 0x1000, BIT(6), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(spi2_eb, "spi2-eb", "ext-26m",
+                               0x0, 0x1000, BIT(7), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(spi3_eb, "spi3-eb", "ext-26m",
+                               0x0, 0x1000, BIT(8), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(i2c0_eb, "i2c0-eb", "ext-26m",
+                               0x0, 0x1000, BIT(9), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(i2c1_eb, "i2c1-eb", "ext-26m",
+                               0x0, 0x1000, BIT(10), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(i2c2_eb, "i2c2-eb", "ext-26m",
+                               0x0, 0x1000, BIT(11), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(i2c3_eb, "i2c3-eb", "ext-26m",
+                               0x0, 0x1000, BIT(12), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(i2c4_eb, "i2c4-eb", "ext-26m",
+                               0x0, 0x1000, BIT(13), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(uart0_eb, "uart0-eb", "ext-26m",
+                               0x0, 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(uart1_eb, "uart1-eb", "ext-26m",
+                               0x0, 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(uart2_eb, "uart2-eb", "ext-26m",
+                               0x0, 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sim0_32k_eb, "sim0-32k-eb", "ext-26m",
+                               0x0, 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(spi0_lfin_eb, "spi0-lfin-eb", "ext-26m",
+                               0x0, 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(spi1_lfin_eb, "spi1-lfin-eb", "ext-26m",
+                               0x0, 0x1000, BIT(19), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(spi2_lfin_eb, "spi2-lfin-eb", "ext-26m",
+                               0x0, 0x1000, BIT(20), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(spi3_lfin_eb, "spi3-lfin-eb", "ext-26m",
+                               0x0, 0x1000, BIT(21), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sdio0_eb, "sdio0-eb", "ext-26m",
+                               0x0, 0x1000, BIT(22), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sdio1_eb, "sdio1-eb", "ext-26m",
+                               0x0, 0x1000, BIT(23), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sdio2_eb, "sdio2-eb", "ext-26m",
+                               0x0, 0x1000, BIT(24), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(emmc_eb, "emmc-eb", "ext-26m",
+                               0x0, 0x1000, BIT(25), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sdio0_32k_eb, "sdio0-32k-eb", "ext-26m",
+                               0x0, 0x1000, BIT(26), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sdio1_32k_eb, "sdio1-32k-eb", "ext-26m",
+                               0x0, 0x1000, BIT(27), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(sdio2_32k_eb, "sdio2-32k-eb", "ext-26m",
+                               0x0, 0x1000, BIT(28), 0, 0);
+static SPRD_SC_GATE_CLK_FW_NAME(emmc_32k_eb, "emmc-32k-eb", "ext-26m",
+                               0x0, 0x1000, BIT(29), 0, 0);
+
+static struct sprd_clk_common *ums512_apapb_gate[] = {
+       /* address base is 0x71000000 */
+       &sim0_eb.common,
+       &iis0_eb.common,
+       &iis1_eb.common,
+       &iis2_eb.common,
+       &apb_reg_eb.common,
+       &spi0_eb.common,
+       &spi1_eb.common,
+       &spi2_eb.common,
+       &spi3_eb.common,
+       &i2c0_eb.common,
+       &i2c1_eb.common,
+       &i2c2_eb.common,
+       &i2c3_eb.common,
+       &i2c4_eb.common,
+       &uart0_eb.common,
+       &uart1_eb.common,
+       &uart2_eb.common,
+       &sim0_32k_eb.common,
+       &spi0_lfin_eb.common,
+       &spi1_lfin_eb.common,
+       &spi2_lfin_eb.common,
+       &spi3_lfin_eb.common,
+       &sdio0_eb.common,
+       &sdio1_eb.common,
+       &sdio2_eb.common,
+       &emmc_eb.common,
+       &sdio0_32k_eb.common,
+       &sdio1_32k_eb.common,
+       &sdio2_32k_eb.common,
+       &emmc_32k_eb.common,
+};
+
+static struct clk_hw_onecell_data ums512_apapb_gate_hws = {
+       .hws    = {
+               [CLK_SIM0_EB]           = &sim0_eb.common.hw,
+               [CLK_IIS0_EB]           = &iis0_eb.common.hw,
+               [CLK_IIS1_EB]           = &iis1_eb.common.hw,
+               [CLK_IIS2_EB]           = &iis2_eb.common.hw,
+               [CLK_APB_REG_EB]        = &apb_reg_eb.common.hw,
+               [CLK_SPI0_EB]           = &spi0_eb.common.hw,
+               [CLK_SPI1_EB]           = &spi1_eb.common.hw,
+               [CLK_SPI2_EB]           = &spi2_eb.common.hw,
+               [CLK_SPI3_EB]           = &spi3_eb.common.hw,
+               [CLK_I2C0_EB]           = &i2c0_eb.common.hw,
+               [CLK_I2C1_EB]           = &i2c1_eb.common.hw,
+               [CLK_I2C2_EB]           = &i2c2_eb.common.hw,
+               [CLK_I2C3_EB]           = &i2c3_eb.common.hw,
+               [CLK_I2C4_EB]           = &i2c4_eb.common.hw,
+               [CLK_UART0_EB]          = &uart0_eb.common.hw,
+               [CLK_UART1_EB]          = &uart1_eb.common.hw,
+               [CLK_UART2_EB]          = &uart2_eb.common.hw,
+               [CLK_SIM0_32K_EB]       = &sim0_32k_eb.common.hw,
+               [CLK_SPI0_LFIN_EB]      = &spi0_lfin_eb.common.hw,
+               [CLK_SPI1_LFIN_EB]      = &spi1_lfin_eb.common.hw,
+               [CLK_SPI2_LFIN_EB]      = &spi2_lfin_eb.common.hw,
+               [CLK_SPI3_LFIN_EB]      = &spi3_lfin_eb.common.hw,
+               [CLK_SDIO0_EB]          = &sdio0_eb.common.hw,
+               [CLK_SDIO1_EB]          = &sdio1_eb.common.hw,
+               [CLK_SDIO2_EB]          = &sdio2_eb.common.hw,
+               [CLK_EMMC_EB]           = &emmc_eb.common.hw,
+               [CLK_SDIO0_32K_EB]      = &sdio0_32k_eb.common.hw,
+               [CLK_SDIO1_32K_EB]      = &sdio1_32k_eb.common.hw,
+               [CLK_SDIO2_32K_EB]      = &sdio2_32k_eb.common.hw,
+               [CLK_EMMC_32K_EB]       = &emmc_32k_eb.common.hw,
+       },
+       .num    = CLK_AP_APB_GATE_NUM,
+};
+
+static struct sprd_clk_desc ums512_apapb_gate_desc = {
+       .clk_clks       = ums512_apapb_gate,
+       .num_clk_clks   = ARRAY_SIZE(ums512_apapb_gate),
+       .hw_clks        = &ums512_apapb_gate_hws,
+};
+
+static const struct of_device_id sprd_ums512_clk_ids[] = {
+       { .compatible = "sprd,ums512-pmu-gate",         /* 0x327e0000 */
+         .data = &ums512_pmu_gate_desc },
+       { .compatible = "sprd,ums512-g0-pll",           /* 0x32390000 */
+         .data = &ums512_g0_pll_desc },
+       { .compatible = "sprd,ums512-g2-pll",           /* 0x323b0000 */
+         .data = &ums512_g2_pll_desc },
+       { .compatible = "sprd,ums512-g3-pll",           /* 0x323c0000 */
+         .data = &ums512_g3_pll_desc },
+       { .compatible = "sprd,ums512-gc-pll",           /* 0x323e0000 */
+         .data = &ums512_gc_pll_desc },
+       { .compatible = "sprd,ums512-apahb-gate",       /* 0x20100000 */
+         .data = &ums512_apahb_gate_desc },
+       { .compatible = "sprd,ums512-ap-clk",           /* 0x20200000 */
+         .data = &ums512_ap_clk_desc },
+       { .compatible = "sprd,ums512-aonapb-clk",       /* 0x32080200 */
+         .data = &ums512_aon_apb_desc },
+       { .compatible = "sprd,ums512-aon-gate",         /* 0x327d0000 */
+         .data = &ums512_aon_gate_desc },
+       { .compatible = "sprd,ums512-audcpapb-gate",    /* 0x3350d000 */
+         .data = &ums512_audcpapb_gate_desc },
+       { .compatible = "sprd,ums512-audcpahb-gate",    /* 0x335e0000 */
+         .data = &ums512_audcpahb_gate_desc },
+       { .compatible = "sprd,ums512-gpu-clk",          /* 0x60100000 */
+         .data = &ums512_gpu_clk_desc },
+       { .compatible = "sprd,ums512-mm-clk",           /* 0x62100000 */
+         .data = &ums512_mm_clk_desc },
+       { .compatible = "sprd,ums512-mm-gate-clk",      /* 0x62200000 */
+         .data = &ums512_mm_gate_clk_desc },
+       { .compatible = "sprd,ums512-apapb-gate",       /* 0x71000000 */
+         .data = &ums512_apapb_gate_desc },
+       { }
+};
+MODULE_DEVICE_TABLE(of, sprd_ums512_clk_ids);
+
+static int ums512_clk_probe(struct platform_device *pdev)
+{
+       const struct sprd_clk_desc *desc;
+       int ret;
+
+       desc = device_get_match_data(&pdev->dev);
+       if (!desc)
+               return -ENODEV;
+
+       ret = sprd_clk_regmap_init(pdev, desc);
+       if (ret)
+               return ret;
+
+       return sprd_clk_probe(&pdev->dev, desc->hw_clks);
+}
+
+static struct platform_driver ums512_clk_driver = {
+       .probe  = ums512_clk_probe,
+       .driver = {
+               .name   = "ums512-clk",
+               .of_match_table = sprd_ums512_clk_ids,
+       },
+};
+module_platform_driver(ums512_clk_driver);
+
+MODULE_DESCRIPTION("Unisoc UMS512 Clock Driver");
+MODULE_LICENSE("GPL");
index 582a22c..d820292 100644 (file)
@@ -987,6 +987,7 @@ static void __init st_of_quadfs_setup(struct device_node *np,
        const char *pll_name, *clk_parent_name;
        void __iomem *reg;
        spinlock_t *lock;
+       struct device_node *parent_np;
 
        /*
         * First check for reg property within the node to keep backward
@@ -994,7 +995,9 @@ static void __init st_of_quadfs_setup(struct device_node *np,
         */
        reg = of_iomap(np, 0);
        if (!reg) {
-               reg = of_iomap(of_get_parent(np), 0);
+               parent_np = of_get_parent(np);
+               reg = of_iomap(parent_np, 0);
+               of_node_put(parent_np);
                if (!reg) {
                        pr_err("%s: Failed to get base address\n", __func__);
                        return;
index ee39af7..596e939 100644 (file)
@@ -56,6 +56,7 @@ static void __init st_of_clkgen_mux_setup(struct device_node *np,
        void __iomem *reg;
        const char **parents;
        int num_parents = 0;
+       struct device_node *parent_np;
 
        /*
         * First check for reg property within the node to keep backward
@@ -63,7 +64,9 @@ static void __init st_of_clkgen_mux_setup(struct device_node *np,
         */
        reg = of_iomap(np, 0);
        if (!reg) {
-               reg = of_iomap(of_get_parent(np), 0);
+               parent_np = of_get_parent(np);
+               reg = of_iomap(parent_np, 0);
+               of_node_put(parent_np);
                if (!reg) {
                        pr_err("%s: Failed to get base address\n", __func__);
                        return;
index 51058ba..8ef3cde 100644 (file)
@@ -104,6 +104,8 @@ static struct ccu_nm pll_video0_4x_clk = {
        .lock           = BIT(28),
        .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
        .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .min_rate       = 252000000U,
+       .max_rate       = 2400000000U,
        .common         = {
                .reg            = 0x040,
                .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-video0-4x", osc24M,
@@ -126,6 +128,8 @@ static struct ccu_nm pll_video1_4x_clk = {
        .lock           = BIT(28),
        .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
        .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .min_rate       = 252000000U,
+       .max_rate       = 2400000000U,
        .common         = {
                .reg            = 0x048,
                .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-video1-4x", osc24M,
@@ -175,6 +179,8 @@ static struct ccu_nm pll_audio0_4x_clk = {
        .m              = _SUNXI_CCU_DIV(16, 6),
        .sdm            = _SUNXI_CCU_SDM(pll_audio0_sdm_table, BIT(24),
                                         0x178, BIT(31)),
+       .min_rate       = 180000000U,
+       .max_rate       = 3000000000U,
        .common         = {
                .reg            = 0x078,
                .features       = CCU_FEATURE_SIGMA_DELTA_MOD,
@@ -202,6 +208,8 @@ static struct ccu_nm pll_audio1_clk = {
        .lock           = BIT(28),
        .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
        .m              = _SUNXI_CCU_DIV(1, 1),
+       .min_rate       = 180000000U,
+       .max_rate       = 3000000000U,
        .common         = {
                .reg            = 0x080,
                .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-audio1", osc24M,
index 2f6f02f..b70b312 100644 (file)
@@ -256,29 +256,19 @@ static int sunxi_de2_clk_probe(struct platform_device *pdev)
                return PTR_ERR(reg);
 
        bus_clk = devm_clk_get(&pdev->dev, "bus");
-       if (IS_ERR(bus_clk)) {
-               ret = PTR_ERR(bus_clk);
-               if (ret != -EPROBE_DEFER)
-                       dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret);
-               return ret;
-       }
+       if (IS_ERR(bus_clk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(bus_clk),
+                                    "Couldn't get bus clk\n");
 
        mod_clk = devm_clk_get(&pdev->dev, "mod");
-       if (IS_ERR(mod_clk)) {
-               ret = PTR_ERR(mod_clk);
-               if (ret != -EPROBE_DEFER)
-                       dev_err(&pdev->dev, "Couldn't get mod clk: %d\n", ret);
-               return ret;
-       }
+       if (IS_ERR(mod_clk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(mod_clk),
+                                    "Couldn't get mod clk\n");
 
        rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
-       if (IS_ERR(rstc)) {
-               ret = PTR_ERR(rstc);
-               if (ret != -EPROBE_DEFER)
-                       dev_err(&pdev->dev,
-                               "Couldn't get reset control: %d\n", ret);
-               return ret;
-       }
+       if (IS_ERR(rstc))
+               return dev_err_probe(&pdev->dev, PTR_ERR(rstc),
+                                    "Couldn't get reset control\n");
 
        /* The clocks need to be enabled for us to access the registers */
        ret = clk_prepare_enable(bus_clk);
index f2fe0e1..1d8b1ae 100644 (file)
@@ -213,21 +213,14 @@ static int sun9i_a80_de_clk_probe(struct platform_device *pdev)
                return PTR_ERR(reg);
 
        bus_clk = devm_clk_get(&pdev->dev, "bus");
-       if (IS_ERR(bus_clk)) {
-               ret = PTR_ERR(bus_clk);
-               if (ret != -EPROBE_DEFER)
-                       dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret);
-               return ret;
-       }
+       if (IS_ERR(bus_clk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(bus_clk),
+                                    "Couldn't get bus clk\n");
 
        rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
-       if (IS_ERR(rstc)) {
-               ret = PTR_ERR(rstc);
-               if (ret != -EPROBE_DEFER)
-                       dev_err(&pdev->dev,
-                               "Couldn't get reset control: %d\n", ret);
-               return ret;
-       }
+       if (IS_ERR(rstc))
+               return dev_err_probe(&pdev->dev, PTR_ERR(rstc),
+                                    "Couldn't get reset control\n");
 
        /* The bus clock needs to be enabled for us to access the registers */
        ret = clk_prepare_enable(bus_clk);
index 575ae4c..a0fb0da 100644 (file)
@@ -101,12 +101,9 @@ static int sun9i_a80_usb_clk_probe(struct platform_device *pdev)
                return PTR_ERR(reg);
 
        bus_clk = devm_clk_get(&pdev->dev, "bus");
-       if (IS_ERR(bus_clk)) {
-               ret = PTR_ERR(bus_clk);
-               if (ret != -EPROBE_DEFER)
-                       dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret);
-               return ret;
-       }
+       if (IS_ERR(bus_clk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(bus_clk),
+                                    "Couldn't get bus clk\n");
 
        /* The bus clock needs to be enabled for us to access the registers */
        ret = clk_prepare_enable(bus_clk);
index 3748a39..d82a71f 100644 (file)
@@ -349,7 +349,7 @@ static int tegra_bpmp_clk_get_info(struct tegra_bpmp *bpmp, unsigned int id,
        if (err < 0)
                return err;
 
-       strlcpy(info->name, response.name, MRQ_CLK_NAME_MAXLEN);
+       strscpy(info->name, response.name, MRQ_CLK_NAME_MAXLEN);
        info->num_parents = response.num_parents;
 
        for (i = 0; i < info->num_parents; i++)
index ef718c4..f7405a5 100644 (file)
@@ -1317,6 +1317,7 @@ static void __init tegra114_clock_init(struct device_node *np)
        }
 
        pmc_base = of_iomap(node, 0);
+       of_node_put(node);
        if (!pmc_base) {
                pr_err("Can't map pmc registers\n");
                WARN_ON(1);
index 934520a..a9d4efc 100644 (file)
@@ -1471,6 +1471,7 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
        }
 
        pmc_base = of_iomap(node, 0);
+       of_node_put(node);
        if (!pmc_base) {
                pr_err("Can't map pmc registers\n");
                WARN_ON(1);
index be3c334..8a4514f 100644 (file)
@@ -1131,6 +1131,7 @@ static void __init tegra20_clock_init(struct device_node *np)
        }
 
        pmc_base = of_iomap(node, 0);
+       of_node_put(node);
        if (!pmc_base) {
                pr_err("Can't map pmc registers\n");
                BUG();
index b909901..499f999 100644 (file)
@@ -3748,6 +3748,7 @@ static void __init tegra210_clock_init(struct device_node *np)
        }
 
        pmc_base = of_iomap(node, 0);
+       of_node_put(node);
        if (!pmc_base) {
                pr_err("Can't map pmc registers\n");
                WARN_ON(1);
index 04b4961..168c07d 100644 (file)
@@ -1320,6 +1320,7 @@ static void __init tegra30_clock_init(struct device_node *np)
        }
 
        pmc_base = of_iomap(node, 0);
+       of_node_put(node);
        if (!pmc_base) {
                pr_err("Can't map pmc registers\n");
                BUG();
index f0f5bf6..ff4d6a9 100644 (file)
@@ -245,14 +245,16 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
                if (rc) {
                        pr_err("%s: failed to lookup atl clock %d\n", __func__,
                               i);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto pm_put;
                }
 
                clk = of_clk_get_from_provider(&clkspec);
                if (IS_ERR(clk)) {
                        pr_err("%s: failed to get atl clock %d from provider\n",
                               __func__, i);
-                       return PTR_ERR(clk);
+                       ret = PTR_ERR(clk);
+                       goto pm_put;
                }
 
                cdesc = to_atl_desc(__clk_get_hw(clk));
@@ -285,8 +287,9 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
                if (cdesc->enabled)
                        atl_clk_enable(__clk_get_hw(clk));
        }
-       pm_runtime_put_sync(cinfo->dev);
 
+pm_put:
+       pm_runtime_put_sync(cinfo->dev);
        return ret;
 }
 
index ef2a445..a992792 100644 (file)
@@ -139,11 +139,12 @@ static struct device_node *ti_find_clock_provider(struct device_node *from,
                        break;
                }
        }
-       of_node_put(from);
        kfree(tmp);
 
-       if (found)
+       if (found) {
+               of_node_put(from);
                return np;
+       }
 
        /* Fall back to using old node name base provider name */
        return of_find_node_by_name(from, name);
index 5224114..f205522 100644 (file)
@@ -17,3 +17,15 @@ config XILINX_VCU
          To compile this driver as a module, choose M here: the
          module will be called xlnx_vcu.
 
+config COMMON_CLK_XLNX_CLKWZRD
+       tristate "Xilinx Clocking Wizard"
+       depends on COMMON_CLK && OF
+       depends on HAS_IOMEM
+       help
+         Support for the Xilinx Clocking Wizard IP core clock generator.
+         Adds support for clocking wizard and compatible.
+         This driver supports the Xilinx clocking wizard programmable clock
+         synthesizer. The number of output is configurable in the design.
+
+         If unsure, say N.
+
index dee8fd5..7ac1789 100644 (file)
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_XILINX_VCU)       += xlnx_vcu.o
+obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clk-xlnx-clock-wizard.o
@@ -2,9 +2,10 @@
 /*
  * Xilinx 'Clocking Wizard' driver
  *
- *  Copyright (C) 2013 - 2014 Xilinx
+ *  Copyright (C) 2013 - 2021 Xilinx
  *
  *  Sören Brinkmann <soren.brinkmann@xilinx.com>
+ *
  */
 
 #include <linux/platform_device.h>
@@ -43,6 +44,8 @@
 #define WZRD_DR_INIT_REG_OFFSET                0x25C
 #define WZRD_DR_DIV_TO_PHASE_OFFSET    4
 #define WZRD_DR_BEGIN_DYNA_RECONF      0x03
+#define WZRD_DR_BEGIN_DYNA_RECONF_5_2  0x07
+#define WZRD_DR_BEGIN_DYNA_RECONF1_5_2 0x02
 
 #define WZRD_USEC_POLL         10
 #define WZRD_TIMEOUT_POLL              1000
@@ -164,7 +167,9 @@ static int clk_wzrd_dynamic_reconfig(struct clk_hw *hw, unsigned long rate,
                goto err_reconfig;
 
        /* Initiate reconfiguration */
-       writel(WZRD_DR_BEGIN_DYNA_RECONF,
+       writel(WZRD_DR_BEGIN_DYNA_RECONF_5_2,
+              divider->base + WZRD_DR_INIT_REG_OFFSET);
+       writel(WZRD_DR_BEGIN_DYNA_RECONF1_5_2,
               divider->base + WZRD_DR_INIT_REG_OFFSET);
 
        /* Check status register */
@@ -223,7 +228,7 @@ static int clk_wzrd_dynamic_reconfig_f(struct clk_hw *hw, unsigned long rate,
        struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
        void __iomem *div_addr = divider->base + divider->offset;
 
-       rate_div = ((parent_rate * 1000) / rate);
+       rate_div = DIV_ROUND_DOWN_ULL(parent_rate * 1000, rate);
        clockout0_div = rate_div / 1000;
 
        pre = DIV_ROUND_CLOSEST((parent_rate * 1000), rate);
@@ -245,7 +250,9 @@ static int clk_wzrd_dynamic_reconfig_f(struct clk_hw *hw, unsigned long rate,
                return err;
 
        /* Initiate reconfiguration */
-       writel(WZRD_DR_BEGIN_DYNA_RECONF,
+       writel(WZRD_DR_BEGIN_DYNA_RECONF_5_2,
+              divider->base + WZRD_DR_INIT_REG_OFFSET);
+       writel(WZRD_DR_BEGIN_DYNA_RECONF1_5_2,
               divider->base + WZRD_DR_INIT_REG_OFFSET);
 
        /* Check status register */
@@ -441,18 +448,14 @@ static int clk_wzrd_probe(struct platform_device *pdev)
        }
 
        clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1");
-       if (IS_ERR(clk_wzrd->clk_in1)) {
-               if (clk_wzrd->clk_in1 != ERR_PTR(-EPROBE_DEFER))
-                       dev_err(&pdev->dev, "clk_in1 not found\n");
-               return PTR_ERR(clk_wzrd->clk_in1);
-       }
+       if (IS_ERR(clk_wzrd->clk_in1))
+               return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1),
+                                    "clk_in1 not found\n");
 
        clk_wzrd->axi_clk = devm_clk_get(&pdev->dev, "s_axi_aclk");
-       if (IS_ERR(clk_wzrd->axi_clk)) {
-               if (clk_wzrd->axi_clk != ERR_PTR(-EPROBE_DEFER))
-                       dev_err(&pdev->dev, "s_axi_aclk not found\n");
-               return PTR_ERR(clk_wzrd->axi_clk);
-       }
+       if (IS_ERR(clk_wzrd->axi_clk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->axi_clk),
+                                    "s_axi_aclk not found\n");
        ret = clk_prepare_enable(clk_wzrd->axi_clk);
        if (ret) {
                dev_err(&pdev->dev, "enabling s_axi_aclk failed\n");
@@ -479,7 +482,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
                goto err_disable_clk;
        }
 
-       ret = of_property_read_u32(np, "nr-outputs", &nr_outputs);
+       ret = of_property_read_u32(np, "xlnx,nr-outputs", &nr_outputs);
        if (ret || nr_outputs > WZRD_NUM_OUTPUTS) {
                ret = -EINVAL;
                goto err_disable_clk;
@@ -614,6 +617,8 @@ static int clk_wzrd_remove(struct platform_device *pdev)
 
 static const struct of_device_id clk_wzrd_ids[] = {
        { .compatible = "xlnx,clocking-wizard" },
+       { .compatible = "xlnx,clocking-wizard-v5.2" },
+       { .compatible = "xlnx,clocking-wizard-v6.0" },
        { },
 };
 MODULE_DEVICE_TABLE(of, clk_wzrd_ids);
index eb25303..5636ff1 100644 (file)
@@ -163,7 +163,7 @@ static int zynqmp_get_clock_name(u32 clk_id, char *clk_name)
 
        ret = zynqmp_is_valid_clock(clk_id);
        if (ret == 1) {
-               strncpy(clk_name, clock[clk_id].clk_name, MAX_NAME_LEN);
+               strscpy(clk_name, clock[clk_id].clk_name, MAX_NAME_LEN);
                return 0;
        }
 
@@ -220,18 +220,22 @@ static int zynqmp_pm_clock_get_num_clocks(u32 *nclocks)
  * This function is used to get name of clock specified by given
  * clock ID.
  *
- * Return: Returns 0
+ * Return: 0 on success else error+reason
  */
 static int zynqmp_pm_clock_get_name(u32 clock_id,
                                    struct name_resp *response)
 {
        struct zynqmp_pm_query_data qdata = {0};
        u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
 
        qdata.qid = PM_QID_CLOCK_GET_NAME;
        qdata.arg1 = clock_id;
 
-       zynqmp_pm_query_data(qdata, ret_payload);
+       ret = zynqmp_pm_query_data(qdata, ret_payload);
+       if (ret)
+               return ret;
+
        memcpy(response, ret_payload, sizeof(*response));
 
        return 0;
@@ -710,9 +714,16 @@ static void zynqmp_get_clock_info(void)
                                  FIELD_PREP(CLK_ATTR_NODE_INDEX, i);
 
                zynqmp_pm_clock_get_name(clock[i].clk_id, &name);
+
+               /*
+                * Terminate with NULL character in case name provided by firmware
+                * is longer and truncated due to size limit.
+                */
+               name.name[sizeof(name.name) - 1] = '\0';
+
                if (!strcmp(name.name, RESERVED_CLK_NAME))
                        continue;
-               strncpy(clock[i].clk_name, name.name, MAX_NAME_LEN);
+               strscpy(clock[i].clk_name, name.name, MAX_NAME_LEN);
        }
 
        /* Get topology of all clock */
index 422ea79..33a3b2a 100644 (file)
@@ -113,17 +113,20 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,
 static void zynqmp_get_divider2_val(struct clk_hw *hw,
                                    unsigned long rate,
                                    struct zynqmp_clk_divider *divider,
-                                   int *bestdiv)
+                                   u32 *bestdiv)
 {
        int div1;
        int div2;
        long error = LONG_MAX;
        unsigned long div1_prate;
        struct clk_hw *div1_parent_hw;
+       struct zynqmp_clk_divider *pdivider;
        struct clk_hw *div2_parent_hw = clk_hw_get_parent(hw);
-       struct zynqmp_clk_divider *pdivider =
-                               to_zynqmp_clk_divider(div2_parent_hw);
 
+       if (!div2_parent_hw)
+               return;
+
+       pdivider = to_zynqmp_clk_divider(div2_parent_hw);
        if (!pdivider)
                return;
 
index 91a6b4c..0d3e137 100644 (file)
@@ -102,26 +102,25 @@ static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
                                  unsigned long *prate)
 {
        u32 fbdiv;
-       long rate_div, f;
+       u32 mult, div;
 
-       /* Enable the fractional mode if needed */
-       rate_div = (rate * FRAC_DIV) / *prate;
-       f = rate_div % FRAC_DIV;
-       if (f) {
-               if (rate > PS_PLL_VCO_MAX) {
-                       fbdiv = rate / PS_PLL_VCO_MAX;
-                       rate = rate / (fbdiv + 1);
-               }
-               if (rate < PS_PLL_VCO_MIN) {
-                       fbdiv = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate);
-                       rate = rate * fbdiv;
-               }
-               return rate;
+       /* Let rate fall inside the range PS_PLL_VCO_MIN ~ PS_PLL_VCO_MAX */
+       if (rate > PS_PLL_VCO_MAX) {
+               div = DIV_ROUND_UP(rate, PS_PLL_VCO_MAX);
+               rate = rate / div;
+       }
+       if (rate < PS_PLL_VCO_MIN) {
+               mult = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate);
+               rate = rate * mult;
        }
 
        fbdiv = DIV_ROUND_CLOSEST(rate, *prate);
-       fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
-       return *prate * fbdiv;
+       if (fbdiv < PLL_FBDIV_MIN || fbdiv > PLL_FBDIV_MAX) {
+               fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
+               rate = *prate * fbdiv;
+       }
+
+       return rate;
 }
 
 /**
index c6cc493..2b97b8a 100644 (file)
@@ -148,30 +148,22 @@ aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,
                              struct amdgpu_reset_context *reset_context)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
+       struct list_head *reset_device_list = reset_context->reset_device_list;
        struct amdgpu_device *tmp_adev = NULL;
-       struct list_head reset_device_list;
        int r = 0;
 
        dev_dbg(adev->dev, "aldebaran perform hw reset\n");
+
+       if (reset_device_list == NULL)
+               return -EINVAL;
+
        if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2) &&
            reset_context->hive == NULL) {
                /* Wrong context, return error */
                return -EINVAL;
        }
 
-       INIT_LIST_HEAD(&reset_device_list);
-       if (reset_context->hive) {
-               list_for_each_entry (tmp_adev,
-                                    &reset_context->hive->device_list,
-                                    gmc.xgmi.head)
-                       list_add_tail(&tmp_adev->reset_list,
-                                     &reset_device_list);
-       } else {
-               list_add_tail(&reset_context->reset_req_dev->reset_list,
-                             &reset_device_list);
-       }
-
-       list_for_each_entry (tmp_adev, &reset_device_list, reset_list) {
+       list_for_each_entry(tmp_adev, reset_device_list, reset_list) {
                mutex_lock(&tmp_adev->reset_cntl->reset_lock);
                tmp_adev->reset_cntl->active_reset = AMD_RESET_METHOD_MODE2;
        }
@@ -179,7 +171,7 @@ aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,
         * Mode2 reset doesn't need any sync between nodes in XGMI hive, instead launch
         * them together so that they can be completed asynchronously on multiple nodes
         */
-       list_for_each_entry (tmp_adev, &reset_device_list, reset_list) {
+       list_for_each_entry(tmp_adev, reset_device_list, reset_list) {
                /* For XGMI run all resets in parallel to speed up the process */
                if (tmp_adev->gmc.xgmi.num_physical_nodes > 1) {
                        if (!queue_work(system_unbound_wq,
@@ -197,7 +189,7 @@ aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,
 
        /* For XGMI wait for all resets to complete before proceed */
        if (!r) {
-               list_for_each_entry (tmp_adev, &reset_device_list, reset_list) {
+               list_for_each_entry(tmp_adev, reset_device_list, reset_list) {
                        if (tmp_adev->gmc.xgmi.num_physical_nodes > 1) {
                                flush_work(&tmp_adev->reset_cntl->reset_work);
                                r = tmp_adev->asic_reset_res;
@@ -207,7 +199,7 @@ aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,
                }
        }
 
-       list_for_each_entry (tmp_adev, &reset_device_list, reset_list) {
+       list_for_each_entry(tmp_adev, reset_device_list, reset_list) {
                mutex_unlock(&tmp_adev->reset_cntl->reset_lock);
                tmp_adev->reset_cntl->active_reset = AMD_RESET_METHOD_NONE;
        }
@@ -339,10 +331,13 @@ static int
 aldebaran_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl,
                                  struct amdgpu_reset_context *reset_context)
 {
+       struct list_head *reset_device_list = reset_context->reset_device_list;
        struct amdgpu_device *tmp_adev = NULL;
-       struct list_head reset_device_list;
        int r;
 
+       if (reset_device_list == NULL)
+               return -EINVAL;
+
        if (reset_context->reset_req_dev->ip_versions[MP1_HWIP][0] ==
                    IP_VERSION(13, 0, 2) &&
            reset_context->hive == NULL) {
@@ -350,19 +345,7 @@ aldebaran_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl,
                return -EINVAL;
        }
 
-       INIT_LIST_HEAD(&reset_device_list);
-       if (reset_context->hive) {
-               list_for_each_entry (tmp_adev,
-                                    &reset_context->hive->device_list,
-                                    gmc.xgmi.head)
-                       list_add_tail(&tmp_adev->reset_list,
-                                     &reset_device_list);
-       } else {
-               list_add_tail(&reset_context->reset_req_dev->reset_list,
-                             &reset_device_list);
-       }
-
-       list_for_each_entry (tmp_adev, &reset_device_list, reset_list) {
+       list_for_each_entry(tmp_adev, reset_device_list, reset_list) {
                dev_info(tmp_adev->dev,
                         "GPU reset succeeded, trying to resume\n");
                r = aldebaran_mode2_restore_ip(tmp_adev);
index e146810..d597e26 100644 (file)
@@ -317,7 +317,7 @@ enum amdgpu_kiq_irq {
        AMDGPU_CP_KIQ_IRQ_DRIVER0 = 0,
        AMDGPU_CP_KIQ_IRQ_LAST
 };
-
+#define SRIOV_USEC_TIMEOUT  1200000 /* wait 12 * 100ms for SRIOV */
 #define MAX_KIQ_REG_WAIT       5000 /* in usecs, 5ms */
 #define MAX_KIQ_REG_BAILOUT_INTERVAL   5 /* in msecs, 5ms */
 #define MAX_KIQ_REG_TRY 1000
index 3c09dcc..647220a 100644 (file)
@@ -96,6 +96,7 @@ struct amdgpu_amdkfd_fence {
 struct amdgpu_kfd_dev {
        struct kfd_dev *dev;
        uint64_t vram_used;
+       uint64_t vram_used_aligned;
        bool init_complete;
        struct work_struct reset_work;
 };
index a699134..cbd593f 100644 (file)
 #define AMDGPU_USERPTR_RESTORE_DELAY_MS 1
 
 /*
- * Align VRAM allocations to 2MB to avoid fragmentation caused by 4K allocations in the tail 2MB
+ * Align VRAM availability to 2MB to avoid fragmentation caused by 4K allocations in the tail 2MB
  * BO chunk
  */
-#define VRAM_ALLOCATION_ALIGN (1 << 21)
+#define VRAM_AVAILABLITY_ALIGN (1 << 21)
 
 /* Impose limit on how much memory KFD can use */
 static struct {
@@ -149,7 +149,7 @@ int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
                 * to avoid fragmentation caused by 4K allocations in the tail
                 * 2M BO chunk.
                 */
-               vram_needed = ALIGN(size, VRAM_ALLOCATION_ALIGN);
+               vram_needed = size;
        } else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR) {
                system_mem_needed = size;
        } else if (!(alloc_flag &
@@ -182,8 +182,10 @@ int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
         */
        WARN_ONCE(vram_needed && !adev,
                  "adev reference can't be null when vram is used");
-       if (adev)
+       if (adev) {
                adev->kfd.vram_used += vram_needed;
+               adev->kfd.vram_used_aligned += ALIGN(vram_needed, VRAM_AVAILABLITY_ALIGN);
+       }
        kfd_mem_limit.system_mem_used += system_mem_needed;
        kfd_mem_limit.ttm_mem_used += ttm_mem_needed;
 
@@ -203,8 +205,10 @@ void amdgpu_amdkfd_unreserve_mem_limit(struct amdgpu_device *adev,
        } else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
                WARN_ONCE(!adev,
                          "adev reference can't be null when alloc mem flags vram is set");
-               if (adev)
-                       adev->kfd.vram_used -= ALIGN(size, VRAM_ALLOCATION_ALIGN);
+               if (adev) {
+                       adev->kfd.vram_used -= size;
+                       adev->kfd.vram_used_aligned -= ALIGN(size, VRAM_AVAILABLITY_ALIGN);
+               }
        } else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR) {
                kfd_mem_limit.system_mem_used -= size;
        } else if (!(alloc_flag &
@@ -1608,15 +1612,14 @@ size_t amdgpu_amdkfd_get_available_memory(struct amdgpu_device *adev)
        uint64_t reserved_for_pt =
                ESTIMATE_PT_SIZE(amdgpu_amdkfd_total_mem_size);
        size_t available;
-
        spin_lock(&kfd_mem_limit.mem_limit_lock);
        available = adev->gmc.real_vram_size
-               - adev->kfd.vram_used
+               - adev->kfd.vram_used_aligned
                - atomic64_read(&adev->vram_pin_size)
                - reserved_for_pt;
        spin_unlock(&kfd_mem_limit.mem_limit_lock);
 
-       return ALIGN_DOWN(available, VRAM_ALLOCATION_ALIGN);
+       return ALIGN_DOWN(available, VRAM_AVAILABLITY_ALIGN);
 }
 
 int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
index fd8f373..b81b77a 100644 (file)
@@ -314,7 +314,7 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
                                        mem_channel_number = vram_info->v30.channel_num;
                                        mem_channel_width = vram_info->v30.channel_width;
                                        if (vram_width)
-                                               *vram_width = mem_channel_number * mem_channel_width;
+                                               *vram_width = mem_channel_number * (1 << mem_channel_width);
                                        break;
                                default:
                                        return -EINVAL;
index d8f1335..b7bae83 100644 (file)
@@ -837,16 +837,12 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
                        continue;
 
                r = amdgpu_vm_bo_update(adev, bo_va, false);
-               if (r) {
-                       mutex_unlock(&p->bo_list->bo_list_mutex);
+               if (r)
                        return r;
-               }
 
                r = amdgpu_sync_fence(&p->job->sync, bo_va->last_pt_update);
-               if (r) {
-                       mutex_unlock(&p->bo_list->bo_list_mutex);
+               if (r)
                        return r;
-               }
        }
 
        r = amdgpu_vm_handle_moved(adev, vm);
index e2eec98..cb00c7d 100644 (file)
@@ -1705,7 +1705,7 @@ static ssize_t amdgpu_reset_dump_register_list_write(struct file *f,
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
        char reg_offset[11];
-       uint32_t *new, *tmp = NULL;
+       uint32_t *new = NULL, *tmp = NULL;
        int ret, i = 0, len = 0;
 
        do {
@@ -1747,7 +1747,8 @@ static ssize_t amdgpu_reset_dump_register_list_write(struct file *f,
        ret = size;
 
 error_free:
-       kfree(tmp);
+       if (tmp != new)
+               kfree(tmp);
        kfree(new);
        return ret;
 }
index c4a6fe3..e8a0b19 100644 (file)
@@ -4742,6 +4742,8 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
        tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
                                    reset_list);
        amdgpu_reset_reg_dumps(tmp_adev);
+
+       reset_context->reset_device_list = device_list_handle;
        r = amdgpu_reset_perform_reset(tmp_adev, reset_context);
        /* If reset handler not implemented, continue; otherwise return */
        if (r == -ENOSYS)
index 5071b96..b1099ee 100644 (file)
@@ -272,10 +272,6 @@ void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched)
        /* Signal all jobs not yet scheduled */
        for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {
                struct drm_sched_rq *rq = &sched->sched_rq[i];
-
-               if (!rq)
-                       continue;
-
                spin_lock(&rq->lock);
                list_for_each_entry(s_entity, &rq->entities, list) {
                        while ((s_job = to_drm_sched_job(spsc_queue_pop(&s_entity->job_queue)))) {
index 9e55a5d..ffda156 100644 (file)
@@ -37,6 +37,7 @@ struct amdgpu_reset_context {
        struct amdgpu_device *reset_req_dev;
        struct amdgpu_job *job;
        struct amdgpu_hive_info *hive;
+       struct list_head *reset_device_list;
        unsigned long flags;
 };
 
index 3b4c194..134575a 100644 (file)
@@ -637,6 +637,8 @@ struct amdgpu_ttm_tt {
 #endif
 };
 
+#define ttm_to_amdgpu_ttm_tt(ptr)      container_of(ptr, struct amdgpu_ttm_tt, ttm)
+
 #ifdef CONFIG_DRM_AMDGPU_USERPTR
 /*
  * amdgpu_ttm_tt_get_user_pages - get device accessible pages that back user
@@ -648,7 +650,7 @@ struct amdgpu_ttm_tt {
 int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
 {
        struct ttm_tt *ttm = bo->tbo.ttm;
-       struct amdgpu_ttm_tt *gtt = (void *)ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
        unsigned long start = gtt->userptr;
        struct vm_area_struct *vma;
        struct mm_struct *mm;
@@ -702,7 +704,7 @@ out_unlock:
  */
 bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm)
 {
-       struct amdgpu_ttm_tt *gtt = (void *)ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
        bool r = false;
 
        if (!gtt || !gtt->userptr)
@@ -751,7 +753,7 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_device *bdev,
                                     struct ttm_tt *ttm)
 {
        struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);
-       struct amdgpu_ttm_tt *gtt = (void *)ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
        int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
        enum dma_data_direction direction = write ?
                DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
@@ -788,7 +790,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_device *bdev,
                                        struct ttm_tt *ttm)
 {
        struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);
-       struct amdgpu_ttm_tt *gtt = (void *)ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
        int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
        enum dma_data_direction direction = write ?
                DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
@@ -822,7 +824,7 @@ static void amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
 {
        struct amdgpu_bo *abo = ttm_to_amdgpu_bo(tbo);
        struct ttm_tt *ttm = tbo->ttm;
-       struct amdgpu_ttm_tt *gtt = (void *)ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
 
        if (amdgpu_bo_encrypted(abo))
                flags |= AMDGPU_PTE_TMZ;
@@ -860,7 +862,7 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev,
                                   struct ttm_resource *bo_mem)
 {
        struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);
-       struct amdgpu_ttm_tt *gtt = (void*)ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
        uint64_t flags;
        int r;
 
@@ -927,7 +929,7 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
 {
        struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
        struct ttm_operation_ctx ctx = { false, false };
-       struct amdgpu_ttm_tt *gtt = (void *)bo->ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(bo->ttm);
        struct ttm_placement placement;
        struct ttm_place placements;
        struct ttm_resource *tmp;
@@ -998,7 +1000,7 @@ static void amdgpu_ttm_backend_unbind(struct ttm_device *bdev,
                                      struct ttm_tt *ttm)
 {
        struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);
-       struct amdgpu_ttm_tt *gtt = (void *)ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
 
        /* if the pages have userptr pinning then clear that first */
        if (gtt->userptr) {
@@ -1025,7 +1027,7 @@ static void amdgpu_ttm_backend_unbind(struct ttm_device *bdev,
 static void amdgpu_ttm_backend_destroy(struct ttm_device *bdev,
                                       struct ttm_tt *ttm)
 {
-       struct amdgpu_ttm_tt *gtt = (void *)ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
 
        if (gtt->usertask)
                put_task_struct(gtt->usertask);
@@ -1079,7 +1081,7 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev,
                                  struct ttm_operation_ctx *ctx)
 {
        struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);
-       struct amdgpu_ttm_tt *gtt = (void *)ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
        pgoff_t i;
        int ret;
 
@@ -1113,7 +1115,7 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev,
 static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev,
                                     struct ttm_tt *ttm)
 {
-       struct amdgpu_ttm_tt *gtt = (void *)ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
        struct amdgpu_device *adev;
        pgoff_t i;
 
@@ -1182,7 +1184,7 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo,
        /* Set TTM_TT_FLAG_EXTERNAL before populate but after create. */
        bo->ttm->page_flags |= TTM_TT_FLAG_EXTERNAL;
 
-       gtt = (void *)bo->ttm;
+       gtt = ttm_to_amdgpu_ttm_tt(bo->ttm);
        gtt->userptr = addr;
        gtt->userflags = flags;
 
@@ -1199,7 +1201,7 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo,
  */
 struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm)
 {
-       struct amdgpu_ttm_tt *gtt = (void *)ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
 
        if (gtt == NULL)
                return NULL;
@@ -1218,7 +1220,7 @@ struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm)
 bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
                                  unsigned long end, unsigned long *userptr)
 {
-       struct amdgpu_ttm_tt *gtt = (void *)ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
        unsigned long size;
 
        if (gtt == NULL || !gtt->userptr)
@@ -1241,7 +1243,7 @@ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
  */
 bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm)
 {
-       struct amdgpu_ttm_tt *gtt = (void *)ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
 
        if (gtt == NULL || !gtt->userptr)
                return false;
@@ -1254,7 +1256,7 @@ bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm)
  */
 bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm)
 {
-       struct amdgpu_ttm_tt *gtt = (void *)ttm;
+       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
 
        if (gtt == NULL)
                return false;
index 108e8e8..576849e 100644 (file)
@@ -496,8 +496,7 @@ static int amdgpu_vkms_sw_init(void *handle)
        adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
 
        adev_to_drm(adev)->mode_config.preferred_depth = 24;
-       /* disable prefer shadow for now due to hibernation issues */
-       adev_to_drm(adev)->mode_config.prefer_shadow = 0;
+       adev_to_drm(adev)->mode_config.prefer_shadow = 1;
 
        adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
 
index 33a8a73..f0e235f 100644 (file)
 #include "navi10_enum.h"
 #include "soc15_common.h"
 
+#define regATHUB_MISC_CNTL_V3_0_1                      0x00d7
+#define regATHUB_MISC_CNTL_V3_0_1_BASE_IDX             0
+
+
+static uint32_t athub_v3_0_get_cg_cntl(struct amdgpu_device *adev)
+{
+       uint32_t data;
+
+       switch (adev->ip_versions[ATHUB_HWIP][0]) {
+       case IP_VERSION(3, 0, 1):
+               data = RREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL_V3_0_1);
+               break;
+       default:
+               data = RREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL);
+               break;
+       }
+       return data;
+}
+
+static void athub_v3_0_set_cg_cntl(struct amdgpu_device *adev, uint32_t data)
+{
+       switch (adev->ip_versions[ATHUB_HWIP][0]) {
+       case IP_VERSION(3, 0, 1):
+               WREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL_V3_0_1, data);
+               break;
+       default:
+               WREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL, data);
+               break;
+       }
+}
+
 static void
 athub_v3_0_update_medium_grain_clock_gating(struct amdgpu_device *adev,
                                            bool enable)
 {
        uint32_t def, data;
 
-       def = data = RREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL);
+       def = data = athub_v3_0_get_cg_cntl(adev);
 
        if (enable && (adev->cg_flags & AMD_CG_SUPPORT_ATHUB_MGCG))
                data |= ATHUB_MISC_CNTL__CG_ENABLE_MASK;
@@ -42,7 +73,7 @@ athub_v3_0_update_medium_grain_clock_gating(struct amdgpu_device *adev,
                data &= ~ATHUB_MISC_CNTL__CG_ENABLE_MASK;
 
        if (def != data)
-               WREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL, data);
+               athub_v3_0_set_cg_cntl(adev, data);
 }
 
 static void
@@ -51,7 +82,7 @@ athub_v3_0_update_medium_grain_light_sleep(struct amdgpu_device *adev,
 {
        uint32_t def, data;
 
-       def = data = RREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL);
+       def = data = athub_v3_0_get_cg_cntl(adev);
 
        if (enable && (adev->cg_flags & AMD_CG_SUPPORT_ATHUB_LS))
                data |= ATHUB_MISC_CNTL__CG_MEM_LS_ENABLE_MASK;
@@ -59,7 +90,7 @@ athub_v3_0_update_medium_grain_light_sleep(struct amdgpu_device *adev,
                data &= ~ATHUB_MISC_CNTL__CG_MEM_LS_ENABLE_MASK;
 
        if (def != data)
-               WREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL, data);
+               athub_v3_0_set_cg_cntl(adev, data);
 }
 
 int athub_v3_0_set_clockgating(struct amdgpu_device *adev,
@@ -70,6 +101,7 @@ int athub_v3_0_set_clockgating(struct amdgpu_device *adev,
 
        switch (adev->ip_versions[ATHUB_HWIP][0]) {
        case IP_VERSION(3, 0, 0):
+       case IP_VERSION(3, 0, 1):
        case IP_VERSION(3, 0, 2):
                athub_v3_0_update_medium_grain_clock_gating(adev,
                                state == AMD_CG_STATE_GATE);
@@ -88,7 +120,7 @@ void athub_v3_0_get_clockgating(struct amdgpu_device *adev, u64 *flags)
        int data;
 
        /* AMD_CG_SUPPORT_ATHUB_MGCG */
-       data = RREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL);
+       data = athub_v3_0_get_cg_cntl(adev);
        if (data & ATHUB_MISC_CNTL__CG_ENABLE_MASK)
                *flags |= AMD_CG_SUPPORT_ATHUB_MGCG;
 
index 9c964cd..288fce7 100644 (file)
@@ -2796,8 +2796,7 @@ static int dce_v10_0_sw_init(void *handle)
        adev_to_drm(adev)->mode_config.max_height = 16384;
 
        adev_to_drm(adev)->mode_config.preferred_depth = 24;
-       /* disable prefer shadow for now due to hibernation issues */
-       adev_to_drm(adev)->mode_config.prefer_shadow = 0;
+       adev_to_drm(adev)->mode_config.prefer_shadow = 1;
 
        adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
 
index e0ad9f2..cbe5250 100644 (file)
@@ -2914,8 +2914,7 @@ static int dce_v11_0_sw_init(void *handle)
        adev_to_drm(adev)->mode_config.max_height = 16384;
 
        adev_to_drm(adev)->mode_config.preferred_depth = 24;
-       /* disable prefer shadow for now due to hibernation issues */
-       adev_to_drm(adev)->mode_config.prefer_shadow = 0;
+       adev_to_drm(adev)->mode_config.prefer_shadow = 1;
 
        adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
 
index 77f5e99..b1c44fa 100644 (file)
@@ -2673,8 +2673,7 @@ static int dce_v6_0_sw_init(void *handle)
        adev_to_drm(adev)->mode_config.max_width = 16384;
        adev_to_drm(adev)->mode_config.max_height = 16384;
        adev_to_drm(adev)->mode_config.preferred_depth = 24;
-       /* disable prefer shadow for now due to hibernation issues */
-       adev_to_drm(adev)->mode_config.prefer_shadow = 0;
+       adev_to_drm(adev)->mode_config.prefer_shadow = 1;
        adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
        adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
 
index 802e5c7..a22b45c 100644 (file)
@@ -2693,8 +2693,11 @@ static int dce_v8_0_sw_init(void *handle)
        adev_to_drm(adev)->mode_config.max_height = 16384;
 
        adev_to_drm(adev)->mode_config.preferred_depth = 24;
-       /* disable prefer shadow for now due to hibernation issues */
-       adev_to_drm(adev)->mode_config.prefer_shadow = 0;
+       if (adev->asic_type == CHIP_HAWAII)
+               /* disable prefer shadow for now due to hibernation issues */
+               adev_to_drm(adev)->mode_config.prefer_shadow = 0;
+       else
+               adev_to_drm(adev)->mode_config.prefer_shadow = 1;
 
        adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
 
index fafbad3..a2a4dc1 100644 (file)
@@ -4846,7 +4846,7 @@ static int gfx_v10_0_sw_init(void *handle)
        case IP_VERSION(10, 3, 3):
        case IP_VERSION(10, 3, 7):
                adev->gfx.me.num_me = 1;
-               adev->gfx.me.num_pipe_per_me = 2;
+               adev->gfx.me.num_pipe_per_me = 1;
                adev->gfx.me.num_queue_per_pipe = 1;
                adev->gfx.mec.num_mec = 2;
                adev->gfx.mec.num_pipe_per_mec = 4;
index 6fd71cb..158d87e 100644 (file)
@@ -53,6 +53,7 @@
 #define GFX11_MEC_HPD_SIZE     2048
 
 #define RLCG_UCODE_LOADING_START_ADDRESS       0x00002000L
+#define RLC_PG_DELAY_3_DEFAULT_GC_11_0_1       0x1388
 
 #define regCGTT_WD_CLK_CTRL            0x5086
 #define regCGTT_WD_CLK_CTRL_BASE_IDX   1
@@ -5279,6 +5280,38 @@ static const struct amdgpu_rlc_funcs gfx_v11_0_rlc_funcs = {
        .update_spm_vmid = gfx_v11_0_update_spm_vmid,
 };
 
+static void gfx_v11_cntl_power_gating(struct amdgpu_device *adev, bool enable)
+{
+       u32 data = RREG32_SOC15(GC, 0, regRLC_PG_CNTL);
+
+       if (enable && (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG))
+               data |= RLC_PG_CNTL__GFX_POWER_GATING_ENABLE_MASK;
+       else
+               data &= ~RLC_PG_CNTL__GFX_POWER_GATING_ENABLE_MASK;
+
+       WREG32_SOC15(GC, 0, regRLC_PG_CNTL, data);
+
+       // Program RLC_PG_DELAY3 for CGPG hysteresis
+       if (enable && (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)) {
+               switch (adev->ip_versions[GC_HWIP][0]) {
+               case IP_VERSION(11, 0, 1):
+                       WREG32_SOC15(GC, 0, regRLC_PG_DELAY_3, RLC_PG_DELAY_3_DEFAULT_GC_11_0_1);
+                       break;
+               default:
+                       break;
+               }
+       }
+}
+
+static void gfx_v11_cntl_pg(struct amdgpu_device *adev, bool enable)
+{
+       amdgpu_gfx_rlc_enter_safe_mode(adev);
+
+       gfx_v11_cntl_power_gating(adev, enable);
+
+       amdgpu_gfx_rlc_exit_safe_mode(adev);
+}
+
 static int gfx_v11_0_set_powergating_state(void *handle,
                                           enum amd_powergating_state state)
 {
@@ -5293,6 +5326,11 @@ static int gfx_v11_0_set_powergating_state(void *handle,
        case IP_VERSION(11, 0, 2):
                amdgpu_gfx_off_ctrl(adev, enable);
                break;
+       case IP_VERSION(11, 0, 1):
+               gfx_v11_cntl_pg(adev, enable);
+               /* TODO: Enable this when GFXOFF is ready */
+               // amdgpu_gfx_off_ctrl(adev, enable);
+               break;
        default:
                break;
        }
@@ -5310,6 +5348,7 @@ static int gfx_v11_0_set_clockgating_state(void *handle,
 
        switch (adev->ip_versions[GC_HWIP][0]) {
        case IP_VERSION(11, 0, 0):
+       case IP_VERSION(11, 0, 1):
        case IP_VERSION(11, 0, 2):
                gfx_v11_0_update_gfx_clock_gating(adev,
                                state ==  AMD_CG_STATE_GATE);
index 9ae8cda..f513e2c 100644 (file)
@@ -419,6 +419,7 @@ static int gmc_v10_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
        uint32_t seq;
        uint16_t queried_pasid;
        bool ret;
+       u32 usec_timeout = amdgpu_sriov_vf(adev) ? SRIOV_USEC_TIMEOUT : adev->usec_timeout;
        struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
        struct amdgpu_kiq *kiq = &adev->gfx.kiq;
 
@@ -437,7 +438,7 @@ static int gmc_v10_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
 
                amdgpu_ring_commit(ring);
                spin_unlock(&adev->gfx.kiq.ring_lock);
-               r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
+               r = amdgpu_fence_wait_polling(ring, seq, usec_timeout);
                if (r < 1) {
                        dev_err(adev->dev, "wait for kiq fence error: %ld.\n", r);
                        return -ETIME;
index 22761a3..4603653 100644 (file)
@@ -896,6 +896,7 @@ static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
        uint32_t seq;
        uint16_t queried_pasid;
        bool ret;
+       u32 usec_timeout = amdgpu_sriov_vf(adev) ? SRIOV_USEC_TIMEOUT : adev->usec_timeout;
        struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
        struct amdgpu_kiq *kiq = &adev->gfx.kiq;
 
@@ -935,7 +936,7 @@ static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
 
                amdgpu_ring_commit(ring);
                spin_unlock(&adev->gfx.kiq.ring_lock);
-               r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
+               r = amdgpu_fence_wait_polling(ring, seq, usec_timeout);
                if (r < 1) {
                        dev_err(adev->dev, "wait for kiq fence error: %ld.\n", r);
                        up_read(&adev->reset_domain->sem);
@@ -1624,12 +1625,15 @@ static int gmc_v9_0_sw_init(void *handle)
                        amdgpu_vm_adjust_size(adev, 256 * 1024, 9, 3, 47);
                else
                        amdgpu_vm_adjust_size(adev, 256 * 1024, 9, 3, 48);
+               if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2))
+                       adev->gmc.translate_further = adev->vm_manager.num_level > 1;
                break;
        case IP_VERSION(9, 4, 1):
                adev->num_vmhubs = 3;
 
                /* Keep the vm size same with Vega20 */
                amdgpu_vm_adjust_size(adev, 256 * 1024, 9, 3, 48);
+               adev->gmc.translate_further = adev->vm_manager.num_level > 1;
                break;
        default:
                break;
index 39a696c..29c3484 100644 (file)
@@ -40,6 +40,156 @@ static void hdp_v5_2_flush_hdp(struct amdgpu_device *adev,
                        0);
 }
 
+static void hdp_v5_2_update_mem_power_gating(struct amdgpu_device *adev,
+                                            bool enable)
+{
+       uint32_t hdp_clk_cntl;
+       uint32_t hdp_mem_pwr_cntl;
+
+       if (!(adev->cg_flags & (AMD_CG_SUPPORT_HDP_LS |
+                               AMD_CG_SUPPORT_HDP_DS |
+                               AMD_CG_SUPPORT_HDP_SD)))
+               return;
+
+       hdp_clk_cntl = RREG32_SOC15(HDP, 0, regHDP_CLK_CNTL);
+       hdp_mem_pwr_cntl = RREG32_SOC15(HDP, 0, regHDP_MEM_POWER_CTRL);
+
+       /* Before doing clock/power mode switch, forced on MEM clock */
+       hdp_clk_cntl = REG_SET_FIELD(hdp_clk_cntl, HDP_CLK_CNTL,
+                                    ATOMIC_MEM_CLK_SOFT_OVERRIDE, 1);
+       hdp_clk_cntl = REG_SET_FIELD(hdp_clk_cntl, HDP_CLK_CNTL,
+                                    RC_MEM_CLK_SOFT_OVERRIDE, 1);
+       WREG32_SOC15(HDP, 0, regHDP_CLK_CNTL, hdp_clk_cntl);
+
+       /* disable clock and power gating before any changing */
+       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL,
+                                        ATOMIC_MEM_POWER_CTRL_EN, 0);
+       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL,
+                                        ATOMIC_MEM_POWER_LS_EN, 0);
+       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL,
+                                        ATOMIC_MEM_POWER_DS_EN, 0);
+       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL,
+                                        ATOMIC_MEM_POWER_SD_EN, 0);
+       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL,
+                                        RC_MEM_POWER_CTRL_EN, 0);
+       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL,
+                                        RC_MEM_POWER_LS_EN, 0);
+       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL,
+                                        RC_MEM_POWER_DS_EN, 0);
+       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL,
+                                        RC_MEM_POWER_SD_EN, 0);
+       WREG32_SOC15(HDP, 0, regHDP_MEM_POWER_CTRL, hdp_mem_pwr_cntl);
+
+       /* Already disabled above. The actions below are for "enabled" only */
+       if (enable) {
+               /* only one clock gating mode (LS/DS/SD) can be enabled */
+               if (adev->cg_flags & AMD_CG_SUPPORT_HDP_SD) {
+                       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl,
+                                                        HDP_MEM_POWER_CTRL,
+                                                        ATOMIC_MEM_POWER_SD_EN, 1);
+                       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl,
+                                                        HDP_MEM_POWER_CTRL,
+                                                        RC_MEM_POWER_SD_EN, 1);
+               } else if (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS) {
+                       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl,
+                                                        HDP_MEM_POWER_CTRL,
+                                                        ATOMIC_MEM_POWER_LS_EN, 1);
+                       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl,
+                                                        HDP_MEM_POWER_CTRL,
+                                                        RC_MEM_POWER_LS_EN, 1);
+               } else if (adev->cg_flags & AMD_CG_SUPPORT_HDP_DS) {
+                       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl,
+                                                        HDP_MEM_POWER_CTRL,
+                                                        ATOMIC_MEM_POWER_DS_EN, 1);
+                       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl,
+                                                        HDP_MEM_POWER_CTRL,
+                                                        RC_MEM_POWER_DS_EN, 1);
+               }
+
+               /* confirmed that ATOMIC/RC_MEM_POWER_CTRL_EN have to be set for SRAM LS/DS/SD */
+               if (adev->cg_flags & (AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_HDP_DS |
+                                     AMD_CG_SUPPORT_HDP_SD)) {
+                       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL,
+                                                        ATOMIC_MEM_POWER_CTRL_EN, 1);
+                       hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL,
+                                                        RC_MEM_POWER_CTRL_EN, 1);
+                       WREG32_SOC15(HDP, 0, regHDP_MEM_POWER_CTRL, hdp_mem_pwr_cntl);
+               }
+       }
+
+       /* disable MEM clock override after clock/power mode changing */
+       hdp_clk_cntl = REG_SET_FIELD(hdp_clk_cntl, HDP_CLK_CNTL,
+                                    ATOMIC_MEM_CLK_SOFT_OVERRIDE, 0);
+       hdp_clk_cntl = REG_SET_FIELD(hdp_clk_cntl, HDP_CLK_CNTL,
+                                    RC_MEM_CLK_SOFT_OVERRIDE, 0);
+       WREG32_SOC15(HDP, 0, regHDP_CLK_CNTL, hdp_clk_cntl);
+}
+
+static void hdp_v5_2_update_medium_grain_clock_gating(struct amdgpu_device *adev,
+                                                     bool enable)
+{
+       uint32_t hdp_clk_cntl;
+
+       if (!(adev->cg_flags & AMD_CG_SUPPORT_HDP_MGCG))
+               return;
+
+       hdp_clk_cntl = RREG32_SOC15(HDP, 0, regHDP_CLK_CNTL);
+
+       if (enable) {
+               hdp_clk_cntl &=
+                       ~(uint32_t)
+                       (HDP_CLK_CNTL__ATOMIC_MEM_CLK_SOFT_OVERRIDE_MASK |
+                        HDP_CLK_CNTL__RC_MEM_CLK_SOFT_OVERRIDE_MASK |
+                        HDP_CLK_CNTL__DBUS_CLK_SOFT_OVERRIDE_MASK |
+                        HDP_CLK_CNTL__DYN_CLK_SOFT_OVERRIDE_MASK |
+                        HDP_CLK_CNTL__XDP_REG_CLK_SOFT_OVERRIDE_MASK |
+                        HDP_CLK_CNTL__HDP_REG_CLK_SOFT_OVERRIDE_MASK);
+       } else {
+               hdp_clk_cntl |= HDP_CLK_CNTL__ATOMIC_MEM_CLK_SOFT_OVERRIDE_MASK |
+                       HDP_CLK_CNTL__RC_MEM_CLK_SOFT_OVERRIDE_MASK |
+                       HDP_CLK_CNTL__DBUS_CLK_SOFT_OVERRIDE_MASK |
+                       HDP_CLK_CNTL__DYN_CLK_SOFT_OVERRIDE_MASK |
+                       HDP_CLK_CNTL__XDP_REG_CLK_SOFT_OVERRIDE_MASK |
+                       HDP_CLK_CNTL__HDP_REG_CLK_SOFT_OVERRIDE_MASK;
+       }
+
+       WREG32_SOC15(HDP, 0, regHDP_CLK_CNTL, hdp_clk_cntl);
+}
+
+static void hdp_v5_2_get_clockgating_state(struct amdgpu_device *adev,
+                                          u64 *flags)
+{
+       uint32_t tmp;
+
+       /* AMD_CG_SUPPORT_HDP_MGCG */
+       tmp = RREG32_SOC15(HDP, 0, regHDP_CLK_CNTL);
+       if (!(tmp & (HDP_CLK_CNTL__ATOMIC_MEM_CLK_SOFT_OVERRIDE_MASK |
+                    HDP_CLK_CNTL__RC_MEM_CLK_SOFT_OVERRIDE_MASK |
+                    HDP_CLK_CNTL__DBUS_CLK_SOFT_OVERRIDE_MASK |
+                    HDP_CLK_CNTL__DYN_CLK_SOFT_OVERRIDE_MASK |
+                    HDP_CLK_CNTL__XDP_REG_CLK_SOFT_OVERRIDE_MASK |
+                    HDP_CLK_CNTL__HDP_REG_CLK_SOFT_OVERRIDE_MASK)))
+               *flags |= AMD_CG_SUPPORT_HDP_MGCG;
+
+       /* AMD_CG_SUPPORT_HDP_LS/DS/SD */
+       tmp = RREG32_SOC15(HDP, 0, regHDP_MEM_POWER_CTRL);
+       if (tmp & HDP_MEM_POWER_CTRL__ATOMIC_MEM_POWER_LS_EN_MASK)
+               *flags |= AMD_CG_SUPPORT_HDP_LS;
+       else if (tmp & HDP_MEM_POWER_CTRL__ATOMIC_MEM_POWER_DS_EN_MASK)
+               *flags |= AMD_CG_SUPPORT_HDP_DS;
+       else if (tmp & HDP_MEM_POWER_CTRL__ATOMIC_MEM_POWER_SD_EN_MASK)
+               *flags |= AMD_CG_SUPPORT_HDP_SD;
+}
+
+static void hdp_v5_2_update_clock_gating(struct amdgpu_device *adev,
+                                             bool enable)
+{
+       hdp_v5_2_update_mem_power_gating(adev, enable);
+       hdp_v5_2_update_medium_grain_clock_gating(adev, enable);
+}
+
 const struct amdgpu_hdp_funcs hdp_v5_2_funcs = {
        .flush_hdp = hdp_v5_2_flush_hdp,
+       .update_clock_gating = hdp_v5_2_update_clock_gating,
+       .get_clock_gating_state = hdp_v5_2_get_clockgating_state,
 };
index 92dc60a..085e613 100644 (file)
@@ -727,6 +727,7 @@ static const struct amd_ip_funcs ih_v6_0_ip_funcs = {
 static const struct amdgpu_ih_funcs ih_v6_0_funcs = {
        .get_wptr = ih_v6_0_get_wptr,
        .decode_iv = amdgpu_ih_decode_iv_helper,
+       .decode_iv_ts = amdgpu_ih_decode_iv_ts_helper,
        .set_rptr = ih_v6_0_set_rptr
 };
 
index cac72ce..e8058ed 100644 (file)
@@ -518,18 +518,41 @@ static u64 mmhub_v3_0_1_get_mc_fb_offset(struct amdgpu_device *adev)
 static void mmhub_v3_0_1_update_medium_grain_clock_gating(struct amdgpu_device *adev,
                                                          bool enable)
 {
-       //TODO
+       uint32_t def, data;
+
+       def = data = RREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG);
+
+       if (enable)
+               data |= MM_ATC_L2_MISC_CG__ENABLE_MASK;
+       else
+               data &= ~MM_ATC_L2_MISC_CG__ENABLE_MASK;
+
+       if (def != data)
+               WREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG, data);
 }
 
 static void mmhub_v3_0_1_update_medium_grain_light_sleep(struct amdgpu_device *adev,
                                                         bool enable)
 {
-       //TODO
+       uint32_t def, data;
+
+       def = data = RREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG);
+
+       if (enable)
+               data |= MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
+       else
+               data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
+
+       if (def != data)
+               WREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG, data);
 }
 
 static int mmhub_v3_0_1_set_clockgating(struct amdgpu_device *adev,
                                        enum amd_clockgating_state state)
 {
+       if (amdgpu_sriov_vf(adev))
+               return 0;
+
        mmhub_v3_0_1_update_medium_grain_clock_gating(adev,
                        state == AMD_CG_STATE_GATE);
        mmhub_v3_0_1_update_medium_grain_light_sleep(adev,
@@ -539,7 +562,20 @@ static int mmhub_v3_0_1_set_clockgating(struct amdgpu_device *adev,
 
 static void mmhub_v3_0_1_get_clockgating(struct amdgpu_device *adev, u64 *flags)
 {
-       //TODO
+       int data;
+
+       if (amdgpu_sriov_vf(adev))
+               *flags = 0;
+
+       data = RREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG);
+
+       /* AMD_CG_SUPPORT_MC_MGCG */
+       if (data & MM_ATC_L2_MISC_CG__ENABLE_MASK)
+               *flags |= AMD_CG_SUPPORT_MC_MGCG;
+
+       /* AMD_CG_SUPPORT_MC_LS */
+       if (data & MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK)
+               *flags |= AMD_CG_SUPPORT_MC_LS;
 }
 
 const struct amdgpu_mmhub_funcs mmhub_v3_0_1_funcs = {
index 4b5396d..eec13cb 100644 (file)
@@ -409,9 +409,11 @@ static u32 navi10_ih_get_wptr(struct amdgpu_device *adev,
        u32 wptr, tmp;
        struct amdgpu_ih_regs *ih_regs;
 
-       if (ih == &adev->irq.ih) {
+       if (ih == &adev->irq.ih || ih == &adev->irq.ih_soft) {
                /* Only ring0 supports writeback. On other rings fall back
                 * to register-based code with overflow checking below.
+                * ih_soft ring doesn't have any backing hardware registers,
+                * update wptr and return.
                 */
                wptr = le32_to_cpu(*ih->wptr_cpu);
 
@@ -483,6 +485,9 @@ static void navi10_ih_set_rptr(struct amdgpu_device *adev,
 {
        struct amdgpu_ih_regs *ih_regs;
 
+       if (ih == &adev->irq.ih_soft)
+               return;
+
        if (ih->use_doorbell) {
                /* XXX check if swapping is necessary on BE */
                *ih->rptr_cpu = ih->rptr;
index a258820..0b2ac41 100644 (file)
@@ -101,6 +101,16 @@ static int psp_v12_0_init_microcode(struct psp_context *psp)
                adev->psp.dtm_context.context.bin_desc.start_addr =
                        (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
                        le32_to_cpu(ta_hdr->dtm.offset_bytes);
+
+               if (adev->apu_flags & AMD_APU_IS_RENOIR) {
+                       adev->psp.securedisplay_context.context.bin_desc.fw_version =
+                               le32_to_cpu(ta_hdr->securedisplay.fw_version);
+                       adev->psp.securedisplay_context.context.bin_desc.size_bytes =
+                               le32_to_cpu(ta_hdr->securedisplay.size_bytes);
+                       adev->psp.securedisplay_context.context.bin_desc.start_addr =
+                               (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
+                               le32_to_cpu(ta_hdr->securedisplay.offset_bytes);
+               }
        }
 
        return 0;
index 726a5bb..a75a286 100644 (file)
@@ -20,7 +20,6 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  *
  */
-#include <linux/dev_printk.h>
 #include <drm/drm_drv.h>
 #include <linux/vmalloc.h>
 #include "amdgpu.h"
index 52816de..1ff7fc7 100644 (file)
@@ -546,8 +546,10 @@ static int soc21_common_early_init(void *handle)
        case IP_VERSION(11, 0, 0):
                adev->cg_flags = AMD_CG_SUPPORT_GFX_CGCG |
                        AMD_CG_SUPPORT_GFX_CGLS |
+#if 0
                        AMD_CG_SUPPORT_GFX_3D_CGCG |
                        AMD_CG_SUPPORT_GFX_3D_CGLS |
+#endif
                        AMD_CG_SUPPORT_GFX_MGCG |
                        AMD_CG_SUPPORT_REPEATER_FGCG |
                        AMD_CG_SUPPORT_GFX_FGCG |
@@ -575,7 +577,9 @@ static int soc21_common_early_init(void *handle)
                        AMD_CG_SUPPORT_VCN_MGCG |
                        AMD_CG_SUPPORT_JPEG_MGCG |
                        AMD_CG_SUPPORT_ATHUB_MGCG |
-                       AMD_CG_SUPPORT_ATHUB_LS;
+                       AMD_CG_SUPPORT_ATHUB_LS |
+                       AMD_CG_SUPPORT_IH_CG |
+                       AMD_CG_SUPPORT_HDP_SD;
                adev->pg_flags =
                        AMD_PG_SUPPORT_VCN |
                        AMD_PG_SUPPORT_VCN_DPG |
@@ -586,9 +590,23 @@ static int soc21_common_early_init(void *handle)
                break;
        case IP_VERSION(11, 0, 1):
                adev->cg_flags =
+                       AMD_CG_SUPPORT_GFX_CGCG |
+                       AMD_CG_SUPPORT_GFX_CGLS |
+                       AMD_CG_SUPPORT_GFX_MGCG |
+                       AMD_CG_SUPPORT_GFX_FGCG |
+                       AMD_CG_SUPPORT_REPEATER_FGCG |
+                       AMD_CG_SUPPORT_GFX_PERF_CLK |
+                       AMD_CG_SUPPORT_MC_MGCG |
+                       AMD_CG_SUPPORT_MC_LS |
+                       AMD_CG_SUPPORT_HDP_MGCG |
+                       AMD_CG_SUPPORT_HDP_LS |
+                       AMD_CG_SUPPORT_ATHUB_MGCG |
+                       AMD_CG_SUPPORT_ATHUB_LS |
+                       AMD_CG_SUPPORT_IH_CG |
                        AMD_CG_SUPPORT_VCN_MGCG |
                        AMD_CG_SUPPORT_JPEG_MGCG;
                adev->pg_flags =
+                       AMD_PG_SUPPORT_GFX_PG |
                        AMD_PG_SUPPORT_JPEG;
                adev->external_rev_id = adev->rev_id + 0x1;
                break;
@@ -683,6 +701,7 @@ static int soc21_common_set_clockgating_state(void *handle,
 
        switch (adev->ip_versions[NBIO_HWIP][0]) {
        case IP_VERSION(4, 3, 0):
+       case IP_VERSION(4, 3, 1):
                adev->nbio.funcs->update_medium_grain_clock_gating(adev,
                                state == AMD_CG_STATE_GATE);
                adev->nbio.funcs->update_medium_grain_light_sleep(adev,
@@ -690,6 +709,10 @@ static int soc21_common_set_clockgating_state(void *handle,
                adev->hdp.funcs->update_clock_gating(adev,
                                state == AMD_CG_STATE_GATE);
                break;
+       case IP_VERSION(7, 7, 0):
+               adev->hdp.funcs->update_clock_gating(adev,
+                               state == AMD_CG_STATE_GATE);
+               break;
        default:
                break;
        }
index ca14c3e..fb2d74f 100644 (file)
@@ -1115,7 +1115,7 @@ static int vcn_v4_0_start(struct amdgpu_device *adev)
  *
  * Stop VCN block with dpg mode
  */
-static int vcn_v4_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
+static void vcn_v4_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
 {
        uint32_t tmp;
 
@@ -1133,7 +1133,6 @@ static int vcn_v4_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
        /* disable dynamic power gating mode */
        WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, regUVD_POWER_STATUS), 0,
                ~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
-       return 0;
 }
 
 /**
@@ -1154,7 +1153,7 @@ static int vcn_v4_0_stop(struct amdgpu_device *adev)
                fw_shared->sq.queue_mode |= FW_QUEUE_DPG_HOLD_OFF;
 
                if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
-                       r = vcn_v4_0_stop_dpg_mode(adev, i);
+                       vcn_v4_0_stop_dpg_mode(adev, i);
                        continue;
                }
 
index cdd599a..03b7066 100644 (file)
@@ -334,9 +334,11 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
        u32 wptr, tmp;
        struct amdgpu_ih_regs *ih_regs;
 
-       if (ih == &adev->irq.ih) {
+       if (ih == &adev->irq.ih || ih == &adev->irq.ih_soft) {
                /* Only ring0 supports writeback. On other rings fall back
                 * to register-based code with overflow checking below.
+                * ih_soft ring doesn't have any backing hardware registers,
+                * update wptr and return.
                 */
                wptr = le32_to_cpu(*ih->wptr_cpu);
 
@@ -409,6 +411,9 @@ static void vega10_ih_set_rptr(struct amdgpu_device *adev,
 {
        struct amdgpu_ih_regs *ih_regs;
 
+       if (ih == &adev->irq.ih_soft)
+               return;
+
        if (ih->use_doorbell) {
                /* XXX check if swapping is necessary on BE */
                *ih->rptr_cpu = ih->rptr;
index 3b4eb82..2022ffb 100644 (file)
@@ -385,9 +385,11 @@ static u32 vega20_ih_get_wptr(struct amdgpu_device *adev,
        u32 wptr, tmp;
        struct amdgpu_ih_regs *ih_regs;
 
-       if (ih == &adev->irq.ih) {
+       if (ih == &adev->irq.ih || ih == &adev->irq.ih_soft) {
                /* Only ring0 supports writeback. On other rings fall back
                 * to register-based code with overflow checking below.
+                * ih_soft ring doesn't have any backing hardware registers,
+                * update wptr and return.
                 */
                wptr = le32_to_cpu(*ih->wptr_cpu);
 
@@ -461,6 +463,9 @@ static void vega20_ih_set_rptr(struct amdgpu_device *adev,
 {
        struct amdgpu_ih_regs *ih_regs;
 
+       if (ih == &adev->irq.ih_soft)
+               return;
+
        if (ih->use_doorbell) {
                /* XXX check if swapping is necessary on BE */
                *ih->rptr_cpu = ih->rptr;
index 2b3d8bc..dc774dd 100644 (file)
@@ -874,7 +874,7 @@ static int kfd_ioctl_wait_events(struct file *filp, struct kfd_process *p,
        err = kfd_wait_on_events(p, args->num_events,
                        (void __user *)args->events_ptr,
                        (args->wait_for_all != 0),
-                       args->timeout, &args->wait_result);
+                       &args->timeout, &args->wait_result);
 
        return err;
 }
index f585383..357298e 100644 (file)
@@ -102,13 +102,18 @@ static void kfd_device_info_set_sdma_info(struct kfd_dev *kfd)
 
        switch (sdma_version) {
        case IP_VERSION(6, 0, 0):
-       case IP_VERSION(6, 0, 1):
        case IP_VERSION(6, 0, 2):
                /* Reserve 1 for paging and 1 for gfx */
                kfd->device_info.num_reserved_sdma_queues_per_engine = 2;
                /* BIT(0)=engine-0 queue-0; BIT(1)=engine-1 queue-0; BIT(2)=engine-0 queue-1; ... */
                kfd->device_info.reserved_sdma_queues_bitmap = 0xFULL;
                break;
+       case IP_VERSION(6, 0, 1):
+               /* Reserve 1 for paging and 1 for gfx */
+               kfd->device_info.num_reserved_sdma_queues_per_engine = 2;
+               /* BIT(0)=engine-0 queue-0; BIT(1)=engine-0 queue-1; ... */
+               kfd->device_info.reserved_sdma_queues_bitmap = 0x3ULL;
+               break;
        default:
                break;
        }
index 3942a56..83e3ce9 100644 (file)
@@ -894,7 +894,8 @@ static long user_timeout_to_jiffies(uint32_t user_timeout_ms)
        return msecs_to_jiffies(user_timeout_ms) + 1;
 }
 
-static void free_waiters(uint32_t num_events, struct kfd_event_waiter *waiters)
+static void free_waiters(uint32_t num_events, struct kfd_event_waiter *waiters,
+                        bool undo_auto_reset)
 {
        uint32_t i;
 
@@ -903,6 +904,9 @@ static void free_waiters(uint32_t num_events, struct kfd_event_waiter *waiters)
                        spin_lock(&waiters[i].event->lock);
                        remove_wait_queue(&waiters[i].event->wq,
                                          &waiters[i].wait);
+                       if (undo_auto_reset && waiters[i].activated &&
+                           waiters[i].event && waiters[i].event->auto_reset)
+                               set_event(waiters[i].event);
                        spin_unlock(&waiters[i].event->lock);
                }
 
@@ -911,7 +915,7 @@ static void free_waiters(uint32_t num_events, struct kfd_event_waiter *waiters)
 
 int kfd_wait_on_events(struct kfd_process *p,
                       uint32_t num_events, void __user *data,
-                      bool all, uint32_t user_timeout_ms,
+                      bool all, uint32_t *user_timeout_ms,
                       uint32_t *wait_result)
 {
        struct kfd_event_data __user *events =
@@ -920,7 +924,7 @@ int kfd_wait_on_events(struct kfd_process *p,
        int ret = 0;
 
        struct kfd_event_waiter *event_waiters = NULL;
-       long timeout = user_timeout_to_jiffies(user_timeout_ms);
+       long timeout = user_timeout_to_jiffies(*user_timeout_ms);
 
        event_waiters = alloc_event_waiters(num_events);
        if (!event_waiters) {
@@ -970,15 +974,11 @@ int kfd_wait_on_events(struct kfd_process *p,
                }
 
                if (signal_pending(current)) {
-                       /*
-                        * This is wrong when a nonzero, non-infinite timeout
-                        * is specified. We need to use
-                        * ERESTARTSYS_RESTARTBLOCK, but struct restart_block
-                        * contains a union with data for each user and it's
-                        * in generic kernel code that I don't want to
-                        * touch yet.
-                        */
                        ret = -ERESTARTSYS;
+                       if (*user_timeout_ms != KFD_EVENT_TIMEOUT_IMMEDIATE &&
+                           *user_timeout_ms != KFD_EVENT_TIMEOUT_INFINITE)
+                               *user_timeout_ms = jiffies_to_msecs(
+                                       max(0l, timeout-1));
                        break;
                }
 
@@ -1019,7 +1019,7 @@ int kfd_wait_on_events(struct kfd_process *p,
                                               event_waiters, events);
 
 out_unlock:
-       free_waiters(num_events, event_waiters);
+       free_waiters(num_events, event_waiters, ret == -ERESTARTSYS);
        mutex_unlock(&p->event_mutex);
 out:
        if (ret)
index d03a3b9..bf610e3 100644 (file)
@@ -1317,7 +1317,7 @@ void kfd_event_free_process(struct kfd_process *p);
 int kfd_event_mmap(struct kfd_process *process, struct vm_area_struct *vma);
 int kfd_wait_on_events(struct kfd_process *p,
                       uint32_t num_events, void __user *data,
-                      bool all, uint32_t user_timeout_ms,
+                      bool all, uint32_t *user_timeout_ms,
                       uint32_t *wait_result);
 void kfd_signal_event_interrupt(u32 pasid, uint32_t partial_id,
                                uint32_t valid_id_bits);
index a67ba88..11074cc 100644 (file)
@@ -541,7 +541,6 @@ svm_range_vram_node_new(struct amdgpu_device *adev, struct svm_range *prange,
                kfree(svm_bo);
                return -ESRCH;
        }
-       svm_bo->svms = prange->svms;
        svm_bo->eviction_fence =
                amdgpu_amdkfd_fence_create(dma_fence_context_alloc(1),
                                           mm,
@@ -3273,7 +3272,6 @@ int svm_range_schedule_evict_svm_bo(struct amdgpu_amdkfd_fence *fence)
 static void svm_range_evict_svm_bo_worker(struct work_struct *work)
 {
        struct svm_range_bo *svm_bo;
-       struct kfd_process *p;
        struct mm_struct *mm;
        int r = 0;
 
@@ -3281,13 +3279,12 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work)
        if (!svm_bo_ref_unless_zero(svm_bo))
                return; /* svm_bo was freed while eviction was pending */
 
-       /* svm_range_bo_release destroys this worker thread. So during
-        * the lifetime of this thread, kfd_process and mm will be valid.
-        */
-       p = container_of(svm_bo->svms, struct kfd_process, svms);
-       mm = p->mm;
-       if (!mm)
+       if (mmget_not_zero(svm_bo->eviction_fence->mm)) {
+               mm = svm_bo->eviction_fence->mm;
+       } else {
+               svm_range_bo_unref(svm_bo);
                return;
+       }
 
        mmap_read_lock(mm);
        spin_lock(&svm_bo->list_lock);
@@ -3305,8 +3302,7 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work)
 
                mutex_lock(&prange->migrate_mutex);
                do {
-                       r = svm_migrate_vram_to_ram(prange,
-                                               svm_bo->eviction_fence->mm,
+                       r = svm_migrate_vram_to_ram(prange, mm,
                                                KFD_MIGRATE_TRIGGER_TTM_EVICTION);
                } while (!r && prange->actual_loc && --retries);
 
@@ -3324,6 +3320,7 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work)
        }
        spin_unlock(&svm_bo->list_lock);
        mmap_read_unlock(mm);
+       mmput(mm);
 
        dma_fence_signal(&svm_bo->eviction_fence->base);
 
index 9156b04..cfac13a 100644 (file)
@@ -46,7 +46,6 @@ struct svm_range_bo {
        spinlock_t                      list_lock;
        struct amdgpu_amdkfd_fence      *eviction_fence;
        struct work_struct              eviction_work;
-       struct svm_range_list           *svms;
        uint32_t                        evicting;
        struct work_struct              release_work;
 };
index 25990be..3f0a4a4 100644 (file)
@@ -1392,8 +1392,8 @@ static int kfd_build_p2p_node_entry(struct kfd_topology_device *dev,
 
 static int kfd_create_indirect_link_prop(struct kfd_topology_device *kdev, int gpu_node)
 {
+       struct kfd_iolink_properties *gpu_link, *tmp_link, *cpu_link;
        struct kfd_iolink_properties *props = NULL, *props2 = NULL;
-       struct kfd_iolink_properties *gpu_link, *cpu_link;
        struct kfd_topology_device *cpu_dev;
        int ret = 0;
        int i, num_cpu;
@@ -1416,16 +1416,19 @@ static int kfd_create_indirect_link_prop(struct kfd_topology_device *kdev, int g
                        continue;
 
                /* find CPU <-->  CPU links */
+               cpu_link = NULL;
                cpu_dev = kfd_topology_device_by_proximity_domain(i);
                if (cpu_dev) {
-                       list_for_each_entry(cpu_link,
+                       list_for_each_entry(tmp_link,
                                        &cpu_dev->io_link_props, list) {
-                               if (cpu_link->node_to == gpu_link->node_to)
+                               if (tmp_link->node_to == gpu_link->node_to) {
+                                       cpu_link = tmp_link;
                                        break;
+                               }
                        }
                }
 
-               if (cpu_link->node_to != gpu_link->node_to)
+               if (!cpu_link)
                        return -ENOMEM;
 
                /* CPU <--> CPU <--> GPU, GPU node*/
index 8660d93..5140d9c 100644 (file)
@@ -3825,8 +3825,11 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev)
        adev_to_drm(adev)->mode_config.max_height = 16384;
 
        adev_to_drm(adev)->mode_config.preferred_depth = 24;
-       /* disable prefer shadow for now due to hibernation issues */
-       adev_to_drm(adev)->mode_config.prefer_shadow = 0;
+       if (adev->asic_type == CHIP_HAWAII)
+               /* disable prefer shadow for now due to hibernation issues */
+               adev_to_drm(adev)->mode_config.prefer_shadow = 0;
+       else
+               adev_to_drm(adev)->mode_config.prefer_shadow = 1;
        /* indicates support for immediate flip */
        adev_to_drm(adev)->mode_config.async_page_flip = true;
 
@@ -4135,6 +4138,7 @@ static void register_backlight_device(struct amdgpu_display_manager *dm,
        }
 }
 
+static void amdgpu_set_panel_orientation(struct drm_connector *connector);
 
 /*
  * In this architecture, the association
@@ -4326,6 +4330,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
                                        adev_to_drm(adev)->vblank_disable_immediate = false;
                        }
                }
+               amdgpu_set_panel_orientation(&aconnector->base);
        }
 
        /* Software is initialized. Now we can register interrupt handlers. */
@@ -6684,6 +6689,10 @@ static void amdgpu_set_panel_orientation(struct drm_connector *connector)
            connector->connector_type != DRM_MODE_CONNECTOR_LVDS)
                return;
 
+       mutex_lock(&connector->dev->mode_config.mutex);
+       amdgpu_dm_connector_get_modes(connector);
+       mutex_unlock(&connector->dev->mode_config.mutex);
+
        encoder = amdgpu_dm_connector_to_encoder(connector);
        if (!encoder)
                return;
@@ -6728,8 +6737,6 @@ static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector,
                 * restored here.
                 */
                amdgpu_dm_update_freesync_caps(connector, edid);
-
-               amdgpu_set_panel_orientation(connector);
        } else {
                amdgpu_dm_connector->num_modes = 0;
        }
index b841b8b..fca7cf9 100644 (file)
@@ -660,7 +660,7 @@ static int get_plane_modifiers(struct amdgpu_device *adev, unsigned int plane_ty
                        add_gfx10_1_modifiers(adev, mods, &size, &capacity);
                break;
        case AMDGPU_FAMILY_GC_11_0_0:
-       case AMDGPU_FAMILY_GC_11_0_2:
+       case AMDGPU_FAMILY_GC_11_0_1:
                add_gfx11_modifiers(adev, mods, &size, &capacity);
                break;
        }
@@ -1412,7 +1412,7 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
                }
                break;
        case AMDGPU_FAMILY_GC_11_0_0:
-       case AMDGPU_FAMILY_GC_11_0_2:
+       case AMDGPU_FAMILY_GC_11_0_1:
                switch (AMD_FMT_MOD_GET(TILE, modifier)) {
                case AMD_FMT_MOD_TILE_GFX11_256K_R_X:
                case AMD_FMT_MOD_TILE_GFX9_64K_R_X:
index 6767fab..352e9af 100644 (file)
@@ -100,3 +100,24 @@ void convert_float_matrix(
                matrix[i] = (uint16_t)reg_value;
        }
 }
+
+static uint32_t find_gcd(uint32_t a, uint32_t b)
+{
+       uint32_t remainder = 0;
+       while (b != 0) {
+               remainder = a % b;
+               a = b;
+               b = remainder;
+       }
+       return a;
+}
+
+void reduce_fraction(uint32_t num, uint32_t den,
+               uint32_t *out_num, uint32_t *out_den)
+{
+       uint32_t gcd = 0;
+
+       gcd = find_gcd(num, den);
+       *out_num = num / gcd;
+       *out_den = den / gcd;
+}
index ade785c..81da4e6 100644 (file)
@@ -38,6 +38,9 @@ void convert_float_matrix(
        struct fixed31_32 *flt,
        uint32_t buffer_size);
 
+void reduce_fraction(uint32_t num, uint32_t den,
+               uint32_t *out_num, uint32_t *out_den);
+
 static inline unsigned int log_2(unsigned int num)
 {
        return ilog2(num);
index 4c76091..f276abb 100644 (file)
@@ -337,7 +337,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p
            break;
        }
 
-       case AMDGPU_FAMILY_GC_11_0_2: {
+       case AMDGPU_FAMILY_GC_11_0_1: {
                struct clk_mgr_dcn314 *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL);
 
                if (clk_mgr == NULL) {
@@ -397,7 +397,7 @@ void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base)
                dcn32_clk_mgr_destroy(clk_mgr);
                break;
 
-       case AMDGPU_FAMILY_GC_11_0_2:
+       case AMDGPU_FAMILY_GC_11_0_1:
                dcn314_clk_mgr_destroy(clk_mgr);
                break;
 
index 0202dc6..ca6dfd2 100644 (file)
  */
 
 #include "dccg.h"
-#include "clk_mgr_internal.h"
+#include "rn_clk_mgr.h"
 
 #include "dcn20/dcn20_clk_mgr.h"
-#include "rn_clk_mgr.h"
 #include "dml/dcn20/dcn20_fpu.h"
 
 #include "dce100/dce_clk_mgr.h"
index 2e088c5..f131995 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "clk_mgr.h"
 #include "dm_pp_smu.h"
+#include "clk_mgr_internal.h"
 
 extern struct wm_table ddr4_wm_table_gs;
 extern struct wm_table lpddr4_wm_table_gs;
index ee99974..beb025c 100644 (file)
@@ -307,16 +307,6 @@ static void dcn314_enable_pme_wa(struct clk_mgr *clk_mgr_base)
        dcn314_smu_enable_pme_wa(clk_mgr);
 }
 
-void dcn314_init_clocks(struct clk_mgr *clk_mgr)
-{
-       memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks));
-       // Assumption is that boot state always supports pstate
-       clk_mgr->clks.p_state_change_support = true;
-       clk_mgr->clks.prev_p_state_change_support = true;
-       clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN;
-       clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN;
-}
-
 bool dcn314_are_clock_states_equal(struct dc_clocks *a,
                struct dc_clocks *b)
 {
@@ -425,7 +415,7 @@ static struct wm_table lpddr5_wm_table = {
        }
 };
 
-static DpmClocks_t dummy_clocks;
+static DpmClocks314_t dummy_clocks;
 
 static struct dcn314_watermarks dummy_wms = { 0 };
 
@@ -510,7 +500,7 @@ static void dcn314_notify_wm_ranges(struct clk_mgr *clk_mgr_base)
 static void dcn314_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr,
                struct dcn314_smu_dpm_clks *smu_dpm_clks)
 {
-       DpmClocks_t *table = smu_dpm_clks->dpm_clks;
+       DpmClocks314_t *table = smu_dpm_clks->dpm_clks;
 
        if (!clk_mgr->smu_ver)
                return;
@@ -527,6 +517,26 @@ static void dcn314_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr,
        dcn314_smu_transfer_dpm_table_smu_2_dram(clk_mgr);
 }
 
+static inline bool is_valid_clock_value(uint32_t clock_value)
+{
+       return clock_value > 1 && clock_value < 100000;
+}
+
+static unsigned int convert_wck_ratio(uint8_t wck_ratio)
+{
+       switch (wck_ratio) {
+       case WCK_RATIO_1_2:
+               return 2;
+
+       case WCK_RATIO_1_4:
+               return 4;
+
+       default:
+               break;
+       }
+       return 1;
+}
+
 static uint32_t find_max_clk_value(const uint32_t clocks[], uint32_t num_clocks)
 {
        uint32_t max = 0;
@@ -540,89 +550,127 @@ static uint32_t find_max_clk_value(const uint32_t clocks[], uint32_t num_clocks)
        return max;
 }
 
-static unsigned int find_clk_for_voltage(
-               const DpmClocks_t *clock_table,
-               const uint32_t clocks[],
-               unsigned int voltage)
-{
-       int i;
-       int max_voltage = 0;
-       int clock = 0;
-
-       for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++) {
-               if (clock_table->SocVoltage[i] == voltage) {
-                       return clocks[i];
-               } else if (clock_table->SocVoltage[i] >= max_voltage &&
-                               clock_table->SocVoltage[i] < voltage) {
-                       max_voltage = clock_table->SocVoltage[i];
-                       clock = clocks[i];
-               }
-       }
-
-       ASSERT(clock);
-       return clock;
-}
-
 static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk_mgr,
                                                    struct integrated_info *bios_info,
-                                                   const DpmClocks_t *clock_table)
+                                                   const DpmClocks314_t *clock_table)
 {
-       int i, j;
        struct clk_bw_params *bw_params = clk_mgr->base.bw_params;
-       uint32_t max_dispclk = 0, max_dppclk = 0;
-
-       j = -1;
-
-       ASSERT(NUM_DF_PSTATE_LEVELS <= MAX_NUM_DPM_LVL);
-
-       /* Find lowest DPM, FCLK is filled in reverse order*/
+       struct clk_limit_table_entry def_max = bw_params->clk_table.entries[bw_params->clk_table.num_entries - 1];
+       uint32_t max_pstate = 0,  max_fclk = 0,  min_pstate = 0, max_dispclk = 0, max_dppclk = 0;
+       int i;
 
-       for (i = NUM_DF_PSTATE_LEVELS - 1; i >= 0; i--) {
-               if (clock_table->DfPstateTable[i].FClk != 0) {
-                       j = i;
-                       break;
+       /* Find highest valid fclk pstate */
+       for (i = 0; i < clock_table->NumDfPstatesEnabled; i++) {
+               if (is_valid_clock_value(clock_table->DfPstateTable[i].FClk) &&
+                   clock_table->DfPstateTable[i].FClk > max_fclk) {
+                       max_fclk = clock_table->DfPstateTable[i].FClk;
+                       max_pstate = i;
                }
        }
 
-       if (j == -1) {
-               /* clock table is all 0s, just use our own hardcode */
-               ASSERT(0);
-               return;
-       }
-
-       bw_params->clk_table.num_entries = j + 1;
+       /* We expect the table to contain at least one valid fclk entry. */
+       ASSERT(is_valid_clock_value(max_fclk));
 
-       /* dispclk and dppclk can be max at any voltage, same number of levels for both */
+       /* Dispclk and dppclk can be max at any voltage, same number of levels for both */
        if (clock_table->NumDispClkLevelsEnabled <= NUM_DISPCLK_DPM_LEVELS &&
            clock_table->NumDispClkLevelsEnabled <= NUM_DPPCLK_DPM_LEVELS) {
                max_dispclk = find_max_clk_value(clock_table->DispClocks, clock_table->NumDispClkLevelsEnabled);
                max_dppclk = find_max_clk_value(clock_table->DppClocks, clock_table->NumDispClkLevelsEnabled);
        } else {
+               /* Invalid number of entries in the table from PMFW. */
                ASSERT(0);
        }
 
-       for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) {
-               bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].FClk;
-               bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].MemClk;
-               bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].Voltage;
-               switch (clock_table->DfPstateTable[j].WckRatio) {
-               case WCK_RATIO_1_2:
-                       bw_params->clk_table.entries[i].wck_ratio = 2;
-                       break;
-               case WCK_RATIO_1_4:
-                       bw_params->clk_table.entries[i].wck_ratio = 4;
-                       break;
-               default:
-                       bw_params->clk_table.entries[i].wck_ratio = 1;
+       /* Base the clock table on dcfclk, need at least one entry regardless of pmfw table */
+       for (i = 0; i < clock_table->NumDcfClkLevelsEnabled; i++) {
+               uint32_t min_fclk = clock_table->DfPstateTable[0].FClk;
+               int j;
+
+               for (j = 1; j < clock_table->NumDfPstatesEnabled; j++) {
+                       if (is_valid_clock_value(clock_table->DfPstateTable[j].FClk) &&
+                           clock_table->DfPstateTable[j].FClk < min_fclk &&
+                           clock_table->DfPstateTable[j].Voltage <= clock_table->SocVoltage[i]) {
+                               min_fclk = clock_table->DfPstateTable[j].FClk;
+                               min_pstate = j;
+                       }
                }
-               bw_params->clk_table.entries[i].dcfclk_mhz = find_clk_for_voltage(clock_table, clock_table->DcfClocks, clock_table->DfPstateTable[j].Voltage);
-               bw_params->clk_table.entries[i].socclk_mhz = find_clk_for_voltage(clock_table, clock_table->SocClocks, clock_table->DfPstateTable[j].Voltage);
+
+               /* First search defaults for the clocks we don't read using closest lower or equal default dcfclk */
+               for (j = bw_params->clk_table.num_entries - 1; j > 0; j--)
+                       if (bw_params->clk_table.entries[j].dcfclk_mhz <= clock_table->DcfClocks[i])
+                               break;
+
+               bw_params->clk_table.entries[i].phyclk_mhz = bw_params->clk_table.entries[j].phyclk_mhz;
+               bw_params->clk_table.entries[i].phyclk_d18_mhz = bw_params->clk_table.entries[j].phyclk_d18_mhz;
+               bw_params->clk_table.entries[i].dtbclk_mhz = bw_params->clk_table.entries[j].dtbclk_mhz;
+
+               /* Now update clocks we do read */
+               bw_params->clk_table.entries[i].fclk_mhz = min_fclk;
+               bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[min_pstate].MemClk;
+               bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[min_pstate].Voltage;
+               bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[i];
+               bw_params->clk_table.entries[i].socclk_mhz = clock_table->SocClocks[i];
                bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk;
                bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk;
+               bw_params->clk_table.entries[i].wck_ratio = convert_wck_ratio(
+                       clock_table->DfPstateTable[min_pstate].WckRatio);
+       };
+
+       /* Make sure to include at least one entry at highest pstate */
+       if (max_pstate != min_pstate || i == 0) {
+               if (i > MAX_NUM_DPM_LVL - 1)
+                       i = MAX_NUM_DPM_LVL - 1;
+
+               bw_params->clk_table.entries[i].fclk_mhz = max_fclk;
+               bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[max_pstate].MemClk;
+               bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[max_pstate].Voltage;
+               bw_params->clk_table.entries[i].dcfclk_mhz = find_max_clk_value(clock_table->DcfClocks, NUM_DCFCLK_DPM_LEVELS);
+               bw_params->clk_table.entries[i].socclk_mhz = find_max_clk_value(clock_table->SocClocks, NUM_SOCCLK_DPM_LEVELS);
+               bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk;
+               bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk;
+               bw_params->clk_table.entries[i].wck_ratio = convert_wck_ratio(
+                       clock_table->DfPstateTable[max_pstate].WckRatio);
+               i++;
        }
+       bw_params->clk_table.num_entries = i--;
+
+       /* Make sure all highest clocks are included*/
+       bw_params->clk_table.entries[i].socclk_mhz = find_max_clk_value(clock_table->SocClocks, NUM_SOCCLK_DPM_LEVELS);
+       bw_params->clk_table.entries[i].dispclk_mhz = find_max_clk_value(clock_table->DispClocks, NUM_DISPCLK_DPM_LEVELS);
+       bw_params->clk_table.entries[i].dppclk_mhz = find_max_clk_value(clock_table->DppClocks, NUM_DPPCLK_DPM_LEVELS);
+       ASSERT(clock_table->DcfClocks[i] == find_max_clk_value(clock_table->DcfClocks, NUM_DCFCLK_DPM_LEVELS));
+       bw_params->clk_table.entries[i].phyclk_mhz = def_max.phyclk_mhz;
+       bw_params->clk_table.entries[i].phyclk_d18_mhz = def_max.phyclk_d18_mhz;
+       bw_params->clk_table.entries[i].dtbclk_mhz = def_max.dtbclk_mhz;
 
+       /*
+        * Set any 0 clocks to max default setting. Not an issue for
+        * power since we aren't doing switching in such case anyway
+        */
+       for (i = 0; i < bw_params->clk_table.num_entries; i++) {
+               if (!bw_params->clk_table.entries[i].fclk_mhz) {
+                       bw_params->clk_table.entries[i].fclk_mhz = def_max.fclk_mhz;
+                       bw_params->clk_table.entries[i].memclk_mhz = def_max.memclk_mhz;
+                       bw_params->clk_table.entries[i].voltage = def_max.voltage;
+               }
+               if (!bw_params->clk_table.entries[i].dcfclk_mhz)
+                       bw_params->clk_table.entries[i].dcfclk_mhz = def_max.dcfclk_mhz;
+               if (!bw_params->clk_table.entries[i].socclk_mhz)
+                       bw_params->clk_table.entries[i].socclk_mhz = def_max.socclk_mhz;
+               if (!bw_params->clk_table.entries[i].dispclk_mhz)
+                       bw_params->clk_table.entries[i].dispclk_mhz = def_max.dispclk_mhz;
+               if (!bw_params->clk_table.entries[i].dppclk_mhz)
+                       bw_params->clk_table.entries[i].dppclk_mhz = def_max.dppclk_mhz;
+               if (!bw_params->clk_table.entries[i].phyclk_mhz)
+                       bw_params->clk_table.entries[i].phyclk_mhz = def_max.phyclk_mhz;
+               if (!bw_params->clk_table.entries[i].phyclk_d18_mhz)
+                       bw_params->clk_table.entries[i].phyclk_d18_mhz = def_max.phyclk_d18_mhz;
+               if (!bw_params->clk_table.entries[i].dtbclk_mhz)
+                       bw_params->clk_table.entries[i].dtbclk_mhz = def_max.dtbclk_mhz;
+       }
+       ASSERT(bw_params->clk_table.entries[i-1].dcfclk_mhz);
        bw_params->vram_type = bios_info->memory_type;
-       bw_params->num_channels = bios_info->ma_channel_number;
+       bw_params->num_channels = bios_info->ma_channel_number ? bios_info->ma_channel_number : 4;
 
        for (i = 0; i < WM_SET_COUNT; i++) {
                bw_params->wm_table.entries[i].wm_inst = i;
@@ -641,7 +689,7 @@ static struct clk_mgr_funcs dcn314_funcs = {
        .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
        .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
        .update_clocks = dcn314_update_clocks,
-       .init_clocks = dcn314_init_clocks,
+       .init_clocks = dcn31_init_clocks,
        .enable_pme_wa = dcn314_enable_pme_wa,
        .are_clock_states_equal = dcn314_are_clock_states_equal,
        .notify_wm_ranges = dcn314_notify_wm_ranges
@@ -681,10 +729,10 @@ void dcn314_clk_mgr_construct(
        }
        ASSERT(clk_mgr->smu_wm_set.wm_set);
 
-       smu_dpm_clks.dpm_clks = (DpmClocks_t *)dm_helpers_allocate_gpu_mem(
+       smu_dpm_clks.dpm_clks = (DpmClocks314_t *)dm_helpers_allocate_gpu_mem(
                                clk_mgr->base.base.ctx,
                                DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
-                               sizeof(DpmClocks_t),
+                               sizeof(DpmClocks314_t),
                                &smu_dpm_clks.mc_address.quad_part);
 
        if (smu_dpm_clks.dpm_clks == NULL) {
@@ -729,7 +777,7 @@ void dcn314_clk_mgr_construct(
        if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
                dcn314_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks);
 
-               if (ctx->dc_bios && ctx->dc_bios->integrated_info) {
+               if (ctx->dc_bios && ctx->dc_bios->integrated_info && ctx->dc->config.use_default_clock_table == false) {
                        dcn314_clk_mgr_helper_populate_bw_params(
                                        &clk_mgr->base,
                                        ctx->dc_bios->integrated_info,
index c695a44..171f843 100644 (file)
@@ -42,7 +42,7 @@ struct clk_mgr_dcn314 {
 
 bool dcn314_are_clock_states_equal(struct dc_clocks *a,
                struct dc_clocks *b);
-void dcn314_init_clocks(struct clk_mgr *clk_mgr);
+
 void dcn314_update_clocks(struct clk_mgr *clk_mgr_base,
                        struct dc_state *context,
                        bool safe_to_lower);
index a7958dc..047d19e 100644 (file)
@@ -36,6 +36,37 @@ typedef enum {
        WCK_RATIO_MAX
 } WCK_RATIO_e;
 
+typedef struct {
+  uint32_t FClk;
+  uint32_t MemClk;
+  uint32_t Voltage;
+  uint8_t  WckRatio;
+  uint8_t  Spare[3];
+} DfPstateTable314_t;
+
+//Freq in MHz
+//Voltage in milli volts with 2 fractional bits
+typedef struct {
+  uint32_t DcfClocks[NUM_DCFCLK_DPM_LEVELS];
+  uint32_t DispClocks[NUM_DISPCLK_DPM_LEVELS];
+  uint32_t DppClocks[NUM_DPPCLK_DPM_LEVELS];
+  uint32_t SocClocks[NUM_SOCCLK_DPM_LEVELS];
+  uint32_t VClocks[NUM_VCN_DPM_LEVELS];
+  uint32_t DClocks[NUM_VCN_DPM_LEVELS];
+  uint32_t SocVoltage[NUM_SOC_VOLTAGE_LEVELS];
+  DfPstateTable314_t DfPstateTable[NUM_DF_PSTATE_LEVELS];
+
+  uint8_t  NumDcfClkLevelsEnabled;
+  uint8_t  NumDispClkLevelsEnabled; //Applies to both Dispclk and Dppclk
+  uint8_t  NumSocClkLevelsEnabled;
+  uint8_t  VcnClkLevelsEnabled;     //Applies to both Vclk and Dclk
+  uint8_t  NumDfPstatesEnabled;
+  uint8_t  spare[3];
+
+  uint32_t MinGfxClk;
+  uint32_t MaxGfxClk;
+} DpmClocks314_t;
+
 struct dcn314_watermarks {
        // Watermarks
        WatermarkRowGeneric_t WatermarkRow[WM_COUNT][NUM_WM_RANGES];
@@ -43,7 +74,7 @@ struct dcn314_watermarks {
 };
 
 struct dcn314_smu_dpm_clks {
-       DpmClocks_t *dpm_clks;
+       DpmClocks314_t *dpm_clks;
        union large_integer mc_address;
 };
 
index e42f44f..aeecca6 100644 (file)
@@ -1074,8 +1074,15 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
                struct dc_stream_state *old_stream =
                                dc->current_state->res_ctx.pipe_ctx[i].stream;
                bool should_disable = true;
-               bool pipe_split_change =
-                       context->res_ctx.pipe_ctx[i].top_pipe != dc->current_state->res_ctx.pipe_ctx[i].top_pipe;
+               bool pipe_split_change = false;
+
+               if ((context->res_ctx.pipe_ctx[i].top_pipe) &&
+                       (dc->current_state->res_ctx.pipe_ctx[i].top_pipe))
+                       pipe_split_change = context->res_ctx.pipe_ctx[i].top_pipe->pipe_idx !=
+                               dc->current_state->res_ctx.pipe_ctx[i].top_pipe->pipe_idx;
+               else
+                       pipe_split_change = context->res_ctx.pipe_ctx[i].top_pipe !=
+                               dc->current_state->res_ctx.pipe_ctx[i].top_pipe;
 
                for (j = 0; j < context->stream_count; j++) {
                        if (old_stream == context->streams[j]) {
@@ -3229,7 +3236,7 @@ static void commit_planes_for_stream(struct dc *dc,
                                odm_pipe->ttu_regs.min_ttu_vblank = MAX_TTU;
        }
 
-       if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) {
+       if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed)
                if (top_pipe_to_program &&
                        top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
                        if (should_use_dmub_lock(stream->link)) {
@@ -3247,7 +3254,6 @@ static void commit_planes_for_stream(struct dc *dc,
                                top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable(
                                                top_pipe_to_program->stream_res.tg);
                }
-       }
 
        if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
                if (dc->hwss.subvp_pipe_control_lock)
@@ -3466,7 +3472,7 @@ static void commit_planes_for_stream(struct dc *dc,
                dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
        }
 
-       if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) {
+       if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed)
                if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
                        top_pipe_to_program->stream_res.tg->funcs->wait_for_state(
                                top_pipe_to_program->stream_res.tg,
@@ -3493,21 +3499,19 @@ static void commit_planes_for_stream(struct dc *dc,
                                top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_disable(
                                        top_pipe_to_program->stream_res.tg);
                }
-       }
 
-       if (update_type != UPDATE_TYPE_FAST) {
+       if (update_type != UPDATE_TYPE_FAST)
                dc->hwss.post_unlock_program_front_end(dc, context);
 
-               /* Since phantom pipe programming is moved to post_unlock_program_front_end,
-                * move the SubVP lock to after the phantom pipes have been setup
-                */
-               if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
-                       if (dc->hwss.subvp_pipe_control_lock)
-                               dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
-               } else {
-                       if (dc->hwss.subvp_pipe_control_lock)
-                               dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, top_pipe_to_program, subvp_prev_use);
-               }
+       /* Since phantom pipe programming is moved to post_unlock_program_front_end,
+        * move the SubVP lock to after the phantom pipes have been setup
+        */
+       if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
+               if (dc->hwss.subvp_pipe_control_lock)
+                       dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
+       } else {
+               if (dc->hwss.subvp_pipe_control_lock)
+                       dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, top_pipe_to_program, subvp_prev_use);
        }
 
        // Fire manual trigger only when bottom plane is flipped
@@ -4292,7 +4296,7 @@ bool dc_is_dmub_outbox_supported(struct dc *dc)
            !dc->debug.dpia_debug.bits.disable_dpia)
                return true;
 
-       if (dc->ctx->asic_id.chip_family == AMDGPU_FAMILY_GC_11_0_2 &&
+       if (dc->ctx->asic_id.chip_family == AMDGPU_FAMILY_GC_11_0_1 &&
            !dc->debug.dpia_debug.bits.disable_dpia)
                return true;
 
@@ -4340,6 +4344,7 @@ void dc_enable_dmub_outbox(struct dc *dc)
        struct dc_context *dc_ctx = dc->ctx;
 
        dmub_enable_outbox_notification(dc_ctx->dmub_srv);
+       DC_LOG_DC("%s: dmub outbox notifications enabled\n", __func__);
 }
 
 /**
index 9e51338..66d2ae7 100644 (file)
@@ -3372,7 +3372,7 @@ bool dc_link_setup_psr(struct dc_link *link,
                switch(link->ctx->asic_id.chip_family) {
                case FAMILY_YELLOW_CARP:
                case AMDGPU_FAMILY_GC_10_3_6:
-               case AMDGPU_FAMILY_GC_11_0_2:
+               case AMDGPU_FAMILY_GC_11_0_1:
                        if(!dc->debug.disable_z10)
                                psr_context->psr_level.bits.SKIP_CRTC_DISABLE = false;
                        break;
index ffc0f1c..7dbab15 100644 (file)
@@ -169,7 +169,7 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
                if (ASICREV_IS_GC_11_0_2(asic_id.hw_internal_rev))
                        dc_version = DCN_VERSION_3_21;
                break;
-       case AMDGPU_FAMILY_GC_11_0_2:
+       case AMDGPU_FAMILY_GC_11_0_1:
                dc_version = DCN_VERSION_3_14;
                break;
        default:
index 8e1e400..5908b60 100644 (file)
@@ -47,7 +47,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.196"
+#define DC_VER "3.2.198"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
@@ -213,6 +213,7 @@ struct dc_caps {
        uint32_t cache_num_ways;
        uint16_t subvp_fw_processing_delay_us;
        uint16_t subvp_prefetch_end_to_mall_start_us;
+       uint8_t subvp_swath_height_margin_lines; // subvp start line must be aligned to 2 x swath height
        uint16_t subvp_pstate_allow_width_us;
        uint16_t subvp_vertical_int_margin_us;
        bool seamless_odm;
@@ -352,6 +353,7 @@ struct dc_config {
        bool use_pipe_ctx_sync_logic;
        bool ignore_dpref_ss;
        bool enable_mipi_converter_optimization;
+       bool use_default_clock_table;
 };
 
 enum visual_confirm {
@@ -609,6 +611,7 @@ struct dc_bounding_box_overrides {
        int percent_of_ideal_drambw;
        int dram_clock_change_latency_ns;
        int dummy_clock_change_latency_ns;
+       int fclk_clock_change_latency_ns;
        /* This forces a hard min on the DCFCLK we use
         * for DML.  Unlike the debug option for forcing
         * DCFCLK, this override affects watermark calculations
@@ -751,6 +754,7 @@ struct dc_debug_options {
        uint32_t mst_start_top_delay;
        uint8_t psr_power_use_phy_fsm;
        enum dml_hostvm_override_opts dml_hostvm_override;
+       bool dml_disallow_alternate_prefetch_modes;
        bool use_legacy_soc_bb_mechanism;
        bool exit_idle_opt_for_cursor_updates;
        bool enable_single_display_2to1_odm_policy;
index 2d61c2a..09b3045 100644 (file)
@@ -29,6 +29,7 @@
 #include "dm_helpers.h"
 #include "dc_hw_types.h"
 #include "core_types.h"
+#include "../basics/conversion.h"
 
 #define CTX dc_dmub_srv->ctx
 #define DC_LOGGER CTX->logger
@@ -275,8 +276,7 @@ void dc_dmub_srv_set_drr_manual_trigger_cmd(struct dc *dc, uint32_t tg_inst)
        union dmub_rb_cmd cmd = { 0 };
 
        cmd.drr_update.header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH;
-       // TODO: Uncomment once FW headers are promoted
-       //cmd.drr_update.header.sub_type = DMUB_CMD__FAMS_SET_MANUAL_TRIGGER;
+       cmd.drr_update.header.sub_type = DMUB_CMD__FAMS_SET_MANUAL_TRIGGER;
        cmd.drr_update.dmub_optc_state_req.tg_inst = tg_inst;
 
        cmd.drr_update.header.payload_bytes = sizeof(cmd.drr_update) - sizeof(cmd.drr_update.header);
@@ -601,6 +601,7 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
                        &cmd->fw_assisted_mclk_switch_v2.config_data.pipe_data[cmd_pipe_index];
        struct dc_crtc_timing *main_timing = &subvp_pipe->stream->timing;
        struct dc_crtc_timing *phantom_timing = &subvp_pipe->stream->mall_stream_config.paired_stream->timing;
+       uint32_t out_num, out_den;
 
        pipe_data->mode = SUBVP;
        pipe_data->pipe_config.subvp_data.pix_clk_100hz = subvp_pipe->stream->timing.pix_clk_100hz;
@@ -612,6 +613,16 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
                        main_timing->v_total - main_timing->v_front_porch - main_timing->v_addressable;
        pipe_data->pipe_config.subvp_data.mall_region_lines = phantom_timing->v_addressable;
        pipe_data->pipe_config.subvp_data.main_pipe_index = subvp_pipe->pipe_idx;
+       pipe_data->pipe_config.subvp_data.is_drr = subvp_pipe->stream->ignore_msa_timing_param;
+
+       /* Calculate the scaling factor from the src and dst height.
+        * e.g. If 3840x2160 being downscaled to 1920x1080, the scaling factor is 1/2.
+        * Reduce the fraction 1080/2160 = 1/2 for the "scaling factor"
+        */
+       reduce_fraction(subvp_pipe->stream->src.height, subvp_pipe->stream->dst.height, &out_num, &out_den);
+       // TODO: Uncomment below lines once DMCUB include headers are promoted
+       //pipe_data->pipe_config.subvp_data.scale_factor_numerator = out_num;
+       //pipe_data->pipe_config.subvp_data.scale_factor_denominator = out_den;
 
        // Prefetch lines is equal to VACTIVE + BP + VSYNC
        pipe_data->pipe_config.subvp_data.prefetch_lines =
index a0af0f6..9544abf 100644 (file)
@@ -344,6 +344,7 @@ enum dc_detect_reason {
        DETECT_REASON_HPDRX,
        DETECT_REASON_FALLBACK,
        DETECT_REASON_RETRAIN,
+       DETECT_REASON_TDR,
 };
 
 bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
index 213de8c..1653923 100644 (file)
@@ -543,9 +543,11 @@ static void dce112_get_pix_clk_dividers_helper (
                switch (pix_clk_params->color_depth) {
                case COLOR_DEPTH_101010:
                        actual_pixel_clock_100hz = (actual_pixel_clock_100hz * 5) >> 2;
+                       actual_pixel_clock_100hz -= actual_pixel_clock_100hz % 10;
                        break;
                case COLOR_DEPTH_121212:
                        actual_pixel_clock_100hz = (actual_pixel_clock_100hz * 6) >> 2;
+                       actual_pixel_clock_100hz -= actual_pixel_clock_100hz % 10;
                        break;
                case COLOR_DEPTH_161616:
                        actual_pixel_clock_100hz = actual_pixel_clock_100hz * 2;
index d4a6504..db7ca4b 100644 (file)
@@ -361,8 +361,6 @@ void dpp1_cnv_setup (
                select = INPUT_CSC_SELECT_ICSC;
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
-               pixel_format = 22;
-               break;
        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
                pixel_format = 26; /* ARGB16161616_UNORM */
                break;
index b54c124..564e061 100644 (file)
@@ -278,9 +278,6 @@ void hubp1_program_pixel_format(
                                SURFACE_PIXEL_FORMAT, 10);
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
-               REG_UPDATE(DCSURF_SURFACE_CONFIG,
-                               SURFACE_PIXEL_FORMAT, 22);
-               break;
        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: /*we use crossbar already*/
                REG_UPDATE(DCSURF_SURFACE_CONFIG,
                                SURFACE_PIXEL_FORMAT, 26); /* ARGB16161616_UNORM */
index bed7837..5b5d952 100644 (file)
@@ -110,6 +110,7 @@ void dcn10_lock_all_pipes(struct dc *dc,
                 */
                if (pipe_ctx->top_pipe ||
                    !pipe_ctx->stream ||
+                   !pipe_ctx->plane_state ||
                    !tg->funcs->is_tg_enabled(tg))
                        continue;
 
index 7699743..8e93840 100644 (file)
@@ -131,6 +131,12 @@ struct mpcc *mpc1_get_mpcc_for_dpp(struct mpc_tree *tree, int dpp_id)
        while (tmp_mpcc != NULL) {
                if (tmp_mpcc->dpp_id == dpp_id)
                        return tmp_mpcc;
+
+               /* avoid circular linked list */
+               ASSERT(tmp_mpcc != tmp_mpcc->mpcc_bot);
+               if (tmp_mpcc == tmp_mpcc->mpcc_bot)
+                       break;
+
                tmp_mpcc = tmp_mpcc->mpcc_bot;
        }
        return NULL;
index e1a9a45..3fc300c 100644 (file)
@@ -465,6 +465,11 @@ void optc1_enable_optc_clock(struct timing_generator *optc, bool enable)
                                OTG_CLOCK_ON, 1,
                                1, 1000);
        } else  {
+
+               //last chance to clear underflow, otherwise, it will always there due to clock is off.
+               if (optc->funcs->is_optc_underflow_occurred(optc) == true)
+                       optc->funcs->clear_optc_underflow(optc);
+
                REG_UPDATE_2(OTG_CLOCK_CONTROL,
                                OTG_CLOCK_GATE_DIS, 0,
                                OTG_CLOCK_EN, 0);
index ea1f14a..eaa7032 100644 (file)
@@ -166,8 +166,6 @@ static void dpp2_cnv_setup (
                select = DCN2_ICSC_SELECT_ICSC_A;
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
-               pixel_format = 22;
-               break;
        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
                pixel_format = 26; /* ARGB16161616_UNORM */
                break;
index 936af65..9570c21 100644 (file)
@@ -463,9 +463,6 @@ void hubp2_program_pixel_format(
                                SURFACE_PIXEL_FORMAT, 10);
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
-               REG_UPDATE(DCSURF_SURFACE_CONFIG,
-                               SURFACE_PIXEL_FORMAT, 22);
-               break;
        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: /*we use crossbar already*/
                REG_UPDATE(DCSURF_SURFACE_CONFIG,
                                SURFACE_PIXEL_FORMAT, 26); /* ARGB16161616_UNORM */
index 3d307dd..116f67a 100644 (file)
@@ -531,6 +531,12 @@ static struct mpcc *mpc2_get_mpcc_for_dpp(struct mpc_tree *tree, int dpp_id)
        while (tmp_mpcc != NULL) {
                if (tmp_mpcc->dpp_id == 0xf || tmp_mpcc->dpp_id == dpp_id)
                        return tmp_mpcc;
+
+               /* avoid circular linked list */
+               ASSERT(tmp_mpcc != tmp_mpcc->mpcc_bot);
+               if (tmp_mpcc == tmp_mpcc->mpcc_bot)
+                       break;
+
                tmp_mpcc = tmp_mpcc->mpcc_bot;
        }
        return NULL;
index c5e200d..5752271 100644 (file)
@@ -67,9 +67,15 @@ static uint32_t convert_and_clamp(
 void dcn21_dchvm_init(struct hubbub *hubbub)
 {
        struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
-       uint32_t riommu_active;
+       uint32_t riommu_active, prefetch_done;
        int i;
 
+       REG_GET(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, &prefetch_done);
+
+       if (prefetch_done) {
+               hubbub->riommu_active = true;
+               return;
+       }
        //Init DCHVM block
        REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1);
 
index 77b00f8..4a668d6 100644 (file)
@@ -244,8 +244,6 @@ void dpp3_cnv_setup (
                select = INPUT_CSC_SELECT_ICSC;
                break;
        case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
-               pixel_format = 22;
-               break;
        case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
                pixel_format = 26; /* ARGB16161616_UNORM */
                break;
index 6a4dcaf..dc3e8df 100644 (file)
@@ -86,7 +86,7 @@ bool hubp3_program_surface_flip_and_addr(
                        VMID, address->vmid);
 
        if (address->type == PLN_ADDR_TYPE_GRPH_STEREO) {
-               REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x1);
+               REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0);
                REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x1);
 
        } else {
index 0a67f8a..d970766 100644 (file)
@@ -372,7 +372,7 @@ static struct stream_encoder *dcn303_stream_encoder_create(enum engine_id eng_id
        int afmt_inst;
 
        /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
-       if (eng_id <= ENGINE_ID_DIGE) {
+       if (eng_id <= ENGINE_ID_DIGB) {
                vpg_inst = eng_id;
                afmt_inst = eng_id;
        } else
index 7c77c71..82c3b3a 100644 (file)
        SE_SF(DP_SYM32_ENC0_DP_SYM32_ENC_SDP_AUDIO_CONTROL0, AIP_ENABLE, mask_sh),\
        SE_SF(DP_SYM32_ENC0_DP_SYM32_ENC_SDP_AUDIO_CONTROL0, ACM_ENABLE, mask_sh),\
        SE_SF(DP_SYM32_ENC0_DP_SYM32_ENC_VID_CRC_CONTROL, CRC_ENABLE, mask_sh),\
-       SE_SF(DP_SYM32_ENC0_DP_SYM32_ENC_VID_CRC_CONTROL, CRC_CONT_MODE_ENABLE, mask_sh)
+       SE_SF(DP_SYM32_ENC0_DP_SYM32_ENC_VID_CRC_CONTROL, CRC_CONT_MODE_ENABLE, mask_sh),\
+       SE_SF(DP_SYM32_ENC0_DP_SYM32_ENC_HBLANK_CONTROL, HBLANK_MINIMUM_SYMBOL_WIDTH, mask_sh)
 
 
 #define DCN3_1_HPO_DP_STREAM_ENC_REG_FIELD_LIST(type) \
index 468a893..aedff18 100644 (file)
@@ -2153,7 +2153,7 @@ static bool dcn31_resource_construct(
                pool->base.usb4_dpia_count = 4;
        }
 
-       if (dc->ctx->asic_id.chip_family == AMDGPU_FAMILY_GC_11_0_2)
+       if (dc->ctx->asic_id.chip_family == AMDGPU_FAMILY_GC_11_0_1)
                pool->base.usb4_dpia_count = 4;
 
        /* Audio, Stream Encoders including HPO and virtual, MPC 3D LUTs */
index 41f8ec9..9014365 100644 (file)
@@ -32,7 +32,6 @@
        container_of(pool, struct dcn31_resource_pool, base)
 
 extern struct _vcs_dpi_ip_params_st dcn3_1_ip;
-extern struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc;
 
 struct dcn31_resource_pool {
        struct resource_pool base;
index e3b5a95..702c28c 100644 (file)
 DCN314 = dcn314_resource.o dcn314_hwseq.o dcn314_init.o \
                dcn314_dio_stream_encoder.o dcn314_dccg.o dcn314_optc.o
 
-ifdef CONFIG_X86
-CFLAGS_$(AMDDALPATH)/dc/dcn314/dcn314_resource.o := -mhard-float -msse
-endif
-
-ifdef CONFIG_PPC64
-CFLAGS_$(AMDDALPATH)/dc/dcn314/dcn314_resource.o := -mhard-float -maltivec
-endif
-
-ifdef CONFIG_CC_IS_GCC
-ifeq ($(call cc-ifversion, -lt, 0701, y), y)
-IS_OLD_GCC = 1
-endif
-endif
-
-ifdef CONFIG_X86
-ifdef IS_OLD_GCC
-# Stack alignment mismatch, proceed with caution.
-# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3
-# (8B stack alignment).
-CFLAGS_$(AMDDALPATH)/dc/dcn314/dcn314_resource.o += -mpreferred-stack-boundary=4
-else
-CFLAGS_$(AMDDALPATH)/dc/dcn314/dcn314_resource.o += -msse2
-endif
-endif
-
 AMD_DAL_DCN314 = $(addprefix $(AMDDALPATH)/dc/dcn314/,$(DCN314))
 
 AMD_DISPLAY_FILES += $(AMD_DAL_DCN314)
index 755c715..39931d4 100644 (file)
@@ -343,7 +343,10 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
 {
        struct dc_stream_state *stream = pipe_ctx->stream;
        unsigned int odm_combine_factor = 0;
+       struct dc *dc = pipe_ctx->stream->ctx->dc;
+       bool two_pix_per_container = false;
 
+       two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing);
        odm_combine_factor = get_odm_config(pipe_ctx, NULL);
 
        if (is_dp_128b_132b_signal(pipe_ctx)) {
@@ -355,16 +358,13 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
                else
                        *k2_div = PIXEL_RATE_DIV_BY_4;
        } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
-               if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
+               if (two_pix_per_container) {
                        *k1_div = PIXEL_RATE_DIV_BY_1;
                        *k2_div = PIXEL_RATE_DIV_BY_2;
-               } else if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422) {
-                       *k1_div = PIXEL_RATE_DIV_BY_2;
-                       *k2_div = PIXEL_RATE_DIV_BY_2;
                } else {
-                       if (odm_combine_factor == 1)
-                               *k2_div = PIXEL_RATE_DIV_BY_4;
-                       else if (odm_combine_factor == 2)
+                       *k1_div = PIXEL_RATE_DIV_BY_1;
+                       *k2_div = PIXEL_RATE_DIV_BY_4;
+                       if ((odm_combine_factor == 2) || dc->debug.enable_dp_dig_pixel_rate_div_policy)
                                *k2_div = PIXEL_RATE_DIV_BY_2;
                }
        }
@@ -374,3 +374,31 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
 
        return odm_combine_factor;
 }
+
+void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx)
+{
+       uint32_t pix_per_cycle = 1;
+       uint32_t odm_combine_factor = 1;
+
+       if (!pipe_ctx || !pipe_ctx->stream || !pipe_ctx->stream_res.stream_enc)
+               return;
+
+       odm_combine_factor = get_odm_config(pipe_ctx, NULL);
+       if (optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing) || odm_combine_factor > 1
+               || dcn314_is_dp_dig_pixel_rate_div_policy(pipe_ctx))
+               pix_per_cycle = 2;
+
+       if (pipe_ctx->stream_res.stream_enc->funcs->set_input_mode)
+               pipe_ctx->stream_res.stream_enc->funcs->set_input_mode(pipe_ctx->stream_res.stream_enc,
+                               pix_per_cycle);
+}
+
+bool dcn314_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx)
+{
+       struct dc *dc = pipe_ctx->stream->ctx->dc;
+
+       if (dc_is_dp_signal(pipe_ctx->stream->signal) && !is_dp_128b_132b_signal(pipe_ctx) &&
+               dc->debug.enable_dp_dig_pixel_rate_div_policy)
+               return true;
+       return false;
+}
index be0f5e4..d014580 100644 (file)
@@ -39,4 +39,8 @@ void dcn314_enable_power_gating_plane(struct dce_hwseq *hws, bool enable);
 
 unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div);
 
+void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx);
+
+bool dcn314_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx);
+
 #endif /* __DC_HWSS_DCN314_H__ */
index b9debeb..fcf67eb 100644 (file)
@@ -145,6 +145,8 @@ static const struct hwseq_private_funcs dcn314_private_funcs = {
        .set_shaper_3dlut = dcn20_set_shaper_3dlut,
        .setup_hpo_hw_control = dcn31_setup_hpo_hw_control,
        .calculate_dccg_k1_k2_values = dcn314_calculate_dccg_k1_k2_values,
+       .set_pixels_per_cycle = dcn314_set_pixels_per_cycle,
+       .is_dp_dig_pixel_rate_div_policy = dcn314_is_dp_dig_pixel_rate_div_policy,
 };
 
 void dcn314_hw_sequencer_construct(struct dc *dc)
index 63861cd..85f3220 100644 (file)
@@ -70,6 +70,7 @@
 #include "dce110/dce110_resource.h"
 #include "dml/display_mode_vba.h"
 #include "dml/dcn31/dcn31_fpu.h"
+#include "dml/dcn314/dcn314_fpu.h"
 #include "dcn314/dcn314_dccg.h"
 #include "dcn10/dcn10_resource.h"
 #include "dcn31/dcn31_panel_cntl.h"
@@ -132,155 +133,6 @@ static const struct IP_BASE DCN_BASE = { { { { 0x00000012, 0x000000C0, 0x000034C
 
 #define DC_LOGGER_INIT(logger)
 
-#define DCN3_14_DEFAULT_DET_SIZE 384
-#define DCN3_14_MAX_DET_SIZE 384
-#define DCN3_14_MIN_COMPBUF_SIZE_KB 128
-#define DCN3_14_CRB_SEGMENT_SIZE_KB 64
-struct _vcs_dpi_ip_params_st dcn3_14_ip = {
-       .VBlankNomDefaultUS = 668,
-       .gpuvm_enable = 1,
-       .gpuvm_max_page_table_levels = 1,
-       .hostvm_enable = 1,
-       .hostvm_max_page_table_levels = 2,
-       .rob_buffer_size_kbytes = 64,
-       .det_buffer_size_kbytes = DCN3_14_DEFAULT_DET_SIZE,
-       .config_return_buffer_size_in_kbytes = 1792,
-       .compressed_buffer_segment_size_in_kbytes = 64,
-       .meta_fifo_size_in_kentries = 32,
-       .zero_size_buffer_entries = 512,
-       .compbuf_reserved_space_64b = 256,
-       .compbuf_reserved_space_zs = 64,
-       .dpp_output_buffer_pixels = 2560,
-       .opp_output_buffer_lines = 1,
-       .pixel_chunk_size_kbytes = 8,
-       .meta_chunk_size_kbytes = 2,
-       .min_meta_chunk_size_bytes = 256,
-       .writeback_chunk_size_kbytes = 8,
-       .ptoi_supported = false,
-       .num_dsc = 4,
-       .maximum_dsc_bits_per_component = 10,
-       .dsc422_native_support = false,
-       .is_line_buffer_bpp_fixed = true,
-       .line_buffer_fixed_bpp = 48,
-       .line_buffer_size_bits = 789504,
-       .max_line_buffer_lines = 12,
-       .writeback_interface_buffer_size_kbytes = 90,
-       .max_num_dpp = 4,
-       .max_num_otg = 4,
-       .max_num_hdmi_frl_outputs = 1,
-       .max_num_wb = 1,
-       .max_dchub_pscl_bw_pix_per_clk = 4,
-       .max_pscl_lb_bw_pix_per_clk = 2,
-       .max_lb_vscl_bw_pix_per_clk = 4,
-       .max_vscl_hscl_bw_pix_per_clk = 4,
-       .max_hscl_ratio = 6,
-       .max_vscl_ratio = 6,
-       .max_hscl_taps = 8,
-       .max_vscl_taps = 8,
-       .dpte_buffer_size_in_pte_reqs_luma = 64,
-       .dpte_buffer_size_in_pte_reqs_chroma = 34,
-       .dispclk_ramp_margin_percent = 1,
-       .max_inter_dcn_tile_repeaters = 8,
-       .cursor_buffer_size = 16,
-       .cursor_chunk_size = 2,
-       .writeback_line_buffer_buffer_size = 0,
-       .writeback_min_hscl_ratio = 1,
-       .writeback_min_vscl_ratio = 1,
-       .writeback_max_hscl_ratio = 1,
-       .writeback_max_vscl_ratio = 1,
-       .writeback_max_hscl_taps = 1,
-       .writeback_max_vscl_taps = 1,
-       .dppclk_delay_subtotal = 46,
-       .dppclk_delay_scl = 50,
-       .dppclk_delay_scl_lb_only = 16,
-       .dppclk_delay_cnvc_formatter = 27,
-       .dppclk_delay_cnvc_cursor = 6,
-       .dispclk_delay_subtotal = 119,
-       .dynamic_metadata_vm_enabled = false,
-       .odm_combine_4to1_supported = false,
-       .dcc_supported = true,
-};
-
-struct _vcs_dpi_soc_bounding_box_st dcn3_14_soc = {
-               /*TODO: correct dispclk/dppclk voltage level determination*/
-       .clock_limits = {
-               {
-                       .state = 0,
-                       .dispclk_mhz = 1200.0,
-                       .dppclk_mhz = 1200.0,
-                       .phyclk_mhz = 600.0,
-                       .phyclk_d18_mhz = 667.0,
-                       .dscclk_mhz = 186.0,
-                       .dtbclk_mhz = 625.0,
-               },
-               {
-                       .state = 1,
-                       .dispclk_mhz = 1200.0,
-                       .dppclk_mhz = 1200.0,
-                       .phyclk_mhz = 810.0,
-                       .phyclk_d18_mhz = 667.0,
-                       .dscclk_mhz = 209.0,
-                       .dtbclk_mhz = 625.0,
-               },
-               {
-                       .state = 2,
-                       .dispclk_mhz = 1200.0,
-                       .dppclk_mhz = 1200.0,
-                       .phyclk_mhz = 810.0,
-                       .phyclk_d18_mhz = 667.0,
-                       .dscclk_mhz = 209.0,
-                       .dtbclk_mhz = 625.0,
-               },
-               {
-                       .state = 3,
-                       .dispclk_mhz = 1200.0,
-                       .dppclk_mhz = 1200.0,
-                       .phyclk_mhz = 810.0,
-                       .phyclk_d18_mhz = 667.0,
-                       .dscclk_mhz = 371.0,
-                       .dtbclk_mhz = 625.0,
-               },
-               {
-                       .state = 4,
-                       .dispclk_mhz = 1200.0,
-                       .dppclk_mhz = 1200.0,
-                       .phyclk_mhz = 810.0,
-                       .phyclk_d18_mhz = 667.0,
-                       .dscclk_mhz = 417.0,
-                       .dtbclk_mhz = 625.0,
-               },
-       },
-       .num_states = 5,
-       .sr_exit_time_us = 9.0,
-       .sr_enter_plus_exit_time_us = 11.0,
-       .sr_exit_z8_time_us = 442.0,
-       .sr_enter_plus_exit_z8_time_us = 560.0,
-       .writeback_latency_us = 12.0,
-       .dram_channel_width_bytes = 4,
-       .round_trip_ping_latency_dcfclk_cycles = 106,
-       .urgent_latency_pixel_data_only_us = 4.0,
-       .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
-       .urgent_latency_vm_data_only_us = 4.0,
-       .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
-       .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
-       .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
-       .pct_ideal_sdp_bw_after_urgent = 80.0,
-       .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0,
-       .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
-       .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
-       .max_avg_sdp_bw_use_normal_percent = 60.0,
-       .max_avg_dram_bw_use_normal_percent = 60.0,
-       .fabric_datapath_to_dcn_data_return_bytes = 32,
-       .return_bus_width_bytes = 64,
-       .downspread_percent = 0.38,
-       .dcn_downspread_percent = 0.5,
-       .gpuvm_min_page_size_bytes = 4096,
-       .hostvm_min_page_size_bytes = 4096,
-       .do_urgent_latency_adjustment = false,
-       .urgent_latency_adjustment_fabric_clock_component_us = 0,
-       .urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
-};
-
 enum dcn31_clk_src_array_id {
        DCN31_CLK_SRC_PLL0,
        DCN31_CLK_SRC_PLL1,
@@ -1402,7 +1254,7 @@ static struct stream_encoder *dcn314_stream_encoder_create(
        int afmt_inst;
 
        /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
-       if (eng_id <= ENGINE_ID_DIGF) {
+       if (eng_id < ENGINE_ID_DIGF) {
                vpg_inst = eng_id;
                afmt_inst = eng_id;
        } else
@@ -1447,7 +1299,8 @@ static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create(
         * VPG[8] -> HPO_DP[2]
         * VPG[9] -> HPO_DP[3]
         */
-       vpg_inst = hpo_dp_inst + 6;
+       //Uses offset index 5-8, but actually maps to vpg_inst 6-9
+       vpg_inst = hpo_dp_inst + 5;
 
        /* Mapping of APG register blocks to HPO DP block instance:
         * APG[0] -> HPO_DP[0]
@@ -1793,109 +1646,16 @@ static struct clock_source *dcn31_clock_source_create(
        return NULL;
 }
 
-static bool is_dual_plane(enum surface_pixel_format format)
-{
-       return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
-}
-
 static int dcn314_populate_dml_pipes_from_context(
        struct dc *dc, struct dc_state *context,
        display_e2e_pipe_params_st *pipes,
        bool fast_validate)
 {
-       int i, pipe_cnt;
-       struct resource_context *res_ctx = &context->res_ctx;
-       struct pipe_ctx *pipe;
-       bool upscaled = false;
-
-       dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
-
-       for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
-               struct dc_crtc_timing *timing;
-
-               if (!res_ctx->pipe_ctx[i].stream)
-                       continue;
-               pipe = &res_ctx->pipe_ctx[i];
-               timing = &pipe->stream->timing;
-
-               if (dc_extended_blank_supported(dc) && pipe->stream->adjust.v_total_max == pipe->stream->adjust.v_total_min
-                       && pipe->stream->adjust.v_total_min > timing->v_total)
-                       pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min;
-
-               if (pipe->plane_state &&
-                               (pipe->plane_state->src_rect.height < pipe->plane_state->dst_rect.height ||
-                               pipe->plane_state->src_rect.width < pipe->plane_state->dst_rect.width))
-                       upscaled = true;
-
-               /*
-                * Immediate flip can be set dynamically after enabling the plane.
-                * We need to require support for immediate flip or underflow can be
-                * intermittently experienced depending on peak b/w requirements.
-                */
-               pipes[pipe_cnt].pipe.src.immediate_flip = true;
-
-               pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
-               pipes[pipe_cnt].pipe.src.hostvm = dc->res_pool->hubbub->riommu_active;
-               pipes[pipe_cnt].pipe.src.gpuvm = true;
-               pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
-               pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0;
-               pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
-               pipes[pipe_cnt].pipe.src.dcc_rate = 3;
-               pipes[pipe_cnt].dout.dsc_input_bpc = 0;
-
-               if (pipes[pipe_cnt].dout.dsc_enable) {
-                       switch (timing->display_color_depth) {
-                       case COLOR_DEPTH_888:
-                               pipes[pipe_cnt].dout.dsc_input_bpc = 8;
-                               break;
-                       case COLOR_DEPTH_101010:
-                               pipes[pipe_cnt].dout.dsc_input_bpc = 10;
-                               break;
-                       case COLOR_DEPTH_121212:
-                               pipes[pipe_cnt].dout.dsc_input_bpc = 12;
-                               break;
-                       default:
-                               ASSERT(0);
-                               break;
-                       }
-               }
-
-               pipe_cnt++;
-       }
-       context->bw_ctx.dml.ip.det_buffer_size_kbytes = DCN3_14_DEFAULT_DET_SIZE;
-
-       dc->config.enable_4to1MPC = false;
-       if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
-               if (is_dual_plane(pipe->plane_state->format)
-                               && pipe->plane_state->src_rect.width <= 1920 && pipe->plane_state->src_rect.height <= 1080) {
-                       dc->config.enable_4to1MPC = true;
-               } else if (!is_dual_plane(pipe->plane_state->format) && pipe->plane_state->src_rect.width <= 5120) {
-                       /* Limit to 5k max to avoid forced pipe split when there is not enough detile for swath */
-                       context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
-                       pipes[0].pipe.src.unbounded_req_mode = true;
-               }
-       } else if (context->stream_count >= dc->debug.crb_alloc_policy_min_disp_count
-                       && dc->debug.crb_alloc_policy > DET_SIZE_DEFAULT) {
-               context->bw_ctx.dml.ip.det_buffer_size_kbytes = dc->debug.crb_alloc_policy * 64;
-       } else if (context->stream_count >= 3 && upscaled) {
-               context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
-       }
-
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-
-               if (!pipe->stream)
-                       continue;
+       int pipe_cnt;
 
-               if (pipe->stream->signal == SIGNAL_TYPE_EDP && dc->debug.seamless_boot_odm_combine &&
-                               pipe->stream->apply_seamless_boot_optimization) {
-
-                       if (pipe->stream->apply_boot_odm_mode == dm_odm_combine_policy_2to1) {
-                               context->bw_ctx.dml.vba.ODMCombinePolicy = dm_odm_combine_policy_2to1;
-                               break;
-                       }
-               }
-       }
+       DC_FP_START();
+       pipe_cnt = dcn314_populate_dml_pipes_from_context_fpu(dc, context, pipes, fast_validate);
+       DC_FP_END();
 
        return pipe_cnt;
 }
@@ -1906,88 +1666,9 @@ static struct dc_cap_funcs cap_funcs = {
 
 static void dcn314_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
 {
-       struct clk_limit_table *clk_table = &bw_params->clk_table;
-       struct _vcs_dpi_voltage_scaling_st *clock_tmp = dcn3_14_soc._clock_tmp;
-       unsigned int i, closest_clk_lvl;
-       int max_dispclk_mhz = 0, max_dppclk_mhz = 0;
-       int j;
-
-       // Default clock levels are used for diags, which may lead to overclocking.
-       if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
-
-               dcn3_14_ip.max_num_otg = dc->res_pool->res_cap->num_timing_generator;
-               dcn3_14_ip.max_num_dpp = dc->res_pool->pipe_count;
-
-               if (bw_params->num_channels > 0)
-                       dcn3_14_soc.num_chans = bw_params->num_channels;
-
-               ASSERT(dcn3_14_soc.num_chans);
-               ASSERT(clk_table->num_entries);
-
-               /* Prepass to find max clocks independent of voltage level. */
-               for (i = 0; i < clk_table->num_entries; ++i) {
-                       if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz)
-                               max_dispclk_mhz = clk_table->entries[i].dispclk_mhz;
-                       if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz)
-                               max_dppclk_mhz = clk_table->entries[i].dppclk_mhz;
-               }
-
-               for (i = 0; i < clk_table->num_entries; i++) {
-                       /* loop backwards*/
-                       for (closest_clk_lvl = 0, j = dcn3_14_soc.num_states - 1; j >= 0; j--) {
-                               if ((unsigned int) dcn3_14_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
-                                       closest_clk_lvl = j;
-                                       break;
-                               }
-                       }
-                       if (clk_table->num_entries == 1) {
-                               /*smu gives one DPM level, let's take the highest one*/
-                               closest_clk_lvl = dcn3_14_soc.num_states - 1;
-                       }
-
-                       clock_tmp[i].state = i;
-
-                       /* Clocks dependent on voltage level. */
-                       clock_tmp[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
-                       if (clk_table->num_entries == 1 &&
-                               clock_tmp[i].dcfclk_mhz < dcn3_14_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) {
-                               /*SMU fix not released yet*/
-                               clock_tmp[i].dcfclk_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].dcfclk_mhz;
-                       }
-                       clock_tmp[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
-                       clock_tmp[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
-
-                       if (clk_table->entries[i].memclk_mhz && clk_table->entries[i].wck_ratio)
-                               clock_tmp[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio;
-
-                       /* Clocks independent of voltage level. */
-                       clock_tmp[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz :
-                               dcn3_14_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
-
-                       clock_tmp[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz :
-                               dcn3_14_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
-
-                       clock_tmp[i].dram_bw_per_chan_gbps = dcn3_14_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
-                       clock_tmp[i].dscclk_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
-                       clock_tmp[i].dtbclk_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
-                       clock_tmp[i].phyclk_d18_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
-                       clock_tmp[i].phyclk_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
-               }
-               for (i = 0; i < clk_table->num_entries; i++)
-                       dcn3_14_soc.clock_limits[i] = clock_tmp[i];
-               if (clk_table->num_entries)
-                       dcn3_14_soc.num_states = clk_table->num_entries;
-       }
-
-       if (max_dispclk_mhz) {
-               dcn3_14_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
-               dc->dml.soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
-       }
-
-       if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
-               dml_init_instance(&dc->dml, &dcn3_14_soc, &dcn3_14_ip, DML_PROJECT_DCN31);
-       else
-               dml_init_instance(&dc->dml, &dcn3_14_soc, &dcn3_14_ip, DML_PROJECT_DCN31_FPGA);
+       DC_FP_START();
+       dcn314_update_bw_bounding_box_fpu(dc, bw_params);
+       DC_FP_END();
 }
 
 static struct resource_funcs dcn314_res_pool_funcs = {
index c411088..0dd3153 100644 (file)
@@ -29,6 +29,9 @@
 
 #include "core_types.h"
 
+extern struct _vcs_dpi_ip_params_st dcn3_14_ip;
+extern struct _vcs_dpi_soc_bounding_box_st dcn3_14_soc;
+
 #define TO_DCN314_RES_POOL(pool)\
        container_of(pool, struct dcn314_resource_pool, base)
 
index 39929fa..22849ea 100644 (file)
@@ -32,7 +32,6 @@
        container_of(pool, struct dcn315_resource_pool, base)
 
 extern struct _vcs_dpi_ip_params_st dcn3_15_ip;
-extern struct _vcs_dpi_ip_params_st dcn3_15_soc;
 
 struct dcn315_resource_pool {
        struct resource_pool base;
index 0dc5a6c..aba6d63 100644 (file)
@@ -32,7 +32,6 @@
        container_of(pool, struct dcn316_resource_pool, base)
 
 extern struct _vcs_dpi_ip_params_st dcn3_16_ip;
-extern struct _vcs_dpi_ip_params_st dcn3_16_soc;
 
 struct dcn316_resource_pool {
        struct resource_pool base;
index d38341f..ebd3945 100644 (file)
@@ -250,6 +250,7 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c
        uint32_t total_lines = 0;
        uint32_t lines_per_way = 0;
        uint32_t num_ways = 0;
+       uint32_t prev_addr_low = 0;
 
        for (i = 0; i < ctx->stream_count; i++) {
                stream = ctx->streams[i];
@@ -267,10 +268,20 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c
                        plane = ctx->stream_status[i].plane_states[j];
 
                        // Calculate total surface size
-                       surface_size = plane->plane_size.surface_pitch *
+                       if (prev_addr_low != plane->address.grph.addr.u.low_part) {
+                               /* if plane address are different from prev FB, then userspace allocated separate FBs*/
+                               surface_size += plane->plane_size.surface_pitch *
                                        plane->plane_size.surface_size.height *
                                        (plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4);
 
+                               prev_addr_low = plane->address.grph.addr.u.low_part;
+                       } else {
+                               /* We have the same fb for all the planes.
+                                * Xorg always creates one giant fb that holds all surfaces,
+                                * so allocating it once is sufficient.
+                                * */
+                               continue;
+                       }
                        // Convert surface size + starting address to number of cache lines required
                        // (alignment accounted for)
                        cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size,
@@ -320,7 +331,10 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c
 bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable)
 {
        union dmub_rb_cmd cmd;
-       uint8_t ways;
+       uint8_t ways, i;
+       int j;
+       bool stereo_in_use = false;
+       struct dc_plane_state *plane = NULL;
 
        if (!dc->ctx->dmub_srv)
                return false;
@@ -349,7 +363,23 @@ bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable)
                         * and configure HUBP's to fetch from MALL
                         */
                        ways = dcn32_calculate_cab_allocation(dc, dc->current_state);
-                       if (ways <= dc->caps.cache_num_ways) {
+
+                       /* MALL not supported with Stereo3D. If any plane is using stereo,
+                        * don't try to enter MALL.
+                        */
+                       for (i = 0; i < dc->current_state->stream_count; i++) {
+                               for (j = 0; j < dc->current_state->stream_status[i].plane_count; j++) {
+                                       plane = dc->current_state->stream_status[i].plane_states[j];
+
+                                       if (plane->address.type == PLN_ADDR_TYPE_GRPH_STEREO) {
+                                               stereo_in_use = true;
+                                               break;
+                                       }
+                               }
+                               if (stereo_in_use)
+                                       break;
+                       }
+                       if (ways <= dc->caps.cache_num_ways && !stereo_in_use) {
                                memset(&cmd, 0, sizeof(cmd));
                                cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
                                cmd.cab.header.sub_type = DMUB_CMD__CAB_DCN_SS_FIT_IN_CAB;
@@ -683,9 +713,11 @@ void dcn32_update_mall_sel(struct dc *dc, struct dc_state *context)
                        if (pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
                                        hubp->funcs->hubp_update_mall_sel(hubp, 1, false);
                        } else {
+                               // MALL not supported with Stereo3D
                                hubp->funcs->hubp_update_mall_sel(hubp,
                                        num_ways <= dc->caps.cache_num_ways &&
-                                       pipe->stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED ? 2 : 0,
+                                       pipe->stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED &&
+                                       pipe->plane_state->address.type !=  PLN_ADDR_TYPE_GRPH_STEREO ? 2 : 0,
                                                        cache_cursor);
                        }
                }
index eff1f4e..1fad7b4 100644 (file)
@@ -281,7 +281,7 @@ static struct timing_generator_funcs dcn32_tg_funcs = {
                .lock_doublebuffer_enable = optc3_lock_doublebuffer_enable,
                .lock_doublebuffer_disable = optc3_lock_doublebuffer_disable,
                .enable_optc_clock = optc1_enable_optc_clock,
-               .set_drr = optc31_set_drr, // TODO: Update to optc32_set_drr once FW headers are promoted
+               .set_drr = optc32_set_drr,
                .get_last_used_drr_vtotal = optc2_get_last_used_drr_vtotal,
                .set_vtotal_min_max = optc3_set_vtotal_min_max,
                .set_static_screen_control = optc1_set_static_screen_control,
index 9a26d24..8b887b5 100644 (file)
@@ -867,7 +867,7 @@ static const struct dc_debug_options debug_defaults_drv = {
                }
        },
        .use_max_lb = true,
-       .force_disable_subvp = true,
+       .force_disable_subvp = false,
        .exit_idle_opt_for_cursor_updates = true,
        .enable_single_display_2to1_odm_policy = true,
        .enable_dp_dig_pixel_rate_div_policy = 1,
@@ -2051,6 +2051,7 @@ static bool dcn32_resource_construct(
        dc->caps.max_cab_allocation_bytes = 67108864; // 64MB = 1024 * 1024 * 64
        dc->caps.subvp_fw_processing_delay_us = 15;
        dc->caps.subvp_prefetch_end_to_mall_start_us = 15;
+       dc->caps.subvp_swath_height_margin_lines = 16;
        dc->caps.subvp_pstate_allow_width_us = 20;
        dc->caps.subvp_vertical_int_margin_us = 30;
 
index b3f8503..955f52e 100644 (file)
@@ -63,7 +63,7 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat
                if (pipe->stream && pipe->plane_state && !pipe->top_pipe &&
                                pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
                        bytes_per_pixel = pipe->plane_state->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4;
-                       mall_region_pixels = pipe->stream->timing.h_addressable * pipe->stream->timing.v_addressable;
+                       mall_region_pixels = pipe->plane_state->plane_size.surface_pitch * pipe->stream->timing.v_addressable;
 
                        // For bytes required in MALL, calculate based on number of MBlks required
                        num_mblks = (mall_region_pixels * bytes_per_pixel +
index 8157e40..c8b7d6f 100644 (file)
@@ -868,7 +868,7 @@ static const struct dc_debug_options debug_defaults_drv = {
                }
        },
        .use_max_lb = true,
-       .force_disable_subvp = true,
+       .force_disable_subvp = false,
        .exit_idle_opt_for_cursor_updates = true,
        .enable_single_display_2to1_odm_policy = true,
        .enable_dp_dig_pixel_rate_div_policy = 1,
@@ -1662,8 +1662,9 @@ static bool dcn321_resource_construct(
        dc->caps.max_cab_allocation_bytes = 33554432; // 32MB = 1024 * 1024 * 32
        dc->caps.subvp_fw_processing_delay_us = 15;
        dc->caps.subvp_prefetch_end_to_mall_start_us = 15;
+       dc->caps.subvp_swath_height_margin_lines = 16;
        dc->caps.subvp_pstate_allow_width_us = 20;
-
+       dc->caps.subvp_vertical_int_margin_us = 30;
        dc->caps.max_slave_planes = 1;
        dc->caps.max_slave_yuv_planes = 1;
        dc->caps.max_slave_rgb_planes = 1;
index 359f6e9..86a3b5b 100644 (file)
@@ -61,7 +61,6 @@ CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn10/dcn10_fpu.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/dcn20_fpu.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags)
-CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20v2.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20v2.o := $(dml_ccflags)
@@ -71,6 +70,7 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_ccflags) $(fram
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_ccflags) $(frame_warn_flag)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_ccflags)
+CFLAGS_$(AMDDALPATH)/dc/dml/dcn314/dcn314_fpu.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/dcn30_fpu.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/dcn32_fpu.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/display_mode_vba_32.o := $(dml_ccflags) $(frame_warn_flag)
@@ -82,7 +82,6 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn301/dcn301_fpu.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn302/dcn302_fpu.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn303/dcn303_fpu.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dsc/rc_calc_fpu.o := $(dml_ccflags)
-CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/calcs/dcn_calcs.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/calcs/dcn_calc_auto.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/calcs/dcn_calc_math.o := $(dml_ccflags) -Wno-tautological-compare
@@ -131,6 +130,7 @@ DML += dcn321/dcn321_fpu.o
 DML += dcn301/dcn301_fpu.o
 DML += dcn302/dcn302_fpu.o
 DML += dcn303/dcn303_fpu.o
+DML += dcn314/dcn314_fpu.o
 DML += dsc/rc_calc_fpu.o
 DML += calcs/dcn_calcs.o calcs/dcn_calc_math.o calcs/dcn_calc_auto.o
 endif
index ca44df4..d34e0f1 100644 (file)
@@ -30,6 +30,7 @@
 #include "dchubbub.h"
 #include "dcn20/dcn20_resource.h"
 #include "dcn21/dcn21_resource.h"
+#include "clk_mgr/dcn21/rn_clk_mgr.h"
 
 #include "dcn20_fpu.h"
 
index 7ef66e5..d211cf6 100644 (file)
@@ -26,6 +26,7 @@
 #include "clk_mgr.h"
 #include "dcn20/dcn20_resource.h"
 #include "dcn301/dcn301_resource.h"
+#include "clk_mgr/dcn301/vg_clk_mgr.h"
 
 #include "dml/dcn20/dcn20_fpu.h"
 #include "dcn301_fpu.h"
index e36cfa5..149a1b1 100644 (file)
@@ -25,6 +25,9 @@
 
 #include "resource.h"
 #include "clk_mgr.h"
+#include "dcn31/dcn31_resource.h"
+#include "dcn315/dcn315_resource.h"
+#include "dcn316/dcn316_resource.h"
 
 #include "dml/dcn20/dcn20_fpu.h"
 #include "dcn31_fpu.h"
@@ -114,7 +117,7 @@ struct _vcs_dpi_ip_params_st dcn3_1_ip = {
        .dcc_supported = true,
 };
 
-struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc = {
+static struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc = {
                /*TODO: correct dispclk/dppclk voltage level determination*/
        .clock_limits = {
                {
@@ -259,7 +262,7 @@ struct _vcs_dpi_ip_params_st dcn3_15_ip = {
        .dcc_supported = true,
 };
 
-struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc = {
+static struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc = {
        .sr_exit_time_us = 9.0,
        .sr_enter_plus_exit_time_us = 11.0,
        .sr_exit_z8_time_us = 50.0,
@@ -355,7 +358,7 @@ struct _vcs_dpi_ip_params_st dcn3_16_ip = {
        .dcc_supported = true,
 };
 
-struct _vcs_dpi_soc_bounding_box_st dcn3_16_soc = {
+static struct _vcs_dpi_soc_bounding_box_st dcn3_16_soc = {
                /*TODO: correct dispclk/dppclk voltage level determination*/
        .clock_limits = {
                {
index 3fab191..d63b420 100644 (file)
@@ -26,7 +26,7 @@
 #include "dc.h"
 #include "dc_link.h"
 #include "../display_mode_lib.h"
-#include "dml/dcn30/display_mode_vba_30.h"
+#include "../dcn30/display_mode_vba_30.h"
 #include "display_mode_vba_31.h"
 #include "../dml_inline_defs.h"
 
index 66b82e4..35d10b4 100644 (file)
@@ -27,7 +27,7 @@
 #include "../display_mode_vba.h"
 #include "../dml_inline_defs.h"
 #include "display_rq_dlg_calc_31.h"
-#include "dml/dcn30/display_mode_vba_30.h"
+#include "../dcn30/display_mode_vba_30.h"
 
 static bool is_dual_plane(enum source_format_class source_format)
 {
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
new file mode 100644 (file)
index 0000000..34a5d0f
--- /dev/null
@@ -0,0 +1,376 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "clk_mgr.h"
+#include "resource.h"
+#include "dcn31/dcn31_hubbub.h"
+#include "dcn314_fpu.h"
+#include "dml/dcn20/dcn20_fpu.h"
+#include "dml/display_mode_vba.h"
+
+struct _vcs_dpi_ip_params_st dcn3_14_ip = {
+       .VBlankNomDefaultUS = 668,
+       .gpuvm_enable = 1,
+       .gpuvm_max_page_table_levels = 1,
+       .hostvm_enable = 1,
+       .hostvm_max_page_table_levels = 2,
+       .rob_buffer_size_kbytes = 64,
+       .det_buffer_size_kbytes = DCN3_14_DEFAULT_DET_SIZE,
+       .config_return_buffer_size_in_kbytes = 1792,
+       .compressed_buffer_segment_size_in_kbytes = 64,
+       .meta_fifo_size_in_kentries = 32,
+       .zero_size_buffer_entries = 512,
+       .compbuf_reserved_space_64b = 256,
+       .compbuf_reserved_space_zs = 64,
+       .dpp_output_buffer_pixels = 2560,
+       .opp_output_buffer_lines = 1,
+       .pixel_chunk_size_kbytes = 8,
+       .meta_chunk_size_kbytes = 2,
+       .min_meta_chunk_size_bytes = 256,
+       .writeback_chunk_size_kbytes = 8,
+       .ptoi_supported = false,
+       .num_dsc = 4,
+       .maximum_dsc_bits_per_component = 10,
+       .dsc422_native_support = false,
+       .is_line_buffer_bpp_fixed = true,
+       .line_buffer_fixed_bpp = 48,
+       .line_buffer_size_bits = 789504,
+       .max_line_buffer_lines = 12,
+       .writeback_interface_buffer_size_kbytes = 90,
+       .max_num_dpp = 4,
+       .max_num_otg = 4,
+       .max_num_hdmi_frl_outputs = 1,
+       .max_num_wb = 1,
+       .max_dchub_pscl_bw_pix_per_clk = 4,
+       .max_pscl_lb_bw_pix_per_clk = 2,
+       .max_lb_vscl_bw_pix_per_clk = 4,
+       .max_vscl_hscl_bw_pix_per_clk = 4,
+       .max_hscl_ratio = 6,
+       .max_vscl_ratio = 6,
+       .max_hscl_taps = 8,
+       .max_vscl_taps = 8,
+       .dpte_buffer_size_in_pte_reqs_luma = 64,
+       .dpte_buffer_size_in_pte_reqs_chroma = 34,
+       .dispclk_ramp_margin_percent = 1,
+       .max_inter_dcn_tile_repeaters = 8,
+       .cursor_buffer_size = 16,
+       .cursor_chunk_size = 2,
+       .writeback_line_buffer_buffer_size = 0,
+       .writeback_min_hscl_ratio = 1,
+       .writeback_min_vscl_ratio = 1,
+       .writeback_max_hscl_ratio = 1,
+       .writeback_max_vscl_ratio = 1,
+       .writeback_max_hscl_taps = 1,
+       .writeback_max_vscl_taps = 1,
+       .dppclk_delay_subtotal = 46,
+       .dppclk_delay_scl = 50,
+       .dppclk_delay_scl_lb_only = 16,
+       .dppclk_delay_cnvc_formatter = 27,
+       .dppclk_delay_cnvc_cursor = 6,
+       .dispclk_delay_subtotal = 119,
+       .dynamic_metadata_vm_enabled = false,
+       .odm_combine_4to1_supported = false,
+       .dcc_supported = true,
+};
+
+struct _vcs_dpi_soc_bounding_box_st dcn3_14_soc = {
+               /*TODO: correct dispclk/dppclk voltage level determination*/
+       .clock_limits = {
+               {
+                       .state = 0,
+                       .dispclk_mhz = 1200.0,
+                       .dppclk_mhz = 1200.0,
+                       .phyclk_mhz = 600.0,
+                       .phyclk_d18_mhz = 667.0,
+                       .dscclk_mhz = 186.0,
+                       .dtbclk_mhz = 600.0,
+               },
+               {
+                       .state = 1,
+                       .dispclk_mhz = 1200.0,
+                       .dppclk_mhz = 1200.0,
+                       .phyclk_mhz = 810.0,
+                       .phyclk_d18_mhz = 667.0,
+                       .dscclk_mhz = 209.0,
+                       .dtbclk_mhz = 600.0,
+               },
+               {
+                       .state = 2,
+                       .dispclk_mhz = 1200.0,
+                       .dppclk_mhz = 1200.0,
+                       .phyclk_mhz = 810.0,
+                       .phyclk_d18_mhz = 667.0,
+                       .dscclk_mhz = 209.0,
+                       .dtbclk_mhz = 600.0,
+               },
+               {
+                       .state = 3,
+                       .dispclk_mhz = 1200.0,
+                       .dppclk_mhz = 1200.0,
+                       .phyclk_mhz = 810.0,
+                       .phyclk_d18_mhz = 667.0,
+                       .dscclk_mhz = 371.0,
+                       .dtbclk_mhz = 600.0,
+               },
+               {
+                       .state = 4,
+                       .dispclk_mhz = 1200.0,
+                       .dppclk_mhz = 1200.0,
+                       .phyclk_mhz = 810.0,
+                       .phyclk_d18_mhz = 667.0,
+                       .dscclk_mhz = 417.0,
+                       .dtbclk_mhz = 600.0,
+               },
+       },
+       .num_states = 5,
+       .sr_exit_time_us = 9.0,
+       .sr_enter_plus_exit_time_us = 11.0,
+       .sr_exit_z8_time_us = 442.0,
+       .sr_enter_plus_exit_z8_time_us = 560.0,
+       .writeback_latency_us = 12.0,
+       .dram_channel_width_bytes = 4,
+       .round_trip_ping_latency_dcfclk_cycles = 106,
+       .urgent_latency_pixel_data_only_us = 4.0,
+       .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
+       .urgent_latency_vm_data_only_us = 4.0,
+       .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
+       .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
+       .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
+       .pct_ideal_sdp_bw_after_urgent = 80.0,
+       .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0,
+       .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
+       .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
+       .max_avg_sdp_bw_use_normal_percent = 60.0,
+       .max_avg_dram_bw_use_normal_percent = 60.0,
+       .fabric_datapath_to_dcn_data_return_bytes = 32,
+       .return_bus_width_bytes = 64,
+       .downspread_percent = 0.38,
+       .dcn_downspread_percent = 0.5,
+       .gpuvm_min_page_size_bytes = 4096,
+       .hostvm_min_page_size_bytes = 4096,
+       .do_urgent_latency_adjustment = false,
+       .urgent_latency_adjustment_fabric_clock_component_us = 0,
+       .urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
+};
+
+
+void dcn314_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
+{
+       struct clk_limit_table *clk_table = &bw_params->clk_table;
+       struct _vcs_dpi_voltage_scaling_st *clock_limits =
+               dcn3_14_soc.clock_limits;
+       unsigned int i, closest_clk_lvl;
+       int max_dispclk_mhz = 0, max_dppclk_mhz = 0;
+       int j;
+
+       dc_assert_fp_enabled();
+
+       // Default clock levels are used for diags, which may lead to overclocking.
+       if (!IS_DIAG_DC(dc->ctx->dce_environment) && dc->config.use_default_clock_table == false) {
+
+               dcn3_14_ip.max_num_otg = dc->res_pool->res_cap->num_timing_generator;
+               dcn3_14_ip.max_num_dpp = dc->res_pool->pipe_count;
+
+               if (bw_params->num_channels > 0)
+                       dcn3_14_soc.num_chans = bw_params->num_channels;
+
+               ASSERT(dcn3_14_soc.num_chans);
+               ASSERT(clk_table->num_entries);
+
+               /* Prepass to find max clocks independent of voltage level. */
+               for (i = 0; i < clk_table->num_entries; ++i) {
+                       if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz)
+                               max_dispclk_mhz = clk_table->entries[i].dispclk_mhz;
+                       if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz)
+                               max_dppclk_mhz = clk_table->entries[i].dppclk_mhz;
+               }
+
+               for (i = 0; i < clk_table->num_entries; i++) {
+                       /* loop backwards*/
+                       for (closest_clk_lvl = 0, j = dcn3_14_soc.num_states - 1; j >= 0; j--) {
+                               if ((unsigned int) dcn3_14_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
+                                       closest_clk_lvl = j;
+                                       break;
+                               }
+                       }
+                       if (clk_table->num_entries == 1) {
+                               /*smu gives one DPM level, let's take the highest one*/
+                               closest_clk_lvl = dcn3_14_soc.num_states - 1;
+                       }
+
+                       clock_limits[i].state = i;
+
+                       /* Clocks dependent on voltage level. */
+                       clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
+                       if (clk_table->num_entries == 1 &&
+                               clock_limits[i].dcfclk_mhz < dcn3_14_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) {
+                               /*SMU fix not released yet*/
+                               clock_limits[i].dcfclk_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].dcfclk_mhz;
+                       }
+                       clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
+                       clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
+
+                       if (clk_table->entries[i].memclk_mhz && clk_table->entries[i].wck_ratio)
+                               clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio;
+
+                       /* Clocks independent of voltage level. */
+                       clock_limits[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz :
+                               dcn3_14_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
+
+                       clock_limits[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz :
+                               dcn3_14_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
+
+                       clock_limits[i].dram_bw_per_chan_gbps = dcn3_14_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
+                       clock_limits[i].dscclk_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
+                       clock_limits[i].dtbclk_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
+                       clock_limits[i].phyclk_d18_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
+                       clock_limits[i].phyclk_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
+               }
+               for (i = 0; i < clk_table->num_entries; i++)
+                       dcn3_14_soc.clock_limits[i] = clock_limits[i];
+               if (clk_table->num_entries) {
+                       dcn3_14_soc.num_states = clk_table->num_entries;
+               }
+       }
+
+       if (max_dispclk_mhz) {
+               dcn3_14_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
+               dc->dml.soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
+       }
+
+       if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
+               dml_init_instance(&dc->dml, &dcn3_14_soc, &dcn3_14_ip, DML_PROJECT_DCN31);
+       else
+               dml_init_instance(&dc->dml, &dcn3_14_soc, &dcn3_14_ip, DML_PROJECT_DCN31_FPGA);
+}
+
+static bool is_dual_plane(enum surface_pixel_format format)
+{
+       return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
+}
+
+int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *context,
+                                              display_e2e_pipe_params_st *pipes,
+                                              bool fast_validate)
+{
+       int i, pipe_cnt;
+       struct resource_context *res_ctx = &context->res_ctx;
+       struct pipe_ctx *pipe;
+       bool upscaled = false;
+
+       dc_assert_fp_enabled();
+
+       dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
+
+       for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
+               struct dc_crtc_timing *timing;
+
+               if (!res_ctx->pipe_ctx[i].stream)
+                       continue;
+               pipe = &res_ctx->pipe_ctx[i];
+               timing = &pipe->stream->timing;
+
+               if (dc_extended_blank_supported(dc) && pipe->stream->adjust.v_total_max == pipe->stream->adjust.v_total_min
+                       && pipe->stream->adjust.v_total_min > timing->v_total)
+                       pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min;
+
+               if (pipe->plane_state &&
+                               (pipe->plane_state->src_rect.height < pipe->plane_state->dst_rect.height ||
+                               pipe->plane_state->src_rect.width < pipe->plane_state->dst_rect.width))
+                       upscaled = true;
+
+               /*
+                * Immediate flip can be set dynamically after enabling the plane.
+                * We need to require support for immediate flip or underflow can be
+                * intermittently experienced depending on peak b/w requirements.
+                */
+               pipes[pipe_cnt].pipe.src.immediate_flip = true;
+
+               pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
+               pipes[pipe_cnt].pipe.src.hostvm = dc->res_pool->hubbub->riommu_active;
+               pipes[pipe_cnt].pipe.src.gpuvm = true;
+               pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
+               pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0;
+               pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
+               pipes[pipe_cnt].pipe.src.dcc_rate = 3;
+               pipes[pipe_cnt].dout.dsc_input_bpc = 0;
+
+               if (pipes[pipe_cnt].dout.dsc_enable) {
+                       switch (timing->display_color_depth) {
+                       case COLOR_DEPTH_888:
+                               pipes[pipe_cnt].dout.dsc_input_bpc = 8;
+                               break;
+                       case COLOR_DEPTH_101010:
+                               pipes[pipe_cnt].dout.dsc_input_bpc = 10;
+                               break;
+                       case COLOR_DEPTH_121212:
+                               pipes[pipe_cnt].dout.dsc_input_bpc = 12;
+                               break;
+                       default:
+                               ASSERT(0);
+                               break;
+                       }
+               }
+
+               pipe_cnt++;
+       }
+       context->bw_ctx.dml.ip.det_buffer_size_kbytes = DCN3_14_DEFAULT_DET_SIZE;
+
+       dc->config.enable_4to1MPC = false;
+       if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
+               if (is_dual_plane(pipe->plane_state->format)
+                               && pipe->plane_state->src_rect.width <= 1920 && pipe->plane_state->src_rect.height <= 1080) {
+                       dc->config.enable_4to1MPC = true;
+               } else if (!is_dual_plane(pipe->plane_state->format) && pipe->plane_state->src_rect.width <= 5120) {
+                       /* Limit to 5k max to avoid forced pipe split when there is not enough detile for swath */
+                       context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
+                       pipes[0].pipe.src.unbounded_req_mode = true;
+               }
+       } else if (context->stream_count >= dc->debug.crb_alloc_policy_min_disp_count
+                       && dc->debug.crb_alloc_policy > DET_SIZE_DEFAULT) {
+               context->bw_ctx.dml.ip.det_buffer_size_kbytes = dc->debug.crb_alloc_policy * 64;
+       } else if (context->stream_count >= 3 && upscaled) {
+               context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (!pipe->stream)
+                       continue;
+
+               if (pipe->stream->signal == SIGNAL_TYPE_EDP && dc->debug.seamless_boot_odm_combine &&
+                               pipe->stream->apply_seamless_boot_optimization) {
+
+                       if (pipe->stream->apply_boot_odm_mode == dm_odm_combine_policy_2to1) {
+                               context->bw_ctx.dml.vba.ODMCombinePolicy = dm_odm_combine_policy_2to1;
+                               break;
+                       }
+               }
+       }
+
+       return pipe_cnt;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.h
new file mode 100644 (file)
index 0000000..d32c5bb
--- /dev/null
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DCN314_FPU_H__
+#define __DCN314_FPU_H__
+
+#define DCN3_14_DEFAULT_DET_SIZE 384
+#define DCN3_14_MAX_DET_SIZE 384
+#define DCN3_14_MIN_COMPBUF_SIZE_KB 128
+#define DCN3_14_CRB_SEGMENT_SIZE_KB 64
+
+void dcn314_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params);
+int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *context,
+                                              display_e2e_pipe_params_st *pipes,
+                                              bool fast_validate);
+
+#endif
index 6645354..8118cfc 100644 (file)
@@ -473,8 +473,11 @@ void dcn32_set_phantom_stream_timing(struct dc *dc,
 
        // DML calculation for MALL region doesn't take into account FW delay
        // and required pstate allow width for multi-display cases
+       /* Add 16 lines margin to the MALL REGION because SUB_VP_START_LINE must be aligned
+        * to 2 swaths (i.e. 16 lines)
+        */
        phantom_vactive = get_subviewport_lines_needed_in_mall(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx) +
-                               pstate_width_fw_delay_lines;
+                               pstate_width_fw_delay_lines + dc->caps.subvp_swath_height_margin_lines;
 
        // For backporch of phantom pipe, use vstartup of the main pipe
        phantom_bp = get_vstartup(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
@@ -490,6 +493,7 @@ void dcn32_set_phantom_stream_timing(struct dc *dc,
                                                phantom_stream->timing.v_front_porch +
                                                phantom_stream->timing.v_sync_width +
                                                phantom_bp;
+       phantom_stream->timing.flags.DSC = 0; // Don't need DSC for phantom timing
 }
 
 /**
@@ -983,9 +987,15 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,
         * DML favors voltage over p-state, but we're more interested in
         * supporting p-state over voltage. We can't support p-state in
         * prefetch mode > 0 so try capping the prefetch mode to start.
+        * Override present for testing.
         */
-       context->bw_ctx.dml.soc.allow_for_pstate_or_stutter_in_vblank_final =
+       if (dc->debug.dml_disallow_alternate_prefetch_modes)
+               context->bw_ctx.dml.soc.allow_for_pstate_or_stutter_in_vblank_final =
                        dm_prefetch_support_uclk_fclk_and_stutter;
+       else
+               context->bw_ctx.dml.soc.allow_for_pstate_or_stutter_in_vblank_final =
+                       dm_prefetch_support_uclk_fclk_and_stutter_if_possible;
+
        *vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, *pipe_cnt);
        /* This may adjust vlevel and maxMpcComb */
        if (*vlevel < context->bw_ctx.dml.soc.num_states)
@@ -1014,7 +1024,9 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,
                         * will not allow for switch in VBLANK. The DRR display must have it's VBLANK stretched
                         * enough to support MCLK switching.
                         */
-                       if (*vlevel == context->bw_ctx.dml.soc.num_states) {
+                       if (*vlevel == context->bw_ctx.dml.soc.num_states &&
+                               context->bw_ctx.dml.soc.allow_for_pstate_or_stutter_in_vblank_final ==
+                                       dm_prefetch_support_uclk_fclk_and_stutter) {
                                context->bw_ctx.dml.soc.allow_for_pstate_or_stutter_in_vblank_final =
                                                                dm_prefetch_support_stutter;
                                /* There are params (such as FabricClock) that need to be recalculated
@@ -1344,7 +1356,8 @@ bool dcn32_internal_validate_bw(struct dc *dc,
        int split[MAX_PIPES] = { 0 };
        bool merge[MAX_PIPES] = { false };
        bool newly_split[MAX_PIPES] = { false };
-       int pipe_cnt, i, pipe_idx, vlevel;
+       int pipe_cnt, i, pipe_idx;
+       int vlevel = context->bw_ctx.dml.soc.num_states;
        struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
 
        dc_assert_fp_enabled();
@@ -1373,17 +1386,22 @@ bool dcn32_internal_validate_bw(struct dc *dc,
                DC_FP_END();
        }
 
-       if (fast_validate || vlevel == context->bw_ctx.dml.soc.num_states ||
-                       vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported) {
+       if (fast_validate ||
+                       (dc->debug.dml_disallow_alternate_prefetch_modes &&
+                       (vlevel == context->bw_ctx.dml.soc.num_states ||
+                               vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported))) {
                /*
-                * If mode is unsupported or there's still no p-state support then
-                * fall back to favoring voltage.
+                * If dml_disallow_alternate_prefetch_modes is false, then we have already
+                * tried alternate prefetch modes during full validation.
+                *
+                * If mode is unsupported or there is no p-state support, then
+                * fall back to favouring voltage.
                 *
-                * If Prefetch mode 0 failed for this config, or passed with Max UCLK, try if
-                * supported with Prefetch mode 1 (dm_prefetch_support_fclk_and_stutter == 2)
+                * If Prefetch mode 0 failed for this config, or passed with Max UCLK, then try
+                * to support with Prefetch mode 1 (dm_prefetch_support_fclk_and_stutter == 2)
                 */
                context->bw_ctx.dml.soc.allow_for_pstate_or_stutter_in_vblank_final =
-                               dm_prefetch_support_fclk_and_stutter;
+                       dm_prefetch_support_fclk_and_stutter;
 
                vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
 
@@ -2098,6 +2116,13 @@ void dcn32_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_pa
                                dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
                }
 
+               if ((int)(dcn3_2_soc.fclk_change_latency_us * 1000)
+                               != dc->bb_overrides.fclk_clock_change_latency_ns
+                               && dc->bb_overrides.fclk_clock_change_latency_ns) {
+                       dcn3_2_soc.fclk_change_latency_us =
+                               dc->bb_overrides.fclk_clock_change_latency_ns / 1000;
+               }
+
                if ((int)(dcn3_2_soc.dummy_pstate_latency_us * 1000)
                                != dc->bb_overrides.dummy_clock_change_latency_ns
                                && dc->bb_overrides.dummy_clock_change_latency_ns) {
index 890612d..cb20257 100644 (file)
@@ -221,7 +221,6 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
                // VBA_DELTA
                // Calculate DET size, swath height
                dml32_CalculateSwathAndDETConfiguration(
-                               &v->dummy_vars.dml32_CalculateSwathAndDETConfiguration,
                                mode_lib->vba.DETSizeOverride,
                                mode_lib->vba.UsesMALLForPStateChange,
                                mode_lib->vba.ConfigReturnBufferSizeInKByte,
@@ -461,7 +460,6 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
        {
 
                dml32_CalculateVMRowAndSwath(
-                               &v->dummy_vars.dml32_CalculateVMRowAndSwath,
                                mode_lib->vba.NumberOfActiveSurfaces,
                                v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.SurfaceParameters,
                                v->SurfaceSizeInMALL,
@@ -757,9 +755,7 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
                        v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe.BytePerPixelY = v->BytePerPixelY[k];
                        v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe.BytePerPixelC = v->BytePerPixelC[k];
                        v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe.ProgressiveToInterlaceUnitInOPP = mode_lib->vba.ProgressiveToInterlaceUnitInOPP;
-                       v->ErrorResult[k] = dml32_CalculatePrefetchSchedule(
-                                       &v->dummy_vars.dml32_CalculatePrefetchSchedule,
-                                       v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.HostVMInefficiencyFactor,
+                       v->ErrorResult[k] = dml32_CalculatePrefetchSchedule(v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.HostVMInefficiencyFactor,
                                        &v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe, v->DSCDelay[k],
                                        mode_lib->vba.DPPCLKDelaySubtotal + mode_lib->vba.DPPCLKDelayCNVCFormater,
                                        mode_lib->vba.DPPCLKDelaySCL,
@@ -1167,7 +1163,6 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
                v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.mmSOCParameters.SMNLatency = mode_lib->vba.SMNLatency;
 
                dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
-                       &v->dummy_vars.dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport,
                        mode_lib->vba.USRRetrainingRequiredFinal,
                        mode_lib->vba.UsesMALLForPStateChange,
                        mode_lib->vba.PrefetchModePerState[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb],
@@ -1952,7 +1947,6 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
        }
 
        dml32_CalculateSwathAndDETConfiguration(
-                       &v->dummy_vars.dml32_CalculateSwathAndDETConfiguration,
                        mode_lib->vba.DETSizeOverride,
                        mode_lib->vba.UsesMALLForPStateChange,
                        mode_lib->vba.ConfigReturnBufferSizeInKByte,
@@ -2549,7 +2543,6 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
                        }
 
                        dml32_CalculateSwathAndDETConfiguration(
-                                       &v->dummy_vars.dml32_CalculateSwathAndDETConfiguration,
                                        mode_lib->vba.DETSizeOverride,
                                        mode_lib->vba.UsesMALLForPStateChange,
                                        mode_lib->vba.ConfigReturnBufferSizeInKByte,
@@ -2749,7 +2742,6 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
 
                        {
                                dml32_CalculateVMRowAndSwath(
-                                               &v->dummy_vars.dml32_CalculateVMRowAndSwath,
                                                mode_lib->vba.NumberOfActiveSurfaces,
                                                v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.SurfParameters,
                                                mode_lib->vba.SurfaceSizeInMALL,
@@ -3266,7 +3258,6 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
 
                                        mode_lib->vba.NoTimeForPrefetch[i][j][k] =
                                                dml32_CalculatePrefetchSchedule(
-                                                       &v->dummy_vars.dml32_CalculatePrefetchSchedule,
                                                        v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.HostVMInefficiencyFactor,
                                                        &v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe,
                                                        mode_lib->vba.DSCDelayPerState[i][k],
@@ -3566,7 +3557,6 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
 
                        {
                                dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
-                                               &v->dummy_vars.dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport,
                                                mode_lib->vba.USRRetrainingRequiredFinal,
                                                mode_lib->vba.UsesMALLForPStateChange,
                                                mode_lib->vba.PrefetchModePerState[i][j],
index 07f8f3b..05fc14a 100644 (file)
@@ -391,7 +391,6 @@ void dml32_CalculateBytePerPixelAndBlockSizes(
 } // CalculateBytePerPixelAndBlockSizes
 
 void dml32_CalculateSwathAndDETConfiguration(
-               struct dml32_CalculateSwathAndDETConfiguration *st_vars,
                unsigned int DETSizeOverride[],
                enum dm_use_mall_for_pstate_change_mode UseMALLForPStateChange[],
                unsigned int ConfigReturnBufferSizeInKByte,
@@ -456,10 +455,18 @@ void dml32_CalculateSwathAndDETConfiguration(
                bool ViewportSizeSupportPerSurface[],
                bool *ViewportSizeSupport)
 {
+       unsigned int MaximumSwathHeightY[DC__NUM_DPP__MAX];
+       unsigned int MaximumSwathHeightC[DC__NUM_DPP__MAX];
+       unsigned int RoundedUpMaxSwathSizeBytesY[DC__NUM_DPP__MAX];
+       unsigned int RoundedUpMaxSwathSizeBytesC[DC__NUM_DPP__MAX];
+       unsigned int RoundedUpSwathSizeBytesY;
+       unsigned int RoundedUpSwathSizeBytesC;
+       double SwathWidthdoubleDPP[DC__NUM_DPP__MAX];
+       double SwathWidthdoubleDPPChroma[DC__NUM_DPP__MAX];
        unsigned int k;
-
-       st_vars->TotalActiveDPP = 0;
-       st_vars->NoChromaSurfaces = true;
+       unsigned int TotalActiveDPP = 0;
+       bool NoChromaSurfaces = true;
+       unsigned int DETBufferSizeInKByteForSwathCalculation;
 
 #ifdef __DML_VBA_DEBUG__
        dml_print("DML::%s: ForceSingleDPP = %d\n", __func__, ForceSingleDPP);
@@ -494,43 +501,43 @@ void dml32_CalculateSwathAndDETConfiguration(
                        DPPPerSurface,
 
                        /* Output */
-                       st_vars->SwathWidthdoubleDPP,
-                       st_vars->SwathWidthdoubleDPPChroma,
+                       SwathWidthdoubleDPP,
+                       SwathWidthdoubleDPPChroma,
                        SwathWidth,
                        SwathWidthChroma,
-                       st_vars->MaximumSwathHeightY,
-                       st_vars->MaximumSwathHeightC,
+                       MaximumSwathHeightY,
+                       MaximumSwathHeightC,
                        swath_width_luma_ub,
                        swath_width_chroma_ub);
 
        for (k = 0; k < NumberOfActiveSurfaces; ++k) {
-               st_vars->RoundedUpMaxSwathSizeBytesY[k] = swath_width_luma_ub[k] * BytePerPixDETY[k] * st_vars->MaximumSwathHeightY[k];
-               st_vars->RoundedUpMaxSwathSizeBytesC[k] = swath_width_chroma_ub[k] * BytePerPixDETC[k] * st_vars->MaximumSwathHeightC[k];
+               RoundedUpMaxSwathSizeBytesY[k] = swath_width_luma_ub[k] * BytePerPixDETY[k] * MaximumSwathHeightY[k];
+               RoundedUpMaxSwathSizeBytesC[k] = swath_width_chroma_ub[k] * BytePerPixDETC[k] * MaximumSwathHeightC[k];
 #ifdef __DML_VBA_DEBUG__
                dml_print("DML::%s: k=%0d DPPPerSurface = %d\n", __func__, k, DPPPerSurface[k]);
                dml_print("DML::%s: k=%0d swath_width_luma_ub = %d\n", __func__, k, swath_width_luma_ub[k]);
                dml_print("DML::%s: k=%0d BytePerPixDETY = %f\n", __func__, k, BytePerPixDETY[k]);
-               dml_print("DML::%s: k=%0d MaximumSwathHeightY = %d\n", __func__, k, st_vars->MaximumSwathHeightY[k]);
+               dml_print("DML::%s: k=%0d MaximumSwathHeightY = %d\n", __func__, k, MaximumSwathHeightY[k]);
                dml_print("DML::%s: k=%0d RoundedUpMaxSwathSizeBytesY = %d\n", __func__, k,
-                               st_vars->RoundedUpMaxSwathSizeBytesY[k]);
+                               RoundedUpMaxSwathSizeBytesY[k]);
                dml_print("DML::%s: k=%0d swath_width_chroma_ub = %d\n", __func__, k, swath_width_chroma_ub[k]);
                dml_print("DML::%s: k=%0d BytePerPixDETC = %f\n", __func__, k, BytePerPixDETC[k]);
-               dml_print("DML::%s: k=%0d MaximumSwathHeightC = %d\n", __func__, k, st_vars->MaximumSwathHeightC[k]);
+               dml_print("DML::%s: k=%0d MaximumSwathHeightC = %d\n", __func__, k, MaximumSwathHeightC[k]);
                dml_print("DML::%s: k=%0d RoundedUpMaxSwathSizeBytesC = %d\n", __func__, k,
-                               st_vars->RoundedUpMaxSwathSizeBytesC[k]);
+                               RoundedUpMaxSwathSizeBytesC[k]);
 #endif
 
                if (SourcePixelFormat[k] == dm_420_10) {
-                       st_vars->RoundedUpMaxSwathSizeBytesY[k] = dml_ceil((unsigned int) st_vars->RoundedUpMaxSwathSizeBytesY[k], 256);
-                       st_vars->RoundedUpMaxSwathSizeBytesC[k] = dml_ceil((unsigned int) st_vars->RoundedUpMaxSwathSizeBytesC[k], 256);
+                       RoundedUpMaxSwathSizeBytesY[k] = dml_ceil((unsigned int) RoundedUpMaxSwathSizeBytesY[k], 256);
+                       RoundedUpMaxSwathSizeBytesC[k] = dml_ceil((unsigned int) RoundedUpMaxSwathSizeBytesC[k], 256);
                }
        }
 
        for (k = 0; k < NumberOfActiveSurfaces; ++k) {
-               st_vars->TotalActiveDPP = st_vars->TotalActiveDPP + (ForceSingleDPP ? 1 : DPPPerSurface[k]);
+               TotalActiveDPP = TotalActiveDPP + (ForceSingleDPP ? 1 : DPPPerSurface[k]);
                if (SourcePixelFormat[k] == dm_420_8 || SourcePixelFormat[k] == dm_420_10 ||
                                SourcePixelFormat[k] == dm_420_12 || SourcePixelFormat[k] == dm_rgbe_alpha) {
-                       st_vars->NoChromaSurfaces = false;
+                       NoChromaSurfaces = false;
                }
        }
 
@@ -540,10 +547,10 @@ void dml32_CalculateSwathAndDETConfiguration(
        // if unbounded req is enabled, program reserved space such that the ROB will not hold more than 8 swaths worth of data
        // - assume worst-case compression rate of 4. [ROB size - 8 * swath_size / max_compression ratio]
        // - assume for "narrow" vp case in which the ROB can fit 8 swaths, the DET should be big enough to do full size req
-       *CompBufReservedSpaceNeedAdjustment = ((int) ROBSizeKBytes - (int) *CompBufReservedSpaceKBytes) > (int) (st_vars->RoundedUpMaxSwathSizeBytesY[0]/512);
+       *CompBufReservedSpaceNeedAdjustment = ((int) ROBSizeKBytes - (int) *CompBufReservedSpaceKBytes) > (int) (RoundedUpMaxSwathSizeBytesY[0]/512);
 
        if (*CompBufReservedSpaceNeedAdjustment == 1) {
-               *CompBufReservedSpaceKBytes = ROBSizeKBytes - st_vars->RoundedUpMaxSwathSizeBytesY[0]/512;
+               *CompBufReservedSpaceKBytes = ROBSizeKBytes - RoundedUpMaxSwathSizeBytesY[0]/512;
        }
 
        #ifdef __DML_VBA_DEBUG__
@@ -551,7 +558,7 @@ void dml32_CalculateSwathAndDETConfiguration(
                dml_print("DML::%s: CompBufReservedSpaceNeedAdjustment  = %d\n",  __func__, *CompBufReservedSpaceNeedAdjustment);
        #endif
 
-       *UnboundedRequestEnabled = dml32_UnboundedRequest(UseUnboundedRequestingFinal, st_vars->TotalActiveDPP, st_vars->NoChromaSurfaces, Output[0], SurfaceTiling[0], *CompBufReservedSpaceNeedAdjustment, DisableUnboundRequestIfCompBufReservedSpaceNeedAdjustment);
+       *UnboundedRequestEnabled = dml32_UnboundedRequest(UseUnboundedRequestingFinal, TotalActiveDPP, NoChromaSurfaces, Output[0], SurfaceTiling[0], *CompBufReservedSpaceNeedAdjustment, DisableUnboundRequestIfCompBufReservedSpaceNeedAdjustment);
 
        dml32_CalculateDETBufferSize(DETSizeOverride,
                        UseMALLForPStateChange,
@@ -566,8 +573,8 @@ void dml32_CalculateSwathAndDETConfiguration(
                        SourcePixelFormat,
                        ReadBandwidthLuma,
                        ReadBandwidthChroma,
-                       st_vars->RoundedUpMaxSwathSizeBytesY,
-                       st_vars->RoundedUpMaxSwathSizeBytesC,
+                       RoundedUpMaxSwathSizeBytesY,
+                       RoundedUpMaxSwathSizeBytesC,
                        DPPPerSurface,
 
                        /* Output */
@@ -575,7 +582,7 @@ void dml32_CalculateSwathAndDETConfiguration(
                        CompressedBufferSizeInkByte);
 
 #ifdef __DML_VBA_DEBUG__
-       dml_print("DML::%s: TotalActiveDPP = %d\n", __func__, st_vars->TotalActiveDPP);
+       dml_print("DML::%s: TotalActiveDPP = %d\n", __func__, TotalActiveDPP);
        dml_print("DML::%s: nomDETInKByte = %d\n", __func__, nomDETInKByte);
        dml_print("DML::%s: ConfigReturnBufferSizeInKByte = %d\n", __func__, ConfigReturnBufferSizeInKByte);
        dml_print("DML::%s: UseUnboundedRequestingFinal = %d\n", __func__, UseUnboundedRequestingFinal);
@@ -586,42 +593,42 @@ void dml32_CalculateSwathAndDETConfiguration(
        *ViewportSizeSupport = true;
        for (k = 0; k < NumberOfActiveSurfaces; ++k) {
 
-               st_vars->DETBufferSizeInKByteForSwathCalculation = (UseMALLForPStateChange[k] ==
+               DETBufferSizeInKByteForSwathCalculation = (UseMALLForPStateChange[k] ==
                                dm_use_mall_pstate_change_phantom_pipe ? 1024 : DETBufferSizeInKByte[k]);
 #ifdef __DML_VBA_DEBUG__
                dml_print("DML::%s: k=%0d DETBufferSizeInKByteForSwathCalculation = %d\n", __func__, k,
-                               st_vars->DETBufferSizeInKByteForSwathCalculation);
+                               DETBufferSizeInKByteForSwathCalculation);
 #endif
 
-               if (st_vars->RoundedUpMaxSwathSizeBytesY[k] + st_vars->RoundedUpMaxSwathSizeBytesC[k] <=
-                               st_vars->DETBufferSizeInKByteForSwathCalculation * 1024 / 2) {
-                       SwathHeightY[k] = st_vars->MaximumSwathHeightY[k];
-                       SwathHeightC[k] = st_vars->MaximumSwathHeightC[k];
-                       st_vars->RoundedUpSwathSizeBytesY = st_vars->RoundedUpMaxSwathSizeBytesY[k];
-                       st_vars->RoundedUpSwathSizeBytesC = st_vars->RoundedUpMaxSwathSizeBytesC[k];
-               } else if (st_vars->RoundedUpMaxSwathSizeBytesY[k] >= 1.5 * st_vars->RoundedUpMaxSwathSizeBytesC[k] &&
-                               st_vars->RoundedUpMaxSwathSizeBytesY[k] / 2 + st_vars->RoundedUpMaxSwathSizeBytesC[k] <=
-                               st_vars->DETBufferSizeInKByteForSwathCalculation * 1024 / 2) {
-                       SwathHeightY[k] = st_vars->MaximumSwathHeightY[k] / 2;
-                       SwathHeightC[k] = st_vars->MaximumSwathHeightC[k];
-                       st_vars->RoundedUpSwathSizeBytesY = st_vars->RoundedUpMaxSwathSizeBytesY[k] / 2;
-                       st_vars->RoundedUpSwathSizeBytesC = st_vars->RoundedUpMaxSwathSizeBytesC[k];
-               } else if (st_vars->RoundedUpMaxSwathSizeBytesY[k] < 1.5 * st_vars->RoundedUpMaxSwathSizeBytesC[k] &&
-                               st_vars->RoundedUpMaxSwathSizeBytesY[k] + st_vars->RoundedUpMaxSwathSizeBytesC[k] / 2 <=
-                               st_vars->DETBufferSizeInKByteForSwathCalculation * 1024 / 2) {
-                       SwathHeightY[k] = st_vars->MaximumSwathHeightY[k];
-                       SwathHeightC[k] = st_vars->MaximumSwathHeightC[k] / 2;
-                       st_vars->RoundedUpSwathSizeBytesY = st_vars->RoundedUpMaxSwathSizeBytesY[k];
-                       st_vars->RoundedUpSwathSizeBytesC = st_vars->RoundedUpMaxSwathSizeBytesC[k] / 2;
+               if (RoundedUpMaxSwathSizeBytesY[k] + RoundedUpMaxSwathSizeBytesC[k] <=
+                               DETBufferSizeInKByteForSwathCalculation * 1024 / 2) {
+                       SwathHeightY[k] = MaximumSwathHeightY[k];
+                       SwathHeightC[k] = MaximumSwathHeightC[k];
+                       RoundedUpSwathSizeBytesY = RoundedUpMaxSwathSizeBytesY[k];
+                       RoundedUpSwathSizeBytesC = RoundedUpMaxSwathSizeBytesC[k];
+               } else if (RoundedUpMaxSwathSizeBytesY[k] >= 1.5 * RoundedUpMaxSwathSizeBytesC[k] &&
+                               RoundedUpMaxSwathSizeBytesY[k] / 2 + RoundedUpMaxSwathSizeBytesC[k] <=
+                               DETBufferSizeInKByteForSwathCalculation * 1024 / 2) {
+                       SwathHeightY[k] = MaximumSwathHeightY[k] / 2;
+                       SwathHeightC[k] = MaximumSwathHeightC[k];
+                       RoundedUpSwathSizeBytesY = RoundedUpMaxSwathSizeBytesY[k] / 2;
+                       RoundedUpSwathSizeBytesC = RoundedUpMaxSwathSizeBytesC[k];
+               } else if (RoundedUpMaxSwathSizeBytesY[k] < 1.5 * RoundedUpMaxSwathSizeBytesC[k] &&
+                               RoundedUpMaxSwathSizeBytesY[k] + RoundedUpMaxSwathSizeBytesC[k] / 2 <=
+                               DETBufferSizeInKByteForSwathCalculation * 1024 / 2) {
+                       SwathHeightY[k] = MaximumSwathHeightY[k];
+                       SwathHeightC[k] = MaximumSwathHeightC[k] / 2;
+                       RoundedUpSwathSizeBytesY = RoundedUpMaxSwathSizeBytesY[k];
+                       RoundedUpSwathSizeBytesC = RoundedUpMaxSwathSizeBytesC[k] / 2;
                } else {
-                       SwathHeightY[k] = st_vars->MaximumSwathHeightY[k] / 2;
-                       SwathHeightC[k] = st_vars->MaximumSwathHeightC[k] / 2;
-                       st_vars->RoundedUpSwathSizeBytesY = st_vars->RoundedUpMaxSwathSizeBytesY[k] / 2;
-                       st_vars->RoundedUpSwathSizeBytesC = st_vars->RoundedUpMaxSwathSizeBytesC[k] / 2;
+                       SwathHeightY[k] = MaximumSwathHeightY[k] / 2;
+                       SwathHeightC[k] = MaximumSwathHeightC[k] / 2;
+                       RoundedUpSwathSizeBytesY = RoundedUpMaxSwathSizeBytesY[k] / 2;
+                       RoundedUpSwathSizeBytesC = RoundedUpMaxSwathSizeBytesC[k] / 2;
                }
 
-               if ((st_vars->RoundedUpMaxSwathSizeBytesY[k] / 2 + st_vars->RoundedUpMaxSwathSizeBytesC[k] / 2 >
-                               st_vars->DETBufferSizeInKByteForSwathCalculation * 1024 / 2)
+               if ((RoundedUpMaxSwathSizeBytesY[k] / 2 + RoundedUpMaxSwathSizeBytesC[k] / 2 >
+                               DETBufferSizeInKByteForSwathCalculation * 1024 / 2)
                                || SwathWidth[k] > MaximumSwathWidthLuma[k] || (SwathHeightC[k] > 0 &&
                                                SwathWidthChroma[k] > MaximumSwathWidthChroma[k])) {
                        *ViewportSizeSupport = false;
@@ -636,7 +643,7 @@ void dml32_CalculateSwathAndDETConfiguration(
 #endif
                        DETBufferSizeY[k] = DETBufferSizeInKByte[k] * 1024;
                        DETBufferSizeC[k] = 0;
-               } else if (st_vars->RoundedUpSwathSizeBytesY <= 1.5 * st_vars->RoundedUpSwathSizeBytesC) {
+               } else if (RoundedUpSwathSizeBytesY <= 1.5 * RoundedUpSwathSizeBytesC) {
 #ifdef __DML_VBA_DEBUG__
                        dml_print("DML::%s: k=%0d Half DET for plane0, half for plane1\n", __func__, k);
 #endif
@@ -654,11 +661,11 @@ void dml32_CalculateSwathAndDETConfiguration(
                dml_print("DML::%s: k=%0d SwathHeightY = %d\n", __func__, k, SwathHeightY[k]);
                dml_print("DML::%s: k=%0d SwathHeightC = %d\n", __func__, k, SwathHeightC[k]);
                dml_print("DML::%s: k=%0d RoundedUpMaxSwathSizeBytesY = %d\n", __func__,
-                               k, st_vars->RoundedUpMaxSwathSizeBytesY[k]);
+                               k, RoundedUpMaxSwathSizeBytesY[k]);
                dml_print("DML::%s: k=%0d RoundedUpMaxSwathSizeBytesC = %d\n", __func__,
-                               k, st_vars->RoundedUpMaxSwathSizeBytesC[k]);
-               dml_print("DML::%s: k=%0d RoundedUpSwathSizeBytesY = %d\n", __func__, k, st_vars->RoundedUpSwathSizeBytesY);
-               dml_print("DML::%s: k=%0d RoundedUpSwathSizeBytesC = %d\n", __func__, k, st_vars->RoundedUpSwathSizeBytesC);
+                               k, RoundedUpMaxSwathSizeBytesC[k]);
+               dml_print("DML::%s: k=%0d RoundedUpSwathSizeBytesY = %d\n", __func__, k, RoundedUpSwathSizeBytesY);
+               dml_print("DML::%s: k=%0d RoundedUpSwathSizeBytesC = %d\n", __func__, k, RoundedUpSwathSizeBytesC);
                dml_print("DML::%s: k=%0d DETBufferSizeInKByte = %d\n", __func__, k, DETBufferSizeInKByte[k]);
                dml_print("DML::%s: k=%0d DETBufferSizeY = %d\n", __func__, k, DETBufferSizeY[k]);
                dml_print("DML::%s: k=%0d DETBufferSizeC = %d\n", __func__, k, DETBufferSizeC[k]);
@@ -1867,7 +1874,6 @@ void dml32_CalculateSurfaceSizeInMall(
 } // CalculateSurfaceSizeInMall
 
 void dml32_CalculateVMRowAndSwath(
-               struct dml32_CalculateVMRowAndSwath *st_vars,
                unsigned int NumberOfActiveSurfaces,
                DmlPipe myPipe[],
                unsigned int SurfaceSizeInMALL[],
@@ -1933,6 +1939,21 @@ void dml32_CalculateVMRowAndSwath(
                unsigned int BIGK_FRAGMENT_SIZE[])
 {
        unsigned int k;
+       unsigned int PTEBufferSizeInRequestsForLuma[DC__NUM_DPP__MAX];
+       unsigned int PTEBufferSizeInRequestsForChroma[DC__NUM_DPP__MAX];
+       unsigned int PDEAndMetaPTEBytesFrameY;
+       unsigned int PDEAndMetaPTEBytesFrameC;
+       unsigned int MetaRowByteY[DC__NUM_DPP__MAX];
+       unsigned int MetaRowByteC[DC__NUM_DPP__MAX];
+       unsigned int PixelPTEBytesPerRowY[DC__NUM_DPP__MAX];
+       unsigned int PixelPTEBytesPerRowC[DC__NUM_DPP__MAX];
+       unsigned int PixelPTEBytesPerRowY_one_row_per_frame[DC__NUM_DPP__MAX];
+       unsigned int PixelPTEBytesPerRowC_one_row_per_frame[DC__NUM_DPP__MAX];
+       unsigned int dpte_row_width_luma_ub_one_row_per_frame[DC__NUM_DPP__MAX];
+       unsigned int dpte_row_height_luma_one_row_per_frame[DC__NUM_DPP__MAX];
+       unsigned int dpte_row_width_chroma_ub_one_row_per_frame[DC__NUM_DPP__MAX];
+       unsigned int dpte_row_height_chroma_one_row_per_frame[DC__NUM_DPP__MAX];
+       bool one_row_per_frame_fits_in_buffer[DC__NUM_DPP__MAX];
 
        for (k = 0; k < NumberOfActiveSurfaces; ++k) {
                if (HostVMEnable == true) {
@@ -1954,15 +1975,15 @@ void dml32_CalculateVMRowAndSwath(
                                myPipe[k].SourcePixelFormat == dm_rgbe_alpha) {
                        if ((myPipe[k].SourcePixelFormat == dm_420_10 || myPipe[k].SourcePixelFormat == dm_420_12) &&
                                        !IsVertical(myPipe[k].SourceRotation)) {
-                               st_vars->PTEBufferSizeInRequestsForLuma[k] =
+                               PTEBufferSizeInRequestsForLuma[k] =
                                                (PTEBufferSizeInRequestsLuma + PTEBufferSizeInRequestsChroma) / 2;
-                               st_vars->PTEBufferSizeInRequestsForChroma[k] = st_vars->PTEBufferSizeInRequestsForLuma[k];
+                               PTEBufferSizeInRequestsForChroma[k] = PTEBufferSizeInRequestsForLuma[k];
                        } else {
-                               st_vars->PTEBufferSizeInRequestsForLuma[k] = PTEBufferSizeInRequestsLuma;
-                               st_vars->PTEBufferSizeInRequestsForChroma[k] = PTEBufferSizeInRequestsChroma;
+                               PTEBufferSizeInRequestsForLuma[k] = PTEBufferSizeInRequestsLuma;
+                               PTEBufferSizeInRequestsForChroma[k] = PTEBufferSizeInRequestsChroma;
                        }
 
-                       st_vars->PDEAndMetaPTEBytesFrameC = dml32_CalculateVMAndRowBytes(
+                       PDEAndMetaPTEBytesFrameC = dml32_CalculateVMAndRowBytes(
                                        myPipe[k].ViewportStationary,
                                        myPipe[k].DCCEnable,
                                        myPipe[k].DPPPerSurface,
@@ -1982,21 +2003,21 @@ void dml32_CalculateVMRowAndSwath(
                                        GPUVMMaxPageTableLevels,
                                        GPUVMMinPageSizeKBytes[k],
                                        HostVMMinPageSize,
-                                       st_vars->PTEBufferSizeInRequestsForChroma[k],
+                                       PTEBufferSizeInRequestsForChroma[k],
                                        myPipe[k].PitchC,
                                        myPipe[k].DCCMetaPitchC,
                                        myPipe[k].BlockWidthC,
                                        myPipe[k].BlockHeightC,
 
                                        /* Output */
-                                       &st_vars->MetaRowByteC[k],
-                                       &st_vars->PixelPTEBytesPerRowC[k],
+                                       &MetaRowByteC[k],
+                                       &PixelPTEBytesPerRowC[k],
                                        &dpte_row_width_chroma_ub[k],
                                        &dpte_row_height_chroma[k],
                                        &dpte_row_height_linear_chroma[k],
-                                       &st_vars->PixelPTEBytesPerRowC_one_row_per_frame[k],
-                                       &st_vars->dpte_row_width_chroma_ub_one_row_per_frame[k],
-                                       &st_vars->dpte_row_height_chroma_one_row_per_frame[k],
+                                       &PixelPTEBytesPerRowC_one_row_per_frame[k],
+                                       &dpte_row_width_chroma_ub_one_row_per_frame[k],
+                                       &dpte_row_height_chroma_one_row_per_frame[k],
                                        &meta_req_width_chroma[k],
                                        &meta_req_height_chroma[k],
                                        &meta_row_width_chroma[k],
@@ -2024,19 +2045,19 @@ void dml32_CalculateVMRowAndSwath(
                                        &VInitPreFillC[k],
                                        &MaxNumSwathC[k]);
                } else {
-                       st_vars->PTEBufferSizeInRequestsForLuma[k] = PTEBufferSizeInRequestsLuma + PTEBufferSizeInRequestsChroma;
-                       st_vars->PTEBufferSizeInRequestsForChroma[k] = 0;
-                       st_vars->PixelPTEBytesPerRowC[k] = 0;
-                       st_vars->PDEAndMetaPTEBytesFrameC = 0;
-                       st_vars->MetaRowByteC[k] = 0;
+                       PTEBufferSizeInRequestsForLuma[k] = PTEBufferSizeInRequestsLuma + PTEBufferSizeInRequestsChroma;
+                       PTEBufferSizeInRequestsForChroma[k] = 0;
+                       PixelPTEBytesPerRowC[k] = 0;
+                       PDEAndMetaPTEBytesFrameC = 0;
+                       MetaRowByteC[k] = 0;
                        MaxNumSwathC[k] = 0;
                        PrefetchSourceLinesC[k] = 0;
-                       st_vars->dpte_row_height_chroma_one_row_per_frame[k] = 0;
-                       st_vars->dpte_row_width_chroma_ub_one_row_per_frame[k] = 0;
-                       st_vars->PixelPTEBytesPerRowC_one_row_per_frame[k] = 0;
+                       dpte_row_height_chroma_one_row_per_frame[k] = 0;
+                       dpte_row_width_chroma_ub_one_row_per_frame[k] = 0;
+                       PixelPTEBytesPerRowC_one_row_per_frame[k] = 0;
                }
 
-               st_vars->PDEAndMetaPTEBytesFrameY = dml32_CalculateVMAndRowBytes(
+               PDEAndMetaPTEBytesFrameY = dml32_CalculateVMAndRowBytes(
                                myPipe[k].ViewportStationary,
                                myPipe[k].DCCEnable,
                                myPipe[k].DPPPerSurface,
@@ -2056,21 +2077,21 @@ void dml32_CalculateVMRowAndSwath(
                                GPUVMMaxPageTableLevels,
                                GPUVMMinPageSizeKBytes[k],
                                HostVMMinPageSize,
-                               st_vars->PTEBufferSizeInRequestsForLuma[k],
+                               PTEBufferSizeInRequestsForLuma[k],
                                myPipe[k].PitchY,
                                myPipe[k].DCCMetaPitchY,
                                myPipe[k].BlockWidthY,
                                myPipe[k].BlockHeightY,
 
                                /* Output */
-                               &st_vars->MetaRowByteY[k],
-                               &st_vars->PixelPTEBytesPerRowY[k],
+                               &MetaRowByteY[k],
+                               &PixelPTEBytesPerRowY[k],
                                &dpte_row_width_luma_ub[k],
                                &dpte_row_height_luma[k],
                                &dpte_row_height_linear_luma[k],
-                               &st_vars->PixelPTEBytesPerRowY_one_row_per_frame[k],
-                               &st_vars->dpte_row_width_luma_ub_one_row_per_frame[k],
-                               &st_vars->dpte_row_height_luma_one_row_per_frame[k],
+                               &PixelPTEBytesPerRowY_one_row_per_frame[k],
+                               &dpte_row_width_luma_ub_one_row_per_frame[k],
+                               &dpte_row_height_luma_one_row_per_frame[k],
                                &meta_req_width[k],
                                &meta_req_height[k],
                                &meta_row_width[k],
@@ -2098,19 +2119,19 @@ void dml32_CalculateVMRowAndSwath(
                                &VInitPreFillY[k],
                                &MaxNumSwathY[k]);
 
-               PDEAndMetaPTEBytesFrame[k] = st_vars->PDEAndMetaPTEBytesFrameY + st_vars->PDEAndMetaPTEBytesFrameC;
-               MetaRowByte[k] = st_vars->MetaRowByteY[k] + st_vars->MetaRowByteC[k];
+               PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY + PDEAndMetaPTEBytesFrameC;
+               MetaRowByte[k] = MetaRowByteY[k] + MetaRowByteC[k];
 
-               if (st_vars->PixelPTEBytesPerRowY[k] <= 64 * st_vars->PTEBufferSizeInRequestsForLuma[k] &&
-                               st_vars->PixelPTEBytesPerRowC[k] <= 64 * st_vars->PTEBufferSizeInRequestsForChroma[k]) {
+               if (PixelPTEBytesPerRowY[k] <= 64 * PTEBufferSizeInRequestsForLuma[k] &&
+                               PixelPTEBytesPerRowC[k] <= 64 * PTEBufferSizeInRequestsForChroma[k]) {
                        PTEBufferSizeNotExceeded[k] = true;
                } else {
                        PTEBufferSizeNotExceeded[k] = false;
                }
 
-               st_vars->one_row_per_frame_fits_in_buffer[k] = (st_vars->PixelPTEBytesPerRowY_one_row_per_frame[k] <= 64 * 2 *
-                       st_vars->PTEBufferSizeInRequestsForLuma[k] &&
-                       st_vars->PixelPTEBytesPerRowC_one_row_per_frame[k] <= 64 * 2 * st_vars->PTEBufferSizeInRequestsForChroma[k]);
+               one_row_per_frame_fits_in_buffer[k] = (PixelPTEBytesPerRowY_one_row_per_frame[k] <= 64 * 2 *
+                       PTEBufferSizeInRequestsForLuma[k] &&
+                       PixelPTEBytesPerRowC_one_row_per_frame[k] <= 64 * 2 * PTEBufferSizeInRequestsForChroma[k]);
        }
 
        dml32_CalculateMALLUseForStaticScreen(
@@ -2118,7 +2139,7 @@ void dml32_CalculateVMRowAndSwath(
                        MALLAllocatedForDCN,
                        UseMALLForStaticScreen,   // mode
                        SurfaceSizeInMALL,
-                       st_vars->one_row_per_frame_fits_in_buffer,
+                       one_row_per_frame_fits_in_buffer,
                        /* Output */
                        UsesMALLForStaticScreen); // boolen
 
@@ -2144,13 +2165,13 @@ void dml32_CalculateVMRowAndSwath(
                                !(UseMALLForPStateChange[k] == dm_use_mall_pstate_change_full_frame);
 
                if (use_one_row_for_frame[k]) {
-                       dpte_row_height_luma[k] = st_vars->dpte_row_height_luma_one_row_per_frame[k];
-                       dpte_row_width_luma_ub[k] = st_vars->dpte_row_width_luma_ub_one_row_per_frame[k];
-                       st_vars->PixelPTEBytesPerRowY[k] = st_vars->PixelPTEBytesPerRowY_one_row_per_frame[k];
-                       dpte_row_height_chroma[k] = st_vars->dpte_row_height_chroma_one_row_per_frame[k];
-                       dpte_row_width_chroma_ub[k] = st_vars->dpte_row_width_chroma_ub_one_row_per_frame[k];
-                       st_vars->PixelPTEBytesPerRowC[k] = st_vars->PixelPTEBytesPerRowC_one_row_per_frame[k];
-                       PTEBufferSizeNotExceeded[k] = st_vars->one_row_per_frame_fits_in_buffer[k];
+                       dpte_row_height_luma[k] = dpte_row_height_luma_one_row_per_frame[k];
+                       dpte_row_width_luma_ub[k] = dpte_row_width_luma_ub_one_row_per_frame[k];
+                       PixelPTEBytesPerRowY[k] = PixelPTEBytesPerRowY_one_row_per_frame[k];
+                       dpte_row_height_chroma[k] = dpte_row_height_chroma_one_row_per_frame[k];
+                       dpte_row_width_chroma_ub[k] = dpte_row_width_chroma_ub_one_row_per_frame[k];
+                       PixelPTEBytesPerRowC[k] = PixelPTEBytesPerRowC_one_row_per_frame[k];
+                       PTEBufferSizeNotExceeded[k] = one_row_per_frame_fits_in_buffer[k];
                }
 
                if (MetaRowByte[k] <= DCCMetaBufferSizeBytes)
@@ -2158,7 +2179,7 @@ void dml32_CalculateVMRowAndSwath(
                else
                        DCCMetaBufferSizeNotExceeded[k] = false;
 
-               PixelPTEBytesPerRow[k] = st_vars->PixelPTEBytesPerRowY[k] + st_vars->PixelPTEBytesPerRowC[k];
+               PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY[k] + PixelPTEBytesPerRowC[k];
                if (use_one_row_for_frame[k])
                        PixelPTEBytesPerRow[k] = PixelPTEBytesPerRow[k] / 2;
 
@@ -2169,11 +2190,11 @@ void dml32_CalculateVMRowAndSwath(
                                myPipe[k].VRatioChroma,
                                myPipe[k].DCCEnable,
                                myPipe[k].HTotal / myPipe[k].PixelClock,
-                               st_vars->MetaRowByteY[k], st_vars->MetaRowByteC[k],
+                               MetaRowByteY[k], MetaRowByteC[k],
                                meta_row_height[k],
                                meta_row_height_chroma[k],
-                               st_vars->PixelPTEBytesPerRowY[k],
-                               st_vars->PixelPTEBytesPerRowC[k],
+                               PixelPTEBytesPerRowY[k],
+                               PixelPTEBytesPerRowC[k],
                                dpte_row_height_luma[k],
                                dpte_row_height_chroma[k],
 
@@ -2189,12 +2210,12 @@ void dml32_CalculateVMRowAndSwath(
                dml_print("DML::%s: k=%d, dpte_row_height_luma         = %d\n",  __func__, k, dpte_row_height_luma[k]);
                dml_print("DML::%s: k=%d, dpte_row_width_luma_ub       = %d\n",
                                __func__, k, dpte_row_width_luma_ub[k]);
-               dml_print("DML::%s: k=%d, PixelPTEBytesPerRowY         = %d\n",  __func__, k, st_vars->PixelPTEBytesPerRowY[k]);
+               dml_print("DML::%s: k=%d, PixelPTEBytesPerRowY         = %d\n",  __func__, k, PixelPTEBytesPerRowY[k]);
                dml_print("DML::%s: k=%d, dpte_row_height_chroma       = %d\n",
                                __func__, k, dpte_row_height_chroma[k]);
                dml_print("DML::%s: k=%d, dpte_row_width_chroma_ub     = %d\n",
                                __func__, k, dpte_row_width_chroma_ub[k]);
-               dml_print("DML::%s: k=%d, PixelPTEBytesPerRowC         = %d\n",  __func__, k, st_vars->PixelPTEBytesPerRowC[k]);
+               dml_print("DML::%s: k=%d, PixelPTEBytesPerRowC         = %d\n",  __func__, k, PixelPTEBytesPerRowC[k]);
                dml_print("DML::%s: k=%d, PixelPTEBytesPerRow          = %d\n",  __func__, k, PixelPTEBytesPerRow[k]);
                dml_print("DML::%s: k=%d, PTEBufferSizeNotExceeded     = %d\n",
                                __func__, k, PTEBufferSizeNotExceeded[k]);
@@ -3342,7 +3363,6 @@ double dml32_CalculateExtraLatency(
 } // CalculateExtraLatency
 
 bool dml32_CalculatePrefetchSchedule(
-               struct dml32_CalculatePrefetchSchedule *st_vars,
                double HostVMInefficiencyFactor,
                DmlPipe *myPipe,
                unsigned int DSCDelay,
@@ -3406,18 +3426,45 @@ bool dml32_CalculatePrefetchSchedule(
                double   *VReadyOffsetPix)
 {
        bool MyError = false;
-
-       st_vars->TimeForFetchingMetaPTE = 0;
-       st_vars->TimeForFetchingRowInVBlank = 0;
-       st_vars->LinesToRequestPrefetchPixelData = 0;
-       st_vars->max_vratio_pre = __DML_MAX_VRATIO_PRE__;
-       st_vars->Tsw_est1 = 0;
-       st_vars->Tsw_est3 = 0;
+       unsigned int DPPCycles, DISPCLKCycles;
+       double DSTTotalPixelsAfterScaler;
+       double LineTime;
+       double dst_y_prefetch_equ;
+       double prefetch_bw_oto;
+       double Tvm_oto;
+       double Tr0_oto;
+       double Tvm_oto_lines;
+       double Tr0_oto_lines;
+       double dst_y_prefetch_oto;
+       double TimeForFetchingMetaPTE = 0;
+       double TimeForFetchingRowInVBlank = 0;
+       double LinesToRequestPrefetchPixelData = 0;
+       unsigned int HostVMDynamicLevelsTrips;
+       double  trip_to_mem;
+       double  Tvm_trips;
+       double  Tr0_trips;
+       double  Tvm_trips_rounded;
+       double  Tr0_trips_rounded;
+       double  Lsw_oto;
+       double  Tpre_rounded;
+       double  prefetch_bw_equ;
+       double  Tvm_equ;
+       double  Tr0_equ;
+       double  Tdmbf;
+       double  Tdmec;
+       double  Tdmsks;
+       double  prefetch_sw_bytes;
+       double  bytes_pp;
+       double  dep_bytes;
+       unsigned int max_vratio_pre = __DML_MAX_VRATIO_PRE__;
+       double  min_Lsw;
+       double  Tsw_est1 = 0;
+       double  Tsw_est3 = 0;
 
        if (GPUVMEnable == true && HostVMEnable == true)
-               st_vars->HostVMDynamicLevelsTrips = HostVMMaxNonCachedPageTableLevels;
+               HostVMDynamicLevelsTrips = HostVMMaxNonCachedPageTableLevels;
        else
-               st_vars->HostVMDynamicLevelsTrips = 0;
+               HostVMDynamicLevelsTrips = 0;
 #ifdef __DML_VBA_DEBUG__
        dml_print("DML::%s: GPUVMEnable = %d\n", __func__, GPUVMEnable);
        dml_print("DML::%s: GPUVMPageTableLevels = %d\n", __func__, GPUVMPageTableLevels);
@@ -3440,19 +3487,19 @@ bool dml32_CalculatePrefetchSchedule(
                        TSetup,
 
                        /* output */
-                       &st_vars->Tdmbf,
-                       &st_vars->Tdmec,
-                       &st_vars->Tdmsks,
+                       &Tdmbf,
+                       &Tdmec,
+                       &Tdmsks,
                        VUpdateOffsetPix,
                        VUpdateWidthPix,
                        VReadyOffsetPix);
 
-       st_vars->LineTime = myPipe->HTotal / myPipe->PixelClock;
-       st_vars->trip_to_mem = UrgentLatency;
-       st_vars->Tvm_trips = UrgentExtraLatency + st_vars->trip_to_mem * (GPUVMPageTableLevels * (st_vars->HostVMDynamicLevelsTrips + 1) - 1);
+       LineTime = myPipe->HTotal / myPipe->PixelClock;
+       trip_to_mem = UrgentLatency;
+       Tvm_trips = UrgentExtraLatency + trip_to_mem * (GPUVMPageTableLevels * (HostVMDynamicLevelsTrips + 1) - 1);
 
        if (DynamicMetadataVMEnabled == true)
-               *Tdmdl = TWait + st_vars->Tvm_trips + st_vars->trip_to_mem;
+               *Tdmdl = TWait + Tvm_trips + trip_to_mem;
        else
                *Tdmdl = TWait + UrgentExtraLatency;
 
@@ -3462,15 +3509,15 @@ bool dml32_CalculatePrefetchSchedule(
 #endif
 
        if (DynamicMetadataEnable == true) {
-               if (VStartup * st_vars->LineTime < *TSetup + *Tdmdl + st_vars->Tdmbf + st_vars->Tdmec + st_vars->Tdmsks) {
+               if (VStartup * LineTime < *TSetup + *Tdmdl + Tdmbf + Tdmec + Tdmsks) {
                        *NotEnoughTimeForDynamicMetadata = true;
 #ifdef __DML_VBA_DEBUG__
                        dml_print("DML::%s: Not Enough Time for Dynamic Meta!\n", __func__);
                        dml_print("DML::%s: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n",
-                                       __func__, st_vars->Tdmbf);
-                       dml_print("DML::%s: Tdmec: %fus - time dio takes to transfer dmd\n", __func__, st_vars->Tdmec);
+                                       __func__, Tdmbf);
+                       dml_print("DML::%s: Tdmec: %fus - time dio takes to transfer dmd\n", __func__, Tdmec);
                        dml_print("DML::%s: Tdmsks: %fus - time before active dmd must complete transmission at dio\n",
-                                       __func__, st_vars->Tdmsks);
+                                       __func__, Tdmsks);
                        dml_print("DML::%s: Tdmdl: %fus - time for fabric to become ready and fetch dmd\n",
                                        __func__, *Tdmdl);
 #endif
@@ -3482,21 +3529,21 @@ bool dml32_CalculatePrefetchSchedule(
        }
 
        *Tdmdl_vm =  (DynamicMetadataEnable == true && DynamicMetadataVMEnabled == true &&
-                       GPUVMEnable == true ? TWait + st_vars->Tvm_trips : 0);
+                       GPUVMEnable == true ? TWait + Tvm_trips : 0);
 
        if (myPipe->ScalerEnabled)
-               st_vars->DPPCycles = DPPCLKDelaySubtotalPlusCNVCFormater + DPPCLKDelaySCL;
+               DPPCycles = DPPCLKDelaySubtotalPlusCNVCFormater + DPPCLKDelaySCL;
        else
-               st_vars->DPPCycles = DPPCLKDelaySubtotalPlusCNVCFormater + DPPCLKDelaySCLLBOnly;
+               DPPCycles = DPPCLKDelaySubtotalPlusCNVCFormater + DPPCLKDelaySCLLBOnly;
 
-       st_vars->DPPCycles = st_vars->DPPCycles + myPipe->NumberOfCursors * DPPCLKDelayCNVCCursor;
+       DPPCycles = DPPCycles + myPipe->NumberOfCursors * DPPCLKDelayCNVCCursor;
 
-       st_vars->DISPCLKCycles = DISPCLKDelaySubtotal;
+       DISPCLKCycles = DISPCLKDelaySubtotal;
 
        if (myPipe->Dppclk == 0.0 || myPipe->Dispclk == 0.0)
                return true;
 
-       *DSTXAfterScaler = st_vars->DPPCycles * myPipe->PixelClock / myPipe->Dppclk + st_vars->DISPCLKCycles *
+       *DSTXAfterScaler = DPPCycles * myPipe->PixelClock / myPipe->Dppclk + DISPCLKCycles *
                        myPipe->PixelClock / myPipe->Dispclk + DSCDelay;
 
        *DSTXAfterScaler = *DSTXAfterScaler + (myPipe->ODMMode != dm_odm_combine_mode_disabled ? 18 : 0)
@@ -3506,10 +3553,10 @@ bool dml32_CalculatePrefetchSchedule(
                        + ((myPipe->ODMMode == dm_odm_mode_mso_1to4) ? myPipe->HActive * 3 / 4 : 0);
 
 #ifdef __DML_VBA_DEBUG__
-       dml_print("DML::%s: DPPCycles: %d\n", __func__, st_vars->DPPCycles);
+       dml_print("DML::%s: DPPCycles: %d\n", __func__, DPPCycles);
        dml_print("DML::%s: PixelClock: %f\n", __func__, myPipe->PixelClock);
        dml_print("DML::%s: Dppclk: %f\n", __func__, myPipe->Dppclk);
-       dml_print("DML::%s: DISPCLKCycles: %d\n", __func__, st_vars->DISPCLKCycles);
+       dml_print("DML::%s: DISPCLKCycles: %d\n", __func__, DISPCLKCycles);
        dml_print("DML::%s: DISPCLK: %f\n", __func__,  myPipe->Dispclk);
        dml_print("DML::%s: DSCDelay: %d\n", __func__,  DSCDelay);
        dml_print("DML::%s: ODMMode: %d\n", __func__,  myPipe->ODMMode);
@@ -3522,9 +3569,9 @@ bool dml32_CalculatePrefetchSchedule(
        else
                *DSTYAfterScaler = 0;
 
-       st_vars->DSTTotalPixelsAfterScaler = *DSTYAfterScaler * myPipe->HTotal + *DSTXAfterScaler;
-       *DSTYAfterScaler = dml_floor(st_vars->DSTTotalPixelsAfterScaler / myPipe->HTotal, 1);
-       *DSTXAfterScaler = st_vars->DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * myPipe->HTotal));
+       DSTTotalPixelsAfterScaler = *DSTYAfterScaler * myPipe->HTotal + *DSTXAfterScaler;
+       *DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / myPipe->HTotal, 1);
+       *DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * myPipe->HTotal));
 #ifdef __DML_VBA_DEBUG__
        dml_print("DML::%s: DSTXAfterScaler: %d (final)\n", __func__,  *DSTXAfterScaler);
        dml_print("DML::%s: DSTYAfterScaler: %d (final)\n", __func__, *DSTYAfterScaler);
@@ -3532,132 +3579,132 @@ bool dml32_CalculatePrefetchSchedule(
 
        MyError = false;
 
-       st_vars->Tr0_trips = st_vars->trip_to_mem * (st_vars->HostVMDynamicLevelsTrips + 1);
+       Tr0_trips = trip_to_mem * (HostVMDynamicLevelsTrips + 1);
 
        if (GPUVMEnable == true) {
-               st_vars->Tvm_trips_rounded = dml_ceil(4.0 * st_vars->Tvm_trips / st_vars->LineTime, 1.0) / 4.0 * st_vars->LineTime;
-               st_vars->Tr0_trips_rounded = dml_ceil(4.0 * st_vars->Tr0_trips / st_vars->LineTime, 1.0) / 4.0 * st_vars->LineTime;
+               Tvm_trips_rounded = dml_ceil(4.0 * Tvm_trips / LineTime, 1.0) / 4.0 * LineTime;
+               Tr0_trips_rounded = dml_ceil(4.0 * Tr0_trips / LineTime, 1.0) / 4.0 * LineTime;
                if (GPUVMPageTableLevels >= 3) {
-                       *Tno_bw = UrgentExtraLatency + st_vars->trip_to_mem *
-                                       (double) ((GPUVMPageTableLevels - 2) * (st_vars->HostVMDynamicLevelsTrips + 1) - 1);
+                       *Tno_bw = UrgentExtraLatency + trip_to_mem *
+                                       (double) ((GPUVMPageTableLevels - 2) * (HostVMDynamicLevelsTrips + 1) - 1);
                } else if (GPUVMPageTableLevels == 1 && myPipe->DCCEnable != true) {
-                       st_vars->Tr0_trips_rounded = dml_ceil(4.0 * UrgentExtraLatency / st_vars->LineTime, 1.0) /
-                                       4.0 * st_vars->LineTime; // VBA_ERROR
+                       Tr0_trips_rounded = dml_ceil(4.0 * UrgentExtraLatency / LineTime, 1.0) /
+                                       4.0 * LineTime; // VBA_ERROR
                        *Tno_bw = UrgentExtraLatency;
                } else {
                        *Tno_bw = 0;
                }
        } else if (myPipe->DCCEnable == true) {
-               st_vars->Tvm_trips_rounded = st_vars->LineTime / 4.0;
-               st_vars->Tr0_trips_rounded = dml_ceil(4.0 * st_vars->Tr0_trips / st_vars->LineTime, 1.0) / 4.0 * st_vars->LineTime;
+               Tvm_trips_rounded = LineTime / 4.0;
+               Tr0_trips_rounded = dml_ceil(4.0 * Tr0_trips / LineTime, 1.0) / 4.0 * LineTime;
                *Tno_bw = 0;
        } else {
-               st_vars->Tvm_trips_rounded = st_vars->LineTime / 4.0;
-               st_vars->Tr0_trips_rounded = st_vars->LineTime / 2.0;
+               Tvm_trips_rounded = LineTime / 4.0;
+               Tr0_trips_rounded = LineTime / 2.0;
                *Tno_bw = 0;
        }
-       st_vars->Tvm_trips_rounded = dml_max(st_vars->Tvm_trips_rounded, st_vars->LineTime / 4.0);
-       st_vars->Tr0_trips_rounded = dml_max(st_vars->Tr0_trips_rounded, st_vars->LineTime / 4.0);
+       Tvm_trips_rounded = dml_max(Tvm_trips_rounded, LineTime / 4.0);
+       Tr0_trips_rounded = dml_max(Tr0_trips_rounded, LineTime / 4.0);
 
        if (myPipe->SourcePixelFormat == dm_420_8 || myPipe->SourcePixelFormat == dm_420_10
                        || myPipe->SourcePixelFormat == dm_420_12) {
-               st_vars->bytes_pp = myPipe->BytePerPixelY + myPipe->BytePerPixelC / 4;
+               bytes_pp = myPipe->BytePerPixelY + myPipe->BytePerPixelC / 4;
        } else {
-               st_vars->bytes_pp = myPipe->BytePerPixelY + myPipe->BytePerPixelC;
+               bytes_pp = myPipe->BytePerPixelY + myPipe->BytePerPixelC;
        }
 
-       st_vars->prefetch_sw_bytes = PrefetchSourceLinesY * swath_width_luma_ub * myPipe->BytePerPixelY
+       prefetch_sw_bytes = PrefetchSourceLinesY * swath_width_luma_ub * myPipe->BytePerPixelY
                        + PrefetchSourceLinesC * swath_width_chroma_ub * myPipe->BytePerPixelC;
-       st_vars->prefetch_bw_oto = dml_max(st_vars->bytes_pp * myPipe->PixelClock / myPipe->DPPPerSurface,
-                       st_vars->prefetch_sw_bytes / (dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * st_vars->LineTime));
+       prefetch_bw_oto = dml_max(bytes_pp * myPipe->PixelClock / myPipe->DPPPerSurface,
+                       prefetch_sw_bytes / (dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime));
 
-       st_vars->min_Lsw = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) / st_vars->max_vratio_pre;
-       st_vars->min_Lsw = dml_max(st_vars->min_Lsw, 1.0);
-       st_vars->Lsw_oto = dml_ceil(4.0 * dml_max(st_vars->prefetch_sw_bytes / st_vars->prefetch_bw_oto / st_vars->LineTime, st_vars->min_Lsw), 1.0) / 4.0;
+       min_Lsw = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) / max_vratio_pre;
+       min_Lsw = dml_max(min_Lsw, 1.0);
+       Lsw_oto = dml_ceil(4.0 * dml_max(prefetch_sw_bytes / prefetch_bw_oto / LineTime, min_Lsw), 1.0) / 4.0;
 
        if (GPUVMEnable == true) {
-               st_vars->Tvm_oto = dml_max3(
-                               st_vars->Tvm_trips,
-                               *Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / st_vars->prefetch_bw_oto,
-                               st_vars->LineTime / 4.0);
+               Tvm_oto = dml_max3(
+                               Tvm_trips,
+                               *Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / prefetch_bw_oto,
+                               LineTime / 4.0);
        } else
-               st_vars->Tvm_oto = st_vars->LineTime / 4.0;
+               Tvm_oto = LineTime / 4.0;
 
        if ((GPUVMEnable == true || myPipe->DCCEnable == true)) {
-               st_vars->Tr0_oto = dml_max4(
-                               st_vars->Tr0_trips,
-                               (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / st_vars->prefetch_bw_oto,
-                               (st_vars->LineTime - st_vars->Tvm_oto)/2.0,
-                               st_vars->LineTime / 4.0);
+               Tr0_oto = dml_max4(
+                               Tr0_trips,
+                               (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / prefetch_bw_oto,
+                               (LineTime - Tvm_oto)/2.0,
+                               LineTime / 4.0);
 #ifdef __DML_VBA_DEBUG__
                dml_print("DML::%s: Tr0_oto max0 = %f\n", __func__,
-                               (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / st_vars->prefetch_bw_oto);
-               dml_print("DML::%s: Tr0_oto max1 = %f\n", __func__, st_vars->Tr0_trips);
-               dml_print("DML::%s: Tr0_oto max2 = %f\n", __func__, st_vars->LineTime - st_vars->Tvm_oto);
-               dml_print("DML::%s: Tr0_oto max3 = %f\n", __func__, st_vars->LineTime / 4);
+                               (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / prefetch_bw_oto);
+               dml_print("DML::%s: Tr0_oto max1 = %f\n", __func__, Tr0_trips);
+               dml_print("DML::%s: Tr0_oto max2 = %f\n", __func__, LineTime - Tvm_oto);
+               dml_print("DML::%s: Tr0_oto max3 = %f\n", __func__, LineTime / 4);
 #endif
        } else
-               st_vars->Tr0_oto = (st_vars->LineTime - st_vars->Tvm_oto) / 2.0;
+               Tr0_oto = (LineTime - Tvm_oto) / 2.0;
 
-       st_vars->Tvm_oto_lines = dml_ceil(4.0 * st_vars->Tvm_oto / st_vars->LineTime, 1) / 4.0;
-       st_vars->Tr0_oto_lines = dml_ceil(4.0 * st_vars->Tr0_oto / st_vars->LineTime, 1) / 4.0;
-       st_vars->dst_y_prefetch_oto = st_vars->Tvm_oto_lines + 2 * st_vars->Tr0_oto_lines + st_vars->Lsw_oto;
+       Tvm_oto_lines = dml_ceil(4.0 * Tvm_oto / LineTime, 1) / 4.0;
+       Tr0_oto_lines = dml_ceil(4.0 * Tr0_oto / LineTime, 1) / 4.0;
+       dst_y_prefetch_oto = Tvm_oto_lines + 2 * Tr0_oto_lines + Lsw_oto;
 
-       st_vars->dst_y_prefetch_equ = VStartup - (*TSetup + dml_max(TWait + TCalc, *Tdmdl)) / st_vars->LineTime -
+       dst_y_prefetch_equ = VStartup - (*TSetup + dml_max(TWait + TCalc, *Tdmdl)) / LineTime -
                        (*DSTYAfterScaler + (double) *DSTXAfterScaler / (double) myPipe->HTotal);
 
 #ifdef __DML_VBA_DEBUG__
        dml_print("DML::%s: HTotal = %d\n", __func__, myPipe->HTotal);
-       dml_print("DML::%s: min_Lsw = %f\n", __func__, st_vars->min_Lsw);
+       dml_print("DML::%s: min_Lsw = %f\n", __func__, min_Lsw);
        dml_print("DML::%s: *Tno_bw = %f\n", __func__, *Tno_bw);
        dml_print("DML::%s: UrgentExtraLatency = %f\n", __func__, UrgentExtraLatency);
-       dml_print("DML::%s: trip_to_mem = %f\n", __func__, st_vars->trip_to_mem);
+       dml_print("DML::%s: trip_to_mem = %f\n", __func__, trip_to_mem);
        dml_print("DML::%s: BytePerPixelY = %d\n", __func__, myPipe->BytePerPixelY);
        dml_print("DML::%s: PrefetchSourceLinesY = %f\n", __func__, PrefetchSourceLinesY);
        dml_print("DML::%s: swath_width_luma_ub = %d\n", __func__, swath_width_luma_ub);
        dml_print("DML::%s: BytePerPixelC = %d\n", __func__, myPipe->BytePerPixelC);
        dml_print("DML::%s: PrefetchSourceLinesC = %f\n", __func__, PrefetchSourceLinesC);
        dml_print("DML::%s: swath_width_chroma_ub = %d\n", __func__, swath_width_chroma_ub);
-       dml_print("DML::%s: prefetch_sw_bytes = %f\n", __func__, st_vars->prefetch_sw_bytes);
-       dml_print("DML::%s: bytes_pp = %f\n", __func__, st_vars->bytes_pp);
+       dml_print("DML::%s: prefetch_sw_bytes = %f\n", __func__, prefetch_sw_bytes);
+       dml_print("DML::%s: bytes_pp = %f\n", __func__, bytes_pp);
        dml_print("DML::%s: PDEAndMetaPTEBytesFrame = %d\n", __func__, PDEAndMetaPTEBytesFrame);
        dml_print("DML::%s: MetaRowByte = %d\n", __func__, MetaRowByte);
        dml_print("DML::%s: PixelPTEBytesPerRow = %d\n", __func__, PixelPTEBytesPerRow);
        dml_print("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, HostVMInefficiencyFactor);
-       dml_print("DML::%s: Tvm_trips = %f\n", __func__, st_vars->Tvm_trips);
-       dml_print("DML::%s: Tr0_trips = %f\n", __func__, st_vars->Tr0_trips);
-       dml_print("DML::%s: prefetch_bw_oto = %f\n", __func__, st_vars->prefetch_bw_oto);
-       dml_print("DML::%s: Tr0_oto = %f\n", __func__, st_vars->Tr0_oto);
-       dml_print("DML::%s: Tvm_oto = %f\n", __func__, st_vars->Tvm_oto);
-       dml_print("DML::%s: Tvm_oto_lines = %f\n", __func__, st_vars->Tvm_oto_lines);
-       dml_print("DML::%s: Tr0_oto_lines = %f\n", __func__, st_vars->Tr0_oto_lines);
-       dml_print("DML::%s: Lsw_oto = %f\n", __func__, st_vars->Lsw_oto);
-       dml_print("DML::%s: dst_y_prefetch_oto = %f\n", __func__, st_vars->dst_y_prefetch_oto);
-       dml_print("DML::%s: dst_y_prefetch_equ = %f\n", __func__, st_vars->dst_y_prefetch_equ);
+       dml_print("DML::%s: Tvm_trips = %f\n", __func__, Tvm_trips);
+       dml_print("DML::%s: Tr0_trips = %f\n", __func__, Tr0_trips);
+       dml_print("DML::%s: prefetch_bw_oto = %f\n", __func__, prefetch_bw_oto);
+       dml_print("DML::%s: Tr0_oto = %f\n", __func__, Tr0_oto);
+       dml_print("DML::%s: Tvm_oto = %f\n", __func__, Tvm_oto);
+       dml_print("DML::%s: Tvm_oto_lines = %f\n", __func__, Tvm_oto_lines);
+       dml_print("DML::%s: Tr0_oto_lines = %f\n", __func__, Tr0_oto_lines);
+       dml_print("DML::%s: Lsw_oto = %f\n", __func__, Lsw_oto);
+       dml_print("DML::%s: dst_y_prefetch_oto = %f\n", __func__, dst_y_prefetch_oto);
+       dml_print("DML::%s: dst_y_prefetch_equ = %f\n", __func__, dst_y_prefetch_equ);
 #endif
 
-       st_vars->dst_y_prefetch_equ = dml_floor(4.0 * (st_vars->dst_y_prefetch_equ + 0.125), 1) / 4.0;
-       st_vars->Tpre_rounded = st_vars->dst_y_prefetch_equ * st_vars->LineTime;
+       dst_y_prefetch_equ = dml_floor(4.0 * (dst_y_prefetch_equ + 0.125), 1) / 4.0;
+       Tpre_rounded = dst_y_prefetch_equ * LineTime;
 #ifdef __DML_VBA_DEBUG__
-       dml_print("DML::%s: dst_y_prefetch_equ: %f (after round)\n", __func__, st_vars->dst_y_prefetch_equ);
-       dml_print("DML::%s: LineTime: %f\n", __func__, st_vars->LineTime);
+       dml_print("DML::%s: dst_y_prefetch_equ: %f (after round)\n", __func__, dst_y_prefetch_equ);
+       dml_print("DML::%s: LineTime: %f\n", __func__, LineTime);
        dml_print("DML::%s: VStartup: %d\n", __func__, VStartup);
        dml_print("DML::%s: Tvstartup: %fus - time between vstartup and first pixel of active\n",
-                       __func__, VStartup * st_vars->LineTime);
+                       __func__, VStartup * LineTime);
        dml_print("DML::%s: TSetup: %fus - time from vstartup to vready\n", __func__, *TSetup);
        dml_print("DML::%s: TCalc: %fus - time for calculations in dchub starting at vready\n", __func__, TCalc);
-       dml_print("DML::%s: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n", __func__, st_vars->Tdmbf);
-       dml_print("DML::%s: Tdmec: %fus - time dio takes to transfer dmd\n", __func__, st_vars->Tdmec);
+       dml_print("DML::%s: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n", __func__, Tdmbf);
+       dml_print("DML::%s: Tdmec: %fus - time dio takes to transfer dmd\n", __func__, Tdmec);
        dml_print("DML::%s: Tdmdl_vm: %fus - time for vm stages of dmd\n", __func__, *Tdmdl_vm);
        dml_print("DML::%s: Tdmdl: %fus - time for fabric to become ready and fetch dmd\n", __func__, *Tdmdl);
        dml_print("DML::%s: DSTYAfterScaler: %d lines - number of lines of pipeline and buffer delay after scaler\n",
                        __func__, *DSTYAfterScaler);
 #endif
-       st_vars->dep_bytes = dml_max(PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor,
+       dep_bytes = dml_max(PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor,
                        MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor);
 
-       if (st_vars->prefetch_sw_bytes < st_vars->dep_bytes)
-               st_vars->prefetch_sw_bytes = 2 * st_vars->dep_bytes;
+       if (prefetch_sw_bytes < dep_bytes)
+               prefetch_sw_bytes = 2 * dep_bytes;
 
        *PrefetchBandwidth = 0;
        *DestinationLinesToRequestVMInVBlank = 0;
@@ -3665,61 +3712,61 @@ bool dml32_CalculatePrefetchSchedule(
        *VRatioPrefetchY = 0;
        *VRatioPrefetchC = 0;
        *RequiredPrefetchPixDataBWLuma = 0;
-       if (st_vars->dst_y_prefetch_equ > 1) {
+       if (dst_y_prefetch_equ > 1) {
                double PrefetchBandwidth1;
                double PrefetchBandwidth2;
                double PrefetchBandwidth3;
                double PrefetchBandwidth4;
 
-               if (st_vars->Tpre_rounded - *Tno_bw > 0) {
+               if (Tpre_rounded - *Tno_bw > 0) {
                        PrefetchBandwidth1 = (PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor + 2 * MetaRowByte
                                        + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor
-                                       + st_vars->prefetch_sw_bytes) / (st_vars->Tpre_rounded - *Tno_bw);
-                       st_vars->Tsw_est1 = st_vars->prefetch_sw_bytes / PrefetchBandwidth1;
+                                       + prefetch_sw_bytes) / (Tpre_rounded - *Tno_bw);
+                       Tsw_est1 = prefetch_sw_bytes / PrefetchBandwidth1;
                } else
                        PrefetchBandwidth1 = 0;
 
-               if (VStartup == MaxVStartup && (st_vars->Tsw_est1 / st_vars->LineTime < st_vars->min_Lsw)
-                               && st_vars->Tpre_rounded - st_vars->min_Lsw * st_vars->LineTime - 0.75 * st_vars->LineTime - *Tno_bw > 0) {
+               if (VStartup == MaxVStartup && (Tsw_est1 / LineTime < min_Lsw)
+                               && Tpre_rounded - min_Lsw * LineTime - 0.75 * LineTime - *Tno_bw > 0) {
                        PrefetchBandwidth1 = (PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor + 2 * MetaRowByte
                                        + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor)
-                                       / (st_vars->Tpre_rounded - st_vars->min_Lsw * st_vars->LineTime - 0.75 * st_vars->LineTime - *Tno_bw);
+                                       / (Tpre_rounded - min_Lsw * LineTime - 0.75 * LineTime - *Tno_bw);
                }
 
-               if (st_vars->Tpre_rounded - *Tno_bw - 2 * st_vars->Tr0_trips_rounded > 0)
-                       PrefetchBandwidth2 = (PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor + st_vars->prefetch_sw_bytes) /
-                       (st_vars->Tpre_rounded - *Tno_bw - 2 * st_vars->Tr0_trips_rounded);
+               if (Tpre_rounded - *Tno_bw - 2 * Tr0_trips_rounded > 0)
+                       PrefetchBandwidth2 = (PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor + prefetch_sw_bytes) /
+                       (Tpre_rounded - *Tno_bw - 2 * Tr0_trips_rounded);
                else
                        PrefetchBandwidth2 = 0;
 
-               if (st_vars->Tpre_rounded - st_vars->Tvm_trips_rounded > 0) {
+               if (Tpre_rounded - Tvm_trips_rounded > 0) {
                        PrefetchBandwidth3 = (2 * MetaRowByte + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor
-                                       + st_vars->prefetch_sw_bytes) / (st_vars->Tpre_rounded - st_vars->Tvm_trips_rounded);
-                       st_vars->Tsw_est3 = st_vars->prefetch_sw_bytes / PrefetchBandwidth3;
+                                       + prefetch_sw_bytes) / (Tpre_rounded - Tvm_trips_rounded);
+                       Tsw_est3 = prefetch_sw_bytes / PrefetchBandwidth3;
                } else
                        PrefetchBandwidth3 = 0;
 
 
                if (VStartup == MaxVStartup &&
-                               (st_vars->Tsw_est3 / st_vars->LineTime < st_vars->min_Lsw) && st_vars->Tpre_rounded - st_vars->min_Lsw * st_vars->LineTime - 0.75 *
-                               st_vars->LineTime - st_vars->Tvm_trips_rounded > 0) {
+                               (Tsw_est3 / LineTime < min_Lsw) && Tpre_rounded - min_Lsw * LineTime - 0.75 *
+                               LineTime - Tvm_trips_rounded > 0) {
                        PrefetchBandwidth3 = (2 * MetaRowByte + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor)
-                                       / (st_vars->Tpre_rounded - st_vars->min_Lsw * st_vars->LineTime - 0.75 * st_vars->LineTime - st_vars->Tvm_trips_rounded);
+                                       / (Tpre_rounded - min_Lsw * LineTime - 0.75 * LineTime - Tvm_trips_rounded);
                }
 
-               if (st_vars->Tpre_rounded - st_vars->Tvm_trips_rounded - 2 * st_vars->Tr0_trips_rounded > 0) {
-                       PrefetchBandwidth4 = st_vars->prefetch_sw_bytes /
-                                       (st_vars->Tpre_rounded - st_vars->Tvm_trips_rounded - 2 * st_vars->Tr0_trips_rounded);
+               if (Tpre_rounded - Tvm_trips_rounded - 2 * Tr0_trips_rounded > 0) {
+                       PrefetchBandwidth4 = prefetch_sw_bytes /
+                                       (Tpre_rounded - Tvm_trips_rounded - 2 * Tr0_trips_rounded);
                } else {
                        PrefetchBandwidth4 = 0;
                }
 
 #ifdef __DML_VBA_DEBUG__
-               dml_print("DML::%s: Tpre_rounded: %f\n", __func__, st_vars->Tpre_rounded);
+               dml_print("DML::%s: Tpre_rounded: %f\n", __func__, Tpre_rounded);
                dml_print("DML::%s: Tno_bw: %f\n", __func__, *Tno_bw);
-               dml_print("DML::%s: Tvm_trips_rounded: %f\n", __func__, st_vars->Tvm_trips_rounded);
-               dml_print("DML::%s: Tsw_est1: %f\n", __func__, st_vars->Tsw_est1);
-               dml_print("DML::%s: Tsw_est3: %f\n", __func__, st_vars->Tsw_est3);
+               dml_print("DML::%s: Tvm_trips_rounded: %f\n", __func__, Tvm_trips_rounded);
+               dml_print("DML::%s: Tsw_est1: %f\n", __func__, Tsw_est1);
+               dml_print("DML::%s: Tsw_est3: %f\n", __func__, Tsw_est3);
                dml_print("DML::%s: PrefetchBandwidth1: %f\n", __func__, PrefetchBandwidth1);
                dml_print("DML::%s: PrefetchBandwidth2: %f\n", __func__, PrefetchBandwidth2);
                dml_print("DML::%s: PrefetchBandwidth3: %f\n", __func__, PrefetchBandwidth3);
@@ -3732,9 +3779,9 @@ bool dml32_CalculatePrefetchSchedule(
 
                        if (PrefetchBandwidth1 > 0) {
                                if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth1
-                                               >= st_vars->Tvm_trips_rounded
+                                               >= Tvm_trips_rounded
                                                && (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor)
-                                                               / PrefetchBandwidth1 >= st_vars->Tr0_trips_rounded) {
+                                                               / PrefetchBandwidth1 >= Tr0_trips_rounded) {
                                        Case1OK = true;
                                } else {
                                        Case1OK = false;
@@ -3745,9 +3792,9 @@ bool dml32_CalculatePrefetchSchedule(
 
                        if (PrefetchBandwidth2 > 0) {
                                if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth2
-                                               >= st_vars->Tvm_trips_rounded
+                                               >= Tvm_trips_rounded
                                                && (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor)
-                                               / PrefetchBandwidth2 < st_vars->Tr0_trips_rounded) {
+                                               / PrefetchBandwidth2 < Tr0_trips_rounded) {
                                        Case2OK = true;
                                } else {
                                        Case2OK = false;
@@ -3758,9 +3805,9 @@ bool dml32_CalculatePrefetchSchedule(
 
                        if (PrefetchBandwidth3 > 0) {
                                if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth3 <
-                                               st_vars->Tvm_trips_rounded && (MetaRowByte + PixelPTEBytesPerRow *
+                                               Tvm_trips_rounded && (MetaRowByte + PixelPTEBytesPerRow *
                                                                HostVMInefficiencyFactor) / PrefetchBandwidth3 >=
-                                                               st_vars->Tr0_trips_rounded) {
+                                                               Tr0_trips_rounded) {
                                        Case3OK = true;
                                } else {
                                        Case3OK = false;
@@ -3770,80 +3817,80 @@ bool dml32_CalculatePrefetchSchedule(
                        }
 
                        if (Case1OK)
-                               st_vars->prefetch_bw_equ = PrefetchBandwidth1;
+                               prefetch_bw_equ = PrefetchBandwidth1;
                        else if (Case2OK)
-                               st_vars->prefetch_bw_equ = PrefetchBandwidth2;
+                               prefetch_bw_equ = PrefetchBandwidth2;
                        else if (Case3OK)
-                               st_vars->prefetch_bw_equ = PrefetchBandwidth3;
+                               prefetch_bw_equ = PrefetchBandwidth3;
                        else
-                               st_vars->prefetch_bw_equ = PrefetchBandwidth4;
+                               prefetch_bw_equ = PrefetchBandwidth4;
 
 #ifdef __DML_VBA_DEBUG__
                        dml_print("DML::%s: Case1OK: %d\n", __func__, Case1OK);
                        dml_print("DML::%s: Case2OK: %d\n", __func__, Case2OK);
                        dml_print("DML::%s: Case3OK: %d\n", __func__, Case3OK);
-                       dml_print("DML::%s: prefetch_bw_equ: %f\n", __func__, st_vars->prefetch_bw_equ);
+                       dml_print("DML::%s: prefetch_bw_equ: %f\n", __func__, prefetch_bw_equ);
 #endif
 
-                       if (st_vars->prefetch_bw_equ > 0) {
+                       if (prefetch_bw_equ > 0) {
                                if (GPUVMEnable == true) {
-                                       st_vars->Tvm_equ = dml_max3(*Tno_bw + PDEAndMetaPTEBytesFrame *
-                                                       HostVMInefficiencyFactor / st_vars->prefetch_bw_equ,
-                                                       st_vars->Tvm_trips, st_vars->LineTime / 4);
+                                       Tvm_equ = dml_max3(*Tno_bw + PDEAndMetaPTEBytesFrame *
+                                                       HostVMInefficiencyFactor / prefetch_bw_equ,
+                                                       Tvm_trips, LineTime / 4);
                                } else {
-                                       st_vars->Tvm_equ = st_vars->LineTime / 4;
+                                       Tvm_equ = LineTime / 4;
                                }
 
                                if ((GPUVMEnable == true || myPipe->DCCEnable == true)) {
-                                       st_vars->Tr0_equ = dml_max4((MetaRowByte + PixelPTEBytesPerRow *
-                                                       HostVMInefficiencyFactor) / st_vars->prefetch_bw_equ, st_vars->Tr0_trips,
-                                                       (st_vars->LineTime - st_vars->Tvm_equ) / 2, st_vars->LineTime / 4);
+                                       Tr0_equ = dml_max4((MetaRowByte + PixelPTEBytesPerRow *
+                                                       HostVMInefficiencyFactor) / prefetch_bw_equ, Tr0_trips,
+                                                       (LineTime - Tvm_equ) / 2, LineTime / 4);
                                } else {
-                                       st_vars->Tr0_equ = (st_vars->LineTime - st_vars->Tvm_equ) / 2;
+                                       Tr0_equ = (LineTime - Tvm_equ) / 2;
                                }
                        } else {
-                               st_vars->Tvm_equ = 0;
-                               st_vars->Tr0_equ = 0;
+                               Tvm_equ = 0;
+                               Tr0_equ = 0;
 #ifdef __DML_VBA_DEBUG__
                                dml_print("DML: prefetch_bw_equ equals 0! %s:%d\n", __FILE__, __LINE__);
 #endif
                        }
                }
 
-               if (st_vars->dst_y_prefetch_oto < st_vars->dst_y_prefetch_equ) {
-                       *DestinationLinesForPrefetch = st_vars->dst_y_prefetch_oto;
-                       st_vars->TimeForFetchingMetaPTE = st_vars->Tvm_oto;
-                       st_vars->TimeForFetchingRowInVBlank = st_vars->Tr0_oto;
-                       *PrefetchBandwidth = st_vars->prefetch_bw_oto;
+               if (dst_y_prefetch_oto < dst_y_prefetch_equ) {
+                       *DestinationLinesForPrefetch = dst_y_prefetch_oto;
+                       TimeForFetchingMetaPTE = Tvm_oto;
+                       TimeForFetchingRowInVBlank = Tr0_oto;
+                       *PrefetchBandwidth = prefetch_bw_oto;
                } else {
-                       *DestinationLinesForPrefetch = st_vars->dst_y_prefetch_equ;
-                       st_vars->TimeForFetchingMetaPTE = st_vars->Tvm_equ;
-                       st_vars->TimeForFetchingRowInVBlank = st_vars->Tr0_equ;
-                       *PrefetchBandwidth = st_vars->prefetch_bw_equ;
+                       *DestinationLinesForPrefetch = dst_y_prefetch_equ;
+                       TimeForFetchingMetaPTE = Tvm_equ;
+                       TimeForFetchingRowInVBlank = Tr0_equ;
+                       *PrefetchBandwidth = prefetch_bw_equ;
                }
 
-               *DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * st_vars->TimeForFetchingMetaPTE / st_vars->LineTime, 1.0) / 4.0;
+               *DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * TimeForFetchingMetaPTE / LineTime, 1.0) / 4.0;
 
                *DestinationLinesToRequestRowInVBlank =
-                               dml_ceil(4.0 * st_vars->TimeForFetchingRowInVBlank / st_vars->LineTime, 1.0) / 4.0;
+                               dml_ceil(4.0 * TimeForFetchingRowInVBlank / LineTime, 1.0) / 4.0;
 
-               st_vars->LinesToRequestPrefetchPixelData = *DestinationLinesForPrefetch -
+               LinesToRequestPrefetchPixelData = *DestinationLinesForPrefetch -
                                *DestinationLinesToRequestVMInVBlank - 2 * *DestinationLinesToRequestRowInVBlank;
 
 #ifdef __DML_VBA_DEBUG__
                dml_print("DML::%s: DestinationLinesForPrefetch = %f\n", __func__, *DestinationLinesForPrefetch);
                dml_print("DML::%s: DestinationLinesToRequestVMInVBlank = %f\n",
                                __func__, *DestinationLinesToRequestVMInVBlank);
-               dml_print("DML::%s: TimeForFetchingRowInVBlank = %f\n", __func__, st_vars->TimeForFetchingRowInVBlank);
-               dml_print("DML::%s: LineTime = %f\n", __func__, st_vars->LineTime);
+               dml_print("DML::%s: TimeForFetchingRowInVBlank = %f\n", __func__, TimeForFetchingRowInVBlank);
+               dml_print("DML::%s: LineTime = %f\n", __func__, LineTime);
                dml_print("DML::%s: DestinationLinesToRequestRowInVBlank = %f\n",
                                __func__, *DestinationLinesToRequestRowInVBlank);
                dml_print("DML::%s: PrefetchSourceLinesY = %f\n", __func__, PrefetchSourceLinesY);
-               dml_print("DML::%s: LinesToRequestPrefetchPixelData = %f\n", __func__, st_vars->LinesToRequestPrefetchPixelData);
+               dml_print("DML::%s: LinesToRequestPrefetchPixelData = %f\n", __func__, LinesToRequestPrefetchPixelData);
 #endif
 
-               if (st_vars->LinesToRequestPrefetchPixelData >= 1 && st_vars->prefetch_bw_equ > 0) {
-                       *VRatioPrefetchY = (double) PrefetchSourceLinesY / st_vars->LinesToRequestPrefetchPixelData;
+               if (LinesToRequestPrefetchPixelData >= 1 && prefetch_bw_equ > 0) {
+                       *VRatioPrefetchY = (double) PrefetchSourceLinesY / LinesToRequestPrefetchPixelData;
                        *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
 #ifdef __DML_VBA_DEBUG__
                        dml_print("DML::%s: VRatioPrefetchY = %f\n", __func__, *VRatioPrefetchY);
@@ -3851,12 +3898,12 @@ bool dml32_CalculatePrefetchSchedule(
                        dml_print("DML::%s: VInitPreFillY = %d\n", __func__, VInitPreFillY);
 #endif
                        if ((SwathHeightY > 4) && (VInitPreFillY > 3)) {
-                               if (st_vars->LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) {
+                               if (LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) {
                                        *VRatioPrefetchY =
                                                        dml_max((double) PrefetchSourceLinesY /
-                                                                       st_vars->LinesToRequestPrefetchPixelData,
+                                                                       LinesToRequestPrefetchPixelData,
                                                                        (double) MaxNumSwathY * SwathHeightY /
-                                                                       (st_vars->LinesToRequestPrefetchPixelData -
+                                                                       (LinesToRequestPrefetchPixelData -
                                                                        (VInitPreFillY - 3.0) / 2.0));
                                        *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
                                } else {
@@ -3870,7 +3917,7 @@ bool dml32_CalculatePrefetchSchedule(
 #endif
                        }
 
-                       *VRatioPrefetchC = (double) PrefetchSourceLinesC / st_vars->LinesToRequestPrefetchPixelData;
+                       *VRatioPrefetchC = (double) PrefetchSourceLinesC / LinesToRequestPrefetchPixelData;
                        *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
 
 #ifdef __DML_VBA_DEBUG__
@@ -3879,11 +3926,11 @@ bool dml32_CalculatePrefetchSchedule(
                        dml_print("DML::%s: VInitPreFillC = %d\n", __func__, VInitPreFillC);
 #endif
                        if ((SwathHeightC > 4)) {
-                               if (st_vars->LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) {
+                               if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) {
                                        *VRatioPrefetchC =
                                                dml_max(*VRatioPrefetchC,
                                                        (double) MaxNumSwathC * SwathHeightC /
-                                                       (st_vars->LinesToRequestPrefetchPixelData -
+                                                       (LinesToRequestPrefetchPixelData -
                                                        (VInitPreFillC - 3.0) / 2.0));
                                        *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
                                } else {
@@ -3898,25 +3945,25 @@ bool dml32_CalculatePrefetchSchedule(
                        }
 
                        *RequiredPrefetchPixDataBWLuma = (double) PrefetchSourceLinesY
-                                       / st_vars->LinesToRequestPrefetchPixelData * myPipe->BytePerPixelY * swath_width_luma_ub
-                                       / st_vars->LineTime;
+                                       / LinesToRequestPrefetchPixelData * myPipe->BytePerPixelY * swath_width_luma_ub
+                                       / LineTime;
 
 #ifdef __DML_VBA_DEBUG__
                        dml_print("DML::%s: BytePerPixelY = %d\n", __func__, myPipe->BytePerPixelY);
                        dml_print("DML::%s: swath_width_luma_ub = %d\n", __func__, swath_width_luma_ub);
-                       dml_print("DML::%s: LineTime = %f\n", __func__, st_vars->LineTime);
+                       dml_print("DML::%s: LineTime = %f\n", __func__, LineTime);
                        dml_print("DML::%s: RequiredPrefetchPixDataBWLuma = %f\n",
                                        __func__, *RequiredPrefetchPixDataBWLuma);
 #endif
                        *RequiredPrefetchPixDataBWChroma = (double) PrefetchSourceLinesC /
-                                       st_vars->LinesToRequestPrefetchPixelData
+                                       LinesToRequestPrefetchPixelData
                                        * myPipe->BytePerPixelC
-                                       * swath_width_chroma_ub / st_vars->LineTime;
+                                       * swath_width_chroma_ub / LineTime;
                } else {
                        MyError = true;
 #ifdef __DML_VBA_DEBUG__
                        dml_print("DML:%s: MyErr set. LinesToRequestPrefetchPixelData: %f, should be > 0\n",
-                                       __func__, st_vars->LinesToRequestPrefetchPixelData);
+                                       __func__, LinesToRequestPrefetchPixelData);
 #endif
                        *VRatioPrefetchY = 0;
                        *VRatioPrefetchC = 0;
@@ -3925,15 +3972,15 @@ bool dml32_CalculatePrefetchSchedule(
                }
 #ifdef __DML_VBA_DEBUG__
                dml_print("DML: Tpre: %fus - sum of time to request meta pte, 2 x data pte + meta data, swaths\n",
-                       (double)st_vars->LinesToRequestPrefetchPixelData * st_vars->LineTime +
-                       2.0*st_vars->TimeForFetchingRowInVBlank + st_vars->TimeForFetchingMetaPTE);
-               dml_print("DML:  Tvm: %fus - time to fetch page tables for meta surface\n", st_vars->TimeForFetchingMetaPTE);
+                       (double)LinesToRequestPrefetchPixelData * LineTime +
+                       2.0*TimeForFetchingRowInVBlank + TimeForFetchingMetaPTE);
+               dml_print("DML:  Tvm: %fus - time to fetch page tables for meta surface\n", TimeForFetchingMetaPTE);
                dml_print("DML: To: %fus - time for propagation from scaler to optc\n",
-                       (*DSTYAfterScaler + ((double) (*DSTXAfterScaler) / (double) myPipe->HTotal)) * st_vars->LineTime);
+                       (*DSTYAfterScaler + ((double) (*DSTXAfterScaler) / (double) myPipe->HTotal)) * LineTime);
                dml_print("DML: Tvstartup - TSetup - Tcalc - Twait - Tpre - To > 0\n");
-               dml_print("DML: Tslack(pre): %fus - time left over in schedule\n", VStartup * st_vars->LineTime -
-                       st_vars->TimeForFetchingMetaPTE - 2*st_vars->TimeForFetchingRowInVBlank - (*DSTYAfterScaler +
-                       ((double) (*DSTXAfterScaler) / (double) myPipe->HTotal)) * st_vars->LineTime - TWait - TCalc - *TSetup);
+               dml_print("DML: Tslack(pre): %fus - time left over in schedule\n", VStartup * LineTime -
+                       TimeForFetchingMetaPTE - 2*TimeForFetchingRowInVBlank - (*DSTYAfterScaler +
+                       ((double) (*DSTXAfterScaler) / (double) myPipe->HTotal)) * LineTime - TWait - TCalc - *TSetup);
                dml_print("DML: row_bytes = dpte_row_bytes (per_pipe) = PixelPTEBytesPerRow = : %d\n",
                                PixelPTEBytesPerRow);
 #endif
@@ -3941,7 +3988,7 @@ bool dml32_CalculatePrefetchSchedule(
                MyError = true;
 #ifdef __DML_VBA_DEBUG__
                dml_print("DML::%s: MyErr set, dst_y_prefetch_equ = %f (should be > 1)\n",
-                               __func__, st_vars->dst_y_prefetch_equ);
+                               __func__, dst_y_prefetch_equ);
 #endif
        }
 
@@ -3957,10 +4004,10 @@ bool dml32_CalculatePrefetchSchedule(
                        dml_print("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, HostVMInefficiencyFactor);
                        dml_print("DML::%s: DestinationLinesToRequestVMInVBlank = %f\n",
                                        __func__, *DestinationLinesToRequestVMInVBlank);
-                       dml_print("DML::%s: LineTime = %f\n", __func__, st_vars->LineTime);
+                       dml_print("DML::%s: LineTime = %f\n", __func__, LineTime);
 #endif
                        prefetch_vm_bw = PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor /
-                                       (*DestinationLinesToRequestVMInVBlank * st_vars->LineTime);
+                                       (*DestinationLinesToRequestVMInVBlank * LineTime);
 #ifdef __DML_VBA_DEBUG__
                        dml_print("DML::%s: prefetch_vm_bw = %f\n", __func__, prefetch_vm_bw);
 #endif
@@ -3977,7 +4024,7 @@ bool dml32_CalculatePrefetchSchedule(
                        prefetch_row_bw = 0;
                } else if (*DestinationLinesToRequestRowInVBlank > 0) {
                        prefetch_row_bw = (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) /
-                                       (*DestinationLinesToRequestRowInVBlank * st_vars->LineTime);
+                                       (*DestinationLinesToRequestRowInVBlank * LineTime);
 
 #ifdef __DML_VBA_DEBUG__
                        dml_print("DML::%s: MetaRowByte = %d\n", __func__, MetaRowByte);
@@ -4000,12 +4047,12 @@ bool dml32_CalculatePrefetchSchedule(
 
        if (MyError) {
                *PrefetchBandwidth = 0;
-               st_vars->TimeForFetchingMetaPTE = 0;
-               st_vars->TimeForFetchingRowInVBlank = 0;
+               TimeForFetchingMetaPTE = 0;
+               TimeForFetchingRowInVBlank = 0;
                *DestinationLinesToRequestVMInVBlank = 0;
                *DestinationLinesToRequestRowInVBlank = 0;
                *DestinationLinesForPrefetch = 0;
-               st_vars->LinesToRequestPrefetchPixelData = 0;
+               LinesToRequestPrefetchPixelData = 0;
                *VRatioPrefetchY = 0;
                *VRatioPrefetchC = 0;
                *RequiredPrefetchPixDataBWLuma = 0;
@@ -4159,7 +4206,6 @@ void dml32_CalculateFlipSchedule(
 } // CalculateFlipSchedule
 
 void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
-               struct dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport *st_vars,
                bool USRRetrainingRequiredFinal,
                enum dm_use_mall_for_pstate_change_mode UseMALLForPStateChange[],
                unsigned int PrefetchMode,
@@ -4221,15 +4267,37 @@ void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
                double ActiveDRAMClockChangeLatencyMargin[])
 {
        unsigned int i, j, k;
-
-       st_vars->SurfaceWithMinActiveFCLKChangeMargin = 0;
-       st_vars->DRAMClockChangeSupportNumber = 0;
-       st_vars->DRAMClockChangeMethod = 0;
-       st_vars->FoundFirstSurfaceWithMinActiveFCLKChangeMargin = false;
-       st_vars->MinActiveFCLKChangeMargin = 0.;
-       st_vars->SecondMinActiveFCLKChangeMarginOneDisplayInVBLank = 0.;
-       st_vars->TotalPixelBW = 0.0;
-       st_vars->TotalActiveWriteback = 0;
+       unsigned int SurfaceWithMinActiveFCLKChangeMargin = 0;
+       unsigned int DRAMClockChangeSupportNumber = 0;
+       unsigned int LastSurfaceWithoutMargin;
+       unsigned int DRAMClockChangeMethod = 0;
+       bool FoundFirstSurfaceWithMinActiveFCLKChangeMargin = false;
+       double MinActiveFCLKChangeMargin = 0.;
+       double SecondMinActiveFCLKChangeMarginOneDisplayInVBLank = 0.;
+       double ActiveClockChangeLatencyHidingY;
+       double ActiveClockChangeLatencyHidingC;
+       double ActiveClockChangeLatencyHiding;
+    double EffectiveDETBufferSizeY;
+       double     ActiveFCLKChangeLatencyMargin[DC__NUM_DPP__MAX];
+       double     USRRetrainingLatencyMargin[DC__NUM_DPP__MAX];
+       double TotalPixelBW = 0.0;
+       bool    SynchronizedSurfaces[DC__NUM_DPP__MAX][DC__NUM_DPP__MAX];
+       double     EffectiveLBLatencyHidingY;
+       double     EffectiveLBLatencyHidingC;
+       double     LinesInDETY[DC__NUM_DPP__MAX];
+       double     LinesInDETC[DC__NUM_DPP__MAX];
+       unsigned int    LinesInDETYRoundedDownToSwath[DC__NUM_DPP__MAX];
+       unsigned int    LinesInDETCRoundedDownToSwath[DC__NUM_DPP__MAX];
+       double     FullDETBufferingTimeY;
+       double     FullDETBufferingTimeC;
+       double     WritebackDRAMClockChangeLatencyMargin;
+       double     WritebackFCLKChangeLatencyMargin;
+       double     WritebackLatencyHiding;
+       bool    SameTimingForFCLKChange;
+
+       unsigned int    TotalActiveWriteback = 0;
+       unsigned int LBLatencyHidingSourceLinesY[DC__NUM_DPP__MAX];
+       unsigned int LBLatencyHidingSourceLinesC[DC__NUM_DPP__MAX];
 
        Watermark->UrgentWatermark = mmSOCParameters.UrgentLatency + mmSOCParameters.ExtraLatency;
        Watermark->USRRetrainingWatermark = mmSOCParameters.UrgentLatency + mmSOCParameters.ExtraLatency
@@ -4261,13 +4329,13 @@ void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
 #endif
 
 
-       st_vars->TotalActiveWriteback = 0;
+       TotalActiveWriteback = 0;
        for (k = 0; k < NumberOfActiveSurfaces; ++k) {
                if (WritebackEnable[k] == true)
-                       st_vars->TotalActiveWriteback = st_vars->TotalActiveWriteback + 1;
+                       TotalActiveWriteback = TotalActiveWriteback + 1;
        }
 
-       if (st_vars->TotalActiveWriteback <= 1) {
+       if (TotalActiveWriteback <= 1) {
                Watermark->WritebackUrgentWatermark = mmSOCParameters.WritebackLatency;
        } else {
                Watermark->WritebackUrgentWatermark = mmSOCParameters.WritebackLatency
@@ -4277,7 +4345,7 @@ void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
                Watermark->WritebackUrgentWatermark = Watermark->WritebackUrgentWatermark
                                + mmSOCParameters.USRRetrainingLatency;
 
-       if (st_vars->TotalActiveWriteback <= 1) {
+       if (TotalActiveWriteback <= 1) {
                Watermark->WritebackDRAMClockChangeWatermark = mmSOCParameters.DRAMClockChangeLatency
                                + mmSOCParameters.WritebackLatency;
                Watermark->WritebackFCLKChangeWatermark = mmSOCParameters.FCLKChangeLatency
@@ -4307,14 +4375,14 @@ void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
 #endif
 
        for (k = 0; k < NumberOfActiveSurfaces; ++k) {
-               st_vars->TotalPixelBW = st_vars->TotalPixelBW + DPPPerSurface[k] * (SwathWidthY[k] * BytePerPixelDETY[k] * VRatio[k] +
+               TotalPixelBW = TotalPixelBW + DPPPerSurface[k] * (SwathWidthY[k] * BytePerPixelDETY[k] * VRatio[k] +
                                SwathWidthC[k] * BytePerPixelDETC[k] * VRatioChroma[k]) / (HTotal[k] / PixelClock[k]);
        }
 
        for (k = 0; k < NumberOfActiveSurfaces; ++k) {
 
-               st_vars->LBLatencyHidingSourceLinesY[k] = dml_min((double) MaxLineBufferLines, dml_floor(LineBufferSize / LBBitPerPixel[k] / (SwathWidthY[k] / dml_max(HRatio[k], 1.0)), 1)) - (VTaps[k] - 1);
-               st_vars->LBLatencyHidingSourceLinesC[k] = dml_min((double) MaxLineBufferLines, dml_floor(LineBufferSize / LBBitPerPixel[k] / (SwathWidthC[k] / dml_max(HRatioChroma[k], 1.0)), 1)) - (VTapsChroma[k] - 1);
+               LBLatencyHidingSourceLinesY[k] = dml_min((double) MaxLineBufferLines, dml_floor(LineBufferSize / LBBitPerPixel[k] / (SwathWidthY[k] / dml_max(HRatio[k], 1.0)), 1)) - (VTaps[k] - 1);
+               LBLatencyHidingSourceLinesC[k] = dml_min((double) MaxLineBufferLines, dml_floor(LineBufferSize / LBBitPerPixel[k] / (SwathWidthC[k] / dml_max(HRatioChroma[k], 1.0)), 1)) - (VTapsChroma[k] - 1);
 
 
 #ifdef __DML_VBA_DEBUG__
@@ -4325,72 +4393,72 @@ void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
                dml_print("DML::%s: k=%d, VTaps              = %d\n", __func__, k, VTaps[k]);
 #endif
 
-               st_vars->EffectiveLBLatencyHidingY = st_vars->LBLatencyHidingSourceLinesY[k] / VRatio[k] * (HTotal[k] / PixelClock[k]);
-               st_vars->EffectiveLBLatencyHidingC = st_vars->LBLatencyHidingSourceLinesC[k] / VRatioChroma[k] * (HTotal[k] / PixelClock[k]);
-               st_vars->EffectiveDETBufferSizeY = DETBufferSizeY[k];
+               EffectiveLBLatencyHidingY = LBLatencyHidingSourceLinesY[k] / VRatio[k] * (HTotal[k] / PixelClock[k]);
+               EffectiveLBLatencyHidingC = LBLatencyHidingSourceLinesC[k] / VRatioChroma[k] * (HTotal[k] / PixelClock[k]);
+               EffectiveDETBufferSizeY = DETBufferSizeY[k];
 
                if (UnboundedRequestEnabled) {
-                       st_vars->EffectiveDETBufferSizeY = st_vars->EffectiveDETBufferSizeY
+                       EffectiveDETBufferSizeY = EffectiveDETBufferSizeY
                                        + CompressedBufferSizeInkByte * 1024
                                                        * (SwathWidthY[k] * BytePerPixelDETY[k] * VRatio[k])
-                                                       / (HTotal[k] / PixelClock[k]) / st_vars->TotalPixelBW;
+                                                       / (HTotal[k] / PixelClock[k]) / TotalPixelBW;
                }
 
-               st_vars->LinesInDETY[k] = (double) st_vars->EffectiveDETBufferSizeY / BytePerPixelDETY[k] / SwathWidthY[k];
-               st_vars->LinesInDETYRoundedDownToSwath[k] = dml_floor(st_vars->LinesInDETY[k], SwathHeightY[k]);
-               st_vars->FullDETBufferingTimeY = st_vars->LinesInDETYRoundedDownToSwath[k] * (HTotal[k] / PixelClock[k]) / VRatio[k];
+               LinesInDETY[k] = (double) EffectiveDETBufferSizeY / BytePerPixelDETY[k] / SwathWidthY[k];
+               LinesInDETYRoundedDownToSwath[k] = dml_floor(LinesInDETY[k], SwathHeightY[k]);
+               FullDETBufferingTimeY = LinesInDETYRoundedDownToSwath[k] * (HTotal[k] / PixelClock[k]) / VRatio[k];
 
-               st_vars->ActiveClockChangeLatencyHidingY = st_vars->EffectiveLBLatencyHidingY + st_vars->FullDETBufferingTimeY
+               ActiveClockChangeLatencyHidingY = EffectiveLBLatencyHidingY + FullDETBufferingTimeY
                                - (DSTXAfterScaler[k] / HTotal[k] + DSTYAfterScaler[k]) * HTotal[k] / PixelClock[k];
 
                if (NumberOfActiveSurfaces > 1) {
-                       st_vars->ActiveClockChangeLatencyHidingY = st_vars->ActiveClockChangeLatencyHidingY
+                       ActiveClockChangeLatencyHidingY = ActiveClockChangeLatencyHidingY
                                        - (1 - 1 / NumberOfActiveSurfaces) * SwathHeightY[k] * HTotal[k]
                                                        / PixelClock[k] / VRatio[k];
                }
 
                if (BytePerPixelDETC[k] > 0) {
-                       st_vars->LinesInDETC[k] = DETBufferSizeC[k] / BytePerPixelDETC[k] / SwathWidthC[k];
-                       st_vars->LinesInDETCRoundedDownToSwath[k] = dml_floor(st_vars->LinesInDETC[k], SwathHeightC[k]);
-                       st_vars->FullDETBufferingTimeC = st_vars->LinesInDETCRoundedDownToSwath[k] * (HTotal[k] / PixelClock[k])
+                       LinesInDETC[k] = DETBufferSizeC[k] / BytePerPixelDETC[k] / SwathWidthC[k];
+                       LinesInDETCRoundedDownToSwath[k] = dml_floor(LinesInDETC[k], SwathHeightC[k]);
+                       FullDETBufferingTimeC = LinesInDETCRoundedDownToSwath[k] * (HTotal[k] / PixelClock[k])
                                        / VRatioChroma[k];
-                       st_vars->ActiveClockChangeLatencyHidingC = st_vars->EffectiveLBLatencyHidingC + st_vars->FullDETBufferingTimeC
+                       ActiveClockChangeLatencyHidingC = EffectiveLBLatencyHidingC + FullDETBufferingTimeC
                                        - (DSTXAfterScaler[k] / HTotal[k] + DSTYAfterScaler[k]) * HTotal[k]
                                                        / PixelClock[k];
                        if (NumberOfActiveSurfaces > 1) {
-                               st_vars->ActiveClockChangeLatencyHidingC = st_vars->ActiveClockChangeLatencyHidingC
+                               ActiveClockChangeLatencyHidingC = ActiveClockChangeLatencyHidingC
                                                - (1 - 1 / NumberOfActiveSurfaces) * SwathHeightC[k] * HTotal[k]
                                                                / PixelClock[k] / VRatioChroma[k];
                        }
-                       st_vars->ActiveClockChangeLatencyHiding = dml_min(st_vars->ActiveClockChangeLatencyHidingY,
-                                       st_vars->ActiveClockChangeLatencyHidingC);
+                       ActiveClockChangeLatencyHiding = dml_min(ActiveClockChangeLatencyHidingY,
+                                       ActiveClockChangeLatencyHidingC);
                } else {
-                       st_vars->ActiveClockChangeLatencyHiding = st_vars->ActiveClockChangeLatencyHidingY;
+                       ActiveClockChangeLatencyHiding = ActiveClockChangeLatencyHidingY;
                }
 
-               ActiveDRAMClockChangeLatencyMargin[k] = st_vars->ActiveClockChangeLatencyHiding - Watermark->UrgentWatermark
+               ActiveDRAMClockChangeLatencyMargin[k] = ActiveClockChangeLatencyHiding - Watermark->UrgentWatermark
                                - Watermark->DRAMClockChangeWatermark;
-               st_vars->ActiveFCLKChangeLatencyMargin[k] = st_vars->ActiveClockChangeLatencyHiding - Watermark->UrgentWatermark
+               ActiveFCLKChangeLatencyMargin[k] = ActiveClockChangeLatencyHiding - Watermark->UrgentWatermark
                                - Watermark->FCLKChangeWatermark;
-               st_vars->USRRetrainingLatencyMargin[k] = st_vars->ActiveClockChangeLatencyHiding - Watermark->USRRetrainingWatermark;
+               USRRetrainingLatencyMargin[k] = ActiveClockChangeLatencyHiding - Watermark->USRRetrainingWatermark;
 
                if (WritebackEnable[k]) {
-                       st_vars->WritebackLatencyHiding = WritebackInterfaceBufferSize * 1024
+                       WritebackLatencyHiding = WritebackInterfaceBufferSize * 1024
                                        / (WritebackDestinationWidth[k] * WritebackDestinationHeight[k]
                                                        / (WritebackSourceHeight[k] * HTotal[k] / PixelClock[k]) * 4);
                        if (WritebackPixelFormat[k] == dm_444_64)
-                               st_vars->WritebackLatencyHiding = st_vars->WritebackLatencyHiding / 2;
+                               WritebackLatencyHiding = WritebackLatencyHiding / 2;
 
-                       st_vars->WritebackDRAMClockChangeLatencyMargin = st_vars->WritebackLatencyHiding
+                       WritebackDRAMClockChangeLatencyMargin = WritebackLatencyHiding
                                        - Watermark->WritebackDRAMClockChangeWatermark;
 
-                       st_vars->WritebackFCLKChangeLatencyMargin = st_vars->WritebackLatencyHiding
+                       WritebackFCLKChangeLatencyMargin = WritebackLatencyHiding
                                        - Watermark->WritebackFCLKChangeWatermark;
 
                        ActiveDRAMClockChangeLatencyMargin[k] = dml_min(ActiveDRAMClockChangeLatencyMargin[k],
-                                       st_vars->WritebackFCLKChangeLatencyMargin);
-                       st_vars->ActiveFCLKChangeLatencyMargin[k] = dml_min(st_vars->ActiveFCLKChangeLatencyMargin[k],
-                                       st_vars->WritebackDRAMClockChangeLatencyMargin);
+                                       WritebackFCLKChangeLatencyMargin);
+                       ActiveFCLKChangeLatencyMargin[k] = dml_min(ActiveFCLKChangeLatencyMargin[k],
+                                       WritebackDRAMClockChangeLatencyMargin);
                }
                MaxActiveDRAMClockChangeLatencySupported[k] =
                                (UseMALLForPStateChange[k] == dm_use_mall_pstate_change_phantom_pipe) ?
@@ -4409,41 +4477,41 @@ void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
                                        HTotal[i] == HTotal[j] && VTotal[i] == VTotal[j] &&
                                        VActive[i] == VActive[j]) || (SynchronizeDRRDisplaysForUCLKPStateChangeFinal &&
                                        (DRRDisplay[i] || DRRDisplay[j]))) {
-                               st_vars->SynchronizedSurfaces[i][j] = true;
+                               SynchronizedSurfaces[i][j] = true;
                        } else {
-                               st_vars->SynchronizedSurfaces[i][j] = false;
+                               SynchronizedSurfaces[i][j] = false;
                        }
                }
        }
 
        for (k = 0; k < NumberOfActiveSurfaces; ++k) {
                if ((UseMALLForPStateChange[k] != dm_use_mall_pstate_change_phantom_pipe) &&
-                               (!st_vars->FoundFirstSurfaceWithMinActiveFCLKChangeMargin ||
-                               st_vars->ActiveFCLKChangeLatencyMargin[k] < st_vars->MinActiveFCLKChangeMargin)) {
-                       st_vars->FoundFirstSurfaceWithMinActiveFCLKChangeMargin = true;
-                       st_vars->MinActiveFCLKChangeMargin = st_vars->ActiveFCLKChangeLatencyMargin[k];
-                       st_vars->SurfaceWithMinActiveFCLKChangeMargin = k;
+                               (!FoundFirstSurfaceWithMinActiveFCLKChangeMargin ||
+                               ActiveFCLKChangeLatencyMargin[k] < MinActiveFCLKChangeMargin)) {
+                       FoundFirstSurfaceWithMinActiveFCLKChangeMargin = true;
+                       MinActiveFCLKChangeMargin = ActiveFCLKChangeLatencyMargin[k];
+                       SurfaceWithMinActiveFCLKChangeMargin = k;
                }
        }
 
-       *MinActiveFCLKChangeLatencySupported = st_vars->MinActiveFCLKChangeMargin + mmSOCParameters.FCLKChangeLatency;
+       *MinActiveFCLKChangeLatencySupported = MinActiveFCLKChangeMargin + mmSOCParameters.FCLKChangeLatency;
 
-       st_vars->SameTimingForFCLKChange = true;
+       SameTimingForFCLKChange = true;
        for (k = 0; k < NumberOfActiveSurfaces; ++k) {
-               if (!st_vars->SynchronizedSurfaces[k][st_vars->SurfaceWithMinActiveFCLKChangeMargin]) {
+               if (!SynchronizedSurfaces[k][SurfaceWithMinActiveFCLKChangeMargin]) {
                        if ((UseMALLForPStateChange[k] != dm_use_mall_pstate_change_phantom_pipe) &&
-                                       (st_vars->SameTimingForFCLKChange ||
-                                       st_vars->ActiveFCLKChangeLatencyMargin[k] <
-                                       st_vars->SecondMinActiveFCLKChangeMarginOneDisplayInVBLank)) {
-                               st_vars->SecondMinActiveFCLKChangeMarginOneDisplayInVBLank = st_vars->ActiveFCLKChangeLatencyMargin[k];
+                                       (SameTimingForFCLKChange ||
+                                       ActiveFCLKChangeLatencyMargin[k] <
+                                       SecondMinActiveFCLKChangeMarginOneDisplayInVBLank)) {
+                               SecondMinActiveFCLKChangeMarginOneDisplayInVBLank = ActiveFCLKChangeLatencyMargin[k];
                        }
-                       st_vars->SameTimingForFCLKChange = false;
+                       SameTimingForFCLKChange = false;
                }
        }
 
-       if (st_vars->MinActiveFCLKChangeMargin > 0) {
+       if (MinActiveFCLKChangeMargin > 0) {
                *FCLKChangeSupport = dm_fclock_change_vactive;
-       } else if ((st_vars->SameTimingForFCLKChange || st_vars->SecondMinActiveFCLKChangeMarginOneDisplayInVBLank > 0) &&
+       } else if ((SameTimingForFCLKChange || SecondMinActiveFCLKChangeMarginOneDisplayInVBLank > 0) &&
                        (PrefetchMode <= 1)) {
                *FCLKChangeSupport = dm_fclock_change_vblank;
        } else {
@@ -4453,7 +4521,7 @@ void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
        *USRRetrainingSupport = true;
        for (k = 0; k < NumberOfActiveSurfaces; ++k) {
                if ((UseMALLForPStateChange[k] != dm_use_mall_pstate_change_phantom_pipe) &&
-                               (st_vars->USRRetrainingLatencyMargin[k] < 0)) {
+                               (USRRetrainingLatencyMargin[k] < 0)) {
                        *USRRetrainingSupport = false;
                }
        }
@@ -4464,42 +4532,42 @@ void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
                                UseMALLForPStateChange[k] != dm_use_mall_pstate_change_phantom_pipe &&
                                ActiveDRAMClockChangeLatencyMargin[k] < 0) {
                        if (PrefetchMode > 0) {
-                               st_vars->DRAMClockChangeSupportNumber = 2;
-                       } else if (st_vars->DRAMClockChangeSupportNumber == 0) {
-                               st_vars->DRAMClockChangeSupportNumber = 1;
-                               st_vars->LastSurfaceWithoutMargin = k;
-                       } else if (st_vars->DRAMClockChangeSupportNumber == 1 &&
-                                       !st_vars->SynchronizedSurfaces[st_vars->LastSurfaceWithoutMargin][k]) {
-                               st_vars->DRAMClockChangeSupportNumber = 2;
+                               DRAMClockChangeSupportNumber = 2;
+                       } else if (DRAMClockChangeSupportNumber == 0) {
+                               DRAMClockChangeSupportNumber = 1;
+                               LastSurfaceWithoutMargin = k;
+                       } else if (DRAMClockChangeSupportNumber == 1 &&
+                                       !SynchronizedSurfaces[LastSurfaceWithoutMargin][k]) {
+                               DRAMClockChangeSupportNumber = 2;
                        }
                }
        }
 
        for (k = 0; k < NumberOfActiveSurfaces; ++k) {
                if (UseMALLForPStateChange[k] == dm_use_mall_pstate_change_full_frame)
-                       st_vars->DRAMClockChangeMethod = 1;
+                       DRAMClockChangeMethod = 1;
                else if (UseMALLForPStateChange[k] == dm_use_mall_pstate_change_sub_viewport)
-                       st_vars->DRAMClockChangeMethod = 2;
+                       DRAMClockChangeMethod = 2;
        }
 
-       if (st_vars->DRAMClockChangeMethod == 0) {
-               if (st_vars->DRAMClockChangeSupportNumber == 0)
+       if (DRAMClockChangeMethod == 0) {
+               if (DRAMClockChangeSupportNumber == 0)
                        *DRAMClockChangeSupport = dm_dram_clock_change_vactive;
-               else if (st_vars->DRAMClockChangeSupportNumber == 1)
+               else if (DRAMClockChangeSupportNumber == 1)
                        *DRAMClockChangeSupport = dm_dram_clock_change_vblank;
                else
                        *DRAMClockChangeSupport = dm_dram_clock_change_unsupported;
-       } else if (st_vars->DRAMClockChangeMethod == 1) {
-               if (st_vars->DRAMClockChangeSupportNumber == 0)
+       } else if (DRAMClockChangeMethod == 1) {
+               if (DRAMClockChangeSupportNumber == 0)
                        *DRAMClockChangeSupport = dm_dram_clock_change_vactive_w_mall_full_frame;
-               else if (st_vars->DRAMClockChangeSupportNumber == 1)
+               else if (DRAMClockChangeSupportNumber == 1)
                        *DRAMClockChangeSupport = dm_dram_clock_change_vblank_w_mall_full_frame;
                else
                        *DRAMClockChangeSupport = dm_dram_clock_change_unsupported;
        } else {
-               if (st_vars->DRAMClockChangeSupportNumber == 0)
+               if (DRAMClockChangeSupportNumber == 0)
                        *DRAMClockChangeSupport = dm_dram_clock_change_vactive_w_mall_sub_vp;
-               else if (st_vars->DRAMClockChangeSupportNumber == 1)
+               else if (DRAMClockChangeSupportNumber == 1)
                        *DRAMClockChangeSupport = dm_dram_clock_change_vblank_w_mall_sub_vp;
                else
                        *DRAMClockChangeSupport = dm_dram_clock_change_unsupported;
@@ -4513,7 +4581,7 @@ void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
 
                dst_y_pstate = dml_ceil((mmSOCParameters.DRAMClockChangeLatency + mmSOCParameters.UrgentLatency) / (HTotal[k] / PixelClock[k]), 1);
                src_y_pstate_l = dml_ceil(dst_y_pstate * VRatio[k], SwathHeightY[k]);
-               src_y_ahead_l = dml_floor(DETBufferSizeY[k] / BytePerPixelDETY[k] / SwathWidthY[k], SwathHeightY[k]) + st_vars->LBLatencyHidingSourceLinesY[k];
+               src_y_ahead_l = dml_floor(DETBufferSizeY[k] / BytePerPixelDETY[k] / SwathWidthY[k], SwathHeightY[k]) + LBLatencyHidingSourceLinesY[k];
                sub_vp_lines_l = src_y_pstate_l + src_y_ahead_l + meta_row_height[k];
 
 #ifdef __DML_VBA_DEBUG__
@@ -4521,7 +4589,7 @@ dml_print("DML::%s: k=%d, DETBufferSizeY               = %d\n", __func__, k, DET
 dml_print("DML::%s: k=%d, BytePerPixelDETY             = %f\n", __func__, k, BytePerPixelDETY[k]);
 dml_print("DML::%s: k=%d, SwathWidthY                  = %d\n", __func__, k, SwathWidthY[k]);
 dml_print("DML::%s: k=%d, SwathHeightY                 = %d\n", __func__, k, SwathHeightY[k]);
-dml_print("DML::%s: k=%d, LBLatencyHidingSourceLinesY  = %d\n", __func__, k, st_vars->LBLatencyHidingSourceLinesY[k]);
+dml_print("DML::%s: k=%d, LBLatencyHidingSourceLinesY  = %d\n", __func__, k, LBLatencyHidingSourceLinesY[k]);
 dml_print("DML::%s: k=%d, dst_y_pstate      = %d\n", __func__, k, dst_y_pstate);
 dml_print("DML::%s: k=%d, src_y_pstate_l    = %d\n", __func__, k, src_y_pstate_l);
 dml_print("DML::%s: k=%d, src_y_ahead_l     = %d\n", __func__, k, src_y_ahead_l);
@@ -4532,7 +4600,7 @@ dml_print("DML::%s: k=%d, sub_vp_lines_l    = %d\n", __func__, k, sub_vp_lines_l
 
                if (BytePerPixelDETC[k] > 0) {
                        src_y_pstate_c = dml_ceil(dst_y_pstate * VRatioChroma[k], SwathHeightC[k]);
-                       src_y_ahead_c = dml_floor(DETBufferSizeC[k] / BytePerPixelDETC[k] / SwathWidthC[k], SwathHeightC[k]) + st_vars->LBLatencyHidingSourceLinesC[k];
+                       src_y_ahead_c = dml_floor(DETBufferSizeC[k] / BytePerPixelDETC[k] / SwathWidthC[k], SwathHeightC[k]) + LBLatencyHidingSourceLinesC[k];
                        sub_vp_lines_c = src_y_pstate_c + src_y_ahead_c + meta_row_height_chroma[k];
                        SubViewportLinesNeededInMALL[k] = dml_max(sub_vp_lines_l, sub_vp_lines_c);
 
index 37a314c..d293856 100644 (file)
@@ -30,7 +30,6 @@
 #include "os_types.h"
 #include "../dc_features.h"
 #include "../display_mode_structs.h"
-#include "dml/display_mode_vba.h"
 
 unsigned int dml32_dscceComputeDelay(
                unsigned int bpc,
@@ -82,7 +81,6 @@ void dml32_CalculateSinglePipeDPPCLKAndSCLThroughput(
                double *DPPCLKUsingSingleDPP);
 
 void dml32_CalculateSwathAndDETConfiguration(
-               struct dml32_CalculateSwathAndDETConfiguration *st_vars,
                unsigned int DETSizeOverride[],
                enum dm_use_mall_for_pstate_change_mode UseMALLForPStateChange[],
                unsigned int ConfigReturnBufferSizeInKByte,
@@ -362,7 +360,6 @@ void dml32_CalculateSurfaceSizeInMall(
                bool *ExceededMALLSize);
 
 void dml32_CalculateVMRowAndSwath(
-               struct dml32_CalculateVMRowAndSwath *st_vars,
                unsigned int NumberOfActiveSurfaces,
                DmlPipe myPipe[],
                unsigned int SurfaceSizeInMALL[],
@@ -715,7 +712,6 @@ double dml32_CalculateExtraLatency(
                unsigned int HostVMMaxNonCachedPageTableLevels);
 
 bool dml32_CalculatePrefetchSchedule(
-               struct dml32_CalculatePrefetchSchedule *st_vars,
                double HostVMInefficiencyFactor,
                DmlPipe *myPipe,
                unsigned int DSCDelay,
@@ -811,7 +807,6 @@ void dml32_CalculateFlipSchedule(
                bool *ImmediateFlipSupportedForPipe);
 
 void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
-               struct dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport *st_vars,
                bool USRRetrainingRequiredFinal,
                enum dm_use_mall_for_pstate_change_mode UseMALLForPStateChange[],
                unsigned int PrefetchMode,
index 84b4b00..c870916 100644 (file)
@@ -498,6 +498,13 @@ void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_p
                                dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
                }
 
+               if ((int)(dcn3_21_soc.fclk_change_latency_us * 1000)
+                               != dc->bb_overrides.fclk_clock_change_latency_ns
+                               && dc->bb_overrides.fclk_clock_change_latency_ns) {
+                       dcn3_21_soc.fclk_change_latency_us =
+                               dc->bb_overrides.fclk_clock_change_latency_ns / 1000;
+               }
+
                if ((int)(dcn3_21_soc.dummy_pstate_latency_us * 1000)
                                != dc->bb_overrides.dummy_clock_change_latency_ns
                                && dc->bb_overrides.dummy_clock_change_latency_ns) {
index 8460aef..492aec6 100644 (file)
@@ -182,108 +182,6 @@ void Calculate256BBlockSizes(
                unsigned int *BlockWidth256BytesY,
                unsigned int *BlockWidth256BytesC);
 
-struct dml32_CalculateSwathAndDETConfiguration {
-       unsigned int MaximumSwathHeightY[DC__NUM_DPP__MAX];
-       unsigned int MaximumSwathHeightC[DC__NUM_DPP__MAX];
-       unsigned int RoundedUpMaxSwathSizeBytesY[DC__NUM_DPP__MAX];
-       unsigned int RoundedUpMaxSwathSizeBytesC[DC__NUM_DPP__MAX];
-       unsigned int RoundedUpSwathSizeBytesY;
-       unsigned int RoundedUpSwathSizeBytesC;
-       double SwathWidthdoubleDPP[DC__NUM_DPP__MAX];
-       double SwathWidthdoubleDPPChroma[DC__NUM_DPP__MAX];
-       unsigned int TotalActiveDPP;
-       bool NoChromaSurfaces;
-       unsigned int DETBufferSizeInKByteForSwathCalculation;
-};
-
-struct dml32_CalculateVMRowAndSwath {
-       unsigned int PTEBufferSizeInRequestsForLuma[DC__NUM_DPP__MAX];
-       unsigned int PTEBufferSizeInRequestsForChroma[DC__NUM_DPP__MAX];
-       unsigned int PDEAndMetaPTEBytesFrameY;
-       unsigned int PDEAndMetaPTEBytesFrameC;
-       unsigned int MetaRowByteY[DC__NUM_DPP__MAX];
-       unsigned int MetaRowByteC[DC__NUM_DPP__MAX];
-       unsigned int PixelPTEBytesPerRowY[DC__NUM_DPP__MAX];
-       unsigned int PixelPTEBytesPerRowC[DC__NUM_DPP__MAX];
-       unsigned int PixelPTEBytesPerRowY_one_row_per_frame[DC__NUM_DPP__MAX];
-       unsigned int PixelPTEBytesPerRowC_one_row_per_frame[DC__NUM_DPP__MAX];
-       unsigned int dpte_row_width_luma_ub_one_row_per_frame[DC__NUM_DPP__MAX];
-       unsigned int dpte_row_height_luma_one_row_per_frame[DC__NUM_DPP__MAX];
-       unsigned int dpte_row_width_chroma_ub_one_row_per_frame[DC__NUM_DPP__MAX];
-       unsigned int dpte_row_height_chroma_one_row_per_frame[DC__NUM_DPP__MAX];
-       bool one_row_per_frame_fits_in_buffer[DC__NUM_DPP__MAX];
-};
-
-struct dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport {
-       unsigned int SurfaceWithMinActiveFCLKChangeMargin;
-       unsigned int DRAMClockChangeSupportNumber;
-       unsigned int LastSurfaceWithoutMargin;
-       unsigned int DRAMClockChangeMethod;
-       bool FoundFirstSurfaceWithMinActiveFCLKChangeMargin;
-       double MinActiveFCLKChangeMargin;
-       double SecondMinActiveFCLKChangeMarginOneDisplayInVBLank;
-       double ActiveClockChangeLatencyHidingY;
-       double ActiveClockChangeLatencyHidingC;
-       double ActiveClockChangeLatencyHiding;
-       double EffectiveDETBufferSizeY;
-       double ActiveFCLKChangeLatencyMargin[DC__NUM_DPP__MAX];
-       double USRRetrainingLatencyMargin[DC__NUM_DPP__MAX];
-       double TotalPixelBW;
-       bool SynchronizedSurfaces[DC__NUM_DPP__MAX][DC__NUM_DPP__MAX];
-       double EffectiveLBLatencyHidingY;
-       double EffectiveLBLatencyHidingC;
-       double LinesInDETY[DC__NUM_DPP__MAX];
-       double LinesInDETC[DC__NUM_DPP__MAX];
-       unsigned int LinesInDETYRoundedDownToSwath[DC__NUM_DPP__MAX];
-       unsigned int LinesInDETCRoundedDownToSwath[DC__NUM_DPP__MAX];
-       double FullDETBufferingTimeY;
-       double FullDETBufferingTimeC;
-       double WritebackDRAMClockChangeLatencyMargin;
-       double WritebackFCLKChangeLatencyMargin;
-       double WritebackLatencyHiding;
-       bool SameTimingForFCLKChange;
-       unsigned int TotalActiveWriteback;
-       unsigned int LBLatencyHidingSourceLinesY[DC__NUM_DPP__MAX];
-       unsigned int LBLatencyHidingSourceLinesC[DC__NUM_DPP__MAX];
-};
-
-struct dml32_CalculatePrefetchSchedule {
-       unsigned int DPPCycles, DISPCLKCycles;
-       double DSTTotalPixelsAfterScaler;
-       double LineTime;
-       double dst_y_prefetch_equ;
-       double prefetch_bw_oto;
-       double Tvm_oto;
-       double Tr0_oto;
-       double Tvm_oto_lines;
-       double Tr0_oto_lines;
-       double dst_y_prefetch_oto;
-       double TimeForFetchingMetaPTE;
-       double TimeForFetchingRowInVBlank;
-       double LinesToRequestPrefetchPixelData;
-       unsigned int HostVMDynamicLevelsTrips;
-       double trip_to_mem;
-       double Tvm_trips;
-       double Tr0_trips;
-       double Tvm_trips_rounded;
-       double Tr0_trips_rounded;
-       double Lsw_oto;
-       double Tpre_rounded;
-       double prefetch_bw_equ;
-       double Tvm_equ;
-       double Tr0_equ;
-       double Tdmbf;
-       double Tdmec;
-       double Tdmsks;
-       double prefetch_sw_bytes;
-       double bytes_pp;
-       double dep_bytes;
-       unsigned int max_vratio_pre;
-       double min_Lsw;
-       double Tsw_est1;
-       double Tsw_est3;
-};
-
 struct DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation {
        unsigned int dummy_integer_array[2][DC__NUM_DPP__MAX];
        double dummy_single_array[2][DC__NUM_DPP__MAX];
@@ -355,10 +253,6 @@ struct dummy_vars {
        struct DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation
        DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation;
        struct dml32_ModeSupportAndSystemConfigurationFull dml32_ModeSupportAndSystemConfigurationFull;
-       struct dml32_CalculateSwathAndDETConfiguration dml32_CalculateSwathAndDETConfiguration;
-       struct dml32_CalculateVMRowAndSwath dml32_CalculateVMRowAndSwath;
-       struct dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport;
-       struct dml32_CalculatePrefetchSchedule dml32_CalculatePrefetchSchedule;
 };
 
 struct vba_vars_st {
index ab06c7f..9f3558c 100644 (file)
@@ -244,13 +244,15 @@ enum {
 #define ASICREV_IS_GC_10_3_7(eChipRev) ((eChipRev >= GC_10_3_7_A0) && (eChipRev < GC_10_3_7_UNKNOWN))
 
 #define AMDGPU_FAMILY_GC_11_0_0 145
-#define AMDGPU_FAMILY_GC_11_0_2 148
+#define AMDGPU_FAMILY_GC_11_0_1 148
 #define GC_11_0_0_A0 0x1
 #define GC_11_0_2_A0 0x10
+#define GC_11_0_3_A0 0x20
 #define GC_11_UNKNOWN 0xFF
 
 #define ASICREV_IS_GC_11_0_0(eChipRev) (eChipRev < GC_11_0_2_A0)
-#define ASICREV_IS_GC_11_0_2(eChipRev) (eChipRev >= GC_11_0_2_A0 && eChipRev < GC_11_UNKNOWN)
+#define ASICREV_IS_GC_11_0_2(eChipRev) (eChipRev >= GC_11_0_2_A0 && eChipRev < GC_11_0_3_A0)
+#define ASICREV_IS_GC_11_0_3(eChipRev) (eChipRev >= GC_11_0_3_A0 && eChipRev < GC_11_UNKNOWN)
 
 /*
  * ASIC chip ID
index f093b49..3bf08a6 100644 (file)
@@ -119,13 +119,15 @@ enum dc_log_type {
        LOG_HDMI_RETIMER_REDRIVER,
        LOG_DSC,
        LOG_SMU_MSG,
+       LOG_DC2RESERVED4,
+       LOG_DC2RESERVED5,
        LOG_DWB,
        LOG_GAMMA_DEBUG,
        LOG_MAX_HW_POINTS,
        LOG_ALL_TF_CHANNELS,
        LOG_SAMPLE_1DLUT,
        LOG_DP2,
-       LOG_SECTION_TOTAL_COUNT
+       LOG_DC2RESERVED12,
 };
 
 #define DC_MIN_LOG_MASK ((1 << LOG_ERROR) | \
index da09ba7..0f39ab9 100644 (file)
@@ -613,10 +613,6 @@ static void build_vrr_infopacket_data_v1(const struct mod_vrr_params *vrr,
         * Note: We should never go above the field rate of the mode timing set.
         */
        infopacket->sb[8] = (unsigned char)((vrr->max_refresh_in_uhz + 500000) / 1000000);
-
-       /* FreeSync HDR */
-       infopacket->sb[9] = 0;
-       infopacket->sb[10] = 0;
 }
 
 static void build_vrr_infopacket_data_v3(const struct mod_vrr_params *vrr,
@@ -684,10 +680,6 @@ static void build_vrr_infopacket_data_v3(const struct mod_vrr_params *vrr,
 
        /* PB16 : Reserved bits 7:1, FixedRate bit 0 */
        infopacket->sb[16] = (vrr->state == VRR_STATE_ACTIVE_FIXED) ? 1 : 0;
-
-       //FreeSync HDR
-       infopacket->sb[9] = 0;
-       infopacket->sb[10] = 0;
 }
 
 static void build_vrr_infopacket_fs2_data(enum color_transfer_func app_tf,
@@ -772,8 +764,7 @@ static void build_vrr_infopacket_header_v2(enum signal_type signal,
                /* HB2  = [Bits 7:5 = 0] [Bits 4:0 = Length = 0x09] */
                infopacket->hb2 = 0x09;
 
-               *payload_size = 0x0A;
-
+               *payload_size = 0x09;
        } else if (dc_is_dp_signal(signal)) {
 
                /* HEADER */
@@ -822,9 +813,9 @@ static void build_vrr_infopacket_header_v3(enum signal_type signal,
                infopacket->hb1 = version;
 
                /* HB2  = [Bits 7:5 = 0] [Bits 4:0 = Length] */
-               *payload_size = 0x10;
-               infopacket->hb2 = *payload_size - 1; //-1 for checksum
+               infopacket->hb2 = 0x10;
 
+               *payload_size = 0x10;
        } else if (dc_is_dp_signal(signal)) {
 
                /* HEADER */
index 76f695a..ae2d337 100644 (file)
@@ -27,7 +27,7 @@
 // *** IMPORTANT ***
 // SMU TEAM: Always increment the interface version if
 // any structure is changed in this file
-#define PMFW_DRIVER_IF_VERSION 4
+#define PMFW_DRIVER_IF_VERSION 5
 
 typedef struct {
   int32_t value;
@@ -197,6 +197,8 @@ typedef struct {
 
   uint16_t SkinTemp;
   uint16_t DeviceState;
+  uint16_t CurTemp;                     //[centi-Celsius]
+  uint16_t spare2;
 } SmuMetrics_t;
 
 typedef struct {
index c02e5e5..6fe2fe9 100644 (file)
@@ -28,7 +28,7 @@
 #define SMU13_DRIVER_IF_VERSION_INV 0xFFFFFFFF
 #define SMU13_DRIVER_IF_VERSION_YELLOW_CARP 0x04
 #define SMU13_DRIVER_IF_VERSION_ALDE 0x08
-#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x04
+#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x05
 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04
 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0 0x2C
 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x2C
index fa520d7..6db67f0 100644 (file)
@@ -4283,6 +4283,7 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = {
        .dump_pptable = sienna_cichlid_dump_pptable,
        .init_microcode = smu_v11_0_init_microcode,
        .load_microcode = smu_v11_0_load_microcode,
+       .fini_microcode = smu_v11_0_fini_microcode,
        .init_smc_tables = sienna_cichlid_init_smc_tables,
        .fini_smc_tables = smu_v11_0_fini_smc_tables,
        .init_power = smu_v11_0_init_power,
index e8fe84f..18ee3b5 100644 (file)
@@ -212,6 +212,9 @@ int smu_v13_0_init_pptable_microcode(struct smu_context *smu)
        if (!adev->scpm_enabled)
                return 0;
 
+       if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 7))
+               return 0;
+
        /* override pptable_id from driver parameter */
        if (amdgpu_smu_pptable_id >= 0) {
                pptable_id = amdgpu_smu_pptable_id;
@@ -219,16 +222,10 @@ int smu_v13_0_init_pptable_microcode(struct smu_context *smu)
        } else {
                pptable_id = smu->smu_table.boot_values.pp_table_id;
 
-               if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 7) &&
-                       pptable_id == 3667)
-                       pptable_id = 36671;
-
-               if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 7) &&
-                       pptable_id == 3688)
-                       pptable_id = 36881;
                /*
                 * Temporary solution for SMU V13.0.0 with SCPM enabled:
                 *   - use 36831 signed pptable when pp_table_id is 3683
+                *   - use 37151 signed pptable when pp_table_id is 3715
                 *   - use 36641 signed pptable when pp_table_id is 3664 or 0
                 * TODO: drop these when the pptable carried in vbios is ready.
                 */
@@ -241,6 +238,9 @@ int smu_v13_0_init_pptable_microcode(struct smu_context *smu)
                        case 3683:
                                pptable_id = 36831;
                                break;
+                       case 3715:
+                               pptable_id = 37151;
+                               break;
                        default:
                                dev_err(adev->dev, "Unsupported pptable id %d\n", pptable_id);
                                return -EINVAL;
@@ -478,7 +478,7 @@ int smu_v13_0_setup_pptable(struct smu_context *smu)
 
                /*
                 * Temporary solution for SMU V13.0.0 with SCPM disabled:
-                *   - use 3664 or 3683 on request
+                *   - use 3664, 3683 or 3715 on request
                 *   - use 3664 when pptable_id is 0
                 * TODO: drop these when the pptable carried in vbios is ready.
                 */
@@ -489,6 +489,7 @@ int smu_v13_0_setup_pptable(struct smu_context *smu)
                                break;
                        case 3664:
                        case 3683:
+                       case 3715:
                                break;
                        default:
                                dev_err(adev->dev, "Unsupported pptable id %d\n", pptable_id);
@@ -2344,8 +2345,8 @@ int smu_v13_0_set_gfx_power_up_by_imu(struct smu_context *smu)
 
        index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG,
                                               SMU_MSG_EnableGfxImu);
-
-       return smu_cmn_send_msg_without_waiting(smu, index, 0);
+       /* Param 1 to tell PMFW to enable GFXOFF feature */
+       return smu_cmn_send_msg_without_waiting(smu, index, 1);
 }
 
 int smu_v13_0_od_edit_dpm_table(struct smu_context *smu,
index 1bbecee..df4a47a 100644 (file)
@@ -1792,7 +1792,9 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
        .dump_pptable = smu_v13_0_0_dump_pptable,
        .init_microcode = smu_v13_0_init_microcode,
        .load_microcode = smu_v13_0_load_microcode,
+       .fini_microcode = smu_v13_0_fini_microcode,
        .init_smc_tables = smu_v13_0_0_init_smc_tables,
+       .fini_smc_tables = smu_v13_0_fini_smc_tables,
        .init_power = smu_v13_0_init_power,
        .fini_power = smu_v13_0_fini_power,
        .check_fw_status = smu_v13_0_check_fw_status,
index 82d3718..97e1d55 100644 (file)
@@ -71,7 +71,6 @@ static struct cmn2asic_msg_mapping smu_v13_0_4_message_map[SMU_MSG_MAX_COUNT] =
        MSG_MAP(TestMessage,                    PPSMC_MSG_TestMessage,                  1),
        MSG_MAP(GetSmuVersion,                  PPSMC_MSG_GetPmfwVersion,               1),
        MSG_MAP(GetDriverIfVersion,             PPSMC_MSG_GetDriverIfVersion,           1),
-       MSG_MAP(EnableGfxOff,                   PPSMC_MSG_EnableGfxOff,                 1),
        MSG_MAP(AllowGfxOff,                    PPSMC_MSG_AllowGfxOff,                  1),
        MSG_MAP(DisallowGfxOff,                 PPSMC_MSG_DisallowGfxOff,               1),
        MSG_MAP(PowerDownVcn,                   PPSMC_MSG_PowerDownVcn,                 1),
@@ -199,6 +198,9 @@ static int smu_v13_0_4_fini_smc_tables(struct smu_context *smu)
        kfree(smu_table->watermarks_table);
        smu_table->watermarks_table = NULL;
 
+       kfree(smu_table->gpu_metrics_table);
+       smu_table->gpu_metrics_table = NULL;
+
        return 0;
 }
 
@@ -226,18 +228,6 @@ static int smu_v13_0_4_system_features_control(struct smu_context *smu, bool en)
        return ret;
 }
 
-static int smu_v13_0_4_post_smu_init(struct smu_context *smu)
-{
-       struct amdgpu_device *adev = smu->adev;
-       int ret = 0;
-
-       /* allow message will be sent after enable message */
-       ret = smu_cmn_send_smc_msg(smu, SMU_MSG_EnableGfxOff, NULL);
-       if (ret)
-               dev_err(adev->dev, "Failed to Enable GfxOff!\n");
-       return ret;
-}
-
 static ssize_t smu_v13_0_4_get_gpu_metrics(struct smu_context *smu,
                                           void **table)
 {
@@ -1026,7 +1016,6 @@ static const struct pptable_funcs smu_v13_0_4_ppt_funcs = {
        .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
        .set_driver_table_location = smu_v13_0_set_driver_table_location,
        .gfx_off_control = smu_v13_0_gfx_off_control,
-       .post_init = smu_v13_0_4_post_smu_init,
        .mode2_reset = smu_v13_0_4_mode2_reset,
        .get_dpm_ultimate_freq = smu_v13_0_4_get_dpm_ultimate_freq,
        .od_edit_dpm_table = smu_v13_0_od_edit_dpm_table,
index 47360ef..6644596 100644 (file)
@@ -176,6 +176,9 @@ static int smu_v13_0_5_fini_smc_tables(struct smu_context *smu)
        kfree(smu_table->watermarks_table);
        smu_table->watermarks_table = NULL;
 
+       kfree(smu_table->gpu_metrics_table);
+       smu_table->gpu_metrics_table = NULL;
+
        return 0;
 }
 
index 9dd56e7..1016d1c 100644 (file)
@@ -1567,6 +1567,16 @@ static int smu_v13_0_7_set_mp1_state(struct smu_context *smu,
        return ret;
 }
 
+static bool smu_v13_0_7_is_mode1_reset_supported(struct smu_context *smu)
+{
+       struct amdgpu_device *adev = smu->adev;
+
+       /* SRIOV does not support SMU mode1 reset */
+       if (amdgpu_sriov_vf(adev))
+               return false;
+
+       return true;
+}
 static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
        .get_allowed_feature_mask = smu_v13_0_7_get_allowed_feature_mask,
        .set_default_dpm_table = smu_v13_0_7_set_default_dpm_table,
@@ -1574,7 +1584,9 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
        .dump_pptable = smu_v13_0_7_dump_pptable,
        .init_microcode = smu_v13_0_init_microcode,
        .load_microcode = smu_v13_0_load_microcode,
+       .fini_microcode = smu_v13_0_fini_microcode,
        .init_smc_tables = smu_v13_0_7_init_smc_tables,
+       .fini_smc_tables = smu_v13_0_fini_smc_tables,
        .init_power = smu_v13_0_init_power,
        .fini_power = smu_v13_0_fini_power,
        .check_fw_status = smu_v13_0_7_check_fw_status,
@@ -1624,6 +1636,8 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
        .baco_set_state = smu_v13_0_baco_set_state,
        .baco_enter = smu_v13_0_baco_enter,
        .baco_exit = smu_v13_0_baco_exit,
+       .mode1_reset_is_support = smu_v13_0_7_is_mode1_reset_supported,
+       .mode1_reset = smu_v13_0_mode1_reset,
        .set_mp1_state = smu_v13_0_7_set_mp1_state,
 };
 
index 702ea80..39e7004 100644 (file)
@@ -180,7 +180,7 @@ static int lvds_codec_probe(struct platform_device *pdev)
                of_node_put(bus_node);
                if (ret == -ENODEV) {
                        dev_warn(dev, "missing 'data-mapping' DT property\n");
-               } else if (ret) {
+               } else if (ret < 0) {
                        dev_err(dev, "invalid 'data-mapping' DT property\n");
                        return ret;
                } else {
index ccec405..389e9f1 100644 (file)
@@ -268,7 +268,7 @@ static void __i915_gem_object_free_mmaps(struct drm_i915_gem_object *obj)
  */
 void __i915_gem_object_pages_fini(struct drm_i915_gem_object *obj)
 {
-       assert_object_held(obj);
+       assert_object_held_shared(obj);
 
        if (!list_empty(&obj->vma.list)) {
                struct i915_vma *vma;
@@ -331,15 +331,7 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
                        continue;
                }
 
-               if (!i915_gem_object_trylock(obj, NULL)) {
-                       /* busy, toss it back to the pile */
-                       if (llist_add(&obj->freed, &i915->mm.free_list))
-                               queue_delayed_work(i915->wq, &i915->mm.free_work, msecs_to_jiffies(10));
-                       continue;
-               }
-
                __i915_gem_object_pages_fini(obj);
-               i915_gem_object_unlock(obj);
                __i915_gem_free_object(obj);
 
                /* But keep the pointer alive for RCU-protected lookups */
@@ -359,7 +351,7 @@ void i915_gem_flush_free_objects(struct drm_i915_private *i915)
 static void __i915_gem_free_work(struct work_struct *work)
 {
        struct drm_i915_private *i915 =
-               container_of(work, struct drm_i915_private, mm.free_work.work);
+               container_of(work, struct drm_i915_private, mm.free_work);
 
        i915_gem_flush_free_objects(i915);
 }
@@ -391,7 +383,7 @@ static void i915_gem_free_object(struct drm_gem_object *gem_obj)
         */
 
        if (llist_add(&obj->freed, &i915->mm.free_list))
-               queue_delayed_work(i915->wq, &i915->mm.free_work, 0);
+               queue_work(i915->wq, &i915->mm.free_work);
 }
 
 void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj,
@@ -745,7 +737,7 @@ bool i915_gem_object_needs_ccs_pages(struct drm_i915_gem_object *obj)
 
 void i915_gem_init__objects(struct drm_i915_private *i915)
 {
-       INIT_DELAYED_WORK(&i915->mm.free_work, __i915_gem_free_work);
+       INIT_WORK(&i915->mm.free_work, __i915_gem_free_work);
 }
 
 void i915_objects_module_exit(void)
index 5cf36a1..9f6b14e 100644 (file)
@@ -335,7 +335,6 @@ struct drm_i915_gem_object {
 #define I915_BO_READONLY          BIT(7)
 #define I915_TILING_QUIRK_BIT     8 /* unknown swizzling; do not release! */
 #define I915_BO_PROTECTED         BIT(9)
-#define I915_BO_WAS_BOUND_BIT     10
        /**
         * @mem_flags - Mutable placement-related flags
         *
@@ -616,6 +615,8 @@ struct drm_i915_gem_object {
                 * pages were last acquired.
                 */
                bool dirty:1;
+
+               u32 tlb;
        } mm;
 
        struct {
index 97c820e..8357dbd 100644 (file)
@@ -6,14 +6,15 @@
 
 #include <drm/drm_cache.h>
 
+#include "gt/intel_gt.h"
+#include "gt/intel_gt_pm.h"
+
 #include "i915_drv.h"
 #include "i915_gem_object.h"
 #include "i915_scatterlist.h"
 #include "i915_gem_lmem.h"
 #include "i915_gem_mman.h"
 
-#include "gt/intel_gt.h"
-
 void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
                                 struct sg_table *pages,
                                 unsigned int sg_page_sizes)
@@ -190,6 +191,18 @@ static void unmap_object(struct drm_i915_gem_object *obj, void *ptr)
                vunmap(ptr);
 }
 
+static void flush_tlb_invalidate(struct drm_i915_gem_object *obj)
+{
+       struct drm_i915_private *i915 = to_i915(obj->base.dev);
+       struct intel_gt *gt = to_gt(i915);
+
+       if (!obj->mm.tlb)
+               return;
+
+       intel_gt_invalidate_tlb(gt, obj->mm.tlb);
+       obj->mm.tlb = 0;
+}
+
 struct sg_table *
 __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj)
 {
@@ -215,13 +228,7 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj)
        __i915_gem_object_reset_page_iter(obj);
        obj->mm.page_sizes.phys = obj->mm.page_sizes.sg = 0;
 
-       if (test_and_clear_bit(I915_BO_WAS_BOUND_BIT, &obj->flags)) {
-               struct drm_i915_private *i915 = to_i915(obj->base.dev);
-               intel_wakeref_t wakeref;
-
-               with_intel_runtime_pm_if_active(&i915->runtime_pm, wakeref)
-                       intel_gt_invalidate_tlbs(to_gt(i915));
-       }
+       flush_tlb_invalidate(obj);
 
        return pages;
 }
index 68c2b0d..f435e06 100644 (file)
@@ -11,7 +11,9 @@
 #include "pxp/intel_pxp.h"
 
 #include "i915_drv.h"
+#include "i915_perf_oa_regs.h"
 #include "intel_context.h"
+#include "intel_engine_pm.h"
 #include "intel_engine_regs.h"
 #include "intel_ggtt_gmch.h"
 #include "intel_gt.h"
@@ -36,8 +38,6 @@ static void __intel_gt_init_early(struct intel_gt *gt)
 {
        spin_lock_init(&gt->irq_lock);
 
-       mutex_init(&gt->tlb_invalidate_lock);
-
        INIT_LIST_HEAD(&gt->closed_vma);
        spin_lock_init(&gt->closed_lock);
 
@@ -48,6 +48,8 @@ static void __intel_gt_init_early(struct intel_gt *gt)
        intel_gt_init_reset(gt);
        intel_gt_init_requests(gt);
        intel_gt_init_timelines(gt);
+       mutex_init(&gt->tlb.invalidate_lock);
+       seqcount_mutex_init(&gt->tlb.seqno, &gt->tlb.invalidate_lock);
        intel_gt_pm_init_early(gt);
 
        intel_uc_init_early(&gt->uc);
@@ -768,6 +770,7 @@ void intel_gt_driver_late_release_all(struct drm_i915_private *i915)
                intel_gt_fini_requests(gt);
                intel_gt_fini_reset(gt);
                intel_gt_fini_timelines(gt);
+               mutex_destroy(&gt->tlb.invalidate_lock);
                intel_engines_free(gt);
        }
 }
@@ -906,7 +909,7 @@ get_reg_and_bit(const struct intel_engine_cs *engine, const bool gen8,
        return rb;
 }
 
-void intel_gt_invalidate_tlbs(struct intel_gt *gt)
+static void mmio_invalidate_full(struct intel_gt *gt)
 {
        static const i915_reg_t gen8_regs[] = {
                [RENDER_CLASS]                  = GEN8_RTCR,
@@ -924,13 +927,11 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt)
        struct drm_i915_private *i915 = gt->i915;
        struct intel_uncore *uncore = gt->uncore;
        struct intel_engine_cs *engine;
+       intel_engine_mask_t awake, tmp;
        enum intel_engine_id id;
        const i915_reg_t *regs;
        unsigned int num = 0;
 
-       if (I915_SELFTEST_ONLY(gt->awake == -ENODEV))
-               return;
-
        if (GRAPHICS_VER(i915) == 12) {
                regs = gen12_regs;
                num = ARRAY_SIZE(gen12_regs);
@@ -945,28 +946,41 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt)
                          "Platform does not implement TLB invalidation!"))
                return;
 
-       GEM_TRACE("\n");
-
-       assert_rpm_wakelock_held(&i915->runtime_pm);
-
-       mutex_lock(&gt->tlb_invalidate_lock);
        intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
 
        spin_lock_irq(&uncore->lock); /* serialise invalidate with GT reset */
 
+       awake = 0;
        for_each_engine(engine, gt, id) {
                struct reg_and_bit rb;
 
+               if (!intel_engine_pm_is_awake(engine))
+                       continue;
+
                rb = get_reg_and_bit(engine, regs == gen8_regs, regs, num);
                if (!i915_mmio_reg_offset(rb.reg))
                        continue;
 
                intel_uncore_write_fw(uncore, rb.reg, rb.bit);
+               awake |= engine->mask;
        }
 
+       GT_TRACE(gt, "invalidated engines %08x\n", awake);
+
+       /* Wa_2207587034:tgl,dg1,rkl,adl-s,adl-p */
+       if (awake &&
+           (IS_TIGERLAKE(i915) ||
+            IS_DG1(i915) ||
+            IS_ROCKETLAKE(i915) ||
+            IS_ALDERLAKE_S(i915) ||
+            IS_ALDERLAKE_P(i915)))
+               intel_uncore_write_fw(uncore, GEN12_OA_TLB_INV_CR, 1);
+
        spin_unlock_irq(&uncore->lock);
 
-       for_each_engine(engine, gt, id) {
+       for_each_engine_masked(engine, gt, awake, tmp) {
+               struct reg_and_bit rb;
+
                /*
                 * HW architecture suggest typical invalidation time at 40us,
                 * with pessimistic cases up to 100us and a recommendation to
@@ -974,12 +988,8 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt)
                 */
                const unsigned int timeout_us = 100;
                const unsigned int timeout_ms = 4;
-               struct reg_and_bit rb;
 
                rb = get_reg_and_bit(engine, regs == gen8_regs, regs, num);
-               if (!i915_mmio_reg_offset(rb.reg))
-                       continue;
-
                if (__intel_wait_for_register_fw(uncore,
                                                 rb.reg, rb.bit, 0,
                                                 timeout_us, timeout_ms,
@@ -996,5 +1006,38 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt)
         * transitions.
         */
        intel_uncore_forcewake_put_delayed(uncore, FORCEWAKE_ALL);
-       mutex_unlock(&gt->tlb_invalidate_lock);
+}
+
+static bool tlb_seqno_passed(const struct intel_gt *gt, u32 seqno)
+{
+       u32 cur = intel_gt_tlb_seqno(gt);
+
+       /* Only skip if a *full* TLB invalidate barrier has passed */
+       return (s32)(cur - ALIGN(seqno, 2)) > 0;
+}
+
+void intel_gt_invalidate_tlb(struct intel_gt *gt, u32 seqno)
+{
+       intel_wakeref_t wakeref;
+
+       if (I915_SELFTEST_ONLY(gt->awake == -ENODEV))
+               return;
+
+       if (intel_gt_is_wedged(gt))
+               return;
+
+       if (tlb_seqno_passed(gt, seqno))
+               return;
+
+       with_intel_gt_pm_if_awake(gt, wakeref) {
+               mutex_lock(&gt->tlb.invalidate_lock);
+               if (tlb_seqno_passed(gt, seqno))
+                       goto unlock;
+
+               mmio_invalidate_full(gt);
+
+               write_seqcount_invalidate(&gt->tlb.seqno);
+unlock:
+               mutex_unlock(&gt->tlb.invalidate_lock);
+       }
 }
index 82d6f24..40b06ad 100644 (file)
@@ -101,6 +101,16 @@ void intel_gt_info_print(const struct intel_gt_info *info,
 
 void intel_gt_watchdog_work(struct work_struct *work);
 
-void intel_gt_invalidate_tlbs(struct intel_gt *gt);
+static inline u32 intel_gt_tlb_seqno(const struct intel_gt *gt)
+{
+       return seqprop_sequence(&gt->tlb.seqno);
+}
+
+static inline u32 intel_gt_next_invalidate_tlb_full(const struct intel_gt *gt)
+{
+       return intel_gt_tlb_seqno(gt) | 1;
+}
+
+void intel_gt_invalidate_tlb(struct intel_gt *gt, u32 seqno);
 
 #endif /* __INTEL_GT_H__ */
index bc898df..a334787 100644 (file)
@@ -55,6 +55,9 @@ static inline void intel_gt_pm_might_put(struct intel_gt *gt)
        for (tmp = 1, intel_gt_pm_get(gt); tmp; \
             intel_gt_pm_put(gt), tmp = 0)
 
+#define with_intel_gt_pm_if_awake(gt, wf) \
+       for (wf = intel_gt_pm_get_if_awake(gt); wf; intel_gt_pm_put_async(gt), wf = 0)
+
 static inline int intel_gt_pm_wait_for_idle(struct intel_gt *gt)
 {
        return intel_wakeref_wait_for_idle(&gt->wakeref);
index df70880..3804a58 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/llist.h>
 #include <linux/mutex.h>
 #include <linux/notifier.h>
+#include <linux/seqlock.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
@@ -83,7 +84,22 @@ struct intel_gt {
        struct intel_uc uc;
        struct intel_gsc gsc;
 
-       struct mutex tlb_invalidate_lock;
+       struct {
+               /* Serialize global tlb invalidations */
+               struct mutex invalidate_lock;
+
+               /*
+                * Batch TLB invalidations
+                *
+                * After unbinding the PTE, we need to ensure the TLB
+                * are invalidated prior to releasing the physical pages.
+                * But we only need one such invalidation for all unbinds,
+                * so we track how many TLB invalidations have been
+                * performed since unbind the PTE and only emit an extra
+                * invalidate if no full barrier has been passed.
+                */
+               seqcount_mutex_t seqno;
+       } tlb;
 
        struct i915_wa_list wa_list;
 
index 2c35324..2b10b96 100644 (file)
@@ -708,7 +708,7 @@ intel_context_migrate_copy(struct intel_context *ce,
        u8 src_access, dst_access;
        struct i915_request *rq;
        int src_sz, dst_sz;
-       bool ccs_is_src;
+       bool ccs_is_src, overwrite_ccs;
        int err;
 
        GEM_BUG_ON(ce->vm != ce->engine->gt->migrate.context->vm);
@@ -749,6 +749,8 @@ intel_context_migrate_copy(struct intel_context *ce,
                        get_ccs_sg_sgt(&it_ccs, bytes_to_cpy);
        }
 
+       overwrite_ccs = HAS_FLAT_CCS(i915) && !ccs_bytes_to_cpy && dst_is_lmem;
+
        src_offset = 0;
        dst_offset = CHUNK_SZ;
        if (HAS_64K_PAGES(ce->engine->i915)) {
@@ -852,6 +854,25 @@ intel_context_migrate_copy(struct intel_context *ce,
                        if (err)
                                goto out_rq;
                        ccs_bytes_to_cpy -= ccs_sz;
+               } else if (overwrite_ccs) {
+                       err = rq->engine->emit_flush(rq, EMIT_INVALIDATE);
+                       if (err)
+                               goto out_rq;
+
+                       /*
+                        * While we can't always restore/manage the CCS state,
+                        * we still need to ensure we don't leak the CCS state
+                        * from the previous user, so make sure we overwrite it
+                        * with something.
+                        */
+                       err = emit_copy_ccs(rq, dst_offset, INDIRECT_ACCESS,
+                                           dst_offset, DIRECT_ACCESS, len);
+                       if (err)
+                               goto out_rq;
+
+                       err = rq->engine->emit_flush(rq, EMIT_INVALIDATE);
+                       if (err)
+                               goto out_rq;
                }
 
                /* Arbitration is re-enabled between requests. */
index d8b94d6..6ee8d11 100644 (file)
@@ -206,8 +206,12 @@ void ppgtt_bind_vma(struct i915_address_space *vm,
 void ppgtt_unbind_vma(struct i915_address_space *vm,
                      struct i915_vma_resource *vma_res)
 {
-       if (vma_res->allocated)
-               vm->clear_range(vm, vma_res->start, vma_res->vma_size);
+       if (!vma_res->allocated)
+               return;
+
+       vm->clear_range(vm, vma_res->start, vma_res->vma_size);
+       if (vma_res->tlb)
+               vma_invalidate_tlb(vm, vma_res->tlb);
 }
 
 static unsigned long pd_count(u64 size, int shift)
index 6e90032..aa6aed8 100644 (file)
@@ -15,6 +15,7 @@
 #include "gt/intel_gt_mcr.h"
 #include "gt/intel_gt_regs.h"
 
+#ifdef CONFIG_64BIT
 static void _release_bars(struct pci_dev *pdev)
 {
        int resno;
@@ -111,6 +112,9 @@ static void i915_resize_lmem_bar(struct drm_i915_private *i915, resource_size_t
        pci_assign_unassigned_bus_resources(pdev->bus);
        pci_write_config_dword(pdev, PCI_COMMAND, pci_cmd);
 }
+#else
+static void i915_resize_lmem_bar(struct drm_i915_private *i915, resource_size_t lmem_size) {}
+#endif
 
 static int
 region_lmem_release(struct intel_memory_region *mem)
index d25647b..086bbe8 100644 (file)
@@ -247,7 +247,7 @@ struct i915_gem_mm {
         * List of objects which are pending destruction.
         */
        struct llist_head free_list;
-       struct delayed_work free_work;
+       struct work_struct free_work;
        /**
         * Count of objects pending destructions. Used to skip needlessly
         * waiting on an RCU barrier if no objects are waiting to be freed.
@@ -1378,7 +1378,7 @@ static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
         * armed the work again.
         */
        while (atomic_read(&i915->mm.free_count)) {
-               flush_delayed_work(&i915->mm.free_work);
+               flush_work(&i915->mm.free_work);
                flush_delayed_work(&i915->bdev.wq);
                rcu_barrier();
        }
index ef3b04c..2603717 100644 (file)
@@ -538,8 +538,6 @@ int i915_vma_bind(struct i915_vma *vma,
                                   bind_flags);
        }
 
-       set_bit(I915_BO_WAS_BOUND_BIT, &vma->obj->flags);
-
        atomic_or(bind_flags, &vma->flags);
        return 0;
 }
@@ -1310,6 +1308,19 @@ err_unpin:
        return err;
 }
 
+void vma_invalidate_tlb(struct i915_address_space *vm, u32 *tlb)
+{
+       /*
+        * Before we release the pages that were bound by this vma, we
+        * must invalidate all the TLBs that may still have a reference
+        * back to our physical address. It only needs to be done once,
+        * so after updating the PTE to point away from the pages, record
+        * the most recent TLB invalidation seqno, and if we have not yet
+        * flushed the TLBs upon release, perform a full invalidation.
+        */
+       WRITE_ONCE(*tlb, intel_gt_next_invalidate_tlb_full(vm->gt));
+}
+
 static void __vma_put_pages(struct i915_vma *vma, unsigned int count)
 {
        /* We allocate under vma_get_pages, so beware the shrinker */
@@ -1941,7 +1952,12 @@ struct dma_fence *__i915_vma_evict(struct i915_vma *vma, bool async)
                vma->vm->skip_pte_rewrite;
        trace_i915_vma_unbind(vma);
 
-       unbind_fence = i915_vma_resource_unbind(vma_res);
+       if (async)
+               unbind_fence = i915_vma_resource_unbind(vma_res,
+                                                       &vma->obj->mm.tlb);
+       else
+               unbind_fence = i915_vma_resource_unbind(vma_res, NULL);
+
        vma->resource = NULL;
 
        atomic_and(~(I915_VMA_BIND_MASK | I915_VMA_ERROR | I915_VMA_GGTT_WRITE),
@@ -1949,10 +1965,13 @@ struct dma_fence *__i915_vma_evict(struct i915_vma *vma, bool async)
 
        i915_vma_detach(vma);
 
-       if (!async && unbind_fence) {
-               dma_fence_wait(unbind_fence, false);
-               dma_fence_put(unbind_fence);
-               unbind_fence = NULL;
+       if (!async) {
+               if (unbind_fence) {
+                       dma_fence_wait(unbind_fence, false);
+                       dma_fence_put(unbind_fence);
+                       unbind_fence = NULL;
+               }
+               vma_invalidate_tlb(vma->vm, &vma->obj->mm.tlb);
        }
 
        /*
index 88ca0bd..33a58f6 100644 (file)
@@ -213,6 +213,7 @@ bool i915_vma_misplaced(const struct i915_vma *vma,
                        u64 size, u64 alignment, u64 flags);
 void __i915_vma_set_map_and_fenceable(struct i915_vma *vma);
 void i915_vma_revoke_mmap(struct i915_vma *vma);
+void vma_invalidate_tlb(struct i915_address_space *vm, u32 *tlb);
 struct dma_fence *__i915_vma_evict(struct i915_vma *vma, bool async);
 int __i915_vma_unbind(struct i915_vma *vma);
 int __must_check i915_vma_unbind(struct i915_vma *vma);
index 27c5502..5a67995 100644 (file)
@@ -223,10 +223,13 @@ i915_vma_resource_fence_notify(struct i915_sw_fence *fence,
  * Return: A refcounted pointer to a dma-fence that signals when unbinding is
  * complete.
  */
-struct dma_fence *i915_vma_resource_unbind(struct i915_vma_resource *vma_res)
+struct dma_fence *i915_vma_resource_unbind(struct i915_vma_resource *vma_res,
+                                          u32 *tlb)
 {
        struct i915_address_space *vm = vma_res->vm;
 
+       vma_res->tlb = tlb;
+
        /* Reference for the sw fence */
        i915_vma_resource_get(vma_res);
 
index 5d8427c..06923d1 100644 (file)
@@ -67,6 +67,7 @@ struct i915_page_sizes {
  * taken when the unbind is scheduled.
  * @skip_pte_rewrite: During ggtt suspend and vm takedown pte rewriting
  * needs to be skipped for unbind.
+ * @tlb: pointer for obj->mm.tlb, if async unbind. Otherwise, NULL
  *
  * The lifetime of a struct i915_vma_resource is from a binding request to
  * the actual possible asynchronous unbind has completed.
@@ -119,6 +120,8 @@ struct i915_vma_resource {
        bool immediate_unbind:1;
        bool needs_wakeref:1;
        bool skip_pte_rewrite:1;
+
+       u32 *tlb;
 };
 
 bool i915_vma_resource_hold(struct i915_vma_resource *vma_res,
@@ -131,7 +134,8 @@ struct i915_vma_resource *i915_vma_resource_alloc(void);
 
 void i915_vma_resource_free(struct i915_vma_resource *vma_res);
 
-struct dma_fence *i915_vma_resource_unbind(struct i915_vma_resource *vma_res);
+struct dma_fence *i915_vma_resource_unbind(struct i915_vma_resource *vma_res,
+                                          u32 *tlb);
 
 void __i915_vma_resource_init(struct i915_vma_resource *vma_res);
 
index 9b84df3..8cf3352 100644 (file)
@@ -142,8 +142,6 @@ struct dcss_kms_dev *dcss_kms_attach(struct dcss_dev *dcss)
 
        drm_kms_helper_poll_init(drm);
 
-       drm_bridge_connector_enable_hpd(kms->connector);
-
        ret = drm_dev_register(drm, 0);
        if (ret)
                goto cleanup_crtc;
index 1b70938..bd4ca11 100644 (file)
@@ -115,8 +115,11 @@ static bool meson_vpu_has_available_connectors(struct device *dev)
        for_each_endpoint_of_node(dev->of_node, ep) {
                /* If the endpoint node exists, consider it enabled */
                remote = of_graph_get_remote_port(ep);
-               if (remote)
+               if (remote) {
+                       of_node_put(remote);
+                       of_node_put(ep);
                        return true;
+               }
        }
 
        return false;
index 568182e..d8cf71f 100644 (file)
@@ -2605,6 +2605,27 @@ nv172_chipset = {
 };
 
 static const struct nvkm_device_chip
+nv173_chipset = {
+       .name = "GA103",
+       .bar      = { 0x00000001, tu102_bar_new },
+       .bios     = { 0x00000001, nvkm_bios_new },
+       .devinit  = { 0x00000001, ga100_devinit_new },
+       .fb       = { 0x00000001, ga102_fb_new },
+       .gpio     = { 0x00000001, ga102_gpio_new },
+       .i2c      = { 0x00000001, gm200_i2c_new },
+       .imem     = { 0x00000001, nv50_instmem_new },
+       .mc       = { 0x00000001, ga100_mc_new },
+       .mmu      = { 0x00000001, tu102_mmu_new },
+       .pci      = { 0x00000001, gp100_pci_new },
+       .privring = { 0x00000001, gm200_privring_new },
+       .timer    = { 0x00000001, gk20a_timer_new },
+       .top      = { 0x00000001, ga100_top_new },
+       .disp     = { 0x00000001, ga102_disp_new },
+       .dma      = { 0x00000001, gv100_dma_new },
+       .fifo     = { 0x00000001, ga102_fifo_new },
+};
+
+static const struct nvkm_device_chip
 nv174_chipset = {
        .name = "GA104",
        .bar      = { 0x00000001, tu102_bar_new },
@@ -3067,6 +3088,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
                case 0x167: device->chip = &nv167_chipset; break;
                case 0x168: device->chip = &nv168_chipset; break;
                case 0x172: device->chip = &nv172_chipset; break;
+               case 0x173: device->chip = &nv173_chipset; break;
                case 0x174: device->chip = &nv174_chipset; break;
                case 0x176: device->chip = &nv176_chipset; break;
                case 0x177: device->chip = &nv177_chipset; break;
index b4dfa16..34234a1 100644 (file)
@@ -531,7 +531,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
                                    struct drm_display_mode *mode)
 {
        struct mipi_dsi_device *device = dsi->device;
-       unsigned int Bpp = mipi_dsi_pixel_format_to_bpp(device->format) / 8;
+       int Bpp = mipi_dsi_pixel_format_to_bpp(device->format) / 8;
        u16 hbp = 0, hfp = 0, hsa = 0, hblk = 0, vblk = 0;
        u32 basic_ctl = 0;
        size_t bytes;
@@ -555,7 +555,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
                 * (4 bytes). Its minimal size is therefore 10 bytes
                 */
 #define HSA_PACKET_OVERHEAD    10
-               hsa = max((unsigned int)HSA_PACKET_OVERHEAD,
+               hsa = max(HSA_PACKET_OVERHEAD,
                          (mode->hsync_end - mode->hsync_start) * Bpp - HSA_PACKET_OVERHEAD);
 
                /*
@@ -564,7 +564,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
                 * therefore 6 bytes
                 */
 #define HBP_PACKET_OVERHEAD    6
-               hbp = max((unsigned int)HBP_PACKET_OVERHEAD,
+               hbp = max(HBP_PACKET_OVERHEAD,
                          (mode->htotal - mode->hsync_end) * Bpp - HBP_PACKET_OVERHEAD);
 
                /*
@@ -574,7 +574,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
                 * 16 bytes
                 */
 #define HFP_PACKET_OVERHEAD    16
-               hfp = max((unsigned int)HFP_PACKET_OVERHEAD,
+               hfp = max(HFP_PACKET_OVERHEAD,
                          (mode->hsync_start - mode->hdisplay) * Bpp - HFP_PACKET_OVERHEAD);
 
                /*
@@ -583,7 +583,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
                 * bytes). Its minimal size is therefore 10 bytes.
                 */
 #define HBLK_PACKET_OVERHEAD   10
-               hblk = max((unsigned int)HBLK_PACKET_OVERHEAD,
+               hblk = max(HBLK_PACKET_OVERHEAD,
                           (mode->htotal - (mode->hsync_end - mode->hsync_start)) * Bpp -
                           HBLK_PACKET_OVERHEAD);
 
index 0e210df..97184c3 100644 (file)
@@ -912,7 +912,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
        /*
         * We might need to add a TTM.
         */
-       if (bo->resource->mem_type == TTM_PL_SYSTEM) {
+       if (!bo->resource || bo->resource->mem_type == TTM_PL_SYSTEM) {
                ret = ttm_tt_create(bo, true);
                if (ret)
                        return ret;
index 78fb1a4..e47fa34 100644 (file)
@@ -1572,9 +1572,7 @@ static int i2c_imx_remove(struct platform_device *pdev)
        struct imx_i2c_struct *i2c_imx = platform_get_drvdata(pdev);
        int irq, ret;
 
-       ret = pm_runtime_resume_and_get(&pdev->dev);
-       if (ret < 0)
-               return ret;
+       ret = pm_runtime_get_sync(&pdev->dev);
 
        hrtimer_cancel(&i2c_imx->slave_timer);
 
@@ -1585,17 +1583,21 @@ static int i2c_imx_remove(struct platform_device *pdev)
        if (i2c_imx->dma)
                i2c_imx_dma_free(i2c_imx);
 
-       /* setup chip registers to defaults */
-       imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IADR);
-       imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IFDR);
-       imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2CR);
-       imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2SR);
+       if (ret == 0) {
+               /* setup chip registers to defaults */
+               imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IADR);
+               imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IFDR);
+               imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2CR);
+               imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2SR);
+               clk_disable(i2c_imx->clk);
+       }
 
        clk_notifier_unregister(i2c_imx->clk, &i2c_imx->clk_change_nb);
        irq = platform_get_irq(pdev, 0);
        if (irq >= 0)
                free_irq(irq, i2c_imx);
-       clk_disable_unprepare(i2c_imx->clk);
+
+       clk_unprepare(i2c_imx->clk);
 
        pm_runtime_put_noidle(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
index 79798fc..6746aa4 100644 (file)
@@ -30,7 +30,7 @@ struct acpi_smbus_cmi {
        u8 cap_info:1;
        u8 cap_read:1;
        u8 cap_write:1;
-       const struct smbus_methods_t *methods;
+       struct smbus_methods_t *methods;
 };
 
 static const struct smbus_methods_t smbus_methods = {
@@ -361,6 +361,7 @@ static acpi_status acpi_smbus_cmi_query_methods(acpi_handle handle, u32 level,
 static int acpi_smbus_cmi_add(struct acpi_device *device)
 {
        struct acpi_smbus_cmi *smbus_cmi;
+       const struct acpi_device_id *id;
        int ret;
 
        smbus_cmi = kzalloc(sizeof(struct acpi_smbus_cmi), GFP_KERNEL);
@@ -368,7 +369,6 @@ static int acpi_smbus_cmi_add(struct acpi_device *device)
                return -ENOMEM;
 
        smbus_cmi->handle = device->handle;
-       smbus_cmi->methods = device_get_match_data(&device->dev);
        strcpy(acpi_device_name(device), ACPI_SMBUS_HC_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_SMBUS_HC_CLASS);
        device->driver_data = smbus_cmi;
@@ -376,6 +376,11 @@ static int acpi_smbus_cmi_add(struct acpi_device *device)
        smbus_cmi->cap_read = 0;
        smbus_cmi->cap_write = 0;
 
+       for (id = acpi_smbus_cmi_ids; id->id[0]; id++)
+               if (!strcmp(id->id, acpi_device_hid(device)))
+                       smbus_cmi->methods =
+                               (struct smbus_methods_t *) id->driver_data;
+
        acpi_walk_namespace(ACPI_TYPE_METHOD, smbus_cmi->handle, 1,
                            acpi_smbus_cmi_query_methods, NULL, smbus_cmi, NULL);
 
index fce80a4..04c04e6 100644 (file)
@@ -18,6 +18,7 @@ int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf)
        struct scatterlist *sg;
        unsigned long start, end, cur = 0;
        unsigned int nmap = 0;
+       long ret;
        int i;
 
        dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv);
@@ -67,9 +68,14 @@ wait_fence:
         * may be not up-to-date. Wait for the exporter to finish
         * the migration.
         */
-       return dma_resv_wait_timeout(umem_dmabuf->attach->dmabuf->resv,
+       ret = dma_resv_wait_timeout(umem_dmabuf->attach->dmabuf->resv,
                                     DMA_RESV_USAGE_KERNEL,
                                     false, MAX_SCHEDULE_TIMEOUT);
+       if (ret < 0)
+               return ret;
+       if (ret == 0)
+               return -ETIMEDOUT;
+       return 0;
 }
 EXPORT_SYMBOL(ib_umem_dmabuf_map_pages);
 
index c16017f..14392c9 100644 (file)
@@ -2468,31 +2468,24 @@ static int accept_cr(struct c4iw_ep *ep, struct sk_buff *skb,
                        opt2 |= CCTRL_ECN_V(1);
        }
 
-       skb_get(skb);
-       rpl = cplhdr(skb);
        if (!is_t4(adapter_type)) {
-               BUILD_BUG_ON(sizeof(*rpl5) != roundup(sizeof(*rpl5), 16));
-               skb_trim(skb, sizeof(*rpl5));
-               rpl5 = (void *)rpl;
-               INIT_TP_WR(rpl5, ep->hwtid);
-       } else {
-               skb_trim(skb, sizeof(*rpl));
-               INIT_TP_WR(rpl, ep->hwtid);
-       }
-       OPCODE_TID(rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_PASS_ACCEPT_RPL,
-                                                   ep->hwtid));
-
-       if (CHELSIO_CHIP_VERSION(adapter_type) > CHELSIO_T4) {
                u32 isn = (prandom_u32() & ~7UL) - 1;
+
+               skb = get_skb(skb, roundup(sizeof(*rpl5), 16), GFP_KERNEL);
+               rpl5 = __skb_put_zero(skb, roundup(sizeof(*rpl5), 16));
+               rpl = (void *)rpl5;
+               INIT_TP_WR_CPL(rpl5, CPL_PASS_ACCEPT_RPL, ep->hwtid);
                opt2 |= T5_OPT_2_VALID_F;
                opt2 |= CONG_CNTRL_V(CONG_ALG_TAHOE);
                opt2 |= T5_ISS_F;
-               rpl5 = (void *)rpl;
-               memset_after(rpl5, 0, iss);
                if (peer2peer)
                        isn += 4;
                rpl5->iss = cpu_to_be32(isn);
                pr_debug("iss %u\n", be32_to_cpu(rpl5->iss));
+       } else {
+               skb = get_skb(skb, sizeof(*rpl), GFP_KERNEL);
+               rpl = __skb_put_zero(skb, sizeof(*rpl));
+               INIT_TP_WR_CPL(rpl, CPL_PASS_ACCEPT_RPL, ep->hwtid);
        }
 
        rpl->opt0 = cpu_to_be64(opt0);
index 72f0817..bc3ec22 100644 (file)
@@ -407,7 +407,7 @@ static int erdma_push_one_sqe(struct erdma_qp *qp, u16 *pi,
                             to_erdma_access_flags(reg_wr(send_wr)->access);
                regmr_sge->addr = cpu_to_le64(mr->ibmr.iova);
                regmr_sge->length = cpu_to_le32(mr->ibmr.length);
-               regmr_sge->stag = cpu_to_le32(mr->ibmr.lkey);
+               regmr_sge->stag = cpu_to_le32(reg_wr(send_wr)->key);
                attrs = FIELD_PREP(ERDMA_SQE_MR_MODE_MASK, 0) |
                        FIELD_PREP(ERDMA_SQE_MR_ACCESS_MASK, mr->access) |
                        FIELD_PREP(ERDMA_SQE_MR_MTT_CNT_MASK,
index a7a3d42..699bd3f 100644 (file)
@@ -280,7 +280,7 @@ int erdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr,
        attr->vendor_id = PCI_VENDOR_ID_ALIBABA;
        attr->vendor_part_id = dev->pdev->device;
        attr->hw_ver = dev->pdev->revision;
-       attr->max_qp = dev->attrs.max_qp;
+       attr->max_qp = dev->attrs.max_qp - 1;
        attr->max_qp_wr = min(dev->attrs.max_send_wr, dev->attrs.max_recv_wr);
        attr->max_qp_rd_atom = dev->attrs.max_ord;
        attr->max_qp_init_rd_atom = dev->attrs.max_ird;
@@ -291,7 +291,7 @@ int erdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr,
        attr->max_send_sge = dev->attrs.max_send_sge;
        attr->max_recv_sge = dev->attrs.max_recv_sge;
        attr->max_sge_rd = dev->attrs.max_sge_rd;
-       attr->max_cq = dev->attrs.max_cq;
+       attr->max_cq = dev->attrs.max_cq - 1;
        attr->max_cqe = dev->attrs.max_cqe;
        attr->max_mr = dev->attrs.max_mr;
        attr->max_pd = dev->attrs.max_pd;
index a174a0e..fc94a1b 100644 (file)
@@ -2738,26 +2738,24 @@ static int set_has_smi_cap(struct mlx5_ib_dev *dev)
        int err;
        int port;
 
-       for (port = 1; port <= ARRAY_SIZE(dev->port_caps); port++) {
-               dev->port_caps[port - 1].has_smi = false;
-               if (MLX5_CAP_GEN(dev->mdev, port_type) ==
-                   MLX5_CAP_PORT_TYPE_IB) {
-                       if (MLX5_CAP_GEN(dev->mdev, ib_virt)) {
-                               err = mlx5_query_hca_vport_context(dev->mdev, 0,
-                                                                  port, 0,
-                                                                  &vport_ctx);
-                               if (err) {
-                                       mlx5_ib_err(dev, "query_hca_vport_context for port=%d failed %d\n",
-                                                   port, err);
-                                       return err;
-                               }
-                               dev->port_caps[port - 1].has_smi =
-                                       vport_ctx.has_smi;
-                       } else {
-                               dev->port_caps[port - 1].has_smi = true;
-                       }
+       if (MLX5_CAP_GEN(dev->mdev, port_type) != MLX5_CAP_PORT_TYPE_IB)
+               return 0;
+
+       for (port = 1; port <= dev->num_ports; port++) {
+               if (!MLX5_CAP_GEN(dev->mdev, ib_virt)) {
+                       dev->port_caps[port - 1].has_smi = true;
+                       continue;
                }
+               err = mlx5_query_hca_vport_context(dev->mdev, 0, port, 0,
+                                                  &vport_ctx);
+               if (err) {
+                       mlx5_ib_err(dev, "query_hca_vport_context for port=%d failed %d\n",
+                                   port, err);
+                       return err;
+               }
+               dev->port_caps[port - 1].has_smi = vport_ctx.has_smi;
        }
+
        return 0;
 }
 
index bd5f3b5..7b83f48 100644 (file)
@@ -537,6 +537,7 @@ void iser_login_rsp(struct ib_cq *cq, struct ib_wc *wc)
        struct iscsi_hdr *hdr;
        char *data;
        int length;
+       bool full_feature_phase;
 
        if (unlikely(wc->status != IB_WC_SUCCESS)) {
                iser_err_comp(wc, "login_rsp");
@@ -550,6 +551,9 @@ void iser_login_rsp(struct ib_cq *cq, struct ib_wc *wc)
        hdr = desc->rsp + sizeof(struct iser_ctrl);
        data = desc->rsp + ISER_HEADERS_LEN;
        length = wc->byte_len - ISER_HEADERS_LEN;
+       full_feature_phase = ((hdr->flags & ISCSI_FULL_FEATURE_PHASE) ==
+                             ISCSI_FULL_FEATURE_PHASE) &&
+                            (hdr->flags & ISCSI_FLAG_CMD_FINAL);
 
        iser_dbg("op 0x%x itt 0x%x dlen %d\n", hdr->opcode,
                 hdr->itt, length);
@@ -560,7 +564,8 @@ void iser_login_rsp(struct ib_cq *cq, struct ib_wc *wc)
                                      desc->rsp_dma, ISER_RX_LOGIN_SIZE,
                                      DMA_FROM_DEVICE);
 
-       if (iser_conn->iscsi_conn->session->discovery_sess)
+       if (!full_feature_phase ||
+           iser_conn->iscsi_conn->session->discovery_sess)
                return;
 
        /* Post the first RX buffer that is skipped in iser_post_rx_bufs() */
index 51bd66a..e190bb8 100644 (file)
@@ -68,7 +68,6 @@ static int hyperv_irq_remapping_alloc(struct irq_domain *domain,
 {
        struct irq_alloc_info *info = arg;
        struct irq_data *irq_data;
-       struct irq_desc *desc;
        int ret = 0;
 
        if (!info || info->type != X86_IRQ_ALLOC_TYPE_IOAPIC || nr_irqs > 1)
@@ -90,8 +89,7 @@ static int hyperv_irq_remapping_alloc(struct irq_domain *domain,
         * Hypver-V IO APIC irq affinity should be in the scope of
         * ioapic_max_cpumask because no irq remapping support.
         */
-       desc = irq_data_to_desc(irq_data);
-       cpumask_copy(desc->irq_common_data.affinity, &ioapic_max_cpumask);
+       irq_data_update_affinity(irq_data, &ioapic_max_cpumask);
 
        return 0;
 }
index 327f3ab..741612b 100644 (file)
@@ -129,7 +129,7 @@ static int __init cpuintc_acpi_init(union acpi_subtable_headers *header,
        clear_csr_ecfg(ECFG0_IM);
        clear_csr_estat(ESTATF_IP);
 
-       cpuintc_handle = irq_domain_alloc_fwnode(NULL);
+       cpuintc_handle = irq_domain_alloc_named_fwnode("CPUINTC");
        irq_domain = irq_domain_create_linear(cpuintc_handle, EXCCODE_INT_NUM,
                                        &loongarch_cpu_intc_irq_domain_ops, NULL);
 
index 80d8ca6..16e9af8 100644 (file)
@@ -111,11 +111,15 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af
        regaddr = EIOINTC_REG_ENABLE + ((vector >> 5) << 2);
 
        /* Mask target vector */
-       csr_any_send(regaddr, EIOINTC_ALL_ENABLE & (~BIT(vector & 0x1F)), 0x0, 0);
+       csr_any_send(regaddr, EIOINTC_ALL_ENABLE & (~BIT(vector & 0x1F)),
+                       0x0, priv->node * CORES_PER_EIO_NODE);
+
        /* Set route for target vector */
        eiointc_set_irq_route(vector, cpu, priv->node, &priv->node_map);
+
        /* Unmask target vector */
-       csr_any_send(regaddr, EIOINTC_ALL_ENABLE, 0x0, 0);
+       csr_any_send(regaddr, EIOINTC_ALL_ENABLE,
+                       0x0, priv->node * CORES_PER_EIO_NODE);
 
        irq_data_update_effective_affinity(d, cpumask_of(cpu));
 
@@ -286,7 +290,7 @@ static void acpi_set_vec_parent(int node, struct irq_domain *parent, struct acpi
        }
 }
 
-struct irq_domain *acpi_get_vec_parent(int node, struct acpi_vector_group *vec_group)
+static struct irq_domain *acpi_get_vec_parent(int node, struct acpi_vector_group *vec_group)
 {
        int i;
 
@@ -344,7 +348,8 @@ int __init eiointc_acpi_init(struct irq_domain *parent,
        if (!priv)
                return -ENOMEM;
 
-       priv->domain_handle = irq_domain_alloc_fwnode((phys_addr_t *)acpi_eiointc);
+       priv->domain_handle = irq_domain_alloc_named_id_fwnode("EIOPIC",
+                                                              acpi_eiointc->node);
        if (!priv->domain_handle) {
                pr_err("Unable to allocate domain handle\n");
                goto out_free_priv;
index c4f3c88..0da8716 100644 (file)
@@ -207,7 +207,7 @@ static int liointc_init(phys_addr_t addr, unsigned long size, int revision,
                                        "reg-names", core_reg_names[i]);
 
                        if (index < 0)
-                               return -EINVAL;
+                               goto out_iounmap;
 
                        priv->core_isr[i] = of_iomap(node, index);
                }
@@ -360,7 +360,7 @@ int __init liointc_acpi_init(struct irq_domain *parent, struct acpi_madt_lio_pic
        parent_irq[0] = irq_create_mapping(parent, acpi_liointc->cascade[0]);
        parent_irq[1] = irq_create_mapping(parent, acpi_liointc->cascade[1]);
 
-       domain_handle = irq_domain_alloc_fwnode((phys_addr_t *)acpi_liointc);
+       domain_handle = irq_domain_alloc_fwnode(&acpi_liointc->address);
        if (!domain_handle) {
                pr_err("Unable to allocate domain handle\n");
                return -ENOMEM;
index d0e8551..a72ede9 100644 (file)
@@ -282,7 +282,7 @@ int __init pch_msi_acpi_init(struct irq_domain *parent,
        int ret;
        struct fwnode_handle *domain_handle;
 
-       domain_handle = irq_domain_alloc_fwnode((phys_addr_t *)acpi_pchmsi);
+       domain_handle = irq_domain_alloc_fwnode(&acpi_pchmsi->msg_address);
        ret = pch_msi_init(acpi_pchmsi->msg_address, acpi_pchmsi->start,
                                acpi_pchmsi->count, parent, domain_handle);
        if (ret < 0)
index b6f1392..c01b9c2 100644 (file)
@@ -48,25 +48,6 @@ static struct pch_pic *pch_pic_priv[MAX_IO_PICS];
 
 struct fwnode_handle *pch_pic_handle[MAX_IO_PICS];
 
-int find_pch_pic(u32 gsi)
-{
-       int i;
-
-       /* Find the PCH_PIC that manages this GSI. */
-       for (i = 0; i < MAX_IO_PICS; i++) {
-               struct pch_pic *priv = pch_pic_priv[i];
-
-               if (!priv)
-                       return -1;
-
-               if (gsi >= priv->gsi_base && gsi < (priv->gsi_base + priv->vec_count))
-                       return i;
-       }
-
-       pr_err("ERROR: Unable to locate PCH_PIC for GSI %d\n", gsi);
-       return -1;
-}
-
 static void pch_pic_bitset(struct pch_pic *priv, int offset, int bit)
 {
        u32 reg;
@@ -325,6 +306,25 @@ IRQCHIP_DECLARE(pch_pic, "loongson,pch-pic-1.0", pch_pic_of_init);
 #endif
 
 #ifdef CONFIG_ACPI
+int find_pch_pic(u32 gsi)
+{
+       int i;
+
+       /* Find the PCH_PIC that manages this GSI. */
+       for (i = 0; i < MAX_IO_PICS; i++) {
+               struct pch_pic *priv = pch_pic_priv[i];
+
+               if (!priv)
+                       return -1;
+
+               if (gsi >= priv->gsi_base && gsi < (priv->gsi_base + priv->vec_count))
+                       return i;
+       }
+
+       pr_err("ERROR: Unable to locate PCH_PIC for GSI %d\n", gsi);
+       return -1;
+}
+
 static int __init
 pch_lpc_parse_madt(union acpi_subtable_headers *header,
                       const unsigned long end)
@@ -349,7 +349,7 @@ int __init pch_pic_acpi_init(struct irq_domain *parent,
 
        vec_base = acpi_pchpic->gsi_base - GSI_MIN_PCH_IRQ;
 
-       domain_handle = irq_domain_alloc_fwnode((phys_addr_t *)acpi_pchpic);
+       domain_handle = irq_domain_alloc_fwnode(&acpi_pchpic->address);
        if (!domain_handle) {
                pr_err("Unable to allocate domain handle\n");
                return -ENOMEM;
index 2f08d44..fc46299 100644 (file)
@@ -1172,8 +1172,10 @@ static int meson_mmc_probe(struct platform_device *pdev)
        }
 
        ret = device_reset_optional(&pdev->dev);
-       if (ret)
-               return dev_err_probe(&pdev->dev, ret, "device reset failed\n");
+       if (ret) {
+               dev_err_probe(&pdev->dev, ret, "device reset failed\n");
+               goto free_host;
+       }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        host->regs = devm_ioremap_resource(&pdev->dev, res);
index 4ff73d1..69d7860 100644 (file)
@@ -2446,6 +2446,9 @@ static void msdc_cqe_disable(struct mmc_host *mmc, bool recovery)
        /* disable busy check */
        sdr_clr_bits(host->base + MSDC_PATCH_BIT1, MSDC_PB1_BUSY_CHECK_SEL);
 
+       val = readl(host->base + MSDC_INT);
+       writel(val, host->base + MSDC_INT);
+
        if (recovery) {
                sdr_set_field(host->base + MSDC_DMA_CTRL,
                              MSDC_DMA_CTRL_STOP, 1);
@@ -2932,11 +2935,14 @@ static int __maybe_unused msdc_suspend(struct device *dev)
        struct mmc_host *mmc = dev_get_drvdata(dev);
        struct msdc_host *host = mmc_priv(mmc);
        int ret;
+       u32 val;
 
        if (mmc->caps2 & MMC_CAP2_CQE) {
                ret = cqhci_suspend(mmc);
                if (ret)
                        return ret;
+               val = readl(host->base + MSDC_INT);
+               writel(val, host->base + MSDC_INT);
        }
 
        /*
index 0db9490..e4003f6 100644 (file)
@@ -648,7 +648,7 @@ static int pxamci_probe(struct platform_device *pdev)
 
        ret = pxamci_of_init(pdev, mmc);
        if (ret)
-               return ret;
+               goto out;
 
        host = mmc_priv(mmc);
        host->mmc = mmc;
@@ -672,7 +672,7 @@ static int pxamci_probe(struct platform_device *pdev)
 
        ret = pxamci_init_ocr(host);
        if (ret < 0)
-               return ret;
+               goto out;
 
        mmc->caps = 0;
        host->cmdat = 0;
index 4e90485..a7343d4 100644 (file)
@@ -349,6 +349,15 @@ static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = {
        .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
 };
 
+#ifdef CONFIG_ACPI
+static const struct sdhci_pltfm_data sdhci_dwcmshc_bf3_pdata = {
+       .ops = &sdhci_dwcmshc_ops,
+       .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
+       .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
+                  SDHCI_QUIRK2_ACMD23_BROKEN,
+};
+#endif
+
 static const struct sdhci_pltfm_data sdhci_dwcmshc_rk35xx_pdata = {
        .ops = &sdhci_dwcmshc_rk35xx_ops,
        .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
@@ -431,7 +440,10 @@ MODULE_DEVICE_TABLE(of, sdhci_dwcmshc_dt_ids);
 
 #ifdef CONFIG_ACPI
 static const struct acpi_device_id sdhci_dwcmshc_acpi_ids[] = {
-       { .id = "MLNXBF30" },
+       {
+               .id = "MLNXBF30",
+               .driver_data = (kernel_ulong_t)&sdhci_dwcmshc_bf3_pdata,
+       },
        {}
 };
 #endif
@@ -447,7 +459,7 @@ static int dwcmshc_probe(struct platform_device *pdev)
        int err;
        u32 extra;
 
-       pltfm_data = of_device_get_match_data(&pdev->dev);
+       pltfm_data = device_get_match_data(&pdev->dev);
        if (!pltfm_data) {
                dev_err(&pdev->dev, "Error: No device match data found\n");
                return -ENODEV;
index 4b14d80..e4f446d 100644 (file)
@@ -613,6 +613,9 @@ int ksz9477_fdb_dump(struct ksz_device *dev, int port,
                        goto exit;
                }
 
+               if (!(ksz_data & ALU_VALID))
+                       continue;
+
                /* read ALU table */
                ksz9477_read_table(dev, alu_table);
 
index a4c6eb9..83dca91 100644 (file)
@@ -118,6 +118,9 @@ static int mv88e6060_setup_port(struct mv88e6060_priv *priv, int p)
        int addr = REG_PORT(p);
        int ret;
 
+       if (dsa_is_unused_port(priv->ds, p))
+               return 0;
+
        /* Do not force flow control, disable Ingress and Egress
         * Header tagging, disable VLAN tunneling, and set the port
         * state to Forwarding.  Additionally, if this is the CPU
index b4034b7..1cdce8a 100644 (file)
@@ -274,27 +274,98 @@ static const u32 vsc9959_rew_regmap[] = {
 
 static const u32 vsc9959_sys_regmap[] = {
        REG(SYS_COUNT_RX_OCTETS,                0x000000),
+       REG(SYS_COUNT_RX_UNICAST,               0x000004),
        REG(SYS_COUNT_RX_MULTICAST,             0x000008),
+       REG(SYS_COUNT_RX_BROADCAST,             0x00000c),
        REG(SYS_COUNT_RX_SHORTS,                0x000010),
        REG(SYS_COUNT_RX_FRAGMENTS,             0x000014),
        REG(SYS_COUNT_RX_JABBERS,               0x000018),
+       REG(SYS_COUNT_RX_CRC_ALIGN_ERRS,        0x00001c),
+       REG(SYS_COUNT_RX_SYM_ERRS,              0x000020),
        REG(SYS_COUNT_RX_64,                    0x000024),
        REG(SYS_COUNT_RX_65_127,                0x000028),
        REG(SYS_COUNT_RX_128_255,               0x00002c),
-       REG(SYS_COUNT_RX_256_1023,              0x000030),
-       REG(SYS_COUNT_RX_1024_1526,             0x000034),
-       REG(SYS_COUNT_RX_1527_MAX,              0x000038),
-       REG(SYS_COUNT_RX_LONGS,                 0x000044),
+       REG(SYS_COUNT_RX_256_511,               0x000030),
+       REG(SYS_COUNT_RX_512_1023,              0x000034),
+       REG(SYS_COUNT_RX_1024_1526,             0x000038),
+       REG(SYS_COUNT_RX_1527_MAX,              0x00003c),
+       REG(SYS_COUNT_RX_PAUSE,                 0x000040),
+       REG(SYS_COUNT_RX_CONTROL,               0x000044),
+       REG(SYS_COUNT_RX_LONGS,                 0x000048),
+       REG(SYS_COUNT_RX_CLASSIFIED_DROPS,      0x00004c),
+       REG(SYS_COUNT_RX_RED_PRIO_0,            0x000050),
+       REG(SYS_COUNT_RX_RED_PRIO_1,            0x000054),
+       REG(SYS_COUNT_RX_RED_PRIO_2,            0x000058),
+       REG(SYS_COUNT_RX_RED_PRIO_3,            0x00005c),
+       REG(SYS_COUNT_RX_RED_PRIO_4,            0x000060),
+       REG(SYS_COUNT_RX_RED_PRIO_5,            0x000064),
+       REG(SYS_COUNT_RX_RED_PRIO_6,            0x000068),
+       REG(SYS_COUNT_RX_RED_PRIO_7,            0x00006c),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_0,         0x000070),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_1,         0x000074),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_2,         0x000078),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_3,         0x00007c),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_4,         0x000080),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_5,         0x000084),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_6,         0x000088),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_7,         0x00008c),
+       REG(SYS_COUNT_RX_GREEN_PRIO_0,          0x000090),
+       REG(SYS_COUNT_RX_GREEN_PRIO_1,          0x000094),
+       REG(SYS_COUNT_RX_GREEN_PRIO_2,          0x000098),
+       REG(SYS_COUNT_RX_GREEN_PRIO_3,          0x00009c),
+       REG(SYS_COUNT_RX_GREEN_PRIO_4,          0x0000a0),
+       REG(SYS_COUNT_RX_GREEN_PRIO_5,          0x0000a4),
+       REG(SYS_COUNT_RX_GREEN_PRIO_6,          0x0000a8),
+       REG(SYS_COUNT_RX_GREEN_PRIO_7,          0x0000ac),
        REG(SYS_COUNT_TX_OCTETS,                0x000200),
+       REG(SYS_COUNT_TX_UNICAST,               0x000204),
+       REG(SYS_COUNT_TX_MULTICAST,             0x000208),
+       REG(SYS_COUNT_TX_BROADCAST,             0x00020c),
        REG(SYS_COUNT_TX_COLLISION,             0x000210),
        REG(SYS_COUNT_TX_DROPS,                 0x000214),
+       REG(SYS_COUNT_TX_PAUSE,                 0x000218),
        REG(SYS_COUNT_TX_64,                    0x00021c),
        REG(SYS_COUNT_TX_65_127,                0x000220),
-       REG(SYS_COUNT_TX_128_511,               0x000224),
-       REG(SYS_COUNT_TX_512_1023,              0x000228),
-       REG(SYS_COUNT_TX_1024_1526,             0x00022c),
-       REG(SYS_COUNT_TX_1527_MAX,              0x000230),
+       REG(SYS_COUNT_TX_128_255,               0x000224),
+       REG(SYS_COUNT_TX_256_511,               0x000228),
+       REG(SYS_COUNT_TX_512_1023,              0x00022c),
+       REG(SYS_COUNT_TX_1024_1526,             0x000230),
+       REG(SYS_COUNT_TX_1527_MAX,              0x000234),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_0,         0x000238),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_1,         0x00023c),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_2,         0x000240),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_3,         0x000244),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_4,         0x000248),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_5,         0x00024c),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_6,         0x000250),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_7,         0x000254),
+       REG(SYS_COUNT_TX_GREEN_PRIO_0,          0x000258),
+       REG(SYS_COUNT_TX_GREEN_PRIO_1,          0x00025c),
+       REG(SYS_COUNT_TX_GREEN_PRIO_2,          0x000260),
+       REG(SYS_COUNT_TX_GREEN_PRIO_3,          0x000264),
+       REG(SYS_COUNT_TX_GREEN_PRIO_4,          0x000268),
+       REG(SYS_COUNT_TX_GREEN_PRIO_5,          0x00026c),
+       REG(SYS_COUNT_TX_GREEN_PRIO_6,          0x000270),
+       REG(SYS_COUNT_TX_GREEN_PRIO_7,          0x000274),
        REG(SYS_COUNT_TX_AGING,                 0x000278),
+       REG(SYS_COUNT_DROP_LOCAL,               0x000400),
+       REG(SYS_COUNT_DROP_TAIL,                0x000404),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_0,       0x000408),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_1,       0x00040c),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_2,       0x000410),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_3,       0x000414),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_4,       0x000418),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_5,       0x00041c),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_6,       0x000420),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_7,       0x000424),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_0,        0x000428),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_1,        0x00042c),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_2,        0x000430),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_3,        0x000434),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_4,        0x000438),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_5,        0x00043c),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_6,        0x000440),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_7,        0x000444),
        REG(SYS_RESET_CFG,                      0x000e00),
        REG(SYS_SR_ETYPE_CFG,                   0x000e04),
        REG(SYS_VLAN_ETYPE_CFG,                 0x000e08),
@@ -547,100 +618,379 @@ static const struct reg_field vsc9959_regfields[REGFIELD_MAX] = {
        [SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 7, 4),
 };
 
-static const struct ocelot_stat_layout vsc9959_stats_layout[] = {
-       { .offset = 0x00,       .name = "rx_octets", },
-       { .offset = 0x01,       .name = "rx_unicast", },
-       { .offset = 0x02,       .name = "rx_multicast", },
-       { .offset = 0x03,       .name = "rx_broadcast", },
-       { .offset = 0x04,       .name = "rx_shorts", },
-       { .offset = 0x05,       .name = "rx_fragments", },
-       { .offset = 0x06,       .name = "rx_jabbers", },
-       { .offset = 0x07,       .name = "rx_crc_align_errs", },
-       { .offset = 0x08,       .name = "rx_sym_errs", },
-       { .offset = 0x09,       .name = "rx_frames_below_65_octets", },
-       { .offset = 0x0A,       .name = "rx_frames_65_to_127_octets", },
-       { .offset = 0x0B,       .name = "rx_frames_128_to_255_octets", },
-       { .offset = 0x0C,       .name = "rx_frames_256_to_511_octets", },
-       { .offset = 0x0D,       .name = "rx_frames_512_to_1023_octets", },
-       { .offset = 0x0E,       .name = "rx_frames_1024_to_1526_octets", },
-       { .offset = 0x0F,       .name = "rx_frames_over_1526_octets", },
-       { .offset = 0x10,       .name = "rx_pause", },
-       { .offset = 0x11,       .name = "rx_control", },
-       { .offset = 0x12,       .name = "rx_longs", },
-       { .offset = 0x13,       .name = "rx_classified_drops", },
-       { .offset = 0x14,       .name = "rx_red_prio_0", },
-       { .offset = 0x15,       .name = "rx_red_prio_1", },
-       { .offset = 0x16,       .name = "rx_red_prio_2", },
-       { .offset = 0x17,       .name = "rx_red_prio_3", },
-       { .offset = 0x18,       .name = "rx_red_prio_4", },
-       { .offset = 0x19,       .name = "rx_red_prio_5", },
-       { .offset = 0x1A,       .name = "rx_red_prio_6", },
-       { .offset = 0x1B,       .name = "rx_red_prio_7", },
-       { .offset = 0x1C,       .name = "rx_yellow_prio_0", },
-       { .offset = 0x1D,       .name = "rx_yellow_prio_1", },
-       { .offset = 0x1E,       .name = "rx_yellow_prio_2", },
-       { .offset = 0x1F,       .name = "rx_yellow_prio_3", },
-       { .offset = 0x20,       .name = "rx_yellow_prio_4", },
-       { .offset = 0x21,       .name = "rx_yellow_prio_5", },
-       { .offset = 0x22,       .name = "rx_yellow_prio_6", },
-       { .offset = 0x23,       .name = "rx_yellow_prio_7", },
-       { .offset = 0x24,       .name = "rx_green_prio_0", },
-       { .offset = 0x25,       .name = "rx_green_prio_1", },
-       { .offset = 0x26,       .name = "rx_green_prio_2", },
-       { .offset = 0x27,       .name = "rx_green_prio_3", },
-       { .offset = 0x28,       .name = "rx_green_prio_4", },
-       { .offset = 0x29,       .name = "rx_green_prio_5", },
-       { .offset = 0x2A,       .name = "rx_green_prio_6", },
-       { .offset = 0x2B,       .name = "rx_green_prio_7", },
-       { .offset = 0x80,       .name = "tx_octets", },
-       { .offset = 0x81,       .name = "tx_unicast", },
-       { .offset = 0x82,       .name = "tx_multicast", },
-       { .offset = 0x83,       .name = "tx_broadcast", },
-       { .offset = 0x84,       .name = "tx_collision", },
-       { .offset = 0x85,       .name = "tx_drops", },
-       { .offset = 0x86,       .name = "tx_pause", },
-       { .offset = 0x87,       .name = "tx_frames_below_65_octets", },
-       { .offset = 0x88,       .name = "tx_frames_65_to_127_octets", },
-       { .offset = 0x89,       .name = "tx_frames_128_255_octets", },
-       { .offset = 0x8B,       .name = "tx_frames_256_511_octets", },
-       { .offset = 0x8C,       .name = "tx_frames_1024_1526_octets", },
-       { .offset = 0x8D,       .name = "tx_frames_over_1526_octets", },
-       { .offset = 0x8E,       .name = "tx_yellow_prio_0", },
-       { .offset = 0x8F,       .name = "tx_yellow_prio_1", },
-       { .offset = 0x90,       .name = "tx_yellow_prio_2", },
-       { .offset = 0x91,       .name = "tx_yellow_prio_3", },
-       { .offset = 0x92,       .name = "tx_yellow_prio_4", },
-       { .offset = 0x93,       .name = "tx_yellow_prio_5", },
-       { .offset = 0x94,       .name = "tx_yellow_prio_6", },
-       { .offset = 0x95,       .name = "tx_yellow_prio_7", },
-       { .offset = 0x96,       .name = "tx_green_prio_0", },
-       { .offset = 0x97,       .name = "tx_green_prio_1", },
-       { .offset = 0x98,       .name = "tx_green_prio_2", },
-       { .offset = 0x99,       .name = "tx_green_prio_3", },
-       { .offset = 0x9A,       .name = "tx_green_prio_4", },
-       { .offset = 0x9B,       .name = "tx_green_prio_5", },
-       { .offset = 0x9C,       .name = "tx_green_prio_6", },
-       { .offset = 0x9D,       .name = "tx_green_prio_7", },
-       { .offset = 0x9E,       .name = "tx_aged", },
-       { .offset = 0x100,      .name = "drop_local", },
-       { .offset = 0x101,      .name = "drop_tail", },
-       { .offset = 0x102,      .name = "drop_yellow_prio_0", },
-       { .offset = 0x103,      .name = "drop_yellow_prio_1", },
-       { .offset = 0x104,      .name = "drop_yellow_prio_2", },
-       { .offset = 0x105,      .name = "drop_yellow_prio_3", },
-       { .offset = 0x106,      .name = "drop_yellow_prio_4", },
-       { .offset = 0x107,      .name = "drop_yellow_prio_5", },
-       { .offset = 0x108,      .name = "drop_yellow_prio_6", },
-       { .offset = 0x109,      .name = "drop_yellow_prio_7", },
-       { .offset = 0x10A,      .name = "drop_green_prio_0", },
-       { .offset = 0x10B,      .name = "drop_green_prio_1", },
-       { .offset = 0x10C,      .name = "drop_green_prio_2", },
-       { .offset = 0x10D,      .name = "drop_green_prio_3", },
-       { .offset = 0x10E,      .name = "drop_green_prio_4", },
-       { .offset = 0x10F,      .name = "drop_green_prio_5", },
-       { .offset = 0x110,      .name = "drop_green_prio_6", },
-       { .offset = 0x111,      .name = "drop_green_prio_7", },
-       OCELOT_STAT_END
+static const struct ocelot_stat_layout vsc9959_stats_layout[OCELOT_NUM_STATS] = {
+       [OCELOT_STAT_RX_OCTETS] = {
+               .name = "rx_octets",
+               .reg = SYS_COUNT_RX_OCTETS,
+       },
+       [OCELOT_STAT_RX_UNICAST] = {
+               .name = "rx_unicast",
+               .reg = SYS_COUNT_RX_UNICAST,
+       },
+       [OCELOT_STAT_RX_MULTICAST] = {
+               .name = "rx_multicast",
+               .reg = SYS_COUNT_RX_MULTICAST,
+       },
+       [OCELOT_STAT_RX_BROADCAST] = {
+               .name = "rx_broadcast",
+               .reg = SYS_COUNT_RX_BROADCAST,
+       },
+       [OCELOT_STAT_RX_SHORTS] = {
+               .name = "rx_shorts",
+               .reg = SYS_COUNT_RX_SHORTS,
+       },
+       [OCELOT_STAT_RX_FRAGMENTS] = {
+               .name = "rx_fragments",
+               .reg = SYS_COUNT_RX_FRAGMENTS,
+       },
+       [OCELOT_STAT_RX_JABBERS] = {
+               .name = "rx_jabbers",
+               .reg = SYS_COUNT_RX_JABBERS,
+       },
+       [OCELOT_STAT_RX_CRC_ALIGN_ERRS] = {
+               .name = "rx_crc_align_errs",
+               .reg = SYS_COUNT_RX_CRC_ALIGN_ERRS,
+       },
+       [OCELOT_STAT_RX_SYM_ERRS] = {
+               .name = "rx_sym_errs",
+               .reg = SYS_COUNT_RX_SYM_ERRS,
+       },
+       [OCELOT_STAT_RX_64] = {
+               .name = "rx_frames_below_65_octets",
+               .reg = SYS_COUNT_RX_64,
+       },
+       [OCELOT_STAT_RX_65_127] = {
+               .name = "rx_frames_65_to_127_octets",
+               .reg = SYS_COUNT_RX_65_127,
+       },
+       [OCELOT_STAT_RX_128_255] = {
+               .name = "rx_frames_128_to_255_octets",
+               .reg = SYS_COUNT_RX_128_255,
+       },
+       [OCELOT_STAT_RX_256_511] = {
+               .name = "rx_frames_256_to_511_octets",
+               .reg = SYS_COUNT_RX_256_511,
+       },
+       [OCELOT_STAT_RX_512_1023] = {
+               .name = "rx_frames_512_to_1023_octets",
+               .reg = SYS_COUNT_RX_512_1023,
+       },
+       [OCELOT_STAT_RX_1024_1526] = {
+               .name = "rx_frames_1024_to_1526_octets",
+               .reg = SYS_COUNT_RX_1024_1526,
+       },
+       [OCELOT_STAT_RX_1527_MAX] = {
+               .name = "rx_frames_over_1526_octets",
+               .reg = SYS_COUNT_RX_1527_MAX,
+       },
+       [OCELOT_STAT_RX_PAUSE] = {
+               .name = "rx_pause",
+               .reg = SYS_COUNT_RX_PAUSE,
+       },
+       [OCELOT_STAT_RX_CONTROL] = {
+               .name = "rx_control",
+               .reg = SYS_COUNT_RX_CONTROL,
+       },
+       [OCELOT_STAT_RX_LONGS] = {
+               .name = "rx_longs",
+               .reg = SYS_COUNT_RX_LONGS,
+       },
+       [OCELOT_STAT_RX_CLASSIFIED_DROPS] = {
+               .name = "rx_classified_drops",
+               .reg = SYS_COUNT_RX_CLASSIFIED_DROPS,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_0] = {
+               .name = "rx_red_prio_0",
+               .reg = SYS_COUNT_RX_RED_PRIO_0,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_1] = {
+               .name = "rx_red_prio_1",
+               .reg = SYS_COUNT_RX_RED_PRIO_1,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_2] = {
+               .name = "rx_red_prio_2",
+               .reg = SYS_COUNT_RX_RED_PRIO_2,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_3] = {
+               .name = "rx_red_prio_3",
+               .reg = SYS_COUNT_RX_RED_PRIO_3,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_4] = {
+               .name = "rx_red_prio_4",
+               .reg = SYS_COUNT_RX_RED_PRIO_4,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_5] = {
+               .name = "rx_red_prio_5",
+               .reg = SYS_COUNT_RX_RED_PRIO_5,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_6] = {
+               .name = "rx_red_prio_6",
+               .reg = SYS_COUNT_RX_RED_PRIO_6,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_7] = {
+               .name = "rx_red_prio_7",
+               .reg = SYS_COUNT_RX_RED_PRIO_7,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_0] = {
+               .name = "rx_yellow_prio_0",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_0,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_1] = {
+               .name = "rx_yellow_prio_1",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_1,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_2] = {
+               .name = "rx_yellow_prio_2",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_2,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_3] = {
+               .name = "rx_yellow_prio_3",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_3,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_4] = {
+               .name = "rx_yellow_prio_4",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_4,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_5] = {
+               .name = "rx_yellow_prio_5",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_5,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_6] = {
+               .name = "rx_yellow_prio_6",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_6,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_7] = {
+               .name = "rx_yellow_prio_7",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_7,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_0] = {
+               .name = "rx_green_prio_0",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_0,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_1] = {
+               .name = "rx_green_prio_1",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_1,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_2] = {
+               .name = "rx_green_prio_2",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_2,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_3] = {
+               .name = "rx_green_prio_3",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_3,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_4] = {
+               .name = "rx_green_prio_4",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_4,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_5] = {
+               .name = "rx_green_prio_5",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_5,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_6] = {
+               .name = "rx_green_prio_6",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_6,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_7] = {
+               .name = "rx_green_prio_7",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_7,
+       },
+       [OCELOT_STAT_TX_OCTETS] = {
+               .name = "tx_octets",
+               .reg = SYS_COUNT_TX_OCTETS,
+       },
+       [OCELOT_STAT_TX_UNICAST] = {
+               .name = "tx_unicast",
+               .reg = SYS_COUNT_TX_UNICAST,
+       },
+       [OCELOT_STAT_TX_MULTICAST] = {
+               .name = "tx_multicast",
+               .reg = SYS_COUNT_TX_MULTICAST,
+       },
+       [OCELOT_STAT_TX_BROADCAST] = {
+               .name = "tx_broadcast",
+               .reg = SYS_COUNT_TX_BROADCAST,
+       },
+       [OCELOT_STAT_TX_COLLISION] = {
+               .name = "tx_collision",
+               .reg = SYS_COUNT_TX_COLLISION,
+       },
+       [OCELOT_STAT_TX_DROPS] = {
+               .name = "tx_drops",
+               .reg = SYS_COUNT_TX_DROPS,
+       },
+       [OCELOT_STAT_TX_PAUSE] = {
+               .name = "tx_pause",
+               .reg = SYS_COUNT_TX_PAUSE,
+       },
+       [OCELOT_STAT_TX_64] = {
+               .name = "tx_frames_below_65_octets",
+               .reg = SYS_COUNT_TX_64,
+       },
+       [OCELOT_STAT_TX_65_127] = {
+               .name = "tx_frames_65_to_127_octets",
+               .reg = SYS_COUNT_TX_65_127,
+       },
+       [OCELOT_STAT_TX_128_255] = {
+               .name = "tx_frames_128_255_octets",
+               .reg = SYS_COUNT_TX_128_255,
+       },
+       [OCELOT_STAT_TX_256_511] = {
+               .name = "tx_frames_256_511_octets",
+               .reg = SYS_COUNT_TX_256_511,
+       },
+       [OCELOT_STAT_TX_512_1023] = {
+               .name = "tx_frames_512_1023_octets",
+               .reg = SYS_COUNT_TX_512_1023,
+       },
+       [OCELOT_STAT_TX_1024_1526] = {
+               .name = "tx_frames_1024_1526_octets",
+               .reg = SYS_COUNT_TX_1024_1526,
+       },
+       [OCELOT_STAT_TX_1527_MAX] = {
+               .name = "tx_frames_over_1526_octets",
+               .reg = SYS_COUNT_TX_1527_MAX,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_0] = {
+               .name = "tx_yellow_prio_0",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_0,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_1] = {
+               .name = "tx_yellow_prio_1",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_1,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_2] = {
+               .name = "tx_yellow_prio_2",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_2,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_3] = {
+               .name = "tx_yellow_prio_3",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_3,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_4] = {
+               .name = "tx_yellow_prio_4",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_4,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_5] = {
+               .name = "tx_yellow_prio_5",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_5,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_6] = {
+               .name = "tx_yellow_prio_6",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_6,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_7] = {
+               .name = "tx_yellow_prio_7",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_7,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_0] = {
+               .name = "tx_green_prio_0",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_0,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_1] = {
+               .name = "tx_green_prio_1",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_1,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_2] = {
+               .name = "tx_green_prio_2",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_2,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_3] = {
+               .name = "tx_green_prio_3",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_3,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_4] = {
+               .name = "tx_green_prio_4",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_4,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_5] = {
+               .name = "tx_green_prio_5",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_5,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_6] = {
+               .name = "tx_green_prio_6",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_6,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_7] = {
+               .name = "tx_green_prio_7",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_7,
+       },
+       [OCELOT_STAT_TX_AGED] = {
+               .name = "tx_aged",
+               .reg = SYS_COUNT_TX_AGING,
+       },
+       [OCELOT_STAT_DROP_LOCAL] = {
+               .name = "drop_local",
+               .reg = SYS_COUNT_DROP_LOCAL,
+       },
+       [OCELOT_STAT_DROP_TAIL] = {
+               .name = "drop_tail",
+               .reg = SYS_COUNT_DROP_TAIL,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_0] = {
+               .name = "drop_yellow_prio_0",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_0,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_1] = {
+               .name = "drop_yellow_prio_1",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_1,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_2] = {
+               .name = "drop_yellow_prio_2",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_2,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_3] = {
+               .name = "drop_yellow_prio_3",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_3,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_4] = {
+               .name = "drop_yellow_prio_4",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_4,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_5] = {
+               .name = "drop_yellow_prio_5",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_5,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_6] = {
+               .name = "drop_yellow_prio_6",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_6,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_7] = {
+               .name = "drop_yellow_prio_7",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_7,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_0] = {
+               .name = "drop_green_prio_0",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_0,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_1] = {
+               .name = "drop_green_prio_1",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_1,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_2] = {
+               .name = "drop_green_prio_2",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_2,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_3] = {
+               .name = "drop_green_prio_3",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_3,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_4] = {
+               .name = "drop_green_prio_4",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_4,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_5] = {
+               .name = "drop_green_prio_5",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_5,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_6] = {
+               .name = "drop_green_prio_6",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_6,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_7] = {
+               .name = "drop_green_prio_7",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_7,
+       },
 };
 
 static const struct vcap_field vsc9959_vcap_es0_keys[] = {
@@ -2166,7 +2516,7 @@ static void vsc9959_psfp_sgi_table_del(struct ocelot *ocelot,
 static void vsc9959_psfp_counters_get(struct ocelot *ocelot, u32 index,
                                      struct felix_stream_filter_counters *counters)
 {
-       mutex_lock(&ocelot->stats_lock);
+       spin_lock(&ocelot->stats_lock);
 
        ocelot_rmw(ocelot, SYS_STAT_CFG_STAT_VIEW(index),
                   SYS_STAT_CFG_STAT_VIEW_M,
@@ -2183,7 +2533,7 @@ static void vsc9959_psfp_counters_get(struct ocelot *ocelot, u32 index,
                     SYS_STAT_CFG_STAT_CLEAR_SHOT(0x10),
                     SYS_STAT_CFG);
 
-       mutex_unlock(&ocelot->stats_lock);
+       spin_unlock(&ocelot->stats_lock);
 }
 
 static int vsc9959_psfp_filter_add(struct ocelot *ocelot, int port,
index ea06492..b34f4cd 100644 (file)
@@ -270,27 +270,98 @@ static const u32 vsc9953_rew_regmap[] = {
 
 static const u32 vsc9953_sys_regmap[] = {
        REG(SYS_COUNT_RX_OCTETS,                0x000000),
+       REG(SYS_COUNT_RX_UNICAST,               0x000004),
        REG(SYS_COUNT_RX_MULTICAST,             0x000008),
+       REG(SYS_COUNT_RX_BROADCAST,             0x00000c),
        REG(SYS_COUNT_RX_SHORTS,                0x000010),
        REG(SYS_COUNT_RX_FRAGMENTS,             0x000014),
        REG(SYS_COUNT_RX_JABBERS,               0x000018),
+       REG(SYS_COUNT_RX_CRC_ALIGN_ERRS,        0x00001c),
+       REG(SYS_COUNT_RX_SYM_ERRS,              0x000020),
        REG(SYS_COUNT_RX_64,                    0x000024),
        REG(SYS_COUNT_RX_65_127,                0x000028),
        REG(SYS_COUNT_RX_128_255,               0x00002c),
-       REG(SYS_COUNT_RX_256_1023,              0x000030),
-       REG(SYS_COUNT_RX_1024_1526,             0x000034),
-       REG(SYS_COUNT_RX_1527_MAX,              0x000038),
+       REG(SYS_COUNT_RX_256_511,               0x000030),
+       REG(SYS_COUNT_RX_512_1023,              0x000034),
+       REG(SYS_COUNT_RX_1024_1526,             0x000038),
+       REG(SYS_COUNT_RX_1527_MAX,              0x00003c),
+       REG(SYS_COUNT_RX_PAUSE,                 0x000040),
+       REG(SYS_COUNT_RX_CONTROL,               0x000044),
        REG(SYS_COUNT_RX_LONGS,                 0x000048),
+       REG(SYS_COUNT_RX_CLASSIFIED_DROPS,      0x00004c),
+       REG(SYS_COUNT_RX_RED_PRIO_0,            0x000050),
+       REG(SYS_COUNT_RX_RED_PRIO_1,            0x000054),
+       REG(SYS_COUNT_RX_RED_PRIO_2,            0x000058),
+       REG(SYS_COUNT_RX_RED_PRIO_3,            0x00005c),
+       REG(SYS_COUNT_RX_RED_PRIO_4,            0x000060),
+       REG(SYS_COUNT_RX_RED_PRIO_5,            0x000064),
+       REG(SYS_COUNT_RX_RED_PRIO_6,            0x000068),
+       REG(SYS_COUNT_RX_RED_PRIO_7,            0x00006c),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_0,         0x000070),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_1,         0x000074),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_2,         0x000078),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_3,         0x00007c),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_4,         0x000080),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_5,         0x000084),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_6,         0x000088),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_7,         0x00008c),
+       REG(SYS_COUNT_RX_GREEN_PRIO_0,          0x000090),
+       REG(SYS_COUNT_RX_GREEN_PRIO_1,          0x000094),
+       REG(SYS_COUNT_RX_GREEN_PRIO_2,          0x000098),
+       REG(SYS_COUNT_RX_GREEN_PRIO_3,          0x00009c),
+       REG(SYS_COUNT_RX_GREEN_PRIO_4,          0x0000a0),
+       REG(SYS_COUNT_RX_GREEN_PRIO_5,          0x0000a4),
+       REG(SYS_COUNT_RX_GREEN_PRIO_6,          0x0000a8),
+       REG(SYS_COUNT_RX_GREEN_PRIO_7,          0x0000ac),
        REG(SYS_COUNT_TX_OCTETS,                0x000100),
+       REG(SYS_COUNT_TX_UNICAST,               0x000104),
+       REG(SYS_COUNT_TX_MULTICAST,             0x000108),
+       REG(SYS_COUNT_TX_BROADCAST,             0x00010c),
        REG(SYS_COUNT_TX_COLLISION,             0x000110),
        REG(SYS_COUNT_TX_DROPS,                 0x000114),
+       REG(SYS_COUNT_TX_PAUSE,                 0x000118),
        REG(SYS_COUNT_TX_64,                    0x00011c),
        REG(SYS_COUNT_TX_65_127,                0x000120),
-       REG(SYS_COUNT_TX_128_511,               0x000124),
-       REG(SYS_COUNT_TX_512_1023,              0x000128),
-       REG(SYS_COUNT_TX_1024_1526,             0x00012c),
-       REG(SYS_COUNT_TX_1527_MAX,              0x000130),
+       REG(SYS_COUNT_TX_128_255,               0x000124),
+       REG(SYS_COUNT_TX_256_511,               0x000128),
+       REG(SYS_COUNT_TX_512_1023,              0x00012c),
+       REG(SYS_COUNT_TX_1024_1526,             0x000130),
+       REG(SYS_COUNT_TX_1527_MAX,              0x000134),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_0,         0x000138),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_1,         0x00013c),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_2,         0x000140),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_3,         0x000144),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_4,         0x000148),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_5,         0x00014c),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_6,         0x000150),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_7,         0x000154),
+       REG(SYS_COUNT_TX_GREEN_PRIO_0,          0x000158),
+       REG(SYS_COUNT_TX_GREEN_PRIO_1,          0x00015c),
+       REG(SYS_COUNT_TX_GREEN_PRIO_2,          0x000160),
+       REG(SYS_COUNT_TX_GREEN_PRIO_3,          0x000164),
+       REG(SYS_COUNT_TX_GREEN_PRIO_4,          0x000168),
+       REG(SYS_COUNT_TX_GREEN_PRIO_5,          0x00016c),
+       REG(SYS_COUNT_TX_GREEN_PRIO_6,          0x000170),
+       REG(SYS_COUNT_TX_GREEN_PRIO_7,          0x000174),
        REG(SYS_COUNT_TX_AGING,                 0x000178),
+       REG(SYS_COUNT_DROP_LOCAL,               0x000200),
+       REG(SYS_COUNT_DROP_TAIL,                0x000204),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_0,       0x000208),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_1,       0x00020c),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_2,       0x000210),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_3,       0x000214),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_4,       0x000218),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_5,       0x00021c),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_6,       0x000220),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_7,       0x000224),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_0,        0x000228),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_1,        0x00022c),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_2,        0x000230),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_3,        0x000234),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_4,        0x000238),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_5,        0x00023c),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_6,        0x000240),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_7,        0x000244),
        REG(SYS_RESET_CFG,                      0x000318),
        REG_RESERVED(SYS_SR_ETYPE_CFG),
        REG(SYS_VLAN_ETYPE_CFG,                 0x000320),
@@ -543,101 +614,379 @@ static const struct reg_field vsc9953_regfields[REGFIELD_MAX] = {
        [SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 11, 4),
 };
 
-static const struct ocelot_stat_layout vsc9953_stats_layout[] = {
-       { .offset = 0x00,       .name = "rx_octets", },
-       { .offset = 0x01,       .name = "rx_unicast", },
-       { .offset = 0x02,       .name = "rx_multicast", },
-       { .offset = 0x03,       .name = "rx_broadcast", },
-       { .offset = 0x04,       .name = "rx_shorts", },
-       { .offset = 0x05,       .name = "rx_fragments", },
-       { .offset = 0x06,       .name = "rx_jabbers", },
-       { .offset = 0x07,       .name = "rx_crc_align_errs", },
-       { .offset = 0x08,       .name = "rx_sym_errs", },
-       { .offset = 0x09,       .name = "rx_frames_below_65_octets", },
-       { .offset = 0x0A,       .name = "rx_frames_65_to_127_octets", },
-       { .offset = 0x0B,       .name = "rx_frames_128_to_255_octets", },
-       { .offset = 0x0C,       .name = "rx_frames_256_to_511_octets", },
-       { .offset = 0x0D,       .name = "rx_frames_512_to_1023_octets", },
-       { .offset = 0x0E,       .name = "rx_frames_1024_to_1526_octets", },
-       { .offset = 0x0F,       .name = "rx_frames_over_1526_octets", },
-       { .offset = 0x10,       .name = "rx_pause", },
-       { .offset = 0x11,       .name = "rx_control", },
-       { .offset = 0x12,       .name = "rx_longs", },
-       { .offset = 0x13,       .name = "rx_classified_drops", },
-       { .offset = 0x14,       .name = "rx_red_prio_0", },
-       { .offset = 0x15,       .name = "rx_red_prio_1", },
-       { .offset = 0x16,       .name = "rx_red_prio_2", },
-       { .offset = 0x17,       .name = "rx_red_prio_3", },
-       { .offset = 0x18,       .name = "rx_red_prio_4", },
-       { .offset = 0x19,       .name = "rx_red_prio_5", },
-       { .offset = 0x1A,       .name = "rx_red_prio_6", },
-       { .offset = 0x1B,       .name = "rx_red_prio_7", },
-       { .offset = 0x1C,       .name = "rx_yellow_prio_0", },
-       { .offset = 0x1D,       .name = "rx_yellow_prio_1", },
-       { .offset = 0x1E,       .name = "rx_yellow_prio_2", },
-       { .offset = 0x1F,       .name = "rx_yellow_prio_3", },
-       { .offset = 0x20,       .name = "rx_yellow_prio_4", },
-       { .offset = 0x21,       .name = "rx_yellow_prio_5", },
-       { .offset = 0x22,       .name = "rx_yellow_prio_6", },
-       { .offset = 0x23,       .name = "rx_yellow_prio_7", },
-       { .offset = 0x24,       .name = "rx_green_prio_0", },
-       { .offset = 0x25,       .name = "rx_green_prio_1", },
-       { .offset = 0x26,       .name = "rx_green_prio_2", },
-       { .offset = 0x27,       .name = "rx_green_prio_3", },
-       { .offset = 0x28,       .name = "rx_green_prio_4", },
-       { .offset = 0x29,       .name = "rx_green_prio_5", },
-       { .offset = 0x2A,       .name = "rx_green_prio_6", },
-       { .offset = 0x2B,       .name = "rx_green_prio_7", },
-       { .offset = 0x40,       .name = "tx_octets", },
-       { .offset = 0x41,       .name = "tx_unicast", },
-       { .offset = 0x42,       .name = "tx_multicast", },
-       { .offset = 0x43,       .name = "tx_broadcast", },
-       { .offset = 0x44,       .name = "tx_collision", },
-       { .offset = 0x45,       .name = "tx_drops", },
-       { .offset = 0x46,       .name = "tx_pause", },
-       { .offset = 0x47,       .name = "tx_frames_below_65_octets", },
-       { .offset = 0x48,       .name = "tx_frames_65_to_127_octets", },
-       { .offset = 0x49,       .name = "tx_frames_128_255_octets", },
-       { .offset = 0x4A,       .name = "tx_frames_256_511_octets", },
-       { .offset = 0x4B,       .name = "tx_frames_512_1023_octets", },
-       { .offset = 0x4C,       .name = "tx_frames_1024_1526_octets", },
-       { .offset = 0x4D,       .name = "tx_frames_over_1526_octets", },
-       { .offset = 0x4E,       .name = "tx_yellow_prio_0", },
-       { .offset = 0x4F,       .name = "tx_yellow_prio_1", },
-       { .offset = 0x50,       .name = "tx_yellow_prio_2", },
-       { .offset = 0x51,       .name = "tx_yellow_prio_3", },
-       { .offset = 0x52,       .name = "tx_yellow_prio_4", },
-       { .offset = 0x53,       .name = "tx_yellow_prio_5", },
-       { .offset = 0x54,       .name = "tx_yellow_prio_6", },
-       { .offset = 0x55,       .name = "tx_yellow_prio_7", },
-       { .offset = 0x56,       .name = "tx_green_prio_0", },
-       { .offset = 0x57,       .name = "tx_green_prio_1", },
-       { .offset = 0x58,       .name = "tx_green_prio_2", },
-       { .offset = 0x59,       .name = "tx_green_prio_3", },
-       { .offset = 0x5A,       .name = "tx_green_prio_4", },
-       { .offset = 0x5B,       .name = "tx_green_prio_5", },
-       { .offset = 0x5C,       .name = "tx_green_prio_6", },
-       { .offset = 0x5D,       .name = "tx_green_prio_7", },
-       { .offset = 0x5E,       .name = "tx_aged", },
-       { .offset = 0x80,       .name = "drop_local", },
-       { .offset = 0x81,       .name = "drop_tail", },
-       { .offset = 0x82,       .name = "drop_yellow_prio_0", },
-       { .offset = 0x83,       .name = "drop_yellow_prio_1", },
-       { .offset = 0x84,       .name = "drop_yellow_prio_2", },
-       { .offset = 0x85,       .name = "drop_yellow_prio_3", },
-       { .offset = 0x86,       .name = "drop_yellow_prio_4", },
-       { .offset = 0x87,       .name = "drop_yellow_prio_5", },
-       { .offset = 0x88,       .name = "drop_yellow_prio_6", },
-       { .offset = 0x89,       .name = "drop_yellow_prio_7", },
-       { .offset = 0x8A,       .name = "drop_green_prio_0", },
-       { .offset = 0x8B,       .name = "drop_green_prio_1", },
-       { .offset = 0x8C,       .name = "drop_green_prio_2", },
-       { .offset = 0x8D,       .name = "drop_green_prio_3", },
-       { .offset = 0x8E,       .name = "drop_green_prio_4", },
-       { .offset = 0x8F,       .name = "drop_green_prio_5", },
-       { .offset = 0x90,       .name = "drop_green_prio_6", },
-       { .offset = 0x91,       .name = "drop_green_prio_7", },
-       OCELOT_STAT_END
+static const struct ocelot_stat_layout vsc9953_stats_layout[OCELOT_NUM_STATS] = {
+       [OCELOT_STAT_RX_OCTETS] = {
+               .name = "rx_octets",
+               .reg = SYS_COUNT_RX_OCTETS,
+       },
+       [OCELOT_STAT_RX_UNICAST] = {
+               .name = "rx_unicast",
+               .reg = SYS_COUNT_RX_UNICAST,
+       },
+       [OCELOT_STAT_RX_MULTICAST] = {
+               .name = "rx_multicast",
+               .reg = SYS_COUNT_RX_MULTICAST,
+       },
+       [OCELOT_STAT_RX_BROADCAST] = {
+               .name = "rx_broadcast",
+               .reg = SYS_COUNT_RX_BROADCAST,
+       },
+       [OCELOT_STAT_RX_SHORTS] = {
+               .name = "rx_shorts",
+               .reg = SYS_COUNT_RX_SHORTS,
+       },
+       [OCELOT_STAT_RX_FRAGMENTS] = {
+               .name = "rx_fragments",
+               .reg = SYS_COUNT_RX_FRAGMENTS,
+       },
+       [OCELOT_STAT_RX_JABBERS] = {
+               .name = "rx_jabbers",
+               .reg = SYS_COUNT_RX_JABBERS,
+       },
+       [OCELOT_STAT_RX_CRC_ALIGN_ERRS] = {
+               .name = "rx_crc_align_errs",
+               .reg = SYS_COUNT_RX_CRC_ALIGN_ERRS,
+       },
+       [OCELOT_STAT_RX_SYM_ERRS] = {
+               .name = "rx_sym_errs",
+               .reg = SYS_COUNT_RX_SYM_ERRS,
+       },
+       [OCELOT_STAT_RX_64] = {
+               .name = "rx_frames_below_65_octets",
+               .reg = SYS_COUNT_RX_64,
+       },
+       [OCELOT_STAT_RX_65_127] = {
+               .name = "rx_frames_65_to_127_octets",
+               .reg = SYS_COUNT_RX_65_127,
+       },
+       [OCELOT_STAT_RX_128_255] = {
+               .name = "rx_frames_128_to_255_octets",
+               .reg = SYS_COUNT_RX_128_255,
+       },
+       [OCELOT_STAT_RX_256_511] = {
+               .name = "rx_frames_256_to_511_octets",
+               .reg = SYS_COUNT_RX_256_511,
+       },
+       [OCELOT_STAT_RX_512_1023] = {
+               .name = "rx_frames_512_to_1023_octets",
+               .reg = SYS_COUNT_RX_512_1023,
+       },
+       [OCELOT_STAT_RX_1024_1526] = {
+               .name = "rx_frames_1024_to_1526_octets",
+               .reg = SYS_COUNT_RX_1024_1526,
+       },
+       [OCELOT_STAT_RX_1527_MAX] = {
+               .name = "rx_frames_over_1526_octets",
+               .reg = SYS_COUNT_RX_1527_MAX,
+       },
+       [OCELOT_STAT_RX_PAUSE] = {
+               .name = "rx_pause",
+               .reg = SYS_COUNT_RX_PAUSE,
+       },
+       [OCELOT_STAT_RX_CONTROL] = {
+               .name = "rx_control",
+               .reg = SYS_COUNT_RX_CONTROL,
+       },
+       [OCELOT_STAT_RX_LONGS] = {
+               .name = "rx_longs",
+               .reg = SYS_COUNT_RX_LONGS,
+       },
+       [OCELOT_STAT_RX_CLASSIFIED_DROPS] = {
+               .name = "rx_classified_drops",
+               .reg = SYS_COUNT_RX_CLASSIFIED_DROPS,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_0] = {
+               .name = "rx_red_prio_0",
+               .reg = SYS_COUNT_RX_RED_PRIO_0,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_1] = {
+               .name = "rx_red_prio_1",
+               .reg = SYS_COUNT_RX_RED_PRIO_1,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_2] = {
+               .name = "rx_red_prio_2",
+               .reg = SYS_COUNT_RX_RED_PRIO_2,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_3] = {
+               .name = "rx_red_prio_3",
+               .reg = SYS_COUNT_RX_RED_PRIO_3,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_4] = {
+               .name = "rx_red_prio_4",
+               .reg = SYS_COUNT_RX_RED_PRIO_4,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_5] = {
+               .name = "rx_red_prio_5",
+               .reg = SYS_COUNT_RX_RED_PRIO_5,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_6] = {
+               .name = "rx_red_prio_6",
+               .reg = SYS_COUNT_RX_RED_PRIO_6,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_7] = {
+               .name = "rx_red_prio_7",
+               .reg = SYS_COUNT_RX_RED_PRIO_7,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_0] = {
+               .name = "rx_yellow_prio_0",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_0,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_1] = {
+               .name = "rx_yellow_prio_1",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_1,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_2] = {
+               .name = "rx_yellow_prio_2",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_2,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_3] = {
+               .name = "rx_yellow_prio_3",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_3,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_4] = {
+               .name = "rx_yellow_prio_4",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_4,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_5] = {
+               .name = "rx_yellow_prio_5",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_5,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_6] = {
+               .name = "rx_yellow_prio_6",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_6,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_7] = {
+               .name = "rx_yellow_prio_7",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_7,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_0] = {
+               .name = "rx_green_prio_0",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_0,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_1] = {
+               .name = "rx_green_prio_1",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_1,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_2] = {
+               .name = "rx_green_prio_2",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_2,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_3] = {
+               .name = "rx_green_prio_3",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_3,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_4] = {
+               .name = "rx_green_prio_4",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_4,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_5] = {
+               .name = "rx_green_prio_5",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_5,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_6] = {
+               .name = "rx_green_prio_6",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_6,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_7] = {
+               .name = "rx_green_prio_7",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_7,
+       },
+       [OCELOT_STAT_TX_OCTETS] = {
+               .name = "tx_octets",
+               .reg = SYS_COUNT_TX_OCTETS,
+       },
+       [OCELOT_STAT_TX_UNICAST] = {
+               .name = "tx_unicast",
+               .reg = SYS_COUNT_TX_UNICAST,
+       },
+       [OCELOT_STAT_TX_MULTICAST] = {
+               .name = "tx_multicast",
+               .reg = SYS_COUNT_TX_MULTICAST,
+       },
+       [OCELOT_STAT_TX_BROADCAST] = {
+               .name = "tx_broadcast",
+               .reg = SYS_COUNT_TX_BROADCAST,
+       },
+       [OCELOT_STAT_TX_COLLISION] = {
+               .name = "tx_collision",
+               .reg = SYS_COUNT_TX_COLLISION,
+       },
+       [OCELOT_STAT_TX_DROPS] = {
+               .name = "tx_drops",
+               .reg = SYS_COUNT_TX_DROPS,
+       },
+       [OCELOT_STAT_TX_PAUSE] = {
+               .name = "tx_pause",
+               .reg = SYS_COUNT_TX_PAUSE,
+       },
+       [OCELOT_STAT_TX_64] = {
+               .name = "tx_frames_below_65_octets",
+               .reg = SYS_COUNT_TX_64,
+       },
+       [OCELOT_STAT_TX_65_127] = {
+               .name = "tx_frames_65_to_127_octets",
+               .reg = SYS_COUNT_TX_65_127,
+       },
+       [OCELOT_STAT_TX_128_255] = {
+               .name = "tx_frames_128_255_octets",
+               .reg = SYS_COUNT_TX_128_255,
+       },
+       [OCELOT_STAT_TX_256_511] = {
+               .name = "tx_frames_256_511_octets",
+               .reg = SYS_COUNT_TX_256_511,
+       },
+       [OCELOT_STAT_TX_512_1023] = {
+               .name = "tx_frames_512_1023_octets",
+               .reg = SYS_COUNT_TX_512_1023,
+       },
+       [OCELOT_STAT_TX_1024_1526] = {
+               .name = "tx_frames_1024_1526_octets",
+               .reg = SYS_COUNT_TX_1024_1526,
+       },
+       [OCELOT_STAT_TX_1527_MAX] = {
+               .name = "tx_frames_over_1526_octets",
+               .reg = SYS_COUNT_TX_1527_MAX,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_0] = {
+               .name = "tx_yellow_prio_0",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_0,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_1] = {
+               .name = "tx_yellow_prio_1",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_1,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_2] = {
+               .name = "tx_yellow_prio_2",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_2,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_3] = {
+               .name = "tx_yellow_prio_3",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_3,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_4] = {
+               .name = "tx_yellow_prio_4",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_4,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_5] = {
+               .name = "tx_yellow_prio_5",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_5,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_6] = {
+               .name = "tx_yellow_prio_6",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_6,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_7] = {
+               .name = "tx_yellow_prio_7",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_7,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_0] = {
+               .name = "tx_green_prio_0",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_0,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_1] = {
+               .name = "tx_green_prio_1",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_1,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_2] = {
+               .name = "tx_green_prio_2",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_2,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_3] = {
+               .name = "tx_green_prio_3",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_3,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_4] = {
+               .name = "tx_green_prio_4",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_4,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_5] = {
+               .name = "tx_green_prio_5",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_5,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_6] = {
+               .name = "tx_green_prio_6",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_6,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_7] = {
+               .name = "tx_green_prio_7",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_7,
+       },
+       [OCELOT_STAT_TX_AGED] = {
+               .name = "tx_aged",
+               .reg = SYS_COUNT_TX_AGING,
+       },
+       [OCELOT_STAT_DROP_LOCAL] = {
+               .name = "drop_local",
+               .reg = SYS_COUNT_DROP_LOCAL,
+       },
+       [OCELOT_STAT_DROP_TAIL] = {
+               .name = "drop_tail",
+               .reg = SYS_COUNT_DROP_TAIL,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_0] = {
+               .name = "drop_yellow_prio_0",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_0,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_1] = {
+               .name = "drop_yellow_prio_1",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_1,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_2] = {
+               .name = "drop_yellow_prio_2",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_2,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_3] = {
+               .name = "drop_yellow_prio_3",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_3,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_4] = {
+               .name = "drop_yellow_prio_4",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_4,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_5] = {
+               .name = "drop_yellow_prio_5",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_5,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_6] = {
+               .name = "drop_yellow_prio_6",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_6,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_7] = {
+               .name = "drop_yellow_prio_7",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_7,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_0] = {
+               .name = "drop_green_prio_0",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_0,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_1] = {
+               .name = "drop_green_prio_1",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_1,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_2] = {
+               .name = "drop_green_prio_2",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_2,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_3] = {
+               .name = "drop_green_prio_3",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_3,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_4] = {
+               .name = "drop_green_prio_4",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_4,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_5] = {
+               .name = "drop_green_prio_5",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_5,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_6] = {
+               .name = "drop_green_prio_6",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_6,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_7] = {
+               .name = "drop_green_prio_7",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_7,
+       },
 };
 
 static const struct vcap_field vsc9953_vcap_es0_keys[] = {
index 0569ff0..10c6fea 100644 (file)
@@ -93,7 +93,7 @@ static int sja1105_setup_devlink_regions(struct dsa_switch *ds)
 
                region = dsa_devlink_region_create(ds, ops, 1, size);
                if (IS_ERR(region)) {
-                       while (i-- >= 0)
+                       while (--i >= 0)
                                dsa_devlink_region_destroy(priv->regions[i]);
                        return PTR_ERR(region);
                }
index 7071604..0280851 100644 (file)
@@ -13844,7 +13844,7 @@ static void bnx2x_check_kr2_wa(struct link_params *params,
 
        /* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery
         * Since some switches tend to reinit the AN process and clear the
-        * the advertised BP/NP after ~2 seconds causing the KR2 to be disabled
+        * advertised BP/NP after ~2 seconds causing the KR2 to be disabled
         * and recovered many times
         */
        if (vars->check_kr2_recovery_cnt > 0) {
index 84604af..89256b8 100644 (file)
@@ -243,7 +243,7 @@ static int cxgb_ulp_iscsi_ctl(struct adapter *adapter, unsigned int req,
 
                /*
                 * on rx, the iscsi pdu has to be < rx page size and the
-                * the max rx data length programmed in TP
+                * max rx data length programmed in TP
                 */
                val = min(adapter->params.tp.rx_pg_size,
                          ((t3_read_reg(adapter, A_TP_PARA_REG2)) >>
index 26433a6..fed5f93 100644 (file)
@@ -497,7 +497,7 @@ struct cpl_t5_pass_accept_rpl {
        __be32 opt2;
        __be64 opt0;
        __be32 iss;
-       __be32 rsvd[3];
+       __be32 rsvd;
 };
 
 struct cpl_act_open_req {
index 7d49c28..3dc3c0b 100644 (file)
@@ -135,11 +135,7 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
                 * NSEC_PER_SEC - ts.tv_nsec. Add the remaining nanoseconds
                 * to current timer would be next second.
                 */
-               tempval = readl(fep->hwp + FEC_ATIME_CTRL);
-               tempval |= FEC_T_CTRL_CAPTURE;
-               writel(tempval, fep->hwp + FEC_ATIME_CTRL);
-
-               tempval = readl(fep->hwp + FEC_ATIME);
+               tempval = fep->cc.read(&fep->cc);
                /* Convert the ptp local counter to 1588 timestamp */
                ns = timecounter_cyc2time(&fep->tc, tempval);
                ts = ns_to_timespec64(ns);
index b36bf9c..9f1d5de 100644 (file)
@@ -384,7 +384,9 @@ static void i40e_tx_timeout(struct net_device *netdev, unsigned int txqueue)
                set_bit(__I40E_GLOBAL_RESET_REQUESTED, pf->state);
                break;
        default:
-               netdev_err(netdev, "tx_timeout recovery unsuccessful\n");
+               netdev_err(netdev, "tx_timeout recovery unsuccessful, device is in non-recoverable state.\n");
+               set_bit(__I40E_DOWN_REQUESTED, pf->state);
+               set_bit(__I40E_VSI_DOWN_REQUESTED, vsi->state);
                break;
        }
 
index f6ba97a..d422616 100644 (file)
@@ -3203,11 +3203,13 @@ static int i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
 
        protocol = vlan_get_protocol(skb);
 
-       if (eth_p_mpls(protocol))
+       if (eth_p_mpls(protocol)) {
                ip.hdr = skb_inner_network_header(skb);
-       else
+               l4.hdr = skb_checksum_start(skb);
+       } else {
                ip.hdr = skb_network_header(skb);
-       l4.hdr = skb_checksum_start(skb);
+               l4.hdr = skb_transport_header(skb);
+       }
 
        /* set the tx_flags to indicate the IP protocol type. this is
         * required so that checksum header computation below is accurate.
index cd4e6a2..9ffbd24 100644 (file)
@@ -324,6 +324,7 @@ static enum iavf_status iavf_config_arq_regs(struct iavf_hw *hw)
 static enum iavf_status iavf_init_asq(struct iavf_hw *hw)
 {
        enum iavf_status ret_code = 0;
+       int i;
 
        if (hw->aq.asq.count > 0) {
                /* queue already initialized */
@@ -354,12 +355,17 @@ static enum iavf_status iavf_init_asq(struct iavf_hw *hw)
        /* initialize base registers */
        ret_code = iavf_config_asq_regs(hw);
        if (ret_code)
-               goto init_adminq_free_rings;
+               goto init_free_asq_bufs;
 
        /* success! */
        hw->aq.asq.count = hw->aq.num_asq_entries;
        goto init_adminq_exit;
 
+init_free_asq_bufs:
+       for (i = 0; i < hw->aq.num_asq_entries; i++)
+               iavf_free_dma_mem(hw, &hw->aq.asq.r.asq_bi[i]);
+       iavf_free_virt_mem(hw, &hw->aq.asq.dma_head);
+
 init_adminq_free_rings:
        iavf_free_adminq_asq(hw);
 
@@ -383,6 +389,7 @@ init_adminq_exit:
 static enum iavf_status iavf_init_arq(struct iavf_hw *hw)
 {
        enum iavf_status ret_code = 0;
+       int i;
 
        if (hw->aq.arq.count > 0) {
                /* queue already initialized */
@@ -413,12 +420,16 @@ static enum iavf_status iavf_init_arq(struct iavf_hw *hw)
        /* initialize base registers */
        ret_code = iavf_config_arq_regs(hw);
        if (ret_code)
-               goto init_adminq_free_rings;
+               goto init_free_arq_bufs;
 
        /* success! */
        hw->aq.arq.count = hw->aq.num_arq_entries;
        goto init_adminq_exit;
 
+init_free_arq_bufs:
+       for (i = 0; i < hw->aq.num_arq_entries; i++)
+               iavf_free_dma_mem(hw, &hw->aq.arq.r.arq_bi[i]);
+       iavf_free_virt_mem(hw, &hw->aq.arq.dma_head);
 init_adminq_free_rings:
        iavf_free_adminq_arq(hw);
 
index 45d097a..f39440a 100644 (file)
@@ -2367,7 +2367,7 @@ static void iavf_init_get_resources(struct iavf_adapter *adapter)
        err = iavf_get_vf_config(adapter);
        if (err == -EALREADY) {
                err = iavf_send_vf_config_msg(adapter);
-               goto err_alloc;
+               goto err;
        } else if (err == -EINVAL) {
                /* We only get -EINVAL if the device is in a very bad
                 * state or if we've been disabled for previous bad
@@ -3086,12 +3086,15 @@ continue_reset:
 
        return;
 reset_err:
+       if (running) {
+               set_bit(__IAVF_VSI_DOWN, adapter->vsi.state);
+               iavf_free_traffic_irqs(adapter);
+       }
+       iavf_disable_vf(adapter);
+
        mutex_unlock(&adapter->client_lock);
        mutex_unlock(&adapter->crit_lock);
-       if (running)
-               iavf_change_state(adapter, __IAVF_RUNNING);
        dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
-       iavf_close(netdev);
 }
 
 /**
@@ -4085,8 +4088,17 @@ static int iavf_open(struct net_device *netdev)
                return -EIO;
        }
 
-       while (!mutex_trylock(&adapter->crit_lock))
+       while (!mutex_trylock(&adapter->crit_lock)) {
+               /* If we are in __IAVF_INIT_CONFIG_ADAPTER state the crit_lock
+                * is already taken and iavf_open is called from an upper
+                * device's notifier reacting on NETDEV_REGISTER event.
+                * We have to leave here to avoid dead lock.
+                */
+               if (adapter->state == __IAVF_INIT_CONFIG_ADAPTER)
+                       return -EBUSY;
+
                usleep_range(500, 1000);
+       }
 
        if (adapter->state != __IAVF_DOWN) {
                err = -EBUSY;
index 85a9448..40e678c 100644 (file)
@@ -62,7 +62,7 @@ ice_fltr_set_vlan_vsi_promisc(struct ice_hw *hw, struct ice_vsi *vsi,
        int result;
 
        result = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, false);
-       if (result)
+       if (result && result != -EEXIST)
                dev_err(ice_pf_to_dev(pf),
                        "Error setting promisc mode on VSI %i (rc=%d)\n",
                        vsi->vsi_num, result);
@@ -86,7 +86,7 @@ ice_fltr_clear_vlan_vsi_promisc(struct ice_hw *hw, struct ice_vsi *vsi,
        int result;
 
        result = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, true);
-       if (result)
+       if (result && result != -EEXIST)
                dev_err(ice_pf_to_dev(pf),
                        "Error clearing promisc mode on VSI %i (rc=%d)\n",
                        vsi->vsi_num, result);
@@ -109,7 +109,7 @@ ice_fltr_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
        int result;
 
        result = ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask, vid);
-       if (result)
+       if (result && result != -EEXIST)
                dev_err(ice_pf_to_dev(pf),
                        "Error clearing promisc mode on VSI %i for VID %u (rc=%d)\n",
                        ice_get_hw_vsi_num(hw, vsi_handle), vid, result);
@@ -132,7 +132,7 @@ ice_fltr_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
        int result;
 
        result = ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid);
-       if (result)
+       if (result && result != -EEXIST)
                dev_err(ice_pf_to_dev(pf),
                        "Error setting promisc mode on VSI %i for VID %u (rc=%d)\n",
                        ice_get_hw_vsi_num(hw, vsi_handle), vid, result);
index a830f7f..733c455 100644 (file)
@@ -3181,7 +3181,7 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
 
        pf = vsi->back;
        vtype = vsi->type;
-       if (WARN_ON(vtype == ICE_VSI_VF) && !vsi->vf)
+       if (WARN_ON(vtype == ICE_VSI_VF && !vsi->vf))
                return -EINVAL;
 
        ice_vsi_init_vlan_ops(vsi);
@@ -4062,7 +4062,11 @@ int ice_vsi_del_vlan_zero(struct ice_vsi *vsi)
        if (err && err != -EEXIST)
                return err;
 
-       return 0;
+       /* when deleting the last VLAN filter, make sure to disable the VLAN
+        * promisc mode so the filter isn't left by accident
+        */
+       return ice_clear_vsi_promisc(&vsi->back->hw, vsi->idx,
+                                   ICE_MCAST_VLAN_PROMISC_BITS, 0);
 }
 
 /**
index eb40526..4ecaf40 100644 (file)
@@ -267,8 +267,10 @@ static int ice_set_promisc(struct ice_vsi *vsi, u8 promisc_m)
                status = ice_fltr_set_vsi_promisc(&vsi->back->hw, vsi->idx,
                                                  promisc_m, 0);
        }
+       if (status && status != -EEXIST)
+               return status;
 
-       return status;
+       return 0;
 }
 
 /**
@@ -3573,6 +3575,14 @@ ice_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
        while (test_and_set_bit(ICE_CFG_BUSY, vsi->state))
                usleep_range(1000, 2000);
 
+       ret = ice_clear_vsi_promisc(&vsi->back->hw, vsi->idx,
+                                   ICE_MCAST_VLAN_PROMISC_BITS, vid);
+       if (ret) {
+               netdev_err(netdev, "Error clearing multicast promiscuous mode on VSI %i\n",
+                          vsi->vsi_num);
+               vsi->current_netdev_flags |= IFF_ALLMULTI;
+       }
+
        vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
 
        /* Make sure VLAN delete is successful before updating VLAN
index 262e553..3808034 100644 (file)
@@ -4445,6 +4445,13 @@ ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
                goto free_fltr_list;
 
        list_for_each_entry(list_itr, &vsi_list_head, list_entry) {
+               /* Avoid enabling or disabling VLAN zero twice when in double
+                * VLAN mode
+                */
+               if (ice_is_dvm_ena(hw) &&
+                   list_itr->fltr_info.l_data.vlan.tpid == 0)
+                       continue;
+
                vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;
                if (rm_vlan_promisc)
                        status = ice_clear_vsi_promisc(hw, vsi_handle,
@@ -4452,7 +4459,7 @@ ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
                else
                        status = ice_set_vsi_promisc(hw, vsi_handle,
                                                     promisc_mask, vlan_id);
-               if (status)
+               if (status && status != -EEXIST)
                        break;
        }
 
index 8fd7c3e..0abeed0 100644 (file)
@@ -571,8 +571,10 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
 
        if (ice_is_vf_disabled(vf)) {
                vsi = ice_get_vf_vsi(vf);
-               if (WARN_ON(!vsi))
+               if (!vsi) {
+                       dev_dbg(dev, "VF is already removed\n");
                        return -EINVAL;
+               }
                ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, vf->vf_id);
                ice_vsi_stop_all_rx_rings(vsi);
                dev_dbg(dev, "VF is already disabled, there is no need for resetting it, telling VM, all is fine %d\n",
@@ -762,13 +764,16 @@ static int ice_cfg_mac_antispoof(struct ice_vsi *vsi, bool enable)
 static int ice_vsi_ena_spoofchk(struct ice_vsi *vsi)
 {
        struct ice_vsi_vlan_ops *vlan_ops;
-       int err;
+       int err = 0;
 
        vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
 
-       err = vlan_ops->ena_tx_filtering(vsi);
-       if (err)
-               return err;
+       /* Allow VF with VLAN 0 only to send all tagged traffic */
+       if (vsi->type != ICE_VSI_VF || ice_vsi_has_non_zero_vlans(vsi)) {
+               err = vlan_ops->ena_tx_filtering(vsi);
+               if (err)
+                       return err;
+       }
 
        return ice_cfg_mac_antispoof(vsi, true);
 }
index 094e3c9..2b4c791 100644 (file)
@@ -2288,6 +2288,15 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)
 
                        /* Enable VLAN filtering on first non-zero VLAN */
                        if (!vlan_promisc && vid && !ice_is_dvm_ena(&pf->hw)) {
+                               if (vf->spoofchk) {
+                                       status = vsi->inner_vlan_ops.ena_tx_filtering(vsi);
+                                       if (status) {
+                                               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+                                               dev_err(dev, "Enable VLAN anti-spoofing on VLAN ID: %d failed error-%d\n",
+                                                       vid, status);
+                                               goto error_param;
+                                       }
+                               }
                                if (vsi->inner_vlan_ops.ena_rx_filtering(vsi)) {
                                        v_ret = VIRTCHNL_STATUS_ERR_PARAM;
                                        dev_err(dev, "Enable VLAN pruning on VLAN ID: %d failed error-%d\n",
@@ -2333,8 +2342,10 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)
                        }
 
                        /* Disable VLAN filtering when only VLAN 0 is left */
-                       if (!ice_vsi_has_non_zero_vlans(vsi))
+                       if (!ice_vsi_has_non_zero_vlans(vsi)) {
+                               vsi->inner_vlan_ops.dis_tx_filtering(vsi);
                                vsi->inner_vlan_ops.dis_rx_filtering(vsi);
+                       }
 
                        if (vlan_promisc)
                                ice_vf_dis_vlan_promisc(vsi, &vlan);
@@ -2838,6 +2849,13 @@ ice_vc_del_vlans(struct ice_vf *vf, struct ice_vsi *vsi,
 
                        if (vlan_promisc)
                                ice_vf_dis_vlan_promisc(vsi, &vlan);
+
+                       /* Disable VLAN filtering when only VLAN 0 is left */
+                       if (!ice_vsi_has_non_zero_vlans(vsi) && ice_is_dvm_ena(&vsi->back->hw)) {
+                               err = vsi->outer_vlan_ops.dis_tx_filtering(vsi);
+                               if (err)
+                                       return err;
+                       }
                }
 
                vc_vlan = &vlan_fltr->inner;
@@ -2853,8 +2871,17 @@ ice_vc_del_vlans(struct ice_vf *vf, struct ice_vsi *vsi,
                        /* no support for VLAN promiscuous on inner VLAN unless
                         * we are in Single VLAN Mode (SVM)
                         */
-                       if (!ice_is_dvm_ena(&vsi->back->hw) && vlan_promisc)
-                               ice_vf_dis_vlan_promisc(vsi, &vlan);
+                       if (!ice_is_dvm_ena(&vsi->back->hw)) {
+                               if (vlan_promisc)
+                                       ice_vf_dis_vlan_promisc(vsi, &vlan);
+
+                               /* Disable VLAN filtering when only VLAN 0 is left */
+                               if (!ice_vsi_has_non_zero_vlans(vsi)) {
+                                       err = vsi->inner_vlan_ops.dis_tx_filtering(vsi);
+                                       if (err)
+                                               return err;
+                               }
+                       }
                }
        }
 
@@ -2931,6 +2958,13 @@ ice_vc_add_vlans(struct ice_vf *vf, struct ice_vsi *vsi,
                                if (err)
                                        return err;
                        }
+
+                       /* Enable VLAN filtering on first non-zero VLAN */
+                       if (vf->spoofchk && vlan.vid && ice_is_dvm_ena(&vsi->back->hw)) {
+                               err = vsi->outer_vlan_ops.ena_tx_filtering(vsi);
+                               if (err)
+                                       return err;
+                       }
                }
 
                vc_vlan = &vlan_fltr->inner;
@@ -2946,10 +2980,19 @@ ice_vc_add_vlans(struct ice_vf *vf, struct ice_vsi *vsi,
                        /* no support for VLAN promiscuous on inner VLAN unless
                         * we are in Single VLAN Mode (SVM)
                         */
-                       if (!ice_is_dvm_ena(&vsi->back->hw) && vlan_promisc) {
-                               err = ice_vf_ena_vlan_promisc(vsi, &vlan);
-                               if (err)
-                                       return err;
+                       if (!ice_is_dvm_ena(&vsi->back->hw)) {
+                               if (vlan_promisc) {
+                                       err = ice_vf_ena_vlan_promisc(vsi, &vlan);
+                                       if (err)
+                                               return err;
+                               }
+
+                               /* Enable VLAN filtering on first non-zero VLAN */
+                               if (vf->spoofchk && vlan.vid) {
+                                       err = vsi->inner_vlan_ops.ena_tx_filtering(vsi);
+                                       if (err)
+                                               return err;
+                               }
                        }
                }
        }
index 2d3daf0..015b781 100644 (file)
@@ -664,6 +664,8 @@ struct igb_adapter {
        struct igb_mac_addr *mac_table;
        struct vf_mac_filter vf_macs;
        struct vf_mac_filter *vf_mac_list;
+       /* lock for VF resources */
+       spinlock_t vfs_lock;
 };
 
 /* flags controlling PTP/1588 function */
index d8b836a..2796e81 100644 (file)
@@ -3637,6 +3637,7 @@ static int igb_disable_sriov(struct pci_dev *pdev)
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct igb_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
+       unsigned long flags;
 
        /* reclaim resources allocated to VFs */
        if (adapter->vf_data) {
@@ -3649,12 +3650,13 @@ static int igb_disable_sriov(struct pci_dev *pdev)
                        pci_disable_sriov(pdev);
                        msleep(500);
                }
-
+               spin_lock_irqsave(&adapter->vfs_lock, flags);
                kfree(adapter->vf_mac_list);
                adapter->vf_mac_list = NULL;
                kfree(adapter->vf_data);
                adapter->vf_data = NULL;
                adapter->vfs_allocated_count = 0;
+               spin_unlock_irqrestore(&adapter->vfs_lock, flags);
                wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);
                wrfl();
                msleep(100);
@@ -3814,7 +3816,9 @@ static void igb_remove(struct pci_dev *pdev)
        igb_release_hw_control(adapter);
 
 #ifdef CONFIG_PCI_IOV
+       rtnl_lock();
        igb_disable_sriov(pdev);
+       rtnl_unlock();
 #endif
 
        unregister_netdev(netdev);
@@ -3974,6 +3978,9 @@ static int igb_sw_init(struct igb_adapter *adapter)
 
        spin_lock_init(&adapter->nfc_lock);
        spin_lock_init(&adapter->stats64_lock);
+
+       /* init spinlock to avoid concurrency of VF resources */
+       spin_lock_init(&adapter->vfs_lock);
 #ifdef CONFIG_PCI_IOV
        switch (hw->mac.type) {
        case e1000_82576:
@@ -7958,8 +7965,10 @@ unlock:
 static void igb_msg_task(struct igb_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
+       unsigned long flags;
        u32 vf;
 
+       spin_lock_irqsave(&adapter->vfs_lock, flags);
        for (vf = 0; vf < adapter->vfs_allocated_count; vf++) {
                /* process any reset requests */
                if (!igb_check_for_rst(hw, vf))
@@ -7973,6 +7982,7 @@ static void igb_msg_task(struct igb_adapter *adapter)
                if (!igb_check_for_ack(hw, vf))
                        igb_rcv_ack_from_vf(adapter, vf);
        }
+       spin_unlock_irqrestore(&adapter->vfs_lock, flags);
 }
 
 /**
index d9426b0..8aff4c0 100644 (file)
@@ -1732,7 +1732,7 @@ static u32 mtk_xdp_run(struct mtk_eth *eth, struct mtk_rx_ring *ring,
        case XDP_TX: {
                struct xdp_frame *xdpf = xdp_convert_buff_to_frame(xdp);
 
-               if (mtk_xdp_submit_frame(eth, xdpf, dev, false)) {
+               if (!xdpf || mtk_xdp_submit_frame(eth, xdpf, dev, false)) {
                        count = &hw_stats->xdp_stats.rx_xdp_tx_errors;
                        act = XDP_DROP;
                        break;
index 4c1599d..0c66774 100644 (file)
@@ -696,6 +696,13 @@ static int mlx5e_init_rep(struct mlx5_core_dev *mdev,
 {
        struct mlx5e_priv *priv = netdev_priv(netdev);
 
+       priv->fs = mlx5e_fs_init(priv->profile, mdev,
+                                !test_bit(MLX5E_STATE_DESTROYING, &priv->state));
+       if (!priv->fs) {
+               netdev_err(priv->netdev, "FS allocation failed\n");
+               return -ENOMEM;
+       }
+
        mlx5e_build_rep_params(netdev);
        mlx5e_timestamp_init(priv);
 
@@ -708,12 +715,21 @@ static int mlx5e_init_ul_rep(struct mlx5_core_dev *mdev,
        struct mlx5e_priv *priv = netdev_priv(netdev);
        int err;
 
+       priv->fs = mlx5e_fs_init(priv->profile, mdev,
+                                !test_bit(MLX5E_STATE_DESTROYING, &priv->state));
+       if (!priv->fs) {
+               netdev_err(priv->netdev, "FS allocation failed\n");
+               return -ENOMEM;
+       }
+
        err = mlx5e_ipsec_init(priv);
        if (err)
                mlx5_core_err(mdev, "Uplink rep IPsec initialization failed, %d\n", err);
 
        mlx5e_vxlan_set_netdev_info(priv);
-       return mlx5e_init_rep(mdev, netdev);
+       mlx5e_build_rep_params(netdev);
+       mlx5e_timestamp_init(priv);
+       return 0;
 }
 
 static void mlx5e_cleanup_rep(struct mlx5e_priv *priv)
@@ -836,13 +852,6 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
        struct mlx5_core_dev *mdev = priv->mdev;
        int err;
 
-       priv->fs = mlx5e_fs_init(priv->profile, mdev,
-                                !test_bit(MLX5E_STATE_DESTROYING, &priv->state));
-       if (!priv->fs) {
-               netdev_err(priv->netdev, "FS allocation failed\n");
-               return -ENOMEM;
-       }
-
        priv->rx_res = mlx5e_rx_res_alloc();
        if (!priv->rx_res) {
                err = -ENOMEM;
index 1e240cd..30c7b0e 100644 (file)
@@ -1897,9 +1897,9 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u16 local_port)
 
        cancel_delayed_work_sync(&mlxsw_sp_port->periodic_hw_stats.update_dw);
        cancel_delayed_work_sync(&mlxsw_sp_port->ptp.shaper_dw);
-       mlxsw_sp_port_ptp_clear(mlxsw_sp_port);
        mlxsw_core_port_clear(mlxsw_sp->core, local_port, mlxsw_sp);
        unregister_netdev(mlxsw_sp_port->dev); /* This calls ndo_stop */
+       mlxsw_sp_port_ptp_clear(mlxsw_sp_port);
        mlxsw_sp_port_vlan_classification_set(mlxsw_sp_port, true, true);
        mlxsw_sp->ports[local_port] = NULL;
        mlxsw_sp_port_vlan_flush(mlxsw_sp_port, true);
index 2e0b704..7b01b9c 100644 (file)
@@ -46,6 +46,7 @@ struct mlxsw_sp2_ptp_state {
                                          * enabled.
                                          */
        struct hwtstamp_config config;
+       struct mutex lock; /* Protects 'config' and HW configuration. */
 };
 
 struct mlxsw_sp1_ptp_key {
@@ -1374,6 +1375,7 @@ struct mlxsw_sp_ptp_state *mlxsw_sp2_ptp_init(struct mlxsw_sp *mlxsw_sp)
                goto err_ptp_traps_set;
 
        refcount_set(&ptp_state->ptp_port_enabled_ref, 0);
+       mutex_init(&ptp_state->lock);
        return &ptp_state->common;
 
 err_ptp_traps_set:
@@ -1388,6 +1390,7 @@ void mlxsw_sp2_ptp_fini(struct mlxsw_sp_ptp_state *ptp_state_common)
 
        ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp);
 
+       mutex_destroy(&ptp_state->lock);
        mlxsw_sp_ptp_traps_unset(mlxsw_sp);
        kfree(ptp_state);
 }
@@ -1461,7 +1464,10 @@ int mlxsw_sp2_ptp_hwtstamp_get(struct mlxsw_sp_port *mlxsw_sp_port,
 
        ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp_port->mlxsw_sp);
 
+       mutex_lock(&ptp_state->lock);
        *config = ptp_state->config;
+       mutex_unlock(&ptp_state->lock);
+
        return 0;
 }
 
@@ -1523,6 +1529,9 @@ mlxsw_sp2_ptp_get_message_types(const struct hwtstamp_config *config,
                return -EINVAL;
        }
 
+       if ((ing_types && !egr_types) || (!ing_types && egr_types))
+               return -EINVAL;
+
        *p_ing_types = ing_types;
        *p_egr_types = egr_types;
        return 0;
@@ -1574,8 +1583,6 @@ static int mlxsw_sp2_ptp_configure_port(struct mlxsw_sp_port *mlxsw_sp_port,
        struct mlxsw_sp2_ptp_state *ptp_state;
        int err;
 
-       ASSERT_RTNL();
-
        ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp_port->mlxsw_sp);
 
        if (refcount_inc_not_zero(&ptp_state->ptp_port_enabled_ref))
@@ -1597,8 +1604,6 @@ static int mlxsw_sp2_ptp_deconfigure_port(struct mlxsw_sp_port *mlxsw_sp_port,
        struct mlxsw_sp2_ptp_state *ptp_state;
        int err;
 
-       ASSERT_RTNL();
-
        ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp_port->mlxsw_sp);
 
        if (!refcount_dec_and_test(&ptp_state->ptp_port_enabled_ref))
@@ -1618,16 +1623,20 @@ err_ptp_disable:
 int mlxsw_sp2_ptp_hwtstamp_set(struct mlxsw_sp_port *mlxsw_sp_port,
                               struct hwtstamp_config *config)
 {
+       struct mlxsw_sp2_ptp_state *ptp_state;
        enum hwtstamp_rx_filters rx_filter;
        struct hwtstamp_config new_config;
        u16 new_ing_types, new_egr_types;
        bool ptp_enabled;
        int err;
 
+       ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp_port->mlxsw_sp);
+       mutex_lock(&ptp_state->lock);
+
        err = mlxsw_sp2_ptp_get_message_types(config, &new_ing_types,
                                              &new_egr_types, &rx_filter);
        if (err)
-               return err;
+               goto err_get_message_types;
 
        new_config.flags = config->flags;
        new_config.tx_type = config->tx_type;
@@ -1640,11 +1649,11 @@ int mlxsw_sp2_ptp_hwtstamp_set(struct mlxsw_sp_port *mlxsw_sp_port,
                err = mlxsw_sp2_ptp_configure_port(mlxsw_sp_port, new_ing_types,
                                                   new_egr_types, new_config);
                if (err)
-                       return err;
+                       goto err_configure_port;
        } else if (!new_ing_types && !new_egr_types && ptp_enabled) {
                err = mlxsw_sp2_ptp_deconfigure_port(mlxsw_sp_port, new_config);
                if (err)
-                       return err;
+                       goto err_deconfigure_port;
        }
 
        mlxsw_sp_port->ptp.ing_types = new_ing_types;
@@ -1652,8 +1661,15 @@ int mlxsw_sp2_ptp_hwtstamp_set(struct mlxsw_sp_port *mlxsw_sp_port,
 
        /* Notify the ioctl caller what we are actually timestamping. */
        config->rx_filter = rx_filter;
+       mutex_unlock(&ptp_state->lock);
 
        return 0;
+
+err_deconfigure_port:
+err_configure_port:
+err_get_message_types:
+       mutex_unlock(&ptp_state->lock);
+       return err;
 }
 
 int mlxsw_sp2_ptp_get_ts_info(struct mlxsw_sp *mlxsw_sp,
index 2d1628f..a8b8823 100644 (file)
@@ -171,10 +171,11 @@ static inline void mlxsw_sp1_get_stats(struct mlxsw_sp_port *mlxsw_sp_port,
 {
 }
 
-int mlxsw_sp_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core,
-                                struct mlxsw_sp_port *mlxsw_sp_port,
-                                struct sk_buff *skb,
-                                const struct mlxsw_tx_info *tx_info)
+static inline int
+mlxsw_sp_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core,
+                            struct mlxsw_sp_port *mlxsw_sp_port,
+                            struct sk_buff *skb,
+                            const struct mlxsw_tx_info *tx_info)
 {
        return -EOPNOTSUPP;
 }
@@ -231,10 +232,11 @@ static inline int mlxsw_sp2_ptp_get_ts_info(struct mlxsw_sp *mlxsw_sp,
        return mlxsw_sp_ptp_get_ts_info_noptp(info);
 }
 
-int mlxsw_sp2_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core,
-                                 struct mlxsw_sp_port *mlxsw_sp_port,
-                                 struct sk_buff *skb,
-                                 const struct mlxsw_tx_info *tx_info)
+static inline int
+mlxsw_sp2_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core,
+                             struct mlxsw_sp_port *mlxsw_sp_port,
+                             struct sk_buff *skb,
+                             const struct mlxsw_tx_info *tx_info)
 {
        return -EOPNOTSUPP;
 }
index 1d6e3b6..d928b75 100644 (file)
@@ -710,7 +710,7 @@ static void lan966x_cleanup_ports(struct lan966x *lan966x)
        disable_irq(lan966x->xtr_irq);
        lan966x->xtr_irq = -ENXIO;
 
-       if (lan966x->ana_irq) {
+       if (lan966x->ana_irq > 0) {
                disable_irq(lan966x->ana_irq);
                lan966x->ana_irq = -ENXIO;
        }
@@ -718,10 +718,10 @@ static void lan966x_cleanup_ports(struct lan966x *lan966x)
        if (lan966x->fdma)
                devm_free_irq(lan966x->dev, lan966x->fdma_irq, lan966x);
 
-       if (lan966x->ptp_irq)
+       if (lan966x->ptp_irq > 0)
                devm_free_irq(lan966x->dev, lan966x->ptp_irq, lan966x);
 
-       if (lan966x->ptp_ext_irq)
+       if (lan966x->ptp_ext_irq > 0)
                devm_free_irq(lan966x->dev, lan966x->ptp_ext_irq, lan966x);
 }
 
@@ -1049,7 +1049,7 @@ static int lan966x_probe(struct platform_device *pdev)
        }
 
        lan966x->ana_irq = platform_get_irq_byname(pdev, "ana");
-       if (lan966x->ana_irq) {
+       if (lan966x->ana_irq > 0) {
                err = devm_request_threaded_irq(&pdev->dev, lan966x->ana_irq, NULL,
                                                lan966x_ana_irq_handler, IRQF_ONESHOT,
                                                "ana irq", lan966x);
index a3214a7..19009a6 100644 (file)
@@ -62,9 +62,6 @@ static int moxart_set_mac_address(struct net_device *ndev, void *addr)
 {
        struct sockaddr *address = addr;
 
-       if (!is_valid_ether_addr(address->sa_data))
-               return -EADDRNOTAVAIL;
-
        eth_hw_addr_set(ndev, address->sa_data);
        moxart_update_mac_address(ndev);
 
@@ -77,7 +74,7 @@ static void moxart_mac_free_memory(struct net_device *ndev)
        int i;
 
        for (i = 0; i < RX_DESC_NUM; i++)
-               dma_unmap_single(&ndev->dev, priv->rx_mapping[i],
+               dma_unmap_single(&priv->pdev->dev, priv->rx_mapping[i],
                                 priv->rx_buf_size, DMA_FROM_DEVICE);
 
        if (priv->tx_desc_base)
@@ -147,11 +144,11 @@ static void moxart_mac_setup_desc_ring(struct net_device *ndev)
                       desc + RX_REG_OFFSET_DESC1);
 
                priv->rx_buf[i] = priv->rx_buf_base + priv->rx_buf_size * i;
-               priv->rx_mapping[i] = dma_map_single(&ndev->dev,
+               priv->rx_mapping[i] = dma_map_single(&priv->pdev->dev,
                                                     priv->rx_buf[i],
                                                     priv->rx_buf_size,
                                                     DMA_FROM_DEVICE);
-               if (dma_mapping_error(&ndev->dev, priv->rx_mapping[i]))
+               if (dma_mapping_error(&priv->pdev->dev, priv->rx_mapping[i]))
                        netdev_err(ndev, "DMA mapping error\n");
 
                moxart_desc_write(priv->rx_mapping[i],
@@ -172,9 +169,6 @@ static int moxart_mac_open(struct net_device *ndev)
 {
        struct moxart_mac_priv_t *priv = netdev_priv(ndev);
 
-       if (!is_valid_ether_addr(ndev->dev_addr))
-               return -EADDRNOTAVAIL;
-
        napi_enable(&priv->napi);
 
        moxart_mac_reset(ndev);
@@ -240,7 +234,7 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
                if (len > RX_BUF_SIZE)
                        len = RX_BUF_SIZE;
 
-               dma_sync_single_for_cpu(&ndev->dev,
+               dma_sync_single_for_cpu(&priv->pdev->dev,
                                        priv->rx_mapping[rx_head],
                                        priv->rx_buf_size, DMA_FROM_DEVICE);
                skb = netdev_alloc_skb_ip_align(ndev, len);
@@ -294,7 +288,7 @@ static void moxart_tx_finished(struct net_device *ndev)
        unsigned int tx_tail = priv->tx_tail;
 
        while (tx_tail != tx_head) {
-               dma_unmap_single(&ndev->dev, priv->tx_mapping[tx_tail],
+               dma_unmap_single(&priv->pdev->dev, priv->tx_mapping[tx_tail],
                                 priv->tx_len[tx_tail], DMA_TO_DEVICE);
 
                ndev->stats.tx_packets++;
@@ -358,9 +352,9 @@ static netdev_tx_t moxart_mac_start_xmit(struct sk_buff *skb,
 
        len = skb->len > TX_BUF_SIZE ? TX_BUF_SIZE : skb->len;
 
-       priv->tx_mapping[tx_head] = dma_map_single(&ndev->dev, skb->data,
+       priv->tx_mapping[tx_head] = dma_map_single(&priv->pdev->dev, skb->data,
                                                   len, DMA_TO_DEVICE);
-       if (dma_mapping_error(&ndev->dev, priv->tx_mapping[tx_head])) {
+       if (dma_mapping_error(&priv->pdev->dev, priv->tx_mapping[tx_head])) {
                netdev_err(ndev, "DMA mapping error\n");
                goto out_unlock;
        }
@@ -379,7 +373,7 @@ static netdev_tx_t moxart_mac_start_xmit(struct sk_buff *skb,
                len = ETH_ZLEN;
        }
 
-       dma_sync_single_for_device(&ndev->dev, priv->tx_mapping[tx_head],
+       dma_sync_single_for_device(&priv->pdev->dev, priv->tx_mapping[tx_head],
                                   priv->tx_buf_size, DMA_TO_DEVICE);
 
        txdes1 = TX_DESC1_LTS | TX_DESC1_FTS | (len & TX_DESC1_BUF_SIZE_MASK);
@@ -488,12 +482,19 @@ static int moxart_mac_probe(struct platform_device *pdev)
        }
        ndev->base_addr = res->start;
 
+       ret = platform_get_ethdev_address(p_dev, ndev);
+       if (ret == -EPROBE_DEFER)
+               goto init_fail;
+       if (ret)
+               eth_hw_addr_random(ndev);
+       moxart_update_mac_address(ndev);
+
        spin_lock_init(&priv->txlock);
 
        priv->tx_buf_size = TX_BUF_SIZE;
        priv->rx_buf_size = RX_BUF_SIZE;
 
-       priv->tx_desc_base = dma_alloc_coherent(&pdev->dev, TX_REG_DESC_SIZE *
+       priv->tx_desc_base = dma_alloc_coherent(p_dev, TX_REG_DESC_SIZE *
                                                TX_DESC_NUM, &priv->tx_base,
                                                GFP_DMA | GFP_KERNEL);
        if (!priv->tx_desc_base) {
@@ -501,7 +502,7 @@ static int moxart_mac_probe(struct platform_device *pdev)
                goto init_fail;
        }
 
-       priv->rx_desc_base = dma_alloc_coherent(&pdev->dev, RX_REG_DESC_SIZE *
+       priv->rx_desc_base = dma_alloc_coherent(p_dev, RX_REG_DESC_SIZE *
                                                RX_DESC_NUM, &priv->rx_base,
                                                GFP_DMA | GFP_KERNEL);
        if (!priv->rx_desc_base) {
index d4649e4..306026e 100644 (file)
@@ -1860,16 +1860,20 @@ void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset, u8 *data)
        if (sset != ETH_SS_STATS)
                return;
 
-       for (i = 0; i < ocelot->num_stats; i++)
+       for (i = 0; i < OCELOT_NUM_STATS; i++) {
+               if (ocelot->stats_layout[i].name[0] == '\0')
+                       continue;
+
                memcpy(data + i * ETH_GSTRING_LEN, ocelot->stats_layout[i].name,
                       ETH_GSTRING_LEN);
+       }
 }
 EXPORT_SYMBOL(ocelot_get_strings);
 
 /* Caller must hold &ocelot->stats_lock */
 static int ocelot_port_update_stats(struct ocelot *ocelot, int port)
 {
-       unsigned int idx = port * ocelot->num_stats;
+       unsigned int idx = port * OCELOT_NUM_STATS;
        struct ocelot_stats_region *region;
        int err, j;
 
@@ -1877,9 +1881,8 @@ static int ocelot_port_update_stats(struct ocelot *ocelot, int port)
        ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port), SYS_STAT_CFG);
 
        list_for_each_entry(region, &ocelot->stats_regions, node) {
-               err = ocelot_bulk_read_rix(ocelot, SYS_COUNT_RX_OCTETS,
-                                          region->offset, region->buf,
-                                          region->count);
+               err = ocelot_bulk_read(ocelot, region->base, region->buf,
+                                      region->count);
                if (err)
                        return err;
 
@@ -1906,13 +1909,13 @@ static void ocelot_check_stats_work(struct work_struct *work)
                                             stats_work);
        int i, err;
 
-       mutex_lock(&ocelot->stats_lock);
+       spin_lock(&ocelot->stats_lock);
        for (i = 0; i < ocelot->num_phys_ports; i++) {
                err = ocelot_port_update_stats(ocelot, i);
                if (err)
                        break;
        }
-       mutex_unlock(&ocelot->stats_lock);
+       spin_unlock(&ocelot->stats_lock);
 
        if (err)
                dev_err(ocelot->dev, "Error %d updating ethtool stats\n",  err);
@@ -1925,16 +1928,22 @@ void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data)
 {
        int i, err;
 
-       mutex_lock(&ocelot->stats_lock);
+       spin_lock(&ocelot->stats_lock);
 
        /* check and update now */
        err = ocelot_port_update_stats(ocelot, port);
 
-       /* Copy all counters */
-       for (i = 0; i < ocelot->num_stats; i++)
-               *data++ = ocelot->stats[port * ocelot->num_stats + i];
+       /* Copy all supported counters */
+       for (i = 0; i < OCELOT_NUM_STATS; i++) {
+               int index = port * OCELOT_NUM_STATS + i;
+
+               if (ocelot->stats_layout[i].name[0] == '\0')
+                       continue;
+
+               *data++ = ocelot->stats[index];
+       }
 
-       mutex_unlock(&ocelot->stats_lock);
+       spin_unlock(&ocelot->stats_lock);
 
        if (err)
                dev_err(ocelot->dev, "Error %d updating ethtool stats\n", err);
@@ -1943,10 +1952,16 @@ EXPORT_SYMBOL(ocelot_get_ethtool_stats);
 
 int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset)
 {
+       int i, num_stats = 0;
+
        if (sset != ETH_SS_STATS)
                return -EOPNOTSUPP;
 
-       return ocelot->num_stats;
+       for (i = 0; i < OCELOT_NUM_STATS; i++)
+               if (ocelot->stats_layout[i].name[0] != '\0')
+                       num_stats++;
+
+       return num_stats;
 }
 EXPORT_SYMBOL(ocelot_get_sset_count);
 
@@ -1958,8 +1973,11 @@ static int ocelot_prepare_stats_regions(struct ocelot *ocelot)
 
        INIT_LIST_HEAD(&ocelot->stats_regions);
 
-       for (i = 0; i < ocelot->num_stats; i++) {
-               if (region && ocelot->stats_layout[i].offset == last + 1) {
+       for (i = 0; i < OCELOT_NUM_STATS; i++) {
+               if (ocelot->stats_layout[i].name[0] == '\0')
+                       continue;
+
+               if (region && ocelot->stats_layout[i].reg == last + 4) {
                        region->count++;
                } else {
                        region = devm_kzalloc(ocelot->dev, sizeof(*region),
@@ -1967,12 +1985,12 @@ static int ocelot_prepare_stats_regions(struct ocelot *ocelot)
                        if (!region)
                                return -ENOMEM;
 
-                       region->offset = ocelot->stats_layout[i].offset;
+                       region->base = ocelot->stats_layout[i].reg;
                        region->count = 1;
                        list_add_tail(&region->node, &ocelot->stats_regions);
                }
 
-               last = ocelot->stats_layout[i].offset;
+               last = ocelot->stats_layout[i].reg;
        }
 
        list_for_each_entry(region, &ocelot->stats_regions, node) {
@@ -3340,7 +3358,6 @@ static void ocelot_detect_features(struct ocelot *ocelot)
 
 int ocelot_init(struct ocelot *ocelot)
 {
-       const struct ocelot_stat_layout *stat;
        char queue_name[32];
        int i, ret;
        u32 port;
@@ -3353,17 +3370,13 @@ int ocelot_init(struct ocelot *ocelot)
                }
        }
 
-       ocelot->num_stats = 0;
-       for_each_stat(ocelot, stat)
-               ocelot->num_stats++;
-
        ocelot->stats = devm_kcalloc(ocelot->dev,
-                                    ocelot->num_phys_ports * ocelot->num_stats,
+                                    ocelot->num_phys_ports * OCELOT_NUM_STATS,
                                     sizeof(u64), GFP_KERNEL);
        if (!ocelot->stats)
                return -ENOMEM;
 
-       mutex_init(&ocelot->stats_lock);
+       spin_lock_init(&ocelot->stats_lock);
        mutex_init(&ocelot->ptp_lock);
        mutex_init(&ocelot->mact_lock);
        mutex_init(&ocelot->fwd_domain_lock);
@@ -3511,7 +3524,6 @@ void ocelot_deinit(struct ocelot *ocelot)
        cancel_delayed_work(&ocelot->stats_work);
        destroy_workqueue(ocelot->stats_queue);
        destroy_workqueue(ocelot->owq);
-       mutex_destroy(&ocelot->stats_lock);
 }
 EXPORT_SYMBOL(ocelot_deinit);
 
index 5e6136e..330d308 100644 (file)
@@ -725,37 +725,42 @@ static void ocelot_get_stats64(struct net_device *dev,
        struct ocelot_port_private *priv = netdev_priv(dev);
        struct ocelot *ocelot = priv->port.ocelot;
        int port = priv->port.index;
+       u64 *s;
 
-       /* Configure the port to read the stats from */
-       ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port),
-                    SYS_STAT_CFG);
+       spin_lock(&ocelot->stats_lock);
+
+       s = &ocelot->stats[port * OCELOT_NUM_STATS];
 
        /* Get Rx stats */
-       stats->rx_bytes = ocelot_read(ocelot, SYS_COUNT_RX_OCTETS);
-       stats->rx_packets = ocelot_read(ocelot, SYS_COUNT_RX_SHORTS) +
-                           ocelot_read(ocelot, SYS_COUNT_RX_FRAGMENTS) +
-                           ocelot_read(ocelot, SYS_COUNT_RX_JABBERS) +
-                           ocelot_read(ocelot, SYS_COUNT_RX_LONGS) +
-                           ocelot_read(ocelot, SYS_COUNT_RX_64) +
-                           ocelot_read(ocelot, SYS_COUNT_RX_65_127) +
-                           ocelot_read(ocelot, SYS_COUNT_RX_128_255) +
-                           ocelot_read(ocelot, SYS_COUNT_RX_256_1023) +
-                           ocelot_read(ocelot, SYS_COUNT_RX_1024_1526) +
-                           ocelot_read(ocelot, SYS_COUNT_RX_1527_MAX);
-       stats->multicast = ocelot_read(ocelot, SYS_COUNT_RX_MULTICAST);
+       stats->rx_bytes = s[OCELOT_STAT_RX_OCTETS];
+       stats->rx_packets = s[OCELOT_STAT_RX_SHORTS] +
+                           s[OCELOT_STAT_RX_FRAGMENTS] +
+                           s[OCELOT_STAT_RX_JABBERS] +
+                           s[OCELOT_STAT_RX_LONGS] +
+                           s[OCELOT_STAT_RX_64] +
+                           s[OCELOT_STAT_RX_65_127] +
+                           s[OCELOT_STAT_RX_128_255] +
+                           s[OCELOT_STAT_RX_256_511] +
+                           s[OCELOT_STAT_RX_512_1023] +
+                           s[OCELOT_STAT_RX_1024_1526] +
+                           s[OCELOT_STAT_RX_1527_MAX];
+       stats->multicast = s[OCELOT_STAT_RX_MULTICAST];
        stats->rx_dropped = dev->stats.rx_dropped;
 
        /* Get Tx stats */
-       stats->tx_bytes = ocelot_read(ocelot, SYS_COUNT_TX_OCTETS);
-       stats->tx_packets = ocelot_read(ocelot, SYS_COUNT_TX_64) +
-                           ocelot_read(ocelot, SYS_COUNT_TX_65_127) +
-                           ocelot_read(ocelot, SYS_COUNT_TX_128_511) +
-                           ocelot_read(ocelot, SYS_COUNT_TX_512_1023) +
-                           ocelot_read(ocelot, SYS_COUNT_TX_1024_1526) +
-                           ocelot_read(ocelot, SYS_COUNT_TX_1527_MAX);
-       stats->tx_dropped = ocelot_read(ocelot, SYS_COUNT_TX_DROPS) +
-                           ocelot_read(ocelot, SYS_COUNT_TX_AGING);
-       stats->collisions = ocelot_read(ocelot, SYS_COUNT_TX_COLLISION);
+       stats->tx_bytes = s[OCELOT_STAT_TX_OCTETS];
+       stats->tx_packets = s[OCELOT_STAT_TX_64] +
+                           s[OCELOT_STAT_TX_65_127] +
+                           s[OCELOT_STAT_TX_128_255] +
+                           s[OCELOT_STAT_TX_256_511] +
+                           s[OCELOT_STAT_TX_512_1023] +
+                           s[OCELOT_STAT_TX_1024_1526] +
+                           s[OCELOT_STAT_TX_1527_MAX];
+       stats->tx_dropped = s[OCELOT_STAT_TX_DROPS] +
+                           s[OCELOT_STAT_TX_AGED];
+       stats->collisions = s[OCELOT_STAT_TX_COLLISION];
+
+       spin_unlock(&ocelot->stats_lock);
 }
 
 static int ocelot_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
index 961f803..9c48895 100644 (file)
@@ -96,101 +96,379 @@ static const struct reg_field ocelot_regfields[REGFIELD_MAX] = {
        [SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 12, 4),
 };
 
-static const struct ocelot_stat_layout ocelot_stats_layout[] = {
-       { .name = "rx_octets", .offset = 0x00, },
-       { .name = "rx_unicast", .offset = 0x01, },
-       { .name = "rx_multicast", .offset = 0x02, },
-       { .name = "rx_broadcast", .offset = 0x03, },
-       { .name = "rx_shorts", .offset = 0x04, },
-       { .name = "rx_fragments", .offset = 0x05, },
-       { .name = "rx_jabbers", .offset = 0x06, },
-       { .name = "rx_crc_align_errs", .offset = 0x07, },
-       { .name = "rx_sym_errs", .offset = 0x08, },
-       { .name = "rx_frames_below_65_octets", .offset = 0x09, },
-       { .name = "rx_frames_65_to_127_octets", .offset = 0x0A, },
-       { .name = "rx_frames_128_to_255_octets", .offset = 0x0B, },
-       { .name = "rx_frames_256_to_511_octets", .offset = 0x0C, },
-       { .name = "rx_frames_512_to_1023_octets", .offset = 0x0D, },
-       { .name = "rx_frames_1024_to_1526_octets", .offset = 0x0E, },
-       { .name = "rx_frames_over_1526_octets", .offset = 0x0F, },
-       { .name = "rx_pause", .offset = 0x10, },
-       { .name = "rx_control", .offset = 0x11, },
-       { .name = "rx_longs", .offset = 0x12, },
-       { .name = "rx_classified_drops", .offset = 0x13, },
-       { .name = "rx_red_prio_0", .offset = 0x14, },
-       { .name = "rx_red_prio_1", .offset = 0x15, },
-       { .name = "rx_red_prio_2", .offset = 0x16, },
-       { .name = "rx_red_prio_3", .offset = 0x17, },
-       { .name = "rx_red_prio_4", .offset = 0x18, },
-       { .name = "rx_red_prio_5", .offset = 0x19, },
-       { .name = "rx_red_prio_6", .offset = 0x1A, },
-       { .name = "rx_red_prio_7", .offset = 0x1B, },
-       { .name = "rx_yellow_prio_0", .offset = 0x1C, },
-       { .name = "rx_yellow_prio_1", .offset = 0x1D, },
-       { .name = "rx_yellow_prio_2", .offset = 0x1E, },
-       { .name = "rx_yellow_prio_3", .offset = 0x1F, },
-       { .name = "rx_yellow_prio_4", .offset = 0x20, },
-       { .name = "rx_yellow_prio_5", .offset = 0x21, },
-       { .name = "rx_yellow_prio_6", .offset = 0x22, },
-       { .name = "rx_yellow_prio_7", .offset = 0x23, },
-       { .name = "rx_green_prio_0", .offset = 0x24, },
-       { .name = "rx_green_prio_1", .offset = 0x25, },
-       { .name = "rx_green_prio_2", .offset = 0x26, },
-       { .name = "rx_green_prio_3", .offset = 0x27, },
-       { .name = "rx_green_prio_4", .offset = 0x28, },
-       { .name = "rx_green_prio_5", .offset = 0x29, },
-       { .name = "rx_green_prio_6", .offset = 0x2A, },
-       { .name = "rx_green_prio_7", .offset = 0x2B, },
-       { .name = "tx_octets", .offset = 0x40, },
-       { .name = "tx_unicast", .offset = 0x41, },
-       { .name = "tx_multicast", .offset = 0x42, },
-       { .name = "tx_broadcast", .offset = 0x43, },
-       { .name = "tx_collision", .offset = 0x44, },
-       { .name = "tx_drops", .offset = 0x45, },
-       { .name = "tx_pause", .offset = 0x46, },
-       { .name = "tx_frames_below_65_octets", .offset = 0x47, },
-       { .name = "tx_frames_65_to_127_octets", .offset = 0x48, },
-       { .name = "tx_frames_128_255_octets", .offset = 0x49, },
-       { .name = "tx_frames_256_511_octets", .offset = 0x4A, },
-       { .name = "tx_frames_512_1023_octets", .offset = 0x4B, },
-       { .name = "tx_frames_1024_1526_octets", .offset = 0x4C, },
-       { .name = "tx_frames_over_1526_octets", .offset = 0x4D, },
-       { .name = "tx_yellow_prio_0", .offset = 0x4E, },
-       { .name = "tx_yellow_prio_1", .offset = 0x4F, },
-       { .name = "tx_yellow_prio_2", .offset = 0x50, },
-       { .name = "tx_yellow_prio_3", .offset = 0x51, },
-       { .name = "tx_yellow_prio_4", .offset = 0x52, },
-       { .name = "tx_yellow_prio_5", .offset = 0x53, },
-       { .name = "tx_yellow_prio_6", .offset = 0x54, },
-       { .name = "tx_yellow_prio_7", .offset = 0x55, },
-       { .name = "tx_green_prio_0", .offset = 0x56, },
-       { .name = "tx_green_prio_1", .offset = 0x57, },
-       { .name = "tx_green_prio_2", .offset = 0x58, },
-       { .name = "tx_green_prio_3", .offset = 0x59, },
-       { .name = "tx_green_prio_4", .offset = 0x5A, },
-       { .name = "tx_green_prio_5", .offset = 0x5B, },
-       { .name = "tx_green_prio_6", .offset = 0x5C, },
-       { .name = "tx_green_prio_7", .offset = 0x5D, },
-       { .name = "tx_aged", .offset = 0x5E, },
-       { .name = "drop_local", .offset = 0x80, },
-       { .name = "drop_tail", .offset = 0x81, },
-       { .name = "drop_yellow_prio_0", .offset = 0x82, },
-       { .name = "drop_yellow_prio_1", .offset = 0x83, },
-       { .name = "drop_yellow_prio_2", .offset = 0x84, },
-       { .name = "drop_yellow_prio_3", .offset = 0x85, },
-       { .name = "drop_yellow_prio_4", .offset = 0x86, },
-       { .name = "drop_yellow_prio_5", .offset = 0x87, },
-       { .name = "drop_yellow_prio_6", .offset = 0x88, },
-       { .name = "drop_yellow_prio_7", .offset = 0x89, },
-       { .name = "drop_green_prio_0", .offset = 0x8A, },
-       { .name = "drop_green_prio_1", .offset = 0x8B, },
-       { .name = "drop_green_prio_2", .offset = 0x8C, },
-       { .name = "drop_green_prio_3", .offset = 0x8D, },
-       { .name = "drop_green_prio_4", .offset = 0x8E, },
-       { .name = "drop_green_prio_5", .offset = 0x8F, },
-       { .name = "drop_green_prio_6", .offset = 0x90, },
-       { .name = "drop_green_prio_7", .offset = 0x91, },
-       OCELOT_STAT_END
+static const struct ocelot_stat_layout ocelot_stats_layout[OCELOT_NUM_STATS] = {
+       [OCELOT_STAT_RX_OCTETS] = {
+               .name = "rx_octets",
+               .reg = SYS_COUNT_RX_OCTETS,
+       },
+       [OCELOT_STAT_RX_UNICAST] = {
+               .name = "rx_unicast",
+               .reg = SYS_COUNT_RX_UNICAST,
+       },
+       [OCELOT_STAT_RX_MULTICAST] = {
+               .name = "rx_multicast",
+               .reg = SYS_COUNT_RX_MULTICAST,
+       },
+       [OCELOT_STAT_RX_BROADCAST] = {
+               .name = "rx_broadcast",
+               .reg = SYS_COUNT_RX_BROADCAST,
+       },
+       [OCELOT_STAT_RX_SHORTS] = {
+               .name = "rx_shorts",
+               .reg = SYS_COUNT_RX_SHORTS,
+       },
+       [OCELOT_STAT_RX_FRAGMENTS] = {
+               .name = "rx_fragments",
+               .reg = SYS_COUNT_RX_FRAGMENTS,
+       },
+       [OCELOT_STAT_RX_JABBERS] = {
+               .name = "rx_jabbers",
+               .reg = SYS_COUNT_RX_JABBERS,
+       },
+       [OCELOT_STAT_RX_CRC_ALIGN_ERRS] = {
+               .name = "rx_crc_align_errs",
+               .reg = SYS_COUNT_RX_CRC_ALIGN_ERRS,
+       },
+       [OCELOT_STAT_RX_SYM_ERRS] = {
+               .name = "rx_sym_errs",
+               .reg = SYS_COUNT_RX_SYM_ERRS,
+       },
+       [OCELOT_STAT_RX_64] = {
+               .name = "rx_frames_below_65_octets",
+               .reg = SYS_COUNT_RX_64,
+       },
+       [OCELOT_STAT_RX_65_127] = {
+               .name = "rx_frames_65_to_127_octets",
+               .reg = SYS_COUNT_RX_65_127,
+       },
+       [OCELOT_STAT_RX_128_255] = {
+               .name = "rx_frames_128_to_255_octets",
+               .reg = SYS_COUNT_RX_128_255,
+       },
+       [OCELOT_STAT_RX_256_511] = {
+               .name = "rx_frames_256_to_511_octets",
+               .reg = SYS_COUNT_RX_256_511,
+       },
+       [OCELOT_STAT_RX_512_1023] = {
+               .name = "rx_frames_512_to_1023_octets",
+               .reg = SYS_COUNT_RX_512_1023,
+       },
+       [OCELOT_STAT_RX_1024_1526] = {
+               .name = "rx_frames_1024_to_1526_octets",
+               .reg = SYS_COUNT_RX_1024_1526,
+       },
+       [OCELOT_STAT_RX_1527_MAX] = {
+               .name = "rx_frames_over_1526_octets",
+               .reg = SYS_COUNT_RX_1527_MAX,
+       },
+       [OCELOT_STAT_RX_PAUSE] = {
+               .name = "rx_pause",
+               .reg = SYS_COUNT_RX_PAUSE,
+       },
+       [OCELOT_STAT_RX_CONTROL] = {
+               .name = "rx_control",
+               .reg = SYS_COUNT_RX_CONTROL,
+       },
+       [OCELOT_STAT_RX_LONGS] = {
+               .name = "rx_longs",
+               .reg = SYS_COUNT_RX_LONGS,
+       },
+       [OCELOT_STAT_RX_CLASSIFIED_DROPS] = {
+               .name = "rx_classified_drops",
+               .reg = SYS_COUNT_RX_CLASSIFIED_DROPS,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_0] = {
+               .name = "rx_red_prio_0",
+               .reg = SYS_COUNT_RX_RED_PRIO_0,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_1] = {
+               .name = "rx_red_prio_1",
+               .reg = SYS_COUNT_RX_RED_PRIO_1,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_2] = {
+               .name = "rx_red_prio_2",
+               .reg = SYS_COUNT_RX_RED_PRIO_2,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_3] = {
+               .name = "rx_red_prio_3",
+               .reg = SYS_COUNT_RX_RED_PRIO_3,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_4] = {
+               .name = "rx_red_prio_4",
+               .reg = SYS_COUNT_RX_RED_PRIO_4,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_5] = {
+               .name = "rx_red_prio_5",
+               .reg = SYS_COUNT_RX_RED_PRIO_5,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_6] = {
+               .name = "rx_red_prio_6",
+               .reg = SYS_COUNT_RX_RED_PRIO_6,
+       },
+       [OCELOT_STAT_RX_RED_PRIO_7] = {
+               .name = "rx_red_prio_7",
+               .reg = SYS_COUNT_RX_RED_PRIO_7,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_0] = {
+               .name = "rx_yellow_prio_0",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_0,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_1] = {
+               .name = "rx_yellow_prio_1",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_1,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_2] = {
+               .name = "rx_yellow_prio_2",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_2,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_3] = {
+               .name = "rx_yellow_prio_3",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_3,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_4] = {
+               .name = "rx_yellow_prio_4",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_4,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_5] = {
+               .name = "rx_yellow_prio_5",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_5,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_6] = {
+               .name = "rx_yellow_prio_6",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_6,
+       },
+       [OCELOT_STAT_RX_YELLOW_PRIO_7] = {
+               .name = "rx_yellow_prio_7",
+               .reg = SYS_COUNT_RX_YELLOW_PRIO_7,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_0] = {
+               .name = "rx_green_prio_0",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_0,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_1] = {
+               .name = "rx_green_prio_1",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_1,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_2] = {
+               .name = "rx_green_prio_2",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_2,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_3] = {
+               .name = "rx_green_prio_3",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_3,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_4] = {
+               .name = "rx_green_prio_4",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_4,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_5] = {
+               .name = "rx_green_prio_5",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_5,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_6] = {
+               .name = "rx_green_prio_6",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_6,
+       },
+       [OCELOT_STAT_RX_GREEN_PRIO_7] = {
+               .name = "rx_green_prio_7",
+               .reg = SYS_COUNT_RX_GREEN_PRIO_7,
+       },
+       [OCELOT_STAT_TX_OCTETS] = {
+               .name = "tx_octets",
+               .reg = SYS_COUNT_TX_OCTETS,
+       },
+       [OCELOT_STAT_TX_UNICAST] = {
+               .name = "tx_unicast",
+               .reg = SYS_COUNT_TX_UNICAST,
+       },
+       [OCELOT_STAT_TX_MULTICAST] = {
+               .name = "tx_multicast",
+               .reg = SYS_COUNT_TX_MULTICAST,
+       },
+       [OCELOT_STAT_TX_BROADCAST] = {
+               .name = "tx_broadcast",
+               .reg = SYS_COUNT_TX_BROADCAST,
+       },
+       [OCELOT_STAT_TX_COLLISION] = {
+               .name = "tx_collision",
+               .reg = SYS_COUNT_TX_COLLISION,
+       },
+       [OCELOT_STAT_TX_DROPS] = {
+               .name = "tx_drops",
+               .reg = SYS_COUNT_TX_DROPS,
+       },
+       [OCELOT_STAT_TX_PAUSE] = {
+               .name = "tx_pause",
+               .reg = SYS_COUNT_TX_PAUSE,
+       },
+       [OCELOT_STAT_TX_64] = {
+               .name = "tx_frames_below_65_octets",
+               .reg = SYS_COUNT_TX_64,
+       },
+       [OCELOT_STAT_TX_65_127] = {
+               .name = "tx_frames_65_to_127_octets",
+               .reg = SYS_COUNT_TX_65_127,
+       },
+       [OCELOT_STAT_TX_128_255] = {
+               .name = "tx_frames_128_255_octets",
+               .reg = SYS_COUNT_TX_128_255,
+       },
+       [OCELOT_STAT_TX_256_511] = {
+               .name = "tx_frames_256_511_octets",
+               .reg = SYS_COUNT_TX_256_511,
+       },
+       [OCELOT_STAT_TX_512_1023] = {
+               .name = "tx_frames_512_1023_octets",
+               .reg = SYS_COUNT_TX_512_1023,
+       },
+       [OCELOT_STAT_TX_1024_1526] = {
+               .name = "tx_frames_1024_1526_octets",
+               .reg = SYS_COUNT_TX_1024_1526,
+       },
+       [OCELOT_STAT_TX_1527_MAX] = {
+               .name = "tx_frames_over_1526_octets",
+               .reg = SYS_COUNT_TX_1527_MAX,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_0] = {
+               .name = "tx_yellow_prio_0",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_0,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_1] = {
+               .name = "tx_yellow_prio_1",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_1,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_2] = {
+               .name = "tx_yellow_prio_2",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_2,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_3] = {
+               .name = "tx_yellow_prio_3",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_3,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_4] = {
+               .name = "tx_yellow_prio_4",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_4,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_5] = {
+               .name = "tx_yellow_prio_5",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_5,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_6] = {
+               .name = "tx_yellow_prio_6",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_6,
+       },
+       [OCELOT_STAT_TX_YELLOW_PRIO_7] = {
+               .name = "tx_yellow_prio_7",
+               .reg = SYS_COUNT_TX_YELLOW_PRIO_7,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_0] = {
+               .name = "tx_green_prio_0",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_0,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_1] = {
+               .name = "tx_green_prio_1",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_1,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_2] = {
+               .name = "tx_green_prio_2",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_2,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_3] = {
+               .name = "tx_green_prio_3",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_3,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_4] = {
+               .name = "tx_green_prio_4",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_4,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_5] = {
+               .name = "tx_green_prio_5",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_5,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_6] = {
+               .name = "tx_green_prio_6",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_6,
+       },
+       [OCELOT_STAT_TX_GREEN_PRIO_7] = {
+               .name = "tx_green_prio_7",
+               .reg = SYS_COUNT_TX_GREEN_PRIO_7,
+       },
+       [OCELOT_STAT_TX_AGED] = {
+               .name = "tx_aged",
+               .reg = SYS_COUNT_TX_AGING,
+       },
+       [OCELOT_STAT_DROP_LOCAL] = {
+               .name = "drop_local",
+               .reg = SYS_COUNT_DROP_LOCAL,
+       },
+       [OCELOT_STAT_DROP_TAIL] = {
+               .name = "drop_tail",
+               .reg = SYS_COUNT_DROP_TAIL,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_0] = {
+               .name = "drop_yellow_prio_0",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_0,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_1] = {
+               .name = "drop_yellow_prio_1",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_1,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_2] = {
+               .name = "drop_yellow_prio_2",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_2,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_3] = {
+               .name = "drop_yellow_prio_3",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_3,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_4] = {
+               .name = "drop_yellow_prio_4",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_4,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_5] = {
+               .name = "drop_yellow_prio_5",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_5,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_6] = {
+               .name = "drop_yellow_prio_6",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_6,
+       },
+       [OCELOT_STAT_DROP_YELLOW_PRIO_7] = {
+               .name = "drop_yellow_prio_7",
+               .reg = SYS_COUNT_DROP_YELLOW_PRIO_7,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_0] = {
+               .name = "drop_green_prio_0",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_0,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_1] = {
+               .name = "drop_green_prio_1",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_1,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_2] = {
+               .name = "drop_green_prio_2",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_2,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_3] = {
+               .name = "drop_green_prio_3",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_3,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_4] = {
+               .name = "drop_green_prio_4",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_4,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_5] = {
+               .name = "drop_green_prio_5",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_5,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_6] = {
+               .name = "drop_green_prio_6",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_6,
+       },
+       [OCELOT_STAT_DROP_GREEN_PRIO_7] = {
+               .name = "drop_green_prio_7",
+               .reg = SYS_COUNT_DROP_GREEN_PRIO_7,
+       },
 };
 
 static void ocelot_pll5_init(struct ocelot *ocelot)
index c2af4eb..9cf82ec 100644 (file)
@@ -180,13 +180,38 @@ const u32 vsc7514_sys_regmap[] = {
        REG(SYS_COUNT_RX_64,                            0x000024),
        REG(SYS_COUNT_RX_65_127,                        0x000028),
        REG(SYS_COUNT_RX_128_255,                       0x00002c),
-       REG(SYS_COUNT_RX_256_1023,                      0x000030),
-       REG(SYS_COUNT_RX_1024_1526,                     0x000034),
-       REG(SYS_COUNT_RX_1527_MAX,                      0x000038),
-       REG(SYS_COUNT_RX_PAUSE,                         0x00003c),
-       REG(SYS_COUNT_RX_CONTROL,                       0x000040),
-       REG(SYS_COUNT_RX_LONGS,                         0x000044),
-       REG(SYS_COUNT_RX_CLASSIFIED_DROPS,              0x000048),
+       REG(SYS_COUNT_RX_256_511,                       0x000030),
+       REG(SYS_COUNT_RX_512_1023,                      0x000034),
+       REG(SYS_COUNT_RX_1024_1526,                     0x000038),
+       REG(SYS_COUNT_RX_1527_MAX,                      0x00003c),
+       REG(SYS_COUNT_RX_PAUSE,                         0x000040),
+       REG(SYS_COUNT_RX_CONTROL,                       0x000044),
+       REG(SYS_COUNT_RX_LONGS,                         0x000048),
+       REG(SYS_COUNT_RX_CLASSIFIED_DROPS,              0x00004c),
+       REG(SYS_COUNT_RX_RED_PRIO_0,                    0x000050),
+       REG(SYS_COUNT_RX_RED_PRIO_1,                    0x000054),
+       REG(SYS_COUNT_RX_RED_PRIO_2,                    0x000058),
+       REG(SYS_COUNT_RX_RED_PRIO_3,                    0x00005c),
+       REG(SYS_COUNT_RX_RED_PRIO_4,                    0x000060),
+       REG(SYS_COUNT_RX_RED_PRIO_5,                    0x000064),
+       REG(SYS_COUNT_RX_RED_PRIO_6,                    0x000068),
+       REG(SYS_COUNT_RX_RED_PRIO_7,                    0x00006c),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_0,                 0x000070),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_1,                 0x000074),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_2,                 0x000078),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_3,                 0x00007c),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_4,                 0x000080),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_5,                 0x000084),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_6,                 0x000088),
+       REG(SYS_COUNT_RX_YELLOW_PRIO_7,                 0x00008c),
+       REG(SYS_COUNT_RX_GREEN_PRIO_0,                  0x000090),
+       REG(SYS_COUNT_RX_GREEN_PRIO_1,                  0x000094),
+       REG(SYS_COUNT_RX_GREEN_PRIO_2,                  0x000098),
+       REG(SYS_COUNT_RX_GREEN_PRIO_3,                  0x00009c),
+       REG(SYS_COUNT_RX_GREEN_PRIO_4,                  0x0000a0),
+       REG(SYS_COUNT_RX_GREEN_PRIO_5,                  0x0000a4),
+       REG(SYS_COUNT_RX_GREEN_PRIO_6,                  0x0000a8),
+       REG(SYS_COUNT_RX_GREEN_PRIO_7,                  0x0000ac),
        REG(SYS_COUNT_TX_OCTETS,                        0x000100),
        REG(SYS_COUNT_TX_UNICAST,                       0x000104),
        REG(SYS_COUNT_TX_MULTICAST,                     0x000108),
@@ -196,11 +221,46 @@ const u32 vsc7514_sys_regmap[] = {
        REG(SYS_COUNT_TX_PAUSE,                         0x000118),
        REG(SYS_COUNT_TX_64,                            0x00011c),
        REG(SYS_COUNT_TX_65_127,                        0x000120),
-       REG(SYS_COUNT_TX_128_511,                       0x000124),
-       REG(SYS_COUNT_TX_512_1023,                      0x000128),
-       REG(SYS_COUNT_TX_1024_1526,                     0x00012c),
-       REG(SYS_COUNT_TX_1527_MAX,                      0x000130),
-       REG(SYS_COUNT_TX_AGING,                         0x000170),
+       REG(SYS_COUNT_TX_128_255,                       0x000124),
+       REG(SYS_COUNT_TX_256_511,                       0x000128),
+       REG(SYS_COUNT_TX_512_1023,                      0x00012c),
+       REG(SYS_COUNT_TX_1024_1526,                     0x000130),
+       REG(SYS_COUNT_TX_1527_MAX,                      0x000134),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_0,                 0x000138),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_1,                 0x00013c),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_2,                 0x000140),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_3,                 0x000144),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_4,                 0x000148),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_5,                 0x00014c),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_6,                 0x000150),
+       REG(SYS_COUNT_TX_YELLOW_PRIO_7,                 0x000154),
+       REG(SYS_COUNT_TX_GREEN_PRIO_0,                  0x000158),
+       REG(SYS_COUNT_TX_GREEN_PRIO_1,                  0x00015c),
+       REG(SYS_COUNT_TX_GREEN_PRIO_2,                  0x000160),
+       REG(SYS_COUNT_TX_GREEN_PRIO_3,                  0x000164),
+       REG(SYS_COUNT_TX_GREEN_PRIO_4,                  0x000168),
+       REG(SYS_COUNT_TX_GREEN_PRIO_5,                  0x00016c),
+       REG(SYS_COUNT_TX_GREEN_PRIO_6,                  0x000170),
+       REG(SYS_COUNT_TX_GREEN_PRIO_7,                  0x000174),
+       REG(SYS_COUNT_TX_AGING,                         0x000178),
+       REG(SYS_COUNT_DROP_LOCAL,                       0x000200),
+       REG(SYS_COUNT_DROP_TAIL,                        0x000204),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_0,               0x000208),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_1,               0x00020c),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_2,               0x000210),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_3,               0x000214),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_4,               0x000218),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_5,               0x00021c),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_6,               0x000220),
+       REG(SYS_COUNT_DROP_YELLOW_PRIO_7,               0x000214),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_0,                0x000218),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_1,                0x00021c),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_2,                0x000220),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_3,                0x000224),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_4,                0x000228),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_5,                0x00022c),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_6,                0x000230),
+       REG(SYS_COUNT_DROP_GREEN_PRIO_7,                0x000234),
        REG(SYS_RESET_CFG,                              0x000508),
        REG(SYS_CMID,                                   0x00050c),
        REG(SYS_VLAN_ETYPE_CFG,                         0x000510),
index 52f9ed8..4f2b82a 100644 (file)
@@ -1134,6 +1134,7 @@ static void intel_eth_pci_remove(struct pci_dev *pdev)
 
        stmmac_dvr_remove(&pdev->dev);
 
+       clk_disable_unprepare(priv->plat->stmmac_clk);
        clk_unregister_fixed_rate(priv->plat->stmmac_clk);
 
        pcim_iounmap_regions(pdev, BIT(0));
index 76c4a70..e97db82 100644 (file)
@@ -348,7 +348,7 @@ do {                                                                        \
  *             This macro is invoked by the OS-specific before it left the
  *             function mac_drv_rx_complete. This macro calls mac_drv_fill_rxd
  *             if the number of used RxDs is equal or lower than the
- *             the given low water mark.
+ *             given low water mark.
  *
  * para        low_water       low water mark of used RxD's
  *
index a5b3553..6f35438 100644 (file)
@@ -48,7 +48,7 @@ struct ipa;
  *
  * The offset of registers related to resource types is computed by a macro
  * that is supplied a parameter "rt".  The "rt" represents a resource type,
- * which is is a member of the ipa_resource_type_src enumerated type for
+ * which is a member of the ipa_resource_type_src enumerated type for
  * source endpoint resources or the ipa_resource_type_dst enumerated type
  * for destination endpoint resources.
  *
index d934774..9cce7de 100644 (file)
@@ -1211,7 +1211,7 @@ static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash,
        if (!hdr_hash || !skb)
                return;
 
-       switch ((int)hdr_hash->hash_report) {
+       switch (__le16_to_cpu(hdr_hash->hash_report)) {
        case VIRTIO_NET_HASH_REPORT_TCPv4:
        case VIRTIO_NET_HASH_REPORT_UDPv4:
        case VIRTIO_NET_HASH_REPORT_TCPv6:
@@ -1229,7 +1229,7 @@ static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash,
        default:
                rss_hash_type = PKT_HASH_TYPE_NONE;
        }
-       skb_set_hash(skb, (unsigned int)hdr_hash->hash_value, rss_hash_type);
+       skb_set_hash(skb, __le32_to_cpu(hdr_hash->hash_value), rss_hash_type);
 }
 
 static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
@@ -3432,29 +3432,6 @@ static unsigned int mergeable_min_buf_len(struct virtnet_info *vi, struct virtqu
                   (unsigned int)GOOD_PACKET_LEN);
 }
 
-static void virtnet_config_sizes(struct virtnet_info *vi, u32 *sizes)
-{
-       u32 i, rx_size, tx_size;
-
-       if (vi->speed == SPEED_UNKNOWN || vi->speed < SPEED_10000) {
-               rx_size = 1024;
-               tx_size = 1024;
-
-       } else if (vi->speed < SPEED_40000) {
-               rx_size = 1024 * 4;
-               tx_size = 1024 * 4;
-
-       } else {
-               rx_size = 1024 * 8;
-               tx_size = 1024 * 8;
-       }
-
-       for (i = 0; i < vi->max_queue_pairs; i++) {
-               sizes[rxq2vq(i)] = rx_size;
-               sizes[txq2vq(i)] = tx_size;
-       }
-}
-
 static int virtnet_find_vqs(struct virtnet_info *vi)
 {
        vq_callback_t **callbacks;
@@ -3462,7 +3439,6 @@ static int virtnet_find_vqs(struct virtnet_info *vi)
        int ret = -ENOMEM;
        int i, total_vqs;
        const char **names;
-       u32 *sizes;
        bool *ctx;
 
        /* We expect 1 RX virtqueue followed by 1 TX virtqueue, followed by
@@ -3490,15 +3466,10 @@ static int virtnet_find_vqs(struct virtnet_info *vi)
                ctx = NULL;
        }
 
-       sizes = kmalloc_array(total_vqs, sizeof(*sizes), GFP_KERNEL);
-       if (!sizes)
-               goto err_sizes;
-
        /* Parameters for control virtqueue, if any */
        if (vi->has_cvq) {
                callbacks[total_vqs - 1] = NULL;
                names[total_vqs - 1] = "control";
-               sizes[total_vqs - 1] = 64;
        }
 
        /* Allocate/initialize parameters for send/receive virtqueues */
@@ -3513,10 +3484,8 @@ static int virtnet_find_vqs(struct virtnet_info *vi)
                        ctx[rxq2vq(i)] = true;
        }
 
-       virtnet_config_sizes(vi, sizes);
-
-       ret = virtio_find_vqs_ctx_size(vi->vdev, total_vqs, vqs, callbacks,
-                                      names, sizes, ctx, NULL);
+       ret = virtio_find_vqs_ctx(vi->vdev, total_vqs, vqs, callbacks,
+                                 names, ctx, NULL);
        if (ret)
                goto err_find;
 
@@ -3536,8 +3505,6 @@ static int virtnet_find_vqs(struct virtnet_info *vi)
 
 
 err_find:
-       kfree(sizes);
-err_sizes:
        kfree(ctx);
 err_ctx:
        kfree(names);
@@ -3897,9 +3864,6 @@ static int virtnet_probe(struct virtio_device *vdev)
                vi->curr_queue_pairs = num_online_cpus();
        vi->max_queue_pairs = max_queue_pairs;
 
-       virtnet_init_settings(dev);
-       virtnet_update_settings(vi);
-
        /* Allocate/initialize the rx/tx queues, and invoke find_vqs */
        err = init_vqs(vi);
        if (err)
@@ -3912,6 +3876,8 @@ static int virtnet_probe(struct virtio_device *vdev)
        netif_set_real_num_tx_queues(dev, vi->curr_queue_pairs);
        netif_set_real_num_rx_queues(dev, vi->curr_queue_pairs);
 
+       virtnet_init_settings(dev);
+
        if (virtio_has_feature(vdev, VIRTIO_NET_F_STANDBY)) {
                vi->failover = net_failover_create(vi->dev);
                if (IS_ERR(vi->failover)) {
index 3427787..2c20b0d 100644 (file)
@@ -72,7 +72,7 @@ static void pmu_legacy_ctr_start(struct perf_event *event, u64 ival)
        local64_set(&hwc->prev_count, initial_val);
 }
 
-/**
+/*
  * This is just a simple implementation to allow legacy implementations
  * compatible with new RISC-V PMU driver framework.
  * This driver only allows reading two counters i.e CYCLE & INSTRET.
index 8be13d4..1ae3c56 100644 (file)
@@ -928,7 +928,6 @@ static int mlxbf_tmfifo_virtio_find_vqs(struct virtio_device *vdev,
                                        struct virtqueue *vqs[],
                                        vq_callback_t *callbacks[],
                                        const char * const names[],
-                                       u32 sizes[],
                                        const bool *ctx,
                                        struct irq_affinity *desc)
 {
index 67feed2..5362f1a 100644 (file)
@@ -328,6 +328,7 @@ static const struct acpi_device_id smi_acpi_ids[] = {
        { "INT3515", (unsigned long)&int3515_data },
        /* Non-conforming _HID for Cirrus Logic already released */
        { "CLSA0100", (unsigned long)&cs35l41_hda },
+       { "CLSA0101", (unsigned long)&cs35l41_hda },
        { }
 };
 MODULE_DEVICE_TABLE(acpi, smi_acpi_ids);
index 7150b1d..d8373cb 100644 (file)
@@ -4784,10 +4784,10 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
                consumers[i].consumer = regulator_get(dev,
                                                      consumers[i].supply);
                if (IS_ERR(consumers[i].consumer)) {
-                       consumers[i].consumer = NULL;
                        ret = dev_err_probe(dev, PTR_ERR(consumers[i].consumer),
                                            "Failed to get supply '%s'",
                                            consumers[i].supply);
+                       consumers[i].consumer = NULL;
                        goto err;
                }
 
index 81c4f57..0f7706e 100644 (file)
@@ -158,7 +158,6 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
                                 struct virtqueue *vqs[],
                                 vq_callback_t *callbacks[],
                                 const char * const names[],
-                                u32 sizes[],
                                 const bool * ctx,
                                 struct irq_affinity *desc)
 {
index 806773e..85f7abd 100644 (file)
@@ -152,6 +152,13 @@ config RESET_PISTACHIO
        help
          This enables the reset driver for ImgTec Pistachio SoCs.
 
+config RESET_POLARFIRE_SOC
+       bool "Microchip PolarFire SoC (MPFS) Reset Driver"
+       depends on AUXILIARY_BUS && MCHP_CLK_MPFS
+       default MCHP_CLK_MPFS
+       help
+         This driver supports peripheral reset for the Microchip PolarFire SoC
+
 config RESET_QCOM_AOSS
        tristate "Qcom AOSS Reset Driver"
        depends on ARCH_QCOM || COMPILE_TEST
index cd5cf8e..3e7e5fd 100644 (file)
@@ -22,6 +22,7 @@ obj-$(CONFIG_RESET_MESON_AUDIO_ARB) += reset-meson-audio-arb.o
 obj-$(CONFIG_RESET_NPCM) += reset-npcm.o
 obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
 obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o
+obj-$(CONFIG_RESET_POLARFIRE_SOC) += reset-mpfs.o
 obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o
 obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o
 obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
@@ -40,4 +41,3 @@ 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
-
diff --git a/drivers/reset/reset-mpfs.c b/drivers/reset/reset-mpfs.c
new file mode 100644 (file)
index 0000000..e003e50
--- /dev/null
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * PolarFire SoC (MPFS) Peripheral Clock Reset Controller
+ *
+ * Author: Conor Dooley <conor.dooley@microchip.com>
+ * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
+ *
+ */
+#include <linux/auxiliary_bus.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <dt-bindings/clock/microchip,mpfs-clock.h>
+#include <soc/microchip/mpfs.h>
+
+/*
+ * The ENVM reset is the lowest bit in the register & I am using the CLK_FOO
+ * defines in the dt to make things easier to configure - so this is accounting
+ * for the offset of 3 there.
+ */
+#define MPFS_PERIPH_OFFSET     CLK_ENVM
+#define MPFS_NUM_RESETS                30u
+#define MPFS_SLEEP_MIN_US      100
+#define MPFS_SLEEP_MAX_US      200
+
+/* block concurrent access to the soft reset register */
+static DEFINE_SPINLOCK(mpfs_reset_lock);
+
+/*
+ * Peripheral clock resets
+ */
+
+static int mpfs_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+       unsigned long flags;
+       u32 reg;
+
+       spin_lock_irqsave(&mpfs_reset_lock, flags);
+
+       reg = mpfs_reset_read(rcdev->dev);
+       reg |= BIT(id);
+       mpfs_reset_write(rcdev->dev, reg);
+
+       spin_unlock_irqrestore(&mpfs_reset_lock, flags);
+
+       return 0;
+}
+
+static int mpfs_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+       unsigned long flags;
+       u32 reg;
+
+       spin_lock_irqsave(&mpfs_reset_lock, flags);
+
+       reg = mpfs_reset_read(rcdev->dev);
+       reg &= ~BIT(id);
+       mpfs_reset_write(rcdev->dev, reg);
+
+       spin_unlock_irqrestore(&mpfs_reset_lock, flags);
+
+       return 0;
+}
+
+static int mpfs_status(struct reset_controller_dev *rcdev, unsigned long id)
+{
+       u32 reg = mpfs_reset_read(rcdev->dev);
+
+       /*
+        * It is safe to return here as MPFS_NUM_RESETS makes sure the sign bit
+        * is never hit.
+        */
+       return (reg & BIT(id));
+}
+
+static int mpfs_reset(struct reset_controller_dev *rcdev, unsigned long id)
+{
+       mpfs_assert(rcdev, id);
+
+       usleep_range(MPFS_SLEEP_MIN_US, MPFS_SLEEP_MAX_US);
+
+       mpfs_deassert(rcdev, id);
+
+       return 0;
+}
+
+static const struct reset_control_ops mpfs_reset_ops = {
+       .reset = mpfs_reset,
+       .assert = mpfs_assert,
+       .deassert = mpfs_deassert,
+       .status = mpfs_status,
+};
+
+static int mpfs_reset_xlate(struct reset_controller_dev *rcdev,
+                           const struct of_phandle_args *reset_spec)
+{
+       unsigned int index = reset_spec->args[0];
+
+       /*
+        * CLK_RESERVED does not map to a clock, but it does map to a reset,
+        * so it has to be accounted for here. It is the reset for the fabric,
+        * so if this reset gets called - do not reset it.
+        */
+       if (index == CLK_RESERVED) {
+               dev_err(rcdev->dev, "Resetting the fabric is not supported\n");
+               return -EINVAL;
+       }
+
+       if (index < MPFS_PERIPH_OFFSET || index >= (MPFS_PERIPH_OFFSET + rcdev->nr_resets)) {
+               dev_err(rcdev->dev, "Invalid reset index %u\n", index);
+               return -EINVAL;
+       }
+
+       return index - MPFS_PERIPH_OFFSET;
+}
+
+static int mpfs_reset_probe(struct auxiliary_device *adev,
+                           const struct auxiliary_device_id *id)
+{
+       struct device *dev = &adev->dev;
+       struct reset_controller_dev *rcdev;
+
+       rcdev = devm_kzalloc(dev, sizeof(*rcdev), GFP_KERNEL);
+       if (!rcdev)
+               return -ENOMEM;
+
+       rcdev->dev = dev;
+       rcdev->dev->parent = dev->parent;
+       rcdev->ops = &mpfs_reset_ops;
+       rcdev->of_node = dev->parent->of_node;
+       rcdev->of_reset_n_cells = 1;
+       rcdev->of_xlate = mpfs_reset_xlate;
+       rcdev->nr_resets = MPFS_NUM_RESETS;
+
+       return devm_reset_controller_register(dev, rcdev);
+}
+
+static const struct auxiliary_device_id mpfs_reset_ids[] = {
+       {
+               .name = "clk_mpfs.reset-mpfs",
+       },
+       { }
+};
+MODULE_DEVICE_TABLE(auxiliary, mpfs_reset_ids);
+
+static struct auxiliary_driver mpfs_reset_driver = {
+       .probe          = mpfs_reset_probe,
+       .id_table       = mpfs_reset_ids,
+};
+
+module_auxiliary_driver(mpfs_reset_driver);
+
+MODULE_DESCRIPTION("Microchip PolarFire SoC Reset Driver");
+MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(MCHP_CLK_MPFS);
index 8f1d1cf..59ac98f 100644 (file)
@@ -2086,6 +2086,9 @@ static inline void ap_scan_adapter(int ap)
  */
 static bool ap_get_configuration(void)
 {
+       if (!ap_qci_info)       /* QCI not supported */
+               return false;
+
        memcpy(ap_qci_info_old, ap_qci_info, sizeof(*ap_qci_info));
        ap_fetch_qci_info(ap_qci_info);
 
index 0c40af1..0f17933 100644 (file)
@@ -148,12 +148,16 @@ struct ap_driver {
        /*
         * Called at the start of the ap bus scan function when
         * the crypto config information (qci) has changed.
+        * This callback is not invoked if there is no AP
+        * QCI support available.
         */
        void (*on_config_changed)(struct ap_config_info *new_config_info,
                                  struct ap_config_info *old_config_info);
        /*
         * Called at the end of the ap bus scan function when
         * the crypto config information (qci) has changed.
+        * This callback is not invoked if there is no AP
+        * QCI support available.
         */
        void (*on_scan_complete)(struct ap_config_info *new_config_info,
                                 struct ap_config_info *old_config_info);
index 896896e..a10dbe6 100644 (file)
@@ -637,7 +637,6 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
                               struct virtqueue *vqs[],
                               vq_callback_t *callbacks[],
                               const char * const names[],
-                              u32 sizes[],
                               const bool *ctx,
                               struct irq_affinity *desc)
 {
index 0bc7daa..e4cb52e 100644 (file)
@@ -156,6 +156,7 @@ struct meson_spicc_device {
        void __iomem                    *base;
        struct clk                      *core;
        struct clk                      *pclk;
+       struct clk_divider              pow2_div;
        struct clk                      *clk;
        struct spi_message              *message;
        struct spi_transfer             *xfer;
@@ -168,6 +169,8 @@ struct meson_spicc_device {
        unsigned long                   xfer_remain;
 };
 
+#define pow2_clk_to_spicc(_div) container_of(_div, struct meson_spicc_device, pow2_div)
+
 static void meson_spicc_oen_enable(struct meson_spicc_device *spicc)
 {
        u32 conf;
@@ -421,7 +424,7 @@ static int meson_spicc_prepare_message(struct spi_master *master,
 {
        struct meson_spicc_device *spicc = spi_master_get_devdata(master);
        struct spi_device *spi = message->spi;
-       u32 conf = 0;
+       u32 conf = readl_relaxed(spicc->base + SPICC_CONREG) & SPICC_DATARATE_MASK;
 
        /* Store current message */
        spicc->message = message;
@@ -458,8 +461,6 @@ static int meson_spicc_prepare_message(struct spi_master *master,
        /* Select CS */
        conf |= FIELD_PREP(SPICC_CS_MASK, spi->chip_select);
 
-       /* Default Clock rate core/4 */
-
        /* Default 8bit word */
        conf |= FIELD_PREP(SPICC_BITLENGTH_MASK, 8 - 1);
 
@@ -476,12 +477,16 @@ static int meson_spicc_prepare_message(struct spi_master *master,
 static int meson_spicc_unprepare_transfer(struct spi_master *master)
 {
        struct meson_spicc_device *spicc = spi_master_get_devdata(master);
+       u32 conf = readl_relaxed(spicc->base + SPICC_CONREG) & SPICC_DATARATE_MASK;
 
        /* Disable all IRQs */
        writel(0, spicc->base + SPICC_INTREG);
 
        device_reset_optional(&spicc->pdev->dev);
 
+       /* Set default configuration, keeping datarate field */
+       writel_relaxed(conf, spicc->base + SPICC_CONREG);
+
        return 0;
 }
 
@@ -518,14 +523,60 @@ static void meson_spicc_cleanup(struct spi_device *spi)
  * Clk path for G12A series:
  *    pclk -> pow2 fixed div -> pow2 div -> mux -> out
  *    pclk -> enh fixed div -> enh div -> mux -> out
+ *
+ * The pow2 divider is tied to the controller HW state, and the
+ * divider is only valid when the controller is initialized.
+ *
+ * A set of clock ops is added to make sure we don't read/set this
+ * clock rate while the controller is in an unknown state.
  */
 
-static int meson_spicc_clk_init(struct meson_spicc_device *spicc)
+static unsigned long meson_spicc_pow2_recalc_rate(struct clk_hw *hw,
+                                                 unsigned long parent_rate)
+{
+       struct clk_divider *divider = to_clk_divider(hw);
+       struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider);
+
+       if (!spicc->master->cur_msg || !spicc->master->busy)
+               return 0;
+
+       return clk_divider_ops.recalc_rate(hw, parent_rate);
+}
+
+static int meson_spicc_pow2_determine_rate(struct clk_hw *hw,
+                                          struct clk_rate_request *req)
+{
+       struct clk_divider *divider = to_clk_divider(hw);
+       struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider);
+
+       if (!spicc->master->cur_msg || !spicc->master->busy)
+               return -EINVAL;
+
+       return clk_divider_ops.determine_rate(hw, req);
+}
+
+static int meson_spicc_pow2_set_rate(struct clk_hw *hw, unsigned long rate,
+                                    unsigned long parent_rate)
+{
+       struct clk_divider *divider = to_clk_divider(hw);
+       struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider);
+
+       if (!spicc->master->cur_msg || !spicc->master->busy)
+               return -EINVAL;
+
+       return clk_divider_ops.set_rate(hw, rate, parent_rate);
+}
+
+const struct clk_ops meson_spicc_pow2_clk_ops = {
+       .recalc_rate = meson_spicc_pow2_recalc_rate,
+       .determine_rate = meson_spicc_pow2_determine_rate,
+       .set_rate = meson_spicc_pow2_set_rate,
+};
+
+static int meson_spicc_pow2_clk_init(struct meson_spicc_device *spicc)
 {
        struct device *dev = &spicc->pdev->dev;
-       struct clk_fixed_factor *pow2_fixed_div, *enh_fixed_div;
-       struct clk_divider *pow2_div, *enh_div;
-       struct clk_mux *mux;
+       struct clk_fixed_factor *pow2_fixed_div;
        struct clk_init_data init;
        struct clk *clk;
        struct clk_parent_data parent_data[2];
@@ -560,31 +611,45 @@ static int meson_spicc_clk_init(struct meson_spicc_device *spicc)
        if (WARN_ON(IS_ERR(clk)))
                return PTR_ERR(clk);
 
-       pow2_div = devm_kzalloc(dev, sizeof(*pow2_div), GFP_KERNEL);
-       if (!pow2_div)
-               return -ENOMEM;
-
        snprintf(name, sizeof(name), "%s#pow2_div", dev_name(dev));
        init.name = name;
-       init.ops = &clk_divider_ops;
-       init.flags = CLK_SET_RATE_PARENT;
+       init.ops = &meson_spicc_pow2_clk_ops;
+       /*
+        * Set NOCACHE here to make sure we read the actual HW value
+        * since we reset the HW after each transfer.
+        */
+       init.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE;
        parent_data[0].hw = &pow2_fixed_div->hw;
        init.num_parents = 1;
 
-       pow2_div->shift = 16,
-       pow2_div->width = 3,
-       pow2_div->flags = CLK_DIVIDER_POWER_OF_TWO,
-       pow2_div->reg = spicc->base + SPICC_CONREG;
-       pow2_div->hw.init = &init;
+       spicc->pow2_div.shift = 16,
+       spicc->pow2_div.width = 3,
+       spicc->pow2_div.flags = CLK_DIVIDER_POWER_OF_TWO,
+       spicc->pow2_div.reg = spicc->base + SPICC_CONREG;
+       spicc->pow2_div.hw.init = &init;
 
-       clk = devm_clk_register(dev, &pow2_div->hw);
-       if (WARN_ON(IS_ERR(clk)))
-               return PTR_ERR(clk);
+       spicc->clk = devm_clk_register(dev, &spicc->pow2_div.hw);
+       if (WARN_ON(IS_ERR(spicc->clk)))
+               return PTR_ERR(spicc->clk);
 
-       if (!spicc->data->has_enhance_clk_div) {
-               spicc->clk = clk;
-               return 0;
-       }
+       return 0;
+}
+
+static int meson_spicc_enh_clk_init(struct meson_spicc_device *spicc)
+{
+       struct device *dev = &spicc->pdev->dev;
+       struct clk_fixed_factor *enh_fixed_div;
+       struct clk_divider *enh_div;
+       struct clk_mux *mux;
+       struct clk_init_data init;
+       struct clk *clk;
+       struct clk_parent_data parent_data[2];
+       char name[64];
+
+       memset(&init, 0, sizeof(init));
+       memset(&parent_data, 0, sizeof(parent_data));
+
+       init.parent_data = parent_data;
 
        /* algorithm for enh div: rate = freq / 2 / (N + 1) */
 
@@ -637,7 +702,7 @@ static int meson_spicc_clk_init(struct meson_spicc_device *spicc)
        snprintf(name, sizeof(name), "%s#sel", dev_name(dev));
        init.name = name;
        init.ops = &clk_mux_ops;
-       parent_data[0].hw = &pow2_div->hw;
+       parent_data[0].hw = &spicc->pow2_div.hw;
        parent_data[1].hw = &enh_div->hw;
        init.num_parents = 2;
        init.flags = CLK_SET_RATE_PARENT;
@@ -754,12 +819,20 @@ static int meson_spicc_probe(struct platform_device *pdev)
 
        meson_spicc_oen_enable(spicc);
 
-       ret = meson_spicc_clk_init(spicc);
+       ret = meson_spicc_pow2_clk_init(spicc);
        if (ret) {
-               dev_err(&pdev->dev, "clock registration failed\n");
+               dev_err(&pdev->dev, "pow2 clock registration failed\n");
                goto out_clk;
        }
 
+       if (spicc->data->has_enhance_clk_div) {
+               ret = meson_spicc_enh_clk_init(spicc);
+               if (ret) {
+                       dev_err(&pdev->dev, "clock registration failed\n");
+                       goto out_clk;
+               }
+       }
+
        ret = devm_spi_register_master(&pdev->dev, master);
        if (ret) {
                dev_err(&pdev->dev, "spi master registration failed\n");
index 8f97a3e..83da886 100644 (file)
@@ -95,7 +95,7 @@ static ssize_t driver_override_show(struct device *dev,
 }
 static DEVICE_ATTR_RW(driver_override);
 
-static struct spi_statistics *spi_alloc_pcpu_stats(struct device *dev)
+static struct spi_statistics __percpu *spi_alloc_pcpu_stats(struct device *dev)
 {
        struct spi_statistics __percpu *pcpu_stats;
 
@@ -162,7 +162,7 @@ static struct device_attribute dev_attr_spi_device_##field = {              \
 }
 
 #define SPI_STATISTICS_SHOW_NAME(name, file, field)                    \
-static ssize_t spi_statistics_##name##_show(struct spi_statistics *stat, \
+static ssize_t spi_statistics_##name##_show(struct spi_statistics __percpu *stat, \
                                            char *buf)                  \
 {                                                                      \
        ssize_t len;                                                    \
@@ -309,7 +309,7 @@ static const struct attribute_group *spi_master_groups[] = {
        NULL,
 };
 
-static void spi_statistics_add_transfer_stats(struct spi_statistics *pcpu_stats,
+static void spi_statistics_add_transfer_stats(struct spi_statistics __percpu *pcpu_stats,
                                              struct spi_transfer *xfer,
                                              struct spi_controller *ctlr)
 {
@@ -1275,8 +1275,8 @@ static int spi_transfer_wait(struct spi_controller *ctlr,
                             struct spi_message *msg,
                             struct spi_transfer *xfer)
 {
-       struct spi_statistics *statm = ctlr->pcpu_statistics;
-       struct spi_statistics *stats = msg->spi->pcpu_statistics;
+       struct spi_statistics __percpu *statm = ctlr->pcpu_statistics;
+       struct spi_statistics __percpu *stats = msg->spi->pcpu_statistics;
        u32 speed_hz = xfer->speed_hz;
        unsigned long long ms;
 
@@ -1432,8 +1432,8 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
        struct spi_transfer *xfer;
        bool keep_cs = false;
        int ret = 0;
-       struct spi_statistics *statm = ctlr->pcpu_statistics;
-       struct spi_statistics *stats = msg->spi->pcpu_statistics;
+       struct spi_statistics __percpu *statm = ctlr->pcpu_statistics;
+       struct spi_statistics __percpu *stats = msg->spi->pcpu_statistics;
 
        spi_set_cs(msg->spi, true, false);
 
index 3bd80f9..211436b 100644 (file)
@@ -62,8 +62,6 @@ source "drivers/staging/gdm724x/Kconfig"
 
 source "drivers/staging/fwserial/Kconfig"
 
-source "drivers/staging/clocking-wizard/Kconfig"
-
 source "drivers/staging/fbtft/Kconfig"
 
 source "drivers/staging/most/Kconfig"
index 1d9ae39..f1be26a 100644 (file)
@@ -21,7 +21,6 @@ obj-$(CONFIG_MFD_NVEC)                += nvec/
 obj-$(CONFIG_STAGING_BOARD)    += board/
 obj-$(CONFIG_LTE_GDM724X)      += gdm724x/
 obj-$(CONFIG_FIREWIRE_SERIAL)  += fwserial/
-obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clocking-wizard/
 obj-$(CONFIG_FB_TFT)           += fbtft/
 obj-$(CONFIG_MOST)             += most/
 obj-$(CONFIG_KS7010)           += ks7010/
diff --git a/drivers/staging/clocking-wizard/Kconfig b/drivers/staging/clocking-wizard/Kconfig
deleted file mode 100644 (file)
index 2324b5d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Xilinx Clocking Wizard Driver
-#
-
-config COMMON_CLK_XLNX_CLKWZRD
-       tristate "Xilinx Clocking Wizard"
-       depends on COMMON_CLK && OF && HAS_IOMEM
-       help
-         Support for the Xilinx Clocking Wizard IP core clock generator.
diff --git a/drivers/staging/clocking-wizard/Makefile b/drivers/staging/clocking-wizard/Makefile
deleted file mode 100644 (file)
index b1f9152..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clk-xlnx-clock-wizard.o
diff --git a/drivers/staging/clocking-wizard/TODO b/drivers/staging/clocking-wizard/TODO
deleted file mode 100644 (file)
index c7e1dc5..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-TODO:
-       - support for fractional multiplier
-       - support for fractional divider (output 0 only)
-       - support for set_rate() operations (may benefit from Stephen Boyd's
-         refactoring of the clk primitives:
-         https://lore.kernel.org/lkml/1409957256-23729-1-git-send-email-sboyd@codeaurora.org)
-       - review arithmetic
-         - overflow after multiplication?
-         - maximize accuracy before divisions
-
-Patches to:
-       Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-       Sören Brinkmann <soren.brinkmann@xilinx.com>
diff --git a/drivers/staging/clocking-wizard/dt-binding.txt b/drivers/staging/clocking-wizard/dt-binding.txt
deleted file mode 100644 (file)
index efb67ff..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-Binding for Xilinx Clocking Wizard IP Core
-
-This binding uses the common clock binding[1]. Details about the devices can be
-found in the product guide[2].
-
-[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
-[2] Clocking Wizard Product Guide
-https://www.xilinx.com/support/documentation/ip_documentation/clk_wiz/v5_1/pg065-clk-wiz.pdf
-
-Required properties:
- - compatible: Must be 'xlnx,clocking-wizard'
- - reg: Base and size of the cores register space
- - clocks: Handle to input clock
- - clock-names: Tuple containing 'clk_in1' and 's_axi_aclk'
- - clock-output-names: Names for the output clocks
-
-Optional properties:
- - speed-grade: Speed grade of the device (valid values are 1..3)
-
-Example:
-       clock-generator@40040000 {
-               reg = <0x40040000 0x1000>;
-               compatible = "xlnx,clocking-wizard";
-               speed-grade = <1>;
-               clock-names = "clk_in1", "s_axi_aclk";
-               clocks = <&clkc 15>, <&clkc 15>;
-               clock-output-names = "clk_out0", "clk_out1", "clk_out2",
-                                    "clk_out3", "clk_out4", "clk_out5",
-                                    "clk_out6", "clk_out7";
-       };
index f2b1bce..1175f3a 100644 (file)
@@ -326,6 +326,9 @@ struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx,
        void *ret;
        int id;
 
+       if (!access_ok((void __user *)addr, length))
+               return ERR_PTR(-EFAULT);
+
        mutex_lock(&teedev->mutex);
        id = idr_alloc(&teedev->idr, NULL, 1, 0, GFP_KERNEL);
        mutex_unlock(&teedev->mutex);
index c492a57..3ff746e 100644 (file)
@@ -360,7 +360,7 @@ static void vm_synchronize_cbs(struct virtio_device *vdev)
 
 static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int index,
                                  void (*callback)(struct virtqueue *vq),
-                                 const char *name, u32 size, bool ctx)
+                                 const char *name, bool ctx)
 {
        struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
        struct virtio_mmio_vq_info *info;
@@ -395,11 +395,8 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
                goto error_new_virtqueue;
        }
 
-       if (!size || size > num)
-               size = num;
-
        /* Create the vring */
-       vq = vring_create_virtqueue(index, size, VIRTIO_MMIO_VRING_ALIGN, vdev,
+       vq = vring_create_virtqueue(index, num, VIRTIO_MMIO_VRING_ALIGN, vdev,
                                 true, true, ctx, vm_notify, callback, name);
        if (!vq) {
                err = -ENOMEM;
@@ -477,7 +474,6 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
                       struct virtqueue *vqs[],
                       vq_callback_t *callbacks[],
                       const char * const names[],
-                      u32 sizes[],
                       const bool *ctx,
                       struct irq_affinity *desc)
 {
@@ -503,7 +499,6 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
                }
 
                vqs[i] = vm_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
-                                    sizes ? sizes[i] : 0,
                                     ctx ? ctx[i] : false);
                if (IS_ERR(vqs[i])) {
                        vm_del_vqs(vdev);
index 00ad476..ad258a9 100644 (file)
@@ -174,7 +174,6 @@ error:
 static struct virtqueue *vp_setup_vq(struct virtio_device *vdev, unsigned int index,
                                     void (*callback)(struct virtqueue *vq),
                                     const char *name,
-                                    u32 size,
                                     bool ctx,
                                     u16 msix_vec)
 {
@@ -187,7 +186,7 @@ static struct virtqueue *vp_setup_vq(struct virtio_device *vdev, unsigned int in
        if (!info)
                return ERR_PTR(-ENOMEM);
 
-       vq = vp_dev->setup_vq(vp_dev, info, index, callback, name, size, ctx,
+       vq = vp_dev->setup_vq(vp_dev, info, index, callback, name, ctx,
                              msix_vec);
        if (IS_ERR(vq))
                goto out_info;
@@ -284,7 +283,7 @@ void vp_del_vqs(struct virtio_device *vdev)
 
 static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned int nvqs,
                struct virtqueue *vqs[], vq_callback_t *callbacks[],
-               const char * const names[], u32 sizes[], bool per_vq_vectors,
+               const char * const names[], bool per_vq_vectors,
                const bool *ctx,
                struct irq_affinity *desc)
 {
@@ -327,8 +326,8 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned int nvqs,
                else
                        msix_vec = VP_MSIX_VQ_VECTOR;
                vqs[i] = vp_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
-                                    sizes ? sizes[i] : 0,
-                                    ctx ? ctx[i] : false, msix_vec);
+                                    ctx ? ctx[i] : false,
+                                    msix_vec);
                if (IS_ERR(vqs[i])) {
                        err = PTR_ERR(vqs[i]);
                        goto error_find;
@@ -358,7 +357,7 @@ error_find:
 
 static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned int nvqs,
                struct virtqueue *vqs[], vq_callback_t *callbacks[],
-               const char * const names[], u32 sizes[], const bool *ctx)
+               const char * const names[], const bool *ctx)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        int i, err, queue_idx = 0;
@@ -380,7 +379,6 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned int nvqs,
                        continue;
                }
                vqs[i] = vp_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
-                                    sizes ? sizes[i] : 0,
                                     ctx ? ctx[i] : false,
                                     VIRTIO_MSI_NO_VECTOR);
                if (IS_ERR(vqs[i])) {
@@ -398,21 +396,21 @@ out_del_vqs:
 /* the config->find_vqs() implementation */
 int vp_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
                struct virtqueue *vqs[], vq_callback_t *callbacks[],
-               const char * const names[], u32 sizes[], const bool *ctx,
+               const char * const names[], const bool *ctx,
                struct irq_affinity *desc)
 {
        int err;
 
        /* Try MSI-X with one vector per queue. */
-       err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, sizes, true, ctx, desc);
+       err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, true, ctx, desc);
        if (!err)
                return 0;
        /* Fallback: MSI-X with one vector for config, one shared for queues. */
-       err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, sizes, false, ctx, desc);
+       err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, false, ctx, desc);
        if (!err)
                return 0;
        /* Finally fall back to regular interrupts. */
-       return vp_find_vqs_intx(vdev, nvqs, vqs, callbacks, names, sizes, ctx);
+       return vp_find_vqs_intx(vdev, nvqs, vqs, callbacks, names, ctx);
 }
 
 const char *vp_bus_name(struct virtio_device *vdev)
index c044837..23112d8 100644 (file)
@@ -80,7 +80,6 @@ struct virtio_pci_device {
                                      unsigned int idx,
                                      void (*callback)(struct virtqueue *vq),
                                      const char *name,
-                                     u32 size,
                                      bool ctx,
                                      u16 msix_vec);
        void (*del_vq)(struct virtio_pci_vq_info *info);
@@ -111,7 +110,7 @@ void vp_del_vqs(struct virtio_device *vdev);
 /* the config->find_vqs() implementation */
 int vp_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
                struct virtqueue *vqs[], vq_callback_t *callbacks[],
-               const char * const names[], u32 sizes[], const bool *ctx,
+               const char * const names[], const bool *ctx,
                struct irq_affinity *desc);
 const char *vp_bus_name(struct virtio_device *vdev);
 
index d75e5c4..2257f1b 100644 (file)
@@ -112,7 +112,6 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
                                  unsigned int index,
                                  void (*callback)(struct virtqueue *vq),
                                  const char *name,
-                                 u32 size,
                                  bool ctx,
                                  u16 msix_vec)
 {
@@ -126,13 +125,10 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
        if (!num || vp_legacy_get_queue_enable(&vp_dev->ldev, index))
                return ERR_PTR(-ENOENT);
 
-       if (!size || size > num)
-               size = num;
-
        info->msix_vector = msix_vec;
 
        /* create the vring */
-       vq = vring_create_virtqueue(index, size,
+       vq = vring_create_virtqueue(index, num,
                                    VIRTIO_PCI_VRING_ALIGN, &vp_dev->vdev,
                                    true, false, ctx,
                                    vp_notify, callback, name);
index f7965c5..c3b9f27 100644 (file)
@@ -293,7 +293,6 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
                                  unsigned int index,
                                  void (*callback)(struct virtqueue *vq),
                                  const char *name,
-                                 u32 size,
                                  bool ctx,
                                  u16 msix_vec)
 {
@@ -311,18 +310,15 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
        if (!num || vp_modern_get_queue_enable(mdev, index))
                return ERR_PTR(-ENOENT);
 
-       if (!size || size > num)
-               size = num;
-
-       if (size & (size - 1)) {
-               dev_warn(&vp_dev->pci_dev->dev, "bad queue size %u", size);
+       if (num & (num - 1)) {
+               dev_warn(&vp_dev->pci_dev->dev, "bad queue size %u", num);
                return ERR_PTR(-EINVAL);
        }
 
        info->msix_vector = msix_vec;
 
        /* create the vring */
-       vq = vring_create_virtqueue(index, size,
+       vq = vring_create_virtqueue(index, num,
                                    SMP_CACHE_BYTES, &vp_dev->vdev,
                                    true, true, ctx,
                                    vp_notify, callback, name);
@@ -351,15 +347,12 @@ err:
 static int vp_modern_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
                              struct virtqueue *vqs[],
                              vq_callback_t *callbacks[],
-                             const char * const names[],
-                             u32 sizes[],
-                             const bool *ctx,
+                             const char * const names[], const bool *ctx,
                              struct irq_affinity *desc)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        struct virtqueue *vq;
-       int rc = vp_find_vqs(vdev, nvqs, vqs, callbacks, names, sizes, ctx,
-                            desc);
+       int rc = vp_find_vqs(vdev, nvqs, vqs, callbacks, names, ctx, desc);
 
        if (rc)
                return rc;
index d66c8e6..4620e9d 100644 (file)
@@ -2426,6 +2426,14 @@ static inline bool more_used(const struct vring_virtqueue *vq)
        return vq->packed_ring ? more_used_packed(vq) : more_used_split(vq);
 }
 
+/**
+ * vring_interrupt - notify a virtqueue on an interrupt
+ * @irq: the IRQ number (ignored)
+ * @_vq: the struct virtqueue to notify
+ *
+ * Calls the callback function of @_vq to process the virtqueue
+ * notification.
+ */
 irqreturn_t vring_interrupt(int irq, void *_vq)
 {
        struct vring_virtqueue *vq = to_vvq(_vq);
index 9bc4d11..9670cc7 100644 (file)
@@ -131,7 +131,7 @@ static irqreturn_t virtio_vdpa_virtqueue_cb(void *private)
 static struct virtqueue *
 virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index,
                     void (*callback)(struct virtqueue *vq),
-                    const char *name, u32 size, bool ctx)
+                    const char *name, bool ctx)
 {
        struct virtio_vdpa_device *vd_dev = to_virtio_vdpa_device(vdev);
        struct vdpa_device *vdpa = vd_get_vdpa(vdev);
@@ -168,17 +168,14 @@ virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index,
                goto error_new_virtqueue;
        }
 
-       if (!size || size > max_num)
-               size = max_num;
-
        if (ops->get_vq_num_min)
                min_num = ops->get_vq_num_min(vdpa);
 
-       may_reduce_num = (size == min_num) ? false : true;
+       may_reduce_num = (max_num == min_num) ? false : true;
 
        /* Create the vring */
        align = ops->get_vq_align(vdpa);
-       vq = vring_create_virtqueue(index, size, align, vdev,
+       vq = vring_create_virtqueue(index, max_num, align, vdev,
                                    true, may_reduce_num, ctx,
                                    virtio_vdpa_notify, callback, name);
        if (!vq) {
@@ -272,7 +269,6 @@ static int virtio_vdpa_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
                                struct virtqueue *vqs[],
                                vq_callback_t *callbacks[],
                                const char * const names[],
-                               u32 sizes[],
                                const bool *ctx,
                                struct irq_affinity *desc)
 {
@@ -288,9 +284,9 @@ static int virtio_vdpa_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
                        continue;
                }
 
-               vqs[i] = virtio_vdpa_setup_vq(vdev, queue_idx++, callbacks[i],
-                                                 names[i], sizes ? sizes[i] : 0,
-                                                 ctx ? ctx[i] : false);
+               vqs[i] = virtio_vdpa_setup_vq(vdev, queue_idx++,
+                                             callbacks[i], names[i], ctx ?
+                                             ctx[i] : false);
                if (IS_ERR(vqs[i])) {
                        err = PTR_ERR(vqs[i]);
                        goto err_setup_vq;
index c3aecfb..993aca2 100644 (file)
@@ -1640,9 +1640,11 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
                                div64_u64(zone_unusable * 100, bg->length));
                trace_btrfs_reclaim_block_group(bg);
                ret = btrfs_relocate_chunk(fs_info, bg->start);
-               if (ret)
+               if (ret) {
+                       btrfs_dec_block_group_ro(bg);
                        btrfs_err(fs_info, "error relocating chunk %llu",
                                  bg->start);
+               }
 
 next:
                btrfs_put_block_group(bg);
index 6e55603..ebfa35f 100644 (file)
@@ -2075,6 +2075,9 @@ cow_done:
 
                if (!p->skip_locking) {
                        level = btrfs_header_level(b);
+
+                       btrfs_maybe_reset_lockdep_class(root, b);
+
                        if (level <= write_lock_level) {
                                btrfs_tree_lock(b);
                                p->locks[level] = BTRFS_WRITE_LOCK;
index 4db85b9..4edb4bf 100644 (file)
@@ -1173,6 +1173,8 @@ enum {
        BTRFS_ROOT_ORPHAN_CLEANUP,
        /* This root has a drop operation that was started previously. */
        BTRFS_ROOT_UNFINISHED_DROP,
+       /* This reloc root needs to have its buffers lockdep class reset. */
+       BTRFS_ROOT_RESET_LOCKDEP_CLASS,
 };
 
 static inline void btrfs_wake_unfinished_drop(struct btrfs_fs_info *fs_info)
index 4c3166f..820b1f1 100644 (file)
@@ -87,88 +87,6 @@ struct async_submit_bio {
 };
 
 /*
- * Lockdep class keys for extent_buffer->lock's in this root.  For a given
- * eb, the lockdep key is determined by the btrfs_root it belongs to and
- * the level the eb occupies in the tree.
- *
- * Different roots are used for different purposes and may nest inside each
- * other and they require separate keysets.  As lockdep keys should be
- * static, assign keysets according to the purpose of the root as indicated
- * by btrfs_root->root_key.objectid.  This ensures that all special purpose
- * roots have separate keysets.
- *
- * Lock-nesting across peer nodes is always done with the immediate parent
- * node locked thus preventing deadlock.  As lockdep doesn't know this, use
- * subclass to avoid triggering lockdep warning in such cases.
- *
- * The key is set by the readpage_end_io_hook after the buffer has passed
- * csum validation but before the pages are unlocked.  It is also set by
- * btrfs_init_new_buffer on freshly allocated blocks.
- *
- * We also add a check to make sure the highest level of the tree is the
- * same as our lockdep setup here.  If BTRFS_MAX_LEVEL changes, this code
- * needs update as well.
- */
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-# if BTRFS_MAX_LEVEL != 8
-#  error
-# endif
-
-#define DEFINE_LEVEL(stem, level)                                      \
-       .names[level] = "btrfs-" stem "-0" #level,
-
-#define DEFINE_NAME(stem)                                              \
-       DEFINE_LEVEL(stem, 0)                                           \
-       DEFINE_LEVEL(stem, 1)                                           \
-       DEFINE_LEVEL(stem, 2)                                           \
-       DEFINE_LEVEL(stem, 3)                                           \
-       DEFINE_LEVEL(stem, 4)                                           \
-       DEFINE_LEVEL(stem, 5)                                           \
-       DEFINE_LEVEL(stem, 6)                                           \
-       DEFINE_LEVEL(stem, 7)
-
-static struct btrfs_lockdep_keyset {
-       u64                     id;             /* root objectid */
-       /* Longest entry: btrfs-free-space-00 */
-       char                    names[BTRFS_MAX_LEVEL][20];
-       struct lock_class_key   keys[BTRFS_MAX_LEVEL];
-} btrfs_lockdep_keysets[] = {
-       { .id = BTRFS_ROOT_TREE_OBJECTID,       DEFINE_NAME("root")     },
-       { .id = BTRFS_EXTENT_TREE_OBJECTID,     DEFINE_NAME("extent")   },
-       { .id = BTRFS_CHUNK_TREE_OBJECTID,      DEFINE_NAME("chunk")    },
-       { .id = BTRFS_DEV_TREE_OBJECTID,        DEFINE_NAME("dev")      },
-       { .id = BTRFS_CSUM_TREE_OBJECTID,       DEFINE_NAME("csum")     },
-       { .id = BTRFS_QUOTA_TREE_OBJECTID,      DEFINE_NAME("quota")    },
-       { .id = BTRFS_TREE_LOG_OBJECTID,        DEFINE_NAME("log")      },
-       { .id = BTRFS_TREE_RELOC_OBJECTID,      DEFINE_NAME("treloc")   },
-       { .id = BTRFS_DATA_RELOC_TREE_OBJECTID, DEFINE_NAME("dreloc")   },
-       { .id = BTRFS_UUID_TREE_OBJECTID,       DEFINE_NAME("uuid")     },
-       { .id = BTRFS_FREE_SPACE_TREE_OBJECTID, DEFINE_NAME("free-space") },
-       { .id = 0,                              DEFINE_NAME("tree")     },
-};
-
-#undef DEFINE_LEVEL
-#undef DEFINE_NAME
-
-void btrfs_set_buffer_lockdep_class(u64 objectid, struct extent_buffer *eb,
-                                   int level)
-{
-       struct btrfs_lockdep_keyset *ks;
-
-       BUG_ON(level >= ARRAY_SIZE(ks->keys));
-
-       /* find the matching keyset, id 0 is the default entry */
-       for (ks = btrfs_lockdep_keysets; ks->id; ks++)
-               if (ks->id == objectid)
-                       break;
-
-       lockdep_set_class_and_name(&eb->lock,
-                                  &ks->keys[level], ks->names[level]);
-}
-
-#endif
-
-/*
  * Compute the csum of a btree block and store the result to provided buffer.
  */
 static void csum_tree_block(struct extent_buffer *buf, u8 *result)
index 8993b42..47ad8e0 100644 (file)
@@ -137,14 +137,4 @@ int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags);
 int btrfs_get_free_objectid(struct btrfs_root *root, u64 *objectid);
 int btrfs_init_root_free_objectid(struct btrfs_root *root);
 
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-void btrfs_set_buffer_lockdep_class(u64 objectid,
-                                   struct extent_buffer *eb, int level);
-#else
-static inline void btrfs_set_buffer_lockdep_class(u64 objectid,
-                                       struct extent_buffer *eb, int level)
-{
-}
-#endif
-
 #endif
index ea3ec1e..ab944d1 100644 (file)
@@ -4867,6 +4867,7 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 {
        struct btrfs_fs_info *fs_info = root->fs_info;
        struct extent_buffer *buf;
+       u64 lockdep_owner = owner;
 
        buf = btrfs_find_create_tree_block(fs_info, bytenr, owner, level);
        if (IS_ERR(buf))
@@ -4886,11 +4887,26 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
        }
 
        /*
+        * The reloc trees are just snapshots, so we need them to appear to be
+        * just like any other fs tree WRT lockdep.
+        *
+        * The exception however is in replace_path() in relocation, where we
+        * hold the lock on the original fs root and then search for the reloc
+        * root.  At that point we need to make sure any reloc root buffers are
+        * set to the BTRFS_TREE_RELOC_OBJECTID lockdep class in order to make
+        * lockdep happy.
+        */
+       if (lockdep_owner == BTRFS_TREE_RELOC_OBJECTID &&
+           !test_bit(BTRFS_ROOT_RESET_LOCKDEP_CLASS, &root->state))
+               lockdep_owner = BTRFS_FS_TREE_OBJECTID;
+
+       /*
         * This needs to stay, because we could allocate a freed block from an
         * old tree into a new tree, so we need to make sure this new block is
         * set to the appropriate level and owner.
         */
-       btrfs_set_buffer_lockdep_class(owner, buf, level);
+       btrfs_set_buffer_lockdep_class(lockdep_owner, buf, level);
+
        __btrfs_tree_lock(buf, nest);
        btrfs_clean_tree_block(buf);
        clear_bit(EXTENT_BUFFER_STALE, &buf->bflags);
index bfae67c..eed81a7 100644 (file)
@@ -6140,6 +6140,7 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
        struct extent_buffer *exists = NULL;
        struct page *p;
        struct address_space *mapping = fs_info->btree_inode->i_mapping;
+       u64 lockdep_owner = owner_root;
        int uptodate = 1;
        int ret;
 
@@ -6164,7 +6165,15 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
        eb = __alloc_extent_buffer(fs_info, start, len);
        if (!eb)
                return ERR_PTR(-ENOMEM);
-       btrfs_set_buffer_lockdep_class(owner_root, eb, level);
+
+       /*
+        * The reloc trees are just snapshots, so we need them to appear to be
+        * just like any other fs tree WRT lockdep.
+        */
+       if (lockdep_owner == BTRFS_TREE_RELOC_OBJECTID)
+               lockdep_owner = BTRFS_FS_TREE_OBJECTID;
+
+       btrfs_set_buffer_lockdep_class(lockdep_owner, eb, level);
 
        num_pages = num_extent_pages(eb);
        for (i = 0; i < num_pages; i++, index++) {
index 33461b4..9063072 100644 (file)
 #include "locking.h"
 
 /*
+ * Lockdep class keys for extent_buffer->lock's in this root.  For a given
+ * eb, the lockdep key is determined by the btrfs_root it belongs to and
+ * the level the eb occupies in the tree.
+ *
+ * Different roots are used for different purposes and may nest inside each
+ * other and they require separate keysets.  As lockdep keys should be
+ * static, assign keysets according to the purpose of the root as indicated
+ * by btrfs_root->root_key.objectid.  This ensures that all special purpose
+ * roots have separate keysets.
+ *
+ * Lock-nesting across peer nodes is always done with the immediate parent
+ * node locked thus preventing deadlock.  As lockdep doesn't know this, use
+ * subclass to avoid triggering lockdep warning in such cases.
+ *
+ * The key is set by the readpage_end_io_hook after the buffer has passed
+ * csum validation but before the pages are unlocked.  It is also set by
+ * btrfs_init_new_buffer on freshly allocated blocks.
+ *
+ * We also add a check to make sure the highest level of the tree is the
+ * same as our lockdep setup here.  If BTRFS_MAX_LEVEL changes, this code
+ * needs update as well.
+ */
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+#if BTRFS_MAX_LEVEL != 8
+#error
+#endif
+
+#define DEFINE_LEVEL(stem, level)                                      \
+       .names[level] = "btrfs-" stem "-0" #level,
+
+#define DEFINE_NAME(stem)                                              \
+       DEFINE_LEVEL(stem, 0)                                           \
+       DEFINE_LEVEL(stem, 1)                                           \
+       DEFINE_LEVEL(stem, 2)                                           \
+       DEFINE_LEVEL(stem, 3)                                           \
+       DEFINE_LEVEL(stem, 4)                                           \
+       DEFINE_LEVEL(stem, 5)                                           \
+       DEFINE_LEVEL(stem, 6)                                           \
+       DEFINE_LEVEL(stem, 7)
+
+static struct btrfs_lockdep_keyset {
+       u64                     id;             /* root objectid */
+       /* Longest entry: btrfs-free-space-00 */
+       char                    names[BTRFS_MAX_LEVEL][20];
+       struct lock_class_key   keys[BTRFS_MAX_LEVEL];
+} btrfs_lockdep_keysets[] = {
+       { .id = BTRFS_ROOT_TREE_OBJECTID,       DEFINE_NAME("root")     },
+       { .id = BTRFS_EXTENT_TREE_OBJECTID,     DEFINE_NAME("extent")   },
+       { .id = BTRFS_CHUNK_TREE_OBJECTID,      DEFINE_NAME("chunk")    },
+       { .id = BTRFS_DEV_TREE_OBJECTID,        DEFINE_NAME("dev")      },
+       { .id = BTRFS_CSUM_TREE_OBJECTID,       DEFINE_NAME("csum")     },
+       { .id = BTRFS_QUOTA_TREE_OBJECTID,      DEFINE_NAME("quota")    },
+       { .id = BTRFS_TREE_LOG_OBJECTID,        DEFINE_NAME("log")      },
+       { .id = BTRFS_TREE_RELOC_OBJECTID,      DEFINE_NAME("treloc")   },
+       { .id = BTRFS_DATA_RELOC_TREE_OBJECTID, DEFINE_NAME("dreloc")   },
+       { .id = BTRFS_UUID_TREE_OBJECTID,       DEFINE_NAME("uuid")     },
+       { .id = BTRFS_FREE_SPACE_TREE_OBJECTID, DEFINE_NAME("free-space") },
+       { .id = 0,                              DEFINE_NAME("tree")     },
+};
+
+#undef DEFINE_LEVEL
+#undef DEFINE_NAME
+
+void btrfs_set_buffer_lockdep_class(u64 objectid, struct extent_buffer *eb, int level)
+{
+       struct btrfs_lockdep_keyset *ks;
+
+       BUG_ON(level >= ARRAY_SIZE(ks->keys));
+
+       /* Find the matching keyset, id 0 is the default entry */
+       for (ks = btrfs_lockdep_keysets; ks->id; ks++)
+               if (ks->id == objectid)
+                       break;
+
+       lockdep_set_class_and_name(&eb->lock, &ks->keys[level], ks->names[level]);
+}
+
+void btrfs_maybe_reset_lockdep_class(struct btrfs_root *root, struct extent_buffer *eb)
+{
+       if (test_bit(BTRFS_ROOT_RESET_LOCKDEP_CLASS, &root->state))
+               btrfs_set_buffer_lockdep_class(root->root_key.objectid,
+                                              eb, btrfs_header_level(eb));
+}
+
+#endif
+
+/*
  * Extent buffer locking
  * =====================
  *
@@ -164,6 +251,8 @@ struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root)
 
        while (1) {
                eb = btrfs_root_node(root);
+
+               btrfs_maybe_reset_lockdep_class(root, eb);
                btrfs_tree_lock(eb);
                if (eb == root->node)
                        break;
@@ -185,6 +274,8 @@ struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root)
 
        while (1) {
                eb = btrfs_root_node(root);
+
+               btrfs_maybe_reset_lockdep_class(root, eb);
                btrfs_tree_read_lock(eb);
                if (eb == root->node)
                        break;
index bbc4553..ab268be 100644 (file)
@@ -131,4 +131,18 @@ void btrfs_drew_write_unlock(struct btrfs_drew_lock *lock);
 void btrfs_drew_read_lock(struct btrfs_drew_lock *lock);
 void btrfs_drew_read_unlock(struct btrfs_drew_lock *lock);
 
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+void btrfs_set_buffer_lockdep_class(u64 objectid, struct extent_buffer *eb, int level);
+void btrfs_maybe_reset_lockdep_class(struct btrfs_root *root, struct extent_buffer *eb);
+#else
+static inline void btrfs_set_buffer_lockdep_class(u64 objectid,
+                                       struct extent_buffer *eb, int level)
+{
+}
+static inline void btrfs_maybe_reset_lockdep_class(struct btrfs_root *root,
+                                                  struct extent_buffer *eb)
+{
+}
+#endif
+
 #endif
index a6dc827..45c02ab 100644 (file)
@@ -1326,7 +1326,9 @@ again:
                btrfs_release_path(path);
 
                path->lowest_level = level;
+               set_bit(BTRFS_ROOT_RESET_LOCKDEP_CLASS, &src->state);
                ret = btrfs_search_slot(trans, src, &key, path, 0, 1);
+               clear_bit(BTRFS_ROOT_RESET_LOCKDEP_CLASS, &src->state);
                path->lowest_level = 0;
                if (ret) {
                        if (ret > 0)
@@ -3573,7 +3575,12 @@ int prepare_to_relocate(struct reloc_control *rc)
                 */
                return PTR_ERR(trans);
        }
-       return btrfs_commit_transaction(trans);
+
+       ret = btrfs_commit_transaction(trans);
+       if (ret)
+               unset_reloc_control(rc);
+
+       return ret;
 }
 
 static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
index 9e0e0ae..43f905a 100644 (file)
@@ -1233,7 +1233,8 @@ static void extent_err(const struct extent_buffer *eb, int slot,
 }
 
 static int check_extent_item(struct extent_buffer *leaf,
-                            struct btrfs_key *key, int slot)
+                            struct btrfs_key *key, int slot,
+                            struct btrfs_key *prev_key)
 {
        struct btrfs_fs_info *fs_info = leaf->fs_info;
        struct btrfs_extent_item *ei;
@@ -1453,6 +1454,26 @@ static int check_extent_item(struct extent_buffer *leaf,
                           total_refs, inline_refs);
                return -EUCLEAN;
        }
+
+       if ((prev_key->type == BTRFS_EXTENT_ITEM_KEY) ||
+           (prev_key->type == BTRFS_METADATA_ITEM_KEY)) {
+               u64 prev_end = prev_key->objectid;
+
+               if (prev_key->type == BTRFS_METADATA_ITEM_KEY)
+                       prev_end += fs_info->nodesize;
+               else
+                       prev_end += prev_key->offset;
+
+               if (unlikely(prev_end > key->objectid)) {
+                       extent_err(leaf, slot,
+       "previous extent [%llu %u %llu] overlaps current extent [%llu %u %llu]",
+                                  prev_key->objectid, prev_key->type,
+                                  prev_key->offset, key->objectid, key->type,
+                                  key->offset);
+                       return -EUCLEAN;
+               }
+       }
+
        return 0;
 }
 
@@ -1621,7 +1642,7 @@ static int check_leaf_item(struct extent_buffer *leaf,
                break;
        case BTRFS_EXTENT_ITEM_KEY:
        case BTRFS_METADATA_ITEM_KEY:
-               ret = check_extent_item(leaf, key, slot);
+               ret = check_extent_item(leaf, key, slot, prev_key);
                break;
        case BTRFS_TREE_BLOCK_REF_KEY:
        case BTRFS_SHARED_DATA_REF_KEY:
index dcf75a8..9205c4a 100644 (file)
@@ -1146,7 +1146,9 @@ again:
        extref = btrfs_lookup_inode_extref(NULL, root, path, name, namelen,
                                           inode_objectid, parent_objectid, 0,
                                           0);
-       if (!IS_ERR_OR_NULL(extref)) {
+       if (IS_ERR(extref)) {
+               return PTR_ERR(extref);
+       } else if (extref) {
                u32 item_size;
                u32 cur_offset = 0;
                unsigned long base;
@@ -1457,7 +1459,7 @@ static int add_link(struct btrfs_trans_handle *trans,
         * on the inode will not free it. We will fixup the link count later.
         */
        if (other_inode->i_nlink == 0)
-               inc_nlink(other_inode);
+               set_nlink(other_inode, 1);
 add_link:
        ret = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode),
                             name, namelen, 0, ref_index);
@@ -1600,7 +1602,7 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
                                 * free it. We will fixup the link count later.
                                 */
                                if (!ret && inode->i_nlink == 0)
-                                       inc_nlink(inode);
+                                       set_nlink(inode, 1);
                        }
                        if (ret < 0)
                                goto out;
index 11fd85d..c05477e 100644 (file)
@@ -42,7 +42,7 @@ void cifs_dump_detail(void *buf, struct TCP_Server_Info *server)
                 smb->Command, smb->Status.CifsError,
                 smb->Flags, smb->Flags2, smb->Mid, smb->Pid);
        cifs_dbg(VFS, "smb buf %p len %u\n", smb,
-                server->ops->calc_smb_size(smb, server));
+                server->ops->calc_smb_size(smb));
 #endif /* CONFIG_CIFS_DEBUG2 */
 }
 
index bc0ee2d..f15d7b0 100644 (file)
@@ -417,7 +417,7 @@ struct smb_version_operations {
        int (*close_dir)(const unsigned int, struct cifs_tcon *,
                         struct cifs_fid *);
        /* calculate a size of SMB message */
-       unsigned int (*calc_smb_size)(void *buf, struct TCP_Server_Info *ptcpi);
+       unsigned int (*calc_smb_size)(void *buf);
        /* check for STATUS_PENDING and process the response if yes */
        bool (*is_status_pending)(char *buf, struct TCP_Server_Info *server);
        /* check for STATUS_NETWORK_SESSION_EXPIRED */
index 87a77a6..3bc94bc 100644 (file)
@@ -151,7 +151,7 @@ extern int cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
 extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
 extern int cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
                                  struct cifsFileInfo **ret_file);
-extern unsigned int smbCalcSize(void *buf, struct TCP_Server_Info *server);
+extern unsigned int smbCalcSize(void *buf);
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
                        struct TCP_Server_Info *server);
 extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
index 9e91a5a..56ec1b2 100644 (file)
@@ -59,7 +59,7 @@ static int __init cifs_root_setup(char *line)
                        pr_err("Root-CIFS: UNC path too long\n");
                        return 1;
                }
-               strlcpy(root_dev, line, len);
+               strscpy(root_dev, line, len);
                srvaddr = parse_srvaddr(&line[2], s);
                if (*s) {
                        int n = snprintf(root_opts,
index 9111c02..3da5da9 100644 (file)
@@ -3994,7 +3994,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
                }
                bcc_ptr += length + 1;
                bytes_left -= (length + 1);
-               strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
+               strscpy(tcon->treeName, tree, sizeof(tcon->treeName));
 
                /* mostly informational -- no need to fail on error here */
                kfree(tcon->nativeFileSystem);
index 34d990f..87f60f7 100644 (file)
@@ -354,7 +354,7 @@ checkSMB(char *buf, unsigned int total_read, struct TCP_Server_Info *server)
        /* otherwise, there is enough to get to the BCC */
        if (check_smb_hdr(smb))
                return -EIO;
-       clc_len = smbCalcSize(smb, server);
+       clc_len = smbCalcSize(smb);
 
        if (4 + rfclen != total_read) {
                cifs_dbg(VFS, "Length read does not match RFC1001 length %d\n",
@@ -737,6 +737,8 @@ cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode)
        list_for_each_entry(cfile, &cifs_inode->openFileList, flist) {
                if (delayed_work_pending(&cfile->deferred)) {
                        if (cancel_delayed_work(&cfile->deferred)) {
+                               cifs_del_deferred_close(cfile);
+
                                tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
                                if (tmp_list == NULL)
                                        break;
@@ -766,6 +768,8 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon)
        list_for_each_entry(cfile, &tcon->openFileList, tlist) {
                if (delayed_work_pending(&cfile->deferred)) {
                        if (cancel_delayed_work(&cfile->deferred)) {
+                               cifs_del_deferred_close(cfile);
+
                                tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
                                if (tmp_list == NULL)
                                        break;
@@ -799,6 +803,8 @@ cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)
                if (strstr(full_path, path)) {
                        if (delayed_work_pending(&cfile->deferred)) {
                                if (cancel_delayed_work(&cfile->deferred)) {
+                                       cifs_del_deferred_close(cfile);
+
                                        tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
                                        if (tmp_list == NULL)
                                                break;
index 28caae7..1b52e6a 100644 (file)
@@ -909,7 +909,7 @@ map_and_check_smb_error(struct mid_q_entry *mid, bool logErr)
  * portion, the number of word parameters and the data portion of the message
  */
 unsigned int
-smbCalcSize(void *buf, struct TCP_Server_Info *server)
+smbCalcSize(void *buf)
 {
        struct smb_hdr *ptr = buf;
        return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
index 2eece8a..8e060c0 100644 (file)
@@ -806,8 +806,7 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos,
 
                end_of_smb = cfile->srch_inf.ntwrk_buf_start +
                        server->ops->calc_smb_size(
-                                       cfile->srch_inf.ntwrk_buf_start,
-                                       server);
+                                       cfile->srch_inf.ntwrk_buf_start);
 
                cur_ent = cfile->srch_inf.srch_entries_start;
                first_entry_in_buffer = cfile->srch_inf.index_of_last_entry
@@ -1161,8 +1160,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
        cifs_dbg(FYI, "loop through %d times filling dir for net buf %p\n",
                 num_to_fill, cifsFile->srch_inf.ntwrk_buf_start);
        max_len = tcon->ses->server->ops->calc_smb_size(
-                       cifsFile->srch_inf.ntwrk_buf_start,
-                       tcon->ses->server);
+                       cifsFile->srch_inf.ntwrk_buf_start);
        end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
 
        tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL);
index f5dcc49..9dfd2dd 100644 (file)
@@ -61,7 +61,6 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
                nr_ioctl_req.Reserved = 0;
                rc = SMB2_ioctl(xid, oparms->tcon, fid->persistent_fid,
                        fid->volatile_fid, FSCTL_LMR_REQUEST_RESILIENCY,
-                       true /* is_fsctl */,
                        (char *)&nr_ioctl_req, sizeof(nr_ioctl_req),
                        CIFSMaxBufSize, NULL, NULL /* no return info */);
                if (rc == -EOPNOTSUPP) {
index 6a6ec6e..d73e567 100644 (file)
@@ -222,7 +222,7 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
                }
        }
 
-       calc_len = smb2_calc_size(buf, server);
+       calc_len = smb2_calc_size(buf);
 
        /* For SMB2_IOCTL, OutputOffset and OutputLength are optional, so might
         * be 0, and not a real miscalculation */
@@ -410,7 +410,7 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *shdr)
  * portion, the number of word parameters and the data portion of the message.
  */
 unsigned int
-smb2_calc_size(void *buf, struct TCP_Server_Info *srvr)
+smb2_calc_size(void *buf)
 {
        struct smb2_pdu *pdu = buf;
        struct smb2_hdr *shdr = &pdu->hdr;
index f406af5..96f3b05 100644 (file)
@@ -387,7 +387,7 @@ smb2_dump_detail(void *buf, struct TCP_Server_Info *server)
                 shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId,
                 shdr->Id.SyncId.ProcessId);
        cifs_server_dbg(VFS, "smb buf %p len %u\n", buf,
-                server->ops->calc_smb_size(buf, server));
+                server->ops->calc_smb_size(buf));
 #endif
 }
 
@@ -681,7 +681,7 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
        struct cifs_ses *ses = tcon->ses;
 
        rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
-                       FSCTL_QUERY_NETWORK_INTERFACE_INFO, true /* is_fsctl */,
+                       FSCTL_QUERY_NETWORK_INTERFACE_INFO,
                        NULL /* no data input */, 0 /* no data input */,
                        CIFSMaxBufSize, (char **)&out_buf, &ret_data_len);
        if (rc == -EOPNOTSUPP) {
@@ -1323,9 +1323,8 @@ SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon,
        struct resume_key_req *res_key;
 
        rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid,
-                       FSCTL_SRV_REQUEST_RESUME_KEY, true /* is_fsctl */,
-                       NULL, 0 /* no input */, CIFSMaxBufSize,
-                       (char **)&res_key, &ret_data_len);
+                       FSCTL_SRV_REQUEST_RESUME_KEY, NULL, 0 /* no input */,
+                       CIFSMaxBufSize, (char **)&res_key, &ret_data_len);
 
        if (rc == -EOPNOTSUPP) {
                pr_warn_once("Server share %s does not support copy range\n", tcon->treeName);
@@ -1467,7 +1466,7 @@ smb2_ioctl_query_info(const unsigned int xid,
                rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
 
                rc = SMB2_ioctl_init(tcon, server, &rqst[1], COMPOUND_FID, COMPOUND_FID,
-                                    qi.info_type, true, buffer, qi.output_buffer_length,
+                                    qi.info_type, buffer, qi.output_buffer_length,
                                     CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE -
                                     MAX_SMB2_CLOSE_RESPONSE_SIZE);
                free_req1_func = SMB2_ioctl_free;
@@ -1643,9 +1642,8 @@ smb2_copychunk_range(const unsigned int xid,
                retbuf = NULL;
                rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
                        trgtfile->fid.volatile_fid, FSCTL_SRV_COPYCHUNK_WRITE,
-                       true /* is_fsctl */, (char *)pcchunk,
-                       sizeof(struct copychunk_ioctl), CIFSMaxBufSize,
-                       (char **)&retbuf, &ret_data_len);
+                       (char *)pcchunk, sizeof(struct copychunk_ioctl),
+                       CIFSMaxBufSize, (char **)&retbuf, &ret_data_len);
                if (rc == 0) {
                        if (ret_data_len !=
                                        sizeof(struct copychunk_ioctl_rsp)) {
@@ -1805,7 +1803,6 @@ static bool smb2_set_sparse(const unsigned int xid, struct cifs_tcon *tcon,
 
        rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
                        cfile->fid.volatile_fid, FSCTL_SET_SPARSE,
-                       true /* is_fctl */,
                        &setsparse, 1, CIFSMaxBufSize, NULL, NULL);
        if (rc) {
                tcon->broken_sparse_sup = true;
@@ -1888,7 +1885,6 @@ smb2_duplicate_extents(const unsigned int xid,
        rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
                        trgtfile->fid.volatile_fid,
                        FSCTL_DUPLICATE_EXTENTS_TO_FILE,
-                       true /* is_fsctl */,
                        (char *)&dup_ext_buf,
                        sizeof(struct duplicate_extents_to_file),
                        CIFSMaxBufSize, NULL,
@@ -1923,7 +1919,6 @@ smb3_set_integrity(const unsigned int xid, struct cifs_tcon *tcon,
        return SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
                        cfile->fid.volatile_fid,
                        FSCTL_SET_INTEGRITY_INFORMATION,
-                       true /* is_fsctl */,
                        (char *)&integr_info,
                        sizeof(struct fsctl_set_integrity_information_req),
                        CIFSMaxBufSize, NULL,
@@ -1976,7 +1971,6 @@ smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon,
        rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
                        cfile->fid.volatile_fid,
                        FSCTL_SRV_ENUMERATE_SNAPSHOTS,
-                       true /* is_fsctl */,
                        NULL, 0 /* no input data */, max_response_size,
                        (char **)&retbuf,
                        &ret_data_len);
@@ -2699,7 +2693,6 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
        do {
                rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
                                FSCTL_DFS_GET_REFERRALS,
-                               true /* is_fsctl */,
                                (char *)dfs_req, dfs_req_size, CIFSMaxBufSize,
                                (char **)&dfs_rsp, &dfs_rsp_size);
                if (!is_retryable_error(rc))
@@ -2906,8 +2899,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 
        rc = SMB2_ioctl_init(tcon, server,
                             &rqst[1], fid.persistent_fid,
-                            fid.volatile_fid, FSCTL_GET_REPARSE_POINT,
-                            true /* is_fctl */, NULL, 0,
+                            fid.volatile_fid, FSCTL_GET_REPARSE_POINT, NULL, 0,
                             CIFSMaxBufSize -
                             MAX_SMB2_CREATE_RESPONSE_SIZE -
                             MAX_SMB2_CLOSE_RESPONSE_SIZE);
@@ -3087,8 +3079,7 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
 
        rc = SMB2_ioctl_init(tcon, server,
                             &rqst[1], COMPOUND_FID,
-                            COMPOUND_FID, FSCTL_GET_REPARSE_POINT,
-                            true /* is_fctl */, NULL, 0,
+                            COMPOUND_FID, FSCTL_GET_REPARSE_POINT, NULL, 0,
                             CIFSMaxBufSize -
                             MAX_SMB2_CREATE_RESPONSE_SIZE -
                             MAX_SMB2_CLOSE_RESPONSE_SIZE);
@@ -3358,7 +3349,7 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
        fsctl_buf.BeyondFinalZero = cpu_to_le64(offset + len);
 
        rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
-                       cfile->fid.volatile_fid, FSCTL_SET_ZERO_DATA, true,
+                       cfile->fid.volatile_fid, FSCTL_SET_ZERO_DATA,
                        (char *)&fsctl_buf,
                        sizeof(struct file_zero_data_information),
                        0, NULL, NULL);
@@ -3421,7 +3412,7 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
 
        rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
                        cfile->fid.volatile_fid, FSCTL_SET_ZERO_DATA,
-                       true /* is_fctl */, (char *)&fsctl_buf,
+                       (char *)&fsctl_buf,
                        sizeof(struct file_zero_data_information),
                        CIFSMaxBufSize, NULL, NULL);
        free_xid(xid);
@@ -3481,7 +3472,7 @@ static int smb3_simple_fallocate_range(unsigned int xid,
        in_data.length = cpu_to_le64(len);
        rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
                        cfile->fid.volatile_fid,
-                       FSCTL_QUERY_ALLOCATED_RANGES, true,
+                       FSCTL_QUERY_ALLOCATED_RANGES,
                        (char *)&in_data, sizeof(in_data),
                        1024 * sizeof(struct file_allocated_range_buffer),
                        (char **)&out_data, &out_data_len);
@@ -3802,7 +3793,7 @@ static loff_t smb3_llseek(struct file *file, struct cifs_tcon *tcon, loff_t offs
 
        rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
                        cfile->fid.volatile_fid,
-                       FSCTL_QUERY_ALLOCATED_RANGES, true,
+                       FSCTL_QUERY_ALLOCATED_RANGES,
                        (char *)&in_data, sizeof(in_data),
                        sizeof(struct file_allocated_range_buffer),
                        (char **)&out_data, &out_data_len);
@@ -3862,7 +3853,7 @@ static int smb3_fiemap(struct cifs_tcon *tcon,
 
        rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
                        cfile->fid.volatile_fid,
-                       FSCTL_QUERY_ALLOCATED_RANGES, true,
+                       FSCTL_QUERY_ALLOCATED_RANGES,
                        (char *)&in_data, sizeof(in_data),
                        1024 * sizeof(struct file_allocated_range_buffer),
                        (char **)&out_data, &out_data_len);
index 9b31ea9..91cfc5b 100644 (file)
@@ -1173,7 +1173,7 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
        }
 
        rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
-               FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */,
+               FSCTL_VALIDATE_NEGOTIATE_INFO,
                (char *)pneg_inbuf, inbuflen, CIFSMaxBufSize,
                (char **)&pneg_rsp, &rsplen);
        if (rc == -EOPNOTSUPP) {
@@ -1928,7 +1928,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
        tcon->capabilities = rsp->Capabilities; /* we keep caps little endian */
        tcon->maximal_access = le32_to_cpu(rsp->MaximalAccess);
        tcon->tid = le32_to_cpu(rsp->hdr.Id.SyncId.TreeId);
-       strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
+       strscpy(tcon->treeName, tree, sizeof(tcon->treeName));
 
        if ((rsp->Capabilities & SMB2_SHARE_CAP_DFS) &&
            ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0))
@@ -3056,7 +3056,7 @@ int
 SMB2_ioctl_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
                struct smb_rqst *rqst,
                u64 persistent_fid, u64 volatile_fid, u32 opcode,
-               bool is_fsctl, char *in_data, u32 indatalen,
+               char *in_data, u32 indatalen,
                __u32 max_response_size)
 {
        struct smb2_ioctl_req *req;
@@ -3131,10 +3131,8 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
        req->hdr.CreditCharge =
                cpu_to_le16(DIV_ROUND_UP(max(indatalen, max_response_size),
                                         SMB2_MAX_BUFFER_SIZE));
-       if (is_fsctl)
-               req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL);
-       else
-               req->Flags = 0;
+       /* always an FSCTL (for now) */
+       req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL);
 
        /* validate negotiate request must be signed - see MS-SMB2 3.2.5.5 */
        if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO)
@@ -3161,9 +3159,9 @@ SMB2_ioctl_free(struct smb_rqst *rqst)
  */
 int
 SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
-          u64 volatile_fid, u32 opcode, bool is_fsctl,
-          char *in_data, u32 indatalen, u32 max_out_data_len,
-          char **out_data, u32 *plen /* returned data len */)
+          u64 volatile_fid, u32 opcode, char *in_data, u32 indatalen,
+          u32 max_out_data_len, char **out_data,
+          u32 *plen /* returned data len */)
 {
        struct smb_rqst rqst;
        struct smb2_ioctl_rsp *rsp = NULL;
@@ -3205,7 +3203,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
 
        rc = SMB2_ioctl_init(tcon, server,
                             &rqst, persistent_fid, volatile_fid, opcode,
-                            is_fsctl, in_data, indatalen, max_out_data_len);
+                            in_data, indatalen, max_out_data_len);
        if (rc)
                goto ioctl_exit;
 
@@ -3297,7 +3295,7 @@ SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
                        cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
 
        rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid,
-                       FSCTL_SET_COMPRESSION, true /* is_fsctl */,
+                       FSCTL_SET_COMPRESSION,
                        (char *)&fsctl_input /* data input */,
                        2 /* in data len */, CIFSMaxBufSize /* max out data */,
                        &ret_data /* out data */, NULL);
index 51c5bf4..3f740f2 100644 (file)
@@ -23,7 +23,7 @@ struct smb_rqst;
 extern int map_smb2_to_linux_error(char *buf, bool log_err);
 extern int smb2_check_message(char *buf, unsigned int length,
                              struct TCP_Server_Info *server);
-extern unsigned int smb2_calc_size(void *buf, struct TCP_Server_Info *server);
+extern unsigned int smb2_calc_size(void *buf);
 extern char *smb2_get_data_area_len(int *off, int *len,
                                    struct smb2_hdr *shdr);
 extern __le16 *cifs_convert_path_to_utf16(const char *from,
@@ -137,13 +137,13 @@ extern int SMB2_open_init(struct cifs_tcon *tcon,
 extern void SMB2_open_free(struct smb_rqst *rqst);
 extern int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon,
                     u64 persistent_fid, u64 volatile_fid, u32 opcode,
-                    bool is_fsctl, char *in_data, u32 indatalen, u32 maxoutlen,
+                    char *in_data, u32 indatalen, u32 maxoutlen,
                     char **out_data, u32 *plen /* returned data len */);
 extern int SMB2_ioctl_init(struct cifs_tcon *tcon,
                           struct TCP_Server_Info *server,
                           struct smb_rqst *rqst,
                           u64 persistent_fid, u64 volatile_fid, u32 opcode,
-                          bool is_fsctl, char *in_data, u32 indatalen,
+                          char *in_data, u32 indatalen,
                           __u32 max_response_size);
 extern void SMB2_ioctl_free(struct smb_rqst *rqst);
 extern int SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
index c5dc32a..bb0c4d0 100644 (file)
@@ -2270,6 +2270,48 @@ bool d_same_name(const struct dentry *dentry, const struct dentry *parent,
 }
 EXPORT_SYMBOL_GPL(d_same_name);
 
+/*
+ * This is __d_lookup_rcu() when the parent dentry has
+ * DCACHE_OP_COMPARE, which makes things much nastier.
+ */
+static noinline struct dentry *__d_lookup_rcu_op_compare(
+       const struct dentry *parent,
+       const struct qstr *name,
+       unsigned *seqp)
+{
+       u64 hashlen = name->hash_len;
+       struct hlist_bl_head *b = d_hash(hashlen_hash(hashlen));
+       struct hlist_bl_node *node;
+       struct dentry *dentry;
+
+       hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
+               int tlen;
+               const char *tname;
+               unsigned seq;
+
+seqretry:
+               seq = raw_seqcount_begin(&dentry->d_seq);
+               if (dentry->d_parent != parent)
+                       continue;
+               if (d_unhashed(dentry))
+                       continue;
+               if (dentry->d_name.hash != hashlen_hash(hashlen))
+                       continue;
+               tlen = dentry->d_name.len;
+               tname = dentry->d_name.name;
+               /* we want a consistent (name,len) pair */
+               if (read_seqcount_retry(&dentry->d_seq, seq)) {
+                       cpu_relax();
+                       goto seqretry;
+               }
+               if (parent->d_op->d_compare(dentry, tlen, tname, name) != 0)
+                       continue;
+               *seqp = seq;
+               return dentry;
+       }
+       return NULL;
+}
+
 /**
  * __d_lookup_rcu - search for a dentry (racy, store-free)
  * @parent: parent dentry
@@ -2316,6 +2358,9 @@ struct dentry *__d_lookup_rcu(const struct dentry *parent,
         * Keep the two functions in sync.
         */
 
+       if (unlikely(parent->d_flags & DCACHE_OP_COMPARE))
+               return __d_lookup_rcu_op_compare(parent, name, seqp);
+
        /*
         * The hash list is protected using RCU.
         *
@@ -2332,7 +2377,6 @@ struct dentry *__d_lookup_rcu(const struct dentry *parent,
        hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
                unsigned seq;
 
-seqretry:
                /*
                 * The dentry sequence count protects us from concurrent
                 * renames, and thus protects parent and name fields.
@@ -2355,28 +2399,10 @@ seqretry:
                        continue;
                if (d_unhashed(dentry))
                        continue;
-
-               if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) {
-                       int tlen;
-                       const char *tname;
-                       if (dentry->d_name.hash != hashlen_hash(hashlen))
-                               continue;
-                       tlen = dentry->d_name.len;
-                       tname = dentry->d_name.name;
-                       /* we want a consistent (name,len) pair */
-                       if (read_seqcount_retry(&dentry->d_seq, seq)) {
-                               cpu_relax();
-                               goto seqretry;
-                       }
-                       if (parent->d_op->d_compare(dentry,
-                                                   tlen, tname, name) != 0)
-                               continue;
-               } else {
-                       if (dentry->d_name.hash_len != hashlen)
-                               continue;
-                       if (dentry_cmp(dentry, str, hashlen_len(hashlen)) != 0)
-                               continue;
-               }
+               if (dentry->d_name.hash_len != hashlen)
+                       continue;
+               if (dentry_cmp(dentry, str, hashlen_len(hashlen)) != 0)
+                       continue;
                *seqp = seq;
                return dentry;
        }
index f793221..9a5ca7b 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -584,11 +584,11 @@ static int copy_strings(int argc, struct user_arg_ptr argv,
 
                                if (kmapped_page) {
                                        flush_dcache_page(kmapped_page);
-                                       kunmap(kmapped_page);
+                                       kunmap_local(kaddr);
                                        put_arg_page(kmapped_page);
                                }
                                kmapped_page = page;
-                               kaddr = kmap(kmapped_page);
+                               kaddr = kmap_local_page(kmapped_page);
                                kpos = pos & PAGE_MASK;
                                flush_arg_page(bprm, kpos, kmapped_page);
                        }
@@ -602,7 +602,7 @@ static int copy_strings(int argc, struct user_arg_ptr argv,
 out:
        if (kmapped_page) {
                flush_dcache_page(kmapped_page);
-               kunmap(kmapped_page);
+               kunmap_local(kaddr);
                put_arg_page(kmapped_page);
        }
        return ret;
@@ -880,11 +880,11 @@ int transfer_args_to_stack(struct linux_binprm *bprm,
 
        for (index = MAX_ARG_PAGES - 1; index >= stop; index--) {
                unsigned int offset = index == stop ? bprm->p & ~PAGE_MASK : 0;
-               char *src = kmap(bprm->page[index]) + offset;
+               char *src = kmap_local_page(bprm->page[index]) + offset;
                sp -= PAGE_SIZE - offset;
                if (copy_to_user((void *) sp, src, PAGE_SIZE - offset) != 0)
                        ret = -EFAULT;
-               kunmap(bprm->page[index]);
+               kunmap_local(src);
                if (ret)
                        goto out;
        }
@@ -1686,13 +1686,13 @@ int remove_arg_zero(struct linux_binprm *bprm)
                        ret = -EFAULT;
                        goto out;
                }
-               kaddr = kmap_atomic(page);
+               kaddr = kmap_local_page(page);
 
                for (; offset < PAGE_SIZE && kaddr[offset];
                                offset++, bprm->p++)
                        ;
 
-               kunmap_atomic(kaddr);
+               kunmap_local(kaddr);
                put_arg_page(page);
        } while (offset == PAGE_SIZE);
 
index 52aa0ad..e0cbcfa 100644 (file)
@@ -349,6 +349,7 @@ enum KSMBD_TREE_CONN_STATUS {
 #define KSMBD_SHARE_FLAG_STREAMS               BIT(11)
 #define KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS       BIT(12)
 #define KSMBD_SHARE_FLAG_ACL_XATTR             BIT(13)
+#define KSMBD_SHARE_FLAG_UPDATE                BIT(14)
 
 /*
  * Tree connect request flags.
@@ -364,6 +365,7 @@ enum KSMBD_TREE_CONN_STATUS {
 #define KSMBD_TREE_CONN_FLAG_READ_ONLY         BIT(1)
 #define KSMBD_TREE_CONN_FLAG_WRITABLE          BIT(2)
 #define KSMBD_TREE_CONN_FLAG_ADMIN_ACCOUNT     BIT(3)
+#define KSMBD_TREE_CONN_FLAG_UPDATE            BIT(4)
 
 /*
  * RPC over IPC.
index 70655af..c9bca1c 100644 (file)
@@ -51,12 +51,16 @@ static void kill_share(struct ksmbd_share_config *share)
        kfree(share);
 }
 
-void __ksmbd_share_config_put(struct ksmbd_share_config *share)
+void ksmbd_share_config_del(struct ksmbd_share_config *share)
 {
        down_write(&shares_table_lock);
        hash_del(&share->hlist);
        up_write(&shares_table_lock);
+}
 
+void __ksmbd_share_config_put(struct ksmbd_share_config *share)
+{
+       ksmbd_share_config_del(share);
        kill_share(share);
 }
 
index 28bf351..902f2cb 100644 (file)
@@ -64,6 +64,7 @@ static inline int test_share_config_flag(struct ksmbd_share_config *share,
        return share->flags & flag;
 }
 
+void ksmbd_share_config_del(struct ksmbd_share_config *share);
 void __ksmbd_share_config_put(struct ksmbd_share_config *share);
 
 static inline void ksmbd_share_config_put(struct ksmbd_share_config *share)
index b35ea6a..97ab798 100644 (file)
@@ -19,7 +19,7 @@ struct ksmbd_tree_conn_status
 ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess,
                        char *share_name)
 {
-       struct ksmbd_tree_conn_status status = {-EINVAL, NULL};
+       struct ksmbd_tree_conn_status status = {-ENOENT, NULL};
        struct ksmbd_tree_connect_response *resp = NULL;
        struct ksmbd_share_config *sc;
        struct ksmbd_tree_connect *tree_conn = NULL;
@@ -57,6 +57,20 @@ ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess,
                goto out_error;
 
        tree_conn->flags = resp->connection_flags;
+       if (test_tree_conn_flag(tree_conn, KSMBD_TREE_CONN_FLAG_UPDATE)) {
+               struct ksmbd_share_config *new_sc;
+
+               ksmbd_share_config_del(sc);
+               new_sc = ksmbd_share_config_get(share_name);
+               if (!new_sc) {
+                       pr_err("Failed to update stale share config\n");
+                       status.ret = -ESTALE;
+                       goto out_error;
+               }
+               ksmbd_share_config_put(sc);
+               sc = new_sc;
+       }
+
        tree_conn->user = sess->user;
        tree_conn->share_conf = sc;
        status.tree_conn = tree_conn;
index 9751cc9..19412ac 100644 (file)
@@ -1944,8 +1944,10 @@ out_err1:
                rsp->hdr.Status = STATUS_SUCCESS;
                rc = 0;
                break;
+       case -ESTALE:
+       case -ENOENT:
        case KSMBD_TREE_CONN_STATUS_NO_SHARE:
-               rsp->hdr.Status = STATUS_BAD_NETWORK_PATH;
+               rsp->hdr.Status = STATUS_BAD_NETWORK_NAME;
                break;
        case -ENOMEM:
        case KSMBD_TREE_CONN_STATUS_NOMEM:
@@ -2328,15 +2330,15 @@ static int smb2_remove_smb_xattrs(struct path *path)
                        name += strlen(name) + 1) {
                ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name));
 
-               if (strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
-                   strncmp(&name[XATTR_USER_PREFIX_LEN], DOS_ATTRIBUTE_PREFIX,
-                           DOS_ATTRIBUTE_PREFIX_LEN) &&
-                   strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX, STREAM_PREFIX_LEN))
-                       continue;
-
-               err = ksmbd_vfs_remove_xattr(user_ns, path->dentry, name);
-               if (err)
-                       ksmbd_debug(SMB, "remove xattr failed : %s\n", name);
+               if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
+                   !strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX,
+                            STREAM_PREFIX_LEN)) {
+                       err = ksmbd_vfs_remove_xattr(user_ns, path->dentry,
+                                                    name);
+                       if (err)
+                               ksmbd_debug(SMB, "remove xattr failed : %s\n",
+                                           name);
+               }
        }
 out:
        kvfree(xattr_list);
@@ -3042,12 +3044,6 @@ int smb2_open(struct ksmbd_work *work)
        list_add(&fp->node, &fp->f_ci->m_fp_list);
        write_unlock(&fp->f_ci->m_lock);
 
-       rc = ksmbd_vfs_getattr(&path, &stat);
-       if (rc) {
-               generic_fillattr(user_ns, d_inode(path.dentry), &stat);
-               rc = 0;
-       }
-
        /* Check delete pending among previous fp before oplock break */
        if (ksmbd_inode_pending_delete(fp)) {
                rc = -EBUSY;
@@ -3134,6 +3130,10 @@ int smb2_open(struct ksmbd_work *work)
                }
        }
 
+       rc = ksmbd_vfs_getattr(&path, &stat);
+       if (rc)
+               goto err_out;
+
        if (stat.result_mask & STATX_BTIME)
                fp->create_time = ksmbd_UnixTimeToNT(stat.btime);
        else
@@ -3149,9 +3149,6 @@ int smb2_open(struct ksmbd_work *work)
 
        memcpy(fp->client_guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);
 
-       generic_fillattr(user_ns, file_inode(fp->filp),
-                        &stat);
-
        rsp->StructureSize = cpu_to_le16(89);
        rcu_read_lock();
        opinfo = rcu_dereference(fp->f_opinfo);
index e8c00dd..71f870d 100644 (file)
@@ -84,8 +84,8 @@ static inline bool attr_must_be_resident(struct ntfs_sb_info *sbi,
 /*
  * attr_load_runs - Load all runs stored in @attr.
  */
-int attr_load_runs(struct ATTRIB *attr, struct ntfs_inode *ni,
-                  struct runs_tree *run, const CLST *vcn)
+static int attr_load_runs(struct ATTRIB *attr, struct ntfs_inode *ni,
+                         struct runs_tree *run, const CLST *vcn)
 {
        int err;
        CLST svcn = le64_to_cpu(attr->nres.svcn);
@@ -140,7 +140,10 @@ failed:
                }
 
                if (lcn != SPARSE_LCN) {
-                       mark_as_free_ex(sbi, lcn, clen, trim);
+                       if (sbi) {
+                               /* mark bitmap range [lcn + clen) as free and trim clusters. */
+                               mark_as_free_ex(sbi, lcn, clen, trim);
+                       }
                        dn += clen;
                }
 
@@ -173,7 +176,6 @@ int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run,
 {
        int err;
        CLST flen, vcn0 = vcn, pre = pre_alloc ? *pre_alloc : 0;
-       struct wnd_bitmap *wnd = &sbi->used.bitmap;
        size_t cnt = run->count;
 
        for (;;) {
@@ -196,9 +198,7 @@ int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run,
                /* Add new fragment into run storage. */
                if (!run_add_entry(run, vcn, lcn, flen, opt == ALLOCATE_MFT)) {
                        /* Undo last 'ntfs_look_for_free_space' */
-                       down_write_nested(&wnd->rw_lock, BITMAP_MUTEX_CLUSTERS);
-                       wnd_set_free(wnd, lcn, flen);
-                       up_write(&wnd->rw_lock);
+                       mark_as_free_ex(sbi, lcn, len, false);
                        err = -ENOMEM;
                        goto out;
                }
@@ -320,7 +320,7 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
 
        err = ni_insert_nonresident(ni, attr_s->type, attr_name(attr_s),
                                    attr_s->name_len, run, 0, alen,
-                                   attr_s->flags, &attr, NULL);
+                                   attr_s->flags, &attr, NULL, NULL);
        if (err)
                goto out3;
 
@@ -419,40 +419,44 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
        struct mft_inode *mi, *mi_b;
        CLST alen, vcn, lcn, new_alen, old_alen, svcn, evcn;
        CLST next_svcn, pre_alloc = -1, done = 0;
-       bool is_ext;
+       bool is_ext, is_bad = false;
        u32 align;
        struct MFT_REC *rec;
 
 again:
+       alen = 0;
        le_b = NULL;
        attr_b = ni_find_attr(ni, NULL, &le_b, type, name, name_len, NULL,
                              &mi_b);
        if (!attr_b) {
                err = -ENOENT;
-               goto out;
+               goto bad_inode;
        }
 
        if (!attr_b->non_res) {
                err = attr_set_size_res(ni, attr_b, le_b, mi_b, new_size, run,
                                        &attr_b);
-               if (err || !attr_b->non_res)
-                       goto out;
+               if (err)
+                       return err;
+
+               /* Return if file is still resident. */
+               if (!attr_b->non_res)
+                       goto ok1;
 
                /* Layout of records may be changed, so do a full search. */
                goto again;
        }
 
        is_ext = is_attr_ext(attr_b);
-
-again_1:
        align = sbi->cluster_size;
-
        if (is_ext)
                align <<= attr_b->nres.c_unit;
 
        old_valid = le64_to_cpu(attr_b->nres.valid_size);
        old_size = le64_to_cpu(attr_b->nres.data_size);
        old_alloc = le64_to_cpu(attr_b->nres.alloc_size);
+
+again_1:
        old_alen = old_alloc >> cluster_bits;
 
        new_alloc = (new_size + align - 1) & ~(u64)(align - 1);
@@ -475,24 +479,27 @@ again_1:
                mi = mi_b;
        } else if (!le_b) {
                err = -EINVAL;
-               goto out;
+               goto bad_inode;
        } else {
                le = le_b;
                attr = ni_find_attr(ni, attr_b, &le, type, name, name_len, &vcn,
                                    &mi);
                if (!attr) {
                        err = -EINVAL;
-                       goto out;
+                       goto bad_inode;
                }
 
 next_le_1:
                svcn = le64_to_cpu(attr->nres.svcn);
                evcn = le64_to_cpu(attr->nres.evcn);
        }
-
+       /*
+        * Here we have:
+        * attr,mi,le - last attribute segment (containing 'vcn').
+        * attr_b,mi_b,le_b - base (primary) attribute segment.
+        */
 next_le:
        rec = mi->mrec;
-
        err = attr_load_runs(attr, ni, run, NULL);
        if (err)
                goto out;
@@ -507,6 +514,13 @@ next_le:
                        goto ok;
                }
 
+               /*
+                * Add clusters. In simple case we have to:
+                *  - allocate space (vcn, lcn, len)
+                *  - update packed run in 'mi'
+                *  - update attr->nres.evcn
+                *  - update attr_b->nres.data_size/attr_b->nres.alloc_size
+                */
                to_allocate = new_alen - old_alen;
 add_alloc_in_same_attr_seg:
                lcn = 0;
@@ -520,9 +534,11 @@ add_alloc_in_same_attr_seg:
                        pre_alloc = 0;
                        if (type == ATTR_DATA && !name_len &&
                            sbi->options->prealloc) {
-                               CLST new_alen2 = bytes_to_cluster(
-                                       sbi, get_pre_allocated(new_size));
-                               pre_alloc = new_alen2 - new_alen;
+                               pre_alloc =
+                                       bytes_to_cluster(
+                                               sbi,
+                                               get_pre_allocated(new_size)) -
+                                       new_alen;
                        }
 
                        /* Get the last LCN to allocate from. */
@@ -580,7 +596,7 @@ add_alloc_in_same_attr_seg:
 pack_runs:
                err = mi_pack_runs(mi, attr, run, vcn - svcn);
                if (err)
-                       goto out;
+                       goto undo_1;
 
                next_svcn = le64_to_cpu(attr->nres.evcn) + 1;
                new_alloc_tmp = (u64)next_svcn << cluster_bits;
@@ -614,7 +630,7 @@ pack_runs:
                if (type == ATTR_LIST) {
                        err = ni_expand_list(ni);
                        if (err)
-                               goto out;
+                               goto undo_2;
                        if (next_svcn < vcn)
                                goto pack_runs;
 
@@ -624,8 +640,9 @@ pack_runs:
 
                if (!ni->attr_list.size) {
                        err = ni_create_attr_list(ni);
+                       /* In case of error layout of records is not changed. */
                        if (err)
-                               goto out;
+                               goto undo_2;
                        /* Layout of records is changed. */
                }
 
@@ -637,48 +654,57 @@ pack_runs:
                /* Insert new attribute segment. */
                err = ni_insert_nonresident(ni, type, name, name_len, run,
                                            next_svcn, vcn - next_svcn,
-                                           attr_b->flags, &attr, &mi);
-               if (err)
-                       goto out;
-
-               if (!is_mft)
-                       run_truncate_head(run, evcn + 1);
-
-               svcn = le64_to_cpu(attr->nres.svcn);
-               evcn = le64_to_cpu(attr->nres.evcn);
+                                           attr_b->flags, &attr, &mi, NULL);
 
-               le_b = NULL;
                /*
                 * Layout of records maybe changed.
                 * Find base attribute to update.
                 */
+               le_b = NULL;
                attr_b = ni_find_attr(ni, NULL, &le_b, type, name, name_len,
                                      NULL, &mi_b);
                if (!attr_b) {
-                       err = -ENOENT;
-                       goto out;
+                       err = -EINVAL;
+                       goto bad_inode;
                }
 
-               attr_b->nres.alloc_size = cpu_to_le64((u64)vcn << cluster_bits);
-               attr_b->nres.data_size = attr_b->nres.alloc_size;
-               attr_b->nres.valid_size = attr_b->nres.alloc_size;
+               if (err) {
+                       /* ni_insert_nonresident failed. */
+                       attr = NULL;
+                       goto undo_2;
+               }
+
+               if (!is_mft)
+                       run_truncate_head(run, evcn + 1);
+
+               svcn = le64_to_cpu(attr->nres.svcn);
+               evcn = le64_to_cpu(attr->nres.evcn);
+
+               /*
+                * Attribute is in consistency state.
+                * Save this point to restore to if next steps fail.
+                */
+               old_valid = old_size = old_alloc = (u64)vcn << cluster_bits;
+               attr_b->nres.valid_size = attr_b->nres.data_size =
+                       attr_b->nres.alloc_size = cpu_to_le64(old_size);
                mi_b->dirty = true;
                goto again_1;
        }
 
        if (new_size != old_size ||
            (new_alloc != old_alloc && !keep_prealloc)) {
+               /*
+                * Truncate clusters. In simple case we have to:
+                *  - update packed run in 'mi'
+                *  - update attr->nres.evcn
+                *  - update attr_b->nres.data_size/attr_b->nres.alloc_size
+                *  - mark and trim clusters as free (vcn, lcn, len)
+                */
+               CLST dlen = 0;
+
                vcn = max(svcn, new_alen);
                new_alloc_tmp = (u64)vcn << cluster_bits;
 
-               alen = 0;
-               err = run_deallocate_ex(sbi, run, vcn, evcn - vcn + 1, &alen,
-                                       true);
-               if (err)
-                       goto out;
-
-               run_truncate(run, vcn);
-
                if (vcn > svcn) {
                        err = mi_pack_runs(mi, attr, run, vcn - svcn);
                        if (err)
@@ -697,7 +723,7 @@ pack_runs:
 
                        if (!al_remove_le(ni, le)) {
                                err = -EINVAL;
-                               goto out;
+                               goto bad_inode;
                        }
 
                        le = (struct ATTR_LIST_ENTRY *)((u8 *)le - le_sz);
@@ -723,12 +749,20 @@ pack_runs:
                                attr_b->nres.valid_size =
                                        attr_b->nres.alloc_size;
                }
+               mi_b->dirty = true;
 
-               if (is_ext)
+               err = run_deallocate_ex(sbi, run, vcn, evcn - vcn + 1, &dlen,
+                                       true);
+               if (err)
+                       goto out;
+
+               if (is_ext) {
+                       /* dlen - really deallocated clusters. */
                        le64_sub_cpu(&attr_b->nres.total_size,
-                                    ((u64)alen << cluster_bits));
+                                    ((u64)dlen << cluster_bits));
+               }
 
-               mi_b->dirty = true;
+               run_truncate(run, vcn);
 
                if (new_alloc_tmp <= new_alloc)
                        goto ok;
@@ -747,7 +781,7 @@ pack_runs:
                if (le->type != type || le->name_len != name_len ||
                    memcmp(le_name(le), name, name_len * sizeof(short))) {
                        err = -EINVAL;
-                       goto out;
+                       goto bad_inode;
                }
 
                err = ni_load_mi(ni, le, &mi);
@@ -757,7 +791,7 @@ pack_runs:
                attr = mi_find_attr(mi, NULL, type, name, name_len, &le->id);
                if (!attr) {
                        err = -EINVAL;
-                       goto out;
+                       goto bad_inode;
                }
                goto next_le_1;
        }
@@ -772,13 +806,13 @@ ok:
                }
        }
 
-out:
-       if (!err && attr_b && ret)
+ok1:
+       if (ret)
                *ret = attr_b;
 
        /* Update inode_set_bytes. */
-       if (!err && ((type == ATTR_DATA && !name_len) ||
-                    (type == ATTR_ALLOC && name == I30_NAME))) {
+       if (((type == ATTR_DATA && !name_len) ||
+            (type == ATTR_ALLOC && name == I30_NAME))) {
                bool dirty = false;
 
                if (ni->vfs_inode.i_size != new_size) {
@@ -786,7 +820,7 @@ out:
                        dirty = true;
                }
 
-               if (attr_b && attr_b->non_res) {
+               if (attr_b->non_res) {
                        new_alloc = le64_to_cpu(attr_b->nres.alloc_size);
                        if (inode_get_bytes(&ni->vfs_inode) != new_alloc) {
                                inode_set_bytes(&ni->vfs_inode, new_alloc);
@@ -800,6 +834,47 @@ out:
                }
        }
 
+       return 0;
+
+undo_2:
+       vcn -= alen;
+       attr_b->nres.data_size = cpu_to_le64(old_size);
+       attr_b->nres.valid_size = cpu_to_le64(old_valid);
+       attr_b->nres.alloc_size = cpu_to_le64(old_alloc);
+
+       /* Restore 'attr' and 'mi'. */
+       if (attr)
+               goto restore_run;
+
+       if (le64_to_cpu(attr_b->nres.svcn) <= svcn &&
+           svcn <= le64_to_cpu(attr_b->nres.evcn)) {
+               attr = attr_b;
+               le = le_b;
+               mi = mi_b;
+       } else if (!le_b) {
+               err = -EINVAL;
+               goto bad_inode;
+       } else {
+               le = le_b;
+               attr = ni_find_attr(ni, attr_b, &le, type, name, name_len,
+                                   &svcn, &mi);
+               if (!attr)
+                       goto bad_inode;
+       }
+
+restore_run:
+       if (mi_pack_runs(mi, attr, run, evcn - svcn + 1))
+               is_bad = true;
+
+undo_1:
+       run_deallocate_ex(sbi, run, vcn, alen, NULL, false);
+
+       run_truncate(run, vcn);
+out:
+       if (is_bad) {
+bad_inode:
+               _ntfs_bad_inode(&ni->vfs_inode);
+       }
        return err;
 }
 
@@ -855,7 +930,7 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
                goto out;
        }
 
-       asize = le64_to_cpu(attr_b->nres.alloc_size) >> sbi->cluster_bits;
+       asize = le64_to_cpu(attr_b->nres.alloc_size) >> cluster_bits;
        if (vcn >= asize) {
                err = -EINVAL;
                goto out;
@@ -1047,7 +1122,7 @@ ins_ext:
        if (evcn1 > next_svcn) {
                err = ni_insert_nonresident(ni, ATTR_DATA, NULL, 0, run,
                                            next_svcn, evcn1 - next_svcn,
-                                           attr_b->flags, &attr, &mi);
+                                           attr_b->flags, &attr, &mi, NULL);
                if (err)
                        goto out;
        }
@@ -1173,7 +1248,7 @@ int attr_load_runs_range(struct ntfs_inode *ni, enum ATTR_TYPE type,
 {
        struct ntfs_sb_info *sbi = ni->mi.sbi;
        u8 cluster_bits = sbi->cluster_bits;
-       CLST vcn = from >> cluster_bits;
+       CLST vcn;
        CLST vcn_last = (to - 1) >> cluster_bits;
        CLST lcn, clen;
        int err;
@@ -1647,7 +1722,7 @@ ins_ext:
        if (evcn1 > next_svcn) {
                err = ni_insert_nonresident(ni, ATTR_DATA, NULL, 0, run,
                                            next_svcn, evcn1 - next_svcn,
-                                           attr_b->flags, &attr, &mi);
+                                           attr_b->flags, &attr, &mi, NULL);
                if (err)
                        goto out;
        }
@@ -1812,18 +1887,12 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
                                err = ni_insert_nonresident(
                                        ni, ATTR_DATA, NULL, 0, run, next_svcn,
                                        evcn1 - eat - next_svcn, a_flags, &attr,
-                                       &mi);
+                                       &mi, &le);
                                if (err)
                                        goto out;
 
                                /* Layout of records maybe changed. */
                                attr_b = NULL;
-                               le = al_find_ex(ni, NULL, ATTR_DATA, NULL, 0,
-                                               &next_svcn);
-                               if (!le) {
-                                       err = -EINVAL;
-                                       goto out;
-                               }
                        }
 
                        /* Free all allocated memory. */
@@ -1918,7 +1987,7 @@ next_attr:
 out:
        up_write(&ni->file.run_lock);
        if (err)
-               make_bad_inode(&ni->vfs_inode);
+               _ntfs_bad_inode(&ni->vfs_inode);
 
        return err;
 }
@@ -1936,9 +2005,11 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
        struct ATTRIB *attr = NULL, *attr_b;
        struct ATTR_LIST_ENTRY *le, *le_b;
        struct mft_inode *mi, *mi_b;
-       CLST svcn, evcn1, vcn, len, end, alen, dealloc;
+       CLST svcn, evcn1, vcn, len, end, alen, hole, next_svcn;
        u64 total_size, alloc_size;
        u32 mask;
+       __le16 a_flags;
+       struct runs_tree run2;
 
        if (!bytes)
                return 0;
@@ -1990,6 +2061,9 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
        }
 
        down_write(&ni->file.run_lock);
+       run_init(&run2);
+       run_truncate(run, 0);
+
        /*
         * Enumerate all attribute segments and punch hole where necessary.
         */
@@ -1997,10 +2071,11 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
        vcn = vbo >> sbi->cluster_bits;
        len = bytes >> sbi->cluster_bits;
        end = vcn + len;
-       dealloc = 0;
+       hole = 0;
 
        svcn = le64_to_cpu(attr_b->nres.svcn);
        evcn1 = le64_to_cpu(attr_b->nres.evcn) + 1;
+       a_flags = attr_b->flags;
 
        if (svcn <= vcn && vcn < evcn1) {
                attr = attr_b;
@@ -2008,14 +2083,14 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
                mi = mi_b;
        } else if (!le_b) {
                err = -EINVAL;
-               goto out;
+               goto bad_inode;
        } else {
                le = le_b;
                attr = ni_find_attr(ni, attr_b, &le, ATTR_DATA, NULL, 0, &vcn,
                                    &mi);
                if (!attr) {
                        err = -EINVAL;
-                       goto out;
+                       goto bad_inode;
                }
 
                svcn = le64_to_cpu(attr->nres.svcn);
@@ -2023,49 +2098,91 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
        }
 
        while (svcn < end) {
-               CLST vcn1, zero, dealloc2;
+               CLST vcn1, zero, hole2 = hole;
 
                err = attr_load_runs(attr, ni, run, &svcn);
                if (err)
-                       goto out;
+                       goto done;
                vcn1 = max(vcn, svcn);
                zero = min(end, evcn1) - vcn1;
 
-               dealloc2 = dealloc;
-               err = run_deallocate_ex(sbi, run, vcn1, zero, &dealloc, true);
+               /*
+                * Check range [vcn1 + zero).
+                * Calculate how many clusters there are.
+                * Don't do any destructive actions.
+                */
+               err = run_deallocate_ex(NULL, run, vcn1, zero, &hole2, false);
                if (err)
-                       goto out;
+                       goto done;
 
-               if (dealloc2 == dealloc) {
-                       /* Looks like the required range is already sparsed. */
-               } else {
-                       if (!run_add_entry(run, vcn1, SPARSE_LCN, zero,
-                                          false)) {
-                               err = -ENOMEM;
-                               goto out;
-                       }
+               /* Check if required range is already hole. */
+               if (hole2 == hole)
+                       goto next_attr;
+
+               /* Make a clone of run to undo. */
+               err = run_clone(run, &run2);
+               if (err)
+                       goto done;
+
+               /* Make a hole range (sparse) [vcn1 + zero). */
+               if (!run_add_entry(run, vcn1, SPARSE_LCN, zero, false)) {
+                       err = -ENOMEM;
+                       goto done;
+               }
 
-                       err = mi_pack_runs(mi, attr, run, evcn1 - svcn);
+               /* Update run in attribute segment. */
+               err = mi_pack_runs(mi, attr, run, evcn1 - svcn);
+               if (err)
+                       goto done;
+               next_svcn = le64_to_cpu(attr->nres.evcn) + 1;
+               if (next_svcn < evcn1) {
+                       /* Insert new attribute segment. */
+                       err = ni_insert_nonresident(ni, ATTR_DATA, NULL, 0, run,
+                                                   next_svcn,
+                                                   evcn1 - next_svcn, a_flags,
+                                                   &attr, &mi, &le);
                        if (err)
-                               goto out;
+                               goto undo_punch;
+
+                       /* Layout of records maybe changed. */
+                       attr_b = NULL;
                }
+
+               /* Real deallocate. Should not fail. */
+               run_deallocate_ex(sbi, &run2, vcn1, zero, &hole, true);
+
+next_attr:
                /* Free all allocated memory. */
                run_truncate(run, 0);
 
                if (evcn1 >= alen)
                        break;
 
+               /* Get next attribute segment. */
                attr = ni_enum_attr_ex(ni, attr, &le, &mi);
                if (!attr) {
                        err = -EINVAL;
-                       goto out;
+                       goto bad_inode;
                }
 
                svcn = le64_to_cpu(attr->nres.svcn);
                evcn1 = le64_to_cpu(attr->nres.evcn) + 1;
        }
 
-       total_size -= (u64)dealloc << sbi->cluster_bits;
+done:
+       if (!hole)
+               goto out;
+
+       if (!attr_b) {
+               attr_b = ni_find_attr(ni, NULL, NULL, ATTR_DATA, NULL, 0, NULL,
+                                     &mi_b);
+               if (!attr_b) {
+                       err = -EINVAL;
+                       goto bad_inode;
+               }
+       }
+
+       total_size -= (u64)hole << sbi->cluster_bits;
        attr_b->nres.total_size = cpu_to_le64(total_size);
        mi_b->dirty = true;
 
@@ -2075,9 +2192,263 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
        mark_inode_dirty(&ni->vfs_inode);
 
 out:
+       run_close(&run2);
        up_write(&ni->file.run_lock);
+       return err;
+
+bad_inode:
+       _ntfs_bad_inode(&ni->vfs_inode);
+       goto out;
+
+undo_punch:
+       /*
+        * Restore packed runs.
+        * 'mi_pack_runs' should not fail, cause we restore original.
+        */
+       if (mi_pack_runs(mi, attr, &run2, evcn1 - svcn))
+               goto bad_inode;
+
+       goto done;
+}
+
+/*
+ * attr_insert_range - Insert range (hole) in file.
+ * Not for normal files.
+ */
+int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
+{
+       int err = 0;
+       struct runs_tree *run = &ni->file.run;
+       struct ntfs_sb_info *sbi = ni->mi.sbi;
+       struct ATTRIB *attr = NULL, *attr_b;
+       struct ATTR_LIST_ENTRY *le, *le_b;
+       struct mft_inode *mi, *mi_b;
+       CLST vcn, svcn, evcn1, len, next_svcn;
+       u64 data_size, alloc_size;
+       u32 mask;
+       __le16 a_flags;
+
+       if (!bytes)
+               return 0;
+
+       le_b = NULL;
+       attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL, 0, NULL, &mi_b);
+       if (!attr_b)
+               return -ENOENT;
+
+       if (!is_attr_ext(attr_b)) {
+               /* It was checked above. See fallocate. */
+               return -EOPNOTSUPP;
+       }
+
+       if (!attr_b->non_res) {
+               data_size = le32_to_cpu(attr_b->res.data_size);
+               alloc_size = data_size;
+               mask = sbi->cluster_mask; /* cluster_size - 1 */
+       } else {
+               data_size = le64_to_cpu(attr_b->nres.data_size);
+               alloc_size = le64_to_cpu(attr_b->nres.alloc_size);
+               mask = (sbi->cluster_size << attr_b->nres.c_unit) - 1;
+       }
+
+       if (vbo > data_size) {
+               /* Insert range after the file size is not allowed. */
+               return -EINVAL;
+       }
+
+       if ((vbo & mask) || (bytes & mask)) {
+               /* Allow to insert only frame aligned ranges. */
+               return -EINVAL;
+       }
+
+       /*
+        * valid_size <= data_size <= alloc_size
+        * Check alloc_size for maximum possible.
+        */
+       if (bytes > sbi->maxbytes_sparse - alloc_size)
+               return -EFBIG;
+
+       vcn = vbo >> sbi->cluster_bits;
+       len = bytes >> sbi->cluster_bits;
+
+       down_write(&ni->file.run_lock);
+
+       if (!attr_b->non_res) {
+               err = attr_set_size(ni, ATTR_DATA, NULL, 0, run,
+                                   data_size + bytes, NULL, false, NULL);
+
+               le_b = NULL;
+               attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL, 0, NULL,
+                                     &mi_b);
+               if (!attr_b) {
+                       err = -EINVAL;
+                       goto bad_inode;
+               }
+
+               if (err)
+                       goto out;
+
+               if (!attr_b->non_res) {
+                       /* Still resident. */
+                       char *data = Add2Ptr(attr_b, attr_b->res.data_off);
+
+                       memmove(data + bytes, data, bytes);
+                       memset(data, 0, bytes);
+                       goto done;
+               }
+
+               /* Resident files becomes nonresident. */
+               data_size = le64_to_cpu(attr_b->nres.data_size);
+               alloc_size = le64_to_cpu(attr_b->nres.alloc_size);
+       }
+
+       /*
+        * Enumerate all attribute segments and shift start vcn.
+        */
+       a_flags = attr_b->flags;
+       svcn = le64_to_cpu(attr_b->nres.svcn);
+       evcn1 = le64_to_cpu(attr_b->nres.evcn) + 1;
+
+       if (svcn <= vcn && vcn < evcn1) {
+               attr = attr_b;
+               le = le_b;
+               mi = mi_b;
+       } else if (!le_b) {
+               err = -EINVAL;
+               goto bad_inode;
+       } else {
+               le = le_b;
+               attr = ni_find_attr(ni, attr_b, &le, ATTR_DATA, NULL, 0, &vcn,
+                                   &mi);
+               if (!attr) {
+                       err = -EINVAL;
+                       goto bad_inode;
+               }
+
+               svcn = le64_to_cpu(attr->nres.svcn);
+               evcn1 = le64_to_cpu(attr->nres.evcn) + 1;
+       }
+
+       run_truncate(run, 0); /* clear cached values. */
+       err = attr_load_runs(attr, ni, run, NULL);
+       if (err)
+               goto out;
+
+       if (!run_insert_range(run, vcn, len)) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       /* Try to pack in current record as much as possible. */
+       err = mi_pack_runs(mi, attr, run, evcn1 + len - svcn);
        if (err)
-               make_bad_inode(&ni->vfs_inode);
+               goto out;
+
+       next_svcn = le64_to_cpu(attr->nres.evcn) + 1;
+
+       while ((attr = ni_enum_attr_ex(ni, attr, &le, &mi)) &&
+              attr->type == ATTR_DATA && !attr->name_len) {
+               le64_add_cpu(&attr->nres.svcn, len);
+               le64_add_cpu(&attr->nres.evcn, len);
+               if (le) {
+                       le->vcn = attr->nres.svcn;
+                       ni->attr_list.dirty = true;
+               }
+               mi->dirty = true;
+       }
+
+       if (next_svcn < evcn1 + len) {
+               err = ni_insert_nonresident(ni, ATTR_DATA, NULL, 0, run,
+                                           next_svcn, evcn1 + len - next_svcn,
+                                           a_flags, NULL, NULL, NULL);
+
+               le_b = NULL;
+               attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL, 0, NULL,
+                                     &mi_b);
+               if (!attr_b) {
+                       err = -EINVAL;
+                       goto bad_inode;
+               }
+
+               if (err) {
+                       /* ni_insert_nonresident failed. Try to undo. */
+                       goto undo_insert_range;
+               }
+       }
+
+       /*
+        * Update primary attribute segment.
+        */
+       if (vbo <= ni->i_valid)
+               ni->i_valid += bytes;
+
+       attr_b->nres.data_size = le64_to_cpu(data_size + bytes);
+       attr_b->nres.alloc_size = le64_to_cpu(alloc_size + bytes);
+
+       /* ni->valid may be not equal valid_size (temporary). */
+       if (ni->i_valid > data_size + bytes)
+               attr_b->nres.valid_size = attr_b->nres.data_size;
+       else
+               attr_b->nres.valid_size = cpu_to_le64(ni->i_valid);
+       mi_b->dirty = true;
+
+done:
+       ni->vfs_inode.i_size += bytes;
+       ni->ni_flags |= NI_FLAG_UPDATE_PARENT;
+       mark_inode_dirty(&ni->vfs_inode);
+
+out:
+       run_truncate(run, 0); /* clear cached values. */
+
+       up_write(&ni->file.run_lock);
 
        return err;
+
+bad_inode:
+       _ntfs_bad_inode(&ni->vfs_inode);
+       goto out;
+
+undo_insert_range:
+       svcn = le64_to_cpu(attr_b->nres.svcn);
+       evcn1 = le64_to_cpu(attr_b->nres.evcn) + 1;
+
+       if (svcn <= vcn && vcn < evcn1) {
+               attr = attr_b;
+               le = le_b;
+               mi = mi_b;
+       } else if (!le_b) {
+               goto bad_inode;
+       } else {
+               le = le_b;
+               attr = ni_find_attr(ni, attr_b, &le, ATTR_DATA, NULL, 0, &vcn,
+                                   &mi);
+               if (!attr) {
+                       goto bad_inode;
+               }
+
+               svcn = le64_to_cpu(attr->nres.svcn);
+               evcn1 = le64_to_cpu(attr->nres.evcn) + 1;
+       }
+
+       if (attr_load_runs(attr, ni, run, NULL))
+               goto bad_inode;
+
+       if (!run_collapse_range(run, vcn, len))
+               goto bad_inode;
+
+       if (mi_pack_runs(mi, attr, run, evcn1 + len - svcn))
+               goto bad_inode;
+
+       while ((attr = ni_enum_attr_ex(ni, attr, &le, &mi)) &&
+              attr->type == ATTR_DATA && !attr->name_len) {
+               le64_sub_cpu(&attr->nres.svcn, len);
+               le64_sub_cpu(&attr->nres.evcn, len);
+               if (le) {
+                       le->vcn = attr->nres.svcn;
+                       ni->attr_list.dirty = true;
+               }
+               mi->dirty = true;
+       }
+
+       goto out;
 }
index aa18440..5d44cea 100644 (file)
@@ -51,11 +51,6 @@ void ntfs3_exit_bitmap(void)
        kmem_cache_destroy(ntfs_enode_cachep);
 }
 
-static inline u32 wnd_bits(const struct wnd_bitmap *wnd, size_t i)
-{
-       return i + 1 == wnd->nwnd ? wnd->bits_last : wnd->sb->s_blocksize * 8;
-}
-
 /*
  * wnd_scan
  *
@@ -1333,9 +1328,7 @@ int wnd_extend(struct wnd_bitmap *wnd, size_t new_bits)
                if (!new_free)
                        return -ENOMEM;
 
-               if (new_free != wnd->free_bits)
-                       memcpy(new_free, wnd->free_bits,
-                              wnd->nwnd * sizeof(short));
+               memcpy(new_free, wnd->free_bits, wnd->nwnd * sizeof(short));
                memset(new_free + wnd->nwnd, 0,
                       (new_wnd - wnd->nwnd) * sizeof(short));
                kfree(wnd->free_bits);
@@ -1395,9 +1388,8 @@ int wnd_extend(struct wnd_bitmap *wnd, size_t new_bits)
 
 void wnd_zone_set(struct wnd_bitmap *wnd, size_t lcn, size_t len)
 {
-       size_t zlen;
+       size_t zlen = wnd->zone_end - wnd->zone_bit;
 
-       zlen = wnd->zone_end - wnd->zone_bit;
        if (zlen)
                wnd_add_free_ext(wnd, wnd->zone_bit, zlen, false);
 
index 4a21745..4f2ffc7 100644 (file)
@@ -530,21 +530,35 @@ static int ntfs_truncate(struct inode *inode, loff_t new_size)
 static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)
 {
        struct inode *inode = file->f_mapping->host;
+       struct address_space *mapping = inode->i_mapping;
        struct super_block *sb = inode->i_sb;
        struct ntfs_sb_info *sbi = sb->s_fs_info;
        struct ntfs_inode *ni = ntfs_i(inode);
        loff_t end = vbo + len;
        loff_t vbo_down = round_down(vbo, PAGE_SIZE);
-       loff_t i_size;
+       bool is_supported_holes = is_sparsed(ni) || is_compressed(ni);
+       loff_t i_size, new_size;
+       bool map_locked;
        int err;
 
        /* No support for dir. */
        if (!S_ISREG(inode->i_mode))
                return -EOPNOTSUPP;
 
-       /* Return error if mode is not supported. */
-       if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
-                    FALLOC_FL_COLLAPSE_RANGE)) {
+       /*
+        * vfs_fallocate checks all possible combinations of mode.
+        * Do additional checks here before ntfs_set_state(dirty).
+        */
+       if (mode & FALLOC_FL_PUNCH_HOLE) {
+               if (!is_supported_holes)
+                       return -EOPNOTSUPP;
+       } else if (mode & FALLOC_FL_COLLAPSE_RANGE) {
+       } else if (mode & FALLOC_FL_INSERT_RANGE) {
+               if (!is_supported_holes)
+                       return -EOPNOTSUPP;
+       } else if (mode &
+                  ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
+                    FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE)) {
                ntfs_inode_warn(inode, "fallocate(0x%x) is not supported",
                                mode);
                return -EOPNOTSUPP;
@@ -554,6 +568,8 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)
 
        inode_lock(inode);
        i_size = inode->i_size;
+       new_size = max(end, i_size);
+       map_locked = false;
 
        if (WARN_ON(ni->ni_flags & NI_FLAG_COMPRESSED_MASK)) {
                /* Should never be here, see ntfs_file_open. */
@@ -561,38 +577,27 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)
                goto out;
        }
 
+       if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE |
+                   FALLOC_FL_INSERT_RANGE)) {
+               inode_dio_wait(inode);
+               filemap_invalidate_lock(mapping);
+               map_locked = true;
+       }
+
        if (mode & FALLOC_FL_PUNCH_HOLE) {
                u32 frame_size;
                loff_t mask, vbo_a, end_a, tmp;
 
-               if (!(mode & FALLOC_FL_KEEP_SIZE)) {
-                       err = -EINVAL;
-                       goto out;
-               }
-
-               err = filemap_write_and_wait_range(inode->i_mapping, vbo,
-                                                  end - 1);
+               err = filemap_write_and_wait_range(mapping, vbo, end - 1);
                if (err)
                        goto out;
 
-               err = filemap_write_and_wait_range(inode->i_mapping, end,
-                                                  LLONG_MAX);
+               err = filemap_write_and_wait_range(mapping, end, LLONG_MAX);
                if (err)
                        goto out;
 
-               inode_dio_wait(inode);
-
                truncate_pagecache(inode, vbo_down);
 
-               if (!is_sparsed(ni) && !is_compressed(ni)) {
-                       /*
-                        * Normal file, can't make hole.
-                        * TODO: Try to find way to save info about hole.
-                        */
-                       err = -EOPNOTSUPP;
-                       goto out;
-               }
-
                ni_lock(ni);
                err = attr_punch_hole(ni, vbo, len, &frame_size);
                ni_unlock(ni);
@@ -624,17 +629,11 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)
                        ni_unlock(ni);
                }
        } else if (mode & FALLOC_FL_COLLAPSE_RANGE) {
-               if (mode & ~FALLOC_FL_COLLAPSE_RANGE) {
-                       err = -EINVAL;
-                       goto out;
-               }
-
                /*
                 * Write tail of the last page before removed range since
                 * it will get removed from the page cache below.
                 */
-               err = filemap_write_and_wait_range(inode->i_mapping, vbo_down,
-                                                  vbo);
+               err = filemap_write_and_wait_range(mapping, vbo_down, vbo);
                if (err)
                        goto out;
 
@@ -642,34 +641,58 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)
                 * Write data that will be shifted to preserve them
                 * when discarding page cache below.
                 */
-               err = filemap_write_and_wait_range(inode->i_mapping, end,
-                                                  LLONG_MAX);
+               err = filemap_write_and_wait_range(mapping, end, LLONG_MAX);
                if (err)
                        goto out;
 
-               /* Wait for existing dio to complete. */
-               inode_dio_wait(inode);
-
                truncate_pagecache(inode, vbo_down);
 
                ni_lock(ni);
                err = attr_collapse_range(ni, vbo, len);
                ni_unlock(ni);
+       } else if (mode & FALLOC_FL_INSERT_RANGE) {
+               /* Check new size. */
+               err = inode_newsize_ok(inode, new_size);
+               if (err)
+                       goto out;
+
+               /* Write out all dirty pages. */
+               err = filemap_write_and_wait_range(mapping, vbo_down,
+                                                  LLONG_MAX);
+               if (err)
+                       goto out;
+               truncate_pagecache(inode, vbo_down);
+
+               ni_lock(ni);
+               err = attr_insert_range(ni, vbo, len);
+               ni_unlock(ni);
        } else {
-               /*
-                * Normal file: Allocate clusters, do not change 'valid' size.
-                */
-               loff_t new_size = max(end, i_size);
+               /* Check new size. */
+
+               /* generic/213: expected -ENOSPC instead of -EFBIG. */
+               if (!is_supported_holes) {
+                       loff_t to_alloc = new_size - inode_get_bytes(inode);
+
+                       if (to_alloc > 0 &&
+                           (to_alloc >> sbi->cluster_bits) >
+                                   wnd_zeroes(&sbi->used.bitmap)) {
+                               err = -ENOSPC;
+                               goto out;
+                       }
+               }
 
                err = inode_newsize_ok(inode, new_size);
                if (err)
                        goto out;
 
+               /*
+                * Allocate clusters, do not change 'valid' size.
+                */
                err = ntfs_set_size(inode, new_size);
                if (err)
                        goto out;
 
-               if (is_sparsed(ni) || is_compressed(ni)) {
+               if (is_supported_holes) {
                        CLST vcn_v = ni->i_valid >> sbi->cluster_bits;
                        CLST vcn = vbo >> sbi->cluster_bits;
                        CLST cend = bytes_to_cluster(sbi, end);
@@ -717,8 +740,8 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)
        }
 
 out:
-       if (err == -EFBIG)
-               err = -ENOSPC;
+       if (map_locked)
+               filemap_invalidate_unlock(mapping);
 
        if (!err) {
                inode->i_ctime = inode->i_mtime = current_time(inode);
@@ -989,7 +1012,6 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from)
                if (bytes > count)
                        bytes = count;
 
-               frame = pos >> frame_bits;
                frame_vbo = pos & ~(frame_size - 1);
                index = frame_vbo >> PAGE_SHIFT;
 
index 1884299..381a38a 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/fiemap.h>
 #include <linux/fs.h>
+#include <linux/minmax.h>
 #include <linux/vmalloc.h>
 
 #include "debug.h"
@@ -468,7 +469,7 @@ ni_ins_new_attr(struct ntfs_inode *ni, struct mft_inode *mi,
                                &ref, &le);
                if (err) {
                        /* No memory or no space. */
-                       return NULL;
+                       return ERR_PTR(err);
                }
                le_added = true;
 
@@ -649,6 +650,7 @@ static int ni_try_remove_attr_list(struct ntfs_inode *ni)
        struct mft_inode *mi;
        u32 asize, free;
        struct MFT_REF ref;
+       struct MFT_REC *mrec;
        __le16 id;
 
        if (!ni->attr_list.dirty)
@@ -692,11 +694,17 @@ static int ni_try_remove_attr_list(struct ntfs_inode *ni)
                free -= asize;
        }
 
+       /* Make a copy of primary record to restore if error. */
+       mrec = kmemdup(ni->mi.mrec, sbi->record_size, GFP_NOFS);
+       if (!mrec)
+               return 0; /* Not critical. */
+
        /* It seems that attribute list can be removed from primary record. */
        mi_remove_attr(NULL, &ni->mi, attr_list);
 
        /*
-        * Repeat the cycle above and move all attributes to primary record.
+        * Repeat the cycle above and copy all attributes to primary record.
+        * Do not remove original attributes from subrecords!
         * It should be success!
         */
        le = NULL;
@@ -707,14 +715,14 @@ static int ni_try_remove_attr_list(struct ntfs_inode *ni)
                mi = ni_find_mi(ni, ino_get(&le->ref));
                if (!mi) {
                        /* Should never happened, 'cause already checked. */
-                       goto bad;
+                       goto out;
                }
 
                attr = mi_find_attr(mi, NULL, le->type, le_name(le),
                                    le->name_len, &le->id);
                if (!attr) {
                        /* Should never happened, 'cause already checked. */
-                       goto bad;
+                       goto out;
                }
                asize = le32_to_cpu(attr->size);
 
@@ -724,18 +732,33 @@ static int ni_try_remove_attr_list(struct ntfs_inode *ni)
                                          le16_to_cpu(attr->name_off));
                if (!attr_ins) {
                        /*
-                        * Internal error.
-                        * Either no space in primary record (already checked).
-                        * Either tried to insert another
-                        * non indexed attribute (logic error).
+                        * No space in primary record (already checked).
                         */
-                       goto bad;
+                       goto out;
                }
 
                /* Copy all except id. */
                id = attr_ins->id;
                memcpy(attr_ins, attr, asize);
                attr_ins->id = id;
+       }
+
+       /*
+        * Repeat the cycle above and remove all attributes from subrecords.
+        */
+       le = NULL;
+       while ((le = al_enumerate(ni, le))) {
+               if (!memcmp(&le->ref, &ref, sizeof(ref)))
+                       continue;
+
+               mi = ni_find_mi(ni, ino_get(&le->ref));
+               if (!mi)
+                       continue;
+
+               attr = mi_find_attr(mi, NULL, le->type, le_name(le),
+                                   le->name_len, &le->id);
+               if (!attr)
+                       continue;
 
                /* Remove from original record. */
                mi_remove_attr(NULL, mi, attr);
@@ -748,11 +771,13 @@ static int ni_try_remove_attr_list(struct ntfs_inode *ni)
        ni->attr_list.le = NULL;
        ni->attr_list.dirty = false;
 
+       kfree(mrec);
+       return 0;
+out:
+       /* Restore primary record. */
+       swap(mrec, ni->mi.mrec);
+       kfree(mrec);
        return 0;
-bad:
-       ntfs_inode_err(&ni->vfs_inode, "Internal error");
-       make_bad_inode(&ni->vfs_inode);
-       return -EINVAL;
 }
 
 /*
@@ -986,6 +1011,8 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le,
                                       name_off, svcn, ins_le);
                if (!attr)
                        continue;
+               if (IS_ERR(attr))
+                       return PTR_ERR(attr);
 
                if (ins_attr)
                        *ins_attr = attr;
@@ -1007,8 +1034,15 @@ insert_ext:
 
        attr = ni_ins_new_attr(ni, mi, le, type, name, name_len, asize,
                               name_off, svcn, ins_le);
-       if (!attr)
+       if (!attr) {
+               err = -EINVAL;
                goto out2;
+       }
+
+       if (IS_ERR(attr)) {
+               err = PTR_ERR(attr);
+               goto out2;
+       }
 
        if (ins_attr)
                *ins_attr = attr;
@@ -1020,10 +1054,9 @@ insert_ext:
 out2:
        ni_remove_mi(ni, mi);
        mi_put(mi);
-       err = -EINVAL;
 
 out1:
-       ntfs_mark_rec_free(sbi, rno);
+       ntfs_mark_rec_free(sbi, rno, is_mft);
 
 out:
        return err;
@@ -1076,6 +1109,11 @@ static int ni_insert_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
        if (asize <= free) {
                attr = ni_ins_new_attr(ni, &ni->mi, NULL, type, name, name_len,
                                       asize, name_off, svcn, ins_le);
+               if (IS_ERR(attr)) {
+                       err = PTR_ERR(attr);
+                       goto out;
+               }
+
                if (attr) {
                        if (ins_attr)
                                *ins_attr = attr;
@@ -1173,6 +1211,11 @@ static int ni_insert_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
                goto out;
        }
 
+       if (IS_ERR(attr)) {
+               err = PTR_ERR(attr);
+               goto out;
+       }
+
        if (ins_attr)
                *ins_attr = attr;
        if (ins_mi)
@@ -1218,7 +1261,7 @@ static int ni_expand_mft_list(struct ntfs_inode *ni)
                mft_min = mft_new;
                mi_min = mi_new;
        } else {
-               ntfs_mark_rec_free(sbi, mft_new);
+               ntfs_mark_rec_free(sbi, mft_new, true);
                mft_new = 0;
                ni_remove_mi(ni, mi_new);
        }
@@ -1262,7 +1305,7 @@ static int ni_expand_mft_list(struct ntfs_inode *ni)
        done = asize - run_size - SIZEOF_NONRESIDENT;
        le32_sub_cpu(&ni->mi.mrec->used, done);
 
-       /* Estimate the size of second part: run_buf=NULL. */
+       /* Estimate packed size (run_buf=NULL). */
        err = run_pack(run, svcn, evcn + 1 - svcn, NULL, sbi->record_size,
                       &plen);
        if (err < 0)
@@ -1288,10 +1331,16 @@ static int ni_expand_mft_list(struct ntfs_inode *ni)
                goto out;
        }
 
+       if (IS_ERR(attr)) {
+               err = PTR_ERR(attr);
+               goto out;
+       }
+
        attr->non_res = 1;
        attr->name_off = SIZEOF_NONRESIDENT_LE;
        attr->flags = 0;
 
+       /* This function can't fail - cause already checked above. */
        run_pack(run, svcn, evcn + 1 - svcn, Add2Ptr(attr, SIZEOF_NONRESIDENT),
                 run_size, &plen);
 
@@ -1301,7 +1350,7 @@ static int ni_expand_mft_list(struct ntfs_inode *ni)
 
 out:
        if (mft_new) {
-               ntfs_mark_rec_free(sbi, mft_new);
+               ntfs_mark_rec_free(sbi, mft_new, true);
                ni_remove_mi(ni, mi_new);
        }
 
@@ -1367,8 +1416,6 @@ int ni_expand_list(struct ntfs_inode *ni)
 
        /* Split MFT data as much as possible. */
        err = ni_expand_mft_list(ni);
-       if (err)
-               goto out;
 
 out:
        return !err && !done ? -EOPNOTSUPP : err;
@@ -1381,7 +1428,7 @@ int ni_insert_nonresident(struct ntfs_inode *ni, enum ATTR_TYPE type,
                          const __le16 *name, u8 name_len,
                          const struct runs_tree *run, CLST svcn, CLST len,
                          __le16 flags, struct ATTRIB **new_attr,
-                         struct mft_inode **mi)
+                         struct mft_inode **mi, struct ATTR_LIST_ENTRY **le)
 {
        int err;
        CLST plen;
@@ -1394,6 +1441,7 @@ int ni_insert_nonresident(struct ntfs_inode *ni, enum ATTR_TYPE type,
        u32 run_size, asize;
        struct ntfs_sb_info *sbi = ni->mi.sbi;
 
+       /* Estimate packed size (run_buf=NULL). */
        err = run_pack(run, svcn, len, NULL, sbi->max_bytes_per_attr - run_off,
                       &plen);
        if (err < 0)
@@ -1414,7 +1462,7 @@ int ni_insert_nonresident(struct ntfs_inode *ni, enum ATTR_TYPE type,
        }
 
        err = ni_insert_attr(ni, type, name, name_len, asize, name_off, svcn,
-                            &attr, mi, NULL);
+                            &attr, mi, le);
 
        if (err)
                goto out;
@@ -1423,12 +1471,12 @@ int ni_insert_nonresident(struct ntfs_inode *ni, enum ATTR_TYPE type,
        attr->name_off = cpu_to_le16(name_off);
        attr->flags = flags;
 
+       /* This function can't fail - cause already checked above. */
        run_pack(run, svcn, len, Add2Ptr(attr, run_off), run_size, &plen);
 
        attr->nres.svcn = cpu_to_le64(svcn);
        attr->nres.evcn = cpu_to_le64((u64)svcn + len - 1);
 
-       err = 0;
        if (new_attr)
                *new_attr = attr;
 
@@ -1560,7 +1608,7 @@ int ni_delete_all(struct ntfs_inode *ni)
                mi->dirty = true;
                mi_write(mi, 0);
 
-               ntfs_mark_rec_free(sbi, mi->rno);
+               ntfs_mark_rec_free(sbi, mi->rno, false);
                ni_remove_mi(ni, mi);
                mi_put(mi);
                node = next;
@@ -1571,7 +1619,7 @@ int ni_delete_all(struct ntfs_inode *ni)
        ni->mi.dirty = true;
        err = mi_write(&ni->mi, 0);
 
-       ntfs_mark_rec_free(sbi, ni->mi.rno);
+       ntfs_mark_rec_free(sbi, ni->mi.rno, false);
 
        return err;
 }
@@ -1589,7 +1637,8 @@ struct ATTR_FILE_NAME *ni_fname_name(struct ntfs_inode *ni,
        struct ATTRIB *attr = NULL;
        struct ATTR_FILE_NAME *fname;
 
-       *le = NULL;
+       if (le)
+               *le = NULL;
 
        /* Enumerate all names. */
 next:
@@ -1605,7 +1654,7 @@ next:
                goto next;
 
        if (!uni)
-               goto next;
+               return fname;
 
        if (uni->len != fname->name_len)
                goto next;
@@ -2302,10 +2351,8 @@ remove_wof:
 
 out:
        kfree(pages);
-       if (err) {
-               make_bad_inode(inode);
-               ntfs_set_state(sbi, NTFS_DIRTY_ERROR);
-       }
+       if (err)
+               _ntfs_bad_inode(inode);
 
        return err;
 }
@@ -2944,7 +2991,7 @@ bool ni_remove_name_undo(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
 }
 
 /*
- * ni_add_name - Add new name in MFT and in directory.
+ * ni_add_name - Add new name into MFT and into directory.
  */
 int ni_add_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
                struct NTFS_DE *de)
@@ -2953,13 +3000,20 @@ int ni_add_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
        struct ATTRIB *attr;
        struct ATTR_LIST_ENTRY *le;
        struct mft_inode *mi;
+       struct ATTR_FILE_NAME *fname;
        struct ATTR_FILE_NAME *de_name = (struct ATTR_FILE_NAME *)(de + 1);
        u16 de_key_size = le16_to_cpu(de->key_size);
 
        mi_get_ref(&ni->mi, &de->ref);
        mi_get_ref(&dir_ni->mi, &de_name->home);
 
-       /* Insert new name in MFT. */
+       /* Fill duplicate from any ATTR_NAME. */
+       fname = ni_fname_name(ni, NULL, NULL, NULL, NULL);
+       if (fname)
+               memcpy(&de_name->dup, &fname->dup, sizeof(fname->dup));
+       de_name->dup.fa = ni->std_fa;
+
+       /* Insert new name into MFT. */
        err = ni_insert_resident(ni, de_key_size, ATTR_NAME, NULL, 0, &attr,
                                 &mi, &le);
        if (err)
@@ -2967,7 +3021,7 @@ int ni_add_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
 
        memcpy(Add2Ptr(attr, SIZEOF_RESIDENT), de_name, de_key_size);
 
-       /* Insert new name in directory. */
+       /* Insert new name into directory. */
        err = indx_insert_entry(&dir_ni->dir, dir_ni, de, ni->mi.sbi, NULL, 0);
        if (err)
                ni_remove_attr_le(ni, attr, mi, le);
@@ -2991,7 +3045,7 @@ int ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni,
         * 1) Add new name and remove old name.
         * 2) Remove old name and add new name.
         *
-        * In most cases (not all!) adding new name in MFT and in directory can
+        * In most cases (not all!) adding new name into MFT and into directory can
         * allocate additional cluster(s).
         * Second way may result to bad inode if we can't add new name
         * and then can't restore (add) old name.
@@ -3261,7 +3315,7 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint)
                        err = err2;
 
                if (is_empty) {
-                       ntfs_mark_rec_free(sbi, mi->rno);
+                       ntfs_mark_rec_free(sbi, mi->rno, false);
                        rb_erase(node, &ni->mi_tree);
                        mi_put(mi);
                }
index 49b7df6..e7c4940 100644 (file)
@@ -3843,6 +3843,8 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)
 
        memset(&rst_info2, 0, sizeof(struct restart_info));
        err = log_read_rst(log, l_size, false, &rst_info2);
+       if (err)
+               goto out;
 
        /* Determine which restart area to use. */
        if (!rst_info2.restart || rst_info2.last_lsn <= rst_info.last_lsn)
@@ -5057,7 +5059,7 @@ undo_action_next:
                goto add_allocated_vcns;
 
        vcn = le64_to_cpu(lrh->target_vcn);
-       vcn &= ~(log->clst_per_page - 1);
+       vcn &= ~(u64)(log->clst_per_page - 1);
 
 add_allocated_vcns:
        for (i = 0, vcn = le64_to_cpu(lrh->target_vcn),
index 1835e35..4ed15f6 100644 (file)
@@ -703,12 +703,14 @@ out:
 
 /*
  * ntfs_mark_rec_free - Mark record as free.
+ * is_mft - true if we are changing MFT
  */
-void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno)
+void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno, bool is_mft)
 {
        struct wnd_bitmap *wnd = &sbi->mft.bitmap;
 
-       down_write_nested(&wnd->rw_lock, BITMAP_MUTEX_MFT);
+       if (!is_mft)
+               down_write_nested(&wnd->rw_lock, BITMAP_MUTEX_MFT);
        if (rno >= wnd->nbits)
                goto out;
 
@@ -727,7 +729,8 @@ void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno)
                sbi->mft.next_free = rno;
 
 out:
-       up_write(&wnd->rw_lock);
+       if (!is_mft)
+               up_write(&wnd->rw_lock);
 }
 
 /*
@@ -780,7 +783,7 @@ out:
  */
 int ntfs_refresh_zone(struct ntfs_sb_info *sbi)
 {
-       CLST zone_limit, zone_max, lcn, vcn, len;
+       CLST lcn, vcn, len;
        size_t lcn_s, zlen;
        struct wnd_bitmap *wnd = &sbi->used.bitmap;
        struct ntfs_inode *ni = sbi->mft.ni;
@@ -789,16 +792,6 @@ int ntfs_refresh_zone(struct ntfs_sb_info *sbi)
        if (wnd_zone_len(wnd))
                return 0;
 
-       /*
-        * Compute the MFT zone at two steps.
-        * It would be nice if we are able to allocate 1/8 of
-        * total clusters for MFT but not more then 512 MB.
-        */
-       zone_limit = (512 * 1024 * 1024) >> sbi->cluster_bits;
-       zone_max = wnd->nbits >> 3;
-       if (zone_max > zone_limit)
-               zone_max = zone_limit;
-
        vcn = bytes_to_cluster(sbi,
                               (u64)sbi->mft.bitmap.nbits << sbi->record_bits);
 
@@ -812,13 +805,7 @@ int ntfs_refresh_zone(struct ntfs_sb_info *sbi)
        lcn_s = lcn + 1;
 
        /* Try to allocate clusters after last MFT run. */
-       zlen = wnd_find(wnd, zone_max, lcn_s, 0, &lcn_s);
-       if (!zlen) {
-               ntfs_notice(sbi->sb, "MftZone: unavailable");
-               return 0;
-       }
-
-       /* Truncate too large zone. */
+       zlen = wnd_find(wnd, sbi->zone_max, lcn_s, 0, &lcn_s);
        wnd_zone_set(wnd, lcn_s, zlen);
 
        return 0;
@@ -827,16 +814,21 @@ int ntfs_refresh_zone(struct ntfs_sb_info *sbi)
 /*
  * ntfs_update_mftmirr - Update $MFTMirr data.
  */
-int ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait)
+void ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait)
 {
        int err;
        struct super_block *sb = sbi->sb;
-       u32 blocksize = sb->s_blocksize;
+       u32 blocksize;
        sector_t block1, block2;
        u32 bytes;
 
+       if (!sb)
+               return;
+
+       blocksize = sb->s_blocksize;
+
        if (!(sbi->flags & NTFS_FLAGS_MFTMIRR))
-               return 0;
+               return;
 
        err = 0;
        bytes = sbi->mft.recs_mirr << sbi->record_bits;
@@ -847,16 +839,13 @@ int ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait)
                struct buffer_head *bh1, *bh2;
 
                bh1 = sb_bread(sb, block1++);
-               if (!bh1) {
-                       err = -EIO;
-                       goto out;
-               }
+               if (!bh1)
+                       return;
 
                bh2 = sb_getblk(sb, block2++);
                if (!bh2) {
                        put_bh(bh1);
-                       err = -EIO;
-                       goto out;
+                       return;
                }
 
                if (buffer_locked(bh2))
@@ -876,13 +865,24 @@ int ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait)
 
                put_bh(bh2);
                if (err)
-                       goto out;
+                       return;
        }
 
        sbi->flags &= ~NTFS_FLAGS_MFTMIRR;
+}
 
-out:
-       return err;
+/*
+ * ntfs_bad_inode
+ *
+ * Marks inode as bad and marks fs as 'dirty'
+ */
+void ntfs_bad_inode(struct inode *inode, const char *hint)
+{
+       struct ntfs_sb_info *sbi = inode->i_sb->s_fs_info;
+
+       ntfs_inode_err(inode, "%s", hint);
+       make_bad_inode(inode);
+       ntfs_set_state(sbi, NTFS_DIRTY_ERROR);
 }
 
 /*
@@ -1395,7 +1395,7 @@ int ntfs_write_bh(struct ntfs_sb_info *sbi, struct NTFS_RECORD_HEADER *rhdr,
                if (buffer_locked(bh))
                        __wait_on_buffer(bh);
 
-               lock_buffer(nb->bh[idx]);
+               lock_buffer(bh);
 
                bh_data = bh->b_data + off;
                end_data = Add2Ptr(bh_data, op);
@@ -2424,7 +2424,7 @@ static inline void ntfs_unmap_and_discard(struct ntfs_sb_info *sbi, CLST lcn,
 
 void mark_as_free_ex(struct ntfs_sb_info *sbi, CLST lcn, CLST len, bool trim)
 {
-       CLST end, i;
+       CLST end, i, zone_len, zlen;
        struct wnd_bitmap *wnd = &sbi->used.bitmap;
 
        down_write_nested(&wnd->rw_lock, BITMAP_MUTEX_CLUSTERS);
@@ -2459,6 +2459,28 @@ void mark_as_free_ex(struct ntfs_sb_info *sbi, CLST lcn, CLST len, bool trim)
                ntfs_unmap_and_discard(sbi, lcn, len);
        wnd_set_free(wnd, lcn, len);
 
+       /* append to MFT zone, if possible. */
+       zone_len = wnd_zone_len(wnd);
+       zlen = min(zone_len + len, sbi->zone_max);
+
+       if (zlen == zone_len) {
+               /* MFT zone already has maximum size. */
+       } else if (!zone_len) {
+               /* Create MFT zone only if 'zlen' is large enough. */
+               if (zlen == sbi->zone_max)
+                       wnd_zone_set(wnd, lcn, zlen);
+       } else {
+               CLST zone_lcn = wnd_zone_bit(wnd);
+
+               if (lcn + len == zone_lcn) {
+                       /* Append into head MFT zone. */
+                       wnd_zone_set(wnd, lcn, zlen);
+               } else if (zone_lcn + zone_len == lcn) {
+                       /* Append into tail MFT zone. */
+                       wnd_zone_set(wnd, zone_lcn, zlen);
+               }
+       }
+
 out:
        up_write(&wnd->rw_lock);
 }
index 6f81e3a..4403281 100644 (file)
@@ -1042,19 +1042,16 @@ int indx_find(struct ntfs_index *indx, struct ntfs_inode *ni,
 {
        int err;
        struct NTFS_DE *e;
-       const struct INDEX_HDR *hdr;
        struct indx_node *node;
 
        if (!root)
                root = indx_get_root(&ni->dir, ni, NULL, NULL);
 
        if (!root) {
-               err = -EINVAL;
-               goto out;
+               /* Should not happen. */
+               return -EINVAL;
        }
 
-       hdr = &root->ihdr;
-
        /* Check cache. */
        e = fnd->level ? fnd->de[fnd->level - 1] : fnd->root_de;
        if (e && !de_is_last(e) &&
@@ -1068,39 +1065,35 @@ int indx_find(struct ntfs_index *indx, struct ntfs_inode *ni,
        fnd_clear(fnd);
 
        /* Lookup entry that is <= to the search value. */
-       e = hdr_find_e(indx, hdr, key, key_len, ctx, diff);
+       e = hdr_find_e(indx, &root->ihdr, key, key_len, ctx, diff);
        if (!e)
                return -EINVAL;
 
        fnd->root_de = e;
-       err = 0;
 
        for (;;) {
                node = NULL;
-               if (*diff >= 0 || !de_has_vcn_ex(e)) {
-                       *entry = e;
-                       goto out;
-               }
+               if (*diff >= 0 || !de_has_vcn_ex(e))
+                       break;
 
                /* Read next level. */
                err = indx_read(indx, ni, de_get_vbn(e), &node);
                if (err)
-                       goto out;
+                       return err;
 
                /* Lookup entry that is <= to the search value. */
                e = hdr_find_e(indx, &node->index->ihdr, key, key_len, ctx,
                               diff);
                if (!e) {
-                       err = -EINVAL;
                        put_indx_node(node);
-                       goto out;
+                       return -EINVAL;
                }
 
                fnd_push(fnd, node, e);
        }
 
-out:
-       return err;
+       *entry = e;
+       return 0;
 }
 
 int indx_find_sort(struct ntfs_index *indx, struct ntfs_inode *ni,
@@ -1354,7 +1347,7 @@ static int indx_create_allocate(struct ntfs_index *indx, struct ntfs_inode *ni,
                goto out;
 
        err = ni_insert_nonresident(ni, ATTR_ALLOC, in->name, in->name_len,
-                                   &run, 0, len, 0, &alloc, NULL);
+                                   &run, 0, len, 0, &alloc, NULL, NULL);
        if (err)
                goto out1;
 
@@ -1685,8 +1678,8 @@ indx_insert_into_buffer(struct ntfs_index *indx, struct ntfs_inode *ni,
 {
        int err;
        const struct NTFS_DE *sp;
-       struct NTFS_DE *e, *de_t, *up_e = NULL;
-       struct indx_node *n2 = NULL;
+       struct NTFS_DE *e, *de_t, *up_e;
+       struct indx_node *n2;
        struct indx_node *n1 = fnd->nodes[level];
        struct INDEX_HDR *hdr1 = &n1->index->ihdr;
        struct INDEX_HDR *hdr2;
@@ -1994,7 +1987,7 @@ static int indx_free_children(struct ntfs_index *indx, struct ntfs_inode *ni,
                              const struct NTFS_DE *e, bool trim)
 {
        int err;
-       struct indx_node *n;
+       struct indx_node *n = NULL;
        struct INDEX_HDR *hdr;
        CLST vbn = de_get_vbn(e);
        size_t i;
index 80104af..51363d4 100644 (file)
@@ -430,6 +430,7 @@ end_enum:
        } else if (fname && fname->home.low == cpu_to_le32(MFT_REC_EXTEND) &&
                   fname->home.seq == cpu_to_le16(MFT_REC_EXTEND)) {
                /* Records in $Extend are not a files or general directories. */
+               inode->i_op = &ntfs_file_inode_operations;
        } else {
                err = -EINVAL;
                goto out;
@@ -500,7 +501,7 @@ struct inode *ntfs_iget5(struct super_block *sb, const struct MFT_REF *ref,
                inode = ntfs_read_mft(inode, name, ref);
        else if (ref->seq != ntfs_i(inode)->mi.mrec->seq) {
                /* Inode overlaps? */
-               make_bad_inode(inode);
+               _ntfs_bad_inode(inode);
        }
 
        return inode;
@@ -1632,7 +1633,7 @@ out4:
        ni->mi.dirty = false;
        discard_new_inode(inode);
 out3:
-       ntfs_mark_rec_free(sbi, ino);
+       ntfs_mark_rec_free(sbi, ino, false);
 
 out2:
        __putname(new_de);
@@ -1655,7 +1656,6 @@ int ntfs_link_inode(struct inode *inode, struct dentry *dentry)
        struct ntfs_inode *ni = ntfs_i(inode);
        struct ntfs_sb_info *sbi = inode->i_sb->s_fs_info;
        struct NTFS_DE *de;
-       struct ATTR_FILE_NAME *de_name;
 
        /* Allocate PATH_MAX bytes. */
        de = __getname();
@@ -1670,15 +1670,6 @@ int ntfs_link_inode(struct inode *inode, struct dentry *dentry)
        if (err)
                goto out;
 
-       de_name = (struct ATTR_FILE_NAME *)(de + 1);
-       /* Fill duplicate info. */
-       de_name->dup.cr_time = de_name->dup.m_time = de_name->dup.c_time =
-               de_name->dup.a_time = kernel2nt(&inode->i_ctime);
-       de_name->dup.alloc_size = de_name->dup.data_size =
-               cpu_to_le64(inode->i_size);
-       de_name->dup.fa = ni->std_fa;
-       de_name->dup.ea_size = de_name->dup.reparse = 0;
-
        err = ni_add_name(ntfs_i(d_inode(dentry->d_parent)), ni, de);
 out:
        __putname(de);
@@ -1731,9 +1722,7 @@ int ntfs_unlink_inode(struct inode *dir, const struct dentry *dentry)
                if (inode->i_nlink)
                        mark_inode_dirty(inode);
        } else if (!ni_remove_name_undo(dir_ni, ni, de, de2, undo_remove)) {
-               make_bad_inode(inode);
-               ntfs_inode_err(inode, "failed to undo unlink");
-               ntfs_set_state(sbi, NTFS_DIRTY_ERROR);
+               _ntfs_bad_inode(inode);
        } else {
                if (ni_is_dirty(dir))
                        mark_inode_dirty(dir);
index bc74121..bc22cc3 100644 (file)
@@ -208,7 +208,7 @@ static int ntfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
 }
 
 /*
- * ntfs_rmdir - inode_operations::rm_dir
+ * ntfs_rmdir - inode_operations::rmdir
  */
 static int ntfs_rmdir(struct inode *dir, struct dentry *dentry)
 {
@@ -308,9 +308,7 @@ static int ntfs_rename(struct user_namespace *mnt_userns, struct inode *dir,
        err = ni_rename(dir_ni, new_dir_ni, ni, de, new_de, &is_bad);
        if (is_bad) {
                /* Restore after failed rename failed too. */
-               make_bad_inode(inode);
-               ntfs_inode_err(inode, "failed to undo rename");
-               ntfs_set_state(sbi, NTFS_DIRTY_ERROR);
+               _ntfs_bad_inode(inode);
        } else if (!err) {
                inode->i_ctime = dir->i_ctime = dir->i_mtime =
                        current_time(dir);
index 8dbdca0..2c79122 100644 (file)
@@ -220,6 +220,7 @@ struct ntfs_sb_info {
 
        u32 flags; // See NTFS_FLAGS_XXX.
 
+       CLST zone_max; // Maximum MFT zone length in clusters
        CLST bad_clusters; // The count of marked bad clusters.
 
        u16 max_bytes_per_attr; // Maximum attribute size in record.
@@ -408,8 +409,6 @@ enum REPARSE_SIGN {
 };
 
 /* Functions from attrib.c */
-int attr_load_runs(struct ATTRIB *attr, struct ntfs_inode *ni,
-                  struct runs_tree *run, const CLST *vcn);
 int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run,
                           CLST vcn, CLST lcn, CLST len, CLST *pre_alloc,
                           enum ALLOCATE_OPT opt, CLST *alen, const size_t fr,
@@ -440,6 +439,7 @@ int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
 int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
                        u64 new_valid);
 int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes);
+int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes);
 int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size);
 
 /* Functions from attrlist.c */
@@ -528,7 +528,7 @@ int ni_insert_nonresident(struct ntfs_inode *ni, enum ATTR_TYPE type,
                          const __le16 *name, u8 name_len,
                          const struct runs_tree *run, CLST svcn, CLST len,
                          __le16 flags, struct ATTRIB **new_attr,
-                         struct mft_inode **mi);
+                         struct mft_inode **mi, struct ATTR_LIST_ENTRY **le);
 int ni_insert_resident(struct ntfs_inode *ni, u32 data_size,
                       enum ATTR_TYPE type, const __le16 *name, u8 name_len,
                       struct ATTRIB **new_attr, struct mft_inode **mi,
@@ -589,10 +589,12 @@ int ntfs_look_for_free_space(struct ntfs_sb_info *sbi, CLST lcn, CLST len,
                             enum ALLOCATE_OPT opt);
 int ntfs_look_free_mft(struct ntfs_sb_info *sbi, CLST *rno, bool mft,
                       struct ntfs_inode *ni, struct mft_inode **mi);
-void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno);
+void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno, bool is_mft);
 int ntfs_clear_mft_tail(struct ntfs_sb_info *sbi, size_t from, size_t to);
 int ntfs_refresh_zone(struct ntfs_sb_info *sbi);
-int ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait);
+void ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait);
+void ntfs_bad_inode(struct inode *inode, const char *hint);
+#define _ntfs_bad_inode(i) ntfs_bad_inode(i, __func__)
 enum NTFS_DIRTY_FLAGS {
        NTFS_DIRTY_CLEAR = 0,
        NTFS_DIRTY_DIRTY = 1,
@@ -738,7 +740,6 @@ static inline struct ATTRIB *rec_find_attr_le(struct mft_inode *rec,
 int mi_write(struct mft_inode *mi, int wait);
 int mi_format_new(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno,
                  __le16 flags, bool is_mft);
-void mi_mark_free(struct mft_inode *mi);
 struct ATTRIB *mi_insert_attr(struct mft_inode *mi, enum ATTR_TYPE type,
                              const __le16 *name, u8 name_len, u32 asize,
                              u16 name_off);
@@ -780,10 +781,10 @@ bool run_lookup_entry(const struct runs_tree *run, CLST vcn, CLST *lcn,
 void run_truncate(struct runs_tree *run, CLST vcn);
 void run_truncate_head(struct runs_tree *run, CLST vcn);
 void run_truncate_around(struct runs_tree *run, CLST vcn);
-bool run_lookup(const struct runs_tree *run, CLST vcn, size_t *Index);
 bool run_add_entry(struct runs_tree *run, CLST vcn, CLST lcn, CLST len,
                   bool is_mft);
 bool run_collapse_range(struct runs_tree *run, CLST vcn, CLST len);
+bool run_insert_range(struct runs_tree *run, CLST vcn, CLST len);
 bool run_get_entry(const struct runs_tree *run, size_t index, CLST *vcn,
                   CLST *lcn, CLST *len);
 bool run_is_mapped_full(const struct runs_tree *run, CLST svcn, CLST evcn);
@@ -802,6 +803,7 @@ int run_unpack_ex(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
 #define run_unpack_ex run_unpack
 #endif
 int run_get_highest_vcn(CLST vcn, const u8 *run_buf, u64 *highest_vcn);
+int run_clone(const struct runs_tree *run, struct runs_tree *new_run);
 
 /* Globals from super.c */
 void *ntfs_set_shared(void *ptr, u32 bytes);
index 861e357..7d2fac5 100644 (file)
@@ -395,28 +395,6 @@ int mi_format_new(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno,
 }
 
 /*
- * mi_mark_free - Mark record as unused and marks it as free in bitmap.
- */
-void mi_mark_free(struct mft_inode *mi)
-{
-       CLST rno = mi->rno;
-       struct ntfs_sb_info *sbi = mi->sbi;
-
-       if (rno >= MFT_REC_RESERVED && rno < MFT_REC_FREE) {
-               ntfs_clear_mft_tail(sbi, rno, rno + 1);
-               mi->dirty = false;
-               return;
-       }
-
-       if (mi->mrec) {
-               clear_rec_inuse(mi->mrec);
-               mi->dirty = true;
-               mi_write(mi, 0);
-       }
-       ntfs_mark_rec_free(sbi, rno);
-}
-
-/*
  * mi_insert_attr - Reserve space for new attribute.
  *
  * Return: Not full constructed attribute or NULL if not possible to create.
@@ -445,12 +423,11 @@ struct ATTRIB *mi_insert_attr(struct mft_inode *mi, enum ATTR_TYPE type,
        attr = NULL;
        while ((attr = mi_enum_attr(mi, attr))) {
                diff = compare_attr(attr, type, name, name_len, upcase);
-               if (diff > 0)
-                       break;
+
                if (diff < 0)
                        continue;
 
-               if (!is_attr_indexed(attr))
+               if (!diff && !is_attr_indexed(attr))
                        return NULL;
                break;
        }
index a8fec65..aaaa0d3 100644 (file)
@@ -31,7 +31,7 @@ struct ntfs_run {
  * Case of entry missing from list 'index' will be set to
  * point to insertion position for the entry question.
  */
-bool run_lookup(const struct runs_tree *run, CLST vcn, size_t *index)
+static bool run_lookup(const struct runs_tree *run, CLST vcn, size_t *index)
 {
        size_t min_idx, max_idx, mid_idx;
        struct ntfs_run *r;
@@ -547,6 +547,48 @@ bool run_collapse_range(struct runs_tree *run, CLST vcn, CLST len)
        return true;
 }
 
+/* run_insert_range
+ *
+ * Helper for attr_insert_range(),
+ * which is helper for fallocate(insert_range).
+ */
+bool run_insert_range(struct runs_tree *run, CLST vcn, CLST len)
+{
+       size_t index;
+       struct ntfs_run *r, *e;
+
+       if (WARN_ON(!run_lookup(run, vcn, &index)))
+               return false; /* Should never be here. */
+
+       e = run->runs + run->count;
+       r = run->runs + index;
+
+       if (vcn > r->vcn)
+               r += 1;
+
+       for (; r < e; r++)
+               r->vcn += len;
+
+       r = run->runs + index;
+
+       if (vcn > r->vcn) {
+               /* split fragment. */
+               CLST len1 = vcn - r->vcn;
+               CLST len2 = r->len - len1;
+               CLST lcn2 = r->lcn == SPARSE_LCN ? SPARSE_LCN : (r->lcn + len1);
+
+               r->len = len1;
+
+               if (!run_add_entry(run, vcn + len, lcn2, len2, false))
+                       return false;
+       }
+
+       if (!run_add_entry(run, vcn, SPARSE_LCN, len, false))
+               return false;
+
+       return true;
+}
+
 /*
  * run_get_entry - Return index-th mapped region.
  */
@@ -778,26 +820,36 @@ int run_pack(const struct runs_tree *run, CLST svcn, CLST len, u8 *run_buf,
        CLST next_vcn, vcn, lcn;
        CLST prev_lcn = 0;
        CLST evcn1 = svcn + len;
+       const struct ntfs_run *r, *r_end;
        int packed_size = 0;
        size_t i;
-       bool ok;
        s64 dlcn;
        int offset_size, size_size, tmp;
 
-       next_vcn = vcn = svcn;
-
        *packed_vcns = 0;
 
        if (!len)
                goto out;
 
-       ok = run_lookup_entry(run, vcn, &lcn, &len, &i);
+       /* Check all required entries [svcn, encv1) available. */
+       if (!run_lookup(run, svcn, &i))
+               return -ENOENT;
+
+       r_end = run->runs + run->count;
+       r = run->runs + i;
 
-       if (!ok)
-               goto error;
+       for (next_vcn = r->vcn + r->len; next_vcn < evcn1;
+            next_vcn = r->vcn + r->len) {
+               if (++r >= r_end || r->vcn != next_vcn)
+                       return -ENOENT;
+       }
 
-       if (next_vcn != vcn)
-               goto error;
+       /* Repeat cycle above and pack runs. Assume no errors. */
+       r = run->runs + i;
+       len = svcn - r->vcn;
+       vcn = svcn;
+       lcn = r->lcn == SPARSE_LCN ? SPARSE_LCN : (r->lcn + len);
+       len = r->len - len;
 
        for (;;) {
                next_vcn = vcn + len;
@@ -846,12 +898,10 @@ int run_pack(const struct runs_tree *run, CLST svcn, CLST len, u8 *run_buf,
                if (packed_size + 1 >= run_buf_size || next_vcn >= evcn1)
                        goto out;
 
-               ok = run_get_entry(run, ++i, &vcn, &lcn, &len);
-               if (!ok)
-                       goto error;
-
-               if (next_vcn != vcn)
-                       goto error;
+               r += 1;
+               vcn = r->vcn;
+               lcn = r->lcn;
+               len = r->len;
        }
 
 out:
@@ -860,9 +910,6 @@ out:
                run_buf[0] = 0;
 
        return packed_size + 1;
-
-error:
-       return -EOPNOTSUPP;
 }
 
 /*
@@ -1109,3 +1156,28 @@ int run_get_highest_vcn(CLST vcn, const u8 *run_buf, u64 *highest_vcn)
        *highest_vcn = vcn64 - 1;
        return 0;
 }
+
+/*
+ * run_clone
+ *
+ * Make a copy of run
+ */
+int run_clone(const struct runs_tree *run, struct runs_tree *new_run)
+{
+       size_t bytes = run->count * sizeof(struct ntfs_run);
+
+       if (bytes > new_run->allocated) {
+               struct ntfs_run *new_ptr = kvmalloc(bytes, GFP_KERNEL);
+
+               if (!new_ptr)
+                       return -ENOMEM;
+
+               kvfree(new_run->runs);
+               new_run->runs = new_ptr;
+               new_run->allocated = bytes;
+       }
+
+       memcpy(new_run->runs, run->runs, bytes);
+       new_run->count = run->count;
+       return 0;
+}
index 0c6de62..47012c9 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/fs_context.h>
 #include <linux/fs_parser.h>
 #include <linux/log2.h>
+#include <linux/minmax.h>
 #include <linux/module.h>
 #include <linux/nls.h>
 #include <linux/seq_file.h>
@@ -390,7 +391,7 @@ static int ntfs_fs_reconfigure(struct fs_context *fc)
                return -EINVAL;
        }
 
-       memcpy(sbi->options, new_opts, sizeof(*new_opts));
+       swap(sbi->options, fc->fs_private);
 
        return 0;
 }
@@ -870,6 +871,13 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
        sb->s_maxbytes = 0xFFFFFFFFull << sbi->cluster_bits;
 #endif
 
+       /*
+        * Compute the MFT zone at two steps.
+        * It would be nice if we are able to allocate 1/8 of
+        * total clusters for MFT but not more then 512 MB.
+        */
+       sbi->zone_max = min_t(CLST, 0x20000000 >> sbi->cluster_bits, clusters >> 3);
+
        err = 0;
 
 out:
@@ -900,6 +908,8 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
        ref.high = 0;
 
        sbi->sb = sb;
+       sbi->options = fc->fs_private;
+       fc->fs_private = NULL;
        sb->s_flags |= SB_NODIRATIME;
        sb->s_magic = 0x7366746e; // "ntfs"
        sb->s_op = &ntfs_sops;
@@ -1262,8 +1272,6 @@ load_root:
                goto put_inode_out;
        }
 
-       fc->fs_private = NULL;
-
        return 0;
 
 put_inode_out:
@@ -1378,7 +1386,7 @@ static const struct fs_context_operations ntfs_context_ops = {
 /*
  * ntfs_init_fs_context - Initialize spi and opts
  *
- * This will called when mount/remount. We will first initiliaze
+ * This will called when mount/remount. We will first initialize
  * options so that if remount we can use just that.
  */
 static int ntfs_init_fs_context(struct fs_context *fc)
@@ -1416,7 +1424,6 @@ static int ntfs_init_fs_context(struct fs_context *fc)
        mutex_init(&sbi->compress.mtx_lzx);
 #endif
 
-       sbi->options = opts;
        fc->s_fs_info = sbi;
 ok:
        fc->fs_private = opts;
index 5e0e028..5bdff12 100644 (file)
@@ -118,7 +118,7 @@ static int ntfs_read_ea(struct ntfs_inode *ni, struct EA_FULL **ea,
 
                run_init(&run);
 
-               err = attr_load_runs(attr_ea, ni, &run, NULL);
+               err = attr_load_runs_range(ni, ATTR_EA, NULL, 0, &run, 0, size);
                if (!err)
                        err = ntfs_read_run_nb(sbi, &run, 0, ea_p, size, NULL);
                run_close(&run);
@@ -444,6 +444,11 @@ update_ea:
                /* Delete xattr, ATTR_EA */
                ni_remove_attr_le(ni, attr, mi, le);
        } else if (attr->non_res) {
+               err = attr_load_runs_range(ni, ATTR_EA, NULL, 0, &ea_run, 0,
+                                          size);
+               if (err)
+                       goto out;
+
                err = ntfs_sb_write_run(sbi, &ea_run, 0, ea_all, size, 0);
                if (err)
                        goto out;
@@ -547,28 +552,23 @@ static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
 {
        const char *name;
        size_t size, name_len;
-       void *value = NULL;
-       int err = 0;
+       void *value;
+       int err;
        int flags;
+       umode_t mode;
 
        if (S_ISLNK(inode->i_mode))
                return -EOPNOTSUPP;
 
+       mode = inode->i_mode;
        switch (type) {
        case ACL_TYPE_ACCESS:
                /* Do not change i_mode if we are in init_acl */
                if (acl && !init_acl) {
-                       umode_t mode;
-
                        err = posix_acl_update_mode(mnt_userns, inode, &mode,
                                                    &acl);
                        if (err)
-                               goto out;
-
-                       if (inode->i_mode != mode) {
-                               inode->i_mode = mode;
-                               mark_inode_dirty(inode);
-                       }
+                               return err;
                }
                name = XATTR_NAME_POSIX_ACL_ACCESS;
                name_len = sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1;
@@ -604,8 +604,13 @@ static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
        err = ntfs_set_ea(inode, name, name_len, value, size, flags, 0);
        if (err == -ENODATA && !size)
                err = 0; /* Removing non existed xattr. */
-       if (!err)
+       if (!err) {
                set_cached_acl(inode, type, acl);
+               if (inode->i_mode != mode) {
+                       inode->i_mode = mode;
+                       mark_inode_dirty(inode);
+               }
+       }
 
 out:
        kfree(value);
@@ -706,13 +711,13 @@ int ntfs_init_acl(struct user_namespace *mnt_userns, struct inode *inode,
                inode->i_default_acl = NULL;
        }
 
-       if (!acl)
-               inode->i_acl = NULL;
-       else {
+       if (acl) {
                if (!err)
                        err = ntfs_set_acl_ex(mnt_userns, inode, acl,
                                              ACL_TYPE_ACCESS, true);
                posix_acl_release(acl);
+       } else {
+               inode->i_acl = NULL;
        }
 
        return err;
index 3096f08..71ab4ba 100644 (file)
@@ -39,9 +39,6 @@ arch_test_and_set_bit(unsigned int nr, volatile unsigned long *p)
        unsigned long mask = BIT_MASK(nr);
 
        p += BIT_WORD(nr);
-       if (READ_ONCE(*p) & mask)
-               return 1;
-
        old = arch_atomic_long_fetch_or(mask, (atomic_long_t *)p);
        return !!(old & mask);
 }
@@ -53,9 +50,6 @@ arch_test_and_clear_bit(unsigned int nr, volatile unsigned long *p)
        unsigned long mask = BIT_MASK(nr);
 
        p += BIT_WORD(nr);
-       if (!(READ_ONCE(*p) & mask))
-               return 0;
-
        old = arch_atomic_long_fetch_andnot(mask, (atomic_long_t *)p);
        return !!(old & mask);
 }
index 0b6a3c6..88d5289 100644 (file)
 #define CLK_MOUT_CLKCMU_APM_BUS                46
 #define CLK_DOUT_CLKCMU_APM_BUS                47
 #define CLK_GOUT_CLKCMU_APM_BUS                48
-#define TOP_NR_CLK                     49
+#define CLK_MOUT_AUD                   49
+#define CLK_GOUT_AUD                   50
+#define CLK_DOUT_AUD                   51
+#define CLK_MOUT_IS_BUS                        52
+#define CLK_MOUT_IS_ITP                        53
+#define CLK_MOUT_IS_VRA                        54
+#define CLK_MOUT_IS_GDC                        55
+#define CLK_GOUT_IS_BUS                        56
+#define CLK_GOUT_IS_ITP                        57
+#define CLK_GOUT_IS_VRA                        58
+#define CLK_GOUT_IS_GDC                        59
+#define CLK_DOUT_IS_BUS                        60
+#define CLK_DOUT_IS_ITP                        61
+#define CLK_DOUT_IS_VRA                        62
+#define CLK_DOUT_IS_GDC                        63
+#define CLK_MOUT_MFCMSCL_MFC           64
+#define CLK_MOUT_MFCMSCL_M2M           65
+#define CLK_MOUT_MFCMSCL_MCSC          66
+#define CLK_MOUT_MFCMSCL_JPEG          67
+#define CLK_GOUT_MFCMSCL_MFC           68
+#define CLK_GOUT_MFCMSCL_M2M           69
+#define CLK_GOUT_MFCMSCL_MCSC          70
+#define CLK_GOUT_MFCMSCL_JPEG          71
+#define CLK_DOUT_MFCMSCL_MFC           72
+#define CLK_DOUT_MFCMSCL_M2M           73
+#define CLK_DOUT_MFCMSCL_MCSC          74
+#define CLK_DOUT_MFCMSCL_JPEG          75
+#define TOP_NR_CLK                     76
 
 /* CMU_APM */
 #define CLK_RCO_I3C_PMIC               1
 #define CLK_GOUT_SYSREG_APM_PCLK       24
 #define APM_NR_CLK                     25
 
+/* CMU_AUD */
+#define CLK_DOUT_AUD_AUDIF             1
+#define CLK_DOUT_AUD_BUSD              2
+#define CLK_DOUT_AUD_BUSP              3
+#define CLK_DOUT_AUD_CNT               4
+#define CLK_DOUT_AUD_CPU               5
+#define CLK_DOUT_AUD_CPU_ACLK          6
+#define CLK_DOUT_AUD_CPU_PCLKDBG       7
+#define CLK_DOUT_AUD_FM                        8
+#define CLK_DOUT_AUD_FM_SPDY           9
+#define CLK_DOUT_AUD_MCLK              10
+#define CLK_DOUT_AUD_UAIF0             11
+#define CLK_DOUT_AUD_UAIF1             12
+#define CLK_DOUT_AUD_UAIF2             13
+#define CLK_DOUT_AUD_UAIF3             14
+#define CLK_DOUT_AUD_UAIF4             15
+#define CLK_DOUT_AUD_UAIF5             16
+#define CLK_DOUT_AUD_UAIF6             17
+#define CLK_FOUT_AUD_PLL               18
+#define CLK_GOUT_AUD_ABOX_ACLK         19
+#define CLK_GOUT_AUD_ASB_CCLK          20
+#define CLK_GOUT_AUD_CA32_CCLK         21
+#define CLK_GOUT_AUD_CNT_BCLK          22
+#define CLK_GOUT_AUD_CODEC_MCLK                23
+#define CLK_GOUT_AUD_DAP_CCLK          24
+#define CLK_GOUT_AUD_GPIO_PCLK         25
+#define CLK_GOUT_AUD_PPMU_ACLK         26
+#define CLK_GOUT_AUD_PPMU_PCLK         27
+#define CLK_GOUT_AUD_SPDY_BCLK         28
+#define CLK_GOUT_AUD_SYSMMU_CLK                29
+#define CLK_GOUT_AUD_SYSREG_PCLK       30
+#define CLK_GOUT_AUD_TZPC_PCLK         31
+#define CLK_GOUT_AUD_UAIF0_BCLK                32
+#define CLK_GOUT_AUD_UAIF1_BCLK                33
+#define CLK_GOUT_AUD_UAIF2_BCLK                34
+#define CLK_GOUT_AUD_UAIF3_BCLK                35
+#define CLK_GOUT_AUD_UAIF4_BCLK                36
+#define CLK_GOUT_AUD_UAIF5_BCLK                37
+#define CLK_GOUT_AUD_UAIF6_BCLK                38
+#define CLK_GOUT_AUD_WDT_PCLK          39
+#define CLK_MOUT_AUD_CPU               40
+#define CLK_MOUT_AUD_CPU_HCH           41
+#define CLK_MOUT_AUD_CPU_USER          42
+#define CLK_MOUT_AUD_FM                        43
+#define CLK_MOUT_AUD_PLL               44
+#define CLK_MOUT_AUD_TICK_USB_USER     45
+#define CLK_MOUT_AUD_UAIF0             46
+#define CLK_MOUT_AUD_UAIF1             47
+#define CLK_MOUT_AUD_UAIF2             48
+#define CLK_MOUT_AUD_UAIF3             49
+#define CLK_MOUT_AUD_UAIF4             50
+#define CLK_MOUT_AUD_UAIF5             51
+#define CLK_MOUT_AUD_UAIF6             52
+#define IOCLK_AUDIOCDCLK0              53
+#define IOCLK_AUDIOCDCLK1              54
+#define IOCLK_AUDIOCDCLK2              55
+#define IOCLK_AUDIOCDCLK3              56
+#define IOCLK_AUDIOCDCLK4              57
+#define IOCLK_AUDIOCDCLK5              58
+#define IOCLK_AUDIOCDCLK6              59
+#define TICK_USB                       60
+#define AUD_NR_CLK                     61
+
 /* CMU_CMGP */
 #define CLK_RCO_CMGP                   1
 #define CLK_MOUT_CMGP_ADC              2
 #define CLK_GOUT_SYSREG_HSI_PCLK       13
 #define HSI_NR_CLK                     14
 
+/* CMU_IS */
+#define CLK_MOUT_IS_BUS_USER           1
+#define CLK_MOUT_IS_ITP_USER           2
+#define CLK_MOUT_IS_VRA_USER           3
+#define CLK_MOUT_IS_GDC_USER           4
+#define CLK_DOUT_IS_BUSP               5
+#define CLK_GOUT_IS_CMU_IS_PCLK                6
+#define CLK_GOUT_IS_CSIS0_ACLK         7
+#define CLK_GOUT_IS_CSIS1_ACLK         8
+#define CLK_GOUT_IS_CSIS2_ACLK         9
+#define CLK_GOUT_IS_TZPC_PCLK          10
+#define CLK_GOUT_IS_CSIS_DMA_CLK       11
+#define CLK_GOUT_IS_GDC_CLK            12
+#define CLK_GOUT_IS_IPP_CLK            13
+#define CLK_GOUT_IS_ITP_CLK            14
+#define CLK_GOUT_IS_MCSC_CLK           15
+#define CLK_GOUT_IS_VRA_CLK            16
+#define CLK_GOUT_IS_PPMU_IS0_ACLK      17
+#define CLK_GOUT_IS_PPMU_IS0_PCLK      18
+#define CLK_GOUT_IS_PPMU_IS1_ACLK      19
+#define CLK_GOUT_IS_PPMU_IS1_PCLK      20
+#define CLK_GOUT_IS_SYSMMU_IS0_CLK     21
+#define CLK_GOUT_IS_SYSMMU_IS1_CLK     22
+#define CLK_GOUT_IS_SYSREG_PCLK                23
+#define IS_NR_CLK                      24
+
+/* CMU_MFCMSCL */
+#define CLK_MOUT_MFCMSCL_MFC_USER              1
+#define CLK_MOUT_MFCMSCL_M2M_USER              2
+#define CLK_MOUT_MFCMSCL_MCSC_USER             3
+#define CLK_MOUT_MFCMSCL_JPEG_USER             4
+#define CLK_DOUT_MFCMSCL_BUSP                  5
+#define CLK_GOUT_MFCMSCL_CMU_MFCMSCL_PCLK      6
+#define CLK_GOUT_MFCMSCL_TZPC_PCLK             7
+#define CLK_GOUT_MFCMSCL_JPEG_ACLK             8
+#define CLK_GOUT_MFCMSCL_M2M_ACLK              9
+#define CLK_GOUT_MFCMSCL_MCSC_CLK              10
+#define CLK_GOUT_MFCMSCL_MFC_ACLK              11
+#define CLK_GOUT_MFCMSCL_PPMU_ACLK             12
+#define CLK_GOUT_MFCMSCL_PPMU_PCLK             13
+#define CLK_GOUT_MFCMSCL_SYSMMU_CLK            14
+#define CLK_GOUT_MFCMSCL_SYSREG_PCLK           15
+#define MFCMSCL_NR_CLK                         16
+
 /* CMU_PERI */
 #define CLK_MOUT_PERI_BUS_USER         1
 #define CLK_MOUT_PERI_UART_USER                2
index 47c6f7f..1f768b2 100644 (file)
 #define IMX8MM_CLK_CLKOUT2_DIV                 256
 #define IMX8MM_CLK_CLKOUT2                     257
 
-
 #define IMX8MM_CLK_END                         258
 
 #endif
index 21fda9c..19bc327 100644 (file)
 #define IMX93_CLK_TMC_GATE             187
 #define IMX93_CLK_PMRO_GATE            188
 #define IMX93_CLK_32K                  189
-#define IMX93_CLK_END                  190
+#define IMX93_CLK_SAI1_IPG             190
+#define IMX93_CLK_SAI2_IPG             191
+#define IMX93_CLK_SAI3_IPG             192
+#define IMX93_CLK_MU1_A_GATE           193
+#define IMX93_CLK_MU1_B_GATE           194
+#define IMX93_CLK_MU2_A_GATE           195
+#define IMX93_CLK_MU2_B_GATE           196
+#define IMX93_CLK_END                  197
 
 #endif
index db2b41f..c92d969 100644 (file)
 #define PXA168_CLK_PLL1_2_1_5          19
 #define PXA168_CLK_PLL1_3_16           20
 #define PXA168_CLK_PLL1_192            21
+#define PXA168_CLK_PLL1_2_1_10         22
+#define PXA168_CLK_PLL1_2_3_16         23
 #define PXA168_CLK_UART_PLL            27
 #define PXA168_CLK_USB_PLL             28
+#define PXA168_CLK_CLK32_2             50
 
 /* apb peripherals */
 #define PXA168_CLK_TWSI0               60
@@ -56,6 +59,9 @@
 #define PXA168_CLK_CCIC0               107
 #define PXA168_CLK_CCIC0_PHY           108
 #define PXA168_CLK_CCIC0_SPHY          109
+#define PXA168_CLK_SDH3                        110
+#define PXA168_CLK_SDH01_AXI           111
+#define PXA168_CLK_SDH23_AXI           112
 
 #define PXA168_NR_CLKS                 200
 #endif
diff --git a/include/dt-bindings/clock/mediatek,mt6795-clk.h b/include/dt-bindings/clock/mediatek,mt6795-clk.h
new file mode 100644 (file)
index 0000000..9902906
--- /dev/null
@@ -0,0 +1,275 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2022 Collabora Ltd.
+ * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT6795_H
+#define _DT_BINDINGS_CLK_MT6795_H
+
+/* TOPCKGEN */
+#define CLK_TOP_ADSYS_26M              0
+#define CLK_TOP_CLKPH_MCK_O            1
+#define CLK_TOP_USB_SYSPLL_125M                2
+#define CLK_TOP_DSI0_DIG               3
+#define CLK_TOP_DSI1_DIG               4
+#define CLK_TOP_ARMCA53PLL_754M                5
+#define CLK_TOP_ARMCA53PLL_502M                6
+#define CLK_TOP_MAIN_H546M             7
+#define CLK_TOP_MAIN_H364M             8
+#define CLK_TOP_MAIN_H218P4M           9
+#define CLK_TOP_MAIN_H156M             10
+#define CLK_TOP_TVDPLL_445P5M          11
+#define CLK_TOP_TVDPLL_594M            12
+#define CLK_TOP_UNIV_624M              13
+#define CLK_TOP_UNIV_416M              14
+#define CLK_TOP_UNIV_249P6M            15
+#define CLK_TOP_UNIV_178P3M            16
+#define CLK_TOP_UNIV_48M               17
+#define CLK_TOP_CLKRTC_EXT             18
+#define CLK_TOP_CLKRTC_INT             19
+#define CLK_TOP_FPC                    20
+#define CLK_TOP_HDMITXPLL_D2           21
+#define CLK_TOP_HDMITXPLL_D3           22
+#define CLK_TOP_ARMCA53PLL_D2          23
+#define CLK_TOP_ARMCA53PLL_D3          24
+#define CLK_TOP_APLL1                  25
+#define CLK_TOP_APLL2                  26
+#define CLK_TOP_DMPLL                  27
+#define CLK_TOP_DMPLL_D2               28
+#define CLK_TOP_DMPLL_D4               29
+#define CLK_TOP_DMPLL_D8               30
+#define CLK_TOP_DMPLL_D16              31
+#define CLK_TOP_MMPLL                  32
+#define CLK_TOP_MMPLL_D2               33
+#define CLK_TOP_MSDCPLL                        34
+#define CLK_TOP_MSDCPLL_D2             35
+#define CLK_TOP_MSDCPLL_D4             36
+#define CLK_TOP_MSDCPLL2               37
+#define CLK_TOP_MSDCPLL2_D2            38
+#define CLK_TOP_MSDCPLL2_D4            39
+#define CLK_TOP_SYSPLL_D2              40
+#define CLK_TOP_SYSPLL1_D2             41
+#define CLK_TOP_SYSPLL1_D4             42
+#define CLK_TOP_SYSPLL1_D8             43
+#define CLK_TOP_SYSPLL1_D16            44
+#define CLK_TOP_SYSPLL_D3              45
+#define CLK_TOP_SYSPLL2_D2             46
+#define CLK_TOP_SYSPLL2_D4             47
+#define CLK_TOP_SYSPLL_D5              48
+#define CLK_TOP_SYSPLL3_D2             49
+#define CLK_TOP_SYSPLL3_D4             50
+#define CLK_TOP_SYSPLL_D7              51
+#define CLK_TOP_SYSPLL4_D2             52
+#define CLK_TOP_SYSPLL4_D4             53
+#define CLK_TOP_TVDPLL                 54
+#define CLK_TOP_TVDPLL_D2              55
+#define CLK_TOP_TVDPLL_D4              56
+#define CLK_TOP_TVDPLL_D8              57
+#define CLK_TOP_TVDPLL_D16             58
+#define CLK_TOP_UNIVPLL_D2             59
+#define CLK_TOP_UNIVPLL1_D2            60
+#define CLK_TOP_UNIVPLL1_D4            61
+#define CLK_TOP_UNIVPLL1_D8            62
+#define CLK_TOP_UNIVPLL_D3             63
+#define CLK_TOP_UNIVPLL2_D2            64
+#define CLK_TOP_UNIVPLL2_D4            65
+#define CLK_TOP_UNIVPLL2_D8            66
+#define CLK_TOP_UNIVPLL_D5             67
+#define CLK_TOP_UNIVPLL3_D2            68
+#define CLK_TOP_UNIVPLL3_D4            69
+#define CLK_TOP_UNIVPLL3_D8            70
+#define CLK_TOP_UNIVPLL_D7             71
+#define CLK_TOP_UNIVPLL_D26            72
+#define CLK_TOP_UNIVPLL_D52            73
+#define CLK_TOP_VCODECPLL              74
+#define CLK_TOP_VCODECPLL_370P5                75
+#define CLK_TOP_VENCPLL                        76
+#define CLK_TOP_VENCPLL_D2             77
+#define CLK_TOP_VENCPLL_D4             78
+#define CLK_TOP_AXI_SEL                        79
+#define CLK_TOP_MEM_SEL                        80
+#define CLK_TOP_DDRPHYCFG_SEL          81
+#define CLK_TOP_MM_SEL                 82
+#define CLK_TOP_PWM_SEL                        83
+#define CLK_TOP_VDEC_SEL               84
+#define CLK_TOP_VENC_SEL               85
+#define CLK_TOP_MFG_SEL                        86
+#define CLK_TOP_CAMTG_SEL              87
+#define CLK_TOP_UART_SEL               88
+#define CLK_TOP_SPI_SEL                        89
+#define CLK_TOP_USB20_SEL              90
+#define CLK_TOP_USB30_SEL              91
+#define CLK_TOP_MSDC50_0_H_SEL         92
+#define CLK_TOP_MSDC50_0_SEL           93
+#define CLK_TOP_MSDC30_1_SEL           94
+#define CLK_TOP_MSDC30_2_SEL           95
+#define CLK_TOP_MSDC30_3_SEL           96
+#define CLK_TOP_AUDIO_SEL              97
+#define CLK_TOP_AUD_INTBUS_SEL         98
+#define CLK_TOP_PMICSPI_SEL            99
+#define CLK_TOP_SCP_SEL                        100
+#define CLK_TOP_MJC_SEL                        101
+#define CLK_TOP_DPI0_SEL               102
+#define CLK_TOP_IRDA_SEL               103
+#define CLK_TOP_CCI400_SEL             104
+#define CLK_TOP_AUD_1_SEL              105
+#define CLK_TOP_AUD_2_SEL              106
+#define CLK_TOP_MEM_MFG_IN_SEL         107
+#define CLK_TOP_AXI_MFG_IN_SEL         108
+#define CLK_TOP_SCAM_SEL               109
+#define CLK_TOP_I2S0_M_SEL             110
+#define CLK_TOP_I2S1_M_SEL             111
+#define CLK_TOP_I2S2_M_SEL             112
+#define CLK_TOP_I2S3_M_SEL             113
+#define CLK_TOP_I2S3_B_SEL             114
+#define CLK_TOP_APLL1_DIV0             115
+#define CLK_TOP_APLL1_DIV1             116
+#define CLK_TOP_APLL1_DIV2             117
+#define CLK_TOP_APLL1_DIV3             118
+#define CLK_TOP_APLL1_DIV4             119
+#define CLK_TOP_APLL1_DIV5             120
+#define CLK_TOP_APLL2_DIV0             121
+#define CLK_TOP_APLL2_DIV1             122
+#define CLK_TOP_APLL2_DIV2             123
+#define CLK_TOP_APLL2_DIV3             124
+#define CLK_TOP_APLL2_DIV4             125
+#define CLK_TOP_APLL2_DIV5             126
+#define CLK_TOP_NR_CLK                 127
+
+/* APMIXED_SYS */
+#define CLK_APMIXED_ARMCA53PLL         0
+#define CLK_APMIXED_MAINPLL            1
+#define CLK_APMIXED_UNIVPLL            2
+#define CLK_APMIXED_MMPLL              3
+#define CLK_APMIXED_MSDCPLL            4
+#define CLK_APMIXED_VENCPLL            5
+#define CLK_APMIXED_TVDPLL             6
+#define CLK_APMIXED_MPLL               7
+#define CLK_APMIXED_VCODECPLL          8
+#define CLK_APMIXED_APLL1              9
+#define CLK_APMIXED_APLL2              10
+#define CLK_APMIXED_REF2USB_TX         11
+#define CLK_APMIXED_NR_CLK             12
+
+/* INFRA_SYS */
+#define CLK_INFRA_DBGCLK               0
+#define CLK_INFRA_SMI                  1
+#define CLK_INFRA_AUDIO                        2
+#define CLK_INFRA_GCE                  3
+#define CLK_INFRA_L2C_SRAM             4
+#define CLK_INFRA_M4U                  5
+#define CLK_INFRA_MD1MCU               6
+#define CLK_INFRA_MD1BUS               7
+#define CLK_INFRA_MD1DBB               8
+#define CLK_INFRA_DEVICE_APC           9
+#define CLK_INFRA_TRNG                 10
+#define CLK_INFRA_MD1LTE               11
+#define CLK_INFRA_CPUM                 12
+#define CLK_INFRA_KP                   13
+#define CLK_INFRA_CA53_C0_SEL          14
+#define CLK_INFRA_CA53_C1_SEL          15
+#define CLK_INFRA_NR_CLK               16
+
+/* PERI_SYS */
+#define CLK_PERI_NFI                   0
+#define CLK_PERI_THERM                 1
+#define CLK_PERI_PWM1                  2
+#define CLK_PERI_PWM2                  3
+#define CLK_PERI_PWM3                  4
+#define CLK_PERI_PWM4                  5
+#define CLK_PERI_PWM5                  6
+#define CLK_PERI_PWM6                  7
+#define CLK_PERI_PWM7                  8
+#define CLK_PERI_PWM                   9
+#define CLK_PERI_USB0                  10
+#define CLK_PERI_USB1                  11
+#define CLK_PERI_AP_DMA                        12
+#define CLK_PERI_MSDC30_0              13
+#define CLK_PERI_MSDC30_1              14
+#define CLK_PERI_MSDC30_2              15
+#define CLK_PERI_MSDC30_3              16
+#define CLK_PERI_NLI_ARB               17
+#define CLK_PERI_IRDA                  18
+#define CLK_PERI_UART0                 19
+#define CLK_PERI_UART1                 20
+#define CLK_PERI_UART2                 21
+#define CLK_PERI_UART3                 22
+#define CLK_PERI_I2C0                  23
+#define CLK_PERI_I2C1                  24
+#define CLK_PERI_I2C2                  25
+#define CLK_PERI_I2C3                  26
+#define CLK_PERI_I2C4                  27
+#define CLK_PERI_AUXADC                        28
+#define CLK_PERI_SPI0                  29
+#define CLK_PERI_UART0_SEL             30
+#define CLK_PERI_UART1_SEL             31
+#define CLK_PERI_UART2_SEL             32
+#define CLK_PERI_UART3_SEL             33
+#define CLK_PERI_NR_CLK                        34
+
+/* MFG */
+#define CLK_MFG_BAXI                   0
+#define CLK_MFG_BMEM                   1
+#define CLK_MFG_BG3D                   2
+#define CLK_MFG_B26M                   3
+#define CLK_MFG_NR_CLK                 4
+
+/* MM_SYS */
+#define CLK_MM_SMI_COMMON              0
+#define CLK_MM_SMI_LARB0               1
+#define CLK_MM_CAM_MDP                 2
+#define CLK_MM_MDP_RDMA0               3
+#define CLK_MM_MDP_RDMA1               4
+#define CLK_MM_MDP_RSZ0                        5
+#define CLK_MM_MDP_RSZ1                        6
+#define CLK_MM_MDP_RSZ2                        7
+#define CLK_MM_MDP_TDSHP0              8
+#define CLK_MM_MDP_TDSHP1              9
+#define CLK_MM_MDP_CROP                        10
+#define CLK_MM_MDP_WDMA                        11
+#define CLK_MM_MDP_WROT0               12
+#define CLK_MM_MDP_WROT1               13
+#define CLK_MM_FAKE_ENG                        14
+#define CLK_MM_MUTEX_32K               15
+#define CLK_MM_DISP_OVL0               16
+#define CLK_MM_DISP_OVL1               17
+#define CLK_MM_DISP_RDMA0              18
+#define CLK_MM_DISP_RDMA1              19
+#define CLK_MM_DISP_RDMA2              20
+#define CLK_MM_DISP_WDMA0              21
+#define CLK_MM_DISP_WDMA1              22
+#define CLK_MM_DISP_COLOR0             23
+#define CLK_MM_DISP_COLOR1             24
+#define CLK_MM_DISP_AAL                        25
+#define CLK_MM_DISP_GAMMA              26
+#define CLK_MM_DISP_UFOE               27
+#define CLK_MM_DISP_SPLIT0             28
+#define CLK_MM_DISP_SPLIT1             29
+#define CLK_MM_DISP_MERGE              30
+#define CLK_MM_DISP_OD                 31
+#define CLK_MM_DISP_PWM0MM             32
+#define CLK_MM_DISP_PWM026M            33
+#define CLK_MM_DISP_PWM1MM             34
+#define CLK_MM_DISP_PWM126M            35
+#define CLK_MM_DSI0_ENGINE             36
+#define CLK_MM_DSI0_DIGITAL            37
+#define CLK_MM_DSI1_ENGINE             38
+#define CLK_MM_DSI1_DIGITAL            39
+#define CLK_MM_DPI_PIXEL               40
+#define CLK_MM_DPI_ENGINE              41
+#define CLK_MM_NR_CLK                  42
+
+/* VDEC_SYS */
+#define CLK_VDEC_CKEN                  0
+#define CLK_VDEC_LARB_CKEN             1
+#define CLK_VDEC_NR_CLK                        2
+
+/* VENC_SYS */
+#define CLK_VENC_LARB                  0
+#define CLK_VENC_VENC                  1
+#define CLK_VENC_JPGENC                        2
+#define CLK_VENC_JPGDEC                        3
+#define CLK_VENC_NR_CLK                        4
+
+#endif /* _DT_BINDINGS_CLK_MT6795_H */
diff --git a/include/dt-bindings/clock/mediatek,mt8365-clk.h b/include/dt-bindings/clock/mediatek,mt8365-clk.h
new file mode 100644 (file)
index 0000000..f9aff17
--- /dev/null
@@ -0,0 +1,373 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+ *
+ * Copyright (c) 2022 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT8365_H
+#define _DT_BINDINGS_CLK_MT8365_H
+
+/* TOPCKGEN */
+#define CLK_TOP_CLK_NULL               0
+#define CLK_TOP_I2S0_BCK               1
+#define CLK_TOP_DSI0_LNTC_DSICK                2
+#define CLK_TOP_VPLL_DPIX              3
+#define CLK_TOP_LVDSTX_CLKDIG_CTS      4
+#define CLK_TOP_MFGPLL                 5
+#define CLK_TOP_SYSPLL_D2              6
+#define CLK_TOP_SYSPLL1_D2             7
+#define CLK_TOP_SYSPLL1_D4             8
+#define CLK_TOP_SYSPLL1_D8             9
+#define CLK_TOP_SYSPLL1_D16            10
+#define CLK_TOP_SYSPLL_D3              11
+#define CLK_TOP_SYSPLL2_D2             12
+#define CLK_TOP_SYSPLL2_D4             13
+#define CLK_TOP_SYSPLL2_D8             14
+#define CLK_TOP_SYSPLL_D5              15
+#define CLK_TOP_SYSPLL3_D2             16
+#define CLK_TOP_SYSPLL3_D4             17
+#define CLK_TOP_SYSPLL_D7              18
+#define CLK_TOP_SYSPLL4_D2             19
+#define CLK_TOP_SYSPLL4_D4             20
+#define CLK_TOP_UNIVPLL                        21
+#define CLK_TOP_UNIVPLL_D2             22
+#define CLK_TOP_UNIVPLL1_D2            23
+#define CLK_TOP_UNIVPLL1_D4            24
+#define CLK_TOP_UNIVPLL_D3             25
+#define CLK_TOP_UNIVPLL2_D2            26
+#define CLK_TOP_UNIVPLL2_D4            27
+#define CLK_TOP_UNIVPLL2_D8            28
+#define CLK_TOP_UNIVPLL2_D32           29
+#define CLK_TOP_UNIVPLL_D5             30
+#define CLK_TOP_UNIVPLL3_D2            31
+#define CLK_TOP_UNIVPLL3_D4            32
+#define CLK_TOP_MMPLL                  33
+#define CLK_TOP_MMPLL_D2               34
+#define CLK_TOP_LVDSPLL_D2             35
+#define CLK_TOP_LVDSPLL_D4             36
+#define CLK_TOP_LVDSPLL_D8             37
+#define CLK_TOP_LVDSPLL_D16            38
+#define CLK_TOP_USB20_192M             39
+#define CLK_TOP_USB20_192M_D4          40
+#define CLK_TOP_USB20_192M_D8          41
+#define CLK_TOP_USB20_192M_D16         42
+#define CLK_TOP_USB20_192M_D32         43
+#define CLK_TOP_APLL1                  44
+#define CLK_TOP_APLL1_D2               45
+#define CLK_TOP_APLL1_D4               46
+#define CLK_TOP_APLL1_D8               47
+#define CLK_TOP_APLL2                  48
+#define CLK_TOP_APLL2_D2               49
+#define CLK_TOP_APLL2_D4               50
+#define CLK_TOP_APLL2_D8               51
+#define CLK_TOP_SYS_26M_D2             52
+#define CLK_TOP_MSDCPLL                        53
+#define CLK_TOP_MSDCPLL_D2             54
+#define CLK_TOP_DSPPLL                 55
+#define CLK_TOP_DSPPLL_D2              56
+#define CLK_TOP_DSPPLL_D4              57
+#define CLK_TOP_DSPPLL_D8              58
+#define CLK_TOP_APUPLL                 59
+#define CLK_TOP_CLK26M_D52             60
+#define CLK_TOP_AXI_SEL                        61
+#define CLK_TOP_MEM_SEL                        62
+#define CLK_TOP_MM_SEL                 63
+#define CLK_TOP_SCP_SEL                        64
+#define CLK_TOP_MFG_SEL                        65
+#define CLK_TOP_ATB_SEL                        66
+#define CLK_TOP_CAMTG_SEL              67
+#define CLK_TOP_CAMTG1_SEL             68
+#define CLK_TOP_UART_SEL               69
+#define CLK_TOP_SPI_SEL                        70
+#define CLK_TOP_MSDC50_0_HC_SEL                71
+#define CLK_TOP_MSDC2_2_HC_SEL         72
+#define CLK_TOP_MSDC50_0_SEL           73
+#define CLK_TOP_MSDC50_2_SEL           74
+#define CLK_TOP_MSDC30_1_SEL           75
+#define CLK_TOP_AUDIO_SEL              76
+#define CLK_TOP_AUD_INTBUS_SEL         77
+#define CLK_TOP_AUD_1_SEL              78
+#define CLK_TOP_AUD_2_SEL              79
+#define CLK_TOP_AUD_ENGEN1_SEL         80
+#define CLK_TOP_AUD_ENGEN2_SEL         81
+#define CLK_TOP_AUD_SPDIF_SEL          82
+#define CLK_TOP_DISP_PWM_SEL           83
+#define CLK_TOP_DXCC_SEL               84
+#define CLK_TOP_SSUSB_SYS_SEL          85
+#define CLK_TOP_SSUSB_XHCI_SEL         86
+#define CLK_TOP_SPM_SEL                        87
+#define CLK_TOP_I2C_SEL                        88
+#define CLK_TOP_PWM_SEL                        89
+#define CLK_TOP_SENIF_SEL              90
+#define CLK_TOP_AES_FDE_SEL            91
+#define CLK_TOP_CAMTM_SEL              92
+#define CLK_TOP_DPI0_SEL               93
+#define CLK_TOP_DPI1_SEL               94
+#define CLK_TOP_DSP_SEL                        95
+#define CLK_TOP_NFI2X_SEL              96
+#define CLK_TOP_NFIECC_SEL             97
+#define CLK_TOP_ECC_SEL                        98
+#define CLK_TOP_ETH_SEL                        99
+#define CLK_TOP_GCPU_SEL               100
+#define CLK_TOP_GCPU_CPM_SEL           101
+#define CLK_TOP_APU_SEL                        102
+#define CLK_TOP_APU_IF_SEL             103
+#define CLK_TOP_MBIST_DIAG_SEL         104
+#define CLK_TOP_APLL_I2S0_SEL          105
+#define CLK_TOP_APLL_I2S1_SEL          106
+#define CLK_TOP_APLL_I2S2_SEL          107
+#define CLK_TOP_APLL_I2S3_SEL          108
+#define CLK_TOP_APLL_TDMOUT_SEL                109
+#define CLK_TOP_APLL_TDMIN_SEL         110
+#define CLK_TOP_APLL_SPDIF_SEL         111
+#define CLK_TOP_APLL12_CK_DIV0         112
+#define CLK_TOP_APLL12_CK_DIV1         113
+#define CLK_TOP_APLL12_CK_DIV2         114
+#define CLK_TOP_APLL12_CK_DIV3         115
+#define CLK_TOP_APLL12_CK_DIV4         116
+#define CLK_TOP_APLL12_CK_DIV4B                117
+#define CLK_TOP_APLL12_CK_DIV5         118
+#define CLK_TOP_APLL12_CK_DIV5B                119
+#define CLK_TOP_APLL12_CK_DIV6         120
+#define CLK_TOP_AUD_I2S0_M             121
+#define CLK_TOP_AUD_I2S1_M             122
+#define CLK_TOP_AUD_I2S2_M             123
+#define CLK_TOP_AUD_I2S3_M             124
+#define CLK_TOP_AUD_TDMOUT_M           125
+#define CLK_TOP_AUD_TDMOUT_B           126
+#define CLK_TOP_AUD_TDMIN_M            127
+#define CLK_TOP_AUD_TDMIN_B            128
+#define CLK_TOP_AUD_SPDIF_M            129
+#define CLK_TOP_USB20_48M_EN           130
+#define CLK_TOP_UNIVPLL_48M_EN         131
+#define CLK_TOP_LVDSTX_CLKDIG_EN       132
+#define CLK_TOP_VPLL_DPIX_EN           133
+#define CLK_TOP_SSUSB_TOP_CK_EN                134
+#define CLK_TOP_SSUSB_PHY_CK_EN                135
+#define CLK_TOP_CONN_32K               136
+#define CLK_TOP_CONN_26M               137
+#define CLK_TOP_DSP_32K                        138
+#define CLK_TOP_DSP_26M                        139
+#define CLK_TOP_NR_CLK                 140
+
+/* INFRACFG */
+#define CLK_IFR_PMIC_TMR               0
+#define CLK_IFR_PMIC_AP                        1
+#define CLK_IFR_PMIC_MD                        2
+#define CLK_IFR_PMIC_CONN              3
+#define CLK_IFR_ICUSB                  4
+#define CLK_IFR_GCE                    5
+#define CLK_IFR_THERM                  6
+#define CLK_IFR_PWM_HCLK               7
+#define CLK_IFR_PWM1                   8
+#define CLK_IFR_PWM2                   9
+#define CLK_IFR_PWM3                   10
+#define CLK_IFR_PWM4                   11
+#define CLK_IFR_PWM5                   12
+#define CLK_IFR_PWM                    13
+#define CLK_IFR_UART0                  14
+#define CLK_IFR_UART1                  15
+#define CLK_IFR_UART2                  16
+#define CLK_IFR_DSP_UART               17
+#define CLK_IFR_GCE_26M                        18
+#define CLK_IFR_CQ_DMA_FPC             19
+#define CLK_IFR_BTIF                   20
+#define CLK_IFR_SPI0                   21
+#define CLK_IFR_MSDC0_HCLK             22
+#define CLK_IFR_MSDC2_HCLK             23
+#define CLK_IFR_MSDC1_HCLK             24
+#define CLK_IFR_DVFSRC                 25
+#define CLK_IFR_GCPU                   26
+#define CLK_IFR_TRNG                   27
+#define CLK_IFR_AUXADC                 28
+#define CLK_IFR_CPUM                   29
+#define CLK_IFR_AUXADC_MD              30
+#define CLK_IFR_AP_DMA                 31
+#define CLK_IFR_DEBUGSYS               32
+#define CLK_IFR_AUDIO                  33
+#define CLK_IFR_PWM_FBCLK6             34
+#define CLK_IFR_DISP_PWM               35
+#define CLK_IFR_AUD_26M_BK             36
+#define CLK_IFR_CQ_DMA                 37
+#define CLK_IFR_MSDC0_SF               38
+#define CLK_IFR_MSDC1_SF               39
+#define CLK_IFR_MSDC2_SF               40
+#define CLK_IFR_AP_MSDC0               41
+#define CLK_IFR_MD_MSDC0               42
+#define CLK_IFR_MSDC0_SRC              43
+#define CLK_IFR_MSDC1_SRC              44
+#define CLK_IFR_MSDC2_SRC              45
+#define CLK_IFR_PWRAP_TMR              46
+#define CLK_IFR_PWRAP_SPI              47
+#define CLK_IFR_PWRAP_SYS              48
+#define CLK_IFR_MCU_PM_BK              49
+#define CLK_IFR_IRRX_26M               50
+#define CLK_IFR_IRRX_32K               51
+#define CLK_IFR_I2C0_AXI               52
+#define CLK_IFR_I2C1_AXI               53
+#define CLK_IFR_I2C2_AXI               54
+#define CLK_IFR_I2C3_AXI               55
+#define CLK_IFR_NIC_AXI                        56
+#define CLK_IFR_NIC_SLV_AXI            57
+#define CLK_IFR_APU_AXI                        58
+#define CLK_IFR_NFIECC                 59
+#define CLK_IFR_NFIECC_BK              60
+#define CLK_IFR_NFI1X_BK               61
+#define CLK_IFR_NFI_BK                 62
+#define CLK_IFR_MSDC2_AP_BK            63
+#define CLK_IFR_MSDC2_MD_BK            64
+#define CLK_IFR_MSDC2_BK               65
+#define CLK_IFR_SUSB_133_BK            66
+#define CLK_IFR_SUSB_66_BK             67
+#define CLK_IFR_SSUSB_SYS              68
+#define CLK_IFR_SSUSB_REF              69
+#define CLK_IFR_SSUSB_XHCI             70
+#define CLK_IFR_NR_CLK                 71
+
+/* PERICFG */
+#define CLK_PERIAXI                    0
+#define CLK_PERI_NR_CLK                        1
+
+/* APMIXEDSYS */
+#define CLK_APMIXED_ARMPLL             0
+#define CLK_APMIXED_MAINPLL            1
+#define CLK_APMIXED_UNIVPLL            2
+#define CLK_APMIXED_MFGPLL             3
+#define CLK_APMIXED_MSDCPLL            4
+#define CLK_APMIXED_MMPLL              5
+#define CLK_APMIXED_APLL1              6
+#define CLK_APMIXED_APLL2              7
+#define CLK_APMIXED_LVDSPLL            8
+#define CLK_APMIXED_DSPPLL             9
+#define CLK_APMIXED_APUPLL             10
+#define CLK_APMIXED_UNIV_EN            11
+#define CLK_APMIXED_USB20_EN           12
+#define CLK_APMIXED_NR_CLK             13
+
+/* GCE */
+#define CLK_GCE_FAXI                   0
+#define CLK_GCE_NR_CLK                 1
+
+/* AUDIOTOP */
+#define CLK_AUD_AFE                    0
+#define CLK_AUD_I2S                    1
+#define CLK_AUD_22M                    2
+#define CLK_AUD_24M                    3
+#define CLK_AUD_INTDIR                 4
+#define CLK_AUD_APLL2_TUNER            5
+#define CLK_AUD_APLL_TUNER             6
+#define CLK_AUD_SPDF                   7
+#define CLK_AUD_HDMI                   8
+#define CLK_AUD_HDMI_IN                        9
+#define CLK_AUD_ADC                    10
+#define CLK_AUD_DAC                    11
+#define CLK_AUD_DAC_PREDIS             12
+#define CLK_AUD_TML                    13
+#define CLK_AUD_I2S1_BK                        14
+#define CLK_AUD_I2S2_BK                        15
+#define CLK_AUD_I2S3_BK                        16
+#define CLK_AUD_I2S4_BK                        17
+#define CLK_AUD_NR_CLK                 18
+
+/* MIPI_CSI0A */
+#define CLK_MIPI0A_CSR_CSI_EN_0A       0
+#define CLK_MIPI_RX_ANA_CSI0A_NR_CLK   1
+
+/* MIPI_CSI0B */
+#define CLK_MIPI0B_CSR_CSI_EN_0B       0
+#define CLK_MIPI_RX_ANA_CSI0B_NR_CLK   1
+
+/* MIPI_CSI1A */
+#define CLK_MIPI1A_CSR_CSI_EN_1A       0
+#define CLK_MIPI_RX_ANA_CSI1A_NR_CLK   1
+
+/* MIPI_CSI1B */
+#define CLK_MIPI1B_CSR_CSI_EN_1B       0
+#define CLK_MIPI_RX_ANA_CSI1B_NR_CLK   1
+
+/* MIPI_CSI2A */
+#define CLK_MIPI2A_CSR_CSI_EN_2A       0
+#define CLK_MIPI_RX_ANA_CSI2A_NR_CLK   1
+
+/* MIPI_CSI2B */
+#define CLK_MIPI2B_CSR_CSI_EN_2B       0
+#define CLK_MIPI_RX_ANA_CSI2B_NR_CLK   1
+
+/* MCUCFG */
+#define CLK_MCU_BUS_SEL                        0
+#define CLK_MCU_NR_CLK                 1
+
+/* MFGCFG */
+#define CLK_MFG_BG3D                   0
+#define CLK_MFG_MBIST_DIAG             1
+#define CLK_MFG_NR_CLK                 2
+
+/* MMSYS */
+#define CLK_MM_MM_MDP_RDMA0            0
+#define CLK_MM_MM_MDP_CCORR0           1
+#define CLK_MM_MM_MDP_RSZ0             2
+#define CLK_MM_MM_MDP_RSZ1             3
+#define CLK_MM_MM_MDP_TDSHP0           4
+#define CLK_MM_MM_MDP_WROT0            5
+#define CLK_MM_MM_MDP_WDMA0            6
+#define CLK_MM_MM_DISP_OVL0            7
+#define CLK_MM_MM_DISP_OVL0_2L         8
+#define CLK_MM_MM_DISP_RSZ0            9
+#define CLK_MM_MM_DISP_RDMA0           10
+#define CLK_MM_MM_DISP_WDMA0           11
+#define CLK_MM_MM_DISP_COLOR0          12
+#define CLK_MM_MM_DISP_CCORR0          13
+#define CLK_MM_MM_DISP_AAL0            14
+#define CLK_MM_MM_DISP_GAMMA0          15
+#define CLK_MM_MM_DISP_DITHER0         16
+#define CLK_MM_MM_DSI0                 17
+#define CLK_MM_MM_DISP_RDMA1           18
+#define CLK_MM_MM_MDP_RDMA1            19
+#define CLK_MM_DPI0_DPI0               20
+#define CLK_MM_MM_FAKE                 21
+#define CLK_MM_MM_SMI_COMMON           22
+#define CLK_MM_MM_SMI_LARB0            23
+#define CLK_MM_MM_SMI_COMM0            24
+#define CLK_MM_MM_SMI_COMM1            25
+#define CLK_MM_MM_CAM_MDP              26
+#define CLK_MM_MM_SMI_IMG              27
+#define CLK_MM_MM_SMI_CAM              28
+#define CLK_MM_IMG_IMG_DL_RELAY                29
+#define CLK_MM_IMG_IMG_DL_ASYNC_TOP    30
+#define CLK_MM_DSI0_DIG_DSI            31
+#define CLK_MM_26M_HRTWT               32
+#define CLK_MM_MM_DPI0                 33
+#define CLK_MM_LVDSTX_PXL              34
+#define CLK_MM_LVDSTX_CTS              35
+#define CLK_MM_NR_CLK                  36
+
+/* IMGSYS */
+#define CLK_CAM_LARB2                  0
+#define CLK_CAM                                1
+#define CLK_CAMTG                      2
+#define CLK_CAM_SENIF                  3
+#define CLK_CAMSV0                     4
+#define CLK_CAMSV1                     5
+#define CLK_CAM_FDVT                   6
+#define CLK_CAM_WPE                    7
+#define CLK_CAM_NR_CLK                 8
+
+/* VDECSYS */
+#define CLK_VDEC_VDEC                  0
+#define CLK_VDEC_LARB1                 1
+#define CLK_VDEC_NR_CLK                        2
+
+/* VENCSYS */
+#define CLK_VENC                       0
+#define CLK_VENC_JPGENC                        1
+#define CLK_VENC_NR_CLK                        2
+
+/* APUSYS */
+#define CLK_APU_IPU_CK                 0
+#define CLK_APU_AXI                    1
+#define CLK_APU_JTAG                   2
+#define CLK_APU_IF_CK                  3
+#define CLK_APU_EDMA                   4
+#define CLK_APU_AHB                    5
+#define CLK_APU_NR_CLK                 6
+
+#endif /* _DT_BINDINGS_CLK_MT8365_H */
index 4048669..79775a5 100644 (file)
 #define CLK_RTCREF     33
 #define CLK_MSSPLL     34
 
+/* Clock Conditioning Circuitry Clock IDs */
+
+#define CLK_CCC_PLL0           0
+#define CLK_CCC_PLL1           1
+#define CLK_CCC_DLL0           2
+#define CLK_CCC_DLL1           3
+
+#define CLK_CCC_PLL0_OUT0      4
+#define CLK_CCC_PLL0_OUT1      5
+#define CLK_CCC_PLL0_OUT2      6
+#define CLK_CCC_PLL0_OUT3      7
+
+#define CLK_CCC_PLL1_OUT0      8
+#define CLK_CCC_PLL1_OUT1      9
+#define CLK_CCC_PLL1_OUT2      10
+#define CLK_CCC_PLL1_OUT3      11
+
+#define CLK_CCC_DLL0_OUT0      12
+#define CLK_CCC_DLL0_OUT1      13
+
+#define CLK_CCC_DLL1_OUT0      14
+#define CLK_CCC_DLL1_OUT1      15
+
 #endif /* _DT_BINDINGS_CLK_MICROCHIP_MPFS_H_ */
index 95cf812..d70d017 100644 (file)
 #define CLK_VDO1_DPINTF                                47
 #define CLK_VDO1_DISP_MONITOR_DPINTF           48
 #define CLK_VDO1_26M_SLOW                      49
-#define CLK_VDO1_NR_CLK                                50
+#define CLK_VDO1_DPI1_HDMI                     50
+#define CLK_VDO1_NR_CLK                                51
+
 
 #endif /* _DT_BINDINGS_CLK_MT8195_H */
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8909.h b/include/dt-bindings/clock/qcom,gcc-msm8909.h
new file mode 100644 (file)
index 0000000..4394ba0
--- /dev/null
@@ -0,0 +1,218 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2022 Kernkonzept GmbH.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GCC_8909_H
+#define _DT_BINDINGS_CLK_QCOM_GCC_8909_H
+
+/* PLLs */
+#define GPLL0_EARLY                            0
+#define GPLL0                                  1
+#define GPLL1                                  2
+#define GPLL1_VOTE                             3
+#define GPLL2_EARLY                            4
+#define GPLL2                                  5
+#define BIMC_PLL_EARLY                         6
+#define BIMC_PLL                               7
+
+/* RCGs */
+#define APSS_AHB_CLK_SRC                       8
+#define BIMC_DDR_CLK_SRC                       9
+#define BIMC_GPU_CLK_SRC                       10
+#define BLSP1_QUP1_I2C_APPS_CLK_SRC            11
+#define BLSP1_QUP1_SPI_APPS_CLK_SRC            12
+#define BLSP1_QUP2_I2C_APPS_CLK_SRC            13
+#define BLSP1_QUP2_SPI_APPS_CLK_SRC            14
+#define BLSP1_QUP3_I2C_APPS_CLK_SRC            15
+#define BLSP1_QUP3_SPI_APPS_CLK_SRC            16
+#define BLSP1_QUP4_I2C_APPS_CLK_SRC            17
+#define BLSP1_QUP4_SPI_APPS_CLK_SRC            18
+#define BLSP1_QUP5_I2C_APPS_CLK_SRC            19
+#define BLSP1_QUP5_SPI_APPS_CLK_SRC            20
+#define BLSP1_QUP6_I2C_APPS_CLK_SRC            21
+#define BLSP1_QUP6_SPI_APPS_CLK_SRC            22
+#define BLSP1_UART1_APPS_CLK_SRC               23
+#define BLSP1_UART2_APPS_CLK_SRC               24
+#define BYTE0_CLK_SRC                          25
+#define CAMSS_GP0_CLK_SRC                      26
+#define CAMSS_GP1_CLK_SRC                      27
+#define CAMSS_TOP_AHB_CLK_SRC                  28
+#define CODEC_DIGCODEC_CLK_SRC                 29
+#define CRYPTO_CLK_SRC                         30
+#define CSI0_CLK_SRC                           31
+#define CSI0PHYTIMER_CLK_SRC                   32
+#define CSI1_CLK_SRC                           33
+#define ESC0_CLK_SRC                           34
+#define GFX3D_CLK_SRC                          35
+#define GP1_CLK_SRC                            36
+#define GP2_CLK_SRC                            37
+#define GP3_CLK_SRC                            38
+#define MCLK0_CLK_SRC                          39
+#define MCLK1_CLK_SRC                          40
+#define MDP_CLK_SRC                            41
+#define PCLK0_CLK_SRC                          42
+#define PCNOC_BFDCD_CLK_SRC                    43
+#define PDM2_CLK_SRC                           44
+#define SDCC1_APPS_CLK_SRC                     45
+#define SDCC2_APPS_CLK_SRC                     46
+#define SYSTEM_NOC_BFDCD_CLK_SRC               47
+#define ULTAUDIO_AHBFABRIC_CLK_SRC             48
+#define ULTAUDIO_LPAIF_AUX_I2S_CLK_SRC         49
+#define ULTAUDIO_LPAIF_PRI_I2S_CLK_SRC         50
+#define ULTAUDIO_LPAIF_SEC_I2S_CLK_SRC         51
+#define ULTAUDIO_XO_CLK_SRC                    52
+#define USB_HS_SYSTEM_CLK_SRC                  53
+#define VCODEC0_CLK_SRC                                54
+#define VFE0_CLK_SRC                           55
+#define VSYNC_CLK_SRC                          56
+
+/* Voteable Clocks */
+#define GCC_APSS_TCU_CLK                       57
+#define GCC_BLSP1_AHB_CLK                      58
+#define GCC_BLSP1_SLEEP_CLK                    59
+#define GCC_BOOT_ROM_AHB_CLK                   60
+#define GCC_CRYPTO_CLK                         61
+#define GCC_CRYPTO_AHB_CLK                     62
+#define GCC_CRYPTO_AXI_CLK                     63
+#define GCC_GFX_TBU_CLK                                64
+#define GCC_GFX_TCU_CLK                                65
+#define GCC_GTCU_AHB_CLK                       66
+#define GCC_MDP_TBU_CLK                                67
+#define GCC_PRNG_AHB_CLK                       68
+#define GCC_SMMU_CFG_CLK                       69
+#define GCC_VENUS_TBU_CLK                      70
+#define GCC_VFE_TBU_CLK                                71
+
+/* Branches */
+#define GCC_BIMC_GFX_CLK                       72
+#define GCC_BIMC_GPU_CLK                       73
+#define GCC_BLSP1_QUP1_I2C_APPS_CLK            74
+#define GCC_BLSP1_QUP1_SPI_APPS_CLK            75
+#define GCC_BLSP1_QUP2_I2C_APPS_CLK            76
+#define GCC_BLSP1_QUP2_SPI_APPS_CLK            77
+#define GCC_BLSP1_QUP3_I2C_APPS_CLK            78
+#define GCC_BLSP1_QUP3_SPI_APPS_CLK            79
+#define GCC_BLSP1_QUP4_I2C_APPS_CLK            80
+#define GCC_BLSP1_QUP4_SPI_APPS_CLK            81
+#define GCC_BLSP1_QUP5_I2C_APPS_CLK            82
+#define GCC_BLSP1_QUP5_SPI_APPS_CLK            83
+#define GCC_BLSP1_QUP6_I2C_APPS_CLK            84
+#define GCC_BLSP1_QUP6_SPI_APPS_CLK            85
+#define GCC_BLSP1_UART1_APPS_CLK               86
+#define GCC_BLSP1_UART2_APPS_CLK               87
+#define GCC_CAMSS_AHB_CLK                      88
+#define GCC_CAMSS_CSI0_CLK                     89
+#define GCC_CAMSS_CSI0_AHB_CLK                 90
+#define GCC_CAMSS_CSI0PHY_CLK                  91
+#define GCC_CAMSS_CSI0PHYTIMER_CLK             92
+#define GCC_CAMSS_CSI0PIX_CLK                  93
+#define GCC_CAMSS_CSI0RDI_CLK                  94
+#define GCC_CAMSS_CSI1_CLK                     95
+#define GCC_CAMSS_CSI1_AHB_CLK                 96
+#define GCC_CAMSS_CSI1PHY_CLK                  97
+#define GCC_CAMSS_CSI1PIX_CLK                  98
+#define GCC_CAMSS_CSI1RDI_CLK                  99
+#define GCC_CAMSS_CSI_VFE0_CLK                 100
+#define GCC_CAMSS_GP0_CLK                      101
+#define GCC_CAMSS_GP1_CLK                      102
+#define GCC_CAMSS_ISPIF_AHB_CLK                        103
+#define GCC_CAMSS_MCLK0_CLK                    104
+#define GCC_CAMSS_MCLK1_CLK                    105
+#define GCC_CAMSS_TOP_AHB_CLK                  106
+#define GCC_CAMSS_VFE0_CLK                     107
+#define GCC_CAMSS_VFE_AHB_CLK                  108
+#define GCC_CAMSS_VFE_AXI_CLK                  109
+#define GCC_CODEC_DIGCODEC_CLK                 110
+#define GCC_GP1_CLK                            111
+#define GCC_GP2_CLK                            112
+#define GCC_GP3_CLK                            113
+#define GCC_MDSS_AHB_CLK                       114
+#define GCC_MDSS_AXI_CLK                       115
+#define GCC_MDSS_BYTE0_CLK                     116
+#define GCC_MDSS_ESC0_CLK                      117
+#define GCC_MDSS_MDP_CLK                       118
+#define GCC_MDSS_PCLK0_CLK                     119
+#define GCC_MDSS_VSYNC_CLK                     120
+#define GCC_MSS_CFG_AHB_CLK                    121
+#define GCC_MSS_Q6_BIMC_AXI_CLK                        122
+#define GCC_OXILI_AHB_CLK                      123
+#define GCC_OXILI_GFX3D_CLK                    124
+#define GCC_PDM2_CLK                           125
+#define GCC_PDM_AHB_CLK                                126
+#define GCC_SDCC1_AHB_CLK                      127
+#define GCC_SDCC1_APPS_CLK                     128
+#define GCC_SDCC2_AHB_CLK                      129
+#define GCC_SDCC2_APPS_CLK                     130
+#define GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK    131
+#define GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_LPM_CLK        132
+#define GCC_ULTAUDIO_AVSYNC_XO_CLK             133
+#define GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK         134
+#define GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK         135
+#define GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK         136
+#define GCC_ULTAUDIO_PCNOC_MPORT_CLK           137
+#define GCC_ULTAUDIO_PCNOC_SWAY_CLK            138
+#define GCC_ULTAUDIO_STC_XO_CLK                        139
+#define GCC_USB2A_PHY_SLEEP_CLK                        140
+#define GCC_USB_HS_AHB_CLK                     141
+#define GCC_USB_HS_PHY_CFG_AHB_CLK             142
+#define GCC_USB_HS_SYSTEM_CLK                  143
+#define GCC_VENUS0_AHB_CLK                     144
+#define GCC_VENUS0_AXI_CLK                     145
+#define GCC_VENUS0_CORE0_VCODEC0_CLK           146
+#define GCC_VENUS0_VCODEC0_CLK                 147
+
+/* Resets */
+#define GCC_AUDIO_CORE_BCR                     0
+#define GCC_BLSP1_BCR                          1
+#define GCC_BLSP1_QUP1_BCR                     2
+#define GCC_BLSP1_QUP2_BCR                     3
+#define GCC_BLSP1_QUP3_BCR                     4
+#define GCC_BLSP1_QUP4_BCR                     5
+#define GCC_BLSP1_QUP5_BCR                     6
+#define GCC_BLSP1_QUP6_BCR                     7
+#define GCC_BLSP1_UART1_BCR                    8
+#define GCC_BLSP1_UART2_BCR                    9
+#define GCC_CAMSS_CSI0_BCR                     10
+#define GCC_CAMSS_CSI0PHY_BCR                  11
+#define GCC_CAMSS_CSI0PIX_BCR                  12
+#define GCC_CAMSS_CSI0RDI_BCR                  13
+#define GCC_CAMSS_CSI1_BCR                     14
+#define GCC_CAMSS_CSI1PHY_BCR                  15
+#define GCC_CAMSS_CSI1PIX_BCR                  16
+#define GCC_CAMSS_CSI1RDI_BCR                  17
+#define GCC_CAMSS_CSI_VFE0_BCR                 18
+#define GCC_CAMSS_GP0_BCR                      19
+#define GCC_CAMSS_GP1_BCR                      20
+#define GCC_CAMSS_ISPIF_BCR                    21
+#define GCC_CAMSS_MCLK0_BCR                    22
+#define GCC_CAMSS_MCLK1_BCR                    23
+#define GCC_CAMSS_PHY0_BCR                     24
+#define GCC_CAMSS_TOP_BCR                      25
+#define GCC_CAMSS_TOP_AHB_BCR                  26
+#define GCC_CAMSS_VFE_BCR                      27
+#define GCC_CRYPTO_BCR                         28
+#define GCC_MDSS_BCR                           29
+#define GCC_OXILI_BCR                          30
+#define GCC_PDM_BCR                            31
+#define GCC_PRNG_BCR                           32
+#define GCC_QUSB2_PHY_BCR                      33
+#define GCC_SDCC1_BCR                          34
+#define GCC_SDCC2_BCR                          35
+#define GCC_ULT_AUDIO_BCR                      36
+#define GCC_USB2A_PHY_BCR                      37
+#define GCC_USB2_HS_PHY_ONLY_BCR               38
+#define GCC_USB_HS_BCR                         39
+#define GCC_VENUS0_BCR                         40
+
+/* Subsystem Restart */
+#define GCC_MSS_RESTART                                41
+
+/* Power Domains */
+#define MDSS_GDSC                              0
+#define OXILI_GDSC                             1
+#define VENUS_GDSC                             2
+#define VENUS_CORE0_GDSC                       3
+#define VFE_GDSC                               4
+
+#endif
index 968fa65..d78b899 100644 (file)
 #define GCC_QSPI_CNOC_PERIPH_AHB_CLK                           189
 #define GCC_LPASS_Q6_AXI_CLK                                   190
 #define GCC_LPASS_SWAY_CLK                                     191
+#define GPLL6                                                  192
 
 /* GCC Resets */
 #define GCC_MMSS_BCR                                           0
diff --git a/include/dt-bindings/clock/qcom,gpucc-sc8280xp.h b/include/dt-bindings/clock/qcom,gpucc-sc8280xp.h
new file mode 100644 (file)
index 0000000..bb7da46
--- /dev/null
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SC8280XP_H
+#define _DT_BINDINGS_CLK_QCOM_GPU_CC_SC8280XP_H
+
+/* GPU_CC clocks */
+#define GPU_CC_PLL0                                            0
+#define GPU_CC_PLL1                                            1
+#define GPU_CC_AHB_CLK                                         2
+#define GPU_CC_CB_CLK                                          3
+#define GPU_CC_CRC_AHB_CLK                                     4
+#define GPU_CC_CX_GMU_CLK                                      5
+#define GPU_CC_CX_SNOC_DVM_CLK                                 6
+#define GPU_CC_CXO_AON_CLK                                     7
+#define GPU_CC_CXO_CLK                                         8
+#define GPU_CC_FREQ_MEASURE_CLK                                        9
+#define GPU_CC_GMU_CLK_SRC                                     10
+#define GPU_CC_GX_GMU_CLK                                      11
+#define GPU_CC_GX_VSENSE_CLK                                   12
+#define GPU_CC_HUB_AHB_DIV_CLK_SRC                             13
+#define GPU_CC_HUB_AON_CLK                                     14
+#define GPU_CC_HUB_CLK_SRC                                     15
+#define GPU_CC_HUB_CX_INT_CLK                                  16
+#define GPU_CC_HUB_CX_INT_DIV_CLK_SRC                          17
+#define GPU_CC_SLEEP_CLK                                       18
+#define GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK                         19
+
+/* GPU_CC power domains */
+#define GPU_CC_CX_GDSC                         0
+#define GPU_CC_GX_GDSC                         1
+
+#endif
index 25b92bb..e0fb4ac 100644 (file)
@@ -19,4 +19,6 @@
 #define SPDIF_CLK                      10
 #define AHBIX_CLK                      11
 
+#define LCC_PCM_RESET                  0
+
 #endif
index 20ef2ea..22dcd47 100644 (file)
 #define LPASS_AUDIO_CC_RX_MCLK_CLK                     14
 #define LPASS_AUDIO_CC_RX_MCLK_CLK_SRC                 15
 
+/* LPASS AUDIO CC CSR */
+#define LPASS_AUDIO_SWR_RX_CGCR                                0
+#define LPASS_AUDIO_SWR_TX_CGCR                                1
+#define LPASS_AUDIO_SWR_WSA_CGCR                       2
+
 /* LPASS_AON_CC clocks */
 #define LPASS_AON_CC_PLL                               0
 #define LPASS_AON_CC_PLL_OUT_EVEN                      1
index 28ed2a0..0324c69 100644 (file)
@@ -19,6 +19,8 @@
 #define LPASS_CORE_CC_LPM_CORE_CLK                     9
 #define LPASS_CORE_CC_LPM_MEM0_CORE_CLK                        10
 #define LPASS_CORE_CC_SYSNOC_MPORT_CORE_CLK            11
+#define LPASS_CORE_CC_EXT_MCLK0_CLK                    12
+#define LPASS_CORE_CC_EXT_MCLK0_CLK_SRC                        13
 
 /* LPASS_CORE_CC power domains */
 #define LPASS_CORE_CC_LPASS_CORE_HM_GDSC               0
index 015db95..c0ad624 100644 (file)
 #define RPM_SMD_CPUSS_GNOC_A_CLK               121
 #define RPM_SMD_MSS_CFG_AHB_CLK                122
 #define RPM_SMD_MSS_CFG_AHB_A_CLK              123
+#define RPM_SMD_BIMC_FREQ_LOG                  124
 
 #endif
diff --git a/include/dt-bindings/clock/qcom,sm6115-dispcc.h b/include/dt-bindings/clock/qcom,sm6115-dispcc.h
new file mode 100644 (file)
index 0000000..d1a6c45
--- /dev/null
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2022, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_DISP_CC_SM6115_H
+#define _DT_BINDINGS_CLK_QCOM_DISP_CC_SM6115_H
+
+/* DISP_CC clocks */
+#define DISP_CC_PLL0                   0
+#define DISP_CC_PLL0_OUT_MAIN          1
+#define DISP_CC_MDSS_AHB_CLK           2
+#define DISP_CC_MDSS_AHB_CLK_SRC       3
+#define DISP_CC_MDSS_BYTE0_CLK         4
+#define DISP_CC_MDSS_BYTE0_CLK_SRC     5
+#define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC 6
+#define DISP_CC_MDSS_BYTE0_INTF_CLK    7
+#define DISP_CC_MDSS_ESC0_CLK          8
+#define DISP_CC_MDSS_ESC0_CLK_SRC      9
+#define DISP_CC_MDSS_MDP_CLK           10
+#define DISP_CC_MDSS_MDP_CLK_SRC       11
+#define DISP_CC_MDSS_MDP_LUT_CLK       12
+#define DISP_CC_MDSS_NON_GDSC_AHB_CLK  13
+#define DISP_CC_MDSS_PCLK0_CLK         14
+#define DISP_CC_MDSS_PCLK0_CLK_SRC     15
+#define DISP_CC_MDSS_ROT_CLK           16
+#define DISP_CC_MDSS_ROT_CLK_SRC       17
+#define DISP_CC_MDSS_VSYNC_CLK         18
+#define DISP_CC_MDSS_VSYNC_CLK_SRC     19
+#define DISP_CC_SLEEP_CLK              20
+#define DISP_CC_SLEEP_CLK_SRC          21
+
+/* DISP_CC GDSCR */
+#define MDSS_GDSC                      0
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,sm6375-gcc.h b/include/dt-bindings/clock/qcom,sm6375-gcc.h
new file mode 100644 (file)
index 0000000..1e9801e
--- /dev/null
@@ -0,0 +1,234 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022, Konrad Dybcio <konrad.dybcio@somainline.org>
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SM6375_H
+#define _DT_BINDINGS_CLK_QCOM_GCC_SM6375_H
+
+/* Clocks */
+#define GPLL0                                          0
+#define GPLL0_OUT_EVEN                                 1
+#define GPLL0_OUT_ODD                                  2
+#define GPLL1                                          3
+#define GPLL10                                         4
+#define GPLL11                                         5
+#define GPLL3                                          6
+#define GPLL3_OUT_EVEN                                 7
+#define GPLL4                                          8
+#define GPLL5                                          9
+#define GPLL6                                          10
+#define GPLL6_OUT_EVEN                                 11
+#define GPLL7                                          12
+#define GPLL8                                          13
+#define GPLL8_OUT_EVEN                                 14
+#define GPLL9                                          15
+#define GPLL9_OUT_MAIN                                 16
+#define GCC_AHB2PHY_CSI_CLK                            17
+#define GCC_AHB2PHY_USB_CLK                            18
+#define GCC_BIMC_GPU_AXI_CLK                           19
+#define GCC_BOOT_ROM_AHB_CLK                           20
+#define GCC_CAM_THROTTLE_NRT_CLK                       21
+#define GCC_CAM_THROTTLE_RT_CLK                                22
+#define GCC_CAMERA_AHB_CLK                             23
+#define GCC_CAMERA_XO_CLK                              24
+#define GCC_CAMSS_AXI_CLK                              25
+#define GCC_CAMSS_AXI_CLK_SRC                          26
+#define GCC_CAMSS_CAMNOC_ATB_CLK                       27
+#define GCC_CAMSS_CAMNOC_NTS_XO_CLK                    28
+#define GCC_CAMSS_CCI_0_CLK                            29
+#define GCC_CAMSS_CCI_0_CLK_SRC                                30
+#define GCC_CAMSS_CCI_1_CLK                            31
+#define GCC_CAMSS_CCI_1_CLK_SRC                                32
+#define GCC_CAMSS_CPHY_0_CLK                           33
+#define GCC_CAMSS_CPHY_1_CLK                           34
+#define GCC_CAMSS_CPHY_2_CLK                           35
+#define GCC_CAMSS_CPHY_3_CLK                           36
+#define GCC_CAMSS_CSI0PHYTIMER_CLK                     37
+#define GCC_CAMSS_CSI0PHYTIMER_CLK_SRC                 38
+#define GCC_CAMSS_CSI1PHYTIMER_CLK                     39
+#define GCC_CAMSS_CSI1PHYTIMER_CLK_SRC                 40
+#define GCC_CAMSS_CSI2PHYTIMER_CLK                     41
+#define GCC_CAMSS_CSI2PHYTIMER_CLK_SRC                 42
+#define GCC_CAMSS_CSI3PHYTIMER_CLK                     43
+#define GCC_CAMSS_CSI3PHYTIMER_CLK_SRC                 44
+#define GCC_CAMSS_MCLK0_CLK                            45
+#define GCC_CAMSS_MCLK0_CLK_SRC                                46
+#define GCC_CAMSS_MCLK1_CLK                            47
+#define GCC_CAMSS_MCLK1_CLK_SRC                                48
+#define GCC_CAMSS_MCLK2_CLK                            49
+#define GCC_CAMSS_MCLK2_CLK_SRC                                50
+#define GCC_CAMSS_MCLK3_CLK                            51
+#define GCC_CAMSS_MCLK3_CLK_SRC                                52
+#define GCC_CAMSS_MCLK4_CLK                            53
+#define GCC_CAMSS_MCLK4_CLK_SRC                                54
+#define GCC_CAMSS_NRT_AXI_CLK                          55
+#define GCC_CAMSS_OPE_AHB_CLK                          56
+#define GCC_CAMSS_OPE_AHB_CLK_SRC                      57
+#define GCC_CAMSS_OPE_CLK                              58
+#define GCC_CAMSS_OPE_CLK_SRC                          59
+#define GCC_CAMSS_RT_AXI_CLK                           60
+#define GCC_CAMSS_TFE_0_CLK                            61
+#define GCC_CAMSS_TFE_0_CLK_SRC                                62
+#define GCC_CAMSS_TFE_0_CPHY_RX_CLK                    63
+#define GCC_CAMSS_TFE_0_CSID_CLK                       64
+#define GCC_CAMSS_TFE_0_CSID_CLK_SRC                   65
+#define GCC_CAMSS_TFE_1_CLK                            66
+#define GCC_CAMSS_TFE_1_CLK_SRC                                67
+#define GCC_CAMSS_TFE_1_CPHY_RX_CLK                    68
+#define GCC_CAMSS_TFE_1_CSID_CLK                       69
+#define GCC_CAMSS_TFE_1_CSID_CLK_SRC                   70
+#define GCC_CAMSS_TFE_2_CLK                            71
+#define GCC_CAMSS_TFE_2_CLK_SRC                                72
+#define GCC_CAMSS_TFE_2_CPHY_RX_CLK                    73
+#define GCC_CAMSS_TFE_2_CSID_CLK                       74
+#define GCC_CAMSS_TFE_2_CSID_CLK_SRC                   75
+#define GCC_CAMSS_TFE_CPHY_RX_CLK_SRC                  76
+#define GCC_CAMSS_TOP_AHB_CLK                          77
+#define GCC_CAMSS_TOP_AHB_CLK_SRC                      78
+#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK                  79
+#define GCC_CPUSS_AHB_CLK_SRC                          80
+#define GCC_CPUSS_AHB_POSTDIV_CLK_SRC                  81
+#define GCC_CPUSS_GNOC_CLK                             82
+#define GCC_DISP_AHB_CLK                               83
+#define GCC_DISP_GPLL0_CLK_SRC                         84
+#define GCC_DISP_GPLL0_DIV_CLK_SRC                     85
+#define GCC_DISP_HF_AXI_CLK                            86
+#define GCC_DISP_SLEEP_CLK                             87
+#define GCC_DISP_THROTTLE_CORE_CLK                     88
+#define GCC_DISP_XO_CLK                                        89
+#define GCC_GP1_CLK                                    90
+#define GCC_GP1_CLK_SRC                                        91
+#define GCC_GP2_CLK                                    92
+#define GCC_GP2_CLK_SRC                                        93
+#define GCC_GP3_CLK                                    94
+#define GCC_GP3_CLK_SRC                                        95
+#define GCC_GPU_CFG_AHB_CLK                            96
+#define GCC_GPU_GPLL0_CLK_SRC                          97
+#define GCC_GPU_GPLL0_DIV_CLK_SRC                      98
+#define GCC_GPU_MEMNOC_GFX_CLK                         99
+#define GCC_GPU_SNOC_DVM_GFX_CLK                       100
+#define GCC_GPU_THROTTLE_CORE_CLK                      101
+#define GCC_PDM2_CLK                                   102
+#define GCC_PDM2_CLK_SRC                               103
+#define GCC_PDM_AHB_CLK                                        104
+#define GCC_PDM_XO4_CLK                                        105
+#define GCC_PRNG_AHB_CLK                               106
+#define GCC_QMIP_CAMERA_NRT_AHB_CLK                    107
+#define GCC_QMIP_CAMERA_RT_AHB_CLK                     108
+#define GCC_QMIP_DISP_AHB_CLK                          109
+#define GCC_QMIP_GPU_CFG_AHB_CLK                       110
+#define GCC_QMIP_VIDEO_VCODEC_AHB_CLK                  111
+#define GCC_QUPV3_WRAP0_CORE_2X_CLK                    112
+#define GCC_QUPV3_WRAP0_CORE_CLK                       113
+#define GCC_QUPV3_WRAP0_S0_CLK                         114
+#define GCC_QUPV3_WRAP0_S0_CLK_SRC                     115
+#define GCC_QUPV3_WRAP0_S1_CLK                         116
+#define GCC_QUPV3_WRAP0_S1_CLK_SRC                     117
+#define GCC_QUPV3_WRAP0_S2_CLK                         118
+#define GCC_QUPV3_WRAP0_S2_CLK_SRC                     119
+#define GCC_QUPV3_WRAP0_S3_CLK                         120
+#define GCC_QUPV3_WRAP0_S3_CLK_SRC                     121
+#define GCC_QUPV3_WRAP0_S4_CLK                         122
+#define GCC_QUPV3_WRAP0_S4_CLK_SRC                     123
+#define GCC_QUPV3_WRAP0_S5_CLK                         124
+#define GCC_QUPV3_WRAP0_S5_CLK_SRC                     125
+#define GCC_QUPV3_WRAP1_CORE_2X_CLK                    126
+#define GCC_QUPV3_WRAP1_CORE_CLK                       127
+#define GCC_QUPV3_WRAP1_S0_CLK                         128
+#define GCC_QUPV3_WRAP1_S0_CLK_SRC                     129
+#define GCC_QUPV3_WRAP1_S1_CLK                         130
+#define GCC_QUPV3_WRAP1_S1_CLK_SRC                     131
+#define GCC_QUPV3_WRAP1_S2_CLK                         132
+#define GCC_QUPV3_WRAP1_S2_CLK_SRC                     133
+#define GCC_QUPV3_WRAP1_S3_CLK                         134
+#define GCC_QUPV3_WRAP1_S3_CLK_SRC                     135
+#define GCC_QUPV3_WRAP1_S4_CLK                         136
+#define GCC_QUPV3_WRAP1_S4_CLK_SRC                     137
+#define GCC_QUPV3_WRAP1_S5_CLK                         138
+#define GCC_QUPV3_WRAP1_S5_CLK_SRC                     139
+#define GCC_QUPV3_WRAP_0_M_AHB_CLK                     140
+#define GCC_QUPV3_WRAP_0_S_AHB_CLK                     141
+#define GCC_QUPV3_WRAP_1_M_AHB_CLK                     142
+#define GCC_QUPV3_WRAP_1_S_AHB_CLK                     143
+#define GCC_RX5_PCIE_CLKREF_EN_CLK                     144
+#define GCC_SDCC1_AHB_CLK                              145
+#define GCC_SDCC1_APPS_CLK                             146
+#define GCC_SDCC1_APPS_CLK_SRC                         147
+#define GCC_SDCC1_ICE_CORE_CLK                         148
+#define GCC_SDCC1_ICE_CORE_CLK_SRC                     149
+#define GCC_SDCC2_AHB_CLK                              150
+#define GCC_SDCC2_APPS_CLK                             151
+#define GCC_SDCC2_APPS_CLK_SRC                         152
+#define GCC_SYS_NOC_CPUSS_AHB_CLK                      153
+#define GCC_SYS_NOC_UFS_PHY_AXI_CLK                    154
+#define GCC_SYS_NOC_USB3_PRIM_AXI_CLK                  155
+#define GCC_UFS_MEM_CLKREF_CLK                         156
+#define GCC_UFS_PHY_AHB_CLK                            157
+#define GCC_UFS_PHY_AXI_CLK                            158
+#define GCC_UFS_PHY_AXI_CLK_SRC                                159
+#define GCC_UFS_PHY_ICE_CORE_CLK                       160
+#define GCC_UFS_PHY_ICE_CORE_CLK_SRC                   161
+#define GCC_UFS_PHY_PHY_AUX_CLK                                162
+#define GCC_UFS_PHY_PHY_AUX_CLK_SRC                    163
+#define GCC_UFS_PHY_RX_SYMBOL_0_CLK                    164
+#define GCC_UFS_PHY_TX_SYMBOL_0_CLK                    165
+#define GCC_UFS_PHY_UNIPRO_CORE_CLK                    166
+#define GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC                        167
+#define GCC_USB30_PRIM_MASTER_CLK                      168
+#define GCC_USB30_PRIM_MASTER_CLK_SRC                  169
+#define GCC_USB30_PRIM_MOCK_UTMI_CLK                   170
+#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC               171
+#define GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC       172
+#define GCC_USB30_PRIM_SLEEP_CLK                       173
+#define GCC_USB3_PRIM_CLKREF_CLK                       174
+#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC                  175
+#define GCC_USB3_PRIM_PHY_COM_AUX_CLK                  176
+#define GCC_USB3_PRIM_PHY_PIPE_CLK                     177
+#define GCC_VCODEC0_AXI_CLK                            178
+#define GCC_VENUS_AHB_CLK                              179
+#define GCC_VENUS_CTL_AXI_CLK                          180
+#define GCC_VIDEO_AHB_CLK                              181
+#define GCC_VIDEO_AXI0_CLK                             182
+#define GCC_VIDEO_THROTTLE_CORE_CLK                    183
+#define GCC_VIDEO_VCODEC0_SYS_CLK                      184
+#define GCC_VIDEO_VENUS_CLK_SRC                                185
+#define GCC_VIDEO_VENUS_CTL_CLK                                186
+#define GCC_VIDEO_XO_CLK                               187
+
+/* Resets */
+#define GCC_CAMSS_OPE_BCR                              0
+#define GCC_CAMSS_TFE_BCR                              1
+#define GCC_CAMSS_TOP_BCR                              2
+#define GCC_GPU_BCR                                    3
+#define GCC_MMSS_BCR                                   4
+#define GCC_PDM_BCR                                    5
+#define GCC_PRNG_BCR                                   6
+#define GCC_QUPV3_WRAPPER_0_BCR                                7
+#define GCC_QUPV3_WRAPPER_1_BCR                                8
+#define GCC_QUSB2PHY_PRIM_BCR                          9
+#define GCC_QUSB2PHY_SEC_BCR                           10
+#define GCC_SDCC1_BCR                                  11
+#define GCC_SDCC2_BCR                                  12
+#define GCC_UFS_PHY_BCR                                        13
+#define GCC_USB30_PRIM_BCR                             14
+#define GCC_USB_PHY_CFG_AHB2PHY_BCR                    15
+#define GCC_VCODEC0_BCR                                        16
+#define GCC_VENUS_BCR                                  17
+#define GCC_VIDEO_INTERFACE_BCR                                18
+#define GCC_USB3_DP_PHY_PRIM_BCR                       19
+#define GCC_USB3_PHY_PRIM_SP0_BCR                      20
+
+/* GDSCs */
+#define USB30_PRIM_GDSC                                        0
+#define UFS_PHY_GDSC                                   1
+#define CAMSS_TOP_GDSC                                 2
+#define VENUS_GDSC                                     3
+#define VCODEC0_GDSC                                   4
+#define HLOS1_VOTE_MM_SNOC_MMU_TBU_NRT_GDSC            5
+#define HLOS1_VOTE_MM_SNOC_MMU_TBU_RT_GDSC             6
+#define HLOS1_VOTE_TURING_MMU_TBU0_GDSC                        7
+#define HLOS1_VOTE_TURING_MMU_TBU1_GDSC                        8
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,sm8450-dispcc.h b/include/dt-bindings/clock/qcom,sm8450-dispcc.h
new file mode 100644 (file)
index 0000000..fd16ca8
--- /dev/null
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2022, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_DISP_CC_SM8450_H
+#define _DT_BINDINGS_CLK_QCOM_DISP_CC_SM8450_H
+
+/* DISP_CC clocks */
+#define DISP_CC_MDSS_AHB1_CLK                                  0
+#define DISP_CC_MDSS_AHB_CLK                                   1
+#define DISP_CC_MDSS_AHB_CLK_SRC                               2
+#define DISP_CC_MDSS_BYTE0_CLK                                 3
+#define DISP_CC_MDSS_BYTE0_CLK_SRC                             4
+#define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC                         5
+#define DISP_CC_MDSS_BYTE0_INTF_CLK                            6
+#define DISP_CC_MDSS_BYTE1_CLK                                 7
+#define DISP_CC_MDSS_BYTE1_CLK_SRC                             8
+#define DISP_CC_MDSS_BYTE1_DIV_CLK_SRC                         9
+#define DISP_CC_MDSS_BYTE1_INTF_CLK                            10
+#define DISP_CC_MDSS_DPTX0_AUX_CLK                             11
+#define DISP_CC_MDSS_DPTX0_AUX_CLK_SRC                         12
+#define DISP_CC_MDSS_DPTX0_CRYPTO_CLK                          13
+#define DISP_CC_MDSS_DPTX0_LINK_CLK                            14
+#define DISP_CC_MDSS_DPTX0_LINK_CLK_SRC                                15
+#define DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC                    16
+#define DISP_CC_MDSS_DPTX0_LINK_INTF_CLK                       17
+#define DISP_CC_MDSS_DPTX0_PIXEL0_CLK                          18
+#define DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC                      19
+#define DISP_CC_MDSS_DPTX0_PIXEL1_CLK                          20
+#define DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC                      21
+#define DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK            22
+#define DISP_CC_MDSS_DPTX1_AUX_CLK                             23
+#define DISP_CC_MDSS_DPTX1_AUX_CLK_SRC                         24
+#define DISP_CC_MDSS_DPTX1_CRYPTO_CLK                          25
+#define DISP_CC_MDSS_DPTX1_LINK_CLK                            26
+#define DISP_CC_MDSS_DPTX1_LINK_CLK_SRC                                27
+#define DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC                    28
+#define DISP_CC_MDSS_DPTX1_LINK_INTF_CLK                       29
+#define DISP_CC_MDSS_DPTX1_PIXEL0_CLK                          30
+#define DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC                      31
+#define DISP_CC_MDSS_DPTX1_PIXEL1_CLK                          32
+#define DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC                      33
+#define DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK            34
+#define DISP_CC_MDSS_DPTX2_AUX_CLK                             35
+#define DISP_CC_MDSS_DPTX2_AUX_CLK_SRC                         36
+#define DISP_CC_MDSS_DPTX2_CRYPTO_CLK                          37
+#define DISP_CC_MDSS_DPTX2_LINK_CLK                            38
+#define DISP_CC_MDSS_DPTX2_LINK_CLK_SRC                                39
+#define DISP_CC_MDSS_DPTX2_LINK_DIV_CLK_SRC                    40
+#define DISP_CC_MDSS_DPTX2_LINK_INTF_CLK                       41
+#define DISP_CC_MDSS_DPTX2_PIXEL0_CLK                          42
+#define DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC                      43
+#define DISP_CC_MDSS_DPTX2_PIXEL1_CLK                          44
+#define DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC                      45
+#define DISP_CC_MDSS_DPTX3_AUX_CLK                             46
+#define DISP_CC_MDSS_DPTX3_AUX_CLK_SRC                         47
+#define DISP_CC_MDSS_DPTX3_CRYPTO_CLK                          48
+#define DISP_CC_MDSS_DPTX3_LINK_CLK                            49
+#define DISP_CC_MDSS_DPTX3_LINK_CLK_SRC                                50
+#define DISP_CC_MDSS_DPTX3_LINK_DIV_CLK_SRC                    51
+#define DISP_CC_MDSS_DPTX3_LINK_INTF_CLK                       52
+#define DISP_CC_MDSS_DPTX3_PIXEL0_CLK                          53
+#define DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC                      54
+#define DISP_CC_MDSS_ESC0_CLK                                  55
+#define DISP_CC_MDSS_ESC0_CLK_SRC                              56
+#define DISP_CC_MDSS_ESC1_CLK                                  57
+#define DISP_CC_MDSS_ESC1_CLK_SRC                              58
+#define DISP_CC_MDSS_MDP1_CLK                                  59
+#define DISP_CC_MDSS_MDP_CLK                                   60
+#define DISP_CC_MDSS_MDP_CLK_SRC                               61
+#define DISP_CC_MDSS_MDP_LUT1_CLK                              62
+#define DISP_CC_MDSS_MDP_LUT_CLK                               63
+#define DISP_CC_MDSS_NON_GDSC_AHB_CLK                          64
+#define DISP_CC_MDSS_PCLK0_CLK                                 65
+#define DISP_CC_MDSS_PCLK0_CLK_SRC                             66
+#define DISP_CC_MDSS_PCLK1_CLK                                 67
+#define DISP_CC_MDSS_PCLK1_CLK_SRC                             68
+#define DISP_CC_MDSS_ROT1_CLK                                  69
+#define DISP_CC_MDSS_ROT_CLK                                   70
+#define DISP_CC_MDSS_ROT_CLK_SRC                               71
+#define DISP_CC_MDSS_RSCC_AHB_CLK                              72
+#define DISP_CC_MDSS_RSCC_VSYNC_CLK                            73
+#define DISP_CC_MDSS_VSYNC1_CLK                                        74
+#define DISP_CC_MDSS_VSYNC_CLK                                 75
+#define DISP_CC_MDSS_VSYNC_CLK_SRC                             76
+#define DISP_CC_PLL0                                           77
+#define DISP_CC_PLL1                                           78
+#define DISP_CC_SLEEP_CLK                                      79
+#define DISP_CC_SLEEP_CLK_SRC                                  80
+#define DISP_CC_XO_CLK                                         81
+#define DISP_CC_XO_CLK_SRC                                     82
+
+/* DISP_CC resets */
+#define DISP_CC_MDSS_CORE_BCR                                  0
+#define DISP_CC_MDSS_CORE_INT2_BCR                             1
+#define DISP_CC_MDSS_RSCC_BCR                                  2
+
+/* DISP_CC GDSCR */
+#define MDSS_GDSC                              0
+#define MDSS_INT2_GDSC                         1
+
+#endif
diff --git a/include/dt-bindings/clock/rockchip,rv1126-cru.h b/include/dt-bindings/clock/rockchip,rv1126-cru.h
new file mode 100644 (file)
index 0000000..e89a3a5
--- /dev/null
@@ -0,0 +1,632 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2019 Rockchip Electronics Co. Ltd.
+ * Author: Finley Xiao <finley.xiao@rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RV1126_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RV1126_H
+
+/* pmucru-clocks indices */
+
+/* pll clocks */
+#define PLL_GPLL               1
+
+/* sclk (special clocks) */
+#define CLK_OSC0_DIV32K                2
+#define CLK_RTC32K             3
+#define CLK_WIFI_DIV           4
+#define CLK_WIFI_OSC0          5
+#define CLK_WIFI               6
+#define CLK_PMU                        7
+#define SCLK_UART1_DIV         8
+#define SCLK_UART1_FRACDIV     9
+#define SCLK_UART1_MUX         10
+#define SCLK_UART1             11
+#define CLK_I2C0               12
+#define CLK_I2C2               13
+#define CLK_CAPTURE_PWM0       14
+#define CLK_PWM0               15
+#define CLK_CAPTURE_PWM1       16
+#define CLK_PWM1               17
+#define CLK_SPI0               18
+#define DBCLK_GPIO0            19
+#define CLK_PMUPVTM            20
+#define CLK_CORE_PMUPVTM       21
+#define CLK_REF12M             22
+#define CLK_USBPHY_OTG_REF     23
+#define CLK_USBPHY_HOST_REF    24
+#define CLK_REF24M             25
+#define CLK_MIPIDSIPHY_REF     26
+
+/* pclk */
+#define PCLK_PDPMU             30
+#define PCLK_PMU               31
+#define PCLK_UART1             32
+#define PCLK_I2C0              33
+#define PCLK_I2C2              34
+#define PCLK_PWM0              35
+#define PCLK_PWM1              36
+#define PCLK_SPI0              37
+#define PCLK_GPIO0             38
+#define PCLK_PMUSGRF           39
+#define PCLK_PMUGRF            40
+#define PCLK_PMUCRU            41
+#define PCLK_CHIPVEROTP                42
+#define PCLK_PDPMU_NIU         43
+#define PCLK_PMUPVTM           44
+#define PCLK_SCRKEYGEN         45
+
+#define CLKPMU_NR_CLKS         (PCLK_SCRKEYGEN + 1)
+
+/* cru-clocks indices */
+
+/* pll clocks */
+#define PLL_APLL               1
+#define PLL_DPLL               2
+#define PLL_CPLL               3
+#define PLL_HPLL               4
+
+/* sclk (special clocks) */
+#define ARMCLK                 5
+#define USB480M                        6
+#define CLK_CORE_CPUPVTM       7
+#define CLK_CPUPVTM            8
+#define CLK_SCR1               9
+#define CLK_SCR1_CORE          10
+#define CLK_SCR1_RTC           11
+#define CLK_SCR1_JTAG          12
+#define SCLK_UART0_DIV         13
+#define SCLK_UART0_FRAC                14
+#define SCLK_UART0_MUX         15
+#define SCLK_UART0             16
+#define SCLK_UART2_DIV         17
+#define SCLK_UART2_FRAC                18
+#define SCLK_UART2_MUX         19
+#define SCLK_UART2             20
+#define SCLK_UART3_DIV         21
+#define SCLK_UART3_FRAC                22
+#define SCLK_UART3_MUX         23
+#define SCLK_UART3             24
+#define SCLK_UART4_DIV         25
+#define SCLK_UART4_FRAC                26
+#define SCLK_UART4_MUX         27
+#define SCLK_UART4             28
+#define SCLK_UART5_DIV         29
+#define SCLK_UART5_FRAC                30
+#define SCLK_UART5_MUX         31
+#define SCLK_UART5             32
+#define CLK_I2C1               33
+#define CLK_I2C3               34
+#define CLK_I2C4               35
+#define CLK_I2C5               36
+#define CLK_SPI1               37
+#define CLK_CAPTURE_PWM2       38
+#define CLK_PWM2               39
+#define DBCLK_GPIO1            40
+#define DBCLK_GPIO2            41
+#define DBCLK_GPIO3            42
+#define DBCLK_GPIO4            43
+#define CLK_SARADC             44
+#define CLK_TIMER0             45
+#define CLK_TIMER1             46
+#define CLK_TIMER2             47
+#define CLK_TIMER3             48
+#define CLK_TIMER4             49
+#define CLK_TIMER5             50
+#define CLK_CAN                        51
+#define CLK_NPU_TSADC          52
+#define CLK_NPU_TSADCPHY       53
+#define CLK_CPU_TSADC          54
+#define CLK_CPU_TSADCPHY       55
+#define CLK_CRYPTO_CORE                56
+#define CLK_CRYPTO_PKA         57
+#define MCLK_I2S0_TX_DIV       58
+#define MCLK_I2S0_TX_FRACDIV   59
+#define MCLK_I2S0_TX_MUX       60
+#define MCLK_I2S0_TX           61
+#define MCLK_I2S0_RX_DIV       62
+#define MCLK_I2S0_RX_FRACDIV   63
+#define MCLK_I2S0_RX_MUX       64
+#define MCLK_I2S0_RX           65
+#define MCLK_I2S0_TX_OUT2IO    66
+#define MCLK_I2S0_RX_OUT2IO    67
+#define MCLK_I2S1_DIV          68
+#define MCLK_I2S1_FRACDIV      69
+#define MCLK_I2S1_MUX          70
+#define MCLK_I2S1              71
+#define MCLK_I2S1_OUT2IO       72
+#define MCLK_I2S2_DIV          73
+#define MCLK_I2S2_FRACDIV      74
+#define MCLK_I2S2_MUX          75
+#define MCLK_I2S2              76
+#define MCLK_I2S2_OUT2IO       77
+#define MCLK_PDM               78
+#define SCLK_ADUPWM_DIV                79
+#define SCLK_AUDPWM_FRACDIV    80
+#define SCLK_AUDPWM_MUX                81
+#define        SCLK_AUDPWM             82
+#define CLK_ACDCDIG_ADC                83
+#define CLK_ACDCDIG_DAC                84
+#define CLK_ACDCDIG_I2C                85
+#define CLK_VENC_CORE          86
+#define CLK_VDEC_CORE          87
+#define CLK_VDEC_CA            88
+#define CLK_VDEC_HEVC_CA       89
+#define CLK_RGA_CORE           90
+#define CLK_IEP_CORE           91
+#define CLK_ISP_DIV            92
+#define CLK_ISP_NP5            93
+#define CLK_ISP_NUX            94
+#define CLK_ISP                        95
+#define CLK_CIF_OUT_DIV                96
+#define CLK_CIF_OUT_FRACDIV    97
+#define CLK_CIF_OUT_MUX                98
+#define CLK_CIF_OUT            99
+#define CLK_MIPICSI_OUT_DIV    100
+#define CLK_MIPICSI_OUT_FRACDIV        101
+#define CLK_MIPICSI_OUT_MUX    102
+#define CLK_MIPICSI_OUT                103
+#define CLK_ISPP_DIV           104
+#define CLK_ISPP_NP5           105
+#define CLK_ISPP_NUX           106
+#define CLK_ISPP               107
+#define CLK_SDMMC              108
+#define SCLK_SDMMC_DRV         109
+#define SCLK_SDMMC_SAMPLE      110
+#define CLK_SDIO               111
+#define SCLK_SDIO_DRV          112
+#define SCLK_SDIO_SAMPLE       113
+#define CLK_EMMC               114
+#define SCLK_EMMC_DRV          115
+#define SCLK_EMMC_SAMPLE       116
+#define CLK_NANDC              117
+#define SCLK_SFC               118
+#define CLK_USBHOST_UTMI_OHCI  119
+#define CLK_USBOTG_REF         120
+#define CLK_GMAC_DIV           121
+#define CLK_GMAC_RGMII_M0      122
+#define CLK_GMAC_SRC_M0                123
+#define CLK_GMAC_RGMII_M1      124
+#define CLK_GMAC_SRC_M1                125
+#define CLK_GMAC_SRC           126
+#define CLK_GMAC_REF           127
+#define CLK_GMAC_TX_SRC                128
+#define CLK_GMAC_TX_DIV5       129
+#define CLK_GMAC_TX_DIV50      130
+#define RGMII_MODE_CLK         131
+#define CLK_GMAC_RX_SRC                132
+#define CLK_GMAC_RX_DIV2       133
+#define CLK_GMAC_RX_DIV20      134
+#define RMII_MODE_CLK          135
+#define CLK_GMAC_TX_RX         136
+#define CLK_GMAC_PTPREF                137
+#define CLK_GMAC_ETHERNET_OUT  138
+#define CLK_DDRPHY             139
+#define CLK_DDR_MON            140
+#define TMCLK_DDR_MON          141
+#define CLK_NPU_DIV            142
+#define CLK_NPU_NP5            143
+#define CLK_CORE_NPU           144
+#define CLK_CORE_NPUPVTM       145
+#define CLK_NPUPVTM            146
+#define SCLK_DDRCLK            147
+#define CLK_OTP                        148
+
+/* dclk */
+#define DCLK_DECOM             150
+#define DCLK_VOP_DIV           151
+#define DCLK_VOP_FRACDIV       152
+#define DCLK_VOP_MUX           153
+#define DCLK_VOP               154
+#define DCLK_CIF               155
+#define DCLK_CIFLITE           156
+
+/* aclk */
+#define ACLK_PDBUS             160
+#define ACLK_DMAC              161
+#define ACLK_DCF               162
+#define ACLK_SPINLOCK          163
+#define ACLK_DECOM             164
+#define ACLK_PDCRYPTO          165
+#define ACLK_CRYPTO            166
+#define ACLK_PDVEPU            167
+#define ACLK_VENC              168
+#define ACLK_PDVDEC            169
+#define ACLK_PDJPEG            170
+#define ACLK_VDEC              171
+#define ACLK_JPEG              172
+#define ACLK_PDVO              173
+#define ACLK_RGA               174
+#define ACLK_VOP               175
+#define ACLK_IEP               176
+#define ACLK_PDVI_DIV          177
+#define ACLK_PDVI_NP5          178
+#define ACLK_PDVI              179
+#define ACLK_ISP               180
+#define ACLK_CIF               181
+#define ACLK_CIFLITE           182
+#define ACLK_PDISPP_DIV                183
+#define ACLK_PDISPP_NP5                184
+#define ACLK_PDISPP            185
+#define ACLK_ISPP              186
+#define ACLK_PDPHP             187
+#define ACLK_PDUSB             188
+#define ACLK_USBOTG            189
+#define ACLK_PDGMAC            190
+#define ACLK_GMAC              191
+#define ACLK_PDNPU_DIV         192
+#define ACLK_PDNPU_NP5         193
+#define ACLK_PDNPU             194
+#define ACLK_NPU               195
+
+/* hclk */
+#define HCLK_PDCORE_NIU                200
+#define HCLK_PDUSB             201
+#define HCLK_PDCRYPTO          202
+#define HCLK_CRYPTO            203
+#define HCLK_PDAUDIO           204
+#define HCLK_I2S0              205
+#define HCLK_I2S1              206
+#define HCLK_I2S2              207
+#define HCLK_PDM               208
+#define HCLK_AUDPWM            209
+#define HCLK_PDVEPU            210
+#define HCLK_VENC              211
+#define HCLK_PDVDEC            212
+#define HCLK_PDJPEG            213
+#define HCLK_VDEC              214
+#define HCLK_JPEG              215
+#define HCLK_PDVO              216
+#define HCLK_RGA               217
+#define HCLK_VOP               218
+#define HCLK_IEP               219
+#define HCLK_PDVI              220
+#define HCLK_ISP               221
+#define HCLK_CIF               222
+#define HCLK_CIFLITE           223
+#define HCLK_PDISPP            224
+#define HCLK_ISPP              225
+#define HCLK_PDPHP             226
+#define HCLK_PDSDMMC           227
+#define HCLK_SDMMC             228
+#define HCLK_PDSDIO            229
+#define HCLK_SDIO              230
+#define HCLK_PDNVM             231
+#define HCLK_EMMC              232
+#define HCLK_NANDC             233
+#define HCLK_SFC               234
+#define HCLK_SFCXIP            235
+#define HCLK_PDBUS             236
+#define HCLK_USBHOST           237
+#define HCLK_USBHOST_ARB       238
+#define HCLK_PDNPU             239
+#define HCLK_NPU               240
+
+/* pclk */
+#define PCLK_CPUPVTM           245
+#define PCLK_PDBUS             246
+#define PCLK_DCF               247
+#define PCLK_WDT               248
+#define PCLK_MAILBOX           249
+#define PCLK_UART0             250
+#define PCLK_UART2             251
+#define PCLK_UART3             252
+#define PCLK_UART4             253
+#define PCLK_UART5             254
+#define PCLK_I2C1              255
+#define PCLK_I2C3              256
+#define PCLK_I2C4              257
+#define PCLK_I2C5              258
+#define PCLK_SPI1              259
+#define PCLK_PWM2              261
+#define PCLK_GPIO1             262
+#define PCLK_GPIO2             263
+#define PCLK_GPIO3             264
+#define PCLK_GPIO4             265
+#define PCLK_SARADC            266
+#define PCLK_TIMER             267
+#define PCLK_DECOM             268
+#define PCLK_CAN               269
+#define PCLK_NPU_TSADC         270
+#define PCLK_CPU_TSADC         271
+#define PCLK_ACDCDIG           272
+#define PCLK_PDVO              273
+#define PCLK_DSIHOST           274
+#define PCLK_PDVI              275
+#define PCLK_CSIHOST           276
+#define PCLK_PDGMAC            277
+#define PCLK_GMAC              278
+#define PCLK_PDDDR             279
+#define PCLK_DDR_MON           280
+#define PCLK_PDNPU             281
+#define PCLK_NPUPVTM           282
+#define PCLK_PDTOP             283
+#define PCLK_TOPCRU            284
+#define PCLK_TOPGRF            285
+#define PCLK_CPUEMADET         286
+#define PCLK_DDRPHY            287
+#define PCLK_DSIPHY            289
+#define PCLK_CSIPHY0           290
+#define PCLK_CSIPHY1           291
+#define PCLK_USBPHY_HOST       292
+#define PCLK_USBPHY_OTG                293
+#define PCLK_OTP               294
+
+#define CLK_NR_CLKS            (PCLK_OTP + 1)
+
+/* pmu soft-reset indices */
+
+/* pmu_cru_softrst_con0 */
+#define SRST_PDPMU_NIU_P       0
+#define SRST_PMU_SGRF_P                1
+#define SRST_PMU_SGRF_REMAP_P  2
+#define SRST_I2C0_P            3
+#define SRST_I2C0              4
+#define SRST_I2C2_P            7
+#define SRST_I2C2              8
+#define SRST_UART1_P           9
+#define SRST_UART1             10
+#define SRST_PWM0_P            11
+#define SRST_PWM0              12
+#define SRST_PWM1_P            13
+#define SRST_PWM1              14
+#define SRST_DDR_FAIL_SAFE     15
+
+/* pmu_cru_softrst_con1 */
+#define SRST_GPIO0_P           17
+#define SRST_GPIO0_DB          18
+#define SRST_SPI0_P            19
+#define SRST_SPI0              20
+#define SRST_PMUGRF_P          21
+#define SRST_CHIPVEROTP_P      22
+#define SRST_PMUPVTM           24
+#define SRST_PMUPVTM_P         25
+#define SRST_PMUCRU_P          30
+
+/* soft-reset indices */
+
+/* cru_softrst_con0 */
+#define SRST_CORE0_PO          0
+#define SRST_CORE1_PO          1
+#define SRST_CORE2_PO          2
+#define SRST_CORE3_PO          3
+#define SRST_CORE0             4
+#define SRST_CORE1             5
+#define SRST_CORE2             6
+#define SRST_CORE3             7
+#define SRST_CORE0_DBG         8
+#define SRST_CORE1_DBG         9
+#define SRST_CORE2_DBG         10
+#define SRST_CORE3_DBG         11
+#define SRST_NL2               12
+#define SRST_CORE_NIU_A                13
+#define SRST_DBG_DAPLITE_P     14
+#define SRST_DAPLITE_P         15
+
+/* cru_softrst_con1 */
+#define SRST_PDBUS_NIU1_A      16
+#define SRST_PDBUS_NIU1_H      17
+#define SRST_PDBUS_NIU1_P      18
+#define SRST_PDBUS_NIU2_A      19
+#define SRST_PDBUS_NIU2_H      20
+#define SRST_PDBUS_NIU3_A      21
+#define SRST_PDBUS_NIU3_H      22
+#define SRST_PDBUS_HOLD_NIU1_A 23
+#define SRST_DBG_NIU_P         24
+#define SRST_PDCORE_NIIU_H     25
+#define SRST_MUC_NIU           26
+#define SRST_DCF_A             29
+#define SRST_DCF_P             30
+#define SRST_SYSTEM_SRAM_A     31
+
+/* cru_softrst_con2 */
+#define SRST_I2C1_P            32
+#define SRST_I2C1              33
+#define SRST_I2C3_P            34
+#define SRST_I2C3              35
+#define SRST_I2C4_P            36
+#define SRST_I2C4              37
+#define SRST_I2C5_P            38
+#define SRST_I2C5              39
+#define SRST_SPI1_P            40
+#define SRST_SPI1              41
+#define SRST_MCU_CORE          42
+#define SRST_PWM2_P            44
+#define SRST_PWM2              45
+#define SRST_SPINLOCK_A                46
+
+/* cru_softrst_con3 */
+#define SRST_UART0_P           48
+#define SRST_UART0             49
+#define SRST_UART2_P           50
+#define SRST_UART2             51
+#define SRST_UART3_P           52
+#define SRST_UART3             53
+#define SRST_UART4_P           54
+#define SRST_UART4             55
+#define SRST_UART5_P           56
+#define SRST_UART5             57
+#define SRST_WDT_P             58
+#define SRST_SARADC_P          59
+#define SRST_GRF_P             61
+#define SRST_TIMER_P           62
+#define SRST_MAILBOX_P         63
+
+/* cru_softrst_con4 */
+#define SRST_TIMER0            64
+#define SRST_TIMER1            65
+#define SRST_TIMER2            66
+#define SRST_TIMER3            67
+#define SRST_TIMER4            68
+#define SRST_TIMER5            69
+#define SRST_INTMUX_P          70
+#define SRST_GPIO1_P           72
+#define SRST_GPIO1_DB          73
+#define SRST_GPIO2_P           74
+#define SRST_GPIO2_DB          75
+#define SRST_GPIO3_P           76
+#define SRST_GPIO3_DB          77
+#define SRST_GPIO4_P           78
+#define SRST_GPIO4_DB          79
+
+/* cru_softrst_con5 */
+#define SRST_CAN_P             80
+#define SRST_CAN               81
+#define SRST_DECOM_A           85
+#define SRST_DECOM_P           86
+#define SRST_DECOM_D           87
+#define SRST_PDCRYPTO_NIU_A    88
+#define SRST_PDCRYPTO_NIU_H    89
+#define SRST_CRYPTO_A          90
+#define SRST_CRYPTO_H          91
+#define SRST_CRYPTO_CORE       92
+#define SRST_CRYPTO_PKA                93
+#define SRST_SGRF_P            95
+
+/* cru_softrst_con6 */
+#define SRST_PDAUDIO_NIU_H     96
+#define SRST_PDAUDIO_NIU_P     97
+#define SRST_I2S0_H            98
+#define SRST_I2S0_TX_M         99
+#define SRST_I2S0_RX_M         100
+#define SRST_I2S1_H            101
+#define SRST_I2S1_M            102
+#define SRST_I2S2_H            103
+#define SRST_I2S2_M            104
+#define SRST_PDM_H             105
+#define SRST_PDM_M             106
+#define SRST_AUDPWM_H          107
+#define SRST_AUDPWM            108
+#define SRST_ACDCDIG_P         109
+#define SRST_ACDCDIG           110
+
+/* cru_softrst_con7 */
+#define SRST_PDVEPU_NIU_A      112
+#define SRST_PDVEPU_NIU_H      113
+#define SRST_VENC_A            114
+#define SRST_VENC_H            115
+#define SRST_VENC_CORE         116
+#define SRST_PDVDEC_NIU_A      117
+#define SRST_PDVDEC_NIU_H      118
+#define SRST_VDEC_A            119
+#define SRST_VDEC_H            120
+#define SRST_VDEC_CORE         121
+#define SRST_VDEC_CA           122
+#define SRST_VDEC_HEVC_CA      123
+#define SRST_PDJPEG_NIU_A      124
+#define SRST_PDJPEG_NIU_H      125
+#define SRST_JPEG_A            126
+#define SRST_JPEG_H            127
+
+/* cru_softrst_con8 */
+#define SRST_PDVO_NIU_A                128
+#define SRST_PDVO_NIU_H                129
+#define SRST_PDVO_NIU_P                130
+#define SRST_RGA_A             131
+#define SRST_RGA_H             132
+#define SRST_RGA_CORE          133
+#define SRST_VOP_A             134
+#define SRST_VOP_H             135
+#define SRST_VOP_D             136
+#define SRST_TXBYTEHS_DSIHOST  137
+#define SRST_DSIHOST_P         138
+#define SRST_IEP_A             139
+#define SRST_IEP_H             140
+#define SRST_IEP_CORE          141
+#define SRST_ISP_RX_P          142
+
+/* cru_softrst_con9 */
+#define SRST_PDVI_NIU_A                144
+#define SRST_PDVI_NIU_H                145
+#define SRST_PDVI_NIU_P                146
+#define SRST_ISP               147
+#define SRST_CIF_A             148
+#define SRST_CIF_H             149
+#define SRST_CIF_D             150
+#define SRST_CIF_P             151
+#define SRST_CIF_I             152
+#define SRST_CIF_RX_P          153
+#define SRST_PDISPP_NIU_A      154
+#define SRST_PDISPP_NIU_H      155
+#define SRST_ISPP_A            156
+#define SRST_ISPP_H            157
+#define SRST_ISPP              158
+#define SRST_CSIHOST_P         159
+
+/* cru_softrst_con10 */
+#define SRST_PDPHPMID_NIU_A    160
+#define SRST_PDPHPMID_NIU_H    161
+#define SRST_PDNVM_NIU_H       163
+#define SRST_SDMMC_H           164
+#define SRST_SDIO_H            165
+#define SRST_EMMC_H            166
+#define SRST_SFC_H             167
+#define SRST_SFCXIP_H          168
+#define SRST_SFC               169
+#define SRST_NANDC_H           170
+#define SRST_NANDC             171
+#define SRST_PDSDMMC_H         173
+#define SRST_PDSDIO_H          174
+
+/* cru_softrst_con11 */
+#define SRST_PDUSB_NIU_A       176
+#define SRST_PDUSB_NIU_H       177
+#define SRST_USBHOST_H         178
+#define SRST_USBHOST_ARB_H     179
+#define SRST_USBHOST_UTMI      180
+#define SRST_USBOTG_A          181
+#define SRST_USBPHY_OTG_P      182
+#define SRST_USBPHY_HOST_P     183
+#define SRST_USBPHYPOR_OTG     184
+#define SRST_USBPHYPOR_HOST    185
+#define SRST_PDGMAC_NIU_A      188
+#define SRST_PDGMAC_NIU_P      189
+#define SRST_GMAC_A            190
+
+/* cru_softrst_con12 */
+#define SRST_DDR_DFICTL_P      193
+#define SRST_DDR_MON_P         194
+#define SRST_DDR_STANDBY_P     195
+#define SRST_DDR_GRF_P         196
+#define SRST_DDR_MSCH_P                197
+#define SRST_DDR_SPLIT_A       198
+#define SRST_DDR_MSCH          199
+#define SRST_DDR_DFICTL                202
+#define SRST_DDR_STANDBY       203
+#define SRST_NPUMCU_NIU                205
+#define SRST_DDRPHY_P          206
+#define SRST_DDRPHY            207
+
+/* cru_softrst_con13 */
+#define SRST_PDNPU_NIU_A       208
+#define SRST_PDNPU_NIU_H       209
+#define SRST_PDNPU_NIU_P       210
+#define SRST_NPU_A             211
+#define SRST_NPU_H             212
+#define SRST_NPU               213
+#define SRST_NPUPVTM_P         214
+#define SRST_NPUPVTM           215
+#define SRST_NPU_TSADC_P       216
+#define SRST_NPU_TSADC         217
+#define SRST_NPU_TSADCPHY      218
+#define SRST_CIFLITE_A         220
+#define SRST_CIFLITE_H         221
+#define SRST_CIFLITE_D         222
+#define SRST_CIFLITE_RX_P      223
+
+/* cru_softrst_con14 */
+#define SRST_TOPNIU_P          224
+#define SRST_TOPCRU_P          225
+#define SRST_TOPGRF_P          226
+#define SRST_CPUEMADET_P       227
+#define SRST_CSIPHY0_P         228
+#define SRST_CSIPHY1_P         229
+#define SRST_DSIPHY_P          230
+#define SRST_CPU_TSADC_P       232
+#define SRST_CPU_TSADC         233
+#define SRST_CPU_TSADCPHY      234
+#define SRST_CPUPVTM_P         235
+#define SRST_CPUPVTM           236
+
+#endif
index ea9f91b..42133af 100644 (file)
 
 #define CORE_NR_CLK                    6
 
+/* CMU_FSYS0 */
+#define CLK_MOUT_FSYS0_BUS_USER                1
+#define CLK_MOUT_FSYS0_PCIE_USER       2
+#define CLK_GOUT_FSYS0_BUS_PCLK                3
+
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X1_REFCLK         4
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X2_REFCLK         5
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X1_DBI_ACLK       6
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X1_MSTR_ACLK      7
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X1_SLV_ACLK       8
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X2_DBI_ACLK       9
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X2_MSTR_ACLK      10
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X2_SLV_ACLK       11
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L0_X2_PIPE_CLK       12
+#define CLK_GOUT_FSYS0_PCIE_GEN3A_2L0_CLK              13
+#define CLK_GOUT_FSYS0_PCIE_GEN3B_2L0_CLK              14
+
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X1_REFCLK         15
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X2_REFCLK         16
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X1_DBI_ACLK       17
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X1_MSTR_ACLK      18
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X1_SLV_ACLK       19
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X2_DBI_ACLK       20
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X2_MSTR_ACLK      21
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X2_SLV_ACLK       22
+#define CLK_GOUT_FSYS0_PCIE_GEN3_2L1_X2_PIPE_CLK       23
+#define CLK_GOUT_FSYS0_PCIE_GEN3A_2L1_CLK              24
+#define CLK_GOUT_FSYS0_PCIE_GEN3B_2L1_CLK              25
+
+#define CLK_GOUT_FSYS0_PCIE_GEN3_4L_X2_REFCLK          26
+#define CLK_GOUT_FSYS0_PCIE_GEN3_4L_X4_REFCLK          27
+#define CLK_GOUT_FSYS0_PCIE_GEN3_4L_X2_DBI_ACLK                28
+#define CLK_GOUT_FSYS0_PCIE_GEN3_4L_X2_MSTR_ACLK       29
+#define CLK_GOUT_FSYS0_PCIE_GEN3_4L_X2_SLV_ACLK                30
+#define CLK_GOUT_FSYS0_PCIE_GEN3_4L_X4_DBI_ACLK                31
+#define CLK_GOUT_FSYS0_PCIE_GEN3_4L_X4_MSTR_ACLK       32
+#define CLK_GOUT_FSYS0_PCIE_GEN3_4L_X4_SLV_ACLK                33
+#define CLK_GOUT_FSYS0_PCIE_GEN3_4L_X4_PIPE_CLK                34
+#define CLK_GOUT_FSYS0_PCIE_GEN3A_4L_CLK               35
+#define CLK_GOUT_FSYS0_PCIE_GEN3B_4L_CLK               36
+
+#define FSYS0_NR_CLK                   37
+
+/* CMU_FSYS1 */
+#define FOUT_MMC_PLL                           1
+
+#define CLK_MOUT_FSYS1_BUS_USER                        2
+#define CLK_MOUT_FSYS1_MMC_PLL                 3
+#define CLK_MOUT_FSYS1_MMC_CARD_USER           4
+#define CLK_MOUT_FSYS1_USBDRD_USER             5
+#define CLK_MOUT_FSYS1_MMC_CARD                        6
+
+#define CLK_DOUT_FSYS1_MMC_CARD                        7
+
+#define CLK_GOUT_FSYS1_PCLK                    8
+#define CLK_GOUT_FSYS1_MMC_CARD_SDCLKIN                9
+#define CLK_GOUT_FSYS1_MMC_CARD_ACLK           10
+#define CLK_GOUT_FSYS1_USB20DRD_0_REFCLK       11
+#define CLK_GOUT_FSYS1_USB20DRD_1_REFCLK       12
+#define CLK_GOUT_FSYS1_USB30DRD_0_REFCLK       13
+#define CLK_GOUT_FSYS1_USB30DRD_1_REFCLK       14
+#define CLK_GOUT_FSYS1_USB20_0_ACLK            15
+#define CLK_GOUT_FSYS1_USB20_1_ACLK            16
+#define CLK_GOUT_FSYS1_USB30_0_ACLK            17
+#define CLK_GOUT_FSYS1_USB30_1_ACLK            18
+
+#define FSYS1_NR_CLK                           19
+
 /* CMU_FSYS2 */
 #define CLK_MOUT_FSYS2_BUS_USER                1
 #define CLK_MOUT_FSYS2_UFS_EMBD_USER   2
 #define CLK_GOUT_PERIC0_IPCLK_8                28
 #define CLK_GOUT_PERIC0_IPCLK_9                29
 #define CLK_GOUT_PERIC0_IPCLK_10       30
-#define CLK_GOUT_PERIC0_IPCLK_11       30
-#define CLK_GOUT_PERIC0_PCLK_0         31
-#define CLK_GOUT_PERIC0_PCLK_1         32
-#define CLK_GOUT_PERIC0_PCLK_2         33
-#define CLK_GOUT_PERIC0_PCLK_3         34
-#define CLK_GOUT_PERIC0_PCLK_4         35
-#define CLK_GOUT_PERIC0_PCLK_5         36
-#define CLK_GOUT_PERIC0_PCLK_6         37
-#define CLK_GOUT_PERIC0_PCLK_7         38
-#define CLK_GOUT_PERIC0_PCLK_8         39
-#define CLK_GOUT_PERIC0_PCLK_9         40
-#define CLK_GOUT_PERIC0_PCLK_10                41
-#define CLK_GOUT_PERIC0_PCLK_11                42
-
-#define PERIC0_NR_CLK                  43
+#define CLK_GOUT_PERIC0_IPCLK_11       31
+#define CLK_GOUT_PERIC0_PCLK_0         32
+#define CLK_GOUT_PERIC0_PCLK_1         33
+#define CLK_GOUT_PERIC0_PCLK_2         34
+#define CLK_GOUT_PERIC0_PCLK_3         35
+#define CLK_GOUT_PERIC0_PCLK_4         36
+#define CLK_GOUT_PERIC0_PCLK_5         37
+#define CLK_GOUT_PERIC0_PCLK_6         38
+#define CLK_GOUT_PERIC0_PCLK_7         39
+#define CLK_GOUT_PERIC0_PCLK_8         40
+#define CLK_GOUT_PERIC0_PCLK_9         41
+#define CLK_GOUT_PERIC0_PCLK_10                42
+#define CLK_GOUT_PERIC0_PCLK_11                43
+
+#define PERIC0_NR_CLK                  44
 
 /* CMU_PERIC1 */
 #define CLK_MOUT_PERIC1_BUS_USER       1
 #define CLK_GOUT_PERIC1_IPCLK_8                28
 #define CLK_GOUT_PERIC1_IPCLK_9                29
 #define CLK_GOUT_PERIC1_IPCLK_10       30
-#define CLK_GOUT_PERIC1_IPCLK_11       30
-#define CLK_GOUT_PERIC1_PCLK_0         31
-#define CLK_GOUT_PERIC1_PCLK_1         32
-#define CLK_GOUT_PERIC1_PCLK_2         33
-#define CLK_GOUT_PERIC1_PCLK_3         34
-#define CLK_GOUT_PERIC1_PCLK_4         35
-#define CLK_GOUT_PERIC1_PCLK_5         36
-#define CLK_GOUT_PERIC1_PCLK_6         37
-#define CLK_GOUT_PERIC1_PCLK_7         38
-#define CLK_GOUT_PERIC1_PCLK_8         39
-#define CLK_GOUT_PERIC1_PCLK_9         40
-#define CLK_GOUT_PERIC1_PCLK_10                41
-#define CLK_GOUT_PERIC1_PCLK_11                42
-
-#define PERIC1_NR_CLK                  43
+#define CLK_GOUT_PERIC1_IPCLK_11       31
+#define CLK_GOUT_PERIC1_PCLK_0         32
+#define CLK_GOUT_PERIC1_PCLK_1         33
+#define CLK_GOUT_PERIC1_PCLK_2         34
+#define CLK_GOUT_PERIC1_PCLK_3         35
+#define CLK_GOUT_PERIC1_PCLK_4         36
+#define CLK_GOUT_PERIC1_PCLK_5         37
+#define CLK_GOUT_PERIC1_PCLK_6         38
+#define CLK_GOUT_PERIC1_PCLK_7         39
+#define CLK_GOUT_PERIC1_PCLK_8         40
+#define CLK_GOUT_PERIC1_PCLK_9         41
+#define CLK_GOUT_PERIC1_PCLK_10                42
+#define CLK_GOUT_PERIC1_PCLK_11                43
+
+#define PERIC1_NR_CLK                  44
 
 /* CMU_PERIS */
 #define CLK_MOUT_PERIS_BUS_USER                1
index 3578e83..c691efa 100644 (file)
 
 #define CCU_SYS_SATA_REF_RST           0
 #define CCU_SYS_APB_RST                        1
+#define CCU_SYS_DDR_FULL_RST           2
+#define CCU_SYS_DDR_INIT_RST           3
+#define CCU_SYS_PCIE_PCS_PHY_RST       4
+#define CCU_SYS_PCIE_PIPE0_RST         5
+#define CCU_SYS_PCIE_CORE_RST          6
+#define CCU_SYS_PCIE_PWR_RST           7
+#define CCU_SYS_PCIE_STICKY_RST                8
+#define CCU_SYS_PCIE_NSTICKY_RST       9
+#define CCU_SYS_PCIE_HOT_RST           10
 
 #endif /* __DT_BINDINGS_RESET_BT1_CCU_H */
diff --git a/include/dt-bindings/reset/mediatek,mt6795-resets.h b/include/dt-bindings/reset/mediatek,mt6795-resets.h
new file mode 100644 (file)
index 0000000..5464a4a
--- /dev/null
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2022 Collabora Ltd.
+ * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT6795
+#define _DT_BINDINGS_RESET_CONTROLLER_MT6795
+
+/* INFRACFG resets */
+#define MT6795_INFRA_RST0_SCPSYS_RST           0
+#define MT6795_INFRA_RST0_PMIC_WRAP_RST                1
+#define MT6795_INFRA_RST1_MIPI_DSI_RST         2
+#define MT6795_INFRA_RST1_MIPI_CSI_RST         3
+#define MT6795_INFRA_RST1_MM_IOMMU_RST         4
+
+/* MMSYS resets */
+#define MT6795_MMSYS_SW0_RST_B_SMI_COMMON      0
+#define MT6795_MMSYS_SW0_RST_B_SMI_LARB                1
+#define MT6795_MMSYS_SW0_RST_B_CAM_MDP         2
+#define MT6795_MMSYS_SW0_RST_B_MDP_RDMA0       3
+#define MT6795_MMSYS_SW0_RST_B_MDP_RDMA1       4
+#define MT6795_MMSYS_SW0_RST_B_MDP_RSZ0                5
+#define MT6795_MMSYS_SW0_RST_B_MDP_RSZ1                6
+#define MT6795_MMSYS_SW0_RST_B_MDP_RSZ2                7
+#define MT6795_MMSYS_SW0_RST_B_MDP_TDSHP0      8
+#define MT6795_MMSYS_SW0_RST_B_MDP_TDSHP1      9
+#define MT6795_MMSYS_SW0_RST_B_MDP_WDMA                10
+#define MT6795_MMSYS_SW0_RST_B_MDP_WROT0       11
+#define MT6795_MMSYS_SW0_RST_B_MDP_WROT1       12
+#define MT6795_MMSYS_SW0_RST_B_MDP_CROP                13
+
+/*  PERICFG resets */
+#define MT6795_PERI_NFI_SW_RST                 0
+#define MT6795_PERI_THERM_SW_RST               1
+#define MT6795_PERI_MSDC1_SW_RST               2
+
+/* TOPRGU resets */
+#define MT6795_TOPRGU_INFRA_SW_RST             0
+#define MT6795_TOPRGU_MM_SW_RST                        1
+#define MT6795_TOPRGU_MFG_SW_RST               2
+#define MT6795_TOPRGU_VENC_SW_RST              3
+#define MT6795_TOPRGU_VDEC_SW_RST              4
+#define MT6795_TOPRGU_IMG_SW_RST               5
+#define MT6795_TOPRGU_DDRPHY_SW_RST            6
+#define MT6795_TOPRGU_MD_SW_RST                        7
+#define MT6795_TOPRGU_INFRA_AO_SW_RST          8
+#define MT6795_TOPRGU_MD_LITE_SW_RST           9
+#define MT6795_TOPRGU_APMIXED_SW_RST           10
+#define MT6795_TOPRGU_PWRAP_SPI_CTL_RST                11
+#define MT6795_TOPRGU_SW_RST_NUM               12
+
+#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT6795 */
index 0b1937f..24ab363 100644 (file)
@@ -31,5 +31,8 @@
 #define MT8195_INFRA_RST0_THERM_CTRL_SWRST     0
 #define MT8195_INFRA_RST3_THERM_CTRL_PTP_SWRST 1
 #define MT8195_INFRA_RST4_THERM_CTRL_MCU_SWRST 2
+#define MT8195_INFRA_RST2_PCIE_P0_SWRST        3
+#define MT8195_INFRA_RST2_PCIE_P1_SWRST        4
+#define MT8195_INFRA_RST2_USBSIF_P1_SWRST      5
 
 #endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8195 */
index effee1d..92294a5 100644 (file)
@@ -857,7 +857,6 @@ void blk_mq_kick_requeue_list(struct request_queue *q);
 void blk_mq_delay_kick_requeue_list(struct request_queue *q, unsigned long msecs);
 void blk_mq_complete_request(struct request *rq);
 bool blk_mq_complete_request_remote(struct request *rq);
-bool blk_mq_queue_stopped(struct request_queue *q);
 void blk_mq_stop_hw_queue(struct blk_mq_hw_ctx *hctx);
 void blk_mq_start_hw_queue(struct blk_mq_hw_ctx *hctx);
 void blk_mq_stop_hw_queues(struct request_queue *q);
index 1615010..2108b56 100644 (file)
@@ -350,7 +350,7 @@ struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev,
                const char *parent_name, const struct clk_hw *parent_hw,
                const struct clk_parent_data *parent_data, unsigned long flags,
                unsigned long fixed_rate, unsigned long fixed_accuracy,
-               unsigned long clk_fixed_flags);
+               unsigned long clk_fixed_flags, bool devm);
 struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                unsigned long fixed_rate);
@@ -365,7 +365,20 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
  */
 #define clk_hw_register_fixed_rate(dev, name, parent_name, flags, fixed_rate)  \
        __clk_hw_register_fixed_rate((dev), NULL, (name), (parent_name), NULL, \
-                                    NULL, (flags), (fixed_rate), 0, 0)
+                                    NULL, (flags), (fixed_rate), 0, 0, false)
+
+/**
+ * devm_clk_hw_register_fixed_rate - register fixed-rate clock with the clock
+ * framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ */
+#define devm_clk_hw_register_fixed_rate(dev, name, parent_name, flags, fixed_rate)  \
+       __clk_hw_register_fixed_rate((dev), NULL, (name), (parent_name), NULL, \
+                                    NULL, (flags), (fixed_rate), 0, 0, true)
 /**
  * clk_hw_register_fixed_rate_parent_hw - register fixed-rate clock with
  * the clock framework
@@ -378,7 +391,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
 #define clk_hw_register_fixed_rate_parent_hw(dev, name, parent_hw, flags,     \
                                             fixed_rate)                      \
        __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, (parent_hw),  \
-                                    NULL, (flags), (fixed_rate), 0, 0)
+                                    NULL, (flags), (fixed_rate), 0, 0, false)
 /**
  * clk_hw_register_fixed_rate_parent_data - register fixed-rate clock with
  * the clock framework
@@ -392,7 +405,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
                                             fixed_rate)                      \
        __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, NULL,         \
                                     (parent_data), (flags), (fixed_rate), 0, \
-                                    0)
+                                    0, false)
 /**
  * clk_hw_register_fixed_rate_with_accuracy - register fixed-rate clock with
  * the clock framework
@@ -408,7 +421,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
                                                 fixed_accuracy)              \
        __clk_hw_register_fixed_rate((dev), NULL, (name), (parent_name),      \
                                     NULL, NULL, (flags), (fixed_rate),       \
-                                    (fixed_accuracy), 0)
+                                    (fixed_accuracy), 0, false)
 /**
  * clk_hw_register_fixed_rate_with_accuracy_parent_hw - register fixed-rate
  * clock with the clock framework
@@ -423,7 +436,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
                parent_hw, flags, fixed_rate, fixed_accuracy)                 \
        __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, (parent_hw)   \
                                     NULL, NULL, (flags), (fixed_rate),       \
-                                    (fixed_accuracy), 0)
+                                    (fixed_accuracy), 0, false)
 /**
  * clk_hw_register_fixed_rate_with_accuracy_parent_data - register fixed-rate
  * clock with the clock framework
@@ -438,7 +451,21 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
                parent_data, flags, fixed_rate, fixed_accuracy)               \
        __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, NULL,         \
                                     (parent_data), NULL, (flags),            \
-                                    (fixed_rate), (fixed_accuracy), 0)
+                                    (fixed_rate), (fixed_accuracy), 0, false)
+/**
+ * clk_hw_register_fixed_rate_parent_accuracy - register fixed-rate clock with
+ * the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ */
+#define clk_hw_register_fixed_rate_parent_accuracy(dev, name, parent_data,    \
+                                                  flags, fixed_rate)         \
+       __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, NULL,      \
+                                    (parent_data), (flags), (fixed_rate), 0,    \
+                                    CLK_FIXED_RATE_PARENT_ACCURACY, false)
 
 void clk_unregister_fixed_rate(struct clk *clk);
 void clk_hw_unregister_fixed_rate(struct clk_hw *hw);
@@ -957,6 +984,13 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
                              (parent_names), NULL, NULL, (flags), (reg),     \
                              (shift), (mask), (clk_mux_flags), (table),      \
                              (lock))
+#define clk_hw_register_mux_table_parent_data(dev, name, parent_data,        \
+                                 num_parents, flags, reg, shift, mask,       \
+                                 clk_mux_flags, table, lock)                 \
+       __clk_hw_register_mux((dev), NULL, (name), (num_parents),             \
+                             NULL, NULL, (parent_data), (flags), (reg),      \
+                             (shift), (mask), (clk_mux_flags), (table),      \
+                             (lock))
 #define clk_hw_register_mux(dev, name, parent_names, num_parents, flags, reg, \
                            shift, width, clk_mux_flags, lock)                \
        __clk_hw_register_mux((dev), NULL, (name), (num_parents),             \
@@ -974,6 +1008,13 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
        __clk_hw_register_mux((dev), NULL, (name), (num_parents), NULL, NULL, \
                              (parent_data), (flags), (reg), (shift),         \
                              BIT((width)) - 1, (clk_mux_flags), NULL, (lock))
+#define clk_hw_register_mux_parent_data_table(dev, name, parent_data,        \
+                                             num_parents, flags, reg, shift, \
+                                             width, clk_mux_flags, table,    \
+                                             lock)                           \
+       __clk_hw_register_mux((dev), NULL, (name), (num_parents), NULL, NULL, \
+                             (parent_data), (flags), (reg), (shift),         \
+                             BIT((width)) - 1, (clk_mux_flags), table, (lock))
 #define devm_clk_hw_register_mux(dev, name, parent_names, num_parents, flags, reg, \
                            shift, width, clk_mux_flags, lock)                \
        __devm_clk_hw_register_mux((dev), NULL, (name), (num_parents),        \
@@ -987,6 +1028,13 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
                                   (parent_hws), NULL, (flags), (reg),        \
                                   (shift), BIT((width)) - 1,                 \
                                   (clk_mux_flags), NULL, (lock))
+#define devm_clk_hw_register_mux_parent_data_table(dev, name, parent_data,    \
+                                             num_parents, flags, reg, shift, \
+                                             width, clk_mux_flags, table,    \
+                                             lock)                           \
+       __devm_clk_hw_register_mux((dev), NULL, (name), (num_parents), NULL,  \
+                             NULL, (parent_data), (flags), (reg), (shift),   \
+                             BIT((width)) - 1, (clk_mux_flags), table, (lock))
 
 int clk_mux_val_to_index(struct clk_hw *hw, const u32 *table, unsigned int flags,
                         unsigned int val);
@@ -1454,7 +1502,7 @@ int devm_of_clk_add_hw_provider(struct device *dev,
                                                 void *data),
                           void *data);
 void of_clk_del_provider(struct device_node *np);
-void devm_of_clk_del_provider(struct device *dev);
+
 struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
                                  void *data);
 struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec,
@@ -1491,7 +1539,7 @@ static inline int devm_of_clk_add_hw_provider(struct device *dev,
        return 0;
 }
 static inline void of_clk_del_provider(struct device_node *np) {}
-static inline void devm_of_clk_del_provider(struct device *dev) {}
+
 static inline struct clk *of_clk_src_simple_get(
        struct of_phandle_args *clkspec, void *data)
 {
index 8a7b5cd..f6ebab6 100644 (file)
@@ -28,13 +28,5 @@ int dm365_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgch
 int dm365_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip);
 int dm365_psc_init(struct device *dev, void __iomem *base);
 #endif
-#ifdef CONFIG_ARCH_DAVINCI_DM644x
-int dm644x_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip);
-int dm644x_psc_init(struct device *dev, void __iomem *base);
-#endif
-#ifdef CONFIG_ARCH_DAVINCI_DM646x
-int dm646x_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip);
-int dm646x_psc_init(struct device *dev, void __iomem *base);
-#endif
 
 #endif /* __LINUX_CLK_DAVINCI_PLL_H___ */
index 8a8423e..45570bc 100644 (file)
@@ -46,6 +46,4 @@ int clk_hw_register_clkdev(struct clk_hw *, const char *, const char *);
 
 int devm_clk_hw_register_clkdev(struct device *dev, struct clk_hw *hw,
                                const char *con_id, const char *dev_id);
-void devm_clk_release_clkdev(struct device *dev, const char *con_id,
-                            const char *dev_id);
 #endif
index 0d435d0..bd04786 100644 (file)
@@ -202,12 +202,13 @@ static inline unsigned int cpumask_local_spread(unsigned int i, int node)
        return 0;
 }
 
-static inline int cpumask_any_and_distribute(const struct cpumask *src1p,
-                                            const struct cpumask *src2p) {
+static inline unsigned int cpumask_any_and_distribute(const struct cpumask *src1p,
+                                                     const struct cpumask *src2p)
+{
        return cpumask_first_and(src1p, src2p);
 }
 
-static inline int cpumask_any_distribute(const struct cpumask *srcp)
+static inline unsigned int cpumask_any_distribute(const struct cpumask *srcp)
 {
        return cpumask_first(srcp);
 }
@@ -261,7 +262,26 @@ unsigned int cpumask_next_and(int n, const struct cpumask *src1p,
                (cpu) = cpumask_next_zero((cpu), (mask)),       \
                (cpu) < nr_cpu_ids;)
 
+#if NR_CPUS == 1
+static inline
+unsigned int cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool wrap)
+{
+       cpumask_check(start);
+       if (n != -1)
+               cpumask_check(n);
+
+       /*
+        * Return the first available CPU when wrapping, or when starting before cpu0,
+        * since there is only one valid option.
+        */
+       if (wrap && n >= 0)
+               return nr_cpumask_bits;
+
+       return cpumask_first(mask);
+}
+#else
 unsigned int __pure cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool wrap);
+#endif
 
 /**
  * for_each_cpu_wrap - iterate over every cpu in a mask, starting at a specified location
index 1c480b1..f4519d3 100644 (file)
@@ -656,12 +656,12 @@ struct kvm_irq_routing_table {
 };
 #endif
 
-#ifndef KVM_PRIVATE_MEM_SLOTS
-#define KVM_PRIVATE_MEM_SLOTS 0
+#ifndef KVM_INTERNAL_MEM_SLOTS
+#define KVM_INTERNAL_MEM_SLOTS 0
 #endif
 
 #define KVM_MEM_SLOTS_NUM SHRT_MAX
-#define KVM_USER_MEM_SLOTS (KVM_MEM_SLOTS_NUM - KVM_PRIVATE_MEM_SLOTS)
+#define KVM_USER_MEM_SLOTS (KVM_MEM_SLOTS_NUM - KVM_INTERNAL_MEM_SLOTS)
 
 #ifndef __KVM_VCPU_MULTIPLE_ADDRESS_SPACE
 static inline int kvm_arch_vcpu_memslots_id(struct kvm_vcpu *vcpu)
@@ -765,10 +765,10 @@ struct kvm {
 
 #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
        struct mmu_notifier mmu_notifier;
-       unsigned long mmu_notifier_seq;
-       long mmu_notifier_count;
-       unsigned long mmu_notifier_range_start;
-       unsigned long mmu_notifier_range_end;
+       unsigned long mmu_invalidate_seq;
+       long mmu_invalidate_in_progress;
+       unsigned long mmu_invalidate_range_start;
+       unsigned long mmu_invalidate_range_end;
 #endif
        struct list_head devices;
        u64 manual_dirty_log_protect;
@@ -1357,10 +1357,10 @@ void kvm_mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc);
 void *kvm_mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc);
 #endif
 
-void kvm_inc_notifier_count(struct kvm *kvm, unsigned long start,
-                                  unsigned long end);
-void kvm_dec_notifier_count(struct kvm *kvm, unsigned long start,
-                                  unsigned long end);
+void kvm_mmu_invalidate_begin(struct kvm *kvm, unsigned long start,
+                             unsigned long end);
+void kvm_mmu_invalidate_end(struct kvm *kvm, unsigned long start,
+                           unsigned long end);
 
 long kvm_arch_dev_ioctl(struct file *filp,
                        unsigned int ioctl, unsigned long arg);
@@ -1907,42 +1907,44 @@ extern const struct kvm_stats_header kvm_vcpu_stats_header;
 extern const struct _kvm_stats_desc kvm_vcpu_stats_desc[];
 
 #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
-static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq)
+static inline int mmu_invalidate_retry(struct kvm *kvm, unsigned long mmu_seq)
 {
-       if (unlikely(kvm->mmu_notifier_count))
+       if (unlikely(kvm->mmu_invalidate_in_progress))
                return 1;
        /*
-        * Ensure the read of mmu_notifier_count happens before the read
-        * of mmu_notifier_seq.  This interacts with the smp_wmb() in
-        * mmu_notifier_invalidate_range_end to make sure that the caller
-        * either sees the old (non-zero) value of mmu_notifier_count or
-        * the new (incremented) value of mmu_notifier_seq.
-        * PowerPC Book3s HV KVM calls this under a per-page lock
-        * rather than under kvm->mmu_lock, for scalability, so
-        * can't rely on kvm->mmu_lock to keep things ordered.
+        * Ensure the read of mmu_invalidate_in_progress happens before
+        * the read of mmu_invalidate_seq.  This interacts with the
+        * smp_wmb() in mmu_notifier_invalidate_range_end to make sure
+        * that the caller either sees the old (non-zero) value of
+        * mmu_invalidate_in_progress or the new (incremented) value of
+        * mmu_invalidate_seq.
+        *
+        * PowerPC Book3s HV KVM calls this under a per-page lock rather
+        * than under kvm->mmu_lock, for scalability, so can't rely on
+        * kvm->mmu_lock to keep things ordered.
         */
        smp_rmb();
-       if (kvm->mmu_notifier_seq != mmu_seq)
+       if (kvm->mmu_invalidate_seq != mmu_seq)
                return 1;
        return 0;
 }
 
-static inline int mmu_notifier_retry_hva(struct kvm *kvm,
-                                        unsigned long mmu_seq,
-                                        unsigned long hva)
+static inline int mmu_invalidate_retry_hva(struct kvm *kvm,
+                                          unsigned long mmu_seq,
+                                          unsigned long hva)
 {
        lockdep_assert_held(&kvm->mmu_lock);
        /*
-        * If mmu_notifier_count is non-zero, then the range maintained by
-        * kvm_mmu_notifier_invalidate_range_start contains all addresses that
-        * might be being invalidated. Note that it may include some false
+        * If mmu_invalidate_in_progress is non-zero, then the range maintained
+        * by kvm_mmu_notifier_invalidate_range_start contains all addresses
+        * that might be being invalidated. Note that it may include some false
         * positives, due to shortcuts when handing concurrent invalidations.
         */
-       if (unlikely(kvm->mmu_notifier_count) &&
-           hva >= kvm->mmu_notifier_range_start &&
-           hva < kvm->mmu_notifier_range_end)
+       if (unlikely(kvm->mmu_invalidate_in_progress) &&
+           hva >= kvm->mmu_invalidate_range_start &&
+           hva < kvm->mmu_invalidate_range_end)
                return 1;
-       if (kvm->mmu_notifier_seq != mmu_seq)
+       if (kvm->mmu_invalidate_seq != mmu_seq)
                return 1;
        return 0;
 }
index 0269ff1..698032e 100644 (file)
@@ -1382,7 +1382,8 @@ extern const struct attribute_group *ata_common_sdev_groups[];
        .proc_name              = drv_name,                     \
        .slave_destroy          = ata_scsi_slave_destroy,       \
        .bios_param             = ata_std_bios_param,           \
-       .unlock_native_capacity = ata_scsi_unlock_native_capacity
+       .unlock_native_capacity = ata_scsi_unlock_native_capacity,\
+       .max_sectors            = ATA_MAX_SECTORS_LBA48
 
 #define ATA_SUBBASE_SHT(drv_name)                              \
        __ATA_BASE_SHT(drv_name),                               \
index 82c9d48..3ab8c07 100644 (file)
@@ -41,6 +41,7 @@ struct qcom_smd_rpm;
 #define QCOM_SMD_RPM_HWKM_CLK  0x6d6b7768
 #define QCOM_SMD_RPM_PKA_CLK   0x616b70
 #define QCOM_SMD_RPM_MCFG_CLK  0x6766636d
+#define QCOM_SMD_RPM_MMXI_CLK  0x69786d6d
 
 int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
                       int state,
index a3f73bb..dcab9c7 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/gfp.h>
 
 /**
- * virtqueue - a queue to register buffers for sending or receiving.
+ * struct virtqueue - a queue to register buffers for sending or receiving.
  * @list: the chain of virtqueues for this device
  * @callback: the function to call when buffers are consumed (can be NULL).
  * @name: the name of this virtqueue (mainly for debugging)
@@ -97,7 +97,7 @@ int virtqueue_resize(struct virtqueue *vq, u32 num,
                     void (*recycle)(struct virtqueue *vq, void *buf));
 
 /**
- * virtio_device - representation of a device using virtio
+ * struct virtio_device - representation of a device using virtio
  * @index: unique position on the virtio bus
  * @failed: saved value for VIRTIO_CONFIG_S_FAILED bit (for restore)
  * @config_enabled: configuration change reporting enabled
@@ -156,7 +156,7 @@ size_t virtio_max_dma_size(struct virtio_device *vdev);
        list_for_each_entry(vq, &vdev->vqs, list)
 
 /**
- * virtio_driver - operations for a virtio I/O driver
+ * struct virtio_driver - operations for a virtio I/O driver
  * @driver: underlying device driver (populate name and owner).
  * @id_table: the ids serviced by this driver.
  * @feature_table: an array of feature numbers supported by this driver.
index 6adff09..4b51764 100644 (file)
@@ -55,7 +55,6 @@ struct virtio_shm_region {
  *             include a NULL entry for vqs that do not need a callback
  *     names: array of virtqueue names (mainly for debugging)
  *             include a NULL entry for vqs unused by driver
- *     sizes: array of virtqueue sizes
  *     Returns 0 on success or error status
  * @del_vqs: free virtqueues found by find_vqs().
  * @synchronize_cbs: synchronize with the virtqueue callbacks (optional)
@@ -104,9 +103,7 @@ struct virtio_config_ops {
        void (*reset)(struct virtio_device *vdev);
        int (*find_vqs)(struct virtio_device *, unsigned nvqs,
                        struct virtqueue *vqs[], vq_callback_t *callbacks[],
-                       const char * const names[],
-                       u32 sizes[],
-                       const bool *ctx,
+                       const char * const names[], const bool *ctx,
                        struct irq_affinity *desc);
        void (*del_vqs)(struct virtio_device *);
        void (*synchronize_cbs)(struct virtio_device *);
@@ -215,7 +212,7 @@ struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev,
        const char *names[] = { n };
        struct virtqueue *vq;
        int err = vdev->config->find_vqs(vdev, 1, &vq, callbacks, names, NULL,
-                                        NULL, NULL);
+                                        NULL);
        if (err < 0)
                return ERR_PTR(err);
        return vq;
@@ -227,8 +224,7 @@ int virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
                        const char * const names[],
                        struct irq_affinity *desc)
 {
-       return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, NULL,
-                                     NULL, desc);
+       return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, NULL, desc);
 }
 
 static inline
@@ -237,25 +233,13 @@ int virtio_find_vqs_ctx(struct virtio_device *vdev, unsigned nvqs,
                        const char * const names[], const bool *ctx,
                        struct irq_affinity *desc)
 {
-       return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, NULL,
-                                     ctx, desc);
-}
-
-static inline
-int virtio_find_vqs_ctx_size(struct virtio_device *vdev, u32 nvqs,
-                            struct virtqueue *vqs[],
-                            vq_callback_t *callbacks[],
-                            const char * const names[],
-                            u32 sizes[],
-                            const bool *ctx, struct irq_affinity *desc)
-{
-       return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, sizes,
-                                     ctx, desc);
+       return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, ctx,
+                                     desc);
 }
 
 /**
  * virtio_synchronize_cbs - synchronize with virtqueue callbacks
- * @vdev: the device
+ * @dev: the virtio device
  */
 static inline
 void virtio_synchronize_cbs(struct virtio_device *dev)
@@ -274,7 +258,7 @@ void virtio_synchronize_cbs(struct virtio_device *dev)
 
 /**
  * virtio_device_ready - enable vq use in probe function
- * @vdev: the device
+ * @dev: the virtio device
  *
  * Driver must call this to use vqs in the probe function.
  *
@@ -322,7 +306,7 @@ const char *virtio_bus_name(struct virtio_device *vdev)
 /**
  * virtqueue_set_affinity - setting affinity for a virtqueue
  * @vq: the virtqueue
- * @cpu: the cpu no.
+ * @cpu_mask: the cpu mask
  *
  * Pay attention the function are best-effort: the affinity hint may not be set
  * due to config support, irq type and sharing.
index 9f0bab0..3827a6b 100644 (file)
@@ -83,6 +83,7 @@ struct neigh_parms {
        struct rcu_head rcu_head;
 
        int     reachable_time;
+       int     qlen;
        int     data[NEIGH_VAR_DATA_MAX];
        DECLARE_BITMAP(data_state, NEIGH_VAR_DATA_MAX);
 };
index 0677cd3..c396a38 100644 (file)
@@ -95,7 +95,7 @@ struct nf_ip_net {
 
 struct netns_ct {
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
-       bool ctnetlink_has_listener;
+       u8 ctnetlink_has_listener;
        bool ecache_dwork_pending;
 #endif
        u8                      sysctl_log_invalid; /* Log invalid packets */
index 05a1bbd..d08cfe1 100644 (file)
@@ -578,6 +578,31 @@ static inline bool sk_user_data_is_nocopy(const struct sock *sk)
 #define __sk_user_data(sk) ((*((void __rcu **)&(sk)->sk_user_data)))
 
 /**
+ * __locked_read_sk_user_data_with_flags - return the pointer
+ * only if argument flags all has been set in sk_user_data. Otherwise
+ * return NULL
+ *
+ * @sk: socket
+ * @flags: flag bits
+ *
+ * The caller must be holding sk->sk_callback_lock.
+ */
+static inline void *
+__locked_read_sk_user_data_with_flags(const struct sock *sk,
+                                     uintptr_t flags)
+{
+       uintptr_t sk_user_data =
+               (uintptr_t)rcu_dereference_check(__sk_user_data(sk),
+                                                lockdep_is_held(&sk->sk_callback_lock));
+
+       WARN_ON_ONCE(flags & SK_USER_DATA_PTRMASK);
+
+       if ((sk_user_data & flags) == flags)
+               return (void *)(sk_user_data & SK_USER_DATA_PTRMASK);
+       return NULL;
+}
+
+/**
  * __rcu_dereference_sk_user_data_with_flags - return the pointer
  * only if argument flags all has been set in sk_user_data. Otherwise
  * return NULL
index 6466515..f916dcd 100644 (file)
@@ -40,4 +40,12 @@ struct mpfs_sys_controller *mpfs_sys_controller_get(struct device *dev);
 
 #endif /* if IS_ENABLED(CONFIG_POLARFIRE_SOC_SYS_CTRL) */
 
+#if IS_ENABLED(CONFIG_MCHP_CLK_MPFS)
+
+u32 mpfs_reset_read(struct device *dev);
+
+void mpfs_reset_write(struct device *dev, u32 val);
+
+#endif /* if IS_ENABLED(CONFIG_MCHP_CLK_MPFS) */
+
 #endif /* __SOC_MPFS_H__ */
index ac151ec..2edea90 100644 (file)
 #define REG_RESERVED_ADDR              0xffffffff
 #define REG_RESERVED(reg)              REG(reg, REG_RESERVED_ADDR)
 
-#define for_each_stat(ocelot, stat)                            \
-       for ((stat) = (ocelot)->stats_layout;                   \
-            ((stat)->name[0] != '\0');                         \
-            (stat)++)
-
 enum ocelot_target {
        ANA = 1,
        QS,
@@ -335,13 +330,38 @@ enum ocelot_reg {
        SYS_COUNT_RX_64,
        SYS_COUNT_RX_65_127,
        SYS_COUNT_RX_128_255,
-       SYS_COUNT_RX_256_1023,
+       SYS_COUNT_RX_256_511,
+       SYS_COUNT_RX_512_1023,
        SYS_COUNT_RX_1024_1526,
        SYS_COUNT_RX_1527_MAX,
        SYS_COUNT_RX_PAUSE,
        SYS_COUNT_RX_CONTROL,
        SYS_COUNT_RX_LONGS,
        SYS_COUNT_RX_CLASSIFIED_DROPS,
+       SYS_COUNT_RX_RED_PRIO_0,
+       SYS_COUNT_RX_RED_PRIO_1,
+       SYS_COUNT_RX_RED_PRIO_2,
+       SYS_COUNT_RX_RED_PRIO_3,
+       SYS_COUNT_RX_RED_PRIO_4,
+       SYS_COUNT_RX_RED_PRIO_5,
+       SYS_COUNT_RX_RED_PRIO_6,
+       SYS_COUNT_RX_RED_PRIO_7,
+       SYS_COUNT_RX_YELLOW_PRIO_0,
+       SYS_COUNT_RX_YELLOW_PRIO_1,
+       SYS_COUNT_RX_YELLOW_PRIO_2,
+       SYS_COUNT_RX_YELLOW_PRIO_3,
+       SYS_COUNT_RX_YELLOW_PRIO_4,
+       SYS_COUNT_RX_YELLOW_PRIO_5,
+       SYS_COUNT_RX_YELLOW_PRIO_6,
+       SYS_COUNT_RX_YELLOW_PRIO_7,
+       SYS_COUNT_RX_GREEN_PRIO_0,
+       SYS_COUNT_RX_GREEN_PRIO_1,
+       SYS_COUNT_RX_GREEN_PRIO_2,
+       SYS_COUNT_RX_GREEN_PRIO_3,
+       SYS_COUNT_RX_GREEN_PRIO_4,
+       SYS_COUNT_RX_GREEN_PRIO_5,
+       SYS_COUNT_RX_GREEN_PRIO_6,
+       SYS_COUNT_RX_GREEN_PRIO_7,
        SYS_COUNT_TX_OCTETS,
        SYS_COUNT_TX_UNICAST,
        SYS_COUNT_TX_MULTICAST,
@@ -351,11 +371,46 @@ enum ocelot_reg {
        SYS_COUNT_TX_PAUSE,
        SYS_COUNT_TX_64,
        SYS_COUNT_TX_65_127,
-       SYS_COUNT_TX_128_511,
+       SYS_COUNT_TX_128_255,
+       SYS_COUNT_TX_256_511,
        SYS_COUNT_TX_512_1023,
        SYS_COUNT_TX_1024_1526,
        SYS_COUNT_TX_1527_MAX,
+       SYS_COUNT_TX_YELLOW_PRIO_0,
+       SYS_COUNT_TX_YELLOW_PRIO_1,
+       SYS_COUNT_TX_YELLOW_PRIO_2,
+       SYS_COUNT_TX_YELLOW_PRIO_3,
+       SYS_COUNT_TX_YELLOW_PRIO_4,
+       SYS_COUNT_TX_YELLOW_PRIO_5,
+       SYS_COUNT_TX_YELLOW_PRIO_6,
+       SYS_COUNT_TX_YELLOW_PRIO_7,
+       SYS_COUNT_TX_GREEN_PRIO_0,
+       SYS_COUNT_TX_GREEN_PRIO_1,
+       SYS_COUNT_TX_GREEN_PRIO_2,
+       SYS_COUNT_TX_GREEN_PRIO_3,
+       SYS_COUNT_TX_GREEN_PRIO_4,
+       SYS_COUNT_TX_GREEN_PRIO_5,
+       SYS_COUNT_TX_GREEN_PRIO_6,
+       SYS_COUNT_TX_GREEN_PRIO_7,
        SYS_COUNT_TX_AGING,
+       SYS_COUNT_DROP_LOCAL,
+       SYS_COUNT_DROP_TAIL,
+       SYS_COUNT_DROP_YELLOW_PRIO_0,
+       SYS_COUNT_DROP_YELLOW_PRIO_1,
+       SYS_COUNT_DROP_YELLOW_PRIO_2,
+       SYS_COUNT_DROP_YELLOW_PRIO_3,
+       SYS_COUNT_DROP_YELLOW_PRIO_4,
+       SYS_COUNT_DROP_YELLOW_PRIO_5,
+       SYS_COUNT_DROP_YELLOW_PRIO_6,
+       SYS_COUNT_DROP_YELLOW_PRIO_7,
+       SYS_COUNT_DROP_GREEN_PRIO_0,
+       SYS_COUNT_DROP_GREEN_PRIO_1,
+       SYS_COUNT_DROP_GREEN_PRIO_2,
+       SYS_COUNT_DROP_GREEN_PRIO_3,
+       SYS_COUNT_DROP_GREEN_PRIO_4,
+       SYS_COUNT_DROP_GREEN_PRIO_5,
+       SYS_COUNT_DROP_GREEN_PRIO_6,
+       SYS_COUNT_DROP_GREEN_PRIO_7,
        SYS_RESET_CFG,
        SYS_SR_ETYPE_CFG,
        SYS_VLAN_ETYPE_CFG,
@@ -538,16 +593,111 @@ enum ocelot_ptp_pins {
        TOD_ACC_PIN
 };
 
+enum ocelot_stat {
+       OCELOT_STAT_RX_OCTETS,
+       OCELOT_STAT_RX_UNICAST,
+       OCELOT_STAT_RX_MULTICAST,
+       OCELOT_STAT_RX_BROADCAST,
+       OCELOT_STAT_RX_SHORTS,
+       OCELOT_STAT_RX_FRAGMENTS,
+       OCELOT_STAT_RX_JABBERS,
+       OCELOT_STAT_RX_CRC_ALIGN_ERRS,
+       OCELOT_STAT_RX_SYM_ERRS,
+       OCELOT_STAT_RX_64,
+       OCELOT_STAT_RX_65_127,
+       OCELOT_STAT_RX_128_255,
+       OCELOT_STAT_RX_256_511,
+       OCELOT_STAT_RX_512_1023,
+       OCELOT_STAT_RX_1024_1526,
+       OCELOT_STAT_RX_1527_MAX,
+       OCELOT_STAT_RX_PAUSE,
+       OCELOT_STAT_RX_CONTROL,
+       OCELOT_STAT_RX_LONGS,
+       OCELOT_STAT_RX_CLASSIFIED_DROPS,
+       OCELOT_STAT_RX_RED_PRIO_0,
+       OCELOT_STAT_RX_RED_PRIO_1,
+       OCELOT_STAT_RX_RED_PRIO_2,
+       OCELOT_STAT_RX_RED_PRIO_3,
+       OCELOT_STAT_RX_RED_PRIO_4,
+       OCELOT_STAT_RX_RED_PRIO_5,
+       OCELOT_STAT_RX_RED_PRIO_6,
+       OCELOT_STAT_RX_RED_PRIO_7,
+       OCELOT_STAT_RX_YELLOW_PRIO_0,
+       OCELOT_STAT_RX_YELLOW_PRIO_1,
+       OCELOT_STAT_RX_YELLOW_PRIO_2,
+       OCELOT_STAT_RX_YELLOW_PRIO_3,
+       OCELOT_STAT_RX_YELLOW_PRIO_4,
+       OCELOT_STAT_RX_YELLOW_PRIO_5,
+       OCELOT_STAT_RX_YELLOW_PRIO_6,
+       OCELOT_STAT_RX_YELLOW_PRIO_7,
+       OCELOT_STAT_RX_GREEN_PRIO_0,
+       OCELOT_STAT_RX_GREEN_PRIO_1,
+       OCELOT_STAT_RX_GREEN_PRIO_2,
+       OCELOT_STAT_RX_GREEN_PRIO_3,
+       OCELOT_STAT_RX_GREEN_PRIO_4,
+       OCELOT_STAT_RX_GREEN_PRIO_5,
+       OCELOT_STAT_RX_GREEN_PRIO_6,
+       OCELOT_STAT_RX_GREEN_PRIO_7,
+       OCELOT_STAT_TX_OCTETS,
+       OCELOT_STAT_TX_UNICAST,
+       OCELOT_STAT_TX_MULTICAST,
+       OCELOT_STAT_TX_BROADCAST,
+       OCELOT_STAT_TX_COLLISION,
+       OCELOT_STAT_TX_DROPS,
+       OCELOT_STAT_TX_PAUSE,
+       OCELOT_STAT_TX_64,
+       OCELOT_STAT_TX_65_127,
+       OCELOT_STAT_TX_128_255,
+       OCELOT_STAT_TX_256_511,
+       OCELOT_STAT_TX_512_1023,
+       OCELOT_STAT_TX_1024_1526,
+       OCELOT_STAT_TX_1527_MAX,
+       OCELOT_STAT_TX_YELLOW_PRIO_0,
+       OCELOT_STAT_TX_YELLOW_PRIO_1,
+       OCELOT_STAT_TX_YELLOW_PRIO_2,
+       OCELOT_STAT_TX_YELLOW_PRIO_3,
+       OCELOT_STAT_TX_YELLOW_PRIO_4,
+       OCELOT_STAT_TX_YELLOW_PRIO_5,
+       OCELOT_STAT_TX_YELLOW_PRIO_6,
+       OCELOT_STAT_TX_YELLOW_PRIO_7,
+       OCELOT_STAT_TX_GREEN_PRIO_0,
+       OCELOT_STAT_TX_GREEN_PRIO_1,
+       OCELOT_STAT_TX_GREEN_PRIO_2,
+       OCELOT_STAT_TX_GREEN_PRIO_3,
+       OCELOT_STAT_TX_GREEN_PRIO_4,
+       OCELOT_STAT_TX_GREEN_PRIO_5,
+       OCELOT_STAT_TX_GREEN_PRIO_6,
+       OCELOT_STAT_TX_GREEN_PRIO_7,
+       OCELOT_STAT_TX_AGED,
+       OCELOT_STAT_DROP_LOCAL,
+       OCELOT_STAT_DROP_TAIL,
+       OCELOT_STAT_DROP_YELLOW_PRIO_0,
+       OCELOT_STAT_DROP_YELLOW_PRIO_1,
+       OCELOT_STAT_DROP_YELLOW_PRIO_2,
+       OCELOT_STAT_DROP_YELLOW_PRIO_3,
+       OCELOT_STAT_DROP_YELLOW_PRIO_4,
+       OCELOT_STAT_DROP_YELLOW_PRIO_5,
+       OCELOT_STAT_DROP_YELLOW_PRIO_6,
+       OCELOT_STAT_DROP_YELLOW_PRIO_7,
+       OCELOT_STAT_DROP_GREEN_PRIO_0,
+       OCELOT_STAT_DROP_GREEN_PRIO_1,
+       OCELOT_STAT_DROP_GREEN_PRIO_2,
+       OCELOT_STAT_DROP_GREEN_PRIO_3,
+       OCELOT_STAT_DROP_GREEN_PRIO_4,
+       OCELOT_STAT_DROP_GREEN_PRIO_5,
+       OCELOT_STAT_DROP_GREEN_PRIO_6,
+       OCELOT_STAT_DROP_GREEN_PRIO_7,
+       OCELOT_NUM_STATS,
+};
+
 struct ocelot_stat_layout {
-       u32 offset;
+       u32 reg;
        char name[ETH_GSTRING_LEN];
 };
 
-#define OCELOT_STAT_END { .name = "" }
-
 struct ocelot_stats_region {
        struct list_head node;
-       u32 offset;
+       u32 base;
        int count;
        u32 *buf;
 };
@@ -707,7 +857,6 @@ struct ocelot {
        const u32 *const                *map;
        const struct ocelot_stat_layout *stats_layout;
        struct list_head                stats_regions;
-       unsigned int                    num_stats;
 
        u32                             pool_size[OCELOT_SB_NUM][OCELOT_SB_POOL_NUM];
        int                             packet_buffer_size;
@@ -750,7 +899,7 @@ struct ocelot {
        struct ocelot_psfp_list         psfp;
 
        /* Workqueue to check statistics for overflow with its lock */
-       struct mutex                    stats_lock;
+       spinlock_t                      stats_lock;
        u64                             *stats;
        struct delayed_work             stats_work;
        struct workqueue_struct         *stats_queue;
@@ -786,8 +935,8 @@ struct ocelot_policer {
        u32 burst; /* bytes */
 };
 
-#define ocelot_bulk_read_rix(ocelot, reg, ri, buf, count) \
-       __ocelot_bulk_read_ix(ocelot, reg, reg##_RSZ * (ri), buf, count)
+#define ocelot_bulk_read(ocelot, reg, buf, count) \
+       __ocelot_bulk_read_ix(ocelot, reg, 0, buf, count)
 
 #define ocelot_read_ix(ocelot, reg, gi, ri) \
        __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri))
index 476d3e5..f8c20d3 100644 (file)
 #define VRING_USED_ALIGN_SIZE 4
 #define VRING_DESC_ALIGN_SIZE 16
 
-/* Virtio ring descriptors: 16 bytes.  These can chain together via "next". */
+/**
+ * struct vring_desc - Virtio ring descriptors,
+ * 16 bytes long. These can chain together via @next.
+ *
+ * @addr: buffer address (guest-physical)
+ * @len: buffer length
+ * @flags: descriptor flags
+ * @next: index of the next descriptor in the chain,
+ *        if the VRING_DESC_F_NEXT flag is set. We chain unused
+ *        descriptors via this, too.
+ */
 struct vring_desc {
-       /* Address (guest-physical). */
        __virtio64 addr;
-       /* Length. */
        __virtio32 len;
-       /* The flags as indicated above. */
        __virtio16 flags;
-       /* We chain unused descriptors via this, too */
        __virtio16 next;
 };
 
index 80fe60f..532362f 100644 (file)
@@ -70,11 +70,7 @@ config CC_CAN_LINK_STATIC
        default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(USERCFLAGS) $(USERLDFLAGS) $(m64-flag) -static) if 64BIT
        default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(USERCFLAGS) $(USERLDFLAGS) $(m32-flag) -static)
 
-config CC_HAS_ASM_GOTO
-       def_bool $(success,$(srctree)/scripts/gcc-goto.sh $(CC))
-
 config CC_HAS_ASM_GOTO_OUTPUT
-       depends on CC_HAS_ASM_GOTO
        def_bool $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null)
 
 config CC_HAS_ASM_GOTO_TIED_OUTPUT
index 6d71748..f8cdf1d 100644 (file)
@@ -116,7 +116,7 @@ static void io_netmsg_recycle(struct io_kiocb *req, unsigned int issue_flags)
 {
        struct io_async_msghdr *hdr = req->async_data;
 
-       if (!hdr || issue_flags & IO_URING_F_UNLOCKED)
+       if (!req_has_async_data(req) || issue_flags & IO_URING_F_UNLOCKED)
                return;
 
        /* Let normal cleanup path reap it if we fail adding to the cache */
@@ -152,9 +152,9 @@ static int io_setup_async_msg(struct io_kiocb *req,
                              struct io_async_msghdr *kmsg,
                              unsigned int issue_flags)
 {
-       struct io_async_msghdr *async_msg = req->async_data;
+       struct io_async_msghdr *async_msg;
 
-       if (async_msg)
+       if (req_has_async_data(req))
                return -EAGAIN;
        async_msg = io_recvmsg_alloc_async(req, issue_flags);
        if (!async_msg) {
@@ -977,6 +977,14 @@ int io_sendzc(struct io_kiocb *req, unsigned int issue_flags)
        msg.msg_controllen = 0;
        msg.msg_namelen = 0;
 
+       if (zc->addr) {
+               ret = move_addr_to_kernel(zc->addr, zc->addr_len, &address);
+               if (unlikely(ret < 0))
+                       return ret;
+               msg.msg_name = (struct sockaddr *)&address;
+               msg.msg_namelen = zc->addr_len;
+       }
+
        if (zc->flags & IORING_RECVSEND_FIXED_BUF) {
                ret = io_import_fixed(WRITE, &msg.msg_iter, req->imu,
                                        (u64)(uintptr_t)zc->buf, zc->len);
@@ -992,14 +1000,6 @@ int io_sendzc(struct io_kiocb *req, unsigned int issue_flags)
                        return ret;
        }
 
-       if (zc->addr) {
-               ret = move_addr_to_kernel(zc->addr, zc->addr_len, &address);
-               if (unlikely(ret < 0))
-                       return ret;
-               msg.msg_name = (struct sockaddr *)&address;
-               msg.msg_namelen = zc->addr_len;
-       }
-
        msg_flags = zc->msg_flags | MSG_ZEROCOPY;
        if (issue_flags & IO_URING_F_NONBLOCK)
                msg_flags |= MSG_DONTWAIT;
index 65f0b42..80f6445 100644 (file)
@@ -8,7 +8,7 @@
 #include "rsrc.h"
 
 #define IO_NOTIF_SPLICE_BATCH  32
-#define IORING_MAX_NOTIF_SLOTS (1U << 10)
+#define IORING_MAX_NOTIF_SLOTS (1U << 15)
 
 struct io_notif_data {
        struct file             *file;
index 85fa9db..82c6161 100644 (file)
@@ -24,7 +24,7 @@ void bpf_sk_reuseport_detach(struct sock *sk)
        struct sock __rcu **socks;
 
        write_lock_bh(&sk->sk_callback_lock);
-       socks = __rcu_dereference_sk_user_data_with_flags(sk, SK_USER_DATA_BPF);
+       socks = __locked_read_sk_user_data_with_flags(sk, SK_USER_DATA_BPF);
        if (socks) {
                WRITE_ONCE(sk->sk_user_data, NULL);
                /*
index bc921a3..126c769 100644 (file)
@@ -2974,6 +2974,16 @@ int ftrace_startup(struct ftrace_ops *ops, int command)
 
        ftrace_startup_enable(command);
 
+       /*
+        * If ftrace is in an undefined state, we just remove ops from list
+        * to prevent the NULL pointer, instead of totally rolling it back and
+        * free trampoline, because those actions could cause further damage.
+        */
+       if (unlikely(ftrace_disabled)) {
+               __unregister_ftrace_function(ops);
+               return -ENODEV;
+       }
+
        ops->flags &= ~FTRACE_OPS_FL_ADDING;
 
        return 0;
index 4a0e9d9..1783e34 100644 (file)
@@ -227,6 +227,7 @@ static int trace_eprobe_tp_arg_update(struct trace_eprobe *ep, int i)
        struct probe_arg *parg = &ep->tp.args[i];
        struct ftrace_event_field *field;
        struct list_head *head;
+       int ret = -ENOENT;
 
        head = trace_get_fields(ep->event);
        list_for_each_entry(field, head, link) {
@@ -236,9 +237,20 @@ static int trace_eprobe_tp_arg_update(struct trace_eprobe *ep, int i)
                        return 0;
                }
        }
+
+       /*
+        * Argument not found on event. But allow for comm and COMM
+        * to be used to get the current->comm.
+        */
+       if (strcmp(parg->code->data, "COMM") == 0 ||
+           strcmp(parg->code->data, "comm") == 0) {
+               parg->code->op = FETCH_OP_COMM;
+               ret = 0;
+       }
+
        kfree(parg->code->data);
        parg->code->data = NULL;
-       return -ENOENT;
+       return ret;
 }
 
 static int eprobe_event_define_fields(struct trace_event_call *event_call)
@@ -311,6 +323,27 @@ static unsigned long get_event_field(struct fetch_insn *code, void *rec)
 
        addr = rec + field->offset;
 
+       if (is_string_field(field)) {
+               switch (field->filter_type) {
+               case FILTER_DYN_STRING:
+                       val = (unsigned long)(rec + (*(unsigned int *)addr & 0xffff));
+                       break;
+               case FILTER_RDYN_STRING:
+                       val = (unsigned long)(addr + (*(unsigned int *)addr & 0xffff));
+                       break;
+               case FILTER_STATIC_STRING:
+                       val = (unsigned long)addr;
+                       break;
+               case FILTER_PTR_STRING:
+                       val = (unsigned long)(*(char *)addr);
+                       break;
+               default:
+                       WARN_ON_ONCE(1);
+                       return 0;
+               }
+               return val;
+       }
+
        switch (field->size) {
        case 1:
                if (field->is_signed)
@@ -342,16 +375,38 @@ static unsigned long get_event_field(struct fetch_insn *code, void *rec)
 
 static int get_eprobe_size(struct trace_probe *tp, void *rec)
 {
+       struct fetch_insn *code;
        struct probe_arg *arg;
        int i, len, ret = 0;
 
        for (i = 0; i < tp->nr_args; i++) {
                arg = tp->args + i;
-               if (unlikely(arg->dynamic)) {
+               if (arg->dynamic) {
                        unsigned long val;
 
-                       val = get_event_field(arg->code, rec);
-                       len = process_fetch_insn_bottom(arg->code + 1, val, NULL, NULL);
+                       code = arg->code;
+ retry:
+                       switch (code->op) {
+                       case FETCH_OP_TP_ARG:
+                               val = get_event_field(code, rec);
+                               break;
+                       case FETCH_OP_IMM:
+                               val = code->immediate;
+                               break;
+                       case FETCH_OP_COMM:
+                               val = (unsigned long)current->comm;
+                               break;
+                       case FETCH_OP_DATA:
+                               val = (unsigned long)code->data;
+                               break;
+                       case FETCH_NOP_SYMBOL:  /* Ignore a place holder */
+                               code++;
+                               goto retry;
+                       default:
+                               continue;
+                       }
+                       code++;
+                       len = process_fetch_insn_bottom(code, val, NULL, NULL);
                        if (len > 0)
                                ret += len;
                }
@@ -369,8 +424,28 @@ process_fetch_insn(struct fetch_insn *code, void *rec, void *dest,
 {
        unsigned long val;
 
-       val = get_event_field(code, rec);
-       return process_fetch_insn_bottom(code + 1, val, dest, base);
+ retry:
+       switch (code->op) {
+       case FETCH_OP_TP_ARG:
+               val = get_event_field(code, rec);
+               break;
+       case FETCH_OP_IMM:
+               val = code->immediate;
+               break;
+       case FETCH_OP_COMM:
+               val = (unsigned long)current->comm;
+               break;
+       case FETCH_OP_DATA:
+               val = (unsigned long)code->data;
+               break;
+       case FETCH_NOP_SYMBOL:  /* Ignore a place holder */
+               code++;
+               goto retry;
+       default:
+               return -EILSEQ;
+       }
+       code++;
+       return process_fetch_insn_bottom(code, val, dest, base);
 }
 NOKPROBE_SYMBOL(process_fetch_insn)
 
@@ -845,6 +920,10 @@ static int trace_eprobe_tp_update_arg(struct trace_eprobe *ep, const char *argv[
                        trace_probe_log_err(0, BAD_ATTACH_ARG);
        }
 
+       /* Handle symbols "@" */
+       if (!ret)
+               ret = traceprobe_update_arg(&ep->tp.args[i]);
+
        return ret;
 }
 
@@ -883,7 +962,7 @@ static int __trace_eprobe_create(int argc, const char *argv[])
        trace_probe_log_set_index(1);
        sys_event = argv[1];
        ret = traceprobe_parse_event_name(&sys_event, &sys_name, buf2, 0);
-       if (!sys_event || !sys_name) {
+       if (ret || !sys_event || !sys_name) {
                trace_probe_log_err(0, NO_EVENT_INFO);
                goto parse_error;
        }
index a114549..61e3a26 100644 (file)
@@ -157,7 +157,7 @@ static void perf_trace_event_unreg(struct perf_event *p_event)
        int i;
 
        if (--tp_event->perf_refcount > 0)
-               goto out;
+               return;
 
        tp_event->class->reg(tp_event, TRACE_REG_PERF_UNREGISTER, NULL);
 
@@ -176,8 +176,6 @@ static void perf_trace_event_unreg(struct perf_event *p_event)
                        perf_trace_buf[i] = NULL;
                }
        }
-out:
-       trace_event_put_ref(tp_event);
 }
 
 static int perf_trace_event_open(struct perf_event *p_event)
@@ -241,6 +239,7 @@ void perf_trace_destroy(struct perf_event *p_event)
        mutex_lock(&event_mutex);
        perf_trace_event_close(p_event);
        perf_trace_event_unreg(p_event);
+       trace_event_put_ref(p_event->tp_event);
        mutex_unlock(&event_mutex);
 }
 
@@ -292,6 +291,7 @@ void perf_kprobe_destroy(struct perf_event *p_event)
        mutex_lock(&event_mutex);
        perf_trace_event_close(p_event);
        perf_trace_event_unreg(p_event);
+       trace_event_put_ref(p_event->tp_event);
        mutex_unlock(&event_mutex);
 
        destroy_local_trace_kprobe(p_event->tp_event);
@@ -347,6 +347,7 @@ void perf_uprobe_destroy(struct perf_event *p_event)
        mutex_lock(&event_mutex);
        perf_trace_event_close(p_event);
        perf_trace_event_unreg(p_event);
+       trace_event_put_ref(p_event->tp_event);
        mutex_unlock(&event_mutex);
        destroy_local_trace_uprobe(p_event->tp_event);
 }
index 181f081..0356cae 100644 (file)
@@ -176,6 +176,7 @@ static int trace_define_generic_fields(void)
 
        __generic_field(int, CPU, FILTER_CPU);
        __generic_field(int, cpu, FILTER_CPU);
+       __generic_field(int, common_cpu, FILTER_CPU);
        __generic_field(char *, COMM, FILTER_COMM);
        __generic_field(char *, comm, FILTER_COMM);
 
index 850a88a..36dff27 100644 (file)
@@ -283,7 +283,14 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
        int ret = 0;
        int len;
 
-       if (strcmp(arg, "retval") == 0) {
+       if (flags & TPARG_FL_TPOINT) {
+               if (code->data)
+                       return -EFAULT;
+               code->data = kstrdup(arg, GFP_KERNEL);
+               if (!code->data)
+                       return -ENOMEM;
+               code->op = FETCH_OP_TP_ARG;
+       } else if (strcmp(arg, "retval") == 0) {
                if (flags & TPARG_FL_RETURN) {
                        code->op = FETCH_OP_RETVAL;
                } else {
@@ -307,7 +314,7 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
                        }
                } else
                        goto inval_var;
-       } else if (strcmp(arg, "comm") == 0) {
+       } else if (strcmp(arg, "comm") == 0 || strcmp(arg, "COMM") == 0) {
                code->op = FETCH_OP_COMM;
 #ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
        } else if (((flags & TPARG_FL_MASK) ==
@@ -323,13 +330,6 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
                code->op = FETCH_OP_ARG;
                code->param = (unsigned int)param - 1;
 #endif
-       } else if (flags & TPARG_FL_TPOINT) {
-               if (code->data)
-                       return -EFAULT;
-               code->data = kstrdup(arg, GFP_KERNEL);
-               if (!code->data)
-                       return -ENOMEM;
-               code->op = FETCH_OP_TP_ARG;
        } else
                goto inval_var;
 
@@ -384,6 +384,11 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
                break;
 
        case '%':       /* named register */
+               if (flags & TPARG_FL_TPOINT) {
+                       /* eprobes do not handle registers */
+                       trace_probe_log_err(offs, BAD_VAR);
+                       break;
+               }
                ret = regs_query_register_offset(arg + 1);
                if (ret >= 0) {
                        code->op = FETCH_OP_REG;
@@ -617,9 +622,11 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
 
        /*
         * Since $comm and immediate string can not be dereferenced,
-        * we can find those by strcmp.
+        * we can find those by strcmp. But ignore for eprobes.
         */
-       if (strcmp(arg, "$comm") == 0 || strncmp(arg, "\\\"", 2) == 0) {
+       if (!(flags & TPARG_FL_TPOINT) &&
+           (strcmp(arg, "$comm") == 0 || strcmp(arg, "$COMM") == 0 ||
+            strncmp(arg, "\\\"", 2) == 0)) {
                /* The type of $comm must be "string", and not an array. */
                if (parg->count || (t && strcmp(t, "string")))
                        goto out;
index c952121..5927d7f 100644 (file)
@@ -34,9 +34,10 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
         is_single_threaded.o plist.o decompress.o kobject_uevent.o \
         earlycpio.o seq_buf.o siphash.o dec_and_lock.o \
         nmi_backtrace.o win_minmax.o memcat_p.o \
-        buildid.o cpumask.o
+        buildid.o
 
 lib-$(CONFIG_PRINTK) += dump_stack.o
+lib-$(CONFIG_SMP) += cpumask.o
 
 lib-y  += kobject.o klist.o
 obj-y  += lockref.o
index 8baeb37..f0ae119 100644 (file)
@@ -109,7 +109,6 @@ void __init free_bootmem_cpumask_var(cpumask_var_t mask)
 }
 #endif
 
-#if NR_CPUS > 1
 /**
  * cpumask_local_spread - select the i'th cpu with local numa cpu's first
  * @i: index number
@@ -197,4 +196,3 @@ unsigned int cpumask_any_distribute(const struct cpumask *srcp)
        return next;
 }
 EXPORT_SYMBOL(cpumask_any_distribute);
-#endif /* NR_CPUS */
index a10335b..c8d137e 100644 (file)
@@ -345,7 +345,7 @@ static void gnet_stats_add_queue_cpu(struct gnet_stats_queue *qstats,
        for_each_possible_cpu(i) {
                const struct gnet_stats_queue *qcpu = per_cpu_ptr(q, i);
 
-               qstats->qlen += qcpu->backlog;
+               qstats->qlen += qcpu->qlen;
                qstats->backlog += qcpu->backlog;
                qstats->drops += qcpu->drops;
                qstats->requeues += qcpu->requeues;
index 6a8c259..5b669eb 100644 (file)
@@ -307,14 +307,32 @@ static int neigh_del_timer(struct neighbour *n)
        return 0;
 }
 
-static void pneigh_queue_purge(struct sk_buff_head *list)
+static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net)
 {
+       unsigned long flags;
        struct sk_buff *skb;
 
-       while ((skb = skb_dequeue(list)) != NULL) {
-               dev_put(skb->dev);
-               kfree_skb(skb);
+       spin_lock_irqsave(&list->lock, flags);
+       skb = skb_peek(list);
+       while (skb != NULL) {
+               struct sk_buff *skb_next = skb_peek_next(skb, list);
+               struct net_device *dev = skb->dev;
+               if (net == NULL || net_eq(dev_net(dev), net)) {
+                       struct in_device *in_dev;
+
+                       rcu_read_lock();
+                       in_dev = __in_dev_get_rcu(dev);
+                       if (in_dev)
+                               in_dev->arp_parms->qlen--;
+                       rcu_read_unlock();
+                       __skb_unlink(skb, list);
+
+                       dev_put(dev);
+                       kfree_skb(skb);
+               }
+               skb = skb_next;
        }
+       spin_unlock_irqrestore(&list->lock, flags);
 }
 
 static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev,
@@ -385,9 +403,9 @@ static int __neigh_ifdown(struct neigh_table *tbl, struct net_device *dev,
        write_lock_bh(&tbl->lock);
        neigh_flush_dev(tbl, dev, skip_perm);
        pneigh_ifdown_and_unlock(tbl, dev);
-
-       del_timer_sync(&tbl->proxy_timer);
-       pneigh_queue_purge(&tbl->proxy_queue);
+       pneigh_queue_purge(&tbl->proxy_queue, dev_net(dev));
+       if (skb_queue_empty_lockless(&tbl->proxy_queue))
+               del_timer_sync(&tbl->proxy_timer);
        return 0;
 }
 
@@ -1597,8 +1615,15 @@ static void neigh_proxy_process(struct timer_list *t)
 
                if (tdif <= 0) {
                        struct net_device *dev = skb->dev;
+                       struct in_device *in_dev;
 
+                       rcu_read_lock();
+                       in_dev = __in_dev_get_rcu(dev);
+                       if (in_dev)
+                               in_dev->arp_parms->qlen--;
+                       rcu_read_unlock();
                        __skb_unlink(skb, &tbl->proxy_queue);
+
                        if (tbl->proxy_redo && netif_running(dev)) {
                                rcu_read_lock();
                                tbl->proxy_redo(skb);
@@ -1623,7 +1648,7 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
        unsigned long sched_next = jiffies +
                        prandom_u32_max(NEIGH_VAR(p, PROXY_DELAY));
 
-       if (tbl->proxy_queue.qlen > NEIGH_VAR(p, PROXY_QLEN)) {
+       if (p->qlen > NEIGH_VAR(p, PROXY_QLEN)) {
                kfree_skb(skb);
                return;
        }
@@ -1639,6 +1664,7 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
        skb_dst_drop(skb);
        dev_hold(skb->dev);
        __skb_queue_tail(&tbl->proxy_queue, skb);
+       p->qlen++;
        mod_timer(&tbl->proxy_timer, sched_next);
        spin_unlock(&tbl->proxy_queue.lock);
 }
@@ -1671,6 +1697,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
                refcount_set(&p->refcnt, 1);
                p->reachable_time =
                                neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME));
+               p->qlen = 0;
                netdev_hold(dev, &p->dev_tracker, GFP_KERNEL);
                p->dev = dev;
                write_pnet(&p->net, net);
@@ -1736,6 +1763,7 @@ void neigh_table_init(int index, struct neigh_table *tbl)
        refcount_set(&tbl->parms.refcnt, 1);
        tbl->parms.reachable_time =
                          neigh_rand_reach_time(NEIGH_VAR(&tbl->parms, BASE_REACHABLE_TIME));
+       tbl->parms.qlen = 0;
 
        tbl->stats = alloc_percpu(struct neigh_statistics);
        if (!tbl->stats)
@@ -1787,7 +1815,7 @@ int neigh_table_clear(int index, struct neigh_table *tbl)
        cancel_delayed_work_sync(&tbl->managed_work);
        cancel_delayed_work_sync(&tbl->gc_work);
        del_timer_sync(&tbl->proxy_timer);
-       pneigh_queue_purge(&tbl->proxy_queue);
+       pneigh_queue_purge(&tbl->proxy_queue, NULL);
        neigh_ifdown(tbl, NULL);
        if (atomic_read(&tbl->entries))
                pr_crit("neighbour leakage\n");
index ac45328..4b5b15c 100644 (file)
@@ -6070,6 +6070,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
        if (kind == RTNL_KIND_DEL && (nlh->nlmsg_flags & NLM_F_BULK) &&
            !(flags & RTNL_FLAG_BULK_DEL_SUPPORTED)) {
                NL_SET_ERR_MSG(extack, "Bulk delete is not supported");
+               module_put(owner);
                goto err_unlock;
        }
 
index f47338d..59e75ff 100644 (file)
@@ -1194,8 +1194,9 @@ static int sk_psock_verdict_recv(struct sock *sk, struct sk_buff *skb)
                ret = bpf_prog_run_pin_on_cpu(prog, skb);
                ret = sk_psock_map_verd(ret, skb_bpf_redirect_fetch(skb));
        }
-       if (sk_psock_verdict_apply(psock, skb, ret) < 0)
-               len = 0;
+       ret = sk_psock_verdict_apply(psock, skb, ret);
+       if (ret < 0)
+               len = ret;
 out:
        rcu_read_unlock();
        return len;
index 2dd76eb..a8895ee 100644 (file)
@@ -145,11 +145,14 @@ int dsa_port_set_state(struct dsa_port *dp, u8 state, bool do_fast_age)
 static void dsa_port_set_state_now(struct dsa_port *dp, u8 state,
                                   bool do_fast_age)
 {
+       struct dsa_switch *ds = dp->ds;
        int err;
 
        err = dsa_port_set_state(dp, state, do_fast_age);
-       if (err)
-               pr_err("DSA: failed to set STP state %u (%d)\n", state, err);
+       if (err && err != -EOPNOTSUPP) {
+               dev_err(ds->dev, "port %d failed to set STP state %u: %pe\n",
+                       dp->index, state, ERR_PTR(err));
+       }
 }
 
 int dsa_port_set_mst_state(struct dsa_port *dp,
index 970e9a2..bbe2187 100644 (file)
@@ -1567,17 +1567,11 @@ static int tcp_peek_sndq(struct sock *sk, struct msghdr *msg, int len)
  * calculation of whether or not we must ACK for the sake of
  * a window update.
  */
-void tcp_cleanup_rbuf(struct sock *sk, int copied)
+static void __tcp_cleanup_rbuf(struct sock *sk, int copied)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        bool time_to_ack = false;
 
-       struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
-
-       WARN(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq),
-            "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n",
-            tp->copied_seq, TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt);
-
        if (inet_csk_ack_scheduled(sk)) {
                const struct inet_connection_sock *icsk = inet_csk(sk);
 
@@ -1623,6 +1617,17 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied)
                tcp_send_ack(sk);
 }
 
+void tcp_cleanup_rbuf(struct sock *sk, int copied)
+{
+       struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
+       struct tcp_sock *tp = tcp_sk(sk);
+
+       WARN(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq),
+            "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n",
+            tp->copied_seq, TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt);
+       __tcp_cleanup_rbuf(sk, copied);
+}
+
 static void tcp_eat_recv_skb(struct sock *sk, struct sk_buff *skb)
 {
        __skb_unlink(skb, &sk->sk_receive_queue);
@@ -1756,34 +1761,26 @@ int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
        if (sk->sk_state == TCP_LISTEN)
                return -ENOTCONN;
 
-       while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
-               int used;
-
-               __skb_unlink(skb, &sk->sk_receive_queue);
-               used = recv_actor(sk, skb);
-               if (used <= 0) {
-                       if (!copied)
-                               copied = used;
-                       break;
-               }
-               seq += used;
-               copied += used;
+       skb = tcp_recv_skb(sk, seq, &offset);
+       if (!skb)
+               return 0;
 
-               if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) {
-                       consume_skb(skb);
+       __skb_unlink(skb, &sk->sk_receive_queue);
+       WARN_ON(!skb_set_owner_sk_safe(skb, sk));
+       copied = recv_actor(sk, skb);
+       if (copied >= 0) {
+               seq += copied;
+               if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
                        ++seq;
-                       break;
-               }
-               consume_skb(skb);
-               break;
        }
+       consume_skb(skb);
        WRITE_ONCE(tp->copied_seq, seq);
 
        tcp_rcv_space_adjust(sk);
 
        /* Clean up data we have read: This will do ACK frames. */
        if (copied > 0)
-               tcp_cleanup_rbuf(sk, copied);
+               __tcp_cleanup_rbuf(sk, copied);
 
        return copied;
 }
index 3fda563..79c6a82 100644 (file)
@@ -1517,7 +1517,7 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
  *   ip6_tnl_change() updates the tunnel parameters
  **/
 
-static int
+static void
 ip6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p)
 {
        t->parms.laddr = p->laddr;
@@ -1531,29 +1531,25 @@ ip6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p)
        t->parms.fwmark = p->fwmark;
        dst_cache_reset(&t->dst_cache);
        ip6_tnl_link_config(t);
-       return 0;
 }
 
-static int ip6_tnl_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
+static void ip6_tnl_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
 {
        struct net *net = t->net;
        struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
-       int err;
 
        ip6_tnl_unlink(ip6n, t);
        synchronize_net();
-       err = ip6_tnl_change(t, p);
+       ip6_tnl_change(t, p);
        ip6_tnl_link(ip6n, t);
        netdev_state_change(t->dev);
-       return err;
 }
 
-static int ip6_tnl0_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
+static void ip6_tnl0_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
 {
        /* for default tnl0 device allow to change only the proto */
        t->parms.proto = p->proto;
        netdev_state_change(t->dev);
-       return 0;
 }
 
 static void
@@ -1667,9 +1663,9 @@ ip6_tnl_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
                        } else
                                t = netdev_priv(dev);
                        if (dev == ip6n->fb_tnl_dev)
-                               err = ip6_tnl0_update(t, &p1);
+                               ip6_tnl0_update(t, &p1);
                        else
-                               err = ip6_tnl_update(t, &p1);
+                               ip6_tnl_update(t, &p1);
                }
                if (!IS_ERR(t)) {
                        err = 0;
@@ -2091,7 +2087,8 @@ static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[],
        } else
                t = netdev_priv(dev);
 
-       return ip6_tnl_update(t, &p);
+       ip6_tnl_update(t, &p);
+       return 0;
 }
 
 static void ip6_tnl_dellink(struct net_device *dev, struct list_head *head)
index 9845369..3a55349 100644 (file)
@@ -1378,6 +1378,9 @@ static void ndisc_router_discovery(struct sk_buff *skb)
        if (!rt && lifetime) {
                ND_PRINTK(3, info, "RA: adding default router\n");
 
+               if (neigh)
+                       neigh_release(neigh);
+
                rt = rt6_add_dflt_router(net, &ipv6_hdr(skb)->saddr,
                                         skb->dev, pref, defrtr_usr_metric);
                if (!rt) {
index 22f15eb..4b8d046 100644 (file)
@@ -144,7 +144,6 @@ config NF_CONNTRACK_ZONES
 
 config NF_CONNTRACK_PROCFS
        bool "Supply CT list in procfs (OBSOLETE)"
-       default y
        depends on PROC_FS
        help
        This option enables for the list of known conntrack entries
index a414274..0d9332e 100644 (file)
@@ -34,11 +34,6 @@ MODULE_DESCRIPTION("ftp connection tracking helper");
 MODULE_ALIAS("ip_conntrack_ftp");
 MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
 
-/* This is slow, but it's simple. --RR */
-static char *ftp_buffer;
-
-static DEFINE_SPINLOCK(nf_ftp_lock);
-
 #define MAX_PORTS 8
 static u_int16_t ports[MAX_PORTS];
 static unsigned int ports_c;
@@ -398,6 +393,9 @@ static int help(struct sk_buff *skb,
                return NF_ACCEPT;
        }
 
+       if (unlikely(skb_linearize(skb)))
+               return NF_DROP;
+
        th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
        if (th == NULL)
                return NF_ACCEPT;
@@ -411,12 +409,8 @@ static int help(struct sk_buff *skb,
        }
        datalen = skb->len - dataoff;
 
-       spin_lock_bh(&nf_ftp_lock);
-       fb_ptr = skb_header_pointer(skb, dataoff, datalen, ftp_buffer);
-       if (!fb_ptr) {
-               spin_unlock_bh(&nf_ftp_lock);
-               return NF_ACCEPT;
-       }
+       spin_lock_bh(&ct->lock);
+       fb_ptr = skb->data + dataoff;
 
        ends_in_nl = (fb_ptr[datalen - 1] == '\n');
        seq = ntohl(th->seq) + datalen;
@@ -544,7 +538,7 @@ out_update_nl:
        if (ends_in_nl)
                update_nl_seq(ct, seq, ct_ftp_info, dir, skb);
  out:
-       spin_unlock_bh(&nf_ftp_lock);
+       spin_unlock_bh(&ct->lock);
        return ret;
 }
 
@@ -571,7 +565,6 @@ static const struct nf_conntrack_expect_policy ftp_exp_policy = {
 static void __exit nf_conntrack_ftp_fini(void)
 {
        nf_conntrack_helpers_unregister(ftp, ports_c * 2);
-       kfree(ftp_buffer);
 }
 
 static int __init nf_conntrack_ftp_init(void)
@@ -580,10 +573,6 @@ static int __init nf_conntrack_ftp_init(void)
 
        NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_ftp_master));
 
-       ftp_buffer = kmalloc(65536, GFP_KERNEL);
-       if (!ftp_buffer)
-               return -ENOMEM;
-
        if (ports_c == 0)
                ports[ports_c++] = FTP_PORT;
 
@@ -603,7 +592,6 @@ static int __init nf_conntrack_ftp_init(void)
        ret = nf_conntrack_helpers_register(ftp, ports_c * 2);
        if (ret < 0) {
                pr_err("failed to register helpers\n");
-               kfree(ftp_buffer);
                return ret;
        }
 
index bb76305..5a9bce2 100644 (file)
@@ -34,6 +34,8 @@
 #include <net/netfilter/nf_conntrack_zones.h>
 #include <linux/netfilter/nf_conntrack_h323.h>
 
+#define H323_MAX_SIZE 65535
+
 /* Parameters */
 static unsigned int default_rrq_ttl __read_mostly = 300;
 module_param(default_rrq_ttl, uint, 0600);
@@ -86,6 +88,9 @@ static int get_tpkt_data(struct sk_buff *skb, unsigned int protoff,
        if (tcpdatalen <= 0)    /* No TCP data */
                goto clear_out;
 
+       if (tcpdatalen > H323_MAX_SIZE)
+               tcpdatalen = H323_MAX_SIZE;
+
        if (*data == NULL) {    /* first TPKT */
                /* Get first TPKT pointer */
                tpkt = skb_header_pointer(skb, tcpdataoff, tcpdatalen,
@@ -1169,6 +1174,9 @@ static unsigned char *get_udp_data(struct sk_buff *skb, unsigned int protoff,
        if (dataoff >= skb->len)
                return NULL;
        *datalen = skb->len - dataoff;
+       if (*datalen > H323_MAX_SIZE)
+               *datalen = H323_MAX_SIZE;
+
        return skb_header_pointer(skb, dataoff, *datalen, h323_buffer);
 }
 
@@ -1770,7 +1778,7 @@ static int __init nf_conntrack_h323_init(void)
 
        NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_h323_master));
 
-       h323_buffer = kmalloc(65536, GFP_KERNEL);
+       h323_buffer = kmalloc(H323_MAX_SIZE + 1, GFP_KERNEL);
        if (!h323_buffer)
                return -ENOMEM;
        ret = h323_helper_init();
index 08ee4e7..1796c45 100644 (file)
@@ -39,6 +39,7 @@ unsigned int (*nf_nat_irc_hook)(struct sk_buff *skb,
 EXPORT_SYMBOL_GPL(nf_nat_irc_hook);
 
 #define HELPER_NAME "irc"
+#define MAX_SEARCH_SIZE        4095
 
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
@@ -121,6 +122,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,
        int i, ret = NF_ACCEPT;
        char *addr_beg_p, *addr_end_p;
        typeof(nf_nat_irc_hook) nf_nat_irc;
+       unsigned int datalen;
 
        /* If packet is coming from IRC server */
        if (dir == IP_CT_DIR_REPLY)
@@ -140,8 +142,12 @@ static int help(struct sk_buff *skb, unsigned int protoff,
        if (dataoff >= skb->len)
                return NF_ACCEPT;
 
+       datalen = skb->len - dataoff;
+       if (datalen > MAX_SEARCH_SIZE)
+               datalen = MAX_SEARCH_SIZE;
+
        spin_lock_bh(&irc_buffer_lock);
-       ib_ptr = skb_header_pointer(skb, dataoff, skb->len - dataoff,
+       ib_ptr = skb_header_pointer(skb, dataoff, datalen,
                                    irc_buffer);
        if (!ib_ptr) {
                spin_unlock_bh(&irc_buffer_lock);
@@ -149,7 +155,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,
        }
 
        data = ib_ptr;
-       data_limit = ib_ptr + skb->len - dataoff;
+       data_limit = ib_ptr + datalen;
 
        /* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24
         * 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
@@ -251,7 +257,7 @@ static int __init nf_conntrack_irc_init(void)
        irc_exp_policy.max_expected = max_dcc_channels;
        irc_exp_policy.timeout = dcc_timeout;
 
-       irc_buffer = kmalloc(65536, GFP_KERNEL);
+       irc_buffer = kmalloc(MAX_SEARCH_SIZE + 1, GFP_KERNEL);
        if (!irc_buffer)
                return -ENOMEM;
 
index fcb33b1..13dc421 100644 (file)
@@ -34,10 +34,6 @@ MODULE_AUTHOR("Michal Schmidt <mschmidt@redhat.com>");
 MODULE_DESCRIPTION("SANE connection tracking helper");
 MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
 
-static char *sane_buffer;
-
-static DEFINE_SPINLOCK(nf_sane_lock);
-
 #define MAX_PORTS 8
 static u_int16_t ports[MAX_PORTS];
 static unsigned int ports_c;
@@ -67,14 +63,16 @@ static int help(struct sk_buff *skb,
        unsigned int dataoff, datalen;
        const struct tcphdr *th;
        struct tcphdr _tcph;
-       void *sb_ptr;
        int ret = NF_ACCEPT;
        int dir = CTINFO2DIR(ctinfo);
        struct nf_ct_sane_master *ct_sane_info = nfct_help_data(ct);
        struct nf_conntrack_expect *exp;
        struct nf_conntrack_tuple *tuple;
-       struct sane_request *req;
        struct sane_reply_net_start *reply;
+       union {
+               struct sane_request req;
+               struct sane_reply_net_start repl;
+       } buf;
 
        /* Until there's been traffic both ways, don't look in packets. */
        if (ctinfo != IP_CT_ESTABLISHED &&
@@ -92,59 +90,62 @@ static int help(struct sk_buff *skb,
                return NF_ACCEPT;
 
        datalen = skb->len - dataoff;
-
-       spin_lock_bh(&nf_sane_lock);
-       sb_ptr = skb_header_pointer(skb, dataoff, datalen, sane_buffer);
-       if (!sb_ptr) {
-               spin_unlock_bh(&nf_sane_lock);
-               return NF_ACCEPT;
-       }
-
        if (dir == IP_CT_DIR_ORIGINAL) {
+               const struct sane_request *req;
+
                if (datalen != sizeof(struct sane_request))
-                       goto out;
+                       return NF_ACCEPT;
+
+               req = skb_header_pointer(skb, dataoff, datalen, &buf.req);
+               if (!req)
+                       return NF_ACCEPT;
 
-               req = sb_ptr;
                if (req->RPC_code != htonl(SANE_NET_START)) {
                        /* Not an interesting command */
-                       ct_sane_info->state = SANE_STATE_NORMAL;
-                       goto out;
+                       WRITE_ONCE(ct_sane_info->state, SANE_STATE_NORMAL);
+                       return NF_ACCEPT;
                }
 
                /* We're interested in the next reply */
-               ct_sane_info->state = SANE_STATE_START_REQUESTED;
-               goto out;
+               WRITE_ONCE(ct_sane_info->state, SANE_STATE_START_REQUESTED);
+               return NF_ACCEPT;
        }
 
+       /* IP_CT_DIR_REPLY */
+
        /* Is it a reply to an uninteresting command? */
-       if (ct_sane_info->state != SANE_STATE_START_REQUESTED)
-               goto out;
+       if (READ_ONCE(ct_sane_info->state) != SANE_STATE_START_REQUESTED)
+               return NF_ACCEPT;
 
        /* It's a reply to SANE_NET_START. */
-       ct_sane_info->state = SANE_STATE_NORMAL;
+       WRITE_ONCE(ct_sane_info->state, SANE_STATE_NORMAL);
 
        if (datalen < sizeof(struct sane_reply_net_start)) {
                pr_debug("NET_START reply too short\n");
-               goto out;
+               return NF_ACCEPT;
        }
 
-       reply = sb_ptr;
+       datalen = sizeof(struct sane_reply_net_start);
+
+       reply = skb_header_pointer(skb, dataoff, datalen, &buf.repl);
+       if (!reply)
+               return NF_ACCEPT;
+
        if (reply->status != htonl(SANE_STATUS_SUCCESS)) {
                /* saned refused the command */
                pr_debug("unsuccessful SANE_STATUS = %u\n",
                         ntohl(reply->status));
-               goto out;
+               return NF_ACCEPT;
        }
 
        /* Invalid saned reply? Ignore it. */
        if (reply->zero != 0)
-               goto out;
+               return NF_ACCEPT;
 
        exp = nf_ct_expect_alloc(ct);
        if (exp == NULL) {
                nf_ct_helper_log(skb, ct, "cannot alloc expectation");
-               ret = NF_DROP;
-               goto out;
+               return NF_DROP;
        }
 
        tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
@@ -162,9 +163,6 @@ static int help(struct sk_buff *skb,
        }
 
        nf_ct_expect_put(exp);
-
-out:
-       spin_unlock_bh(&nf_sane_lock);
        return ret;
 }
 
@@ -178,7 +176,6 @@ static const struct nf_conntrack_expect_policy sane_exp_policy = {
 static void __exit nf_conntrack_sane_fini(void)
 {
        nf_conntrack_helpers_unregister(sane, ports_c * 2);
-       kfree(sane_buffer);
 }
 
 static int __init nf_conntrack_sane_init(void)
@@ -187,10 +184,6 @@ static int __init nf_conntrack_sane_init(void)
 
        NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_sane_master));
 
-       sane_buffer = kmalloc(65536, GFP_KERNEL);
-       if (!sane_buffer)
-               return -ENOMEM;
-
        if (ports_c == 0)
                ports[ports_c++] = SANE_PORT;
 
@@ -210,7 +203,6 @@ static int __init nf_conntrack_sane_init(void)
        ret = nf_conntrack_helpers_register(sane, ports_c * 2);
        if (ret < 0) {
                pr_err("failed to register helpers\n");
-               kfree(sane_buffer);
                return ret;
        }
 
index 3cc8899..62cfb0e 100644 (file)
@@ -889,7 +889,7 @@ static int nf_tables_dump_tables(struct sk_buff *skb,
 
        rcu_read_lock();
        nft_net = nft_pernet(net);
-       cb->seq = nft_net->base_seq;
+       cb->seq = READ_ONCE(nft_net->base_seq);
 
        list_for_each_entry_rcu(table, &nft_net->tables, list) {
                if (family != NFPROTO_UNSPEC && family != table->family)
@@ -1705,7 +1705,7 @@ static int nf_tables_dump_chains(struct sk_buff *skb,
 
        rcu_read_lock();
        nft_net = nft_pernet(net);
-       cb->seq = nft_net->base_seq;
+       cb->seq = READ_ONCE(nft_net->base_seq);
 
        list_for_each_entry_rcu(table, &nft_net->tables, list) {
                if (family != NFPROTO_UNSPEC && family != table->family)
@@ -3149,7 +3149,7 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
 
        rcu_read_lock();
        nft_net = nft_pernet(net);
-       cb->seq = nft_net->base_seq;
+       cb->seq = READ_ONCE(nft_net->base_seq);
 
        list_for_each_entry_rcu(table, &nft_net->tables, list) {
                if (family != NFPROTO_UNSPEC && family != table->family)
@@ -3907,7 +3907,7 @@ cont:
                list_for_each_entry(i, &ctx->table->sets, list) {
                        int tmp;
 
-                       if (!nft_is_active_next(ctx->net, set))
+                       if (!nft_is_active_next(ctx->net, i))
                                continue;
                        if (!sscanf(i->name, name, &tmp))
                                continue;
@@ -4133,7 +4133,7 @@ static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
 
        rcu_read_lock();
        nft_net = nft_pernet(net);
-       cb->seq = nft_net->base_seq;
+       cb->seq = READ_ONCE(nft_net->base_seq);
 
        list_for_each_entry_rcu(table, &nft_net->tables, list) {
                if (ctx->family != NFPROTO_UNSPEC &&
@@ -4451,6 +4451,11 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
                err = nf_tables_set_desc_parse(&desc, nla[NFTA_SET_DESC]);
                if (err < 0)
                        return err;
+
+               if (desc.field_count > 1 && !(flags & NFT_SET_CONCAT))
+                       return -EINVAL;
+       } else if (flags & NFT_SET_CONCAT) {
+               return -EINVAL;
        }
 
        if (nla[NFTA_SET_EXPR] || nla[NFTA_SET_EXPRESSIONS])
@@ -5061,6 +5066,8 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
 
        rcu_read_lock();
        nft_net = nft_pernet(net);
+       cb->seq = READ_ONCE(nft_net->base_seq);
+
        list_for_each_entry_rcu(table, &nft_net->tables, list) {
                if (dump_ctx->ctx.family != NFPROTO_UNSPEC &&
                    dump_ctx->ctx.family != table->family)
@@ -5196,6 +5203,9 @@ static int nft_setelem_parse_flags(const struct nft_set *set,
        if (!(set->flags & NFT_SET_INTERVAL) &&
            *flags & NFT_SET_ELEM_INTERVAL_END)
                return -EINVAL;
+       if ((*flags & (NFT_SET_ELEM_INTERVAL_END | NFT_SET_ELEM_CATCHALL)) ==
+           (NFT_SET_ELEM_INTERVAL_END | NFT_SET_ELEM_CATCHALL))
+               return -EINVAL;
 
        return 0;
 }
@@ -5599,7 +5609,7 @@ int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set,
 
                err = nft_expr_clone(expr, set->exprs[i]);
                if (err < 0) {
-                       nft_expr_destroy(ctx, expr);
+                       kfree(expr);
                        goto err_expr;
                }
                expr_array[i] = expr;
@@ -5842,6 +5852,24 @@ static void nft_setelem_remove(const struct net *net,
                set->ops->remove(net, set, elem);
 }
 
+static bool nft_setelem_valid_key_end(const struct nft_set *set,
+                                     struct nlattr **nla, u32 flags)
+{
+       if ((set->flags & (NFT_SET_CONCAT | NFT_SET_INTERVAL)) ==
+                         (NFT_SET_CONCAT | NFT_SET_INTERVAL)) {
+               if (flags & NFT_SET_ELEM_INTERVAL_END)
+                       return false;
+               if (!nla[NFTA_SET_ELEM_KEY_END] &&
+                   !(flags & NFT_SET_ELEM_CATCHALL))
+                       return false;
+       } else {
+               if (nla[NFTA_SET_ELEM_KEY_END])
+                       return false;
+       }
+
+       return true;
+}
+
 static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
                            const struct nlattr *attr, u32 nlmsg_flags)
 {
@@ -5892,6 +5920,18 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
                        return -EINVAL;
        }
 
+       if (set->flags & NFT_SET_OBJECT) {
+               if (!nla[NFTA_SET_ELEM_OBJREF] &&
+                   !(flags & NFT_SET_ELEM_INTERVAL_END))
+                       return -EINVAL;
+       } else {
+               if (nla[NFTA_SET_ELEM_OBJREF])
+                       return -EINVAL;
+       }
+
+       if (!nft_setelem_valid_key_end(set, nla, flags))
+               return -EINVAL;
+
        if ((flags & NFT_SET_ELEM_INTERVAL_END) &&
             (nla[NFTA_SET_ELEM_DATA] ||
              nla[NFTA_SET_ELEM_OBJREF] ||
@@ -5899,6 +5939,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
              nla[NFTA_SET_ELEM_EXPIRATION] ||
              nla[NFTA_SET_ELEM_USERDATA] ||
              nla[NFTA_SET_ELEM_EXPR] ||
+             nla[NFTA_SET_ELEM_KEY_END] ||
              nla[NFTA_SET_ELEM_EXPRESSIONS]))
                return -EINVAL;
 
@@ -6029,10 +6070,6 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
        }
 
        if (nla[NFTA_SET_ELEM_OBJREF] != NULL) {
-               if (!(set->flags & NFT_SET_OBJECT)) {
-                       err = -EINVAL;
-                       goto err_parse_key_end;
-               }
                obj = nft_obj_lookup(ctx->net, ctx->table,
                                     nla[NFTA_SET_ELEM_OBJREF],
                                     set->objtype, genmask);
@@ -6325,6 +6362,9 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
        if (!nla[NFTA_SET_ELEM_KEY] && !(flags & NFT_SET_ELEM_CATCHALL))
                return -EINVAL;
 
+       if (!nft_setelem_valid_key_end(set, nla, flags))
+               return -EINVAL;
+
        nft_set_ext_prepare(&tmpl);
 
        if (flags != 0) {
@@ -6941,7 +6981,7 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
 
        rcu_read_lock();
        nft_net = nft_pernet(net);
-       cb->seq = nft_net->base_seq;
+       cb->seq = READ_ONCE(nft_net->base_seq);
 
        list_for_each_entry_rcu(table, &nft_net->tables, list) {
                if (family != NFPROTO_UNSPEC && family != table->family)
@@ -7873,7 +7913,7 @@ static int nf_tables_dump_flowtable(struct sk_buff *skb,
 
        rcu_read_lock();
        nft_net = nft_pernet(net);
-       cb->seq = nft_net->base_seq;
+       cb->seq = READ_ONCE(nft_net->base_seq);
 
        list_for_each_entry_rcu(table, &nft_net->tables, list) {
                if (family != NFPROTO_UNSPEC && family != table->family)
@@ -8806,6 +8846,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
        struct nft_trans_elem *te;
        struct nft_chain *chain;
        struct nft_table *table;
+       unsigned int base_seq;
        LIST_HEAD(adl);
        int err;
 
@@ -8855,9 +8896,12 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
         * Bump generation counter, invalidate any dump in progress.
         * Cannot fail after this point.
         */
-       while (++nft_net->base_seq == 0)
+       base_seq = READ_ONCE(nft_net->base_seq);
+       while (++base_seq == 0)
                ;
 
+       WRITE_ONCE(nft_net->base_seq, base_seq);
+
        /* step 3. Start new generation, rules_gen_X now in use. */
        net->nft.gencursor = nft_gencursor_next(net);
 
@@ -9419,13 +9463,9 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
                                break;
                        }
                }
-
-               cond_resched();
        }
 
        list_for_each_entry(set, &ctx->table->sets, list) {
-               cond_resched();
-
                if (!nft_is_active_next(ctx->net, set))
                        continue;
                if (!(set->flags & NFT_SET_MAP) ||
index c24b124..9c44518 100644 (file)
@@ -44,6 +44,10 @@ MODULE_DESCRIPTION("Netfilter messages via netlink socket");
 
 static unsigned int nfnetlink_pernet_id __read_mostly;
 
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+static DEFINE_SPINLOCK(nfnl_grp_active_lock);
+#endif
+
 struct nfnl_net {
        struct sock *nfnl;
 };
@@ -654,6 +658,44 @@ static void nfnetlink_rcv(struct sk_buff *skb)
                netlink_rcv_skb(skb, nfnetlink_rcv_msg);
 }
 
+static void nfnetlink_bind_event(struct net *net, unsigned int group)
+{
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+       int type, group_bit;
+       u8 v;
+
+       /* All NFNLGRP_CONNTRACK_* group bits fit into u8.
+        * The other groups are not relevant and can be ignored.
+        */
+       if (group >= 8)
+               return;
+
+       type = nfnl_group2type[group];
+
+       switch (type) {
+       case NFNL_SUBSYS_CTNETLINK:
+               break;
+       case NFNL_SUBSYS_CTNETLINK_EXP:
+               break;
+       default:
+               return;
+       }
+
+       group_bit = (1 << group);
+
+       spin_lock(&nfnl_grp_active_lock);
+       v = READ_ONCE(net->ct.ctnetlink_has_listener);
+       if ((v & group_bit) == 0) {
+               v |= group_bit;
+
+               /* read concurrently without nfnl_grp_active_lock held. */
+               WRITE_ONCE(net->ct.ctnetlink_has_listener, v);
+       }
+
+       spin_unlock(&nfnl_grp_active_lock);
+#endif
+}
+
 static int nfnetlink_bind(struct net *net, int group)
 {
        const struct nfnetlink_subsystem *ss;
@@ -670,28 +712,45 @@ static int nfnetlink_bind(struct net *net, int group)
        if (!ss)
                request_module_nowait("nfnetlink-subsys-%d", type);
 
-#ifdef CONFIG_NF_CONNTRACK_EVENTS
-       if (type == NFNL_SUBSYS_CTNETLINK) {
-               nfnl_lock(NFNL_SUBSYS_CTNETLINK);
-               WRITE_ONCE(net->ct.ctnetlink_has_listener, true);
-               nfnl_unlock(NFNL_SUBSYS_CTNETLINK);
-       }
-#endif
+       nfnetlink_bind_event(net, group);
        return 0;
 }
 
 static void nfnetlink_unbind(struct net *net, int group)
 {
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
+       int type, group_bit;
+
        if (group <= NFNLGRP_NONE || group > NFNLGRP_MAX)
                return;
 
-       if (nfnl_group2type[group] == NFNL_SUBSYS_CTNETLINK) {
-               nfnl_lock(NFNL_SUBSYS_CTNETLINK);
-               if (!nfnetlink_has_listeners(net, group))
-                       WRITE_ONCE(net->ct.ctnetlink_has_listener, false);
-               nfnl_unlock(NFNL_SUBSYS_CTNETLINK);
+       type = nfnl_group2type[group];
+
+       switch (type) {
+       case NFNL_SUBSYS_CTNETLINK:
+               break;
+       case NFNL_SUBSYS_CTNETLINK_EXP:
+               break;
+       default:
+               return;
+       }
+
+       /* ctnetlink_has_listener is u8 */
+       if (group >= 8)
+               return;
+
+       group_bit = (1 << group);
+
+       spin_lock(&nfnl_grp_active_lock);
+       if (!nfnetlink_has_listeners(net, group)) {
+               u8 v = READ_ONCE(net->ct.ctnetlink_has_listener);
+
+               v &= ~group_bit;
+
+               /* read concurrently without nfnl_grp_active_lock held. */
+               WRITE_ONCE(net->ct.ctnetlink_has_listener, v);
        }
+       spin_unlock(&nfnl_grp_active_lock);
 #endif
 }
 
index 1afca2a..5701092 100644 (file)
@@ -1174,13 +1174,17 @@ static int ctrl_dumppolicy_start(struct netlink_callback *cb)
                                                             op.policy,
                                                             op.maxattr);
                        if (err)
-                               return err;
+                               goto err_free_state;
                }
        }
 
        if (!ctx->state)
                return -ENODATA;
        return 0;
+
+err_free_state:
+       netlink_policy_dump_free(ctx->state);
+       return err;
 }
 
 static void *ctrl_dumppolicy_prep(struct sk_buff *skb,
index 8d7c900..87e3de0 100644 (file)
@@ -144,7 +144,7 @@ int netlink_policy_dump_add_policy(struct netlink_policy_dump_state **pstate,
 
        err = add_policy(&state, policy, maxtype);
        if (err)
-               return err;
+               goto err_try_undo;
 
        for (policy_idx = 0;
             policy_idx < state->n_alloc && state->policies[policy_idx].policy;
@@ -164,7 +164,7 @@ int netlink_policy_dump_add_policy(struct netlink_policy_dump_state **pstate,
                                                 policy[type].nested_policy,
                                                 policy[type].len);
                                if (err)
-                                       return err;
+                                       goto err_try_undo;
                                break;
                        default:
                                break;
@@ -174,6 +174,16 @@ int netlink_policy_dump_add_policy(struct netlink_policy_dump_state **pstate,
 
        *pstate = state;
        return 0;
+
+err_try_undo:
+       /* Try to preserve reasonable unwind semantics - if we're starting from
+        * scratch clean up fully, otherwise record what we got and caller will.
+        */
+       if (!*pstate)
+               netlink_policy_dump_free(state);
+       else
+               *pstate = state;
+       return err;
 }
 
 static bool
index 18196e1..9ced13c 100644 (file)
@@ -78,11 +78,6 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
        struct qrtr_mhi_dev *qdev;
        int rc;
 
-       /* start channels */
-       rc = mhi_prepare_for_transfer_autoqueue(mhi_dev);
-       if (rc)
-               return rc;
-
        qdev = devm_kzalloc(&mhi_dev->dev, sizeof(*qdev), GFP_KERNEL);
        if (!qdev)
                return -ENOMEM;
@@ -96,6 +91,13 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
        if (rc)
                return rc;
 
+       /* start channels */
+       rc = mhi_prepare_for_transfer_autoqueue(mhi_dev);
+       if (rc) {
+               qrtr_endpoint_unregister(&qdev->ep);
+               return rc;
+       }
+
        dev_dbg(qdev->dev, "Qualcomm MHI QRTR driver probed\n");
 
        return 0;
index 6fdedd9..cfbf0e1 100644 (file)
@@ -363,6 +363,7 @@ static int acquire_refill(struct rds_connection *conn)
 static void release_refill(struct rds_connection *conn)
 {
        clear_bit(RDS_RECV_REFILL, &conn->c_flags);
+       smp_mb__after_atomic();
 
        /* We don't use wait_on_bit()/wake_up_bit() because our waking is in a
         * hot path and finding waiters is very rare.  We don't want to walk
index 3f935cb..48712bc 100644 (file)
@@ -424,6 +424,11 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
                        return -EINVAL;
        }
 
+       if (!nhandle) {
+               NL_SET_ERR_MSG(extack, "Replacing with handle of 0 is invalid");
+               return -EINVAL;
+       }
+
        h1 = to_hash(nhandle);
        b = rtnl_dereference(head->table[h1]);
        if (!b) {
@@ -477,6 +482,11 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
        int err;
        bool new = true;
 
+       if (!handle) {
+               NL_SET_ERR_MSG(extack, "Creating with handle of 0 is invalid");
+               return -EINVAL;
+       }
+
        if (opt == NULL)
                return handle ? -EINVAL : 0;
 
index 7330eb9..c65c90a 100644 (file)
@@ -291,8 +291,10 @@ static ssize_t rpc_sysfs_xprt_state_change(struct kobject *kobj,
        int offline = 0, online = 0, remove = 0;
        struct rpc_xprt_switch *xps = rpc_sysfs_xprt_kobj_get_xprt_switch(kobj);
 
-       if (!xprt)
-               return 0;
+       if (!xprt || !xps) {
+               count = 0;
+               goto out_put;
+       }
 
        if (!strncmp(buf, "offline", 7))
                offline = 1;
index f76119f..fe27241 100644 (file)
@@ -2702,7 +2702,9 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
                        crypto_info->version != TLS_1_3_VERSION &&
                        !!(tfm->__crt_alg->cra_flags & CRYPTO_ALG_ASYNC);
 
-               tls_strp_init(&sw_ctx_rx->strp, sk);
+               rc = tls_strp_init(&sw_ctx_rx->strp, sk);
+               if (rc)
+                       goto free_aead;
        }
 
        goto out;
index f5f0d6f..0621c39 100644 (file)
@@ -49,7 +49,6 @@ ifdef CONFIG_CC_IS_CLANG
 KBUILD_CFLAGS += -Wno-initializer-overrides
 KBUILD_CFLAGS += -Wno-format
 KBUILD_CFLAGS += -Wno-sign-compare
-KBUILD_CFLAGS += -Wno-format-zero-length
 KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast)
 KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare
 KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access)
index 692d64a..e4deaf5 100644 (file)
@@ -4,7 +4,7 @@ gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY)  += latent_entropy_plugin.so
 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY)          \
                += -DLATENT_ENTROPY_PLUGIN
 ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
-    DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable
+    DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable -ULATENT_ENTROPY_PLUGIN
 endif
 export DISABLE_LATENT_ENTROPY_PLUGIN
 
index f754415..1337ced 100755 (executable)
@@ -51,6 +51,7 @@ def run_analysis(entry):
         checks += "linuxkernel-*"
     else:
         checks += "clang-analyzer-*"
+        checks += ",-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling"
     p = subprocess.run(["clang-tidy", "-p", args.path, checks, entry["file"]],
                        stdout=subprocess.PIPE,
                        stderr=subprocess.STDOUT,
index 7db8258..1db1889 100755 (executable)
@@ -59,7 +59,7 @@ fi
 if arg_contain -E "$@"; then
        # For scripts/cc-version.sh; This emulates GCC 20.0.0
        if arg_contain - "$@"; then
-               sed -n '/^GCC/{s/__GNUC__/20/; s/__GNUC_MINOR__/0/; s/__GNUC_PATCHLEVEL__/0/; p;}'
+               sed -n '/^GCC/{s/__GNUC__/20/; s/__GNUC_MINOR__/0/; s/__GNUC_PATCHLEVEL__/0/; p;}; s/__LONG_DOUBLE_128__/1/ p'
                exit 0
        else
                echo "no input files" >&2
diff --git a/scripts/gcc-goto.sh b/scripts/gcc-goto.sh
deleted file mode 100755 (executable)
index 8b980fb..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-# Test for gcc 'asm goto' support
-# Copyright (C) 2010, Jason Baron <jbaron@redhat.com>
-
-cat << "END" | $@ -x c - -fno-PIE -c -o /dev/null
-int main(void)
-{
-#if defined(__arm__) || defined(__aarch64__)
-       /*
-        * Not related to asm goto, but used by jump label
-        * and broken on some ARM GCC versions (see GCC Bug 48637).
-        */
-       static struct { int dummy; int state; } tp;
-       asm (".long %c0" :: "i" (&tp.state));
-#endif
-
-entry:
-       asm goto ("" :::: entry);
-       return 0;
-}
-END
index 55e32af..2c80da0 100644 (file)
@@ -2021,13 +2021,11 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod)
        /* record CRCs for exported symbols */
        buf_printf(buf, "\n");
        list_for_each_entry(sym, &mod->exported_symbols, list) {
-               if (!sym->crc_valid) {
+               if (!sym->crc_valid)
                        warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n"
                             "Is \"%s\" prototyped in <asm/asm-prototypes.h>?\n",
                             sym->name, mod->name, mod->is_vmlinux ? "" : ".ko",
                             sym->name);
-                       continue;
-               }
 
                buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x, \"%s\");\n",
                           sym->name, sym->crc, sym->is_gpl_only ? "_gpl" : "");
index 6ab5f2b..4452158 100644 (file)
@@ -356,13 +356,11 @@ static long dm_verity_ioctl(struct file *filp, unsigned int cmd, unsigned long a
 {
        void __user *uarg = (void __user *)arg;
        unsigned int fd;
-       int rc;
 
        switch (cmd) {
        case LOADPIN_IOC_SET_TRUSTED_VERITY_DIGESTS:
-               rc = copy_from_user(&fd, uarg, sizeof(fd));
-               if (rc)
-                       return rc;
+               if (copy_from_user(&fd, uarg, sizeof(fd)))
+                       return -EFAULT;
 
                return read_trusted_verity_root_digests(fd);
 
index b8058b3..0b2f04d 100644 (file)
@@ -111,9 +111,9 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
        entry = data->entry;
        mutex_lock(&entry->access);
        if (entry->c.ops->llseek) {
-               offset = entry->c.ops->llseek(entry,
-                                             data->file_private_data,
-                                             file, offset, orig);
+               ret = entry->c.ops->llseek(entry,
+                                          data->file_private_data,
+                                          file, offset, orig);
                goto out;
        }
 
index 129bffb..15e2a00 100644 (file)
@@ -1163,6 +1163,11 @@ static int cs35l41_no_acpi_dsd(struct cs35l41_hda *cs35l41, struct device *physd
                hw_cfg->gpio1.func = CS35l41_VSPK_SWITCH;
                hw_cfg->gpio1.valid = true;
        } else {
+               /*
+                * Note: CLSA010(0/1) are special cases which use a slightly different design.
+                * All other HIDs e.g. CSC3551 require valid ACPI _DSD properties to be supported.
+                */
+               dev_err(cs35l41->dev, "Error: ACPI _DSD Properties are missing for HID %s.\n", hid);
                hw_cfg->valid = false;
                hw_cfg->gpio1.valid = false;
                hw_cfg->gpio2.valid = false;
index e0d3a8b..b288874 100644 (file)
@@ -546,6 +546,10 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0BD6, "Dolphin", CS8409_DOLPHIN),
        SND_PCI_QUIRK(0x1028, 0x0BD7, "Dolphin", CS8409_DOLPHIN),
        SND_PCI_QUIRK(0x1028, 0x0BD8, "Dolphin", CS8409_DOLPHIN),
+       SND_PCI_QUIRK(0x1028, 0x0C43, "Dolphin", CS8409_DOLPHIN),
+       SND_PCI_QUIRK(0x1028, 0x0C50, "Dolphin", CS8409_DOLPHIN),
+       SND_PCI_QUIRK(0x1028, 0x0C51, "Dolphin", CS8409_DOLPHIN),
+       SND_PCI_QUIRK(0x1028, 0x0C52, "Dolphin", CS8409_DOLPHIN),
        {} /* terminator */
 };
 
index fd630d6..47e72cf 100644 (file)
@@ -9283,6 +9283,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1271, "ASUS X430UN", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1043, 0x12af, "ASUS UX582ZS", ALC245_FIXUP_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
        SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
        SND_PCI_QUIRK(0x1043, 0x1313, "Asus K42JZ", ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE),
@@ -9303,6 +9304,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
        SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
+       SND_PCI_QUIRK(0x1043, 0x1a8f, "ASUS UX582ZS", ALC245_FIXUP_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x1b11, "ASUS UX431DA", ALC294_FIXUP_ASUS_COEF_1B),
        SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
        SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
@@ -9389,6 +9391,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1558, 0x70f4, "Clevo NH77EPY", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x70f6, "Clevo NH77DPQ-Y", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x7716, "Clevo NS50PU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1558, 0x7717, "Clevo NS70PU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x7718, "Clevo L140PU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x8228, "Clevo NR40BU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x8520, "Clevo NH50D[CD]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
@@ -9490,6 +9493,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x3852, "Lenovo Yoga 7 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
        SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
        SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
+       SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
        SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
        SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
        SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
index ecfe7a7..e0b24e1 100644 (file)
@@ -143,6 +143,34 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "21CL"),
                }
        },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "21EM"),
+               }
+       },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "21EN"),
+               }
+       },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "21J5"),
+               }
+       },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "21J6"),
+               }
+       },
        {}
 };
 
index 38ab8d4..5a84432 100644 (file)
@@ -1986,7 +1986,7 @@ static int rt5640_set_bias_level(struct snd_soc_component *component,
                snd_soc_component_write(component, RT5640_PWR_MIXER, 0x0000);
                if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER)
                        snd_soc_component_write(component, RT5640_PWR_ANLG1,
-                               0x0018);
+                               0x2818);
                else
                        snd_soc_component_write(component, RT5640_PWR_ANLG1,
                                0x0000);
@@ -2600,7 +2600,8 @@ static void rt5640_enable_hda_jack_detect(
        snd_soc_component_update_bits(component, RT5640_DUMMY1, 0x400, 0x0);
 
        snd_soc_component_update_bits(component, RT5640_PWR_ANLG1,
-               RT5640_PWR_VREF2, RT5640_PWR_VREF2);
+               RT5640_PWR_VREF2 | RT5640_PWR_MB | RT5640_PWR_BG,
+               RT5640_PWR_VREF2 | RT5640_PWR_MB | RT5640_PWR_BG);
        usleep_range(10000, 15000);
        snd_soc_component_update_bits(component, RT5640_PWR_ANLG1,
                RT5640_PWR_FV2, RT5640_PWR_FV2);
index 3cb634c..bb653b6 100644 (file)
@@ -46,34 +46,22 @@ static void tas2770_reset(struct tas2770_priv *tas2770)
        usleep_range(1000, 2000);
 }
 
-static int tas2770_set_bias_level(struct snd_soc_component *component,
-                                enum snd_soc_bias_level level)
+static int tas2770_update_pwr_ctrl(struct tas2770_priv *tas2770)
 {
-       struct tas2770_priv *tas2770 =
-                       snd_soc_component_get_drvdata(component);
+       struct snd_soc_component *component = tas2770->component;
+       unsigned int val;
+       int ret;
 
-       switch (level) {
-       case SND_SOC_BIAS_ON:
-               snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
-                                             TAS2770_PWR_CTRL_MASK,
-                                             TAS2770_PWR_CTRL_ACTIVE);
-               break;
-       case SND_SOC_BIAS_STANDBY:
-       case SND_SOC_BIAS_PREPARE:
-               snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
-                                             TAS2770_PWR_CTRL_MASK,
-                                             TAS2770_PWR_CTRL_MUTE);
-               break;
-       case SND_SOC_BIAS_OFF:
-               snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
-                                             TAS2770_PWR_CTRL_MASK,
-                                             TAS2770_PWR_CTRL_SHUTDOWN);
-               break;
+       if (tas2770->dac_powered)
+               val = tas2770->unmuted ?
+                       TAS2770_PWR_CTRL_ACTIVE : TAS2770_PWR_CTRL_MUTE;
+       else
+               val = TAS2770_PWR_CTRL_SHUTDOWN;
 
-       default:
-               dev_err(tas2770->dev, "wrong power level setting %d\n", level);
-               return -EINVAL;
-       }
+       ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
+                                           TAS2770_PWR_CTRL_MASK, val);
+       if (ret < 0)
+               return ret;
 
        return 0;
 }
@@ -114,9 +102,7 @@ static int tas2770_codec_resume(struct snd_soc_component *component)
                gpiod_set_value_cansleep(tas2770->sdz_gpio, 1);
                usleep_range(1000, 2000);
        } else {
-               ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
-                                                   TAS2770_PWR_CTRL_MASK,
-                                                   TAS2770_PWR_CTRL_ACTIVE);
+               ret = tas2770_update_pwr_ctrl(tas2770);
                if (ret < 0)
                        return ret;
        }
@@ -152,24 +138,19 @@ static int tas2770_dac_event(struct snd_soc_dapm_widget *w,
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
-                                                   TAS2770_PWR_CTRL_MASK,
-                                                   TAS2770_PWR_CTRL_MUTE);
+               tas2770->dac_powered = 1;
+               ret = tas2770_update_pwr_ctrl(tas2770);
                break;
        case SND_SOC_DAPM_PRE_PMD:
-               ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
-                                                   TAS2770_PWR_CTRL_MASK,
-                                                   TAS2770_PWR_CTRL_SHUTDOWN);
+               tas2770->dac_powered = 0;
+               ret = tas2770_update_pwr_ctrl(tas2770);
                break;
        default:
                dev_err(tas2770->dev, "Not supported evevt\n");
                return -EINVAL;
        }
 
-       if (ret < 0)
-               return ret;
-
-       return 0;
+       return ret;
 }
 
 static const struct snd_kcontrol_new isense_switch =
@@ -203,21 +184,11 @@ static const struct snd_soc_dapm_route tas2770_audio_map[] = {
 static int tas2770_mute(struct snd_soc_dai *dai, int mute, int direction)
 {
        struct snd_soc_component *component = dai->component;
-       int ret;
-
-       if (mute)
-               ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
-                                                   TAS2770_PWR_CTRL_MASK,
-                                                   TAS2770_PWR_CTRL_MUTE);
-       else
-               ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
-                                                   TAS2770_PWR_CTRL_MASK,
-                                                   TAS2770_PWR_CTRL_ACTIVE);
-
-       if (ret < 0)
-               return ret;
+       struct tas2770_priv *tas2770 =
+                       snd_soc_component_get_drvdata(component);
 
-       return 0;
+       tas2770->unmuted = !mute;
+       return tas2770_update_pwr_ctrl(tas2770);
 }
 
 static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth)
@@ -337,7 +308,7 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        struct snd_soc_component *component = dai->component;
        struct tas2770_priv *tas2770 =
                        snd_soc_component_get_drvdata(component);
-       u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0;
+       u8 tdm_rx_start_slot = 0, invert_fpol = 0, fpol_preinv = 0, asi_cfg_1 = 0;
        int ret;
 
        switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
@@ -349,9 +320,15 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        }
 
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_NB_IF:
+               invert_fpol = 1;
+               fallthrough;
        case SND_SOC_DAIFMT_NB_NF:
                asi_cfg_1 |= TAS2770_TDM_CFG_REG1_RX_RSING;
                break;
+       case SND_SOC_DAIFMT_IB_IF:
+               invert_fpol = 1;
+               fallthrough;
        case SND_SOC_DAIFMT_IB_NF:
                asi_cfg_1 |= TAS2770_TDM_CFG_REG1_RX_FALING;
                break;
@@ -369,15 +346,19 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
                tdm_rx_start_slot = 1;
+               fpol_preinv = 0;
                break;
        case SND_SOC_DAIFMT_DSP_A:
                tdm_rx_start_slot = 0;
+               fpol_preinv = 1;
                break;
        case SND_SOC_DAIFMT_DSP_B:
                tdm_rx_start_slot = 1;
+               fpol_preinv = 1;
                break;
        case SND_SOC_DAIFMT_LEFT_J:
                tdm_rx_start_slot = 0;
+               fpol_preinv = 1;
                break;
        default:
                dev_err(tas2770->dev,
@@ -391,6 +372,14 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        if (ret < 0)
                return ret;
 
+       ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG0,
+                                           TAS2770_TDM_CFG_REG0_FPOL_MASK,
+                                           (fpol_preinv ^ invert_fpol)
+                                            ? TAS2770_TDM_CFG_REG0_FPOL_RSING
+                                            : TAS2770_TDM_CFG_REG0_FPOL_FALING);
+       if (ret < 0)
+               return ret;
+
        return 0;
 }
 
@@ -489,7 +478,7 @@ static struct snd_soc_dai_driver tas2770_dai_driver[] = {
                .id = 0,
                .playback = {
                        .stream_name    = "ASI1 Playback",
-                       .channels_min   = 2,
+                       .channels_min   = 1,
                        .channels_max   = 2,
                        .rates      = TAS2770_RATES,
                        .formats    = TAS2770_FORMATS,
@@ -537,7 +526,6 @@ static const struct snd_soc_component_driver soc_component_driver_tas2770 = {
        .probe                  = tas2770_codec_probe,
        .suspend                = tas2770_codec_suspend,
        .resume                 = tas2770_codec_resume,
-       .set_bias_level = tas2770_set_bias_level,
        .controls               = tas2770_snd_controls,
        .num_controls           = ARRAY_SIZE(tas2770_snd_controls),
        .dapm_widgets           = tas2770_dapm_widgets,
index d156666..f75f407 100644 (file)
@@ -41,6 +41,9 @@
 #define TAS2770_TDM_CFG_REG0_31_44_1_48KHZ  0x6
 #define TAS2770_TDM_CFG_REG0_31_88_2_96KHZ  0x8
 #define TAS2770_TDM_CFG_REG0_31_176_4_192KHZ  0xa
+#define TAS2770_TDM_CFG_REG0_FPOL_MASK  BIT(0)
+#define TAS2770_TDM_CFG_REG0_FPOL_RSING  0
+#define TAS2770_TDM_CFG_REG0_FPOL_FALING  1
     /* TDM Configuration Reg1 */
 #define TAS2770_TDM_CFG_REG1  TAS2770_REG(0X0, 0x0B)
 #define TAS2770_TDM_CFG_REG1_MASK      GENMASK(5, 1)
@@ -135,6 +138,8 @@ struct tas2770_priv {
        struct device *dev;
        int v_sense_slot;
        int i_sense_slot;
+       bool dac_powered;
+       bool unmuted;
 };
 
 #endif /* __TAS2770__ */
index 4b74805..ffe1828 100644 (file)
@@ -49,6 +49,8 @@ struct aic32x4_priv {
        struct aic32x4_setup_data *setup;
        struct device *dev;
        enum aic32x4_type type;
+
+       unsigned int fmt;
 };
 
 static int aic32x4_reset_adc(struct snd_soc_dapm_widget *w,
@@ -611,6 +613,7 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
        struct snd_soc_component *component = codec_dai->component;
+       struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
        u8 iface_reg_1 = 0;
        u8 iface_reg_2 = 0;
        u8 iface_reg_3 = 0;
@@ -653,6 +656,8 @@ static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                return -EINVAL;
        }
 
+       aic32x4->fmt = fmt;
+
        snd_soc_component_update_bits(component, AIC32X4_IFACE1,
                                AIC32X4_IFACE1_DATATYPE_MASK |
                                AIC32X4_IFACE1_MASTER_MASK, iface_reg_1);
@@ -757,6 +762,10 @@ static int aic32x4_setup_clocks(struct snd_soc_component *component,
                return -EINVAL;
        }
 
+       /* PCM over I2S is always 2-channel */
+       if ((aic32x4->fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S)
+               channels = 2;
+
        madc = DIV_ROUND_UP((32 * adc_resource_class), aosr);
        max_dosr = (AIC32X4_MAX_DOSR_FREQ / sample_rate / dosr_increment) *
                        dosr_increment;
index f21b0cd..8fe5917 100644 (file)
@@ -636,8 +636,8 @@ static ssize_t topology_name_read(struct file *file, char __user *user_buf, size
        char buf[64];
        size_t len;
 
-       len = snprintf(buf, sizeof(buf), "%s/%s\n", component->driver->topology_name_prefix,
-                      mach->tplg_filename);
+       len = scnprintf(buf, sizeof(buf), "%s/%s\n", component->driver->topology_name_prefix,
+                       mach->tplg_filename);
 
        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
index c7f33c8..606cc32 100644 (file)
@@ -760,6 +760,9 @@ static int sof_es8336_remove(struct platform_device *pdev)
 
 static const struct platform_device_id board_ids[] = {
        {
+               .name = "sof-essx8336", /* default quirk == 0 */
+       },
+       {
                .name = "adl_es83x6_c1_h02",
                .driver_data = (kernel_ulong_t)(SOF_ES8336_SSP_CODEC(1) |
                                        SOF_NO_OF_HDMI_CAPTURE_SSP(2) |
@@ -786,5 +789,4 @@ module_platform_driver(sof_es8336_driver);
 
 MODULE_DESCRIPTION("ASoC Intel(R) SOF + ES8336 Machine driver");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:sof-essx8336");
 MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
index 0d0594a..7ace0c0 100644 (file)
@@ -1017,32 +1017,36 @@ static int rz_ssi_probe(struct platform_device *pdev)
 
        ssi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
        if (IS_ERR(ssi->rstc)) {
-               rz_ssi_release_dma_channels(ssi);
-               return PTR_ERR(ssi->rstc);
+               ret = PTR_ERR(ssi->rstc);
+               goto err_reset;
        }
 
        reset_control_deassert(ssi->rstc);
        pm_runtime_enable(&pdev->dev);
        ret = pm_runtime_resume_and_get(&pdev->dev);
        if (ret < 0) {
-               rz_ssi_release_dma_channels(ssi);
-               pm_runtime_disable(ssi->dev);
-               reset_control_assert(ssi->rstc);
-               return dev_err_probe(ssi->dev, ret, "pm_runtime_resume_and_get failed\n");
+               dev_err(&pdev->dev, "pm_runtime_resume_and_get failed\n");
+               goto err_pm;
        }
 
        ret = devm_snd_soc_register_component(&pdev->dev, &rz_ssi_soc_component,
                                              rz_ssi_soc_dai,
                                              ARRAY_SIZE(rz_ssi_soc_dai));
        if (ret < 0) {
-               rz_ssi_release_dma_channels(ssi);
-
-               pm_runtime_put(ssi->dev);
-               pm_runtime_disable(ssi->dev);
-               reset_control_assert(ssi->rstc);
                dev_err(&pdev->dev, "failed to register snd component\n");
+               goto err_snd_soc;
        }
 
+       return 0;
+
+err_snd_soc:
+       pm_runtime_put(ssi->dev);
+err_pm:
+       pm_runtime_disable(ssi->dev);
+       reset_control_assert(ssi->rstc);
+err_reset:
+       rz_ssi_release_dma_channels(ssi);
+
        return ret;
 }
 
index 5b99bf2..4f60c0a 100644 (file)
@@ -1317,6 +1317,9 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
                if (!be->dai_link->no_pcm)
                        continue;
 
+               if (!snd_soc_dpcm_get_substream(be, stream))
+                       continue;
+
                for_each_rtd_dais(be, i, dai) {
                        w = snd_soc_dai_get_widget(dai, stream);
 
index c5d797e..d9a3ce7 100644 (file)
@@ -252,9 +252,9 @@ static int memory_info_update(struct snd_sof_dev *sdev, char *buf, size_t buff_s
        }
 
        for (i = 0, len = 0; i < reply->num_elems; i++) {
-               ret = snprintf(buf + len, buff_size - len, "zone %d.%d used %#8x free %#8x\n",
-                              reply->elems[i].zone, reply->elems[i].id,
-                              reply->elems[i].used, reply->elems[i].free);
+               ret = scnprintf(buf + len, buff_size - len, "zone %d.%d used %#8x free %#8x\n",
+                               reply->elems[i].zone, reply->elems[i].id,
+                               reply->elems[i].used, reply->elems[i].free);
                if (ret < 0)
                        goto error;
                len += ret;
index 8639ea6..6d4ecbe 100644 (file)
@@ -574,7 +574,7 @@ static void hda_dsp_dump_ext_rom_status(struct snd_sof_dev *sdev, const char *le
        chip = get_chip_info(sdev->pdata);
        for (i = 0; i < HDA_EXT_ROM_STATUS_SIZE; i++) {
                value = snd_sof_dsp_read(sdev, HDA_DSP_BAR, chip->rom_status_reg + i * 0x4);
-               len += snprintf(msg + len, sizeof(msg) - len, " 0x%x", value);
+               len += scnprintf(msg + len, sizeof(msg) - len, " 0x%x", value);
        }
 
        dev_printk(level, sdev->dev, "extended rom status: %s", msg);
index b2cc046..65923e7 100644 (file)
@@ -2338,7 +2338,7 @@ static int sof_ipc3_parse_manifest(struct snd_soc_component *scomp, int index,
        }
 
        dev_info(scomp->dev,
-                "Topology: ABI %d:%d:%d Kernel ABI %hhu:%hhu:%hhu\n",
+                "Topology: ABI %d:%d:%d Kernel ABI %d:%d:%d\n",
                 man->priv.data[0], man->priv.data[1], man->priv.data[2],
                 SOF_ABI_MAJOR, SOF_ABI_MINOR, SOF_ABI_PATCH);
 
index 7a6b148..a73cf01 100644 (file)
@@ -74,6 +74,7 @@ struct kvm_s390_io_adapter_req {
 #define KVM_S390_VM_CRYPTO             2
 #define KVM_S390_VM_CPU_MODEL          3
 #define KVM_S390_VM_MIGRATION          4
+#define KVM_S390_VM_CPU_TOPOLOGY       5
 
 /* kvm attributes for mem_ctrl */
 #define KVM_S390_VM_MEM_ENABLE_CMMA    0
index 8323ac5..235dc85 100644 (file)
 #define X86_FEATURE_IBRS               ( 7*32+25) /* Indirect Branch Restricted Speculation */
 #define X86_FEATURE_IBPB               ( 7*32+26) /* Indirect Branch Prediction Barrier */
 #define X86_FEATURE_STIBP              ( 7*32+27) /* Single Thread Indirect Branch Predictors */
-#define X86_FEATURE_ZEN                        ( 7*32+28) /* "" CPU is AMD family 0x17 or above (Zen) */
+#define X86_FEATURE_ZEN                        (7*32+28) /* "" CPU based on Zen microarchitecture */
 #define X86_FEATURE_L1TF_PTEINV                ( 7*32+29) /* "" L1TF workaround PTE inversion */
 #define X86_FEATURE_IBRS_ENHANCED      ( 7*32+30) /* Enhanced IBRS */
 #define X86_FEATURE_MSR_IA32_FEAT_CTL  ( 7*32+31) /* "" MSR IA32_FEAT_CTL configured */
 #define X86_FEATURE_RETHUNK            (11*32+14) /* "" Use REturn THUNK */
 #define X86_FEATURE_UNRET              (11*32+15) /* "" AMD BTB untrain return */
 #define X86_FEATURE_USE_IBPB_FW                (11*32+16) /* "" Use IBPB during runtime firmware calls */
-#define X86_FEATURE_RSB_VMEXIT_LITE    (11*32+17) /* "" Fill RSB on VM-Exit when EIBRS is enabled */
+#define X86_FEATURE_RSB_VMEXIT_LITE    (11*32+17) /* "" Fill RSB on VM exit when EIBRS is enabled */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
 #define X86_FEATURE_AVX_VNNI           (12*32+ 4) /* AVX VNNI instructions */
 #define X86_FEATURE_AVIC               (15*32+13) /* Virtual Interrupt Controller */
 #define X86_FEATURE_V_VMSAVE_VMLOAD    (15*32+15) /* Virtual VMSAVE VMLOAD */
 #define X86_FEATURE_VGIF               (15*32+16) /* Virtual GIF */
+#define X86_FEATURE_X2AVIC             (15*32+18) /* Virtual x2apic */
 #define X86_FEATURE_V_SPEC_CTRL                (15*32+20) /* Virtual SPEC_CTRL */
 #define X86_FEATURE_SVME_ADDR_CHK      (15*32+28) /* "" SVME addr check */
 
 #define X86_BUG_SRBDS                  X86_BUG(24) /* CPU may leak RNG bits if not mitigated */
 #define X86_BUG_MMIO_STALE_DATA                X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */
 #define X86_BUG_RETBLEED               X86_BUG(26) /* CPU is affected by RETBleed */
+#define X86_BUG_EIBRS_PBRSB            X86_BUG(27) /* EIBRS is vulnerable to Post Barrier RSB Predictions */
 
 #endif /* _ASM_X86_CPUFEATURES_H */
index e057e03..6674bdb 100644 (file)
 #define PERF_CAP_PT_IDX                        16
 
 #define MSR_PEBS_LD_LAT_THRESHOLD      0x000003f6
+#define PERF_CAP_PEBS_TRAP             BIT_ULL(6)
+#define PERF_CAP_ARCH_REG              BIT_ULL(7)
+#define PERF_CAP_PEBS_FORMAT           0xf00
+#define PERF_CAP_PEBS_BASELINE         BIT_ULL(14)
+#define PERF_CAP_PEBS_MASK     (PERF_CAP_PEBS_TRAP | PERF_CAP_ARCH_REG | \
+                                PERF_CAP_PEBS_FORMAT | PERF_CAP_PEBS_BASELINE)
 
 #define MSR_IA32_RTIT_CTL              0x00000570
 #define RTIT_CTL_TRACEEN               BIT(0)
 #define MSR_TURBO_ACTIVATION_RATIO     0x0000064C
 
 #define MSR_PLATFORM_ENERGY_STATUS     0x0000064D
+#define MSR_SECONDARY_TURBO_RATIO_LIMIT        0x00000650
 
 #define MSR_PKG_WEIGHTED_CORE_C0_RES   0x00000658
 #define MSR_PKG_ANY_CORE_C0_RES                0x00000659
 #define MSR_IA32_VMX_TRUE_EXIT_CTLS      0x0000048f
 #define MSR_IA32_VMX_TRUE_ENTRY_CTLS     0x00000490
 #define MSR_IA32_VMX_VMFUNC             0x00000491
+#define MSR_IA32_VMX_PROCBASED_CTLS3   0x00000492
 
 /* VMX_BASIC bits and bitmasks */
 #define VMX_BASIC_VMCS_SIZE_SHIFT      32
index fee7983..11ff975 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef _TOOLS_LINUX_ASM_X86_RMWcc
 #define _TOOLS_LINUX_ASM_X86_RMWcc
 
-#ifdef CONFIG_CC_HAS_ASM_GOTO
-
 #define __GEN_RMWcc(fullop, var, cc, ...)                              \
 do {                                                                   \
        asm_volatile_goto (fullop "; j" cc " %l[cc_label]"              \
@@ -20,23 +18,4 @@ cc_label:                                                            \
 #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc)                 \
        __GEN_RMWcc(op " %1, " arg0, var, cc, vcon (val))
 
-#else /* !CONFIG_CC_HAS_ASM_GOTO */
-
-#define __GEN_RMWcc(fullop, var, cc, ...)                              \
-do {                                                                   \
-       char c;                                                         \
-       asm volatile (fullop "; set" cc " %1"                           \
-                       : "+m" (var), "=qm" (c)                         \
-                       : __VA_ARGS__ : "memory");                      \
-       return c != 0;                                                  \
-} while (0)
-
-#define GEN_UNARY_RMWcc(op, var, arg0, cc)                             \
-       __GEN_RMWcc(op " " arg0, var, cc)
-
-#define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc)                 \
-       __GEN_RMWcc(op " %2, " arg0, var, cc, vcon (val))
-
-#endif /* CONFIG_CC_HAS_ASM_GOTO */
-
 #endif /* _TOOLS_LINUX_ASM_X86_RMWcc */
index ec53c9f..46de10a 100644 (file)
@@ -306,7 +306,8 @@ struct kvm_pit_state {
        struct kvm_pit_channel_state channels[3];
 };
 
-#define KVM_PIT_FLAGS_HPET_LEGACY  0x00000001
+#define KVM_PIT_FLAGS_HPET_LEGACY     0x00000001
+#define KVM_PIT_FLAGS_SPEAKER_DATA_ON 0x00000002
 
 struct kvm_pit_state2 {
        struct kvm_pit_channel_state channels[3];
@@ -325,6 +326,7 @@ struct kvm_reinject_control {
 #define KVM_VCPUEVENT_VALID_SHADOW     0x00000004
 #define KVM_VCPUEVENT_VALID_SMM                0x00000008
 #define KVM_VCPUEVENT_VALID_PAYLOAD    0x00000010
+#define KVM_VCPUEVENT_VALID_TRIPLE_FAULT       0x00000020
 
 /* Interrupt shadow states */
 #define KVM_X86_SHADOW_INT_MOV_SS      0x01
@@ -359,7 +361,10 @@ struct kvm_vcpu_events {
                __u8 smm_inside_nmi;
                __u8 latched_init;
        } smi;
-       __u8 reserved[27];
+       struct {
+               __u8 pending;
+       } triple_fault;
+       __u8 reserved[26];
        __u8 exception_has_payload;
        __u64 exception_payload;
 };
@@ -434,6 +439,7 @@ struct kvm_sync_regs {
 #define KVM_X86_QUIRK_OUT_7E_INC_RIP           (1 << 3)
 #define KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT     (1 << 4)
 #define KVM_X86_QUIRK_FIX_HYPERCALL_INSN       (1 << 5)
+#define KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS    (1 << 6)
 
 #define KVM_STATE_NESTED_FORMAT_VMX    0
 #define KVM_STATE_NESTED_FORMAT_SVM    1
index 946d761..a5faf6d 100644 (file)
@@ -91,6 +91,7 @@
 #define EXIT_REASON_UMWAIT              67
 #define EXIT_REASON_TPAUSE              68
 #define EXIT_REASON_BUS_LOCK            74
+#define EXIT_REASON_NOTIFY              75
 
 #define VMX_EXIT_REASONS \
        { EXIT_REASON_EXCEPTION_NMI,         "EXCEPTION_NMI" }, \
        { EXIT_REASON_XRSTORS,               "XRSTORS" }, \
        { EXIT_REASON_UMWAIT,                "UMWAIT" }, \
        { EXIT_REASON_TPAUSE,                "TPAUSE" }, \
-       { EXIT_REASON_BUS_LOCK,              "BUS_LOCK" }
+       { EXIT_REASON_BUS_LOCK,              "BUS_LOCK" }, \
+       { EXIT_REASON_NOTIFY,                "NOTIFY" }
 
 #define VMX_EXIT_REASON_FLAGS \
        { VMX_EXIT_REASONS_FAILED_VMENTRY,      "FAILED_VMENTRY" }
index b28ff5d..520ad26 100644 (file)
@@ -751,14 +751,27 @@ typedef struct drm_i915_irq_wait {
 
 /* Must be kept compact -- no holes and well documented */
 
-typedef struct drm_i915_getparam {
+/**
+ * struct drm_i915_getparam - Driver parameter query structure.
+ */
+struct drm_i915_getparam {
+       /** @param: Driver parameter to query. */
        __s32 param;
-       /*
+
+       /**
+        * @value: Address of memory where queried value should be put.
+        *
         * WARNING: Using pointers instead of fixed-size u64 means we need to write
         * compat32 code. Don't repeat this mistake.
         */
        int __user *value;
-} drm_i915_getparam_t;
+};
+
+/**
+ * typedef drm_i915_getparam_t - Driver parameter query structure.
+ * See struct drm_i915_getparam.
+ */
+typedef struct drm_i915_getparam drm_i915_getparam_t;
 
 /* Ioctl to set kernel params:
  */
@@ -1239,76 +1252,119 @@ struct drm_i915_gem_exec_object2 {
        __u64 rsvd2;
 };
 
+/**
+ * struct drm_i915_gem_exec_fence - An input or output fence for the execbuf
+ * ioctl.
+ *
+ * The request will wait for input fence to signal before submission.
+ *
+ * The returned output fence will be signaled after the completion of the
+ * request.
+ */
 struct drm_i915_gem_exec_fence {
-       /**
-        * User's handle for a drm_syncobj to wait on or signal.
-        */
+       /** @handle: User's handle for a drm_syncobj to wait on or signal. */
        __u32 handle;
 
+       /**
+        * @flags: Supported flags are:
+        *
+        * I915_EXEC_FENCE_WAIT:
+        * Wait for the input fence before request submission.
+        *
+        * I915_EXEC_FENCE_SIGNAL:
+        * Return request completion fence as output
+        */
+       __u32 flags;
 #define I915_EXEC_FENCE_WAIT            (1<<0)
 #define I915_EXEC_FENCE_SIGNAL          (1<<1)
 #define __I915_EXEC_FENCE_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SIGNAL << 1))
-       __u32 flags;
 };
 
-/*
- * See drm_i915_gem_execbuffer_ext_timeline_fences.
- */
-#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES 0
-
-/*
+/**
+ * struct drm_i915_gem_execbuffer_ext_timeline_fences - Timeline fences
+ * for execbuf ioctl.
+ *
  * This structure describes an array of drm_syncobj and associated points for
  * timeline variants of drm_syncobj. It is invalid to append this structure to
  * the execbuf if I915_EXEC_FENCE_ARRAY is set.
  */
 struct drm_i915_gem_execbuffer_ext_timeline_fences {
+#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES 0
+       /** @base: Extension link. See struct i915_user_extension. */
        struct i915_user_extension base;
 
        /**
-        * Number of element in the handles_ptr & value_ptr arrays.
+        * @fence_count: Number of elements in the @handles_ptr & @value_ptr
+        * arrays.
         */
        __u64 fence_count;
 
        /**
-        * Pointer to an array of struct drm_i915_gem_exec_fence of length
-        * fence_count.
+        * @handles_ptr: Pointer to an array of struct drm_i915_gem_exec_fence
+        * of length @fence_count.
         */
        __u64 handles_ptr;
 
        /**
-        * Pointer to an array of u64 values of length fence_count. Values
-        * must be 0 for a binary drm_syncobj. A Value of 0 for a timeline
-        * drm_syncobj is invalid as it turns a drm_syncobj into a binary one.
+        * @values_ptr: Pointer to an array of u64 values of length
+        * @fence_count.
+        * Values must be 0 for a binary drm_syncobj. A Value of 0 for a
+        * timeline drm_syncobj is invalid as it turns a drm_syncobj into a
+        * binary one.
         */
        __u64 values_ptr;
 };
 
+/**
+ * struct drm_i915_gem_execbuffer2 - Structure for DRM_I915_GEM_EXECBUFFER2
+ * ioctl.
+ */
 struct drm_i915_gem_execbuffer2 {
-       /**
-        * List of gem_exec_object2 structs
-        */
+       /** @buffers_ptr: Pointer to a list of gem_exec_object2 structs */
        __u64 buffers_ptr;
+
+       /** @buffer_count: Number of elements in @buffers_ptr array */
        __u32 buffer_count;
 
-       /** Offset in the batchbuffer to start execution from. */
+       /**
+        * @batch_start_offset: Offset in the batchbuffer to start execution
+        * from.
+        */
        __u32 batch_start_offset;
-       /** Bytes used in batchbuffer from batch_start_offset */
+
+       /**
+        * @batch_len: Length in bytes of the batch buffer, starting from the
+        * @batch_start_offset. If 0, length is assumed to be the batch buffer
+        * object size.
+        */
        __u32 batch_len;
+
+       /** @DR1: deprecated */
        __u32 DR1;
+
+       /** @DR4: deprecated */
        __u32 DR4;
+
+       /** @num_cliprects: See @cliprects_ptr */
        __u32 num_cliprects;
+
        /**
-        * This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY
-        * & I915_EXEC_USE_EXTENSIONS are not set.
+        * @cliprects_ptr: Kernel clipping was a DRI1 misfeature.
+        *
+        * It is invalid to use this field if I915_EXEC_FENCE_ARRAY or
+        * I915_EXEC_USE_EXTENSIONS flags are not set.
         *
         * If I915_EXEC_FENCE_ARRAY is set, then this is a pointer to an array
-        * of struct drm_i915_gem_exec_fence and num_cliprects is the length
-        * of the array.
+        * of &drm_i915_gem_exec_fence and @num_cliprects is the length of the
+        * array.
         *
         * If I915_EXEC_USE_EXTENSIONS is set, then this is a pointer to a
-        * single struct i915_user_extension and num_cliprects is 0.
+        * single &i915_user_extension and num_cliprects is 0.
         */
        __u64 cliprects_ptr;
+
+       /** @flags: Execbuf flags */
+       __u64 flags;
 #define I915_EXEC_RING_MASK              (0x3f)
 #define I915_EXEC_DEFAULT                (0<<0)
 #define I915_EXEC_RENDER                 (1<<0)
@@ -1326,10 +1382,6 @@ struct drm_i915_gem_execbuffer2 {
 #define I915_EXEC_CONSTANTS_REL_GENERAL (0<<6) /* default */
 #define I915_EXEC_CONSTANTS_ABSOLUTE   (1<<6)
 #define I915_EXEC_CONSTANTS_REL_SURFACE (2<<6) /* gen4/5 only */
-       __u64 flags;
-       __u64 rsvd1; /* now used for context info */
-       __u64 rsvd2;
-};
 
 /** Resets the SO write offset registers for transform feedback on gen7. */
 #define I915_EXEC_GEN7_SOL_RESET       (1<<8)
@@ -1432,9 +1484,23 @@ struct drm_i915_gem_execbuffer2 {
  * drm_i915_gem_execbuffer_ext enum.
  */
 #define I915_EXEC_USE_EXTENSIONS       (1 << 21)
-
 #define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_USE_EXTENSIONS << 1))
 
+       /** @rsvd1: Context id */
+       __u64 rsvd1;
+
+       /**
+        * @rsvd2: in and out sync_file file descriptors.
+        *
+        * When I915_EXEC_FENCE_IN or I915_EXEC_FENCE_SUBMIT flag is set, the
+        * lower 32 bits of this field will have the in sync_file fd (input).
+        *
+        * When I915_EXEC_FENCE_OUT flag is set, the upper 32 bits of this
+        * field will have the out sync_file fd (output).
+        */
+       __u64 rsvd2;
+};
+
 #define I915_EXEC_CONTEXT_ID_MASK      (0xffffffff)
 #define i915_execbuffer2_set_context_id(eb2, context) \
        (eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK
@@ -1814,19 +1880,58 @@ struct drm_i915_gem_context_create {
        __u32 pad;
 };
 
+/**
+ * struct drm_i915_gem_context_create_ext - Structure for creating contexts.
+ */
 struct drm_i915_gem_context_create_ext {
-       __u32 ctx_id; /* output: id of new context*/
+       /** @ctx_id: Id of the created context (output) */
+       __u32 ctx_id;
+
+       /**
+        * @flags: Supported flags are:
+        *
+        * I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS:
+        *
+        * Extensions may be appended to this structure and driver must check
+        * for those. See @extensions.
+        *
+        * I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE
+        *
+        * Created context will have single timeline.
+        */
        __u32 flags;
 #define I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS       (1u << 0)
 #define I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE      (1u << 1)
 #define I915_CONTEXT_CREATE_FLAGS_UNKNOWN \
        (-(I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE << 1))
+
+       /**
+        * @extensions: Zero-terminated chain of extensions.
+        *
+        * I915_CONTEXT_CREATE_EXT_SETPARAM:
+        * Context parameter to set or query during context creation.
+        * See struct drm_i915_gem_context_create_ext_setparam.
+        *
+        * I915_CONTEXT_CREATE_EXT_CLONE:
+        * This extension has been removed. On the off chance someone somewhere
+        * has attempted to use it, never re-use this extension number.
+        */
        __u64 extensions;
+#define I915_CONTEXT_CREATE_EXT_SETPARAM 0
+#define I915_CONTEXT_CREATE_EXT_CLONE 1
 };
 
+/**
+ * struct drm_i915_gem_context_param - Context parameter to set or query.
+ */
 struct drm_i915_gem_context_param {
+       /** @ctx_id: Context id */
        __u32 ctx_id;
+
+       /** @size: Size of the parameter @value */
        __u32 size;
+
+       /** @param: Parameter to set or query */
        __u64 param;
 #define I915_CONTEXT_PARAM_BAN_PERIOD  0x1
 /* I915_CONTEXT_PARAM_NO_ZEROMAP has been removed.  On the off chance
@@ -1973,6 +2078,7 @@ struct drm_i915_gem_context_param {
 #define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
 /* Must be kept compact -- no holes and well documented */
 
+       /** @value: Context parameter value to be set or queried */
        __u64 value;
 };
 
@@ -2371,23 +2477,29 @@ struct i915_context_param_engines {
        struct i915_engine_class_instance engines[N__]; \
 } __attribute__((packed)) name__
 
+/**
+ * struct drm_i915_gem_context_create_ext_setparam - Context parameter
+ * to set or query during context creation.
+ */
 struct drm_i915_gem_context_create_ext_setparam {
-#define I915_CONTEXT_CREATE_EXT_SETPARAM 0
+       /** @base: Extension link. See struct i915_user_extension. */
        struct i915_user_extension base;
+
+       /**
+        * @param: Context parameter to set or query.
+        * See struct drm_i915_gem_context_param.
+        */
        struct drm_i915_gem_context_param param;
 };
 
-/* This API has been removed.  On the off chance someone somewhere has
- * attempted to use it, never re-use this extension number.
- */
-#define I915_CONTEXT_CREATE_EXT_CLONE 1
-
 struct drm_i915_gem_context_destroy {
        __u32 ctx_id;
        __u32 pad;
 };
 
-/*
+/**
+ * struct drm_i915_gem_vm_control - Structure to create or destroy VM.
+ *
  * DRM_I915_GEM_VM_CREATE -
  *
  * Create a new virtual memory address space (ppGTT) for use within a context
@@ -2397,20 +2509,23 @@ struct drm_i915_gem_context_destroy {
  * The id of new VM (bound to the fd) for use with I915_CONTEXT_PARAM_VM is
  * returned in the outparam @id.
  *
- * No flags are defined, with all bits reserved and must be zero.
- *
  * An extension chain maybe provided, starting with @extensions, and terminated
  * by the @next_extension being 0. Currently, no extensions are defined.
  *
  * DRM_I915_GEM_VM_DESTROY -
  *
- * Destroys a previously created VM id, specified in @id.
+ * Destroys a previously created VM id, specified in @vm_id.
  *
  * No extensions or flags are allowed currently, and so must be zero.
  */
 struct drm_i915_gem_vm_control {
+       /** @extensions: Zero-terminated chain of extensions. */
        __u64 extensions;
+
+       /** @flags: reserved for future usage, currently MBZ */
        __u32 flags;
+
+       /** @vm_id: Id of the VM created or to be destroyed */
        __u32 vm_id;
 };
 
@@ -3207,36 +3322,6 @@ struct drm_i915_gem_memory_class_instance {
  * struct drm_i915_memory_region_info - Describes one region as known to the
  * driver.
  *
- * Note that we reserve some stuff here for potential future work. As an example
- * we might want expose the capabilities for a given region, which could include
- * things like if the region is CPU mappable/accessible, what are the supported
- * mapping types etc.
- *
- * Note that to extend struct drm_i915_memory_region_info and struct
- * drm_i915_query_memory_regions in the future the plan is to do the following:
- *
- * .. code-block:: C
- *
- *     struct drm_i915_memory_region_info {
- *             struct drm_i915_gem_memory_class_instance region;
- *             union {
- *                     __u32 rsvd0;
- *                     __u32 new_thing1;
- *             };
- *             ...
- *             union {
- *                     __u64 rsvd1[8];
- *                     struct {
- *                             __u64 new_thing2;
- *                             __u64 new_thing3;
- *                             ...
- *                     };
- *             };
- *     };
- *
- * With this things should remain source compatible between versions for
- * userspace, even as we add new fields.
- *
  * Note this is using both struct drm_i915_query_item and struct drm_i915_query.
  * For this new query we are adding the new query id DRM_I915_QUERY_MEMORY_REGIONS
  * at &drm_i915_query_item.query_id.
@@ -3248,14 +3333,81 @@ struct drm_i915_memory_region_info {
        /** @rsvd0: MBZ */
        __u32 rsvd0;
 
-       /** @probed_size: Memory probed by the driver (-1 = unknown) */
+       /**
+        * @probed_size: Memory probed by the driver
+        *
+        * Note that it should not be possible to ever encounter a zero value
+        * here, also note that no current region type will ever return -1 here.
+        * Although for future region types, this might be a possibility. The
+        * same applies to the other size fields.
+        */
        __u64 probed_size;
 
-       /** @unallocated_size: Estimate of memory remaining (-1 = unknown) */
+       /**
+        * @unallocated_size: Estimate of memory remaining
+        *
+        * Requires CAP_PERFMON or CAP_SYS_ADMIN to get reliable accounting.
+        * Without this (or if this is an older kernel) the value here will
+        * always equal the @probed_size. Note this is only currently tracked
+        * for I915_MEMORY_CLASS_DEVICE regions (for other types the value here
+        * will always equal the @probed_size).
+        */
        __u64 unallocated_size;
 
-       /** @rsvd1: MBZ */
-       __u64 rsvd1[8];
+       union {
+               /** @rsvd1: MBZ */
+               __u64 rsvd1[8];
+               struct {
+                       /**
+                        * @probed_cpu_visible_size: Memory probed by the driver
+                        * that is CPU accessible.
+                        *
+                        * This will be always be <= @probed_size, and the
+                        * remainder (if there is any) will not be CPU
+                        * accessible.
+                        *
+                        * On systems without small BAR, the @probed_size will
+                        * always equal the @probed_cpu_visible_size, since all
+                        * of it will be CPU accessible.
+                        *
+                        * Note this is only tracked for
+                        * I915_MEMORY_CLASS_DEVICE regions (for other types the
+                        * value here will always equal the @probed_size).
+                        *
+                        * Note that if the value returned here is zero, then
+                        * this must be an old kernel which lacks the relevant
+                        * small-bar uAPI support (including
+                        * I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS), but on
+                        * such systems we should never actually end up with a
+                        * small BAR configuration, assuming we are able to load
+                        * the kernel module. Hence it should be safe to treat
+                        * this the same as when @probed_cpu_visible_size ==
+                        * @probed_size.
+                        */
+                       __u64 probed_cpu_visible_size;
+
+                       /**
+                        * @unallocated_cpu_visible_size: Estimate of CPU
+                        * visible memory remaining.
+                        *
+                        * Note this is only tracked for
+                        * I915_MEMORY_CLASS_DEVICE regions (for other types the
+                        * value here will always equal the
+                        * @probed_cpu_visible_size).
+                        *
+                        * Requires CAP_PERFMON or CAP_SYS_ADMIN to get reliable
+                        * accounting.  Without this the value here will always
+                        * equal the @probed_cpu_visible_size. Note this is only
+                        * currently tracked for I915_MEMORY_CLASS_DEVICE
+                        * regions (for other types the value here will also
+                        * always equal the @probed_cpu_visible_size).
+                        *
+                        * If this is an older kernel the value here will be
+                        * zero, see also @probed_cpu_visible_size.
+                        */
+                       __u64 unallocated_cpu_visible_size;
+               };
+       };
 };
 
 /**
@@ -3329,11 +3481,11 @@ struct drm_i915_query_memory_regions {
  * struct drm_i915_gem_create_ext - Existing gem_create behaviour, with added
  * extension support using struct i915_user_extension.
  *
- * Note that in the future we want to have our buffer flags here, at least for
- * the stuff that is immutable. Previously we would have two ioctls, one to
- * create the object with gem_create, and another to apply various parameters,
- * however this creates some ambiguity for the params which are considered
- * immutable. Also in general we're phasing out the various SET/GET ioctls.
+ * Note that new buffer flags should be added here, at least for the stuff that
+ * is immutable. Previously we would have two ioctls, one to create the object
+ * with gem_create, and another to apply various parameters, however this
+ * creates some ambiguity for the params which are considered immutable. Also in
+ * general we're phasing out the various SET/GET ioctls.
  */
 struct drm_i915_gem_create_ext {
        /**
@@ -3341,7 +3493,6 @@ struct drm_i915_gem_create_ext {
         *
         * The (page-aligned) allocated size for the object will be returned.
         *
-        *
         * DG2 64K min page size implications:
         *
         * On discrete platforms, starting from DG2, we have to contend with GTT
@@ -3353,7 +3504,9 @@ struct drm_i915_gem_create_ext {
         *
         * Note that the returned size here will always reflect any required
         * rounding up done by the kernel, i.e 4K will now become 64K on devices
-        * such as DG2.
+        * such as DG2. The kernel will always select the largest minimum
+        * page-size for the set of possible placements as the value to use when
+        * rounding up the @size.
         *
         * Special DG2 GTT address alignment requirement:
         *
@@ -3377,14 +3530,58 @@ struct drm_i915_gem_create_ext {
         * is deemed to be a good compromise.
         */
        __u64 size;
+
        /**
         * @handle: Returned handle for the object.
         *
         * Object handles are nonzero.
         */
        __u32 handle;
-       /** @flags: MBZ */
+
+       /**
+        * @flags: Optional flags.
+        *
+        * Supported values:
+        *
+        * I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS - Signal to the kernel that
+        * the object will need to be accessed via the CPU.
+        *
+        * Only valid when placing objects in I915_MEMORY_CLASS_DEVICE, and only
+        * strictly required on configurations where some subset of the device
+        * memory is directly visible/mappable through the CPU (which we also
+        * call small BAR), like on some DG2+ systems. Note that this is quite
+        * undesirable, but due to various factors like the client CPU, BIOS etc
+        * it's something we can expect to see in the wild. See
+        * &drm_i915_memory_region_info.probed_cpu_visible_size for how to
+        * determine if this system applies.
+        *
+        * Note that one of the placements MUST be I915_MEMORY_CLASS_SYSTEM, to
+        * ensure the kernel can always spill the allocation to system memory,
+        * if the object can't be allocated in the mappable part of
+        * I915_MEMORY_CLASS_DEVICE.
+        *
+        * Also note that since the kernel only supports flat-CCS on objects
+        * that can *only* be placed in I915_MEMORY_CLASS_DEVICE, we therefore
+        * don't support I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS together with
+        * flat-CCS.
+        *
+        * Without this hint, the kernel will assume that non-mappable
+        * I915_MEMORY_CLASS_DEVICE is preferred for this object. Note that the
+        * kernel can still migrate the object to the mappable part, as a last
+        * resort, if userspace ever CPU faults this object, but this might be
+        * expensive, and so ideally should be avoided.
+        *
+        * On older kernels which lack the relevant small-bar uAPI support (see
+        * also &drm_i915_memory_region_info.probed_cpu_visible_size),
+        * usage of the flag will result in an error, but it should NEVER be
+        * possible to end up with a small BAR configuration, assuming we can
+        * also successfully load the i915 kernel module. In such cases the
+        * entire I915_MEMORY_CLASS_DEVICE region will be CPU accessible, and as
+        * such there are zero restrictions on where the object can be placed.
+        */
+#define I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS (1 << 0)
        __u32 flags;
+
        /**
         * @extensions: The chain of extensions to apply to this object.
         *
@@ -3443,6 +3640,22 @@ struct drm_i915_gem_create_ext {
  * At which point we get the object handle in &drm_i915_gem_create_ext.handle,
  * along with the final object size in &drm_i915_gem_create_ext.size, which
  * should account for any rounding up, if required.
+ *
+ * Note that userspace has no means of knowing the current backing region
+ * for objects where @num_regions is larger than one. The kernel will only
+ * ensure that the priority order of the @regions array is honoured, either
+ * when initially placing the object, or when moving memory around due to
+ * memory pressure
+ *
+ * On Flat-CCS capable HW, compression is supported for the objects residing
+ * in I915_MEMORY_CLASS_DEVICE. When such objects (compressed) have other
+ * memory class in @regions and migrated (by i915, due to memory
+ * constraints) to the non I915_MEMORY_CLASS_DEVICE region, then i915 needs to
+ * decompress the content. But i915 doesn't have the required information to
+ * decompress the userspace compressed objects.
+ *
+ * So i915 supports Flat-CCS, on the objects which can reside only on
+ * I915_MEMORY_CLASS_DEVICE regions.
  */
 struct drm_i915_gem_create_ext_memory_regions {
        /** @base: Extension link. See struct i915_user_extension. */
index 9f4428b..a756b29 100644 (file)
@@ -27,7 +27,8 @@
 #define FSCRYPT_MODE_AES_128_CBC               5
 #define FSCRYPT_MODE_AES_128_CTS               6
 #define FSCRYPT_MODE_ADIANTUM                  9
-/* If adding a mode number > 9, update FSCRYPT_MODE_MAX in fscrypt_private.h */
+#define FSCRYPT_MODE_AES_256_HCTR2             10
+/* If adding a mode number > 10, update FSCRYPT_MODE_MAX in fscrypt_private.h */
 
 /*
  * Legacy policy version; ad-hoc KDF and no key verification.
index cb6e384..eed0315 100644 (file)
@@ -270,6 +270,8 @@ struct kvm_xen_exit {
 #define KVM_EXIT_X86_BUS_LOCK     33
 #define KVM_EXIT_XEN              34
 #define KVM_EXIT_RISCV_SBI        35
+#define KVM_EXIT_RISCV_CSR        36
+#define KVM_EXIT_NOTIFY           37
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
@@ -496,6 +498,18 @@ struct kvm_run {
                        unsigned long args[6];
                        unsigned long ret[2];
                } riscv_sbi;
+               /* KVM_EXIT_RISCV_CSR */
+               struct {
+                       unsigned long csr_num;
+                       unsigned long new_value;
+                       unsigned long write_mask;
+                       unsigned long ret_value;
+               } riscv_csr;
+               /* KVM_EXIT_NOTIFY */
+               struct {
+#define KVM_NOTIFY_CONTEXT_INVALID     (1 << 0)
+                       __u32 flags;
+               } notify;
                /* Fix the size of the union. */
                char padding[256];
        };
@@ -1157,6 +1171,12 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_VM_TSC_CONTROL 214
 #define KVM_CAP_SYSTEM_EVENT_DATA 215
 #define KVM_CAP_ARM_SYSTEM_SUSPEND 216
+#define KVM_CAP_S390_PROTECTED_DUMP 217
+#define KVM_CAP_X86_TRIPLE_FAULT_EVENT 218
+#define KVM_CAP_X86_NOTIFY_VMEXIT 219
+#define KVM_CAP_VM_DISABLE_NX_HUGE_PAGES 220
+#define KVM_CAP_S390_ZPCI_OP 221
+#define KVM_CAP_S390_CPU_TOPOLOGY 222
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1660,6 +1680,55 @@ struct kvm_s390_pv_unp {
        __u64 tweak;
 };
 
+enum pv_cmd_dmp_id {
+       KVM_PV_DUMP_INIT,
+       KVM_PV_DUMP_CONFIG_STOR_STATE,
+       KVM_PV_DUMP_COMPLETE,
+       KVM_PV_DUMP_CPU,
+};
+
+struct kvm_s390_pv_dmp {
+       __u64 subcmd;
+       __u64 buff_addr;
+       __u64 buff_len;
+       __u64 gaddr;            /* For dump storage state */
+       __u64 reserved[4];
+};
+
+enum pv_cmd_info_id {
+       KVM_PV_INFO_VM,
+       KVM_PV_INFO_DUMP,
+};
+
+struct kvm_s390_pv_info_dump {
+       __u64 dump_cpu_buffer_len;
+       __u64 dump_config_mem_buffer_per_1m;
+       __u64 dump_config_finalize_len;
+};
+
+struct kvm_s390_pv_info_vm {
+       __u64 inst_calls_list[4];
+       __u64 max_cpus;
+       __u64 max_guests;
+       __u64 max_guest_addr;
+       __u64 feature_indication;
+};
+
+struct kvm_s390_pv_info_header {
+       __u32 id;
+       __u32 len_max;
+       __u32 len_written;
+       __u32 reserved;
+};
+
+struct kvm_s390_pv_info {
+       struct kvm_s390_pv_info_header header;
+       union {
+               struct kvm_s390_pv_info_dump dump;
+               struct kvm_s390_pv_info_vm vm;
+       };
+};
+
 enum pv_cmd_id {
        KVM_PV_ENABLE,
        KVM_PV_DISABLE,
@@ -1668,6 +1737,8 @@ enum pv_cmd_id {
        KVM_PV_VERIFY,
        KVM_PV_PREP_RESET,
        KVM_PV_UNSHARE_ALL,
+       KVM_PV_INFO,
+       KVM_PV_DUMP,
 };
 
 struct kvm_pv_cmd {
@@ -2119,4 +2190,41 @@ struct kvm_stats_desc {
 /* Available with KVM_CAP_XSAVE2 */
 #define KVM_GET_XSAVE2           _IOR(KVMIO,  0xcf, struct kvm_xsave)
 
+/* Available with KVM_CAP_S390_PROTECTED_DUMP */
+#define KVM_S390_PV_CPU_COMMAND        _IOWR(KVMIO, 0xd0, struct kvm_pv_cmd)
+
+/* Available with KVM_CAP_X86_NOTIFY_VMEXIT */
+#define KVM_X86_NOTIFY_VMEXIT_ENABLED          (1ULL << 0)
+#define KVM_X86_NOTIFY_VMEXIT_USER             (1ULL << 1)
+
+/* Available with KVM_CAP_S390_ZPCI_OP */
+#define KVM_S390_ZPCI_OP         _IOW(KVMIO,  0xd1, struct kvm_s390_zpci_op)
+
+struct kvm_s390_zpci_op {
+       /* in */
+       __u32 fh;               /* target device */
+       __u8  op;               /* operation to perform */
+       __u8  pad[3];
+       union {
+               /* for KVM_S390_ZPCIOP_REG_AEN */
+               struct {
+                       __u64 ibv;      /* Guest addr of interrupt bit vector */
+                       __u64 sb;       /* Guest addr of summary bit */
+                       __u32 flags;
+                       __u32 noi;      /* Number of interrupts */
+                       __u8 isc;       /* Guest interrupt subclass */
+                       __u8 sbo;       /* Offset of guest summary bit vector */
+                       __u16 pad;
+               } reg_aen;
+               __u64 reserved[8];
+       } u;
+};
+
+/* types for kvm_s390_zpci_op->op */
+#define KVM_S390_ZPCIOP_REG_AEN                0
+#define KVM_S390_ZPCIOP_DEREG_AEN      1
+
+/* flags for kvm_s390_zpci_op->u.reg_aen.flags */
+#define KVM_S390_ZPCIOP_REGAEN_HOST    (1 << 0)
+
 #endif /* __LINUX_KVM_H */
index e2b77fb..581ed4b 100644 (file)
@@ -301,6 +301,7 @@ enum {
  *       { u64         time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
  *       { u64         time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
  *       { u64         id;           } && PERF_FORMAT_ID
+ *       { u64         lost;         } && PERF_FORMAT_LOST
  *     } && !PERF_FORMAT_GROUP
  *
  *     { u64           nr;
@@ -308,6 +309,7 @@ enum {
  *       { u64         time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
  *       { u64         value;
  *         { u64       id;           } && PERF_FORMAT_ID
+ *         { u64       lost;         } && PERF_FORMAT_LOST
  *       }             cntr[nr];
  *     } && PERF_FORMAT_GROUP
  * };
@@ -317,8 +319,9 @@ enum perf_event_read_format {
        PERF_FORMAT_TOTAL_TIME_RUNNING          = 1U << 1,
        PERF_FORMAT_ID                          = 1U << 2,
        PERF_FORMAT_GROUP                       = 1U << 3,
+       PERF_FORMAT_LOST                        = 1U << 4,
 
-       PERF_FORMAT_MAX = 1U << 4,              /* non-ABI */
+       PERF_FORMAT_MAX = 1U << 5,              /* non-ABI */
 };
 
 #define PERF_ATTR_SIZE_VER0    64      /* sizeof first published struct */
index cab645d..f9f115a 100644 (file)
 #define VHOST_VDPA_SET_GROUP_ASID      _IOW(VHOST_VIRTIO, 0x7C, \
                                             struct vhost_vring_state)
 
+/* Suspend a device so it does not process virtqueue requests anymore
+ *
+ * After the return of ioctl the device must preserve all the necessary state
+ * (the virtqueue vring base plus the possible device specific states) that is
+ * required for restoring in the future. The device must not change its
+ * configuration after that point.
+ */
+#define VHOST_VDPA_SUSPEND             _IO(VHOST_VIRTIO, 0x7D)
+
 #endif
index 384d5e0..6cd0be7 100644 (file)
@@ -309,7 +309,7 @@ bool perf_cpu_map__has(const struct perf_cpu_map *cpus, struct perf_cpu cpu)
        return perf_cpu_map__idx(cpus, cpu) != -1;
 }
 
-struct perf_cpu perf_cpu_map__max(struct perf_cpu_map *map)
+struct perf_cpu perf_cpu_map__max(const struct perf_cpu_map *map)
 {
        struct perf_cpu result = {
                .cpu = -1
index 952f352..8ce5bbd 100644 (file)
@@ -305,6 +305,9 @@ int perf_evsel__read_size(struct perf_evsel *evsel)
        if (read_format & PERF_FORMAT_ID)
                entry += sizeof(u64);
 
+       if (read_format & PERF_FORMAT_LOST)
+               entry += sizeof(u64);
+
        if (read_format & PERF_FORMAT_GROUP) {
                nr = evsel->nr_members;
                size += sizeof(u64);
@@ -314,24 +317,98 @@ int perf_evsel__read_size(struct perf_evsel *evsel)
        return size;
 }
 
+/* This only reads values for the leader */
+static int perf_evsel__read_group(struct perf_evsel *evsel, int cpu_map_idx,
+                                 int thread, struct perf_counts_values *count)
+{
+       size_t size = perf_evsel__read_size(evsel);
+       int *fd = FD(evsel, cpu_map_idx, thread);
+       u64 read_format = evsel->attr.read_format;
+       u64 *data;
+       int idx = 1;
+
+       if (fd == NULL || *fd < 0)
+               return -EINVAL;
+
+       data = calloc(1, size);
+       if (data == NULL)
+               return -ENOMEM;
+
+       if (readn(*fd, data, size) <= 0) {
+               free(data);
+               return -errno;
+       }
+
+       /*
+        * This reads only the leader event intentionally since we don't have
+        * perf counts values for sibling events.
+        */
+       if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
+               count->ena = data[idx++];
+       if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+               count->run = data[idx++];
+
+       /* value is always available */
+       count->val = data[idx++];
+       if (read_format & PERF_FORMAT_ID)
+               count->id = data[idx++];
+       if (read_format & PERF_FORMAT_LOST)
+               count->lost = data[idx++];
+
+       free(data);
+       return 0;
+}
+
+/*
+ * The perf read format is very flexible.  It needs to set the proper
+ * values according to the read format.
+ */
+static void perf_evsel__adjust_values(struct perf_evsel *evsel, u64 *buf,
+                                     struct perf_counts_values *count)
+{
+       u64 read_format = evsel->attr.read_format;
+       int n = 0;
+
+       count->val = buf[n++];
+
+       if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
+               count->ena = buf[n++];
+
+       if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+               count->run = buf[n++];
+
+       if (read_format & PERF_FORMAT_ID)
+               count->id = buf[n++];
+
+       if (read_format & PERF_FORMAT_LOST)
+               count->lost = buf[n++];
+}
+
 int perf_evsel__read(struct perf_evsel *evsel, int cpu_map_idx, int thread,
                     struct perf_counts_values *count)
 {
        size_t size = perf_evsel__read_size(evsel);
        int *fd = FD(evsel, cpu_map_idx, thread);
+       u64 read_format = evsel->attr.read_format;
+       struct perf_counts_values buf;
 
        memset(count, 0, sizeof(*count));
 
        if (fd == NULL || *fd < 0)
                return -EINVAL;
 
+       if (read_format & PERF_FORMAT_GROUP)
+               return perf_evsel__read_group(evsel, cpu_map_idx, thread, count);
+
        if (MMAP(evsel, cpu_map_idx, thread) &&
+           !(read_format & (PERF_FORMAT_ID | PERF_FORMAT_LOST)) &&
            !perf_mmap__read_self(MMAP(evsel, cpu_map_idx, thread), count))
                return 0;
 
-       if (readn(*fd, count->values, size) <= 0)
+       if (readn(*fd, buf.values, size) <= 0)
                return -errno;
 
+       perf_evsel__adjust_values(evsel, buf.values, count);
        return 0;
 }
 
index 24de795..03aceb7 100644 (file)
@@ -23,7 +23,7 @@ LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *map);
 LIBPERF_API struct perf_cpu perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx);
 LIBPERF_API int perf_cpu_map__nr(const struct perf_cpu_map *cpus);
 LIBPERF_API bool perf_cpu_map__empty(const struct perf_cpu_map *map);
-LIBPERF_API struct perf_cpu perf_cpu_map__max(struct perf_cpu_map *map);
+LIBPERF_API struct perf_cpu perf_cpu_map__max(const struct perf_cpu_map *map);
 LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
 
 #define perf_cpu_map__for_each_cpu(cpu, idx, cpus)             \
index 556bb06..93bf93a 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/types.h>
 #include <linux/limits.h>
 #include <linux/bpf.h>
+#include <linux/compiler.h>
 #include <sys/types.h> /* pid_t */
 
 #define event_contains(obj, mem) ((obj).header.size > offsetof(typeof(obj), mem))
@@ -76,7 +77,7 @@ struct perf_record_lost_samples {
 };
 
 /*
- * PERF_FORMAT_ENABLED | PERF_FORMAT_RUNNING | PERF_FORMAT_ID
+ * PERF_FORMAT_ENABLED | PERF_FORMAT_RUNNING | PERF_FORMAT_ID | PERF_FORMAT_LOST
  */
 struct perf_record_read {
        struct perf_event_header header;
@@ -85,6 +86,7 @@ struct perf_record_read {
        __u64                    time_enabled;
        __u64                    time_running;
        __u64                    id;
+       __u64                    lost;
 };
 
 struct perf_record_throttle {
@@ -153,22 +155,60 @@ enum {
        PERF_CPU_MAP__MASK = 1,
 };
 
+/*
+ * Array encoding of a perf_cpu_map where nr is the number of entries in cpu[]
+ * and each entry is a value for a CPU in the map.
+ */
 struct cpu_map_entries {
        __u16                    nr;
        __u16                    cpu[];
 };
 
-struct perf_record_record_cpu_map {
+/* Bitmap encoding of a perf_cpu_map where bitmap entries are 32-bit. */
+struct perf_record_mask_cpu_map32 {
+       /* Number of mask values. */
+       __u16                    nr;
+       /* Constant 4. */
+       __u16                    long_size;
+       /* Bitmap data. */
+       __u32                    mask[];
+};
+
+/* Bitmap encoding of a perf_cpu_map where bitmap entries are 64-bit. */
+struct perf_record_mask_cpu_map64 {
+       /* Number of mask values. */
        __u16                    nr;
+       /* Constant 8. */
        __u16                    long_size;
-       unsigned long            mask[];
+       /* Legacy padding. */
+       char                     __pad[4];
+       /* Bitmap data. */
+       __u64                    mask[];
 };
 
-struct perf_record_cpu_map_data {
+/*
+ * 'struct perf_record_cpu_map_data' is packed as unfortunately an earlier
+ * version had unaligned data and we wish to retain file format compatibility.
+ * -irogers
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpacked"
+#pragma GCC diagnostic ignored "-Wattributes"
+
+struct __packed perf_record_cpu_map_data {
        __u16                    type;
-       char                     data[];
+       union {
+               /* Used when type == PERF_CPU_MAP__CPUS. */
+               struct cpu_map_entries cpus_data;
+               /* Used when type == PERF_CPU_MAP__MASK and long_size == 4. */
+               struct perf_record_mask_cpu_map32 mask32_data;
+               /* Used when type == PERF_CPU_MAP__MASK and long_size == 8. */
+               struct perf_record_mask_cpu_map64 mask64_data;
+       };
 };
 
+#pragma GCC diagnostic pop
+
 struct perf_record_cpu_map {
        struct perf_event_header         header;
        struct perf_record_cpu_map_data  data;
index 699c0ed..6f92204 100644 (file)
@@ -18,8 +18,10 @@ struct perf_counts_values {
                        uint64_t val;
                        uint64_t ena;
                        uint64_t run;
+                       uint64_t id;
+                       uint64_t lost;
                };
-               uint64_t values[3];
+               uint64_t values[5];
        };
 };
 
index 89be89a..a11fc51 100644 (file)
@@ -1,10 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <stdarg.h>
 #include <stdio.h>
+#include <string.h>
 #include <linux/perf_event.h>
+#include <linux/kernel.h>
 #include <perf/cpumap.h>
 #include <perf/threadmap.h>
 #include <perf/evsel.h>
+#include <internal/evsel.h>
 #include <internal/tests.h>
 #include "tests.h"
 
@@ -189,6 +192,163 @@ static int test_stat_user_read(int event)
        return 0;
 }
 
+static int test_stat_read_format_single(struct perf_event_attr *attr, struct perf_thread_map *threads)
+{
+       struct perf_evsel *evsel;
+       struct perf_counts_values counts;
+       volatile int count = 0x100000;
+       int err;
+
+       evsel = perf_evsel__new(attr);
+       __T("failed to create evsel", evsel);
+
+       /* skip old kernels that don't support the format */
+       err = perf_evsel__open(evsel, NULL, threads);
+       if (err < 0)
+               return 0;
+
+       while (count--) ;
+
+       memset(&counts, -1, sizeof(counts));
+       perf_evsel__read(evsel, 0, 0, &counts);
+
+       __T("failed to read value", counts.val);
+       if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
+               __T("failed to read TOTAL_TIME_ENABLED", counts.ena);
+       if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+               __T("failed to read TOTAL_TIME_RUNNING", counts.run);
+       if (attr->read_format & PERF_FORMAT_ID)
+               __T("failed to read ID", counts.id);
+       if (attr->read_format & PERF_FORMAT_LOST)
+               __T("failed to read LOST", counts.lost == 0);
+
+       perf_evsel__close(evsel);
+       perf_evsel__delete(evsel);
+       return 0;
+}
+
+static int test_stat_read_format_group(struct perf_event_attr *attr, struct perf_thread_map *threads)
+{
+       struct perf_evsel *leader, *member;
+       struct perf_counts_values counts;
+       volatile int count = 0x100000;
+       int err;
+
+       attr->read_format |= PERF_FORMAT_GROUP;
+       leader = perf_evsel__new(attr);
+       __T("failed to create leader", leader);
+
+       attr->read_format &= ~PERF_FORMAT_GROUP;
+       member = perf_evsel__new(attr);
+       __T("failed to create member", member);
+
+       member->leader = leader;
+       leader->nr_members = 2;
+
+       /* skip old kernels that don't support the format */
+       err = perf_evsel__open(leader, NULL, threads);
+       if (err < 0)
+               return 0;
+       err = perf_evsel__open(member, NULL, threads);
+       if (err < 0)
+               return 0;
+
+       while (count--) ;
+
+       memset(&counts, -1, sizeof(counts));
+       perf_evsel__read(leader, 0, 0, &counts);
+
+       __T("failed to read leader value", counts.val);
+       if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
+               __T("failed to read leader TOTAL_TIME_ENABLED", counts.ena);
+       if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+               __T("failed to read leader TOTAL_TIME_RUNNING", counts.run);
+       if (attr->read_format & PERF_FORMAT_ID)
+               __T("failed to read leader ID", counts.id);
+       if (attr->read_format & PERF_FORMAT_LOST)
+               __T("failed to read leader LOST", counts.lost == 0);
+
+       memset(&counts, -1, sizeof(counts));
+       perf_evsel__read(member, 0, 0, &counts);
+
+       __T("failed to read member value", counts.val);
+       if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
+               __T("failed to read member TOTAL_TIME_ENABLED", counts.ena);
+       if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+               __T("failed to read member TOTAL_TIME_RUNNING", counts.run);
+       if (attr->read_format & PERF_FORMAT_ID)
+               __T("failed to read member ID", counts.id);
+       if (attr->read_format & PERF_FORMAT_LOST)
+               __T("failed to read member LOST", counts.lost == 0);
+
+       perf_evsel__close(member);
+       perf_evsel__close(leader);
+       perf_evsel__delete(member);
+       perf_evsel__delete(leader);
+       return 0;
+}
+
+static int test_stat_read_format(void)
+{
+       struct perf_thread_map *threads;
+       struct perf_event_attr attr = {
+               .type   = PERF_TYPE_SOFTWARE,
+               .config = PERF_COUNT_SW_TASK_CLOCK,
+       };
+       int err, i;
+
+#define FMT(_fmt)  PERF_FORMAT_ ## _fmt
+#define FMT_TIME  (FMT(TOTAL_TIME_ENABLED) | FMT(TOTAL_TIME_RUNNING))
+
+       uint64_t test_formats [] = {
+               0,
+               FMT_TIME,
+               FMT(ID),
+               FMT(LOST),
+               FMT_TIME | FMT(ID),
+               FMT_TIME | FMT(LOST),
+               FMT_TIME | FMT(ID) | FMT(LOST),
+               FMT(ID) | FMT(LOST),
+       };
+
+#undef FMT
+#undef FMT_TIME
+
+       threads = perf_thread_map__new_dummy();
+       __T("failed to create threads", threads);
+
+       perf_thread_map__set_pid(threads, 0, 0);
+
+       for (i = 0; i < (int)ARRAY_SIZE(test_formats); i++) {
+               attr.read_format = test_formats[i];
+               __T_VERBOSE("testing single read with read_format: %lx\n",
+                           (unsigned long)test_formats[i]);
+
+               err = test_stat_read_format_single(&attr, threads);
+               __T("failed to read single format", err == 0);
+       }
+
+       perf_thread_map__put(threads);
+
+       threads = perf_thread_map__new_array(2, NULL);
+       __T("failed to create threads", threads);
+
+       perf_thread_map__set_pid(threads, 0, 0);
+       perf_thread_map__set_pid(threads, 1, 0);
+
+       for (i = 0; i < (int)ARRAY_SIZE(test_formats); i++) {
+               attr.read_format = test_formats[i];
+               __T_VERBOSE("testing group read with read_format: %lx\n",
+                           (unsigned long)test_formats[i]);
+
+               err = test_stat_read_format_group(&attr, threads);
+               __T("failed to read group format", err == 0);
+       }
+
+       perf_thread_map__put(threads);
+       return 0;
+}
+
 int test_evsel(int argc, char **argv)
 {
        __T_START;
@@ -200,6 +360,7 @@ int test_evsel(int argc, char **argv)
        test_stat_thread_enable();
        test_stat_user_read(PERF_COUNT_HW_INSTRUCTIONS);
        test_stat_user_read(PERF_COUNT_HW_CPU_CYCLES);
+       test_stat_read_format();
 
        __T_END;
        return tests_failed == 0 ? 0 : -1;
index 0cec74d..9167825 100644 (file)
@@ -4096,7 +4096,8 @@ static int validate_ibt(struct objtool_file *file)
                 * These sections can reference text addresses, but not with
                 * the intent to indirect branch to them.
                 */
-               if (!strncmp(sec->name, ".discard", 8)                  ||
+               if ((!strncmp(sec->name, ".discard", 8) &&
+                    strcmp(sec->name, ".discard.ibt_endbr_noseal"))    ||
                    !strncmp(sec->name, ".debug", 6)                    ||
                    !strcmp(sec->name, ".altinstructions")              ||
                    !strcmp(sec->name, ".ibt_endbr_seal")               ||
index f94929e..7ea150c 100644 (file)
@@ -17,21 +17,23 @@ static int process_event_mask(struct perf_tool *tool __maybe_unused,
                         struct machine *machine __maybe_unused)
 {
        struct perf_record_cpu_map *map_event = &event->cpu_map;
-       struct perf_record_record_cpu_map *mask;
        struct perf_record_cpu_map_data *data;
        struct perf_cpu_map *map;
        int i;
+       unsigned int long_size;
 
        data = &map_event->data;
 
        TEST_ASSERT_VAL("wrong type", data->type == PERF_CPU_MAP__MASK);
 
-       mask = (struct perf_record_record_cpu_map *)data->data;
+       long_size = data->mask32_data.long_size;
 
-       TEST_ASSERT_VAL("wrong nr",   mask->nr == 1);
+       TEST_ASSERT_VAL("wrong long_size", long_size == 4 || long_size == 8);
+
+       TEST_ASSERT_VAL("wrong nr",   data->mask32_data.nr == 1);
 
        for (i = 0; i < 20; i++) {
-               TEST_ASSERT_VAL("wrong cpu", test_bit(i, mask->mask));
+               TEST_ASSERT_VAL("wrong cpu", perf_record_cpu_map_data__test_bit(i, data));
        }
 
        map = cpu_map__new_data(data);
@@ -51,7 +53,6 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused,
                         struct machine *machine __maybe_unused)
 {
        struct perf_record_cpu_map *map_event = &event->cpu_map;
-       struct cpu_map_entries *cpus;
        struct perf_record_cpu_map_data *data;
        struct perf_cpu_map *map;
 
@@ -59,11 +60,9 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused,
 
        TEST_ASSERT_VAL("wrong type", data->type == PERF_CPU_MAP__CPUS);
 
-       cpus = (struct cpu_map_entries *)data->data;
-
-       TEST_ASSERT_VAL("wrong nr",   cpus->nr == 2);
-       TEST_ASSERT_VAL("wrong cpu",  cpus->cpu[0] == 1);
-       TEST_ASSERT_VAL("wrong cpu",  cpus->cpu[1] == 256);
+       TEST_ASSERT_VAL("wrong nr",   data->cpus_data.nr == 2);
+       TEST_ASSERT_VAL("wrong cpu",  data->cpus_data.cpu[0] == 1);
+       TEST_ASSERT_VAL("wrong cpu",  data->cpus_data.cpu[1] == 256);
 
        map = cpu_map__new_data(data);
        TEST_ASSERT_VAL("wrong nr",  perf_cpu_map__nr(map) == 2);
index 07f2411..20930dd 100644 (file)
@@ -86,10 +86,15 @@ static bool samples_same(const struct perf_sample *s1,
                        COMP(read.time_running);
                /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
                if (read_format & PERF_FORMAT_GROUP) {
-                       for (i = 0; i < s1->read.group.nr; i++)
-                               MCOMP(read.group.values[i]);
+                       for (i = 0; i < s1->read.group.nr; i++) {
+                               /* FIXME: check values without LOST */
+                               if (read_format & PERF_FORMAT_LOST)
+                                       MCOMP(read.group.values[i]);
+                       }
                } else {
                        COMP(read.one.id);
+                       if (read_format & PERF_FORMAT_LOST)
+                               COMP(read.one.lost);
                }
        }
 
@@ -263,7 +268,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
                        .data   = (void *)aux_data,
                },
        };
-       struct sample_read_value values[] = {{1, 5}, {9, 3}, {2, 7}, {6, 4},};
+       struct sample_read_value values[] = {{1, 5, 0}, {9, 3, 0}, {2, 7, 0}, {6, 4, 1},};
        struct perf_sample sample_out, sample_out_endian;
        size_t i, sz, bufsz;
        int err, ret = -1;
@@ -286,6 +291,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
        } else {
                sample.read.one.value = 0x08789faeb786aa87ULL;
                sample.read.one.id    = 99;
+               sample.read.one.lost  = 1;
        }
 
        sz = perf_event__sample_event_size(&sample, sample_type, read_format);
@@ -370,7 +376,7 @@ out_free:
  */
 static int test__sample_parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
 {
-       const u64 rf[] = {4, 5, 6, 7, 12, 13, 14, 15};
+       const u64 rf[] = {4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 28, 29, 30, 31};
        u64 sample_type;
        u64 sample_regs;
        size_t i;
index 17311ad..de3701a 100644 (file)
@@ -14,6 +14,8 @@ struct file;
 struct pid;
 struct cred;
 struct socket;
+struct sock;
+struct sk_buff;
 
 #define __sockaddr_check_size(size)    \
        BUILD_BUG_ON(((size) > sizeof(struct __kernel_sockaddr_storage)))
@@ -69,6 +71,9 @@ struct msghdr {
        unsigned int    msg_flags;      /* flags on received message */
        __kernel_size_t msg_controllen; /* ancillary data buffer length */
        struct kiocb    *msg_iocb;      /* ptr to iocb for async requests */
+       struct ubuf_info *msg_ubuf;
+       int (*sg_from_iter)(struct sock *sk, struct sk_buff *skb,
+                           struct iov_iter *from, size_t length);
 };
 
 struct user_msghdr {
@@ -416,10 +421,9 @@ extern int recvmsg_copy_msghdr(struct msghdr *msg,
                               struct user_msghdr __user *umsg, unsigned flags,
                               struct sockaddr __user **uaddr,
                               struct iovec **iov);
-extern int __copy_msghdr_from_user(struct msghdr *kmsg,
-                                  struct user_msghdr __user *umsg,
-                                  struct sockaddr __user **save_addr,
-                                  struct iovec __user **uiov, size_t *nsegs);
+extern int __copy_msghdr(struct msghdr *kmsg,
+                        struct user_msghdr *umsg,
+                        struct sockaddr __user **save_addr);
 
 /* helpers which do the actual work for syscalls */
 extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size,
@@ -428,10 +432,6 @@ extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size,
 extern int __sys_sendto(int fd, void __user *buff, size_t len,
                        unsigned int flags, struct sockaddr __user *addr,
                        int addr_len);
-extern int __sys_accept4_file(struct file *file, unsigned file_flags,
-                       struct sockaddr __user *upeer_sockaddr,
-                        int __user *upeer_addrlen, int flags,
-                        unsigned long nofile);
 extern struct file *do_accept(struct file *file, unsigned file_flags,
                              struct sockaddr __user *upeer_sockaddr,
                              int __user *upeer_addrlen, int flags);
index 12b2243..ae43fb8 100644 (file)
@@ -22,54 +22,102 @@ static int max_node_num;
  */
 static int *cpunode_map;
 
-static struct perf_cpu_map *cpu_map__from_entries(struct cpu_map_entries *cpus)
+bool perf_record_cpu_map_data__test_bit(int i,
+                                       const struct perf_record_cpu_map_data *data)
+{
+       int bit_word32 = i / 32;
+       __u32 bit_mask32 = 1U << (i & 31);
+       int bit_word64 = i / 64;
+       __u64 bit_mask64 = ((__u64)1) << (i & 63);
+
+       return (data->mask32_data.long_size == 4)
+               ? (bit_word32 < data->mask32_data.nr) &&
+               (data->mask32_data.mask[bit_word32] & bit_mask32) != 0
+               : (bit_word64 < data->mask64_data.nr) &&
+               (data->mask64_data.mask[bit_word64] & bit_mask64) != 0;
+}
+
+/* Read ith mask value from data into the given 64-bit sized bitmap */
+static void perf_record_cpu_map_data__read_one_mask(const struct perf_record_cpu_map_data *data,
+                                                   int i, unsigned long *bitmap)
+{
+#if __SIZEOF_LONG__ == 8
+       if (data->mask32_data.long_size == 4)
+               bitmap[0] = data->mask32_data.mask[i];
+       else
+               bitmap[0] = data->mask64_data.mask[i];
+#else
+       if (data->mask32_data.long_size == 4) {
+               bitmap[0] = data->mask32_data.mask[i];
+               bitmap[1] = 0;
+       } else {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+               bitmap[0] = (unsigned long)(data->mask64_data.mask[i] >> 32);
+               bitmap[1] = (unsigned long)data->mask64_data.mask[i];
+#else
+               bitmap[0] = (unsigned long)data->mask64_data.mask[i];
+               bitmap[1] = (unsigned long)(data->mask64_data.mask[i] >> 32);
+#endif
+       }
+#endif
+}
+static struct perf_cpu_map *cpu_map__from_entries(const struct perf_record_cpu_map_data *data)
 {
        struct perf_cpu_map *map;
 
-       map = perf_cpu_map__empty_new(cpus->nr);
+       map = perf_cpu_map__empty_new(data->cpus_data.nr);
        if (map) {
                unsigned i;
 
-               for (i = 0; i < cpus->nr; i++) {
+               for (i = 0; i < data->cpus_data.nr; i++) {
                        /*
                         * Special treatment for -1, which is not real cpu number,
                         * and we need to use (int) -1 to initialize map[i],
                         * otherwise it would become 65535.
                         */
-                       if (cpus->cpu[i] == (u16) -1)
+                       if (data->cpus_data.cpu[i] == (u16) -1)
                                map->map[i].cpu = -1;
                        else
-                               map->map[i].cpu = (int) cpus->cpu[i];
+                               map->map[i].cpu = (int) data->cpus_data.cpu[i];
                }
        }
 
        return map;
 }
 
-static struct perf_cpu_map *cpu_map__from_mask(struct perf_record_record_cpu_map *mask)
+static struct perf_cpu_map *cpu_map__from_mask(const struct perf_record_cpu_map_data *data)
 {
+       DECLARE_BITMAP(local_copy, 64);
+       int weight = 0, mask_nr = data->mask32_data.nr;
        struct perf_cpu_map *map;
-       int nr, nbits = mask->nr * mask->long_size * BITS_PER_BYTE;
 
-       nr = bitmap_weight(mask->mask, nbits);
+       for (int i = 0; i < mask_nr; i++) {
+               perf_record_cpu_map_data__read_one_mask(data, i, local_copy);
+               weight += bitmap_weight(local_copy, 64);
+       }
+
+       map = perf_cpu_map__empty_new(weight);
+       if (!map)
+               return NULL;
 
-       map = perf_cpu_map__empty_new(nr);
-       if (map) {
-               int cpu, i = 0;
+       for (int i = 0, j = 0; i < mask_nr; i++) {
+               int cpus_per_i = (i * data->mask32_data.long_size  * BITS_PER_BYTE);
+               int cpu;
 
-               for_each_set_bit(cpu, mask->mask, nbits)
-                       map->map[i++].cpu = cpu;
+               perf_record_cpu_map_data__read_one_mask(data, i, local_copy);
+               for_each_set_bit(cpu, local_copy, 64)
+                       map->map[j++].cpu = cpu + cpus_per_i;
        }
        return map;
 
 }
 
-struct perf_cpu_map *cpu_map__new_data(struct perf_record_cpu_map_data *data)
+struct perf_cpu_map *cpu_map__new_data(const struct perf_record_cpu_map_data *data)
 {
        if (data->type == PERF_CPU_MAP__CPUS)
-               return cpu_map__from_entries((struct cpu_map_entries *)data->data);
+               return cpu_map__from_entries(data);
        else
-               return cpu_map__from_mask((struct perf_record_record_cpu_map *)data->data);
+               return cpu_map__from_mask(data);
 }
 
 size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp)
index 703ae6d..fa8a5ac 100644 (file)
@@ -37,9 +37,11 @@ struct cpu_aggr_map {
 
 struct perf_record_cpu_map_data;
 
+bool perf_record_cpu_map_data__test_bit(int i, const struct perf_record_cpu_map_data *data);
+
 struct perf_cpu_map *perf_cpu_map__empty_new(int nr);
 
-struct perf_cpu_map *cpu_map__new_data(struct perf_record_cpu_map_data *data);
+struct perf_cpu_map *cpu_map__new_data(const struct perf_record_cpu_map_data *data);
 size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size);
 size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size);
 size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp);
index a7b0931..12eae69 100644 (file)
@@ -65,7 +65,8 @@ struct stack_dump {
 
 struct sample_read_value {
        u64 value;
-       u64 id;
+       u64 id;   /* only if PERF_FORMAT_ID */
+       u64 lost; /* only if PERF_FORMAT_LOST */
 };
 
 struct sample_read {
@@ -80,6 +81,24 @@ struct sample_read {
        };
 };
 
+static inline size_t sample_read_value_size(u64 read_format)
+{
+       /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
+       if (read_format & PERF_FORMAT_LOST)
+               return sizeof(struct sample_read_value);
+       else
+               return offsetof(struct sample_read_value, lost);
+}
+
+static inline struct sample_read_value *
+next_sample_read_value(struct sample_read_value *v, u64 read_format)
+{
+       return (void *)v + sample_read_value_size(read_format);
+}
+
+#define sample_read_group__for_each(v, nr, rf)         \
+       for (int __i = 0; __i < (int)nr; v = next_sample_read_value(v, rf), __i++)
+
 struct ip_callchain {
        u64 nr;
        u64 ips[];
@@ -463,10 +482,6 @@ size_t perf_event__fprintf(union perf_event *event, struct machine *machine, FIL
 int kallsyms__get_function_start(const char *kallsyms_filename,
                                 const char *symbol_name, u64 *addr);
 
-void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int *max);
-void  cpu_map_data__synthesize(struct perf_record_cpu_map_data *data, struct perf_cpu_map *map,
-                              u16 type, int max);
-
 void event_attr_init(struct perf_event_attr *attr);
 
 int perf_event_paranoid(void);
index 4852089..18c3eb8 100644 (file)
@@ -1541,7 +1541,7 @@ static int evsel__read_one(struct evsel *evsel, int cpu_map_idx, int thread)
 }
 
 static void evsel__set_count(struct evsel *counter, int cpu_map_idx, int thread,
-                            u64 val, u64 ena, u64 run)
+                            u64 val, u64 ena, u64 run, u64 lost)
 {
        struct perf_counts_values *count;
 
@@ -1550,6 +1550,7 @@ static void evsel__set_count(struct evsel *counter, int cpu_map_idx, int thread,
        count->val    = val;
        count->ena    = ena;
        count->run    = run;
+       count->lost   = lost;
 
        perf_counts__set_loaded(counter->counts, cpu_map_idx, thread, true);
 }
@@ -1558,7 +1559,7 @@ static int evsel__process_group_data(struct evsel *leader, int cpu_map_idx, int
 {
        u64 read_format = leader->core.attr.read_format;
        struct sample_read_value *v;
-       u64 nr, ena = 0, run = 0, i;
+       u64 nr, ena = 0, run = 0, lost = 0;
 
        nr = *data++;
 
@@ -1571,18 +1572,18 @@ static int evsel__process_group_data(struct evsel *leader, int cpu_map_idx, int
        if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
                run = *data++;
 
-       v = (struct sample_read_value *) data;
-
-       evsel__set_count(leader, cpu_map_idx, thread, v[0].value, ena, run);
-
-       for (i = 1; i < nr; i++) {
+       v = (void *)data;
+       sample_read_group__for_each(v, nr, read_format) {
                struct evsel *counter;
 
-               counter = evlist__id2evsel(leader->evlist, v[i].id);
+               counter = evlist__id2evsel(leader->evlist, v->id);
                if (!counter)
                        return -EINVAL;
 
-               evsel__set_count(counter, cpu_map_idx, thread, v[i].value, ena, run);
+               if (read_format & PERF_FORMAT_LOST)
+                       lost = v->lost;
+
+               evsel__set_count(counter, cpu_map_idx, thread, v->value, ena, run, lost);
        }
 
        return 0;
@@ -2475,8 +2476,8 @@ int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
 
                        if (data->read.group.nr > max_group_nr)
                                return -EFAULT;
-                       sz = data->read.group.nr *
-                            sizeof(struct sample_read_value);
+
+                       sz = data->read.group.nr * sample_read_value_size(read_format);
                        OVERFLOW_CHECK(array, sz, max_size);
                        data->read.group.values =
                                        (struct sample_read_value *)array;
@@ -2485,6 +2486,12 @@ int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
                        OVERFLOW_CHECK_u64(array);
                        data->read.one.id = *array;
                        array++;
+
+                       if (read_format & PERF_FORMAT_LOST) {
+                               OVERFLOW_CHECK_u64(array);
+                               data->read.one.lost = *array;
+                               array++;
+                       }
                }
        }
 
index 9ef2406..1f2040f 100644 (file)
@@ -642,15 +642,19 @@ exit:
        return pylist;
 }
 
-static PyObject *get_sample_value_as_tuple(struct sample_read_value *value)
+static PyObject *get_sample_value_as_tuple(struct sample_read_value *value,
+                                          u64 read_format)
 {
        PyObject *t;
 
-       t = PyTuple_New(2);
+       t = PyTuple_New(3);
        if (!t)
                Py_FatalError("couldn't create Python tuple");
        PyTuple_SetItem(t, 0, PyLong_FromUnsignedLongLong(value->id));
        PyTuple_SetItem(t, 1, PyLong_FromUnsignedLongLong(value->value));
+       if (read_format & PERF_FORMAT_LOST)
+               PyTuple_SetItem(t, 2, PyLong_FromUnsignedLongLong(value->lost));
+
        return t;
 }
 
@@ -681,12 +685,17 @@ static void set_sample_read_in_dict(PyObject *dict_sample,
                Py_FatalError("couldn't create Python list");
 
        if (read_format & PERF_FORMAT_GROUP) {
-               for (i = 0; i < sample->read.group.nr; i++) {
-                       PyObject *t = get_sample_value_as_tuple(&sample->read.group.values[i]);
+               struct sample_read_value *v = sample->read.group.values;
+
+               i = 0;
+               sample_read_group__for_each(v, sample->read.group.nr, read_format) {
+                       PyObject *t = get_sample_value_as_tuple(v, read_format);
                        PyList_SET_ITEM(values, i, t);
+                       i++;
                }
        } else {
-               PyObject *t = get_sample_value_as_tuple(&sample->read.one);
+               PyObject *t = get_sample_value_as_tuple(&sample->read.one,
+                                                       read_format);
                PyList_SET_ITEM(values, 0, t);
        }
        pydict_set_item_string_decref(dict_sample, "values", values);
index 98e1665..192c927 100644 (file)
@@ -916,30 +916,30 @@ static void perf_event__cpu_map_swap(union perf_event *event,
                                     bool sample_id_all __maybe_unused)
 {
        struct perf_record_cpu_map_data *data = &event->cpu_map.data;
-       struct cpu_map_entries *cpus;
-       struct perf_record_record_cpu_map *mask;
-       unsigned i;
 
        data->type = bswap_16(data->type);
 
        switch (data->type) {
        case PERF_CPU_MAP__CPUS:
-               cpus = (struct cpu_map_entries *)data->data;
-
-               cpus->nr = bswap_16(cpus->nr);
+               data->cpus_data.nr = bswap_16(data->cpus_data.nr);
 
-               for (i = 0; i < cpus->nr; i++)
-                       cpus->cpu[i] = bswap_16(cpus->cpu[i]);
+               for (unsigned i = 0; i < data->cpus_data.nr; i++)
+                       data->cpus_data.cpu[i] = bswap_16(data->cpus_data.cpu[i]);
                break;
        case PERF_CPU_MAP__MASK:
-               mask = (struct perf_record_record_cpu_map *)data->data;
-
-               mask->nr = bswap_16(mask->nr);
-               mask->long_size = bswap_16(mask->long_size);
+               data->mask32_data.long_size = bswap_16(data->mask32_data.long_size);
 
-               switch (mask->long_size) {
-               case 4: mem_bswap_32(&mask->mask, mask->nr); break;
-               case 8: mem_bswap_64(&mask->mask, mask->nr); break;
+               switch (data->mask32_data.long_size) {
+               case 4:
+                       data->mask32_data.nr = bswap_16(data->mask32_data.nr);
+                       for (unsigned i = 0; i < data->mask32_data.nr; i++)
+                               data->mask32_data.mask[i] = bswap_32(data->mask32_data.mask[i]);
+                       break;
+               case 8:
+                       data->mask64_data.nr = bswap_16(data->mask64_data.nr);
+                       for (unsigned i = 0; i < data->mask64_data.nr; i++)
+                               data->mask64_data.mask[i] = bswap_64(data->mask64_data.mask[i]);
+                       break;
                default:
                        pr_err("cpu_map swap: unsupported long size\n");
                }
@@ -1283,21 +1283,25 @@ static void sample_read__printf(struct perf_sample *sample, u64 read_format)
                       sample->read.time_running);
 
        if (read_format & PERF_FORMAT_GROUP) {
-               u64 i;
+               struct sample_read_value *value = sample->read.group.values;
 
                printf(".... group nr %" PRIu64 "\n", sample->read.group.nr);
 
-               for (i = 0; i < sample->read.group.nr; i++) {
-                       struct sample_read_value *value;
-
-                       value = &sample->read.group.values[i];
+               sample_read_group__for_each(value, sample->read.group.nr, read_format) {
                        printf("..... id %016" PRIx64
-                              ", value %016" PRIx64 "\n",
+                              ", value %016" PRIx64,
                               value->id, value->value);
+                       if (read_format & PERF_FORMAT_LOST)
+                               printf(", lost %" PRIu64, value->lost);
+                       printf("\n");
                }
-       } else
-               printf("..... id %016" PRIx64 ", value %016" PRIx64 "\n",
+       } else {
+               printf("..... id %016" PRIx64 ", value %016" PRIx64,
                        sample->read.one.id, sample->read.one.value);
+               if (read_format & PERF_FORMAT_LOST)
+                       printf(", lost %" PRIu64, sample->read.one.lost);
+               printf("\n");
+       }
 }
 
 static void dump_event(struct evlist *evlist, union perf_event *event,
@@ -1411,6 +1415,9 @@ static void dump_read(struct evsel *evsel, union perf_event *event)
 
        if (read_format & PERF_FORMAT_ID)
                printf("... id           : %" PRI_lu64 "\n", read_event->id);
+
+       if (read_format & PERF_FORMAT_LOST)
+               printf("... lost         : %" PRI_lu64 "\n", read_event->lost);
 }
 
 static struct machine *machines__find_for_cpumode(struct machines *machines,
@@ -1479,14 +1486,14 @@ static int deliver_sample_group(struct evlist *evlist,
                                struct perf_tool *tool,
                                union  perf_event *event,
                                struct perf_sample *sample,
-                               struct machine *machine)
+                               struct machine *machine,
+                               u64 read_format)
 {
        int ret = -EINVAL;
-       u64 i;
+       struct sample_read_value *v = sample->read.group.values;
 
-       for (i = 0; i < sample->read.group.nr; i++) {
-               ret = deliver_sample_value(evlist, tool, event, sample,
-                                          &sample->read.group.values[i],
+       sample_read_group__for_each(v, sample->read.group.nr, read_format) {
+               ret = deliver_sample_value(evlist, tool, event, sample, v,
                                           machine);
                if (ret)
                        break;
@@ -1510,7 +1517,7 @@ static int evlist__deliver_sample(struct evlist *evlist, struct perf_tool *tool,
        /* For PERF_SAMPLE_READ we have either single or group mode. */
        if (read_format & PERF_FORMAT_GROUP)
                return deliver_sample_group(evlist, tool, event, sample,
-                                           machine);
+                                           machine, read_format);
        else
                return deliver_sample_value(evlist, tool, event, sample,
                                            &sample->read.one, machine);
index 2ae59c0..812424d 100644 (file)
@@ -1184,52 +1184,48 @@ int perf_event__synthesize_thread_map2(struct perf_tool *tool,
        return err;
 }
 
-static void synthesize_cpus(struct cpu_map_entries *cpus,
-                           struct perf_cpu_map *map)
+static void synthesize_cpus(struct perf_record_cpu_map_data *data,
+                           const struct perf_cpu_map *map)
 {
        int i, map_nr = perf_cpu_map__nr(map);
 
-       cpus->nr = map_nr;
+       data->cpus_data.nr = map_nr;
 
        for (i = 0; i < map_nr; i++)
-               cpus->cpu[i] = perf_cpu_map__cpu(map, i).cpu;
+               data->cpus_data.cpu[i] = perf_cpu_map__cpu(map, i).cpu;
 }
 
-static void synthesize_mask(struct perf_record_record_cpu_map *mask,
-                           struct perf_cpu_map *map, int max)
+static void synthesize_mask(struct perf_record_cpu_map_data *data,
+                           const struct perf_cpu_map *map, int max)
 {
-       int i;
+       int idx;
+       struct perf_cpu cpu;
+
+       /* Due to padding, the 4bytes per entry mask variant is always smaller. */
+       data->mask32_data.nr = BITS_TO_U32(max);
+       data->mask32_data.long_size = 4;
 
-       mask->nr = BITS_TO_LONGS(max);
-       mask->long_size = sizeof(long);
+       perf_cpu_map__for_each_cpu(cpu, idx, map) {
+               int bit_word = cpu.cpu / 32;
+               __u32 bit_mask = 1U << (cpu.cpu & 31);
 
-       for (i = 0; i < perf_cpu_map__nr(map); i++)
-               set_bit(perf_cpu_map__cpu(map, i).cpu, mask->mask);
+               data->mask32_data.mask[bit_word] |= bit_mask;
+       }
 }
 
-static size_t cpus_size(struct perf_cpu_map *map)
+static size_t cpus_size(const struct perf_cpu_map *map)
 {
        return sizeof(struct cpu_map_entries) + perf_cpu_map__nr(map) * sizeof(u16);
 }
 
-static size_t mask_size(struct perf_cpu_map *map, int *max)
+static size_t mask_size(const struct perf_cpu_map *map, int *max)
 {
-       int i;
-
-       *max = 0;
-
-       for (i = 0; i < perf_cpu_map__nr(map); i++) {
-               /* bit position of the cpu is + 1 */
-               int bit = perf_cpu_map__cpu(map, i).cpu + 1;
-
-               if (bit > *max)
-                       *max = bit;
-       }
-
-       return sizeof(struct perf_record_record_cpu_map) + BITS_TO_LONGS(*max) * sizeof(long);
+       *max = perf_cpu_map__max(map).cpu;
+       return sizeof(struct perf_record_mask_cpu_map32) + BITS_TO_U32(*max) * sizeof(__u32);
 }
 
-void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int *max)
+static void *cpu_map_data__alloc(const struct perf_cpu_map *map, size_t *size,
+                                u16 *type, int *max)
 {
        size_t size_cpus, size_mask;
        bool is_dummy = perf_cpu_map__empty(map);
@@ -1258,30 +1254,31 @@ void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int
                *type  = PERF_CPU_MAP__MASK;
        }
 
-       *size += sizeof(struct perf_record_cpu_map_data);
+       *size += sizeof(__u16); /* For perf_record_cpu_map_data.type. */
        *size = PERF_ALIGN(*size, sizeof(u64));
        return zalloc(*size);
 }
 
-void cpu_map_data__synthesize(struct perf_record_cpu_map_data *data, struct perf_cpu_map *map,
-                             u16 type, int max)
+static void cpu_map_data__synthesize(struct perf_record_cpu_map_data *data,
+                                    const struct perf_cpu_map *map,
+                                    u16 type, int max)
 {
        data->type = type;
 
        switch (type) {
        case PERF_CPU_MAP__CPUS:
-               synthesize_cpus((struct cpu_map_entries *) data->data, map);
+               synthesize_cpus(data, map);
                break;
        case PERF_CPU_MAP__MASK:
-               synthesize_mask((struct perf_record_record_cpu_map *)data->data, map, max);
+               synthesize_mask(data, map, max);
        default:
                break;
        }
 }
 
-static struct perf_record_cpu_map *cpu_map_event__new(struct perf_cpu_map *map)
+static struct perf_record_cpu_map *cpu_map_event__new(const struct perf_cpu_map *map)
 {
-       size_t size = sizeof(struct perf_record_cpu_map);
+       size_t size = sizeof(struct perf_event_header);
        struct perf_record_cpu_map *event;
        int max;
        u16 type;
@@ -1299,7 +1296,7 @@ static struct perf_record_cpu_map *cpu_map_event__new(struct perf_cpu_map *map)
 }
 
 int perf_event__synthesize_cpu_map(struct perf_tool *tool,
-                                  struct perf_cpu_map *map,
+                                  const struct perf_cpu_map *map,
                                   perf_event__handler_t process,
                                   struct machine *machine)
 {
@@ -1432,11 +1429,12 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
                        result += sizeof(u64);
                /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
                if (read_format & PERF_FORMAT_GROUP) {
-                       sz = sample->read.group.nr *
-                            sizeof(struct sample_read_value);
-                       result += sz;
+                       sz = sample_read_value_size(read_format);
+                       result += sz * sample->read.group.nr;
                } else {
                        result += sizeof(u64);
+                       if (read_format & PERF_FORMAT_LOST)
+                               result += sizeof(u64);
                }
        }
 
@@ -1521,6 +1519,20 @@ void __weak arch_perf_synthesize_sample_weight(const struct perf_sample *data,
        *array = data->weight;
 }
 
+static __u64 *copy_read_group_values(__u64 *array, __u64 read_format,
+                                    const struct perf_sample *sample)
+{
+       size_t sz = sample_read_value_size(read_format);
+       struct sample_read_value *v = sample->read.group.values;
+
+       sample_read_group__for_each(v, sample->read.group.nr, read_format) {
+               /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
+               memcpy(array, v, sz);
+               array = (void *)array + sz;
+       }
+       return array;
+}
+
 int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format,
                                  const struct perf_sample *sample)
 {
@@ -1602,13 +1614,16 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_fo
 
                /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
                if (read_format & PERF_FORMAT_GROUP) {
-                       sz = sample->read.group.nr *
-                            sizeof(struct sample_read_value);
-                       memcpy(array, sample->read.group.values, sz);
-                       array = (void *)array + sz;
+                       array = copy_read_group_values(array, read_format,
+                                                      sample);
                } else {
                        *array = sample->read.one.id;
                        array++;
+
+                       if (read_format & PERF_FORMAT_LOST) {
+                               *array = sample->read.one.lost;
+                               array++;
+                       }
                }
        }
 
index 81cb3d6..53737d1 100644 (file)
@@ -46,7 +46,7 @@ typedef int (*perf_event__handler_t)(struct perf_tool *tool, union perf_event *e
 int perf_event__synthesize_attrs(struct perf_tool *tool, struct evlist *evlist, perf_event__handler_t process);
 int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_attr *attr, u32 ids, u64 *id, perf_event__handler_t process);
 int perf_event__synthesize_build_id(struct perf_tool *tool, struct dso *pos, u16 misc, perf_event__handler_t process, struct machine *machine);
-int perf_event__synthesize_cpu_map(struct perf_tool *tool, struct perf_cpu_map *cpus, perf_event__handler_t process, struct machine *machine);
+int perf_event__synthesize_cpu_map(struct perf_tool *tool, const struct perf_cpu_map *cpus, perf_event__handler_t process, struct machine *machine);
 int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process);
 int perf_event__synthesize_event_update_name(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process);
 int perf_event__synthesize_event_update_scale(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process);
index a6959df..02868ac 100644 (file)
@@ -9,10 +9,13 @@ TEST_GEN_PROGS := $(src_test:.c=)
 TEST_GEN_PROGS_EXTENDED := true
 
 OVERRIDE_TARGETS := 1
+top_srcdir := ../../../..
 include ../lib.mk
 
+khdr_dir = $(top_srcdir)/usr/include
+
 $(OUTPUT)/true: true.c
        $(LINK.c) $< $(LDLIBS) -o $@ -static
 
-$(OUTPUT)/%_test: %_test.c ../kselftest_harness.h common.h
-       $(LINK.c) $< $(LDLIBS) -o $@ -lcap
+$(OUTPUT)/%_test: %_test.c $(khdr_dir)/linux/landlock.h ../kselftest_harness.h common.h
+       $(LINK.c) $< $(LDLIBS) -o $@ -lcap -I$(khdr_dir)
index d4ffebb..7060bae 100755 (executable)
 # nft_flowtable.sh -o8000 -l1500 -r2000
 #
 
+sfx=$(mktemp -u "XXXXXXXX")
+ns1="ns1-$sfx"
+ns2="ns2-$sfx"
+nsr1="nsr1-$sfx"
+nsr2="nsr2-$sfx"
 
 # Kselftest framework requirement - SKIP code is 4.
 ksft_skip=4
 ret=0
 
-ns1in=""
-ns2in=""
+nsin=""
 ns1out=""
 ns2out=""
 
@@ -36,21 +40,19 @@ checktool (){
 checktool "nft --version" "run test without nft tool"
 checktool "ip -Version" "run test without ip tool"
 checktool "which nc" "run test without nc (netcat)"
-checktool "ip netns add nsr1" "create net namespace"
+checktool "ip netns add $nsr1" "create net namespace $nsr1"
 
-ip netns add ns1
-ip netns add ns2
-
-ip netns add nsr2
+ip netns add $ns1
+ip netns add $ns2
+ip netns add $nsr2
 
 cleanup() {
-       for i in 1 2; do
-               ip netns del ns$i
-               ip netns del nsr$i
-       done
+       ip netns del $ns1
+       ip netns del $ns2
+       ip netns del $nsr1
+       ip netns del $nsr2
 
-       rm -f "$ns1in" "$ns1out"
-       rm -f "$ns2in" "$ns2out"
+       rm -f "$nsin" "$ns1out" "$ns2out"
 
        [ $log_netns -eq 0 ] && sysctl -q net.netfilter.nf_log_all_netns=$log_netns
 }
@@ -59,22 +61,21 @@ trap cleanup EXIT
 
 sysctl -q net.netfilter.nf_log_all_netns=1
 
-ip link add veth0 netns nsr1 type veth peer name eth0 netns ns1
-ip link add veth1 netns nsr1 type veth peer name veth0 netns nsr2
+ip link add veth0 netns $nsr1 type veth peer name eth0 netns $ns1
+ip link add veth1 netns $nsr1 type veth peer name veth0 netns $nsr2
 
-ip link add veth1 netns nsr2 type veth peer name eth0 netns ns2
+ip link add veth1 netns $nsr2 type veth peer name eth0 netns $ns2
 
 for dev in lo veth0 veth1; do
-  for i in 1 2; do
-    ip -net nsr$i link set $dev up
-  done
+    ip -net $nsr1 link set $dev up
+    ip -net $nsr2 link set $dev up
 done
 
-ip -net nsr1 addr add 10.0.1.1/24 dev veth0
-ip -net nsr1 addr add dead:1::1/64 dev veth0
+ip -net $nsr1 addr add 10.0.1.1/24 dev veth0
+ip -net $nsr1 addr add dead:1::1/64 dev veth0
 
-ip -net nsr2 addr add 10.0.2.1/24 dev veth1
-ip -net nsr2 addr add dead:2::1/64 dev veth1
+ip -net $nsr2 addr add 10.0.2.1/24 dev veth1
+ip -net $nsr2 addr add dead:2::1/64 dev veth1
 
 # set different MTUs so we need to push packets coming from ns1 (large MTU)
 # to ns2 (smaller MTU) to stack either to perform fragmentation (ip_no_pmtu_disc=1),
@@ -106,85 +107,76 @@ do
        esac
 done
 
-if ! ip -net nsr1 link set veth0 mtu $omtu; then
+if ! ip -net $nsr1 link set veth0 mtu $omtu; then
        exit 1
 fi
 
-ip -net ns1 link set eth0 mtu $omtu
+ip -net $ns1 link set eth0 mtu $omtu
 
-if ! ip -net nsr2 link set veth1 mtu $rmtu; then
+if ! ip -net $nsr2 link set veth1 mtu $rmtu; then
        exit 1
 fi
 
-ip -net ns2 link set eth0 mtu $rmtu
+ip -net $ns2 link set eth0 mtu $rmtu
 
 # transfer-net between nsr1 and nsr2.
 # these addresses are not used for connections.
-ip -net nsr1 addr add 192.168.10.1/24 dev veth1
-ip -net nsr1 addr add fee1:2::1/64 dev veth1
-
-ip -net nsr2 addr add 192.168.10.2/24 dev veth0
-ip -net nsr2 addr add fee1:2::2/64 dev veth0
-
-for i in 1 2; do
-  ip netns exec nsr$i sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null
-  ip netns exec nsr$i sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null
-
-  ip -net ns$i link set lo up
-  ip -net ns$i link set eth0 up
-  ip -net ns$i addr add 10.0.$i.99/24 dev eth0
-  ip -net ns$i route add default via 10.0.$i.1
-  ip -net ns$i addr add dead:$i::99/64 dev eth0
-  ip -net ns$i route add default via dead:$i::1
-  if ! ip netns exec ns$i sysctl net.ipv4.tcp_no_metrics_save=1 > /dev/null; then
+ip -net $nsr1 addr add 192.168.10.1/24 dev veth1
+ip -net $nsr1 addr add fee1:2::1/64 dev veth1
+
+ip -net $nsr2 addr add 192.168.10.2/24 dev veth0
+ip -net $nsr2 addr add fee1:2::2/64 dev veth0
+
+for i in 0 1; do
+  ip netns exec $nsr1 sysctl net.ipv4.conf.veth$i.forwarding=1 > /dev/null
+  ip netns exec $nsr2 sysctl net.ipv4.conf.veth$i.forwarding=1 > /dev/null
+done
+
+for ns in $ns1 $ns2;do
+  ip -net $ns link set lo up
+  ip -net $ns link set eth0 up
+
+  if ! ip netns exec $ns sysctl net.ipv4.tcp_no_metrics_save=1 > /dev/null; then
        echo "ERROR: Check Originator/Responder values (problem during address addition)"
        exit 1
   fi
-
   # don't set ip DF bit for first two tests
-  ip netns exec ns$i sysctl net.ipv4.ip_no_pmtu_disc=1 > /dev/null
+  ip netns exec $ns sysctl net.ipv4.ip_no_pmtu_disc=1 > /dev/null
 done
 
-ip -net nsr1 route add default via 192.168.10.2
-ip -net nsr2 route add default via 192.168.10.1
+ip -net $ns1 addr add 10.0.1.99/24 dev eth0
+ip -net $ns2 addr add 10.0.2.99/24 dev eth0
+ip -net $ns1 route add default via 10.0.1.1
+ip -net $ns2 route add default via 10.0.2.1
+ip -net $ns1 addr add dead:1::99/64 dev eth0
+ip -net $ns2 addr add dead:2::99/64 dev eth0
+ip -net $ns1 route add default via dead:1::1
+ip -net $ns2 route add default via dead:2::1
+
+ip -net $nsr1 route add default via 192.168.10.2
+ip -net $nsr2 route add default via 192.168.10.1
 
-ip netns exec nsr1 nft -f - <<EOF
+ip netns exec $nsr1 nft -f - <<EOF
 table inet filter {
   flowtable f1 {
      hook ingress priority 0
      devices = { veth0, veth1 }
    }
 
+   counter routed_orig { }
+   counter routed_repl { }
+
    chain forward {
       type filter hook forward priority 0; policy drop;
 
       # flow offloaded? Tag ct with mark 1, so we can detect when it fails.
-      meta oif "veth1" tcp dport 12345 flow offload @f1 counter
-
-      # use packet size to trigger 'should be offloaded by now'.
-      # otherwise, if 'flow offload' expression never offloads, the
-      # test will pass.
-      tcp dport 12345 meta length gt 200 ct mark set 1 counter
+      meta oif "veth1" tcp dport 12345 ct mark set 1 flow add @f1 counter name routed_orig accept
 
-      # this turns off flow offloading internally, so expect packets again
-      tcp flags fin,rst ct mark set 0 accept
-
-      # this allows large packets from responder, we need this as long
-      # as PMTUd is off.
-      # This rule is deleted for the last test, when we expect PMTUd
-      # to kick in and ensure all packets meet mtu requirements.
-      meta length gt $lmtu accept comment something-to-grep-for
-
-      # next line blocks connection w.o. working offload.
-      # we only do this for reverse dir, because we expect packets to
-      # enter slow path due to MTU mismatch of veth0 and veth1.
-      tcp sport 12345 ct mark 1 counter log prefix "mark failure " drop
+      # count packets supposedly offloaded as per direction.
+      ct mark 1 counter name ct direction map { original : routed_orig, reply : routed_repl } accept
 
       ct state established,related accept
 
-      # for packets that we can't offload yet, i.e. SYN (any ct that is not confirmed)
-      meta length lt 200 oif "veth1" tcp dport 12345 counter accept
-
       meta nfproto ipv4 meta l4proto icmp accept
       meta nfproto ipv6 meta l4proto icmpv6 accept
    }
@@ -197,30 +189,30 @@ if [ $? -ne 0 ]; then
 fi
 
 # test basic connectivity
-if ! ip netns exec ns1 ping -c 1 -q 10.0.2.99 > /dev/null; then
-  echo "ERROR: ns1 cannot reach ns2" 1>&2
+if ! ip netns exec $ns1 ping -c 1 -q 10.0.2.99 > /dev/null; then
+  echo "ERROR: $ns1 cannot reach ns2" 1>&2
   exit 1
 fi
 
-if ! ip netns exec ns2 ping -c 1 -q 10.0.1.99 > /dev/null; then
-  echo "ERROR: ns2 cannot reach ns1" 1>&2
+if ! ip netns exec $ns2 ping -c 1 -q 10.0.1.99 > /dev/null; then
+  echo "ERROR: $ns2 cannot reach $ns1" 1>&2
   exit 1
 fi
 
 if [ $ret -eq 0 ];then
-       echo "PASS: netns routing/connectivity: ns1 can reach ns2"
+       echo "PASS: netns routing/connectivity: $ns1 can reach $ns2"
 fi
 
-ns1in=$(mktemp)
+nsin=$(mktemp)
 ns1out=$(mktemp)
-ns2in=$(mktemp)
 ns2out=$(mktemp)
 
 make_file()
 {
        name=$1
 
-       SIZE=$((RANDOM % (1024 * 8)))
+       SIZE=$((RANDOM % (1024 * 128)))
+       SIZE=$((SIZE + (1024 * 8)))
        TSIZE=$((SIZE * 1024))
 
        dd if=/dev/urandom of="$name" bs=1024 count=$SIZE 2> /dev/null
@@ -231,6 +223,38 @@ make_file()
        dd if=/dev/urandom conf=notrunc of="$name" bs=1 count=$SIZE 2> /dev/null
 }
 
+check_counters()
+{
+       local what=$1
+       local ok=1
+
+       local orig=$(ip netns exec $nsr1 nft reset counter inet filter routed_orig | grep packets)
+       local repl=$(ip netns exec $nsr1 nft reset counter inet filter routed_repl | grep packets)
+
+       local orig_cnt=${orig#*bytes}
+       local repl_cnt=${repl#*bytes}
+
+       local fs=$(du -sb $nsin)
+       local max_orig=${fs%%/*}
+       local max_repl=$((max_orig/4))
+
+       if [ $orig_cnt -gt $max_orig ];then
+               echo "FAIL: $what: original counter $orig_cnt exceeds expected value $max_orig" 1>&2
+               ret=1
+               ok=0
+       fi
+
+       if [ $repl_cnt -gt $max_repl ];then
+               echo "FAIL: $what: reply counter $repl_cnt exceeds expected value $max_repl" 1>&2
+               ret=1
+               ok=0
+       fi
+
+       if [ $ok -eq 1 ]; then
+               echo "PASS: $what"
+       fi
+}
+
 check_transfer()
 {
        in=$1
@@ -255,11 +279,11 @@ test_tcp_forwarding_ip()
        local dstport=$4
        local lret=0
 
-       ip netns exec $nsb nc -w 5 -l -p 12345 < "$ns2in" > "$ns2out" &
+       ip netns exec $nsb nc -w 5 -l -p 12345 < "$nsin" > "$ns2out" &
        lpid=$!
 
        sleep 1
-       ip netns exec $nsa nc -w 4 "$dstip" "$dstport" < "$ns1in" > "$ns1out" &
+       ip netns exec $nsa nc -w 4 "$dstip" "$dstport" < "$nsin" > "$ns1out" &
        cpid=$!
 
        sleep 3
@@ -274,11 +298,11 @@ test_tcp_forwarding_ip()
 
        wait
 
-       if ! check_transfer "$ns1in" "$ns2out" "ns1 -> ns2"; then
+       if ! check_transfer "$nsin" "$ns2out" "ns1 -> ns2"; then
                lret=1
        fi
 
-       if ! check_transfer "$ns2in" "$ns1out" "ns1 <- ns2"; then
+       if ! check_transfer "$nsin" "$ns1out" "ns1 <- ns2"; then
                lret=1
        fi
 
@@ -295,41 +319,59 @@ test_tcp_forwarding()
 test_tcp_forwarding_nat()
 {
        local lret
+       local pmtu
 
        test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345
        lret=$?
 
+       pmtu=$3
+       what=$4
+
        if [ $lret -eq 0 ] ; then
+               if [ $pmtu -eq 1 ] ;then
+                       check_counters "flow offload for ns1/ns2 with masquerade and pmtu discovery $what"
+               else
+                       echo "PASS: flow offload for ns1/ns2 with masquerade $what"
+               fi
+
                test_tcp_forwarding_ip "$1" "$2" 10.6.6.6 1666
                lret=$?
+               if [ $pmtu -eq 1 ] ;then
+                       check_counters "flow offload for ns1/ns2 with dnat and pmtu discovery $what"
+               elif [ $lret -eq 0 ] ; then
+                       echo "PASS: flow offload for ns1/ns2 with dnat $what"
+               fi
        fi
 
        return $lret
 }
 
-make_file "$ns1in"
-make_file "$ns2in"
+make_file "$nsin"
 
 # First test:
 # No PMTU discovery, nsr1 is expected to fragment packets from ns1 to ns2 as needed.
-if test_tcp_forwarding ns1 ns2; then
+# Due to MTU mismatch in both directions, all packets (except small packets like pure
+# acks) have to be handled by normal forwarding path.  Therefore, packet counters
+# are not checked.
+if test_tcp_forwarding $ns1 $ns2; then
        echo "PASS: flow offloaded for ns1/ns2"
 else
        echo "FAIL: flow offload for ns1/ns2:" 1>&2
-       ip netns exec nsr1 nft list ruleset
+       ip netns exec $nsr1 nft list ruleset
        ret=1
 fi
 
 # delete default route, i.e. ns2 won't be able to reach ns1 and
 # will depend on ns1 being masqueraded in nsr1.
 # expect ns1 has nsr1 address.
-ip -net ns2 route del default via 10.0.2.1
-ip -net ns2 route del default via dead:2::1
-ip -net ns2 route add 192.168.10.1 via 10.0.2.1
+ip -net $ns2 route del default via 10.0.2.1
+ip -net $ns2 route del default via dead:2::1
+ip -net $ns2 route add 192.168.10.1 via 10.0.2.1
 
 # Second test:
-# Same, but with NAT enabled.
-ip netns exec nsr1 nft -f - <<EOF
+# Same, but with NAT enabled.  Same as in first test: we expect normal forward path
+# to handle most packets.
+ip netns exec $nsr1 nft -f - <<EOF
 table ip nat {
    chain prerouting {
       type nat hook prerouting priority 0; policy accept;
@@ -343,47 +385,45 @@ table ip nat {
 }
 EOF
 
-if test_tcp_forwarding_nat ns1 ns2; then
-       echo "PASS: flow offloaded for ns1/ns2 with NAT"
-else
+if ! test_tcp_forwarding_nat $ns1 $ns2 0 ""; then
        echo "FAIL: flow offload for ns1/ns2 with NAT" 1>&2
-       ip netns exec nsr1 nft list ruleset
+       ip netns exec $nsr1 nft list ruleset
        ret=1
 fi
 
 # Third test:
-# Same as second test, but with PMTU discovery enabled.
-handle=$(ip netns exec nsr1 nft -a list table inet filter | grep something-to-grep-for | cut -d \# -f 2)
-
-if ! ip netns exec nsr1 nft delete rule inet filter forward $handle; then
-       echo "FAIL: Could not delete large-packet accept rule"
-       exit 1
-fi
-
-ip netns exec ns1 sysctl net.ipv4.ip_no_pmtu_disc=0 > /dev/null
-ip netns exec ns2 sysctl net.ipv4.ip_no_pmtu_disc=0 > /dev/null
-
-if test_tcp_forwarding_nat ns1 ns2; then
-       echo "PASS: flow offloaded for ns1/ns2 with NAT and pmtu discovery"
-else
+# Same as second test, but with PMTU discovery enabled. This
+# means that we expect the fastpath to handle packets as soon
+# as the endpoints adjust the packet size.
+ip netns exec $ns1 sysctl net.ipv4.ip_no_pmtu_disc=0 > /dev/null
+ip netns exec $ns2 sysctl net.ipv4.ip_no_pmtu_disc=0 > /dev/null
+
+# reset counters.
+# With pmtu in-place we'll also check that nft counters
+# are lower than file size and packets were forwarded via flowtable layer.
+# For earlier tests (large mtus), packets cannot be handled via flowtable
+# (except pure acks and other small packets).
+ip netns exec $nsr1 nft reset counters table inet filter >/dev/null
+
+if ! test_tcp_forwarding_nat $ns1 $ns2 1 ""; then
        echo "FAIL: flow offload for ns1/ns2 with NAT and pmtu discovery" 1>&2
-       ip netns exec nsr1 nft list ruleset
+       ip netns exec $nsr1 nft list ruleset
 fi
 
 # Another test:
 # Add bridge interface br0 to Router1, with NAT enabled.
-ip -net nsr1 link add name br0 type bridge
-ip -net nsr1 addr flush dev veth0
-ip -net nsr1 link set up dev veth0
-ip -net nsr1 link set veth0 master br0
-ip -net nsr1 addr add 10.0.1.1/24 dev br0
-ip -net nsr1 addr add dead:1::1/64 dev br0
-ip -net nsr1 link set up dev br0
+ip -net $nsr1 link add name br0 type bridge
+ip -net $nsr1 addr flush dev veth0
+ip -net $nsr1 link set up dev veth0
+ip -net $nsr1 link set veth0 master br0
+ip -net $nsr1 addr add 10.0.1.1/24 dev br0
+ip -net $nsr1 addr add dead:1::1/64 dev br0
+ip -net $nsr1 link set up dev br0
 
-ip netns exec nsr1 sysctl net.ipv4.conf.br0.forwarding=1 > /dev/null
+ip netns exec $nsr1 sysctl net.ipv4.conf.br0.forwarding=1 > /dev/null
 
 # br0 with NAT enabled.
-ip netns exec nsr1 nft -f - <<EOF
+ip netns exec $nsr1 nft -f - <<EOF
 flush table ip nat
 table ip nat {
    chain prerouting {
@@ -398,59 +438,56 @@ table ip nat {
 }
 EOF
 
-if test_tcp_forwarding_nat ns1 ns2; then
-       echo "PASS: flow offloaded for ns1/ns2 with bridge NAT"
-else
+if ! test_tcp_forwarding_nat $ns1 $ns2 1 "on bridge"; then
        echo "FAIL: flow offload for ns1/ns2 with bridge NAT" 1>&2
-       ip netns exec nsr1 nft list ruleset
+       ip netns exec $nsr1 nft list ruleset
        ret=1
 fi
 
+
 # Another test:
 # Add bridge interface br0 to Router1, with NAT and VLAN.
-ip -net nsr1 link set veth0 nomaster
-ip -net nsr1 link set down dev veth0
-ip -net nsr1 link add link veth0 name veth0.10 type vlan id 10
-ip -net nsr1 link set up dev veth0
-ip -net nsr1 link set up dev veth0.10
-ip -net nsr1 link set veth0.10 master br0
-
-ip -net ns1 addr flush dev eth0
-ip -net ns1 link add link eth0 name eth0.10 type vlan id 10
-ip -net ns1 link set eth0 up
-ip -net ns1 link set eth0.10 up
-ip -net ns1 addr add 10.0.1.99/24 dev eth0.10
-ip -net ns1 route add default via 10.0.1.1
-ip -net ns1 addr add dead:1::99/64 dev eth0.10
-
-if test_tcp_forwarding_nat ns1 ns2; then
-       echo "PASS: flow offloaded for ns1/ns2 with bridge NAT and VLAN"
-else
+ip -net $nsr1 link set veth0 nomaster
+ip -net $nsr1 link set down dev veth0
+ip -net $nsr1 link add link veth0 name veth0.10 type vlan id 10
+ip -net $nsr1 link set up dev veth0
+ip -net $nsr1 link set up dev veth0.10
+ip -net $nsr1 link set veth0.10 master br0
+
+ip -net $ns1 addr flush dev eth0
+ip -net $ns1 link add link eth0 name eth0.10 type vlan id 10
+ip -net $ns1 link set eth0 up
+ip -net $ns1 link set eth0.10 up
+ip -net $ns1 addr add 10.0.1.99/24 dev eth0.10
+ip -net $ns1 route add default via 10.0.1.1
+ip -net $ns1 addr add dead:1::99/64 dev eth0.10
+
+if ! test_tcp_forwarding_nat $ns1 $ns2 1 "bridge and VLAN"; then
        echo "FAIL: flow offload for ns1/ns2 with bridge NAT and VLAN" 1>&2
-       ip netns exec nsr1 nft list ruleset
+       ip netns exec $nsr1 nft list ruleset
        ret=1
 fi
 
 # restore test topology (remove bridge and VLAN)
-ip -net nsr1 link set veth0 nomaster
-ip -net nsr1 link set veth0 down
-ip -net nsr1 link set veth0.10 down
-ip -net nsr1 link delete veth0.10 type vlan
-ip -net nsr1 link delete br0 type bridge
-ip -net ns1 addr flush dev eth0.10
-ip -net ns1 link set eth0.10 down
-ip -net ns1 link set eth0 down
-ip -net ns1 link delete eth0.10 type vlan
+ip -net $nsr1 link set veth0 nomaster
+ip -net $nsr1 link set veth0 down
+ip -net $nsr1 link set veth0.10 down
+ip -net $nsr1 link delete veth0.10 type vlan
+ip -net $nsr1 link delete br0 type bridge
+ip -net $ns1 addr flush dev eth0.10
+ip -net $ns1 link set eth0.10 down
+ip -net $ns1 link set eth0 down
+ip -net $ns1 link delete eth0.10 type vlan
 
 # restore address in ns1 and nsr1
-ip -net ns1 link set eth0 up
-ip -net ns1 addr add 10.0.1.99/24 dev eth0
-ip -net ns1 route add default via 10.0.1.1
-ip -net ns1 addr add dead:1::99/64 dev eth0
-ip -net ns1 route add default via dead:1::1
-ip -net nsr1 addr add 10.0.1.1/24 dev veth0
-ip -net nsr1 addr add dead:1::1/64 dev veth0
-ip -net nsr1 link set up dev veth0
+ip -net $ns1 link set eth0 up
+ip -net $ns1 addr add 10.0.1.99/24 dev eth0
+ip -net $ns1 route add default via 10.0.1.1
+ip -net $ns1 addr add dead:1::99/64 dev eth0
+ip -net $ns1 route add default via dead:1::1
+ip -net $nsr1 addr add 10.0.1.1/24 dev veth0
+ip -net $nsr1 addr add dead:1::1/64 dev veth0
+ip -net $nsr1 link set up dev veth0
 
 KEY_SHA="0x"$(ps -xaf | sha1sum | cut -d " " -f 1)
 KEY_AES="0x"$(ps -xaf | md5sum | cut -d " " -f 1)
@@ -480,23 +517,23 @@ do_esp() {
 
 }
 
-do_esp nsr1 192.168.10.1 192.168.10.2 10.0.1.0/24 10.0.2.0/24 $SPI1 $SPI2
+do_esp $nsr1 192.168.10.1 192.168.10.2 10.0.1.0/24 10.0.2.0/24 $SPI1 $SPI2
 
-do_esp nsr2 192.168.10.2 192.168.10.1 10.0.2.0/24 10.0.1.0/24 $SPI2 $SPI1
+do_esp $nsr2 192.168.10.2 192.168.10.1 10.0.2.0/24 10.0.1.0/24 $SPI2 $SPI1
 
-ip netns exec nsr1 nft delete table ip nat
+ip netns exec $nsr1 nft delete table ip nat
 
 # restore default routes
-ip -net ns2 route del 192.168.10.1 via 10.0.2.1
-ip -net ns2 route add default via 10.0.2.1
-ip -net ns2 route add default via dead:2::1
+ip -net $ns2 route del 192.168.10.1 via 10.0.2.1
+ip -net $ns2 route add default via 10.0.2.1
+ip -net $ns2 route add default via dead:2::1
 
-if test_tcp_forwarding ns1 ns2; then
-       echo "PASS: ipsec tunnel mode for ns1/ns2"
+if test_tcp_forwarding $ns1 $ns2; then
+       check_counters "ipsec tunnel mode for ns1/ns2"
 else
        echo "FAIL: ipsec tunnel mode for ns1/ns2"
-       ip netns exec nsr1 nft list ruleset 1>&2
-       ip netns exec nsr1 cat /proc/net/xfrm_stat 1>&2
+       ip netns exec $nsr1 nft list ruleset 1>&2
+       ip netns exec $nsr1 cat /proc/net/xfrm_stat 1>&2
 fi
 
 exit $ret
diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/.gitignore b/tools/testing/selftests/powerpc/pmu/event_code_tests/.gitignore
new file mode 100644 (file)
index 0000000..5710683
--- /dev/null
@@ -0,0 +1,20 @@
+blacklisted_events_test
+event_alternatives_tests_p10
+event_alternatives_tests_p9
+generic_events_valid_test
+group_constraint_cache_test
+group_constraint_l2l3_sel_test
+group_constraint_mmcra_sample_test
+group_constraint_pmc56_test
+group_constraint_pmc_count_test
+group_constraint_radix_scope_qual_test
+group_constraint_repeat_test
+group_constraint_thresh_cmp_test
+group_constraint_thresh_ctl_test
+group_constraint_thresh_sel_test
+group_constraint_unit_test
+group_pmc56_exclude_constraints_test
+hw_cache_event_type_test
+invalid_event_code_test
+reserved_bits_mmcra_sample_elig_mode_test
+reserved_bits_mmcra_thresh_ctl_test
index 0fce5a6..f93b4c7 100644 (file)
@@ -1,11 +1,21 @@
-mmcr0_exceptionbits_test
+bhrb_filter_map_test
+bhrb_no_crash_wo_pmu_test
+intr_regs_no_crash_wo_pmu_test
 mmcr0_cc56run_test
-mmcr0_pmccext_test
-mmcr0_pmcjce_test
+mmcr0_exceptionbits_test
 mmcr0_fc56_pmc1ce_test
 mmcr0_fc56_pmc56_test
+mmcr0_pmccext_test
+mmcr0_pmcjce_test
 mmcr1_comb_test
-mmcr2_l2l3_test
+mmcr1_sel_unit_cache_test
 mmcr2_fcs_fch_test
+mmcr2_l2l3_test
 mmcr3_src_test
+mmcra_bhrb_any_test
+mmcra_bhrb_cond_test
+mmcra_bhrb_disable_no_branch_test
+mmcra_bhrb_disable_test
+mmcra_bhrb_ind_call_test
+mmcra_thresh_cmp_test
 mmcra_thresh_marked_sample_test
index 1bea2d1..22e28b7 100644 (file)
@@ -30,8 +30,8 @@ WOPTS :=      -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_A
 
 TRACEFS_HEADERS        := $$($(PKG_CONFIG) --cflags libtracefs)
 
-CFLAGS :=      -O -g -DVERSION=\"$(VERSION)\" $(FOPTS) $(MOPTS) $(WOPTS) $(TRACEFS_HEADERS)
-LDFLAGS        :=      -ggdb
+CFLAGS :=      -O -g -DVERSION=\"$(VERSION)\" $(FOPTS) $(MOPTS) $(WOPTS) $(TRACEFS_HEADERS) $(EXTRA_CFLAGS)
+LDFLAGS        :=      -ggdb $(EXTRA_LDFLAGS)
 LIBS   :=      $$($(PKG_CONFIG) --libs libtracefs)
 
 SRC    :=      $(wildcard src/*.c)
@@ -61,40 +61,50 @@ endif
 LIBTRACEEVENT_MIN_VERSION = 1.5
 LIBTRACEFS_MIN_VERSION = 1.3
 
+.PHONY:        all warnings show_warnings
+all:   warnings rtla
+
 TEST_LIBTRACEEVENT = $(shell sh -c "$(PKG_CONFIG) --atleast-version $(LIBTRACEEVENT_MIN_VERSION) libtraceevent > /dev/null 2>&1 || echo n")
 ifeq ("$(TEST_LIBTRACEEVENT)", "n")
-.PHONY: warning_traceevent
-warning_traceevent:
-       @echo "********************************************"
-       @echo "** NOTICE: libtraceevent version $(LIBTRACEEVENT_MIN_VERSION) or higher not found"
-       @echo "**"
-       @echo "** Consider installing the latest libtraceevent from your"
-       @echo "** distribution, e.g., 'dnf install libtraceevent' on Fedora,"
-       @echo "** or from source:"
-       @echo "**"
-       @echo "**  https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ "
-       @echo "**"
-       @echo "********************************************"
+WARNINGS = show_warnings
+MISSING_LIBS += echo "**   libtraceevent version $(LIBTRACEEVENT_MIN_VERSION) or higher";
+MISSING_PACKAGES += "libtraceevent-devel"
+MISSING_SOURCE += echo "**  https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ ";
 endif
 
 TEST_LIBTRACEFS = $(shell sh -c "$(PKG_CONFIG) --atleast-version $(LIBTRACEFS_MIN_VERSION) libtracefs > /dev/null 2>&1 || echo n")
 ifeq ("$(TEST_LIBTRACEFS)", "n")
-.PHONY: warning_tracefs
-warning_tracefs:
-       @echo "********************************************"
-       @echo "** NOTICE: libtracefs version $(LIBTRACEFS_MIN_VERSION) or higher not found"
-       @echo "**"
-       @echo "** Consider installing the latest libtracefs from your"
-       @echo "** distribution, e.g., 'dnf install libtracefs' on Fedora,"
-       @echo "** or from source:"
-       @echo "**"
-       @echo "**  https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ "
-       @echo "**"
-       @echo "********************************************"
+WARNINGS = show_warnings
+MISSING_LIBS += echo "**   libtracefs version $(LIBTRACEFS_MIN_VERSION) or higher";
+MISSING_PACKAGES += "libtracefs-devel"
+MISSING_SOURCE += echo "**  https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ ";
 endif
 
-.PHONY:        all
-all:   rtla
+define show_dependencies
+       @echo "********************************************";                           \
+       echo "** NOTICE: Failed build dependencies";                                    \
+       echo "**";                                                                      \
+       echo "** Required Libraries:";                                                  \
+       $(MISSING_LIBS)                                                                 \
+       echo "**";                                                                      \
+       echo "** Consider installing the latest libtracefs from your";                  \
+       echo "** distribution, e.g., 'dnf install $(MISSING_PACKAGES)' on Fedora,";     \
+       echo "** or from source:";                                                      \
+       echo "**";                                                                      \
+       $(MISSING_SOURCE)                                                               \
+       echo "**";                                                                      \
+       echo "********************************************"
+endef
+
+show_warnings:
+       $(call show_dependencies);
+
+ifneq ("$(WARNINGS)", "")
+ERROR_OUT = $(error Please add the necessary dependencies)
+
+warnings: $(WARNINGS)
+       $(ERROR_OUT)
+endif
 
 rtla: $(OBJ)
        $(CC) -o rtla $(LDFLAGS) $(OBJ) $(LIBS)
@@ -108,9 +118,9 @@ install: doc_install
        $(INSTALL) rtla -m 755 $(DESTDIR)$(BINDIR)
        $(STRIP) $(DESTDIR)$(BINDIR)/rtla
        @test ! -f $(DESTDIR)$(BINDIR)/osnoise || rm $(DESTDIR)$(BINDIR)/osnoise
-       ln -s $(DESTDIR)$(BINDIR)/rtla $(DESTDIR)$(BINDIR)/osnoise
+       ln -s rtla $(DESTDIR)$(BINDIR)/osnoise
        @test ! -f $(DESTDIR)$(BINDIR)/timerlat || rm $(DESTDIR)$(BINDIR)/timerlat
-       ln -s $(DESTDIR)$(BINDIR)/rtla $(DESTDIR)$(BINDIR)/timerlat
+       ln -s rtla $(DESTDIR)$(BINDIR)/timerlat
 
 .PHONY: clean tarball
 clean: doc_clean
index f3ec628..4b48af8 100644 (file)
@@ -892,7 +892,7 @@ int timerlat_hist_main(int argc, char *argv[])
        return_value = 0;
 
        if (trace_is_off(&tool->trace, &record->trace)) {
-               printf("rtla timelat hit stop tracing\n");
+               printf("rtla timerlat hit stop tracing\n");
                if (params->trace_output) {
                        printf("  Saving trace to %s\n", params->trace_output);
                        save_trace_to_file(record->trace.inst, params->trace_output);
index 35452a1..3342719 100644 (file)
@@ -687,7 +687,7 @@ int timerlat_top_main(int argc, char *argv[])
        return_value = 0;
 
        if (trace_is_off(&top->trace, &record->trace)) {
-               printf("rtla timelat hit stop tracing\n");
+               printf("rtla timerlat hit stop tracing\n");
                if (params->trace_output) {
                        printf("  Saving trace to %s\n", params->trace_output);
                        save_trace_to_file(record->trace.inst, params->trace_output);
index 515dfe9..584a5ba 100644 (file)
@@ -702,30 +702,31 @@ static void kvm_mmu_notifier_change_pte(struct mmu_notifier *mn,
 
        /*
         * .change_pte() must be surrounded by .invalidate_range_{start,end}().
-        * If mmu_notifier_count is zero, then no in-progress invalidations,
-        * including this one, found a relevant memslot at start(); rechecking
-        * memslots here is unnecessary.  Note, a false positive (count elevated
-        * by a different invalidation) is sub-optimal but functionally ok.
+        * If mmu_invalidate_in_progress is zero, then no in-progress
+        * invalidations, including this one, found a relevant memslot at
+        * start(); rechecking memslots here is unnecessary.  Note, a false
+        * positive (count elevated by a different invalidation) is sub-optimal
+        * but functionally ok.
         */
        WARN_ON_ONCE(!READ_ONCE(kvm->mn_active_invalidate_count));
-       if (!READ_ONCE(kvm->mmu_notifier_count))
+       if (!READ_ONCE(kvm->mmu_invalidate_in_progress))
                return;
 
        kvm_handle_hva_range(mn, address, address + 1, pte, kvm_set_spte_gfn);
 }
 
-void kvm_inc_notifier_count(struct kvm *kvm, unsigned long start,
-                                  unsigned long end)
+void kvm_mmu_invalidate_begin(struct kvm *kvm, unsigned long start,
+                             unsigned long end)
 {
        /*
         * The count increase must become visible at unlock time as no
         * spte can be established without taking the mmu_lock and
         * count is also read inside the mmu_lock critical section.
         */
-       kvm->mmu_notifier_count++;
-       if (likely(kvm->mmu_notifier_count == 1)) {
-               kvm->mmu_notifier_range_start = start;
-               kvm->mmu_notifier_range_end = end;
+       kvm->mmu_invalidate_in_progress++;
+       if (likely(kvm->mmu_invalidate_in_progress == 1)) {
+               kvm->mmu_invalidate_range_start = start;
+               kvm->mmu_invalidate_range_end = end;
        } else {
                /*
                 * Fully tracking multiple concurrent ranges has diminishing
@@ -736,10 +737,10 @@ void kvm_inc_notifier_count(struct kvm *kvm, unsigned long start,
                 * accumulate and persist until all outstanding invalidates
                 * complete.
                 */
-               kvm->mmu_notifier_range_start =
-                       min(kvm->mmu_notifier_range_start, start);
-               kvm->mmu_notifier_range_end =
-                       max(kvm->mmu_notifier_range_end, end);
+               kvm->mmu_invalidate_range_start =
+                       min(kvm->mmu_invalidate_range_start, start);
+               kvm->mmu_invalidate_range_end =
+                       max(kvm->mmu_invalidate_range_end, end);
        }
 }
 
@@ -752,7 +753,7 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
                .end            = range->end,
                .pte            = __pte(0),
                .handler        = kvm_unmap_gfn_range,
-               .on_lock        = kvm_inc_notifier_count,
+               .on_lock        = kvm_mmu_invalidate_begin,
                .on_unlock      = kvm_arch_guest_memory_reclaimed,
                .flush_on_ret   = true,
                .may_block      = mmu_notifier_range_blockable(range),
@@ -763,7 +764,7 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
        /*
         * Prevent memslot modification between range_start() and range_end()
         * so that conditionally locking provides the same result in both
-        * functions.  Without that guarantee, the mmu_notifier_count
+        * functions.  Without that guarantee, the mmu_invalidate_in_progress
         * adjustments will be imbalanced.
         *
         * Pairs with the decrement in range_end().
@@ -779,7 +780,8 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
         * any given time, and the caches themselves can check for hva overlap,
         * i.e. don't need to rely on memslot overlap checks for performance.
         * Because this runs without holding mmu_lock, the pfn caches must use
-        * mn_active_invalidate_count (see above) instead of mmu_notifier_count.
+        * mn_active_invalidate_count (see above) instead of
+        * mmu_invalidate_in_progress.
         */
        gfn_to_pfn_cache_invalidate_start(kvm, range->start, range->end,
                                          hva_range.may_block);
@@ -789,22 +791,22 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
        return 0;
 }
 
-void kvm_dec_notifier_count(struct kvm *kvm, unsigned long start,
-                                  unsigned long end)
+void kvm_mmu_invalidate_end(struct kvm *kvm, unsigned long start,
+                           unsigned long end)
 {
        /*
         * This sequence increase will notify the kvm page fault that
         * the page that is going to be mapped in the spte could have
         * been freed.
         */
-       kvm->mmu_notifier_seq++;
+       kvm->mmu_invalidate_seq++;
        smp_wmb();
        /*
         * The above sequence increase must be visible before the
         * below count decrease, which is ensured by the smp_wmb above
-        * in conjunction with the smp_rmb in mmu_notifier_retry().
+        * in conjunction with the smp_rmb in mmu_invalidate_retry().
         */
-       kvm->mmu_notifier_count--;
+       kvm->mmu_invalidate_in_progress--;
 }
 
 static void kvm_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
@@ -816,7 +818,7 @@ static void kvm_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
                .end            = range->end,
                .pte            = __pte(0),
                .handler        = (void *)kvm_null_fn,
-               .on_lock        = kvm_dec_notifier_count,
+               .on_lock        = kvm_mmu_invalidate_end,
                .on_unlock      = (void *)kvm_null_fn,
                .flush_on_ret   = false,
                .may_block      = mmu_notifier_range_blockable(range),
@@ -837,7 +839,7 @@ static void kvm_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
        if (wake)
                rcuwait_wake_up(&kvm->mn_memslots_update_rcuwait);
 
-       BUG_ON(kvm->mmu_notifier_count < 0);
+       BUG_ON(kvm->mmu_invalidate_in_progress < 0);
 }
 
 static int kvm_mmu_notifier_clear_flush_young(struct mmu_notifier *mn,
@@ -1134,6 +1136,9 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
        if (!kvm)
                return ERR_PTR(-ENOMEM);
 
+       /* KVM is pinned via open("/dev/kvm"), the fd passed to this ioctl(). */
+       __module_get(kvm_chardev_ops.owner);
+
        KVM_MMU_LOCK_INIT(kvm);
        mmgrab(current->mm);
        kvm->mm = current->mm;
@@ -1211,9 +1216,17 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
        if (r)
                goto out_err_no_mmu_notifier;
 
+       r = kvm_coalesced_mmio_init(kvm);
+       if (r < 0)
+               goto out_no_coalesced_mmio;
+
+       r = kvm_create_vm_debugfs(kvm, fdname);
+       if (r)
+               goto out_err_no_debugfs;
+
        r = kvm_arch_post_init_vm(kvm);
        if (r)
-               goto out_err_mmu_notifier;
+               goto out_err;
 
        mutex_lock(&kvm_lock);
        list_add(&kvm->vm_list, &vm_list);
@@ -1222,25 +1235,13 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
        preempt_notifier_inc();
        kvm_init_pm_notifier(kvm);
 
-       /*
-        * When the fd passed to this ioctl() is opened it pins the module,
-        * but try_module_get() also prevents getting a reference if the module
-        * is in MODULE_STATE_GOING (e.g. if someone ran "rmmod --wait").
-        */
-       if (!try_module_get(kvm_chardev_ops.owner)) {
-               r = -ENODEV;
-               goto out_err_mmu_notifier;
-       }
-
-       r = kvm_create_vm_debugfs(kvm, fdname);
-       if (r)
-               goto out_err;
-
        return kvm;
 
 out_err:
-       module_put(kvm_chardev_ops.owner);
-out_err_mmu_notifier:
+       kvm_destroy_vm_debugfs(kvm);
+out_err_no_debugfs:
+       kvm_coalesced_mmio_free(kvm);
+out_no_coalesced_mmio:
 #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
        if (kvm->mmu_notifier.ops)
                mmu_notifier_unregister(&kvm->mmu_notifier, current->mm);
@@ -1259,6 +1260,7 @@ out_err_no_irq_srcu:
 out_err_no_srcu:
        kvm_arch_free_vm(kvm);
        mmdrop(current->mm);
+       module_put(kvm_chardev_ops.owner);
        return ERR_PTR(r);
 }
 
@@ -2516,7 +2518,7 @@ static int hva_to_pfn_slow(unsigned long addr, bool *async, bool write_fault,
 {
        unsigned int flags = FOLL_HWPOISON;
        struct page *page;
-       int npages = 0;
+       int npages;
 
        might_sleep();
 
@@ -4378,7 +4380,7 @@ void kvm_unregister_device_ops(u32 type)
 static int kvm_ioctl_create_device(struct kvm *kvm,
                                   struct kvm_create_device *cd)
 {
-       const struct kvm_device_ops *ops = NULL;
+       const struct kvm_device_ops *ops;
        struct kvm_device *dev;
        bool test = cd->flags & KVM_CREATE_DEVICE_TEST;
        int type;
@@ -4913,11 +4915,6 @@ static int kvm_dev_ioctl_create_vm(unsigned long type)
                goto put_fd;
        }
 
-#ifdef CONFIG_KVM_MMIO
-       r = kvm_coalesced_mmio_init(kvm);
-       if (r < 0)
-               goto put_kvm;
-#endif
        file = anon_inode_getfile("kvm-vm", &kvm_vm_fops, kvm, O_RDWR);
        if (IS_ERR(file)) {
                r = PTR_ERR(file);
index ab519f7..68ff41d 100644 (file)
@@ -112,27 +112,28 @@ static inline bool mmu_notifier_retry_cache(struct kvm *kvm, unsigned long mmu_s
 {
        /*
         * mn_active_invalidate_count acts for all intents and purposes
-        * like mmu_notifier_count here; but the latter cannot be used
-        * here because the invalidation of caches in the mmu_notifier
-        * event occurs _before_ mmu_notifier_count is elevated.
+        * like mmu_invalidate_in_progress here; but the latter cannot
+        * be used here because the invalidation of caches in the
+        * mmu_notifier event occurs _before_ mmu_invalidate_in_progress
+        * is elevated.
         *
         * Note, it does not matter that mn_active_invalidate_count
         * is not protected by gpc->lock.  It is guaranteed to
         * be elevated before the mmu_notifier acquires gpc->lock, and
-        * isn't dropped until after mmu_notifier_seq is updated.
+        * isn't dropped until after mmu_invalidate_seq is updated.
         */
        if (kvm->mn_active_invalidate_count)
                return true;
 
        /*
         * Ensure mn_active_invalidate_count is read before
-        * mmu_notifier_seq.  This pairs with the smp_wmb() in
+        * mmu_invalidate_seq.  This pairs with the smp_wmb() in
         * mmu_notifier_invalidate_range_end() to guarantee either the
         * old (non-zero) value of mn_active_invalidate_count or the
-        * new (incremented) value of mmu_notifier_seq is observed.
+        * new (incremented) value of mmu_invalidate_seq is observed.
         */
        smp_rmb();
-       return kvm->mmu_notifier_seq != mmu_seq;
+       return kvm->mmu_invalidate_seq != mmu_seq;
 }
 
 static kvm_pfn_t hva_to_pfn_retry(struct kvm *kvm, struct gfn_to_pfn_cache *gpc)
@@ -155,7 +156,7 @@ static kvm_pfn_t hva_to_pfn_retry(struct kvm *kvm, struct gfn_to_pfn_cache *gpc)
        gpc->valid = false;
 
        do {
-               mmu_seq = kvm->mmu_notifier_seq;
+               mmu_seq = kvm->mmu_invalidate_seq;
                smp_rmb();
 
                write_unlock_irq(&gpc->lock);