summaryrefslogtreecommitdiff
path: root/drivers/pwm
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-05-14 22:59:48 -0400
committerTom Rini <trini@konsulko.com>2021-05-14 22:59:48 -0400
commit579e07501a4f755e29953b9c21527354cb3ac74c (patch)
tree2bd444c2efe035c3fb12482e7b934d09574c8095 /drivers/pwm
parent530c8d4af2e18c6142ab7cac6f11dd92c02b2bc9 (diff)
parentffdc71bc0977c1e6b7b6e6a5a005e1f77213bf21 (diff)
Merge https://source.denx.de/u-boot/custodians/u-boot-riscv
Diffstat (limited to 'drivers/pwm')
-rw-r--r--drivers/pwm/pwm-sifive.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c
index 01212d630a9..b9813a3b6bb 100644
--- a/drivers/pwm/pwm-sifive.c
+++ b/drivers/pwm/pwm-sifive.c
@@ -38,6 +38,9 @@
#define PWM_SIFIVE_SIZE_PWMCMP 4
#define PWM_SIFIVE_CMPWIDTH 16
+#define PWM_SIFIVE_CHANNEL_ENABLE_VAL 0
+#define PWM_SIFIVE_CHANNEL_DISABLE_VAL 0xffff
+
DECLARE_GLOBAL_DATA_PTR;
struct pwm_sifive_regs {
@@ -77,7 +80,7 @@ static int pwm_sifive_set_config(struct udevice *dev, uint channel,
*/
scale_pow = lldiv((uint64_t)priv->freq * period_ns, 1000000000);
scale = clamp(ilog2(scale_pow) - PWM_SIFIVE_CMPWIDTH, 0, 0xf);
- val |= FIELD_PREP(PWM_SIFIVE_PWMCFG_SCALE, scale);
+ val |= (FIELD_PREP(PWM_SIFIVE_PWMCFG_SCALE, scale) | PWM_SIFIVE_PWMCFG_EN_ALWAYS);
/*
* The problem of output producing mixed setting as mentioned at top,
@@ -88,6 +91,7 @@ static int pwm_sifive_set_config(struct udevice *dev, uint channel,
num = (u64)duty_ns * (1U << PWM_SIFIVE_CMPWIDTH);
frac = DIV_ROUND_CLOSEST_ULL(num, period_ns);
frac = min(frac, (1U << PWM_SIFIVE_CMPWIDTH) - 1);
+ frac = (1U << PWM_SIFIVE_CMPWIDTH) - 1 - frac;
writel(val, priv->base + regs->cfg);
writel(frac, priv->base + regs->cmp0 + channel *
@@ -100,18 +104,15 @@ static int pwm_sifive_set_enable(struct udevice *dev, uint channel, bool enable)
{
struct pwm_sifive_priv *priv = dev_get_priv(dev);
const struct pwm_sifive_regs *regs = &priv->data->regs;
- u32 val;
debug("%s: Enable '%s'\n", __func__, dev->name);
- if (enable) {
- val = readl(priv->base + regs->cfg);
- val |= PWM_SIFIVE_PWMCFG_EN_ALWAYS;
- writel(val, priv->base + regs->cfg);
- } else {
- writel(0, priv->base + regs->cmp0 + channel *
- PWM_SIFIVE_SIZE_PWMCMP);
- }
+ if (enable)
+ writel(PWM_SIFIVE_CHANNEL_ENABLE_VAL, priv->base +
+ regs->cmp0 + channel * PWM_SIFIVE_SIZE_PWMCMP);
+ else
+ writel(PWM_SIFIVE_CHANNEL_DISABLE_VAL, priv->base +
+ regs->cmp0 + channel * PWM_SIFIVE_SIZE_PWMCMP);
return 0;
}