From patchwork Mon Feb 17 10:52:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Bultel X-Patchwork-Id: 13977569 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 16BB12163B6; Mon, 17 Feb 2025 10:54:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739789679; cv=none; b=FAVSrpQgVtR6OCKNlSArhP6nuVjrJ6uWGNdpEq2xuCrpyMVcpnbpWOGkoCDz7mau19FvKOBg/9BT32azBbutlBX1qeKHCS2CTZjtTC0siyysIKoCW6k/SS7vMkOLP0L78xQjx9t7RvhMcZMbqiEEJypZEImFKq/e7zN1bwr1TAY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739789679; c=relaxed/simple; bh=aZTht+TSWw8f5DrTjGvycp3e+AZMQiHqsfpC/jdp7d4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gK5ZjrxbwBEz3IZX4vR8vZpNMoRmkglT6ZCSmfCb9sdn1OAoAbymE9b8FaOrjWZncFRhDkd2qD8HO/Y7226lLZXIwddX0uCXyeH61TDtzAPaoWkbOVdyODhIo2FyeoVasEKxZn5Lu4262MFnKge3inDJI3AIQq/wkzGt44OeYG8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: PD6Kg1XiQ3u0mN2pRoz2YA== X-CSE-MsgGUID: O1J+Ij7FQKiQapk+JOdWEg== Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 17 Feb 2025 19:54:30 +0900 Received: from superbuilder.administration.lan (unknown [10.226.93.254]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id E44BB428055E; Mon, 17 Feb 2025 19:54:25 +0900 (JST) From: Thierry Bultel To: thierry.bultel@linatsea.fr, Geert Uytterhoeven , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Magnus Damm Cc: linux-renesas-soc@vger.kernel.org, Thierry Bultel , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 02/13] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC Date: Mon, 17 Feb 2025 11:52:03 +0100 Message-ID: <20250217105354.551788-3-thierry.bultel.yh@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250217105354.551788-1-thierry.bultel.yh@bp.renesas.com> References: <20250217105354.551788-1-thierry.bultel.yh@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Document RZ/T2H (a.k.a r9a09g077) cpg-mssr (Clock Pulse Generator) binding. Signed-off-by: Thierry Bultel --- .../bindings/clock/renesas,cpg-mssr.yaml | 1 + .../dt-bindings/clock/r9a09g077-cpg-mssr.h | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 include/dt-bindings/clock/r9a09g077-cpg-mssr.h diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml index 77ce3615c65a..5649dee7178a 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml @@ -52,6 +52,7 @@ properties: - renesas,r8a779f0-cpg-mssr # R-Car S4-8 - renesas,r8a779g0-cpg-mssr # R-Car V4H - renesas,r8a779h0-cpg-mssr # R-Car V4M + - renesas,r9a09g077-cpg-mssr # RZ/T2H reg: maxItems: 1 diff --git a/include/dt-bindings/clock/r9a09g077-cpg-mssr.h b/include/dt-bindings/clock/r9a09g077-cpg-mssr.h new file mode 100644 index 000000000000..27c9cdcdf7c8 --- /dev/null +++ b/include/dt-bindings/clock/r9a09g077-cpg-mssr.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + * + * Copyright (C) 2025 Renesas Electronics Corp. + */ + +#ifndef __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__ +#define __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__ + +#include + +/* R9A09G077 CPG Core Clocks */ +#define R9A09G077_CA55C0 0 +#define R9A09G077_CA55C1 1 +#define R9A09G077_CA55C2 2 +#define R9A09G077_CA55C3 3 +#define R9A09G077_SDHIHS 4 +#define R9A09G077_CLK_PLL1_ETH_PHY 5 +#define R9A09G077_CLK_OSC_ETH_PHY 6 +#define R9A09G077_CLK_ETHPHY 7 +#define R9A09G077_PCLKAH 8 +#define R9A09G077_PCLKAM 9 +#define R9A09G077_PCLKAL 10 +#define R9A09G077_CLK_SEL_ETH_PHY 11 +#define R9A09G077_DFI 12 +#define R9A09G077_PCLKH 13 +#define R9A09G077_PCLKM 14 +#define R9A09G077_PCLKL 15 +#define R9A09G077_PCLKGPTL 16 +#define R9A09G077_PCLKSHOST 17 +#define R9A09G077_PCLKRTC 18 +#define R9A09G077_USB 19 +#define R9A09G077_SPI0 20 +#define R9A09G077_SPI1 21 +#define R9A09G077_SPI2 22 +#define R9A09G077_SPI3 23 +#define R9A09G077_ETCLKA 24 +#define R9A09G077_ETCLKB 25 +#define R9A09G077_ETCLKC 26 +#define R9A09G077_ETCLKD 27 +#define R9A09G077_ETCLKE 28 +#define R9A09G077_ETHCLKE 29 +#define R9A09G077_ETHCLK_EXTAL 30 +#define R9A09G077_ETH_REFCLK 31 +#define R9A09G077_LCDC_CLKA 32 +#define R9A09G077_LCDC_CLKP 33 +#define R9A09G077_CA55 34 +#define R9A09G077_LCDC_CLKD 35 + +#endif /* __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__ */ From patchwork Mon Feb 17 10:52:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Bultel X-Patchwork-Id: 13977570 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by smtp.subspace.kernel.org (Postfix) with ESMTP id AC348216E1B; Mon, 17 Feb 2025 10:54:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739789690; cv=none; b=RrkO0Ys2BgoxjcvUKNT5/VCqhbi1qXMeMVz6gwH9AfDxU/W5n/OzRQuf41ub49Kp7h+wDUjhQPIOP9CTmOw+D/JstLh2s+CAVaz0EEsl0+iUvSLVq7vVlI1x/OskPJk54YaYQ3bL0HpMS2uMXvvXz8BlVuPoqCcPMQFnR1qXdhc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739789690; c=relaxed/simple; bh=Qsh0HwY5lyjr/noq6U5vgQKLnX1x4QbYJggrRouwLWA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lGWQk7HRFTOvIoM3k1pB5q1FdZnZDDVi5NdmeQRGSPWjrQD6TMtSyvKpA6eLjcJoUfA8LmD4GOqparUtpcy/96NUs+yjAmrIdIzNryQSIBz/0acvwoI8FimevwlD2ZaRCSHaQB4kqmI65RIzAqrP72cbRDWZsUcCD8Ycq6duIig= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: cKSNU2XRTYuNVDM0ZJfr5g== X-CSE-MsgGUID: B9sxQNFhRj+GWMG4Gfg3Lg== Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 17 Feb 2025 19:54:47 +0900 Received: from superbuilder.administration.lan (unknown [10.226.93.254]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id A11D1428055D; Mon, 17 Feb 2025 19:54:44 +0900 (JST) From: Thierry Bultel To: thierry.bultel@linatsea.fr, Geert Uytterhoeven , Michael Turquette , Stephen Boyd Cc: linux-renesas-soc@vger.kernel.org, Thierry Bultel , linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 05/13] clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register Date: Mon, 17 Feb 2025 11:52:06 +0100 Message-ID: <20250217105354.551788-6-thierry.bultel.yh@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250217105354.551788-1-thierry.bultel.yh@bp.renesas.com> References: <20250217105354.551788-1-thierry.bultel.yh@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 In a coming evolution, the registration callback will need more parameters from cpg_mssr_priv (like another base address with clock controllers with double register block). Instead of adding more parameters, mode the needed parameters to a public sub-struct. --- drivers/clk/renesas/r7s9210-cpg-mssr.c | 7 +- drivers/clk/renesas/r8a77970-cpg-mssr.c | 11 +-- drivers/clk/renesas/rcar-gen3-cpg.c | 8 +- drivers/clk/renesas/rcar-gen3-cpg.h | 6 +- drivers/clk/renesas/rcar-gen4-cpg.c | 9 ++- drivers/clk/renesas/rcar-gen4-cpg.h | 3 +- drivers/clk/renesas/renesas-cpg-mssr.c | 99 +++++++++++++------------ drivers/clk/renesas/renesas-cpg-mssr.h | 21 +++++- 8 files changed, 93 insertions(+), 71 deletions(-) diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c index a85227c248f3..733244687daa 100644 --- a/drivers/clk/renesas/r7s9210-cpg-mssr.c +++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c @@ -159,12 +159,13 @@ static void __init r7s9210_update_clk_table(struct clk *extal_clk, static struct clk * __init rza2_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers) + struct cpg_mssr_pub *pub) { - struct clk *parent; + void __iomem *base = pub->base0; + struct clk **clks = pub->clks; unsigned int mult = 1; unsigned int div = 1; + struct clk *parent; parent = clks[core->parent]; if (IS_ERR(parent)) diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c index 3cec0f501b94..c50aa1a49196 100644 --- a/drivers/clk/renesas/r8a77970-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c @@ -218,11 +218,13 @@ static int __init r8a77970_cpg_mssr_init(struct device *dev) } static struct clk * __init r8a77970_cpg_clk_register(struct device *dev, - const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers) + const struct cpg_core_clk *core, + const struct cpg_mssr_info *info, + struct cpg_mssr_pub *pub) { const struct clk_div_table *table; + void __iomem *base = pub->base0; + struct clk **clks = pub->clks; const struct clk *parent; unsigned int shift; @@ -236,8 +238,7 @@ static struct clk * __init r8a77970_cpg_clk_register(struct device *dev, shift = 4; break; default: - return rcar_gen3_cpg_clk_register(dev, core, info, clks, base, - notifiers); + return rcar_gen3_cpg_clk_register(dev, core, info, pub); } parent = clks[core->parent]; diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 027100e84ee4..aafeb139fdb4 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -345,9 +345,11 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = { struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers) + struct cpg_mssr_pub *pub) { + struct raw_notifier_head *notifiers = &pub->notifiers; + void __iomem *base = pub->base0; + struct clk **clks = pub->clks; const struct clk *parent; unsigned int mult = 1; unsigned int div = 1; @@ -431,7 +433,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, } writel(value, csn->reg); - cpg_simple_notifier_register(notifiers, csn); + cpg_simple_notifier_register(&pub->notifiers, csn); break; } diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index bfdc649bdf12..6ad560fca01b 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -80,9 +80,9 @@ struct rcar_gen3_cpg_pll_config { #define CPG_RCKCR 0x240 struct clk *rcar_gen3_cpg_clk_register(struct device *dev, - const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers); + const struct cpg_core_clk *core, + const struct cpg_mssr_info *info, + struct cpg_mssr_pub *pub); int rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config, unsigned int clk_extalr, u32 mode); diff --git a/drivers/clk/renesas/rcar-gen4-cpg.c b/drivers/clk/renesas/rcar-gen4-cpg.c index 31aa790fd003..e02e49f7fcf8 100644 --- a/drivers/clk/renesas/rcar-gen4-cpg.c +++ b/drivers/clk/renesas/rcar-gen4-cpg.c @@ -418,10 +418,11 @@ static const struct clk_div_table cpg_rpcsrc_div_table[] = { struct clk * __init rcar_gen4_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers) + struct cpg_mssr_pub *pub) { const struct clk *parent; + void __iomem *base = pub->base0; + struct clk **clks = pub->clks; unsigned int mult = 1; unsigned int div = 1; u32 value; @@ -479,7 +480,7 @@ struct clk * __init rcar_gen4_cpg_clk_register(struct device *dev, case CLK_TYPE_GEN4_SDH: return cpg_sdh_clk_register(core->name, base + core->offset, - __clk_get_name(parent), notifiers); + __clk_get_name(parent), &pub->notifiers); case CLK_TYPE_GEN4_SD: return cpg_sd_clk_register(core->name, base + core->offset, @@ -517,7 +518,7 @@ struct clk * __init rcar_gen4_cpg_clk_register(struct device *dev, case CLK_TYPE_GEN4_RPC: return cpg_rpc_clk_register(core->name, base + CPG_RPCCKCR, - __clk_get_name(parent), notifiers); + __clk_get_name(parent), &pub->notifiers); case CLK_TYPE_GEN4_RPCD2: return cpg_rpcd2_clk_register(core->name, base + CPG_RPCCKCR, diff --git a/drivers/clk/renesas/rcar-gen4-cpg.h b/drivers/clk/renesas/rcar-gen4-cpg.h index 717fd148464f..6c8280b37c37 100644 --- a/drivers/clk/renesas/rcar-gen4-cpg.h +++ b/drivers/clk/renesas/rcar-gen4-cpg.h @@ -78,8 +78,7 @@ struct rcar_gen4_cpg_pll_config { struct clk *rcar_gen4_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers); + struct cpg_mssr_pub *pub); int rcar_gen4_cpg_init(const struct rcar_gen4_cpg_pll_config *config, unsigned int clk_extalr, u32 mode); diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 79e7a90c3b1b..7d5fba3aef19 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -127,7 +127,6 @@ static const u16 srstclr_for_gen4[] = { * * @rcdev: Optional reset controller entity * @dev: CPG/MSSR device - * @base: CPG/MSSR register block base address * @reg_layout: CPG/MSSR register layout * @rmw_lock: protects RMW register accesses * @np: Device node in DT for this CPG/MSSR module @@ -143,6 +142,7 @@ static const u16 srstclr_for_gen4[] = { * [].val: Saved values of SMSTPCR[] * @reserved_ids: Temporary used, reserved id list * @num_reserved_ids: Temporary used, number of reserved id list + * @pub: Data passed to clock registration callback * @clks: Array containing all Core and Module Clocks */ struct cpg_mssr_priv { @@ -150,16 +150,13 @@ struct cpg_mssr_priv { struct reset_controller_dev rcdev; #endif struct device *dev; - void __iomem *base; enum clk_reg_layout reg_layout; - spinlock_t rmw_lock; struct device_node *np; unsigned int num_core_clks; unsigned int num_mod_clks; unsigned int last_dt_core_clk; - struct raw_notifier_head notifiers; const u16 *status_regs; const u16 *control_regs; const u16 *reset_regs; @@ -172,6 +169,7 @@ struct cpg_mssr_priv { unsigned int *reserved_ids; unsigned int num_reserved_ids; + struct cpg_mssr_pub pub; struct clk *clks[]; }; @@ -205,38 +203,40 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk, enable ? "ON" : "OFF"); - spin_lock_irqsave(&priv->rmw_lock, flags); + spin_lock_irqsave(&priv->pub.rmw_lock, flags); if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { - value = readb(priv->base + priv->control_regs[reg]); + value = readb(priv->pub.base0 + priv->control_regs[reg]); if (enable) value &= ~bitmask; else value |= bitmask; - writeb(value, priv->base + priv->control_regs[reg]); + writeb(value, priv->pub.base0 + priv->control_regs[reg]); /* dummy read to ensure write has completed */ - readb(priv->base + priv->control_regs[reg]); - barrier_data(priv->base + priv->control_regs[reg]); + readb(priv->pub.base0 + priv->control_regs[reg]); + barrier_data(priv->pub.base0 + priv->control_regs[reg]); + } else { - value = readl(priv->base + priv->control_regs[reg]); + value = readl(priv->pub.base0 + priv->control_regs[reg]); if (enable) value &= ~bitmask; else value |= bitmask; - writel(value, priv->base + priv->control_regs[reg]); + writel(value, priv->pub.base0 + priv->control_regs[reg]); } - spin_unlock_irqrestore(&priv->rmw_lock, flags); + spin_unlock_irqrestore(&priv->pub.rmw_lock, flags); - if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A) + if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A || + priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) return 0; - error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg], + error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg], value, !(value & bitmask), 0, 10); if (error) dev_err(dev, "Failed to enable SMSTP %p[%d]\n", - priv->base + priv->control_regs[reg], bit); + priv->pub.base0 + priv->control_regs[reg], bit); return error; } @@ -255,12 +255,13 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) { struct mstp_clock *clock = to_mstp_clock(hw); struct cpg_mssr_priv *priv = clock->priv; + unsigned int reg = clock->index / 32; u32 value; if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) - value = readb(priv->base + priv->control_regs[clock->index / 32]); + value = readb(priv->pub.base0 + priv->control_regs[reg]); else - value = readl(priv->base + priv->status_regs[clock->index / 32]); + value = readl(priv->pub.base0 + priv->status_regs[reg]); return !(value & BIT(clock->index % 32)); } @@ -352,7 +353,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, case CLK_TYPE_DIV6P1: case CLK_TYPE_DIV6_RO: WARN_DEBUG(core->parent >= priv->num_core_clks); - parent = priv->clks[core->parent]; + parent = priv->pub.clks[core->parent]; if (IS_ERR(parent)) { clk = parent; goto fail; @@ -362,12 +363,12 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, if (core->type == CLK_TYPE_DIV6_RO) /* Multiply with the DIV6 register value */ - div *= (readl(priv->base + core->offset) & 0x3f) + 1; + div *= (readl(priv->pub.base0 + core->offset) & 0x3f) + 1; if (core->type == CLK_TYPE_DIV6P1) { clk = cpg_div6_register(core->name, 1, &parent_name, - priv->base + core->offset, - &priv->notifiers); + priv->pub.base0 + core->offset, + &priv->pub.notifiers); } else { clk = clk_register_fixed_factor(NULL, core->name, parent_name, 0, @@ -383,8 +384,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, default: if (info->cpg_clk_register) clk = info->cpg_clk_register(dev, core, info, - priv->clks, priv->base, - &priv->notifiers); + &priv->pub); else dev_err(dev, "%s has unsupported core clock type %u\n", core->name, core->type); @@ -395,7 +395,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, goto fail; dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); - priv->clks[id] = clk; + priv->pub.clks[id] = clk; return; fail: @@ -418,14 +418,14 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod, WARN_DEBUG(id < priv->num_core_clks); WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); - WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); + WARN_DEBUG(PTR_ERR(priv->pub.clks[id]) != -ENOENT); if (!mod->name) { /* Skip NULLified clock */ return; } - parent = priv->clks[mod->parent]; + parent = priv->pub.clks[mod->parent]; if (IS_ERR(parent)) { clk = parent; goto fail; @@ -627,13 +627,13 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, dev_dbg(priv->dev, "reset %u%02u\n", reg, bit); /* Reset module */ - writel(bitmask, priv->base + priv->reset_regs[reg]); + writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ udelay(35); /* Release module from reset state */ - writel(bitmask, priv->base + priv->reset_clear_regs[reg]); + writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); return 0; } @@ -647,7 +647,7 @@ static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id) dev_dbg(priv->dev, "assert %u%02u\n", reg, bit); - writel(bitmask, priv->base + priv->reset_regs[reg]); + writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); return 0; } @@ -661,7 +661,7 @@ static int cpg_mssr_deassert(struct reset_controller_dev *rcdev, dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit); - writel(bitmask, priv->base + priv->reset_clear_regs[reg]); + writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); return 0; } @@ -673,7 +673,7 @@ static int cpg_mssr_status(struct reset_controller_dev *rcdev, unsigned int bit = id % 32; u32 bitmask = BIT(bit); - return !!(readl(priv->base + priv->reset_regs[reg]) & bitmask); + return !!(readl(priv->pub.base0 + priv->reset_regs[reg]) & bitmask); } static const struct reset_control_ops cpg_mssr_reset_ops = { @@ -899,12 +899,12 @@ static int cpg_mssr_suspend_noirq(struct device *dev) if (priv->smstpcr_saved[reg].mask) priv->smstpcr_saved[reg].val = priv->reg_layout == CLK_REG_LAYOUT_RZ_A ? - readb(priv->base + priv->control_regs[reg]) : - readl(priv->base + priv->control_regs[reg]); + readb(priv->pub.base0 + priv->control_regs[reg]) : + readl(priv->pub.base0 + priv->control_regs[reg]); } /* Save core clocks */ - raw_notifier_call_chain(&priv->notifiers, PM_EVENT_SUSPEND, NULL); + raw_notifier_call_chain(&priv->pub.notifiers, PM_EVENT_SUSPEND, NULL); return 0; } @@ -921,7 +921,7 @@ static int cpg_mssr_resume_noirq(struct device *dev) return 0; /* Restore core clocks */ - raw_notifier_call_chain(&priv->notifiers, PM_EVENT_RESUME, NULL); + raw_notifier_call_chain(&priv->pub.notifiers, PM_EVENT_RESUME, NULL); /* Restore module clocks */ for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) { @@ -930,29 +930,29 @@ static int cpg_mssr_resume_noirq(struct device *dev) continue; if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) - oldval = readb(priv->base + priv->control_regs[reg]); + oldval = readb(priv->pub.base0 + priv->control_regs[reg]); else - oldval = readl(priv->base + priv->control_regs[reg]); + oldval = readl(priv->pub.base0 + priv->control_regs[reg]); newval = oldval & ~mask; newval |= priv->smstpcr_saved[reg].val & mask; if (newval == oldval) continue; if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { - writeb(newval, priv->base + priv->control_regs[reg]); + writeb(newval, priv->pub.base0 + priv->control_regs[reg]); /* dummy read to ensure write has completed */ - readb(priv->base + priv->control_regs[reg]); - barrier_data(priv->base + priv->control_regs[reg]); + readb(priv->pub.base0 + priv->control_regs[reg]); + barrier_data(priv->pub.base0 + priv->control_regs[reg]); continue; } else - writel(newval, priv->base + priv->control_regs[reg]); + writel(newval, priv->pub.base0 + priv->control_regs[reg]); /* Wait until enabled clocks are really enabled */ mask &= ~priv->smstpcr_saved[reg].val; if (!mask) continue; - error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg], + error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg], oldval, !(oldval & mask), 0, 10); if (error) dev_warn(dev, "Failed to enable SMSTP%u[0x%x]\n", reg, @@ -1062,12 +1062,13 @@ static int __init cpg_mssr_common_init(struct device *dev, if (!priv) return -ENOMEM; + priv->pub.clks = priv->clks; priv->np = np; priv->dev = dev; - spin_lock_init(&priv->rmw_lock); + spin_lock_init(&priv->pub.rmw_lock); - priv->base = of_iomap(np, 0); - if (!priv->base) { + priv->pub.base0 = of_iomap(np, 0); + if (!priv->pub.base0) { error = -ENOMEM; goto out_err; } @@ -1075,7 +1076,7 @@ static int __init cpg_mssr_common_init(struct device *dev, priv->num_core_clks = info->num_total_core_clks; priv->num_mod_clks = info->num_hw_mod_clks; priv->last_dt_core_clk = info->last_dt_core_clk; - RAW_INIT_NOTIFIER_HEAD(&priv->notifiers); + RAW_INIT_NOTIFIER_HEAD(&priv->pub.notifiers); priv->reg_layout = info->reg_layout; if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) { priv->status_regs = mstpsr; @@ -1095,7 +1096,7 @@ static int __init cpg_mssr_common_init(struct device *dev, } for (i = 0; i < nclks; i++) - priv->clks[i] = ERR_PTR(-ENOENT); + priv->pub.clks[i] = ERR_PTR(-ENOENT); error = cpg_mssr_reserved_init(priv, info); if (error) @@ -1112,8 +1113,8 @@ static int __init cpg_mssr_common_init(struct device *dev, reserve_err: cpg_mssr_reserved_exit(priv); out_err: - if (priv->base) - iounmap(priv->base); + if (priv->pub.base0) + iounmap(priv->pub.base0); kfree(priv); return error; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index a1d6e0cbcff9..adc8948e6af4 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -8,6 +8,8 @@ #ifndef __CLK_RENESAS_CPG_MSSR_H__ #define __CLK_RENESAS_CPG_MSSR_H__ +#include + /* * Definitions of CPG Core Clocks * @@ -27,6 +29,21 @@ struct cpg_core_clk { unsigned int div; unsigned int mult; unsigned int offset; + +/** + * struct cpg_mssr_pub - Private data shared with + * device-specific clk registration code + * + * @base0: CPG/MSSR register block base0 address + * @rmw_lock: protects RMW register accesses + * @notifiers: Notifier chain to save/restore clock state for system resume + * @clks: pointer to clocks + */ +struct cpg_mssr_pub { + void __iomem *base0; + struct raw_notifier_head notifiers; + spinlock_t rmw_lock; + struct clk **clks; }; enum clk_types { @@ -153,8 +170,8 @@ struct cpg_mssr_info { struct clk *(*cpg_clk_register)(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers); + struct cpg_mssr_pub *pub); + }; extern const struct cpg_mssr_info r7s9210_cpg_mssr_info; From patchwork Mon Feb 17 10:52:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Bultel X-Patchwork-Id: 13977571 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B1FBD2185B3; Mon, 17 Feb 2025 10:54:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739789696; cv=none; b=KOWtS8MKPsyw9Qh6FOEtPvqhzIoOvLO29Q1jKmiSyomDpECdCDha81oxzM6qjQedzogtH4RccZBdrvfO5eNzLLt5DqDb32s56a4MkJFxZauitI+XW9jqK6cZh4UN/sItYIn2cm3HXQe0U/i/3FJpeeyZEVShTTZIodQIh5hoc6I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739789696; c=relaxed/simple; bh=yfLSsGRCLaq5JG8L+IkUf1zHaiTZfXpc8ugeLDaRO68=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KbKXbWEPNCL8YelKUFxMkYRpYRgMdyeSkGy7oIiBGR8qFtzgaONx+MSubsymRUJJ6qZ4MxZyQiFQs187WKIVM1cKqttiqldk4dRr4njmCqPy5tzjfUNf7hdopo3KFLNLanHig7f/mRUYaOKps3SWkq1T3j6yf7fKVhk6c8XKc1Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: 5qJbfFX3R6uQ3IgJUR6zHg== X-CSE-MsgGUID: nd//RtjiReyx1+sKnb6wCA== Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 17 Feb 2025 19:54:53 +0900 Received: from superbuilder.administration.lan (unknown [10.226.93.254]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 54AD0428055D; Mon, 17 Feb 2025 19:54:50 +0900 (JST) From: Thierry Bultel To: thierry.bultel@linatsea.fr, Geert Uytterhoeven , Michael Turquette , Stephen Boyd , Magnus Damm Cc: linux-renesas-soc@vger.kernel.org, Thierry Bultel , linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org Subject: [PATCH v2 06/13] clk: renesas: Add support for R9A09G077 SoC Date: Mon, 17 Feb 2025 11:52:07 +0100 Message-ID: <20250217105354.551788-7-thierry.bultel.yh@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250217105354.551788-1-thierry.bultel.yh@bp.renesas.com> References: <20250217105354.551788-1-thierry.bultel.yh@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 RZ/T2H has 2 registers blocks at different addresses. The clock tree has configurable dividers and mux selectors. Add these new clock types, new register layout type, and registration code for mux and div in registration callback. Signed-off-by: Thierry Bultel --- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r9a09g077-cpg-mssr.c | 237 +++++++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 40 ++++ drivers/clk/renesas/renesas-cpg-mssr.h | 23 +++ 5 files changed, 306 insertions(+) create mode 100644 drivers/clk/renesas/r9a09g077-cpg-mssr.c diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index ff01f5f0ed20..58ea50b0e5b8 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -41,6 +41,7 @@ config CLK_RENESAS select CLK_R9A08G045 if ARCH_R9A08G045 select CLK_R9A09G011 if ARCH_R9A09G011 select CLK_R9A09G057 if ARCH_R9A09G057 + select CLK_R9A09G077 if ARCH_R9A09G077 select CLK_SH73A0 if ARCH_SH73A0 if CLK_RENESAS @@ -198,6 +199,10 @@ config CLK_R9A09G057 bool "RZ/V2H(P) clock support" if COMPILE_TEST select CLK_RZV2H +config CLK_R9A09G077 + bool "RZ/T2H clock support" if COMPILE_TEST + select CLK_RZT2H + config CLK_SH73A0 bool "SH-Mobile AG5 clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 82efaa835ac7..61c95d0e3f7a 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_CLK_R8A779A0) += r8a779a0-cpg-mssr.o obj-$(CONFIG_CLK_R8A779F0) += r8a779f0-cpg-mssr.o obj-$(CONFIG_CLK_R8A779G0) += r8a779g0-cpg-mssr.o obj-$(CONFIG_CLK_R8A779H0) += r8a779h0-cpg-mssr.o +obj-$(CONFIG_CLK_R9A09G077) += r9a09g077-cpg-mssr.o obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o obj-$(CONFIG_CLK_R9A07G043) += r9a07g043-cpg.o obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o diff --git a/drivers/clk/renesas/r9a09g077-cpg-mssr.c b/drivers/clk/renesas/r9a09g077-cpg-mssr.c new file mode 100644 index 000000000000..62a5fb115393 --- /dev/null +++ b/drivers/clk/renesas/r9a09g077-cpg-mssr.c @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r9a09g077 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2025 Renesas Electronics Corp. + * + */ + +#include +#include +#include +#include + +#include +#include "renesas-cpg-mssr.h" + +#define SCKCR 0x00 +#define SCKCR2 0x04 +#define SCKCR3 0x08 +#define SCKCR4 0x0C +#define PMSEL 0x10 +#define PMSEL_PLL0 BIT(0) +#define PMSEL_PLL2 BIT(2) +#define PMSEL_PLL3 BIT(3) +#define PLL0EN BIT(0) +#define PLL2EN BIT(0) +#define PLL3EN BIT(0) +#define PLL0MON 0x20 +#define PLL0EN_REG 0x30 +#define PLL0_SSC_CTR 0x34 +#define PLL1MON 0x40 +#define LOCOCR 0x70 +#define HIZCTRLEN 0x80 +#define PLL2MON 0x90 +#define PLL2EN_REG 0xA0 +#define PLL2_SSC_CTR 0xAC +#define PLL3MON 0xB0 +#define PLL3EN_REG 0xC0 +#define PLL3_VCO_CTR0 0xC4 +#define PLL3_VCO_CTR1 0xC8 +#define PLL4MON 0xD0 +#define PHYSEL BIT(21) + +#define MRCTLA 0x240 +#define MRCTLE 0x250 +#define MRCTLI 0x260 +#define MRCTLM 0x270 + +#define DDIV_PACK(offset, bitpos, size) \ + (((offset) << 20) | ((bitpos) << 12) | ((size) << 8)) + +#define DIVCA55 DDIV_PACK(SCKCR2, 8, 4) +#define DIVCA55S DDIV_PACK(SCKCR2, 12, 1) +#define DIVCR520 DDIV_PACK(SCKCR2, 2, 2) +#define DIVCR521 DDIV_PACK(SCKCR2, 0, 2) +#define DIVLCDC DDIV_PACK(SCKCR3, 20, 3) +#define DIVCKIO DDIV_PACK(SCKCR, 16, 3) +#define DIVETHPHY DDIV_PACK(SCKCR, 21, 1) +#define DIVCANFD DDIV_PACK(SCKCR, 20, 1) +#define DIVSPI0 DDIV_PACK(SCKCR3, 0, 2) +#define DIVSPI1 DDIV_PACK(SCKCR3, 2, 2) +#define DIVSPI2 DDIV_PACK(SCKCR3, 4, 2) +#define DIVSPI3 DDIV_PACK(SCKCR2, 16, 2) + +#define SEL_PLL_PACK(offset, bitpos, size) \ + (((offset) << 20) | ((bitpos) << 12) | ((size) << 8)) + +#define SEL_PLL SEL_PLL_PACK(SCKCR, 22, 1) + +#define GET_SHIFT(val) FIELD_GET(GENMASK(19, 12), val) +#define GET_WIDTH(val) FIELD_GET(GENMASK(11, 8), val) +#define GET_REG_OFFSET(val) FIELD_GET(GENMASK(31, 20), val) + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R9A09G077_LCDC_CLKD, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_LOCO, + + /* Internal Core Clocks */ + CLK_PLL0, + CLK_PLL1, + CLK_PLL2, + CLK_PLL3, + CLK_PLL4, + CLK_SEL_PLL0, + CLK_SEL_CLK_PLL0, + CLK_SEL_PLL1, + CLK_SEL_CLK_PLL1, + CLK_SEL_PLL2, + CLK_SEL_CLK_PLL2, + CLK_SEL_PLL4, + CLK_SEL_CLK_PLL4, + CLK_SEL_CLK_SRC, + CLK_SEL_EXTAL, + CLK_SEL_LOCO, + CLK_PLL3_INPUT, + + /* Module Clocks */ + MOD_CLK_BASE, +}; + +static const struct clk_div_table dtable_1_2[] = { + {0, 2}, + {15, 1}, + {0, 0}, +}; + +/* Mux clock tables */ +static const char * const sel_clk_pll0[] = { ".sel_loco", ".sel_pll0" }; +static const char * const sel_clk_pll1[] = { ".sel_loco", ".sel_pll1" }; +static const char * const sel_clk_pll4[] = { ".sel_loco", ".sel_pll4" }; + +static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("loco", CLK_LOCO), + + /* Internal Core Clocks */ + DEF_FIXED(".pll0", CLK_PLL0, CLK_EXTAL, 48, 1), + DEF_FIXED(".pll1", CLK_PLL1, CLK_EXTAL, 40, 1), + DEF_FIXED(".pll4", CLK_PLL4, CLK_EXTAL, 96, 1), + DEF_FIXED(".sel_pll0", CLK_SEL_PLL0, CLK_PLL0, 1, 1), + DEF_MUX(".sel_clk_pll0", CLK_SEL_CLK_PLL0, SEL_PLL, + sel_clk_pll0, ARRAY_SIZE(sel_clk_pll0), 0, CLK_MUX_READ_ONLY), + DEF_FIXED(".sel_pll1", CLK_SEL_PLL1, CLK_PLL1, 1, 1), + DEF_MUX(".sel_clk_pll1", CLK_SEL_CLK_PLL1, SEL_PLL, + sel_clk_pll1, ARRAY_SIZE(sel_clk_pll1), 0, CLK_MUX_READ_ONLY), + DEF_FIXED(".sel_pll4", CLK_SEL_PLL4, CLK_PLL4, 1, 1), + DEF_MUX(".sel_clk_pll4", CLK_SEL_CLK_PLL4, SEL_PLL, + sel_clk_pll4, ARRAY_SIZE(sel_clk_pll4), 0, CLK_MUX_READ_ONLY), + + /* Core output clk */ + DEF_DIV("CA55", R9A09G077_CA55, CLK_SEL_CLK_PLL0, DIVCA55, + dtable_1_2, CLK_DIVIDER_HIWORD_MASK, 1), + DEF_FIXED("PCLKM", R9A09G077_PCLKM, CLK_SEL_CLK_PLL1, 1, 8), + DEF_FIXED("PCLKGPTL", R9A09G077_PCLKGPTL, CLK_SEL_CLK_PLL1, 1, 2), +}; + +static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { + DEF_MOD("sci0", 108, R9A09G077_PCLKM), +}; + +static struct clk * __init +r9a09g077_cpg_div_clk_register(struct device *dev, + const struct cpg_core_clk *core, + void __iomem *base, + struct cpg_mssr_pub *pub) +{ + const struct clk *parent; + const char *parent_name; + struct clk_hw *clk_hw; + + parent = pub->clks[core->parent]; + + if (IS_ERR(parent)) + return ERR_CAST(parent); + + parent_name = __clk_get_name(parent); + + if (core->dtable) + clk_hw = clk_hw_register_divider_table(dev, core->name, + parent_name, 0, + base + GET_REG_OFFSET(core->conf), + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), + core->flag, + core->dtable, + &pub->rmw_lock); + else + clk_hw = clk_hw_register_divider(dev, core->name, + parent_name, 0, + base + GET_REG_OFFSET(core->conf), + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), + core->flag, &pub->rmw_lock); + + if (IS_ERR(clk_hw)) + return ERR_CAST(clk_hw); + + return clk_hw->clk; + +} + +static struct clk * __init +r9a09g077_cpg_mux_clk_register(struct device *dev, + const struct cpg_core_clk *core, + void __iomem *base, + struct cpg_mssr_pub *pub) +{ + struct clk_hw *clk_hw; + + clk_hw = devm_clk_hw_register_mux(dev, core->name, + core->parent_names, core->num_parents, + core->flag, + base + GET_REG_OFFSET(core->conf), + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), + core->mux_flags, &pub->rmw_lock); + return clk_hw->clk; +} + +static struct clk * __init + r9a09g077_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, + const struct cpg_mssr_info *info, + struct cpg_mssr_pub *pub) +{ + void __iomem *base = core->sel_base ? pub->base1 : pub->base0; + + switch (core->type) { + case CLK_TYPE_DIV: + return r9a09g077_cpg_div_clk_register(dev, core, base, pub); + case CLK_TYPE_MUX: + return r9a09g077_cpg_mux_clk_register(dev, core, base, pub); + default: + return ERR_PTR(-EINVAL); + } +} + +const struct cpg_mssr_info r9a09g077_cpg_mssr_info = { + /* Core Clocks */ + .core_clks = r9a09g077_core_clks, + .num_core_clks = ARRAY_SIZE(r9a09g077_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r9a09g077_mod_clks, + .num_mod_clks = ARRAY_SIZE(r9a09g077_mod_clks), + .num_hw_mod_clks = 12 * 32, + + .reg_layout = CLK_REG_LAYOUT_RZ_T2H, + .cpg_clk_register = r9a09g077_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 7d5fba3aef19..2f5aa796b0c6 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -79,6 +79,15 @@ static const u16 mstpcr_for_gen4[] = { 0x2D60, 0x2D64, 0x2D68, 0x2D6C, 0x2D70, 0x2D74, }; +/* Module Stop Control Register (RZ/T2H) + * RZ/T2H has 2 registers blocks. To differentiate them, + * 0x1000 is added to offsets of block 2 + */ +static const u16 mstpcr_for_rzt2h[] = { + 0x0300, 0x0304, 0x0308, 0x030C, 0x0310, 0x1318, 0x1320, 0x0324, + 0x0328, 0x032C, 0x0303, 0x1334, +}; + /* * Standby Control Register offsets (RZ/A) * Base address is FRQCR register @@ -189,6 +198,14 @@ struct mstp_clock { #define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw) +static void *cpg_rzt2h_addr_from_offset(struct clk_hw *hw, u16 offset) +{ + struct mstp_clock *clock = to_mstp_clock(hw); + struct cpg_mssr_priv *priv = clock->priv; + + return offset + (offset > 0x1000 ? priv->pub.base1 - 0x1000 : priv->pub.base0); +} + static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) { struct mstp_clock *clock = to_mstp_clock(hw); @@ -260,6 +277,12 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) value = readb(priv->pub.base0 + priv->control_regs[reg]); + else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) { + void __iomem *addr = + cpg_rzt2h_addr_from_offset(hw, + priv->control_regs[reg]); + value = readw(addr); + } else value = readl(priv->pub.base0 + priv->status_regs[reg]); @@ -875,6 +898,12 @@ static const struct of_device_id cpg_mssr_match[] = { .compatible = "renesas,r8a779h0-cpg-mssr", .data = &r8a779h0_cpg_mssr_info, }, +#endif +#ifdef CONFIG_CLK_R9A09G077 + { + .compatible = "renesas,r9a09g077-cpg-mssr", + .data = &r9a09g077_cpg_mssr_info, + }, #endif { /* sentinel */ } }; @@ -1072,6 +1101,13 @@ static int __init cpg_mssr_common_init(struct device *dev, error = -ENOMEM; goto out_err; } + if (info->reg_layout == CLK_REG_LAYOUT_RZ_T2H) { + priv->pub.base1 = of_iomap(np, 1); + if (!priv->pub.base1) { + error = -ENOMEM; + goto out_err; + } + } priv->num_core_clks = info->num_total_core_clks; priv->num_mod_clks = info->num_hw_mod_clks; @@ -1085,6 +1121,8 @@ static int __init cpg_mssr_common_init(struct device *dev, priv->reset_clear_regs = srstclr; } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { priv->control_regs = stbcr; + } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) { + priv->control_regs = mstpcr_for_rzt2h; } else if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) { priv->status_regs = mstpsr_for_gen4; priv->control_regs = mstpcr_for_gen4; @@ -1115,6 +1153,8 @@ static int __init cpg_mssr_common_init(struct device *dev, out_err: if (priv->pub.base0) iounmap(priv->pub.base0); + if (priv->pub.base1) + iounmap(priv->pub.base1); kfree(priv); return error; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index adc8948e6af4..a6e4a96ba036 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -22,6 +22,8 @@ struct cpg_core_clk { /* Common */ const char *name; + const char * const *parent_names; + const struct clk_div_table *dtable; unsigned int id; unsigned int type; /* Depending on type */ @@ -29,18 +31,26 @@ struct cpg_core_clk { unsigned int div; unsigned int mult; unsigned int offset; + unsigned int conf; + int flag; + int mux_flags; + int num_parents; + int sel_base; +}; /** * struct cpg_mssr_pub - Private data shared with * device-specific clk registration code * * @base0: CPG/MSSR register block base0 address + * @base1: CPG/MSSR register block base1 address * @rmw_lock: protects RMW register accesses * @notifiers: Notifier chain to save/restore clock state for system resume * @clks: pointer to clocks */ struct cpg_mssr_pub { void __iomem *base0; + void __iomem *base1; struct raw_notifier_head notifiers; spinlock_t rmw_lock; struct clk **clks; @@ -53,6 +63,8 @@ enum clk_types { CLK_TYPE_DIV6P1, /* DIV6 Clock with 1 parent clock */ CLK_TYPE_DIV6_RO, /* DIV6 Clock read only with extra divisor */ CLK_TYPE_FR, /* Fixed Rate Clock */ + CLK_TYPE_DIV, /* Clock with divider */ + CLK_TYPE_MUX, /* Clock with clock source selector */ /* Custom definitions start here */ CLK_TYPE_CUSTOM, @@ -73,6 +85,15 @@ enum clk_types { DEF_BASE(_name, _id, CLK_TYPE_DIV6_RO, _parent, .offset = _offset, .div = _div, .mult = 1) #define DEF_RATE(_name, _id, _rate) \ DEF_TYPE(_name, _id, CLK_TYPE_FR, .mult = _rate) +#define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag, _sel_base) \ + DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \ + .parent = _parent, .dtable = _dtable, .flag = _flag, .sel_base = _sel_base) +#define DEF_MUX(_name, _id, _conf, _parent_names, _num_parents, _flag, \ + _mux_flags) \ + DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \ + .parent_names = _parent_names, .num_parents = _num_parents, \ + .flag = _flag, .mux_flags = _mux_flags) + /* * Definitions of Module Clocks @@ -106,6 +127,7 @@ enum clk_reg_layout { CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3 = 0, CLK_REG_LAYOUT_RZ_A, CLK_REG_LAYOUT_RCAR_GEN4, + CLK_REG_LAYOUT_RZ_T2H, }; /** @@ -198,6 +220,7 @@ extern const struct cpg_mssr_info r8a779a0_cpg_mssr_info; extern const struct cpg_mssr_info r8a779f0_cpg_mssr_info; extern const struct cpg_mssr_info r8a779g0_cpg_mssr_info; extern const struct cpg_mssr_info r8a779h0_cpg_mssr_info; +extern const struct cpg_mssr_info r9a09g077_cpg_mssr_info; void __init cpg_mssr_early_init(struct device_node *np, const struct cpg_mssr_info *info);