From: Stephen Boyd <sboyd@kernel.org>
To: Qin Jian <qinjian@cqplus1.com>, robh+dt@kernel.org
Cc: mturquette@baylibre.com, tglx@linutronix.de, maz@kernel.org,
p.zabel@pengutronix.de, linux@armlinux.org.uk,
broonie@kernel.org, arnd@arndb.de, stefan.wahren@i2se.com,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org,
wells.lu@sunplus.com, Qin Jian <qinjian@cqplus1.com>
Subject: Re: [PATCH v7 06/10] clk: Add Sunplus SP7021 clock driver
Date: Wed, 05 Jan 2022 16:42:48 -0800 [thread overview]
Message-ID: <20220106004249.90484C36AEB@smtp.kernel.org> (raw)
In-Reply-To: <7f8302e2c1d02141dd69d2524eaa857d6494fdc7.1640154492.git.qinjian@cqplus1.com>
Quoting Qin Jian (2021-12-21 23:06:02)
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index c5b3dc973..4a186ccf6 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -334,6 +334,15 @@ config COMMON_CLK_VC5
> This driver supports the IDT VersaClock 5 and VersaClock 6
> programmable clock generators.
>
> +config COMMON_CLK_SP7021
> + bool "Clock driver for Sunplus SP7021 SoC"
> + default SOC_SP7021
> + help
> + This driver supports the Sunplus SP7021 SoC clocks.
> + It implements SP7021 PLLs/gate.
> + Not all features of the PLL are currently supported
> + by the driver.
> +
> config COMMON_CLK_STM32MP157
> def_bool COMMON_CLK && MACH_STM32MP157
> help
> @@ -366,7 +375,6 @@ config COMMON_CLK_MMP2
>
> config COMMON_CLK_MMP2_AUDIO
> tristate "Clock driver for MMP2 Audio subsystem"
> - depends on COMMON_CLK_MMP2 || COMPILE_TEST
> help
> This driver supports clocks for Audio subsystem on MMP2 SoC.
>
What's the relevance of this hunk to this patch? Can you drop this part?
> diff --git a/drivers/clk/clk-sp7021.c b/drivers/clk/clk-sp7021.c
> new file mode 100644
> index 000000000..6df87f0a6
> --- /dev/null
> +++ b/drivers/clk/clk-sp7021.c
> @@ -0,0 +1,705 @@
> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +/*
> + * Copyright (C) Sunplus Technology Co., Ltd.
> + * All rights reserved.
> + */
> +//#define DEBUG
> +#include <linux/clk-provider.h>
> +#include <linux/clkdev.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/bitfield.h>
> +#include <linux/slab.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <dt-bindings/clock/sp-sp7021.h>
> +
> +#define REG(i) (pll_regs + (i) * 4)
> +
[....]
> +
> +static long plltv_div(struct sp_pll *clk, unsigned long freq)
> +{
> + if (freq % 100)
> + return plltv_fractional_div(clk, freq);
> + else
> + return plltv_integer_div(clk, freq);
Drop else please
> +}
> +
> +static void plltv_set_rate(struct sp_pll *clk)
> +{
> + u32 reg;
> +
> + reg = HWM_FIELD_PREP(MASK_SEL_FRA, clk->p[SEL_FRA]);
> + reg |= HWM_FIELD_PREP(MASK_SDM_MOD, clk->p[SDM_MOD]);
> + reg |= HWM_FIELD_PREP(MASK_PH_SEL, clk->p[PH_SEL]);
> + reg |= HWM_FIELD_PREP(MASK_NFRA, clk->p[NFRA]);
> + writel(reg, clk->reg);
> +
> + reg = HWM_FIELD_PREP(MASK_DIVR, clk->p[DIVR]);
[...]
> + .set_rate = sp_pll_set_rate
> +};
> +
> +static const struct clk_ops sp_pll_sub_ops = {
> + .enable = sp_pll_enable,
> + .disable = sp_pll_disable,
> + .is_enabled = sp_pll_is_enabled,
> + .recalc_rate = sp_pll_recalc_rate,
> +};
> +
> +struct clk_hw *sp_pll_register(const char *name, const char *parent,
> + void __iomem *reg, int pd_bit, int bp_bit,
> + unsigned long brate, int shift, int width,
> + spinlock_t *lock)
> +{
> + struct sp_pll *pll;
> + struct clk_hw *hw;
> + struct clk_init_data initd = {
> + .name = name,
> + .parent_names = &parent,
Any chance clk_parent_data can be used instead of string names?
> + .ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
> + .num_parents = 1,
> + };
> + int ret;
> +
> + pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> + if (!pll)
> + return ERR_PTR(-ENOMEM);
> +
> + if (reg == PLLSYS_CTL) /* system clock, should not be closed */
s/closed/disabled/
> + initd.flags |= CLK_IS_CRITICAL;
> +
> + pll->hw.init = &initd;
> + pll->reg = reg;
> + pll->pd_bit = pd_bit;
> + pll->bp_bit = bp_bit;
> + pll->brate = brate;
> + pll->div_shift = shift;
> + pll->div_width = width;
> + pll->lock = lock;
> +
> + hw = &pll->hw;
> + ret = clk_hw_register(NULL, hw);
> + if (ret) {
> + kfree(pll);
> + hw = ERR_PTR(ret);
> + } else {
> + pr_info("%-20s%lu\n", name, clk_hw_get_rate(hw));
Drop this print or make it pr_debug()
> + clk_hw_register_clkdev(hw, NULL, name);
> + }
> +
> + return hw;
> +}
> +
> +static void __init sp_clk_setup(struct device_node *np)
> +{
> + int i, j;
> + struct clk_hw **hws;
> +
> + sp_clk_base = of_iomap(np, 0);
> + if (WARN_ON(!sp_clk_base))
> + return; /* -ENXIO */
> +
> + sp_clk_data = kzalloc(struct_size(sp_clk_data, hws, CLK_MAX), GFP_KERNEL);
> + if (!sp_clk_data)
> + return; /* -ENOMEM */
> +
> + hws = sp_clk_data->hws;
> +
> + /* PLL_A */
> + hws[PLL_A] = sp_pll_register("plla", EXTCLK, PLLA_CTL, 11, 12,
> + 27000000, 0, DIV_A, &plla_lock);
> +
> + /* PLL_E */
> + hws[PLL_E] = sp_pll_register("plle", EXTCLK, PLLE_CTL, 6, 2,
> + 50000000, 0, 0, &plle_lock);
> + hws[PLL_E_2P5] = sp_pll_register("plle_2p5", "plle", PLLE_CTL, 13, -1,
> + 2500000, 0, 0, &plle_lock);
> + hws[PLL_E_25] = sp_pll_register("plle_25", "plle", PLLE_CTL, 12, -1,
> + 25000000, 0, 0, &plle_lock);
> + hws[PLL_E_112P5] = sp_pll_register("plle_112p5", "plle", PLLE_CTL, 11, -1,
> + 112500000, 0, 0, &plle_lock);
> +
> + /* PLL_F */
> + hws[PLL_F] = sp_pll_register("pllf", EXTCLK, PLLF_CTL, 0, 10,
> + 13500000, 1, 4, &pllf_lock);
> +
> + /* PLL_TV */
> + hws[PLL_TV] = sp_pll_register("plltv", EXTCLK, PLLTV_CTL, 0, 15,
> + 27000000, 0, DIV_TV, &plltv_lock);
> + hws[PLL_TV_A] = clk_hw_register_divider(NULL, "plltv_a", "plltv", 0,
> + PLLTV_CTL + 4, 5, 1,
> + CLK_DIVIDER_POWER_OF_TWO,
> + &plltv_lock);
> + clk_hw_register_clkdev(hws[PLL_TV_A], NULL, "plltv_a");
> +
> + /* PLL_SYS */
> + hws[PLL_SYS] = sp_pll_register("pllsys", EXTCLK, PLLSYS_CTL, 10, 9,
> + 13500000, 0, 4, &pllsys_lock);
> +
> + /* gates */
> + for (i = 0; i < ARRAY_SIZE(gates); i++) {
> + char s[10];
> +
> + j = gates[i] & 0xffff;
> + sprintf(s, "clken%02x", j);
> + hws[j] = clk_hw_register_gate(NULL, s,
> + parents[gates[i] >> 16].fw_name,
> + CLK_IGNORE_UNUSED,
Why CLK_IGNORE_UNUSED? There should be a comment or it should be
replaced with CLK_IS_CRITICAL.
> + clk_regs + (j >> 4) * 4, j & 0x0f,
> + CLK_GATE_HIWORD_MASK, NULL);
> + }
> +
> + sp_clk_data->num = CLK_MAX;
> + of_clk_add_hw_provider(np, of_clk_hw_onecell_get, sp_clk_data);
> +}
> +
> +CLK_OF_DECLARE_DRIVER(sp_clkc, "sunplus,sp7021-clkc", sp_clk_setup);
Why CLK_OF_DECLARE_DRIVER? There should be a comment but better would be
to make a platform driver instead. If the platform driver can't be used,
we need to know what other device driver is probing based on this clkc
compatible string.
next prev parent reply other threads:[~2022-01-06 0:42 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-22 7:05 [PATCH v7 00/10] Add Sunplus SP7021 SoC Support Qin Jian
2021-12-22 7:05 ` [PATCH v7 01/10] dt-bindings: vendor-prefixes: Add Sunplus Qin Jian
2022-01-10 0:56 ` Rob Herring
2021-12-22 7:05 ` [PATCH v7 02/10] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards Qin Jian
2021-12-22 7:05 ` [PATCH v7 03/10] dt-bindings: reset: Add bindings for SP7021 reset driver Qin Jian
2021-12-22 7:06 ` [PATCH v7 04/10] reset: Add Sunplus " Qin Jian
2021-12-22 7:06 ` [PATCH v7 05/10] dt-bindings: clock: Add bindings for SP7021 clock driver Qin Jian
2021-12-22 17:05 ` Rob Herring
2022-01-06 0:36 ` Stephen Boyd
2021-12-22 7:06 ` [PATCH v7 06/10] clk: Add Sunplus " Qin Jian
2022-01-06 0:42 ` Stephen Boyd [this message]
2022-01-07 7:55 ` qinjian[覃健]
[not found] ` <20220108004112.2AB34C36AE9@smtp.kernel.org>
2022-01-10 6:37 ` qinjian[覃健]
2021-12-22 7:06 ` [PATCH v7 07/10] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller Qin Jian
2021-12-22 7:06 ` [PATCH v7 08/10] irqchip: Add Sunplus SP7021 interrupt controller driver Qin Jian
2021-12-22 7:06 ` [PATCH v7 09/10] ARM: sunplus: Add initial support for Sunplus SP7021 SoC Qin Jian
2021-12-22 7:06 ` [PATCH v7 10/10] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig Qin Jian
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=20220106004249.90484C36AEB@smtp.kernel.org \
--to=sboyd@kernel.org \
--cc=arnd@arndb.de \
--cc=broonie@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=maz@kernel.org \
--cc=mturquette@baylibre.com \
--cc=p.zabel@pengutronix.de \
--cc=qinjian@cqplus1.com \
--cc=robh+dt@kernel.org \
--cc=stefan.wahren@i2se.com \
--cc=tglx@linutronix.de \
--cc=wells.lu@sunplus.com \
/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;
as well as URLs for NNTP newsgroup(s).