From patchwork Fri Jun 21 14:37:13 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: 13707690 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 B3359C27C4F for ; Fri, 21 Jun 2024 14:38:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: Content-Type: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=nFQvBp09SYhqBXHYcpVbluB3rmpVFZWSPU/sKj+XFgQ=; b=N6psYdC/EvFrE/a/6eUPyz/N6s /IVCRj0oFk/3WaPcrveI+6LODJJse23wNpw0e21bmcTbFz3OuJtDRQufu2ZI8mfQHwdNSWD9dqVf7 ythiwts93o9eqlbSXqj7lQkXSZypP6CYDiuj+tHXqLuDzDrZ0G6rf5UQFIXjlr2cHebDCUgyAYoaB QE8qB2W9rTgOITB7zbjqorrxS8QtpHIgKFANxPAaETZcSohhLjrSn9S8et4Qv41LAAHWTr8tuTTq2 jBD2hQhdI584tpfO4xFAsKeaQM/FanE1ze/1o/eWvbqgNnBOLfKzRCMZgfJoqT+h4xqHC6hmM1X3v FgnCAqCw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sKfOp-00000009XAN-259M; Fri, 21 Jun 2024 14:37:59 +0000 Received: from mail-ed1-x52c.google.com ([2a00:1450:4864:20::52c]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sKfOZ-00000009X3H-1TNf for linux-arm-kernel@lists.infradead.org; Fri, 21 Jun 2024 14:37:45 +0000 Received: by mail-ed1-x52c.google.com with SMTP id 4fb4d7f45d1cf-57d05e0017aso2602725a12.1 for ; Fri, 21 Jun 2024 07:37:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1718980662; x=1719585462; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nFQvBp09SYhqBXHYcpVbluB3rmpVFZWSPU/sKj+XFgQ=; b=acMGjSYFkoi2dcCaeUH0UB9lZnjn0htj9jM/H0Pckf/MyKzvxIy2JV8QwJ/LjCUT6C Wg+Y8EoFqTzB/RQYNKz3qYH1dsi2A09Bkf2qhpdRHjfOrZiwdrmqld9qF+D/HcgKSdFg Zg/TWrNpvPxIwySQ6tRW1ZDQrtnrJz1qKvEmxce+vR2l3N42b2sAb0Pyl06Nn/3cqznE Vrq0JRlEmKg15GLi6HaaADaEreARm8IOvZuRvvH7dkANtWMb8UXveJ1YR1cRQcJYTx7P bhR3zsbTQ/X2gl0yIV9Sgy5v/U4DoOHQow94CmoF3aMIykWrxGwqucKY2TD9nkRoPqyD mvfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718980662; x=1719585462; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nFQvBp09SYhqBXHYcpVbluB3rmpVFZWSPU/sKj+XFgQ=; b=qm775FswlF/O83YPGCScb1cSxvMvgtQKrQH/4nUb9lAMCq0DHNHrduW1h8G9FZqdG5 jNV5fddFXBJJ9uylm4Lz+HbMIeR6MYLUVDnBk2fE7smTz0pOO+6ol18wF89R8G3N19Lt 0GNksIghHqPOxjD2Cm62QzUyPcxPnS1NZopwZEovVYdyPXIj6EVBoGvmiKrWQ/+/6/pj 3Jq7zGldfM1dWi33EoVcCA2Cz6nyY3yOdUaArRemUerSCw3p4GJZttVEiPNVh3Xe332B Ek295ifndRy6E8vzBPc5ieNooCR8nyMyykVbQwM/ewlL9uRDRX91Tz4HO+cGrsMeui/5 zrhw== X-Forwarded-Encrypted: i=1; AJvYcCW3mh0gRHPeJy8CPKDczlGyDkNFjYd7O7PuLe+jg6qjSh2JsnDJqUDKvayC0I2LPDiDiKeS3dLysrM1bPHQTPfZd4RMmmBfJhCRxMzoM+A5B8kdZzI= X-Gm-Message-State: AOJu0YxHZB/PkBBFJy941hld6yPXx9OsANb60hzAh6vUneKaR5/I4kNC 52e6zcswao1g5AKe1mlbSe260bbQtLEbS+sa/e4pTlRB7WSgNNjJD8ON2ROwy50= X-Google-Smtp-Source: AGHT+IHhBkbnDwe6DC78mHyYrZoTEMrk9luPtrCGS6uQpBAuAlhQcl4/FTWTW5gRCSAfgVzjizpaQA== X-Received: by 2002:a17:906:fe4d:b0:a6f:4b7d:599b with SMTP id a640c23a62f3a-a6fab64869dmr667183566b.33.1718980661770; Fri, 21 Jun 2024 07:37:41 -0700 (PDT) Received: from localhost (p5091583d.dip0.t-ipconnect.de. [80.145.88.61]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a6fcf56ee06sm90550566b.198.2024.06.21.07.37.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Jun 2024 07:37:41 -0700 (PDT) From: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= To: Fabrice Gasnier , Maxime Coquelin , Alexandre Torgue , Benjamin Gaignard , Lee Jones , Thierry Reding Cc: linux-pwm@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, Trevor Gamblin Subject: [PATCH v2 2/3] pwm: stm32: Fix calculation of prescaler Date: Fri, 21 Jun 2024 16:37:13 +0200 Message-ID: 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=2498; i=u.kleine-koenig@baylibre.com; h=from:subject:message-id; bh=k1b/UZlBPcg27jJ13+cEn2qIvvv2MFL41xaIuM2GWOg=; b=owEBbQGS/pANAwAKAY+A+1h9Ev5OAcsmYgBmdZAdj6nX78OTtkGgf+zjfTRynFlrjHnlSPFLB /sXRGO38cqJATMEAAEKAB0WIQQ/gaxpOnoeWYmt/tOPgPtYfRL+TgUCZnWQHQAKCRCPgPtYfRL+ TpsPCACpUFVr/Itd1iZOgd/j4VQ1XonbgsnD5G7pim5yCA1J/WsMS8mS+NJSuUN83vBBSyk8uEp Jr5j0peLUzVb3MKp8PcSn19eXTfXnkitfvvr+UnJ4HzcKZkUp3jCDf4f+WlNZRM/ZCdHJqDafs1 PGPOGdY3A7h6VtZtSNn40D/sMD9n+bgcS4ZGELGa/mnOQ0seYBXqYyT941X8UpSK60KZHgNAjRp dOVhv184I2YtPmfJGMkDM1jvDqtcOn3u/2mY3UyhNzXS5yEc1cBbm7ljRofEEBG87rZ1c1/oloS wBhYOqRr2nZ0UpEDKNNMyvaaxLinCMBBY32VQkGyLHg45K94 X-Developer-Key: i=u.kleine-koenig@baylibre.com; a=openpgp; fpr=0D2511F322BFAB1C1580266BE2DCDD9132669BD6 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240621_073743_421859_838B7280 X-CRM114-Status: GOOD ( 15.57 ) 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 A small prescaler is beneficial, as this improves the resolution of the duty_cycle configuration. However if the prescaler is too small, the maximal possible period becomes considerably smaller than the requested value. One situation where this goes wrong is the following: With a parent clock rate of 208877930 Hz and max_arr = 0xffff = 65535, a request for period = 941243 ns currently results in PSC = 1. The value for ARR is then calculated to ARR = 941243 * 208877930 / (1000000000 * 2) - 1 = 98301 This value is bigger than 65535 however and so doesn't fit into the respective register field. In this particular case the PWM was configured for a period of 313733.4806027616 ns (with ARR = 98301 & 0xffff). Even if ARR was configured to its maximal value, only period = 627495.6861167669 ns would be achievable. Fix the calculation accordingly and adapt the comment to match the new algorithm. With the calculation fixed the above case results in PSC = 2 and so an actual period of 941229.1667195285 ns. Fixes: 8002fbeef1e4 ("pwm: stm32: Calculate prescaler with a division instead of a loop") Signed-off-by: Uwe Kleine-König --- drivers/pwm/pwm-stm32.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 3e7b2a8e34e7..a7ff39e9fc28 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -321,17 +321,23 @@ static int stm32_pwm_config(struct stm32_pwm *priv, unsigned int ch, * First we need to find the minimal value for prescaler such that * * period_ns * clkrate - * ------------------------------ + * ------------------------------ < max_arr + 1 * NSEC_PER_SEC * (prescaler + 1) * - * isn't bigger than max_arr. + * This equation is equivalent to + * + * period_ns * clkrate + * ---------------------------- < prescaler + 1 + * NSEC_PER_SEC * (max_arr + 1) + * + * Using integer division and knowing that the right hand side is + * integer, this is further equivalent to + * + * (period_ns * clkrate) // (NSEC_PER_SEC * (max_arr + 1)) ≤ prescaler */ 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; - + (u64)NSEC_PER_SEC * (priv->max_arr + 1)); if (prescaler > MAX_TIM_PSC) return -EINVAL;