[coreboot-gerrit] Change in coreboot[master]: nb/intel/gm45/gma.c: Decode EDID before NGI path

Arthur Heymans (Code Review) gerrit at coreboot.org
Sun Apr 30 08:33:44 CEST 2017


Arthur Heymans has uploaded a new change for review. ( https://review.coreboot.org/19503 )

Change subject: nb/intel/gm45/gma.c: Decode EDID before NGI path
......................................................................

nb/intel/gm45/gma.c: Decode EDID before NGI path

This allows to use EDID data outside of NGI path without needing to
fetch it twice.

Change-Id: I6a540b1d036a9f38b44fd004309601630861f6e7
Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
M src/northbridge/intel/gm45/gma.c
1 file changed, 53 insertions(+), 59 deletions(-)


  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/03/19503/1

diff --git a/src/northbridge/intel/gm45/gma.c b/src/northbridge/intel/gm45/gma.c
index cbb8451..be0c077 100644
--- a/src/northbridge/intel/gm45/gma.c
+++ b/src/northbridge/intel/gm45/gma.c
@@ -50,12 +50,10 @@
 }
 
 static void gma_init_lvds(const struct northbridge_intel_gm45_config *info,
-			   u8 *mmio, u32 physbase, u16 piobase, u32 lfb)
+			u8 *mmio, u32 physbase, u16 piobase, u32 lfb,
+			struct edid *edid)
 {
-
 	int i;
-	u8 edid_data[128];
-	struct edid edid;
 	struct edid_mode *mode;
 	u32 hactive, vactive, right_border, bottom_border;
 	int hpolarity, vpolarity;
@@ -93,17 +91,13 @@
 	for (i = 0; i <= 0x18; i++)
 		vga_cr_write(i, cr[i]);
 
-	intel_gmbus_read_edid(mmio + GMBUS0, 3, 0x50, edid_data,
-			sizeof(edid_data));
-	decode_edid(edid_data,
-		    sizeof(edid_data), &edid);
-	mode = &edid.mode;
-
 	/* Disable screen memory to prevent garbage from appearing. */
 	vga_sr_write(1, vga_sr_read(1) | 0x20);
 
-	hactive = edid.x_resolution;
-	vactive = edid.y_resolution;
+	mode = &edid->mode;
+
+	hactive = edid->x_resolution;
+	vactive = edid->y_resolution;
 	right_border = mode->hborder;
 	bottom_border = mode->vborder;
 	hpolarity = (mode->phsync == '-');
@@ -131,11 +125,11 @@
 		vga_gr_write(0x10, 0x1);
 		vga_gr_write(0x11, 0);
 
-		edid.bytes_per_line = (edid.bytes_per_line + 63) & ~63;
+		edid->bytes_per_line = (edid->bytes_per_line + 63) & ~63;
 
 		write32(mmio + DSPCNTR(0), DISPPLANE_BGRX888);
 		write32(mmio + DSPADDR(0), 0);
-		write32(mmio + DSPSTRIDE(0), edid.bytes_per_line);
+		write32(mmio + DSPSTRIDE(0), edid->bytes_per_line);
 		write32(mmio + DSPSURF(0), 0);
 		for (i = 0; i < 0x100; i++)
 			write32(mmio + LGC_PALETTE(0) + 4 * i, i * 0x010101);
@@ -315,18 +309,17 @@
 
 	if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
 		memset((void *) lfb, 0,
-		       edid.x_resolution * edid.y_resolution * 4);
-		set_vbe_mode_info_valid(&edid, lfb);
+		       edid->x_resolution * edid->y_resolution * 4);
+		set_vbe_mode_info_valid(edid, lfb);
 	}
 }
 
 static void gma_init_vga(const struct northbridge_intel_gm45_config *info,
-			 u8 *mmio, u32 physbase, u16 piobase, u32 lfb)
+			u8 *mmio, u32 physbase, u16 piobase, u32 lfb,
+			struct edid *edid)
 {
 
 	int i;
-	u8 edid_data[128];
-	struct edid edid;
 	struct edid_mode *mode;
 	u32 hactive, vactive, right_border, bottom_border;
 	int hpolarity, vpolarity;
@@ -378,19 +371,13 @@
 
 	udelay(1);
 
-	intel_gmbus_read_edid(mmio + GMBUS0, 2, 0x50, edid_data,
-			sizeof(edid_data));
-	intel_gmbus_stop(mmio + GMBUS0);
-	decode_edid(edid_data,
-		    sizeof(edid_data), &edid);
-	mode = &edid.mode;
-
-
 	/* Disable screen memory to prevent garbage from appearing.  */
 	vga_sr_write(1, vga_sr_read(1) | 0x20);
 
-	hactive = edid.x_resolution;
-	vactive = edid.y_resolution;
+	mode = &edid->mode;
+
+	hactive = edid->x_resolution;
+	vactive = edid->y_resolution;
 	right_border = mode->hborder;
 	bottom_border = mode->vborder;
 	hpolarity = (mode->phsync == '-');
@@ -419,12 +406,12 @@
 		vga_gr_write(0x10, 0x1);
 		vga_gr_write(0x11, 0);
 
-		edid.bytes_per_line = (edid.bytes_per_line + 63) & ~63;
+		edid->bytes_per_line = (edid->bytes_per_line + 63) & ~63;
 
 		write32(mmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE
 			| DISPPLANE_BGRX888);
 		write32(mmio + DSPADDR(0), 0);
-		write32(mmio + DSPSTRIDE(0), edid.bytes_per_line);
+		write32(mmio + DSPSTRIDE(0), edid->bytes_per_line);
 		write32(mmio + DSPSURF(0), 0);
 		for (i = 0; i < 0x100; i++)
 			write32(mmio + LGC_PALETTE(0) + 4 * i, i * 0x010101);
@@ -584,30 +571,11 @@
 
 	if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
 		memset((void *) lfb, 0,
-			edid.x_resolution * edid.y_resolution * 4);
-		set_vbe_mode_info_valid(&edid, lfb);
+			edid->x_resolution * edid->y_resolution * 4);
+		set_vbe_mode_info_valid(edid, lfb);
 	}
 
 
-}
-
-/* compare the header of the vga edid header */
-/* if vga is not connected it should not have a correct header */
-static u8 vga_connected(u8 *mmio)
-{
-	u8 vga_edid[128];
-	u8 header[8] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
-	intel_gmbus_read_edid(mmio + GMBUS0, 2, 0x50, vga_edid,
-			sizeof(vga_edid));
-	intel_gmbus_stop(mmio + GMBUS0);
-	for (int i = 0; i < 8; i++) {
-		if (vga_edid[i] != header[i]) {
-			printk(BIOS_DEBUG, "VGA not connected. Using LVDS display\n");
-			return 0;
-		}
-	}
-	printk(BIOS_SPEW, "VGA display connected\n");
-	return 1;
 }
 
 static u32 get_cdclk(struct device *const dev)
@@ -687,6 +655,10 @@
 static void gma_func0_init(struct device *dev)
 {
 	u32 reg32;
+	u8 *mmio;
+	u8 edid_data_vga[128], edid_data_lvds[128];
+	struct edid edid_vga, edid_lvds;
+	int lvds_edid_status, vga_edid_status;
 
 	/* IGD needs to be Bus Master */
 	reg32 = pci_read_config32(dev, PCI_COMMAND);
@@ -695,13 +667,29 @@
 
 	/* Init graphics power management */
 	gtt_res = find_resource(dev, PCI_BASE_ADDRESS_0);
+	mmio = res2mmio(gtt_res, 0, 0);
 
 	struct northbridge_intel_gm45_config *conf = dev->chip_info;
 
 	if (!IS_ENABLED(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT)) {
 		/* PCI Init, will run VBIOS */
+		printk(BIOS_DEBUG, "Initialising IGD using VBIOS\n");
 		pci_dev_init(dev);
 	}
+
+	printk(BIOS_DEBUG, "LVDS EDID\n");
+	intel_gmbus_read_edid(mmio + GMBUS0, 3, 0x50, edid_data_lvds,
+			sizeof(edid_data_lvds));
+	intel_gmbus_stop(mmio + GMBUS0);
+	lvds_edid_status = decode_edid(edid_data_lvds,
+				sizeof(edid_data_lvds), &edid_lvds);
+
+	printk(BIOS_DEBUG, "VGA EDID\n");
+	intel_gmbus_read_edid(mmio + GMBUS0, 2, 0x50, edid_data_vga,
+			sizeof(edid_data_vga));
+	intel_gmbus_stop(mmio + GMBUS0);
+	vga_edid_status = decode_edid(edid_data_vga,
+				sizeof(edid_data_vga), &edid_vga);
 
 	/* Post VBIOS init */
 	gma_pm_init_post_vbios(dev);
@@ -719,14 +707,20 @@
 		if (gtt_res && gtt_res->base && physbase && pio_res
 		    && pio_res->base && lfb_res && lfb_res->base) {
 			printk(BIOS_SPEW,
-			       "Initializing VGA without OPROM. MMIO 0x%llx\n",
+			       "Initializing display without OPROM. MMIO 0x%llx\n",
 			       gtt_res->base);
-			if (vga_connected(res2mmio(gtt_res, 0, 0)))
-				gma_init_vga(conf, res2mmio(gtt_res, 0, 0),
-					physbase, pio_res->base, lfb_res->base);
-			else
-				gma_init_lvds(conf, res2mmio(gtt_res, 0, 0),
-					physbase, pio_res->base, lfb_res->base);
+			if (vga_edid_status != EDID_ABSENT) {
+				printk(BIOS_DEBUG,
+					"Initialising display on VGA output\n");
+				gma_init_vga(conf, mmio, physbase,
+					pio_res->base, lfb_res->base, &edid_vga);
+			} else {
+				printk(BIOS_DEBUG,
+					"Initialising display on LVDS output\n");
+				gma_init_lvds(conf, mmio, physbase,
+					pio_res->base, lfb_res->base,
+					&edid_lvds);
+			}
 		}
 
 		/* Linux relies on VBT for panel info.  */

-- 
To view, visit https://review.coreboot.org/19503
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I6a540b1d036a9f38b44fd004309601630861f6e7
Gerrit-PatchSet: 1
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Owner: Arthur Heymans <arthur at aheymans.xyz>



More information about the coreboot-gerrit mailing list