link/graphics: Add support for EDID

This code is taken from an EDID reader written at Red Hat.

The key function is
int decode_edid(unsigned char *edid, int size, struct edid *out)

Which takes a pointer to an EDID blob, and a size, and decodes it into
a machine-independent format in out, which may be used for driving
chipsets. The EDID blob might come for IO, or a compiled-in EDID
BLOB, or CBFS.

Also included are the changes needed to use the EDID code on Link.

Change-Id: I66b275b8ed28fd77cfa5978bdec1eeef9e9425f1
Signed-off-by: Ronald G. Minnich <rminnich@google.com>
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Reviewed-on: http://review.coreboot.org/2837
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
Ronald G. Minnich 2013-03-13 14:35:01 -07:00 committed by Stefan Reinauer
parent a95a13bd47
commit b3b72f350e
5 changed files with 1857 additions and 362 deletions

66
src/include/edid.h Normal file
View File

@ -0,0 +1,66 @@
/*
* This file is part of the coreboot project.
*
* Copyright 2013 Google Inc.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef EDID_H
#define EDID_H
/* structure for communicating EDID information from a raw EDID block to
* higher level functions.
* The size of the data types is not critical, so we leave them as
* unsigned int. We can move more into into this struct as needed.
*/
struct edid {
char manuf_name[4];
unsigned int model;
unsigned int serial;
unsigned int year;
unsigned int week;
unsigned int version[2];
unsigned int nonconformant;
unsigned int type;
unsigned int bpp;
unsigned int voltage;
unsigned int sync;
unsigned int xsize_cm;
unsigned int ysize_cm;
/* used to compute timing for graphics chips. */
unsigned char phsync;
unsigned char pvsync;
unsigned int ha;
unsigned int hbl;
unsigned int hso;
unsigned int hspw;
unsigned int hborder;
unsigned int va;
unsigned int vbl;
unsigned int vso;
unsigned int vspw;
unsigned int vborder;
/* it is unlikely we need these things. */
/* if one of these is non-zero, use that one. */
unsigned int aspect_landscape;
unsigned int aspect_portrait;
const char *range_class;
const char *syncmethod;
const char *stereo;
};
int decode_edid(unsigned char *edid, int size, struct edid *out);
#endif /* EDID_H */

View File

@ -82,6 +82,7 @@ ramstage-$(CONFIG_BOOTSPLASH) += jpeg.c
ramstage-$(CONFIG_TRACE) += trace.c
ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
ramstage-$(CONFIG_COVERAGE) += libgcov.c
ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += edid.c
ramstage-$(CONFIG_CONSOLE_NE2K) += ne2k.c

1388
src/lib/edid.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -45,6 +45,7 @@
#include <cpu/x86/mtrr.h>
#include <cpu/amd/mtrr.h>
#include <cpu/x86/msr.h>
#include <edid.h>
#include "i915io.h"
enum {
@ -59,6 +60,18 @@ static unsigned short addrport;
static unsigned short dataport;
static unsigned int physbase;
extern int oprom_is_loaded;
static u32 htotal, hblank, hsync, vtotal, vblank, vsync;
const u32 link_edid_data[] = {
0xffffff00, 0x00ffffff, 0x0379e430, 0x00000000,
0x04011500, 0x96121ba5, 0xa2d54f02, 0x26935259,
0x00545017, 0x01010000, 0x01010101, 0x01010101,
0x01010101, 0x6f6d0101, 0xa4a0a000, 0x20306031,
0xb510003a, 0x19000010, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x4c00fe00,
0x69442047, 0x616c7073, 0x20200a79, 0xfe000000,
0x31504c00, 0x45513932, 0x50532d31, 0x24003141,
};
#define READ32(addr) io_i915_READ32(addr)
#define WRITE32(val, addr) io_i915_WRITE32(val, addr)
@ -178,6 +191,8 @@ static int run(int index)
int i, prev = 0;
struct iodef *id, *lastidread = 0;
unsigned long u, t;
if (index >= niodefs)
return index;
/* state machine! */
for(i = index, id = &iodefs[i]; id->op; i++, id++){
switch(id->op){
@ -253,6 +268,8 @@ int i915lightup(unsigned int physbase, unsigned int iobase, unsigned int mmio,
int i915lightup(unsigned int pphysbase, unsigned int piobase,
unsigned int pmmio, unsigned int pgfx)
{
static struct edid edid;
int index;
u32 auxin[16], auxout[16];
mmio = (void *)pmmio;
@ -260,13 +277,35 @@ int i915lightup(unsigned int pphysbase, unsigned int piobase,
dataport = addrport + 4;
physbase = pphysbase;
graphics = pgfx;
printk(BIOS_SPEW,
"i915lightup: graphics %p mmio %p"
printk(BIOS_SPEW, "i915lightup: graphics %p mmio %p"
"addrport %04x physbase %08x\n",
(void *)graphics, mmio, addrport, physbase);
globalstart = rdtscll();
decode_edid((unsigned char *)&link_edid_data, sizeof(link_edid_data), &edid);
htotal = (edid.ha - 1) | ((edid.ha + edid.hbl- 1) << 16);
printk(BIOS_SPEW, "I915_WRITE(HTOTAL(pipe), %08x)\n", htotal);
hblank = (edid.ha - 1) | ((edid.ha + edid.hbl- 1) << 16);
printk(BIOS_SPEW, "I915_WRITE(HBLANK(pipe),0x%08x)\n", hblank);
hsync = (edid.ha + edid.hso - 1) |
((edid.ha + edid.hso + edid.hspw- 1) << 16);
printk(BIOS_SPEW, "I915_WRITE(HSYNC(pipe),0x%08x)\n", hsync);
vtotal = (edid.va - 1) | ((edid.va + edid.vbl- 1) << 16);
printk(BIOS_SPEW, "I915_WRITE(VTOTAL(pipe), %08x)\n", vtotal);
vblank = (edid.va - 1) | ((edid.va + edid.vbl- 1) << 16);
printk(BIOS_SPEW, "I915_WRITE(VBLANK(pipe),0x%08x)\n", vblank);
vsync = (edid.va + edid.vso - 1) |((edid.va + edid.vso + edid.vspw- 1) << 16);
printk(BIOS_SPEW, "I915_WRITE(VSYNC(pipe),0x%08x)\n", vsync);
printk(BIOS_SPEW, "Table has %d elements\n", niodefs);
index = run(0);
printk(BIOS_SPEW, "Run returns %d\n", index);
auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_DPCD_REV<<8|0xe;

View File

@ -352,6 +352,7 @@ struct iodef iodefs[] = {
{M, 1, "[drm:intel_wait_for_vblank], vblank wait timed out", 0x0, 0xcf8e64, 0},
{M, 1, "[drm:intel_dp_mode_fixup], Display port link bw 0a lane count 4clock 270000", 0x0, 0xcf8e64, 0},
{M, 1, "[drm:drm_crtc_helper_set_mode], [CRTC:3]", 0x0, 0xcf8e64, 0},
{I, 0, "(null)", 0x0, 0xcf8e64, 0}, };
{I,},
};
int niodefs = sizeof (iodefs) / sizeof (iodefs[0]);