[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