diff options
Diffstat (limited to 'src/northbridge/intel/i945')
-rw-r--r-- | src/northbridge/intel/i945/chip.h | 11 | ||||
-rw-r--r-- | src/northbridge/intel/i945/gma.c | 67 |
2 files changed, 72 insertions, 6 deletions
diff --git a/src/northbridge/intel/i945/chip.h b/src/northbridge/intel/i945/chip.h index 8eaa5b4a40..3925a73ff2 100644 --- a/src/northbridge/intel/i945/chip.h +++ b/src/northbridge/intel/i945/chip.h @@ -4,8 +4,17 @@ #include <drivers/intel/gma/i915.h> struct northbridge_intel_i945_config { + /* In units of 100us timer */ + /* Timings as defined in VESA Notebook Panel Standard */ + u16 gpu_panel_power_up_delay; /* T1+T2 time sequence */ + u16 gpu_panel_power_down_delay; /* T3 time sequence */ + u16 gpu_panel_power_backlight_on_delay; /* T5 time sequence */ + u16 gpu_panel_power_backlight_off_delay; /* Tx time sequence */ + /* In units of 0.1s */ + u8 gpu_panel_power_cycle_delay; + u32 gpu_hotplug; - u32 gpu_backlight; + u32 pwm_freq; int gpu_lvds_use_spread_spectrum_clock; struct i915_gpu_controller_info gfx; int pci_mmio_size; diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c index eac8717cde..e3fe0973f7 100644 --- a/src/northbridge/intel/i945/gma.c +++ b/src/northbridge/intel/i945/gma.c @@ -47,6 +47,8 @@ #define BASE_FREQUENCY 100000 +#define DEFAULT_BLC_PWM 180 + static int gtt_setup(u8 *mmiobase) { unsigned long PGETBL_save; @@ -134,8 +136,6 @@ static int intel_gma_init_lvds(struct northbridge_intel_i945_config *conf, write32(mmiobase + RENDER_RING_BASE + i, 0); for (i = 0; i < 0x20; i += 4) write32(mmiobase + FENCE_REG_965_0 + i, 0); - write32(mmiobase + PP_ON_DELAYS, 0); - write32(mmiobase + PP_OFF_DELAYS, 0); /* Disable VGA. */ write32(mmiobase + VGACNTRL, VGA_DISP_DISABLE); @@ -292,9 +292,6 @@ static int intel_gma_init_lvds(struct northbridge_intel_i945_config *conf, write32(mmiobase + DSPSIZE(0), (hactive - 1) | ((vactive - 1) << 16)); write32(mmiobase + DSPPOS(0), 0); - /* Backlight init. */ - write32(mmiobase + BLC_PWM_CTL, conf->gpu_backlight); - edid.bytes_per_line = (edid.bytes_per_line + 63) & ~63; write32(mmiobase + DSPADDR(0), 0); write32(mmiobase + DSPSURF(0), 0); @@ -571,6 +568,62 @@ static int probe_edid(u8 *mmiobase, u8 slave) return 1; } +static u32 get_cdclk(struct device *const dev) +{ + u16 gcfgc = pci_read_config16(dev, GCFGC); + + if (gcfgc & GC_LOW_FREQUENCY_ENABLE) { + return 133333333; + } else { + switch (gcfgc & GC_DISPLAY_CLOCK_MASK) { + case GC_DISPLAY_CLOCK_333_320_MHZ: + return 320000000; + default: + case GC_DISPLAY_CLOCK_190_200_MHZ: + return 200000000; + } + } +} + +static u32 freq_to_blc_pwm_ctl(struct device *const dev, u16 pwm_freq) +{ + u32 blc_mod; + + /* Set duty cycle to 100% due to use of legacy backlight control */ + blc_mod = get_cdclk(dev) / (32 * pwm_freq); + return BLM_LEGACY_MODE | ((blc_mod / 2) << 17) | ((blc_mod / 2) << 1); +} + + +static void panel_setup(u8 *mmiobase, struct device *const dev) +{ + const struct northbridge_intel_i945_config *const conf = dev->chip_info; + + u32 reg32; + + /* Set up Panel Power On Delays */ + reg32 = (conf->gpu_panel_power_up_delay & 0x1fff) << 16; + reg32 |= (conf->gpu_panel_power_backlight_on_delay & 0x1fff); + write32(mmiobase + PP_ON_DELAYS, reg32); + + /* Set up Panel Power Off Delays */ + reg32 = (conf->gpu_panel_power_down_delay & 0x1fff) << 16; + reg32 |= (conf->gpu_panel_power_backlight_off_delay & 0x1fff); + write32(mmiobase + PP_OFF_DELAYS, reg32); + + /* Set up Panel Power Cycle Delay */ + reg32 = (get_cdclk(dev) / 20000 - 1) << PP_REFERENCE_DIVIDER_SHIFT; + reg32 |= conf->gpu_panel_power_cycle_delay & 0x1f; + write32(mmiobase + PP_DIVISOR, reg32); + + /* Backlight init. */ + if (conf->pwm_freq) + write32(mmiobase + BLC_PWM_CTL, freq_to_blc_pwm_ctl(dev, + conf->pwm_freq)); + else + write32(mmiobase + BLC_PWM_CTL, freq_to_blc_pwm_ctl(dev, + DEFAULT_BLC_PWM)); +} static void gma_func0_init(struct device *dev) { @@ -605,6 +658,10 @@ static void gma_func0_init(struct device *dev) ); int err; + + if (IS_ENABLED(CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GM)) + panel_setup(mmiobase, dev); + /* probe if VGA is connected and always run */ /* VGA init if no LVDS is connected */ if (!probe_edid(mmiobase, 3) || probe_edid(mmiobase, 2)) |