From: "Chew, Chiau Ee" <chiau.ee.c...@intel.com> This to improve the accuracy of base_unit calculation so that the resulting PWM frquency will be more optimal.
Signed-off-by: Chew, Kean Ho <kean.ho.c...@intel.com> Signed-off-by: Chew, Chiau Ee <chiau.ee.c...@intel.com> Signed-off-by: Maurice Petallo <mauricex.r.peta...@intel.com> --- drivers/pwm/pwm-lpss.c | 25 ++++++++++--------------- drivers/pwm/pwm-lpss.h | 14 ++++++++------ 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c index eeed096..7fae747 100644 --- a/drivers/pwm/pwm-lpss.c +++ b/drivers/pwm/pwm-lpss.c @@ -35,32 +35,27 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns) { struct pwm_lpss_chip *lpwm = to_lpwm(chip); - u8 base_unit_hi, base_unit_lo, on_time_div; + u8 on_time_div; unsigned long c = clk_get_rate(lpwm->clk); - unsigned long hz, cycle_cnt; + unsigned long long base_unit, hz = 1000000000UL; u32 ctrl; - hz = 1000000000UL / period_ns; + do_div(hz, period_ns); - /* - * There is no duty cycle resolution if base_unit value is higher - * than 128. - */ - base_unit_hi = (hz * 256) / c; - if (base_unit_hi > 128) + /* The equation is: base_unit = ((hz / c) * 65536) + correction */ + base_unit = hz * 65536; + do_div(base_unit, c); + base_unit += PWM_DIVISION_CORRECTION; + if (base_unit > PWM_LIMIT) return -EINVAL; - base_unit_lo = (hz * 65536) / c; - cycle_cnt = base_unit_hi ? 256 / base_unit_hi : 256; - if (duty_ns <= 0) duty_ns = 1; - - on_time_div = cycle_cnt / (period_ns / duty_ns); + on_time_div = 255 - (255 * duty_ns / period_ns); ctrl = readl(lpwm->regs + PWM); ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK); - ctrl |= (base_unit_hi | base_unit_lo) << PWM_BASE_UNIT_SHIFT; + ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT; ctrl |= on_time_div; /* request PWM to update on next cycle */ ctrl |= PWM_SW_UPDATE; diff --git a/drivers/pwm/pwm-lpss.h b/drivers/pwm/pwm-lpss.h index d1705e5..a9f2307 100644 --- a/drivers/pwm/pwm-lpss.h +++ b/drivers/pwm/pwm-lpss.h @@ -1,9 +1,11 @@ -#define PWM 0x00000000 -#define PWM_ENABLE BIT(31) -#define PWM_SW_UPDATE BIT(30) -#define PWM_BASE_UNIT_SHIFT 8 -#define PWM_BASE_UNIT_MASK 0x00ffff00 -#define PWM_ON_TIME_DIV_MASK 0x000000ff +#define PWM 0x00000000 +#define PWM_ENABLE BIT(31) +#define PWM_SW_UPDATE BIT(30) +#define PWM_BASE_UNIT_SHIFT 8 +#define PWM_BASE_UNIT_MASK 0x00ffff00 +#define PWM_ON_TIME_DIV_MASK 0x000000ff +#define PWM_DIVISION_CORRECTION 0x2 +#define PWM_LIMIT (0x8000 + PWM_DIVISION_CORRECTION) struct pwm_lpss_chip { struct pwm_chip chip; -- 1.7.10.4 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto