aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/early-quirks.c211
-rw-r--r--arch/x86/kernel/pci-calgary_64.c31
-rw-r--r--include/drm/i915_drm.h20
3 files changed, 221 insertions, 41 deletions
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 6d7d5a1260a6..b0cc3809723d 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -225,7 +225,7 @@ static void __init intel_remapping_check(int num, int slot, int func)
225 * 225 *
226 * And yes, so far on current devices the base addr is always under 4G. 226 * And yes, so far on current devices the base addr is always under 4G.
227 */ 227 */
228static u32 __init intel_stolen_base(int num, int slot, int func) 228static u32 __init intel_stolen_base(int num, int slot, int func, size_t stolen_size)
229{ 229{
230 u32 base; 230 u32 base;
231 231
@@ -244,6 +244,114 @@ static u32 __init intel_stolen_base(int num, int slot, int func)
244#define MB(x) (KB (KB (x))) 244#define MB(x) (KB (KB (x)))
245#define GB(x) (MB (KB (x))) 245#define GB(x) (MB (KB (x)))
246 246
247static size_t __init i830_tseg_size(void)
248{
249 u8 tmp = read_pci_config_byte(0, 0, 0, I830_ESMRAMC);
250
251 if (!(tmp & TSEG_ENABLE))
252 return 0;
253
254 if (tmp & I830_TSEG_SIZE_1M)
255 return MB(1);
256 else
257 return KB(512);
258}
259
260static size_t __init i845_tseg_size(void)
261{
262 u8 tmp = read_pci_config_byte(0, 0, 0, I845_ESMRAMC);
263
264 if (!(tmp & TSEG_ENABLE))
265 return 0;
266
267 switch (tmp & I845_TSEG_SIZE_MASK) {
268 case I845_TSEG_SIZE_512K:
269 return KB(512);
270 case I845_TSEG_SIZE_1M:
271 return MB(1);
272 default:
273 WARN_ON(1);
274 return 0;
275 }
276}
277
278static size_t __init i85x_tseg_size(void)
279{
280 u8 tmp = read_pci_config_byte(0, 0, 0, I85X_ESMRAMC);
281
282 if (!(tmp & TSEG_ENABLE))
283 return 0;
284
285 return MB(1);
286}
287
288static size_t __init i830_mem_size(void)
289{
290 return read_pci_config_byte(0, 0, 0, I830_DRB3) * MB(32);
291}
292
293static size_t __init i85x_mem_size(void)
294{
295 return read_pci_config_byte(0, 0, 1, I85X_DRB3) * MB(32);
296}
297
298/*
299 * On 830/845/85x the stolen memory base isn't available in any
300 * register. We need to calculate it as TOM-TSEG_SIZE-stolen_size.
301 */
302static u32 __init i830_stolen_base(int num, int slot, int func, size_t stolen_size)
303{
304 return i830_mem_size() - i830_tseg_size() - stolen_size;
305}
306
307static u32 __init i845_stolen_base(int num, int slot, int func, size_t stolen_size)
308{
309 return i830_mem_size() - i845_tseg_size() - stolen_size;
310}
311
312static u32 __init i85x_stolen_base(int num, int slot, int func, size_t stolen_size)
313{
314 return i85x_mem_size() - i85x_tseg_size() - stolen_size;
315}
316
317static u32 __init i865_stolen_base(int num, int slot, int func, size_t stolen_size)
318{
319 /*
320 * FIXME is the graphics stolen memory region
321 * always at TOUD? Ie. is it always the last
322 * one to be allocated by the BIOS?
323 */
324 return read_pci_config_16(0, 0, 0, I865_TOUD) << 16;
325}
326
327static size_t __init i830_stolen_size(int num, int slot, int func)
328{
329 size_t stolen_size;
330 u16 gmch_ctrl;
331
332 gmch_ctrl = read_pci_config_16(0, 0, 0, I830_GMCH_CTRL);
333
334 switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
335 case I830_GMCH_GMS_STOLEN_512:
336 stolen_size = KB(512);
337 break;
338 case I830_GMCH_GMS_STOLEN_1024:
339 stolen_size = MB(1);
340 break;
341 case I830_GMCH_GMS_STOLEN_8192:
342 stolen_size = MB(8);
343 break;
344 case I830_GMCH_GMS_LOCAL:
345 /* local memory isn't part of the normal address space */
346 stolen_size = 0;
347 break;
348 default:
349 return 0;
350 }
351
352 return stolen_size;
353}
354
247static size_t __init gen3_stolen_size(int num, int slot, int func) 355static size_t __init gen3_stolen_size(int num, int slot, int func)
248{ 356{
249 size_t stolen_size; 357 size_t stolen_size;
@@ -310,7 +418,7 @@ static size_t __init gen6_stolen_size(int num, int slot, int func)
310 return gmch_ctrl << 25; /* 32 MB units */ 418 return gmch_ctrl << 25; /* 32 MB units */
311} 419}
312 420
313static inline size_t gen8_stolen_size(int num, int slot, int func) 421static size_t gen8_stolen_size(int num, int slot, int func)
314{ 422{
315 u16 gmch_ctrl; 423 u16 gmch_ctrl;
316 424
@@ -320,31 +428,74 @@ static inline size_t gen8_stolen_size(int num, int slot, int func)
320 return gmch_ctrl << 25; /* 32 MB units */ 428 return gmch_ctrl << 25; /* 32 MB units */
321} 429}
322 430
323typedef size_t (*stolen_size_fn)(int num, int slot, int func); 431
432struct intel_stolen_funcs {
433 size_t (*size)(int num, int slot, int func);
434 u32 (*base)(int num, int slot, int func, size_t size);
435};
436
437static const struct intel_stolen_funcs i830_stolen_funcs = {
438 .base = i830_stolen_base,
439 .size = i830_stolen_size,
440};
441
442static const struct intel_stolen_funcs i845_stolen_funcs = {
443 .base = i845_stolen_base,
444 .size = i830_stolen_size,
445};
446
447static const struct intel_stolen_funcs i85x_stolen_funcs = {
448 .base = i85x_stolen_base,
449 .size = gen3_stolen_size,
450};
451
452static const struct intel_stolen_funcs i865_stolen_funcs = {
453 .base = i865_stolen_base,
454 .size = gen3_stolen_size,
455};
456
457static const struct intel_stolen_funcs gen3_stolen_funcs = {
458 .base = intel_stolen_base,
459 .size = gen3_stolen_size,
460};
461
462static const struct intel_stolen_funcs gen6_stolen_funcs = {
463 .base = intel_stolen_base,
464 .size = gen6_stolen_size,
465};
466
467static const struct intel_stolen_funcs gen8_stolen_funcs = {
468 .base = intel_stolen_base,
469 .size = gen8_stolen_size,
470};
324 471
325static struct pci_device_id intel_stolen_ids[] __initdata = { 472static struct pci_device_id intel_stolen_ids[] __initdata = {
326 INTEL_I915G_IDS(gen3_stolen_size), 473 INTEL_I830_IDS(&i830_stolen_funcs),
327 INTEL_I915GM_IDS(gen3_stolen_size), 474 INTEL_I845G_IDS(&i845_stolen_funcs),
328 INTEL_I945G_IDS(gen3_stolen_size), 475 INTEL_I85X_IDS(&i85x_stolen_funcs),
329 INTEL_I945GM_IDS(gen3_stolen_size), 476 INTEL_I865G_IDS(&i865_stolen_funcs),
330 INTEL_VLV_M_IDS(gen6_stolen_size), 477 INTEL_I915G_IDS(&gen3_stolen_funcs),
331 INTEL_VLV_D_IDS(gen6_stolen_size), 478 INTEL_I915GM_IDS(&gen3_stolen_funcs),
332