diff options
Diffstat (limited to 'src/northbridge')
-rw-r--r-- | src/northbridge/intel/haswell/chip.h | 7 | ||||
-rw-r--r-- | src/northbridge/intel/haswell/gma.c | 42 |
2 files changed, 39 insertions, 10 deletions
diff --git a/src/northbridge/intel/haswell/chip.h b/src/northbridge/intel/haswell/chip.h index cfc28845b2..d7ef27df16 100644 --- a/src/northbridge/intel/haswell/chip.h +++ b/src/northbridge/intel/haswell/chip.h @@ -36,8 +36,11 @@ struct northbridge_intel_haswell_config { u16 gpu_panel_power_backlight_on_delay; /* T5 time sequence */ u16 gpu_panel_power_backlight_off_delay; /* Tx time sequence */ - u32 gpu_cpu_backlight; /* CPU Backlight PWM value */ - u32 gpu_pch_backlight; /* PCH Backlight PWM value */ + unsigned int gpu_pch_backlight_pwm_hz; + enum { + GPU_BACKLIGHT_POLARITY_HIGH = 0, + GPU_BACKLIGHT_POLARITY_LOW, + } gpu_pch_backlight_polarity; bool gpu_ddi_e_connected; diff --git a/src/northbridge/intel/haswell/gma.c b/src/northbridge/intel/haswell/gma.c index eed6740bc3..65c5cf3e75 100644 --- a/src/northbridge/intel/haswell/gma.c +++ b/src/northbridge/intel/haswell/gma.c @@ -12,6 +12,7 @@ * GNU General Public License for more details. */ +#include <commonlib/helpers.h> #include <arch/io.h> #include <device/mmio.h> #include <device/pci_ops.h> @@ -347,14 +348,39 @@ static void gma_setup_panel(struct device *dev) gtt_write(PCH_PP_DIVISOR, reg32); } - /* Enable Backlight if needed */ - if (conf->gpu_cpu_backlight) { - gtt_write(BLC_PWM_CPU_CTL2, BLC_PWM2_ENABLE); - gtt_write(BLC_PWM_CPU_CTL, conf->gpu_cpu_backlight); - } - if (conf->gpu_pch_backlight) { - gtt_write(BLC_PWM_PCH_CTL1, BLM_PCH_PWM_ENABLE); - gtt_write(BLC_PWM_PCH_CTL2, conf->gpu_pch_backlight); + /* Enforce the PCH PWM function, as so does Linux. + The CPU PWM controls are disabled after reset. */ + if (conf->gpu_pch_backlight_pwm_hz) { + /* Reference clock is either 24MHz or 135MHz. We can choose + either a 16 or a 128 step increment. Use 16 if we would + have less than 100 steps otherwise. */ + const unsigned int refclock = CONFIG(INTEL_LYNXPOINT_LP) ? 24*MHz : 135*MHz; + const unsigned int hz_limit = refclock / 128 / 100; + unsigned int pwm_increment, pwm_period; + u32 south_chicken2; + + south_chicken2 = gtt_read(SOUTH_CHICKEN2); + if (conf->gpu_pch_backlight_pwm_hz > hz_limit) { + pwm_increment = 16; + south_chicken2 |= LPT_PWM_GRANULARITY; + } else { + pwm_increment = 128; + south_chicken2 &= ~LPT_PWM_GRANULARITY; + } + gtt_write(SOUTH_CHICKEN2, south_chicken2); + + pwm_period = refclock / pwm_increment / conf->gpu_pch_backlight_pwm_hz; + printk(BIOS_INFO, + "GMA: Setting backlight PWM frequency to %uMHz / %u / %u = %uHz\n", + refclock / MHz, pwm_increment, pwm_period, + DIV_ROUND_CLOSEST(refclock, pwm_increment * pwm_period)); + + /* Start with a 50% duty cycle. */ + gtt_write(BLC_PWM_PCH_CTL2, pwm_period << 16 | pwm_period / 2); + + gtt_write(BLC_PWM_PCH_CTL1, + (conf->gpu_pch_backlight_polarity == GPU_BACKLIGHT_POLARITY_LOW) << 29 | + BLM_PCH_OVERRIDE_ENABLE | BLM_PCH_PWM_ENABLE); } /* Get display,pipeline,and DDI registers into a basic sane state */ |