From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=209.85.128.51 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793000823; b=v7jtsZUc4t8tRRAfp9QdelVrezQ0C5ck++EVcxdukm7kLf22x/VvBQ2FZdgfNpIdRd7k hopNX42b9hgsc8gKMYpp5wuktsvozXp2FJKcbA9vanscdqcSreUZ4DPgPR/fHuD7UHEU8 POyK35f9MQyJc8keE6BWzc53+1jleEPaduN1zZ33DCQgHFymKvIk9Ogi4glAQahdh5YHW oKf+z3toiN5p0QcFLlXpx+dxFl3Q5Z9Ht0w0E1x2WJvdmqJQ2943tvl0mrA2vYy/Z1kfK ttvEVOq5Eu9dmTwwh0hwQZgXK+9hCLFEEHfINr9AzJbXnhbgP6xcpKM9OReHSeSJorQ== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793000823; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Gm-Message-State:X-Gm-Gg:X-Received:Received:From:To:Cc:Subject: Date:Message-ID:X-Mailer:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding; bh=AyUGw9y+lTYy33bkDqkQyHAnwgp3s7+TGmPupaPsrss=; b=3Nqmh+Gp+TYensaChqwJJCS7fYqYNtmWOxNv9krIT7K4C+EEnvA2RSFiJka87Pys+4Wj CROPmSKdK3U0qxD1ULIvqtrOJlKeB7Hb5HPXyB5oirE8Xbp1nanhhpzKhjqE8CA9GjZx1 qHOZWrfV4e0PNBkdRvh0fC2SW6/q2xwF4NO32kxr9L94oYz3UZje8BdOWuLkvs4/p1XbU sC66h5Fm1HPpGOqcSAedInr3BUdL4EZlB5SVnc7PqIp8dE5EW1c6AsVuAPNPKhA6uC4y2 yFAqmROT94/4IKtHdKka9k8lSviWGCSeKdqYqkVL77U92QuS9MjOOb+rxtqRtmJut6w== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=amarulasolutions.com; spf=pass smtp.mailfrom=amarulasolutions.com; dkim=pass header.d=amarulasolutions.com header.i=@amarulasolutions.com header.a=rsa-sha256 header.s=google header.b=bX3kRMW2; arc=none smtp.remote-ip=209.85.128.51 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5BC09606A335 for ; Mon, 26 Oct 2026 07:47:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 5BC09606A335 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=amarulasolutions.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amarulasolutions.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key, unprotected) header.d=amarulasolutions.com header.i=@amarulasolutions.com header.a=rsa-sha256 header.s=google header.b=bX3kRMW2 Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-4a214af2076so18107225e9.0 for ; Mon, 26 Oct 2026 00:47:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; t=1793000822; x=1793605622; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=AyUGw9y+lTYy33bkDqkQyHAnwgp3s7+TGmPupaPsrss=; b=bX3kRMW24nMkF8yrKW/om/f/NwBbOa/rUD2be/zPmv5Lr2Yk+iYDXcSX7m9YZDgmFZ aTK2CfZtoOdqJZfuvahIAiflRMMG8qR8v78mk8+EMKOC19aAZ3xKoGuMFl37/gdgEqwn Rmj9gWdnAp+IYSjOHiw2l9CjUCZFmi/BOg7n8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793000822; x=1793605622; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=AyUGw9y+lTYy33bkDqkQyHAnwgp3s7+TGmPupaPsrss=; b=efrWqiNTOAhlfsx31KjAtdvB4AXwcVBpJ+UrMuGx5MaCy/iWie2ai8IvqZ8aUtd/Ds 4L6OFk3RifFV5ZHjpzTZcjS0KeXCg6tdHs33llcZlVJPflNlstaEZs/29YuqSJqiZBR7 uFrPe8jfYK+r2JGaRRUSkYnYgCMyllqipCzdbh2VlaWI/bjb9G+OG8OKA8VW1eTJj6Rf NZPiF3z8B3cdm4l7nNhOIywPGhSOPRkZT5uz/OGMGTINXZ7WB++Weg9HyCWxaQ1dYUTX BleBpj1xg1RZKJOUkTt5TjDOAMLOvWXdcqOplMSqkzA8FFDeV09sLrCGHudugSwF1zot 7jMQ== X-Gm-Message-State: AFq9FYIIlPXus91xS1Ja+6jo5ct0C1jIK3hn4zJsQlqZ6DOY+BLxA0QV KF93NkRCRzHPmOqiyLy0VvMXu4RBruP3UZW+1F3A8qkc9gyYj9EHq8ldty+6/aIugT9rwEgkE2o ZDf6/ X-Gm-Gg: AYBFou0DxFaaXqc6dNqfmtCbKHq1o743YGZWIwre8XgaLJJUG+kI3w1VhcWOWsNBtb8 Mh+M6taVVLTniyXMzSxGJCC2Mkk4k1FEn5rW6vCsMf/dwPVF9QVUcyv9dkL8IHHRLUE1T/Amkh+ pISznXSGyl41iAxcRUSllqd8jYIenbggAwboDkEzmHPZqIQPnyeVbH2T8ksf/RCwuk609ocDdnc 3fgCCQalIRbVa6qnK/IqjykfygFUYmdC3x2MAjceZyN8mgOXiIiKTeygRd169keshhQYgWLOXGn SGAhbXLBLYt3a3augDZM1VvPaM3NP66NHcWU6uSK010oPsTK/yYjSdMQws+0OGxQRfPHLBvTWOm cYCGQrIcwCxINUGWthDkXR1SXph7qt+0HREEA5VNvfQTVXoJb7gIS9Xy18OiYOhFAKFJ2lFM8MF 6paCusnvKQTrDXUVAa50YXFyF4K/nHAH13kcj98znB0vF7pA153XxsbxiUbnPTpAgOe6WSmmhZf Ntto4QktUSNULZ3tjoAHji15VUHk9C/rg4L5j1mjjquo6Fwf/CGOQFYIGnh21JP6GbjFQbcRrFU peFE8BW7H4TcY66lfr/Qc+xr7gz3UG5H92Icm+p8XC3uIDOkixjoPKzvExmhCP7qC8UCimb9PIG Yc6wZRevsuurp0Qx4LO2K0XCF8sw/jGXrA3XgHaZ8Cx9RSImNEfgxcu3nlJnoVaeHuYDsiPk6Z1 8= X-Received: by 2002:a05:600c:4746:b0:4a3:59c9:a744 with SMTP id 5b1f17b1804b1-4a35ac8bb3fmr114614925e9.7.1793000821809; Mon, 26 Oct 2026 00:47:01 -0700 (PDT) Received: from dario-ThinkPad-P14s-Gen-5.homenet.telecomitalia.it (host-79-14-29-58.business.telecomitalia.it. [79.14.29.58]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48e412cc164sm13731353f8f.7.2026.10.26.00.47.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Oct 2026 00:47:01 -0700 (PDT) From: Dario Binacchi To: linux-kernel@vger.kernel.org Cc: linux-amarula@amarulasolutions.com, michael@amarulasolutions.com, Dario Binacchi , Brian Masney , Jerome Brunet , Stephen Boyd , Tero Kristo , linux-clk@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH v2 2/3] clk: ti: dpll: use the generic spread spectrum configuration Date: Mon, 26 Oct 2026 08:46:28 +0100 Message-ID: <20261026074654.3997494-3-dario.binacchi@amarulasolutions.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20261026074654.3997494-1-dario.binacchi@amarulasolutions.com> References: <20261026074654.3997494-1-dario.binacchi@amarulasolutions.com> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The clock framework provides a generic API and DT property for spread spectrum clocking (SSC) since commit c86814e70390 ("clk: Introduce clk_hw_set_spread_spectrum"). Implement the set_spread_spectrum callback and drop the vendor specific properties. The SSC registers are programmed at the next rate change, as with the vendor specific properties. The generic framework expresses the spread in permyriad rather than permille, hence the change in the deltaM step computation, and also supports up-spread, which is rejected as the hardware does not support it. Signed-off-by: Dario Binacchi --- (no changes since v1) drivers/clk/ti/clock.h | 2 ++ drivers/clk/ti/dpll.c | 8 ++--- drivers/clk/ti/dpll3xxx.c | 61 ++++++++++++++++++++++++++++++++------- include/linux/clk/ti.h | 9 ++---- 4 files changed, 57 insertions(+), 23 deletions(-) diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index d5e24fe4ae3a..83225e506314 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -271,6 +271,8 @@ int omap3_noncore_dpll_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate, u8 index); +int omap3_noncore_dpll_set_spread_spectrum(struct clk_hw *hw, + const struct clk_spread_spectrum *ss_conf); int omap3_noncore_dpll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req); int omap2_dpll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req); diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index e01272cd628d..626b44297e42 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -51,6 +51,7 @@ static const struct clk_ops dpll_ck_ops = { .set_parent = &omap3_noncore_dpll_set_parent, .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, .determine_rate = &omap3_noncore_dpll_determine_rate, + .set_spread_spectrum = &omap3_noncore_dpll_set_spread_spectrum, .get_parent = &omap2_init_dpll_parent, .save_context = &omap3_noncore_dpll_save_context, .restore_context = &omap3_noncore_dpll_restore_context, @@ -63,6 +64,7 @@ static const struct clk_ops dpll_no_gate_ck_ops = { .set_parent = &omap3_noncore_dpll_set_parent, .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, .determine_rate = &omap3_noncore_dpll_determine_rate, + .set_spread_spectrum = &omap3_noncore_dpll_set_spread_spectrum, .save_context = &omap3_noncore_dpll_save_context, .restore_context = &omap3_noncore_dpll_restore_context }; @@ -348,12 +350,6 @@ static void __init of_ti_dpll_setup(struct device_node *node, if (ti_clk_get_reg_addr(node, ssc_clk_index++, &dd->ssc_modfreq_reg)) goto cleanup; - - of_property_read_u32(node, "ti,ssc-modfreq-hz", - &dd->ssc_modfreq); - of_property_read_u32(node, "ti,ssc-deltam", &dd->ssc_deltam); - dd->ssc_downspread = - of_property_read_bool(node, "ti,ssc-downspread"); } if (of_property_read_bool(node, "ti,low-power-stop")) diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c index 8c51b988a04f..634fe0a1f9fd 100644 --- a/drivers/clk/ti/dpll3xxx.c +++ b/drivers/clk/ti/dpll3xxx.c @@ -295,30 +295,32 @@ static void _lookup_sddiv(struct clk_hw_omap *clk, u8 *sd_div, u16 m, u8 n) * omap3_noncore_dpll_ssc_program - set spread-spectrum clocking registers * @clk: struct clk * of DPLL to set * - * Enable the DPLL spread spectrum clocking if frequency modulation and - * frequency spreading have been set, otherwise disable it. + * Enable the DPLL spread spectrum clocking according to the configuration + * set by omap3_noncore_dpll_set_spread_spectrum(), otherwise disable it. */ static void omap3_noncore_dpll_ssc_program(struct clk_hw_omap *clk) { struct dpll_data *dd = clk->dpll_data; + const struct clk_spread_spectrum *conf = &dd->ssc_conf; + bool downspread = conf->method == CLK_SPREAD_DOWN; unsigned long ref_rate; u32 v, ctrl, mod_freq_divider, exponent, mantissa; u32 deltam_step, deltam_ceil; ctrl = ti_clk_ll_ops->clk_readl(&dd->control_reg); - if (dd->ssc_modfreq && dd->ssc_deltam) { + if (conf->method != CLK_SPREAD_NO) { ctrl |= dd->ssc_enable_mask; - if (dd->ssc_downspread) + if (downspread) ctrl |= dd->ssc_downspread_mask; else ctrl &= ~dd->ssc_downspread_mask; ref_rate = clk_hw_get_rate(dd->clk_ref); mod_freq_divider = - (ref_rate / dd->last_rounded_n) / (4 * dd->ssc_modfreq); - if (dd->ssc_modfreq > (ref_rate / 70)) + (ref_rate / dd->last_rounded_n) / (4 * conf->modfreq_hz); + if (conf->modfreq_hz > (ref_rate / 70)) pr_warn("clock: SSC modulation frequency of DPLL %s greater than %ld\n", __clk_get_name(clk->hw.clk), ref_rate / 70); @@ -337,9 +339,10 @@ static void omap3_noncore_dpll_ssc_program(struct clk_hw_omap *clk) v |= exponent << __ffs(dd->ssc_modfreq_exp_mask); ti_clk_ll_ops->clk_writel(v, &dd->ssc_modfreq_reg); - deltam_step = dd->last_rounded_m * dd->ssc_deltam; - deltam_step /= 10; - if (dd->ssc_downspread) + /* spread_bp is in permyriad, convert to percent first */ + deltam_step = dd->last_rounded_m * conf->spread_bp; + deltam_step /= 100; + if (downspread) deltam_step /= 2; deltam_step <<= __ffs(dd->ssc_deltam_int_mask); @@ -353,7 +356,7 @@ static void omap3_noncore_dpll_ssc_program(struct clk_hw_omap *clk) if (deltam_step & dd->ssc_deltam_frac_mask) deltam_ceil++; - if ((dd->ssc_downspread && + if ((downspread && ((dd->last_rounded_m - (2 * deltam_ceil)) < 20 || dd->last_rounded_m > 2045)) || ((dd->last_rounded_m - deltam_ceil) < 20 || @@ -682,6 +685,44 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, return ret; } +/** + * omap3_noncore_dpll_set_spread_spectrum - set the DPLL SSC configuration + * @hw: pointer to the clock to set the spread spectrum configuration for + * @ss_conf: spread spectrum configuration + * + * Stores the spread spectrum clocking (SSC) configuration of the DPLL. The + * configuration is programmed along with the DPLL multiplier and divider + * at the next rate change. The hardware supports center-spread and + * down-spread only. Returns 0 on success, or a negative error value on + * failure. + */ +int omap3_noncore_dpll_set_spread_spectrum(struct clk_hw *hw, + const struct clk_spread_spectrum *ss_conf) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + struct dpll_data *dd = clk->dpll_data; + + if (!dd || !dd->ssc_enable_mask) + return -EOPNOTSUPP; + + switch (ss_conf->method) { + case CLK_SPREAD_NO: + break; + case CLK_SPREAD_CENTER: + case CLK_SPREAD_DOWN: + if (!ss_conf->modfreq_hz || !ss_conf->spread_bp) + return -EINVAL; + break; + default: + /* Up-spread is not supported by the hardware */ + return -EINVAL; + } + + dd->ssc_conf = *ss_conf; + + return 0; +} + /** * omap3_noncore_dpll_set_rate_and_parent - set rate and parent for a DPLL clock * @hw: pointer to the clock to set rate and parent for diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index 54a3fa370004..81ac070551f9 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -65,10 +65,7 @@ struct clk_omap_reg { * @ssc_enable_mask: mask of the DPLL SSC enable bit in @control_reg * @ssc_downspread_mask: mask of the DPLL SSC low frequency only bit in * @control_reg - * @ssc_modfreq: the DPLL SSC frequency modulation in kHz - * @ssc_deltam: the DPLL SSC frequency spreading in permille (10th of percent) - * @ssc_downspread: require the only low frequency spread of the DPLL in SSC - * mode + * @ssc_conf: the DPLL SSC configuration, as set by clk_hw_set_spread_spectrum() * @flags: DPLL type/features (see below) * * Possible values for @flags: @@ -124,9 +121,7 @@ struct dpll_data { u32 ssc_modfreq_exp_mask; u32 ssc_enable_mask; u32 ssc_downspread_mask; - u32 ssc_modfreq; - u32 ssc_deltam; - bool ssc_downspread; + struct clk_spread_spectrum ssc_conf; u8 flags; }; -- 2.43.0