intel_extreme: backlight control on pre-PCH devices

Thanks to oco for letting me test this on his old laptop.
This commit is contained in:
Adrien Destugues 2017-11-23 23:56:55 +01:00
parent e042a53b7d
commit 8ddec194c6
2 changed files with 25 additions and 8 deletions

View File

@ -812,9 +812,11 @@ struct intel_free_graphics_memory {
#define PANEL_DIVISOR_POW_CYCLE_DLY_SHIFT 0x1f
// Backlight control registers
#define INTEL_BLC_PWM_CTL2 (0x8250 | REGS_NORTH_SHARED)
#define INTEL_BLC_PWM_CTL (0x8254 | REGS_NORTH_SHARED)
#define INTEL_SBLC_PWM_CTL2 (0x8254 | REGS_SOUTH_SHARED)
#define PCH_BLC_PWM_CTL2 (0x8250 | REGS_NORTH_SHARED)
#define PCH_BLC_PWM_CTL (0x8254 | REGS_NORTH_SHARED)
#define PCH_SBLC_PWM_CTL2 (0x8254 | REGS_SOUTH_SHARED)
#define MCH_BLC_PWM_CTL (0x1254 | REGS_NORTH_PIPE_AND_PORT)
// ring buffer commands

View File

@ -659,6 +659,19 @@ intel_get_edid_info(void* info, size_t size, uint32* _version)
}
static int32_t
intel_get_backlight_register(bool read)
{
if (gInfo->shared_info->pch_info == INTEL_PCH_NONE)
return MCH_BLC_PWM_CTL;
if (read)
return PCH_SBLC_PWM_CTL2;
else
return PCH_BLC_PWM_CTL;
}
status_t
intel_set_brightness(float brightness)
{
@ -667,8 +680,10 @@ intel_set_brightness(float brightness)
if (brightness < 0 || brightness > 1)
return B_BAD_VALUE;
uint16_t sblc = read32(INTEL_SBLC_PWM_CTL2) >> 16;
write32(INTEL_BLC_PWM_CTL, (uint32_t)(sblc * brightness));
uint32_t period = read32(intel_get_backlight_register(true)) >> 16;
uint32_t duty = (uint32_t)(period * brightness) & 0xfffe;
/* Setting the low bit seems to give strange results on some Atom machines */
write32(intel_get_backlight_register(false), duty | (period << 16));
return B_OK;
}
@ -682,9 +697,9 @@ intel_get_brightness(float* brightness)
if (brightness == NULL)
return B_BAD_VALUE;
uint16_t sblc = read32(INTEL_SBLC_PWM_CTL2) >> 16;
uint16_t blc = read32( INTEL_BLC_PWM_CTL );
*brightness = (float)blc / sblc;
uint16_t period = read32(intel_get_backlight_register(true)) >> 16;
uint16_t duty = read32(intel_get_backlight_register(false)) & 0xffff;
*brightness = (float)duty / period;
return B_OK;
}