Bug 12845

Summary: radeon backlight shutoff flashes momentarily
Product: Drivers Reporter: Robert Drury (rtdrury)
Component: Console/FramebuffersAssignee: James Simmons (jsimmons)
Status: CLOSED OBSOLETE    
Severity: normal CC: akpm, alan
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 2.6.23.9 Subsystem:
Regression: No Bisected commit-id:

Description Robert Drury 2009-03-09 04:29:54 UTC
Earliest failing kernel version:
This code appears unchanged since 2004

Distribution: YDL6.1
Hardware Environment: aluminum powerbook G4 with radeon

Problem Description:
When turning off the backlight with:
echo 0 > /sys/class/backlight/radeonbl0/brightness

The backlight momentarily flashes brightly before turning off.
If it is originally set to bright, the flash is not noticeable,
but if it is originally set to dim, the flash is noticeable.
I like to turn it all the way down with pbbuttonsd before turning it off
and I think this is momentary flash is stressful on the power circuit.

The code is in radeon_bl_update_status in
linux-2.6.23.9/drivers/video/aty/radeon_backlight.c

The development discussion is in a long thread:
http://lists.debian.org/debian-powerpc/2004/10/msg00438.html

The code to switch OFF the backlight
includes two writes to a radeon register:

    lvds_gen_cntl &= ~(LVDS_BL_MOD_LEVEL_MASK | LVDS_BL_MOD_EN);
    lvds_gen_cntl |= (radeon_bl_get_level_brightness(pdata, 0) <<
              LVDS_BL_MOD_LEVEL_SHIFT);
    lvds_gen_cntl |= LVDS_DISPLAY_DIS;
    OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);

    udelay(100);
    lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN);
    OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);

The first write causes the problem of turning the backlight way up.
To fix, remove the first manipulation of lvds_gen_cntl above it.
Second manipulation of lvds_gen_cntl does nothing (level always zero).

The first manipulation was needed per the discussion so the display
would not be garbled when the backlight comes back on, but at least
on my powerbook, the garbling problem seems to go away if you change
the udelay to 1000.  So the above code can be replaced with:

    lvds_gen_cntl |= LVDS_DISPLAY_DIS;
    OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);

    udelay(1000);
    lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN);
    OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);

It turns off and back on real nicely now.  So far, no problems.
Comment 1 Andrew Morton 2009-03-09 14:56:04 UTC
Please email a patch as per Docuemntation/SubmittingPatches to

linux-fbdev-devel@lists.sourceforge.net
Benjamin Herrenschmidt <benh@kernel.crashing.org>
Andrew Morton <akpm@linux-foundation.org>

Thanks.