blob: 31249a1da92a3d16b890e26cfb5d4c12e385daf9 [file] [log] [blame]
Stefan Reinauer49428d82013-02-21 15:48:37 -08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2012 Google Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Stefan Reinauer49428d82013-02-21 15:48:37 -080014 */
15
16#include <types.h>
17#include <string.h>
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -080018#include <stdlib.h>
Stefan Reinauer49428d82013-02-21 15:48:37 -080019#include <device/device.h>
20#include <device/device.h>
21#include <device/pci_def.h>
22#include <device/pci_ops.h>
23#include <console/console.h>
24#include <delay.h>
25#include <pc80/mc146818rtc.h>
26#include <arch/acpi.h>
27#include <arch/io.h>
28#include <arch/interrupt.h>
Stefan Reinauer3e4e3032013-03-20 14:08:04 -070029#include <boot/coreboot_tables.h>
Stefan Reinauer49428d82013-02-21 15:48:37 -080030#include "onboard.h"
31#include "ec.h"
32#include <southbridge/intel/bd82x6x/pch.h>
Vladimir Serbinenko12fcb862014-02-23 00:09:48 +010033#include <northbridge/intel/sandybridge/gma.h>
Stefan Reinauer49428d82013-02-21 15:48:37 -080034#include <smbios.h>
35#include <device/pci.h>
36#include <ec/google/chromeec/ec.h>
Stefan Reinauer49428d82013-02-21 15:48:37 -080037
38#include <cpu/x86/tsc.h>
39#include <cpu/x86/cache.h>
40#include <cpu/x86/mtrr.h>
Stefan Reinauer49428d82013-02-21 15:48:37 -080041#include <cpu/x86/msr.h>
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -070042#include <edid.h>
Stefan Reinauer49428d82013-02-21 15:48:37 -080043#include "i915io.h"
44
45enum {
46 vmsg = 1, vio = 2, vspin = 4,
47};
48
49static int verbose = 0;
50
51static unsigned int *mmio;
52static unsigned int graphics;
53static unsigned short addrport;
54static unsigned short dataport;
55static unsigned int physbase;
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -070056static u32 htotal, hblank, hsync, vtotal, vblank, vsync;
57
58const u32 link_edid_data[] = {
59 0xffffff00, 0x00ffffff, 0x0379e430, 0x00000000,
60 0x04011500, 0x96121ba5, 0xa2d54f02, 0x26935259,
61 0x00545017, 0x01010000, 0x01010101, 0x01010101,
62 0x01010101, 0x6f6d0101, 0xa4a0a000, 0x20306031,
63 0xb510003a, 0x19000010, 0x00000000, 0x00000000,
64 0x00000000, 0x00000000, 0x00000000, 0x4c00fe00,
65 0x69442047, 0x616c7073, 0x20200a79, 0xfe000000,
66 0x31504c00, 0x45513932, 0x50532d31, 0x24003141,
67};
Stefan Reinauer49428d82013-02-21 15:48:37 -080068
69#define READ32(addr) io_i915_READ32(addr)
70#define WRITE32(val, addr) io_i915_WRITE32(val, addr)
71
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -080072static char *regname(unsigned long addr)
73{
74 static char name[16];
Vladimir Serbinenkoa37383d2013-11-26 02:41:26 +010075 snprintf(name, sizeof (name), "0x%lx", addr);
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -080076 return name;
77}
78
Ronald G. Minnich665e3d22013-02-27 09:54:47 -080079unsigned long io_i915_READ32(unsigned long addr)
Stefan Reinauer49428d82013-02-21 15:48:37 -080080{
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -080081 unsigned long val;
82 outl(addr, addrport);
83 val = inl(dataport);
84 if (verbose & vio)
85 printk(BIOS_SPEW, "%s: Got %08lx\n", regname(addr), val);
86 return val;
Stefan Reinauer49428d82013-02-21 15:48:37 -080087}
88
Ronald G. Minnich665e3d22013-02-27 09:54:47 -080089void io_i915_WRITE32(unsigned long val, unsigned long addr)
Stefan Reinauer49428d82013-02-21 15:48:37 -080090{
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -080091 if (verbose & vio)
92 printk(BIOS_SPEW, "%s: outl %08lx\n", regname(addr), val);
93 outl(addr, addrport);
94 outl(val, dataport);
Stefan Reinauer49428d82013-02-21 15:48:37 -080095}
96
97
98/*
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -070099 2560
100 4 words per
101 4 *p
102 10240
103 4k bytes per page
104 4096/p
105 2.50
106 1700 lines
107 1700 * p
108 4250.00
109 PTEs
Stefan Reinauer49428d82013-02-21 15:48:37 -0800110*/
111static void
112setgtt(int start, int end, unsigned long base, int inc)
113{
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -0700114 int i;
Stefan Reinauer49428d82013-02-21 15:48:37 -0800115
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -0700116 for(i = start; i < end; i++){
117 u32 word = base + i*inc;
118 WRITE32(word|1,(i*4)|1);
119 }
Stefan Reinauer49428d82013-02-21 15:48:37 -0800120}
121
Stefan Reinauer49428d82013-02-21 15:48:37 -0800122static unsigned long tickspermicrosecond = 1795;
123static unsigned long long globalstart;
124
125static unsigned long
126microseconds(unsigned long long start, unsigned long long end)
127{
128 unsigned long ret;
129 ret = ((end - start)/tickspermicrosecond);
130 return ret;
131}
132
133static unsigned long globalmicroseconds(void)
134{
135 return microseconds(globalstart, rdtscll());
136}
137
138extern struct iodef iodefs[];
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800139extern int niodefs;
Stefan Reinauer49428d82013-02-21 15:48:37 -0800140
141static int i915_init_done = 0;
142
Ronald G. Minnichec2d9142013-03-05 13:32:24 -0800143/* fill the palette. This runs when the P opcode is hit. */
Ronald G. Minnich7982de12013-06-05 08:35:52 -0700144/* and, yes, it's needed for even 32 bits per pixel */
Ronald G. Minnichec2d9142013-03-05 13:32:24 -0800145static void palette(void)
146{
147 int i;
148 unsigned long color = 0;
149
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800150 for(i = 0; i < 256; i++, color += 0x010101){
Ronald G. Minnichec2d9142013-03-05 13:32:24 -0800151 io_i915_WRITE32(color, _LGC_PALETTE_A + (i<<2));
152 }
153}
154
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800155static unsigned long times[4096];
Stefan Reinauer49428d82013-02-21 15:48:37 -0800156
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800157static int run(int index)
Stefan Reinauer49428d82013-02-21 15:48:37 -0800158{
159 int i, prev = 0;
160 struct iodef *id, *lastidread = 0;
161 unsigned long u, t;
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -0700162 if (index >= niodefs)
163 return index;
Stefan Reinauer49428d82013-02-21 15:48:37 -0800164 /* state machine! */
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800165 for(i = index, id = &iodefs[i]; id->op; i++, id++){
Stefan Reinauer49428d82013-02-21 15:48:37 -0800166 switch(id->op){
167 case M:
168 if (verbose & vmsg) printk(BIOS_SPEW, "%ld: %s\n",
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -0700169 globalmicroseconds(), id->msg);
Stefan Reinauer49428d82013-02-21 15:48:37 -0800170 break;
Ronald G. Minnichec2d9142013-03-05 13:32:24 -0800171 case P:
172 palette();
173 break;
Stefan Reinauer49428d82013-02-21 15:48:37 -0800174 case R:
175 u = READ32(id->addr);
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800176 if (verbose & vio)
177 printk(BIOS_SPEW, "\texpect %08lx\n", id->data);
Stefan Reinauer49428d82013-02-21 15:48:37 -0800178 /* we're looking for something. */
179 if (lastidread->addr == id->addr){
180 /* they're going to be polling.
181 * just do it 1000 times
182 */
Ronald G. Minnichec2d9142013-03-05 13:32:24 -0800183 for (t = 0; t < 1000 && id->data != u; t++){
Stefan Reinauer49428d82013-02-21 15:48:37 -0800184 u = READ32(id->addr);
185 }
186 if (verbose & vspin) printk(BIOS_SPEW,
187 "%s: # loops %ld got %08lx want %08lx\n",
188 regname(id->addr),
189 t, u, id->data);
190 }
191 lastidread = id;
192 break;
193 case W:
Stefan Reinauer49428d82013-02-21 15:48:37 -0800194 WRITE32(id->data, id->addr);
195 if (id->addr == PCH_PP_CONTROL){
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800196 if (verbose & vio)
197 printk(BIOS_SPEW, "PCH_PP_CONTROL\n");
Stefan Reinauer49428d82013-02-21 15:48:37 -0800198 switch(id->data & 0xf){
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -0700199 case 8: break;
200 case 7: break;
201 default: udelay(100000);
202 if (verbose & vio)
203 printk(BIOS_SPEW, "U %d\n", 100000);
Stefan Reinauer49428d82013-02-21 15:48:37 -0800204 }
205 }
206 break;
207 case V:
208 if (id->count < 8){
209 prev = verbose;
210 verbose = id->count;
211 } else {
212 verbose = prev;
213 }
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800214 printk(BIOS_SPEW, "Change verbosity to %d\n", verbose);
Stefan Reinauer49428d82013-02-21 15:48:37 -0800215 break;
216 case I:
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800217 printk(BIOS_SPEW, "run: return %d\n", i+1);
218 return i+1;
Stefan Reinauer49428d82013-02-21 15:48:37 -0800219 break;
220 default:
221 printk(BIOS_SPEW, "BAD TABLE, opcode %d @ %d\n", id->op, i);
222 return -1;
223 }
224 if (id->udelay)
225 udelay(id->udelay);
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800226 if (i < ARRAY_SIZE(times))
227 times[i] = globalmicroseconds();
Stefan Reinauer49428d82013-02-21 15:48:37 -0800228 }
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800229 printk(BIOS_SPEW, "run: return %d\n", i);
230 return i+1;
231}
Stefan Reinauer49428d82013-02-21 15:48:37 -0800232
Vladimir Serbinenkoa71bdc32014-08-30 00:35:39 +0200233int i915lightup_sandy(const struct i915_gpu_controller_info *info,
234 u32 pphysbase, u16 piobase, u32 pmmio, u32 pgfx)
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800235{
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -0700236 static struct edid edid;
Ronald G. Minnich7982de12013-06-05 08:35:52 -0700237 int edid_ok;
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -0700238
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800239 int index;
240 u32 auxin[16], auxout[16];
241 mmio = (void *)pmmio;
242 addrport = piobase;
243 dataport = addrport + 4;
244 physbase = pphysbase;
245 graphics = pgfx;
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -0700246 printk(BIOS_SPEW, "i915lightup: graphics %p mmio %p"
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800247 "addrport %04x physbase %08x\n",
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -0700248 (void *)graphics, mmio, addrport, physbase);
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800249 globalstart = rdtscll();
250
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -0700251
Ronald G. Minnich7982de12013-06-05 08:35:52 -0700252 edid_ok = decode_edid((unsigned char *)&link_edid_data,
253 sizeof(link_edid_data), &edid);
254 printk(BIOS_SPEW, "decode edid returns %d\n", edid_ok);
Ronald G. Minnich9518b562013-09-19 16:45:22 -0700255 edid.framebuffer_bits_per_pixel = 32;
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -0700256
257 htotal = (edid.ha - 1) | ((edid.ha + edid.hbl- 1) << 16);
258 printk(BIOS_SPEW, "I915_WRITE(HTOTAL(pipe), %08x)\n", htotal);
259
260 hblank = (edid.ha - 1) | ((edid.ha + edid.hbl- 1) << 16);
261 printk(BIOS_SPEW, "I915_WRITE(HBLANK(pipe),0x%08x)\n", hblank);
262
263 hsync = (edid.ha + edid.hso - 1) |
264 ((edid.ha + edid.hso + edid.hspw- 1) << 16);
265 printk(BIOS_SPEW, "I915_WRITE(HSYNC(pipe),0x%08x)\n", hsync);
266
267 vtotal = (edid.va - 1) | ((edid.va + edid.vbl- 1) << 16);
268 printk(BIOS_SPEW, "I915_WRITE(VTOTAL(pipe), %08x)\n", vtotal);
269
270 vblank = (edid.va - 1) | ((edid.va + edid.vbl- 1) << 16);
271 printk(BIOS_SPEW, "I915_WRITE(VBLANK(pipe),0x%08x)\n", vblank);
272
273 vsync = (edid.va + edid.vso - 1) |((edid.va + edid.vso + edid.vspw- 1) << 16);
274 printk(BIOS_SPEW, "I915_WRITE(VSYNC(pipe),0x%08x)\n", vsync);
275
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800276 printk(BIOS_SPEW, "Table has %d elements\n", niodefs);
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -0700277
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800278 index = run(0);
279 printk(BIOS_SPEW, "Run returns %d\n", index);
280 auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_DPCD_REV<<8|0xe;
281 intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 14);
282 auxout[0] = 0<<31 /* i2c */|1<<30|0x0<<28/*W*/|0x0<<8|0x0;
283 intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 3, auxin, 0);
284 index = run(index);
285 printk(BIOS_SPEW, "Run returns %d\n", index);
286 auxout[0] = 0<<31 /* i2c */|0<<30|0x0<<28/*W*/|0x0<<8|0x0;
287 intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 3, auxin, 0);
288 index = run(index);
289 printk(BIOS_SPEW, "Run returns %d\n", index);
290 auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_SET_POWER<<8|0x0;
291 auxout[1] = 0x01000000;
292 /* DP_SET_POWER_D0 | DP_PSR_SINK_INACTIVE */
293 intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0);
294 index = run(index);
295 auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_LINK_BW_SET<<8|0x8;
296 auxout[1] = 0x0a840000;
297 /*( DP_LINK_BW_2_7 &0xa)|0x0000840a*/
298 auxout[2] = 0x00000000;
299 auxout[3] = 0x01000000;
300 intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 13, auxin, 0);
301 index = run(index);
302 auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0;
303 auxout[1] = 0x21000000;
304 /* DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE |
305 * DP_SYMBOL_ERROR_COUNT_BOTH |0x00000021*/
306 intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0);
307 index = run(index);
308 auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_LANE0_SET<<8|0x3;
309 auxout[1] = 0x00000000;
310 /* DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0 |0x00000000*/
311 intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 8, auxin, 0);
312 index = run(index);
313 auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_LANE0_1_STATUS<<8|0x5;
314 intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 5);
315 index = run(index);
316 auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0;
317 auxout[1] = 0x22000000;
318 /* DP_TRAINING_PATTERN_2 | DP_LINK_SCRAMBLING_DISABLE |
319 * DP_SYMBOL_ERROR_COUNT_BOTH |0x00000022*/
320 intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0);
321 index = run(index);
322 auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_LANE0_SET<<8|0x3;
323 auxout[1] = 0x00000000;
324 /* DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0 |0x00000000*/
325 intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 8, auxin, 0);
326 index = run(index);
327 auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_LANE0_1_STATUS<<8|0x5;
328 intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 5);
329 index = run(index);
330 auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0;
331 auxout[1] = 0x00000000;
332 /* DP_TRAINING_PATTERN_DISABLE | DP_LINK_QUAL_PATTERN_DISABLE |
333 * DP_SYMBOL_ERROR_COUNT_BOTH |0x00000000*/
334 intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0);
335 index = run(index);
336
337 if (index != niodefs)
338 printk(BIOS_ERR, "Left over IO work in i915_lightup"
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -0700339 " -- this is likely a table error. "
340 "Only %d of %d were done.\n", index, niodefs);
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800341 printk(BIOS_SPEW, "DONE startup\n");
342 verbose = 0;
343 /* GTT is the Global Translation Table for the graphics pipeline.
344 * It is used to translate graphics addresses to physical
345 * memory addresses. As in the CPU, GTTs map 4K pages.
346 * There are 32 bits per pixel, or 4 bytes,
347 * which means 1024 pixels per page.
348 * There are 4250 GTTs on Link:
349 * 2650 (X) * 1700 (Y) pixels / 1024 pixels per page.
350 * The setgtt function adds a further bit of flexibility:
351 * it allows you to set a range (the first two parameters) to point
352 * to a physical address (third parameter);the physical address is
353 * incremented by a count (fourth parameter) for each GTT in the
354 * range.
355 * Why do it this way? For ultrafast startup,
356 * we can point all the GTT entries to point to one page,
357 * and set that page to 0s:
358 * memset(physbase, 0, 4096);
359 * setgtt(0, 4250, physbase, 0);
360 * this takes about 2 ms, and is a win because zeroing
361 * the page takes a up to 200 ms. We will be exploiting this
362 * trick in a later rev of this code.
363 * This call sets the GTT to point to a linear range of pages
364 * starting at physbase.
365 */
366 setgtt(0, FRAME_BUFFER_PAGES, physbase, 4096);
Stefan Reinauer49428d82013-02-21 15:48:37 -0800367 printk(BIOS_SPEW, "memset %p to 0 for %d bytes\n",
Ronald G. Minnichb3b72f32013-03-13 14:35:01 -0700368 (void *)graphics, FRAME_BUFFER_BYTES);
Ronald G. Minnicha95a13b2013-03-05 17:07:40 -0800369 memset((void *)graphics, 0, FRAME_BUFFER_BYTES);
Stefan Reinauer49428d82013-02-21 15:48:37 -0800370 printk(BIOS_SPEW, "%ld microseconds\n", globalmicroseconds());
Ronald G. Minnich3a75e5e2013-10-28 15:01:54 -0700371 set_vbe_mode_info_valid(&edid, (uintptr_t)graphics);
Stefan Reinauer49428d82013-02-21 15:48:37 -0800372 i915_init_done = 1;
Kyösti Mälkkiab56b3b2013-11-28 16:44:51 +0200373 return i915_init_done;
Stefan Reinauer49428d82013-02-21 15:48:37 -0800374}