Re: [PATCH] ARM: dts: omap3-gta04: reduce panel backlight PWM frequency to 83Hz
From: H. Nikolaus Schaller
Date: Sat Sep 10 2016 - 03:08:31 EST
Hi,
> Am 10.09.2016 um 05:17 schrieb Matthijs van Duin <matthijsvanduin@xxxxxxxxx>:
>
> On Mon, Sep 05, 2016 at 11:16:38AM +0200, H. Nikolaus Schaller wrote:
>> This helps to get 100% intensity closer to "always on".
>>
>> It compensates for an effect of dmtimer which at 100% still emits short
>> "off" impulses and the startup-time of the DC/DC converter makes
>> backlight intensity not reach full scale. The lower the PWM frequency
>> is, the smaller is this effect.
>
> Sounds to me like you're working around something that should be fixed
Yes and no.
Reducing the PWM frequency is good by itself since it should not be unnecessarily
fast and helps to make the PWM to "average current" translation more linear.
The non-linear effect is that the PWM controlled DC/DC converter reacts almost
immediately to a 1->0 control transition but needs some time (ca. 0.5ms) to recover
on a 0->1 transition. So if you run PWM @ 500Hz and 100% there is 1ms 1 and 1 ms 0.
But this translates to 1.5 ms no power and 0.5ms power which is 50% of the intended
current.
This gives some "reduction" factor to all PWM duty cycle values, but the 100%
case is the most noticeable one.
If we just fix the PWM generator to output a steady 1 signal at 100%, we have a
very significant change if we switch to 99%, depending on PWM frequency.
This effect becomes smaller if the PWM frequency is reduced and 83Hz seems more
reasonable (although still a little arbitrary) than the current value. (BTW: for
the Pyra we already use 83Hz).
> in the pwm-omap-dmtimer driver instead?
Yes, it probably should be fixed as well but it does not completely solve
the backlight control issue due to the DC/DC converter's behaviour.
>
> Looking at the (baremetal) dmtimer pwm code I wrote ages ago, which
> supports fully off to fully on, I do seem to be handling both endpoints
> in a special way. A rough conversion of my code into C:
>
> // period in timer cycles
> void pwm_init( volatile struct dmtimer *timer, u32 period, bool invert )
> {
> assert( period >= 2 );
> timer->if_ctrl = 2; // reset timer, configure as non-posted
> timer->reload = -period;
> timer->trigger = 0;
> timer->config = 0x1043 | invert << 7; // pwm initially disabled
> }
>
> // value in timer cycles, 0 <= value <= period
> void pwm_set( volatile struct dmtimer *timer, u32 value )
> {
> if( value == 0 ) {
> timer->config &= ~0x800; // disable pwm
> return;
> }
> u32 period = -timer->reload;
> if( value >= period )
> timer->match = 0;
> else
> timer->match = value - period - 1;
> timer->config |= 0x800; // enable pwm
> }
>
> At the time I used a scope to check the exact behaviour of dmtimer pwm
> on a dm814x. My notes mention (when pwm enabled):
> match < reload output on continuous
> match == reload output on 1 cycle, off period-1 cycles
> match == -2 output on period-1 cycles, off 1 cycle
> match == -1 output freezes
>
> Hope this helps
>
> Matthijs
BR,
Nikolaus