From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
To: linux-kernel@vger.kernel.org
Cc: linux-amarula@amarulasolutions.com,
Dario Binacchi <dario.binacchi@amarulasolutions.com>,
Abel Vesa <abelvesa@kernel.org>,
Brian Masney <bmasney+clk@redhat.com>,
Fabio Estevam <festevam@gmail.com>, Frank Li <Frank.Li@nxp.com>,
Jerome Brunet <jbrunet+clk@baylibre.com>,
Peng Fan <peng.fan@nxp.com>,
Pengutronix Kernel Team <kernel@pengutronix.de>,
Sascha Hauer <s.hauer@pengutronix.de>,
Stephen Boyd <sboyd@kernel.org>,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-clk@vger.kernel.org
Subject: [PATCH v10 1/1] clk: imx: pll14xx: support spread spectrum clock generation
Date: Mon, 31 Aug 2026 17:27:01 +0200 [thread overview]
Message-ID: <20260831154752.15401-2-dario.binacchi@amarulasolutions.com> (raw)
In-Reply-To: <20260831154752.15401-1-dario.binacchi@amarulasolutions.com>
Add support for spread spectrum clock (SSC) generation to the pll14xx
driver.
Tested on the video PLL of i.MX8MN and i.MX8MP based boards.
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
---
Changes in v10:
- Drop 'Reviewed-by' tag of Peng Fan.
- Adapt the driver to the new infrastructure. Implement the
set_spread_spectrum() and get the modulation parameters from
struct clk_spread_spectrum.
Changes in v9:
- Add 'Reviewed-by' tag of Peng Fan.
drivers/clk/imx/clk-pll14xx.c | 58 +++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
index b6f1cc9f5700..27a637847f57 100644
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -5,6 +5,7 @@
#define pr_fmt(fmt) "pll14xx: " fmt
+#include <dt-bindings/clock/clock.h>
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/clk-provider.h>
@@ -22,6 +23,8 @@
#define GNRL_CTL 0x0
#define DIV_CTL0 0x4
#define DIV_CTL1 0x8
+#define SSCG_CTRL 0xc
+
#define LOCK_STATUS BIT(31)
#define LOCK_SEL_MASK BIT(29)
#define CLKE_MASK BIT(11)
@@ -33,6 +36,13 @@
#define KDIV_MASK GENMASK(15, 0)
#define KDIV_MIN SHRT_MIN
#define KDIV_MAX SHRT_MAX
+#define SSCG_ENABLE BIT(31)
+#define MFREQ_CTL_MASK GENMASK(19, 12)
+#define MRAT_CTL_MASK GENMASK(9, 4)
+#define SEL_PF_DOWN_SPREAD 0
+#define SEL_PF_UP_SPREAD 1
+#define SEL_PF_CENTER_SPREAD 2
+#define SEL_PF_MASK GENMASK(1, 0)
#define LOCK_TIMEOUT_US 10000
@@ -44,6 +54,7 @@ struct clk_pll14xx {
int rate_count;
s16 delta_k;
spinlock_t lock;
+ struct clk_spread_spectrum ss_conf;
};
#define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
@@ -366,6 +377,37 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
return 0;
}
+static void __clk_pll1443x_set_spread_spectrum(struct clk_hw *hw,
+ unsigned long parent_rate,
+ unsigned int pdiv,
+ unsigned int mdiv)
+{
+ struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+ struct clk_spread_spectrum *conf = &pll->ss_conf;
+ u32 sscg_ctrl, mfr, mrr, sel_pf;
+
+ if (conf->method == CLK_SSC_CENTER_SPREAD)
+ sel_pf = SEL_PF_CENTER_SPREAD;
+ else if (conf->method == CLK_SSC_UP_SPREAD)
+ sel_pf = SEL_PF_UP_SPREAD;
+ else if (conf->method == CLK_SSC_DOWN_SPREAD)
+ sel_pf = SEL_PF_DOWN_SPREAD;
+ else
+ return;
+
+ sscg_ctrl = readl_relaxed(pll->base + SSCG_CTRL);
+ sscg_ctrl &= ~(SSCG_ENABLE | MFREQ_CTL_MASK | MRAT_CTL_MASK | SEL_PF_MASK);
+
+ mfr = parent_rate / (conf->modfreq_hz * pdiv * BIT(5));
+ mrr = (conf->spread_bp * mdiv * BIT(6)) / (10000 * mfr);
+
+ sscg_ctrl |= SSCG_ENABLE | FIELD_PREP(MFREQ_CTL_MASK, mfr) |
+ FIELD_PREP(MRAT_CTL_MASK, mrr) |
+ FIELD_PREP(SEL_PF_MASK, sel_pf);
+
+ writel_relaxed(sscg_ctrl, pll->base + SSCG_CTRL);
+}
+
static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
unsigned long prate)
{
@@ -390,6 +432,9 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
writel_relaxed(FIELD_PREP(KDIV_MASK, rate.kdiv),
pll->base + DIV_CTL1);
+ __clk_pll1443x_set_spread_spectrum(hw, prate, rate.pdiv,
+ rate.mdiv);
+
spin_unlock_irqrestore(&pll->lock, flags);
return 0;
@@ -411,6 +456,8 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
writel_relaxed(FIELD_PREP(KDIV_MASK, rate.kdiv), pll->base + DIV_CTL1);
+ __clk_pll1443x_set_spread_spectrum(hw, prate, rate.pdiv, rate.mdiv);
+
spin_unlock_irqrestore(&pll->lock, flags);
/*
@@ -437,6 +484,16 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
return 0;
}
+static int clk_pll1443x_set_spread_spectrum(struct clk_hw *hw,
+ const struct clk_spread_spectrum *ss_conf)
+{
+ struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+
+ memcpy(&pll->ss_conf, ss_conf, sizeof(pll->ss_conf));
+
+ return 0;
+}
+
static int clk_pll14xx_prepare(struct clk_hw *hw)
{
struct clk_pll14xx *pll = to_clk_pll14xx(hw);
@@ -509,6 +566,7 @@ static const struct clk_ops clk_pll1443x_ops = {
.recalc_rate = clk_pll14xx_recalc_rate,
.determine_rate = clk_pll1443x_determine_rate,
.set_rate = clk_pll1443x_set_rate,
+ .set_spread_spectrum = clk_pll1443x_set_spread_spectrum,
};
struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
--
2.43.0
next prev parent reply other threads:[~2026-08-31 15:48 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-31 15:27 [PATCH v10 0/1] Support spread spectrum clocking for i.MX8M PLLs Dario Binacchi
2026-08-31 15:27 ` Dario Binacchi [this message]
2026-08-31 18:48 ` [PATCH v10 1/1] clk: imx: pll14xx: support spread spectrum clock generation sashiko-bot
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=20260831154752.15401-2-dario.binacchi@amarulasolutions.com \
--to=dario.binacchi@amarulasolutions.com \
--cc=Frank.Li@nxp.com \
--cc=abelvesa@kernel.org \
--cc=bmasney+clk@redhat.com \
--cc=festevam@gmail.com \
--cc=imx@lists.linux.dev \
--cc=jbrunet+clk@baylibre.com \
--cc=kernel@pengutronix.de \
--cc=linux-amarula@amarulasolutions.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=peng.fan@nxp.com \
--cc=s.hauer@pengutronix.de \
--cc=sboyd@kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.