immortalwrt-VIKINGYFY/target/linux/rockchip/patches-6.12/039-15-v6.16-pwm-Formally-describe-the-procedure-used-to-pick-a-hardwa.patch
Tianling Shen f2c5abcda3
rockchip: backport pending PWMv4 support
Used by RK3576 SoCs.

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
2025-12-11 14:41:27 +08:00

60 lines
3.0 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From d041b76ac9fb9e60e7cdb0265ed9d8b6058a88bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@baylibre.com>
Date: Wed, 30 Apr 2025 13:56:00 +0200
Subject: [PATCH] pwm: Formally describe the procedure used to pick a hardware
waveform setting
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This serves as specification for both, PWM consumers and the respective
callback for lowlevel drivers.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Link: https://lore.kernel.org/r/d2916bfa70274961ded26b07ab6998c36b90e69a.1746010245.git.u.kleine-koenig@baylibre.com
Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
---
drivers/pwm/core.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -231,7 +231,9 @@ static int __pwm_write_waveform(struct p
*
* Usually all values passed in @wf are rounded down to the nearest possible
* value (in the order period_length_ns, duty_length_ns and then
- * duty_offset_ns). Only if this isn't possible, a value might grow.
+ * duty_offset_ns). Only if this isn't possible, a value might grow. See the
+ * documentation for pwm_set_waveform_might_sleep() for a more formal
+ * description.
*
* Returns: 0 on success, 1 if at least one value had to be rounded up or a
* negative errno.
@@ -411,6 +413,26 @@ static int __pwm_set_waveform(struct pwm
* possible/needed. In the above example requesting .period_length_ns = 94 and
* @exact = true, you get the hardware configured with period = 93.5 ns.
*
+ * Let C be the set of possible hardware configurations for a given PWM device,
+ * consisting of tuples (p, d, o) where p is the period length, d is the duty
+ * length and o the duty offset.
+ *
+ * The following algorithm is implemented to pick the hardware setting
+ * (p, d, o) ∈ C for a given request (p', d', o') with @exact = false::
+ *
+ * p = max( { ṗ | ∃ ḋ, ȯ : (ṗ, ḋ, ȯ) ∈ C ∧ ṗ ≤ p' } { min({ ṗ | ∃ ḋ, ȯ : (ṗ, ḋ, ȯ) ∈ C }) })
+ * d = max( { ḋ | ∃ ȯ : (p, ḋ, ȯ) ∈ C ∧ ḋ ≤ d' } { min({ ḋ | ∃ ȯ : (p, ḋ, ȯ) ∈ C }) })
+ * o = max( { ȯ | (p, d, ȯ) ∈ C ∧ ȯ ≤ o' } { min({ ȯ | (p, d, ȯ) ∈ C }) })
+ *
+ * In words: The chosen period length is the maximal possible period length not
+ * bigger than the requested period length and if that doesn't exist, the
+ * minimal period length. The chosen duty length is the maximal possible duty
+ * length that is compatible with the chosen period length and isn't bigger than
+ * the requested duty length. Again if such a value doesn't exist, the minimal
+ * duty length compatible with the chosen period is picked. After that the duty
+ * offset compatible with the chosen period and duty length is chosen in the
+ * same way.
+ *
* Returns: 0 on success, -EDOM if setting failed due to the exact waveform not
* being possible (if @exact), or a different negative errno on failure.
* Context: May sleep.