From f3e0a13f70f2467dc99fec89baa8298636a9251c Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Wed, 14 Jan 2015 17:33:00 -0800 Subject: [PATCH] broadwell: Turn off panel backlight in S5 SMI handler In order for some panels to meet spec when the system is put into S5 by way of power button during firmware (i.e. not by the OS) then it needs to turn off the backlight and give it time to turn off before going into S5. If the OS properly sequences the panel down then the backlight enable bit will not be set in this step and nothing will happen. BUG=chrome-os-partner:33994 BRANCH=broadwell TEST=build and boot on samus Change-Id: Ic86f388218f889b1fe690cc1bfc5c3e233e95115 Signed-off-by: Stefan Reinauer Original-Commit-Id: e3c9c131a87bae380e1fd3f96c9ad780441add56 Original-Change-Id: I43c5aee8e32768fc9e82790c9f7ceda0ed17ed13 Original-Signed-off-by: Duncan Laurie Original-Reviewed-on: https://chromium-review.googlesource.com/240852 Original-Reviewed-by: Shawn N Reviewed-on: http://review.coreboot.org/9490 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/soc/intel/broadwell/smihandler.c | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/soc/intel/broadwell/smihandler.c b/src/soc/intel/broadwell/smihandler.c index 5004a6a214..63c93739e7 100644 --- a/src/soc/intel/broadwell/smihandler.c +++ b/src/soc/intel/broadwell/smihandler.c @@ -36,6 +36,7 @@ #include #include #include +#include static u8 smm_initialized = 0; @@ -109,6 +110,45 @@ static void busmaster_disable_on_bus(int bus) } } +/* + * Turn off the backlight if it is on, and wait for the specified + * backlight off delay. This will allow panel power timings to meet + * spec and prevent brief garbage on the screen when turned off + * during firmware with power button triggered SMI. + */ +static void backlight_off(void) +{ + void *reg_base; + uint32_t pp_ctrl; + uint32_t bl_off_delay; + + reg_base = (void *)((uintptr_t)pci_read_config32(SA_DEV_IGD, PCI_BASE_ADDRESS_0) & ~0xf); + + /* Check if backlight is enabled */ + pp_ctrl = read32(reg_base + PCH_PP_CONTROL); + if (!(pp_ctrl & EDP_BLC_ENABLE)) + return; + + /* Enable writes to this register */ + pp_ctrl &= ~PANEL_UNLOCK_MASK; + pp_ctrl |= PANEL_UNLOCK_REGS; + + /* Turn off backlight */ + pp_ctrl &= ~EDP_BLC_ENABLE; + + write32(reg_base + PCH_PP_CONTROL, pp_ctrl); + read32(reg_base + PCH_PP_CONTROL); + + /* Read backlight off delay in 100us units */ + bl_off_delay = read32(reg_base + PCH_PP_OFF_DELAYS); + bl_off_delay &= PANEL_LIGHT_OFF_DELAY_MASK; + bl_off_delay *= 100; + + /* Wait for backlight to turn off */ + udelay(bl_off_delay); + + printk(BIOS_INFO, "Backlight turned off\n"); +} static void southbridge_smi_sleep(void) { @@ -170,6 +210,9 @@ static void southbridge_smi_sleep(void) case SLP_TYP_S5: printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n"); + /* Turn off backlight if needed */ + backlight_off(); + /* Disable all GPE */ disable_all_gpe();