nb/intel/gm45/gma: Centralize call to gm45_get_lvds_edid_str()

There is only a single place where we need the LVDS EDID string. Let's
call gm45_get_lvds_edid_str() right there. This simplifies the API and
helps to follow the execution flow.

The function is moved to avoid a forward declaration.

Change-Id: I86f3a88e6b661bcf60319edbe301e70304924727
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/75378
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-by: Felix Singer <service+coreboot-gerrit@felixsinger.de>
diff --git a/src/mainboard/lenovo/x200/blc.c b/src/mainboard/lenovo/x200/blc.c
index 655be56..99def22d 100644
--- a/src/mainboard/lenovo/x200/blc.c
+++ b/src/mainboard/lenovo/x200/blc.c
@@ -38,7 +38,7 @@
 
 const char *mainboard_vbt_filename(void)
 {
-	u16 pwm_freq = get_blc_pwm_freq_value(gm45_get_lvds_edid_str());
+	u16 pwm_freq = get_blc_pwm_freq_value();
 
 	if (pwm_freq == 0) {
 		printk(BIOS_DEBUG,
diff --git a/src/northbridge/intel/gm45/gm45.h b/src/northbridge/intel/gm45/gm45.h
index d30ebe3..d929533 100644
--- a/src/northbridge/intel/gm45/gm45.h
+++ b/src/northbridge/intel/gm45/gm45.h
@@ -444,13 +444,11 @@
 	int pwm_freq; /* In Hz */
 };
 int get_blc_values(const struct blc_pwm_t **entries);
-u16 get_blc_pwm_freq_value(const char *edid_ascii_string);
+u16 get_blc_pwm_freq_value(void);
 
 #include <device/device.h>
 #include <edid.h>
 
-const char *gm45_get_lvds_edid_str(void);
-
 struct acpi_rsdp;
 unsigned long northbridge_write_acpi_tables(const struct device *device, unsigned long start,
 						struct acpi_rsdp *rsdp);
diff --git a/src/northbridge/intel/gm45/gma.c b/src/northbridge/intel/gm45/gma.c
index 6034ae3..0986ad5 100644
--- a/src/northbridge/intel/gm45/gma.c
+++ b/src/northbridge/intel/gm45/gma.c
@@ -29,6 +29,33 @@
 	write32(res2mmio(gtt_res, reg, 0), data);
 }
 
+static const char *gm45_get_lvds_edid_str(void)
+{
+	u8 *mmio;
+	u8 edid_data_lvds[128];
+	struct edid edid_lvds;
+	static char edid_str[EDID_ASCII_STRING_LENGTH + 1];
+
+	if (edid_str[0])
+		return edid_str;
+	if (!gtt_res) {
+		printk(BIOS_ERR, "Never call %s() outside dev.init() context.\n", __func__);
+		return NULL;
+	}
+	mmio = res2mmio(gtt_res, 0, 0);
+
+	printk(BIOS_DEBUG, "LVDS EDID\n");
+	intel_gmbus_read_edid(mmio + GMBUS0, GMBUS_PORT_PANEL, 0x50,
+			edid_data_lvds, sizeof(edid_data_lvds));
+	intel_gmbus_stop(mmio + GMBUS0);
+
+	if (decode_edid(edid_data_lvds, sizeof(edid_data_lvds), &edid_lvds)
+	    != EDID_CONFORMANT)
+		return NULL;
+	memcpy(edid_str, edid_lvds.ascii_string, sizeof(edid_str));
+	return edid_str;
+}
+
 static u32 get_cdclk(struct device *const dev)
 {
 	const u16 cdclk_sel = pci_read_config16(dev, GCFGC_OFFSET) & GCFGC_CD_MASK;
@@ -60,17 +87,22 @@
 		return (blc_mod << 16) | blc_mod;
 }
 
-u16 get_blc_pwm_freq_value(const char *edid_ascii_string)
+u16 get_blc_pwm_freq_value(void)
 {
 	static u16 blc_pwm_freq;
 	const struct blc_pwm_t *blc_pwm;
 	int i;
 	int blc_array_len;
 
-	/* Prevent null-deref on strcmp() below */
-	if (blc_pwm_freq > 0 || !edid_ascii_string)
+	if (blc_pwm_freq > 0)
 		return blc_pwm_freq;
 
+	const char *const edid_ascii_string = gm45_get_lvds_edid_str();
+	if (!edid_ascii_string) {
+		printk(BIOS_ERR, "Need LVDS EDID string to derive backlight PWM frequency!\n");
+		return 0;
+	}
+
 	blc_array_len = get_blc_values(&blc_pwm);
 	/* Find EDID string and pwm freq in lookup table */
 	for (i = 0; i < blc_array_len; i++) {
@@ -94,8 +126,7 @@
 	return blc_pwm_freq;
 }
 
-static void gma_pm_init_post_vbios(struct device *const dev,
-				const char *edid_ascii_string)
+static void gma_pm_init_post_vbios(struct device *const dev)
 {
 	const struct northbridge_intel_gm45_config *const conf = dev->chip_info;
 
@@ -132,7 +163,7 @@
 	reg8 = 100;
 	if (conf->duty_cycle != 0)
 		reg8 = conf->duty_cycle;
-	pwm_freq = get_blc_pwm_freq_value(edid_ascii_string);
+	pwm_freq = get_blc_pwm_freq_value();
 	if (pwm_freq == 0 && conf->default_pwm_freq != 0)
 		pwm_freq = conf->default_pwm_freq;
 
@@ -143,37 +174,9 @@
 								reg8));
 }
 
-const char *gm45_get_lvds_edid_str(void)
-{
-	u8 *mmio;
-	u8 edid_data_lvds[128];
-	struct edid edid_lvds;
-	static char edid_str[EDID_ASCII_STRING_LENGTH + 1];
-
-	if (edid_str[0])
-		return edid_str;
-	if (!gtt_res) {
-		printk(BIOS_ERR, "Never call %s() outside dev.init() context.\n", __func__);
-		return NULL;
-	}
-	mmio = res2mmio(gtt_res, 0, 0);
-
-	printk(BIOS_DEBUG, "LVDS EDID\n");
-	intel_gmbus_read_edid(mmio + GMBUS0, GMBUS_PORT_PANEL, 0x50,
-			edid_data_lvds, sizeof(edid_data_lvds));
-	intel_gmbus_stop(mmio + GMBUS0);
-
-	if (decode_edid(edid_data_lvds, sizeof(edid_data_lvds), &edid_lvds)
-	    != EDID_CONFORMANT)
-		return NULL;
-	memcpy(edid_str, edid_lvds.ascii_string, sizeof(edid_str));
-	return edid_str;
-}
-
 static void gma_func0_init(struct device *dev)
 {
 	const struct northbridge_intel_gm45_config *const conf = dev->chip_info;
-	const char *edid_str;
 
 	/* Probe MMIO resource first. It's needed even for
 	   intel_gma_init_igd_opregion() which may call back. */
@@ -183,10 +186,6 @@
 
 	intel_gma_init_igd_opregion();
 
-	edid_str = gm45_get_lvds_edid_str();
-	if (!edid_str)
-		printk(BIOS_ERR, "Failed to obtain LVDS EDID string!\n");
-
 	/*
 	 * GTT base is at a 2M offset and is 2M big. If GTT is smaller than 2M
 	 * cycles are simply not decoded which is fine.
@@ -204,7 +203,7 @@
 	}
 
 	/* Post VBIOS init */
-	gma_pm_init_post_vbios(dev, edid_str);
+	gma_pm_init_post_vbios(dev);
 
 	if (CONFIG(MAINBOARD_USE_LIBGFXINIT) && !acpi_is_wakeup_s3()) {
 		int vga_disable = (pci_read_config16(dev, D0F0_GGC) & 2) >> 1;