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: 1912963 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2604:1380:4601:e00::3; helo=am.mirrors.kernel.org; envelope-from=linux-pwm+bounces-1790-incoming=patchwork.ozlabs.org@vger.kernel.org; receiver=patchwork.ozlabs.org) Received: from am.mirrors.kernel.org (am.mirrors.kernel.org [IPv6:2604:1380:4601:e00::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TyWtl562fz23sG for ; Mon, 18 Mar 2024 08:52:47 +1100 (AEDT) Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 53E9F1F216F3 for ; Sun, 17 Mar 2024 21:52:44 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DA10F20B0E; Sun, 17 Mar 2024 21:52:40 +0000 (UTC) X-Original-To: linux-pwm@vger.kernel.org Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (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 CDC80208D7 for ; Sun, 17 Mar 2024 21:52:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710712360; cv=none; b=gHmg4SaKpN0JMPdZtFYwi/RGO5VYVpKoQbrUEZJA1LMnCqvH7Z7naL4ZXDIJXquLyl0Lfzb+pvfrXlGmOIYgLU47Jh1m3qryXx/5rhe1djngDy7/iNis9ZF/qDfC0i5pcdIRXMrUzVjIqwkebIwzm9UQ/EIzlfJ1zemibKl/LzI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710712360; c=relaxed/simple; bh=rEQVgXxWi/ELpI3VBppPiQpewrscwVr8g8zdSA8buoQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hJ9lrSUy+3GwsI81AWZJgD3xQaI1cHxkpPabFUVSozKf2uTGHyfi/bGlvn/TGrZWgD2pBQS6HfQBAbseleWk1R/4BtwVnaLAF+AMoR99LycWjvdM5upUzSz19az7HUfhBMJpPnCVArLL4JBveu+xQ6hHT/zN/2Ot3hoWBw9sbuw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de 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: Precedence: bulk X-Mailing-List: linux-pwm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: 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-pwm@vger.kernel.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: 1912962 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2604:1380:45d1:ec00::1; helo=ny.mirrors.kernel.org; envelope-from=linux-pwm+bounces-1791-incoming=patchwork.ozlabs.org@vger.kernel.org; receiver=patchwork.ozlabs.org) Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org [IPv6:2604:1380:45d1:ec00::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TyWtl1fFZz1yX9 for ; Mon, 18 Mar 2024 08:52:47 +1100 (AEDT) Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 10EBA1C20D24 for ; Sun, 17 Mar 2024 21:52:44 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 88D06208B0; Sun, 17 Mar 2024 21:52:41 +0000 (UTC) X-Original-To: linux-pwm@vger.kernel.org Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (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 CB5A8208CA for ; Sun, 17 Mar 2024 21:52:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710712361; cv=none; b=WorqgWr2Y8BFel67Vw1PGTxvwkQJ8j5MURxOip67kd2T3f6RUV+e43Db5PvjahDPfmdFSneUY9Q0RUEGZU3zCw0/8V1oVGhQk0Me3u//TXnxewyuCOqjSNKGJPmC2UmbiJdT1ck/N75nXOSshnPGmSsY7X0EkC7VdyULGPzGBoU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710712361; c=relaxed/simple; bh=LC/LLRqDr9Z7kf3kDVEv9tMRdoh326PaTq2N/xGKxhs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=e+yhTOhs2dO4EjUglGCHYoP0VZLhGIB41iqS9W+EL4cCeV0oZe0xlRkmQKVj+fcZ6Dp0ZnA2EaLphp0trDUPN/9mNBsGB0mGrNRazSFEv5MizhtvLTnLZQeC0geCa3iF1SXaJE0tJq0rbzLcdned7mEZxjus7cXDMSGnZevaxBU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de 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: Precedence: bulk X-Mailing-List: linux-pwm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: 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-pwm@vger.kernel.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: 1912961 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=147.75.199.223; helo=ny.mirrors.kernel.org; envelope-from=linux-pwm+bounces-1792-incoming=patchwork.ozlabs.org@vger.kernel.org; receiver=patchwork.ozlabs.org) Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org [147.75.199.223]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TyWtk5Ggkz1yWs for ; Mon, 18 Mar 2024 08:52:46 +1100 (AEDT) Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 94BD71C2119A for ; Sun, 17 Mar 2024 21:52:44 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id F2703208CA; Sun, 17 Mar 2024 21:52:41 +0000 (UTC) X-Original-To: linux-pwm@vger.kernel.org Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (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 CB5641B7F7 for ; Sun, 17 Mar 2024 21:52:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710712361; cv=none; b=bVMwsI6KvzrsOzZwg6vcnSBVq9ivpOgmpXLRgsw0OMU2OOugZsT7My8nq2d5gPA6jG58m4zXRbFM6VeFUZ1hhsi27SGva5iy5rMOxiJELYidEdSplyVYuIothJzp5VDUYn2P/Z8UjGOXzkrm1N9EBGZwp+RYT+gJGbO9zuJHXkQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710712361; c=relaxed/simple; bh=+gWyc/Xr/gKt2ssnUmtJ3znJ8evskyjFlYjxtuQFMak=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=UYQ9VQNKNdMsS7mc4F3w5Cw7YodPyn8t8kzaidhoBqCDNQEKTE3bM1ziFKBkvai59Kum3ndhVN25jze4o5qhUJZc7nUbASiNA7XVYqKXofzyC8pVnosdQ4FyWdf67yy6h/u4SPfxxWzQ5TBhcrozB2Yq91qmOzWPhRvb7BPTuX8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de 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: Precedence: bulk X-Mailing-List: linux-pwm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: 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-pwm@vger.kernel.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