From patchwork Sun Mar 17 21:52:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= X-Patchwork-Id: 13594861 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 A00EAC54E60 for ; Sun, 17 Mar 2024 21:52:59 +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:References:In-Reply-To: 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: List-Owner; bh=SS8rLNMl2Gw7KKTUkcxK+JDrionYeScrKAvuqogSGIg=; b=Qr66MkN/S7sV8A zCJh4da6BQf+gHQa/SeLs5KQLrnNEshz5mEdbpyuyN2NjEvGOvJfygVXsHL0nKpyBAzuH7NlsCnr8 LPHIHZhqvnskI0WttiugDxhb1K2dot2ceCS5TjyyG/BR7ceLvbVy+9hyKx6VWb51CymqmtyQHWlyT avJAq4T032DKR+HqxA9wDAX9TmD7sNs1a8wZjiTDCg89b5SBPQHi0MfVKGV/WmtyGEhFTvgJiWMUS KfloWMMNw5ch1M42L3AK5Pn5QWqLuwcmSLUjnpnsWNfbv3yusjDGjv/4PuaooGX+mIh0scRqdxgwL VgInfztP8sgOPlfxzR4A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rlyQv-00000006Z6u-2UM8; Sun, 17 Mar 2024 21:52:45 +0000 Received: from metis.whiteo.stw.pengutronix.de ([2a0a:edc0:2:b01:1d::104]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rlyQq-00000006Z4g-1sEg for linux-arm-kernel@lists.infradead.org; Sun, 17 Mar 2024 21:52:43 +0000 Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1rlyQk-0002kn-4u; Sun, 17 Mar 2024 22:52:34 +0100 Received: from [2a0a:edc0:0:900:1d::77] (helo=ptz.office.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rlyQj-006xGq-2A; Sun, 17 Mar 2024 22:52:33 +0100 Received: from ukl by ptz.office.stw.pengutronix.de with local (Exim 4.96) (envelope-from ) id 1rlyQi-007fnz-3A; Sun, 17 Mar 2024 22:52:32 +0100 From: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= To: Fabrice Gasnier , Maxime Coquelin , Alexandre Torgue Cc: linux-pwm@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de Subject: [PATCH 1/3] pwm: stm32: Improve precision of calculation in .apply() Date: Sun, 17 Mar 2024 22:52:14 +0100 Message-ID: <7628ecd8a7538aa5a7397f0fc4199a077168e8a6.1710711976.git.u.kleine-koenig@pengutronix.de> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1734; i=u.kleine-koenig@pengutronix.de; h=from:subject:message-id; bh=rEQVgXxWi/ELpI3VBppPiQpewrscwVr8g8zdSA8buoQ=; b=owEBbQGS/pANAwAKAY+A+1h9Ev5OAcsmYgBl92YScoxX1h3+nr521TOsRmlHYsPPfgDdPHW8Q pC6dqgrkMSJATMEAAEKAB0WIQQ/gaxpOnoeWYmt/tOPgPtYfRL+TgUCZfdmEgAKCRCPgPtYfRL+ TiP+CACXUE7O4GXr8UzfgtBC/6Wj+KUUjMdf1rrenLU1/M/tMQE9nNEhyU9e9Pn1aFfYPGIodc6 E9Xy0xx7eXfbvQ7bJ+R3sreGbcCWPe+4ROfwti7Xo4iV2o7gkazSz6uboiLSWmuXKZNhR6YbRTJ 1eq25Ap59RyJlPchI6cZ2kUcFryfuTVn2CnYra4lRrOf3qPulR7R6ls2ZUqLxHihICreugwz9aN idiAbN6XqvN6fZxf4YtwIGwdNich/7kuuPi8TVyKX7V0qNba0Av5185vvcDzE2/UXFvWoSw3Ovh 84BYlrhbjAu2uIAZn8Isuwu+zoYN8BIeP9iJ3STNeMRdIGHl X-Developer-Key: i=u.kleine-koenig@pengutronix.de; a=openpgp; fpr=0D2511F322BFAB1C1580266BE2DCDD9132669BD6 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ukl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240317_145240_549655_32D3893F X-CRM114-Status: GOOD ( 13.60 ) 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 While mathematically it's ok to calculate the number of cyles for the duty cycle as: duty_cycles = period_cycles * duty_ns / period_ns this doesn't always give the right result when doing integer math. This is best demonstrated using an example: With the input clock running at 208877930 Hz a request for duty_cycle = 383 ns and period = 49996 ns results in period_cycles = clkrate * period_ns / NSEC_PER_SEC = 10443.06098828 Now calculating duty_cycles with the above formula gives: duty_cycles = 10443.06098828 * 383 / 49996 = 80.00024719 However with period_cycle truncated to an integer results in: duty_cycles = 10443 * 383 / 49996 = 79.99977998239859 So while a value of (a little more than) 80 would be the right result, only 79 is used here. The problem here is that 14443 is a rounded result that should better not be used to do further math. So to fix that use the exact formular similar to how period_cycles is calculated. Signed-off-by: Uwe Kleine-König --- drivers/pwm/pwm-stm32.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index ffe572b76174..fb714936ff8f 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -351,8 +351,9 @@ static int stm32_pwm_config(struct stm32_pwm *priv, unsigned int ch, regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE); /* Calculate the duty cycles */ - dty = prd * duty_ns; - do_div(dty, period_ns); + dty = (unsigned long long)clk_get_rate(priv->clk) * duty_ns; + do_div(dty, prescaler + 1); + do_div(dty, NSEC_PER_SEC); regmap_write(priv->regmap, TIM_CCR1 + 4 * ch, dty); From patchwork Sun Mar 17 21:52:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= X-Patchwork-Id: 13594862 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 A2B45C54E68 for ; Sun, 17 Mar 2024 21:53:01 +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:References:In-Reply-To: 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: List-Owner; bh=elB0LEX2Zv6ugplOmWB9+K6I+wG6lv4q8OS3Pl4tITk=; b=SWObjoqH/Mx6Nx gaAyH5uD24RQlqcy2TqIKDTrmYrDY5BnR6xw2uR0E/lth3Ky9fiKbaGHsUSC/4fbaQ+gglZhnlaZI A3agTg3IK4Jh+zy6PX7T9n53n5cja0zx3yw30jjWZ9q9X6onrdhJcDzvBPtMNgQJ7oV6wZnrIqkwp REcOuyhPRsrQkX7IISX8Q3Igi2dR8cobxTg3fbPPx6rX7PQyMF3pttVaGRGj3OzOWT1UDoX7esda5 abQbOM9Z4GZwPNS8fFLFK8OZ6XQU5FDSjJINZP6T3Trl972X6EMrXDpnSfeU4KtkqtodCuidGZlv7 LzfgSUj9ST4Py4eqAjwQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rlyQx-00000006Z7u-3PGF; Sun, 17 Mar 2024 21:52:47 +0000 Received: from metis.whiteo.stw.pengutronix.de ([2a0a:edc0:2:b01:1d::104]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rlyQq-00000006Z4d-1mUa for linux-arm-kernel@lists.infradead.org; Sun, 17 Mar 2024 21:52:43 +0000 Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1rlyQk-0002ko-4u; Sun, 17 Mar 2024 22:52:34 +0100 Received: from [2a0a:edc0:0:900:1d::77] (helo=ptz.office.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rlyQj-006xGt-8J; Sun, 17 Mar 2024 22:52:33 +0100 Received: from ukl by ptz.office.stw.pengutronix.de with local (Exim 4.96) (envelope-from ) id 1rlyQj-007fo3-0Z; Sun, 17 Mar 2024 22:52:33 +0100 From: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= To: Fabrice Gasnier , Maxime Coquelin , Alexandre Torgue Cc: linux-pwm@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de Subject: [PATCH 2/3] pwm: stm32: Fix for settings using period > UINT32_MAX Date: Sun, 17 Mar 2024 22:52:15 +0100 Message-ID: <06b4a650a608d0887d934c1b2b8919e0f78e4db2.1710711976.git.u.kleine-koenig@pengutronix.de> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2570; i=u.kleine-koenig@pengutronix.de; h=from:subject:message-id; bh=LC/LLRqDr9Z7kf3kDVEv9tMRdoh326PaTq2N/xGKxhs=; b=owEBbQGS/pANAwAKAY+A+1h9Ev5OAcsmYgBl92YTQOFkCl9hltuvWQRPORMGwXSAVvQaSYFEj cT5yRnj8+yJATMEAAEKAB0WIQQ/gaxpOnoeWYmt/tOPgPtYfRL+TgUCZfdmEwAKCRCPgPtYfRL+ Tu8hCACpDquxqwbpdvKPAX/vz7ulv7aFcH25NgqtFXF6p8zu0AZZC+Wswk7hzAfwFb5F5USnqNm gbYkpbMLUUspazJvo4Hg6MTBK4ievd3U49DSl08ewTQ43bt/v0GgxHy8vInkCV/gj8Xae4e45WU X06nYnEIE6FqjAZ5klzHgehS7Pqp8ymnlFMZ6tpInbNYG0mnMNL5YmjtGJQ8scrMAsj53YvR5PJ WFCeqZ96g/4bUKeKo3ZtgeMLWF9WjstBhaza0xbODMDAfB7WgL9NOOnr3SqHOa93RDiG+NG2R75 4p4FHzGaI//h4LHMMrbk1/Ap+b14PrF6uUA8IgtmU3NcPdUz X-Developer-Key: i=u.kleine-koenig@pengutronix.de; a=openpgp; fpr=0D2511F322BFAB1C1580266BE2DCDD9132669BD6 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ukl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240317_145240_533504_D20A190D X-CRM114-Status: GOOD ( 14.40 ) 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 stm32_pwm_config() took the duty_cycle and period values with the type int, however stm32_pwm_apply() passed u64 values there. Expand the function parameters to u64 to not discard relevant bits and adapt the calculations to the wider type. To ensure the calculations won't overflow, check in .probe() the input clk doesn't run faster than 1 GHz. Signed-off-by: Uwe Kleine-König --- drivers/pwm/pwm-stm32.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index fb714936ff8f..b20d43408e61 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -309,17 +309,18 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, } static int stm32_pwm_config(struct stm32_pwm *priv, unsigned int ch, - int duty_ns, int period_ns) + u64 duty_ns, u64 period_ns) { unsigned long long prd, div, dty; unsigned int prescaler = 0; u32 ccmr, mask, shift; - /* Period and prescaler values depends on clock rate */ - div = (unsigned long long)clk_get_rate(priv->clk) * period_ns; - - do_div(div, NSEC_PER_SEC); - prd = div; + /* + * .probe() asserted that clk_get_rate() is not bigger than 1 GHz, so + * this won't overflow. + */ + div = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk), + NSEC_PER_SEC); while (div > priv->max_arr) { prescaler++; @@ -351,9 +352,8 @@ static int stm32_pwm_config(struct stm32_pwm *priv, unsigned int ch, regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE); /* Calculate the duty cycles */ - dty = (unsigned long long)clk_get_rate(priv->clk) * duty_ns; - do_div(dty, prescaler + 1); - do_div(dty, NSEC_PER_SEC); + dty = mul_u64_u64_div_u64(duty_ns, clk_get_rate(priv->clk), + (u64)NSEC_PER_SEC * (prescaler + 1)); regmap_write(priv->regmap, TIM_CCR1 + 4 * ch, dty); @@ -659,6 +659,17 @@ static int stm32_pwm_probe(struct platform_device *pdev) stm32_pwm_detect_complementary(priv); + ret = devm_clk_rate_exclusive_get(dev, priv->clk); + if (ret) + return dev_err_probe(dev, ret, "Failed to lock clock\n"); + + /* + * With the clk running with not more than 1 GHz the calculations in + * .apply() won't overflow. + */ + if (clk_get_rate(priv->clk) > 1000000000) + return dev_err_probe(dev, -EINVAL, "Failed to lock clock\n"); + chip->ops = &stm32pwm_ops; /* Initialize clock refcount to number of enabled PWM channels. */ From patchwork Sun Mar 17 21:52:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= X-Patchwork-Id: 13594864 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 7157BC54E68 for ; Sun, 17 Mar 2024 21:53:07 +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:References:In-Reply-To: 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: List-Owner; bh=qxHhWJPywXYlZ0lquCUFkOz6zrw20vwR4qFf6QYq7kI=; b=wzRT5Bxl1TtT3J hLQ5LYhFdgrp/FMewHjYfjjsoP6isD+7ipdpc9CClE8friM+nYGUOseFBsminml2mlc1nGii2QRee OxMUvMuEZLyBwB8UkF21Mvdny6AMGGAy02Hbhn171H9ul84nVz/VLpfvlQ6oaJlNVVzVo0orZ93H/ KzKJC3C9BuOEq8jvMd69lRd2wLK0oZ4zfeKp/Hr9Ti6L+s9pM2tk4sgF9j8lXMbnwMdOATfmnk4D8 oqYatj7KJ7cHF09MuWsaqARtcrN3nE+/lD38LmHO7wsAFlJGG2l6oj1FZ0+EIFObHVPEdVpaqcYy2 nHenw5D3twnhFbmmz54g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rlyQw-00000006Z7B-1t9h; Sun, 17 Mar 2024 21:52:46 +0000 Received: from metis.whiteo.stw.pengutronix.de ([2a0a:edc0:2:b01:1d::104]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rlyQq-00000006Z4f-18Uv for linux-arm-kernel@lists.infradead.org; Sun, 17 Mar 2024 21:52:43 +0000 Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1rlyQk-0002kp-4u; Sun, 17 Mar 2024 22:52:34 +0100 Received: from [2a0a:edc0:0:900:1d::77] (helo=ptz.office.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rlyQj-006xGw-EU; Sun, 17 Mar 2024 22:52:33 +0100 Received: from ukl by ptz.office.stw.pengutronix.de with local (Exim 4.96) (envelope-from ) id 1rlyQj-007fo7-1A; Sun, 17 Mar 2024 22:52:33 +0100 From: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= To: Fabrice Gasnier , Maxime Coquelin , Alexandre Torgue Cc: linux-pwm@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de Subject: [PATCH 3/3] pwm: stm32: Calculate prescaler with a division instead of a loop Date: Sun, 17 Mar 2024 22:52:16 +0100 Message-ID: <498a44b313a6c0a84ccddd03cd67aadaaaf7daf2.1710711976.git.u.kleine-koenig@pengutronix.de> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1940; i=u.kleine-koenig@pengutronix.de; h=from:subject:message-id; bh=+gWyc/Xr/gKt2ssnUmtJ3znJ8evskyjFlYjxtuQFMak=; b=owEBbQGS/pANAwAKAY+A+1h9Ev5OAcsmYgBl92YUyRkkcP0unmpy4kqNjkBTg3KN6NxlE50gB egGrTLT8IWJATMEAAEKAB0WIQQ/gaxpOnoeWYmt/tOPgPtYfRL+TgUCZfdmFAAKCRCPgPtYfRL+ TpFGB/9urgmvkMV9IFZToy3OTLf3mepNXYqCUGpkeRpS9GWqA3c/yZqMGEorYh4Y7C1udikWjCw VYV3KAvGRAF9i56fRD5kpGDDoF9AeZh2ikZjCw2Ge3rnAxNQPxRzZ6WuXN0rl5qXUdC0Vvh1yDj CP5/EYj/9NL4Bgqpi9s5UeziZCpjOpJLcJjxk6momz1zko18AR8IUWkrVSgWts5AuhfOO1lJlQJ 4YaXMlS/aFLJfJPQjNmrYsUH/iJ2CGcZFTlLAm3nBD8BZDbM/eO/g/1k9hOJhSkHw521KlXvN6v iEBTzrPLRdX4xyfWlO/+G7V3w4b+DvI23bfK7DGzD4RMXiYE X-Developer-Key: i=u.kleine-koenig@pengutronix.de; a=openpgp; fpr=0D2511F322BFAB1C1580266BE2DCDD9132669BD6 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ukl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240317_145240_386095_20F83519 X-CRM114-Status: GOOD ( 14.19 ) 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 Instead of looping over increasing values for the prescaler and testing if it's big enough, calculate the value using a single division. Signed-off-by: Uwe Kleine-König --- drivers/pwm/pwm-stm32.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index b20d43408e61..a2f231d13a9f 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -311,28 +311,33 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, static int stm32_pwm_config(struct stm32_pwm *priv, unsigned int ch, u64 duty_ns, u64 period_ns) { - unsigned long long prd, div, dty; - unsigned int prescaler = 0; + unsigned long long prd, dty; + unsigned long long prescaler; u32 ccmr, mask, shift; /* * .probe() asserted that clk_get_rate() is not bigger than 1 GHz, so - * this won't overflow. + * the calculations here won't overflow. + * First we need to find the minimal value for prescaler such that + * + * period_ns * clkrate + * ------------------------------ + * NSEC_PER_SEC * (prescaler + 1) + * + * isn't bigger than max_arr. */ - div = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk), - NSEC_PER_SEC); - while (div > priv->max_arr) { - prescaler++; - div = prd; - do_div(div, prescaler + 1); - } - - prd = div; + prescaler = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk), + (u64)NSEC_PER_SEC * priv->max_arr); + if (prescaler > 0) + prescaler -= 1; if (prescaler > MAX_TIM_PSC) return -EINVAL; + prd = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk), + (u64)NSEC_PER_SEC * (prescaler + 1)); + /* * All channels share the same prescaler and counter so when two * channels are active at the same time we can't change them