From patchwork Mon Feb 10 16:00:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Stein X-Patchwork-Id: 13968124 Received: from mx1.tq-group.com (mx1.tq-group.com [93.104.207.81]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A6D624BCFA for ; Mon, 10 Feb 2025 16:00:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=93.104.207.81 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739203229; cv=none; b=Ld+ePK4G9bQdn/mBSMfy+e93Hl1T0U1mLI6KveDFufeqPFBGuq6OXXnlS/jIxZ8AZ0t7nf/cvQ46MXcqR32ScqyZTfvIvlbSKlmCtHXlS+aclxqdFcEh2YWq0jpuZzlUIiGGGOhiOLtizujGX3217J3D4xJ2RMeecmBPOo5UEPI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739203229; c=relaxed/simple; bh=tQwnWjXakU4FhLJZxL5UozDh6cXB5o8GNeuPhlrPqIQ=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=LL/oAZaiBk4yP06gh3d9rC6SWhlK9eptYYco8dCTVFZVKdPPc4sKPSIsa3bMJpI3ytyuTRmGpXoFmlF2s4pfN0t/s96DeOQszIRPixM9ejQGoIWL96kIGNaVG/xkJeVuxYOJLFIhFJu6dFGLcM/ia4IYWHVgB3KK50rZT33t5qU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ew.tq-group.com; spf=pass smtp.mailfrom=ew.tq-group.com; dkim=pass (2048-bit key) header.d=tq-group.com header.i=@tq-group.com header.b=Lka6XTnC; dkim=fail (0-bit key) header.d=ew.tq-group.com header.i=@ew.tq-group.com header.b=qEnx/Gh/ reason="key not found in DNS"; arc=none smtp.client-ip=93.104.207.81 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ew.tq-group.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ew.tq-group.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tq-group.com header.i=@tq-group.com header.b="Lka6XTnC"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=ew.tq-group.com header.i=@ew.tq-group.com header.b="qEnx/Gh/" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1739203226; x=1770739226; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=bOMbba0A1eJVbzvPVV/zSeVjS+2bYN5BuJsAKJgZbqQ=; b=Lka6XTnCmQeHFf2BlpNZmKYRXr47EL5tuapb9MrCrTxNSBGdMwfLRYnv 1h9KIzpGM2wlhst4leD80FS4XsacUPEs5vXqwUUr4JzgK0sLMTXDi3M6W agdgAI9p62X5ScWoPtnz7xTSMDmogGyZBArGDcRDDsky3MxHFpigv1jHb IrSYaPGJFec7SJoH2aekpMoAsX9XJ2Adw69ByUHqeKoYeN0zsnVSa6rt4 VOJxXv4vXGcwtvIn6tO7TYvOAnlLDF2B7a7a2PIZYFQ9k0y67xbZWb2J5 4/Ei+Vy9lwRw3PDRhy0GMmUSZucs/VSXDS4BSjpvY9PNsvHzguDr/DDnU w==; X-CSE-ConnectionGUID: 3yDWKte7RaiwtEJDQl2RIw== X-CSE-MsgGUID: 2qOTWrZIQbygIG189aMiXA== X-IronPort-AV: E=Sophos;i="6.13,274,1732575600"; d="scan'208";a="41723662" Received: from vmailcow01.tq-net.de ([10.150.86.48]) by mx1.tq-group.com with ESMTP; 10 Feb 2025 17:00:20 +0100 X-CheckPoint: {67AA2294-B-6E0A4539-DBC44C3A} X-MAIL-CPID: 6A27F41018F237B18955565C9E442D6C_1 X-Control-Analysis: str=0001.0A006366.67AA2298.0035,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 16F441615E5; Mon, 10 Feb 2025 17:00:14 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ew.tq-group.com; s=dkim; t=1739203216; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=bOMbba0A1eJVbzvPVV/zSeVjS+2bYN5BuJsAKJgZbqQ=; b=qEnx/Gh/VTeWQNQT5jNkge6mW56hxuqyWi90pTqAu2L+2k0WZuqRoraM4Xqd13ckuUnFcE yrS5gm6sT3Y9HViD6HDMUXKqH0hgOC7Zt4aBWgLXtZjSH5P8InGYdWe/PtO86hWyscLs6+ aHa60xhRFBZW0z5gFSj9YOecjP6Utb1Zfk8+Nk5r2G2Ak6M5xz6blbFvM3ihrrb5gbhiZo alLfxRtrsvBUjWRgaT0MaGjArx0SbT9w+IEJMIfNDuvxmMoyx2bcbPQuLc7uc95X27lwWS B4EJ8mgxeizhB2AcQoUp1wqnTfonFEuKZXdPcXo+N3b/PgPOTjwxm0G6CAyYwA== From: Alexander Stein To: Abel Vesa , Peng Fan , Michael Turquette , Stephen Boyd , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Alexander Stein , linux-clk@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 1/3] clk: imx: clk-fracn-gppll: Do not access num/denom register for integer PLL Date: Mon, 10 Feb 2025 17:00:09 +0100 Message-Id: <20250210160012.783446-1-alexander.stein@ew.tq-group.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: imx@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 Similar to clk_fracn_gppll_set_rate(), do not access the numerator and denominator register for integer PLL. Set MFD/MFN to 0 instead, so the table lookup will match. See i.MX93 RM section 74.5.2.1 (PLL memory map) for ARMPLL, addresses 0x40 and 0x50 are not listed/reserved. Signed-off-by: Alexander Stein --- drivers/clk/imx/clk-fracn-gppll.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c index 85771afd4698a..3aef548110e25 100644 --- a/drivers/clk/imx/clk-fracn-gppll.c +++ b/drivers/clk/imx/clk-fracn-gppll.c @@ -154,17 +154,24 @@ static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned lon { struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); const struct imx_fracn_gppll_rate_table *rate_table = pll->rate_table; - u32 pll_numerator, pll_denominator, pll_div; + u32 pll_div; u32 mfi, mfn, mfd, rdiv, odiv; u64 fvco = parent_rate; long rate = 0; int i; - pll_numerator = readl_relaxed(pll->base + PLL_NUMERATOR); - mfn = FIELD_GET(PLL_MFN_MASK, pll_numerator); + if (pll->flags & CLK_FRACN_GPPLL_FRACN) { + u32 pll_numerator, pll_denominator; + + pll_numerator = readl_relaxed(pll->base + PLL_NUMERATOR); + mfn = FIELD_GET(PLL_MFN_MASK, pll_numerator); - pll_denominator = readl_relaxed(pll->base + PLL_DENOMINATOR); - mfd = FIELD_GET(PLL_MFD_MASK, pll_denominator); + pll_denominator = readl_relaxed(pll->base + PLL_DENOMINATOR); + mfd = FIELD_GET(PLL_MFD_MASK, pll_denominator); + } else { + mfd = 0; + mfn = 0; + } pll_div = readl_relaxed(pll->base + PLL_DIV); mfi = FIELD_GET(PLL_MFI_MASK, pll_div); From patchwork Mon Feb 10 16:00:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Stein X-Patchwork-Id: 13968125 Received: from mx1.tq-group.com (mx1.tq-group.com [93.104.207.81]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DEEBE24BCF7 for ; Mon, 10 Feb 2025 16:00:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=93.104.207.81 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739203230; cv=none; b=JzfiPtf4YabQpvJP3ck0rJCItioCi+UyyF6WD0uFJv1ueBbkk/rTmLLBG/2naocxL8zqaJQk3+Q8cgrcQ9ACudkpUsfKCs1rLimBtkjrPFa/2ztiQ1TPi1fQlxiE2+/aIRrAy4lMQpRa5sr+cqhAnTKcT0jOjHZIjcZnC+4pqDI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739203230; c=relaxed/simple; bh=S7WCCKn1OYpTJTr+0F5iFJ2o0NBwptWevzmCfT/sCwU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=GNXyOBcchssQtePFEqcgtGtOC6vliSAoPBY9NyZ4ymZInu+0T+Afwy2+G+tH2OlxzrZtC+lj6iWNmZnz+vrjcspB9SdekA/ZI9eS/FaXacprANVksdDG+cE+zn7P8OaN3Ja9m0ebmcd429RBSRCo9CErae0ojWQsfvunCwHCtrs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ew.tq-group.com; spf=pass smtp.mailfrom=ew.tq-group.com; dkim=pass (2048-bit key) header.d=tq-group.com header.i=@tq-group.com header.b=a7q8Ycyo; dkim=fail (0-bit key) header.d=ew.tq-group.com header.i=@ew.tq-group.com header.b=MJEPmEx0 reason="key not found in DNS"; arc=none smtp.client-ip=93.104.207.81 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ew.tq-group.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ew.tq-group.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tq-group.com header.i=@tq-group.com header.b="a7q8Ycyo"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=ew.tq-group.com header.i=@ew.tq-group.com header.b="MJEPmEx0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1739203228; x=1770739228; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oJRfGne+1TV9ashFe4VvW6fRk2CL7nzeA1eVvRlpELA=; b=a7q8Ycyo37MgbH2uFZeKSn1xJzwqdS5RDPdMrotM2ur1+It1LFSNYUB+ iBC7EQ3vkeij224pfkUlZZuEpbM82tWl69m4JxYKymag/kF3wX7wf14XX wOHyws8qakcEDx1DN0EEiuNH2ebmrDNvJj4m+pVffICfm6Py5rNM08tA8 Zr8gMJNRDHuwezLR62N5hJ07Vz3ebi42Bw//0BAkep04mk/rwFNvOnU33 mJ0IfnF4I8rVpHGIHF7P4kU5m+A4wqcYPqx3lk2IzFGNX+YPhTiwqQ1oL aMUTpCwT4KniqaF98zzwGu8UDUmolUC4n49EAbJleCrUF0SyvieW0/hap w==; X-CSE-ConnectionGUID: 7bi8+9SGRBGJDm5SGNlRTQ== X-CSE-MsgGUID: VOKpVHugRuC/h3BGDRYaeg== X-IronPort-AV: E=Sophos;i="6.13,274,1732575600"; d="scan'208";a="41723664" Received: from vmailcow01.tq-net.de ([10.150.86.48]) by mx1.tq-group.com with ESMTP; 10 Feb 2025 17:00:25 +0100 X-CheckPoint: {67AA2299-15-28232521-C0C2250B} X-MAIL-CPID: C697A590134ACF1114AF175211420857_4 X-Control-Analysis: str=0001.0A006366.67AA2299.00E4,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id E899B168250; Mon, 10 Feb 2025 17:00:20 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ew.tq-group.com; s=dkim; t=1739203221; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oJRfGne+1TV9ashFe4VvW6fRk2CL7nzeA1eVvRlpELA=; b=MJEPmEx0leaC3HMJHT8d+3y3TIJ+bqMiLiiuFGMoZk7/fn8RQsGuH8CcNycwyIpJQJib5G IfWedpQhjt8/b+W9LCQ3897/sQk9v2lv4XN5uUjlmV/ZxZRxZgqjgp/mcr2OljSqbAbrPf FILMW8YgU8Wmf20mpMxEZK3vMFgcFFlhUD8fvdn0C69T2UnOeKMeyzKbtdK9zES5U+0LPS aFvESH24NWQT3ETJP5xQPYcxMsKQd1Ym9mUmf6xFBYLeFmuamlvhJMqXFtVWSVnxQKRipZ W9Ep5oYoNbT4NvXu42fSJp2pOeL1WEgT0TKmaTwwyJWF5IcchWuuUvHRNCNlIw== From: Alexander Stein To: Abel Vesa , Peng Fan , Michael Turquette , Stephen Boyd , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Alexander Stein , linux-clk@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 2/3] clk: imx: clk-fracn-gppll: Refactor clk_fracn_gppll_calc_rate Date: Mon, 10 Feb 2025 17:00:10 +0100 Message-Id: <20250210160012.783446-2-alexander.stein@ew.tq-group.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250210160012.783446-1-alexander.stein@ew.tq-group.com> References: <20250210160012.783446-1-alexander.stein@ew.tq-group.com> Precedence: bulk X-Mailing-List: imx@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 Move the frequency calculation into its dedicated function for multiple usage. No functional change. Signed-off-by: Alexander Stein --- drivers/clk/imx/clk-fracn-gppll.c | 54 ++++++++++++++++++------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c index 3aef548110e25..a7d57fbe93196 100644 --- a/drivers/clk/imx/clk-fracn-gppll.c +++ b/drivers/clk/imx/clk-fracn-gppll.c @@ -150,35 +150,15 @@ static long clk_fracn_gppll_round_rate(struct clk_hw *hw, unsigned long rate, return rate_table[pll->rate_count - 1].rate; } -static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +static long clk_fracn_gppll_calc_rate(struct clk_fracn_gppll *pll, u32 mfn, + u32 mfd, u32 mfi, u32 rdiv, u32 odiv, + unsigned long parent_rate) { - struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); const struct imx_fracn_gppll_rate_table *rate_table = pll->rate_table; - u32 pll_div; - u32 mfi, mfn, mfd, rdiv, odiv; u64 fvco = parent_rate; long rate = 0; int i; - if (pll->flags & CLK_FRACN_GPPLL_FRACN) { - u32 pll_numerator, pll_denominator; - - pll_numerator = readl_relaxed(pll->base + PLL_NUMERATOR); - mfn = FIELD_GET(PLL_MFN_MASK, pll_numerator); - - pll_denominator = readl_relaxed(pll->base + PLL_DENOMINATOR); - mfd = FIELD_GET(PLL_MFD_MASK, pll_denominator); - } else { - mfd = 0; - mfn = 0; - } - - pll_div = readl_relaxed(pll->base + PLL_DIV); - mfi = FIELD_GET(PLL_MFI_MASK, pll_div); - - rdiv = FIELD_GET(PLL_RDIV_MASK, pll_div); - odiv = FIELD_GET(PLL_ODIV_MASK, pll_div); - /* * Sometimes, the recalculated rate has deviation due to * the frac part. So find the accurate pll rate from the table @@ -222,6 +202,34 @@ static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned lon return (unsigned long)fvco; } +static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); + u32 pll_div; + u32 mfi, mfn, mfd, rdiv, odiv; + + if (pll->flags & CLK_FRACN_GPPLL_FRACN) { + u32 pll_numerator, pll_denominator; + + pll_numerator = readl_relaxed(pll->base + PLL_NUMERATOR); + mfn = FIELD_GET(PLL_MFN_MASK, pll_numerator); + + pll_denominator = readl_relaxed(pll->base + PLL_DENOMINATOR); + mfd = FIELD_GET(PLL_MFD_MASK, pll_denominator); + } else { + mfd = 0; + mfn = 0; + } + + pll_div = readl_relaxed(pll->base + PLL_DIV); + mfi = FIELD_GET(PLL_MFI_MASK, pll_div); + + rdiv = FIELD_GET(PLL_RDIV_MASK, pll_div); + odiv = FIELD_GET(PLL_ODIV_MASK, pll_div); + + return clk_fracn_gppll_calc_rate(pll, mfn, mfd, mfi, rdiv, odiv, parent_rate); +} + static int clk_fracn_gppll_wait_lock(struct clk_fracn_gppll *pll) { u32 val; From patchwork Mon Feb 10 16:00:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Stein X-Patchwork-Id: 13968126 Received: from mx1.tq-group.com (mx1.tq-group.com [93.104.207.81]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 801632451EA for ; Mon, 10 Feb 2025 16:00:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=93.104.207.81 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739203235; cv=none; b=TrGjTmnAPNA5eAADa63dyPDtt1X0f1ZKkoe2yCDwdahh97hsl3flljkxOxCh1+26/1hm05yExWti+iyUpQqTTxpxqQh0O5DjH/3z7UpUPLSp1u0AVFpl/Dun0nXd/HQDJCZ8h6gXdG3TtRr8q35XAnCu/VCBZdMhrBUKt/cXlqY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739203235; c=relaxed/simple; bh=WmOyrQx2zbGj4iXjDTQFGQY/rayYa5Dxker5hffvQBc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=LX+/4O6htOHuSUfPQQ2q8XhnGSkxtGu4GvKGDPJkiewdz0a7P3bCA0H3AD+Q/+AWxWSBVimD9ifml0FSqDqvj+0dt3frMNOOBD+sTYPniouon7p4lIARpgkwG/dAkslqGexfBzzDwNhYR8/HLEqPaf5WNDiE9COsykZmheCE7Ro= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ew.tq-group.com; spf=pass smtp.mailfrom=ew.tq-group.com; dkim=pass (2048-bit key) header.d=tq-group.com header.i=@tq-group.com header.b=e8VbRvn7; dkim=fail (0-bit key) header.d=ew.tq-group.com header.i=@ew.tq-group.com header.b=jPnJdWRY reason="key not found in DNS"; arc=none smtp.client-ip=93.104.207.81 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ew.tq-group.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ew.tq-group.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tq-group.com header.i=@tq-group.com header.b="e8VbRvn7"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=ew.tq-group.com header.i=@ew.tq-group.com header.b="jPnJdWRY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1739203233; x=1770739233; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=eQ7wsV90ZTZbBq8whAYKYY3CfgfedQ5rrh/FaK6/OBI=; b=e8VbRvn7HVAHKYpCJ2B1KpOgxr4wm41V1kRTJ3gQYG5qbAZt8PHcIRMo twH6xcbrH7Tlo3qKmq39fm2XRB3B+D9Gpl44BkqwZmB8aDKZd+1Vt2qiq v1X9xHAEemlFI0GNPYAS1PBPQZPF0aHc62m+6C/68SaMrYuVy+h7zJ2ES HCAss2KVfve5KpSFmBBiaZ4wo+95XxOmnlaxokqhqmJAM+N/kxumxM1W7 HqSOtZjl8GAfjTaj7axr1hk11E/jyIYcdGWxa6CLqL82e70D71TqbVhJa shqlSPS9u1vaQBAszINtAiJiwCOOgaPotlH49ByVWxAlVZ2jnKvX2YEP7 A==; X-CSE-ConnectionGUID: wUPPNZwMTgKS+CfX2ikgcg== X-CSE-MsgGUID: ksmEptQWQkaRFisJ/Nm68Q== X-IronPort-AV: E=Sophos;i="6.13,274,1732575600"; d="scan'208";a="41723666" Received: from vmailcow01.tq-net.de ([10.150.86.48]) by mx1.tq-group.com with ESMTP; 10 Feb 2025 17:00:31 +0100 X-CheckPoint: {67AA229F-B-EBA888C4-C1AC8B84} X-MAIL-CPID: E8F7D8D262BF096E5F9B3401FCF79116_0 X-Control-Analysis: str=0001.0A006368.67AA229F.00BA,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 6467616737F; Mon, 10 Feb 2025 17:00:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ew.tq-group.com; s=dkim; t=1739203226; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eQ7wsV90ZTZbBq8whAYKYY3CfgfedQ5rrh/FaK6/OBI=; b=jPnJdWRYowhIESTjwwMIX2UEWcpNhtWais5YdLTfi9Xcq6++VxN0lYB9H99XfDYqxOQ8hj UWCM30w6gFMBA+abvKrlYNFBXZWFUmeDvqzxZdggIJ7DT1Bra9iT0IsDFrPA1doyYTS2Cv J1e3+XuTZyAQ/cFs1jC1YYreikkooBgAbxM5sn9YLnzMHZ8FuqmADw76cTnHSaQ2NCFnji KUl9eDtlmyPmRvLyWs6aA6Hw1I9TLR9Ev6xt+CV2Ps4F7AnN1TdiH6y309Jstd98R2QjQA IMUHIF17oiFoerGdXADXNr5iyHwZN2C0XAC/5sI+HFjKopTBQqo8grdDKWPPfA== From: Alexander Stein To: Abel Vesa , Peng Fan , Michael Turquette , Stephen Boyd , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Alexander Stein , linux-clk@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 3/3] clk: imx: clk-fracn-gppll: Support dynamic rates Date: Mon, 10 Feb 2025 17:00:11 +0100 Message-Id: <20250210160012.783446-3-alexander.stein@ew.tq-group.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250210160012.783446-1-alexander.stein@ew.tq-group.com> References: <20250210160012.783446-1-alexander.stein@ew.tq-group.com> Precedence: bulk X-Mailing-List: imx@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 The fracn gppll PLL so far only supports rates from a rate table passed during initialization. Calculating PLL settings dynamically helps audio applications to get their desired rates, so support for this is added in this patch. The strategy to get to the PLL setting for a rate is: - The rate table is searched for suitable rates, so for standard rates the same settings are used as without this patch - Then try to only adjust mfn, on fractional PLLs only, which specifies the fractional part of the PLL. This setting can be changed without glitches on the output and is therefore preferred - As a last resort the best settings are calculated dynamically Implementation is inspired by commit b09c68dc57c9d ("clk: imx: pll14xx: Support dynamic rates") Signed-off-by: Alexander Stein --- This is the first time I'm touching PLL code, I might be missing things or not being aware of important aspects when it comes to PLL. Thus this is a RFC drivers/clk/imx/clk-fracn-gppll.c | 203 ++++++++++++++++++++++++++---- 1 file changed, 181 insertions(+), 22 deletions(-) diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c index a7d57fbe93196..68c5b4a95efbe 100644 --- a/drivers/clk/imx/clk-fracn-gppll.c +++ b/drivers/clk/imx/clk-fracn-gppll.c @@ -25,6 +25,12 @@ #define PLL_NUMERATOR 0x40 #define PLL_MFN_MASK GENMASK(31, 2) +#define PLL_MFI_MIN 0x2 +#define PLL_MFI_MAX 0x1ff +#define PLL_MFN_MIN 0x0 +#define PLL_MFN_MAX 0x3fffffff +#define PLL_MFD_MIN 0x1 +#define PLL_MFD_MAX 0x3fffffff #define PLL_DENOMINATOR 0x50 #define PLL_MFD_MASK GENMASK(29, 0) @@ -134,21 +140,6 @@ imx_get_pll_settings(struct clk_fracn_gppll *pll, unsigned long rate) return NULL; } -static long clk_fracn_gppll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); - const struct imx_fracn_gppll_rate_table *rate_table = pll->rate_table; - int i; - - /* Assuming rate_table is in descending order */ - for (i = 0; i < pll->rate_count; i++) - if (rate >= rate_table[i].rate) - return rate_table[i].rate; - - /* return minimum supported value */ - return rate_table[pll->rate_count - 1].rate; -} static long clk_fracn_gppll_calc_rate(struct clk_fracn_gppll *pll, u32 mfn, u32 mfd, u32 mfi, u32 rdiv, u32 odiv, @@ -202,6 +193,174 @@ static long clk_fracn_gppll_calc_rate(struct clk_fracn_gppll *pll, u32 mfn, return (unsigned long)fvco; } +static u32 clk_fracn_gppll_calc_mfi(int rdiv, unsigned long fvco, + unsigned long fref) +{ + u32 mfi; + + /* fvco = fref / rdiv * mfi */ + mfi = DIV_ROUND_CLOSEST(fvco * rdiv, fref); + return clamp_t(u32, mfi, PLL_MFI_MIN, PLL_MFI_MAX); +} + +static long clk_fracn_gppll_calc_mfn(int mfd, int mfi, int odiv, int rdiv, + unsigned long rate, unsigned long prate) +{ + unsigned long tmp; + long mfn; + + /* calc mfn = ((rate * odiv * rdiv / prate) - mfi) * mfd */ + tmp = rate * odiv * rdiv - (mfi * prate); + mfn = DIV_ROUND_CLOSEST(tmp * mfd, prate); + return clamp_t(long, mfn, PLL_MFN_MIN, PLL_MFN_MAX); +} + +static void clk_fracn_gppll_calc_settings(struct clk_fracn_gppll *pll, unsigned long rate, + unsigned long prate, struct imx_fracn_gppll_rate_table *t) +{ + u32 pll_denominator, pll_numerator, pll_div; + u32 mfi, mfn, mfd, rdiv, odiv; + long fout, rate_min, rate_max, dist, best = LONG_MAX; + const struct imx_fracn_gppll_rate_table *tt; + + /* + * PLL constrains: + * + * a) 1 <= MFN <= 0x3fffffff (fractional only) + * b) 1 <= MFD <= 0x3fffffff (fractional only) + * c) 2 <= MFI <= 0x1ff + * d) 1 <= RDIV <= 7 + * e) 2 <= ODIV <= 255 + * f) -2 <= MFN/MFD <= 2 + * g) 20MHz <= (Fref / rdiv) <= 40MHz + * h) 2.5GHz <= Fvco <= 5Ghz + * + * Fvco = (Fref / rdiv) * (MFI + MFN / MFD) + * Fout = Fvco / odiv + */ + + /* First try if we can get the desired rate from one of the static entries */ + tt = imx_get_pll_settings(pll, rate); + if (tt) { + pr_debug("%s: in=%ld, want=%ld, Using PLL setting from table\n", + clk_hw_get_name(&pll->hw), prate, rate); + t->rate = tt->rate; + t->mfi = tt->mfi; + t->mfn = tt->mfn; + t->mfd = tt->mfd; + t->rdiv = tt->rdiv; + t->odiv = tt->odiv; + return; + } + + /* glitch free MFN adjustment only for fractional PLL */ + if (pll->flags & CLK_FRACN_GPPLL_FRACN) { + pll_numerator = readl_relaxed(pll->base + PLL_NUMERATOR); + + pll_denominator = readl_relaxed(pll->base + PLL_DENOMINATOR); + mfd = FIELD_GET(PLL_MFD_MASK, pll_denominator); + + pll_div = readl_relaxed(pll->base + PLL_DIV); + mfi = FIELD_GET(PLL_MFI_MASK, pll_div); + rdiv = FIELD_GET(PLL_RDIV_MASK, pll_div); + odiv = FIELD_GET(PLL_ODIV_MASK, pll_div); + + /* Then see if we can get the desired rate by only adjusting MFN (glitch free) */ + rate_min = clk_fracn_gppll_calc_rate(pll, PLL_MFN_MIN, mfd, mfi, rdiv, odiv, prate); + rate_max = clk_fracn_gppll_calc_rate(pll, PLL_MFN_MAX, mfd, mfi, rdiv, odiv, prate); + + if (rate >= rate_min && rate <= rate_max) { + mfn = clk_fracn_gppll_calc_mfn(mfd, mfi, odiv, rdiv, rate, prate); + pr_debug("%s: in=%ld, want=%ld Only adjust mfn %ld -> %d\n", + clk_hw_get_name(&pll->hw), prate, rate, + FIELD_GET(PLL_MFN_MASK, pll_numerator), mfn); + fout = clk_fracn_gppll_calc_rate(pll, mfn, mfd, mfi, rdiv, odiv, prate); + t->rate = (unsigned int)fout; + t->mfi = mfi; + t->mfn = mfn; + t->mfd = mfd; + t->rdiv = rdiv; + t->odiv = odiv; + return; + } + } + + /* Finally calculate best values */ + for (rdiv = 1; rdiv <= 7; rdiv++) { + if ((prate / rdiv) < 20000000) + continue; + if ((prate / rdiv) > 40000000) + continue; + + for (odiv = 2; odiv <= 255; odiv++) { + mfi = clk_fracn_gppll_calc_mfi(rdiv, rate * odiv, prate); + mfd = 1; + mfn = 0; + + /* Try integer PLL part only first */ + fout = clk_fracn_gppll_calc_rate(pll, mfn, mfd, mfi, rdiv, odiv, prate); + if (fout * odiv < 2500000000UL) + continue; + if (fout * odiv > 5000000000UL) + continue; + + if (pll->flags & CLK_FRACN_GPPLL_FRACN) { + if (!dist) { + /* Disable fractional part upon exact match */ + mfd = 1; + mfn = 0; + } else { + mfd = 100; + mfd = clamp(mfd, PLL_MFD_MIN, PLL_MFN_MAX); + + mfn = clk_fracn_gppll_calc_mfn(mfd, mfi, odiv, rdiv, rate, prate); + if ((mfn / mfd) > 2) + continue; + + fout = clk_fracn_gppll_calc_rate(pll, mfn, mfd, mfi, rdiv, odiv, prate); + if (fout * odiv < 2500000000) + continue; + if (fout * odiv > 5000000000) + continue; + } + } else { + mfd = 0; + mfn = 0; + } + + /* best match */ + dist = abs((long)rate - (long)fout); + if (dist < best) { + best = dist; + t->rate = (unsigned int)fout; + t->mfi = mfi; + t->mfn = mfn; + t->mfd = mfd; + t->rdiv = rdiv; + t->odiv = odiv; + + if (!dist) + goto found; + } + } + } +found: + pr_debug("%s: in=%lu, want=%lu got=%u (mfi=%u mfn=%u mfd=%u rdiv=%u odiv=%u)\n", + clk_hw_get_name(&pll->hw), prate, rate, t->rate, t->mfi, t->mfn, t->mfd, + t->rdiv, t->odiv); +} + +static long clk_fracn_gppll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); + struct imx_fracn_gppll_rate_table t; + + clk_fracn_gppll_calc_settings(pll, rate, *prate, &t); + + return t.rate; +} + static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); @@ -242,11 +401,11 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate, unsigned long prate) { struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); - const struct imx_fracn_gppll_rate_table *rate; + struct imx_fracn_gppll_rate_table rate; u32 tmp, pll_div, ana_mfn; int ret; - rate = imx_get_pll_settings(pll, drate); + clk_fracn_gppll_calc_settings(pll, drate, prate, &rate); /* Hardware control select disable. PLL is control by register */ tmp = readl_relaxed(pll->base + PLL_CTRL); @@ -266,13 +425,13 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate, tmp &= ~CLKMUX_BYPASS; writel_relaxed(tmp, pll->base + PLL_CTRL); - pll_div = FIELD_PREP(PLL_RDIV_MASK, rate->rdiv) | rate->odiv | - FIELD_PREP(PLL_MFI_MASK, rate->mfi); + pll_div = FIELD_PREP(PLL_RDIV_MASK, rate.rdiv) | rate.odiv | + FIELD_PREP(PLL_MFI_MASK, rate.mfi); writel_relaxed(pll_div, pll->base + PLL_DIV); readl(pll->base + PLL_DIV); if (pll->flags & CLK_FRACN_GPPLL_FRACN) { - writel_relaxed(rate->mfd, pll->base + PLL_DENOMINATOR); - writel_relaxed(FIELD_PREP(PLL_MFN_MASK, rate->mfn), pll->base + PLL_NUMERATOR); + writel_relaxed(rate.mfd, pll->base + PLL_DENOMINATOR); + writel_relaxed(FIELD_PREP(PLL_MFN_MASK, rate.mfn), pll->base + PLL_NUMERATOR); readl(pll->base + PLL_NUMERATOR); } @@ -296,7 +455,7 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate, ana_mfn = readl_relaxed(pll->base + PLL_STATUS); ana_mfn = FIELD_GET(PLL_MFN_MASK, ana_mfn); - WARN(ana_mfn != rate->mfn, "ana_mfn != rate->mfn\n"); + WARN(ana_mfn != rate.mfn, "ana_mfn != rate->mfn\n"); return 0; }