From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=209.85.216.51 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793771948; b=lfGZHwWLNLX2Fd42UQl6Hn9IZ9QFRhVSI2CAyh+t6KFG3/ibMedlrIEhBWgcXtUZVvOA tftsGNZ6tFgZMr+cahdlF9VEAGdWXABSsCbscXhf3I/JByWxDaItKGees726kTN5krOQq DskqUlGtVcA7lM5h5K4RwbQEmcOHZVF1XdidH4UqloH7grbcuMBwgxFiH/U/ylw3RMEkX sxQylq/01qg241J0LKtpaLCsR49OTJ5d8w4djgIKcezf7GKbkpXK6/ksiAaE+Ra0RzVdy kNsnNInIs8imuW3D/xcbTMAAWlPq26IAz9SFf2QyUa71IwrNzgjfDmUyYF69nKghRUw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793771948; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted: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=vcGVtTeRbNMuJZikTeTy/aVLP/b0ijAI9oZ17pCLwwI=; b=kxHhsO1YewuThtIt6tDn13nDkRxkfWaOvGp++yaYRPYlXt7QBmdP7eKDe9wt4aXGSIzN 2D/q6NX/AobBD9OR4FIW9raJpM0RmagxnpyDwdDHnYatWCD52sYWTlHV7crlHgKfz6MXY /VvM/qPPDjfsyVRgjTDLiddBKK8AkmcEelLuboGbYBU/gQa6Eyu+vD1NH07/opzl62MsO U2Eux2iGlrkGWXmzErmxqDSmGoFxe0CyoJNNNZbGRYqgVJf0rbVCMFjjvxFvfPptBdYES fnV8vH3yM1zWfDwHfxCrk02WP73k8SStAW7bYDUdhNXAeIy+fu8tAIr9VHRHStxyrhA== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20260707 header.b=RQyqnqA3; arc=none smtp.remote-ip=209.85.216.51 Received: from mail-pj1-f51.google.com (mail-pj1-f51.google.com [209.85.216.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 E41B1606A31B for ; Wed, 4 Nov 2026 05:59:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org E41B1606A31B Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20260707 header.b=RQyqnqA3 Received: by mail-pj1-f51.google.com with SMTP id 98e67ed59e1d1-3ae702d28c4so196430a91.3 for ; Tue, 03 Nov 2026 21:59:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793771947; x=1794376747; 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=vcGVtTeRbNMuJZikTeTy/aVLP/b0ijAI9oZ17pCLwwI=; b=RQyqnqA323GdSXTNNSSZ/xZ3K5TQwCzL5RgcVHfFdyzLb1ZFGAiIF0HXmzRwsq+imI FFCfZomhVZVCkzKYYVmVgHs/d3Sx4t4jPoIPKkn4xXMvILrRVc59mtjMx3+y2ZxCLfe1 YAurjNgVZbwp8opPTwOzjp/0S1oR3Gb27pc+BsHW0/3GyTDswDDC1bJ4C7/MGzt+OJTV rjTDThLzl3ChKJcGWlZDilc2Nc02UCMyGPW6mpYCf4TGLvvcebV9fXMoeT6FfjDtkqak sjWYNbkdMlWbxPaWS0Bj9qeyzizqFxcFxE79aHH2jBn+gWTRjYfawW7YEvd4R+5kmk5z G9tQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793771947; x=1794376747; 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=vcGVtTeRbNMuJZikTeTy/aVLP/b0ijAI9oZ17pCLwwI=; b=WqRqg4EGbpFBHmwcYXXxquPzBz/q1IFMthUjMm2bkA1B3iWIyNd6wRhiWueEPi0T2u oogRMj4PuxJa+kcIbp9goOOwsvEAS+cwLS0TqS38oXHKkeiEO/6sSU/PhuYr8MfLR3K9 3WsG0fDOWe4DK80UubSoCPYf9zI8VsqmJPZxOSZpzEK+Pkb1yORy1frPcfC42qnvTiJR NzCKiX4r27aJcBqWcY3vpcoXjgjRtIiiMBZc3w6HoQpxexz+G8BytvC2LpcfDUXUJbXb +5E1zn4AMsKl3suAypX6C0lwqsm+VVllkrld5llAS3nmoH2hcAdbueERcHGsUHySWWiH 0cjg== X-Forwarded-Encrypted: i=1; AKwUvBzRFvPU7h8S+MT1pq/2XiH97hCv3eo/LieoXbptH+rRGcT5CpOsm3VpFIHkgigCtECQqHM8D7z5b7+QCwg=@vger.kernel.org X-Gm-Message-State: APuU4Z+MzBlxlLhtdz01xDSTH8iBOVhqGCiTcWrc8NedoZoWcMwLM1nC CdMKrPPEepsqSWOV+z9NRpr8JMelrPXyFNeJ91P5jW8xgKdIWewOU34G X-Gm-Gg: AYBFou129Ie9A9DED22bIw97la8jia4D+VwGbP0sINLuPxjKsEwujmn9fr7wQq7CBti 7Gb/oovusrbZNt6aWeaP1ZgpMhTNuzOxxYgH/cIY+JPzIDdFctWZxNjaf1V82QxuusmE/AkPhky rerfjagzSuEMMCi0J1tVCXUv4aNihijQxcVFf1i6OfAjlXcozhYZG7HnYbtjaZUbC1n6n5w3U62 84FX2DWP/meKh/bmNpQzBZLQ2akFOrh87mQUVPfcFkaOxBS6Bk38UCHVDAvFm23wnuebKJNJQyP BJGi7BLOmJvG764H704ZwVlqdH1jQtYV02o+itTLtb+cMuMHaqQ+Ug+w5ZI01iQmpXFPVFawIFV 5+QL7C62HjKCLkd6husphRBi7ziLzOIded/ThP2KUD3SLvtDA6u+hUJPIt1Wob/YMPkdpo7Ynnc eA5tO6b9fBGF3rnb3a24Fnwaa4QOG/1nl8jzYPz4Bi4GVMdeyWakanauMFmsvSiYcwrD91nyvPx +goGZGgAdRu64koLrdKVzJF26Ms6dWVt0Qp8pW/OYGTrHjck1bHOqmS5eKXsbuqrihFkzQ9nGAm UNfBI5RqkrP42evvYPYmnEQN1orzCgcQrhH2ZxePHKwuLxtkTzLADv+0mOyfz8GLML4DEM1lAej fikI3abfbOET+C7t74DfdIkWEWy+UciMtIqXhVk21clMlIL9ETm1m3cPeS9gffE2MmhRLAmbEj8 ROZdypxH0IIA6sIaI+FuiiTOI= X-Received: by 2002:a17:90a:d887:b0:3ac:8af9:4a77 with SMTP id 98e67ed59e1d1-3ae897c94e8mr13520420a91.10.1793771947282; Tue, 03 Nov 2026 21:59:07 -0800 (PST) Received: from ryzen.lan ([2601:644:8000:37f::e34]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3b07c9928c4sm7840110a91.15.2026.11.03.21.59.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Nov 2026 21:59:05 -0800 (PST) From: Rosen Penev To: linux-mips@vger.kernel.org, Thomas Bogendoerfer , Stephen Boyd Cc: Brian Masney , Jerome Brunet , Alban Bedel , Antony Pavlov , linux-kernel@vger.kernel.org (open list), linux-clk@vger.kernel.org (open list:COMMON CLK FRAMEWORK) Subject: [PATCH 8/8] clk: ath79: share the fractional PLL calculation Date: Tue, 3 Nov 2026 21:58:52 -0800 Message-ID: <20261104055852.152340-9-rosenp@gmail.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261104055852.152340-1-rosenp@gmail.com> References: <20261104055852.152340-1-rosenp@gmail.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 AR934x, QCA953x and QCA955x compute their CPU and DDR PLL rates with the same formula, ref / ref_div * (nint + nfrac / frac) / 2^out_div, written three different ways. Use one helper for all of them, with 64-bit intermediates. That fixes the QCA955x DDR PLL rate, whose nfrac * ref product could overflow 32 bits: with a 40 MHz reference clock it did for any nfrac above 107, and with 25 MHz for any above 171. The other rates are unchanged, as checked against the old code with random register values. Signed-off-by: Rosen Penev --- drivers/clk/clk-ath79.c | 47 +++++++++++++---------------------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/drivers/clk/clk-ath79.c b/drivers/clk/clk-ath79.c index 8086b4f6378c..f9a8c9b9aa24 100644 --- a/drivers/clk/clk-ath79.c +++ b/drivers/clk/clk-ath79.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -21,7 +22,6 @@ #include #include -#include #include "clk-ath79.h" @@ -189,24 +189,17 @@ static int __init ar933x_clocks_init(void __iomem *pll_base) ref_div * out_div * ahb_div); } -static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, - u32 frac, u32 out_div) +/* a fractional PLL: ref / ref_div * (nint + nfrac / frac) / 2^out_div */ +static unsigned long __init ath79_pll_rate(unsigned long ref, u32 ref_div, + u32 nint, u32 nfrac, u32 frac, + u32 out_div) { - u64 t; - u32 ret; + unsigned long rate; - t = ref; - t *= nint; - do_div(t, ref_div); - ret = t; + rate = div_u64((u64)ref * nint, ref_div); + rate += div_u64((u64)ref * nfrac, ref_div * frac); - t = ref; - t *= nfrac; - do_div(t, ref_div * frac); - ret += t; - - ret /= (1 << out_div); - return ret; + return rate >> out_div; } static int __init ar934x_clocks_init(void __iomem *pll_base) @@ -243,8 +236,7 @@ static int __init ar934x_clocks_init(void __iomem *pll_base) frac = 1 << 6; } - cpu_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, - nfrac, frac, out_div); + cpu_pll = ath79_pll_rate(ref_rate, ref_div, nint, nfrac, frac, out_div); pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG); if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { @@ -263,8 +255,7 @@ static int __init ar934x_clocks_init(void __iomem *pll_base) frac = 1 << 10; } - ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, - nfrac, frac, out_div); + ddr_pll = ath79_pll_rate(ref_rate, ref_div, nint, nfrac, frac, out_div); iounmap(dpll_base); @@ -325,9 +316,7 @@ static int __init qca953x_clocks_init(void __iomem *pll_base) nint = FIELD_GET(QCA953X_PLL_CPU_CONFIG_NINT, pll); frac = FIELD_GET(QCA953X_PLL_CPU_CONFIG_NFRAC, pll); - cpu_pll = nint * ref_rate / ref_div; - cpu_pll += frac * (ref_rate >> 6) / ref_div; - cpu_pll /= (1 << out_div); + cpu_pll = ath79_pll_rate(ref_rate, ref_div, nint, frac, 1 << 6, out_div); pll = __raw_readl(pll_base + QCA953X_PLL_DDR_CONFIG_REG); out_div = FIELD_GET(QCA953X_PLL_DDR_CONFIG_OUTDIV, pll); @@ -335,9 +324,7 @@ static int __init qca953x_clocks_init(void __iomem *pll_base) nint = FIELD_GET(QCA953X_PLL_DDR_CONFIG_NINT, pll); frac = FIELD_GET(QCA953X_PLL_DDR_CONFIG_NFRAC, pll); - ddr_pll = nint * ref_rate / ref_div; - ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4); - ddr_pll /= (1 << out_div); + ddr_pll = ath79_pll_rate(ref_rate, ref_div, nint, frac, 1 << 10, out_div); clk_ctrl = __raw_readl(pll_base + QCA953X_PLL_CLK_CTRL_REG); @@ -388,9 +375,7 @@ static int __init qca955x_clocks_init(void __iomem *pll_base) nint = FIELD_GET(QCA955X_PLL_CPU_CONFIG_NINT, pll); frac = FIELD_GET(QCA955X_PLL_CPU_CONFIG_NFRAC, pll); - cpu_pll = nint * ref_rate / ref_div; - cpu_pll += frac * ref_rate / (ref_div * (1 << 6)); - cpu_pll /= (1 << out_div); + cpu_pll = ath79_pll_rate(ref_rate, ref_div, nint, frac, 1 << 6, out_div); pll = __raw_readl(pll_base + QCA955X_PLL_DDR_CONFIG_REG); out_div = FIELD_GET(QCA955X_PLL_DDR_CONFIG_OUTDIV, pll); @@ -398,9 +383,7 @@ static int __init qca955x_clocks_init(void __iomem *pll_base) nint = FIELD_GET(QCA955X_PLL_DDR_CONFIG_NINT, pll); frac = FIELD_GET(QCA955X_PLL_DDR_CONFIG_NFRAC, pll); - ddr_pll = nint * ref_rate / ref_div; - ddr_pll += frac * ref_rate / (ref_div * (1 << 10)); - ddr_pll /= (1 << out_div); + ddr_pll = ath79_pll_rate(ref_rate, ref_div, nint, frac, 1 << 10, out_div); clk_ctrl = __raw_readl(pll_base + QCA955X_PLL_CLK_CTRL_REG); -- 2.56.0