aboutsummaryrefslogtreecommitdiff
path: root/src/mainboard/google/link/i915.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mainboard/google/link/i915.c')
-rw-r--r--src/mainboard/google/link/i915.c207
1 files changed, 148 insertions, 59 deletions
diff --git a/src/mainboard/google/link/i915.c b/src/mainboard/google/link/i915.c
index 1c82e178d4..f36c85f8d9 100644
--- a/src/mainboard/google/link/i915.c
+++ b/src/mainboard/google/link/i915.c
@@ -19,6 +19,7 @@
#include <types.h>
#include <string.h>
+#include <stdlib.h>
#include <device/device.h>
#include <device/device.h>
#include <device/pci_def.h>
@@ -62,18 +63,29 @@ extern int oprom_is_loaded;
#define READ32(addr) io_i915_READ32(addr)
#define WRITE32(val, addr) io_i915_WRITE32(val, addr)
+static char *regname(unsigned long addr)
+{
+ static char name[16];
+ sprintf(name, "0x%lx", addr);
+ return name;
+}
+
unsigned long io_i915_READ32(unsigned long addr)
{
- unsigned long val;
- outl(addr, addrport);
- val = inl(dataport);
- return val;
+ unsigned long val;
+ outl(addr, addrport);
+ val = inl(dataport);
+ if (verbose & vio)
+ printk(BIOS_SPEW, "%s: Got %08lx\n", regname(addr), val);
+ return val;
}
void io_i915_WRITE32(unsigned long val, unsigned long addr)
{
- outl(addr, addrport);
- outl(val, dataport);
+ if (verbose & vio)
+ printk(BIOS_SPEW, "%s: outl %08lx\n", regname(addr), val);
+ outl(addr, addrport);
+ outl(val, dataport);
}
@@ -101,13 +113,6 @@ setgtt(int start, int end, unsigned long base, int inc)
}
}
-static char *regname(unsigned long addr)
-{
- static char name[16];
- sprintf(name, "0x%lx", addr);
- return name;
-}
-
static unsigned long tickspermicrosecond = 1795;
static unsigned long long globalstart;
@@ -125,6 +130,7 @@ static unsigned long globalmicroseconds(void)
}
extern struct iodef iodefs[];
+extern int niodefs;
static int i915_init_done = 0;
@@ -134,11 +140,7 @@ static void palette(void)
int i;
unsigned long color = 0;
- for (i = 0; i < 256; i++, color += 0x010101){
- if (verbose & vio)printk(BIOS_SPEW,
- "_LGC_PALETTE_A+%08x: outl %08lx\n",
- i<<2, color);
-
+ for(i = 0; i < 256; i++, color += 0x010101){
io_i915_WRITE32(color, _LGC_PALETTE_A + (i<<2));
}
}
@@ -169,31 +171,15 @@ void fill_lb_framebuffer(struct lb_framebuffer *framebuffer)
}
-int i915lightup(unsigned int physbase, unsigned int iobase, unsigned int mmio,
- unsigned int gfx);
+static unsigned long times[4096];
-int i915lightup(unsigned int pphysbase,
- unsigned int piobase,
- unsigned int pmmio,
- unsigned int pgfx)
+static int run(int index)
{
int i, prev = 0;
struct iodef *id, *lastidread = 0;
unsigned long u, t;
- static unsigned long times[4096];
- mmio = (void *)pmmio;
- addrport = piobase;
- dataport = addrport + 4;
- physbase = pphysbase;
- graphics = pgfx;
- printk(BIOS_SPEW,
- "i915lightup: graphics %p mmio %p"
- "addrport %04x physbase %08x\n",
- (void *)graphics, mmio, addrport, physbase);
- globalstart = rdtscll();
-
/* state machine! */
- for (i = 0, id = iodefs; id->op; i++, id++){
+ for(i = index, id = &iodefs[i]; id->op; i++, id++){
switch(id->op){
case M:
if (verbose & vmsg) printk(BIOS_SPEW, "%ld: %s\n",
@@ -204,8 +190,8 @@ int i915lightup(unsigned int pphysbase,
break;
case R:
u = READ32(id->addr);
- if (verbose & vio)printk(BIOS_SPEW, "%s: Got %08lx, expect %08lx\n",
- regname(id->addr), u, id->data);
+ if (verbose & vio)
+ printk(BIOS_SPEW, "\texpect %08lx\n", id->data);
/* we're looking for something. */
if (lastidread->addr == id->addr){
/* they're going to be polling.
@@ -222,14 +208,16 @@ int i915lightup(unsigned int pphysbase,
lastidread = id;
break;
case W:
- if (verbose & vio)printk(BIOS_SPEW, "%s: outl %08lx\n", regname(id->addr),
- id->data);
WRITE32(id->data, id->addr);
if (id->addr == PCH_PP_CONTROL){
+ if (verbose & vio)
+ printk(BIOS_SPEW, "PCH_PP_CONTROL\n");
switch(id->data & 0xf){
case 8: break;
case 7: break;
default: udelay(100000);
+ if (verbose & vio)
+ printk(BIOS_SPEW, "U %d\n", 100000);
}
}
break;
@@ -240,8 +228,11 @@ int i915lightup(unsigned int pphysbase,
} else {
verbose = prev;
}
+ printk(BIOS_SPEW, "Change verbosity to %d\n", verbose);
break;
case I:
+ printk(BIOS_SPEW, "run: return %d\n", i+1);
+ return i+1;
break;
default:
printk(BIOS_SPEW, "BAD TABLE, opcode %d @ %d\n", id->op, i);
@@ -249,27 +240,125 @@ int i915lightup(unsigned int pphysbase,
}
if (id->udelay)
udelay(id->udelay);
- times[i] = globalmicroseconds();
- }
- /* optional, we don't even want to take timestamp overhead
- * if we can avoid it. */
- if (0)
- for (i = 0, id = iodefs; id->op; i++, id++){
- switch(id->op){
- case R:
- printk(BIOS_SPEW, "%ld: R %08lx\n", times[i], id->addr);
- break;
- case W:
- printk(BIOS_SPEW, "%ld: W %08lx %08lx\n", times[i],
- id->addr, id->data);
- break;
- }
+ if (i < ARRAY_SIZE(times))
+ times[i] = globalmicroseconds();
}
+ printk(BIOS_SPEW, "run: return %d\n", i);
+ return i+1;
+}
+
+int i915lightup(unsigned int physbase, unsigned int iobase, unsigned int mmio,
+ unsigned int gfx);
+
+int i915lightup(unsigned int pphysbase, unsigned int piobase,
+ unsigned int pmmio, unsigned int pgfx)
+{
+ int index;
+ u32 auxin[16], auxout[16];
+ mmio = (void *)pmmio;
+ addrport = piobase;
+ dataport = addrport + 4;
+ physbase = pphysbase;
+ graphics = pgfx;
+ printk(BIOS_SPEW,
+ "i915lightup: graphics %p mmio %p"
+ "addrport %04x physbase %08x\n",
+ (void *)graphics, mmio, addrport, physbase);
+ globalstart = rdtscll();
+
+ 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;
+ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 14);
+ auxout[0] = 0<<31 /* i2c */|1<<30|0x0<<28/*W*/|0x0<<8|0x0;
+ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 3, auxin, 0);
+ index = run(index);
+ printk(BIOS_SPEW, "Run returns %d\n", index);
+ auxout[0] = 0<<31 /* i2c */|0<<30|0x0<<28/*W*/|0x0<<8|0x0;
+ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 3, auxin, 0);
+ index = run(index);
+ printk(BIOS_SPEW, "Run returns %d\n", index);
+ auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_SET_POWER<<8|0x0;
+ auxout[1] = 0x01000000;
+ /* DP_SET_POWER_D0 | DP_PSR_SINK_INACTIVE */
+ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0);
+ index = run(index);
+ auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_LINK_BW_SET<<8|0x8;
+ auxout[1] = 0x0a840000;
+ /*( DP_LINK_BW_2_7 &0xa)|0x0000840a*/
+ auxout[2] = 0x00000000;
+ auxout[3] = 0x01000000;
+ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 13, auxin, 0);
+ index = run(index);
+ auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0;
+ auxout[1] = 0x21000000;
+ /* DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE |
+ * DP_SYMBOL_ERROR_COUNT_BOTH |0x00000021*/
+ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0);
+ index = run(index);
+ auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_LANE0_SET<<8|0x3;
+ auxout[1] = 0x00000000;
+ /* DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0 |0x00000000*/
+ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 8, auxin, 0);
+ index = run(index);
+ auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_LANE0_1_STATUS<<8|0x5;
+ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 5);
+ index = run(index);
+ auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0;
+ auxout[1] = 0x22000000;
+ /* DP_TRAINING_PATTERN_2 | DP_LINK_SCRAMBLING_DISABLE |
+ * DP_SYMBOL_ERROR_COUNT_BOTH |0x00000022*/
+ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0);
+ index = run(index);
+ auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_LANE0_SET<<8|0x3;
+ auxout[1] = 0x00000000;
+ /* DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0 |0x00000000*/
+ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 8, auxin, 0);
+ index = run(index);
+ auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_LANE0_1_STATUS<<8|0x5;
+ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 5);
+ index = run(index);
+ auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0;
+ auxout[1] = 0x00000000;
+ /* DP_TRAINING_PATTERN_DISABLE | DP_LINK_QUAL_PATTERN_DISABLE |
+ * DP_SYMBOL_ERROR_COUNT_BOTH |0x00000000*/
+ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0);
+ index = run(index);
- setgtt(0, 4520, physbase, 4096);
+ if (index != niodefs)
+ printk(BIOS_ERR, "Left over IO work in i915_lightup"
+ " -- this is likely a table error. "
+ "Only %d of %d were done.\n", index, niodefs);
+ printk(BIOS_SPEW, "DONE startup\n");
+ verbose = 0;
+ /* GTT is the Global Translation Table for the graphics pipeline.
+ * It is used to translate graphics addresses to physical
+ * memory addresses. As in the CPU, GTTs map 4K pages.
+ * There are 32 bits per pixel, or 4 bytes,
+ * which means 1024 pixels per page.
+ * There are 4250 GTTs on Link:
+ * 2650 (X) * 1700 (Y) pixels / 1024 pixels per page.
+ * The setgtt function adds a further bit of flexibility:
+ * it allows you to set a range (the first two parameters) to point
+ * to a physical address (third parameter);the physical address is
+ * incremented by a count (fourth parameter) for each GTT in the
+ * range.
+ * Why do it this way? For ultrafast startup,
+ * we can point all the GTT entries to point to one page,
+ * and set that page to 0s:
+ * memset(physbase, 0, 4096);
+ * setgtt(0, 4250, physbase, 0);
+ * this takes about 2 ms, and is a win because zeroing
+ * the page takes a up to 200 ms. We will be exploiting this
+ * trick in a later rev of this code.
+ * This call sets the GTT to point to a linear range of pages
+ * starting at physbase.
+ */
+ setgtt(0, FRAME_BUFFER_PAGES, physbase, 4096);
printk(BIOS_SPEW, "memset %p to 0 for %d bytes\n",
- (void *)graphics, 4520*4096);
- memset((void *)graphics, 0, 4520*4096);
+ (void *)graphics, FRAME_BUFFER_BYTES);
+ memset((void *)graphics, 0, FRAME_BUFFER_BYTES);
printk(BIOS_SPEW, "%ld microseconds\n", globalmicroseconds());
i915_init_done = 1;
oprom_is_loaded = 1;