summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/early-quirks.c132
-rw-r--r--include/drm/i915_drm.h20
2 files changed, 152 insertions, 0 deletions
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index fddd4d05d1fa..5218dd209ede 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -247,6 +247,114 @@ static u32 __init intel_stolen_base(int num, int slot, int func, size_t stolen_s
247#define MB(x) (KB (KB (x))) 247#define MB(x) (KB (KB (x)))
248#define GB(x) (MB (KB (x))) 248#define GB(x) (MB (KB (x)))
249 249
250static size_t __init i830_tseg_size(void)
251{
252 u8 tmp = read_pci_config_byte(0, 0, 0, I830_ESMRAMC);
253
254 if (!(tmp & TSEG_ENABLE))
255 return 0;
256
257 if (tmp & I830_TSEG_SIZE_1M)
258 return MB(1);
259 else
260 return KB(512);
261}
262
263static size_t __init i845_tseg_size(void)
264{
265 u8 tmp = read_pci_config_byte(0, 0, 0, I845_ESMRAMC);
266
267 if (!(tmp & TSEG_ENABLE))
268 return 0;
269
270 switch (tmp & I845_TSEG_SIZE_MASK) {
271 case I845_TSEG_SIZE_512K:
272 return KB(512);
273 case I845_TSEG_SIZE_1M:
274 return MB(1);
275 default:
276 WARN_ON(1);
277 return 0;
278 }
279}
280
281static size_t __init i85x_tseg_size(void)
282{
283 u8 tmp = read_pci_config_byte(0, 0, 0, I85X_ESMRAMC);
284
285 if (!(tmp & TSEG_ENABLE))
286 return 0;
287
288 return MB(1);
289}
290
291static size_t __init i830_mem_size(void)
292{
293 return read_pci_config_byte(0, 0, 0, I830_DRB3) * MB(32);
294}
295
296static size_t __init i85x_mem_size(void)
297{
298 return read_pci_config_byte(0, 0, 1, I85X_DRB3) * MB(32);
299}
300
301/*
302 * On 830/845/85x the stolen memory base isn't available in any
303 * register. We need to calculate it as TOM-TSEG_SIZE-stolen_size.
304 */
305static u32 __init i830_stolen_base(int num, int slot, int func, size_t stolen_size)
306{
307 return i830_mem_size() - i830_tseg_size() - stolen_size;
308}
309
310static u32 __init i845_stolen_base(int num, int slot, int func, size_t stolen_size)
311{
312 return i830_mem_size() - i845_tseg_size() - stolen_size;
313}
314
315static u32 __init i85x_stolen_base(int num, int slot, int func, size_t stolen_size)
316{
317 return i85x_mem_size() - i85x_tseg_size() - stolen_size;
318}
319
320static u32 __init i865_stolen_base(int num, int slot, int func, size_t stolen_size)
321{
322 /*
323 * FIXME is the graphics stolen memory region
324 * always at TOUD? Ie. is it always the last
325 * one to be allocated by the BIOS?
326 */
327 return read_pci_config_16(0, 0, 0, I865_TOUD) << 16;
328}
329
330static size_t __init i830_stolen_size(int num, int slot, int func)
331{
332 size_t stolen_size;
333 u16 gmch_ctrl;
334
335 gmch_ctrl = read_pci_config_16(0, 0, 0, I830_GMCH_CTRL);
336
337 switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
338 case I830_GMCH_GMS_STOLEN_512:
339 stolen_size = KB(512);
340 break;
341 case I830_GMCH_GMS_STOLEN_1024:
342 stolen_size = MB(1);
343 break;
344 case I830_GMCH_GMS_STOLEN_8192:
345 stolen_size = MB(8);
346 break;
347 case I830_GMCH_GMS_LOCAL:
348 /* local memory isn't part of the normal address space */
349 stolen_size = 0;
350 break;
351 default:
352 return 0;
353 }
354
355 return stolen_size;
356}
357
250static size_t __init gen3_stolen_size(int num, int slot, int func) 358static size_t __init gen3_stolen_size(int num, int slot, int func)
251{ 359{
252 size_t stolen_size; 360 size_t stolen_size;
@@ -329,6 +437,26 @@ struct intel_stolen_funcs {
329 u32 (*base)(int num, int slot, int func, size_t size); 437 u32 (*base)(int num, int slot, int func, size_t size);
330}; 438};
331 439
440static const struct intel_stolen_funcs i830_stolen_funcs = {
441 .base = i830_stolen_base,
442 .size = i830_stolen_size,
443};
444
445static const struct intel_stolen_funcs i845_stolen_funcs = {
446 .base = i845_stolen_base,
447 .size = i830_stolen_size,
448};
449
450static const struct intel_stolen_funcs i85x_stolen_funcs = {
451 .base = i85x_stolen_base,
452 .size = gen3_stolen_size,
453};
454
455static const struct intel_stolen_funcs i865_stolen_funcs = {
456 .base = i865_stolen_base,
457 .size = gen3_stolen_size,
458};
459
332static const struct intel_stolen_funcs gen3_stolen_funcs = { 460static const struct intel_stolen_funcs gen3_stolen_funcs = {
333 .base = intel_stolen_base, 461 .base = intel_stolen_base,
334 .size = gen3_stolen_size, 462 .size = gen3_stolen_size,
@@ -345,6 +473,10 @@ static const struct intel_stolen_funcs gen8_stolen_funcs = {
345}; 473};
346 474
347static struct pci_device_id intel_stolen_ids[] __initdata = { 475static struct pci_device_id intel_stolen_ids[] __initdata = {
476 INTEL_I830_IDS(&i830_stolen_funcs),
477 INTEL_I845G_IDS(&i845_stolen_funcs),
478 INTEL_I85X_IDS(&i85x_stolen_funcs),
479 INTEL_I865G_IDS(&i865_stolen_funcs),
348 INTEL_I915G_IDS(&gen3_stolen_funcs), 480 INTEL_I915G_IDS(&gen3_stolen_funcs),
349 INTEL_I915GM_IDS(&gen3_stolen_funcs), 481 INTEL_I915GM_IDS(&gen3_stolen_funcs),
350 INTEL_I945G_IDS(&gen3_stolen_funcs), 482 INTEL_I945G_IDS(&gen3_stolen_funcs),
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 97d5497debc1..595f85c392ac 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -56,6 +56,12 @@ extern bool i915_gpu_turbo_disable(void);
56 56
57#define I830_GMCH_CTRL 0x52 57#define I830_GMCH_CTRL 0x52
58 58
59#define I830_GMCH_GMS_MASK 0x70
60#define I830_GMCH_GMS_LOCAL 0x10
61#define I830_GMCH_GMS_STOLEN_512 0x20
62#define I830_GMCH_GMS_STOLEN_1024 0x30
63#define I830_GMCH_GMS_STOLEN_8192 0x40
64
59#define I855_GMCH_GMS_MASK 0xF0 65#define I855_GMCH_GMS_MASK 0xF0
60#define I855_GMCH_GMS_STOLEN_0M 0x0 66#define I855_GMCH_GMS_STOLEN_0M 0x0
61#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) 67#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4)
@@ -72,4 +78,18 @@ extern bool i915_gpu_turbo_disable(void);
72#define INTEL_GMCH_GMS_STOLEN_224M (0xc << 4) 78#define INTEL_GMCH_GMS_STOLEN_224M (0xc << 4)
73#define INTEL_GMCH_GMS_STOLEN_352M (0xd << 4) 79#define INTEL_GMCH_GMS_STOLEN_352M (0xd << 4)
74 80
81#define I830_DRB3 0x63
82#define I85X_DRB3 0x43
83#define I865_TOUD 0xc4
84
85#define I830_ESMRAMC 0x91
86#define I845_ESMRAMC 0x9e
87#define I85X_ESMRAMC 0x61
88#define TSEG_ENABLE (1 << 0)
89#define I830_TSEG_SIZE_512K (0 << 1)
90#define I830_TSEG_SIZE_1M (1 << 1)
91#define I845_TSEG_SIZE_MASK (3 << 1)
92#define I845_TSEG_SIZE_512K (2 << 1)
93#define I845_TSEG_SIZE_1M (3 << 1)
94
75#endif /* _I915_DRM_H_ */ 95#endif /* _I915_DRM_H_ */