Skip to content

Commit e793eef

Browse files
lokeshvutlathierryreding
authored andcommitted
pwm: omap-dmtimer: Do not disable PWM before changing period/duty_cycle
Only the Timer control register(TCLR) cannot be updated when the timer is running. Registers like Counter register (TCRR), loader register (TLDR) and match register (TMAR) can be updated while the counter is running. Since TCLR is not updated in pwm_omap_dmtimer_config(), do not stop the timer for period/duty_cycle update. Tested-by: Tony Lindgren <[email protected]> Signed-off-by: Lokesh Vutla <[email protected]> Signed-off-by: Thierry Reding <[email protected]>
1 parent 867beb6 commit e793eef

File tree

1 file changed

+7
-14
lines changed

1 file changed

+7
-14
lines changed

drivers/pwm/pwm-omap-dmtimer.c

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
* Limitations:
2020
* - When PWM is stopped, timer counter gets stopped immediately. This
2121
* doesn't allow the current PWM period to complete and stops abruptly.
22+
* - When PWM is running and changing both duty cycle and period,
23+
* we cannot prevent in software that the output might produce
24+
* a period with mixed settings. Especially when period/duty_cyle
25+
* is updated while the pwm pin is high, current pwm period/duty_cycle
26+
* can get updated as below based on the current timer counter:
27+
* - period for current cycle = current_period + new period
28+
* - duty_cycle for current period = current period + new duty_cycle.
2229
*/
2330

2431
#include <linux/clk.h>
@@ -111,7 +118,6 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
111118
u32 load_value, match_value;
112119
struct clk *fclk;
113120
unsigned long clk_rate;
114-
bool timer_active;
115121

116122
dev_dbg(chip->dev, "requested duty cycle: %d ns, period: %d ns\n",
117123
duty_ns, period_ns);
@@ -187,25 +193,12 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
187193
load_value = (DM_TIMER_MAX - period_cycles) + 1;
188194
match_value = load_value + duty_cycles - 1;
189195

190-
/*
191-
* We MUST stop the associated dual-mode timer before attempting to
192-
* write its registers, but calls to omap_dm_timer_start/stop must
193-
* be balanced so check if timer is active before calling timer_stop.
194-
*/
195-
timer_active = pm_runtime_active(&omap->dm_timer_pdev->dev);
196-
if (timer_active)
197-
omap->pdata->stop(omap->dm_timer);
198-
199196
omap->pdata->set_load(omap->dm_timer, load_value);
200197
omap->pdata->set_match(omap->dm_timer, true, match_value);
201198

202199
dev_dbg(chip->dev, "load value: %#08x (%d), match value: %#08x (%d)\n",
203200
load_value, load_value, match_value, match_value);
204201

205-
/* If config was called while timer was running it must be reenabled. */
206-
if (timer_active)
207-
pwm_omap_dmtimer_start(omap);
208-
209202
mutex_unlock(&omap->mutex);
210203

211204
return 0;

0 commit comments

Comments
 (0)