Curiouser and curiouser...
I'm now looking at the "pwm.c" code in the following branch of the following source:
http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/log/?h=imx_2.6.35_maintain
It behaves differently. It doesn't have the bug where it glitches HIGH for a full cycle when the period is changed.
Instead it changes the FREQUENCY! Or more accurately, it changes the PHASE of the waveform on every brightness change.
The main drivers/video/backlight/backlight.c file calls pwm_backlight_update_status() in whatever PWM module is compiled in.
That function has always looked something like this (barring power and regulator complications added later):
static int pwm_backlight_update_status(struct backlight_device *bl)
{
...
if (brightness == 0) {
pwm_config(pb->pwm, 0, pb->period);
pwm_disable(pb->pwm);
} else {
pwm_config(pb->pwm, brightness * pb->period / max, pb->period);
pwm_enable(pb->pwm);
}
So changing the brightness calls pwm_config() then pwm_enable().
The version of the platform PWM code (which used to be in arch/arm/plat-mxc/pwm.c, but has recently moved to drivers/pwm/pwm-imx.c) used to look like this:
int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
{
...
cr = MX3_PWMCR_PRESCALER(prescale) |
MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN |
MX3_PWMCR_DBGEN | MX3_PWMCR_EN;
int pwm_enable(struct pwm_device *pwm)
{
...
if (!pwm->clk_enabled) {
rc = clk_prepare_enable(pwm->clk);
It was then changed to this:
int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
{
...
cr = MX3_PWMCR_PRESCALER(prescale) |
MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEEN |
MX3_PWMCR_WAITEN | MX3_PWMCR_DBGEN;
int pwm_enable(struct pwm_device *pwm)
{
...
pwm->clk_enabled = 1;
reg = readl(pwm->mmio_base + MX3_PWMCR);
reg |= MX3_PWMCR_EN;
writel(reg, pwm->mmio_base + MX3_PWMCR);
The older pwm_config() enabled the PWM module, or left it enabled and the pwm_enable() function did nothing.
The newer pwm_config() disables the PWM module and the following call to pwm_enable() starts it up again.
That results in a change to the brightness resetting the phase and doing this:

There are two places in the above where the brightness was changed and the waveform "restarted". The first one generated an over-long positive pulse with a short glitch in it, and the second one generated a short negative pulse.

Here's another example of what is an unexpected and unwanted output waveform from the PWM on a duty cycle change.
So you have a choice between the old code that glitches high, the newer code that glitches the phase/frequency, or a variation on my code which works without these problems.
The code has changed so much (and keeps changing) that it isn't possible to have anything like a "single patch" that will handle all the different variations. The addition of the "pwm: imx: Avoid sample FIFO overflow for i.MX PWM version2" in the mainline version just prior to v3.17rc1 complicates this even more.
And apparently by inspection (of the patch) changed the code from "phase glitch" back to "cycle glitch" as it leaves the PWM enabled after a call to pwm_config().
There are other bugs in previous versions the people may be using too.
The v3.1 code in pwm.c didn't handle the fact that the period is two cycles longer than the value loaded into the PWMPR register. That was fixed in v3.2
Meanwhile the Freescale code fixed this in a the following patch, which added a different bug:
Author: Yuxi Sun <b36102@freescale.com> 2011-12-15 13:12:53
Branches: imx_2.6.35_maintain
Follows: rel_imx_2.6.35_11.03.00
ENGR00170342 PWM: fix pwm output can't be set to 100% full duty
period_cycles = c;
prescale = period_cycles / 0x10000 + 1;
period_cycles /= prescale;
- c = (unsigned long long)period_cycles * duty_ns;
+ /* the chip document says the counter counts up to
+ * period_cycles + 1 and then is reset to 0, so the
+ * actual period of the PWM wave is period_cycles + 2
+ */
+ c = (unsigned long long)(period_cycles + 2) * duty_ns;
do_div(c, period_ns);
duty_cycles = c;
writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR);
writel(period_cycles, pwm->mmio_base + MX3_PWMPR);
The problem with the above is that it calculates the duty-cycle on the "+2" value of the period instead of the actual period.
For instance, with a period of 4 clocks and a duty of 50%, the correct values are PCMCR=6 and PWMSAR=2. The above calculates PWMCR=6 and PWMSAR=3, giving a 75% resulting duty cycle.
In the "usual case" of a backlight driver where the output frequency is low (less than 1kHz), the period is usually between 30,000 and 65536, so the error caused by this is minimal. But if you're generating a high frequency for power control it might cause a problem.
The Freescale "imx_2.6.35_maintain" branch has the above patch. The last "released" code for the i.MX53 (on the web page for the chip is "L2.6.35_11.09.01_ER" one, which also has the patch and h is probably this:
http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/log/?h=imx_2.6.35_11.09.01
Tom