From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 A161B5D914; Tue, 23 Jan 2024 01:46:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705974417; cv=none; b=pLUj10tY+vbVAF3a3NoNBs/n+3l2JLQ6y/+lUSERroqc2icsM7yRheRxjdw3nVgPrvkItn5unwpOS6dZjTm+whsRqzeDtlrBej3ByVkaL0vPzpeaT00SZa1KAIuH1kM0mO4nVdzuW76aDzDdB7XFMFtLBDav/gzsLIBs/lmyv0I= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705974417; c=relaxed/simple; bh=AWPZNJGqI30VwnJX4zzFbcH9AZ+r5Cakl8eytXPYGSY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Yt6cibWuPJIjaZtDjsUu1p5zM4+yaG8qojqNOrtfAdSe1Ogwl4ND6zRqHQcE/gUAsXhfQbxTbr34Wjv56MNxjCSZCVq9CsMr0gYJZPujquOQG0JgPQuoUXQesOCB0CZ4Ig9tdWU8i39cVTXALagy3NxNOMb7zhrm4XslAAM4GY4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=uNV3C/Dy; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="uNV3C/Dy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 64D72C43399; Tue, 23 Jan 2024 01:46:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1705974417; bh=AWPZNJGqI30VwnJX4zzFbcH9AZ+r5Cakl8eytXPYGSY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uNV3C/DyRWgUh59doNdiDRVbD1HSW79NYofeh/S1cIOFvtKPZ21bkTp6aUpDWEe5S 8iZqh0YKr4Ub3Md5/GYD1VJ1wQ5BivU3odqepWf4tOdczK9CMOb+6cyzSo41gBoBYD iLmvma+A/7DIa+OKjIAoVQkxcDA+SMWz7GyW69eA= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Jay Buddhabhatti , Stephen Boyd , Sasha Levin Subject: [PATCH 5.15 218/374] drivers: clk: zynqmp: update divider round rate logic Date: Mon, 22 Jan 2024 15:57:54 -0800 Message-ID: <20240122235752.237149353@linuxfoundation.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240122235744.598274724@linuxfoundation.org> References: <20240122235744.598274724@linuxfoundation.org> User-Agent: quilt/0.67 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 5.15-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jay Buddhabhatti [ Upstream commit 1fe15be1fb613534ecbac5f8c3f8744f757d237d ] Currently zynqmp divider round rate is considering single parent and calculating rate and parent rate accordingly. But if divider clock flag is set to SET_RATE_PARENT then its not trying to traverse through all parent rate and not selecting best parent rate from that. So use common divider_round_rate() which is traversing through all clock parents and its rate and calculating proper parent rate. Fixes: 3fde0e16d016 ("drivers: clk: Add ZynqMP clock driver") Signed-off-by: Jay Buddhabhatti Link: https://lore.kernel.org/r/20231129112916.23125-3-jay.buddhabhatti@amd.com Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/zynqmp/divider.c | 66 +++--------------------------------- 1 file changed, 5 insertions(+), 61 deletions(-) diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c index 47a199346ddf..e25c76ff2739 100644 --- a/drivers/clk/zynqmp/divider.c +++ b/drivers/clk/zynqmp/divider.c @@ -110,52 +110,6 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw, return DIV_ROUND_UP_ULL(parent_rate, value); } -static void zynqmp_get_divider2_val(struct clk_hw *hw, - unsigned long rate, - struct zynqmp_clk_divider *divider, - u32 *bestdiv) -{ - int div1; - int div2; - long error = LONG_MAX; - unsigned long div1_prate; - struct clk_hw *div1_parent_hw; - struct zynqmp_clk_divider *pdivider; - struct clk_hw *div2_parent_hw = clk_hw_get_parent(hw); - - if (!div2_parent_hw) - return; - - pdivider = to_zynqmp_clk_divider(div2_parent_hw); - if (!pdivider) - return; - - div1_parent_hw = clk_hw_get_parent(div2_parent_hw); - if (!div1_parent_hw) - return; - - div1_prate = clk_hw_get_rate(div1_parent_hw); - *bestdiv = 1; - for (div1 = 1; div1 <= pdivider->max_div;) { - for (div2 = 1; div2 <= divider->max_div;) { - long new_error = ((div1_prate / div1) / div2) - rate; - - if (abs(new_error) < abs(error)) { - *bestdiv = div2; - error = new_error; - } - if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) - div2 = div2 << 1; - else - div2++; - } - if (pdivider->flags & CLK_DIVIDER_POWER_OF_TWO) - div1 = div1 << 1; - else - div1++; - } -} - /** * zynqmp_clk_divider_round_rate() - Round rate of divider clock * @hw: handle between common and hardware-specific interfaces @@ -174,6 +128,7 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, u32 div_type = divider->div_type; u32 bestdiv; int ret; + u8 width; /* if read only, just return current value */ if (divider->flags & CLK_DIVIDER_READ_ONLY) { @@ -193,23 +148,12 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, return DIV_ROUND_UP_ULL((u64)*prate, bestdiv); } - bestdiv = zynqmp_divider_get_val(*prate, rate, divider->flags); - - /* - * In case of two divisors, compute best divider values and return - * divider2 value based on compute value. div1 will be automatically - * set to optimum based on required total divider value. - */ - if (div_type == TYPE_DIV2 && - (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { - zynqmp_get_divider2_val(hw, rate, divider, &bestdiv); - } + width = fls(divider->max_div); - if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac) - bestdiv = rate % *prate ? 1 : bestdiv; + rate = divider_round_rate(hw, rate, prate, NULL, width, divider->flags); - bestdiv = min_t(u32, bestdiv, divider->max_div); - *prate = rate * bestdiv; + if (divider->is_frac && (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && (rate % *prate)) + *prate = rate; return rate; } -- 2.43.0