U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Yixun Lan <dlan@kernel.org>
To: Junhui Liu <junhui.liu@pigmoral.tech>
Cc: Guodong Xu <guodong@riscstar.com>,
	Heiko Schocher <hs@nabladev.com>,
	u-boot-spacemit@groups.io, u-boot@lists.u-boot-project.org,
	Huan Zhou <pericycle.cc@gmail.com>,
	Guodong Xu <guodong.xu@riscstar.com>,
	Tom Rini <trini@konsulko.com>,
	Raymond Mao <raymond.mao@riscstar.com>,
	Lukasz Majewski <lukma@denx.de>,
	Troy Mitchell <troy.mitchell@linux.spacemit.com>
Subject: Re: [PATCH 2/2] i2c: k1: enable all clocks for I2C controllers
Date: Fri, 14 Aug 2026 08:38:00 +0000	[thread overview]
Message-ID: <20260814083800-GKA318749@kernel.org> (raw)
In-Reply-To: <20260814-k1-i2c-fix-v1-2-f2e19cbe0af6@pigmoral.tech>

On 09:46 Fri 14 Aug     , Junhui Liu wrote:
> The K1 clock driver modeled the bus clock enable bit as part of the
> functional clock for regular TWSI controllers. The I2C driver then only
> enabled the functional clock, ignoring the separate bus clock described
> by the device tree. Although this happened to work, it did not match the
> hardware clock topology or the device tree binding.
> 
> Model the functional and bus clocks separately and make the I2C driver
> acquire and enable all clocks provided by the device tree. Also add the
> TWSI2 and TWSI8 bus clocks, together with their APB clock dependencies,
> to the SPL clock tree.
> 
> Keep the combined functional and bus gate for TWSI8, whose clock control
> register is write-only, and retain its bus clock as a fixed-factor
> placeholder.
> 
> The clock-provider and I2C-consumer changes should be applied together,
> as either change on its own would leave I2C unusable.
> 
> Fixes: 3aa2882a3e1a ("clk: spacemit: Add support for K1 SoC")
> Fixes: 271546fb8e54 ("i2c: k1: add I2C driver support")
> Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
> ---
>  drivers/clk/spacemit/clk-k1.c | 41 +++++++++++++++++++++++++++++++++--------
>  drivers/i2c/k1_i2c.c          | 10 ++++------
I'd suggest to have separate patch for clock and i2c changes, as they
belong to different subsystem

>  2 files changed, 37 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/clk/spacemit/clk-k1.c b/drivers/clk/spacemit/clk-k1.c
> index 07adc126ee39..20b8595aa3c4 100644
> --- a/drivers/clk/spacemit/clk-k1.c
> +++ b/drivers/clk/spacemit/clk-k1.c
> @@ -154,11 +154,27 @@ CCU_GATE_DEFINE(CLK_PLL1_409P6, pll1_d6_409p6, pll1_d6_409p6, "pll1_d6",
>  		MPMU_ACGR, BIT(0), 0);
>  CCU_GATE_DEFINE(CLK_PLL1_307P2, pll1_d8_307p2, pll1_d8_307p2, "pll1_d8",
>  		MPMU_ACGR, BIT(13), 0);
> +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_102P4, pll1_d24_102p4, pll1_d24_102p4,
> +		       "pll1_d8", MPMU_ACGR, BIT(12), 3, 1);
> +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_51P2, pll1_d48_51p2, pll1_d48_51p2,
> +		       "pll1_d8", MPMU_ACGR, BIT(7), 6, 1);
> +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_25P6, pll1_d96_25p6, pll1_d96_25p6,
> +		       "pll1_d8", MPMU_ACGR, BIT(4), 12, 1);
>  CCU_FACTOR_GATE_DEFINE(CLK_PLL1_31P5, pll1_d78_31p5, pll1_d78_31p5,
>  		       "pll1_d4", MPMU_ACGR, BIT(6), 39, 2);
>  CCU_DDN_DEFINE(CLK_SLOW_UART2, slow_uart2_48, slow_uart2_48,
>  	       "pll1_d4_614p4", MPMU_SUCCR_1,
>  	       CCU_DDN_MASK(16, 13), 16, CCU_DDN_MASK(0, 13), 0, 2, 0);
> +
> +static const char * const apb_parents[] = {
> +	"pll1_d96_25p6",
> +	"pll1_d48_51p2",
> +	"pll1_d96_25p6",
> +	"pll1_d24_102p4",
> +};
> +
> +CCU_MUX_DEFINE(CLK_APB, apb_clk, apb_clk, apb_parents, ARRAY_SIZE(apb_parents),
> +	       MPMU_APBCSCR, 0, 2, 0);
>  #else
>  CCU_GATE_DEFINE(CLK_PLL1_307P2, pll1_d8_307p2, pll1_d8_307p2, "pll1_d8",
>  		MPMU_ACGR, BIT(13), 0);
> @@ -298,7 +314,7 @@ static const char * const twsi_parents[] = {
>  
>  CCU_MUX_GATE_DEFINE(CLK_TWSI2, twsi2_clk, twsi2_clk, twsi_parents,
>  		    ARRAY_SIZE(twsi_parents), APBC_TWSI2_CLK_RST,
> -		    4, 3, BIT(1) | BIT(0), 0);
> +		    4, 3, BIT(1), 0);
>  /*
>   * APBC_TWSI8_CLK_RST has a quirk that reading always results in zero.
>   * Combine functional and bus bits together as a gate to avoid sharing the
> @@ -306,6 +322,9 @@ CCU_MUX_GATE_DEFINE(CLK_TWSI2, twsi2_clk, twsi2_clk, twsi_parents,
>   */
>  CCU_GATE_DEFINE(CLK_TWSI8, twsi8_clk, twsi8_clk, "pll1_d78_31p5",
>  		APBC_TWSI8_CLK_RST, BIT(1) | BIT(0), 0);
> +CCU_GATE_DEFINE(CLK_TWSI2_BUS, twsi2_bus_clk, twsi2_bus_clk, "apb_clk",
> +		APBC_TWSI2_CLK_RST, BIT(0), 0);
> +CCU_FACTOR_DEFINE(CLK_TWSI8_BUS, twsi8_bus_clk, twsi8_bus_clk, "apb_clk", 1, 1);
>  
>  #else
>  static const char * const uart_clk_parents[] = {
> @@ -326,7 +345,7 @@ static const char * const twsi_parents[] = {
>  
>  CCU_MUX_GATE_DEFINE(CLK_TWSI2, twsi2_clk, twsi2_clk, twsi_parents,
>  		    ARRAY_SIZE(twsi_parents), APBC_TWSI2_CLK_RST,
> -		    4, 3, BIT(1) | BIT(0), 0);
> +		    4, 3, BIT(1), 0);
>  /*
>   * APBC_TWSI8_CLK_RST has a quirk that reading always results in zero.
>   * Combine functional and bus bits together as a gate to avoid sharing the
> @@ -448,22 +467,22 @@ CCU_GATE_DEFINE(CLK_RTC, rtc_clk, rtc_clk, "clock-32k", APBC_RTC_CLK_RST,
>  
>  CCU_MUX_GATE_DEFINE(CLK_TWSI0, twsi0_clk, twsi0_clk, twsi_parents,
>  		    ARRAY_SIZE(twsi_parents), APBC_TWSI0_CLK_RST,
> -		    4, 3, BIT(1) | BIT(0), 0);
> +		    4, 3, BIT(1), 0);
>  CCU_MUX_GATE_DEFINE(CLK_TWSI1, twsi1_clk, twsi1_clk, twsi_parents,
>  		    ARRAY_SIZE(twsi_parents), APBC_TWSI1_CLK_RST,
> -		    4, 3, BIT(1) | BIT(0), 0);
> +		    4, 3, BIT(1), 0);
>  CCU_MUX_GATE_DEFINE(CLK_TWSI4, twsi4_clk, twsi4_clk, twsi_parents,
>  		    ARRAY_SIZE(twsi_parents), APBC_TWSI4_CLK_RST,
> -		    4, 3, BIT(1) | BIT(0), 0);
> +		    4, 3, BIT(1), 0);
>  CCU_MUX_GATE_DEFINE(CLK_TWSI5, twsi5_clk, twsi5_clk, twsi_parents,
>  		    ARRAY_SIZE(twsi_parents), APBC_TWSI5_CLK_RST,
> -		    4, 3, BIT(1) | BIT(0), 0);
> +		    4, 3, BIT(1), 0);
>  CCU_MUX_GATE_DEFINE(CLK_TWSI6, twsi6_clk, twsi6_clk, twsi_parents,
>  		    ARRAY_SIZE(twsi_parents), APBC_TWSI6_CLK_RST,
> -		    4, 3, BIT(1) | BIT(0), 0);
> +		    4, 3, BIT(1), 0);
>  CCU_MUX_GATE_DEFINE(CLK_TWSI7, twsi7_clk, twsi7_clk, twsi_parents,
>  		    ARRAY_SIZE(twsi_parents), APBC_TWSI7_CLK_RST,
> -		    4, 3, BIT(1) | BIT(0), 0);
> +		    4, 3, BIT(1), 0);
>  
>  static const char * const timer_parents[] = {
>  	"pll1_d192_12p8",
> @@ -1232,8 +1251,12 @@ static struct clk *k1_ccu_mpmu_clks[] = {
>  	&pll1_d4_614p4.common.clk,
>  	&pll1_d6_409p6.common.clk,
>  	&pll1_d8_307p2.common.clk,
> +	&pll1_d24_102p4.common.clk,
> +	&pll1_d48_51p2.common.clk,
> +	&pll1_d96_25p6.common.clk,
>  	&pll1_d78_31p5.common.clk,
>  	&slow_uart2_48.common.clk,
> +	&apb_clk.common.clk,
>  };
>  #else
>  static struct clk *k1_ccu_mpmu_clks[] = {
> @@ -1288,6 +1311,8 @@ static struct clk *k1_ccu_apbc_clks[] = {
>  	&uart0_clk.common.clk,
>  	&twsi2_clk.common.clk,
>  	&twsi8_clk.common.clk,
> +	&twsi2_bus_clk.common.clk,
> +	&twsi8_bus_clk.common.clk,
>  };
>  #else
>  static struct clk *k1_ccu_apbc_clks[] = {
> diff --git a/drivers/i2c/k1_i2c.c b/drivers/i2c/k1_i2c.c
> index 2c7a1e0d3775..b11f73959a08 100644
> --- a/drivers/i2c/k1_i2c.c
> +++ b/drivers/i2c/k1_i2c.c
> @@ -51,7 +51,7 @@ struct k1_i2c {
>  struct k1_i2c_priv {
>  	int id;
>  	void __iomem *base;
> -	struct clk clk;
> +	struct clk_bulk clks;
>  };
>  
>  /*
> @@ -487,15 +487,13 @@ static int k1_i2c_probe(struct udevice *bus)
>  		return ret;
>  	}
>  
> -	ret = clk_get_by_index(bus, 0, &priv->clk);
> +	ret = clk_get_bulk(bus, &priv->clks);
>  	if (ret)
>  		return ret;
>  
> -	ret = clk_enable(&priv->clk);
> -	if (ret && ret != -ENOSYS && ret != -EOPNOTSUPP) {
> -		debug("%s: failed to enable clock\n", __func__);
> +	ret = clk_enable_bulk(&priv->clks);
I'd suggest to not use bulk api, to align with k1 i2c kernel driver,
also to make it easy to set func frequency if needed (a weak reason)

> +	if (ret)
>  		return ret;
> -	}
>  
>  	priv->base = (void *)devfdt_get_addr_ptr(bus);
>  
> 
> -- 
> 2.55.0
> 

-- 
Yixun Lan (dlan)

      reply	other threads:[~2026-08-14 12:46 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-14  1:46 [PATCH 0/2] i2c/clk: spacemit: k1: fix bus configuration and clock handling Junhui Liu
2026-08-14  1:46 ` [PATCH 1/2] i2c: k1: fix wrong bus speed setting Junhui Liu
2026-08-14  9:32   ` Heiko Schocher via U-Boot
2026-08-14  1:46 ` [PATCH 2/2] i2c: k1: enable all clocks for I2C controllers Junhui Liu
2026-08-14  8:38   ` Yixun Lan [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260814083800-GKA318749@kernel.org \
    --to=dlan@kernel.org \
    --cc=guodong.xu@riscstar.com \
    --cc=guodong@riscstar.com \
    --cc=hs@nabladev.com \
    --cc=junhui.liu@pigmoral.tech \
    --cc=lukma@denx.de \
    --cc=pericycle.cc@gmail.com \
    --cc=raymond.mao@riscstar.com \
    --cc=trini@konsulko.com \
    --cc=troy.mitchell@linux.spacemit.com \
    --cc=u-boot-spacemit@groups.io \
    --cc=u-boot@lists.u-boot-project.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox