nb/intel/gm45: Set display backlight according to EDID string
Add some known good values for some thinkpads displays.
Known good means that at this pwm frequency the display is evenly lit
on all duty cycles, the display makes minimal to no noise at lower
duty cycles and the display does not flicker. This values differs from
vendor (which uses an obviously wrong display clock (190MHz instead
of 320MHz) resulting in frequency more than 60% off the intended
value.
TESTED on Thinkpad X200 with edid ascii string in list and removed
from list to see if notice message is shown.
Change-Id: Id7bc0d453fac31e806852206ba2c895720b2c843
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/19500
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
diff --git a/src/mainboard/lenovo/t400/Makefile.inc b/src/mainboard/lenovo/t400/Makefile.inc
index 3aa94b5..8ac61bb 100644
--- a/src/mainboard/lenovo/t400/Makefile.inc
+++ b/src/mainboard/lenovo/t400/Makefile.inc
@@ -18,3 +18,4 @@
ramstage-y += dock.c
ramstage-y += cstates.c
romstage-y += hybrid_graphics.c
+ramstage-y += blc.c
diff --git a/src/mainboard/lenovo/t400/blc.c b/src/mainboard/lenovo/t400/blc.c
new file mode 100644
index 0000000..01f34c1
--- /dev/null
+++ b/src/mainboard/lenovo/t400/blc.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 arthur@aheymans.xyz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <commonlib/helpers.h>
+#include <northbridge/intel/gm45/gm45.h>
+
+static const struct blc_pwm_t blc_entries[] = {
+ /* Vendor BIOS seems to intend to set PWM freq at 220Hz */
+ /* T400 */
+ {"B141EW04 V7 ", 110},
+ {"LP141WX3-TLR1", 110},
+ {"LP141WX5-TLP2", 450},
+ {"LTN141AT12401", 450},
+ {"LTN141W1-L05", 110},
+ {"LTN141WD-L05", 110},
+ /* T500 */
+ {"LP154W02-TL06", 110},
+ {"LTN154P3-L02", 110},
+};
+
+int get_blc_values(const struct blc_pwm_t **entries)
+{
+ *entries = blc_entries;
+ return ARRAY_SIZE(blc_entries);
+}
diff --git a/src/mainboard/lenovo/x200/Makefile.inc b/src/mainboard/lenovo/x200/Makefile.inc
index b382efb..c16aa6a 100644
--- a/src/mainboard/lenovo/x200/Makefile.inc
+++ b/src/mainboard/lenovo/x200/Makefile.inc
@@ -15,3 +15,4 @@
ramstage-y += dock.c
ramstage-y += cstates.c
+ramstage-y += blc.c
\ No newline at end of file
diff --git a/src/mainboard/lenovo/x200/blc.c b/src/mainboard/lenovo/x200/blc.c
new file mode 100644
index 0000000..3d35460
--- /dev/null
+++ b/src/mainboard/lenovo/x200/blc.c
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 arthur@aheymans.xyz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <commonlib/helpers.h>
+#include <northbridge/intel/gm45/gm45.h>
+
+static const struct blc_pwm_t blc_entries[] = {
+ {"LTD121EWVB", 165},
+ {"B121EW03 V6 ", 165},
+ /* datasheets: between 100 and 20k, typical 200 */
+ /* TESTED: works best at 400 */
+ {"B121EW09 V3 ", 400},
+ {"HV121WX4-120", 110}, /* Aftermarket AFFS lcd, works well at low pwm */
+ {"LTN121AT03001", 110},
+ {"LTN121AP03001", 750},
+ /* TODO: untested panels found on thinkwiki */
+ /* Generally CCFL runs best at lower PWM */
+ /* {"B121EW09 V2 ", 450}, */
+ /* {"N121IB-L05", 450}, */
+ {"LP121WX3-TLC1", 400}, /* TESTED to work best at this value */
+ /* {"LP121WX3-TLA1" 450}, */
+ /* {"B121EW03 V3 " 110}, */
+ /* {"LTN121AP02001" 110}, */
+};
+
+int get_blc_values(const struct blc_pwm_t **entries)
+{
+ *entries = blc_entries;
+ return ARRAY_SIZE(blc_entries);
+}
diff --git a/src/mainboard/roda/rk9/Makefile.inc b/src/mainboard/roda/rk9/Makefile.inc
index 5a16ed8..f92382ee 100644
--- a/src/mainboard/roda/rk9/Makefile.inc
+++ b/src/mainboard/roda/rk9/Makefile.inc
@@ -15,3 +15,4 @@
ramstage-$(CONFIG_CARDBUS_PLUGIN_SUPPORT) += ti_pci7xx1.c
ramstage-y += cstates.c
+ramstage-y += blc.c
diff --git a/src/mainboard/roda/rk9/blc.c b/src/mainboard/roda/rk9/blc.c
new file mode 100644
index 0000000..4b6104e
--- /dev/null
+++ b/src/mainboard/roda/rk9/blc.c
@@ -0,0 +1,22 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 arthur@aheymans.xyz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <northbridge/intel/gm45/gm45.h>
+
+int get_blc_values(const struct blc_pwm_t **entries)
+{
+ return 0;
+}
diff --git a/src/northbridge/intel/gm45/chip.h b/src/northbridge/intel/gm45/chip.h
index a281ee9..150dd9b 100644
--- a/src/northbridge/intel/gm45/chip.h
+++ b/src/northbridge/intel/gm45/chip.h
@@ -26,7 +26,7 @@
u16 gpu_panel_power_backlight_off_delay; /* Tx time sequence */
u8 gpu_panel_power_cycle_delay; /* T4 time sequence */
struct i915_gpu_controller_info gfx;
- u16 pwm_freq;
+ u16 default_pwm_freq;
u8 duty_cycle;
/*
diff --git a/src/northbridge/intel/gm45/gm45.h b/src/northbridge/intel/gm45/gm45.h
index 258809f..34f734c 100644
--- a/src/northbridge/intel/gm45/gm45.h
+++ b/src/northbridge/intel/gm45/gm45.h
@@ -436,6 +436,13 @@
void init_iommu(void);
+struct blc_pwm_t {
+ char ascii_string[13];
+ int pwm_freq; /* In Hz */
+};
+int get_blc_values(const struct blc_pwm_t **entries);
+
+
#if ENV_RAMSTAGE && !defined(__SIMPLE_DEVICE__)
#include <device/device.h>
diff --git a/src/northbridge/intel/gm45/gma.c b/src/northbridge/intel/gm45/gma.c
index 6ba43a2..c060bb0 100644
--- a/src/northbridge/intel/gm45/gma.c
+++ b/src/northbridge/intel/gm45/gma.c
@@ -653,12 +653,16 @@
return (blc_mod << 16) | blc_mod;
}
-static void gma_pm_init_post_vbios(struct device *const dev)
+static void gma_pm_init_post_vbios(struct device *const dev,
+ const char *edid_ascii_string)
{
const struct northbridge_intel_gm45_config *const conf = dev->chip_info;
u32 reg32;
u8 reg8;
+ const struct blc_pwm_t *blc_pwm;
+ int blc_array_len, i;
+ u16 pwm_freq = 0;
/* Setup Panel Power On Delays */
reg32 = gtt_read(PP_ON_DELAYS);
@@ -689,11 +693,35 @@
reg8 = 100;
if (conf->duty_cycle != 0)
reg8 = conf->duty_cycle;
- if (conf->pwm_freq == 0)
+ blc_array_len = get_blc_values(&blc_pwm);
+ if (conf->default_pwm_freq != 0)
+ pwm_freq = conf->default_pwm_freq;
+
+ /* Find EDID string and pwm freq in lookup table */
+ for (i = 0; i < blc_array_len; i++) {
+ if (!strncmp(blc_pwm[i].ascii_string, edid_ascii_string,
+ strlen(blc_pwm[i].ascii_string))) {
+ pwm_freq = blc_pwm[i].pwm_freq;
+ printk(BIOS_DEBUG, "Found EDID string: %s in lookup table, pwm: %dHz\n",
+ blc_pwm[i].ascii_string, pwm_freq);
+ break;
+ }
+ }
+
+ if (i == blc_array_len)
+ printk(BIOS_NOTICE, "Your panels EDID `%s` wasn't found in the"
+ "lookup table.\n You may have issues with your panels"
+ "backlight.\n If you want to help improving coreboot"
+ "please report: this EDID string\n and the result"
+ "of `intel_read read BLC_PWM_CTL`"
+ "(from intel-gpu-tools)\n while running vendor BIOS\n",
+ edid_ascii_string);
+
+ if (pwm_freq == 0)
gtt_write(BLC_PWM_CTL, 0x06100610);
else
- gtt_write(BLC_PWM_CTL, freq_to_blc_pwm_ctl(dev,
- conf->pwm_freq, reg8));
+ gtt_write(BLC_PWM_CTL, freq_to_blc_pwm_ctl(dev, pwm_freq,
+ reg8));
}
static void gma_func0_init(struct device *dev)
@@ -726,7 +754,7 @@
decode_edid(edid_data_lvds, sizeof(edid_data_lvds), &edid_lvds);
/* Post VBIOS init */
- gma_pm_init_post_vbios(dev);
+ gma_pm_init_post_vbios(dev, edid_lvds.ascii_string);
if (IS_ENABLED(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT))
gma_ngi(dev, &edid_lvds);