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:
parent
a95a13bd47
commit
b3b72f350e
|
@ -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 */
|
|
@ -82,6 +82,7 @@ ramstage-$(CONFIG_BOOTSPLASH) += jpeg.c
|
||||||
ramstage-$(CONFIG_TRACE) += trace.c
|
ramstage-$(CONFIG_TRACE) += trace.c
|
||||||
ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
|
ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
|
||||||
ramstage-$(CONFIG_COVERAGE) += libgcov.c
|
ramstage-$(CONFIG_COVERAGE) += libgcov.c
|
||||||
|
ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += edid.c
|
||||||
|
|
||||||
ramstage-$(CONFIG_CONSOLE_NE2K) += ne2k.c
|
ramstage-$(CONFIG_CONSOLE_NE2K) += ne2k.c
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -45,6 +45,7 @@
|
||||||
#include <cpu/x86/mtrr.h>
|
#include <cpu/x86/mtrr.h>
|
||||||
#include <cpu/amd/mtrr.h>
|
#include <cpu/amd/mtrr.h>
|
||||||
#include <cpu/x86/msr.h>
|
#include <cpu/x86/msr.h>
|
||||||
|
#include <edid.h>
|
||||||
#include "i915io.h"
|
#include "i915io.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -59,6 +60,18 @@ static unsigned short addrport;
|
||||||
static unsigned short dataport;
|
static unsigned short dataport;
|
||||||
static unsigned int physbase;
|
static unsigned int physbase;
|
||||||
extern int oprom_is_loaded;
|
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 READ32(addr) io_i915_READ32(addr)
|
||||||
#define WRITE32(val, addr) io_i915_WRITE32(val, addr)
|
#define WRITE32(val, addr) io_i915_WRITE32(val, addr)
|
||||||
|
@ -178,6 +191,8 @@ static int run(int index)
|
||||||
int i, prev = 0;
|
int i, prev = 0;
|
||||||
struct iodef *id, *lastidread = 0;
|
struct iodef *id, *lastidread = 0;
|
||||||
unsigned long u, t;
|
unsigned long u, t;
|
||||||
|
if (index >= niodefs)
|
||||||
|
return index;
|
||||||
/* state machine! */
|
/* state machine! */
|
||||||
for(i = index, id = &iodefs[i]; id->op; i++, id++){
|
for(i = index, id = &iodefs[i]; id->op; i++, id++){
|
||||||
switch(id->op){
|
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,
|
int i915lightup(unsigned int pphysbase, unsigned int piobase,
|
||||||
unsigned int pmmio, unsigned int pgfx)
|
unsigned int pmmio, unsigned int pgfx)
|
||||||
{
|
{
|
||||||
|
static struct edid edid;
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
u32 auxin[16], auxout[16];
|
u32 auxin[16], auxout[16];
|
||||||
mmio = (void *)pmmio;
|
mmio = (void *)pmmio;
|
||||||
|
@ -260,13 +277,35 @@ int i915lightup(unsigned int pphysbase, unsigned int piobase,
|
||||||
dataport = addrport + 4;
|
dataport = addrport + 4;
|
||||||
physbase = pphysbase;
|
physbase = pphysbase;
|
||||||
graphics = pgfx;
|
graphics = pgfx;
|
||||||
printk(BIOS_SPEW,
|
printk(BIOS_SPEW, "i915lightup: graphics %p mmio %p"
|
||||||
"i915lightup: graphics %p mmio %p"
|
|
||||||
"addrport %04x physbase %08x\n",
|
"addrport %04x physbase %08x\n",
|
||||||
(void *)graphics, mmio, addrport, physbase);
|
(void *)graphics, mmio, addrport, physbase);
|
||||||
globalstart = rdtscll();
|
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);
|
printk(BIOS_SPEW, "Table has %d elements\n", niodefs);
|
||||||
|
|
||||||
index = run(0);
|
index = run(0);
|
||||||
printk(BIOS_SPEW, "Run returns %d\n", index);
|
printk(BIOS_SPEW, "Run returns %d\n", index);
|
||||||
auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_DPCD_REV<<8|0xe;
|
auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_DPCD_REV<<8|0xe;
|
||||||
|
|
|
@ -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_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: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},
|
{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]);
|
int niodefs = sizeof (iodefs) / sizeof (iodefs[0]);
|
||||||
|
|
Loading…
Reference in New Issue