diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml index 325c6fd3566d..b48ea1e4913a 100644 --- a/Documentation/devicetree/bindings/arm/amlogic.yaml +++ b/Documentation/devicetree/bindings/arm/amlogic.yaml @@ -91,13 +91,11 @@ properties: - description: Boards with the Amlogic Meson GXL S905X SoC items: - enum: - - amediatech,x96-max - amlogic,p212 - hwacom,amazetv - khadas,vim - libretech,cc - nexbox,a95x - - seirobotics,sei510 - const: amlogic,s905x - const: amlogic,meson-gxl @@ -129,16 +127,32 @@ properties: - const: amlogic,a113d - const: amlogic,meson-axg - - description: Boards with the Amlogic Meson G12A S905D2 SoC + - description: Boards with the Amlogic Meson G12A S905D2/X2/Y2 SoC items: - enum: + - amediatech,x96-max - amlogic,u200 + - seirobotics,sei510 - const: amlogic,g12a + - description: Boards with the Amlogic Meson G12B A311D SoC + items: + - enum: + - khadas,vim3 + - const: amlogic,a311d + - const: amlogic,g12b + - description: Boards with the Amlogic Meson G12B S922X SoC items: - enum: - hardkernel,odroid-n2 + - khadas,vim3 + - const: amlogic,s922x - const: amlogic,g12b + - description: Boards with the Amlogic Meson SM1 S905X3 SoC + items: + - enum: + - seirobotics,sei610 + - const: amlogic,sm1 ... diff --git a/Documentation/devicetree/bindings/media/amlogic,vdec.txt b/Documentation/devicetree/bindings/media/amlogic,vdec.txt index aabdd01bcf32..9b6aace86ca7 100644 --- a/Documentation/devicetree/bindings/media/amlogic,vdec.txt +++ b/Documentation/devicetree/bindings/media/amlogic,vdec.txt @@ -26,6 +26,7 @@ Required properties: - GXBB (S905) : "amlogic,gxbb-vdec" - GXL (S905X, S905D) : "amlogic,gxl-vdec" - GXM (S912) : "amlogic,gxm-vdec" + followed by the common "amlogic,gx-vdec" - reg: base address and size of he following memory-mapped regions : - dos - esparser @@ -47,8 +48,8 @@ Required properties: Example: -vdec: video-decoder@c8820000 { - compatible = "amlogic,gxbb-vdec"; +vdec: video-codec@c8820000 { + compatible = "amlogic,gxbb-vdec", "amlogic,gx-vdec"; reg = <0x0 0xc8820000 0x0 0x10000>, <0x0 0xc110a580 0x0 0xe4>; reg-names = "dos", "esparser"; diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile index 07b861fe5fa5..edbf128e7707 100644 --- a/arch/arm64/boot/dts/amlogic/Makefile +++ b/arch/arm64/boot/dts/amlogic/Makefile @@ -3,6 +3,8 @@ dtb-$(CONFIG_ARCH_MESON) += meson-axg-s400.dtb dtb-$(CONFIG_ARCH_MESON) += meson-g12a-sei510.dtb dtb-$(CONFIG_ARCH_MESON) += meson-g12a-u200.dtb dtb-$(CONFIG_ARCH_MESON) += meson-g12a-x96-max.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a311d-khadas-vim3.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-g12b-s922x-khadas-vim3.dtb dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nanopi-k2.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nexbox-a95x.dtb @@ -32,3 +34,4 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q200.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q201.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi index 6219337033a0..12bf959c17a7 100644 --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi @@ -182,6 +182,8 @@ <&clkc CLKID_FCLK_DIV2>, <&clkc CLKID_MPLL2>; clock-names = "stmmaceth", "clkin0", "clkin1"; + rx-fifo-depth = <4096>; + tx-fifo-depth = <2048>; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi new file mode 100644 index 000000000000..cd3d23d2c6a2 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi @@ -0,0 +1,2420 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Amlogic, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/ { + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + tdmif_a: audio-controller-0 { + compatible = "amlogic,axg-tdm-iface"; + #sound-dai-cells = <0>; + sound-name-prefix = "TDM_A"; + clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>, + <&clkc_audio AUD_CLKID_MST_A_SCLK>, + <&clkc_audio AUD_CLKID_MST_A_LRCLK>; + clock-names = "mclk", "sclk", "lrclk"; + status = "disabled"; + }; + + tdmif_b: audio-controller-1 { + compatible = "amlogic,axg-tdm-iface"; + #sound-dai-cells = <0>; + sound-name-prefix = "TDM_B"; + clocks = <&clkc_audio AUD_CLKID_MST_B_MCLK>, + <&clkc_audio AUD_CLKID_MST_B_SCLK>, + <&clkc_audio AUD_CLKID_MST_B_LRCLK>; + clock-names = "mclk", "sclk", "lrclk"; + status = "disabled"; + }; + + tdmif_c: audio-controller-2 { + compatible = "amlogic,axg-tdm-iface"; + #sound-dai-cells = <0>; + sound-name-prefix = "TDM_C"; + clocks = <&clkc_audio AUD_CLKID_MST_C_MCLK>, + <&clkc_audio AUD_CLKID_MST_C_SCLK>, + <&clkc_audio AUD_CLKID_MST_C_LRCLK>; + clock-names = "mclk", "sclk", "lrclk"; + status = "disabled"; + }; + + efuse: efuse { + compatible = "amlogic,meson-gxbb-efuse"; + clocks = <&clkc CLKID_EFUSE>; + #address-cells = <1>; + #size-cells = <1>; + read-only; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* 3 MiB reserved for ARM Trusted Firmware (BL31) */ + secmon_reserved: secmon@5000000 { + reg = <0x0 0x05000000 0x0 0x300000>; + no-map; + }; + + linux,cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x0 0x10000000>; + alignment = <0x0 0x400000>; + linux,cma-default; + }; + }; + + sm: secure-monitor { + compatible = "amlogic,meson-gxbb-sm"; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + ethmac: ethernet@ff3f0000 { + compatible = "amlogic,meson-axg-dwmac", + "snps,dwmac-3.70a", + "snps,dwmac"; + reg = <0x0 0xff3f0000 0x0 0x10000 + 0x0 0xff634540 0x0 0x8>; + interrupts = ; + interrupt-names = "macirq"; + clocks = <&clkc CLKID_ETH>, + <&clkc CLKID_FCLK_DIV2>, + <&clkc CLKID_MPLL2>; + clock-names = "stmmaceth", "clkin0", "clkin1"; + rx-fifo-depth = <4096>; + tx-fifo-depth = <2048>; + status = "disabled"; + + mdio0: mdio { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + }; + }; + + apb: bus@ff600000 { + compatible = "simple-bus"; + reg = <0x0 0xff600000 0x0 0x200000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xff600000 0x0 0x200000>; + + hdmi_tx: hdmi-tx@0 { + compatible = "amlogic,meson-g12a-dw-hdmi"; + reg = <0x0 0x0 0x0 0x10000>; + interrupts = ; + resets = <&reset RESET_HDMITX_CAPB3>, + <&reset RESET_HDMITX_PHY>, + <&reset RESET_HDMITX>; + reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; + clocks = <&clkc CLKID_HDMI>, + <&clkc CLKID_HTX_PCLK>, + <&clkc CLKID_VPU_INTR>; + clock-names = "isfr", "iahb", "venci"; + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <0>; + status = "disabled"; + + /* VPU VENC Input */ + hdmi_tx_venc_port: port@0 { + reg = <0>; + + hdmi_tx_in: endpoint { + remote-endpoint = <&hdmi_tx_out>; + }; + }; + + /* TMDS Output */ + hdmi_tx_tmds_port: port@1 { + reg = <1>; + }; + }; + + apb_efuse: bus@30000 { + compatible = "simple-bus"; + reg = <0x0 0x30000 0x0 0x2000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0x30000 0x0 0x2000>; + + hwrng: rng@218 { + compatible = "amlogic,meson-rng"; + reg = <0x0 0x218 0x0 0x4>; + }; + }; + + periphs: bus@34400 { + compatible = "simple-bus"; + reg = <0x0 0x34400 0x0 0x400>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0x34400 0x0 0x400>; + + periphs_pinctrl: pinctrl@40 { + compatible = "amlogic,meson-g12a-periphs-pinctrl"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gpio: bank@40 { + reg = <0x0 0x40 0x0 0x4c>, + <0x0 0xe8 0x0 0x18>, + <0x0 0x120 0x0 0x18>, + <0x0 0x2c0 0x0 0x40>, + <0x0 0x340 0x0 0x1c>; + reg-names = "gpio", + "pull", + "pull-enable", + "mux", + "ds"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&periphs_pinctrl 0 0 86>; + }; + + cec_ao_a_h_pins: cec_ao_a_h { + mux { + groups = "cec_ao_a_h"; + function = "cec_ao_a_h"; + bias-disable; + }; + }; + + cec_ao_b_h_pins: cec_ao_b_h { + mux { + groups = "cec_ao_b_h"; + function = "cec_ao_b_h"; + bias-disable; + }; + }; + + emmc_pins: emmc { + mux-0 { + groups = "emmc_nand_d0", + "emmc_nand_d1", + "emmc_nand_d2", + "emmc_nand_d3", + "emmc_nand_d4", + "emmc_nand_d5", + "emmc_nand_d6", + "emmc_nand_d7", + "emmc_cmd"; + function = "emmc"; + bias-pull-up; + drive-strength-microamp = <4000>; + }; + + mux-1 { + groups = "emmc_clk"; + function = "emmc"; + bias-disable; + drive-strength-microamp = <4000>; + }; + }; + + emmc_ds_pins: emmc-ds { + mux { + groups = "emmc_nand_ds"; + function = "emmc"; + bias-pull-down; + drive-strength-microamp = <4000>; + }; + }; + + emmc_clk_gate_pins: emmc_clk_gate { + mux { + groups = "BOOT_8"; + function = "gpio_periphs"; + bias-pull-down; + drive-strength-microamp = <4000>; + }; + }; + + hdmitx_ddc_pins: hdmitx_ddc { + mux { + groups = "hdmitx_sda", + "hdmitx_sck"; + function = "hdmitx"; + bias-disable; + drive-strength-microamp = <4000>; + }; + }; + + hdmitx_hpd_pins: hdmitx_hpd { + mux { + groups = "hdmitx_hpd_in"; + function = "hdmitx"; + bias-disable; + }; + }; + + + i2c0_sda_c_pins: i2c0-sda-c { + mux { + groups = "i2c0_sda_c"; + function = "i2c0"; + bias-disable; + drive-strength-microamp = <3000>; + + }; + }; + + i2c0_sck_c_pins: i2c0-sck-c { + mux { + groups = "i2c0_sck_c"; + function = "i2c0"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c0_sda_z0_pins: i2c0-sda-z0 { + mux { + groups = "i2c0_sda_z0"; + function = "i2c0"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c0_sck_z1_pins: i2c0-sck-z1 { + mux { + groups = "i2c0_sck_z1"; + function = "i2c0"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c0_sda_z7_pins: i2c0-sda-z7 { + mux { + groups = "i2c0_sda_z7"; + function = "i2c0"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c0_sda_z8_pins: i2c0-sda-z8 { + mux { + groups = "i2c0_sda_z8"; + function = "i2c0"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c1_sda_x_pins: i2c1-sda-x { + mux { + groups = "i2c1_sda_x"; + function = "i2c1"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c1_sck_x_pins: i2c1-sck-x { + mux { + groups = "i2c1_sck_x"; + function = "i2c1"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c1_sda_h2_pins: i2c1-sda-h2 { + mux { + groups = "i2c1_sda_h2"; + function = "i2c1"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c1_sck_h3_pins: i2c1-sck-h3 { + mux { + groups = "i2c1_sck_h3"; + function = "i2c1"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c1_sda_h6_pins: i2c1-sda-h6 { + mux { + groups = "i2c1_sda_h6"; + function = "i2c1"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c1_sck_h7_pins: i2c1-sck-h7 { + mux { + groups = "i2c1_sck_h7"; + function = "i2c1"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c2_sda_x_pins: i2c2-sda-x { + mux { + groups = "i2c2_sda_x"; + function = "i2c2"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c2_sck_x_pins: i2c2-sck-x { + mux { + groups = "i2c2_sck_x"; + function = "i2c2"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c2_sda_z_pins: i2c2-sda-z { + mux { + groups = "i2c2_sda_z"; + function = "i2c2"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c2_sck_z_pins: i2c2-sck-z { + mux { + groups = "i2c2_sck_z"; + function = "i2c2"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c3_sda_h_pins: i2c3-sda-h { + mux { + groups = "i2c3_sda_h"; + function = "i2c3"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c3_sck_h_pins: i2c3-sck-h { + mux { + groups = "i2c3_sck_h"; + function = "i2c3"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c3_sda_a_pins: i2c3-sda-a { + mux { + groups = "i2c3_sda_a"; + function = "i2c3"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c3_sck_a_pins: i2c3-sck-a { + mux { + groups = "i2c3_sck_a"; + function = "i2c3"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + mclk0_a_pins: mclk0-a { + mux { + groups = "mclk0_a"; + function = "mclk0"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + mclk1_a_pins: mclk1-a { + mux { + groups = "mclk1_a"; + function = "mclk1"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + mclk1_x_pins: mclk1-x { + mux { + groups = "mclk1_x"; + function = "mclk1"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + mclk1_z_pins: mclk1-z { + mux { + groups = "mclk1_z"; + function = "mclk1"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + pdm_din0_a_pins: pdm-din0-a { + mux { + groups = "pdm_din0_a"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din0_c_pins: pdm-din0-c { + mux { + groups = "pdm_din0_c"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din0_x_pins: pdm-din0-x { + mux { + groups = "pdm_din0_x"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din0_z_pins: pdm-din0-z { + mux { + groups = "pdm_din0_z"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din1_a_pins: pdm-din1-a { + mux { + groups = "pdm_din1_a"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din1_c_pins: pdm-din1-c { + mux { + groups = "pdm_din1_c"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din1_x_pins: pdm-din1-x { + mux { + groups = "pdm_din1_x"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din1_z_pins: pdm-din1-z { + mux { + groups = "pdm_din1_z"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din2_a_pins: pdm-din2-a { + mux { + groups = "pdm_din2_a"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din2_c_pins: pdm-din2-c { + mux { + groups = "pdm_din2_c"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din2_x_pins: pdm-din2-x { + mux { + groups = "pdm_din2_x"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din2_z_pins: pdm-din2-z { + mux { + groups = "pdm_din2_z"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din3_a_pins: pdm-din3-a { + mux { + groups = "pdm_din3_a"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din3_c_pins: pdm-din3-c { + mux { + groups = "pdm_din3_c"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din3_x_pins: pdm-din3-x { + mux { + groups = "pdm_din3_x"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_din3_z_pins: pdm-din3-z { + mux { + groups = "pdm_din3_z"; + function = "pdm"; + bias-disable; + }; + }; + + pdm_dclk_a_pins: pdm-dclk-a { + mux { + groups = "pdm_dclk_a"; + function = "pdm"; + bias-disable; + drive-strength-microamp = <500>; + }; + }; + + pdm_dclk_c_pins: pdm-dclk-c { + mux { + groups = "pdm_dclk_c"; + function = "pdm"; + bias-disable; + drive-strength-microamp = <500>; + }; + }; + + pdm_dclk_x_pins: pdm-dclk-x { + mux { + groups = "pdm_dclk_x"; + function = "pdm"; + bias-disable; + drive-strength-microamp = <500>; + }; + }; + + pdm_dclk_z_pins: pdm-dclk-z { + mux { + groups = "pdm_dclk_z"; + function = "pdm"; + bias-disable; + drive-strength-microamp = <500>; + }; + }; + + pwm_a_pins: pwm-a { + mux { + groups = "pwm_a"; + function = "pwm_a"; + bias-disable; + }; + }; + + pwm_b_x7_pins: pwm-b-x7 { + mux { + groups = "pwm_b_x7"; + function = "pwm_b"; + bias-disable; + }; + }; + + pwm_b_x19_pins: pwm-b-x19 { + mux { + groups = "pwm_b_x19"; + function = "pwm_b"; + bias-disable; + }; + }; + + pwm_c_c_pins: pwm-c-c { + mux { + groups = "pwm_c_c"; + function = "pwm_c"; + bias-disable; + }; + }; + + pwm_c_x5_pins: pwm-c-x5 { + mux { + groups = "pwm_c_x5"; + function = "pwm_c"; + bias-disable; + }; + }; + + pwm_c_x8_pins: pwm-c-x8 { + mux { + groups = "pwm_c_x8"; + function = "pwm_c"; + bias-disable; + }; + }; + + pwm_d_x3_pins: pwm-d-x3 { + mux { + groups = "pwm_d_x3"; + function = "pwm_d"; + bias-disable; + }; + }; + + pwm_d_x6_pins: pwm-d-x6 { + mux { + groups = "pwm_d_x6"; + function = "pwm_d"; + bias-disable; + }; + }; + + pwm_e_pins: pwm-e { + mux { + groups = "pwm_e"; + function = "pwm_e"; + bias-disable; + }; + }; + + pwm_f_x_pins: pwm-f-x { + mux { + groups = "pwm_f_x"; + function = "pwm_f"; + bias-disable; + }; + }; + + pwm_f_h_pins: pwm-f-h { + mux { + groups = "pwm_f_h"; + function = "pwm_f"; + bias-disable; + }; + }; + + sdcard_c_pins: sdcard_c { + mux-0 { + groups = "sdcard_d0_c", + "sdcard_d1_c", + "sdcard_d2_c", + "sdcard_d3_c", + "sdcard_cmd_c"; + function = "sdcard"; + bias-pull-up; + drive-strength-microamp = <4000>; + }; + + mux-1 { + groups = "sdcard_clk_c"; + function = "sdcard"; + bias-disable; + drive-strength-microamp = <4000>; + }; + }; + + sdcard_clk_gate_c_pins: sdcard_clk_gate_c { + mux { + groups = "GPIOC_4"; + function = "gpio_periphs"; + bias-pull-down; + drive-strength-microamp = <4000>; + }; + }; + + sdcard_z_pins: sdcard_z { + mux-0 { + groups = "sdcard_d0_z", + "sdcard_d1_z", + "sdcard_d2_z", + "sdcard_d3_z", + "sdcard_cmd_z"; + function = "sdcard"; + bias-pull-up; + drive-strength-microamp = <4000>; + }; + + mux-1 { + groups = "sdcard_clk_z"; + function = "sdcard"; + bias-disable; + drive-strength-microamp = <4000>; + }; + }; + + sdcard_clk_gate_z_pins: sdcard_clk_gate_z { + mux { + groups = "GPIOZ_6"; + function = "gpio_periphs"; + bias-pull-down; + drive-strength-microamp = <4000>; + }; + }; + + sdio_pins: sdio { + mux { + groups = "sdio_d0", + "sdio_d1", + "sdio_d2", + "sdio_d3", + "sdio_clk", + "sdio_cmd"; + function = "sdio"; + bias-disable; + drive-strength-microamp = <4000>; + }; + }; + + sdio_clk_gate_pins: sdio_clk_gate { + mux { + groups = "GPIOX_4"; + function = "gpio_periphs"; + bias-pull-down; + drive-strength-microamp = <4000>; + }; + }; + + spdif_in_a10_pins: spdif-in-a10 { + mux { + groups = "spdif_in_a10"; + function = "spdif_in"; + bias-disable; + }; + }; + + spdif_in_a12_pins: spdif-in-a12 { + mux { + groups = "spdif_in_a12"; + function = "spdif_in"; + bias-disable; + }; + }; + + spdif_in_h_pins: spdif-in-h { + mux { + groups = "spdif_in_h"; + function = "spdif_in"; + bias-disable; + }; + }; + + spdif_out_h_pins: spdif-out-h { + mux { + groups = "spdif_out_h"; + function = "spdif_out"; + drive-strength-microamp = <500>; + bias-disable; + }; + }; + + spdif_out_a11_pins: spdif-out-a11 { + mux { + groups = "spdif_out_a11"; + function = "spdif_out"; + drive-strength-microamp = <500>; + bias-disable; + }; + }; + + spdif_out_a13_pins: spdif-out-a13 { + mux { + groups = "spdif_out_a13"; + function = "spdif_out"; + drive-strength-microamp = <500>; + bias-disable; + }; + }; + + tdm_a_din0_pins: tdm-a-din0 { + mux { + groups = "tdm_a_din0"; + function = "tdm_a"; + bias-disable; + }; + }; + + + tdm_a_din1_pins: tdm-a-din1 { + mux { + groups = "tdm_a_din1"; + function = "tdm_a"; + bias-disable; + }; + }; + + tdm_a_dout0_pins: tdm-a-dout0 { + mux { + groups = "tdm_a_dout0"; + function = "tdm_a"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_a_dout1_pins: tdm-a-dout1 { + mux { + groups = "tdm_a_dout1"; + function = "tdm_a"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_a_fs_pins: tdm-a-fs { + mux { + groups = "tdm_a_fs"; + function = "tdm_a"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_a_sclk_pins: tdm-a-sclk { + mux { + groups = "tdm_a_sclk"; + function = "tdm_a"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_a_slv_fs_pins: tdm-a-slv-fs { + mux { + groups = "tdm_a_slv_fs"; + function = "tdm_a"; + bias-disable; + }; + }; + + + tdm_a_slv_sclk_pins: tdm-a-slv-sclk { + mux { + groups = "tdm_a_slv_sclk"; + function = "tdm_a"; + bias-disable; + }; + }; + + tdm_b_din0_pins: tdm-b-din0 { + mux { + groups = "tdm_b_din0"; + function = "tdm_b"; + bias-disable; + }; + }; + + tdm_b_din1_pins: tdm-b-din1 { + mux { + groups = "tdm_b_din1"; + function = "tdm_b"; + bias-disable; + }; + }; + + tdm_b_din2_pins: tdm-b-din2 { + mux { + groups = "tdm_b_din2"; + function = "tdm_b"; + bias-disable; + }; + }; + + tdm_b_din3_a_pins: tdm-b-din3-a { + mux { + groups = "tdm_b_din3_a"; + function = "tdm_b"; + bias-disable; + }; + }; + + tdm_b_din3_h_pins: tdm-b-din3-h { + mux { + groups = "tdm_b_din3_h"; + function = "tdm_b"; + bias-disable; + }; + }; + + tdm_b_dout0_pins: tdm-b-dout0 { + mux { + groups = "tdm_b_dout0"; + function = "tdm_b"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_b_dout1_pins: tdm-b-dout1 { + mux { + groups = "tdm_b_dout1"; + function = "tdm_b"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_b_dout2_pins: tdm-b-dout2 { + mux { + groups = "tdm_b_dout2"; + function = "tdm_b"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_b_dout3_a_pins: tdm-b-dout3-a { + mux { + groups = "tdm_b_dout3_a"; + function = "tdm_b"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_b_dout3_h_pins: tdm-b-dout3-h { + mux { + groups = "tdm_b_dout3_h"; + function = "tdm_b"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_b_fs_pins: tdm-b-fs { + mux { + groups = "tdm_b_fs"; + function = "tdm_b"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_b_sclk_pins: tdm-b-sclk { + mux { + groups = "tdm_b_sclk"; + function = "tdm_b"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_b_slv_fs_pins: tdm-b-slv-fs { + mux { + groups = "tdm_b_slv_fs"; + function = "tdm_b"; + bias-disable; + }; + }; + + tdm_b_slv_sclk_pins: tdm-b-slv-sclk { + mux { + groups = "tdm_b_slv_sclk"; + function = "tdm_b"; + bias-disable; + }; + }; + + tdm_c_din0_a_pins: tdm-c-din0-a { + mux { + groups = "tdm_c_din0_a"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm_c_din0_z_pins: tdm-c-din0-z { + mux { + groups = "tdm_c_din0_z"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm_c_din1_a_pins: tdm-c-din1-a { + mux { + groups = "tdm_c_din1_a"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm_c_din1_z_pins: tdm-c-din1-z { + mux { + groups = "tdm_c_din1_z"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm_c_din2_a_pins: tdm-c-din2-a { + mux { + groups = "tdm_c_din2_a"; + function = "tdm_c"; + bias-disable; + }; + }; + + eth_leds_pins: eth-leds { + mux { + groups = "eth_link_led", + "eth_act_led"; + function = "eth"; + bias-disable; + }; + }; + + eth_pins: eth { + mux { + groups = "eth_mdio", + "eth_mdc", + "eth_rgmii_rx_clk", + "eth_rx_dv", + "eth_rxd0", + "eth_rxd1", + "eth_txen", + "eth_txd0", + "eth_txd1"; + function = "eth"; + drive-strength-microamp = <4000>; + bias-disable; + }; + }; + + eth_rgmii_pins: eth-rgmii { + mux { + groups = "eth_rxd2_rgmii", + "eth_rxd3_rgmii", + "eth_rgmii_tx_clk", + "eth_txd2_rgmii", + "eth_txd3_rgmii"; + function = "eth"; + drive-strength-microamp = <4000>; + bias-disable; + }; + }; + + tdm_c_din2_z_pins: tdm-c-din2-z { + mux { + groups = "tdm_c_din2_z"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm_c_din3_a_pins: tdm-c-din3-a { + mux { + groups = "tdm_c_din3_a"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm_c_din3_z_pins: tdm-c-din3-z { + mux { + groups = "tdm_c_din3_z"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm_c_dout0_a_pins: tdm-c-dout0-a { + mux { + groups = "tdm_c_dout0_a"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_c_dout0_z_pins: tdm-c-dout0-z { + mux { + groups = "tdm_c_dout0_z"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_c_dout1_a_pins: tdm-c-dout1-a { + mux { + groups = "tdm_c_dout1_a"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_c_dout1_z_pins: tdm-c-dout1-z { + mux { + groups = "tdm_c_dout1_z"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_c_dout2_a_pins: tdm-c-dout2-a { + mux { + groups = "tdm_c_dout2_a"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_c_dout2_z_pins: tdm-c-dout2-z { + mux { + groups = "tdm_c_dout2_z"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_c_dout3_a_pins: tdm-c-dout3-a { + mux { + groups = "tdm_c_dout3_a"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_c_dout3_z_pins: tdm-c-dout3-z { + mux { + groups = "tdm_c_dout3_z"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_c_fs_a_pins: tdm-c-fs-a { + mux { + groups = "tdm_c_fs_a"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_c_fs_z_pins: tdm-c-fs-z { + mux { + groups = "tdm_c_fs_z"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_c_sclk_a_pins: tdm-c-sclk-a { + mux { + groups = "tdm_c_sclk_a"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_c_sclk_z_pins: tdm-c-sclk-z { + mux { + groups = "tdm_c_sclk_z"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_c_slv_fs_a_pins: tdm-c-slv-fs-a { + mux { + groups = "tdm_c_slv_fs_a"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm_c_slv_fs_z_pins: tdm-c-slv-fs-z { + mux { + groups = "tdm_c_slv_fs_z"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm_c_slv_sclk_a_pins: tdm-c-slv-sclk-a { + mux { + groups = "tdm_c_slv_sclk_a"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm_c_slv_sclk_z_pins: tdm-c-slv-sclk-z { + mux { + groups = "tdm_c_slv_sclk_z"; + function = "tdm_c"; + bias-disable; + }; + }; + + uart_a_pins: uart-a { + mux { + groups = "uart_a_tx", + "uart_a_rx"; + function = "uart_a"; + bias-disable; + }; + }; + + uart_a_cts_rts_pins: uart-a-cts-rts { + mux { + groups = "uart_a_cts", + "uart_a_rts"; + function = "uart_a"; + bias-disable; + }; + }; + + uart_b_pins: uart-b { + mux { + groups = "uart_b_tx", + "uart_b_rx"; + function = "uart_b"; + bias-disable; + }; + }; + + uart_c_pins: uart-c { + mux { + groups = "uart_c_tx", + "uart_c_rx"; + function = "uart_c"; + bias-disable; + }; + }; + + uart_c_cts_rts_pins: uart-c-cts-rts { + mux { + groups = "uart_c_cts", + "uart_c_rts"; + function = "uart_c"; + bias-disable; + }; + }; + }; + }; + + usb2_phy0: phy@36000 { + compatible = "amlogic,g12a-usb2-phy"; + reg = <0x0 0x36000 0x0 0x2000>; + clocks = <&xtal>; + clock-names = "xtal"; + resets = <&reset RESET_USB_PHY20>; + reset-names = "phy"; + #phy-cells = <0>; + }; + + dmc: bus@38000 { + compatible = "simple-bus"; + reg = <0x0 0x38000 0x0 0x400>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0x38000 0x0 0x400>; + + canvas: video-lut@48 { + compatible = "amlogic,canvas"; + reg = <0x0 0x48 0x0 0x14>; + }; + }; + + usb2_phy1: phy@3a000 { + compatible = "amlogic,g12a-usb2-phy"; + reg = <0x0 0x3a000 0x0 0x2000>; + clocks = <&xtal>; + clock-names = "xtal"; + resets = <&reset RESET_USB_PHY21>; + reset-names = "phy"; + #phy-cells = <0>; + }; + + hiu: bus@3c000 { + compatible = "simple-bus"; + reg = <0x0 0x3c000 0x0 0x1400>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0x3c000 0x0 0x1400>; + + hhi: system-controller@0 { + compatible = "amlogic,meson-gx-hhi-sysctrl", + "simple-mfd", "syscon"; + reg = <0 0 0 0x400>; + + clkc: clock-controller { + compatible = "amlogic,g12a-clkc"; + #clock-cells = <1>; + clocks = <&xtal>; + clock-names = "xtal"; + }; + }; + }; + + pdm: audio-controller@40000 { + compatible = "amlogic,g12a-pdm", + "amlogic,axg-pdm"; + reg = <0x0 0x40000 0x0 0x34>; + #sound-dai-cells = <0>; + sound-name-prefix = "PDM"; + clocks = <&clkc_audio AUD_CLKID_PDM>, + <&clkc_audio AUD_CLKID_PDM_DCLK>, + <&clkc_audio AUD_CLKID_PDM_SYSCLK>; + clock-names = "pclk", "dclk", "sysclk"; + status = "disabled"; + }; + + audio: bus@42000 { + compatible = "simple-bus"; + reg = <0x0 0x42000 0x0 0x2000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0x42000 0x0 0x2000>; + + clkc_audio: clock-controller@0 { + status = "disabled"; + compatible = "amlogic,g12a-audio-clkc"; + reg = <0x0 0x0 0x0 0xb4>; + #clock-cells = <1>; + + clocks = <&clkc CLKID_AUDIO>, + <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>, + <&clkc CLKID_MPLL2>, + <&clkc CLKID_MPLL3>, + <&clkc CLKID_HIFI_PLL>, + <&clkc CLKID_FCLK_DIV3>, + <&clkc CLKID_FCLK_DIV4>, + <&clkc CLKID_GP0_PLL>; + clock-names = "pclk", + "mst_in0", + "mst_in1", + "mst_in2", + "mst_in3", + "mst_in4", + "mst_in5", + "mst_in6", + "mst_in7"; + + resets = <&reset RESET_AUDIO>; + }; + + toddr_a: audio-controller@100 { + compatible = "amlogic,g12a-toddr", + "amlogic,axg-toddr"; + reg = <0x0 0x100 0x0 0x1c>; + #sound-dai-cells = <0>; + sound-name-prefix = "TODDR_A"; + interrupts = ; + clocks = <&clkc_audio AUD_CLKID_TODDR_A>; + resets = <&arb AXG_ARB_TODDR_A>; + status = "disabled"; + }; + + toddr_b: audio-controller@140 { + compatible = "amlogic,g12a-toddr", + "amlogic,axg-toddr"; + reg = <0x0 0x140 0x0 0x1c>; + #sound-dai-cells = <0>; + sound-name-prefix = "TODDR_B"; + interrupts = ; + clocks = <&clkc_audio AUD_CLKID_TODDR_B>; + resets = <&arb AXG_ARB_TODDR_B>; + status = "disabled"; + }; + + toddr_c: audio-controller@180 { + compatible = "amlogic,g12a-toddr", + "amlogic,axg-toddr"; + reg = <0x0 0x180 0x0 0x1c>; + #sound-dai-cells = <0>; + sound-name-prefix = "TODDR_C"; + interrupts = ; + clocks = <&clkc_audio AUD_CLKID_TODDR_C>; + resets = <&arb AXG_ARB_TODDR_C>; + status = "disabled"; + }; + + frddr_a: audio-controller@1c0 { + compatible = "amlogic,g12a-frddr", + "amlogic,axg-frddr"; + reg = <0x0 0x1c0 0x0 0x1c>; + #sound-dai-cells = <0>; + sound-name-prefix = "FRDDR_A"; + interrupts = ; + clocks = <&clkc_audio AUD_CLKID_FRDDR_A>; + resets = <&arb AXG_ARB_FRDDR_A>; + status = "disabled"; + }; + + frddr_b: audio-controller@200 { + compatible = "amlogic,g12a-frddr", + "amlogic,axg-frddr"; + reg = <0x0 0x200 0x0 0x1c>; + #sound-dai-cells = <0>; + sound-name-prefix = "FRDDR_B"; + interrupts = ; + clocks = <&clkc_audio AUD_CLKID_FRDDR_B>; + resets = <&arb AXG_ARB_FRDDR_B>; + status = "disabled"; + }; + + frddr_c: audio-controller@240 { + compatible = "amlogic,g12a-frddr", + "amlogic,axg-frddr"; + reg = <0x0 0x240 0x0 0x1c>; + #sound-dai-cells = <0>; + sound-name-prefix = "FRDDR_C"; + interrupts = ; + clocks = <&clkc_audio AUD_CLKID_FRDDR_C>; + resets = <&arb AXG_ARB_FRDDR_C>; + status = "disabled"; + }; + + arb: reset-controller@280 { + status = "disabled"; + compatible = "amlogic,meson-axg-audio-arb"; + reg = <0x0 0x280 0x0 0x4>; + #reset-cells = <1>; + clocks = <&clkc_audio AUD_CLKID_DDR_ARB>; + }; + + tdmin_a: audio-controller@300 { + compatible = "amlogic,g12a-tdmin", + "amlogic,axg-tdmin"; + reg = <0x0 0x300 0x0 0x40>; + sound-name-prefix = "TDMIN_A"; + clocks = <&clkc_audio AUD_CLKID_TDMIN_A>, + <&clkc_audio AUD_CLKID_TDMIN_A_SCLK>, + <&clkc_audio AUD_CLKID_TDMIN_A_SCLK_SEL>, + <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>, + <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>; + clock-names = "pclk", "sclk", "sclk_sel", + "lrclk", "lrclk_sel"; + status = "disabled"; + }; + + tdmin_b: audio-controller@340 { + compatible = "amlogic,g12a-tdmin", + "amlogic,axg-tdmin"; + reg = <0x0 0x340 0x0 0x40>; + sound-name-prefix = "TDMIN_B"; + clocks = <&clkc_audio AUD_CLKID_TDMIN_B>, + <&clkc_audio AUD_CLKID_TDMIN_B_SCLK>, + <&clkc_audio AUD_CLKID_TDMIN_B_SCLK_SEL>, + <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>, + <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>; + clock-names = "pclk", "sclk", "sclk_sel", + "lrclk", "lrclk_sel"; + status = "disabled"; + }; + + tdmin_c: audio-controller@380 { + compatible = "amlogic,g12a-tdmin", + "amlogic,axg-tdmin"; + reg = <0x0 0x380 0x0 0x40>; + sound-name-prefix = "TDMIN_C"; + clocks = <&clkc_audio AUD_CLKID_TDMIN_C>, + <&clkc_audio AUD_CLKID_TDMIN_C_SCLK>, + <&clkc_audio AUD_CLKID_TDMIN_C_SCLK_SEL>, + <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>, + <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>; + clock-names = "pclk", "sclk", "sclk_sel", + "lrclk", "lrclk_sel"; + status = "disabled"; + }; + + tdmin_lb: audio-controller@3c0 { + compatible = "amlogic,g12a-tdmin", + "amlogic,axg-tdmin"; + reg = <0x0 0x3c0 0x0 0x40>; + sound-name-prefix = "TDMIN_LB"; + clocks = <&clkc_audio AUD_CLKID_TDMIN_LB>, + <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK>, + <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK_SEL>, + <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>, + <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>; + clock-names = "pclk", "sclk", "sclk_sel", + "lrclk", "lrclk_sel"; + status = "disabled"; + }; + + spdifin: audio-controller@400 { + compatible = "amlogic,g12a-spdifin", + "amlogic,axg-spdifin"; + reg = <0x0 0x400 0x0 0x30>; + #sound-dai-cells = <0>; + sound-name-prefix = "SPDIFIN"; + interrupts = ; + clocks = <&clkc_audio AUD_CLKID_SPDIFIN>, + <&clkc_audio AUD_CLKID_SPDIFIN_CLK>; + clock-names = "pclk", "refclk"; + status = "disabled"; + }; + + spdifout: audio-controller@480 { + compatible = "amlogic,g12a-spdifout", + "amlogic,axg-spdifout"; + reg = <0x0 0x480 0x0 0x50>; + #sound-dai-cells = <0>; + sound-name-prefix = "SPDIFOUT"; + clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>, + <&clkc_audio AUD_CLKID_SPDIFOUT_CLK>; + clock-names = "pclk", "mclk"; + status = "disabled"; + }; + + tdmout_a: audio-controller@500 { + compatible = "amlogic,g12a-tdmout"; + reg = <0x0 0x500 0x0 0x40>; + sound-name-prefix = "TDMOUT_A"; + clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>, + <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>, + <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>, + <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>, + <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>; + clock-names = "pclk", "sclk", "sclk_sel", + "lrclk", "lrclk_sel"; + status = "disabled"; + }; + + tdmout_b: audio-controller@540 { + compatible = "amlogic,g12a-tdmout"; + reg = <0x0 0x540 0x0 0x40>; + sound-name-prefix = "TDMOUT_B"; + clocks = <&clkc_audio AUD_CLKID_TDMOUT_B>, + <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK>, + <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK_SEL>, + <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>, + <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>; + clock-names = "pclk", "sclk", "sclk_sel", + "lrclk", "lrclk_sel"; + status = "disabled"; + }; + + tdmout_c: audio-controller@580 { + compatible = "amlogic,g12a-tdmout"; + reg = <0x0 0x580 0x0 0x40>; + sound-name-prefix = "TDMOUT_C"; + clocks = <&clkc_audio AUD_CLKID_TDMOUT_C>, + <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK>, + <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK_SEL>, + <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>, + <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>; + clock-names = "pclk", "sclk", "sclk_sel", + "lrclk", "lrclk_sel"; + status = "disabled"; + }; + + spdifout_b: audio-controller@680 { + compatible = "amlogic,g12a-spdifout", + "amlogic,axg-spdifout"; + reg = <0x0 0x680 0x0 0x50>; + #sound-dai-cells = <0>; + sound-name-prefix = "SPDIFOUT_B"; + clocks = <&clkc_audio AUD_CLKID_SPDIFOUT_B>, + <&clkc_audio AUD_CLKID_SPDIFOUT_B_CLK>; + clock-names = "pclk", "mclk"; + status = "disabled"; + }; + + tohdmitx: audio-controller@744 { + compatible = "amlogic,g12a-tohdmitx"; + reg = <0x0 0x744 0x0 0x4>; + #sound-dai-cells = <1>; + sound-name-prefix = "TOHDMITX"; + status = "disabled"; + }; + }; + + usb3_pcie_phy: phy@46000 { + compatible = "amlogic,g12a-usb3-pcie-phy"; + reg = <0x0 0x46000 0x0 0x2000>; + clocks = <&clkc CLKID_PCIE_PLL>; + clock-names = "ref_clk"; + resets = <&reset RESET_PCIE_PHY>; + reset-names = "phy"; + assigned-clocks = <&clkc CLKID_PCIE_PLL>; + assigned-clock-rates = <100000000>; + #phy-cells = <1>; + }; + + eth_phy: mdio-multiplexer@4c000 { + compatible = "amlogic,g12a-mdio-mux"; + reg = <0x0 0x4c000 0x0 0xa4>; + clocks = <&clkc CLKID_ETH_PHY>, + <&xtal>, + <&clkc CLKID_MPLL_50M>; + clock-names = "pclk", "clkin0", "clkin1"; + mdio-parent-bus = <&mdio0>; + #address-cells = <1>; + #size-cells = <0>; + + ext_mdio: mdio@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + int_mdio: mdio@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + internal_ephy: ethernet_phy@8 { + compatible = "ethernet-phy-id0180.3301", + "ethernet-phy-ieee802.3-c22"; + interrupts = ; + reg = <8>; + max-speed = <100>; + }; + }; + }; + }; + + aobus: bus@ff800000 { + compatible = "simple-bus"; + reg = <0x0 0xff800000 0x0 0x100000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xff800000 0x0 0x100000>; + + rti: sys-ctrl@0 { + compatible = "amlogic,meson-gx-ao-sysctrl", + "simple-mfd", "syscon"; + reg = <0x0 0x0 0x0 0x100>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0x0 0x0 0x100>; + + clkc_AO: clock-controller { + compatible = "amlogic,meson-g12a-aoclkc"; + #clock-cells = <1>; + #reset-cells = <1>; + clocks = <&xtal>, <&clkc CLKID_CLK81>; + clock-names = "xtal", "mpeg-clk"; + }; + + pwrc_vpu: power-controller-vpu { + compatible = "amlogic,meson-g12a-pwrc-vpu"; + #power-domain-cells = <0>; + amlogic,hhi-sysctrl = <&hhi>; + resets = <&reset RESET_VIU>, + <&reset RESET_VENC>, + <&reset RESET_VCBUS>, + <&reset RESET_BT656>, + <&reset RESET_RDMA>, + <&reset RESET_VENCI>, + <&reset RESET_VENCP>, + <&reset RESET_VDAC>, + <&reset RESET_VDI6>, + <&reset RESET_VENCL>, + <&reset RESET_VID_LOCK>; + clocks = <&clkc CLKID_VPU>, + <&clkc CLKID_VAPB>; + clock-names = "vpu", "vapb"; + /* + * VPU clocking is provided by two identical clock paths + * VPU_0 and VPU_1 muxed to a single clock by a glitch + * free mux to safely change frequency while running. + * Same for VAPB but with a final gate after the glitch free mux. + */ + assigned-clocks = <&clkc CLKID_VPU_0_SEL>, + <&clkc CLKID_VPU_0>, + <&clkc CLKID_VPU>, /* Glitch free mux */ + <&clkc CLKID_VAPB_0_SEL>, + <&clkc CLKID_VAPB_0>, + <&clkc CLKID_VAPB_SEL>; /* Glitch free mux */ + assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>, + <0>, /* Do Nothing */ + <&clkc CLKID_VPU_0>, + <&clkc CLKID_FCLK_DIV4>, + <0>, /* Do Nothing */ + <&clkc CLKID_VAPB_0>; + assigned-clock-rates = <0>, /* Do Nothing */ + <666666666>, + <0>, /* Do Nothing */ + <0>, /* Do Nothing */ + <250000000>, + <0>; /* Do Nothing */ + }; + + ao_pinctrl: pinctrl@14 { + compatible = "amlogic,meson-g12a-aobus-pinctrl"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gpio_ao: bank@14 { + reg = <0x0 0x14 0x0 0x8>, + <0x0 0x1c 0x0 0x8>, + <0x0 0x24 0x0 0x14>; + reg-names = "mux", + "ds", + "gpio"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&ao_pinctrl 0 0 15>; + }; + + i2c_ao_sck_pins: i2c_ao_sck_pins { + mux { + groups = "i2c_ao_sck"; + function = "i2c_ao"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c_ao_sda_pins: i2c_ao_sda { + mux { + groups = "i2c_ao_sda"; + function = "i2c_ao"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c_ao_sck_e_pins: i2c_ao_sck_e { + mux { + groups = "i2c_ao_sck_e"; + function = "i2c_ao"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + i2c_ao_sda_e_pins: i2c_ao_sda_e { + mux { + groups = "i2c_ao_sda_e"; + function = "i2c_ao"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + mclk0_ao_pins: mclk0-ao { + mux { + groups = "mclk0_ao"; + function = "mclk0_ao"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_ao_b_din0_pins: tdm-ao-b-din0 { + mux { + groups = "tdm_ao_b_din0"; + function = "tdm_ao_b"; + bias-disable; + }; + }; + + spdif_ao_out_pins: spdif-ao-out { + mux { + groups = "spdif_ao_out"; + function = "spdif_ao_out"; + drive-strength-microamp = <500>; + bias-disable; + }; + }; + + tdm_ao_b_din1_pins: tdm-ao-b-din1 { + mux { + groups = "tdm_ao_b_din1"; + function = "tdm_ao_b"; + bias-disable; + }; + }; + + tdm_ao_b_din2_pins: tdm-ao-b-din2 { + mux { + groups = "tdm_ao_b_din2"; + function = "tdm_ao_b"; + bias-disable; + }; + }; + + tdm_ao_b_dout0_pins: tdm-ao-b-dout0 { + mux { + groups = "tdm_ao_b_dout0"; + function = "tdm_ao_b"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_ao_b_dout1_pins: tdm-ao-b-dout1 { + mux { + groups = "tdm_ao_b_dout1"; + function = "tdm_ao_b"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_ao_b_dout2_pins: tdm-ao-b-dout2 { + mux { + groups = "tdm_ao_b_dout2"; + function = "tdm_ao_b"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_ao_b_fs_pins: tdm-ao-b-fs { + mux { + groups = "tdm_ao_b_fs"; + function = "tdm_ao_b"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_ao_b_sclk_pins: tdm-ao-b-sclk { + mux { + groups = "tdm_ao_b_sclk"; + function = "tdm_ao_b"; + bias-disable; + drive-strength-microamp = <3000>; + }; + }; + + tdm_ao_b_slv_fs_pins: tdm-ao-b-slv-fs { + mux { + groups = "tdm_ao_b_slv_fs"; + function = "tdm_ao_b"; + bias-disable; + }; + }; + + tdm_ao_b_slv_sclk_pins: tdm-ao-b-slv-sclk { + mux { + groups = "tdm_ao_b_slv_sclk"; + function = "tdm_ao_b"; + bias-disable; + }; + }; + + uart_ao_a_pins: uart-a-ao { + mux { + groups = "uart_ao_a_tx", + "uart_ao_a_rx"; + function = "uart_ao_a"; + bias-disable; + }; + }; + + uart_ao_a_cts_rts_pins: uart-ao-a-cts-rts { + mux { + groups = "uart_ao_a_cts", + "uart_ao_a_rts"; + function = "uart_ao_a"; + bias-disable; + }; + }; + + pwm_a_e_pins: pwm-a-e { + mux { + groups = "pwm_a_e"; + function = "pwm_a_e"; + bias-disable; + }; + }; + + pwm_ao_a_pins: pwm-ao-a { + mux { + groups = "pwm_ao_a"; + function = "pwm_ao_a"; + bias-disable; + }; + }; + + pwm_ao_b_pins: pwm-ao-b { + mux { + groups = "pwm_ao_b"; + function = "pwm_ao_b"; + bias-disable; + }; + }; + + pwm_ao_c_4_pins: pwm-ao-c-4 { + mux { + groups = "pwm_ao_c_4"; + function = "pwm_ao_c"; + bias-disable; + }; + }; + + pwm_ao_c_6_pins: pwm-ao-c-6 { + mux { + groups = "pwm_ao_c_6"; + function = "pwm_ao_c"; + bias-disable; + }; + }; + + pwm_ao_d_5_pins: pwm-ao-d-5 { + mux { + groups = "pwm_ao_d_5"; + function = "pwm_ao_d"; + bias-disable; + }; + }; + + pwm_ao_d_10_pins: pwm-ao-d-10 { + mux { + groups = "pwm_ao_d_10"; + function = "pwm_ao_d"; + bias-disable; + }; + }; + + pwm_ao_d_e_pins: pwm-ao-d-e { + mux { + groups = "pwm_ao_d_e"; + function = "pwm_ao_d"; + }; + }; + + remote_input_ao_pins: remote-input-ao { + mux { + groups = "remote_ao_input"; + function = "remote_ao_input"; + bias-disable; + }; + }; + }; + }; + + cec_AO: cec@100 { + compatible = "amlogic,meson-gx-ao-cec"; + reg = <0x0 0x00100 0x0 0x14>; + interrupts = ; + clocks = <&clkc_AO CLKID_AO_CEC>; + clock-names = "core"; + status = "disabled"; + }; + + sec_AO: ao-secure@140 { + compatible = "amlogic,meson-gx-ao-secure", "syscon"; + reg = <0x0 0x140 0x0 0x140>; + amlogic,has-chip-id; + }; + + cecb_AO: cec@280 { + compatible = "amlogic,meson-g12a-ao-cec"; + reg = <0x0 0x00280 0x0 0x1c>; + interrupts = ; + clocks = <&clkc_AO CLKID_AO_CTS_OSCIN>; + clock-names = "oscin"; + status = "disabled"; + }; + + pwm_AO_cd: pwm@2000 { + compatible = "amlogic,meson-g12a-ao-pwm-cd"; + reg = <0x0 0x2000 0x0 0x20>; + #pwm-cells = <3>; + status = "disabled"; + }; + + uart_AO: serial@3000 { + compatible = "amlogic,meson-gx-uart", + "amlogic,meson-ao-uart"; + reg = <0x0 0x3000 0x0 0x18>; + interrupts = ; + clocks = <&xtal>, <&clkc_AO CLKID_AO_UART>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; + status = "disabled"; + }; + + uart_AO_B: serial@4000 { + compatible = "amlogic,meson-gx-uart", + "amlogic,meson-ao-uart"; + reg = <0x0 0x4000 0x0 0x18>; + interrupts = ; + clocks = <&xtal>, <&clkc_AO CLKID_AO_UART2>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; + status = "disabled"; + }; + + i2c_AO: i2c@5000 { + compatible = "amlogic,meson-axg-i2c"; + status = "disabled"; + reg = <0x0 0x05000 0x0 0x20>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkc CLKID_I2C>; + }; + + pwm_AO_ab: pwm@7000 { + compatible = "amlogic,meson-g12a-ao-pwm-ab"; + reg = <0x0 0x7000 0x0 0x20>; + #pwm-cells = <3>; + status = "disabled"; + }; + + ir: ir@8000 { + compatible = "amlogic,meson-gxbb-ir"; + reg = <0x0 0x8000 0x0 0x20>; + interrupts = ; + status = "disabled"; + }; + + saradc: adc@9000 { + compatible = "amlogic,meson-g12a-saradc", + "amlogic,meson-saradc"; + reg = <0x0 0x9000 0x0 0x48>; + #io-channel-cells = <1>; + interrupts = ; + clocks = <&xtal>, + <&clkc_AO CLKID_AO_SAR_ADC>, + <&clkc_AO CLKID_AO_SAR_ADC_CLK>, + <&clkc_AO CLKID_AO_SAR_ADC_SEL>; + clock-names = "clkin", "core", "adc_clk", "adc_sel"; + status = "disabled"; + }; + }; + + vpu: vpu@ff900000 { + compatible = "amlogic,meson-g12a-vpu"; + reg = <0x0 0xff900000 0x0 0x100000>, + <0x0 0xff63c000 0x0 0x1000>; + reg-names = "vpu", "hhi"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + amlogic,canvas = <&canvas>; + power-domains = <&pwrc_vpu>; + + /* CVBS VDAC output port */ + cvbs_vdac_port: port@0 { + reg = <0>; + }; + + /* HDMI-TX output port */ + hdmi_tx_port: port@1 { + reg = <1>; + + hdmi_tx_out: endpoint { + remote-endpoint = <&hdmi_tx_in>; + }; + }; + }; + + gic: interrupt-controller@ffc01000 { + compatible = "arm,gic-400"; + reg = <0x0 0xffc01000 0 0x1000>, + <0x0 0xffc02000 0 0x2000>, + <0x0 0xffc04000 0 0x2000>, + <0x0 0xffc06000 0 0x2000>; + interrupt-controller; + interrupts = ; + #interrupt-cells = <3>; + #address-cells = <0>; + }; + + cbus: bus@ffd00000 { + compatible = "simple-bus"; + reg = <0x0 0xffd00000 0x0 0x100000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xffd00000 0x0 0x100000>; + + reset: reset-controller@1004 { + compatible = "amlogic,meson-g12a-reset", + "amlogic,meson-axg-reset"; + reg = <0x0 0x1004 0x0 0x9c>; + #reset-cells = <1>; + }; + + gpio_intc: interrupt-controller@f080 { + compatible = "amlogic,meson-g12a-gpio-intc", + "amlogic,meson-gpio-intc"; + reg = <0x0 0xf080 0x0 0x10>; + interrupt-controller; + #interrupt-cells = <2>; + amlogic,channel-interrupts = <64 65 66 67 68 69 70 71>; + }; + + pwm_ef: pwm@19000 { + compatible = "amlogic,meson-g12a-ee-pwm"; + reg = <0x0 0x19000 0x0 0x20>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm_cd: pwm@1a000 { + compatible = "amlogic,meson-g12a-ee-pwm"; + reg = <0x0 0x1a000 0x0 0x20>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm_ab: pwm@1b000 { + compatible = "amlogic,meson-g12a-ee-pwm"; + reg = <0x0 0x1b000 0x0 0x20>; + #pwm-cells = <3>; + status = "disabled"; + }; + + i2c3: i2c@1c000 { + compatible = "amlogic,meson-axg-i2c"; + status = "disabled"; + reg = <0x0 0x1c000 0x0 0x20>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkc CLKID_I2C>; + }; + + i2c2: i2c@1d000 { + compatible = "amlogic,meson-axg-i2c"; + status = "disabled"; + reg = <0x0 0x1d000 0x0 0x20>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkc CLKID_I2C>; + }; + + i2c1: i2c@1e000 { + compatible = "amlogic,meson-axg-i2c"; + status = "disabled"; + reg = <0x0 0x1e000 0x0 0x20>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkc CLKID_I2C>; + }; + + i2c0: i2c@1f000 { + compatible = "amlogic,meson-axg-i2c"; + status = "disabled"; + reg = <0x0 0x1f000 0x0 0x20>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkc CLKID_I2C>; + }; + + clk_msr: clock-measure@18000 { + compatible = "amlogic,meson-g12a-clk-measure"; + reg = <0x0 0x18000 0x0 0x10>; + }; + + uart_C: serial@22000 { + compatible = "amlogic,meson-gx-uart"; + reg = <0x0 0x22000 0x0 0x18>; + interrupts = ; + clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; + status = "disabled"; + }; + + uart_B: serial@23000 { + compatible = "amlogic,meson-gx-uart"; + reg = <0x0 0x23000 0x0 0x18>; + interrupts = ; + clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; + status = "disabled"; + }; + + uart_A: serial@24000 { + compatible = "amlogic,meson-gx-uart"; + reg = <0x0 0x24000 0x0 0x18>; + interrupts = ; + clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; + status = "disabled"; + }; + }; + + sd_emmc_a: sd@ffe03000 { + compatible = "amlogic,meson-axg-mmc"; + reg = <0x0 0xffe03000 0x0 0x800>; + interrupts = ; + status = "disabled"; + clocks = <&clkc CLKID_SD_EMMC_A>, + <&clkc CLKID_SD_EMMC_A_CLK0>, + <&clkc CLKID_FCLK_DIV2>; + clock-names = "core", "clkin0", "clkin1"; + resets = <&reset RESET_SD_EMMC_A>; + }; + + sd_emmc_b: sd@ffe05000 { + compatible = "amlogic,meson-axg-mmc"; + reg = <0x0 0xffe05000 0x0 0x800>; + interrupts = ; + status = "disabled"; + clocks = <&clkc CLKID_SD_EMMC_B>, + <&clkc CLKID_SD_EMMC_B_CLK0>, + <&clkc CLKID_FCLK_DIV2>; + clock-names = "core", "clkin0", "clkin1"; + resets = <&reset RESET_SD_EMMC_B>; + }; + + sd_emmc_c: mmc@ffe07000 { + compatible = "amlogic,meson-axg-mmc"; + reg = <0x0 0xffe07000 0x0 0x800>; + interrupts = ; + status = "disabled"; + clocks = <&clkc CLKID_SD_EMMC_C>, + <&clkc CLKID_SD_EMMC_C_CLK0>, + <&clkc CLKID_FCLK_DIV2>; + clock-names = "core", "clkin0", "clkin1"; + resets = <&reset RESET_SD_EMMC_C>; + }; + + usb: usb@ffe09000 { + status = "disabled"; + compatible = "amlogic,meson-g12a-usb-ctrl"; + reg = <0x0 0xffe09000 0x0 0xa0>; + interrupts = ; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + clocks = <&clkc CLKID_USB>; + resets = <&reset RESET_USB>; + + dr_mode = "otg"; + + phys = <&usb2_phy0>, <&usb2_phy1>, + <&usb3_pcie_phy PHY_TYPE_USB3>; + phy-names = "usb2-phy0", "usb2-phy1", "usb3-phy0"; + + dwc2: usb@ff400000 { + compatible = "amlogic,meson-g12a-usb", "snps,dwc2"; + reg = <0x0 0xff400000 0x0 0x40000>; + interrupts = ; + clocks = <&clkc CLKID_USB1_DDR_BRIDGE>; + clock-names = "ddr"; + phys = <&usb2_phy1>; + phy-names = "usb2-phy"; + dr_mode = "peripheral"; + g-rx-fifo-size = <192>; + g-np-tx-fifo-size = <128>; + g-tx-fifo-size = <128 128 16 16 16>; + }; + + dwc3: usb@ff500000 { + compatible = "snps,dwc3"; + reg = <0x0 0xff500000 0x0 0x100000>; + interrupts = ; + dr_mode = "host"; + snps,dis_u2_susphy_quirk; + snps,quirk-frame-length-adjustment; + }; + }; + + mali: gpu@ffe40000 { + compatible = "amlogic,meson-g12a-mali", "arm,mali-bifrost"; + reg = <0x0 0xffe40000 0x0 0x40000>; + interrupt-parent = <&gic>; + interrupts = , + , + ; + interrupt-names = "gpu", "mmu", "job"; + clocks = <&clkc CLKID_MALI>; + resets = <&reset RESET_DVALIN_CAPB3>, <&reset RESET_DVALIN>; + + /* + * Mali clocking is provided by two identical clock paths + * MALI_0 and MALI_1 muxed to a single clock by a glitch + * free mux to safely change frequency while running. + */ + assigned-clocks = <&clkc CLKID_MALI_0_SEL>, + <&clkc CLKID_MALI_0>, + <&clkc CLKID_MALI>; /* Glitch free mux */ + assigned-clock-parents = <&clkc CLKID_FCLK_DIV2P5>, + <0>, /* Do Nothing */ + <&clkc CLKID_MALI_0>; + assigned-clock-rates = <0>, /* Do Nothing */ + <800000000>, + <0>; /* Do Nothing */ + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + arm,no-tick-in-suspend; + }; + + xtal: xtal-clk { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "xtal"; + #clock-cells = <0>; + }; + +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts index c7a87368850b..c9fa23a56562 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts @@ -129,6 +129,25 @@ enable-active-high; }; + vddcpu: regulator-vddcpu { + /* + * SY8120B1ABC DC/DC Regulator. + */ + compatible = "pwm-regulator"; + + regulator-name = "VDDCPU"; + regulator-min-microvolt = <721000>; + regulator-max-microvolt = <1022000>; + + vin-supply = <&dc_in>; + + pwms = <&pwm_AO_cd 1 1250 0>; + pwm-dutycycle-range = <100 0>; + + regulator-boot-on; + regulator-always-on; + }; + vddio_ao1v8: regulator-vddio_ao1v8 { compatible = "regulator-fixed"; regulator-name = "VDDIO_AO1V8"; @@ -297,6 +316,34 @@ status = "okay"; }; +&cpu0 { + cpu-supply = <&vddcpu>; + operating-points-v2 = <&cpu_opp_table>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu1 { + cpu-supply = <&vddcpu>; + operating-points-v2 = <&cpu_opp_table>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu2 { + cpu-supply = <&vddcpu>; + operating-points-v2 = <&cpu_opp_table>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu3 { + cpu-supply = <&vddcpu>; + operating-points-v2 = <&cpu_opp_table>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; @@ -339,6 +386,20 @@ pinctrl-names = "default"; }; +&ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; +}; + +&pwm_AO_cd { + pinctrl-0 = <&pwm_ao_d_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin1"; + status = "okay"; +}; + &pwm_ef { status = "okay"; pinctrl-0 = <&pwm_e_pins>; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts index 8551fbd4a488..2a324f0136e3 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts @@ -129,6 +129,24 @@ regulator-always-on; }; + vddcpu: regulator-vddcpu { + /* + * MP8756GD Regulator. + */ + compatible = "pwm-regulator"; + + regulator-name = "VDDCPU"; + regulator-min-microvolt = <721000>; + regulator-max-microvolt = <1022000>; + + vin-supply = <&main_12v>; + + pwms = <&pwm_AO_cd 1 1250 0>; + pwm-dutycycle-range = <100 0>; + + regulator-boot-on; + regulator-always-on; + }; }; &cec_AO { @@ -145,6 +163,34 @@ hdmi-phandle = <&hdmi_tx>; }; +&cpu0 { + cpu-supply = <&vddcpu>; + operating-points-v2 = <&cpu_opp_table>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu1 { + cpu-supply = <&vddcpu>; + operating-points-v2 = <&cpu_opp_table>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu2 { + cpu-supply = <&vddcpu>; + operating-points-v2 = <&cpu_opp_table>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu3 { + cpu-supply = <&vddcpu>; + operating-points-v2 = <&cpu_opp_table>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; @@ -197,6 +243,14 @@ pinctrl-names = "default"; }; +&pwm_AO_cd { + pinctrl-0 = <&pwm_ao_d_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin1"; + status = "okay"; +}; + /* SD card */ &sd_emmc_b { status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts index fe4013cca876..c1e58a69d434 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts @@ -132,6 +132,22 @@ regulator-always-on; }; + vddcpu: regulator-vddcpu { + compatible = "pwm-regulator"; + + regulator-name = "VDDCPU"; + regulator-min-microvolt = <721000>; + regulator-max-microvolt = <1022000>; + + vin-supply = <&dc_in>; + + pwms = <&pwm_AO_cd 1 1250 0>; + pwm-dutycycle-range = <100 0>; + + regulator-boot-on; + regulator-always-on; + }; + sound { compatible = "amlogic,axg-sound-card"; model = "G12A-X96-MAX"; @@ -242,6 +258,34 @@ status = "okay"; }; +&cpu0 { + cpu-supply = <&vddcpu>; + operating-points-v2 = <&cpu_opp_table>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu1 { + cpu-supply = <&vddcpu>; + operating-points-v2 = <&cpu_opp_table>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu2 { + cpu-supply = <&vddcpu>; + operating-points-v2 = <&cpu_opp_table>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu3 { + cpu-supply = <&vddcpu>; + operating-points-v2 = <&cpu_opp_table>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; @@ -279,6 +323,14 @@ pinctrl-names = "default"; }; +&pwm_AO_cd { + pinctrl-0 = <&pwm_ao_d_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin1"; + status = "okay"; +}; + &ext_mdio { external_phy: ethernet-phy@0 { /* Realtek RTL8211F (0x001cc916) */ diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi index f8d43e3dcf20..733a9d46fc4b 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi @@ -3,56 +3,11 @@ * Copyright (c) 2018 Amlogic, Inc. All rights reserved. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "meson-g12-common.dtsi" / { compatible = "amlogic,g12a"; - interrupt-parent = <&gic>; - #address-cells = <2>; - #size-cells = <2>; - - tdmif_a: audio-controller-0 { - compatible = "amlogic,axg-tdm-iface"; - #sound-dai-cells = <0>; - sound-name-prefix = "TDM_A"; - clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>, - <&clkc_audio AUD_CLKID_MST_A_SCLK>, - <&clkc_audio AUD_CLKID_MST_A_LRCLK>; - clock-names = "mclk", "sclk", "lrclk"; - status = "disabled"; - }; - - tdmif_b: audio-controller-1 { - compatible = "amlogic,axg-tdm-iface"; - #sound-dai-cells = <0>; - sound-name-prefix = "TDM_B"; - clocks = <&clkc_audio AUD_CLKID_MST_B_MCLK>, - <&clkc_audio AUD_CLKID_MST_B_SCLK>, - <&clkc_audio AUD_CLKID_MST_B_LRCLK>; - clock-names = "mclk", "sclk", "lrclk"; - status = "disabled"; - }; - - tdmif_c: audio-controller-2 { - compatible = "amlogic,axg-tdm-iface"; - #sound-dai-cells = <0>; - sound-name-prefix = "TDM_C"; - clocks = <&clkc_audio AUD_CLKID_MST_C_MCLK>, - <&clkc_audio AUD_CLKID_MST_C_SCLK>, - <&clkc_audio AUD_CLKID_MST_C_LRCLK>; - clock-names = "mclk", "sclk", "lrclk"; - status = "disabled"; - }; - cpus { #address-cells = <0x2>; #size-cells = <0x0>; @@ -94,2359 +49,67 @@ }; }; - efuse: efuse { - compatible = "amlogic,meson-gxbb-efuse"; - clocks = <&clkc CLKID_EFUSE>; - #address-cells = <1>; - #size-cells = <1>; - read-only; - }; + cpu_opp_table: opp-table { + compatible = "operating-points-v2"; + opp-shared; - psci { - compatible = "arm,psci-1.0"; - method = "smc"; - }; - - reserved-memory { - #address-cells = <2>; - #size-cells = <2>; - ranges; - - /* 3 MiB reserved for ARM Trusted Firmware (BL31) */ - secmon_reserved: secmon@5000000 { - reg = <0x0 0x05000000 0x0 0x300000>; - no-map; + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <731000>; }; - linux,cma { - compatible = "shared-dma-pool"; - reusable; - size = <0x0 0x10000000>; - alignment = <0x0 0x400000>; - linux,cma-default; + opp-250000000 { + opp-hz = /bits/ 64 <250000000>; + opp-microvolt = <731000>; + }; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <731000>; + }; + + opp-667000000 { + opp-hz = /bits/ 64 <666666666>; + opp-microvolt = <731000>; + }; + + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <731000>; + }; + + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <731000>; + }; + + opp-1398000000 { + opp-hz = /bits/ 64 <1398000000>; + opp-microvolt = <761000>; + }; + + opp-1512000000 { + opp-hz = /bits/ 64 <1512000000>; + opp-microvolt = <791000>; + }; + + opp-1608000000 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <831000>; + }; + + opp-1704000000 { + opp-hz = /bits/ 64 <1704000000>; + opp-microvolt = <861000>; + }; + + opp-1800000000 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <981000>; }; }; - - sm: secure-monitor { - compatible = "amlogic,meson-gxbb-sm"; - }; - - soc { - compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <2>; - ranges; - - ethmac: ethernet@ff3f0000 { - compatible = "amlogic,meson-axg-dwmac", - "snps,dwmac-3.70a", - "snps,dwmac"; - reg = <0x0 0xff3f0000 0x0 0x10000 - 0x0 0xff634540 0x0 0x8>; - interrupts = ; - interrupt-names = "macirq"; - clocks = <&clkc CLKID_ETH>, - <&clkc CLKID_FCLK_DIV2>, - <&clkc CLKID_MPLL2>; - clock-names = "stmmaceth", "clkin0", "clkin1"; - status = "disabled"; - - mdio0: mdio { - #address-cells = <1>; - #size-cells = <0>; - compatible = "snps,dwmac-mdio"; - }; - }; - - apb: bus@ff600000 { - compatible = "simple-bus"; - reg = <0x0 0xff600000 0x0 0x200000>; - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x0 0x0 0xff600000 0x0 0x200000>; - - hdmi_tx: hdmi-tx@0 { - compatible = "amlogic,meson-g12a-dw-hdmi"; - reg = <0x0 0x0 0x0 0x10000>; - interrupts = ; - resets = <&reset RESET_HDMITX_CAPB3>, - <&reset RESET_HDMITX_PHY>, - <&reset RESET_HDMITX>; - reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; - clocks = <&clkc CLKID_HDMI>, - <&clkc CLKID_HTX_PCLK>, - <&clkc CLKID_VPU_INTR>; - clock-names = "isfr", "iahb", "venci"; - #address-cells = <1>; - #size-cells = <0>; - #sound-dai-cells = <0>; - status = "disabled"; - - /* VPU VENC Input */ - hdmi_tx_venc_port: port@0 { - reg = <0>; - - hdmi_tx_in: endpoint { - remote-endpoint = <&hdmi_tx_out>; - }; - }; - - /* TMDS Output */ - hdmi_tx_tmds_port: port@1 { - reg = <1>; - }; - }; - - apb_efuse: bus@30000 { - compatible = "simple-bus"; - reg = <0x0 0x30000 0x0 0x2000>; - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x0 0x0 0x30000 0x0 0x2000>; - - hwrng: rng@218 { - compatible = "amlogic,meson-rng"; - reg = <0x0 0x218 0x0 0x4>; - }; - }; - - periphs: bus@34400 { - compatible = "simple-bus"; - reg = <0x0 0x34400 0x0 0x400>; - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x0 0x0 0x34400 0x0 0x400>; - - periphs_pinctrl: pinctrl@40 { - compatible = "amlogic,meson-g12a-periphs-pinctrl"; - #address-cells = <2>; - #size-cells = <2>; - ranges; - - gpio: bank@40 { - reg = <0x0 0x40 0x0 0x4c>, - <0x0 0xe8 0x0 0x18>, - <0x0 0x120 0x0 0x18>, - <0x0 0x2c0 0x0 0x40>, - <0x0 0x340 0x0 0x1c>; - reg-names = "gpio", - "pull", - "pull-enable", - "mux", - "ds"; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&periphs_pinctrl 0 0 86>; - }; - - cec_ao_a_h_pins: cec_ao_a_h { - mux { - groups = "cec_ao_a_h"; - function = "cec_ao_a_h"; - bias-disable; - }; - }; - - cec_ao_b_h_pins: cec_ao_b_h { - mux { - groups = "cec_ao_b_h"; - function = "cec_ao_b_h"; - bias-disable; - }; - }; - - emmc_pins: emmc { - mux-0 { - groups = "emmc_nand_d0", - "emmc_nand_d1", - "emmc_nand_d2", - "emmc_nand_d3", - "emmc_nand_d4", - "emmc_nand_d5", - "emmc_nand_d6", - "emmc_nand_d7", - "emmc_cmd"; - function = "emmc"; - bias-pull-up; - drive-strength-microamp = <4000>; - }; - - mux-1 { - groups = "emmc_clk"; - function = "emmc"; - bias-disable; - drive-strength-microamp = <4000>; - }; - }; - - emmc_ds_pins: emmc-ds { - mux { - groups = "emmc_nand_ds"; - function = "emmc"; - bias-pull-down; - drive-strength-microamp = <4000>; - }; - }; - - emmc_clk_gate_pins: emmc_clk_gate { - mux { - groups = "BOOT_8"; - function = "gpio_periphs"; - bias-pull-down; - drive-strength-microamp = <4000>; - }; - }; - - hdmitx_ddc_pins: hdmitx_ddc { - mux { - groups = "hdmitx_sda", - "hdmitx_sck"; - function = "hdmitx"; - bias-disable; - drive-strength-microamp = <4000>; - }; - }; - - hdmitx_hpd_pins: hdmitx_hpd { - mux { - groups = "hdmitx_hpd_in"; - function = "hdmitx"; - bias-disable; - }; - }; - - - i2c0_sda_c_pins: i2c0-sda-c { - mux { - groups = "i2c0_sda_c"; - function = "i2c0"; - bias-disable; - drive-strength-microamp = <3000>; - - }; - }; - - i2c0_sck_c_pins: i2c0-sck-c { - mux { - groups = "i2c0_sck_c"; - function = "i2c0"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c0_sda_z0_pins: i2c0-sda-z0 { - mux { - groups = "i2c0_sda_z0"; - function = "i2c0"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c0_sck_z1_pins: i2c0-sck-z1 { - mux { - groups = "i2c0_sck_z1"; - function = "i2c0"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c0_sda_z7_pins: i2c0-sda-z7 { - mux { - groups = "i2c0_sda_z7"; - function = "i2c0"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c0_sda_z8_pins: i2c0-sda-z8 { - mux { - groups = "i2c0_sda_z8"; - function = "i2c0"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c1_sda_x_pins: i2c1-sda-x { - mux { - groups = "i2c1_sda_x"; - function = "i2c1"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c1_sck_x_pins: i2c1-sck-x { - mux { - groups = "i2c1_sck_x"; - function = "i2c1"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c1_sda_h2_pins: i2c1-sda-h2 { - mux { - groups = "i2c1_sda_h2"; - function = "i2c1"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c1_sck_h3_pins: i2c1-sck-h3 { - mux { - groups = "i2c1_sck_h3"; - function = "i2c1"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c1_sda_h6_pins: i2c1-sda-h6 { - mux { - groups = "i2c1_sda_h6"; - function = "i2c1"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c1_sck_h7_pins: i2c1-sck-h7 { - mux { - groups = "i2c1_sck_h7"; - function = "i2c1"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c2_sda_x_pins: i2c2-sda-x { - mux { - groups = "i2c2_sda_x"; - function = "i2c2"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c2_sck_x_pins: i2c2-sck-x { - mux { - groups = "i2c2_sck_x"; - function = "i2c2"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c2_sda_z_pins: i2c2-sda-z { - mux { - groups = "i2c2_sda_z"; - function = "i2c2"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c2_sck_z_pins: i2c2-sck-z { - mux { - groups = "i2c2_sck_z"; - function = "i2c2"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c3_sda_h_pins: i2c3-sda-h { - mux { - groups = "i2c3_sda_h"; - function = "i2c3"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c3_sck_h_pins: i2c3-sck-h { - mux { - groups = "i2c3_sck_h"; - function = "i2c3"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c3_sda_a_pins: i2c3-sda-a { - mux { - groups = "i2c3_sda_a"; - function = "i2c3"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c3_sck_a_pins: i2c3-sck-a { - mux { - groups = "i2c3_sck_a"; - function = "i2c3"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - mclk0_a_pins: mclk0-a { - mux { - groups = "mclk0_a"; - function = "mclk0"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - mclk1_a_pins: mclk1-a { - mux { - groups = "mclk1_a"; - function = "mclk1"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - mclk1_x_pins: mclk1-x { - mux { - groups = "mclk1_x"; - function = "mclk1"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - mclk1_z_pins: mclk1-z { - mux { - groups = "mclk1_z"; - function = "mclk1"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - pdm_din0_a_pins: pdm-din0-a { - mux { - groups = "pdm_din0_a"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din0_c_pins: pdm-din0-c { - mux { - groups = "pdm_din0_c"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din0_x_pins: pdm-din0-x { - mux { - groups = "pdm_din0_x"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din0_z_pins: pdm-din0-z { - mux { - groups = "pdm_din0_z"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din1_a_pins: pdm-din1-a { - mux { - groups = "pdm_din1_a"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din1_c_pins: pdm-din1-c { - mux { - groups = "pdm_din1_c"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din1_x_pins: pdm-din1-x { - mux { - groups = "pdm_din1_x"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din1_z_pins: pdm-din1-z { - mux { - groups = "pdm_din1_z"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din2_a_pins: pdm-din2-a { - mux { - groups = "pdm_din2_a"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din2_c_pins: pdm-din2-c { - mux { - groups = "pdm_din2_c"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din2_x_pins: pdm-din2-x { - mux { - groups = "pdm_din2_x"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din2_z_pins: pdm-din2-z { - mux { - groups = "pdm_din2_z"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din3_a_pins: pdm-din3-a { - mux { - groups = "pdm_din3_a"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din3_c_pins: pdm-din3-c { - mux { - groups = "pdm_din3_c"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din3_x_pins: pdm-din3-x { - mux { - groups = "pdm_din3_x"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_din3_z_pins: pdm-din3-z { - mux { - groups = "pdm_din3_z"; - function = "pdm"; - bias-disable; - }; - }; - - pdm_dclk_a_pins: pdm-dclk-a { - mux { - groups = "pdm_dclk_a"; - function = "pdm"; - bias-disable; - drive-strength-microamp = <500>; - }; - }; - - pdm_dclk_c_pins: pdm-dclk-c { - mux { - groups = "pdm_dclk_c"; - function = "pdm"; - bias-disable; - drive-strength-microamp = <500>; - }; - }; - - pdm_dclk_x_pins: pdm-dclk-x { - mux { - groups = "pdm_dclk_x"; - function = "pdm"; - bias-disable; - drive-strength-microamp = <500>; - }; - }; - - pdm_dclk_z_pins: pdm-dclk-z { - mux { - groups = "pdm_dclk_z"; - function = "pdm"; - bias-disable; - drive-strength-microamp = <500>; - }; - }; - - pwm_a_pins: pwm-a { - mux { - groups = "pwm_a"; - function = "pwm_a"; - bias-disable; - }; - }; - - pwm_b_x7_pins: pwm-b-x7 { - mux { - groups = "pwm_b_x7"; - function = "pwm_b"; - bias-disable; - }; - }; - - pwm_b_x19_pins: pwm-b-x19 { - mux { - groups = "pwm_b_x19"; - function = "pwm_b"; - bias-disable; - }; - }; - - pwm_c_c_pins: pwm-c-c { - mux { - groups = "pwm_c_c"; - function = "pwm_c"; - bias-disable; - }; - }; - - pwm_c_x5_pins: pwm-c-x5 { - mux { - groups = "pwm_c_x5"; - function = "pwm_c"; - bias-disable; - }; - }; - - pwm_c_x8_pins: pwm-c-x8 { - mux { - groups = "pwm_c_x8"; - function = "pwm_c"; - bias-disable; - }; - }; - - pwm_d_x3_pins: pwm-d-x3 { - mux { - groups = "pwm_d_x3"; - function = "pwm_d"; - bias-disable; - }; - }; - - pwm_d_x6_pins: pwm-d-x6 { - mux { - groups = "pwm_d_x6"; - function = "pwm_d"; - bias-disable; - }; - }; - - pwm_e_pins: pwm-e { - mux { - groups = "pwm_e"; - function = "pwm_e"; - bias-disable; - }; - }; - - pwm_f_x_pins: pwm-f-x { - mux { - groups = "pwm_f_x"; - function = "pwm_f"; - bias-disable; - }; - }; - - pwm_f_h_pins: pwm-f-h { - mux { - groups = "pwm_f_h"; - function = "pwm_f"; - bias-disable; - }; - }; - - sdcard_c_pins: sdcard_c { - mux-0 { - groups = "sdcard_d0_c", - "sdcard_d1_c", - "sdcard_d2_c", - "sdcard_d3_c", - "sdcard_cmd_c"; - function = "sdcard"; - bias-pull-up; - drive-strength-microamp = <4000>; - }; - - mux-1 { - groups = "sdcard_clk_c"; - function = "sdcard"; - bias-disable; - drive-strength-microamp = <4000>; - }; - }; - - sdcard_clk_gate_c_pins: sdcard_clk_gate_c { - mux { - groups = "GPIOC_4"; - function = "gpio_periphs"; - bias-pull-down; - drive-strength-microamp = <4000>; - }; - }; - - sdcard_z_pins: sdcard_z { - mux-0 { - groups = "sdcard_d0_z", - "sdcard_d1_z", - "sdcard_d2_z", - "sdcard_d3_z", - "sdcard_cmd_z"; - function = "sdcard"; - bias-pull-up; - drive-strength-microamp = <4000>; - }; - - mux-1 { - groups = "sdcard_clk_z"; - function = "sdcard"; - bias-disable; - drive-strength-microamp = <4000>; - }; - }; - - sdcard_clk_gate_z_pins: sdcard_clk_gate_z { - mux { - groups = "GPIOZ_6"; - function = "gpio_periphs"; - bias-pull-down; - drive-strength-microamp = <4000>; - }; - }; - - sdio_pins: sdio { - mux { - groups = "sdio_d0", - "sdio_d1", - "sdio_d2", - "sdio_d3", - "sdio_clk", - "sdio_cmd"; - function = "sdio"; - bias-disable; - drive-strength-microamp = <4000>; - }; - }; - - sdio_clk_gate_pins: sdio_clk_gate { - mux { - groups = "GPIOX_4"; - function = "gpio_periphs"; - bias-pull-down; - drive-strength-microamp = <4000>; - }; - }; - - spdif_in_a10_pins: spdif-in-a10 { - mux { - groups = "spdif_in_a10"; - function = "spdif_in"; - bias-disable; - }; - }; - - spdif_in_a12_pins: spdif-in-a12 { - mux { - groups = "spdif_in_a12"; - function = "spdif_in"; - bias-disable; - }; - }; - - spdif_in_h_pins: spdif-in-h { - mux { - groups = "spdif_in_h"; - function = "spdif_in"; - bias-disable; - }; - }; - - spdif_out_h_pins: spdif-out-h { - mux { - groups = "spdif_out_h"; - function = "spdif_out"; - drive-strength-microamp = <500>; - bias-disable; - }; - }; - - spdif_out_a11_pins: spdif-out-a11 { - mux { - groups = "spdif_out_a11"; - function = "spdif_out"; - drive-strength-microamp = <500>; - bias-disable; - }; - }; - - spdif_out_a13_pins: spdif-out-a13 { - mux { - groups = "spdif_out_a13"; - function = "spdif_out"; - drive-strength-microamp = <500>; - bias-disable; - }; - }; - - tdm_a_din0_pins: tdm-a-din0 { - mux { - groups = "tdm_a_din0"; - function = "tdm_a"; - bias-disable; - }; - }; - - - tdm_a_din1_pins: tdm-a-din1 { - mux { - groups = "tdm_a_din1"; - function = "tdm_a"; - bias-disable; - }; - }; - - tdm_a_dout0_pins: tdm-a-dout0 { - mux { - groups = "tdm_a_dout0"; - function = "tdm_a"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_a_dout1_pins: tdm-a-dout1 { - mux { - groups = "tdm_a_dout1"; - function = "tdm_a"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_a_fs_pins: tdm-a-fs { - mux { - groups = "tdm_a_fs"; - function = "tdm_a"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_a_sclk_pins: tdm-a-sclk { - mux { - groups = "tdm_a_sclk"; - function = "tdm_a"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_a_slv_fs_pins: tdm-a-slv-fs { - mux { - groups = "tdm_a_slv_fs"; - function = "tdm_a"; - bias-disable; - }; - }; - - - tdm_a_slv_sclk_pins: tdm-a-slv-sclk { - mux { - groups = "tdm_a_slv_sclk"; - function = "tdm_a"; - bias-disable; - }; - }; - - tdm_b_din0_pins: tdm-b-din0 { - mux { - groups = "tdm_b_din0"; - function = "tdm_b"; - bias-disable; - }; - }; - - tdm_b_din1_pins: tdm-b-din1 { - mux { - groups = "tdm_b_din1"; - function = "tdm_b"; - bias-disable; - }; - }; - - tdm_b_din2_pins: tdm-b-din2 { - mux { - groups = "tdm_b_din2"; - function = "tdm_b"; - bias-disable; - }; - }; - - tdm_b_din3_a_pins: tdm-b-din3-a { - mux { - groups = "tdm_b_din3_a"; - function = "tdm_b"; - bias-disable; - }; - }; - - tdm_b_din3_h_pins: tdm-b-din3-h { - mux { - groups = "tdm_b_din3_h"; - function = "tdm_b"; - bias-disable; - }; - }; - - tdm_b_dout0_pins: tdm-b-dout0 { - mux { - groups = "tdm_b_dout0"; - function = "tdm_b"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_b_dout1_pins: tdm-b-dout1 { - mux { - groups = "tdm_b_dout1"; - function = "tdm_b"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_b_dout2_pins: tdm-b-dout2 { - mux { - groups = "tdm_b_dout2"; - function = "tdm_b"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_b_dout3_a_pins: tdm-b-dout3-a { - mux { - groups = "tdm_b_dout3_a"; - function = "tdm_b"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_b_dout3_h_pins: tdm-b-dout3-h { - mux { - groups = "tdm_b_dout3_h"; - function = "tdm_b"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_b_fs_pins: tdm-b-fs { - mux { - groups = "tdm_b_fs"; - function = "tdm_b"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_b_sclk_pins: tdm-b-sclk { - mux { - groups = "tdm_b_sclk"; - function = "tdm_b"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_b_slv_fs_pins: tdm-b-slv-fs { - mux { - groups = "tdm_b_slv_fs"; - function = "tdm_b"; - bias-disable; - }; - }; - - tdm_b_slv_sclk_pins: tdm-b-slv-sclk { - mux { - groups = "tdm_b_slv_sclk"; - function = "tdm_b"; - bias-disable; - }; - }; - - tdm_c_din0_a_pins: tdm-c-din0-a { - mux { - groups = "tdm_c_din0_a"; - function = "tdm_c"; - bias-disable; - }; - }; - - tdm_c_din0_z_pins: tdm-c-din0-z { - mux { - groups = "tdm_c_din0_z"; - function = "tdm_c"; - bias-disable; - }; - }; - - tdm_c_din1_a_pins: tdm-c-din1-a { - mux { - groups = "tdm_c_din1_a"; - function = "tdm_c"; - bias-disable; - }; - }; - - tdm_c_din1_z_pins: tdm-c-din1-z { - mux { - groups = "tdm_c_din1_z"; - function = "tdm_c"; - bias-disable; - }; - }; - - tdm_c_din2_a_pins: tdm-c-din2-a { - mux { - groups = "tdm_c_din2_a"; - function = "tdm_c"; - bias-disable; - }; - }; - - eth_leds_pins: eth-leds { - mux { - groups = "eth_link_led", - "eth_act_led"; - function = "eth"; - bias-disable; - }; - }; - - eth_pins: eth { - mux { - groups = "eth_mdio", - "eth_mdc", - "eth_rgmii_rx_clk", - "eth_rx_dv", - "eth_rxd0", - "eth_rxd1", - "eth_txen", - "eth_txd0", - "eth_txd1"; - function = "eth"; - drive-strength-microamp = <4000>; - bias-disable; - }; - }; - - eth_rgmii_pins: eth-rgmii { - mux { - groups = "eth_rxd2_rgmii", - "eth_rxd3_rgmii", - "eth_rgmii_tx_clk", - "eth_txd2_rgmii", - "eth_txd3_rgmii"; - function = "eth"; - drive-strength-microamp = <4000>; - bias-disable; - }; - }; - - tdm_c_din2_z_pins: tdm-c-din2-z { - mux { - groups = "tdm_c_din2_z"; - function = "tdm_c"; - bias-disable; - }; - }; - - tdm_c_din3_a_pins: tdm-c-din3-a { - mux { - groups = "tdm_c_din3_a"; - function = "tdm_c"; - bias-disable; - }; - }; - - tdm_c_din3_z_pins: tdm-c-din3-z { - mux { - groups = "tdm_c_din3_z"; - function = "tdm_c"; - bias-disable; - }; - }; - - tdm_c_dout0_a_pins: tdm-c-dout0-a { - mux { - groups = "tdm_c_dout0_a"; - function = "tdm_c"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_c_dout0_z_pins: tdm-c-dout0-z { - mux { - groups = "tdm_c_dout0_z"; - function = "tdm_c"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_c_dout1_a_pins: tdm-c-dout1-a { - mux { - groups = "tdm_c_dout1_a"; - function = "tdm_c"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_c_dout1_z_pins: tdm-c-dout1-z { - mux { - groups = "tdm_c_dout1_z"; - function = "tdm_c"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_c_dout2_a_pins: tdm-c-dout2-a { - mux { - groups = "tdm_c_dout2_a"; - function = "tdm_c"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_c_dout2_z_pins: tdm-c-dout2-z { - mux { - groups = "tdm_c_dout2_z"; - function = "tdm_c"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_c_dout3_a_pins: tdm-c-dout3-a { - mux { - groups = "tdm_c_dout3_a"; - function = "tdm_c"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_c_dout3_z_pins: tdm-c-dout3-z { - mux { - groups = "tdm_c_dout3_z"; - function = "tdm_c"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_c_fs_a_pins: tdm-c-fs-a { - mux { - groups = "tdm_c_fs_a"; - function = "tdm_c"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_c_fs_z_pins: tdm-c-fs-z { - mux { - groups = "tdm_c_fs_z"; - function = "tdm_c"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_c_sclk_a_pins: tdm-c-sclk-a { - mux { - groups = "tdm_c_sclk_a"; - function = "tdm_c"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_c_sclk_z_pins: tdm-c-sclk-z { - mux { - groups = "tdm_c_sclk_z"; - function = "tdm_c"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_c_slv_fs_a_pins: tdm-c-slv-fs-a { - mux { - groups = "tdm_c_slv_fs_a"; - function = "tdm_c"; - bias-disable; - }; - }; - - tdm_c_slv_fs_z_pins: tdm-c-slv-fs-z { - mux { - groups = "tdm_c_slv_fs_z"; - function = "tdm_c"; - bias-disable; - }; - }; - - tdm_c_slv_sclk_a_pins: tdm-c-slv-sclk-a { - mux { - groups = "tdm_c_slv_sclk_a"; - function = "tdm_c"; - bias-disable; - }; - }; - - tdm_c_slv_sclk_z_pins: tdm-c-slv-sclk-z { - mux { - groups = "tdm_c_slv_sclk_z"; - function = "tdm_c"; - bias-disable; - }; - }; - - uart_a_pins: uart-a { - mux { - groups = "uart_a_tx", - "uart_a_rx"; - function = "uart_a"; - bias-disable; - }; - }; - - uart_a_cts_rts_pins: uart-a-cts-rts { - mux { - groups = "uart_a_cts", - "uart_a_rts"; - function = "uart_a"; - bias-disable; - }; - }; - - uart_b_pins: uart-b { - mux { - groups = "uart_b_tx", - "uart_b_rx"; - function = "uart_b"; - bias-disable; - }; - }; - - uart_c_pins: uart-c { - mux { - groups = "uart_c_tx", - "uart_c_rx"; - function = "uart_c"; - bias-disable; - }; - }; - - uart_c_cts_rts_pins: uart-c-cts-rts { - mux { - groups = "uart_c_cts", - "uart_c_rts"; - function = "uart_c"; - bias-disable; - }; - }; - }; - }; - - usb2_phy0: phy@36000 { - compatible = "amlogic,g12a-usb2-phy"; - reg = <0x0 0x36000 0x0 0x2000>; - clocks = <&xtal>; - clock-names = "xtal"; - resets = <&reset RESET_USB_PHY20>; - reset-names = "phy"; - #phy-cells = <0>; - }; - - dmc: bus@38000 { - compatible = "simple-bus"; - reg = <0x0 0x38000 0x0 0x400>; - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x0 0x0 0x38000 0x0 0x400>; - - canvas: video-lut@48 { - compatible = "amlogic,canvas"; - reg = <0x0 0x48 0x0 0x14>; - }; - }; - - usb2_phy1: phy@3a000 { - compatible = "amlogic,g12a-usb2-phy"; - reg = <0x0 0x3a000 0x0 0x2000>; - clocks = <&xtal>; - clock-names = "xtal"; - resets = <&reset RESET_USB_PHY21>; - reset-names = "phy"; - #phy-cells = <0>; - }; - - hiu: bus@3c000 { - compatible = "simple-bus"; - reg = <0x0 0x3c000 0x0 0x1400>; - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x0 0x0 0x3c000 0x0 0x1400>; - - hhi: system-controller@0 { - compatible = "amlogic,meson-gx-hhi-sysctrl", - "simple-mfd", "syscon"; - reg = <0 0 0 0x400>; - - clkc: clock-controller { - compatible = "amlogic,g12a-clkc"; - #clock-cells = <1>; - clocks = <&xtal>; - clock-names = "xtal"; - }; - }; - }; - - pdm: audio-controller@40000 { - compatible = "amlogic,g12a-pdm", - "amlogic,axg-pdm"; - reg = <0x0 0x40000 0x0 0x34>; - #sound-dai-cells = <0>; - sound-name-prefix = "PDM"; - clocks = <&clkc_audio AUD_CLKID_PDM>, - <&clkc_audio AUD_CLKID_PDM_DCLK>, - <&clkc_audio AUD_CLKID_PDM_SYSCLK>; - clock-names = "pclk", "dclk", "sysclk"; - status = "disabled"; - }; - - audio: bus@42000 { - compatible = "simple-bus"; - reg = <0x0 0x42000 0x0 0x2000>; - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x0 0x0 0x42000 0x0 0x2000>; - - clkc_audio: clock-controller@0 { - status = "disabled"; - compatible = "amlogic,g12a-audio-clkc"; - reg = <0x0 0x0 0x0 0xb4>; - #clock-cells = <1>; - - clocks = <&clkc CLKID_AUDIO>, - <&clkc CLKID_MPLL0>, - <&clkc CLKID_MPLL1>, - <&clkc CLKID_MPLL2>, - <&clkc CLKID_MPLL3>, - <&clkc CLKID_HIFI_PLL>, - <&clkc CLKID_FCLK_DIV3>, - <&clkc CLKID_FCLK_DIV4>, - <&clkc CLKID_GP0_PLL>; - clock-names = "pclk", - "mst_in0", - "mst_in1", - "mst_in2", - "mst_in3", - "mst_in4", - "mst_in5", - "mst_in6", - "mst_in7"; - - resets = <&reset RESET_AUDIO>; - }; - - toddr_a: audio-controller@100 { - compatible = "amlogic,g12a-toddr", - "amlogic,axg-toddr"; - reg = <0x0 0x100 0x0 0x1c>; - #sound-dai-cells = <0>; - sound-name-prefix = "TODDR_A"; - interrupts = ; - clocks = <&clkc_audio AUD_CLKID_TODDR_A>; - resets = <&arb AXG_ARB_TODDR_A>; - status = "disabled"; - }; - - toddr_b: audio-controller@140 { - compatible = "amlogic,g12a-toddr", - "amlogic,axg-toddr"; - reg = <0x0 0x140 0x0 0x1c>; - #sound-dai-cells = <0>; - sound-name-prefix = "TODDR_B"; - interrupts = ; - clocks = <&clkc_audio AUD_CLKID_TODDR_B>; - resets = <&arb AXG_ARB_TODDR_B>; - status = "disabled"; - }; - - toddr_c: audio-controller@180 { - compatible = "amlogic,g12a-toddr", - "amlogic,axg-toddr"; - reg = <0x0 0x180 0x0 0x1c>; - #sound-dai-cells = <0>; - sound-name-prefix = "TODDR_C"; - interrupts = ; - clocks = <&clkc_audio AUD_CLKID_TODDR_C>; - resets = <&arb AXG_ARB_TODDR_C>; - status = "disabled"; - }; - - frddr_a: audio-controller@1c0 { - compatible = "amlogic,g12a-frddr", - "amlogic,axg-frddr"; - reg = <0x0 0x1c0 0x0 0x1c>; - #sound-dai-cells = <0>; - sound-name-prefix = "FRDDR_A"; - interrupts = ; - clocks = <&clkc_audio AUD_CLKID_FRDDR_A>; - resets = <&arb AXG_ARB_FRDDR_A>; - status = "disabled"; - }; - - frddr_b: audio-controller@200 { - compatible = "amlogic,g12a-frddr", - "amlogic,axg-frddr"; - reg = <0x0 0x200 0x0 0x1c>; - #sound-dai-cells = <0>; - sound-name-prefix = "FRDDR_B"; - interrupts = ; - clocks = <&clkc_audio AUD_CLKID_FRDDR_B>; - resets = <&arb AXG_ARB_FRDDR_B>; - status = "disabled"; - }; - - frddr_c: audio-controller@240 { - compatible = "amlogic,g12a-frddr", - "amlogic,axg-frddr"; - reg = <0x0 0x240 0x0 0x1c>; - #sound-dai-cells = <0>; - sound-name-prefix = "FRDDR_C"; - interrupts = ; - clocks = <&clkc_audio AUD_CLKID_FRDDR_C>; - resets = <&arb AXG_ARB_FRDDR_C>; - status = "disabled"; - }; - - arb: reset-controller@280 { - status = "disabled"; - compatible = "amlogic,meson-axg-audio-arb"; - reg = <0x0 0x280 0x0 0x4>; - #reset-cells = <1>; - clocks = <&clkc_audio AUD_CLKID_DDR_ARB>; - }; - - tdmin_a: audio-controller@300 { - compatible = "amlogic,g12a-tdmin", - "amlogic,axg-tdmin"; - reg = <0x0 0x300 0x0 0x40>; - sound-name-prefix = "TDMIN_A"; - clocks = <&clkc_audio AUD_CLKID_TDMIN_A>, - <&clkc_audio AUD_CLKID_TDMIN_A_SCLK>, - <&clkc_audio AUD_CLKID_TDMIN_A_SCLK_SEL>, - <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>, - <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>; - clock-names = "pclk", "sclk", "sclk_sel", - "lrclk", "lrclk_sel"; - status = "disabled"; - }; - - tdmin_b: audio-controller@340 { - compatible = "amlogic,g12a-tdmin", - "amlogic,axg-tdmin"; - reg = <0x0 0x340 0x0 0x40>; - sound-name-prefix = "TDMIN_B"; - clocks = <&clkc_audio AUD_CLKID_TDMIN_B>, - <&clkc_audio AUD_CLKID_TDMIN_B_SCLK>, - <&clkc_audio AUD_CLKID_TDMIN_B_SCLK_SEL>, - <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>, - <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>; - clock-names = "pclk", "sclk", "sclk_sel", - "lrclk", "lrclk_sel"; - status = "disabled"; - }; - - tdmin_c: audio-controller@380 { - compatible = "amlogic,g12a-tdmin", - "amlogic,axg-tdmin"; - reg = <0x0 0x380 0x0 0x40>; - sound-name-prefix = "TDMIN_C"; - clocks = <&clkc_audio AUD_CLKID_TDMIN_C>, - <&clkc_audio AUD_CLKID_TDMIN_C_SCLK>, - <&clkc_audio AUD_CLKID_TDMIN_C_SCLK_SEL>, - <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>, - <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>; - clock-names = "pclk", "sclk", "sclk_sel", - "lrclk", "lrclk_sel"; - status = "disabled"; - }; - - tdmin_lb: audio-controller@3c0 { - compatible = "amlogic,g12a-tdmin", - "amlogic,axg-tdmin"; - reg = <0x0 0x3c0 0x0 0x40>; - sound-name-prefix = "TDMIN_LB"; - clocks = <&clkc_audio AUD_CLKID_TDMIN_LB>, - <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK>, - <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK_SEL>, - <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>, - <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>; - clock-names = "pclk", "sclk", "sclk_sel", - "lrclk", "lrclk_sel"; - status = "disabled"; - }; - - spdifin: audio-controller@400 { - compatible = "amlogic,g12a-spdifin", - "amlogic,axg-spdifin"; - reg = <0x0 0x400 0x0 0x30>; - #sound-dai-cells = <0>; - sound-name-prefix = "SPDIFIN"; - interrupts = ; - clocks = <&clkc_audio AUD_CLKID_SPDIFIN>, - <&clkc_audio AUD_CLKID_SPDIFIN_CLK>; - clock-names = "pclk", "refclk"; - status = "disabled"; - }; - - spdifout: audio-controller@480 { - compatible = "amlogic,g12a-spdifout", - "amlogic,axg-spdifout"; - reg = <0x0 0x480 0x0 0x50>; - #sound-dai-cells = <0>; - sound-name-prefix = "SPDIFOUT"; - clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>, - <&clkc_audio AUD_CLKID_SPDIFOUT_CLK>; - clock-names = "pclk", "mclk"; - status = "disabled"; - }; - - tdmout_a: audio-controller@500 { - compatible = "amlogic,g12a-tdmout"; - reg = <0x0 0x500 0x0 0x40>; - sound-name-prefix = "TDMOUT_A"; - clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>, - <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>, - <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>, - <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>, - <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>; - clock-names = "pclk", "sclk", "sclk_sel", - "lrclk", "lrclk_sel"; - status = "disabled"; - }; - - tdmout_b: audio-controller@540 { - compatible = "amlogic,g12a-tdmout"; - reg = <0x0 0x540 0x0 0x40>; - sound-name-prefix = "TDMOUT_B"; - clocks = <&clkc_audio AUD_CLKID_TDMOUT_B>, - <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK>, - <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK_SEL>, - <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>, - <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>; - clock-names = "pclk", "sclk", "sclk_sel", - "lrclk", "lrclk_sel"; - status = "disabled"; - }; - - tdmout_c: audio-controller@580 { - compatible = "amlogic,g12a-tdmout"; - reg = <0x0 0x580 0x0 0x40>; - sound-name-prefix = "TDMOUT_C"; - clocks = <&clkc_audio AUD_CLKID_TDMOUT_C>, - <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK>, - <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK_SEL>, - <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>, - <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>; - clock-names = "pclk", "sclk", "sclk_sel", - "lrclk", "lrclk_sel"; - status = "disabled"; - }; - - spdifout_b: audio-controller@680 { - compatible = "amlogic,g12a-spdifout", - "amlogic,axg-spdifout"; - reg = <0x0 0x680 0x0 0x50>; - #sound-dai-cells = <0>; - sound-name-prefix = "SPDIFOUT_B"; - clocks = <&clkc_audio AUD_CLKID_SPDIFOUT_B>, - <&clkc_audio AUD_CLKID_SPDIFOUT_B_CLK>; - clock-names = "pclk", "mclk"; - status = "disabled"; - }; - - tohdmitx: audio-controller@744 { - compatible = "amlogic,g12a-tohdmitx"; - reg = <0x0 0x744 0x0 0x4>; - #sound-dai-cells = <1>; - sound-name-prefix = "TOHDMITX"; - status = "disabled"; - }; - }; - - usb3_pcie_phy: phy@46000 { - compatible = "amlogic,g12a-usb3-pcie-phy"; - reg = <0x0 0x46000 0x0 0x2000>; - clocks = <&clkc CLKID_PCIE_PLL>; - clock-names = "ref_clk"; - resets = <&reset RESET_PCIE_PHY>; - reset-names = "phy"; - assigned-clocks = <&clkc CLKID_PCIE_PLL>; - assigned-clock-rates = <100000000>; - #phy-cells = <1>; - }; - - eth_phy: mdio-multiplexer@4c000 { - compatible = "amlogic,g12a-mdio-mux"; - reg = <0x0 0x4c000 0x0 0xa4>; - clocks = <&clkc CLKID_ETH_PHY>, - <&xtal>, - <&clkc CLKID_MPLL_50M>; - clock-names = "pclk", "clkin0", "clkin1"; - mdio-parent-bus = <&mdio0>; - #address-cells = <1>; - #size-cells = <0>; - - ext_mdio: mdio@0 { - reg = <0>; - #address-cells = <1>; - #size-cells = <0>; - }; - - int_mdio: mdio@1 { - reg = <1>; - #address-cells = <1>; - #size-cells = <0>; - - internal_ephy: ethernet_phy@8 { - compatible = "ethernet-phy-id0180.3301", - "ethernet-phy-ieee802.3-c22"; - interrupts = ; - reg = <8>; - max-speed = <100>; - }; - }; - }; - }; - - aobus: bus@ff800000 { - compatible = "simple-bus"; - reg = <0x0 0xff800000 0x0 0x100000>; - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x0 0x0 0xff800000 0x0 0x100000>; - - rti: sys-ctrl@0 { - compatible = "amlogic,meson-gx-ao-sysctrl", - "simple-mfd", "syscon"; - reg = <0x0 0x0 0x0 0x100>; - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x0 0x0 0x0 0x0 0x100>; - - clkc_AO: clock-controller { - compatible = "amlogic,meson-g12a-aoclkc"; - #clock-cells = <1>; - #reset-cells = <1>; - clocks = <&xtal>, <&clkc CLKID_CLK81>; - clock-names = "xtal", "mpeg-clk"; - }; - - pwrc_vpu: power-controller-vpu { - compatible = "amlogic,meson-g12a-pwrc-vpu"; - #power-domain-cells = <0>; - amlogic,hhi-sysctrl = <&hhi>; - resets = <&reset RESET_VIU>, - <&reset RESET_VENC>, - <&reset RESET_VCBUS>, - <&reset RESET_BT656>, - <&reset RESET_RDMA>, - <&reset RESET_VENCI>, - <&reset RESET_VENCP>, - <&reset RESET_VDAC>, - <&reset RESET_VDI6>, - <&reset RESET_VENCL>, - <&reset RESET_VID_LOCK>; - clocks = <&clkc CLKID_VPU>, - <&clkc CLKID_VAPB>; - clock-names = "vpu", "vapb"; - /* - * VPU clocking is provided by two identical clock paths - * VPU_0 and VPU_1 muxed to a single clock by a glitch - * free mux to safely change frequency while running. - * Same for VAPB but with a final gate after the glitch free mux. - */ - assigned-clocks = <&clkc CLKID_VPU_0_SEL>, - <&clkc CLKID_VPU_0>, - <&clkc CLKID_VPU>, /* Glitch free mux */ - <&clkc CLKID_VAPB_0_SEL>, - <&clkc CLKID_VAPB_0>, - <&clkc CLKID_VAPB_SEL>; /* Glitch free mux */ - assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>, - <0>, /* Do Nothing */ - <&clkc CLKID_VPU_0>, - <&clkc CLKID_FCLK_DIV4>, - <0>, /* Do Nothing */ - <&clkc CLKID_VAPB_0>; - assigned-clock-rates = <0>, /* Do Nothing */ - <666666666>, - <0>, /* Do Nothing */ - <0>, /* Do Nothing */ - <250000000>, - <0>; /* Do Nothing */ - }; - - ao_pinctrl: pinctrl@14 { - compatible = "amlogic,meson-g12a-aobus-pinctrl"; - #address-cells = <2>; - #size-cells = <2>; - ranges; - - gpio_ao: bank@14 { - reg = <0x0 0x14 0x0 0x8>, - <0x0 0x1c 0x0 0x8>, - <0x0 0x24 0x0 0x14>; - reg-names = "mux", - "ds", - "gpio"; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&ao_pinctrl 0 0 15>; - }; - - i2c_ao_sck_pins: i2c_ao_sck_pins { - mux { - groups = "i2c_ao_sck"; - function = "i2c_ao"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c_ao_sda_pins: i2c_ao_sda { - mux { - groups = "i2c_ao_sda"; - function = "i2c_ao"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c_ao_sck_e_pins: i2c_ao_sck_e { - mux { - groups = "i2c_ao_sck_e"; - function = "i2c_ao"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - i2c_ao_sda_e_pins: i2c_ao_sda_e { - mux { - groups = "i2c_ao_sda_e"; - function = "i2c_ao"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - mclk0_ao_pins: mclk0-ao { - mux { - groups = "mclk0_ao"; - function = "mclk0_ao"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_ao_b_din0_pins: tdm-ao-b-din0 { - mux { - groups = "tdm_ao_b_din0"; - function = "tdm_ao_b"; - bias-disable; - }; - }; - - spdif_ao_out_pins: spdif-ao-out { - mux { - groups = "spdif_ao_out"; - function = "spdif_ao_out"; - drive-strength-microamp = <500>; - bias-disable; - }; - }; - - tdm_ao_b_din1_pins: tdm-ao-b-din1 { - mux { - groups = "tdm_ao_b_din1"; - function = "tdm_ao_b"; - bias-disable; - }; - }; - - tdm_ao_b_din2_pins: tdm-ao-b-din2 { - mux { - groups = "tdm_ao_b_din2"; - function = "tdm_ao_b"; - bias-disable; - }; - }; - - tdm_ao_b_dout0_pins: tdm-ao-b-dout0 { - mux { - groups = "tdm_ao_b_dout0"; - function = "tdm_ao_b"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_ao_b_dout1_pins: tdm-ao-b-dout1 { - mux { - groups = "tdm_ao_b_dout1"; - function = "tdm_ao_b"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_ao_b_dout2_pins: tdm-ao-b-dout2 { - mux { - groups = "tdm_ao_b_dout2"; - function = "tdm_ao_b"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_ao_b_fs_pins: tdm-ao-b-fs { - mux { - groups = "tdm_ao_b_fs"; - function = "tdm_ao_b"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_ao_b_sclk_pins: tdm-ao-b-sclk { - mux { - groups = "tdm_ao_b_sclk"; - function = "tdm_ao_b"; - bias-disable; - drive-strength-microamp = <3000>; - }; - }; - - tdm_ao_b_slv_fs_pins: tdm-ao-b-slv-fs { - mux { - groups = "tdm_ao_b_slv_fs"; - function = "tdm_ao_b"; - bias-disable; - }; - }; - - tdm_ao_b_slv_sclk_pins: tdm-ao-b-slv-sclk { - mux { - groups = "tdm_ao_b_slv_sclk"; - function = "tdm_ao_b"; - bias-disable; - }; - }; - - uart_ao_a_pins: uart-a-ao { - mux { - groups = "uart_ao_a_tx", - "uart_ao_a_rx"; - function = "uart_ao_a"; - bias-disable; - }; - }; - - uart_ao_a_cts_rts_pins: uart-ao-a-cts-rts { - mux { - groups = "uart_ao_a_cts", - "uart_ao_a_rts"; - function = "uart_ao_a"; - bias-disable; - }; - }; - - pwm_ao_a_pins: pwm-ao-a { - mux { - groups = "pwm_ao_a"; - function = "pwm_ao_a"; - bias-disable; - }; - }; - - pwm_ao_b_pins: pwm-ao-b { - mux { - groups = "pwm_ao_b"; - function = "pwm_ao_b"; - bias-disable; - }; - }; - - pwm_ao_c_4_pins: pwm-ao-c-4 { - mux { - groups = "pwm_ao_c_4"; - function = "pwm_ao_c"; - bias-disable; - }; - }; - - pwm_ao_c_6_pins: pwm-ao-c-6 { - mux { - groups = "pwm_ao_c_6"; - function = "pwm_ao_c"; - bias-disable; - }; - }; - - pwm_ao_d_5_pins: pwm-ao-d-5 { - mux { - groups = "pwm_ao_d_5"; - function = "pwm_ao_d"; - bias-disable; - }; - }; - - pwm_ao_d_10_pins: pwm-ao-d-10 { - mux { - groups = "pwm_ao_d_10"; - function = "pwm_ao_d"; - bias-disable; - }; - }; - - pwm_ao_d_e_pins: pwm-ao-d-e { - mux { - groups = "pwm_ao_d_e"; - function = "pwm_ao_d"; - }; - }; - - remote_input_ao_pins: remote-input-ao { - mux { - groups = "remote_ao_input"; - function = "remote_ao_input"; - bias-disable; - }; - }; - }; - }; - - cec_AO: cec@100 { - compatible = "amlogic,meson-gx-ao-cec"; - reg = <0x0 0x00100 0x0 0x14>; - interrupts = ; - clocks = <&clkc_AO CLKID_AO_CEC>; - clock-names = "core"; - status = "disabled"; - }; - - sec_AO: ao-secure@140 { - compatible = "amlogic,meson-gx-ao-secure", "syscon"; - reg = <0x0 0x140 0x0 0x140>; - amlogic,has-chip-id; - }; - - cecb_AO: cec@280 { - compatible = "amlogic,meson-g12a-ao-cec"; - reg = <0x0 0x00280 0x0 0x1c>; - interrupts = ; - clocks = <&clkc_AO CLKID_AO_CTS_OSCIN>; - clock-names = "oscin"; - status = "disabled"; - }; - - pwm_AO_cd: pwm@2000 { - compatible = "amlogic,meson-g12a-ao-pwm-cd"; - reg = <0x0 0x2000 0x0 0x20>; - #pwm-cells = <3>; - status = "disabled"; - }; - - uart_AO: serial@3000 { - compatible = "amlogic,meson-gx-uart", - "amlogic,meson-ao-uart"; - reg = <0x0 0x3000 0x0 0x18>; - interrupts = ; - clocks = <&xtal>, <&clkc_AO CLKID_AO_UART>, <&xtal>; - clock-names = "xtal", "pclk", "baud"; - status = "disabled"; - }; - - uart_AO_B: serial@4000 { - compatible = "amlogic,meson-gx-uart", - "amlogic,meson-ao-uart"; - reg = <0x0 0x4000 0x0 0x18>; - interrupts = ; - clocks = <&xtal>, <&clkc_AO CLKID_AO_UART2>, <&xtal>; - clock-names = "xtal", "pclk", "baud"; - status = "disabled"; - }; - - i2c_AO: i2c@5000 { - compatible = "amlogic,meson-axg-i2c"; - status = "disabled"; - reg = <0x0 0x05000 0x0 0x20>; - interrupts = ; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clkc CLKID_I2C>; - }; - - pwm_AO_ab: pwm@7000 { - compatible = "amlogic,meson-g12a-ao-pwm-ab"; - reg = <0x0 0x7000 0x0 0x20>; - #pwm-cells = <3>; - status = "disabled"; - }; - - ir: ir@8000 { - compatible = "amlogic,meson-gxbb-ir"; - reg = <0x0 0x8000 0x0 0x20>; - interrupts = ; - status = "disabled"; - }; - - saradc: adc@9000 { - compatible = "amlogic,meson-g12a-saradc", - "amlogic,meson-saradc"; - reg = <0x0 0x9000 0x0 0x48>; - #io-channel-cells = <1>; - interrupts = ; - clocks = <&xtal>, - <&clkc_AO CLKID_AO_SAR_ADC>, - <&clkc_AO CLKID_AO_SAR_ADC_CLK>, - <&clkc_AO CLKID_AO_SAR_ADC_SEL>; - clock-names = "clkin", "core", "adc_clk", "adc_sel"; - status = "disabled"; - }; - }; - - vpu: vpu@ff900000 { - compatible = "amlogic,meson-g12a-vpu"; - reg = <0x0 0xff900000 0x0 0x100000>, - <0x0 0xff63c000 0x0 0x1000>; - reg-names = "vpu", "hhi"; - interrupts = ; - #address-cells = <1>; - #size-cells = <0>; - amlogic,canvas = <&canvas>; - power-domains = <&pwrc_vpu>; - - /* CVBS VDAC output port */ - cvbs_vdac_port: port@0 { - reg = <0>; - }; - - /* HDMI-TX output port */ - hdmi_tx_port: port@1 { - reg = <1>; - - hdmi_tx_out: endpoint { - remote-endpoint = <&hdmi_tx_in>; - }; - }; - }; - - gic: interrupt-controller@ffc01000 { - compatible = "arm,gic-400"; - reg = <0x0 0xffc01000 0 0x1000>, - <0x0 0xffc02000 0 0x2000>, - <0x0 0xffc04000 0 0x2000>, - <0x0 0xffc06000 0 0x2000>; - interrupt-controller; - interrupts = ; - #interrupt-cells = <3>; - #address-cells = <0>; - }; - - cbus: bus@ffd00000 { - compatible = "simple-bus"; - reg = <0x0 0xffd00000 0x0 0x100000>; - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x0 0x0 0xffd00000 0x0 0x100000>; - - reset: reset-controller@1004 { - compatible = "amlogic,meson-g12a-reset", - "amlogic,meson-axg-reset"; - reg = <0x0 0x1004 0x0 0x9c>; - #reset-cells = <1>; - }; - - gpio_intc: interrupt-controller@f080 { - compatible = "amlogic,meson-g12a-gpio-intc", - "amlogic,meson-gpio-intc"; - reg = <0x0 0xf080 0x0 0x10>; - interrupt-controller; - #interrupt-cells = <2>; - amlogic,channel-interrupts = <64 65 66 67 68 69 70 71>; - }; - - pwm_ef: pwm@19000 { - compatible = "amlogic,meson-g12a-ee-pwm"; - reg = <0x0 0x19000 0x0 0x20>; - #pwm-cells = <3>; - status = "disabled"; - }; - - pwm_cd: pwm@1a000 { - compatible = "amlogic,meson-g12a-ee-pwm"; - reg = <0x0 0x1a000 0x0 0x20>; - #pwm-cells = <3>; - status = "disabled"; - }; - - pwm_ab: pwm@1b000 { - compatible = "amlogic,meson-g12a-ee-pwm"; - reg = <0x0 0x1b000 0x0 0x20>; - #pwm-cells = <3>; - status = "disabled"; - }; - - i2c3: i2c@1c000 { - compatible = "amlogic,meson-axg-i2c"; - status = "disabled"; - reg = <0x0 0x1c000 0x0 0x20>; - interrupts = ; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clkc CLKID_I2C>; - }; - - i2c2: i2c@1d000 { - compatible = "amlogic,meson-axg-i2c"; - status = "disabled"; - reg = <0x0 0x1d000 0x0 0x20>; - interrupts = ; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clkc CLKID_I2C>; - }; - - i2c1: i2c@1e000 { - compatible = "amlogic,meson-axg-i2c"; - status = "disabled"; - reg = <0x0 0x1e000 0x0 0x20>; - interrupts = ; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clkc CLKID_I2C>; - }; - - i2c0: i2c@1f000 { - compatible = "amlogic,meson-axg-i2c"; - status = "disabled"; - reg = <0x0 0x1f000 0x0 0x20>; - interrupts = ; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clkc CLKID_I2C>; - }; - - clk_msr: clock-measure@18000 { - compatible = "amlogic,meson-g12a-clk-measure"; - reg = <0x0 0x18000 0x0 0x10>; - }; - - uart_C: serial@22000 { - compatible = "amlogic,meson-gx-uart"; - reg = <0x0 0x22000 0x0 0x18>; - interrupts = ; - clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>; - clock-names = "xtal", "pclk", "baud"; - status = "disabled"; - }; - - uart_B: serial@23000 { - compatible = "amlogic,meson-gx-uart"; - reg = <0x0 0x23000 0x0 0x18>; - interrupts = ; - clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>; - clock-names = "xtal", "pclk", "baud"; - status = "disabled"; - }; - - uart_A: serial@24000 { - compatible = "amlogic,meson-gx-uart"; - reg = <0x0 0x24000 0x0 0x18>; - interrupts = ; - clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>; - clock-names = "xtal", "pclk", "baud"; - status = "disabled"; - }; - }; - - sd_emmc_a: sd@ffe03000 { - compatible = "amlogic,meson-axg-mmc"; - reg = <0x0 0xffe03000 0x0 0x800>; - interrupts = ; - status = "disabled"; - clocks = <&clkc CLKID_SD_EMMC_A>, - <&clkc CLKID_SD_EMMC_A_CLK0>, - <&clkc CLKID_FCLK_DIV2>; - clock-names = "core", "clkin0", "clkin1"; - resets = <&reset RESET_SD_EMMC_A>; - amlogic,dram-access-quirk; - }; - - sd_emmc_b: sd@ffe05000 { - compatible = "amlogic,meson-axg-mmc"; - reg = <0x0 0xffe05000 0x0 0x800>; - interrupts = ; - status = "disabled"; - clocks = <&clkc CLKID_SD_EMMC_B>, - <&clkc CLKID_SD_EMMC_B_CLK0>, - <&clkc CLKID_FCLK_DIV2>; - clock-names = "core", "clkin0", "clkin1"; - resets = <&reset RESET_SD_EMMC_B>; - }; - - sd_emmc_c: mmc@ffe07000 { - compatible = "amlogic,meson-axg-mmc"; - reg = <0x0 0xffe07000 0x0 0x800>; - interrupts = ; - status = "disabled"; - clocks = <&clkc CLKID_SD_EMMC_C>, - <&clkc CLKID_SD_EMMC_C_CLK0>, - <&clkc CLKID_FCLK_DIV2>; - clock-names = "core", "clkin0", "clkin1"; - resets = <&reset RESET_SD_EMMC_C>; - }; - - usb: usb@ffe09000 { - status = "disabled"; - compatible = "amlogic,meson-g12a-usb-ctrl"; - reg = <0x0 0xffe09000 0x0 0xa0>; - interrupts = ; - #address-cells = <2>; - #size-cells = <2>; - ranges; - - clocks = <&clkc CLKID_USB>; - resets = <&reset RESET_USB>; - - dr_mode = "otg"; - - phys = <&usb2_phy0>, <&usb2_phy1>, - <&usb3_pcie_phy PHY_TYPE_USB3>; - phy-names = "usb2-phy0", "usb2-phy1", "usb3-phy0"; - - dwc2: usb@ff400000 { - compatible = "amlogic,meson-g12a-usb", "snps,dwc2"; - reg = <0x0 0xff400000 0x0 0x40000>; - interrupts = ; - clocks = <&clkc CLKID_USB1_DDR_BRIDGE>; - clock-names = "ddr"; - phys = <&usb2_phy1>; - dr_mode = "peripheral"; - g-rx-fifo-size = <192>; - g-np-tx-fifo-size = <128>; - g-tx-fifo-size = <128 128 16 16 16>; - }; - - dwc3: usb@ff500000 { - compatible = "snps,dwc3"; - reg = <0x0 0xff500000 0x0 0x100000>; - interrupts = ; - dr_mode = "host"; - snps,dis_u2_susphy_quirk; - snps,quirk-frame-length-adjustment; - }; - }; - - mali: gpu@ffe40000 { - compatible = "amlogic,meson-g12a-mali", "arm,mali-bifrost"; - reg = <0x0 0xffe40000 0x0 0x40000>; - interrupt-parent = <&gic>; - interrupts = , - , - ; - interrupt-names = "gpu", "mmu", "job"; - clocks = <&clkc CLKID_MALI>; - resets = <&reset RESET_DVALIN_CAPB3>, <&reset RESET_DVALIN>; - - /* - * Mali clocking is provided by two identical clock paths - * MALI_0 and MALI_1 muxed to a single clock by a glitch - * free mux to safely change frequency while running. - */ - assigned-clocks = <&clkc CLKID_MALI_0_SEL>, - <&clkc CLKID_MALI_0>, - <&clkc CLKID_MALI>; /* Glitch free mux */ - assigned-clock-parents = <&clkc CLKID_FCLK_DIV2P5>, - <0>, /* Do Nothing */ - <&clkc CLKID_MALI_0>; - assigned-clock-rates = <0>, /* Do Nothing */ - <800000000>, - <0>; /* Do Nothing */ - }; - }; - - timer { - compatible = "arm,armv8-timer"; - interrupts = , - , - , - ; - }; - - xtal: xtal-clk { - compatible = "fixed-clock"; - clock-frequency = <24000000>; - clock-output-names = "xtal"; - #clock-cells = <0>; - }; - +}; + +&sd_emmc_a { + amlogic,dram-access-quirk; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dts new file mode 100644 index 000000000000..73128ed24361 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dts @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS + * Author: Neil Armstrong + * Copyright (c) 2019 Christian Hewitt + */ + +/dts-v1/; + +#include "meson-g12b-a311d.dtsi" +#include "meson-g12b-khadas-vim3.dtsi" + +/ { + compatible = "khadas,vim3", "amlogic,a311d", "amlogic,g12b"; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi new file mode 100644 index 000000000000..d61f43052a34 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS + * Author: Neil Armstrong + */ + +#include "meson-g12b.dtsi" + +/ { + cpu_opp_table_0: opp-table-0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <731000>; + }; + + opp-250000000 { + opp-hz = /bits/ 64 <250000000>; + opp-microvolt = <731000>; + }; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <731000>; + }; + + opp-667000000 { + opp-hz = /bits/ 64 <667000000>; + opp-microvolt = <731000>; + }; + + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <761000>; + }; + + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <781000>; + }; + + opp-1398000000 { + opp-hz = /bits/ 64 <1398000000>; + opp-microvolt = <811000>; + }; + + opp-1512000000 { + opp-hz = /bits/ 64 <1512000000>; + opp-microvolt = <861000>; + }; + + opp-1608000000 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <901000>; + }; + + opp-1704000000 { + opp-hz = /bits/ 64 <1704000000>; + opp-microvolt = <951000>; + }; + + opp-1800000000 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <1001000>; + }; + }; + + cpub_opp_table_1: opp-table-1 { + compatible = "operating-points-v2"; + opp-shared; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <731000>; + }; + + opp-250000000 { + opp-hz = /bits/ 64 <250000000>; + opp-microvolt = <731000>; + }; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <731000>; + }; + + opp-667000000 { + opp-hz = /bits/ 64 <667000000>; + opp-microvolt = <731000>; + }; + + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <731000>; + }; + + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <751000>; + }; + + opp-1398000000 { + opp-hz = /bits/ 64 <1398000000>; + opp-microvolt = <771000>; + }; + + opp-1512000000 { + opp-hz = /bits/ 64 <1512000000>; + opp-microvolt = <771000>; + }; + + opp-1608000000 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <781000>; + }; + + opp-1704000000 { + opp-hz = /bits/ 64 <1704000000>; + opp-microvolt = <791000>; + }; + + opp-1800000000 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <831000>; + }; + + opp-1908000000 { + opp-hz = /bits/ 64 <1908000000>; + opp-microvolt = <861000>; + }; + + opp-2016000000 { + opp-hz = /bits/ 64 <2016000000>; + opp-microvolt = <911000>; + }; + + opp-2108000000 { + opp-hz = /bits/ 64 <2108000000>; + opp-microvolt = <951000>; + }; + + opp-2208000000 { + opp-hz = /bits/ 64 <2208000000>; + opp-microvolt = <1011000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi new file mode 100644 index 000000000000..9c3ca2edc725 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi @@ -0,0 +1,544 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS + * Author: Neil Armstrong + * Copyright (c) 2019 Christian Hewitt + */ + +#include +#include +#include + +/ { + model = "Khadas VIM3"; + + aliases { + serial0 = &uart_AO; + ethernet0 = ðmac; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 2>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1710000>; + + button-function { + label = "Function"; + linux,code = ; + press-threshold-microvolt = <10000>; + }; + }; + + leds { + compatible = "gpio-leds"; + + white { + label = "vim3:white:sys"; + gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + + red { + label = "vim3:red"; + gpios = <&gpio_expander 5 GPIO_ACTIVE_LOW>; + }; + }; + + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + poll-interval = <100>; + + power-button { + label = "power"; + linux,code = ; + gpios = <&gpio_ao GPIOAO_7 GPIO_ACTIVE_LOW>; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; + clocks = <&wifi32k>; + clock-names = "ext_clock"; + }; + + dc_in: regulator-dc_in { + compatible = "regulator-fixed"; + regulator-name = "DC_IN"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + vcc_5v: regulator-vcc_5v { + compatible = "regulator-fixed"; + regulator-name = "VCC_5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_in>; + + gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>; + enable-active-high; + }; + + vcc_1v8: regulator-vcc_1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_3v3>; + regulator-always-on; + }; + + vcc_3v3: regulator-vcc_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vsys_3v3>; + regulator-always-on; + /* FIXME: actually controlled by VDDCPU_B_EN */ + }; + + vddcpu_a: regulator-vddcpu-a { + /* + * MP8756GD Regulator. + */ + compatible = "pwm-regulator"; + + regulator-name = "VDDCPU_A"; + regulator-min-microvolt = <690000>; + regulator-max-microvolt = <1050000>; + + vin-supply = <&dc_in>; + + pwms = <&pwm_ab 0 1250 0>; + pwm-dutycycle-range = <100 0>; + + regulator-boot-on; + regulator-always-on; + }; + + vddcpu_b: regulator-vddcpu-b { + /* + * Silergy SY8030DEC Regulator. + */ + compatible = "pwm-regulator"; + + regulator-name = "VDDCPU_B"; + regulator-min-microvolt = <690000>; + regulator-max-microvolt = <1050000>; + + vin-supply = <&vsys_3v3>; + + pwms = <&pwm_AO_cd 1 1250 0>; + pwm-dutycycle-range = <100 0>; + + regulator-boot-on; + regulator-always-on; + }; + + vddao_1v8: regulator-vddao_1v8 { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_AO1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vsys_3v3>; + regulator-always-on; + }; + + emmc_1v8: regulator-emmc_1v8 { + compatible = "regulator-fixed"; + regulator-name = "EMMC_AO1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_3v3>; + regulator-always-on; + }; + + vsys_3v3: regulator-vsys_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VSYS_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&dc_in>; + regulator-always-on; + }; + + usb_pwr: regulator-usb_pwr { + compatible = "regulator-fixed"; + regulator-name = "USB_PWR"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_5v>; + + gpio = <&gpio GPIOA_6 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + hdmi-connector { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi_tx_tmds_out>; + }; + }; + }; + + wifi32k: wifi32k { + compatible = "pwm-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */ + }; + + sound { + compatible = "amlogic,axg-sound-card"; + model = "G12A-KHADAS-VIM3"; + audio-aux-devs = <&tdmout_b>; + audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1", + "TDMOUT_B IN 1", "FRDDR_B OUT 1", + "TDMOUT_B IN 2", "FRDDR_C OUT 1", + "TDM_B Playback", "TDMOUT_B OUT"; + + assigned-clocks = <&clkc CLKID_MPLL2>, + <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&frddr_a>; + }; + + dai-link-1 { + sound-dai = <&frddr_b>; + }; + + dai-link-2 { + sound-dai = <&frddr_c>; + }; + + /* 8ch hdmi interface */ + dai-link-3 { + sound-dai = <&tdmif_b>; + dai-format = "i2s"; + dai-tdm-slot-tx-mask-0 = <1 1>; + dai-tdm-slot-tx-mask-1 = <1 1>; + dai-tdm-slot-tx-mask-2 = <1 1>; + dai-tdm-slot-tx-mask-3 = <1 1>; + mclk-fs = <256>; + + codec { + sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>; + }; + }; + + /* hdmi glue */ + dai-link-4 { + sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>; + + codec { + sound-dai = <&hdmi_tx>; + }; + }; + }; +}; + +&arb { + status = "okay"; +}; + +&cec_AO { + pinctrl-0 = <&cec_ao_a_h_pins>; + pinctrl-names = "default"; + status = "disabled"; + hdmi-phandle = <&hdmi_tx>; +}; + +&cecb_AO { + pinctrl-0 = <&cec_ao_b_h_pins>; + pinctrl-names = "default"; + status = "okay"; + hdmi-phandle = <&hdmi_tx>; +}; + +&clkc_audio { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vddcpu_b>; + operating-points-v2 = <&cpu_opp_table_0>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu1 { + cpu-supply = <&vddcpu_b>; + operating-points-v2 = <&cpu_opp_table_0>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu100 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu101 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu102 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu103 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&ext_mdio { + external_phy: ethernet-phy@0 { + /* Realtek RTL8211F (0x001cc916) */ + reg = <0>; + max-speed = <1000>; + + interrupt-parent = <&gpio_intc>; + /* MAC_INTR on GPIOZ_14 */ + interrupts = <26 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +ðmac { + pinctrl-0 = <ð_pins>, <ð_rgmii_pins>; + pinctrl-names = "default"; + status = "okay"; + phy-mode = "rgmii"; + phy-handle = <&external_phy>; + amlogic,tx-delay-ns = <2>; +}; + +&frddr_a { + status = "okay"; +}; + +&frddr_b { + status = "okay"; +}; + +&frddr_c { + status = "okay"; +}; + +&hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>; + pinctrl-names = "default"; + hdmi-supply = <&vcc_5v>; +}; + +&hdmi_tx_tmds_port { + hdmi_tx_tmds_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; +}; + +&i2c_AO { + status = "okay"; + pinctrl-0 = <&i2c_ao_sck_pins>, <&i2c_ao_sda_pins>; + pinctrl-names = "default"; + + gpio_expander: gpio-controller@20 { + compatible = "ti,tca6408"; + reg = <0x20>; + vcc-supply = <&vcc_3v3>; + gpio-controller; + #gpio-cells = <2>; + }; + + rtc@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + #clock-cells = <0>; + }; +}; + +&ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; + linux,rc-map-name = "rc-khadas"; +}; + +&pwm_ab { + pinctrl-0 = <&pwm_a_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin0"; + status = "okay"; +}; + +&pwm_AO_cd { + pinctrl-0 = <&pwm_ao_d_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin1"; + status = "okay"; +}; + +&pwm_ef { + status = "okay"; + pinctrl-0 = <&pwm_e_pins>; + pinctrl-names = "default"; +}; + +&saradc { + status = "okay"; + vref-supply = <&vddao_1v8>; +}; + +/* SDIO */ +&sd_emmc_a { + status = "okay"; + pinctrl-0 = <&sdio_pins>; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + #address-cells = <1>; + #size-cells = <0>; + + bus-width = <4>; + cap-sd-highspeed; + sd-uhs-sdr50; + max-frequency = <100000000>; + + non-removable; + disable-wp; + + mmc-pwrseq = <&sdio_pwrseq>; + + vmmc-supply = <&vsys_3v3>; + vqmmc-supply = <&vddao_1v8>; + + brcmf: wifi@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + }; +}; + +/* SD card */ +&sd_emmc_b { + status = "okay"; + pinctrl-0 = <&sdcard_c_pins>; + pinctrl-1 = <&sdcard_clk_gate_c_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <4>; + cap-sd-highspeed; + max-frequency = <50000000>; + disable-wp; + + cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>; + vmmc-supply = <&vsys_3v3>; + vqmmc-supply = <&vsys_3v3>; +}; + +/* eMMC */ +&sd_emmc_c { + status = "okay"; + pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <8>; + cap-mmc-highspeed; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + max-frequency = <200000000>; + disable-wp; + + mmc-pwrseq = <&emmc_pwrseq>; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&emmc_1v8>; +}; + +&tdmif_b { + status = "okay"; +}; + +&tdmout_b { + status = "okay"; +}; + +&tohdmitx { + status = "okay"; +}; + +&uart_A { + status = "okay"; + pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>; + pinctrl-names = "default"; + uart-has-rtscts; + + bluetooth { + compatible = "brcm,bcm43438-bt"; + shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>; + max-speed = <2000000>; + clocks = <&wifi32k>; + clock-names = "lpo"; + }; +}; + +&uart_AO { + status = "okay"; + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; +}; + +&usb2_phy0 { + phy-supply = <&dc_in>; +}; + +&usb2_phy1 { + phy-supply = <&usb_pwr>; +}; + +&usb3_pcie_phy { + phy-supply = <&usb_pwr>; +}; + +&usb { + status = "okay"; + dr_mode = "peripheral"; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts index 81780ffcc7f0..6cfc2c69bb4f 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts @@ -6,7 +6,7 @@ /dts-v1/; -#include "meson-g12b.dtsi" +#include "meson-g12b-s922x.dtsi" #include #include #include @@ -53,6 +53,7 @@ gpio = <&gpio_ao GPIOAO_8 GPIO_ACTIVE_HIGH>; enable-active-high; + regulator-always-on; }; tf_io: gpio-regulator-tf_io { @@ -114,6 +115,44 @@ /* FIXME: actually controlled by VDDCPU_B_EN */ }; + vddcpu_a: regulator-vddcpu-a { + /* + * MP8756GD Regulator. + */ + compatible = "pwm-regulator"; + + regulator-name = "VDDCPU_A"; + regulator-min-microvolt = <721000>; + regulator-max-microvolt = <1022000>; + + vin-supply = <&main_12v>; + + pwms = <&pwm_ab 0 1250 0>; + pwm-dutycycle-range = <100 0>; + + regulator-boot-on; + regulator-always-on; + }; + + vddcpu_b: regulator-vddcpu-b { + /* + * Silergy SY8120B1ABC Regulator. + */ + compatible = "pwm-regulator"; + + regulator-name = "VDDCPU_B"; + regulator-min-microvolt = <721000>; + regulator-max-microvolt = <1022000>; + + vin-supply = <&main_12v>; + + pwms = <&pwm_AO_cd 1 1250 0>; + pwm-dutycycle-range = <100 0>; + + regulator-boot-on; + regulator-always-on; + }; + hub_5v: regulator-hub_5v { compatible = "regulator-fixed"; regulator-name = "HUB_5V"; @@ -245,6 +284,48 @@ status = "okay"; }; +&cpu0 { + cpu-supply = <&vddcpu_b>; + operating-points-v2 = <&cpu_opp_table_0>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu1 { + cpu-supply = <&vddcpu_b>; + operating-points-v2 = <&cpu_opp_table_0>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu100 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu101 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu102 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu103 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + &ext_mdio { external_phy: ethernet-phy@0 { /* Realtek RTL8211F (0x001cc916) */ @@ -316,6 +397,22 @@ pinctrl-names = "default"; }; +&pwm_ab { + pinctrl-0 = <&pwm_a_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin0"; + status = "okay"; +}; + +&pwm_AO_cd { + pinctrl-0 = <&pwm_ao_d_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin1"; + status = "okay"; +}; + /* SD card */ &sd_emmc_b { status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-s922x-khadas-vim3.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-s922x-khadas-vim3.dts new file mode 100644 index 000000000000..6bcf972b8bfa --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-s922x-khadas-vim3.dts @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS + * Author: Neil Armstrong + * Copyright (c) 2019 Christian Hewitt + */ + +/dts-v1/; + +#include "meson-g12b-s922x.dtsi" +#include "meson-g12b-khadas-vim3.dtsi" + +/ { + compatible = "khadas,vim3", "amlogic,s922x", "amlogic,g12b"; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi new file mode 100644 index 000000000000..046cc332d07f --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS + * Author: Neil Armstrong + */ + +#include "meson-g12b.dtsi" + +/ { + cpu_opp_table_0: opp-table-0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <731000>; + }; + + opp-250000000 { + opp-hz = /bits/ 64 <250000000>; + opp-microvolt = <731000>; + }; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <731000>; + }; + + opp-667000000 { + opp-hz = /bits/ 64 <667000000>; + opp-microvolt = <731000>; + }; + + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <731000>; + }; + + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <731000>; + }; + + opp-1398000000 { + opp-hz = /bits/ 64 <1398000000>; + opp-microvolt = <761000>; + }; + + opp-1512000000 { + opp-hz = /bits/ 64 <1512000000>; + opp-microvolt = <791000>; + }; + + opp-1608000000 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <831000>; + }; + + opp-1704000000 { + opp-hz = /bits/ 64 <1704000000>; + opp-microvolt = <861000>; + }; + + opp-1896000000 { + opp-hz = /bits/ 64 <1896000000>; + opp-microvolt = <981000>; + }; + }; + + cpub_opp_table_1: opp-table-1 { + compatible = "operating-points-v2"; + opp-shared; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <751000>; + }; + + opp-250000000 { + opp-hz = /bits/ 64 <250000000>; + opp-microvolt = <751000>; + }; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <751000>; + }; + + opp-667000000 { + opp-hz = /bits/ 64 <667000000>; + opp-microvolt = <751000>; + }; + + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <771000>; + }; + + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <771000>; + }; + + opp-1398000000 { + opp-hz = /bits/ 64 <1398000000>; + opp-microvolt = <791000>; + }; + + opp-1512000000 { + opp-hz = /bits/ 64 <1512000000>; + opp-microvolt = <821000>; + }; + + opp-1608000000 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <861000>; + }; + + opp-1704000000 { + opp-hz = /bits/ 64 <1704000000>; + opp-microvolt = <891000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi index 9e88e513b22d..d5edbc1a1991 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi @@ -4,12 +4,15 @@ * Author: Neil Armstrong */ -#include "meson-g12a.dtsi" +#include "meson-g12-common.dtsi" / { compatible = "amlogic,g12b"; cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + cpu-map { cluster0 { core0 { @@ -40,8 +43,21 @@ }; }; - /delete-node/ cpu@2; - /delete-node/ cpu@3; + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0 0x0>; + enable-method = "psci"; + next-level-cache = <&l2>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0 0x1>; + enable-method = "psci"; + next-level-cache = <&l2>; + }; cpu100: cpu@100 { device_type = "cpu"; @@ -74,9 +90,17 @@ enable-method = "psci"; next-level-cache = <&l2>; }; + + l2: l2-cache0 { + compatible = "cache"; + }; }; }; &clkc { compatible = "amlogic,g12b-clkc"; }; + +&sd_emmc_a { + amlogic,dram-access-quirk; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi index 74d03fc706be..ca4b834c65d8 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi @@ -437,6 +437,20 @@ }; }; + vdec: video-codec@c8820000 { + compatible = "amlogic,gx-vdec"; + reg = <0x0 0xc8820000 0x0 0x10000>, + <0x0 0xc110a580 0x0 0xe4>; + reg-names = "dos", "esparser"; + + interrupts = , + ; + interrupt-names = "vdec", "esparser"; + + amlogic,ao-sysctrl = <&sysctrl_AO>; + amlogic,canvas = <&canvas>; + }; + periphs: periphs@c8834000 { compatible = "simple-bus"; reg = <0x0 0xc8834000 0x0 0x2000>; @@ -493,6 +507,8 @@ 0x0 0xc8834540 0x0 0x4>; interrupts = ; interrupt-names = "macirq"; + rx-fifo-depth = <4096>; + tx-fifo-depth = <2048>; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi index f734faaf7b78..0cb40326b0d3 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi @@ -845,3 +845,14 @@ compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu"; power-domains = <&pwrc_vpu>; }; + +&vdec { + compatible = "amlogic,gxbb-vdec", "amlogic,gx-vdec"; + clocks = <&clkc CLKID_DOS_PARSER>, + <&clkc CLKID_DOS>, + <&clkc CLKID_VDEC_1>, + <&clkc CLKID_VDEC_HEVC>; + clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc"; + resets = <&reset RESET_PARSER>; + reset-names = "esparser"; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi index c959456bacc6..a09c53aaa0e8 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi @@ -848,3 +848,14 @@ compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu"; power-domains = <&pwrc_vpu>; }; + +&vdec { + compatible = "amlogic,gxl-vdec", "amlogic,gx-vdec"; + clocks = <&clkc CLKID_DOS_PARSER>, + <&clkc CLKID_DOS>, + <&clkc CLKID_VDEC_1>, + <&clkc CLKID_VDEC_HEVC>; + clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc"; + resets = <&reset RESET_PARSER>; + reset-names = "esparser"; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi index 7a85a82bf65d..a0e677d5a8f7 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi @@ -144,3 +144,7 @@ &dwc3 { phys = <&usb3_phy>, <&usb2_phy0>, <&usb2_phy1>, <&usb2_phy2>; }; + +&vdec { + compatible = "amlogic,gxm-vdec", "amlogic,gx-vdec"; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts new file mode 100644 index 000000000000..5700cd73fefc --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts @@ -0,0 +1,300 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre SAS. All rights reserved. + */ + +/dts-v1/; + +#include "meson-sm1.dtsi" +#include +#include +#include + +/ { + compatible = "seirobotics,sei610", "amlogic,sm1"; + model = "SEI Robotics SEI610"; + + aliases { + serial0 = &uart_AO; + ethernet0 = ðmac; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>; + }; + + gpio-keys { + compatible = "gpio-keys-polled"; + poll-interval = <100>; + + key1 { + label = "A"; + linux,code = ; + gpios = <&gpio GPIOH_6 GPIO_ACTIVE_LOW>; + }; + + key2 { + label = "B"; + linux,code = ; + gpios = <&gpio GPIOH_7 GPIO_ACTIVE_LOW>; + }; + + key3 { + label = "C"; + linux,code = ; + gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + + bluetooth { + label = "sei610:blue:bt"; + gpios = <&gpio GPIOC_7 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; + default-state = "off"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + + power { + label = "sei610:red:power"; + pwms = <&pwm_AO_ab 0 30518 0>; + max-brightness = <255>; + linux,default-trigger = "default-on"; + active-low; + }; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x40000000>; + }; + + ao_5v: regulator-ao_5v { + compatible = "regulator-fixed"; + regulator-name = "AO_5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_in>; + regulator-always-on; + }; + + dc_in: regulator-dc_in { + compatible = "regulator-fixed"; + regulator-name = "DC_IN"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + emmc_1v8: regulator-emmc_1v8 { + compatible = "regulator-fixed"; + regulator-name = "EMMC_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vddao_3v3>; + regulator-always-on; + }; + + vddao_3v3: regulator-vddao_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VDDAO_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&dc_in>; + regulator-always-on; + }; + + /* Used by Tuner, RGB Led & IR Emitter LED array */ + vddao_3v3_t: regulator-vddao_3v3_t { + compatible = "regulator-fixed"; + regulator-name = "VDDAO_3V3_T"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vddao_3v3>; + gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>; + enable-active-low; + regulator-always-on; + }; + + vddio_ao1v8: regulator-vddio_ao1v8 { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_AO1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vddao_3v3>; + regulator-always-on; + }; + + reserved-memory { + /* TEE Reserved Memory */ + bl32_reserved: bl32@5000000 { + reg = <0x0 0x05300000 0x0 0x2000000>; + no-map; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; + clocks = <&wifi32k>; + clock-names = "ext_clock"; + }; + + wifi32k: wifi32k { + compatible = "pwm-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */ + }; +}; + +&cec_AO { + pinctrl-0 = <&cec_ao_a_h_pins>; + pinctrl-names = "default"; + status = "disabled"; + hdmi-phandle = <&hdmi_tx>; +}; + +&cecb_AO { + pinctrl-0 = <&cec_ao_b_h_pins>; + pinctrl-names = "default"; + status = "okay"; + hdmi-phandle = <&hdmi_tx>; +}; + +ðmac { + status = "okay"; + phy-handle = <&internal_ephy>; + phy-mode = "rmii"; +}; + +&i2c3 { + status = "okay"; + pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>; + pinctrl-names = "default"; +}; + +&ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; +}; + +&pwm_AO_ab { + status = "okay"; + pinctrl-0 = <&pwm_ao_a_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin0"; +}; + +&pwm_ef { + status = "okay"; + pinctrl-0 = <&pwm_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin0"; +}; + +&saradc { + status = "okay"; + vref-supply = <&vddio_ao1v8>; +}; + +/* SDIO */ +&sd_emmc_a { + status = "okay"; + pinctrl-0 = <&sdio_pins>; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + #address-cells = <1>; + #size-cells = <0>; + + bus-width = <4>; + cap-sd-highspeed; + sd-uhs-sdr50; + max-frequency = <100000000>; + + non-removable; + disable-wp; + + mmc-pwrseq = <&sdio_pwrseq>; + + vmmc-supply = <&vddao_3v3>; + vqmmc-supply = <&vddio_ao1v8>; + + brcmf: wifi@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + }; +}; + +/* SD card */ +&sd_emmc_b { + status = "okay"; + pinctrl-0 = <&sdcard_c_pins>; + pinctrl-1 = <&sdcard_clk_gate_c_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <4>; + cap-sd-highspeed; + max-frequency = <50000000>; + disable-wp; + + cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>; + vmmc-supply = <&vddao_3v3>; + vqmmc-supply = <&vddao_3v3>; +}; + +/* eMMC */ +&sd_emmc_c { + status = "okay"; + pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <8>; + cap-mmc-highspeed; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + max-frequency = <200000000>; + non-removable; + disable-wp; + + mmc-pwrseq = <&emmc_pwrseq>; + vmmc-supply = <&vddao_3v3>; + vqmmc-supply = <&emmc_1v8>; +}; + +&uart_A { + status = "okay"; + pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>; + pinctrl-names = "default"; + uart-has-rtscts; + + bluetooth { + compatible = "brcm,bcm43438-bt"; + shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>; + max-speed = <2000000>; + clocks = <&wifi32k>; + clock-names = "lpo"; + vbat-supply = <&vddao_3v3>; + vddio-supply = <&vddio_ao1v8>; + }; +}; + +/* Exposed via the on-board USB to Serial FT232RL IC */ +&uart_AO { + status = "okay"; + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi new file mode 100644 index 000000000000..e902d4f9165f --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS + * Author: Neil Armstrong + */ + +#include "meson-g12-common.dtsi" + +/ { + compatible = "amlogic,sm1"; + + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x0 0x0>; + enable-method = "psci"; + next-level-cache = <&l2>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x0 0x1>; + enable-method = "psci"; + next-level-cache = <&l2>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x0 0x2>; + enable-method = "psci"; + next-level-cache = <&l2>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x0 0x3>; + enable-method = "psci"; + next-level-cache = <&l2>; + }; + + l2: l2-cache0 { + compatible = "cache"; + }; + }; +}; + +&cecb_AO { + compatible = "amlogic,meson-sm1-ao-cec"; +}; + +&clk_msr { + compatible = "amlogic,meson-sm1-clk-measure"; +}; + +&pwrc_vpu { + status = "disabled"; +}; + +&vpu { + status = "disabled"; +}; diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index c0990703ce54..c11b1781d24a 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2487,6 +2487,12 @@ runtime_put: return ret; } +int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *parent) +{ + return clk_core_set_parent_nolock(hw->core, parent->core); +} +EXPORT_SYMBOL_GPL(clk_hw_set_parent); + /** * clk_set_parent - switch the parent of a mux clk * @clk: the mux clk whose input we are switching diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index a6b20e123e0c..dabeb435d067 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -1,7 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -config COMMON_CLK_MESON_INPUT - tristate - config COMMON_CLK_MESON_REGMAP tristate select REGMAP @@ -33,13 +30,15 @@ config COMMON_CLK_MESON_VID_PLL_DIV config COMMON_CLK_MESON_AO_CLKC tristate select COMMON_CLK_MESON_REGMAP - select COMMON_CLK_MESON_INPUT select RESET_CONTROLLER config COMMON_CLK_MESON_EE_CLKC tristate select COMMON_CLK_MESON_REGMAP - select COMMON_CLK_MESON_INPUT + +config COMMON_CLK_MESON_CPU_DYNDIV + tristate + select COMMON_CLK_MESON_REGMAP config COMMON_CLK_MESON8B bool @@ -86,7 +85,6 @@ config COMMON_CLK_AXG config COMMON_CLK_AXG_AUDIO tristate "Meson AXG Audio Clock Controller Driver" depends on ARCH_MESON - select COMMON_CLK_MESON_INPUT select COMMON_CLK_MESON_REGMAP select COMMON_CLK_MESON_PHASE select COMMON_CLK_MESON_SCLK_DIV @@ -104,6 +102,7 @@ config COMMON_CLK_G12A select COMMON_CLK_MESON_PLL select COMMON_CLK_MESON_AO_CLKC select COMMON_CLK_MESON_EE_CLKC + select COMMON_CLK_MESON_CPU_DYNDIV select MFD_SYSCON help Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2 diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index bc35a4efd6b7..3939f218587a 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -2,9 +2,9 @@ # Amlogic clock drivers obj-$(CONFIG_COMMON_CLK_MESON_AO_CLKC) += meson-aoclk.o +obj-$(CONFIG_COMMON_CLK_MESON_CPU_DYNDIV) += clk-cpu-dyndiv.o obj-$(CONFIG_COMMON_CLK_MESON_DUALDIV) += clk-dualdiv.o obj-$(CONFIG_COMMON_CLK_MESON_EE_CLKC) += meson-eeclk.o -obj-$(CONFIG_COMMON_CLK_MESON_INPUT) += clk-input.o obj-$(CONFIG_COMMON_CLK_MESON_MPLL) += clk-mpll.o obj-$(CONFIG_COMMON_CLK_MESON_PHASE) += clk-phase.o obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o diff --git a/drivers/clk/meson/axg-aoclk.c b/drivers/clk/meson/axg-aoclk.c index 0086f31288eb..b488b40c9d0e 100644 --- a/drivers/clk/meson/axg-aoclk.c +++ b/drivers/clk/meson/axg-aoclk.c @@ -18,8 +18,6 @@ #include "clk-regmap.h" #include "clk-dualdiv.h" -#define IN_PREFIX "ao-in-" - /* * AO Configuration Clock registers offsets * Register offsets from the data sheet must be multiplied by 4. @@ -42,7 +40,9 @@ static struct clk_regmap axg_aoclk_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "axg_ao_" #_name, \ .ops = &clk_regmap_gate_ops, \ - .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \ + .parent_data = &(const struct clk_parent_data) { \ + .fw_name = "mpeg-clk", \ + }, \ .num_parents = 1, \ .flags = CLK_IGNORE_UNUSED, \ }, \ @@ -64,7 +64,9 @@ static struct clk_regmap axg_aoclk_cts_oscin = { .hw.init = &(struct clk_init_data){ .name = "cts_oscin", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -77,7 +79,9 @@ static struct clk_regmap axg_aoclk_32k_pre = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_32k_pre", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_oscin" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_aoclk_cts_oscin.hw + }, .num_parents = 1, }, }; @@ -124,7 +128,9 @@ static struct clk_regmap axg_aoclk_32k_div = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_32k_div", .ops = &meson_clk_dualdiv_ops, - .parent_names = (const char *[]){ "axg_ao_32k_pre" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_aoclk_32k_pre.hw + }, .num_parents = 1, }, }; @@ -139,8 +145,10 @@ static struct clk_regmap axg_aoclk_32k_sel = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_32k_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "axg_ao_32k_div", - "axg_ao_32k_pre" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_aoclk_32k_div.hw, + &axg_aoclk_32k_pre.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -154,7 +162,9 @@ static struct clk_regmap axg_aoclk_32k = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_32k", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "axg_ao_32k_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_aoclk_32k_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -170,8 +180,10 @@ static struct clk_regmap axg_aoclk_cts_rtc_oscin = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_cts_rtc_oscin", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "axg_ao_32k", - IN_PREFIX "ext_32k-0" }, + .parent_data = (const struct clk_parent_data []) { + { .hw = &axg_aoclk_32k.hw }, + { .fw_name = "ext_32k-0", }, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -187,8 +199,10 @@ static struct clk_regmap axg_aoclk_clk81 = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_clk81", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk", - "axg_ao_cts_rtc_oscin"}, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "mpeg-clk", }, + { .hw = &axg_aoclk_cts_rtc_oscin.hw }, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -203,8 +217,10 @@ static struct clk_regmap axg_aoclk_saradc_mux = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_saradc_mux", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal", - "axg_ao_clk81" }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &axg_aoclk_clk81.hw }, + }, .num_parents = 2, }, }; @@ -218,7 +234,9 @@ static struct clk_regmap axg_aoclk_saradc_div = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_saradc_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "axg_ao_saradc_mux" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_aoclk_saradc_mux.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -232,7 +250,9 @@ static struct clk_regmap axg_aoclk_saradc_gate = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_saradc_gate", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "axg_ao_saradc_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_aoclk_saradc_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -290,12 +310,6 @@ static const struct clk_hw_onecell_data axg_aoclk_onecell_data = { .num = NR_CLKS, }; -static const struct meson_aoclk_input axg_aoclk_inputs[] = { - { .name = "xtal", .required = true }, - { .name = "mpeg-clk", .required = true }, - { .name = "ext-32k-0", .required = false }, -}; - static const struct meson_aoclk_data axg_aoclkc_data = { .reset_reg = AO_RTI_GEN_CNTL_REG0, .num_reset = ARRAY_SIZE(axg_aoclk_reset), @@ -303,9 +317,6 @@ static const struct meson_aoclk_data axg_aoclkc_data = { .num_clks = ARRAY_SIZE(axg_aoclk_regmap), .clks = axg_aoclk_regmap, .hw_data = &axg_aoclk_onecell_data, - .inputs = axg_aoclk_inputs, - .num_inputs = ARRAY_SIZE(axg_aoclk_inputs), - .input_prefix = IN_PREFIX, }; static const struct of_device_id axg_aoclkc_match_table[] = { diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c index 8028ff6f6610..741df7e955ca 100644 --- a/drivers/clk/meson/axg-audio.c +++ b/drivers/clk/meson/axg-audio.c @@ -15,7 +15,6 @@ #include #include "axg-audio.h" -#include "clk-input.h" #include "clk-regmap.h" #include "clk-phase.h" #include "sclk-div.h" @@ -24,7 +23,7 @@ #define AUD_SLV_SCLK_COUNT 10 #define AUD_SLV_LRCLK_COUNT 10 -#define AUD_GATE(_name, _reg, _bit, _pname, _iflags) \ +#define AUD_GATE(_name, _reg, _bit, _phws, _iflags) \ struct clk_regmap aud_##_name = { \ .data = &(struct clk_regmap_gate_data){ \ .offset = (_reg), \ @@ -33,13 +32,13 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "aud_"#_name, \ .ops = &clk_regmap_gate_ops, \ - .parent_names = (const char *[]){ _pname }, \ + .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ .num_parents = 1, \ .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ }, \ } -#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pnames, _iflags) \ +#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pdata, _iflags) \ struct clk_regmap aud_##_name = { \ .data = &(struct clk_regmap_mux_data){ \ .offset = (_reg), \ @@ -50,13 +49,13 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data){ \ .name = "aud_"#_name, \ .ops = &clk_regmap_mux_ops, \ - .parent_names = (_pnames), \ - .num_parents = ARRAY_SIZE(_pnames), \ + .parent_data = _pdata, \ + .num_parents = ARRAY_SIZE(_pdata), \ .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ }, \ } -#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _pname, _iflags) \ +#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _phws, _iflags) \ struct clk_regmap aud_##_name = { \ .data = &(struct clk_regmap_div_data){ \ .offset = (_reg), \ @@ -67,15 +66,27 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data){ \ .name = "aud_"#_name, \ .ops = &clk_regmap_divider_ops, \ - .parent_names = (const char *[]) { _pname }, \ + .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ .num_parents = 1, \ .flags = (_iflags), \ }, \ } #define AUD_PCLK_GATE(_name, _bit) \ - AUD_GATE(_name, AUDIO_CLK_GATE_EN, _bit, "audio_pclk", 0) - +struct clk_regmap aud_##_name = { \ + .data = &(struct clk_regmap_gate_data){ \ + .offset = (AUDIO_CLK_GATE_EN), \ + .bit_idx = (_bit), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = "aud_"#_name, \ + .ops = &clk_regmap_gate_ops, \ + .parent_data = &(const struct clk_parent_data) { \ + .fw_name = "pclk", \ + }, \ + .num_parents = 1, \ + }, \ +} /* Audio peripheral clocks */ static AUD_PCLK_GATE(ddr_arb, 0); static AUD_PCLK_GATE(pdm, 1); @@ -100,14 +111,20 @@ static AUD_PCLK_GATE(power_detect, 19); static AUD_PCLK_GATE(spdifout_b, 21); /* Audio Master Clocks */ -static const char * const mst_mux_parent_names[] = { - "aud_mst_in0", "aud_mst_in1", "aud_mst_in2", "aud_mst_in3", - "aud_mst_in4", "aud_mst_in5", "aud_mst_in6", "aud_mst_in7", +static const struct clk_parent_data mst_mux_parent_data[] = { + { .fw_name = "mst_in0", }, + { .fw_name = "mst_in1", }, + { .fw_name = "mst_in2", }, + { .fw_name = "mst_in3", }, + { .fw_name = "mst_in4", }, + { .fw_name = "mst_in5", }, + { .fw_name = "mst_in6", }, + { .fw_name = "mst_in7", }, }; #define AUD_MST_MUX(_name, _reg, _flag) \ AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag, \ - mst_mux_parent_names, CLK_SET_RATE_PARENT) + mst_mux_parent_data, 0) #define AUD_MST_MCLK_MUX(_name, _reg) \ AUD_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST) @@ -129,7 +146,7 @@ static AUD_MST_MCLK_MUX(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); #define AUD_MST_DIV(_name, _reg, _flag) \ AUD_DIV(_name##_div, _reg, 0, 16, _flag, \ - "aud_"#_name"_sel", CLK_SET_RATE_PARENT) \ + aud_##_name##_sel, CLK_SET_RATE_PARENT) \ #define AUD_MST_MCLK_DIV(_name, _reg) \ AUD_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST) @@ -150,7 +167,7 @@ static AUD_MST_SYS_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); static AUD_MST_MCLK_DIV(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); #define AUD_MST_MCLK_GATE(_name, _reg) \ - AUD_GATE(_name, _reg, 31, "aud_"#_name"_div", \ + AUD_GATE(_name, _reg, 31, aud_##_name##_div, \ CLK_SET_RATE_PARENT) static AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL); @@ -168,7 +185,7 @@ static AUD_MST_MCLK_GATE(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); /* Sample Clocks */ #define AUD_MST_SCLK_PRE_EN(_name, _reg) \ AUD_GATE(mst_##_name##_sclk_pre_en, _reg, 31, \ - "aud_mst_"#_name"_mclk", 0) + aud_mst_##_name##_mclk, 0) static AUD_MST_SCLK_PRE_EN(a, AUDIO_MST_A_SCLK_CTRL0); static AUD_MST_SCLK_PRE_EN(b, AUDIO_MST_B_SCLK_CTRL0); @@ -178,7 +195,7 @@ static AUD_MST_SCLK_PRE_EN(e, AUDIO_MST_E_SCLK_CTRL0); static AUD_MST_SCLK_PRE_EN(f, AUDIO_MST_F_SCLK_CTRL0); #define AUD_SCLK_DIV(_name, _reg, _div_shift, _div_width, \ - _hi_shift, _hi_width, _pname, _iflags) \ + _hi_shift, _hi_width, _phws, _iflags) \ struct clk_regmap aud_##_name = { \ .data = &(struct meson_sclk_div_data) { \ .div = { \ @@ -195,7 +212,7 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "aud_"#_name, \ .ops = &meson_sclk_div_ops, \ - .parent_names = (const char *[]) { _pname }, \ + .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ .num_parents = 1, \ .flags = (_iflags), \ }, \ @@ -203,7 +220,7 @@ struct clk_regmap aud_##_name = { \ #define AUD_MST_SCLK_DIV(_name, _reg) \ AUD_SCLK_DIV(mst_##_name##_sclk_div, _reg, 20, 10, 0, 0, \ - "aud_mst_"#_name"_sclk_pre_en", \ + aud_mst_##_name##_sclk_pre_en, \ CLK_SET_RATE_PARENT) static AUD_MST_SCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); @@ -214,8 +231,8 @@ static AUD_MST_SCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); static AUD_MST_SCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); #define AUD_MST_SCLK_POST_EN(_name, _reg) \ - AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30, \ - "aud_mst_"#_name"_sclk_div", CLK_SET_RATE_PARENT) + AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30, \ + aud_mst_##_name##_sclk_div, CLK_SET_RATE_PARENT) static AUD_MST_SCLK_POST_EN(a, AUDIO_MST_A_SCLK_CTRL0); static AUD_MST_SCLK_POST_EN(b, AUDIO_MST_B_SCLK_CTRL0); @@ -224,8 +241,8 @@ static AUD_MST_SCLK_POST_EN(d, AUDIO_MST_D_SCLK_CTRL0); static AUD_MST_SCLK_POST_EN(e, AUDIO_MST_E_SCLK_CTRL0); static AUD_MST_SCLK_POST_EN(f, AUDIO_MST_F_SCLK_CTRL0); -#define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \ - _pname, _iflags) \ +#define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \ + _phws, _iflags) \ struct clk_regmap aud_##_name = { \ .data = &(struct meson_clk_triphase_data) { \ .ph0 = { \ @@ -247,7 +264,7 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "aud_"#_name, \ .ops = &meson_clk_triphase_ops, \ - .parent_names = (const char *[]) { _pname }, \ + .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ .num_parents = 1, \ .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ }, \ @@ -255,7 +272,7 @@ struct clk_regmap aud_##_name = { \ #define AUD_MST_SCLK(_name, _reg) \ AUD_TRIPHASE(mst_##_name##_sclk, _reg, 1, 0, 2, 4, \ - "aud_mst_"#_name"_sclk_post_en", CLK_SET_RATE_PARENT) + aud_mst_##_name##_sclk_post_en, CLK_SET_RATE_PARENT) static AUD_MST_SCLK(a, AUDIO_MST_A_SCLK_CTRL1); static AUD_MST_SCLK(b, AUDIO_MST_B_SCLK_CTRL1); @@ -266,7 +283,7 @@ static AUD_MST_SCLK(f, AUDIO_MST_F_SCLK_CTRL1); #define AUD_MST_LRCLK_DIV(_name, _reg) \ AUD_SCLK_DIV(mst_##_name##_lrclk_div, _reg, 0, 10, 10, 10, \ - "aud_mst_"#_name"_sclk_post_en", 0) \ + aud_mst_##_name##_sclk_post_en, 0) \ static AUD_MST_LRCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); static AUD_MST_LRCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); @@ -277,7 +294,7 @@ static AUD_MST_LRCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); #define AUD_MST_LRCLK(_name, _reg) \ AUD_TRIPHASE(mst_##_name##_lrclk, _reg, 1, 1, 3, 5, \ - "aud_mst_"#_name"_lrclk_div", CLK_SET_RATE_PARENT) + aud_mst_##_name##_lrclk_div, CLK_SET_RATE_PARENT) static AUD_MST_LRCLK(a, AUDIO_MST_A_SCLK_CTRL1); static AUD_MST_LRCLK(b, AUDIO_MST_B_SCLK_CTRL1); @@ -286,19 +303,29 @@ static AUD_MST_LRCLK(d, AUDIO_MST_D_SCLK_CTRL1); static AUD_MST_LRCLK(e, AUDIO_MST_E_SCLK_CTRL1); static AUD_MST_LRCLK(f, AUDIO_MST_F_SCLK_CTRL1); -static const char * const tdm_sclk_parent_names[] = { - "aud_mst_a_sclk", "aud_mst_b_sclk", "aud_mst_c_sclk", - "aud_mst_d_sclk", "aud_mst_e_sclk", "aud_mst_f_sclk", - "aud_slv_sclk0", "aud_slv_sclk1", "aud_slv_sclk2", - "aud_slv_sclk3", "aud_slv_sclk4", "aud_slv_sclk5", - "aud_slv_sclk6", "aud_slv_sclk7", "aud_slv_sclk8", - "aud_slv_sclk9" +static const struct clk_parent_data tdm_sclk_parent_data[] = { + { .hw = &aud_mst_a_sclk.hw, }, + { .hw = &aud_mst_b_sclk.hw, }, + { .hw = &aud_mst_c_sclk.hw, }, + { .hw = &aud_mst_d_sclk.hw, }, + { .hw = &aud_mst_e_sclk.hw, }, + { .hw = &aud_mst_f_sclk.hw, }, + { .fw_name = "slv_sclk0", }, + { .fw_name = "slv_sclk1", }, + { .fw_name = "slv_sclk2", }, + { .fw_name = "slv_sclk3", }, + { .fw_name = "slv_sclk4", }, + { .fw_name = "slv_sclk5", }, + { .fw_name = "slv_sclk6", }, + { .fw_name = "slv_sclk7", }, + { .fw_name = "slv_sclk8", }, + { .fw_name = "slv_sclk9", }, }; #define AUD_TDM_SCLK_MUX(_name, _reg) \ AUD_MUX(tdm##_name##_sclk_sel, _reg, 0xf, 24, \ CLK_MUX_ROUND_CLOSEST, \ - tdm_sclk_parent_names, 0) + tdm_sclk_parent_data, 0) static AUD_TDM_SCLK_MUX(in_a, AUDIO_CLK_TDMIN_A_CTRL); static AUD_TDM_SCLK_MUX(in_b, AUDIO_CLK_TDMIN_B_CTRL); @@ -310,7 +337,7 @@ static AUD_TDM_SCLK_MUX(out_c, AUDIO_CLK_TDMOUT_C_CTRL); #define AUD_TDM_SCLK_PRE_EN(_name, _reg) \ AUD_GATE(tdm##_name##_sclk_pre_en, _reg, 31, \ - "aud_tdm"#_name"_sclk_sel", CLK_SET_RATE_PARENT) + aud_tdm##_name##_sclk_sel, CLK_SET_RATE_PARENT) static AUD_TDM_SCLK_PRE_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); static AUD_TDM_SCLK_PRE_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); @@ -322,7 +349,7 @@ static AUD_TDM_SCLK_PRE_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); #define AUD_TDM_SCLK_POST_EN(_name, _reg) \ AUD_GATE(tdm##_name##_sclk_post_en, _reg, 30, \ - "aud_tdm"#_name"_sclk_pre_en", CLK_SET_RATE_PARENT) + aud_tdm##_name##_sclk_pre_en, CLK_SET_RATE_PARENT) static AUD_TDM_SCLK_POST_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); static AUD_TDM_SCLK_POST_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); @@ -344,8 +371,9 @@ static AUD_TDM_SCLK_POST_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); .hw.init = &(struct clk_init_data) { \ .name = "aud_tdm"#_name"_sclk", \ .ops = &meson_clk_phase_ops, \ - .parent_names = (const char *[]) \ - { "aud_tdm"#_name"_sclk_post_en" }, \ + .parent_hws = (const struct clk_hw *[]) { \ + &aud_tdm##_name##_sclk_post_en.hw \ + }, \ .num_parents = 1, \ .flags = CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT, \ }, \ @@ -359,19 +387,29 @@ static AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); static AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); static AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); -static const char * const tdm_lrclk_parent_names[] = { - "aud_mst_a_lrclk", "aud_mst_b_lrclk", "aud_mst_c_lrclk", - "aud_mst_d_lrclk", "aud_mst_e_lrclk", "aud_mst_f_lrclk", - "aud_slv_lrclk0", "aud_slv_lrclk1", "aud_slv_lrclk2", - "aud_slv_lrclk3", "aud_slv_lrclk4", "aud_slv_lrclk5", - "aud_slv_lrclk6", "aud_slv_lrclk7", "aud_slv_lrclk8", - "aud_slv_lrclk9" +static const struct clk_parent_data tdm_lrclk_parent_data[] = { + { .hw = &aud_mst_a_lrclk.hw, }, + { .hw = &aud_mst_b_lrclk.hw, }, + { .hw = &aud_mst_c_lrclk.hw, }, + { .hw = &aud_mst_d_lrclk.hw, }, + { .hw = &aud_mst_e_lrclk.hw, }, + { .hw = &aud_mst_f_lrclk.hw, }, + { .fw_name = "slv_lrclk0", }, + { .fw_name = "slv_lrclk1", }, + { .fw_name = "slv_lrclk2", }, + { .fw_name = "slv_lrclk3", }, + { .fw_name = "slv_lrclk4", }, + { .fw_name = "slv_lrclk5", }, + { .fw_name = "slv_lrclk6", }, + { .fw_name = "slv_lrclk7", }, + { .fw_name = "slv_lrclk8", }, + { .fw_name = "slv_lrclk9", }, }; -#define AUD_TDM_LRLCK(_name, _reg) \ - AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \ - CLK_MUX_ROUND_CLOSEST, \ - tdm_lrclk_parent_names, 0) +#define AUD_TDM_LRLCK(_name, _reg) \ + AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \ + CLK_MUX_ROUND_CLOSEST, \ + tdm_lrclk_parent_data, 0) static AUD_TDM_LRLCK(in_a, AUDIO_CLK_TDMIN_A_CTRL); static AUD_TDM_LRLCK(in_b, AUDIO_CLK_TDMIN_B_CTRL); @@ -386,39 +424,51 @@ static AUD_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); AUD_MUX(tdm_##_name, _reg, 0x7, _shift, 0, _parents, \ CLK_SET_RATE_NO_REPARENT) -static const char * const mclk_pad_ctrl_parent_names[] = { - "aud_mst_a_mclk", "aud_mst_b_mclk", "aud_mst_c_mclk", - "aud_mst_d_mclk", "aud_mst_e_mclk", "aud_mst_f_mclk", +static const struct clk_parent_data mclk_pad_ctrl_parent_data[] = { + { .hw = &aud_mst_a_mclk.hw }, + { .hw = &aud_mst_b_mclk.hw }, + { .hw = &aud_mst_c_mclk.hw }, + { .hw = &aud_mst_d_mclk.hw }, + { .hw = &aud_mst_e_mclk.hw }, + { .hw = &aud_mst_f_mclk.hw }, }; static AUD_TDM_PAD_CTRL(mclk_pad_0, AUDIO_MST_PAD_CTRL0, 0, - mclk_pad_ctrl_parent_names); + mclk_pad_ctrl_parent_data); static AUD_TDM_PAD_CTRL(mclk_pad_1, AUDIO_MST_PAD_CTRL0, 4, - mclk_pad_ctrl_parent_names); + mclk_pad_ctrl_parent_data); -static const char * const lrclk_pad_ctrl_parent_names[] = { - "aud_mst_a_lrclk", "aud_mst_b_lrclk", "aud_mst_c_lrclk", - "aud_mst_d_lrclk", "aud_mst_e_lrclk", "aud_mst_f_lrclk", +static const struct clk_parent_data lrclk_pad_ctrl_parent_data[] = { + { .hw = &aud_mst_a_lrclk.hw }, + { .hw = &aud_mst_b_lrclk.hw }, + { .hw = &aud_mst_c_lrclk.hw }, + { .hw = &aud_mst_d_lrclk.hw }, + { .hw = &aud_mst_e_lrclk.hw }, + { .hw = &aud_mst_f_lrclk.hw }, }; static AUD_TDM_PAD_CTRL(lrclk_pad_0, AUDIO_MST_PAD_CTRL1, 16, - lrclk_pad_ctrl_parent_names); + lrclk_pad_ctrl_parent_data); static AUD_TDM_PAD_CTRL(lrclk_pad_1, AUDIO_MST_PAD_CTRL1, 20, - lrclk_pad_ctrl_parent_names); + lrclk_pad_ctrl_parent_data); static AUD_TDM_PAD_CTRL(lrclk_pad_2, AUDIO_MST_PAD_CTRL1, 24, - lrclk_pad_ctrl_parent_names); + lrclk_pad_ctrl_parent_data); -static const char * const sclk_pad_ctrl_parent_names[] = { - "aud_mst_a_sclk", "aud_mst_b_sclk", "aud_mst_c_sclk", - "aud_mst_d_sclk", "aud_mst_e_sclk", "aud_mst_f_sclk", +static const struct clk_parent_data sclk_pad_ctrl_parent_data[] = { + { .hw = &aud_mst_a_sclk.hw }, + { .hw = &aud_mst_b_sclk.hw }, + { .hw = &aud_mst_c_sclk.hw }, + { .hw = &aud_mst_d_sclk.hw }, + { .hw = &aud_mst_e_sclk.hw }, + { .hw = &aud_mst_f_sclk.hw }, }; static AUD_TDM_PAD_CTRL(sclk_pad_0, AUDIO_MST_PAD_CTRL1, 0, - sclk_pad_ctrl_parent_names); + sclk_pad_ctrl_parent_data); static AUD_TDM_PAD_CTRL(sclk_pad_1, AUDIO_MST_PAD_CTRL1, 4, - sclk_pad_ctrl_parent_names); + sclk_pad_ctrl_parent_data); static AUD_TDM_PAD_CTRL(sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8, - sclk_pad_ctrl_parent_names); + sclk_pad_ctrl_parent_data); /* * Array of all clocks provided by this provider @@ -868,54 +918,6 @@ static int devm_clk_get_enable(struct device *dev, char *id) return 0; } -static int axg_register_clk_hw_input(struct device *dev, - const char *name) -{ - char *clk_name; - struct clk_hw *hw; - int err = 0; - - clk_name = kasprintf(GFP_KERNEL, "aud_%s", name); - if (!clk_name) - return -ENOMEM; - - hw = meson_clk_hw_register_input(dev, name, clk_name, 0); - if (IS_ERR(hw)) { - /* It is ok if an input clock is missing */ - if (PTR_ERR(hw) == -ENOENT) { - dev_dbg(dev, "%s not provided", name); - } else { - err = PTR_ERR(hw); - if (err != -EPROBE_DEFER) - dev_err(dev, "failed to get %s clock", name); - } - } - - kfree(clk_name); - return err; -} - -static int axg_register_clk_hw_inputs(struct device *dev, - const char *basename, - unsigned int count) -{ - char *name; - int i, ret; - - for (i = 0; i < count; i++) { - name = kasprintf(GFP_KERNEL, "%s%d", basename, i); - if (!name) - return -ENOMEM; - - ret = axg_register_clk_hw_input(dev, name); - kfree(name); - if (ret) - return ret; - } - - return 0; -} - static const struct regmap_config axg_audio_regmap_cfg = { .reg_bits = 32, .val_bits = 32, @@ -963,29 +965,6 @@ static int axg_audio_clkc_probe(struct platform_device *pdev) return ret; } - /* Register the peripheral input clock */ - hw = meson_clk_hw_register_input(dev, "pclk", "audio_pclk", 0); - if (IS_ERR(hw)) - return PTR_ERR(hw); - - /* Register optional input master clocks */ - ret = axg_register_clk_hw_inputs(dev, "mst_in", - AUD_MST_IN_COUNT); - if (ret) - return ret; - - /* Register optional input slave sclks */ - ret = axg_register_clk_hw_inputs(dev, "slv_sclk", - AUD_SLV_SCLK_COUNT); - if (ret) - return ret; - - /* Register optional input slave lrclks */ - ret = axg_register_clk_hw_inputs(dev, "slv_lrclk", - AUD_SLV_LRCLK_COUNT); - if (ret) - return ret; - /* Populate regmap for the regmap backed clocks */ for (i = 0; i < ARRAY_SIZE(aud_clk_regmaps); i++) aud_clk_regmaps[i]->map = map; diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index 3ddd0efc9ee0..13fc0006f63d 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c @@ -14,7 +14,6 @@ #include #include -#include "clk-input.h" #include "clk-regmap.h" #include "clk-pll.h" #include "clk-mpll.h" @@ -59,7 +58,9 @@ static struct clk_regmap axg_fixed_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -74,7 +75,9 @@ static struct clk_regmap axg_fixed_pll = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "fixed_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fixed_pll_dco.hw + }, .num_parents = 1, /* * This clock won't ever change at runtime so @@ -114,7 +117,9 @@ static struct clk_regmap axg_sys_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "sys_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -129,7 +134,9 @@ static struct clk_regmap axg_sys_pll = { .hw.init = &(struct clk_init_data){ .name = "sys_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "sys_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_sys_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -215,7 +222,9 @@ static struct clk_regmap axg_gp0_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "gp0_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -230,7 +239,9 @@ static struct clk_regmap axg_gp0_pll = { .hw.init = &(struct clk_init_data){ .name = "gp0_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "gp0_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_gp0_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -284,7 +295,9 @@ static struct clk_regmap axg_hifi_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "hifi_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -299,7 +312,9 @@ static struct clk_regmap axg_hifi_pll = { .hw.init = &(struct clk_init_data){ .name = "hifi_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "hifi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_hifi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -311,7 +326,7 @@ static struct clk_fixed_factor axg_fclk_div2_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw }, .num_parents = 1, }, }; @@ -324,7 +339,9 @@ static struct clk_regmap axg_fclk_div2 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div2_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fclk_div2_div.hw + }, .num_parents = 1, .flags = CLK_IS_CRITICAL, }, @@ -336,7 +353,7 @@ static struct clk_fixed_factor axg_fclk_div3_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div3_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw }, .num_parents = 1, }, }; @@ -349,7 +366,9 @@ static struct clk_regmap axg_fclk_div3 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div3", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div3_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fclk_div3_div.hw + }, .num_parents = 1, /* * FIXME: @@ -372,7 +391,7 @@ static struct clk_fixed_factor axg_fclk_div4_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div4_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw }, .num_parents = 1, }, }; @@ -385,7 +404,9 @@ static struct clk_regmap axg_fclk_div4 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div4", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div4_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fclk_div4_div.hw + }, .num_parents = 1, }, }; @@ -396,7 +417,7 @@ static struct clk_fixed_factor axg_fclk_div5_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw }, .num_parents = 1, }, }; @@ -409,7 +430,9 @@ static struct clk_regmap axg_fclk_div5 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div5_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fclk_div5_div.hw + }, .num_parents = 1, }, }; @@ -420,7 +443,9 @@ static struct clk_fixed_factor axg_fclk_div7_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -433,7 +458,9 @@ static struct clk_regmap axg_fclk_div7 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div7_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fclk_div7_div.hw + }, .num_parents = 1, }, }; @@ -447,7 +474,9 @@ static struct clk_regmap axg_mpll_prediv = { .hw.init = &(struct clk_init_data){ .name = "mpll_prediv", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -480,7 +509,9 @@ static struct clk_regmap axg_mpll0_div = { .hw.init = &(struct clk_init_data){ .name = "mpll0_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -493,7 +524,9 @@ static struct clk_regmap axg_mpll0 = { .hw.init = &(struct clk_init_data){ .name = "mpll0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -527,7 +560,9 @@ static struct clk_regmap axg_mpll1_div = { .hw.init = &(struct clk_init_data){ .name = "mpll1_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -540,7 +575,9 @@ static struct clk_regmap axg_mpll1 = { .hw.init = &(struct clk_init_data){ .name = "mpll1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -579,7 +616,9 @@ static struct clk_regmap axg_mpll2_div = { .hw.init = &(struct clk_init_data){ .name = "mpll2_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -592,7 +631,9 @@ static struct clk_regmap axg_mpll2 = { .hw.init = &(struct clk_init_data){ .name = "mpll2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll2_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll2_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -626,7 +667,9 @@ static struct clk_regmap axg_mpll3_div = { .hw.init = &(struct clk_init_data){ .name = "mpll3_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -639,7 +682,9 @@ static struct clk_regmap axg_mpll3 = { .hw.init = &(struct clk_init_data){ .name = "mpll3", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll3_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll3_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -702,7 +747,9 @@ static struct clk_regmap axg_pcie_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "pcie_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -717,7 +764,9 @@ static struct clk_regmap axg_pcie_pll_od = { .hw.init = &(struct clk_init_data){ .name = "pcie_pll_od", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "pcie_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_pcie_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -733,7 +782,9 @@ static struct clk_regmap axg_pcie_pll = { .hw.init = &(struct clk_init_data){ .name = "pcie_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "pcie_pll_od" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_pcie_pll_od.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -750,7 +801,7 @@ static struct clk_regmap axg_pcie_mux = { .hw.init = &(struct clk_init_data){ .name = "pcie_mux", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "pcie_pll" }, + .parent_hws = (const struct clk_hw *[]) { &axg_pcie_pll.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -767,7 +818,7 @@ static struct clk_regmap axg_pcie_ref = { .hw.init = &(struct clk_init_data){ .name = "pcie_ref", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "pcie_mux" }, + .parent_hws = (const struct clk_hw *[]) { &axg_pcie_mux.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -781,7 +832,7 @@ static struct clk_regmap axg_pcie_cml_en0 = { .hw.init = &(struct clk_init_data) { .name = "pcie_cml_en0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "pcie_ref" }, + .parent_hws = (const struct clk_hw *[]) { &axg_pcie_ref.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -796,16 +847,21 @@ static struct clk_regmap axg_pcie_cml_en1 = { .hw.init = &(struct clk_init_data) { .name = "pcie_cml_en1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "pcie_ref" }, + .parent_hws = (const struct clk_hw *[]) { &axg_pcie_ref.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; -static const char * const clk81_parent_names[] = { - IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", - "fclk_div3", "fclk_div5" +static const struct clk_parent_data clk81_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &axg_fclk_div7.hw }, + { .hw = &axg_mpll1.hw }, + { .hw = &axg_mpll2.hw }, + { .hw = &axg_fclk_div4.hw }, + { .hw = &axg_fclk_div3.hw }, + { .hw = &axg_fclk_div5.hw }, }; static struct clk_regmap axg_mpeg_clk_sel = { @@ -818,8 +874,8 @@ static struct clk_regmap axg_mpeg_clk_sel = { .hw.init = &(struct clk_init_data){ .name = "mpeg_clk_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = clk81_parent_names, - .num_parents = ARRAY_SIZE(clk81_parent_names), + .parent_data = clk81_parent_data, + .num_parents = ARRAY_SIZE(clk81_parent_data), }, }; @@ -832,7 +888,9 @@ static struct clk_regmap axg_mpeg_clk_div = { .hw.init = &(struct clk_init_data){ .name = "mpeg_clk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mpeg_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpeg_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -846,15 +904,20 @@ static struct clk_regmap axg_clk81 = { .hw.init = &(struct clk_init_data){ .name = "clk81", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpeg_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpeg_clk_div.hw + }, .num_parents = 1, .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), }, }; -static const char * const axg_sd_emmc_clk0_parent_names[] = { - IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7", - +static const struct clk_parent_data axg_sd_emmc_clk0_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &axg_fclk_div2.hw }, + { .hw = &axg_fclk_div3.hw }, + { .hw = &axg_fclk_div5.hw }, + { .hw = &axg_fclk_div7.hw }, /* * Following these parent clocks, we should also have had mpll2, mpll3 * and gp0_pll but these clocks are too precious to be used here. All @@ -873,8 +936,8 @@ static struct clk_regmap axg_sd_emmc_b_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = axg_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names), + .parent_data = axg_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -889,7 +952,9 @@ static struct clk_regmap axg_sd_emmc_b_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_sd_emmc_b_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -903,7 +968,9 @@ static struct clk_regmap axg_sd_emmc_b_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_b_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_sd_emmc_b_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -919,8 +986,8 @@ static struct clk_regmap axg_sd_emmc_c_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = axg_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names), + .parent_data = axg_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -935,7 +1002,9 @@ static struct clk_regmap axg_sd_emmc_c_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_sd_emmc_c_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -949,7 +1018,9 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_c_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_sd_emmc_c_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -957,9 +1028,18 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = { static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, }; -static const char * const gen_clk_parent_names[] = { - IN_PREFIX "xtal", "hifi_pll", "mpll0", "mpll1", "mpll2", "mpll3", - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll", +static const struct clk_parent_data gen_clk_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &axg_hifi_pll.hw }, + { .hw = &axg_mpll0.hw }, + { .hw = &axg_mpll1.hw }, + { .hw = &axg_mpll2.hw }, + { .hw = &axg_mpll3.hw }, + { .hw = &axg_fclk_div4.hw }, + { .hw = &axg_fclk_div3.hw }, + { .hw = &axg_fclk_div5.hw }, + { .hw = &axg_fclk_div7.hw }, + { .hw = &axg_gp0_pll.hw }, }; static struct clk_regmap axg_gen_clk_sel = { @@ -978,8 +1058,8 @@ static struct clk_regmap axg_gen_clk_sel = { * hifi_pll, mpll0, mpll1, mpll2, mpll3, fdiv4, * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll */ - .parent_names = gen_clk_parent_names, - .num_parents = ARRAY_SIZE(gen_clk_parent_names), + .parent_data = gen_clk_parent_data, + .num_parents = ARRAY_SIZE(gen_clk_parent_data), }, }; @@ -992,7 +1072,9 @@ static struct clk_regmap axg_gen_clk_div = { .hw.init = &(struct clk_init_data){ .name = "gen_clk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "gen_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_gen_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1006,12 +1088,17 @@ static struct clk_regmap axg_gen_clk = { .hw.init = &(struct clk_init_data){ .name = "gen_clk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "gen_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_gen_clk_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; +#define MESON_GATE(_name, _reg, _bit) \ + MESON_PCLK(_name, _reg, _bit, &axg_clk81.hw) + /* Everything Else (EE) domain gates */ static MESON_GATE(axg_ddr, HHI_GCLK_MPEG0, 0); static MESON_GATE(axg_audio_locker, HHI_GCLK_MPEG0, 2); diff --git a/drivers/clk/meson/clk-cpu-dyndiv.c b/drivers/clk/meson/clk-cpu-dyndiv.c new file mode 100644 index 000000000000..36976927fe82 --- /dev/null +++ b/drivers/clk/meson/clk-cpu-dyndiv.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS. + * Author: Neil Armstrong + */ + +#include +#include + +#include "clk-regmap.h" +#include "clk-cpu-dyndiv.h" + +static inline struct meson_clk_cpu_dyndiv_data * +meson_clk_cpu_dyndiv_data(struct clk_regmap *clk) +{ + return (struct meson_clk_cpu_dyndiv_data *)clk->data; +} + +static unsigned long meson_clk_cpu_dyndiv_recalc_rate(struct clk_hw *hw, + unsigned long prate) +{ + struct clk_regmap *clk = to_clk_regmap(hw); + struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk); + + return divider_recalc_rate(hw, prate, + meson_parm_read(clk->map, &data->div), + NULL, 0, data->div.width); +} + +static long meson_clk_cpu_dyndiv_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *prate) +{ + struct clk_regmap *clk = to_clk_regmap(hw); + struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk); + + return divider_round_rate(hw, rate, prate, NULL, data->div.width, 0); +} + +static int meson_clk_cpu_dyndiv_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_regmap *clk = to_clk_regmap(hw); + struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk); + unsigned int val; + int ret; + + ret = divider_get_val(rate, parent_rate, NULL, data->div.width, 0); + if (ret < 0) + return ret; + + val = (unsigned int)ret << data->div.shift; + + /* Write the SYS_CPU_DYN_ENABLE bit before changing the divider */ + meson_parm_write(clk->map, &data->dyn, 1); + + /* Update the divider while removing the SYS_CPU_DYN_ENABLE bit */ + return regmap_update_bits(clk->map, data->div.reg_off, + SETPMASK(data->div.width, data->div.shift) | + SETPMASK(data->dyn.width, data->dyn.shift), + val); +}; + +const struct clk_ops meson_clk_cpu_dyndiv_ops = { + .recalc_rate = meson_clk_cpu_dyndiv_recalc_rate, + .round_rate = meson_clk_cpu_dyndiv_round_rate, + .set_rate = meson_clk_cpu_dyndiv_set_rate, +}; +EXPORT_SYMBOL_GPL(meson_clk_cpu_dyndiv_ops); + +MODULE_DESCRIPTION("Amlogic CPU Dynamic Clock divider"); +MODULE_AUTHOR("Neil Armstrong "); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/meson/clk-cpu-dyndiv.h b/drivers/clk/meson/clk-cpu-dyndiv.h new file mode 100644 index 000000000000..f4908404792e --- /dev/null +++ b/drivers/clk/meson/clk-cpu-dyndiv.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 BayLibre, SAS. + * Author: Neil Armstrong + */ + +#ifndef __MESON_CLK_CPU_DYNDIV_H +#define __MESON_CLK_CPU_DYNDIV_H + +#include +#include "parm.h" + +struct meson_clk_cpu_dyndiv_data { + struct parm div; + struct parm dyn; +}; + +extern const struct clk_ops meson_clk_cpu_dyndiv_ops; + +#endif /* __MESON_CLK_CPU_DYNDIV_H */ diff --git a/drivers/clk/meson/clk-input.c b/drivers/clk/meson/clk-input.c deleted file mode 100644 index 086226e9dba6..000000000000 --- a/drivers/clk/meson/clk-input.c +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MIT) -/* - * Copyright (c) 2018 BayLibre, SAS. - * Author: Jerome Brunet - */ - -#include -#include -#include -#include -#include "clk-input.h" - -static const struct clk_ops meson_clk_no_ops = {}; - -struct clk_hw *meson_clk_hw_register_input(struct device *dev, - const char *of_name, - const char *clk_name, - unsigned long flags) -{ - struct clk *parent_clk = devm_clk_get(dev, of_name); - struct clk_init_data init; - const char *parent_name; - struct clk_hw *hw; - int ret; - - if (IS_ERR(parent_clk)) - return (struct clk_hw *)parent_clk; - - hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); - if (!hw) - return ERR_PTR(-ENOMEM); - - parent_name = __clk_get_name(parent_clk); - init.name = clk_name; - init.ops = &meson_clk_no_ops; - init.flags = flags; - init.parent_names = &parent_name; - init.num_parents = 1; - hw->init = &init; - - ret = devm_clk_hw_register(dev, hw); - - return ret ? ERR_PTR(ret) : hw; -} -EXPORT_SYMBOL_GPL(meson_clk_hw_register_input); - -MODULE_DESCRIPTION("Amlogic clock input helper"); -MODULE_AUTHOR("Jerome Brunet "); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/meson/clk-input.h b/drivers/clk/meson/clk-input.h deleted file mode 100644 index 4a541b9685a6..000000000000 --- a/drivers/clk/meson/clk-input.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2019 BayLibre, SAS. - * Author: Jerome Brunet - */ - -#ifndef __MESON_CLK_INPUT_H -#define __MESON_CLK_INPUT_H - -#include - -struct device; - -struct clk_hw *meson_clk_hw_register_input(struct device *dev, - const char *of_name, - const char *clk_name, - unsigned long flags); - -#endif /* __MESON_CLK_INPUT_H */ diff --git a/drivers/clk/meson/clk-regmap.h b/drivers/clk/meson/clk-regmap.h index 1dd0abe3ba91..c4a39604cffd 100644 --- a/drivers/clk/meson/clk-regmap.h +++ b/drivers/clk/meson/clk-regmap.h @@ -111,7 +111,7 @@ clk_get_regmap_mux_data(struct clk_regmap *clk) extern const struct clk_ops clk_regmap_mux_ops; extern const struct clk_ops clk_regmap_mux_ro_ops; -#define __MESON_GATE(_name, _reg, _bit, _ops) \ +#define __MESON_PCLK(_name, _reg, _bit, _ops, _pname) \ struct clk_regmap _name = { \ .data = &(struct clk_regmap_gate_data){ \ .offset = (_reg), \ @@ -120,15 +120,15 @@ struct clk_regmap _name = { \ .hw.init = &(struct clk_init_data) { \ .name = #_name, \ .ops = _ops, \ - .parent_names = (const char *[]){ "clk81" }, \ + .parent_hws = (const struct clk_hw *[]) { _pname }, \ .num_parents = 1, \ .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ }, \ } -#define MESON_GATE(_name, _reg, _bit) \ - __MESON_GATE(_name, _reg, _bit, &clk_regmap_gate_ops) +#define MESON_PCLK(_name, _reg, _bit, _pname) \ + __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pname) -#define MESON_GATE_RO(_name, _reg, _bit) \ - __MESON_GATE(_name, _reg, _bit, &clk_regmap_gate_ro_ops) +#define MESON_PCLK_RO(_name, _reg, _bit, _pname) \ + __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pname) #endif /* __CLK_REGMAP_H */ diff --git a/drivers/clk/meson/g12a-aoclk.c b/drivers/clk/meson/g12a-aoclk.c index 1994e735396b..62499563e4f5 100644 --- a/drivers/clk/meson/g12a-aoclk.c +++ b/drivers/clk/meson/g12a-aoclk.c @@ -18,8 +18,6 @@ #include "clk-regmap.h" #include "clk-dualdiv.h" -#define IN_PREFIX "ao-in-" - /* * AO Configuration Clock registers offsets * Register offsets from the data sheet must be multiplied by 4. @@ -51,7 +49,9 @@ static struct clk_regmap g12a_aoclk_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "g12a_ao_" #_name, \ .ops = &clk_regmap_gate_ops, \ - .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \ + .parent_data = &(const struct clk_parent_data) { \ + .fw_name = "mpeg-clk", \ + }, \ .num_parents = 1, \ .flags = CLK_IGNORE_UNUSED, \ }, \ @@ -81,7 +81,9 @@ static struct clk_regmap g12a_aoclk_cts_oscin = { .hw.init = &(struct clk_init_data){ .name = "cts_oscin", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -106,7 +108,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_pre = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_32k_by_oscin_pre", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_oscin" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_cts_oscin.hw + }, .num_parents = 1, }, }; @@ -143,7 +147,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_div = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_32k_by_oscin_div", .ops = &meson_clk_dualdiv_ops, - .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_pre" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_32k_by_oscin_pre.hw + }, .num_parents = 1, }, }; @@ -158,8 +164,10 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_sel = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_32k_by_oscin_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_div", - "g12a_ao_32k_by_oscin_pre" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_32k_by_oscin_div.hw, + &g12a_aoclk_32k_by_oscin_pre.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -173,7 +181,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_32k_by_oscin", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_32k_by_oscin_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -189,7 +199,9 @@ static struct clk_regmap g12a_aoclk_cec_pre = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_cec_pre", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_oscin" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_cts_oscin.hw + }, .num_parents = 1, }, }; @@ -226,7 +238,9 @@ static struct clk_regmap g12a_aoclk_cec_div = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_cec_div", .ops = &meson_clk_dualdiv_ops, - .parent_names = (const char *[]){ "g12a_ao_cec_pre" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_cec_pre.hw + }, .num_parents = 1, }, }; @@ -241,8 +255,10 @@ static struct clk_regmap g12a_aoclk_cec_sel = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_cec_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "g12a_ao_cec_div", - "g12a_ao_cec_pre" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_cec_div.hw, + &g12a_aoclk_cec_pre.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -256,7 +272,9 @@ static struct clk_regmap g12a_aoclk_cec = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_cec", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "g12a_ao_cec_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_cec_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -272,8 +290,10 @@ static struct clk_regmap g12a_aoclk_cts_rtc_oscin = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_cts_rtc_oscin", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin", - IN_PREFIX "ext_32k-0" }, + .parent_data = (const struct clk_parent_data []) { + { .hw = &g12a_aoclk_32k_by_oscin.hw }, + { .fw_name = "ext-32k-0", }, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -289,8 +309,10 @@ static struct clk_regmap g12a_aoclk_clk81 = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_clk81", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk", - "g12a_ao_cts_rtc_oscin"}, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "mpeg-clk", }, + { .hw = &g12a_aoclk_cts_rtc_oscin.hw }, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -305,8 +327,10 @@ static struct clk_regmap g12a_aoclk_saradc_mux = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_saradc_mux", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal", - "g12a_ao_clk81" }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_aoclk_clk81.hw }, + }, .num_parents = 2, }, }; @@ -320,7 +344,9 @@ static struct clk_regmap g12a_aoclk_saradc_div = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_saradc_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "g12a_ao_saradc_mux" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_saradc_mux.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -334,7 +360,9 @@ static struct clk_regmap g12a_aoclk_saradc_gate = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_saradc_gate", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "g12a_ao_saradc_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_saradc_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -417,12 +445,6 @@ static const struct clk_hw_onecell_data g12a_aoclk_onecell_data = { .num = NR_CLKS, }; -static const struct meson_aoclk_input g12a_aoclk_inputs[] = { - { .name = "xtal", .required = true }, - { .name = "mpeg-clk", .required = true }, - { .name = "ext-32k-0", .required = false }, -}; - static const struct meson_aoclk_data g12a_aoclkc_data = { .reset_reg = AO_RTI_GEN_CNTL_REG0, .num_reset = ARRAY_SIZE(g12a_aoclk_reset), @@ -430,9 +452,6 @@ static const struct meson_aoclk_data g12a_aoclkc_data = { .num_clks = ARRAY_SIZE(g12a_aoclk_regmap), .clks = g12a_aoclk_regmap, .hw_data = &g12a_aoclk_onecell_data, - .inputs = g12a_aoclk_inputs, - .num_inputs = ARRAY_SIZE(g12a_aoclk_inputs), - .input_prefix = IN_PREFIX, }; static const struct of_device_id g12a_aoclkc_match_table[] = { diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index db1c4ed9d54e..c3f0ffc3280d 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -14,11 +14,12 @@ #include #include #include +#include -#include "clk-input.h" #include "clk-mpll.h" #include "clk-pll.h" #include "clk-regmap.h" +#include "clk-cpu-dyndiv.h" #include "vid-pll-div.h" #include "meson-eeclk.h" #include "g12a.h" @@ -61,7 +62,9 @@ static struct clk_regmap g12a_fixed_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -76,7 +79,9 @@ static struct clk_regmap g12a_fixed_pll = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "fixed_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fixed_pll_dco.hw + }, .num_parents = 1, /* * This clock won't ever change at runtime so @@ -85,16 +90,9 @@ static struct clk_regmap g12a_fixed_pll = { }, }; -/* - * Internal sys pll emulation configuration parameters - */ -static const struct reg_sequence g12a_sys_init_regs[] = { - { .reg = HHI_SYS_PLL_CNTL1, .def = 0x00000000 }, - { .reg = HHI_SYS_PLL_CNTL2, .def = 0x00000000 }, - { .reg = HHI_SYS_PLL_CNTL3, .def = 0x48681c00 }, - { .reg = HHI_SYS_PLL_CNTL4, .def = 0x88770290 }, - { .reg = HHI_SYS_PLL_CNTL5, .def = 0x39272000 }, - { .reg = HHI_SYS_PLL_CNTL6, .def = 0x56540000 }, +static const struct pll_mult_range g12a_sys_pll_mult_range = { + .min = 128, + .max = 250, }; static struct clk_regmap g12a_sys_pll_dco = { @@ -124,14 +122,17 @@ static struct clk_regmap g12a_sys_pll_dco = { .shift = 29, .width = 1, }, - .init_regs = g12a_sys_init_regs, - .init_count = ARRAY_SIZE(g12a_sys_init_regs), + .range = &g12a_sys_pll_mult_range, }, .hw.init = &(struct clk_init_data){ .name = "sys_pll_dco", - .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, + /* This clock feeds the CPU, avoid disabling it */ + .flags = CLK_IS_CRITICAL, }, }; @@ -144,9 +145,12 @@ static struct clk_regmap g12a_sys_pll = { }, .hw.init = &(struct clk_init_data){ .name = "sys_pll", - .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "sys_pll_dco" }, + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sys_pll_dco.hw + }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -177,12 +181,17 @@ static struct clk_regmap g12b_sys1_pll_dco = { .shift = 29, .width = 1, }, + .range = &g12a_sys_pll_mult_range, }, .hw.init = &(struct clk_init_data){ .name = "sys1_pll_dco", - .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, + /* This clock feeds the CPU, avoid disabling it */ + .flags = CLK_IS_CRITICAL, }, }; @@ -195,9 +204,12 @@ static struct clk_regmap g12b_sys1_pll = { }, .hw.init = &(struct clk_init_data){ .name = "sys1_pll", - .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "sys1_pll_dco" }, + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12b_sys1_pll_dco.hw + }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -209,7 +221,7 @@ static struct clk_regmap g12a_sys_pll_div16_en = { .hw.init = &(struct clk_init_data) { .name = "sys_pll_div16_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "sys_pll" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_sys_pll.hw }, .num_parents = 1, /* * This clock is used to debug the sys_pll range @@ -226,7 +238,9 @@ static struct clk_regmap g12b_sys1_pll_div16_en = { .hw.init = &(struct clk_init_data) { .name = "sys1_pll_div16_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "sys1_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_sys1_pll.hw + }, .num_parents = 1, /* * This clock is used to debug the sys_pll range @@ -241,7 +255,9 @@ static struct clk_fixed_factor g12a_sys_pll_div16 = { .hw.init = &(struct clk_init_data){ .name = "sys_pll_div16", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "sys_pll_div16_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sys_pll_div16_en.hw + }, .num_parents = 1, }, }; @@ -252,11 +268,75 @@ static struct clk_fixed_factor g12b_sys1_pll_div16 = { .hw.init = &(struct clk_init_data){ .name = "sys1_pll_div16", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "sys1_pll_div16_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_sys1_pll_div16_en.hw + }, .num_parents = 1, }, }; +static struct clk_fixed_factor g12a_fclk_div2_div = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, + .num_parents = 1, + }, +}; + +static struct clk_regmap g12a_fclk_div2 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_FIX_PLL_CNTL1, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div2_div.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor g12a_fclk_div3_div = { + .mult = 1, + .div = 3, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div3_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, + .num_parents = 1, + }, +}; + +static struct clk_regmap g12a_fclk_div3 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_FIX_PLL_CNTL1, + .bit_idx = 20, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div3", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div3_div.hw + }, + .num_parents = 1, + /* + * This clock is used by the resident firmware and is required + * by the platform to operate correctly. + * Until the following condition are met, we need this clock to + * be marked as critical: + * a) Mark the clock used by a firmware resource, if possible + * b) CCF has a clock hand-off mechanism to make the sure the + * clock stays on until the proper driver comes along + */ + .flags = CLK_IS_CRITICAL, + }, +}; + /* Datasheet names this field as "premux0" */ static struct clk_regmap g12a_cpu_clk_premux0 = { .data = &(struct clk_regmap_mux_data){ @@ -266,42 +346,15 @@ static struct clk_regmap g12a_cpu_clk_premux0 = { }, .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn0_sel", - .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal", - "fclk_div2", - "fclk_div3" }, + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div2.hw }, + { .hw = &g12a_fclk_div3.hw }, + }, .num_parents = 3, - }, -}; - -/* Datasheet names this field as "mux0_divn_tcnt" */ -static struct clk_regmap g12a_cpu_clk_mux0_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_SYS_CPU_CLK_CNTL0, - .shift = 4, - .width = 6, - }, - .hw.init = &(struct clk_init_data){ - .name = "cpu_clk_dyn0_div", - .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_dyn0_sel" }, - .num_parents = 1, - }, -}; - -/* Datasheet names this field as "postmux0" */ -static struct clk_regmap g12a_cpu_clk_postmux0 = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_SYS_CPU_CLK_CNTL0, - .mask = 0x1, - .shift = 2, - }, - .hw.init = &(struct clk_init_data){ - .name = "cpu_clk_dyn0", - .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_dyn0_sel", - "cpu_clk_dyn0_div" }, - .num_parents = 2, + /* This sub-tree is used a parking clock */ + .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -314,11 +367,59 @@ static struct clk_regmap g12a_cpu_clk_premux1 = { }, .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn1_sel", - .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal", - "fclk_div2", - "fclk_div3" }, + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div2.hw }, + { .hw = &g12a_fclk_div3.hw }, + }, .num_parents = 3, + /* This sub-tree is used a parking clock */ + .flags = CLK_SET_RATE_NO_REPARENT + }, +}; + +/* Datasheet names this field as "mux0_divn_tcnt" */ +static struct clk_regmap g12a_cpu_clk_mux0_div = { + .data = &(struct meson_clk_cpu_dyndiv_data){ + .div = { + .reg_off = HHI_SYS_CPU_CLK_CNTL0, + .shift = 4, + .width = 6, + }, + .dyn = { + .reg_off = HHI_SYS_CPU_CLK_CNTL0, + .shift = 26, + .width = 1, + }, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpu_clk_dyn0_div", + .ops = &meson_clk_cpu_dyndiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_premux0.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* Datasheet names this field as "postmux0" */ +static struct clk_regmap g12a_cpu_clk_postmux0 = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL0, + .mask = 0x1, + .shift = 2, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpu_clk_dyn0", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_premux0.hw, + &g12a_cpu_clk_mux0_div.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -332,7 +433,9 @@ static struct clk_regmap g12a_cpu_clk_mux1_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn1_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_dyn1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_premux1.hw + }, .num_parents = 1, }, }; @@ -346,10 +449,14 @@ static struct clk_regmap g12a_cpu_clk_postmux1 = { }, .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn1", - .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_dyn1_sel", - "cpu_clk_dyn1_div" }, + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_premux1.hw, + &g12a_cpu_clk_mux1_div.hw, + }, .num_parents = 2, + /* This sub-tree is used a parking clock */ + .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -362,10 +469,13 @@ static struct clk_regmap g12a_cpu_clk_dyn = { }, .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn", - .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_dyn0", - "cpu_clk_dyn1" }, + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_postmux0.hw, + &g12a_cpu_clk_postmux1.hw, + }, .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -378,10 +488,13 @@ static struct clk_regmap g12a_cpu_clk = { }, .hw.init = &(struct clk_init_data){ .name = "cpu_clk", - .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_dyn", - "sys_pll" }, + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_dyn.hw, + &g12a_sys_pll.hw, + }, .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -394,10 +507,13 @@ static struct clk_regmap g12b_cpu_clk = { }, .hw.init = &(struct clk_init_data){ .name = "cpu_clk", - .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_dyn", - "sys1_pll" }, + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_dyn.hw, + &g12b_sys1_pll.hw + }, .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -410,26 +526,38 @@ static struct clk_regmap g12b_cpub_clk_premux0 = { }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn0_sel", - .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal", - "fclk_div2", - "fclk_div3" }, + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div2.hw }, + { .hw = &g12a_fclk_div3.hw }, + }, .num_parents = 3, }, }; /* Datasheet names this field as "mux0_divn_tcnt" */ static struct clk_regmap g12b_cpub_clk_mux0_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_SYS_CPUB_CLK_CNTL, - .shift = 4, - .width = 6, + .data = &(struct meson_clk_cpu_dyndiv_data){ + .div = { + .reg_off = HHI_SYS_CPUB_CLK_CNTL, + .shift = 4, + .width = 6, + }, + .dyn = { + .reg_off = HHI_SYS_CPUB_CLK_CNTL, + .shift = 26, + .width = 1, + }, }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn0_div", - .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_dyn0_sel" }, + .ops = &meson_clk_cpu_dyndiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_premux0.hw + }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -442,10 +570,13 @@ static struct clk_regmap g12b_cpub_clk_postmux0 = { }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn0", - .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_dyn0_sel", - "cpub_clk_dyn0_div" }, + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_premux0.hw, + &g12b_cpub_clk_mux0_div.hw + }, .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -458,11 +589,15 @@ static struct clk_regmap g12b_cpub_clk_premux1 = { }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn1_sel", - .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal", - "fclk_div2", - "fclk_div3" }, + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div2.hw }, + { .hw = &g12a_fclk_div3.hw }, + }, .num_parents = 3, + /* This sub-tree is used a parking clock */ + .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -476,7 +611,9 @@ static struct clk_regmap g12b_cpub_clk_mux1_div = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn1_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_dyn1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_premux1.hw + }, .num_parents = 1, }, }; @@ -490,10 +627,14 @@ static struct clk_regmap g12b_cpub_clk_postmux1 = { }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn1", - .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_dyn1_sel", - "cpub_clk_dyn1_div" }, + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_premux1.hw, + &g12b_cpub_clk_mux1_div.hw + }, .num_parents = 2, + /* This sub-tree is used a parking clock */ + .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -506,10 +647,13 @@ static struct clk_regmap g12b_cpub_clk_dyn = { }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn", - .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_dyn0", - "cpub_clk_dyn1" }, + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_postmux0.hw, + &g12b_cpub_clk_postmux1.hw + }, .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -522,13 +666,227 @@ static struct clk_regmap g12b_cpub_clk = { }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk", - .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_dyn", - "sys_pll" }, + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_dyn.hw, + &g12a_sys_pll.hw + }, .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, }, }; +static int g12a_cpu_clk_mux_notifier_cb(struct notifier_block *nb, + unsigned long event, void *data) +{ + if (event == POST_RATE_CHANGE || event == PRE_RATE_CHANGE) { + /* Wait for clock propagation before/after changing the mux */ + udelay(100); + return NOTIFY_OK; + } + + return NOTIFY_DONE; +} + +static struct notifier_block g12a_cpu_clk_mux_nb = { + .notifier_call = g12a_cpu_clk_mux_notifier_cb, +}; + +struct g12a_cpu_clk_postmux_nb_data { + struct notifier_block nb; + struct clk_hw *xtal; + struct clk_hw *cpu_clk_dyn; + struct clk_hw *cpu_clk_postmux0; + struct clk_hw *cpu_clk_postmux1; + struct clk_hw *cpu_clk_premux1; +}; + +static int g12a_cpu_clk_postmux_notifier_cb(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct g12a_cpu_clk_postmux_nb_data *nb_data = + container_of(nb, struct g12a_cpu_clk_postmux_nb_data, nb); + + switch (event) { + case PRE_RATE_CHANGE: + /* + * This notifier means cpu_clk_postmux0 clock will be changed + * to feed cpu_clk, this is the current path : + * cpu_clk + * \- cpu_clk_dyn + * \- cpu_clk_postmux0 + * \- cpu_clk_muxX_div + * \- cpu_clk_premux0 + * \- fclk_div3 or fclk_div2 + * OR + * \- cpu_clk_premux0 + * \- fclk_div3 or fclk_div2 + */ + + /* Setup cpu_clk_premux1 to xtal */ + clk_hw_set_parent(nb_data->cpu_clk_premux1, + nb_data->xtal); + + /* Setup cpu_clk_postmux1 to bypass divider */ + clk_hw_set_parent(nb_data->cpu_clk_postmux1, + nb_data->cpu_clk_premux1); + + /* Switch to parking clk on cpu_clk_postmux1 */ + clk_hw_set_parent(nb_data->cpu_clk_dyn, + nb_data->cpu_clk_postmux1); + + /* + * Now, cpu_clk is 24MHz in the current path : + * cpu_clk + * \- cpu_clk_dyn + * \- cpu_clk_postmux1 + * \- cpu_clk_premux1 + * \- xtal + */ + + udelay(100); + + return NOTIFY_OK; + + case POST_RATE_CHANGE: + /* + * The cpu_clk_postmux0 has ben updated, now switch back + * cpu_clk_dyn to cpu_clk_postmux0 and take the changes + * in account. + */ + + /* Configure cpu_clk_dyn back to cpu_clk_postmux0 */ + clk_hw_set_parent(nb_data->cpu_clk_dyn, + nb_data->cpu_clk_postmux0); + + /* + * new path : + * cpu_clk + * \- cpu_clk_dyn + * \- cpu_clk_postmux0 + * \- cpu_clk_muxX_div + * \- cpu_clk_premux0 + * \- fclk_div3 or fclk_div2 + * OR + * \- cpu_clk_premux0 + * \- fclk_div3 or fclk_div2 + */ + + udelay(100); + + return NOTIFY_OK; + + default: + return NOTIFY_DONE; + } +} + +static struct g12a_cpu_clk_postmux_nb_data g12a_cpu_clk_postmux0_nb_data = { + .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw, + .cpu_clk_postmux0 = &g12a_cpu_clk_postmux0.hw, + .cpu_clk_postmux1 = &g12a_cpu_clk_postmux1.hw, + .cpu_clk_premux1 = &g12a_cpu_clk_premux1.hw, + .nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb, +}; + +static struct g12a_cpu_clk_postmux_nb_data g12b_cpub_clk_postmux0_nb_data = { + .cpu_clk_dyn = &g12b_cpub_clk_dyn.hw, + .cpu_clk_postmux0 = &g12b_cpub_clk_postmux0.hw, + .cpu_clk_postmux1 = &g12b_cpub_clk_postmux1.hw, + .cpu_clk_premux1 = &g12b_cpub_clk_premux1.hw, + .nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb, +}; + +struct g12a_sys_pll_nb_data { + struct notifier_block nb; + struct clk_hw *sys_pll; + struct clk_hw *cpu_clk; + struct clk_hw *cpu_clk_dyn; +}; + +static int g12a_sys_pll_notifier_cb(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct g12a_sys_pll_nb_data *nb_data = + container_of(nb, struct g12a_sys_pll_nb_data, nb); + + switch (event) { + case PRE_RATE_CHANGE: + /* + * This notifier means sys_pll clock will be changed + * to feed cpu_clk, this the current path : + * cpu_clk + * \- sys_pll + * \- sys_pll_dco + */ + + /* Configure cpu_clk to use cpu_clk_dyn */ + clk_hw_set_parent(nb_data->cpu_clk, + nb_data->cpu_clk_dyn); + + /* + * Now, cpu_clk uses the dyn path + * cpu_clk + * \- cpu_clk_dyn + * \- cpu_clk_dynX + * \- cpu_clk_dynX_sel + * \- cpu_clk_dynX_div + * \- xtal/fclk_div2/fclk_div3 + * \- xtal/fclk_div2/fclk_div3 + */ + + udelay(100); + + return NOTIFY_OK; + + case POST_RATE_CHANGE: + /* + * The sys_pll has ben updated, now switch back cpu_clk to + * sys_pll + */ + + /* Configure cpu_clk to use sys_pll */ + clk_hw_set_parent(nb_data->cpu_clk, + nb_data->sys_pll); + + udelay(100); + + /* new path : + * cpu_clk + * \- sys_pll + * \- sys_pll_dco + */ + + return NOTIFY_OK; + + default: + return NOTIFY_DONE; + } +} + +static struct g12a_sys_pll_nb_data g12a_sys_pll_nb_data = { + .sys_pll = &g12a_sys_pll.hw, + .cpu_clk = &g12a_cpu_clk.hw, + .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw, + .nb.notifier_call = g12a_sys_pll_notifier_cb, +}; + +/* G12B first CPU cluster uses sys1_pll */ +static struct g12a_sys_pll_nb_data g12b_cpu_clk_sys1_pll_nb_data = { + .sys_pll = &g12b_sys1_pll.hw, + .cpu_clk = &g12b_cpu_clk.hw, + .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw, + .nb.notifier_call = g12a_sys_pll_notifier_cb, +}; + +/* G12B second CPU cluster uses sys_pll */ +static struct g12a_sys_pll_nb_data g12b_cpub_clk_sys_pll_nb_data = { + .sys_pll = &g12a_sys_pll.hw, + .cpu_clk = &g12b_cpub_clk.hw, + .cpu_clk_dyn = &g12b_cpub_clk_dyn.hw, + .nb.notifier_call = g12a_sys_pll_notifier_cb, +}; + static struct clk_regmap g12a_cpu_clk_div16_en = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_SYS_CPU_CLK_CNTL1, @@ -537,7 +895,9 @@ static struct clk_regmap g12a_cpu_clk_div16_en = { .hw.init = &(struct clk_init_data) { .name = "cpu_clk_div16_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk.hw + }, .num_parents = 1, /* * This clock is used to debug the cpu_clk range @@ -554,7 +914,9 @@ static struct clk_regmap g12b_cpub_clk_div16_en = { .hw.init = &(struct clk_init_data) { .name = "cpub_clk_div16_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, /* * This clock is used to debug the cpu_clk range @@ -569,7 +931,9 @@ static struct clk_fixed_factor g12a_cpu_clk_div16 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div16", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk_div16_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_div16_en.hw + }, .num_parents = 1, }, }; @@ -580,7 +944,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div16 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div16", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk_div16_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_div16_en.hw + }, .num_parents = 1, }, }; @@ -595,7 +961,7 @@ static struct clk_regmap g12a_cpu_clk_apb_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_apb_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw }, .num_parents = 1, }, }; @@ -608,7 +974,9 @@ static struct clk_regmap g12a_cpu_clk_apb = { .hw.init = &(struct clk_init_data) { .name = "cpu_clk_apb", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_apb_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_apb_div.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -627,7 +995,7 @@ static struct clk_regmap g12a_cpu_clk_atb_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_atb_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw }, .num_parents = 1, }, }; @@ -640,7 +1008,9 @@ static struct clk_regmap g12a_cpu_clk_atb = { .hw.init = &(struct clk_init_data) { .name = "cpu_clk_atb", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_atb_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_atb_div.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -659,7 +1029,7 @@ static struct clk_regmap g12a_cpu_clk_axi_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_axi_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw }, .num_parents = 1, }, }; @@ -672,7 +1042,9 @@ static struct clk_regmap g12a_cpu_clk_axi = { .hw.init = &(struct clk_init_data) { .name = "cpu_clk_axi", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_axi_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_axi_div.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -691,7 +1063,17 @@ static struct clk_regmap g12a_cpu_clk_trace_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_trace_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_data = &(const struct clk_parent_data) { + /* + * Note: + * G12A and G12B have different cpu_clks (with + * different struct clk_hw). We fallback to the global + * naming string mechanism so cpu_clk_trace_div picks + * up the appropriate one. + */ + .name = "cpu_clk", + .index = -1, + }, .num_parents = 1, }, }; @@ -704,7 +1086,9 @@ static struct clk_regmap g12a_cpu_clk_trace = { .hw.init = &(struct clk_init_data) { .name = "cpu_clk_trace", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_trace_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_trace_div.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -719,7 +1103,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div2 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, }, }; @@ -730,7 +1116,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div3 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div3", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, }, }; @@ -741,7 +1129,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div4 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, }, }; @@ -752,7 +1142,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div5 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div5", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, }, }; @@ -763,7 +1155,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div6 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, }, }; @@ -774,7 +1168,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div7 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div7", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, }, }; @@ -785,7 +1181,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div8 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div8", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, }, }; @@ -801,13 +1199,15 @@ static struct clk_regmap g12b_cpub_clk_apb_sel = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_apb_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_div2", - "cpub_clk_div3", - "cpub_clk_div4", - "cpub_clk_div5", - "cpub_clk_div6", - "cpub_clk_div7", - "cpub_clk_div8" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_div2.hw, + &g12b_cpub_clk_div3.hw, + &g12b_cpub_clk_div4.hw, + &g12b_cpub_clk_div5.hw, + &g12b_cpub_clk_div6.hw, + &g12b_cpub_clk_div7.hw, + &g12b_cpub_clk_div8.hw + }, .num_parents = 7, }, }; @@ -821,7 +1221,9 @@ static struct clk_regmap g12b_cpub_clk_apb = { .hw.init = &(struct clk_init_data) { .name = "cpub_clk_apb", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_apb_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_apb_sel.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -840,13 +1242,15 @@ static struct clk_regmap g12b_cpub_clk_atb_sel = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_atb_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_div2", - "cpub_clk_div3", - "cpub_clk_div4", - "cpub_clk_div5", - "cpub_clk_div6", - "cpub_clk_div7", - "cpub_clk_div8" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_div2.hw, + &g12b_cpub_clk_div3.hw, + &g12b_cpub_clk_div4.hw, + &g12b_cpub_clk_div5.hw, + &g12b_cpub_clk_div6.hw, + &g12b_cpub_clk_div7.hw, + &g12b_cpub_clk_div8.hw + }, .num_parents = 7, }, }; @@ -860,7 +1264,9 @@ static struct clk_regmap g12b_cpub_clk_atb = { .hw.init = &(struct clk_init_data) { .name = "cpub_clk_atb", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_atb_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_atb_sel.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -879,13 +1285,15 @@ static struct clk_regmap g12b_cpub_clk_axi_sel = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_axi_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_div2", - "cpub_clk_div3", - "cpub_clk_div4", - "cpub_clk_div5", - "cpub_clk_div6", - "cpub_clk_div7", - "cpub_clk_div8" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_div2.hw, + &g12b_cpub_clk_div3.hw, + &g12b_cpub_clk_div4.hw, + &g12b_cpub_clk_div5.hw, + &g12b_cpub_clk_div6.hw, + &g12b_cpub_clk_div7.hw, + &g12b_cpub_clk_div8.hw + }, .num_parents = 7, }, }; @@ -899,7 +1307,9 @@ static struct clk_regmap g12b_cpub_clk_axi = { .hw.init = &(struct clk_init_data) { .name = "cpub_clk_axi", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_axi_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_axi_sel.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -918,13 +1328,15 @@ static struct clk_regmap g12b_cpub_clk_trace_sel = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_trace_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_div2", - "cpub_clk_div3", - "cpub_clk_div4", - "cpub_clk_div5", - "cpub_clk_div6", - "cpub_clk_div7", - "cpub_clk_div8" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_div2.hw, + &g12b_cpub_clk_div3.hw, + &g12b_cpub_clk_div4.hw, + &g12b_cpub_clk_div5.hw, + &g12b_cpub_clk_div6.hw, + &g12b_cpub_clk_div7.hw, + &g12b_cpub_clk_div8.hw + }, .num_parents = 7, }, }; @@ -938,7 +1350,9 @@ static struct clk_regmap g12b_cpub_clk_trace = { .hw.init = &(struct clk_init_data) { .name = "cpub_clk_trace", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_trace_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_trace_sel.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -1003,7 +1417,9 @@ static struct clk_regmap g12a_gp0_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "gp0_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -1019,7 +1435,9 @@ static struct clk_regmap g12a_gp0_pll = { .hw.init = &(struct clk_init_data){ .name = "gp0_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "gp0_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_gp0_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1077,7 +1495,9 @@ static struct clk_regmap g12a_hifi_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "hifi_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -1093,7 +1513,9 @@ static struct clk_regmap g12a_hifi_pll = { .hw.init = &(struct clk_init_data){ .name = "hifi_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "hifi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_hifi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1164,7 +1586,9 @@ static struct clk_regmap g12a_pcie_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "pcie_pll_dco", .ops = &meson_clk_pcie_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -1175,7 +1599,9 @@ static struct clk_fixed_factor g12a_pcie_pll_dco_div2 = { .hw.init = &(struct clk_init_data){ .name = "pcie_pll_dco_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "pcie_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_pcie_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1193,7 +1619,9 @@ static struct clk_regmap g12a_pcie_pll_od = { .hw.init = &(struct clk_init_data){ .name = "pcie_pll_od", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "pcie_pll_dco_div2" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_pcie_pll_dco_div2.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1205,7 +1633,9 @@ static struct clk_fixed_factor g12a_pcie_pll = { .hw.init = &(struct clk_init_data){ .name = "pcie_pll_pll", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "pcie_pll_od" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_pcie_pll_od.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1247,7 +1677,9 @@ static struct clk_regmap g12a_hdmi_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, /* * Display directly handle hdmi pll registers ATM, we need @@ -1267,7 +1699,9 @@ static struct clk_regmap g12a_hdmi_pll_od = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_hdmi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -1283,7 +1717,9 @@ static struct clk_regmap g12a_hdmi_pll_od2 = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od2", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_od" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_hdmi_pll_od.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -1299,77 +1735,21 @@ static struct clk_regmap g12a_hdmi_pll = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_od2" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_hdmi_pll_od2.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, }; -static struct clk_fixed_factor g12a_fclk_div2_div = { - .mult = 1, - .div = 2, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div2_div", - .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, - .num_parents = 1, - }, -}; - -static struct clk_regmap g12a_fclk_div2 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_FIX_PLL_CNTL1, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div2", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div2_div" }, - .num_parents = 1, - }, -}; - -static struct clk_fixed_factor g12a_fclk_div3_div = { - .mult = 1, - .div = 3, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div3_div", - .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, - .num_parents = 1, - }, -}; - -static struct clk_regmap g12a_fclk_div3 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_FIX_PLL_CNTL1, - .bit_idx = 20, - }, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div3", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div3_div" }, - .num_parents = 1, - /* - * This clock is used by the resident firmware and is required - * by the platform to operate correctly. - * Until the following condition are met, we need this clock to - * be marked as critical: - * a) Mark the clock used by a firmware resource, if possible - * b) CCF has a clock hand-off mechanism to make the sure the - * clock stays on until the proper driver comes along - */ - .flags = CLK_IS_CRITICAL, - }, -}; - static struct clk_fixed_factor g12a_fclk_div4_div = { .mult = 1, .div = 4, .hw.init = &(struct clk_init_data){ .name = "fclk_div4_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, .num_parents = 1, }, }; @@ -1382,7 +1762,9 @@ static struct clk_regmap g12a_fclk_div4 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div4", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div4_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div4_div.hw + }, .num_parents = 1, }, }; @@ -1393,7 +1775,7 @@ static struct clk_fixed_factor g12a_fclk_div5_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, .num_parents = 1, }, }; @@ -1406,7 +1788,9 @@ static struct clk_regmap g12a_fclk_div5 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div5_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div5_div.hw + }, .num_parents = 1, }, }; @@ -1417,7 +1801,7 @@ static struct clk_fixed_factor g12a_fclk_div7_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, .num_parents = 1, }, }; @@ -1430,7 +1814,9 @@ static struct clk_regmap g12a_fclk_div7 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div7_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div7_div.hw + }, .num_parents = 1, }, }; @@ -1441,7 +1827,9 @@ static struct clk_fixed_factor g12a_fclk_div2p5_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2p5_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fixed_pll_dco.hw + }, .num_parents = 1, }, }; @@ -1454,7 +1842,9 @@ static struct clk_regmap g12a_fclk_div2p5 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2p5", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div2p5_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div2p5_div.hw + }, .num_parents = 1, }, }; @@ -1465,7 +1855,9 @@ static struct clk_fixed_factor g12a_mpll_50m_div = { .hw.init = &(struct clk_init_data){ .name = "mpll_50m_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fixed_pll_dco.hw + }, .num_parents = 1, }, }; @@ -1479,8 +1871,10 @@ static struct clk_regmap g12a_mpll_50m = { .hw.init = &(struct clk_init_data){ .name = "mpll_50m", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal", - "mpll_50m_div" }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_mpll_50m_div.hw }, + }, .num_parents = 2, }, }; @@ -1491,7 +1885,9 @@ static struct clk_fixed_factor g12a_mpll_prediv = { .hw.init = &(struct clk_init_data){ .name = "mpll_prediv", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fixed_pll_dco.hw + }, .num_parents = 1, }, }; @@ -1529,7 +1925,9 @@ static struct clk_regmap g12a_mpll0_div = { .hw.init = &(struct clk_init_data){ .name = "mpll0_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -1542,7 +1940,7 @@ static struct clk_regmap g12a_mpll0 = { .hw.init = &(struct clk_init_data){ .name = "mpll0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll0_div" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_mpll0_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1581,7 +1979,9 @@ static struct clk_regmap g12a_mpll1_div = { .hw.init = &(struct clk_init_data){ .name = "mpll1_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -1594,7 +1994,7 @@ static struct clk_regmap g12a_mpll1 = { .hw.init = &(struct clk_init_data){ .name = "mpll1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll1_div" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_mpll1_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1633,7 +2033,9 @@ static struct clk_regmap g12a_mpll2_div = { .hw.init = &(struct clk_init_data){ .name = "mpll2_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -1646,7 +2048,7 @@ static struct clk_regmap g12a_mpll2 = { .hw.init = &(struct clk_init_data){ .name = "mpll2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll2_div" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_mpll2_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1685,7 +2087,9 @@ static struct clk_regmap g12a_mpll3_div = { .hw.init = &(struct clk_init_data){ .name = "mpll3_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -1698,16 +2102,21 @@ static struct clk_regmap g12a_mpll3 = { .hw.init = &(struct clk_init_data){ .name = "mpll3", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll3_div" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_mpll3_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; -static const char * const clk81_parent_names[] = { - IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", - "fclk_div3", "fclk_div5" +static const struct clk_parent_data clk81_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div7.hw }, + { .hw = &g12a_mpll1.hw }, + { .hw = &g12a_mpll2.hw }, + { .hw = &g12a_fclk_div4.hw }, + { .hw = &g12a_fclk_div3.hw }, + { .hw = &g12a_fclk_div5.hw }, }; static struct clk_regmap g12a_mpeg_clk_sel = { @@ -1720,8 +2129,8 @@ static struct clk_regmap g12a_mpeg_clk_sel = { .hw.init = &(struct clk_init_data){ .name = "mpeg_clk_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = clk81_parent_names, - .num_parents = ARRAY_SIZE(clk81_parent_names), + .parent_data = clk81_parent_data, + .num_parents = ARRAY_SIZE(clk81_parent_data), }, }; @@ -1734,7 +2143,9 @@ static struct clk_regmap g12a_mpeg_clk_div = { .hw.init = &(struct clk_init_data){ .name = "mpeg_clk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mpeg_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mpeg_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1748,15 +2159,20 @@ static struct clk_regmap g12a_clk81 = { .hw.init = &(struct clk_init_data){ .name = "clk81", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpeg_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mpeg_clk_div.hw + }, .num_parents = 1, .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), }, }; -static const char * const g12a_sd_emmc_clk0_parent_names[] = { - IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7", - +static const struct clk_parent_data g12a_sd_emmc_clk0_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div2.hw }, + { .hw = &g12a_fclk_div3.hw }, + { .hw = &g12a_fclk_div5.hw }, + { .hw = &g12a_fclk_div7.hw }, /* * Following these parent clocks, we should also have had mpll2, mpll3 * and gp0_pll but these clocks are too precious to be used here. All @@ -1775,8 +2191,8 @@ static struct clk_regmap g12a_sd_emmc_a_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_a_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names), + .parent_data = g12a_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1790,7 +2206,9 @@ static struct clk_regmap g12a_sd_emmc_a_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_a_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sd_emmc_a_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1804,7 +2222,9 @@ static struct clk_regmap g12a_sd_emmc_a_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_a_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sd_emmc_a_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1820,8 +2240,8 @@ static struct clk_regmap g12a_sd_emmc_b_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names), + .parent_data = g12a_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1835,7 +2255,9 @@ static struct clk_regmap g12a_sd_emmc_b_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sd_emmc_b_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1849,7 +2271,9 @@ static struct clk_regmap g12a_sd_emmc_b_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_b_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sd_emmc_b_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1865,8 +2289,8 @@ static struct clk_regmap g12a_sd_emmc_c_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names), + .parent_data = g12a_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1880,7 +2304,9 @@ static struct clk_regmap g12a_sd_emmc_c_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sd_emmc_c_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1894,399 +2320,14 @@ static struct clk_regmap g12a_sd_emmc_c_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_c_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sd_emmc_c_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -/* VPU Clock */ - -static const char * const g12a_vpu_parent_names[] = { - "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7", - "mpll1", "vid_pll", "hifi_pll", "gp0_pll", -}; - -static struct clk_regmap g12a_vpu_0_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VPU_CLK_CNTL, - .mask = 0x7, - .shift = 9, - }, - .hw.init = &(struct clk_init_data){ - .name = "vpu_0_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vpu_parent_names, - .num_parents = ARRAY_SIZE(g12a_vpu_parent_names), - .flags = CLK_SET_RATE_NO_REPARENT, - }, -}; - -static struct clk_regmap g12a_vpu_0_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_VPU_CLK_CNTL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data){ - .name = "vpu_0_div", - .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vpu_0_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vpu_0 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VPU_CLK_CNTL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "vpu_0", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vpu_0_div" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, - }, -}; - -static struct clk_regmap g12a_vpu_1_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VPU_CLK_CNTL, - .mask = 0x7, - .shift = 25, - }, - .hw.init = &(struct clk_init_data){ - .name = "vpu_1_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vpu_parent_names, - .num_parents = ARRAY_SIZE(g12a_vpu_parent_names), - .flags = CLK_SET_RATE_NO_REPARENT, - }, -}; - -static struct clk_regmap g12a_vpu_1_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_VPU_CLK_CNTL, - .shift = 16, - .width = 7, - }, - .hw.init = &(struct clk_init_data){ - .name = "vpu_1_div", - .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vpu_1_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vpu_1 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VPU_CLK_CNTL, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data) { - .name = "vpu_1", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vpu_1_div" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, - }, -}; - -static struct clk_regmap g12a_vpu = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VPU_CLK_CNTL, - .mask = 1, - .shift = 31, - }, - .hw.init = &(struct clk_init_data){ - .name = "vpu", - .ops = &clk_regmap_mux_ops, - /* - * bit 31 selects from 2 possible parents: - * vpu_0 or vpu_1 - */ - .parent_names = (const char *[]){ "vpu_0", "vpu_1" }, - .num_parents = 2, - .flags = CLK_SET_RATE_NO_REPARENT, - }, -}; - -/* VDEC clocks */ - -static const char * const g12a_vdec_parent_names[] = { - "fclk_div2p5", "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7", - "hifi_pll", "gp0_pll", -}; - -static struct clk_regmap g12a_vdec_1_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VDEC_CLK_CNTL, - .mask = 0x7, - .shift = 9, - .flags = CLK_MUX_ROUND_CLOSEST, - }, - .hw.init = &(struct clk_init_data){ - .name = "vdec_1_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vdec_parent_names, - .num_parents = ARRAY_SIZE(g12a_vdec_parent_names), - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_1_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_VDEC_CLK_CNTL, - .shift = 0, - .width = 7, - .flags = CLK_DIVIDER_ROUND_CLOSEST, - }, - .hw.init = &(struct clk_init_data){ - .name = "vdec_1_div", - .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_1_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_1 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VDEC_CLK_CNTL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "vdec_1", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_1_div" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_hevcf_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VDEC2_CLK_CNTL, - .mask = 0x7, - .shift = 9, - .flags = CLK_MUX_ROUND_CLOSEST, - }, - .hw.init = &(struct clk_init_data){ - .name = "vdec_hevcf_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vdec_parent_names, - .num_parents = ARRAY_SIZE(g12a_vdec_parent_names), - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_hevcf_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_VDEC2_CLK_CNTL, - .shift = 0, - .width = 7, - .flags = CLK_DIVIDER_ROUND_CLOSEST, - }, - .hw.init = &(struct clk_init_data){ - .name = "vdec_hevcf_div", - .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_hevcf_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_hevcf = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VDEC2_CLK_CNTL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "vdec_hevcf", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_hevcf_div" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_hevc_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VDEC2_CLK_CNTL, - .mask = 0x7, - .shift = 25, - .flags = CLK_MUX_ROUND_CLOSEST, - }, - .hw.init = &(struct clk_init_data){ - .name = "vdec_hevc_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vdec_parent_names, - .num_parents = ARRAY_SIZE(g12a_vdec_parent_names), - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_hevc_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_VDEC2_CLK_CNTL, - .shift = 16, - .width = 7, - .flags = CLK_DIVIDER_ROUND_CLOSEST, - }, - .hw.init = &(struct clk_init_data){ - .name = "vdec_hevc_div", - .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_hevc_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_hevc = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VDEC2_CLK_CNTL, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data) { - .name = "vdec_hevc", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_hevc_div" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -/* VAPB Clock */ - -static const char * const g12a_vapb_parent_names[] = { - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", - "mpll1", "vid_pll", "mpll2", "fclk_div2p5", -}; - -static struct clk_regmap g12a_vapb_0_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VAPBCLK_CNTL, - .mask = 0x3, - .shift = 9, - }, - .hw.init = &(struct clk_init_data){ - .name = "vapb_0_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vapb_parent_names, - .num_parents = ARRAY_SIZE(g12a_vapb_parent_names), - .flags = CLK_SET_RATE_NO_REPARENT, - }, -}; - -static struct clk_regmap g12a_vapb_0_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_VAPBCLK_CNTL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data){ - .name = "vapb_0_div", - .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vapb_0_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vapb_0 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VAPBCLK_CNTL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "vapb_0", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vapb_0_div" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, - }, -}; - -static struct clk_regmap g12a_vapb_1_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VAPBCLK_CNTL, - .mask = 0x3, - .shift = 25, - }, - .hw.init = &(struct clk_init_data){ - .name = "vapb_1_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vapb_parent_names, - .num_parents = ARRAY_SIZE(g12a_vapb_parent_names), - .flags = CLK_SET_RATE_NO_REPARENT, - }, -}; - -static struct clk_regmap g12a_vapb_1_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_VAPBCLK_CNTL, - .shift = 16, - .width = 7, - }, - .hw.init = &(struct clk_init_data){ - .name = "vapb_1_div", - .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vapb_1_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vapb_1 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VAPBCLK_CNTL, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data) { - .name = "vapb_1", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vapb_1_div" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, - }, -}; - -static struct clk_regmap g12a_vapb_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VAPBCLK_CNTL, - .mask = 1, - .shift = 31, - }, - .hw.init = &(struct clk_init_data){ - .name = "vapb_sel", - .ops = &clk_regmap_mux_ops, - /* - * bit 31 selects from 2 possible parents: - * vapb_0 or vapb_1 - */ - .parent_names = (const char *[]){ "vapb_0", "vapb_1" }, - .num_parents = 2, - .flags = CLK_SET_RATE_NO_REPARENT, - }, -}; - -static struct clk_regmap g12a_vapb = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VAPBCLK_CNTL, - .bit_idx = 30, - }, - .hw.init = &(struct clk_init_data) { - .name = "vapb", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vapb_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, - }, -}; - /* Video Clocks */ static struct clk_regmap g12a_vid_pll_div = { @@ -2305,14 +2346,16 @@ static struct clk_regmap g12a_vid_pll_div = { .hw.init = &(struct clk_init_data) { .name = "vid_pll_div", .ops = &meson_vid_pll_div_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_pll.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, }, }; -static const char * const g12a_vid_pll_parent_names[] = { "vid_pll_div", - "hdmi_pll" }; +static const struct clk_hw *g12a_vid_pll_parent_hws[] = { + &g12a_vid_pll_div.hw, + &g12a_hdmi_pll.hw, +}; static struct clk_regmap g12a_vid_pll_sel = { .data = &(struct clk_regmap_mux_data){ @@ -2327,8 +2370,8 @@ static struct clk_regmap g12a_vid_pll_sel = { * bit 18 selects from 2 possible parents: * vid_pll_div or hdmi_pll */ - .parent_names = g12a_vid_pll_parent_names, - .num_parents = ARRAY_SIZE(g12a_vid_pll_parent_names), + .parent_hws = g12a_vid_pll_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vid_pll_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2341,15 +2384,453 @@ static struct clk_regmap g12a_vid_pll = { .hw.init = &(struct clk_init_data) { .name = "vid_pll", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vid_pll_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vid_pll_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, }; -static const char * const g12a_vclk_parent_names[] = { - "vid_pll", "gp0_pll", "hifi_pll", "mpll1", "fclk_div3", "fclk_div4", - "fclk_div5", "fclk_div7" +/* VPU Clock */ + +static const struct clk_hw *g12a_vpu_parent_hws[] = { + &g12a_fclk_div3.hw, + &g12a_fclk_div4.hw, + &g12a_fclk_div5.hw, + &g12a_fclk_div7.hw, + &g12a_mpll1.hw, + &g12a_vid_pll.hw, + &g12a_hifi_pll.hw, + &g12a_gp0_pll.hw, +}; + +static struct clk_regmap g12a_vpu_0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VPU_CLK_CNTL, + .mask = 0x7, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_0_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = g12a_vpu_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vpu_parent_hws), + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap g12a_vpu_0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VPU_CLK_CNTL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_0_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vpu_0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VPU_CLK_CNTL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_0_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, +}; + +static struct clk_regmap g12a_vpu_1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VPU_CLK_CNTL, + .mask = 0x7, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = g12a_vpu_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vpu_parent_hws), + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap g12a_vpu_1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VPU_CLK_CNTL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_1_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vpu_1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VPU_CLK_CNTL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_1_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, +}; + +static struct clk_regmap g12a_vpu = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VPU_CLK_CNTL, + .mask = 1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu", + .ops = &clk_regmap_mux_ops, + /* + * bit 31 selects from 2 possible parents: + * vpu_0 or vpu_1 + */ + .parent_hws = (const struct clk_hw *[]) { + &g12a_vpu_0.hw, + &g12a_vpu_1.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +/* VDEC clocks */ + +static const struct clk_hw *g12a_vdec_parent_hws[] = { + &g12a_fclk_div2p5.hw, + &g12a_fclk_div3.hw, + &g12a_fclk_div4.hw, + &g12a_fclk_div5.hw, + &g12a_fclk_div7.hw, + &g12a_hifi_pll.hw, + &g12a_gp0_pll.hw, +}; + +static struct clk_regmap g12a_vdec_1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VDEC_CLK_CNTL, + .mask = 0x7, + .shift = 9, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = g12a_vdec_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VDEC_CLK_CNTL, + .shift = 0, + .width = 7, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vdec_1_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VDEC_CLK_CNTL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdec_1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vdec_1_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_hevcf_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .mask = 0x7, + .shift = 9, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_hevcf_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = g12a_vdec_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_hevcf_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .shift = 0, + .width = 7, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_hevcf_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vdec_hevcf_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_hevcf = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdec_hevcf", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vdec_hevcf_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_hevc_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .mask = 0x7, + .shift = 25, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_hevc_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = g12a_vdec_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_hevc_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .shift = 16, + .width = 7, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_hevc_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vdec_hevc_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_hevc = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdec_hevc", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vdec_hevc_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* VAPB Clock */ + +static const struct clk_hw *g12a_vapb_parent_hws[] = { + &g12a_fclk_div4.hw, + &g12a_fclk_div3.hw, + &g12a_fclk_div5.hw, + &g12a_fclk_div7.hw, + &g12a_mpll1.hw, + &g12a_vid_pll.hw, + &g12a_mpll2.hw, + &g12a_fclk_div2p5.hw, +}; + +static struct clk_regmap g12a_vapb_0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VAPBCLK_CNTL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_0_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = g12a_vapb_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vapb_parent_hws), + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap g12a_vapb_0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VAPBCLK_CNTL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vapb_0_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vapb_0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VAPBCLK_CNTL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vapb_0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vapb_0_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, +}; + +static struct clk_regmap g12a_vapb_1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VAPBCLK_CNTL, + .mask = 0x3, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = g12a_vapb_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vapb_parent_hws), + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap g12a_vapb_1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VAPBCLK_CNTL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vapb_1_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vapb_1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VAPBCLK_CNTL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "vapb_1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vapb_1_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, +}; + +static struct clk_regmap g12a_vapb_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VAPBCLK_CNTL, + .mask = 1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_sel", + .ops = &clk_regmap_mux_ops, + /* + * bit 31 selects from 2 possible parents: + * vapb_0 or vapb_1 + */ + .parent_hws = (const struct clk_hw *[]) { + &g12a_vapb_0.hw, + &g12a_vapb_1.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap g12a_vapb = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VAPBCLK_CNTL, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data) { + .name = "vapb", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_vapb_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, +}; + +static const struct clk_hw *g12a_vclk_parent_hws[] = { + &g12a_vid_pll.hw, + &g12a_gp0_pll.hw, + &g12a_hifi_pll.hw, + &g12a_mpll1.hw, + &g12a_fclk_div3.hw, + &g12a_fclk_div4.hw, + &g12a_fclk_div5.hw, + &g12a_fclk_div7.hw, }; static struct clk_regmap g12a_vclk_sel = { @@ -2361,8 +2842,8 @@ static struct clk_regmap g12a_vclk_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vclk_parent_names, - .num_parents = ARRAY_SIZE(g12a_vclk_parent_names), + .parent_hws = g12a_vclk_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vclk_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2376,8 +2857,8 @@ static struct clk_regmap g12a_vclk2_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk2_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vclk_parent_names, - .num_parents = ARRAY_SIZE(g12a_vclk_parent_names), + .parent_hws = g12a_vclk_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vclk_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2390,7 +2871,7 @@ static struct clk_regmap g12a_vclk_input = { .hw.init = &(struct clk_init_data) { .name = "vclk_input", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk_sel" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2404,7 +2885,7 @@ static struct clk_regmap g12a_vclk2_input = { .hw.init = &(struct clk_init_data) { .name = "vclk2_input", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2_sel" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2419,7 +2900,9 @@ static struct clk_regmap g12a_vclk_div = { .hw.init = &(struct clk_init_data){ .name = "vclk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vclk_input" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk_input.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE, }, @@ -2434,7 +2917,9 @@ static struct clk_regmap g12a_vclk2_div = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vclk2_input" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk2_input.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE, }, @@ -2448,7 +2933,7 @@ static struct clk_regmap g12a_vclk = { .hw.init = &(struct clk_init_data) { .name = "vclk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk_div" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2462,7 +2947,7 @@ static struct clk_regmap g12a_vclk2 = { .hw.init = &(struct clk_init_data) { .name = "vclk2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2_div" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2476,7 +2961,7 @@ static struct clk_regmap g12a_vclk_div1 = { .hw.init = &(struct clk_init_data) { .name = "vclk_div1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2490,7 +2975,7 @@ static struct clk_regmap g12a_vclk_div2_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div2_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2504,7 +2989,7 @@ static struct clk_regmap g12a_vclk_div4_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div4_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2518,7 +3003,7 @@ static struct clk_regmap g12a_vclk_div6_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div6_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2532,7 +3017,7 @@ static struct clk_regmap g12a_vclk_div12_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div12_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2546,7 +3031,7 @@ static struct clk_regmap g12a_vclk2_div1 = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2560,7 +3045,7 @@ static struct clk_regmap g12a_vclk2_div2_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div2_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2574,7 +3059,7 @@ static struct clk_regmap g12a_vclk2_div4_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div4_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2588,7 +3073,7 @@ static struct clk_regmap g12a_vclk2_div6_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div6_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2602,7 +3087,7 @@ static struct clk_regmap g12a_vclk2_div12_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div12_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2614,7 +3099,9 @@ static struct clk_fixed_factor g12a_vclk_div2 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div2_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk_div2_en.hw + }, .num_parents = 1, }, }; @@ -2625,7 +3112,9 @@ static struct clk_fixed_factor g12a_vclk_div4 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div4_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk_div4_en.hw + }, .num_parents = 1, }, }; @@ -2636,7 +3125,9 @@ static struct clk_fixed_factor g12a_vclk_div6 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div6_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk_div6_en.hw + }, .num_parents = 1, }, }; @@ -2647,7 +3138,9 @@ static struct clk_fixed_factor g12a_vclk_div12 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div12", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div12_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk_div12_en.hw + }, .num_parents = 1, }, }; @@ -2658,7 +3151,9 @@ static struct clk_fixed_factor g12a_vclk2_div2 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div2_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk2_div2_en.hw + }, .num_parents = 1, }, }; @@ -2669,7 +3164,9 @@ static struct clk_fixed_factor g12a_vclk2_div4 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div4_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk2_div4_en.hw + }, .num_parents = 1, }, }; @@ -2680,7 +3177,9 @@ static struct clk_fixed_factor g12a_vclk2_div6 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div6_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk2_div6_en.hw + }, .num_parents = 1, }, }; @@ -2691,16 +3190,25 @@ static struct clk_fixed_factor g12a_vclk2_div12 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div12", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div12_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk2_div12_en.hw + }, .num_parents = 1, }, }; static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const char * const g12a_cts_parent_names[] = { - "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6", - "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4", - "vclk2_div6", "vclk2_div12" +static const struct clk_hw *g12a_cts_parent_hws[] = { + &g12a_vclk_div1.hw, + &g12a_vclk_div2.hw, + &g12a_vclk_div4.hw, + &g12a_vclk_div6.hw, + &g12a_vclk_div12.hw, + &g12a_vclk2_div1.hw, + &g12a_vclk2_div2.hw, + &g12a_vclk2_div4.hw, + &g12a_vclk2_div6.hw, + &g12a_vclk2_div12.hw, }; static struct clk_regmap g12a_cts_enci_sel = { @@ -2713,8 +3221,8 @@ static struct clk_regmap g12a_cts_enci_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_enci_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_cts_parent_names, - .num_parents = ARRAY_SIZE(g12a_cts_parent_names), + .parent_hws = g12a_cts_parent_hws, + .num_parents = ARRAY_SIZE(g12a_cts_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2729,8 +3237,8 @@ static struct clk_regmap g12a_cts_encp_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_encp_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_cts_parent_names, - .num_parents = ARRAY_SIZE(g12a_cts_parent_names), + .parent_hws = g12a_cts_parent_hws, + .num_parents = ARRAY_SIZE(g12a_cts_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2745,18 +3253,25 @@ static struct clk_regmap g12a_cts_vdac_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_vdac_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_cts_parent_names, - .num_parents = ARRAY_SIZE(g12a_cts_parent_names), + .parent_hws = g12a_cts_parent_hws, + .num_parents = ARRAY_SIZE(g12a_cts_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; /* TOFIX: add support for cts_tcon */ static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const char * const g12a_cts_hdmi_tx_parent_names[] = { - "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6", - "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4", - "vclk2_div6", "vclk2_div12" +static const struct clk_hw *g12a_cts_hdmi_tx_parent_hws[] = { + &g12a_vclk_div1.hw, + &g12a_vclk_div2.hw, + &g12a_vclk_div4.hw, + &g12a_vclk_div6.hw, + &g12a_vclk_div12.hw, + &g12a_vclk2_div1.hw, + &g12a_vclk2_div2.hw, + &g12a_vclk2_div4.hw, + &g12a_vclk2_div6.hw, + &g12a_vclk2_div12.hw, }; static struct clk_regmap g12a_hdmi_tx_sel = { @@ -2769,8 +3284,8 @@ static struct clk_regmap g12a_hdmi_tx_sel = { .hw.init = &(struct clk_init_data){ .name = "hdmi_tx_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_cts_hdmi_tx_parent_names, - .num_parents = ARRAY_SIZE(g12a_cts_hdmi_tx_parent_names), + .parent_hws = g12a_cts_hdmi_tx_parent_hws, + .num_parents = ARRAY_SIZE(g12a_cts_hdmi_tx_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2783,7 +3298,9 @@ static struct clk_regmap g12a_cts_enci = { .hw.init = &(struct clk_init_data) { .name = "cts_enci", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_enci_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cts_enci_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2797,7 +3314,9 @@ static struct clk_regmap g12a_cts_encp = { .hw.init = &(struct clk_init_data) { .name = "cts_encp", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_encp_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cts_encp_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2811,7 +3330,9 @@ static struct clk_regmap g12a_cts_vdac = { .hw.init = &(struct clk_init_data) { .name = "cts_vdac", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_vdac_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cts_vdac_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2825,7 +3346,9 @@ static struct clk_regmap g12a_hdmi_tx = { .hw.init = &(struct clk_init_data) { .name = "hdmi_tx", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "hdmi_tx_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_hdmi_tx_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2833,8 +3356,11 @@ static struct clk_regmap g12a_hdmi_tx = { /* HDMI Clocks */ -static const char * const g12a_hdmi_parent_names[] = { - IN_PREFIX "xtal", "fclk_div4", "fclk_div3", "fclk_div5" +static const struct clk_parent_data g12a_hdmi_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div4.hw }, + { .hw = &g12a_fclk_div3.hw }, + { .hw = &g12a_fclk_div5.hw }, }; static struct clk_regmap g12a_hdmi_sel = { @@ -2847,8 +3373,8 @@ static struct clk_regmap g12a_hdmi_sel = { .hw.init = &(struct clk_init_data){ .name = "hdmi_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_hdmi_parent_names, - .num_parents = ARRAY_SIZE(g12a_hdmi_parent_names), + .parent_data = g12a_hdmi_parent_data, + .num_parents = ARRAY_SIZE(g12a_hdmi_parent_data), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2862,7 +3388,7 @@ static struct clk_regmap g12a_hdmi_div = { .hw.init = &(struct clk_init_data){ .name = "hdmi_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "hdmi_sel" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_sel.hw }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE, }, @@ -2876,7 +3402,7 @@ static struct clk_regmap g12a_hdmi = { .hw.init = &(struct clk_init_data) { .name = "hdmi", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "hdmi_div" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2886,10 +3412,15 @@ static struct clk_regmap g12a_hdmi = { * The MALI IP is clocked by two identical clocks (mali_0 and mali_1) * muxed by a glitch-free switch. */ - -static const char * const g12a_mali_0_1_parent_names[] = { - IN_PREFIX "xtal", "gp0_pll", "hihi_pll", "fclk_div2p5", - "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7" +static const struct clk_parent_data g12a_mali_0_1_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &g12a_gp0_pll.hw }, + { .hw = &g12a_hifi_pll.hw }, + { .hw = &g12a_fclk_div2p5.hw }, + { .hw = &g12a_fclk_div3.hw }, + { .hw = &g12a_fclk_div4.hw }, + { .hw = &g12a_fclk_div5.hw }, + { .hw = &g12a_fclk_div7.hw }, }; static struct clk_regmap g12a_mali_0_sel = { @@ -2901,7 +3432,7 @@ static struct clk_regmap g12a_mali_0_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_mali_0_1_parent_names, + .parent_data = g12a_mali_0_1_parent_data, .num_parents = 8, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -2916,7 +3447,9 @@ static struct clk_regmap g12a_mali_0_div = { .hw.init = &(struct clk_init_data){ .name = "mali_0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mali_0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mali_0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -2930,7 +3463,9 @@ static struct clk_regmap g12a_mali_0 = { .hw.init = &(struct clk_init_data){ .name = "mali_0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mali_0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mali_0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2945,7 +3480,7 @@ static struct clk_regmap g12a_mali_1_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_1_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_mali_0_1_parent_names, + .parent_data = g12a_mali_0_1_parent_data, .num_parents = 8, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -2960,7 +3495,9 @@ static struct clk_regmap g12a_mali_1_div = { .hw.init = &(struct clk_init_data){ .name = "mali_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mali_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mali_1_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -2974,14 +3511,17 @@ static struct clk_regmap g12a_mali_1 = { .hw.init = &(struct clk_init_data){ .name = "mali_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mali_1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mali_1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const char * const g12a_mali_parent_names[] = { - "mali_0", "mali_1" +static const struct clk_hw *g12a_mali_parent_hws[] = { + &g12a_mali_0.hw, + &g12a_mali_1.hw, }; static struct clk_regmap g12a_mali = { @@ -2993,7 +3533,7 @@ static struct clk_regmap g12a_mali = { .hw.init = &(struct clk_init_data){ .name = "mali", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_mali_parent_names, + .parent_hws = g12a_mali_parent_hws, .num_parents = 2, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -3008,7 +3548,9 @@ static struct clk_regmap g12a_ts_div = { .hw.init = &(struct clk_init_data){ .name = "ts_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -3021,11 +3563,19 @@ static struct clk_regmap g12a_ts = { .hw.init = &(struct clk_init_data){ .name = "ts", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "ts_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_ts_div.hw + }, .num_parents = 1, }, }; +#define MESON_GATE(_name, _reg, _bit) \ + MESON_PCLK(_name, _reg, _bit, &g12a_clk81.hw) + +#define MESON_GATE_RO(_name, _reg, _bit) \ + MESON_PCLK_RO(_name, _reg, _bit, &g12a_clk81.hw) + /* Everything Else (EE) domain gates */ static MESON_GATE(g12a_ddr, HHI_GCLK_MPEG0, 0); static MESON_GATE(g12a_dos, HHI_GCLK_MPEG0, 1); @@ -3792,28 +4342,210 @@ static const struct reg_sequence g12a_init_regs[] = { { .reg = HHI_MPLL_CNTL0, .def = 0x00000543 }, }; -static const struct meson_eeclkc_data g12a_clkc_data = { - .regmap_clks = g12a_clk_regmaps, - .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps), - .hw_onecell_data = &g12a_hw_onecell_data, - .init_regs = g12a_init_regs, - .init_count = ARRAY_SIZE(g12a_init_regs), +static int meson_g12a_dvfs_setup_common(struct platform_device *pdev, + struct clk_hw **hws) +{ + const char *notifier_clk_name; + struct clk *notifier_clk; + struct clk_hw *xtal; + int ret; + + xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0); + + /* Setup clock notifier for cpu_clk_postmux0 */ + g12a_cpu_clk_postmux0_nb_data.xtal = xtal; + notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_postmux0.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, + &g12a_cpu_clk_postmux0_nb_data.nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the cpu_clk_postmux0 notifier\n"); + return ret; + } + + /* Setup clock notifier for cpu_clk_dyn mux */ + notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_dyn.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the cpu_clk_dyn notifier\n"); + return ret; + } + + return 0; +} + +static int meson_g12b_dvfs_setup(struct platform_device *pdev) +{ + struct clk_hw **hws = g12b_hw_onecell_data.hws; + const char *notifier_clk_name; + struct clk *notifier_clk; + struct clk_hw *xtal; + int ret; + + ret = meson_g12a_dvfs_setup_common(pdev, hws); + if (ret) + return ret; + + xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0); + + /* Setup clock notifier for cpu_clk mux */ + notifier_clk_name = clk_hw_get_name(&g12b_cpu_clk.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n"); + return ret; + } + + /* Setup clock notifier for sys1_pll */ + notifier_clk_name = clk_hw_get_name(&g12b_sys1_pll.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, + &g12b_cpu_clk_sys1_pll_nb_data.nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the sys1_pll notifier\n"); + return ret; + } + + /* Add notifiers for the second CPU cluster */ + + /* Setup clock notifier for cpub_clk_postmux0 */ + g12b_cpub_clk_postmux0_nb_data.xtal = xtal; + notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_postmux0.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, + &g12b_cpub_clk_postmux0_nb_data.nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the cpub_clk_postmux0 notifier\n"); + return ret; + } + + /* Setup clock notifier for cpub_clk_dyn mux */ + notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_dyn.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the cpub_clk_dyn notifier\n"); + return ret; + } + + /* Setup clock notifier for cpub_clk mux */ + notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the cpub_clk notifier\n"); + return ret; + } + + /* Setup clock notifier for sys_pll */ + notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, + &g12b_cpub_clk_sys_pll_nb_data.nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the sys_pll notifier\n"); + return ret; + } + + return 0; +} + +static int meson_g12a_dvfs_setup(struct platform_device *pdev) +{ + struct clk_hw **hws = g12a_hw_onecell_data.hws; + const char *notifier_clk_name; + struct clk *notifier_clk; + int ret; + + ret = meson_g12a_dvfs_setup_common(pdev, hws); + if (ret) + return ret; + + /* Setup clock notifier for cpu_clk mux */ + notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n"); + return ret; + } + + /* Setup clock notifier for sys_pll */ + notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, &g12a_sys_pll_nb_data.nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the sys_pll notifier\n"); + return ret; + } + + return 0; +} + +struct meson_g12a_data { + const struct meson_eeclkc_data eeclkc_data; + int (*dvfs_setup)(struct platform_device *pdev); }; -static const struct meson_eeclkc_data g12b_clkc_data = { - .regmap_clks = g12a_clk_regmaps, - .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps), - .hw_onecell_data = &g12b_hw_onecell_data +static int meson_g12a_probe(struct platform_device *pdev) +{ + const struct meson_eeclkc_data *eeclkc_data; + const struct meson_g12a_data *g12a_data; + int ret; + + eeclkc_data = of_device_get_match_data(&pdev->dev); + if (!eeclkc_data) + return -EINVAL; + + ret = meson_eeclkc_probe(pdev); + if (ret) + return ret; + + g12a_data = container_of(eeclkc_data, struct meson_g12a_data, + eeclkc_data); + + if (g12a_data->dvfs_setup) + return g12a_data->dvfs_setup(pdev); + + return 0; +} + +static const struct meson_g12a_data g12a_clkc_data = { + .eeclkc_data = { + .regmap_clks = g12a_clk_regmaps, + .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps), + .hw_onecell_data = &g12a_hw_onecell_data, + .init_regs = g12a_init_regs, + .init_count = ARRAY_SIZE(g12a_init_regs), + }, + .dvfs_setup = meson_g12a_dvfs_setup, +}; + +static const struct meson_g12a_data g12b_clkc_data = { + .eeclkc_data = { + .regmap_clks = g12a_clk_regmaps, + .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps), + .hw_onecell_data = &g12b_hw_onecell_data, + }, + .dvfs_setup = meson_g12b_dvfs_setup, }; static const struct of_device_id clkc_match_table[] = { - { .compatible = "amlogic,g12a-clkc", .data = &g12a_clkc_data }, - { .compatible = "amlogic,g12b-clkc", .data = &g12b_clkc_data }, + { + .compatible = "amlogic,g12a-clkc", + .data = &g12a_clkc_data.eeclkc_data + }, + { + .compatible = "amlogic,g12b-clkc", + .data = &g12b_clkc_data.eeclkc_data + }, {} }; static struct platform_driver g12a_driver = { - .probe = meson_eeclkc_probe, + .probe = meson_g12a_probe, .driver = { .name = "g12a-clkc", .of_match_table = clkc_match_table, diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h index c8aed31fbe17..559a34cfdfeb 100644 --- a/drivers/clk/meson/g12a.h +++ b/drivers/clk/meson/g12a.h @@ -216,7 +216,6 @@ #define CLKID_CPUB_CLK_DYN1_DIV 221 #define CLKID_CPUB_CLK_DYN1 222 #define CLKID_CPUB_CLK_DYN 223 -#define CLKID_CPUB_CLK 224 #define CLKID_CPUB_CLK_DIV16_EN 225 #define CLKID_CPUB_CLK_DIV16 226 #define CLKID_CPUB_CLK_DIV2 227 diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index 449f6ac189d8..e940861a396b 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c @@ -11,8 +11,6 @@ #include "clk-regmap.h" #include "clk-dualdiv.h" -#define IN_PREFIX "ao-in-" - /* AO Configuration Clock registers offsets */ #define AO_RTI_PWR_CNTL_REG1 0x0c #define AO_RTI_PWR_CNTL_REG0 0x10 @@ -31,7 +29,9 @@ static struct clk_regmap _name##_ao = { \ .hw.init = &(struct clk_init_data) { \ .name = #_name "_ao", \ .ops = &clk_regmap_gate_ops, \ - .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \ + .parent_data = &(const struct clk_parent_data) { \ + .fw_name = "mpeg-clk", \ + }, \ .num_parents = 1, \ .flags = CLK_IGNORE_UNUSED, \ }, \ @@ -52,7 +52,9 @@ static struct clk_regmap ao_cts_oscin = { .hw.init = &(struct clk_init_data){ .name = "ao_cts_oscin", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -65,7 +67,7 @@ static struct clk_regmap ao_32k_pre = { .hw.init = &(struct clk_init_data){ .name = "ao_32k_pre", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "ao_cts_oscin" }, + .parent_hws = (const struct clk_hw *[]) { &ao_cts_oscin.hw }, .num_parents = 1, }, }; @@ -112,7 +114,7 @@ static struct clk_regmap ao_32k_div = { .hw.init = &(struct clk_init_data){ .name = "ao_32k_div", .ops = &meson_clk_dualdiv_ops, - .parent_names = (const char *[]){ "ao_32k_pre" }, + .parent_hws = (const struct clk_hw *[]) { &ao_32k_pre.hw }, .num_parents = 1, }, }; @@ -127,8 +129,10 @@ static struct clk_regmap ao_32k_sel = { .hw.init = &(struct clk_init_data){ .name = "ao_32k_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "ao_32k_div", - "ao_32k_pre" }, + .parent_hws = (const struct clk_hw *[]) { + &ao_32k_div.hw, + &ao_32k_pre.hw + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -142,7 +146,7 @@ static struct clk_regmap ao_32k = { .hw.init = &(struct clk_init_data){ .name = "ao_32k", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "ao_32k_sel" }, + .parent_hws = (const struct clk_hw *[]) { &ao_32k_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -159,10 +163,12 @@ static struct clk_regmap ao_cts_rtc_oscin = { .hw.init = &(struct clk_init_data){ .name = "ao_cts_rtc_oscin", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ IN_PREFIX "ext-32k-0", - IN_PREFIX "ext-32k-1", - IN_PREFIX "ext-32k-2", - "ao_32k" }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "ext-32k-0", }, + { .fw_name = "ext-32k-1", }, + { .fw_name = "ext-32k-2", }, + { .hw = &ao_32k.hw }, + }, .num_parents = 4, .flags = CLK_SET_RATE_PARENT, }, @@ -178,8 +184,10 @@ static struct clk_regmap ao_clk81 = { .hw.init = &(struct clk_init_data){ .name = "ao_clk81", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk", - "ao_cts_rtc_oscin" }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "mpeg-clk", }, + { .hw = &ao_cts_rtc_oscin.hw }, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -208,8 +216,10 @@ static struct clk_regmap ao_cts_cec = { * Until CCF gets fixed, adding this fake parent that won't * ever be registered should work around the problem */ - .parent_names = (const char *[]){ "fixme", - "ao_cts_rtc_oscin" }, + .parent_data = (const struct clk_parent_data []) { + { .name = "fixme", .index = -1, }, + { .hw = &ao_cts_rtc_oscin.hw }, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -261,14 +271,6 @@ static const struct clk_hw_onecell_data gxbb_aoclk_onecell_data = { .num = NR_CLKS, }; -static const struct meson_aoclk_input gxbb_aoclk_inputs[] = { - { .name = "xtal", .required = true, }, - { .name = "mpeg-clk", .required = true, }, - {. name = "ext-32k-0", .required = false, }, - {. name = "ext-32k-1", .required = false, }, - {. name = "ext-32k-2", .required = false, }, -}; - static const struct meson_aoclk_data gxbb_aoclkc_data = { .reset_reg = AO_RTI_GEN_CNTL_REG0, .num_reset = ARRAY_SIZE(gxbb_aoclk_reset), @@ -276,9 +278,6 @@ static const struct meson_aoclk_data gxbb_aoclkc_data = { .num_clks = ARRAY_SIZE(gxbb_aoclk), .clks = gxbb_aoclk, .hw_data = &gxbb_aoclk_onecell_data, - .inputs = gxbb_aoclk_inputs, - .num_inputs = ARRAY_SIZE(gxbb_aoclk_inputs), - .input_prefix = IN_PREFIX, }; static const struct of_device_id gxbb_aoclkc_match_table[] = { diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index dab16d9b1af8..7cfb998eeb3e 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -10,15 +10,12 @@ #include #include "gxbb.h" -#include "clk-input.h" #include "clk-regmap.h" #include "clk-pll.h" #include "clk-mpll.h" #include "meson-eeclk.h" #include "vid-pll-div.h" -#define IN_PREFIX "ee-in-" - static DEFINE_SPINLOCK(meson_clk_lock); static const struct pll_params_table gxbb_gp0_pll_params_table[] = { @@ -121,7 +118,9 @@ static struct clk_regmap gxbb_fixed_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -136,7 +135,9 @@ static struct clk_regmap gxbb_fixed_pll = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "fixed_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_fixed_pll_dco.hw + }, .num_parents = 1, /* * This clock won't ever change at runtime so @@ -151,7 +152,9 @@ static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_pre_mult", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -192,7 +195,9 @@ static struct clk_regmap gxbb_hdmi_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_pre_mult" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_hdmi_pll_pre_mult.hw + }, .num_parents = 1, /* * Display directly handle hdmi pll registers ATM, we need @@ -244,7 +249,9 @@ static struct clk_regmap gxl_hdmi_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, /* * Display directly handle hdmi pll registers ATM, we need @@ -264,7 +271,9 @@ static struct clk_regmap gxbb_hdmi_pll_od = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_hdmi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -280,7 +289,9 @@ static struct clk_regmap gxbb_hdmi_pll_od2 = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od2", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_od" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_hdmi_pll_od.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -296,7 +307,9 @@ static struct clk_regmap gxbb_hdmi_pll = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_od2" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_hdmi_pll_od2.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -312,7 +325,9 @@ static struct clk_regmap gxl_hdmi_pll_od = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &gxl_hdmi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -328,7 +343,9 @@ static struct clk_regmap gxl_hdmi_pll_od2 = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od2", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_od" }, + .parent_hws = (const struct clk_hw *[]) { + &gxl_hdmi_pll_od.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -344,7 +361,9 @@ static struct clk_regmap gxl_hdmi_pll = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_od2" }, + .parent_hws = (const struct clk_hw *[]) { + &gxl_hdmi_pll_od2.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -381,7 +400,9 @@ static struct clk_regmap gxbb_sys_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "sys_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -396,7 +417,9 @@ static struct clk_regmap gxbb_sys_pll = { .hw.init = &(struct clk_init_data){ .name = "sys_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "sys_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sys_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -442,7 +465,9 @@ static struct clk_regmap gxbb_gp0_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "gp0_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -494,7 +519,9 @@ static struct clk_regmap gxl_gp0_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "gp0_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -509,7 +536,17 @@ static struct clk_regmap gxbb_gp0_pll = { .hw.init = &(struct clk_init_data){ .name = "gp0_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "gp0_pll_dco" }, + .parent_data = &(const struct clk_parent_data) { + /* + * Note: + * GXL and GXBB have different gp0_pll_dco (with + * different struct clk_hw). We fallback to the global + * naming string mechanism so gp0_pll picks up the + * appropriate one. + */ + .name = "gp0_pll_dco", + .index = -1, + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -521,7 +558,9 @@ static struct clk_fixed_factor gxbb_fclk_div2_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -534,7 +573,9 @@ static struct clk_regmap gxbb_fclk_div2 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div2_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_fclk_div2_div.hw + }, .num_parents = 1, .flags = CLK_IS_CRITICAL, }, @@ -546,7 +587,7 @@ static struct clk_fixed_factor gxbb_fclk_div3_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div3_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw }, .num_parents = 1, }, }; @@ -559,7 +600,9 @@ static struct clk_regmap gxbb_fclk_div3 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div3", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div3_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_fclk_div3_div.hw + }, .num_parents = 1, /* * FIXME: @@ -582,7 +625,7 @@ static struct clk_fixed_factor gxbb_fclk_div4_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div4_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw }, .num_parents = 1, }, }; @@ -595,7 +638,9 @@ static struct clk_regmap gxbb_fclk_div4 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div4", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div4_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_fclk_div4_div.hw + }, .num_parents = 1, }, }; @@ -606,7 +651,7 @@ static struct clk_fixed_factor gxbb_fclk_div5_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw }, .num_parents = 1, }, }; @@ -619,7 +664,9 @@ static struct clk_regmap gxbb_fclk_div5 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div5_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_fclk_div5_div.hw + }, .num_parents = 1, }, }; @@ -630,7 +677,7 @@ static struct clk_fixed_factor gxbb_fclk_div7_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw }, .num_parents = 1, }, }; @@ -643,7 +690,9 @@ static struct clk_regmap gxbb_fclk_div7 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div7_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_fclk_div7_div.hw + }, .num_parents = 1, }, }; @@ -657,7 +706,7 @@ static struct clk_regmap gxbb_mpll_prediv = { .hw.init = &(struct clk_init_data){ .name = "mpll_prediv", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw }, .num_parents = 1, }, }; @@ -684,7 +733,9 @@ static struct clk_regmap gxbb_mpll0_div = { .hw.init = &(struct clk_init_data){ .name = "mpll0_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -697,7 +748,7 @@ static struct clk_regmap gxbb_mpll0 = { .hw.init = &(struct clk_init_data){ .name = "mpll0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll0_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -725,7 +776,9 @@ static struct clk_regmap gxbb_mpll1_div = { .hw.init = &(struct clk_init_data){ .name = "mpll1_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -738,7 +791,7 @@ static struct clk_regmap gxbb_mpll1 = { .hw.init = &(struct clk_init_data){ .name = "mpll1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll1_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll1_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -766,7 +819,9 @@ static struct clk_regmap gxbb_mpll2_div = { .hw.init = &(struct clk_init_data){ .name = "mpll2_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -779,16 +834,21 @@ static struct clk_regmap gxbb_mpll2 = { .hw.init = &(struct clk_init_data){ .name = "mpll2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll2_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll2_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; -static const char * const clk81_parent_names[] = { - IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", - "fclk_div3", "fclk_div5" +static const struct clk_parent_data clk81_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &gxbb_fclk_div7.hw }, + { .hw = &gxbb_mpll1.hw }, + { .hw = &gxbb_mpll2.hw }, + { .hw = &gxbb_fclk_div4.hw }, + { .hw = &gxbb_fclk_div3.hw }, + { .hw = &gxbb_fclk_div5.hw }, }; static struct clk_regmap gxbb_mpeg_clk_sel = { @@ -806,8 +866,8 @@ static struct clk_regmap gxbb_mpeg_clk_sel = { * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2, * fclk_div4, fclk_div3, fclk_div5 */ - .parent_names = clk81_parent_names, - .num_parents = ARRAY_SIZE(clk81_parent_names), + .parent_data = clk81_parent_data, + .num_parents = ARRAY_SIZE(clk81_parent_data), }, }; @@ -820,7 +880,9 @@ static struct clk_regmap gxbb_mpeg_clk_div = { .hw.init = &(struct clk_init_data){ .name = "mpeg_clk_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "mpeg_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpeg_clk_sel.hw + }, .num_parents = 1, }, }; @@ -834,7 +896,9 @@ static struct clk_regmap gxbb_clk81 = { .hw.init = &(struct clk_init_data){ .name = "clk81", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpeg_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpeg_clk_div.hw + }, .num_parents = 1, .flags = CLK_IS_CRITICAL, }, @@ -850,7 +914,10 @@ static struct clk_regmap gxbb_sar_adc_clk_sel = { .name = "sar_adc_clk_sel", .ops = &clk_regmap_mux_ops, /* NOTE: The datasheet doesn't list the parents for bit 10 */ - .parent_names = (const char *[]){ IN_PREFIX "xtal", "clk81", }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &gxbb_clk81.hw }, + }, .num_parents = 2, }, }; @@ -864,7 +931,9 @@ static struct clk_regmap gxbb_sar_adc_clk_div = { .hw.init = &(struct clk_init_data){ .name = "sar_adc_clk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sar_adc_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sar_adc_clk_sel.hw + }, .num_parents = 1, }, }; @@ -877,7 +946,9 @@ static struct clk_regmap gxbb_sar_adc_clk = { .hw.init = &(struct clk_init_data){ .name = "sar_adc_clk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sar_adc_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sar_adc_clk_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -888,9 +959,15 @@ static struct clk_regmap gxbb_sar_adc_clk = { * muxed by a glitch-free switch. */ -static const char * const gxbb_mali_0_1_parent_names[] = { - IN_PREFIX "xtal", "gp0_pll", "mpll2", "mpll1", "fclk_div7", - "fclk_div4", "fclk_div3", "fclk_div5" +static const struct clk_parent_data gxbb_mali_0_1_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &gxbb_gp0_pll.hw }, + { .hw = &gxbb_mpll2.hw }, + { .hw = &gxbb_mpll1.hw }, + { .hw = &gxbb_fclk_div7.hw }, + { .hw = &gxbb_fclk_div4.hw }, + { .hw = &gxbb_fclk_div3.hw }, + { .hw = &gxbb_fclk_div5.hw }, }; static struct clk_regmap gxbb_mali_0_sel = { @@ -907,7 +984,7 @@ static struct clk_regmap gxbb_mali_0_sel = { * xtal, gp0_pll, mpll2, mpll1, fclk_div7, * fclk_div4, fclk_div3, fclk_div5 */ - .parent_names = gxbb_mali_0_1_parent_names, + .parent_data = gxbb_mali_0_1_parent_data, .num_parents = 8, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -922,7 +999,9 @@ static struct clk_regmap gxbb_mali_0_div = { .hw.init = &(struct clk_init_data){ .name = "mali_0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mali_0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mali_0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -936,7 +1015,9 @@ static struct clk_regmap gxbb_mali_0 = { .hw.init = &(struct clk_init_data){ .name = "mali_0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mali_0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mali_0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -956,7 +1037,7 @@ static struct clk_regmap gxbb_mali_1_sel = { * xtal, gp0_pll, mpll2, mpll1, fclk_div7, * fclk_div4, fclk_div3, fclk_div5 */ - .parent_names = gxbb_mali_0_1_parent_names, + .parent_data = gxbb_mali_0_1_parent_data, .num_parents = 8, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -971,7 +1052,9 @@ static struct clk_regmap gxbb_mali_1_div = { .hw.init = &(struct clk_init_data){ .name = "mali_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mali_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mali_1_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -985,14 +1068,17 @@ static struct clk_regmap gxbb_mali_1 = { .hw.init = &(struct clk_init_data){ .name = "mali_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mali_1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mali_1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const char * const gxbb_mali_parent_names[] = { - "mali_0", "mali_1" +static const struct clk_hw *gxbb_mali_parent_hws[] = { + &gxbb_mali_0.hw, + &gxbb_mali_1.hw, }; static struct clk_regmap gxbb_mali = { @@ -1004,7 +1090,7 @@ static struct clk_regmap gxbb_mali = { .hw.init = &(struct clk_init_data){ .name = "mali", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_mali_parent_names, + .parent_hws = gxbb_mali_parent_hws, .num_parents = 2, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -1021,7 +1107,11 @@ static struct clk_regmap gxbb_cts_amclk_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_amclk_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpll0.hw, + &gxbb_mpll1.hw, + &gxbb_mpll2.hw, + }, .num_parents = 3, }, }; @@ -1036,7 +1126,9 @@ static struct clk_regmap gxbb_cts_amclk_div = { .hw.init = &(struct clk_init_data){ .name = "cts_amclk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "cts_amclk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_amclk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1050,7 +1142,9 @@ static struct clk_regmap gxbb_cts_amclk = { .hw.init = &(struct clk_init_data){ .name = "cts_amclk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_amclk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_amclk_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1067,7 +1161,11 @@ static struct clk_regmap gxbb_cts_mclk_i958_sel = { .hw.init = &(struct clk_init_data) { .name = "cts_mclk_i958_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpll0.hw, + &gxbb_mpll1.hw, + &gxbb_mpll2.hw, + }, .num_parents = 3, }, }; @@ -1082,7 +1180,9 @@ static struct clk_regmap gxbb_cts_mclk_i958_div = { .hw.init = &(struct clk_init_data) { .name = "cts_mclk_i958_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "cts_mclk_i958_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_mclk_i958_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1096,7 +1196,9 @@ static struct clk_regmap gxbb_cts_mclk_i958 = { .hw.init = &(struct clk_init_data){ .name = "cts_mclk_i958", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_mclk_i958_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_mclk_i958_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1111,7 +1213,10 @@ static struct clk_regmap gxbb_cts_i958 = { .hw.init = &(struct clk_init_data){ .name = "cts_i958", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "cts_amclk", "cts_mclk_i958" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_amclk.hw, + &gxbb_cts_mclk_i958.hw + }, .num_parents = 2, /* *The parent is specific to origin of the audio data. Let the @@ -1121,6 +1226,33 @@ static struct clk_regmap gxbb_cts_i958 = { }, }; +static const struct clk_parent_data gxbb_32k_clk_parent_data[] = { + { .fw_name = "xtal", }, + /* + * FIXME: This clock is provided by the ao clock controller but the + * clock is not yet part of the binding of this controller, so string + * name must be use to set this parent. + */ + { .name = "cts_slow_oscin", .index = -1 }, + { .hw = &gxbb_fclk_div3.hw }, + { .hw = &gxbb_fclk_div5.hw }, +}; + +static struct clk_regmap gxbb_32k_clk_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_32K_CLK_CNTL, + .mask = 0x3, + .shift = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "32k_clk_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = gxbb_32k_clk_parent_data, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static struct clk_regmap gxbb_32k_clk_div = { .data = &(struct clk_regmap_div_data){ .offset = HHI_32K_CLK_CNTL, @@ -1130,7 +1262,9 @@ static struct clk_regmap gxbb_32k_clk_div = { .hw.init = &(struct clk_init_data){ .name = "32k_clk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "32k_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_32k_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST, }, @@ -1144,34 +1278,20 @@ static struct clk_regmap gxbb_32k_clk = { .hw.init = &(struct clk_init_data){ .name = "32k_clk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "32k_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_32k_clk_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const char * const gxbb_32k_clk_parent_names[] = { - IN_PREFIX "xtal", "cts_slow_oscin", "fclk_div3", "fclk_div5" -}; - -static struct clk_regmap gxbb_32k_clk_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_32K_CLK_CNTL, - .mask = 0x3, - .shift = 16, - }, - .hw.init = &(struct clk_init_data){ - .name = "32k_clk_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_32k_clk_parent_names, - .num_parents = 4, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static const char * const gxbb_sd_emmc_clk0_parent_names[] = { - IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7", - +static const struct clk_parent_data gxbb_sd_emmc_clk0_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &gxbb_fclk_div2.hw }, + { .hw = &gxbb_fclk_div3.hw }, + { .hw = &gxbb_fclk_div5.hw }, + { .hw = &gxbb_fclk_div7.hw }, /* * Following these parent clocks, we should also have had mpll2, mpll3 * and gp0_pll but these clocks are too precious to be used here. All @@ -1190,8 +1310,8 @@ static struct clk_regmap gxbb_sd_emmc_a_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_a_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), + .parent_data = gxbb_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1206,7 +1326,9 @@ static struct clk_regmap gxbb_sd_emmc_a_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_a_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sd_emmc_a_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1220,7 +1342,9 @@ static struct clk_regmap gxbb_sd_emmc_a_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_a_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sd_emmc_a_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1236,8 +1360,8 @@ static struct clk_regmap gxbb_sd_emmc_b_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), + .parent_data = gxbb_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1252,7 +1376,9 @@ static struct clk_regmap gxbb_sd_emmc_b_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sd_emmc_b_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1266,7 +1392,9 @@ static struct clk_regmap gxbb_sd_emmc_b_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_b_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sd_emmc_b_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1282,8 +1410,8 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), + .parent_data = gxbb_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1298,7 +1426,9 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sd_emmc_c_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1312,7 +1442,9 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_c_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sd_emmc_c_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1320,8 +1452,11 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0 = { /* VPU Clock */ -static const char * const gxbb_vpu_parent_names[] = { - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" +static const struct clk_hw *gxbb_vpu_parent_hws[] = { + &gxbb_fclk_div4.hw, + &gxbb_fclk_div3.hw, + &gxbb_fclk_div5.hw, + &gxbb_fclk_div7.hw, }; static struct clk_regmap gxbb_vpu_0_sel = { @@ -1337,8 +1472,8 @@ static struct clk_regmap gxbb_vpu_0_sel = { * bits 9:10 selects from 4 possible parents: * fclk_div4, fclk_div3, fclk_div5, fclk_div7, */ - .parent_names = gxbb_vpu_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vpu_parent_names), + .parent_hws = gxbb_vpu_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vpu_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -1352,7 +1487,7 @@ static struct clk_regmap gxbb_vpu_0_div = { .hw.init = &(struct clk_init_data){ .name = "vpu_0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vpu_0_sel" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_0_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1366,7 +1501,7 @@ static struct clk_regmap gxbb_vpu_0 = { .hw.init = &(struct clk_init_data) { .name = "vpu_0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vpu_0_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_0_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1385,8 +1520,8 @@ static struct clk_regmap gxbb_vpu_1_sel = { * bits 25:26 selects from 4 possible parents: * fclk_div4, fclk_div3, fclk_div5, fclk_div7, */ - .parent_names = gxbb_vpu_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vpu_parent_names), + .parent_hws = gxbb_vpu_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vpu_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -1400,7 +1535,7 @@ static struct clk_regmap gxbb_vpu_1_div = { .hw.init = &(struct clk_init_data){ .name = "vpu_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vpu_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_1_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1414,7 +1549,7 @@ static struct clk_regmap gxbb_vpu_1 = { .hw.init = &(struct clk_init_data) { .name = "vpu_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vpu_1_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_1_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1433,7 +1568,10 @@ static struct clk_regmap gxbb_vpu = { * bit 31 selects from 2 possible parents: * vpu_0 or vpu_1 */ - .parent_names = (const char *[]){ "vpu_0", "vpu_1" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vpu_0.hw, + &gxbb_vpu_1.hw + }, .num_parents = 2, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -1441,8 +1579,11 @@ static struct clk_regmap gxbb_vpu = { /* VAPB Clock */ -static const char * const gxbb_vapb_parent_names[] = { - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" +static const struct clk_hw *gxbb_vapb_parent_hws[] = { + &gxbb_fclk_div4.hw, + &gxbb_fclk_div3.hw, + &gxbb_fclk_div5.hw, + &gxbb_fclk_div7.hw, }; static struct clk_regmap gxbb_vapb_0_sel = { @@ -1458,8 +1599,8 @@ static struct clk_regmap gxbb_vapb_0_sel = { * bits 9:10 selects from 4 possible parents: * fclk_div4, fclk_div3, fclk_div5, fclk_div7, */ - .parent_names = gxbb_vapb_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vapb_parent_names), + .parent_hws = gxbb_vapb_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vapb_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -1473,7 +1614,9 @@ static struct clk_regmap gxbb_vapb_0_div = { .hw.init = &(struct clk_init_data){ .name = "vapb_0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vapb_0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vapb_0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1487,7 +1630,9 @@ static struct clk_regmap gxbb_vapb_0 = { .hw.init = &(struct clk_init_data) { .name = "vapb_0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vapb_0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vapb_0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1506,8 +1651,8 @@ static struct clk_regmap gxbb_vapb_1_sel = { * bits 25:26 selects from 4 possible parents: * fclk_div4, fclk_div3, fclk_div5, fclk_div7, */ - .parent_names = gxbb_vapb_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vapb_parent_names), + .parent_hws = gxbb_vapb_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vapb_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -1521,7 +1666,9 @@ static struct clk_regmap gxbb_vapb_1_div = { .hw.init = &(struct clk_init_data){ .name = "vapb_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vapb_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vapb_1_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1535,7 +1682,9 @@ static struct clk_regmap gxbb_vapb_1 = { .hw.init = &(struct clk_init_data) { .name = "vapb_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vapb_1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vapb_1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1554,7 +1703,10 @@ static struct clk_regmap gxbb_vapb_sel = { * bit 31 selects from 2 possible parents: * vapb_0 or vapb_1 */ - .parent_names = (const char *[]){ "vapb_0", "vapb_1" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vapb_0.hw, + &gxbb_vapb_1.hw + }, .num_parents = 2, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -1568,7 +1720,7 @@ static struct clk_regmap gxbb_vapb = { .hw.init = &(struct clk_init_data) { .name = "vapb", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vapb_sel" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vapb_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1592,13 +1744,33 @@ static struct clk_regmap gxbb_vid_pll_div = { .hw.init = &(struct clk_init_data) { .name = "vid_pll_div", .ops = &meson_vid_pll_div_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll" }, + .parent_data = &(const struct clk_parent_data) { + /* + * Note: + * GXL and GXBB have different hdmi_plls (with + * different struct clk_hw). We fallback to the global + * naming string mechanism so vid_pll_div picks up the + * appropriate one. + */ + .name = "hdmi_pll", + .index = -1, + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, }, }; -static const char * const gxbb_vid_pll_parent_names[] = { "vid_pll_div", "hdmi_pll" }; +static const struct clk_parent_data gxbb_vid_pll_parent_data[] = { + { .hw = &gxbb_vid_pll_div.hw }, + /* + * Note: + * GXL and GXBB have different hdmi_plls (with + * different struct clk_hw). We fallback to the global + * naming string mechanism so vid_pll_div picks up the + * appropriate one. + */ + { .name = "hdmi_pll", .index = -1 }, +}; static struct clk_regmap gxbb_vid_pll_sel = { .data = &(struct clk_regmap_mux_data){ @@ -1613,8 +1785,8 @@ static struct clk_regmap gxbb_vid_pll_sel = { * bit 18 selects from 2 possible parents: * vid_pll_div or hdmi_pll */ - .parent_names = gxbb_vid_pll_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vid_pll_parent_names), + .parent_data = gxbb_vid_pll_parent_data, + .num_parents = ARRAY_SIZE(gxbb_vid_pll_parent_data), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -1627,15 +1799,22 @@ static struct clk_regmap gxbb_vid_pll = { .hw.init = &(struct clk_init_data) { .name = "vid_pll", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vid_pll_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vid_pll_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, }; -static const char * const gxbb_vclk_parent_names[] = { - "vid_pll", "fclk_div4", "fclk_div3", "fclk_div5", "vid_pll", - "fclk_div7", "mpll1", +static const struct clk_hw *gxbb_vclk_parent_hws[] = { + &gxbb_vid_pll.hw, + &gxbb_fclk_div4.hw, + &gxbb_fclk_div3.hw, + &gxbb_fclk_div5.hw, + &gxbb_vid_pll.hw, + &gxbb_fclk_div7.hw, + &gxbb_mpll1.hw, }; static struct clk_regmap gxbb_vclk_sel = { @@ -1652,8 +1831,8 @@ static struct clk_regmap gxbb_vclk_sel = { * vid_pll, fclk_div4, fclk_div3, fclk_div5, * vid_pll, fclk_div7, mp1 */ - .parent_names = gxbb_vclk_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vclk_parent_names), + .parent_hws = gxbb_vclk_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vclk_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -1672,8 +1851,8 @@ static struct clk_regmap gxbb_vclk2_sel = { * vid_pll, fclk_div4, fclk_div3, fclk_div5, * vid_pll, fclk_div7, mp1 */ - .parent_names = gxbb_vclk_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vclk_parent_names), + .parent_hws = gxbb_vclk_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vclk_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -1686,7 +1865,7 @@ static struct clk_regmap gxbb_vclk_input = { .hw.init = &(struct clk_init_data) { .name = "vclk_input", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk_sel" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1700,7 +1879,7 @@ static struct clk_regmap gxbb_vclk2_input = { .hw.init = &(struct clk_init_data) { .name = "vclk2_input", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2_sel" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1715,7 +1894,9 @@ static struct clk_regmap gxbb_vclk_div = { .hw.init = &(struct clk_init_data){ .name = "vclk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vclk_input" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk_input.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE, }, @@ -1730,7 +1911,9 @@ static struct clk_regmap gxbb_vclk2_div = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vclk2_input" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk2_input.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE, }, @@ -1744,7 +1927,7 @@ static struct clk_regmap gxbb_vclk = { .hw.init = &(struct clk_init_data) { .name = "vclk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1758,7 +1941,7 @@ static struct clk_regmap gxbb_vclk2 = { .hw.init = &(struct clk_init_data) { .name = "vclk2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1772,7 +1955,7 @@ static struct clk_regmap gxbb_vclk_div1 = { .hw.init = &(struct clk_init_data) { .name = "vclk_div1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1786,7 +1969,7 @@ static struct clk_regmap gxbb_vclk_div2_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div2_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1800,7 +1983,7 @@ static struct clk_regmap gxbb_vclk_div4_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div4_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1814,7 +1997,7 @@ static struct clk_regmap gxbb_vclk_div6_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div6_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1828,7 +2011,7 @@ static struct clk_regmap gxbb_vclk_div12_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div12_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1842,7 +2025,7 @@ static struct clk_regmap gxbb_vclk2_div1 = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1856,7 +2039,7 @@ static struct clk_regmap gxbb_vclk2_div2_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div2_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1870,7 +2053,7 @@ static struct clk_regmap gxbb_vclk2_div4_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div4_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1884,7 +2067,7 @@ static struct clk_regmap gxbb_vclk2_div6_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div6_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1898,7 +2081,7 @@ static struct clk_regmap gxbb_vclk2_div12_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div12_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1910,7 +2093,9 @@ static struct clk_fixed_factor gxbb_vclk_div2 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div2_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk_div2_en.hw + }, .num_parents = 1, }, }; @@ -1921,7 +2106,9 @@ static struct clk_fixed_factor gxbb_vclk_div4 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div4_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk_div4_en.hw + }, .num_parents = 1, }, }; @@ -1932,7 +2119,9 @@ static struct clk_fixed_factor gxbb_vclk_div6 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div6_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk_div6_en.hw + }, .num_parents = 1, }, }; @@ -1943,7 +2132,9 @@ static struct clk_fixed_factor gxbb_vclk_div12 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div12", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div12_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk_div12_en.hw + }, .num_parents = 1, }, }; @@ -1954,7 +2145,9 @@ static struct clk_fixed_factor gxbb_vclk2_div2 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div2_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk2_div2_en.hw + }, .num_parents = 1, }, }; @@ -1965,7 +2158,9 @@ static struct clk_fixed_factor gxbb_vclk2_div4 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div4_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk2_div4_en.hw + }, .num_parents = 1, }, }; @@ -1976,7 +2171,9 @@ static struct clk_fixed_factor gxbb_vclk2_div6 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div6_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk2_div6_en.hw + }, .num_parents = 1, }, }; @@ -1987,16 +2184,25 @@ static struct clk_fixed_factor gxbb_vclk2_div12 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div12", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div12_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk2_div12_en.hw + }, .num_parents = 1, }, }; static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const char * const gxbb_cts_parent_names[] = { - "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6", - "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4", - "vclk2_div6", "vclk2_div12" +static const struct clk_hw *gxbb_cts_parent_hws[] = { + &gxbb_vclk_div1.hw, + &gxbb_vclk_div2.hw, + &gxbb_vclk_div4.hw, + &gxbb_vclk_div6.hw, + &gxbb_vclk_div12.hw, + &gxbb_vclk2_div1.hw, + &gxbb_vclk2_div2.hw, + &gxbb_vclk2_div4.hw, + &gxbb_vclk2_div6.hw, + &gxbb_vclk2_div12.hw, }; static struct clk_regmap gxbb_cts_enci_sel = { @@ -2009,8 +2215,8 @@ static struct clk_regmap gxbb_cts_enci_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_enci_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_cts_parent_names, - .num_parents = ARRAY_SIZE(gxbb_cts_parent_names), + .parent_hws = gxbb_cts_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2025,8 +2231,8 @@ static struct clk_regmap gxbb_cts_encp_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_encp_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_cts_parent_names, - .num_parents = ARRAY_SIZE(gxbb_cts_parent_names), + .parent_hws = gxbb_cts_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2041,18 +2247,25 @@ static struct clk_regmap gxbb_cts_vdac_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_vdac_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_cts_parent_names, - .num_parents = ARRAY_SIZE(gxbb_cts_parent_names), + .parent_hws = gxbb_cts_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; /* TOFIX: add support for cts_tcon */ static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const char * const gxbb_cts_hdmi_tx_parent_names[] = { - "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6", - "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4", - "vclk2_div6", "vclk2_div12" +static const struct clk_hw *gxbb_cts_hdmi_tx_parent_hws[] = { + &gxbb_vclk_div1.hw, + &gxbb_vclk_div2.hw, + &gxbb_vclk_div4.hw, + &gxbb_vclk_div6.hw, + &gxbb_vclk_div12.hw, + &gxbb_vclk2_div1.hw, + &gxbb_vclk2_div2.hw, + &gxbb_vclk2_div4.hw, + &gxbb_vclk2_div6.hw, + &gxbb_vclk2_div12.hw, }; static struct clk_regmap gxbb_hdmi_tx_sel = { @@ -2071,8 +2284,8 @@ static struct clk_regmap gxbb_hdmi_tx_sel = { * vclk2_div1, vclk2_div2, vclk2_div4, vclk2_div6, vclk2_div12, * cts_tcon */ - .parent_names = gxbb_cts_hdmi_tx_parent_names, - .num_parents = ARRAY_SIZE(gxbb_cts_hdmi_tx_parent_names), + .parent_hws = gxbb_cts_hdmi_tx_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_cts_hdmi_tx_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2085,7 +2298,9 @@ static struct clk_regmap gxbb_cts_enci = { .hw.init = &(struct clk_init_data) { .name = "cts_enci", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_enci_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_enci_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2099,7 +2314,9 @@ static struct clk_regmap gxbb_cts_encp = { .hw.init = &(struct clk_init_data) { .name = "cts_encp", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_encp_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_encp_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2113,7 +2330,9 @@ static struct clk_regmap gxbb_cts_vdac = { .hw.init = &(struct clk_init_data) { .name = "cts_vdac", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_vdac_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_vdac_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2127,7 +2346,9 @@ static struct clk_regmap gxbb_hdmi_tx = { .hw.init = &(struct clk_init_data) { .name = "hdmi_tx", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "hdmi_tx_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_hdmi_tx_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2135,8 +2356,11 @@ static struct clk_regmap gxbb_hdmi_tx = { /* HDMI Clocks */ -static const char * const gxbb_hdmi_parent_names[] = { - IN_PREFIX "xtal", "fclk_div4", "fclk_div3", "fclk_div5" +static const struct clk_parent_data gxbb_hdmi_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &gxbb_fclk_div4.hw }, + { .hw = &gxbb_fclk_div3.hw }, + { .hw = &gxbb_fclk_div5.hw }, }; static struct clk_regmap gxbb_hdmi_sel = { @@ -2149,8 +2373,8 @@ static struct clk_regmap gxbb_hdmi_sel = { .hw.init = &(struct clk_init_data){ .name = "hdmi_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_hdmi_parent_names, - .num_parents = ARRAY_SIZE(gxbb_hdmi_parent_names), + .parent_data = gxbb_hdmi_parent_data, + .num_parents = ARRAY_SIZE(gxbb_hdmi_parent_data), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2164,7 +2388,7 @@ static struct clk_regmap gxbb_hdmi_div = { .hw.init = &(struct clk_init_data){ .name = "hdmi_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "hdmi_sel" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_hdmi_sel.hw }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE, }, @@ -2178,7 +2402,7 @@ static struct clk_regmap gxbb_hdmi = { .hw.init = &(struct clk_init_data) { .name = "hdmi", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "hdmi_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_hdmi_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2186,8 +2410,11 @@ static struct clk_regmap gxbb_hdmi = { /* VDEC clocks */ -static const char * const gxbb_vdec_parent_names[] = { - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" +static const struct clk_hw *gxbb_vdec_parent_hws[] = { + &gxbb_fclk_div4.hw, + &gxbb_fclk_div3.hw, + &gxbb_fclk_div5.hw, + &gxbb_fclk_div7.hw, }; static struct clk_regmap gxbb_vdec_1_sel = { @@ -2200,8 +2427,8 @@ static struct clk_regmap gxbb_vdec_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_1_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_vdec_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vdec_parent_names), + .parent_hws = gxbb_vdec_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vdec_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2216,7 +2443,9 @@ static struct clk_regmap gxbb_vdec_1_div = { .hw.init = &(struct clk_init_data){ .name = "vdec_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vdec_1_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2230,7 +2459,9 @@ static struct clk_regmap gxbb_vdec_1 = { .hw.init = &(struct clk_init_data) { .name = "vdec_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vdec_1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2246,8 +2477,8 @@ static struct clk_regmap gxbb_vdec_hevc_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_hevc_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_vdec_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vdec_parent_names), + .parent_hws = gxbb_vdec_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vdec_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2262,7 +2493,9 @@ static struct clk_regmap gxbb_vdec_hevc_div = { .hw.init = &(struct clk_init_data){ .name = "vdec_hevc_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_hevc_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vdec_hevc_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2276,7 +2509,9 @@ static struct clk_regmap gxbb_vdec_hevc = { .hw.init = &(struct clk_init_data) { .name = "vdec_hevc", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_hevc_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vdec_hevc_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2284,9 +2519,18 @@ static struct clk_regmap gxbb_vdec_hevc = { static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, }; -static const char * const gen_clk_parent_names[] = { - IN_PREFIX "xtal", "vdec_1", "vdec_hevc", "mpll0", "mpll1", "mpll2", - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll", +static const struct clk_parent_data gen_clk_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &gxbb_vdec_1.hw }, + { .hw = &gxbb_vdec_hevc.hw }, + { .hw = &gxbb_mpll0.hw }, + { .hw = &gxbb_mpll1.hw }, + { .hw = &gxbb_mpll2.hw }, + { .hw = &gxbb_fclk_div4.hw }, + { .hw = &gxbb_fclk_div3.hw }, + { .hw = &gxbb_fclk_div5.hw }, + { .hw = &gxbb_fclk_div7.hw }, + { .hw = &gxbb_gp0_pll.hw }, }; static struct clk_regmap gxbb_gen_clk_sel = { @@ -2305,8 +2549,8 @@ static struct clk_regmap gxbb_gen_clk_sel = { * vid_pll, vid2_pll (hevc), mpll0, mpll1, mpll2, fdiv4, * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll */ - .parent_names = gen_clk_parent_names, - .num_parents = ARRAY_SIZE(gen_clk_parent_names), + .parent_data = gen_clk_parent_data, + .num_parents = ARRAY_SIZE(gen_clk_parent_data), }, }; @@ -2319,7 +2563,9 @@ static struct clk_regmap gxbb_gen_clk_div = { .hw.init = &(struct clk_init_data){ .name = "gen_clk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "gen_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_gen_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2333,12 +2579,17 @@ static struct clk_regmap gxbb_gen_clk = { .hw.init = &(struct clk_init_data){ .name = "gen_clk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "gen_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_gen_clk_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; +#define MESON_GATE(_name, _reg, _bit) \ + MESON_PCLK(_name, _reg, _bit, &gxbb_clk81.hw) + /* Everything Else (EE) domain gates */ static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0); static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1); diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c index b67951909e04..bf8bea675d24 100644 --- a/drivers/clk/meson/meson-aoclk.c +++ b/drivers/clk/meson/meson-aoclk.c @@ -17,8 +17,6 @@ #include #include "meson-aoclk.h" -#include "clk-input.h" - static int meson_aoclk_do_reset(struct reset_controller_dev *rcdev, unsigned long id) { @@ -33,37 +31,6 @@ static const struct reset_control_ops meson_aoclk_reset_ops = { .reset = meson_aoclk_do_reset, }; -static int meson_aoclkc_register_inputs(struct device *dev, - struct meson_aoclk_data *data) -{ - struct clk_hw *hw; - char *str; - int i; - - for (i = 0; i < data->num_inputs; i++) { - const struct meson_aoclk_input *in = &data->inputs[i]; - - str = kasprintf(GFP_KERNEL, "%s%s", data->input_prefix, - in->name); - if (!str) - return -ENOMEM; - - hw = meson_clk_hw_register_input(dev, in->name, str, 0); - kfree(str); - - if (IS_ERR(hw)) { - if (!in->required && PTR_ERR(hw) == -ENOENT) - continue; - else if (PTR_ERR(hw) != -EPROBE_DEFER) - dev_err(dev, "failed to register input %s\n", - in->name); - return PTR_ERR(hw); - } - } - - return 0; -} - int meson_aoclkc_probe(struct platform_device *pdev) { struct meson_aoclk_reset_controller *rstc; @@ -86,10 +53,6 @@ int meson_aoclkc_probe(struct platform_device *pdev) return PTR_ERR(regmap); } - ret = meson_aoclkc_register_inputs(dev, data); - if (ret) - return ret; - /* Reset Controller */ rstc->data = data; rstc->regmap = regmap; diff --git a/drivers/clk/meson/meson-aoclk.h b/drivers/clk/meson/meson-aoclk.h index 999cde3868f7..605b43855a69 100644 --- a/drivers/clk/meson/meson-aoclk.h +++ b/drivers/clk/meson/meson-aoclk.h @@ -18,20 +18,12 @@ #include "clk-regmap.h" -struct meson_aoclk_input { - const char *name; - bool required; -}; - struct meson_aoclk_data { const unsigned int reset_reg; const int num_reset; const unsigned int *reset; const int num_clks; struct clk_regmap **clks; - const int num_inputs; - const struct meson_aoclk_input *inputs; - const char *input_prefix; const struct clk_hw_onecell_data *hw_data; }; diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c index 6ba2094be257..a7cb1e7aedc4 100644 --- a/drivers/clk/meson/meson-eeclk.c +++ b/drivers/clk/meson/meson-eeclk.c @@ -10,7 +10,6 @@ #include #include -#include "clk-input.h" #include "clk-regmap.h" #include "meson-eeclk.h" @@ -18,7 +17,6 @@ int meson_eeclkc_probe(struct platform_device *pdev) { const struct meson_eeclkc_data *data; struct device *dev = &pdev->dev; - struct clk_hw *input; struct regmap *map; int ret, i; @@ -37,14 +35,6 @@ int meson_eeclkc_probe(struct platform_device *pdev) if (data->init_count) regmap_multi_reg_write(map, data->init_regs, data->init_count); - input = meson_clk_hw_register_input(dev, "xtal", IN_PREFIX "xtal", 0); - if (IS_ERR(input)) { - ret = PTR_ERR(input); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to get input clock"); - return ret; - } - /* Populate regmap for the regmap backed clocks */ for (i = 0; i < data->regmap_clk_num; i++) data->regmap_clks[i]->map = map; diff --git a/drivers/clk/meson/meson-eeclk.h b/drivers/clk/meson/meson-eeclk.h index 9ab5d6fa7ccb..77316207bde1 100644 --- a/drivers/clk/meson/meson-eeclk.h +++ b/drivers/clk/meson/meson-eeclk.h @@ -10,8 +10,6 @@ #include #include "clk-regmap.h" -#define IN_PREFIX "ee-in-" - struct platform_device; struct meson_eeclkc_data { diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 537219fa573e..67e6691e080c 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -97,7 +97,9 @@ static struct clk_regmap meson8b_fixed_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ "xtal" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_xtal.hw + }, .num_parents = 1, }, }; @@ -112,7 +114,9 @@ static struct clk_regmap meson8b_fixed_pll = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "fixed_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fixed_pll_dco.hw + }, .num_parents = 1, /* * This clock won't ever change at runtime so @@ -158,7 +162,9 @@ static struct clk_regmap meson8b_hdmi_pll_dco = { /* sometimes also called "HPLL" or "HPLL PLL" */ .name = "hdmi_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ "xtal" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_xtal.hw + }, .num_parents = 1, }, }; @@ -173,7 +179,9 @@ static struct clk_regmap meson8b_hdmi_pll_lvds_out = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_lvds_out", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_hdmi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -189,7 +197,9 @@ static struct clk_regmap meson8b_hdmi_pll_hdmi_out = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_hdmi_out", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_hdmi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -227,7 +237,9 @@ static struct clk_regmap meson8b_sys_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "sys_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ "xtal" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_xtal.hw + }, .num_parents = 1, }, }; @@ -242,7 +254,9 @@ static struct clk_regmap meson8b_sys_pll = { .hw.init = &(struct clk_init_data){ .name = "sys_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sys_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_sys_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -254,7 +268,9 @@ static struct clk_fixed_factor meson8b_fclk_div2_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -267,7 +283,9 @@ static struct clk_regmap meson8b_fclk_div2 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div2_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fclk_div2_div.hw + }, .num_parents = 1, /* * FIXME: Ethernet with a RGMII PHYs is not working if @@ -285,7 +303,9 @@ static struct clk_fixed_factor meson8b_fclk_div3_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div3_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -298,7 +318,9 @@ static struct clk_regmap meson8b_fclk_div3 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div3", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div3_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fclk_div3_div.hw + }, .num_parents = 1, }, }; @@ -309,7 +331,9 @@ static struct clk_fixed_factor meson8b_fclk_div4_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div4_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -322,7 +346,9 @@ static struct clk_regmap meson8b_fclk_div4 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div4", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div4_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fclk_div4_div.hw + }, .num_parents = 1, }, }; @@ -333,7 +359,9 @@ static struct clk_fixed_factor meson8b_fclk_div5_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -346,7 +374,9 @@ static struct clk_regmap meson8b_fclk_div5 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div5_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fclk_div5_div.hw + }, .num_parents = 1, }, }; @@ -357,7 +387,9 @@ static struct clk_fixed_factor meson8b_fclk_div7_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -370,7 +402,9 @@ static struct clk_regmap meson8b_fclk_div7 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div7_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fclk_div7_div.hw + }, .num_parents = 1, }, }; @@ -384,7 +418,9 @@ static struct clk_regmap meson8b_mpll_prediv = { .hw.init = &(struct clk_init_data){ .name = "mpll_prediv", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -416,7 +452,9 @@ static struct clk_regmap meson8b_mpll0_div = { .hw.init = &(struct clk_init_data){ .name = "mpll0_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -429,7 +467,9 @@ static struct clk_regmap meson8b_mpll0 = { .hw.init = &(struct clk_init_data){ .name = "mpll0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpll0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -457,7 +497,9 @@ static struct clk_regmap meson8b_mpll1_div = { .hw.init = &(struct clk_init_data){ .name = "mpll1_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -470,7 +512,9 @@ static struct clk_regmap meson8b_mpll1 = { .hw.init = &(struct clk_init_data){ .name = "mpll1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpll1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -498,7 +542,9 @@ static struct clk_regmap meson8b_mpll2_div = { .hw.init = &(struct clk_init_data){ .name = "mpll2_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -511,7 +557,9 @@ static struct clk_regmap meson8b_mpll2 = { .hw.init = &(struct clk_init_data){ .name = "mpll2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll2_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpll2_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -533,8 +581,11 @@ static struct clk_regmap meson8b_mpeg_clk_sel = { * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2, * fclk_div4, fclk_div3, fclk_div5 */ - .parent_names = (const char *[]){ "fclk_div3", "fclk_div4", - "fclk_div5" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fclk_div3.hw, + &meson8b_fclk_div4.hw, + &meson8b_fclk_div5.hw, + }, .num_parents = 3, }, }; @@ -548,7 +599,9 @@ static struct clk_regmap meson8b_mpeg_clk_div = { .hw.init = &(struct clk_init_data){ .name = "mpeg_clk_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "mpeg_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpeg_clk_sel.hw + }, .num_parents = 1, }, }; @@ -561,7 +614,9 @@ static struct clk_regmap meson8b_clk81 = { .hw.init = &(struct clk_init_data){ .name = "clk81", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpeg_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpeg_clk_div.hw + }, .num_parents = 1, .flags = CLK_IS_CRITICAL, }, @@ -576,7 +631,10 @@ static struct clk_regmap meson8b_cpu_in_sel = { .hw.init = &(struct clk_init_data){ .name = "cpu_in_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "xtal", "sys_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_xtal.hw, + &meson8b_sys_pll.hw, + }, .num_parents = 2, .flags = (CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), @@ -589,7 +647,9 @@ static struct clk_fixed_factor meson8b_cpu_in_div2 = { .hw.init = &(struct clk_init_data){ .name = "cpu_in_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_in_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_in_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -601,7 +661,9 @@ static struct clk_fixed_factor meson8b_cpu_in_div3 = { .hw.init = &(struct clk_init_data){ .name = "cpu_in_div3", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_in_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_in_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -630,7 +692,9 @@ static struct clk_regmap meson8b_cpu_scale_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_scale_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "cpu_in_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_in_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -649,13 +713,15 @@ static struct clk_regmap meson8b_cpu_scale_out_sel = { .ops = &clk_regmap_mux_ops, /* * NOTE: We are skipping the parent with value 0x2 (which is - * "cpu_in_div3") because it results in a duty cycle of 33% - * which makes the system unstable and can result in a lockup - * of the whole system. + * meson8b_cpu_in_div3) because it results in a duty cycle of + * 33% which makes the system unstable and can result in a + * lockup of the whole system. */ - .parent_names = (const char *[]) { "cpu_in_sel", - "cpu_in_div2", - "cpu_scale_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_in_sel.hw, + &meson8b_cpu_in_div2.hw, + &meson8b_cpu_scale_div.hw, + }, .num_parents = 3, .flags = CLK_SET_RATE_PARENT, }, @@ -670,8 +736,10 @@ static struct clk_regmap meson8b_cpu_clk = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "xtal", - "cpu_scale_out_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_xtal.hw, + &meson8b_cpu_scale_out_sel.hw, + }, .num_parents = 2, .flags = (CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT | @@ -690,8 +758,13 @@ static struct clk_regmap meson8b_nand_clk_sel = { .name = "nand_clk_sel", .ops = &clk_regmap_mux_ops, /* FIXME all other parents are unknown: */ - .parent_names = (const char *[]){ "fclk_div4", "fclk_div3", - "fclk_div5", "fclk_div7", "xtal" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fclk_div4.hw, + &meson8b_fclk_div3.hw, + &meson8b_fclk_div5.hw, + &meson8b_fclk_div7.hw, + &meson8b_xtal.hw, + }, .num_parents = 5, .flags = CLK_SET_RATE_PARENT, }, @@ -707,7 +780,9 @@ static struct clk_regmap meson8b_nand_clk_div = { .hw.init = &(struct clk_init_data){ .name = "nand_clk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "nand_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_nand_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -721,7 +796,9 @@ static struct clk_regmap meson8b_nand_clk_gate = { .hw.init = &(struct clk_init_data){ .name = "nand_clk_gate", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "nand_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_nand_clk_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -733,7 +810,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div2 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk.hw + }, .num_parents = 1, }, }; @@ -744,7 +823,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div3 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div3", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk.hw + }, .num_parents = 1, }, }; @@ -755,7 +836,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div4 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk.hw + }, .num_parents = 1, }, }; @@ -766,7 +849,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div5 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div5", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk.hw + }, .num_parents = 1, }, }; @@ -777,7 +862,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div6 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk.hw + }, .num_parents = 1, }, }; @@ -788,7 +875,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div7 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div7", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk.hw + }, .num_parents = 1, }, }; @@ -799,7 +888,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div8 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div8", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk.hw + }, .num_parents = 1, }, }; @@ -815,13 +906,15 @@ static struct clk_regmap meson8b_apb_clk_sel = { .hw.init = &(struct clk_init_data){ .name = "apb_clk_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "cpu_clk_div2", - "cpu_clk_div3", - "cpu_clk_div4", - "cpu_clk_div5", - "cpu_clk_div6", - "cpu_clk_div7", - "cpu_clk_div8", }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk_div2.hw, + &meson8b_cpu_clk_div3.hw, + &meson8b_cpu_clk_div4.hw, + &meson8b_cpu_clk_div5.hw, + &meson8b_cpu_clk_div6.hw, + &meson8b_cpu_clk_div7.hw, + &meson8b_cpu_clk_div8.hw, + }, .num_parents = 7, }, }; @@ -835,7 +928,9 @@ static struct clk_regmap meson8b_apb_clk_gate = { .hw.init = &(struct clk_init_data){ .name = "apb_clk_dis", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "apb_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_apb_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -850,13 +945,15 @@ static struct clk_regmap meson8b_periph_clk_sel = { .hw.init = &(struct clk_init_data){ .name = "periph_clk_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "cpu_clk_div2", - "cpu_clk_div3", - "cpu_clk_div4", - "cpu_clk_div5", - "cpu_clk_div6", - "cpu_clk_div7", - "cpu_clk_div8", }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk_div2.hw, + &meson8b_cpu_clk_div3.hw, + &meson8b_cpu_clk_div4.hw, + &meson8b_cpu_clk_div5.hw, + &meson8b_cpu_clk_div6.hw, + &meson8b_cpu_clk_div7.hw, + &meson8b_cpu_clk_div8.hw, + }, .num_parents = 7, }, }; @@ -870,7 +967,9 @@ static struct clk_regmap meson8b_periph_clk_gate = { .hw.init = &(struct clk_init_data){ .name = "periph_clk_dis", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "periph_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_periph_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -887,13 +986,15 @@ static struct clk_regmap meson8b_axi_clk_sel = { .hw.init = &(struct clk_init_data){ .name = "axi_clk_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "cpu_clk_div2", - "cpu_clk_div3", - "cpu_clk_div4", - "cpu_clk_div5", - "cpu_clk_div6", - "cpu_clk_div7", - "cpu_clk_div8", }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk_div2.hw, + &meson8b_cpu_clk_div3.hw, + &meson8b_cpu_clk_div4.hw, + &meson8b_cpu_clk_div5.hw, + &meson8b_cpu_clk_div6.hw, + &meson8b_cpu_clk_div7.hw, + &meson8b_cpu_clk_div8.hw, + }, .num_parents = 7, }, }; @@ -907,7 +1008,9 @@ static struct clk_regmap meson8b_axi_clk_gate = { .hw.init = &(struct clk_init_data){ .name = "axi_clk_dis", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "axi_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_axi_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -922,13 +1025,15 @@ static struct clk_regmap meson8b_l2_dram_clk_sel = { .hw.init = &(struct clk_init_data){ .name = "l2_dram_clk_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "cpu_clk_div2", - "cpu_clk_div3", - "cpu_clk_div4", - "cpu_clk_div5", - "cpu_clk_div6", - "cpu_clk_div7", - "cpu_clk_div8", }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk_div2.hw, + &meson8b_cpu_clk_div3.hw, + &meson8b_cpu_clk_div4.hw, + &meson8b_cpu_clk_div5.hw, + &meson8b_cpu_clk_div6.hw, + &meson8b_cpu_clk_div7.hw, + &meson8b_cpu_clk_div8.hw, + }, .num_parents = 7, }, }; @@ -942,7 +1047,9 @@ static struct clk_regmap meson8b_l2_dram_clk_gate = { .hw.init = &(struct clk_init_data){ .name = "l2_dram_clk_dis", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "l2_dram_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_l2_dram_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -963,7 +1070,9 @@ static struct clk_regmap meson8b_vid_pll_in_sel = { * Meson8b: hdmi_pll_dco * Meson8m2: vid2_pll */ - .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_hdmi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -977,7 +1086,9 @@ static struct clk_regmap meson8b_vid_pll_in_en = { .hw.init = &(struct clk_init_data){ .name = "vid_pll_in_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vid_pll_in_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vid_pll_in_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -992,7 +1103,9 @@ static struct clk_regmap meson8b_vid_pll_pre_div = { .hw.init = &(struct clk_init_data){ .name = "vid_pll_pre_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "vid_pll_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vid_pll_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1007,7 +1120,9 @@ static struct clk_regmap meson8b_vid_pll_post_div = { .hw.init = &(struct clk_init_data){ .name = "vid_pll_post_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "vid_pll_pre_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vid_pll_pre_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1023,8 +1138,10 @@ static struct clk_regmap meson8b_vid_pll = { .name = "vid_pll", .ops = &clk_regmap_mux_ro_ops, /* TODO: parent 0x2 is vid_pll_pre_div_mult7_div2 */ - .parent_names = (const char *[]){ "vid_pll_pre_div", - "vid_pll_post_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vid_pll_pre_div.hw, + &meson8b_vid_pll_post_div.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -1039,15 +1156,22 @@ static struct clk_regmap meson8b_vid_pll_final_div = { .hw.init = &(struct clk_init_data){ .name = "vid_pll_final_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "vid_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vid_pll.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const char * const meson8b_vclk_mux_parents[] = { - "vid_pll_final_div", "fclk_div4", "fclk_div3", "fclk_div5", - "vid_pll_final_div", "fclk_div7", "mpll1" +static const struct clk_hw *meson8b_vclk_mux_parent_hws[] = { + &meson8b_vid_pll_final_div.hw, + &meson8b_fclk_div4.hw, + &meson8b_fclk_div3.hw, + &meson8b_fclk_div5.hw, + &meson8b_vid_pll_final_div.hw, + &meson8b_fclk_div7.hw, + &meson8b_mpll1.hw, }; static struct clk_regmap meson8b_vclk_in_sel = { @@ -1059,8 +1183,8 @@ static struct clk_regmap meson8b_vclk_in_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk_in_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parents), + .parent_hws = meson8b_vclk_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1073,7 +1197,9 @@ static struct clk_regmap meson8b_vclk_in_en = { .hw.init = &(struct clk_init_data){ .name = "vclk_in_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk_in_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_in_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1087,7 +1213,9 @@ static struct clk_regmap meson8b_vclk_div1_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk_div1_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1099,7 +1227,9 @@ static struct clk_fixed_factor meson8b_vclk_div2_div = { .hw.init = &(struct clk_init_data){ .name = "vclk_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1113,7 +1243,9 @@ static struct clk_regmap meson8b_vclk_div2_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk_div2_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk_div2" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_div2_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1125,7 +1257,9 @@ static struct clk_fixed_factor meson8b_vclk_div4_div = { .hw.init = &(struct clk_init_data){ .name = "vclk_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1139,7 +1273,9 @@ static struct clk_regmap meson8b_vclk_div4_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk_div4_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk_div4" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_div4_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1151,7 +1287,9 @@ static struct clk_fixed_factor meson8b_vclk_div6_div = { .hw.init = &(struct clk_init_data){ .name = "vclk_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1165,7 +1303,9 @@ static struct clk_regmap meson8b_vclk_div6_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk_div6_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk_div6" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_div6_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1177,7 +1317,9 @@ static struct clk_fixed_factor meson8b_vclk_div12_div = { .hw.init = &(struct clk_init_data){ .name = "vclk_div12", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1191,7 +1333,9 @@ static struct clk_regmap meson8b_vclk_div12_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk_div12_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk_div12" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_div12_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1206,8 +1350,8 @@ static struct clk_regmap meson8b_vclk2_in_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk2_in_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parents), + .parent_hws = meson8b_vclk_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1220,7 +1364,9 @@ static struct clk_regmap meson8b_vclk2_clk_in_en = { .hw.init = &(struct clk_init_data){ .name = "vclk2_in_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk2_in_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_in_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1234,7 +1380,9 @@ static struct clk_regmap meson8b_vclk2_div1_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div1_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk2_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_clk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1246,7 +1394,9 @@ static struct clk_fixed_factor meson8b_vclk2_div2_div = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_clk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1260,7 +1410,9 @@ static struct clk_regmap meson8b_vclk2_div2_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div2_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk2_div2" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_div2_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1272,7 +1424,9 @@ static struct clk_fixed_factor meson8b_vclk2_div4_div = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_clk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1286,7 +1440,9 @@ static struct clk_regmap meson8b_vclk2_div4_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div4_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk2_div4" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_div4_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1298,7 +1454,9 @@ static struct clk_fixed_factor meson8b_vclk2_div6_div = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_clk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1312,7 +1470,9 @@ static struct clk_regmap meson8b_vclk2_div6_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div6_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk2_div6" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_div6_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1324,7 +1484,9 @@ static struct clk_fixed_factor meson8b_vclk2_div12_div = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div12", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_clk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1338,15 +1500,20 @@ static struct clk_regmap meson8b_vclk2_div12_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div12_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk2_div12" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_div12_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const char * const meson8b_vclk_enc_mux_parents[] = { - "vclk_div1_en", "vclk_div2_en", "vclk_div4_en", "vclk_div6_en", - "vclk_div12_en", +static const struct clk_hw *meson8b_vclk_enc_mux_parent_hws[] = { + &meson8b_vclk_div1_gate.hw, + &meson8b_vclk_div2_div_gate.hw, + &meson8b_vclk_div4_div_gate.hw, + &meson8b_vclk_div6_div_gate.hw, + &meson8b_vclk_div12_div_gate.hw, }; static struct clk_regmap meson8b_cts_enct_sel = { @@ -1358,8 +1525,8 @@ static struct clk_regmap meson8b_cts_enct_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_enct_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk_enc_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents), + .parent_hws = meson8b_vclk_enc_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1372,7 +1539,9 @@ static struct clk_regmap meson8b_cts_enct = { .hw.init = &(struct clk_init_data){ .name = "cts_enct", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cts_enct_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_enct_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1387,8 +1556,8 @@ static struct clk_regmap meson8b_cts_encp_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_encp_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk_enc_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents), + .parent_hws = meson8b_vclk_enc_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1401,7 +1570,9 @@ static struct clk_regmap meson8b_cts_encp = { .hw.init = &(struct clk_init_data){ .name = "cts_encp", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cts_encp_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_encp_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1416,8 +1587,8 @@ static struct clk_regmap meson8b_cts_enci_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_enci_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk_enc_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents), + .parent_hws = meson8b_vclk_enc_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1430,7 +1601,9 @@ static struct clk_regmap meson8b_cts_enci = { .hw.init = &(struct clk_init_data){ .name = "cts_enci", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cts_enci_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_enci_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1445,8 +1618,8 @@ static struct clk_regmap meson8b_hdmi_tx_pixel_sel = { .hw.init = &(struct clk_init_data){ .name = "hdmi_tx_pixel_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk_enc_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents), + .parent_hws = meson8b_vclk_enc_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1459,15 +1632,20 @@ static struct clk_regmap meson8b_hdmi_tx_pixel = { .hw.init = &(struct clk_init_data){ .name = "hdmi_tx_pixel", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "hdmi_tx_pixel_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_hdmi_tx_pixel_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const char * const meson8b_vclk2_enc_mux_parents[] = { - "vclk2_div1_en", "vclk2_div2_en", "vclk2_div4_en", "vclk2_div6_en", - "vclk2_div12_en", +static const struct clk_hw *meson8b_vclk2_enc_mux_parent_hws[] = { + &meson8b_vclk2_div1_gate.hw, + &meson8b_vclk2_div2_div_gate.hw, + &meson8b_vclk2_div4_div_gate.hw, + &meson8b_vclk2_div6_div_gate.hw, + &meson8b_vclk2_div12_div_gate.hw, }; static struct clk_regmap meson8b_cts_encl_sel = { @@ -1479,8 +1657,8 @@ static struct clk_regmap meson8b_cts_encl_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_encl_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk2_enc_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parents), + .parent_hws = meson8b_vclk2_enc_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1493,7 +1671,9 @@ static struct clk_regmap meson8b_cts_encl = { .hw.init = &(struct clk_init_data){ .name = "cts_encl", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cts_encl_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_encl_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1508,8 +1688,8 @@ static struct clk_regmap meson8b_cts_vdac0_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_vdac0_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk2_enc_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parents), + .parent_hws = meson8b_vclk2_enc_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1522,7 +1702,9 @@ static struct clk_regmap meson8b_cts_vdac0 = { .hw.init = &(struct clk_init_data){ .name = "cts_vdac0", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cts_vdac0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_vdac0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1539,7 +1721,9 @@ static struct clk_regmap meson8b_hdmi_sys_sel = { .name = "hdmi_sys_sel", .ops = &clk_regmap_mux_ro_ops, /* FIXME: all other parents are unknown */ - .parent_names = (const char *[]){ "xtal" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_xtal.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -1554,7 +1738,9 @@ static struct clk_regmap meson8b_hdmi_sys_div = { .hw.init = &(struct clk_init_data){ .name = "hdmi_sys_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_sys_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_hdmi_sys_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1568,7 +1754,9 @@ static struct clk_regmap meson8b_hdmi_sys = { .hw.init = &(struct clk_init_data) { .name = "hdmi_sys", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "hdmi_sys_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_hdmi_sys_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1579,9 +1767,14 @@ static struct clk_regmap meson8b_hdmi_sys = { * muxed by a glitch-free switch on Meson8b and Meson8m2. Meson8 only * has mali_0 and no glitch-free mux. */ -static const char * const meson8b_mali_0_1_parent_names[] = { - "xtal", "mpll2", "mpll1", "fclk_div7", "fclk_div4", "fclk_div3", - "fclk_div5" +static const struct clk_hw *meson8b_mali_0_1_parent_hws[] = { + &meson8b_xtal.hw, + &meson8b_mpll2.hw, + &meson8b_mpll1.hw, + &meson8b_fclk_div7.hw, + &meson8b_fclk_div4.hw, + &meson8b_fclk_div3.hw, + &meson8b_fclk_div5.hw, }; static u32 meson8b_mali_0_1_mux_table[] = { 0, 2, 3, 4, 5, 6, 7 }; @@ -1596,8 +1789,8 @@ static struct clk_regmap meson8b_mali_0_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_mali_0_1_parent_names, - .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_names), + .parent_hws = meson8b_mali_0_1_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_hws), /* * Don't propagate rate changes up because the only changeable * parents are mpll1 and mpll2 but we need those for audio and @@ -1617,7 +1810,9 @@ static struct clk_regmap meson8b_mali_0_div = { .hw.init = &(struct clk_init_data){ .name = "mali_0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mali_0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mali_0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1631,7 +1826,9 @@ static struct clk_regmap meson8b_mali_0 = { .hw.init = &(struct clk_init_data){ .name = "mali_0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mali_0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mali_0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1647,8 +1844,8 @@ static struct clk_regmap meson8b_mali_1_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_1_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_mali_0_1_parent_names, - .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_names), + .parent_hws = meson8b_mali_0_1_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_hws), /* * Don't propagate rate changes up because the only changeable * parents are mpll1 and mpll2 but we need those for audio and @@ -1668,7 +1865,9 @@ static struct clk_regmap meson8b_mali_1_div = { .hw.init = &(struct clk_init_data){ .name = "mali_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mali_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mali_1_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1682,7 +1881,9 @@ static struct clk_regmap meson8b_mali_1 = { .hw.init = &(struct clk_init_data){ .name = "mali_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mali_1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mali_1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1697,7 +1898,10 @@ static struct clk_regmap meson8b_mali = { .hw.init = &(struct clk_init_data){ .name = "mali", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "mali_0", "mali_1" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mali_0.hw, + &meson8b_mali_1.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -1740,7 +1944,9 @@ static struct clk_regmap meson8m2_gp_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "gp_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ "xtal" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_xtal.hw + }, .num_parents = 1, }, }; @@ -1755,18 +1961,26 @@ static struct clk_regmap meson8m2_gp_pll = { .hw.init = &(struct clk_init_data){ .name = "gp_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "gp_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8m2_gp_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const char * const meson8b_vpu_0_1_parent_names[] = { - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" +static const struct clk_hw *meson8b_vpu_0_1_parent_hws[] = { + &meson8b_fclk_div4.hw, + &meson8b_fclk_div3.hw, + &meson8b_fclk_div5.hw, + &meson8b_fclk_div7.hw, }; -static const char * const mmeson8m2_vpu_0_1_parent_names[] = { - "fclk_div4", "fclk_div3", "fclk_div5", "gp_pll" +static const struct clk_hw *mmeson8m2_vpu_0_1_parent_hws[] = { + &meson8b_fclk_div4.hw, + &meson8b_fclk_div3.hw, + &meson8b_fclk_div5.hw, + &meson8m2_gp_pll.hw, }; static struct clk_regmap meson8b_vpu_0_sel = { @@ -1778,8 +1992,8 @@ static struct clk_regmap meson8b_vpu_0_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_vpu_0_1_parent_names, - .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_names), + .parent_hws = meson8b_vpu_0_1_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1793,8 +2007,8 @@ static struct clk_regmap meson8m2_vpu_0_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = mmeson8m2_vpu_0_1_parent_names, - .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_names), + .parent_hws = mmeson8m2_vpu_0_1_parent_hws, + .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1808,7 +2022,17 @@ static struct clk_regmap meson8b_vpu_0_div = { .hw.init = &(struct clk_init_data){ .name = "vpu_0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vpu_0_sel" }, + .parent_data = &(const struct clk_parent_data) { + /* + * Note: + * meson8b and meson8m2 have different vpu_0_sels (with + * different struct clk_hw). We fallback to the global + * naming string mechanism so vpu_0_div picks up the + * appropriate one. + */ + .name = "vpu_0_sel", + .index = -1, + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1822,7 +2046,9 @@ static struct clk_regmap meson8b_vpu_0 = { .hw.init = &(struct clk_init_data) { .name = "vpu_0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vpu_0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vpu_0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1837,8 +2063,8 @@ static struct clk_regmap meson8b_vpu_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_1_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_vpu_0_1_parent_names, - .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_names), + .parent_hws = meson8b_vpu_0_1_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1852,8 +2078,8 @@ static struct clk_regmap meson8m2_vpu_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_1_sel", .ops = &clk_regmap_mux_ops, - .parent_names = mmeson8m2_vpu_0_1_parent_names, - .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_names), + .parent_hws = mmeson8m2_vpu_0_1_parent_hws, + .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1867,7 +2093,17 @@ static struct clk_regmap meson8b_vpu_1_div = { .hw.init = &(struct clk_init_data){ .name = "vpu_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vpu_1_sel" }, + .parent_data = &(const struct clk_parent_data) { + /* + * Note: + * meson8b and meson8m2 have different vpu_1_sels (with + * different struct clk_hw). We fallback to the global + * naming string mechanism so vpu_1_div picks up the + * appropriate one. + */ + .name = "vpu_1_sel", + .index = -1, + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1881,7 +2117,9 @@ static struct clk_regmap meson8b_vpu_1 = { .hw.init = &(struct clk_init_data) { .name = "vpu_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vpu_1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vpu_1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1896,14 +2134,22 @@ static struct clk_regmap meson8b_vpu = { .hw.init = &(struct clk_init_data){ .name = "vpu", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "vpu_0", "vpu_1" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vpu_0.hw, + &meson8b_vpu_1.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_NO_REPARENT, }, }; -static const char * const meson8b_vdec_parent_names[] = { - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "mpll2", "mpll1" +static const struct clk_hw *meson8b_vdec_parent_hws[] = { + &meson8b_fclk_div4.hw, + &meson8b_fclk_div3.hw, + &meson8b_fclk_div5.hw, + &meson8b_fclk_div7.hw, + &meson8b_mpll2.hw, + &meson8b_mpll1.hw, }; static struct clk_regmap meson8b_vdec_1_sel = { @@ -1916,8 +2162,8 @@ static struct clk_regmap meson8b_vdec_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_1_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_vdec_parent_names, - .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names), + .parent_hws = meson8b_vdec_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1932,7 +2178,9 @@ static struct clk_regmap meson8b_vdec_1_1_div = { .hw.init = &(struct clk_init_data){ .name = "vdec_1_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_1_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1946,7 +2194,9 @@ static struct clk_regmap meson8b_vdec_1_1 = { .hw.init = &(struct clk_init_data) { .name = "vdec_1_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_1_1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_1_1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1962,7 +2212,9 @@ static struct clk_regmap meson8b_vdec_1_2_div = { .hw.init = &(struct clk_init_data){ .name = "vdec_1_2_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_1_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1976,7 +2228,9 @@ static struct clk_regmap meson8b_vdec_1_2 = { .hw.init = &(struct clk_init_data) { .name = "vdec_1_2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_1_2_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_1_2_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1992,7 +2246,10 @@ static struct clk_regmap meson8b_vdec_1 = { .hw.init = &(struct clk_init_data){ .name = "vdec_1", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "vdec_1_1", "vdec_1_2" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_1_1.hw, + &meson8b_vdec_1_2.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -2008,8 +2265,8 @@ static struct clk_regmap meson8b_vdec_hcodec_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_hcodec_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_vdec_parent_names, - .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names), + .parent_hws = meson8b_vdec_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2024,7 +2281,9 @@ static struct clk_regmap meson8b_vdec_hcodec_div = { .hw.init = &(struct clk_init_data){ .name = "vdec_hcodec_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_hcodec_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_hcodec_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2038,7 +2297,9 @@ static struct clk_regmap meson8b_vdec_hcodec = { .hw.init = &(struct clk_init_data) { .name = "vdec_hcodec", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_hcodec_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_hcodec_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2054,8 +2315,8 @@ static struct clk_regmap meson8b_vdec_2_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_2_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_vdec_parent_names, - .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names), + .parent_hws = meson8b_vdec_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2070,7 +2331,9 @@ static struct clk_regmap meson8b_vdec_2_div = { .hw.init = &(struct clk_init_data){ .name = "vdec_2_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_2_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_2_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2084,7 +2347,9 @@ static struct clk_regmap meson8b_vdec_2 = { .hw.init = &(struct clk_init_data) { .name = "vdec_2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_2_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_2_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2100,8 +2365,8 @@ static struct clk_regmap meson8b_vdec_hevc_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_hevc_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_vdec_parent_names, - .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names), + .parent_hws = meson8b_vdec_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2116,7 +2381,9 @@ static struct clk_regmap meson8b_vdec_hevc_div = { .hw.init = &(struct clk_init_data){ .name = "vdec_hevc_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_hevc_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_hevc_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2130,7 +2397,9 @@ static struct clk_regmap meson8b_vdec_hevc_en = { .hw.init = &(struct clk_init_data) { .name = "vdec_hevc_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_hevc_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_hevc_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2147,15 +2416,19 @@ static struct clk_regmap meson8b_vdec_hevc = { .name = "vdec_hevc", .ops = &clk_regmap_mux_ops, /* TODO: The second parent is currently unknown */ - .parent_names = (const char *[]){ "vdec_hevc_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_hevc_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; /* TODO: the clock at index 0 is "DDR_PLL" which we don't support yet */ -static const char * const meson8b_cts_amclk_parent_names[] = { - "mpll0", "mpll1", "mpll2" +static const struct clk_hw *meson8b_cts_amclk_parent_hws[] = { + &meson8b_mpll0.hw, + &meson8b_mpll1.hw, + &meson8b_mpll2.hw }; static u32 meson8b_cts_amclk_mux_table[] = { 1, 2, 3 }; @@ -2171,8 +2444,8 @@ static struct clk_regmap meson8b_cts_amclk_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_amclk_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_cts_amclk_parent_names, - .num_parents = ARRAY_SIZE(meson8b_cts_amclk_parent_names), + .parent_hws = meson8b_cts_amclk_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_cts_amclk_parent_hws), }, }; @@ -2186,7 +2459,9 @@ static struct clk_regmap meson8b_cts_amclk_div = { .hw.init = &(struct clk_init_data){ .name = "cts_amclk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "cts_amclk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_amclk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2200,15 +2475,19 @@ static struct clk_regmap meson8b_cts_amclk = { .hw.init = &(struct clk_init_data){ .name = "cts_amclk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_amclk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_amclk_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; /* TODO: the clock at index 0 is "DDR_PLL" which we don't support yet */ -static const char * const meson8b_cts_mclk_i958_parent_names[] = { - "mpll0", "mpll1", "mpll2" +static const struct clk_hw *meson8b_cts_mclk_i958_parent_hws[] = { + &meson8b_mpll0.hw, + &meson8b_mpll1.hw, + &meson8b_mpll2.hw }; static u32 meson8b_cts_mclk_i958_mux_table[] = { 1, 2, 3 }; @@ -2224,8 +2503,8 @@ static struct clk_regmap meson8b_cts_mclk_i958_sel = { .hw.init = &(struct clk_init_data) { .name = "cts_mclk_i958_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_cts_mclk_i958_parent_names, - .num_parents = ARRAY_SIZE(meson8b_cts_mclk_i958_parent_names), + .parent_hws = meson8b_cts_mclk_i958_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_cts_mclk_i958_parent_hws), }, }; @@ -2239,7 +2518,9 @@ static struct clk_regmap meson8b_cts_mclk_i958_div = { .hw.init = &(struct clk_init_data) { .name = "cts_mclk_i958_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "cts_mclk_i958_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_mclk_i958_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2253,7 +2534,9 @@ static struct clk_regmap meson8b_cts_mclk_i958 = { .hw.init = &(struct clk_init_data){ .name = "cts_mclk_i958", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_mclk_i958_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_mclk_i958_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2268,8 +2551,10 @@ static struct clk_regmap meson8b_cts_i958 = { .hw.init = &(struct clk_init_data){ .name = "cts_i958", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "cts_amclk", - "cts_mclk_i958" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_amclk.hw, + &meson8b_cts_mclk_i958.hw + }, .num_parents = 2, /* * The parent is specific to origin of the audio data. Let the @@ -2279,6 +2564,9 @@ static struct clk_regmap meson8b_cts_i958 = { }, }; +#define MESON_GATE(_name, _reg, _bit) \ + MESON_PCLK(_name, _reg, _bit, &meson8b_clk81.hw) + /* Everything Else (EE) domain gates */ static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); diff --git a/include/dt-bindings/clock/g12a-clkc.h b/include/dt-bindings/clock/g12a-clkc.h index b6b127e45634..8ccc29ac7a72 100644 --- a/include/dt-bindings/clock/g12a-clkc.h +++ b/include/dt-bindings/clock/g12a-clkc.h @@ -137,5 +137,6 @@ #define CLKID_VDEC_HEVC 207 #define CLKID_VDEC_HEVCF 210 #define CLKID_TS 212 +#define CLKID_CPUB_CLK 224 #endif /* __G12A_CLKC_H */ diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 2ae7604783dd..dce5521a9bf6 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -817,6 +817,7 @@ unsigned int clk_hw_get_num_parents(const struct clk_hw *hw); struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw); struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw, unsigned int index); +int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *new_parent); unsigned int __clk_get_enable_count(struct clk *clk); unsigned long clk_hw_get_rate(const struct clk_hw *hw); unsigned long __clk_get_flags(struct clk *clk);