From nobody Thu Sep 19 01:57:50 2024 Received: from TWMBX01.aspeed.com (mail.aspeedtech.com [211.20.114.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F175D17B4F5; Fri, 26 Jul 2024 11:05:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.20.114.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721991925; cv=none; b=UHK2ISE4/3Rj8d5hfiekntiVwUZAxADS6FsKFrcW1fwFbFLX4MHJq4Xw3g8EMT3GTuJ+5LdcF+3bmmzp9Cn2Ns3tFsFjf1hJ2g8W1cIFr1i+vpfUR0PVW6tSldsmTqHyeJf0NKSrwFsR96PaQ5a2fDE7eS2TYl279a3O3Cqfs60= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721991925; c=relaxed/simple; bh=UwzyFZ7n9Op+4YCeUge/fCqsuYIQqkgF6Ev8Ei4+4js=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=I5v1aoVFwmjdQVaVR7FCwcVK1JsJvlH1fKTF66RWldtFeXHY9eMyOpY3IkBYMdeiDZYHazgK9UjILI1ICcgXjFCE32dyeL+Vog1Vx59918yOJgrs6UWe6w2UvmksSRgeCNiAsqyKR9tZ+oIjBVoQvab7+1wP8PoqDYeZMmnFfmc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com; spf=pass smtp.mailfrom=aspeedtech.com; arc=none smtp.client-ip=211.20.114.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=aspeedtech.com Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Fri, 26 Jul 2024 19:04:00 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Fri, 26 Jul 2024 19:04:00 +0800 From: Kevin Chen To: , , , , , , , , , , , , , , , , , , , , , , , , , , , Subject: [PATCH v1 03/10] clk: ast2700: add clock controller Date: Fri, 26 Jul 2024 19:03:48 +0800 Message-ID: <20240726110355.2181563-4-kevin_chen@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240726110355.2181563-1-kevin_chen@aspeedtech.com> References: <20240726110355.2181563-1-kevin_chen@aspeedtech.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Signed-off-by: Kevin Chen --- drivers/clk/Makefile | 1 + drivers/clk/clk-ast2700.c | 1166 +++++++++++++++++++++++++++++++++++++ 2 files changed, 1167 insertions(+) create mode 100644 drivers/clk/clk-ast2700.c diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index f793a16cad40..0d5992ea0fa4 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_COMMON_CLK_FSL_SAI) +=3D clk-fsl-sai.o obj-$(CONFIG_COMMON_CLK_GEMINI) +=3D clk-gemini.o obj-$(CONFIG_COMMON_CLK_ASPEED) +=3D clk-aspeed.o obj-$(CONFIG_MACH_ASPEED_G6) +=3D clk-ast2600.o +obj-$(CONFIG_MACH_ASPEED_G7) +=3D clk-ast2700.o obj-$(CONFIG_ARCH_HIGHBANK) +=3D clk-highbank.o obj-$(CONFIG_CLK_HSDK) +=3D clk-hsdk-pll.o obj-$(CONFIG_COMMON_CLK_K210) +=3D clk-k210.o diff --git a/drivers/clk/clk-ast2700.c b/drivers/clk/clk-ast2700.c new file mode 100644 index 000000000000..04049f1f1661 --- /dev/null +++ b/drivers/clk/clk-ast2700.c @@ -0,0 +1,1166 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright ASPEED Technology + +#include +#include +#include +#include + +#include +#include + +#define SCU_CLK_24MHZ 24000000 +#define SCU_CLK_25MHZ 25000000 +#define SCU_CLK_192MHZ 192000000 +/* SOC0 USB2 PHY CLK*/ +#define SCU_CLK_12MHZ 12000000 +/* SOC0 */ +#define SCU0_HWSTRAP1 0x010 +#define SCU0_CLK_STOP 0x240 +#define SCU0_CLK_SEL1 0x280 +#define SCU0_CLK_SEL2 0x284 +#define GET_USB_REFCLK_DIV(x) ((GENMASK(23, 20) & (x)) >> 20) +#define UART_DIV13_EN BIT(30) +#define SCU0_HPLL_PARAM 0x300 +#define SCU0_DPLL_PARAM 0x308 +#define SCU0_MPLL_PARAM 0x310 +#define SCU0_D1CLK_PARAM 0x320 +#define SCU0_D2CLK_PARAM 0x330 +#define SCU0_CRT1CLK_PARAM 0x340 +#define SCU0_CRT2CLK_PARAM 0x350 +#define SCU0_MPHYCLK_PARAM 0x360 + +/* SOC1 */ +#define SCU1_CLK_STOP 0x240 +#define SCU1_CLK_STOP2 0x260 +#define SCU1_CLK_SEL1 0x280 +#define SCU1_CLK_SEL2 0x284 +#define UXCLK_MASK GENMASK(1, 0) +#define HUXCLK_MASK GENMASK(4, 3) +#define SCU1_HPLL_PARAM 0x300 +#define SCU1_APLL_PARAM 0x310 +#define SCU1_DPLL_PARAM 0x320 +#define SCU1_UXCLK_CTRL 0x330 +#define SCU1_HUXCLK_CTRL 0x334 +#define SCU1_MAC12_CLK_DLY 0x390 +#define SCU1_MAC12_CLK_DLY_100M 0x394 +#define SCU1_MAC12_CLK_DLY_10M 0x398 + +/* + * MAC Clock Delay settings + */ +#define MAC_CLK_RMII1_50M_RCLK_O_CTRL BIT(30) +#define MAC_CLK_RMII1_50M_RCLK_O_DIS 0 +#define MAC_CLK_RMII1_50M_RCLK_O_EN 1 +#define MAC_CLK_RMII0_50M_RCLK_O_CTRL BIT(29) +#define MAC_CLK_RMII0_5M_RCLK_O_DIS 0 +#define MAC_CLK_RMII0_5M_RCLK_O_EN 1 +#define MAC_CLK_RMII_TXD_FALLING_2 BIT(27) +#define MAC_CLK_RMII_TXD_FALLING_1 BIT(26) +#define MAC_CLK_RXCLK_INV_2 BIT(25) +#define MAC_CLK_RXCLK_INV_1 BIT(24) +#define MAC_CLK_1G_INPUT_DELAY_2 GENMASK(23, 18) +#define MAC_CLK_1G_INPUT_DELAY_1 GENMASK(17, 12) +#define MAC_CLK_1G_OUTPUT_DELAY_2 GENMASK(11, 6) +#define MAC_CLK_1G_OUTPUT_DELAY_1 GENMASK(5, 0) + +#define MAC_CLK_100M_10M_RESERVED GENMASK(31, 26) +#define MAC_CLK_100M_10M_RXCLK_INV_2 BIT(25) +#define MAC_CLK_100M_10M_RXCLK_INV_1 BIT(24) +#define MAC_CLK_100M_10M_INPUT_DELAY_2 GENMASK(23, 18) +#define MAC_CLK_100M_10M_INPUT_DELAY_1 GENMASK(17, 12) +#define MAC_CLK_100M_10M_OUTPUT_DELAY_2 GENMASK(11, 6) +#define MAC_CLK_100M_10M_OUTPUT_DELAY_1 GENMASK(5, 0) + +#define AST2700_DEF_MAC12_DELAY_1G 0x00CF4D75 +#define AST2700_DEF_MAC12_DELAY_100M 0x00410410 +#define AST2700_DEF_MAC12_DELAY_10M 0x00410410 + +struct mac_delay_config { + u32 tx_delay_1000; + u32 rx_delay_1000; + u32 tx_delay_100; + u32 rx_delay_100; + u32 tx_delay_10; + u32 rx_delay_10; +}; + +/* Globally visible clocks */ +static DEFINE_SPINLOCK(ast2700_clk_lock); + +/* Division of RGMII Clock */ +static const struct clk_div_table ast2700_rgmii_div_table[] =3D { + { 0x0, 4 }, + { 0x1, 4 }, + { 0x2, 6 }, + { 0x3, 8 }, + { 0x4, 10 }, + { 0x5, 12 }, + { 0x6, 14 }, + { 0x7, 16 }, + { 0 } +}; + +/* Division of RMII Clock */ +static const struct clk_div_table ast2700_rmii_div_table[] =3D { + { 0x0, 8 }, + { 0x1, 8 }, + { 0x2, 12 }, + { 0x3, 16 }, + { 0x4, 20 }, + { 0x5, 24 }, + { 0x6, 28 }, + { 0x7, 32 }, + { 0 } +}; + +/* Division of HCLK/SDIO/MAC/apll_divn CLK */ +static const struct clk_div_table ast2700_clk_div_table[] =3D { + { 0x0, 2 }, + { 0x1, 2 }, + { 0x2, 3 }, + { 0x3, 4 }, + { 0x4, 5 }, + { 0x5, 6 }, + { 0x6, 7 }, + { 0x7, 8 }, + { 0 } +}; + +/* Division of PCLK/EMMC CLK */ +static const struct clk_div_table ast2700_clk_div_table2[] =3D { + { 0x0, 2 }, + { 0x1, 4 }, + { 0x2, 6 }, + { 0x3, 8 }, + { 0x4, 10 }, + { 0x5, 12 }, + { 0x6, 14 }, + { 0x7, 16 }, + { 0 } +}; + +/* HPLL/DPLL: 2000Mhz(default) */ +struct clk_hw *ast2700_soc0_hw_pll(const char *name, const char *parent_na= me, u32 val) +{ + unsigned int mult, div; + + if (val & BIT(24)) { + /* Pass through mode */ + mult =3D 1; + div =3D 1; + } else { + /* F =3D CLKIN(25MHz) * [(M+1) / 2(N+1)] / (P+1) */ + u32 m =3D val & 0x1fff; + u32 n =3D (val >> 13) & 0x3f; + u32 p =3D (val >> 19) & 0xf; + + mult =3D (m + 1) / (2 * (n + 1)); + div =3D (p + 1); + } + + return clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mult, div= ); +}; + +/* MPLL 1600Mhz(default) */ +struct clk_hw *ast2700_calc_mpll(const char *name, const char *parent_name= , u32 val) +{ + unsigned int mult, div; + + if (val & BIT(24)) { + /* Pass through mode */ + div =3D 1; + mult =3D div; + } else { + /* F =3D CLKIN(25MHz) * [CLKF/(CLKR+1)] /(CLKOD+1) */ + u32 m =3D val & 0x1fff; + u32 n =3D (val >> 13) & 0x3f; + u32 p =3D (val >> 19) & 0xf; + + mult =3D m / (n + 1); + div =3D (p + 1); + } + return clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mult, div= ); +}; + +static struct clk_hw *ast2700_calc_uclk(const char *name, u32 val) +{ + unsigned int mult, div; + + /* UARTCLK =3D UXCLK * R / (N * 2) */ + u32 r =3D val & 0xff; + u32 n =3D (val >> 8) & 0x3ff; + + mult =3D r; + div =3D n * 2; + + return clk_hw_register_fixed_factor(NULL, name, "uxclk", 0, mult, div); +}; + +static struct clk_hw *ast2700_calc_huclk(const char *name, u32 val) +{ + unsigned int mult, div; + + /* UARTCLK =3D UXCLK * R / (N * 2) */ + u32 r =3D val & 0xff; + u32 n =3D (val >> 8) & 0x3ff; + + mult =3D r; + div =3D n * 2; + + return clk_hw_register_fixed_factor(NULL, name, "huxclk", 0, mult, div); +}; + +struct clk_hw *ast2700_calc_soc1_pll(const char *name, const char *parent_= name, u32 val) +{ + unsigned int mult, div; + + if (val & BIT(24)) { + /* Pass through mode */ + div =3D 1; + mult =3D div; + } else { + /* F =3D 25Mhz * [(M + 1) / (n + 1)] / (p + 1) */ + u32 m =3D val & 0x1fff; + u32 n =3D (val >> 13) & 0x3f; + u32 p =3D (val >> 19) & 0xf; + + mult =3D (m + 1) / (n + 1); + div =3D (p + 1); + } + return clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mult, div= ); +}; + +static int ast2700_clk_is_enabled(struct clk_hw *hw) +{ + struct clk_gate *gate =3D to_clk_gate(hw); + u32 clk =3D BIT(gate->bit_idx); + u32 reg; + + reg =3D readl(gate->reg); + + return !(reg & clk); +} + +static int ast2700_clk_enable(struct clk_hw *hw) +{ + struct clk_gate *gate =3D to_clk_gate(hw); + u32 clk =3D BIT(gate->bit_idx); + + if (readl(gate->reg) & clk) + writel(clk, gate->reg + 0x04); + + return 0; +} + +static void ast2700_clk_disable(struct clk_hw *hw) +{ + struct clk_gate *gate =3D to_clk_gate(hw); + u32 clk =3D BIT(gate->bit_idx); + + /* Clock is set to enable, so use write to set register */ + writel(clk, gate->reg); +} + +static const struct clk_ops ast2700_clk_gate_ops =3D { + .enable =3D ast2700_clk_enable, + .disable =3D ast2700_clk_disable, + .is_enabled =3D ast2700_clk_is_enabled, +}; + +static struct clk_hw *ast2700_clk_hw_register_gate(struct device *dev, con= st char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 clock_idx, + u8 clk_gate_flags, spinlock_t *lock) +{ + struct clk_gate *gate; + struct clk_hw *hw; + struct clk_init_data init; + int ret =3D -EINVAL; + + gate =3D kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + init.name =3D name; + init.ops =3D &ast2700_clk_gate_ops; + init.flags =3D flags; + init.parent_names =3D parent_name ? &parent_name : NULL; + init.num_parents =3D parent_name ? 1 : 0; + + gate->reg =3D reg; + gate->bit_idx =3D clock_idx; + gate->flags =3D clk_gate_flags; + gate->lock =3D lock; + gate->hw.init =3D &init; + + hw =3D &gate->hw; + ret =3D clk_hw_register(dev, hw); + if (ret) { + kfree(gate); + hw =3D ERR_PTR(ret); + } + + return hw; +} + +struct ast2700_reset { + void __iomem *base; + struct reset_controller_dev rcdev; +}; + +#define to_rc_data(p) container_of(p, struct ast2700_reset, rcdev) + +static int ast2700_reset_assert(struct reset_controller_dev *rcdev, unsign= ed long id) +{ + struct ast2700_reset *rc =3D to_rc_data(rcdev); + u32 rst =3D BIT(id % 32); + u32 reg =3D id >=3D 32 ? 0x220 : 0x200; + + writel(rst, rc->base + reg); + return 0; +} + +static int ast2700_reset_deassert(struct reset_controller_dev *rcdev, unsi= gned long id) +{ + struct ast2700_reset *rc =3D to_rc_data(rcdev); + u32 rst =3D BIT(id % 32); + u32 reg =3D id >=3D 32 ? 0x220 : 0x200; + + /* Use set to clear register */ + writel(rst, rc->base + reg + 0x04); + return 0; +} + +static int ast2700_reset_status(struct reset_controller_dev *rcdev, unsign= ed long id) +{ + struct ast2700_reset *rc =3D to_rc_data(rcdev); + u32 rst =3D BIT(id % 32); + u32 reg =3D id >=3D 32 ? 0x220 : 0x200; + + return (readl(rc->base + reg) & rst); +} + +static const struct reset_control_ops ast2700_reset_ops =3D { + .assert =3D ast2700_reset_assert, + .deassert =3D ast2700_reset_deassert, + .status =3D ast2700_reset_status, +}; + +static const char *const sdclk_sel[] =3D { + "soc1-hpll", + "soc1-apll", +}; + +static const char *const uartclk_sel[] =3D { + "uartxclk", + "huartxclk", +}; + +static const char *const uxclk_sel[] =3D { + "soc1-apll_div4", + "soc1-apll_div2", + "soc1-apll", + "soc1-hpll", +}; + +static void ast2700_soc1_configure_mac01_clk(struct device_node *np) +{ + void __iomem *clk_base; + struct mac_delay_config mac_cfg; + u32 reg[3]; + int ret; + + clk_base =3D of_iomap(np, 0); + WARN_ON(!clk_base); + + reg[0] =3D AST2700_DEF_MAC12_DELAY_1G; + reg[1] =3D AST2700_DEF_MAC12_DELAY_100M; + reg[2] =3D AST2700_DEF_MAC12_DELAY_10M; + + ret =3D of_property_read_u32_array(np, "mac0-clk-delay", (u32 *)&mac_cfg, + sizeof(mac_cfg) / sizeof(u32)); + if (!ret) { + reg[0] &=3D ~(MAC_CLK_1G_INPUT_DELAY_1 | MAC_CLK_1G_OUTPUT_DELAY_1); + reg[0] |=3D FIELD_PREP(MAC_CLK_1G_INPUT_DELAY_1, mac_cfg.rx_delay_1000) | + FIELD_PREP(MAC_CLK_1G_OUTPUT_DELAY_1, mac_cfg.tx_delay_1000); + + reg[1] &=3D ~(MAC_CLK_100M_10M_INPUT_DELAY_1 | MAC_CLK_100M_10M_OUTPUT_D= ELAY_1); + reg[1] |=3D FIELD_PREP(MAC_CLK_100M_10M_INPUT_DELAY_1, mac_cfg.rx_delay_= 100) | + FIELD_PREP(MAC_CLK_100M_10M_OUTPUT_DELAY_1, mac_cfg.tx_delay_100); + + reg[2] &=3D ~(MAC_CLK_100M_10M_INPUT_DELAY_1 | MAC_CLK_100M_10M_OUTPUT_D= ELAY_1); + reg[2] |=3D FIELD_PREP(MAC_CLK_100M_10M_INPUT_DELAY_1, mac_cfg.rx_delay_= 10) | + FIELD_PREP(MAC_CLK_100M_10M_OUTPUT_DELAY_1, mac_cfg.tx_delay_10); + } + + ret =3D of_property_read_u32_array(np, "mac1-clk-delay", (u32 *)&mac_cfg, + sizeof(mac_cfg) / sizeof(u32)); + if (!ret) { + reg[0] &=3D ~(MAC_CLK_1G_INPUT_DELAY_2 | MAC_CLK_1G_OUTPUT_DELAY_2); + reg[0] |=3D FIELD_PREP(MAC_CLK_1G_INPUT_DELAY_2, mac_cfg.rx_delay_1000) | + FIELD_PREP(MAC_CLK_1G_OUTPUT_DELAY_2, mac_cfg.tx_delay_1000); + + reg[1] &=3D ~(MAC_CLK_100M_10M_INPUT_DELAY_2 | MAC_CLK_100M_10M_OUTPUT_D= ELAY_2); + reg[1] |=3D FIELD_PREP(MAC_CLK_100M_10M_INPUT_DELAY_2, mac_cfg.rx_delay_= 100) | + FIELD_PREP(MAC_CLK_100M_10M_OUTPUT_DELAY_2, mac_cfg.tx_delay_100); + + reg[2] &=3D ~(MAC_CLK_100M_10M_INPUT_DELAY_2 | MAC_CLK_100M_10M_OUTPUT_D= ELAY_2); + reg[2] |=3D FIELD_PREP(MAC_CLK_100M_10M_INPUT_DELAY_2, mac_cfg.rx_delay_= 10) | + FIELD_PREP(MAC_CLK_100M_10M_OUTPUT_DELAY_2, mac_cfg.tx_delay_10); + } + + reg[0] |=3D (readl(clk_base + SCU1_MAC12_CLK_DLY) & ~GENMASK(25, 0)); + writel(reg[0], clk_base + SCU1_MAC12_CLK_DLY); + writel(reg[1], clk_base + SCU1_MAC12_CLK_DLY_100M); + writel(reg[2], clk_base + SCU1_MAC12_CLK_DLY_10M); +} + +static int ast2700_soc1_clk_init(struct device_node *soc1_node) +{ + struct clk_hw_onecell_data *clk_data; + struct ast2700_reset *reset; + u32 uart_clk_source =3D 0; + void __iomem *clk_base; + struct clk_hw **clks; + u32 val, id; + int ret; + + clk_base =3D of_iomap(soc1_node, 0); + WARN_ON(!clk_base); + + clk_data =3D kzalloc(struct_size(clk_data, hws, SOC1_NUM_CLKS), GFP_KERNE= L); + if (!clk_data) + return -ENOMEM; + + clk_data->num =3D SOC1_NUM_CLKS; + clks =3D clk_data->hws; + + reset =3D kzalloc(sizeof(*reset), GFP_KERNEL); + if (!reset) + return -ENOMEM; + + reset->base =3D clk_base; + + reset->rcdev.owner =3D THIS_MODULE; + reset->rcdev.nr_resets =3D SOC1_RESET_NUMS; + reset->rcdev.ops =3D &ast2700_reset_ops; + reset->rcdev.of_node =3D soc1_node; + + ret =3D reset_controller_register(&reset->rcdev); + if (ret) { + pr_err("soc1 failed to register reset controller\n"); + return ret; + } + /* + * Ast2700 A0 workaround: + * I3C reset should assert all of the I3C controllers simultaneously. + * Otherwise, it may lead to failure in accessing I3C registers. + */ + for (id =3D SCU1_RESET_I3C0; id <=3D SCU1_RESET_I3C15; id++) + ast2700_reset_assert(&reset->rcdev, id); + + clks[SCU1_CLKIN] =3D + clk_hw_register_fixed_rate(NULL, "soc1-clkin", NULL, 0, SCU_CLK_25MHZ); + + /* HPLL 1000Mhz */ + val =3D readl(clk_base + SCU1_HPLL_PARAM); + clks[SCU1_CLK_HPLL] =3D ast2700_calc_soc1_pll("soc1-hpll", "soc1-clkin", = val); + + /* HPLL 800Mhz */ + val =3D readl(clk_base + SCU1_APLL_PARAM); + clks[SCU1_CLK_APLL] =3D ast2700_calc_soc1_pll("soc1-apll", "soc1-clkin", = val); + + clks[SCU1_CLK_APLL_DIV2] =3D + clk_hw_register_fixed_factor(NULL, "soc1-apll_div2", "soc1-apll", 0, 1, = 2); + + clks[SCU1_CLK_APLL_DIV4] =3D + clk_hw_register_fixed_factor(NULL, "soc1-apll_div4", "soc1-apll", 0, 1, = 4); + + val =3D readl(clk_base + SCU1_DPLL_PARAM); + clks[SCU1_CLK_DPLL] =3D ast2700_calc_soc1_pll("dpll", "soc1-clkin", val); + + /* uxclk mux selection */ + clks[SCU1_CLK_UXCLK] =3D + clk_hw_register_mux(NULL, "uxclk", uxclk_sel, ARRAY_SIZE(uxclk_sel), + 0, clk_base + SCU1_CLK_SEL2, + 0, 2, 0, &ast2700_clk_lock); + + val =3D readl(clk_base + SCU1_UXCLK_CTRL); + clks[SCU1_CLK_UARTX] =3D ast2700_calc_uclk("uartxclk", val); + + /* huxclk mux selection */ + clks[SCU1_CLK_HUXCLK] =3D + clk_hw_register_mux(NULL, "huxclk", uxclk_sel, ARRAY_SIZE(uxclk_sel), + 0, clk_base + SCU1_CLK_SEL2, + 3, 2, 0, &ast2700_clk_lock); + + val =3D readl(clk_base + SCU1_HUXCLK_CTRL); + clks[SCU1_CLK_HUARTX] =3D ast2700_calc_huclk("huartxclk", val); + + /* AHB CLK =3D 200Mhz */ + clks[SCU1_CLK_AHB] =3D + clk_hw_register_divider_table(NULL, "soc1-ahb", "soc1-hpll", + 0, clk_base + SCU1_CLK_SEL2, + 20, 3, 0, ast2700_clk_div_table, &ast2700_clk_lock); + + /* APB CLK =3D 100Mhz */ + clks[SCU1_CLK_APB] =3D + clk_hw_register_divider_table(NULL, "soc1-apb", "soc1-hpll", + 0, clk_base + SCU1_CLK_SEL1, + 18, 3, 0, ast2700_clk_div_table2, &ast2700_clk_lock); + + /* RMII */ + clks[SCU1_CLK_RMII] =3D + clk_hw_register_divider_table(NULL, "rmii", "soc1-hpll", + 0, clk_base + SCU1_CLK_SEL1, + 21, 3, 0, ast2700_rmii_div_table, &ast2700_clk_lock); + + /* RMII0 50MHz (RCLK) output enable */ + clks[SCU1_CLK_MAC0RCLK] =3D + clk_hw_register_gate(NULL, "mac0rclk", "rmii", 0, + clk_base + SCU1_MAC12_CLK_DLY, 29, + 0, &ast2700_clk_lock); + + /* RMII1 50MHz (RCLK) output enable */ + clks[SCU1_CLK_MAC1RCLK] =3D + clk_hw_register_gate(NULL, "mac1rclk", "rmii", 0, + clk_base + SCU1_MAC12_CLK_DLY, 30, + 0, &ast2700_clk_lock); + + /* RGMII */ + clks[SCU1_CLK_RGMII] =3D + clk_hw_register_divider_table(NULL, "rgmii", "soc1-hpll", + 0, clk_base + SCU1_CLK_SEL1, + 25, 3, 0, ast2700_rgmii_div_table, &ast2700_clk_lock); + + /* MAC HCLK */ + clks[SCU1_CLK_MACHCLK] =3D + clk_hw_register_divider_table(NULL, "machclk", "soc1-hpll", + 0, clk_base + SCU1_CLK_SEL1, + 29, 3, 0, ast2700_clk_div_table, &ast2700_clk_lock); + + /* MAC0/1 RGMII/RMII Clock Delay */ + ast2700_soc1_configure_mac01_clk(soc1_node); + + clks[SCU1_CLK_GATE_LCLK0] =3D + ast2700_clk_hw_register_gate(NULL, "lclk0-gate", NULL, + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP, + 0, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_LCLK0] =3D + ast2700_clk_hw_register_gate(NULL, "lclk1-gate", NULL, + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP, + 1, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_ESPI0CLK] =3D + ast2700_clk_hw_register_gate(NULL, "espi0clk-gate", NULL, + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP, + 2, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_ESPI1CLK] =3D + ast2700_clk_hw_register_gate(NULL, "espi1clk-gate", NULL, + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP, + 3, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_APLL_DIVN] =3D + clk_hw_register_divider_table(NULL, "soc1-apll_divn", "soc1-apll", + 0, clk_base + SCU1_CLK_SEL2, + 8, 3, 0, ast2700_clk_div_table, &ast2700_clk_lock); + + clks[SCU1_CLK_SDMUX] =3D + clk_hw_register_mux(NULL, "sdclk-mux", sdclk_sel, ARRAY_SIZE(sdclk_sel), + 0, clk_base + SCU1_CLK_SEL1, + 13, 1, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_SDCLK] =3D + clk_hw_register_divider_table(NULL, "sdclk", "sdclk-mux", + 0, clk_base + SCU1_CLK_SEL1, + 14, 3, 0, ast2700_clk_div_table, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_SDCLK] =3D + ast2700_clk_hw_register_gate(NULL, "sdclk-gate", "sdclk", + 0, clk_base + SCU1_CLK_STOP, + 4, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_REFCLK] =3D + ast2700_clk_hw_register_gate(NULL, "soc1-refclk-gate", NULL, + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP, + 6, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_LPCHCLK] =3D + ast2700_clk_hw_register_gate(NULL, "lpchclk-gate", NULL, + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP, + 7, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_MAC0CLK] =3D + ast2700_clk_hw_register_gate(NULL, "mac0clk-gate", NULL, + 0, clk_base + SCU1_CLK_STOP, + 8, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_MAC1CLK] =3D + ast2700_clk_hw_register_gate(NULL, "mac1clk-gate", NULL, + 0, clk_base + SCU1_CLK_STOP, + 9, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_MAC2CLK] =3D + ast2700_clk_hw_register_gate(NULL, "mac2clk-gate", NULL, + 0, clk_base + SCU1_CLK_STOP, + 10, 0, &ast2700_clk_lock); + + of_property_read_u32(soc1_node, "uart-clk-source", &uart_clk_source); + if (uart_clk_source) { + val =3D readl(clk_base + SCU1_CLK_SEL1) & ~GENMASK(12, 0); + uart_clk_source &=3D GENMASK(12, 0); + writel(val | uart_clk_source, clk_base + SCU1_CLK_SEL1); + } + + //UART0 + clks[SCU1_CLK_UART0] =3D + clk_hw_register_mux(NULL, "uart0clk", uartclk_sel, ARRAY_SIZE(uartclk_se= l), + 0, clk_base + SCU1_CLK_SEL1, + 0, 1, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_UART0CLK] =3D + ast2700_clk_hw_register_gate(NULL, "uart0clk-gate", "uart0clk", + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP, + 11, 0, &ast2700_clk_lock); + + //UART1 + clks[SCU1_CLK_UART1] =3D + clk_hw_register_mux(NULL, "uart1clk", uartclk_sel, ARRAY_SIZE(uartclk_se= l), + 0, clk_base + SCU1_CLK_SEL1, + 1, 1, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_UART1CLK] =3D + ast2700_clk_hw_register_gate(NULL, "uart1clk-gate", "uart1clk", + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP, + 12, 0, &ast2700_clk_lock); + + //UART2 + clks[SCU1_CLK_UART2] =3D + clk_hw_register_mux(NULL, "uart2clk", uartclk_sel, ARRAY_SIZE(uartclk_se= l), + 0, clk_base + SCU1_CLK_SEL1, + 2, 1, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_UART2CLK] =3D + ast2700_clk_hw_register_gate(NULL, "uart2clk-gate", "uart2clk", + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP, + 13, 0, &ast2700_clk_lock); + + //UART3 + clks[SCU1_CLK_UART3] =3D + clk_hw_register_mux(NULL, "uart3clk", uartclk_sel, ARRAY_SIZE(uartclk_se= l), + 0, clk_base + SCU1_CLK_SEL1, + 3, 1, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_UART3CLK] =3D + ast2700_clk_hw_register_gate(NULL, "uart3clk-gate", "uart3clk", + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP, + 14, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C0CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c0clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 16, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C1CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c1clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 17, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C2CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c2clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 18, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C3CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c3clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 19, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C4CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c4clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 20, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C5CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c5clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 21, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C6CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c6clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 22, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C7CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c7clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 23, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C8CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c8clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 24, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C9CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c9clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 25, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C10CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c10clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 26, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C11CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c11clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 27, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C12CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c12clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 28, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C13CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c13clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 29, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C14CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c14clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 30, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_I3C15CLK] =3D + ast2700_clk_hw_register_gate(NULL, "i3c15clk-gate", "soc1-ahb", + 0, clk_base + SCU1_CLK_STOP, + 31, 0, &ast2700_clk_lock); + + /*clk stop 2 */ + //UART5 + clks[SCU1_CLK_UART5] =3D + clk_hw_register_mux(NULL, "uart5clk", uartclk_sel, ARRAY_SIZE(uartclk_se= l), + 0, clk_base + SCU1_CLK_SEL1, + 5, 1, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_UART5CLK] =3D + ast2700_clk_hw_register_gate(NULL, "uart5clk-gate", "uart5clk", + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP2, + 0, 0, &ast2700_clk_lock); + + //UART6 + clks[SCU1_CLK_UART6] =3D + clk_hw_register_mux(NULL, "uart6clk", uartclk_sel, ARRAY_SIZE(uartclk_se= l), + 0, clk_base + SCU1_CLK_SEL1, + 6, 1, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_UART6CLK] =3D + ast2700_clk_hw_register_gate(NULL, "uart6clk-gate", "uart6clk", + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP2, + 1, 0, &ast2700_clk_lock); + + //UART7 + clks[SCU1_CLK_UART7] =3D + clk_hw_register_mux(NULL, "uart7clk", uartclk_sel, ARRAY_SIZE(uartclk_se= l), + 0, clk_base + SCU1_CLK_SEL1, + 7, 1, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_UART7CLK] =3D + ast2700_clk_hw_register_gate(NULL, "uart7clk-gate", "uart7clk", + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP2, + 2, 0, &ast2700_clk_lock); + + //UART8 + clks[SCU1_CLK_UART8] =3D + clk_hw_register_mux(NULL, "uart8clk", uartclk_sel, ARRAY_SIZE(uartclk_se= l), + 0, clk_base + SCU1_CLK_SEL1, + 8, 1, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_UART8CLK] =3D + ast2700_clk_hw_register_gate(NULL, "uart8clk-gate", "uart8clk", + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP2, + 3, 0, &ast2700_clk_lock); + + //UART9 + clks[SCU1_CLK_UART9] =3D + clk_hw_register_mux(NULL, "uart9clk", uartclk_sel, ARRAY_SIZE(uartclk_se= l), + 0, clk_base + SCU1_CLK_SEL1, + 9, 1, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_UART9CLK] =3D + ast2700_clk_hw_register_gate(NULL, "uart9clk-gate", "uart9clk", + 0, clk_base + SCU1_CLK_STOP2, + 4, 0, &ast2700_clk_lock); + + //UART10 + clks[SCU1_CLK_UART10] =3D + clk_hw_register_mux(NULL, "uart10clk", uartclk_sel, ARRAY_SIZE(uartclk_s= el), + 0, clk_base + SCU1_CLK_SEL1, + 10, 1, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_UART10CLK] =3D + ast2700_clk_hw_register_gate(NULL, "uart10clk-gate", "uart10clk", + 0, clk_base + SCU1_CLK_STOP2, + 5, 0, &ast2700_clk_lock); + + //UART11 + clks[SCU1_CLK_UART11] =3D + clk_hw_register_mux(NULL, "uart11clk", uartclk_sel, ARRAY_SIZE(uartclk_s= el), + 0, clk_base + SCU1_CLK_SEL1, + 11, 1, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_UART11CLK] =3D + ast2700_clk_hw_register_gate(NULL, "uart11clk-gate", "uart11clk", + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP2, + 6, 0, &ast2700_clk_lock); + + //uart12: call bmc uart + clks[SCU1_CLK_UART12] =3D + clk_hw_register_mux(NULL, "uart12clk", uartclk_sel, ARRAY_SIZE(uartclk_s= el), + 0, clk_base + SCU1_CLK_SEL1, + 12, 1, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_UART12CLK] =3D + ast2700_clk_hw_register_gate(NULL, "uart12clk-gate", "uart12clk", + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP2, + 7, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_FSICLK] =3D + ast2700_clk_hw_register_gate(NULL, "fsiclk-gate", NULL, + 0, clk_base + SCU1_CLK_STOP2, + 8, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_LTPIPHYCLK] =3D + ast2700_clk_hw_register_gate(NULL, "ltpiphyclk-gate", NULL, + 0, clk_base + SCU1_CLK_STOP2, + 9, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_LTPICLK] =3D + ast2700_clk_hw_register_gate(NULL, "ltpiclk-gate", NULL, + 0, clk_base + SCU1_CLK_STOP2, + 10, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_VGALCLK] =3D + ast2700_clk_hw_register_gate(NULL, "vgalclk-gate", NULL, + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP2, + 11, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_USBUARTCLK] =3D + ast2700_clk_hw_register_gate(NULL, "usbuartclk-gate", NULL, + 0, clk_base + SCU1_CLK_STOP2, + 12, 0, &ast2700_clk_lock); + + clk_hw_register_fixed_factor(NULL, "canclk", "soc1-apll", 0, 1, 10); + + clks[SCU1_CLK_GATE_CANCLK] =3D + ast2700_clk_hw_register_gate(NULL, "canclk-gate", "canclk", + 0, clk_base + SCU1_CLK_STOP2, + 13, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_PCICLK] =3D + ast2700_clk_hw_register_gate(NULL, "pciclk-gate", NULL, + 0, clk_base + SCU1_CLK_STOP2, + 14, 0, &ast2700_clk_lock); + + clks[SCU1_CLK_GATE_SLICLK] =3D + ast2700_clk_hw_register_gate(NULL, "sliclk-gate", NULL, + CLK_IS_CRITICAL, clk_base + SCU1_CLK_STOP2, + 15, 0, &ast2700_clk_lock); + + of_clk_add_hw_provider(soc1_node, of_clk_hw_onecell_get, clk_data); + + return 0; +}; + +static const char *const pspclk_sel[] =3D { + "soc0-mpll", + "soc0-hpll", +}; + +static const char *const soc0_uartclk_sel[] =3D { + "soc0-clk24Mhz", + "soc0-clk192Mhz", +}; + +static const char *const emmcclk_sel[] =3D { + "soc0-mpll_div4", + "soc0-hpll_div4", +}; + +static int ast2700_soc0_clk_init(struct device_node *soc0_node) +{ + struct clk_hw_onecell_data *clk_data; + void __iomem *clk_base; + struct ast2700_reset *reset; + struct clk_hw **clks; + int div; + u32 val; + int ret; + + clk_data =3D kzalloc(struct_size(clk_data, hws, SOC0_NUM_CLKS), GFP_KERNE= L); + if (!clk_data) + return -ENOMEM; + + clk_data->num =3D SOC0_NUM_CLKS; + clks =3D clk_data->hws; + + clk_base =3D of_iomap(soc0_node, 0); + if (WARN_ON(IS_ERR(clk_base))) + return PTR_ERR(clk_base); + + reset =3D kzalloc(sizeof(*reset), GFP_KERNEL); + if (!reset) + return -ENOMEM; + + reset->base =3D clk_base; + + reset->rcdev.owner =3D THIS_MODULE; + reset->rcdev.nr_resets =3D SOC0_RESET_NUMS; + reset->rcdev.ops =3D &ast2700_reset_ops; + reset->rcdev.of_node =3D soc0_node; + + ret =3D reset_controller_register(&reset->rcdev); + if (ret) { + pr_err("soc0 failed to register reset controller\n"); + return ret; + } + + //refclk + clks[SCU0_CLKIN] =3D + clk_hw_register_fixed_rate(NULL, "soc0-clkin", NULL, 0, SCU_CLK_25MHZ); + + clks[SCU0_CLK_24M] =3D + clk_hw_register_fixed_rate(NULL, "soc0-clk24Mhz", NULL, 0, SCU_CLK_24MHZ= ); + + clks[SCU0_CLK_192M] =3D + clk_hw_register_fixed_rate(NULL, "soc0-clk192Mhz", NULL, 0, SCU_CLK_192M= HZ); + + //hpll + val =3D readl(clk_base + SCU0_HWSTRAP1); + if ((val & GENMASK(3, 2)) !=3D 0) { + switch ((val & GENMASK(3, 2)) >> 2) { + case 1: + clks[SCU0_CLK_HPLL] =3D + clk_hw_register_fixed_rate(NULL, "soc0-hpll", NULL, 0, 1900000000); + break; + case 2: + clks[SCU0_CLK_HPLL] =3D + clk_hw_register_fixed_rate(NULL, "soc0-hpll", NULL, 0, 1800000000); + break; + case 3: + clks[SCU0_CLK_HPLL] =3D + clk_hw_register_fixed_rate(NULL, "soc0-hpll", NULL, 0, 1700000000); + break; + } + } else { + val =3D readl(clk_base + SCU0_HPLL_PARAM); + clks[SCU0_CLK_HPLL] =3D ast2700_soc0_hw_pll("soc0-hpll", "soc0-clkin", v= al); + } + clks[SCU0_CLK_HPLL_DIV2] =3D clk_hw_register_fixed_factor(NULL, "soc0-hpl= l_div2", "soc0-hpll", 0, 1, 2); + clks[SCU0_CLK_HPLL_DIV4] =3D clk_hw_register_fixed_factor(NULL, "soc0-hpl= l_div4", "soc0-hpll", 0, 1, 4); + + //dpll + val =3D readl(clk_base + SCU0_DPLL_PARAM); + clks[SCU0_CLK_DPLL] =3D ast2700_soc0_hw_pll("dpll", "soc0-clkin", val); + + //mpll + val =3D readl(clk_base + SCU0_MPLL_PARAM); + clks[SCU0_CLK_MPLL] =3D ast2700_calc_mpll("soc0-mpll", "soc0-clkin", val); + clks[SCU0_CLK_MPLL_DIV2] =3D clk_hw_register_fixed_factor(NULL, "soc0-mpl= l_div2", "soc0-mpll", 0, 1, 2); + clks[SCU0_CLK_MPLL_DIV4] =3D clk_hw_register_fixed_factor(NULL, "soc0-mpl= l_div4", "soc0-mpll", 0, 1, 4); + clks[SCU0_CLK_MPLL_DIV8] =3D clk_hw_register_fixed_factor(NULL, "soc0-mpl= l_div8", "soc0-mpll", 0, 1, 8); + + val =3D readl(clk_base + SCU0_D1CLK_PARAM); + clks[SCU0_CLK_D1CLK] =3D ast2700_soc0_hw_pll("d1clk", "soc0-clkin", val); + + val =3D readl(clk_base + SCU0_D2CLK_PARAM); + clks[SCU0_CLK_D2CLK] =3D ast2700_soc0_hw_pll("d2clk", "soc0-clkin", val); + + val =3D readl(clk_base + SCU0_CRT1CLK_PARAM); + clks[SCU0_CLK_CRT1] =3D ast2700_soc0_hw_pll("crt1clk", "soc0-clkin", val); + + val =3D readl(clk_base + SCU0_CRT2CLK_PARAM); + clks[SCU0_CLK_CRT2] =3D ast2700_soc0_hw_pll("crt2clk", "soc0-clkin", val); + + val =3D readl(clk_base + SCU0_MPHYCLK_PARAM); + clks[SCU0_CLK_MPHY] =3D clk_hw_register_fixed_factor(NULL, "mphyclk", "so= c0-hpll", 0, 1, val + 1); + + clks[SCU0_CLK_PSP] =3D + clk_hw_register_mux(NULL, "pspclk", pspclk_sel, ARRAY_SIZE(pspclk_sel), + 0, clk_base + SCU0_HWSTRAP1, + 4, 1, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_AXI] =3D + clk_hw_register_fixed_factor(NULL, "axi0clk", "pspclk", 0, 1, 2); + + val =3D readl(clk_base + SCU0_HWSTRAP1); + if (val & BIT(7)) { + clks[SCU0_CLK_AHB] =3D + clk_hw_register_divider_table(NULL, "soc0-ahb", "soc0-hpll", + 0, clk_base + SCU0_HWSTRAP1, + 5, 2, 0, ast2700_clk_div_table, &ast2700_clk_lock); + } else { + clks[SCU0_CLK_AHB] =3D + clk_hw_register_divider_table(NULL, "soc0-ahb", "soc0-mpll", + 0, clk_base + SCU0_HWSTRAP1, + 5, 2, 0, ast2700_clk_div_table, &ast2700_clk_lock); + } + + clks[SCU0_CLK_AXI1] =3D + clk_hw_register_fixed_factor(NULL, "axi1clk", "soc0-ahb", 0, 1, 2); + + clks[SCU0_CLK_APB] =3D + clk_hw_register_divider_table(NULL, "soc0-apb", "axi0clk", + 0, clk_base + SCU0_CLK_SEL1, + 23, 3, 0, ast2700_clk_div_table2, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_MCLK] =3D + ast2700_clk_hw_register_gate(NULL, "mclk", "soc0-mpll", + CLK_IS_CRITICAL, clk_base + SCU0_CLK_STOP, + 0, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_ECLK] =3D + ast2700_clk_hw_register_gate(NULL, "eclk", NULL, + 0, clk_base + SCU0_CLK_STOP, + 1, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_GCLK] =3D + ast2700_clk_hw_register_gate(NULL, "gclk", NULL, + CLK_IS_CRITICAL, clk_base + SCU0_CLK_STOP, + 2, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_VCLK] =3D + ast2700_clk_hw_register_gate(NULL, "vclk", NULL, + 0, clk_base + SCU0_CLK_STOP, + 3, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_BCLK] =3D + ast2700_clk_hw_register_gate(NULL, "bclk", NULL, + CLK_IS_CRITICAL, clk_base + SCU0_CLK_STOP, + 4, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_D1CLK] =3D + ast2700_clk_hw_register_gate(NULL, "d1clk-gate", NULL, + CLK_IS_CRITICAL, clk_base + SCU0_CLK_STOP, + 5, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_REFCLK] =3D + ast2700_clk_hw_register_gate(NULL, "soc0-refclk-gate", "soc0-clkin", + CLK_IS_CRITICAL, clk_base + SCU0_CLK_STOP, + 6, 0, &ast2700_clk_lock); + + div =3D (GET_USB_REFCLK_DIV(readl(clk_base + SCU0_CLK_SEL2)) + 1) * 2; + clks[SCU0_CLK_U2PHY_REFCLK] =3D clk_hw_register_fixed_factor(NULL, "xhci_= ref_clk", "soc0-mpll_div8", 0, 1, div); + + clks[SCU0_CLK_U2PHY_CLK12M] =3D + clk_hw_register_fixed_rate(NULL, "xhci_suspend_clk", NULL, 0, SCU_CLK_12= MHZ); + + clks[SCU0_CLK_GATE_USB0CLK] =3D + ast2700_clk_hw_register_gate(NULL, "usb0clk", NULL, + 0, clk_base + SCU0_CLK_STOP, + 7, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_USB1CLK] =3D + ast2700_clk_hw_register_gate(NULL, "usb1clk", NULL, + 0, clk_base + SCU0_CLK_STOP, + 9, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_D2CLK] =3D + ast2700_clk_hw_register_gate(NULL, "d2clk-gate", NULL, + CLK_IS_CRITICAL, clk_base + SCU0_CLK_STOP, + 10, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_YCLK] =3D + ast2700_clk_hw_register_gate(NULL, "yclk", NULL, + 0, clk_base + SCU0_CLK_STOP, + 13, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_USB2CLK] =3D + ast2700_clk_hw_register_gate(NULL, "usb2clk", NULL, + 0, clk_base + SCU0_CLK_STOP, + 14, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_UART] =3D + clk_hw_register_mux(NULL, "soc0-uartclk", soc0_uartclk_sel, ARRAY_SIZE(s= oc0_uartclk_sel), + 0, clk_base + SCU0_CLK_SEL2, + 14, 1, 0, &ast2700_clk_lock); + + if (readl(clk_base + SCU0_CLK_SEL2) & UART_DIV13_EN) + div =3D 13; + else + div =3D 1; + + clks[SCU0_CLK_UART4] =3D + clk_hw_register_fixed_factor(NULL, "uart4clk", "soc0-uartclk", 0, 1, div= ); + + clks[SCU0_CLK_GATE_UART4CLK] =3D + ast2700_clk_hw_register_gate(NULL, "uart4clk-gate", "uart4clk", + CLK_IS_CRITICAL, clk_base + SCU0_CLK_STOP, + 15, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_DACCLK] =3D + ast2700_clk_hw_register_gate(NULL, "dacclk", NULL, + CLK_IS_CRITICAL, clk_base + SCU0_CLK_STOP, + 17, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_CRT1CLK] =3D + ast2700_clk_hw_register_gate(NULL, "crt1clk-gate", NULL, + 0, clk_base + SCU0_CLK_STOP, + 20, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_CRT2CLK] =3D + ast2700_clk_hw_register_gate(NULL, "crt2clk-gate", NULL, + 0, clk_base + SCU0_CLK_STOP, + 21, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_ECCCLK] =3D + ast2700_clk_hw_register_gate(NULL, "eccclk", NULL, + 0, clk_base + SCU0_CLK_STOP, + 23, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_RSACLK] =3D + ast2700_clk_hw_register_gate(NULL, "rsaclk", NULL, + 0, clk_base + SCU0_CLK_STOP, + 24, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_RVAS0CLK] =3D + ast2700_clk_hw_register_gate(NULL, "rvasclk", NULL, + 0, clk_base + SCU0_CLK_STOP, + 25, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_UFSCLK] =3D + ast2700_clk_hw_register_gate(NULL, "ufsclk", NULL, + 0, clk_base + SCU0_CLK_STOP, + 26, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_EMMCMUX] =3D + clk_hw_register_mux(NULL, "emmcsrc-mux", emmcclk_sel, ARRAY_SIZE(emmcclk= _sel), + 0, clk_base + SCU0_CLK_SEL1, + 11, 1, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_EMMC] =3D + clk_hw_register_divider_table(NULL, "emmcclk", "emmcsrc-mux", + 0, clk_base + SCU0_CLK_SEL1, + 12, 3, 0, ast2700_clk_div_table2, + &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_EMMCCLK] =3D + ast2700_clk_hw_register_gate(NULL, "emmcclk-gate", "emmcclk", + 0, clk_base + SCU0_CLK_STOP, + 27, 0, &ast2700_clk_lock); + + clks[SCU0_CLK_GATE_RVAS1CLK] =3D + ast2700_clk_hw_register_gate(NULL, "rvas2clk", NULL, + 0, clk_base + SCU0_CLK_STOP, + 28, 0, &ast2700_clk_lock); + + of_clk_add_hw_provider(soc0_node, of_clk_hw_onecell_get, clk_data); + + return 0; +}; + +CLK_OF_DECLARE_DRIVER(ast2700_soc0, "aspeed,ast2700-scu0", ast2700_soc0_cl= k_init); +CLK_OF_DECLARE_DRIVER(ast2700_soc1, "aspeed,ast2700-scu1", ast2700_soc1_cl= k_init); --=20 2.34.1