[coreboot-gerrit] New patch to review for coreboot: [WIP] nb/i945/gma.c: Set pwm backlight frequency instead of using magic numbers
Arthur Heymans (arthur@aheymans.xyz)
gerrit at coreboot.org
Sat Jan 14 22:44:45 CET 2017
Arthur Heymans (arthur at aheymans.xyz) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18141
-gerrit
commit 082722b0fca450c92d03faa369285238b4a027fb
Author: Arthur Heymans <arthur at aheymans.xyz>
Date: Sat Jan 14 22:31:54 2017 +0100
[WIP] nb/i945/gma.c: Set pwm backlight frequency instead of using magic numbers
The core display clock on 945gm is fixed on 400MHz according to linux
src.
This assumes that the BLC_PWM_CTL reg has similar semantics as later
Intel chipsets namely: pwm_freq = cdclock / (128 * (BLC_PWM_CTL[31:17]
<< 1)).
It reduces default pwm freq on 945gm board since it was unreasonably
high (> 10000Hz). This value should be fine for LED backlit
display (1000Hz) but since all those boards have CCFL by default a
lower value might be desired (~100Hz).
Most board currently have smm code that rely on legacy mode operation
of blacklight duty cycle.
It reuses some gm45 code to set up panel.
UNTESTED
Change-Id: I1c47b68eecc19624ee534598c22da183bc89425d
Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
src/mainboard/apple/macbook21/devicetree.cb | 2 +-
src/mainboard/lenovo/t60/devicetree.cb | 2 +-
src/mainboard/lenovo/x60/devicetree.cb | 2 +-
src/northbridge/intel/i945/chip.h | 7 ++-
src/northbridge/intel/i945/gma.c | 88 +++++++++++++++++++++++++----
5 files changed, 86 insertions(+), 15 deletions(-)
diff --git a/src/mainboard/apple/macbook21/devicetree.cb b/src/mainboard/apple/macbook21/devicetree.cb
index f37e768..d8a5b40 100644
--- a/src/mainboard/apple/macbook21/devicetree.cb
+++ b/src/mainboard/apple/macbook21/devicetree.cb
@@ -22,7 +22,7 @@ chip northbridge/intel/i945
register "gpu_hotplug" = "0x00000220"
register "gpu_lvds_use_spread_spectrum_clock" = "1"
- register "gpu_backlight" = "0x1290128"
+ register "pwm_freq" = "1000"
device cpu_cluster 0 on
chip cpu/intel/socket_mFCPGA478
diff --git a/src/mainboard/lenovo/t60/devicetree.cb b/src/mainboard/lenovo/t60/devicetree.cb
index f66455b..6ef95d5 100644
--- a/src/mainboard/lenovo/t60/devicetree.cb
+++ b/src/mainboard/lenovo/t60/devicetree.cb
@@ -22,7 +22,7 @@ chip northbridge/intel/i945
register "gpu_hotplug" = "0x00000220"
register "gpu_lvds_use_spread_spectrum_clock" = "1"
- register "gpu_backlight" = "0x1280128"
+ register "pwm_freq" = "1000"
device cpu_cluster 0 on
chip cpu/intel/socket_mFCPGA478
diff --git a/src/mainboard/lenovo/x60/devicetree.cb b/src/mainboard/lenovo/x60/devicetree.cb
index 0ac9273..1e99379 100644
--- a/src/mainboard/lenovo/x60/devicetree.cb
+++ b/src/mainboard/lenovo/x60/devicetree.cb
@@ -22,7 +22,7 @@ chip northbridge/intel/i945
register "gpu_hotplug" = "0x00000220"
register "gpu_lvds_use_spread_spectrum_clock" = "1"
- register "gpu_backlight" = "0x1290128"
+ register "pwm_freq" = "1000"
device cpu_cluster 0 on
chip cpu/intel/socket_mFCPGA478
diff --git a/src/northbridge/intel/i945/chip.h b/src/northbridge/intel/i945/chip.h
index 8eaa5b4..5bbda81 100644
--- a/src/northbridge/intel/i945/chip.h
+++ b/src/northbridge/intel/i945/chip.h
@@ -4,8 +4,13 @@
#include <drivers/intel/gma/i915.h>
struct northbridge_intel_i945_config {
+ 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 */
+ u8 gpu_panel_power_cycle_delay; /* T4 time sequence */
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 b9a37e4..ef57b20 100644
--- a/src/northbridge/intel/i945/gma.c
+++ b/src/northbridge/intel/i945/gma.c
@@ -46,6 +46,20 @@
#define PGETBL_ENABLED 0x00000001
#define BASE_FREQUENCY 100000
+#define CORE_DISPLAY_CLOCK 400000
+#define DEFAULT_PWM 1000
+
+static struct resource *gtt_res = NULL;
+
+u32 gtt_read(u32 reg)
+{
+ return read32(res2mmio(gtt_res, reg, 0));
+}
+
+void gtt_write(u32 reg, u32 data)
+{
+ write32(res2mmio(gtt_res, reg, 0), data);
+}
static int gtt_setup(void *mmiobase)
{
@@ -292,17 +306,6 @@ static int intel_gma_init_lvds(struct northbridge_intel_i945_config *conf,
write32(pmmio + DSPSIZE(0), (hactive - 1) | ((vactive - 1) << 16));
write32(pmmio + DSPPOS(0), 0);
- /* Backlight init. */
- write32(pmmio + FW_BLC_SELF, FW_BLC_SELF_EN_MASK);
- write32(pmmio + FW_BLC, 0x011d011a);
- write32(pmmio + FW_BLC2, 0x00000102);
- write32(pmmio + FW_BLC_SELF, FW_BLC_SELF_EN_MASK);
- write32(pmmio + FW_BLC_SELF, 0x0001003f);
- write32(pmmio + FW_BLC, 0x011d0109);
- write32(pmmio + FW_BLC2, 0x00000102);
- write32(pmmio + FW_BLC_SELF, FW_BLC_SELF_EN_MASK);
- write32(pmmio + BLC_PWM_CTL, conf->gpu_backlight);
-
edid.bytes_per_line = (edid.bytes_per_line + 63) & ~63;
write32(pmmio + DSPADDR(0), 0);
write32(pmmio + DSPSURF(0), 0);
@@ -579,6 +582,64 @@ static int probe_edid(u8 *pmmio, u8 slave)
return 1;
}
+static u32 freq_to_blc_pwm_ctl(struct device *const dev,
+ u16 pwm_freq)
+{
+ u32 blc_mod;
+
+ blc_mod = CORE_DISPLAY_CLOCK / (128 * pwm_freq);
+
+ return BLM_LEGACY_MODE | ((blc_mod / 2) << 17) | ((blc_mod / 2) << 1);
+}
+
+
+static void panel_setup(struct device *const dev)
+{
+ const struct northbridge_intel_i945_config *const conf = dev->chip_info;
+
+ u32 reg32;
+
+ /* Setup Panel Power On Delays */
+ reg32 = gtt_read(PP_ON_DELAYS);
+ if (!reg32) {
+ reg32 = (conf->gpu_panel_power_up_delay & 0x1fff) << 16;
+ reg32 |= (conf->gpu_panel_power_backlight_on_delay & 0x1fff);
+ gtt_write(PP_ON_DELAYS, reg32);
+ }
+
+ /* Setup Panel Power Off Delays */
+ reg32 = gtt_read(PP_OFF_DELAYS);
+ if (!reg32) {
+ reg32 = (conf->gpu_panel_power_down_delay & 0x1fff) << 16;
+ reg32 |= (conf->gpu_panel_power_backlight_off_delay & 0x1fff);
+ gtt_write(PP_OFF_DELAYS, reg32);
+ }
+
+ /* Setup Panel Power Cycle Delay */
+ if (conf->gpu_panel_power_cycle_delay) {
+ reg32 = (CORE_DISPLAY_CLOCK / 20000 - 1)
+ << PP_REFERENCE_DIVIDER_SHIFT;
+ reg32 |= conf->gpu_panel_power_cycle_delay & 0x1f;
+ gtt_write(PP_DIVISOR, reg32);
+ }
+
+ /* Backlight init. */
+ gtt_write(FW_BLC_SELF, FW_BLC_SELF_EN_MASK);
+ gtt_write(FW_BLC, 0x011d011a);
+ gtt_write(FW_BLC2, 0x00000102);
+ gtt_write(FW_BLC_SELF, FW_BLC_SELF_EN_MASK);
+ gtt_write(FW_BLC_SELF, 0x0001003f);
+ gtt_write(FW_BLC, 0x011d0109);
+ gtt_write(FW_BLC2, 0x00000102);
+ gtt_write(FW_BLC_SELF, FW_BLC_SELF_EN_MASK);
+ if (conf->pwm_freq == 0) {
+ reg32 = BLM_LEGACY_MODE | 0x01280128;
+ gtt_write(BLC_PWM_CTL, freq_to_blc_pwm_ctl(dev, DEFAULT_PWM));
+ } else {
+ gtt_write(BLC_PWM_CTL, freq_to_blc_pwm_ctl(dev,
+ conf->pwm_freq));
+ }
+}
static void gma_func0_init(struct device *dev)
{
@@ -596,6 +657,8 @@ static void gma_func0_init(struct device *dev)
pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER
| PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+ gtt_res = find_resource(dev, PCI_BASE_ADDRESS_0);
+
if (IS_ENABLED(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT)) {
/* This should probably run before post VBIOS init. */
printk(BIOS_SPEW, "Initializing VGA without OPROM.\n");
@@ -623,6 +686,9 @@ static void gma_func0_init(struct device *dev)
err = intel_gma_init_lvds(conf,
pci_read_config32(dev, 0x5c) & ~0xf,
iobase, mmiobase, graphics_base);
+
+ panel_setup(dev);
+
if (err == 0)
gfx_set_init_done(1);
/* Linux relies on VBT for panel info. */
More information about the coreboot-gerrit
mailing list