From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8E427C636CC for ; Thu, 16 Feb 2023 03:16:43 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5080A85A6A; Thu, 16 Feb 2023 04:16:39 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=starfivetech.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 461C485A84; Thu, 16 Feb 2023 04:16:36 +0100 (CET) Received: from ex01.ufhost.com (ex01.ufhost.com [61.152.239.75]) by phobos.denx.de (Postfix) with ESMTP id 7BDFD85A66 for ; Thu, 16 Feb 2023 04:16:25 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=starfivetech.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=yanhong.wang@starfivetech.com Received: from EXMBX165.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX165", Issuer "EXMBX165" (not verified)) by ex01.ufhost.com (Postfix) with ESMTP id 1ED3524E023; Thu, 16 Feb 2023 11:16:22 +0800 (CST) Received: from EXMBX073.cuchost.com (172.16.6.83) by EXMBX165.cuchost.com (172.16.6.75) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 16 Feb 2023 11:16:22 +0800 Received: from [192.168.120.49] (171.223.208.138) by EXMBX073.cuchost.com (172.16.6.83) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 16 Feb 2023 11:16:21 +0800 Message-ID: Date: Thu, 16 Feb 2023 11:16:19 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.6.1 Subject: Re: [PATCH v2 06/17] clk: starfive: Add StarFive JH7110 clock driver Content-Language: en-US To: Sean Anderson , , Rick Chen , Leo , Lukasz Majewski CC: Lee Kuan Lim , Jianlong Huang , Emil Renner Berthing References: <20230118081132.31403-1-yanhong.wang@starfivetech.com> <20230118081132.31403-7-yanhong.wang@starfivetech.com> From: yanhong wang In-Reply-To: Content-Type: text/plain; charset="UTF-8" X-Originating-IP: [171.223.208.138] X-ClientProxiedBy: EXCAS064.cuchost.com (172.16.6.24) To EXMBX073.cuchost.com (172.16.6.83) X-YovoleRuleAgent: yovoleflag Content-Transfer-Encoding: quoted-printable X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean On 2023/1/22 2:56, Sean Anderson wrote: > On 1/18/23 03:11, Yanhong Wang wrote: >> Add a DM clock driver for StarFive JH7110 SoC. >> >> Signed-off-by: Yanhong Wang >> --- >> =C2=A0 drivers/clk/Kconfig=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2= =A0 1 + >> =C2=A0 drivers/clk/Makefile=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0 1= + >> =C2=A0 drivers/clk/starfive/Kconfig=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 |=C2=A0 17 + >> =C2=A0 drivers/clk/starfive/Makefile=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0 |=C2=A0=C2=A0 4 + >> =C2=A0 drivers/clk/starfive/clk-jh7110-pll.c | 293 ++++++++++++++ >> =C2=A0 drivers/clk/starfive/clk-jh7110.c=C2=A0=C2=A0=C2=A0=C2=A0 | 559= ++++++++++++++++++++++++++ >> =C2=A0 drivers/clk/starfive/clk.h=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0 60 +++ >> =C2=A0 7 files changed, 935 insertions(+) >> =C2=A0 create mode 100644 drivers/clk/starfive/Kconfig >> =C2=A0 create mode 100644 drivers/clk/starfive/Makefile >> =C2=A0 create mode 100644 drivers/clk/starfive/clk-jh7110-pll.c >> =C2=A0 create mode 100644 drivers/clk/starfive/clk-jh7110.c >> =C2=A0 create mode 100644 drivers/clk/starfive/clk.h >> >> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig >> index 09aa97ee8c..4d60c84aad 100644 >> --- a/drivers/clk/Kconfig >> +++ b/drivers/clk/Kconfig >> @@ -235,6 +235,7 @@ source "drivers/clk/owl/Kconfig" >> =C2=A0 source "drivers/clk/renesas/Kconfig" >> =C2=A0 source "drivers/clk/sunxi/Kconfig" >> =C2=A0 source "drivers/clk/sifive/Kconfig" >> +source "drivers/clk/starfive/Kconfig" >> =C2=A0 source "drivers/clk/stm32/Kconfig" >> =C2=A0 source "drivers/clk/tegra/Kconfig" >> =C2=A0 source "drivers/clk/ti/Kconfig" >> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile >> index c274cda77c..66f5860356 100644 >> --- a/drivers/clk/Makefile >> +++ b/drivers/clk/Makefile >> @@ -13,6 +13,7 @@ obj-$(CONFIG_$(SPL_TPL_)CLK_COMPOSITE_CCF) +=3D clk-= composite.o >> =C2=A0 =C2=A0 obj-y +=3D analogbits/ >> =C2=A0 obj-y +=3D imx/ >> +obj-$(CONFIG_CLK_JH7110) +=3D starfive/ >> =C2=A0 obj-y +=3D tegra/ >> =C2=A0 obj-y +=3D ti/ >> =C2=A0 obj-$(CONFIG_$(SPL_TPL_)CLK_INTEL) +=3D intel/ >> diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconf= ig >> new file mode 100644 >> index 0000000000..9399ef6d51 >> --- /dev/null >> +++ b/drivers/clk/starfive/Kconfig >> @@ -0,0 +1,17 @@ >> +# SPDX-License-Identifier: GPL-2.0+ >> + >> +config SPL_CLK_JH7110 >> +=C2=A0=C2=A0=C2=A0 bool "SPL clock support for JH7110" >> +=C2=A0=C2=A0=C2=A0 depends on STARFIVE_JH7110 && SPL >> +=C2=A0=C2=A0=C2=A0 select SPL_CLK >> +=C2=A0=C2=A0=C2=A0 select SPL_CLK_CCF >> +=C2=A0=C2=A0=C2=A0 help >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 This enables SPL DM support for clock = driver in JH7110. >> + >> +config CLK_JH7110 >> +=C2=A0=C2=A0=C2=A0 bool "StarFive JH7110 clock support" >> +=C2=A0=C2=A0=C2=A0 depends on STARFIVE_JH7110 >> +=C2=A0=C2=A0=C2=A0 select CLK >> +=C2=A0=C2=A0=C2=A0 select CLK_CCF >> +=C2=A0=C2=A0=C2=A0 help >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 This enables support clock driver for = StarFive JH7110 SoC platform. >> diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Make= file >> new file mode 100644 >> index 0000000000..ec0d157094 >> --- /dev/null >> +++ b/drivers/clk/starfive/Makefile >> @@ -0,0 +1,4 @@ >> +# SPDX-License-Identifier: GPL-2.0+ >> + >> +obj-y +=3D clk-jh7110.o >> +obj-y +=3D clk-jh7110-pll.o >> diff --git a/drivers/clk/starfive/clk-jh7110-pll.c b/drivers/clk/starf= ive/clk-jh7110-pll.c >> new file mode 100644 >> index 0000000000..08e1755d3a >> --- /dev/null >> +++ b/drivers/clk/starfive/clk-jh7110-pll.c >> @@ -0,0 +1,293 @@ >> +// SPDX-License-Identifier: GPL-2.0+ >> +/* >> + * Copyright (C) 2022 StarFive Technology Co., Ltd. >=20 > 2022-23 :) >=20 >> + * >> + * Author:=C2=A0=C2=A0=C2=A0 Yanhong Wang >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include "clk.h" >> + >> +#define UBOOT_DM_CLK_JH7110_PLLX "jh7110_clk_pllx" >> + >> +#define PLL_PD_OFF=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 1 >> +#define PLL_PD_ON=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 0 >> + >> +#define CLK_DDR_BUS_MASK=C2=A0=C2=A0=C2=A0 GENMASK(29, 24) >> +#define CLK_DDR_BUS_OFFSET=C2=A0=C2=A0=C2=A0 0xAC >> +#define CLK_DDR_BUS_OSC_DIV2=C2=A0=C2=A0=C2=A0 0 >> +#define CLK_DDR_BUS_PLL1_DIV2=C2=A0=C2=A0=C2=A0 1 >> +#define CLK_DDR_BUS_PLL1_DIV4=C2=A0=C2=A0=C2=A0 2 >> +#define CLK_DDR_BUS_PLL1_DIV8=C2=A0=C2=A0=C2=A0 3 >> + >> +struct clk_jh7110_pllx { >> +=C2=A0=C2=A0=C2=A0 struct clk=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= clk; >> +=C2=A0=C2=A0=C2=A0 void __iomem=C2=A0=C2=A0=C2=A0 *base; >> +=C2=A0=C2=A0=C2=A0 void __iomem=C2=A0=C2=A0=C2=A0 *sysreg; >> +=C2=A0=C2=A0=C2=A0 enum starfive_pll_type=C2=A0=C2=A0=C2=A0 type; >> +=C2=A0=C2=A0=C2=A0 const struct starfive_pllx_offset *offset; >> +=C2=A0=C2=A0=C2=A0 const struct starfive_pllx_rate *rate_table; >> +=C2=A0=C2=A0=C2=A0 int rate_count; >> +}; >> + >> +#define getbits_le32(addr, mask) ((in_le32(addr) & (mask)) >> __ffs((= mask))) >> + >> +#define PLLX_SET(offset, mask, val) do {\ >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 reg =3D readl((ulong *)((u= long)pll->base + (offset))); \ >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 reg &=3D ~(mask); \ >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 reg |=3D (mask) & ((val) <= < __ffs(mask)); \ >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 writel(reg, (ulong *)((ulo= ng)pll->base + (offset))); \ >> +=C2=A0=C2=A0=C2=A0 } while (0) >> + >> +#define PLLX_RATE(_rate, _pd, _fd, _pd1, _da, _ds)=C2=A0=C2=A0=C2=A0 = \ >> +=C2=A0=C2=A0=C2=A0 {=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0 \ >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 .rate=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 =3D (_rate),=C2=A0=C2=A0=C2=A0 \ >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 .prediv=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 =3D (_pd),=C2=A0=C2=A0=C2=A0 \ >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 .fbdiv=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 =3D (_fd),=C2=A0=C2=A0=C2=A0 \ >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 .postdiv1=C2=A0=C2=A0=C2=A0= =3D (_pd1),=C2=A0=C2=A0=C2=A0 \ >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 .dacpd=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 =3D (_da),=C2=A0=C2=A0=C2=A0 \ >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 .dsmpd=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 =3D (_ds),=C2=A0=C2=A0=C2=A0 \ >> +=C2=A0=C2=A0=C2=A0 } >> + >> +#define to_clk_pllx(_clk) container_of(_clk, struct clk_jh7110_pllx, = clk) >> + >> +static const struct starfive_pllx_rate jh7110_pll0_tbl[] =3D { >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(375000000UL, 8, 125, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(500000000UL, 6, 125, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(625000000UL, 24, 625, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(750000000UL, 4, 125, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(875000000UL, 24, 875, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(1000000000UL, 3, 125, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(1250000000UL, 12, 625, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(1375000000UL, 24, 1375, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(1500000000UL, 2, 125, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(1625000000UL, 24, 1625, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(1750000000UL, 12, 875, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(1800000000UL, 3, 225, 1, 1, 1), >> +}; >> + >> +static const struct starfive_pllx_rate jh7110_pll1_tbl[] =3D { >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(1066000000UL, 12, 533, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(1200000000UL, 1, 50, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(1400000000UL, 6, 350, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(1600000000UL, 3, 200, 1, 1, 1), >> +}; >> + >> +static const struct starfive_pllx_rate jh7110_pll2_tbl[] =3D { >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(1228800000UL, 15, 768, 1, 1, 1), >> +=C2=A0=C2=A0=C2=A0 PLLX_RATE(1188000000UL, 2, 99, 1, 1, 1), >> +}; >=20 > My comment from last time stands about pd1/da/ds >=20 The values of pd1/da/ds do not need to be saved, and I will replace them = with constants in the next version. > (sorry for not getting back to you faster) >=20 >> +static const struct starfive_pllx_offset jh7110_pll0_offset =3D { >> +=C2=A0=C2=A0=C2=A0 .prediv =3D 0x24, >> +=C2=A0=C2=A0=C2=A0 .fbdiv =3D 0x1c, >> +=C2=A0=C2=A0=C2=A0 .frac =3D 0x20, >> +=C2=A0=C2=A0=C2=A0 .postdiv1 =3D 0x20, >> +=C2=A0=C2=A0=C2=A0 .dacpd =3D 0x18, >> +=C2=A0=C2=A0=C2=A0 .dsmpd =3D 0x18, >> +=C2=A0=C2=A0=C2=A0 .prediv_mask =3D GENMASK(5, 0), >> +=C2=A0=C2=A0=C2=A0 .fbdiv_mask =3D GENMASK(11, 0), >> +=C2=A0=C2=A0=C2=A0 .frac_mask =3D GENMASK(23, 0), >> +=C2=A0=C2=A0=C2=A0 .postdiv1_mask =3D GENMASK(29, 28), >> +=C2=A0=C2=A0=C2=A0 .dacpd_mask =3D BIT(24), >> +=C2=A0=C2=A0=C2=A0 .dsmpd_mask =3D BIT(25) >> +}; >> + >> +static const struct starfive_pllx_offset jh7110_pll1_offset =3D { >> +=C2=A0=C2=A0=C2=A0 .prediv =3D 0x2c, >> +=C2=A0=C2=A0=C2=A0 .fbdiv =3D 0x24, >> +=C2=A0=C2=A0=C2=A0 .frac =3D 0x28, >> +=C2=A0=C2=A0=C2=A0 .postdiv1 =3D 0x28, >> +=C2=A0=C2=A0=C2=A0 .dacpd =3D 0x24, >> +=C2=A0=C2=A0=C2=A0 .dsmpd =3D 0x24, >> +=C2=A0=C2=A0=C2=A0 .prediv_mask =3D GENMASK(5, 0), >> +=C2=A0=C2=A0=C2=A0 .fbdiv_mask =3D GENMASK(28, 17), >> +=C2=A0=C2=A0=C2=A0 .frac_mask =3D GENMASK(23, 0), >> +=C2=A0=C2=A0=C2=A0 .postdiv1_mask =3D GENMASK(29, 28), >> +=C2=A0=C2=A0=C2=A0 .dacpd_mask =3D BIT(15), >> +=C2=A0=C2=A0=C2=A0 .dsmpd_mask =3D BIT(16) >> +}; >> + >> +static const struct starfive_pllx_offset jh7110_pll2_offset =3D { >> +=C2=A0=C2=A0=C2=A0 .prediv =3D 0x34, >> +=C2=A0=C2=A0=C2=A0 .fbdiv =3D 0x2c, >> +=C2=A0=C2=A0=C2=A0 .frac =3D 0x30, >> +=C2=A0=C2=A0=C2=A0 .postdiv1 =3D 0x30, >> +=C2=A0=C2=A0=C2=A0 .dacpd =3D 0x2c, >> +=C2=A0=C2=A0=C2=A0 .dsmpd =3D 0x2c, >> +=C2=A0=C2=A0=C2=A0 .prediv_mask =3D GENMASK(5, 0), >> +=C2=A0=C2=A0=C2=A0 .fbdiv_mask =3D GENMASK(28, 17), >> +=C2=A0=C2=A0=C2=A0 .frac_mask =3D GENMASK(23, 0), >> +=C2=A0=C2=A0=C2=A0 .postdiv1_mask =3D GENMASK(29, 28), >> +=C2=A0=C2=A0=C2=A0 .dacpd_mask =3D BIT(15), >> +=C2=A0=C2=A0=C2=A0 .dsmpd_mask =3D BIT(16) >> +}; >=20 > OK, so it looks like these PLLs don't have the same register offsets > like I thought. Since this is the case, you can keep your existing styl= e > or use the style from v1. >=20 >> +struct starfive_pllx_clk starfive_jh7110_pll0 __initdata =3D { >> +=C2=A0=C2=A0=C2=A0 .type =3D PLL0, >> +=C2=A0=C2=A0=C2=A0 .offset =3D &jh7110_pll0_offset, >> +=C2=A0=C2=A0=C2=A0 .rate_table =3D jh7110_pll0_tbl, >> +=C2=A0=C2=A0=C2=A0 .rate_count =3D ARRAY_SIZE(jh7110_pll0_tbl), >> +}; >> + >> +struct starfive_pllx_clk starfive_jh7110_pll1 __initdata =3D { >> +=C2=A0=C2=A0=C2=A0 .type =3D PLL1, >> +=C2=A0=C2=A0=C2=A0 .offset =3D &jh7110_pll1_offset, >> +=C2=A0=C2=A0=C2=A0 .rate_table =3D jh7110_pll1_tbl, >> +=C2=A0=C2=A0=C2=A0 .rate_count =3D ARRAY_SIZE(jh7110_pll1_tbl), >> +}; >> + >> +struct starfive_pllx_clk starfive_jh7110_pll2 __initdata =3D { >> +=C2=A0=C2=A0=C2=A0 .type =3D PLL2, >> +=C2=A0=C2=A0=C2=A0 .offset =3D &jh7110_pll2_offset, >> +=C2=A0=C2=A0=C2=A0 .rate_table =3D jh7110_pll2_tbl, >> +=C2=A0=C2=A0=C2=A0 .rate_count =3D ARRAY_SIZE(jh7110_pll2_tbl), >> +}; >> + >> +static const struct starfive_pllx_rate * >> +=C2=A0=C2=A0=C2=A0 jh7110_get_pll_settings(struct clk_jh7110_pllx *pl= l, unsigned long rate) >=20 > No indent necessary. >=20 >> +{ >> +=C2=A0=C2=A0=C2=A0 for (int i =3D 0; i < pll->rate_count; i++) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (rate =3D=3D pll->rate_= table[i].rate) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 re= turn &pll->rate_table[i]; >> + >> +=C2=A0=C2=A0=C2=A0 return NULL; >> +} >> + >> +static void jh7110_pll_set_rate(struct clk_jh7110_pllx *pll, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 const struct starfive_pllx_rate *rate) >> +{ >> +=C2=A0=C2=A0=C2=A0 u32 reg; >> +=C2=A0=C2=A0=C2=A0 bool set =3D (pll->type =3D=3D PLL1) ? true : fals= e; >> + >> +=C2=A0=C2=A0=C2=A0 if (set) { >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 reg =3D readl((ulong *)((u= long)pll->sysreg + CLK_DDR_BUS_OFFSET)); >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 reg &=3D ~CLK_DDR_BUS_MASK= ; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 reg |=3D CLK_DDR_BUS_OSC_D= IV2 << __ffs(CLK_DDR_BUS_MASK); >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 writel(reg, (ulong *)((ulo= ng)pll->sysreg + CLK_DDR_BUS_OFFSET)); >> +=C2=A0=C2=A0=C2=A0 } >> + >> +=C2=A0=C2=A0=C2=A0 PLLX_SET(pll->offset->pd, pll->offset->pd_mask, PL= L_PD_OFF); >> +=C2=A0=C2=A0=C2=A0 PLLX_SET(pll->offset->dacpd, pll->offset->dacpd_ma= sk, rate->dacpd); >> +=C2=A0=C2=A0=C2=A0 PLLX_SET(pll->offset->dsmpd, pll->offset->dsmpd_ma= sk, rate->dsmpd); >=20 > E.g. this can be PLLX_SET(pll->offset->dsmpd, pll->offset->dsmpd_mask, = 1); >=20 >> +=C2=A0=C2=A0=C2=A0 PLLX_SET(pll->offset->prediv, pll->offset->prediv_= mask, rate->prediv); >> +=C2=A0=C2=A0=C2=A0 PLLX_SET(pll->offset->fbdiv, pll->offset->fbdiv_ma= sk, rate->fbdiv); >> +=C2=A0=C2=A0=C2=A0 PLLX_SET(pll->offset->postdiv1, pll->offset->postd= iv1, rate->postdiv1 >> 1); >=20 > Same question from last time. As you explained, we have something like >=20 > postdiv divider > 0=C2=A0=C2=A0=C2=A0 /1 > 1=C2=A0=C2=A0=C2=A0 /2 > 2=C2=A0=C2=A0=C2=A0 /4 > 3=C2=A0=C2=A0=C2=A0 /8 >=20 > But right shifting is not the correct way to do this. You need to use > ffs (or ilog2). Of course, you missed this bug because you only ever us= e > a /1 postdiv. So I suggest you just always write 0 to postdiv and skip > the calculation. >=20 The values of pd1/da/ds do not need to be saved, and I will replace them = with constants in the next version. >> +=C2=A0=C2=A0=C2=A0 PLLX_SET(pll->offset->pd, pll->offset->pd_mask, PL= L_PD_ON); >=20 > This still obscures the actual registers... >=20 > I would prefer for you to combine writes to the same register so it is > clear what is going on. >=20 I will fix. >> + >> +=C2=A0=C2=A0=C2=A0 if (set) { >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 udelay(100); >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 reg =3D readl((ulong *)((u= long)pll->sysreg + CLK_DDR_BUS_OFFSET)); >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 reg &=3D ~CLK_DDR_BUS_MASK= ; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 reg |=3D CLK_DDR_BUS_PLL1_= DIV2 << __ffs(CLK_DDR_BUS_MASK); >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 writel(reg, (ulong *)((ulo= ng)pll->sysreg + CLK_DDR_BUS_OFFSET)); >> +=C2=A0=C2=A0=C2=A0 } >> +} >> + >> +static ulong jh7110_pllx_recalc_rate(struct clk *clk) >> +{ >> +=C2=A0=C2=A0=C2=A0 struct clk_jh7110_pllx *pll =3D to_clk_pllx(dev_ge= t_clk_ptr(clk->dev)); >> +=C2=A0=C2=A0=C2=A0 u64 refclk =3D clk_get_parent_rate(clk); >> +=C2=A0=C2=A0=C2=A0 u32 dacpd, dsmpd; >> +=C2=A0=C2=A0=C2=A0 u32 prediv, fbdiv, postdiv1; >> +=C2=A0=C2=A0=C2=A0 u64 frac; >> + >> +=C2=A0=C2=A0=C2=A0 dacpd =3D getbits_le32((ulong)pll->base + pll->off= set->dacpd, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 pll->offset->dacpd_mask); >> +=C2=A0=C2=A0=C2=A0 dsmpd =3D getbits_le32((ulong)pll->base + pll->off= set->dsmpd, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 pll->offset->dsmpd_mask); >> +=C2=A0=C2=A0=C2=A0 prediv =3D getbits_le32((ulong)pll->base + pll->of= fset->prediv, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 pll->offset->prediv_mask); >> +=C2=A0=C2=A0=C2=A0 fbdiv =3D getbits_le32((ulong)pll->base + pll->off= set->fbdiv, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 pll->offset->fbdiv_mask); >> +=C2=A0=C2=A0=C2=A0 postdiv1 =3D 1 << getbits_le32((ulong)pll->base + = pll->offset->postdiv1, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 pl= l->offset->postdiv1_mask); >> +=C2=A0=C2=A0=C2=A0 frac =3D (u64)getbits_le32((ulong)pll->base + pll-= >offset->frac, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 pl= l->offset->frac_mask); >> + >> +=C2=A0=C2=A0=C2=A0 /* Integer Mode or Fraction Mode */ >> +=C2=A0=C2=A0=C2=A0 if (dacpd =3D=3D 1 && dsmpd =3D=3D 1) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 frac =3D 0; >> +=C2=A0=C2=A0=C2=A0 else if (dacpd =3D=3D 0 && dsmpd =3D=3D 0) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 do_div(frac, 1 << 24); >=20 > Last time you provided an explanation for where this came from. Please > keep that explanation as a comment here. >=20 >> +=C2=A0=C2=A0=C2=A0 else >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return -EINVAL; >> + >> +=C2=A0=C2=A0=C2=A0 refclk *=3D (fbdiv + frac); >> +=C2=A0=C2=A0=C2=A0 do_div(refclk, prediv * postdiv1); >> + >> +=C2=A0=C2=A0=C2=A0 return refclk; >> +} >> + >> +static ulong jh7110_pllx_set_rate(struct clk *clk, ulong drate) >> +{ >> +=C2=A0=C2=A0=C2=A0 struct clk_jh7110_pllx *pll =3D to_clk_pllx(dev_ge= t_clk_ptr(clk->dev)); >> +=C2=A0=C2=A0=C2=A0 const struct starfive_pllx_rate *rate; >> + >> +=C2=A0=C2=A0=C2=A0 rate =3D jh7110_get_pll_settings(pll, drate); >> +=C2=A0=C2=A0=C2=A0 if (!rate) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return -EINVAL; >> + >> +=C2=A0=C2=A0=C2=A0 jh7110_pll_set_rate(pll, rate); >> + >> +=C2=A0=C2=A0=C2=A0 return jh7110_pllx_recalc_rate(clk); >> +} >> + >> +static const struct clk_ops clk_jh7110_ops =3D { >> +=C2=A0=C2=A0=C2=A0 .set_rate=C2=A0=C2=A0=C2=A0 =3D jh7110_pllx_set_ra= te, >> +=C2=A0=C2=A0=C2=A0 .get_rate=C2=A0=C2=A0=C2=A0 =3D jh7110_pllx_recalc= _rate, >> +}; >> + >> +struct clk *starfive_jh7110_pll(const char *name, const char *parent_= name, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 void __iomem *base, void __iomem *sysreg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 const struct starfive_pllx_clk *pll_clk) >> +{ >> +=C2=A0=C2=A0=C2=A0 struct clk_jh7110_pllx *pll; >> +=C2=A0=C2=A0=C2=A0 struct clk *clk; >> +=C2=A0=C2=A0=C2=A0 int ret; >> + >> +=C2=A0=C2=A0=C2=A0 if (!pll_clk || !base || !sysreg) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return ERR_PTR(-EINVAL); >> + >> +=C2=A0=C2=A0=C2=A0 pll =3D kzalloc(sizeof(*pll), GFP_KERNEL); >> +=C2=A0=C2=A0=C2=A0 if (!pll) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return ERR_PTR(-ENOMEM); >> + >> +=C2=A0=C2=A0=C2=A0 pll->base =3D base; >> +=C2=A0=C2=A0=C2=A0 pll->sysreg =3D sysreg; >> +=C2=A0=C2=A0=C2=A0 pll->type =3D pll_clk->type; >> +=C2=A0=C2=A0=C2=A0 pll->offset =3D pll_clk->offset; >> +=C2=A0=C2=A0=C2=A0 pll->rate_table =3D pll_clk->rate_table; >> +=C2=A0=C2=A0=C2=A0 pll->rate_count =3D pll_clk->rate_count; >> + >> +=C2=A0=C2=A0=C2=A0 clk =3D &pll->clk; >> +=C2=A0=C2=A0=C2=A0 ret =3D clk_register(clk, UBOOT_DM_CLK_JH7110_PLLX= , name, parent_name); >> +=C2=A0=C2=A0=C2=A0 if (ret) { >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 kfree(pll); >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return ERR_PTR(ret); >> +=C2=A0=C2=A0=C2=A0 } >> + >> +=C2=A0=C2=A0=C2=A0 if (IS_ENABLED(CONFIG_SPL_BUILD) && pll->type =3D=3D= PLL0) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 jh7110_pllx_set_rate(clk, = 1250000000); >> + >> +=C2=A0=C2=A0=C2=A0 if (IS_ENABLED(CONFIG_SPL_BUILD) && pll->type =3D=3D= PLL2) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 jh7110_pllx_set_rate(clk, = 1188000000); >> + >> +=C2=A0=C2=A0=C2=A0 return clk; >> +} >> + >> +U_BOOT_DRIVER(jh7110_clk_pllx) =3D { >> +=C2=A0=C2=A0=C2=A0 .name=C2=A0=C2=A0=C2=A0 =3D UBOOT_DM_CLK_JH7110_PL= LX, >> +=C2=A0=C2=A0=C2=A0 .id=C2=A0=C2=A0=C2=A0 =3D UCLASS_CLK, >> +=C2=A0=C2=A0=C2=A0 .ops=C2=A0=C2=A0=C2=A0 =3D &clk_jh7110_ops, >> +}; >> diff --git a/drivers/clk/starfive/clk-jh7110.c b/drivers/clk/starfive/= clk-jh7110.c >> new file mode 100644 >> index 0000000000..a904852cab >> --- /dev/null >> +++ b/drivers/clk/starfive/clk-jh7110.c >> @@ -0,0 +1,559 @@ >> +// SPDX-License-Identifier: GPL-2.0+ >> +/* >> + * Copyright (C) 2022 StarFive Technology Co., Ltd. >> + * >> + * Author:=C2=A0=C2=A0=C2=A0 Yanhong Wang >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include "clk.h" >> + >> +#define STARFIVE_CLK_ENABLE_SHIFT=C2=A0=C2=A0=C2=A0 31 /* [31] */ >> +#define STARFIVE_CLK_INVERT_SHIFT=C2=A0=C2=A0=C2=A0 30 /* [30] */ >> +#define STARFIVE_CLK_MUX_SHIFT=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 24 /* [29:24] */ >> +#define STARFIVE_CLK_DIV_SHIFT=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 0=C2=A0 /* [23:0] */ >> + >> +#define OFFSET(id) ((id) * 4) >> +#define AONOFFSET(id) (((id) - JH7110_SYSCLK_END) * 4) >> +#define STGOFFSET(id) (((id) - JH7110_AONCLK_END) * 4) >> + >> +typedef int (*jh1710_init_fn)(struct udevice *dev); >> + >> +struct jh7110_clk_priv { >> +=C2=A0=C2=A0=C2=A0 void __iomem *reg; >> +=C2=A0=C2=A0=C2=A0 jh1710_init_fn init; >> +}; >> + >> +static const char *cpu_root_sels[2] =3D { >> +=C2=A0=C2=A0=C2=A0 [0] =3D "osc", >> +=C2=A0=C2=A0=C2=A0 [1] =3D "pll0_out", >> +}; >> + >> +static const char *perh_root_sels[2] =3D { >> +=C2=A0=C2=A0=C2=A0 [0] =3D "pll0_out", >> +=C2=A0=C2=A0=C2=A0 [1] =3D "pll2_out", >> +}; >> + >> +static const char *bus_root_sels[2] =3D { >> +=C2=A0=C2=A0=C2=A0 [0] =3D "osc", >> +=C2=A0=C2=A0=C2=A0 [1] =3D "pll2_out", >> +}; >> + >> +static const char *qspi_ref_sels[2] =3D { >> +=C2=A0=C2=A0=C2=A0 [0] =3D "osc", >> +=C2=A0=C2=A0=C2=A0 [1] =3D "qspi_ref_src", >> +}; >> + >> +static const char *gmac1_tx_sels[2] =3D { >> +=C2=A0=C2=A0=C2=A0 [0] =3D "gmac1_gtxclk", >> +=C2=A0=C2=A0=C2=A0 [1] =3D "gmac1_rmii_rtx", >> +}; >> + >> +static const char *gmac0_tx_sels[2] =3D { >> +=C2=A0=C2=A0=C2=A0 [0] =3D "gmac0_gtxclk", >> +=C2=A0=C2=A0=C2=A0 [1] =3D "gmac0_rmii_rtx", >> +}; >> + >> +static struct clk *starfive_clk_mux(void __iomem *reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *name, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 unsigned int offset, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 u8 width, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char * const *parent_= names, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 u8 num_parents) >> +{ >> +=C2=A0=C2=A0=C2=A0 return=C2=A0 clk_register_mux(NULL, name, parent_n= ames, num_parents, 0, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 reg + offset, STARFIVE_CLK_MUX_SHIFT, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 width, 0); >> +} >> + >> +static struct clk *starfive_clk_gate(void __iomem *reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *name, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *parent_na= me, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 unsigned int offset) >> +{ >> +=C2=A0=C2=A0=C2=A0 return clk_register_gate(NULL, name, parent_name, = 0, reg + offset, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 STARFIVE_CLK_ENABLE_SHIFT, 0, NULL); >> +} >> + >> +static struct clk *starfive_clk_fix_factor(void __iomem *reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const cha= r *name, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const cha= r *parent_name, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 unsigned = int mult, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 unsigned = int div) >> +{ >> +=C2=A0=C2=A0=C2=A0 return clk_register_fixed_factor(NULL, name, paren= t_name, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 0, mult, div); >> +} >> + >> +static struct clk *starfive_clk_divider(void __iomem *reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *name, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *parent_name, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 unsigned int offset, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 u8 width) >> +{ >> +=C2=A0=C2=A0=C2=A0 return clk_register_divider(NULL, name, parent_nam= e, 0, reg + offset, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 0, width, CLK_DIVIDER_ONE_BASED); >> +} >> + >> +static struct clk *starfive_clk_composite(void __iomem *reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *nam= e, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char * co= nst *parent_names, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 unsigned int nu= m_parents, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 unsigned int of= fset, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 unsigned int mu= x_width, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 unsigned int ga= te_width, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 unsigned int di= v_width) >> +{ >> +=C2=A0=C2=A0=C2=A0 struct clk *clk =3D ERR_PTR(-ENOMEM); >> +=C2=A0=C2=A0=C2=A0 struct clk_divider *div =3D NULL; >> +=C2=A0=C2=A0=C2=A0 struct clk_gate *gate =3D NULL; >> +=C2=A0=C2=A0=C2=A0 struct clk_mux *mux =3D NULL; >> +=C2=A0=C2=A0=C2=A0 int mask_arry[4] =3D {0x1, 0x3, 0x7, 0xF}; >> +=C2=A0=C2=A0=C2=A0 int mask; >> + >> +=C2=A0=C2=A0=C2=A0 if (mux_width) { >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (mux_width > 4) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 go= to fail; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 else >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ma= sk =3D mask_arry[mux_width - 1]; >> + >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 mux =3D kzalloc(sizeof(*mu= x), GFP_KERNEL); >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (!mux) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 go= to fail; >> + >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 mux->reg =3D reg + offset; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 mux->mask =3D mask; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 mux->shift =3D STARFIVE_CL= K_MUX_SHIFT; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 mux->num_parents =3D num_p= arents; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 mux->flags =3D 0; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 mux->parent_names =3D pare= nt_names; >> +=C2=A0=C2=A0=C2=A0 } >> + >> +=C2=A0=C2=A0=C2=A0 if (gate_width) { >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 gate =3D kzalloc(sizeof(*g= ate), GFP_KERNEL); >> + >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (!gate) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 go= to fail; >> + >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 gate->reg =3D reg + offset= ; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 gate->bit_idx =3D STARFIVE= _CLK_ENABLE_SHIFT; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 gate->flags =3D 0; >> +=C2=A0=C2=A0=C2=A0 } >> + >> +=C2=A0=C2=A0=C2=A0 if (div_width) { >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 div =3D kzalloc(sizeof(*di= v), GFP_KERNEL); >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (!div) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 go= to fail; >> + >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 div->reg =3D reg + offset; >> + >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (offset =3D=3D OFFSET(J= H7110_SYSCLK_UART3_CORE) || >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 of= fset =3D=3D OFFSET(JH7110_SYSCLK_UART4_CORE) || >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 of= fset =3D=3D OFFSET(JH7110_SYSCLK_UART5_CORE)) { >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 di= v->shift =3D 8; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 di= v->width =3D 8; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } else { >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 di= v->shift =3D STARFIVE_CLK_DIV_SHIFT; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 di= v->width =3D div_width; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 div->flags =3D CLK_DIVIDER= _ONE_BASED; >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 div->table =3D NULL; >> +=C2=A0=C2=A0=C2=A0 } >> + >> +=C2=A0=C2=A0=C2=A0 clk =3D clk_register_composite(NULL, name, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 parent_names, num_par= ents, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &mux->clk, &clk_mux_o= ps, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &div->clk, &clk_divid= er_ops, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &gate->clk, &clk_gate= _ops, 0); >> + >> +=C2=A0=C2=A0=C2=A0 if (IS_ERR(clk)) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 goto fail; >> + >> +=C2=A0=C2=A0=C2=A0 return clk; >> + >> +fail: >> +=C2=A0=C2=A0=C2=A0 kfree(gate); >> +=C2=A0=C2=A0=C2=A0 kfree(div); >> +=C2=A0=C2=A0=C2=A0 kfree(mux); >> +=C2=A0=C2=A0=C2=A0 return ERR_CAST(clk); >> +} >> + >> +static struct clk *starfive_clk_fix_parent_composite(void __iomem *re= g, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 const char *name, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 const char *parent_names, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 unsigned int offset, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 unsigned int mux_width, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 unsigned int gate_width, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 unsigned int div_width) >> +{ >> +=C2=A0=C2=A0=C2=A0 const char * const *parents; >> + >> +=C2=A0=C2=A0=C2=A0 parents=C2=A0 =3D &parent_names; >> + >> +=C2=A0=C2=A0=C2=A0 return starfive_clk_composite(reg, name, parents, = 1, offset, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 mu= x_width, gate_width, div_width); >> +} >> + >> +static struct clk *starfive_clk_gate_divider(void __iomem *reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= const char *name, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= const char *parent, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= unsigned int offset, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= unsigned int width) >> +{ >> +=C2=A0=C2=A0=C2=A0 const char * const *parent_names; >> + >> +=C2=A0=C2=A0=C2=A0 parent_names=C2=A0 =3D &parent; >> + >> +=C2=A0=C2=A0=C2=A0 return starfive_clk_composite(reg, name, parent_na= mes, 1, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 offset, 0, 1, width); >> +} >> + >> +static int jh7110_syscrg_init(struct udevice *dev) >> +{ >> +=C2=A0=C2=A0=C2=A0 struct jh7110_clk_priv *priv =3D dev_get_priv(dev)= ; >> +=C2=A0=C2=A0=C2=A0 struct ofnode_phandle_args args; >> +=C2=A0=C2=A0=C2=A0 fdt_addr_t addr; >> +=C2=A0=C2=A0=C2=A0 int ret; >> + >> +=C2=A0=C2=A0=C2=A0 ret =3D ofnode_parse_phandle_with_args(dev->node_,= "starfive,sys-syscon", NULL, 0, 0, &args); >> +=C2=A0=C2=A0=C2=A0 if (ret) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return ret; >=20 > Last time you said the bindings in linux had not been updated. Have you > resubmitted with this property added? >=20 The part of the bindings in linux is submitted by other colleagues, and w= e will communicate=20 regularly to maintain consensus. > Maybe you should have a separate binding for the PLLs? See below for > ordering advice. Pll clocks need two base addresses: the base address of syscon and syscrg= clock control. If the pll is=20 separated into independent nodes, the base address of the required syscrg= clock control is not well defined;=20 the parent clock of some clocks in the syscrg clock control is the pll cl= ock , which requires the pll clock=20 driver to be initialized first, otherwise the clock that depends on the p= ll clock will report an error=20 when calling clk_register()[ get parent clock fail]. So it is not appropr= iate to separate the pll clock=20 into independent nodes. >=20 >> +=C2=A0=C2=A0=C2=A0 addr =3D=C2=A0 ofnode_get_addr(args.node); >> +=C2=A0=C2=A0=C2=A0 if (addr =3D=3D FDT_ADDR_T_NONE) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return -EINVAL; >> + >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_PLL0_OUT, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _jh7110_pll("pll0_out", "osc", (void __iomem *)addr, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 priv->reg, &starfive_jh7110_pll0)= ); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_PLL1_OUT, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _jh7110_pll("pll1_out", "osc", (void __iomem *)addr, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 priv->reg, &starfive_jh7110_pll1)= ); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_PLL2_OUT, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _jh7110_pll("pll2_out", "osc", (void __iomem *)addr, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 priv->reg, &starfive_jh7110_pll2)= ); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_CPU_ROOT, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_mux(priv->reg, "cpu_root", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_CPU_ROOT), 1, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 cpu_root_sels, ARRAY_SIZE(cpu_root_sels))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_CPU_CORE, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "cpu_core", "cpu_root", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_CPU_CO= RE), 3)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_CPU_BUS, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "cpu_bus", "cpu_core", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_CPU_BU= S), 2)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_GMACUSB_ROOT, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_fix_factor(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmacusb_= root", "pll0_out", 1, 1)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_PERH_ROOT, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_composite(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "perh_root", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 perh_root_sels,= ARRAY_SIZE(perh_root_sels), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_S= YSCLK_PERH_ROOT), 1, 0, 2)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_BUS_ROOT, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_mux(priv->reg, "bus_root", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_BUS_ROOT), 1, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 bus_root_sels,=C2=A0=C2=A0=C2=A0 ARRAY_SIZE(bus_roo= t_sels))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_AXI_CFG0, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "axi_cfg0", "bus_root", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_AXI_CF= G0), 2)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_STG_AXIAHB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "stg_axiahb", "axi_cfg0", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_STG_AX= IAHB), 2)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_AHB0, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "ahb0", "stg_axiahb", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_AHB0))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_AHB1, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "ahb1", "stg_axiahb", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_AHB1))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_APB_BUS_FUNC, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "apb_bus_func", "stg_axiahb= ", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_APB_BU= S_FUNC), 4)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_PCLK2_MUX_FUNC, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_fix_factor(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "pclk2_mu= x_func", "apb_bus_func", 1, 1)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_PCLK2_MUX, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_fix_factor(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "pclk2_mu= x", "pclk2_mux_func", 1, 1)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_APB_BUS, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_fix_factor(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "apb_bus"= , "pclk2_mux", 1, 1)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_APB0, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "apb0", "apb_bus", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_APB0))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_APB12, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_fix_factor(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "apb12", = "apb_bus", 1, 1)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_AON_APB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_fix_factor(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "aon_apb"= , "apb_bus_func", 1, 1)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_QSPI_AHB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "qspi_ahb", "ahb1", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_QSPI_AHB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_QSPI_APB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "qspi_apb", "apb12", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_QSPI_APB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_QSPI_REF_SRC, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "qspi_ref_src", "gmacusb_ro= ot", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_QSPI_R= EF_SRC), 5)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_QSPI_REF, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_composite(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "qspi_ref", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 qspi_ref_sels, = ARRAY_SIZE(qspi_ref_sels), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_S= YSCLK_QSPI_REF), 1, 1, 0)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_SDIO0_AHB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "sdio0_ahb", "ahb0", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_SDIO0_AHB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_SDIO1_AHB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "sdio1_ahb", "ahb0", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_SDIO1_AHB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_SDIO0_SDCARD, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_fix_parent_composite(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= "sdio0_sdcard", "axi_cfg0", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= OFFSET(JH7110_SYSCLK_SDIO0_SDCARD), 0, 1, 4)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_SDIO1_SDCARD, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_fix_parent_composite(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= "sdio1_sdcard", "axi_cfg0", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= OFFSET(JH7110_SYSCLK_SDIO1_SDCARD), 0, 1, 4)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_USB_125M, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "usb_125m", "gmacusb_root", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_USB_12= 5M), 4)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_GMAC1_AHB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac1_ahb", "ahb0", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_GMAC1_AHB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_GMAC1_AXI, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac1_axi", "stg_axiahb", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_GMAC1_AXI))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_GMAC_SRC, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac_src", "gmacusb_root", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_GMAC_S= RC), 3)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_GMAC1_GTXCLK, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac1_gtxclk", "gmacusb_ro= ot", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_GMAC1_= GTXCLK), 4)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_GMAC1_GTXC, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac1_gtxc", "gmac1_gtxclk", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_GMAC1_GTXC))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_GMAC1_RMII_RTX, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac1_rmii_rtx", "gmac1_rm= ii_refin", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_GMAC1_= RMII_RTX), 5)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_GMAC1_PTP, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac1_ptp", "gmac_sr= c", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_= GMAC1_PTP), 5)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_GMAC1_TX, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_composite(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac1_tx", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 gmac1_tx_sels, = ARRAY_SIZE(gmac1_tx_sels), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_S= YSCLK_GMAC1_TX), 1, 1, 0)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_AON_AHB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_fix_factor(priv->reg, "aon_ahb", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "stg_axia= hb", 1, 1)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_GMAC0_GTXCLK, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac0_gtxclk", "gmac= usb_root", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_= GMAC0_GTXCLK), 4)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_GMAC0_PTP, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac0_ptp", "gmac_sr= c", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_= GMAC0_PTP), 5)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_GMAC0_GTXC, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac0_gtxc", "gmac0_gtxclk", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_GMAC0_GTXC))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_UART0_APB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "uart0_apb", "apb0", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_UART0_APB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_UART0_CORE, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "uart0_core", "osc", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_UART0_CORE))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_UART1_APB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "uart1_apb", "apb0", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_UART1_APB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_UART1_CORE, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "uart1_core", "osc", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_UART1_CORE))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_UART2_APB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "uart2_apb", "apb0", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_UART2_APB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_UART2_CORE, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "uart2_core", "osc", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_UART2_CORE))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_UART3_APB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "uart3_apb", "apb0", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_UART3_APB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_UART3_CORE, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "uart3_core", "perh_r= oot", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_= UART3_CORE), 8)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_UART4_APB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "uart4_apb", "apb0", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_UART4_APB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_UART4_CORE, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "uart4_core", "perh_r= oot", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_= UART4_CORE), 8)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_UART5_APB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "uart5_apb", "apb0", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_UART5_APB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_UART5_CORE, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "uart5_core", "perh_r= oot", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_= UART5_CORE), 8)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_I2C5_APB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "i2c5_apb", "apb12", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 OFFSET(JH7110_SYSCLK_I2C5_APB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_SYSCLK_I2C5_CORE, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_fix_factor(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "i2c5_cor= e", "i2c5_apb", 1, 1)); >> + >> +=C2=A0=C2=A0=C2=A0 return 0; >> +} >=20 > Last time you said that these had to be probed in a particular order. > If that is the case, you need to enforce it. An easy way is to get the > clock parents (which are in your device tree but not used by this > driver), which will ensure that the parent gets probed. >=20 >> +static int jh7110_aoncrg_init(struct udevice *dev) >> +{ >> +=C2=A0=C2=A0=C2=A0 struct jh7110_clk_priv *priv =3D dev_get_priv(dev)= ; >> + >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_AONCLK_GMAC0_AHB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac0_ahb", "aon_ahb", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 AONOFFSET(JH7110_AONCLK_GMAC0_AHB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_AONCLK_GMAC0_AXI, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac0_axi", "aon_ahb", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 AONOFFSET(JH7110_AONCLK_GMAC0_AXI))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_AONCLK_GMAC0_RMII_RTX, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac0_rmii_rtx", "gmac0_rm= ii_refin", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 AONOFFSET(JH7110_AONCLK_GMA= C0_RMII_RTX), 5)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_AONCLK_GMAC0_TX, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_composite(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "gmac0_tx", gma= c0_tx_sels, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ARRAY_SIZE(gmac= 0_tx_sels), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 AONOFFSET(JH711= 0_AONCLK_GMAC0_TX), 1, 1, 0)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_AONCLK_OTPC_APB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "otpc_apb", "aon_apb", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 AONOFFSET(JH7110_AONCLK_OTPC_APB))); >> + >> +=C2=A0=C2=A0=C2=A0 return 0; >> +} >> + >> +static int jh7110_stgcrg_init(struct udevice *dev) >> +{ >> +=C2=A0=C2=A0=C2=A0 struct jh7110_clk_priv *priv =3D dev_get_priv(dev)= ; >> + >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_STGCLK_STG_APB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_fix_factor(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "stg_apb"= , "apb_bus", 1, 1)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_STGCLK_USB_APB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "usb_apb", "stg_apb", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 STGOFFSET(JH7110_STGCLK_USB_APB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_STGCLK_USB_UTMI_APB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "usb_utmi_apb", "stg_apb", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 STGOFFSET(JH7110_STGCLK_USB_UTMI_APB))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_STGCLK_USB_AXI, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "usb_axi", "stg_axiahb", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 STGOFFSET(JH7110_STGCLK_USB_AXI))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_STGCLK_USB_LPM, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "usb_lpm", "osc", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 STGOFFSET(JH7110_STGC= LK_USB_LPM), 2)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_STGCLK_USB_STB, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate_divider(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "usb_stb", "osc", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 STGOFFSET(JH7110_STGC= LK_USB_STB), 3)); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_STGCLK_USB_APP_125, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_gate(priv->reg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 "usb_app_125", "usb_125m", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 STGOFFSET(JH7110_STGCLK_USB_APP_125))); >> +=C2=A0=C2=A0=C2=A0 clk_dm(JH7110_STGCLK_USB_REFCLK, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 starfive= _clk_divider(priv->reg, "usb_refclk", "osc", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 STGOFFSET(JH7110_STGCLK_USB= _REFCLK), 2)); >> +=C2=A0=C2=A0=C2=A0 return 0; >> +} >> + >> +static int jh7110_clk_probe(struct udevice *dev) >> +{ >> +=C2=A0=C2=A0=C2=A0 struct jh7110_clk_priv *priv =3D dev_get_priv(dev)= ; >> + >> +=C2=A0=C2=A0=C2=A0 priv->init =3D (jh1710_init_fn)dev_get_driver_data= (dev); >> +=C2=A0=C2=A0=C2=A0 priv->reg =3D=C2=A0 (void __iomem *)dev_read_addr_= ptr(dev); >> + >> +=C2=A0=C2=A0=C2=A0 if (priv->init) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return priv->init(dev); >> + >> +=C2=A0=C2=A0=C2=A0 return 0; >> +} >> + >> +static int jh7110_clk_bind(struct udevice *dev) >> +{ >> +=C2=A0=C2=A0=C2=A0 /* The reset driver does not have a device node, s= o bind it here */ >> +=C2=A0=C2=A0=C2=A0 return device_bind_driver_to_node(dev, "jh7110_res= et", dev->name, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 dev_ofnode(dev), NULL); >=20 > This will get called for syscrg, stgcrg, and aoncrg. Is that > intentional? >=20 All resets control and clocks control share the same base address, so res= et control does not=20 have an independent device tree node, and shares a device tree node with = clock control.=20 JH7110 is designed in this way and cannot be modified temporarily. >> +} >> + >> +static const struct udevice_id jh7110_clk_of_match[] =3D { >> +=C2=A0=C2=A0=C2=A0 { .compatible =3D "starfive,jh7110-syscrg", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 .data =3D (ulong)&jh7110_syscrg_init >> +=C2=A0=C2=A0=C2=A0 }, >> +=C2=A0=C2=A0=C2=A0 { .compatible =3D "starfive,jh7110-stgcrg", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 .data =3D (ulong)&jh7110_stgcrg_init >> +=C2=A0=C2=A0=C2=A0 }, >> +=C2=A0=C2=A0=C2=A0 { .compatible =3D "starfive,jh7110-aoncrg", >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 .data =3D (ulong)&jh7110_aoncrg_init >> +=C2=A0=C2=A0=C2=A0 }, >> +=C2=A0=C2=A0=C2=A0 { } >> +}; >> + >> +U_BOOT_DRIVER(jh7110_clk) =3D { >> +=C2=A0=C2=A0=C2=A0 .name =3D "jh7110_clk", >> +=C2=A0=C2=A0=C2=A0 .id =3D UCLASS_CLK, >> +=C2=A0=C2=A0=C2=A0 .of_match =3D jh7110_clk_of_match, >> +=C2=A0=C2=A0=C2=A0 .probe =3D jh7110_clk_probe, >> +=C2=A0=C2=A0=C2=A0 .ops =3D &ccf_clk_ops, >> +=C2=A0=C2=A0=C2=A0 .priv_auto =3D sizeof(struct jh7110_clk_priv), >> +=C2=A0=C2=A0=C2=A0 .bind=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =3D= jh7110_clk_bind, >> +}; >> diff --git a/drivers/clk/starfive/clk.h b/drivers/clk/starfive/clk.h >> new file mode 100644 >> index 0000000000..eb158e6517 >> --- /dev/null >> +++ b/drivers/clk/starfive/clk.h >> @@ -0,0 +1,60 @@ >> +/* SPDX-License-Identifier: GPL-2.0+ */ >> +/* >> + * Copyright (C) 2022 Starfive, Inc. >> + * Author:=C2=A0=C2=A0=C2=A0 Yanhong Wang >> + * >> + */ >> + >> +#ifndef __CLK_STARFIVE_H >> +#define __CLK_STARFIVE_H >> + >> +enum starfive_pll_type { >> +=C2=A0=C2=A0=C2=A0 PLL0 =3D 0, >> +=C2=A0=C2=A0=C2=A0 PLL1, >> +=C2=A0=C2=A0=C2=A0 PLL2, >> +=C2=A0=C2=A0=C2=A0 PLL_MAX =3D PLL2 >> +}; >> + >> +struct starfive_pllx_rate { >> +=C2=A0=C2=A0=C2=A0 u64 rate; >> +=C2=A0=C2=A0=C2=A0 u32 prediv; >> +=C2=A0=C2=A0=C2=A0 u32 fbdiv; >> +=C2=A0=C2=A0=C2=A0 u32 frac; >> +=C2=A0=C2=A0=C2=A0 u32 postdiv1; >> +=C2=A0=C2=A0=C2=A0 u32 dacpd; >> +=C2=A0=C2=A0=C2=A0 u32 dsmpd; >> +}; >> + >> +struct starfive_pllx_offset { >> +=C2=A0=C2=A0=C2=A0 u32 pd; >> +=C2=A0=C2=A0=C2=A0 u32 prediv; >> +=C2=A0=C2=A0=C2=A0 u32 fbdiv; >> +=C2=A0=C2=A0=C2=A0 u32 frac; >> +=C2=A0=C2=A0=C2=A0 u32 postdiv1; >> +=C2=A0=C2=A0=C2=A0 u32 dacpd; >> +=C2=A0=C2=A0=C2=A0 u32 dsmpd; >> +=C2=A0=C2=A0=C2=A0 u32 pd_mask; >> +=C2=A0=C2=A0=C2=A0 u32 prediv_mask; >> +=C2=A0=C2=A0=C2=A0 u32 fbdiv_mask; >> +=C2=A0=C2=A0=C2=A0 u32 frac_mask; >> +=C2=A0=C2=A0=C2=A0 u32 postdiv1_mask; >> +=C2=A0=C2=A0=C2=A0 u32 dacpd_mask; >> +=C2=A0=C2=A0=C2=A0 u32 dsmpd_mask; >> +}; >> + >> +struct starfive_pllx_clk { >> +=C2=A0=C2=A0=C2=A0 enum starfive_pll_type type; >> +=C2=A0=C2=A0=C2=A0 const struct starfive_pllx_offset *offset; >> +=C2=A0=C2=A0=C2=A0 const struct starfive_pllx_rate *rate_table; >> +=C2=A0=C2=A0=C2=A0 int rate_count; >> +=C2=A0=C2=A0=C2=A0 int flags; >> +}; >> + >> +extern struct starfive_pllx_clk starfive_jh7110_pll0; >> +extern struct starfive_pllx_clk starfive_jh7110_pll1; >> +extern struct starfive_pllx_clk starfive_jh7110_pll2; >> + >> +struct clk *starfive_jh7110_pll(const char *name, const char *parent_= name, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 void __iomem *base, void __iomem *sysreg, >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 const struct starfive_pllx_clk *pll_clk); >> +#endif >=20