From patchwork Wed Sep 28 20:16:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 12992883 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 07C13C04A95 for ; Wed, 28 Sep 2022 20:18:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=WzhdAp8opncH/D0nYQJK21PpGt9InfCYG8YeIRCVX3c=; b=efJOAxAisJY4mE ZQoqVLUPvSzFKGQf0+R6y9CCc8gWH6qIzy8V4mglw2MZ4uHrnUlrpmXEH8n0YM1INJMJhxmKxstR6 yAPX4VKqTZOfUK0yJcdhTQkK6hAsSsSZNJJMoUgkcFxkfGpPef6UaUmKhEin9fOBnrsBxVorL2zEa sYiBX4Qhe2PCm02FR6UiGJ8n8/wDiF+qh/FtH/rgNYJOPKrezimd588ehWTKGpm+9/Ona6yTcmFUt FN7KCydTgmMikxwJbSVk4DGChwoVyz0/IxiqVpezKvOrmLqnKhLsE579Yx8NfRmRSQfpIzw7sAgCD bOz++TDpXevI5zeDtXsA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oddUS-000JAF-4G; Wed, 28 Sep 2022 20:17:08 +0000 Received: from perceval.ideasonboard.com ([213.167.242.64]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oddUO-000J95-6I for linux-arm-kernel@lists.infradead.org; Wed, 28 Sep 2022 20:17:05 +0000 Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4A47B47C; Wed, 28 Sep 2022 22:16:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1664396218; bh=Uxg50pIgYpOI9PE8XMmtiinzktazEO173WVuv/3uCzA=; h=From:To:Cc:Subject:Date:From; b=fd9VPIWSPV6QVLNl9K7a883IdRAHM31tFf+BhYAvQQoLz/w+XeHf/nOqJDUIHr6gN mP91UT3TyvowaXnLdPaIh5FzCsYbmaqYPEgKvnUttlxZel3NNvxGuh3b7uMj9OvO8m b8IxSGPzk4I8MaxgQzitbzb/ViLRQouHxp7HVeM4= From: Laurent Pinchart To: linux-clk@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, Michal Simek , Rajan Vaja , Quanyang Wang Subject: [PATCH] clk: zynqmp: pll: Fix divider calculation to avoid out-of-range rate Date: Wed, 28 Sep 2022 23:16:56 +0300 Message-Id: <20220928201656.30318-1-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220928_131704_401080_4D9450CB X-CRM114-Status: GOOD ( 11.10 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org When calculating the divider in zynqmp_pll_round_rate() and zynqmp_pll_set_rate(), the division rounding error may result in an output frequency that is slightly outside of the PLL output range if the requested range is close to the low or high limit. As a result, the limits check in clk_calc_new_rates() would fail, and clk_set_rate() would return an error, as seen in the zynqmp-dpsub driver: [ 13.672309] zynqmp-dpsub fd4a0000.display: failed to set pixel clock rate to 297000000 (-22) Fix this by adjusting the divider. The rate calculation then succeeds for zynqmp-dpsub: [ 13.554849] zynqmp-dpsub fd4a0000.display: requested pixel rate: 297000000 actual rate: 255555553 The resulting PLL configuration, however, is not optimal, as the rate error is 14%. The hardware can do much better, but CCF doesn't attempt to find the best overall configuration for cascaded clocks. That's a candidate for a separate fix. Signed-off-by: Laurent Pinchart --- drivers/clk/zynqmp/pll.c | 8 ++++++++ 1 file changed, 8 insertions(+) base-commit: 1c23f9e627a7b412978b4e852793c5e3c3efc555 diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c index 91a6b4cc910e..be6fa44a21e0 100644 --- a/drivers/clk/zynqmp/pll.c +++ b/drivers/clk/zynqmp/pll.c @@ -120,6 +120,10 @@ static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate, } fbdiv = DIV_ROUND_CLOSEST(rate, *prate); + if (*prate * fbdiv < PS_PLL_VCO_MIN) + fbdiv++; + if (*prate * fbdiv > PS_PLL_VCO_MAX) + fbdiv--; fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX); return *prate * fbdiv; } @@ -208,6 +212,10 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate, } fbdiv = DIV_ROUND_CLOSEST(rate, parent_rate); + if (parent_rate * fbdiv < PS_PLL_VCO_MIN) + fbdiv++; + else if (parent_rate * fbdiv > PS_PLL_VCO_MAX) + fbdiv--; fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX); ret = zynqmp_pm_clock_setdivider(clk_id, fbdiv); if (ret)