diff options
author | Dave Airlie <airlied@redhat.com> | 2009-09-07 06:27:20 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-09-07 06:27:20 -0400 |
commit | 11670d3c93210793562748d83502ecbef4034765 (patch) | |
tree | 9e2c33c6249e26b05a2b5db87d4f4840e9049840 /drivers/gpu | |
parent | 575dc34ee0de867ba83abf25998e0963bff451fa (diff) | |
parent | 01dfba93d9dfcf6d7abfc55ff5d9d6e76fa01ba0 (diff) |
Merge intel drm-intel-next branch
Merge remote branch 'anholt/drm-intel-next' of ../anholt-2.6 into drm-next
Conflicts:
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_sdvo.c
Diffstat (limited to 'drivers/gpu')
33 files changed, 1474 insertions, 321 deletions
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index de154556c405..51611722aa02 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -23,44 +23,50 @@ | |||
23 | #define to_drm_minor(d) container_of(d, struct drm_minor, kdev) | 23 | #define to_drm_minor(d) container_of(d, struct drm_minor, kdev) |
24 | #define to_drm_connector(d) container_of(d, struct drm_connector, kdev) | 24 | #define to_drm_connector(d) container_of(d, struct drm_connector, kdev) |
25 | 25 | ||
26 | static struct device_type drm_sysfs_device_minor = { | ||
27 | .name = "drm_minor" | ||
28 | }; | ||
29 | |||
26 | /** | 30 | /** |
27 | * drm_sysfs_suspend - DRM class suspend hook | 31 | * drm_class_suspend - DRM class suspend hook |
28 | * @dev: Linux device to suspend | 32 | * @dev: Linux device to suspend |
29 | * @state: power state to enter | 33 | * @state: power state to enter |
30 | * | 34 | * |
31 | * Just figures out what the actual struct drm_device associated with | 35 | * Just figures out what the actual struct drm_device associated with |
32 | * @dev is and calls its suspend hook, if present. | 36 | * @dev is and calls its suspend hook, if present. |
33 | */ | 37 | */ |
34 | static int drm_sysfs_suspend(struct device *dev, pm_message_t state) | 38 | static int drm_class_suspend(struct device *dev, pm_message_t state) |
35 | { | 39 | { |
36 | struct drm_minor *drm_minor = to_drm_minor(dev); | 40 | if (dev->type == &drm_sysfs_device_minor) { |
37 | struct drm_device *drm_dev = drm_minor->dev; | 41 | struct drm_minor *drm_minor = to_drm_minor(dev); |
38 | 42 | struct drm_device *drm_dev = drm_minor->dev; | |
39 | if (drm_minor->type == DRM_MINOR_LEGACY && | 43 | |
40 | !drm_core_check_feature(drm_dev, DRIVER_MODESET) && | 44 | if (drm_minor->type == DRM_MINOR_LEGACY && |
41 | drm_dev->driver->suspend) | 45 | !drm_core_check_feature(drm_dev, DRIVER_MODESET) && |
42 | return drm_dev->driver->suspend(drm_dev, state); | 46 | drm_dev->driver->suspend) |
43 | 47 | return drm_dev->driver->suspend(drm_dev, state); | |
48 | } | ||
44 | return 0; | 49 | return 0; |
45 | } | 50 | } |
46 | 51 | ||
47 | /** | 52 | /** |
48 | * drm_sysfs_resume - DRM class resume hook | 53 | * drm_class_resume - DRM class resume hook |
49 | * @dev: Linux device to resume | 54 | * @dev: Linux device to resume |
50 | * | 55 | * |
51 | * Just figures out what the actual struct drm_device associated with | 56 | * Just figures out what the actual struct drm_device associated with |
52 | * @dev is and calls its resume hook, if present. | 57 | * @dev is and calls its resume hook, if present. |
53 | */ | 58 | */ |
54 | static int drm_sysfs_resume(struct device *dev) | 59 | static int drm_class_resume(struct device *dev) |
55 | { | 60 | { |
56 | struct drm_minor *drm_minor = to_drm_minor(dev); | 61 | if (dev->type == &drm_sysfs_device_minor) { |
57 | struct drm_device *drm_dev = drm_minor->dev; | 62 | struct drm_minor *drm_minor = to_drm_minor(dev); |
58 | 63 | struct drm_device *drm_dev = drm_minor->dev; | |
59 | if (drm_minor->type == DRM_MINOR_LEGACY && | 64 | |
60 | !drm_core_check_feature(drm_dev, DRIVER_MODESET) && | 65 | if (drm_minor->type == DRM_MINOR_LEGACY && |
61 | drm_dev->driver->resume) | 66 | !drm_core_check_feature(drm_dev, DRIVER_MODESET) && |
62 | return drm_dev->driver->resume(drm_dev); | 67 | drm_dev->driver->resume) |
63 | 68 | return drm_dev->driver->resume(drm_dev); | |
69 | } | ||
64 | return 0; | 70 | return 0; |
65 | } | 71 | } |
66 | 72 | ||
@@ -100,8 +106,8 @@ struct class *drm_sysfs_create(struct module *owner, char *name) | |||
100 | goto err_out; | 106 | goto err_out; |
101 | } | 107 | } |
102 | 108 | ||
103 | class->suspend = drm_sysfs_suspend; | 109 | class->suspend = drm_class_suspend; |
104 | class->resume = drm_sysfs_resume; | 110 | class->resume = drm_class_resume; |
105 | 111 | ||
106 | err = class_create_file(class, &class_attr_version); | 112 | err = class_create_file(class, &class_attr_version); |
107 | if (err) | 113 | if (err) |
@@ -484,6 +490,7 @@ int drm_sysfs_device_add(struct drm_minor *minor) | |||
484 | minor->kdev.class = drm_class; | 490 | minor->kdev.class = drm_class; |
485 | minor->kdev.release = drm_sysfs_device_release; | 491 | minor->kdev.release = drm_sysfs_device_release; |
486 | minor->kdev.devt = minor->device; | 492 | minor->kdev.devt = minor->device; |
493 | minor->kdev.type = &drm_sysfs_device_minor; | ||
487 | if (minor->type == DRM_MINOR_CONTROL) | 494 | if (minor->type == DRM_MINOR_CONTROL) |
488 | minor_str = "controlD%d"; | 495 | minor_str = "controlD%d"; |
489 | else if (minor->type == DRM_MINOR_RENDER) | 496 | else if (minor->type == DRM_MINOR_RENDER) |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 30d6b99fb302..5269dfa5f620 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -4,10 +4,10 @@ | |||
4 | 4 | ||
5 | ccflags-y := -Iinclude/drm | 5 | ccflags-y := -Iinclude/drm |
6 | i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | 6 | i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ |
7 | i915_debugfs.o \ | ||
7 | i915_suspend.o \ | 8 | i915_suspend.o \ |
8 | i915_gem.o \ | 9 | i915_gem.o \ |
9 | i915_gem_debug.o \ | 10 | i915_gem_debug.o \ |
10 | i915_gem_debugfs.o \ | ||
11 | i915_gem_tiling.o \ | 11 | i915_gem_tiling.o \ |
12 | intel_display.o \ | 12 | intel_display.o \ |
13 | intel_crt.o \ | 13 | intel_crt.o \ |
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index cb3b97405fbf..1e3bdcee863c 100644 --- a/drivers/gpu/drm/i915/i915_gem_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -158,16 +158,37 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
158 | struct drm_device *dev = node->minor->dev; | 158 | struct drm_device *dev = node->minor->dev; |
159 | drm_i915_private_t *dev_priv = dev->dev_private; | 159 | drm_i915_private_t *dev_priv = dev->dev_private; |
160 | 160 | ||
161 | seq_printf(m, "Interrupt enable: %08x\n", | 161 | if (!IS_IGDNG(dev)) { |
162 | I915_READ(IER)); | 162 | seq_printf(m, "Interrupt enable: %08x\n", |
163 | seq_printf(m, "Interrupt identity: %08x\n", | 163 | I915_READ(IER)); |
164 | I915_READ(IIR)); | 164 | seq_printf(m, "Interrupt identity: %08x\n", |
165 | seq_printf(m, "Interrupt mask: %08x\n", | 165 | I915_READ(IIR)); |
166 | I915_READ(IMR)); | 166 | seq_printf(m, "Interrupt mask: %08x\n", |
167 | seq_printf(m, "Pipe A stat: %08x\n", | 167 | I915_READ(IMR)); |
168 | I915_READ(PIPEASTAT)); | 168 | seq_printf(m, "Pipe A stat: %08x\n", |
169 | seq_printf(m, "Pipe B stat: %08x\n", | 169 | I915_READ(PIPEASTAT)); |
170 | I915_READ(PIPEBSTAT)); | 170 | seq_printf(m, "Pipe B stat: %08x\n", |
171 | I915_READ(PIPEBSTAT)); | ||
172 | } else { | ||
173 | seq_printf(m, "North Display Interrupt enable: %08x\n", | ||
174 | I915_READ(DEIER)); | ||
175 | seq_printf(m, "North Display Interrupt identity: %08x\n", | ||
176 | I915_READ(DEIIR)); | ||
177 | seq_printf(m, "North Display Interrupt mask: %08x\n", | ||
178 | I915_READ(DEIMR)); | ||
179 | seq_printf(m, "South Display Interrupt enable: %08x\n", | ||
180 | I915_READ(SDEIER)); | ||
181 | seq_printf(m, "South Display Interrupt identity: %08x\n", | ||
182 | I915_READ(SDEIIR)); | ||
183 | seq_printf(m, "South Display Interrupt mask: %08x\n", | ||
184 | I915_READ(SDEIMR)); | ||
185 | seq_printf(m, "Graphics Interrupt enable: %08x\n", | ||
186 | I915_READ(GTIER)); | ||
187 | seq_printf(m, "Graphics Interrupt identity: %08x\n", | ||
188 | I915_READ(GTIIR)); | ||
189 | seq_printf(m, "Graphics Interrupt mask: %08x\n", | ||
190 | I915_READ(GTIMR)); | ||
191 | } | ||
171 | seq_printf(m, "Interrupts received: %d\n", | 192 | seq_printf(m, "Interrupts received: %d\n", |
172 | atomic_read(&dev_priv->irq_received)); | 193 | atomic_read(&dev_priv->irq_received)); |
173 | if (dev_priv->hw_status_page != NULL) { | 194 | if (dev_priv->hw_status_page != NULL) { |
@@ -312,15 +333,13 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
312 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 333 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
313 | struct drm_device *dev = node->minor->dev; | 334 | struct drm_device *dev = node->minor->dev; |
314 | drm_i915_private_t *dev_priv = dev->dev_private; | 335 | drm_i915_private_t *dev_priv = dev->dev_private; |
315 | unsigned int head, tail, mask; | 336 | unsigned int head, tail; |
316 | 337 | ||
317 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | 338 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; |
318 | tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; | 339 | tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; |
319 | mask = dev_priv->ring.tail_mask; | ||
320 | 340 | ||
321 | seq_printf(m, "RingHead : %08x\n", head); | 341 | seq_printf(m, "RingHead : %08x\n", head); |
322 | seq_printf(m, "RingTail : %08x\n", tail); | 342 | seq_printf(m, "RingTail : %08x\n", tail); |
323 | seq_printf(m, "RingMask : %08x\n", mask); | ||
324 | seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size); | 343 | seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size); |
325 | seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); | 344 | seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); |
326 | 345 | ||
@@ -363,7 +382,37 @@ out: | |||
363 | return 0; | 382 | return 0; |
364 | } | 383 | } |
365 | 384 | ||
366 | static struct drm_info_list i915_gem_debugfs_list[] = { | 385 | static int i915_registers_info(struct seq_file *m, void *data) { |
386 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
387 | struct drm_device *dev = node->minor->dev; | ||
388 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
389 | uint32_t reg; | ||
390 | |||
391 | #define DUMP_RANGE(start, end) \ | ||
392 | for (reg=start; reg < end; reg += 4) \ | ||
393 | seq_printf(m, "%08x\t%08x\n", reg, I915_READ(reg)); | ||
394 | |||
395 | DUMP_RANGE(0x00000, 0x00fff); /* VGA registers */ | ||
396 | DUMP_RANGE(0x02000, 0x02fff); /* instruction, memory, interrupt control registers */ | ||
397 | DUMP_RANGE(0x03000, 0x031ff); /* FENCE and PPGTT control registers */ | ||
398 | DUMP_RANGE(0x03200, 0x03fff); /* frame buffer compression registers */ | ||
399 | DUMP_RANGE(0x05000, 0x05fff); /* I/O control registers */ | ||
400 | DUMP_RANGE(0x06000, 0x06fff); /* clock control registers */ | ||
401 | DUMP_RANGE(0x07000, 0x07fff); /* 3D internal debug registers */ | ||
402 | DUMP_RANGE(0x07400, 0x088ff); /* GPE debug registers */ | ||
403 | DUMP_RANGE(0x0a000, 0x0afff); /* display palette registers */ | ||
404 | DUMP_RANGE(0x10000, 0x13fff); /* MMIO MCHBAR */ | ||
405 | DUMP_RANGE(0x30000, 0x3ffff); /* overlay registers */ | ||
406 | DUMP_RANGE(0x60000, 0x6ffff); /* display engine pipeline registers */ | ||
407 | DUMP_RANGE(0x70000, 0x72fff); /* display and cursor registers */ | ||
408 | DUMP_RANGE(0x73000, 0x73fff); /* performance counters */ | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | |||
414 | static struct drm_info_list i915_debugfs_list[] = { | ||
415 | {"i915_regs", i915_registers_info, 0}, | ||
367 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, | 416 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, |
368 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, | 417 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, |
369 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, | 418 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, |
@@ -377,19 +426,19 @@ static struct drm_info_list i915_gem_debugfs_list[] = { | |||
377 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, | 426 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, |
378 | {"i915_error_state", i915_error_state, 0}, | 427 | {"i915_error_state", i915_error_state, 0}, |
379 | }; | 428 | }; |
380 | #define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) | 429 | #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) |
381 | 430 | ||
382 | int i915_gem_debugfs_init(struct drm_minor *minor) | 431 | int i915_debugfs_init(struct drm_minor *minor) |
383 | { | 432 | { |
384 | return drm_debugfs_create_files(i915_gem_debugfs_list, | 433 | return drm_debugfs_create_files(i915_debugfs_list, |
385 | I915_GEM_DEBUGFS_ENTRIES, | 434 | I915_DEBUGFS_ENTRIES, |
386 | minor->debugfs_root, minor); | 435 | minor->debugfs_root, minor); |
387 | } | 436 | } |
388 | 437 | ||
389 | void i915_gem_debugfs_cleanup(struct drm_minor *minor) | 438 | void i915_debugfs_cleanup(struct drm_minor *minor) |
390 | { | 439 | { |
391 | drm_debugfs_remove_files(i915_gem_debugfs_list, | 440 | drm_debugfs_remove_files(i915_debugfs_list, |
392 | I915_GEM_DEBUGFS_ENTRIES, minor); | 441 | I915_DEBUGFS_ENTRIES, minor); |
393 | } | 442 | } |
394 | 443 | ||
395 | #endif /* CONFIG_DEBUG_FS */ | 444 | #endif /* CONFIG_DEBUG_FS */ |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index c628c3671394..91ef4c150193 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -79,6 +79,34 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) | |||
79 | return -EBUSY; | 79 | return -EBUSY; |
80 | } | 80 | } |
81 | 81 | ||
82 | /* As a ringbuffer is only allowed to wrap between instructions, fill | ||
83 | * the tail with NOOPs. | ||
84 | */ | ||
85 | int i915_wrap_ring(struct drm_device *dev) | ||
86 | { | ||
87 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
88 | volatile unsigned int *virt; | ||
89 | int rem; | ||
90 | |||
91 | rem = dev_priv->ring.Size - dev_priv->ring.tail; | ||
92 | if (dev_priv->ring.space < rem) { | ||
93 | int ret = i915_wait_ring(dev, rem, __func__); | ||
94 | if (ret) | ||
95 | return ret; | ||
96 | } | ||
97 | dev_priv->ring.space -= rem; | ||
98 | |||
99 | virt = (unsigned int *) | ||
100 | (dev_priv->ring.virtual_start + dev_priv->ring.tail); | ||
101 | rem /= 4; | ||
102 | while (rem--) | ||
103 | *virt++ = MI_NOOP; | ||
104 | |||
105 | dev_priv->ring.tail = 0; | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
82 | /** | 110 | /** |
83 | * Sets up the hardware status page for devices that need a physical address | 111 | * Sets up the hardware status page for devices that need a physical address |
84 | * in the register. | 112 | * in the register. |
@@ -198,7 +226,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
198 | } | 226 | } |
199 | 227 | ||
200 | dev_priv->ring.Size = init->ring_size; | 228 | dev_priv->ring.Size = init->ring_size; |
201 | dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; | ||
202 | 229 | ||
203 | dev_priv->ring.map.offset = init->ring_start; | 230 | dev_priv->ring.map.offset = init->ring_start; |
204 | dev_priv->ring.map.size = init->ring_size; | 231 | dev_priv->ring.map.size = init->ring_size; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index fc4b68aa2d05..dbe568c9327b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -37,12 +37,15 @@ | |||
37 | #include <linux/console.h> | 37 | #include <linux/console.h> |
38 | #include "drm_crtc_helper.h" | 38 | #include "drm_crtc_helper.h" |
39 | 39 | ||
40 | static unsigned int i915_modeset = -1; | 40 | static int i915_modeset = -1; |
41 | module_param_named(modeset, i915_modeset, int, 0400); | 41 | module_param_named(modeset, i915_modeset, int, 0400); |
42 | 42 | ||
43 | unsigned int i915_fbpercrtc = 0; | 43 | unsigned int i915_fbpercrtc = 0; |
44 | module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); | 44 | module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); |
45 | 45 | ||
46 | unsigned int i915_powersave = 1; | ||
47 | module_param_named(powersave, i915_powersave, int, 0400); | ||
48 | |||
46 | static struct drm_driver driver; | 49 | static struct drm_driver driver; |
47 | 50 | ||
48 | static struct pci_device_id pciidlist[] = { | 51 | static struct pci_device_id pciidlist[] = { |
@@ -188,8 +191,8 @@ static struct drm_driver driver = { | |||
188 | .master_create = i915_master_create, | 191 | .master_create = i915_master_create, |
189 | .master_destroy = i915_master_destroy, | 192 | .master_destroy = i915_master_destroy, |
190 | #if defined(CONFIG_DEBUG_FS) | 193 | #if defined(CONFIG_DEBUG_FS) |
191 | .debugfs_init = i915_gem_debugfs_init, | 194 | .debugfs_init = i915_debugfs_init, |
192 | .debugfs_cleanup = i915_gem_debugfs_cleanup, | 195 | .debugfs_cleanup = i915_debugfs_cleanup, |
193 | #endif | 196 | #endif |
194 | .gem_init_object = i915_gem_init_object, | 197 | .gem_init_object = i915_gem_init_object, |
195 | .gem_free_object = i915_gem_free_object, | 198 | .gem_free_object = i915_gem_free_object, |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7537f57d8a87..2d5bce643e6a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -85,7 +85,6 @@ struct drm_i915_gem_phys_object { | |||
85 | }; | 85 | }; |
86 | 86 | ||
87 | typedef struct _drm_i915_ring_buffer { | 87 | typedef struct _drm_i915_ring_buffer { |
88 | int tail_mask; | ||
89 | unsigned long Size; | 88 | unsigned long Size; |
90 | u8 *virtual_start; | 89 | u8 *virtual_start; |
91 | int head; | 90 | int head; |
@@ -222,6 +221,7 @@ typedef struct drm_i915_private { | |||
222 | unsigned int edp_support:1; | 221 | unsigned int edp_support:1; |
223 | int lvds_ssc_freq; | 222 | int lvds_ssc_freq; |
224 | 223 | ||
224 | int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */ | ||
225 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ | 225 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ |
226 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ | 226 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ |
227 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ | 227 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ |
@@ -310,7 +310,7 @@ typedef struct drm_i915_private { | |||
310 | u32 saveIMR; | 310 | u32 saveIMR; |
311 | u32 saveCACHE_MODE_0; | 311 | u32 saveCACHE_MODE_0; |
312 | u32 saveD_STATE; | 312 | u32 saveD_STATE; |
313 | u32 saveCG_2D_DIS; | 313 | u32 saveDSPCLK_GATE_D; |
314 | u32 saveMI_ARB_STATE; | 314 | u32 saveMI_ARB_STATE; |
315 | u32 saveSWF0[16]; | 315 | u32 saveSWF0[16]; |
316 | u32 saveSWF1[16]; | 316 | u32 saveSWF1[16]; |
@@ -384,6 +384,9 @@ typedef struct drm_i915_private { | |||
384 | */ | 384 | */ |
385 | struct list_head inactive_list; | 385 | struct list_head inactive_list; |
386 | 386 | ||
387 | /** LRU list of objects with fence regs on them. */ | ||
388 | struct list_head fence_list; | ||
389 | |||
387 | /** | 390 | /** |
388 | * List of breadcrumbs associated with GPU requests currently | 391 | * List of breadcrumbs associated with GPU requests currently |
389 | * outstanding. | 392 | * outstanding. |
@@ -439,6 +442,14 @@ typedef struct drm_i915_private { | |||
439 | struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; | 442 | struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; |
440 | } mm; | 443 | } mm; |
441 | struct sdvo_device_mapping sdvo_mappings[2]; | 444 | struct sdvo_device_mapping sdvo_mappings[2]; |
445 | |||
446 | /* Reclocking support */ | ||
447 | bool render_reclock_avail; | ||
448 | bool lvds_downclock_avail; | ||
449 | struct work_struct idle_work; | ||
450 | struct timer_list idle_timer; | ||
451 | bool busy; | ||
452 | u16 orig_clock; | ||
442 | } drm_i915_private_t; | 453 | } drm_i915_private_t; |
443 | 454 | ||
444 | /** driver private structure attached to each drm_gem_object */ | 455 | /** driver private structure attached to each drm_gem_object */ |
@@ -451,6 +462,9 @@ struct drm_i915_gem_object { | |||
451 | /** This object's place on the active/flushing/inactive lists */ | 462 | /** This object's place on the active/flushing/inactive lists */ |
452 | struct list_head list; | 463 | struct list_head list; |
453 | 464 | ||
465 | /** This object's place on the fenced object LRU */ | ||
466 | struct list_head fence_list; | ||
467 | |||
454 | /** | 468 | /** |
455 | * This is set if the object is on the active or flushing lists | 469 | * This is set if the object is on the active or flushing lists |
456 | * (has pending rendering), and is not set if it's on inactive (ready | 470 | * (has pending rendering), and is not set if it's on inactive (ready |
@@ -568,6 +582,7 @@ enum intel_chip_family { | |||
568 | extern struct drm_ioctl_desc i915_ioctls[]; | 582 | extern struct drm_ioctl_desc i915_ioctls[]; |
569 | extern int i915_max_ioctl; | 583 | extern int i915_max_ioctl; |
570 | extern unsigned int i915_fbpercrtc; | 584 | extern unsigned int i915_fbpercrtc; |
585 | extern unsigned int i915_powersave; | ||
571 | 586 | ||
572 | extern int i915_master_create(struct drm_device *dev, struct drm_master *master); | 587 | extern int i915_master_create(struct drm_device *dev, struct drm_master *master); |
573 | extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); | 588 | extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); |
@@ -723,8 +738,8 @@ void i915_gem_dump_object(struct drm_gem_object *obj, int len, | |||
723 | void i915_dump_lru(struct drm_device *dev, const char *where); | 738 | void i915_dump_lru(struct drm_device *dev, const char *where); |
724 | 739 | ||
725 | /* i915_debugfs.c */ | 740 | /* i915_debugfs.c */ |
726 | int i915_gem_debugfs_init(struct drm_minor *minor); | 741 | int i915_debugfs_init(struct drm_minor *minor); |
727 | void i915_gem_debugfs_cleanup(struct drm_minor *minor); | 742 | void i915_debugfs_cleanup(struct drm_minor *minor); |
728 | 743 | ||
729 | /* i915_suspend.c */ | 744 | /* i915_suspend.c */ |
730 | extern int i915_save_state(struct drm_device *dev); | 745 | extern int i915_save_state(struct drm_device *dev); |
@@ -774,33 +789,32 @@ extern void intel_modeset_cleanup(struct drm_device *dev); | |||
774 | 789 | ||
775 | #define I915_VERBOSE 0 | 790 | #define I915_VERBOSE 0 |
776 | 791 | ||
777 | #define RING_LOCALS unsigned int outring, ringmask, outcount; \ | 792 | #define RING_LOCALS volatile unsigned int *ring_virt__; |
778 | volatile char *virt; | 793 | |
779 | 794 | #define BEGIN_LP_RING(n) do { \ | |
780 | #define BEGIN_LP_RING(n) do { \ | 795 | int bytes__ = 4*(n); \ |
781 | if (I915_VERBOSE) \ | 796 | if (I915_VERBOSE) DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ |
782 | DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ | 797 | /* a wrap must occur between instructions so pad beforehand */ \ |
783 | if (dev_priv->ring.space < (n)*4) \ | 798 | if (unlikely (dev_priv->ring.tail + bytes__ > dev_priv->ring.Size)) \ |
784 | i915_wait_ring(dev, (n)*4, __func__); \ | 799 | i915_wrap_ring(dev); \ |
785 | outcount = 0; \ | 800 | if (unlikely (dev_priv->ring.space < bytes__)) \ |
786 | outring = dev_priv->ring.tail; \ | 801 | i915_wait_ring(dev, bytes__, __func__); \ |
787 | ringmask = dev_priv->ring.tail_mask; \ | 802 | ring_virt__ = (unsigned int *) \ |
788 | virt = dev_priv->ring.virtual_start; \ | 803 | (dev_priv->ring.virtual_start + dev_priv->ring.tail); \ |
804 | dev_priv->ring.tail += bytes__; \ | ||
805 | dev_priv->ring.tail &= dev_priv->ring.Size - 1; \ | ||
806 | dev_priv->ring.space -= bytes__; \ | ||
789 | } while (0) | 807 | } while (0) |
790 | 808 | ||
791 | #define OUT_RING(n) do { \ | 809 | #define OUT_RING(n) do { \ |
792 | if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ | 810 | if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ |
793 | *(volatile unsigned int *)(virt + outring) = (n); \ | 811 | *ring_virt__++ = (n); \ |
794 | outcount++; \ | ||
795 | outring += 4; \ | ||
796 | outring &= ringmask; \ | ||
797 | } while (0) | 812 | } while (0) |
798 | 813 | ||
799 | #define ADVANCE_LP_RING() do { \ | 814 | #define ADVANCE_LP_RING() do { \ |
800 | if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \ | 815 | if (I915_VERBOSE) \ |
801 | dev_priv->ring.tail = outring; \ | 816 | DRM_DEBUG("ADVANCE_LP_RING %x\n", dev_priv->ring.tail); \ |
802 | dev_priv->ring.space -= outcount * 4; \ | 817 | I915_WRITE(PRB0_TAIL, dev_priv->ring.tail); \ |
803 | I915_WRITE(PRB0_TAIL, outring); \ | ||
804 | } while(0) | 818 | } while(0) |
805 | 819 | ||
806 | /** | 820 | /** |
@@ -823,6 +837,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev); | |||
823 | #define I915_GEM_HWS_INDEX 0x20 | 837 | #define I915_GEM_HWS_INDEX 0x20 |
824 | #define I915_BREADCRUMB_INDEX 0x21 | 838 | #define I915_BREADCRUMB_INDEX 0x21 |
825 | 839 | ||
840 | extern int i915_wrap_ring(struct drm_device * dev); | ||
826 | extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | 841 | extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); |
827 | 842 | ||
828 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) | 843 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) |
@@ -896,6 +911,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
896 | /* dsparb controlled by hw only */ | 911 | /* dsparb controlled by hw only */ |
897 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 912 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
898 | 913 | ||
914 | #define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev)) | ||
915 | #define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | ||
916 | |||
899 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) | 917 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) |
900 | 918 | ||
901 | #endif | 919 | #endif |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0e6c9cca897c..954fb699131b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "drm.h" | 29 | #include "drm.h" |
30 | #include "i915_drm.h" | 30 | #include "i915_drm.h" |
31 | #include "i915_drv.h" | 31 | #include "i915_drv.h" |
32 | #include "intel_drv.h" | ||
32 | #include <linux/swap.h> | 33 | #include <linux/swap.h> |
33 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
34 | 35 | ||
@@ -979,8 +980,10 @@ int | |||
979 | i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | 980 | i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, |
980 | struct drm_file *file_priv) | 981 | struct drm_file *file_priv) |
981 | { | 982 | { |
983 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
982 | struct drm_i915_gem_set_domain *args = data; | 984 | struct drm_i915_gem_set_domain *args = data; |
983 | struct drm_gem_object *obj; | 985 | struct drm_gem_object *obj; |
986 | struct drm_i915_gem_object *obj_priv; | ||
984 | uint32_t read_domains = args->read_domains; | 987 | uint32_t read_domains = args->read_domains; |
985 | uint32_t write_domain = args->write_domain; | 988 | uint32_t write_domain = args->write_domain; |
986 | int ret; | 989 | int ret; |
@@ -1004,8 +1007,12 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1004 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 1007 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
1005 | if (obj == NULL) | 1008 | if (obj == NULL) |
1006 | return -EBADF; | 1009 | return -EBADF; |
1010 | obj_priv = obj->driver_private; | ||
1007 | 1011 | ||
1008 | mutex_lock(&dev->struct_mutex); | 1012 | mutex_lock(&dev->struct_mutex); |
1013 | |||
1014 | intel_mark_busy(dev, obj); | ||
1015 | |||
1009 | #if WATCH_BUF | 1016 | #if WATCH_BUF |
1010 | DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n", | 1017 | DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n", |
1011 | obj, obj->size, read_domains, write_domain); | 1018 | obj, obj->size, read_domains, write_domain); |
@@ -1013,6 +1020,14 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1013 | if (read_domains & I915_GEM_DOMAIN_GTT) { | 1020 | if (read_domains & I915_GEM_DOMAIN_GTT) { |
1014 | ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); | 1021 | ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); |
1015 | 1022 | ||
1023 | /* Update the LRU on the fence for the CPU access that's | ||
1024 | * about to occur. | ||
1025 | */ | ||
1026 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | ||
1027 | list_move_tail(&obj_priv->fence_list, | ||
1028 | &dev_priv->mm.fence_list); | ||
1029 | } | ||
1030 | |||
1016 | /* Silently promote "you're not bound, there was nothing to do" | 1031 | /* Silently promote "you're not bound, there was nothing to do" |
1017 | * to success, since the client was just asking us to | 1032 | * to success, since the client was just asking us to |
1018 | * make sure everything was done. | 1033 | * make sure everything was done. |
@@ -1156,8 +1171,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1156 | } | 1171 | } |
1157 | 1172 | ||
1158 | /* Need a new fence register? */ | 1173 | /* Need a new fence register? */ |
1159 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE && | 1174 | if (obj_priv->tiling_mode != I915_TILING_NONE) { |
1160 | obj_priv->tiling_mode != I915_TILING_NONE) { | ||
1161 | ret = i915_gem_object_get_fence_reg(obj); | 1175 | ret = i915_gem_object_get_fence_reg(obj); |
1162 | if (ret) { | 1176 | if (ret) { |
1163 | mutex_unlock(&dev->struct_mutex); | 1177 | mutex_unlock(&dev->struct_mutex); |
@@ -2209,6 +2223,12 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2209 | struct drm_i915_gem_object *old_obj_priv = NULL; | 2223 | struct drm_i915_gem_object *old_obj_priv = NULL; |
2210 | int i, ret, avail; | 2224 | int i, ret, avail; |
2211 | 2225 | ||
2226 | /* Just update our place in the LRU if our fence is getting used. */ | ||
2227 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | ||
2228 | list_move_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list); | ||
2229 | return 0; | ||
2230 | } | ||
2231 | |||
2212 | switch (obj_priv->tiling_mode) { | 2232 | switch (obj_priv->tiling_mode) { |
2213 | case I915_TILING_NONE: | 2233 | case I915_TILING_NONE: |
2214 | WARN(1, "allocating a fence for non-tiled object?\n"); | 2234 | WARN(1, "allocating a fence for non-tiled object?\n"); |
@@ -2230,7 +2250,6 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2230 | } | 2250 | } |
2231 | 2251 | ||
2232 | /* First try to find a free reg */ | 2252 | /* First try to find a free reg */ |
2233 | try_again: | ||
2234 | avail = 0; | 2253 | avail = 0; |
2235 | for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { | 2254 | for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { |
2236 | reg = &dev_priv->fence_regs[i]; | 2255 | reg = &dev_priv->fence_regs[i]; |
@@ -2244,63 +2263,62 @@ try_again: | |||
2244 | 2263 | ||
2245 | /* None available, try to steal one or wait for a user to finish */ | 2264 | /* None available, try to steal one or wait for a user to finish */ |
2246 | if (i == dev_priv->num_fence_regs) { | 2265 | if (i == dev_priv->num_fence_regs) { |
2247 | uint32_t seqno = dev_priv->mm.next_gem_seqno; | 2266 | struct drm_gem_object *old_obj = NULL; |
2248 | 2267 | ||
2249 | if (avail == 0) | 2268 | if (avail == 0) |
2250 | return -ENOSPC; | 2269 | return -ENOSPC; |
2251 | 2270 | ||
2252 | for (i = dev_priv->fence_reg_start; | 2271 | list_for_each_entry(old_obj_priv, &dev_priv->mm.fence_list, |
2253 | i < dev_priv->num_fence_regs; i++) { | 2272 | fence_list) { |
2254 | uint32_t this_seqno; | 2273 | old_obj = old_obj_priv->obj; |
2255 | |||
2256 | reg = &dev_priv->fence_regs[i]; | ||
2257 | old_obj_priv = reg->obj->driver_private; | ||
2258 | 2274 | ||
2259 | if (old_obj_priv->pin_count) | 2275 | if (old_obj_priv->pin_count) |
2260 | continue; | 2276 | continue; |
2261 | 2277 | ||
2278 | /* Take a reference, as otherwise the wait_rendering | ||
2279 | * below may cause the object to get freed out from | ||
2280 | * under us. | ||
2281 | */ | ||
2282 | drm_gem_object_reference(old_obj); | ||
2283 | |||
2262 | /* i915 uses fences for GPU access to tiled buffers */ | 2284 | /* i915 uses fences for GPU access to tiled buffers */ |
2263 | if (IS_I965G(dev) || !old_obj_priv->active) | 2285 | if (IS_I965G(dev) || !old_obj_priv->active) |
2264 | break; | 2286 | break; |
2265 | 2287 | ||
2266 | /* find the seqno of the first available fence */ | 2288 | /* This brings the object to the head of the LRU if it |
2267 | this_seqno = old_obj_priv->last_rendering_seqno; | 2289 | * had been written to. The only way this should |
2268 | if (this_seqno != 0 && | 2290 | * result in us waiting longer than the expected |
2269 | reg->obj->write_domain == 0 && | 2291 | * optimal amount of time is if there was a |
2270 | i915_seqno_passed(seqno, this_seqno)) | 2292 | * fence-using buffer later that was read-only. |
2271 | seqno = this_seqno; | 2293 | */ |
2272 | } | 2294 | i915_gem_object_flush_gpu_write_domain(old_obj); |
2273 | 2295 | ret = i915_gem_object_wait_rendering(old_obj); | |
2274 | /* | 2296 | if (ret != 0) { |
2275 | * Now things get ugly... we have to wait for one of the | 2297 | drm_gem_object_unreference(old_obj); |
2276 | * objects to finish before trying again. | 2298 | return ret; |
2277 | */ | ||
2278 | if (i == dev_priv->num_fence_regs) { | ||
2279 | if (seqno == dev_priv->mm.next_gem_seqno) { | ||
2280 | i915_gem_flush(dev, | ||
2281 | I915_GEM_GPU_DOMAINS, | ||
2282 | I915_GEM_GPU_DOMAINS); | ||
2283 | seqno = i915_add_request(dev, NULL, | ||
2284 | I915_GEM_GPU_DOMAINS); | ||
2285 | if (seqno == 0) | ||
2286 | return -ENOMEM; | ||
2287 | } | 2299 | } |
2288 | 2300 | ||
2289 | ret = i915_wait_request(dev, seqno); | 2301 | break; |
2290 | if (ret) | ||
2291 | return ret; | ||
2292 | goto try_again; | ||
2293 | } | 2302 | } |
2294 | 2303 | ||
2295 | /* | 2304 | /* |
2296 | * Zap this virtual mapping so we can set up a fence again | 2305 | * Zap this virtual mapping so we can set up a fence again |
2297 | * for this object next time we need it. | 2306 | * for this object next time we need it. |
2298 | */ | 2307 | */ |
2299 | i915_gem_release_mmap(reg->obj); | 2308 | i915_gem_release_mmap(old_obj); |
2309 | |||
2310 | i = old_obj_priv->fence_reg; | ||
2311 | reg = &dev_priv->fence_regs[i]; | ||
2312 | |||
2300 | old_obj_priv->fence_reg = I915_FENCE_REG_NONE; | 2313 | old_obj_priv->fence_reg = I915_FENCE_REG_NONE; |
2314 | list_del_init(&old_obj_priv->fence_list); | ||
2315 | |||
2316 | drm_gem_object_unreference(old_obj); | ||
2301 | } | 2317 | } |
2302 | 2318 | ||
2303 | obj_priv->fence_reg = i; | 2319 | obj_priv->fence_reg = i; |
2320 | list_add_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list); | ||
2321 | |||
2304 | reg->obj = obj; | 2322 | reg->obj = obj; |
2305 | 2323 | ||
2306 | if (IS_I965G(dev)) | 2324 | if (IS_I965G(dev)) |
@@ -2343,6 +2361,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
2343 | 2361 | ||
2344 | dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL; | 2362 | dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL; |
2345 | obj_priv->fence_reg = I915_FENCE_REG_NONE; | 2363 | obj_priv->fence_reg = I915_FENCE_REG_NONE; |
2364 | list_del_init(&obj_priv->fence_list); | ||
2346 | } | 2365 | } |
2347 | 2366 | ||
2348 | /** | 2367 | /** |
@@ -2762,6 +2781,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) | |||
2762 | BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU); | 2781 | BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU); |
2763 | BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU); | 2782 | BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU); |
2764 | 2783 | ||
2784 | intel_mark_busy(dev, obj); | ||
2785 | |||
2765 | #if WATCH_BUF | 2786 | #if WATCH_BUF |
2766 | DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", | 2787 | DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", |
2767 | __func__, obj, | 2788 | __func__, obj, |
@@ -3596,9 +3617,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
3596 | * Pre-965 chips need a fence register set up in order to | 3617 | * Pre-965 chips need a fence register set up in order to |
3597 | * properly handle tiled surfaces. | 3618 | * properly handle tiled surfaces. |
3598 | */ | 3619 | */ |
3599 | if (!IS_I965G(dev) && | 3620 | if (!IS_I965G(dev) && obj_priv->tiling_mode != I915_TILING_NONE) { |
3600 | obj_priv->fence_reg == I915_FENCE_REG_NONE && | ||
3601 | obj_priv->tiling_mode != I915_TILING_NONE) { | ||
3602 | ret = i915_gem_object_get_fence_reg(obj); | 3621 | ret = i915_gem_object_get_fence_reg(obj); |
3603 | if (ret != 0) { | 3622 | if (ret != 0) { |
3604 | if (ret != -EBUSY && ret != -ERESTARTSYS) | 3623 | if (ret != -EBUSY && ret != -ERESTARTSYS) |
@@ -3807,6 +3826,7 @@ int i915_gem_init_object(struct drm_gem_object *obj) | |||
3807 | obj_priv->obj = obj; | 3826 | obj_priv->obj = obj; |
3808 | obj_priv->fence_reg = I915_FENCE_REG_NONE; | 3827 | obj_priv->fence_reg = I915_FENCE_REG_NONE; |
3809 | INIT_LIST_HEAD(&obj_priv->list); | 3828 | INIT_LIST_HEAD(&obj_priv->list); |
3829 | INIT_LIST_HEAD(&obj_priv->fence_list); | ||
3810 | 3830 | ||
3811 | return 0; | 3831 | return 0; |
3812 | } | 3832 | } |
@@ -4080,7 +4100,6 @@ i915_gem_init_ringbuffer(struct drm_device *dev) | |||
4080 | 4100 | ||
4081 | /* Set up the kernel mapping for the ring. */ | 4101 | /* Set up the kernel mapping for the ring. */ |
4082 | ring->Size = obj->size; | 4102 | ring->Size = obj->size; |
4083 | ring->tail_mask = obj->size - 1; | ||
4084 | 4103 | ||
4085 | ring->map.offset = dev->agp->base + obj_priv->gtt_offset; | 4104 | ring->map.offset = dev->agp->base + obj_priv->gtt_offset; |
4086 | ring->map.size = obj->size; | 4105 | ring->map.size = obj->size; |
@@ -4254,6 +4273,7 @@ i915_gem_load(struct drm_device *dev) | |||
4254 | INIT_LIST_HEAD(&dev_priv->mm.flushing_list); | 4273 | INIT_LIST_HEAD(&dev_priv->mm.flushing_list); |
4255 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); | 4274 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); |
4256 | INIT_LIST_HEAD(&dev_priv->mm.request_list); | 4275 | INIT_LIST_HEAD(&dev_priv->mm.request_list); |
4276 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); | ||
4257 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, | 4277 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, |
4258 | i915_gem_retire_work_handler); | 4278 | i915_gem_retire_work_handler); |
4259 | dev_priv->mm.next_gem_seqno = 1; | 4279 | dev_priv->mm.next_gem_seqno = 1; |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index a2d527b22ec4..e774a4a1a503 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -234,7 +234,13 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) | |||
234 | uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; | 234 | uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; |
235 | bool need_disable; | 235 | bool need_disable; |
236 | 236 | ||
237 | if (!IS_I9XX(dev)) { | 237 | if (IS_IGDNG(dev)) { |
238 | /* On IGDNG whatever DRAM config, GPU always do | ||
239 | * same swizzling setup. | ||
240 | */ | ||
241 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | ||
242 | swizzle_y = I915_BIT_6_SWIZZLE_9; | ||
243 | } else if (!IS_I9XX(dev)) { | ||
238 | /* As far as we know, the 865 doesn't have these bit 6 | 244 | /* As far as we know, the 865 doesn't have these bit 6 |
239 | * swizzling issues. | 245 | * swizzling issues. |
240 | */ | 246 | */ |
@@ -317,13 +323,6 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) | |||
317 | } | 323 | } |
318 | } | 324 | } |
319 | 325 | ||
320 | /* FIXME: check with memory config on IGDNG */ | ||
321 | if (IS_IGDNG(dev)) { | ||
322 | DRM_ERROR("disable tiling on IGDNG...\n"); | ||
323 | swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
324 | swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
325 | } | ||
326 | |||
327 | dev_priv->mm.bit_6_swizzle_x = swizzle_x; | 326 | dev_priv->mm.bit_6_swizzle_x = swizzle_x; |
328 | dev_priv->mm.bit_6_swizzle_y = swizzle_y; | 327 | dev_priv->mm.bit_6_swizzle_y = swizzle_y; |
329 | } | 328 | } |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 7ebc84c2881e..6c89f2ff2495 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -565,6 +565,27 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
565 | 565 | ||
566 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); | 566 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
567 | I915_READ(PORT_HOTPLUG_STAT); | 567 | I915_READ(PORT_HOTPLUG_STAT); |
568 | |||
569 | /* EOS interrupts occurs */ | ||
570 | if (IS_IGD(dev) && | ||
571 | (hotplug_status & CRT_EOS_INT_STATUS)) { | ||
572 | u32 temp; | ||
573 | |||
574 | DRM_DEBUG("EOS interrupt occurs\n"); | ||
575 | /* status is already cleared */ | ||
576 | temp = I915_READ(ADPA); | ||
577 | temp &= ~ADPA_DAC_ENABLE; | ||
578 | I915_WRITE(ADPA, temp); | ||
579 | |||
580 | temp = I915_READ(PORT_HOTPLUG_EN); | ||
581 | temp &= ~CRT_EOS_INT_EN; | ||
582 | I915_WRITE(PORT_HOTPLUG_EN, temp); | ||
583 | |||
584 | temp = I915_READ(PORT_HOTPLUG_STAT); | ||
585 | if (temp & CRT_EOS_INT_STATUS) | ||
586 | I915_WRITE(PORT_HOTPLUG_STAT, | ||
587 | CRT_EOS_INT_STATUS); | ||
588 | } | ||
568 | } | 589 | } |
569 | 590 | ||
570 | I915_WRITE(IIR, iir); | 591 | I915_WRITE(IIR, iir); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2955083aa471..e38cd21161c8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -55,7 +55,7 @@ | |||
55 | /* PCI config space */ | 55 | /* PCI config space */ |
56 | 56 | ||
57 | #define HPLLCC 0xc0 /* 855 only */ | 57 | #define HPLLCC 0xc0 /* 855 only */ |
58 | #define GC_CLOCK_CONTROL_MASK (3 << 0) | 58 | #define GC_CLOCK_CONTROL_MASK (0xf << 0) |
59 | #define GC_CLOCK_133_200 (0 << 0) | 59 | #define GC_CLOCK_133_200 (0 << 0) |
60 | #define GC_CLOCK_100_200 (1 << 0) | 60 | #define GC_CLOCK_100_200 (1 << 0) |
61 | #define GC_CLOCK_100_133 (2 << 0) | 61 | #define GC_CLOCK_100_133 (2 << 0) |
@@ -65,6 +65,25 @@ | |||
65 | #define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4) | 65 | #define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4) |
66 | #define GC_DISPLAY_CLOCK_333_MHZ (4 << 4) | 66 | #define GC_DISPLAY_CLOCK_333_MHZ (4 << 4) |
67 | #define GC_DISPLAY_CLOCK_MASK (7 << 4) | 67 | #define GC_DISPLAY_CLOCK_MASK (7 << 4) |
68 | #define GM45_GC_RENDER_CLOCK_MASK (0xf << 0) | ||
69 | #define GM45_GC_RENDER_CLOCK_266_MHZ (8 << 0) | ||
70 | #define GM45_GC_RENDER_CLOCK_320_MHZ (9 << 0) | ||
71 | #define GM45_GC_RENDER_CLOCK_400_MHZ (0xb << 0) | ||
72 | #define GM45_GC_RENDER_CLOCK_533_MHZ (0xc << 0) | ||
73 | #define I965_GC_RENDER_CLOCK_MASK (0xf << 0) | ||
74 | #define I965_GC_RENDER_CLOCK_267_MHZ (2 << 0) | ||
75 | #define I965_GC_RENDER_CLOCK_333_MHZ (3 << 0) | ||
76 | #define I965_GC_RENDER_CLOCK_444_MHZ (4 << 0) | ||
77 | #define I965_GC_RENDER_CLOCK_533_MHZ (5 << 0) | ||
78 | #define I945_GC_RENDER_CLOCK_MASK (7 << 0) | ||
79 | #define I945_GC_RENDER_CLOCK_166_MHZ (0 << 0) | ||
80 | #define I945_GC_RENDER_CLOCK_200_MHZ (1 << 0) | ||
81 | #define I945_GC_RENDER_CLOCK_250_MHZ (3 << 0) | ||
82 | #define I945_GC_RENDER_CLOCK_400_MHZ (5 << 0) | ||
83 | #define I915_GC_RENDER_CLOCK_MASK (7 << 0) | ||
84 | #define I915_GC_RENDER_CLOCK_166_MHZ (0 << 0) | ||
85 | #define I915_GC_RENDER_CLOCK_200_MHZ (1 << 0) | ||
86 | #define I915_GC_RENDER_CLOCK_333_MHZ (4 << 0) | ||
68 | #define LBB 0xf4 | 87 | #define LBB 0xf4 |
69 | 88 | ||
70 | /* VGA stuff */ | 89 | /* VGA stuff */ |
@@ -553,9 +572,118 @@ | |||
553 | #define DPLLA_TEST_M_BYPASS (1 << 2) | 572 | #define DPLLA_TEST_M_BYPASS (1 << 2) |
554 | #define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) | 573 | #define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) |
555 | #define D_STATE 0x6104 | 574 | #define D_STATE 0x6104 |
556 | #define CG_2D_DIS 0x6200 | 575 | #define DSTATE_PLL_D3_OFF (1<<3) |
557 | #define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) | 576 | #define DSTATE_GFX_CLOCK_GATING (1<<1) |
558 | #define CG_3D_DIS 0x6204 | 577 | #define DSTATE_DOT_CLOCK_GATING (1<<0) |
578 | #define DSPCLK_GATE_D 0x6200 | ||
579 | # define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */ | ||
580 | # define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */ | ||
581 | # define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* 965 */ | ||
582 | # define VRDUNIT_CLOCK_GATE_DISABLE (1 << 27) /* 965 */ | ||
583 | # define AUDUNIT_CLOCK_GATE_DISABLE (1 << 26) /* 965 */ | ||
584 | # define DPUNIT_A_CLOCK_GATE_DISABLE (1 << 25) /* 965 */ | ||
585 | # define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) /* 965 */ | ||
586 | # define TVRUNIT_CLOCK_GATE_DISABLE (1 << 23) /* 915-945 */ | ||
587 | # define TVCUNIT_CLOCK_GATE_DISABLE (1 << 22) /* 915-945 */ | ||
588 | # define TVFUNIT_CLOCK_GATE_DISABLE (1 << 21) /* 915-945 */ | ||
589 | # define TVEUNIT_CLOCK_GATE_DISABLE (1 << 20) /* 915-945 */ | ||
590 | # define DVSUNIT_CLOCK_GATE_DISABLE (1 << 19) /* 915-945 */ | ||
591 | # define DSSUNIT_CLOCK_GATE_DISABLE (1 << 18) /* 915-945 */ | ||
592 | # define DDBUNIT_CLOCK_GATE_DISABLE (1 << 17) /* 915-945 */ | ||
593 | # define DPRUNIT_CLOCK_GATE_DISABLE (1 << 16) /* 915-945 */ | ||
594 | # define DPFUNIT_CLOCK_GATE_DISABLE (1 << 15) /* 915-945 */ | ||
595 | # define DPBMUNIT_CLOCK_GATE_DISABLE (1 << 14) /* 915-945 */ | ||
596 | # define DPLSUNIT_CLOCK_GATE_DISABLE (1 << 13) /* 915-945 */ | ||
597 | # define DPLUNIT_CLOCK_GATE_DISABLE (1 << 12) /* 915-945 */ | ||
598 | # define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11) | ||
599 | # define DPBUNIT_CLOCK_GATE_DISABLE (1 << 10) | ||
600 | # define DCUNIT_CLOCK_GATE_DISABLE (1 << 9) | ||
601 | # define DPUNIT_CLOCK_GATE_DISABLE (1 << 8) | ||
602 | # define VRUNIT_CLOCK_GATE_DISABLE (1 << 7) /* 915+: reserved */ | ||
603 | # define OVHUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 830-865 */ | ||
604 | # define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 915-945 */ | ||
605 | # define OVFUNIT_CLOCK_GATE_DISABLE (1 << 5) | ||
606 | # define OVBUNIT_CLOCK_GATE_DISABLE (1 << 4) | ||
607 | /** | ||
608 | * This bit must be set on the 830 to prevent hangs when turning off the | ||
609 | * overlay scaler. | ||
610 | */ | ||
611 | # define OVRUNIT_CLOCK_GATE_DISABLE (1 << 3) | ||
612 | # define OVCUNIT_CLOCK_GATE_DISABLE (1 << 2) | ||
613 | # define OVUUNIT_CLOCK_GATE_DISABLE (1 << 1) | ||
614 | # define ZVUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 830 */ | ||
615 | # define OVLUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 845,865 */ | ||
616 | |||
617 | #define RENCLK_GATE_D1 0x6204 | ||
618 | # define BLITTER_CLOCK_GATE_DISABLE (1 << 13) /* 945GM only */ | ||
619 | # define MPEG_CLOCK_GATE_DISABLE (1 << 12) /* 945GM only */ | ||
620 | # define PC_FE_CLOCK_GATE_DISABLE (1 << 11) | ||
621 | # define PC_BE_CLOCK_GATE_DISABLE (1 << 10) | ||
622 | # define WINDOWER_CLOCK_GATE_DISABLE (1 << 9) | ||
623 | # define INTERPOLATOR_CLOCK_GATE_DISABLE (1 << 8) | ||
624 | # define COLOR_CALCULATOR_CLOCK_GATE_DISABLE (1 << 7) | ||
625 | # define MOTION_COMP_CLOCK_GATE_DISABLE (1 << 6) | ||
626 | # define MAG_CLOCK_GATE_DISABLE (1 << 5) | ||
627 | /** This bit must be unset on 855,865 */ | ||
628 | # define MECI_CLOCK_GATE_DISABLE (1 << 4) | ||
629 | # define DCMP_CLOCK_GATE_DISABLE (1 << 3) | ||
630 | # define MEC_CLOCK_GATE_DISABLE (1 << 2) | ||
631 | # define MECO_CLOCK_GATE_DISABLE (1 << 1) | ||
632 | /** This bit must be set on 855,865. */ | ||
633 | # define SV_CLOCK_GATE_DISABLE (1 << 0) | ||
634 | # define I915_MPEG_CLOCK_GATE_DISABLE (1 << 16) | ||
635 | # define I915_VLD_IP_PR_CLOCK_GATE_DISABLE (1 << 15) | ||
636 | # define I915_MOTION_COMP_CLOCK_GATE_DISABLE (1 << 14) | ||
637 | # define I915_BD_BF_CLOCK_GATE_DISABLE (1 << 13) | ||
638 | # define I915_SF_SE_CLOCK_GATE_DISABLE (1 << 12) | ||
639 | # define I915_WM_CLOCK_GATE_DISABLE (1 << 11) | ||
640 | # define I915_IZ_CLOCK_GATE_DISABLE (1 << 10) | ||
641 | # define I915_PI_CLOCK_GATE_DISABLE (1 << 9) | ||
642 | # define I915_DI_CLOCK_GATE_DISABLE (1 << 8) | ||
643 | # define I915_SH_SV_CLOCK_GATE_DISABLE (1 << 7) | ||
644 | # define I915_PL_DG_QC_FT_CLOCK_GATE_DISABLE (1 << 6) | ||
645 | # define I915_SC_CLOCK_GATE_DISABLE (1 << 5) | ||
646 | # define I915_FL_CLOCK_GATE_DISABLE (1 << 4) | ||
647 | # define I915_DM_CLOCK_GATE_DISABLE (1 << 3) | ||
648 | # define I915_PS_CLOCK_GATE_DISABLE (1 << 2) | ||
649 | # define I915_CC_CLOCK_GATE_DISABLE (1 << 1) | ||
650 | # define I915_BY_CLOCK_GATE_DISABLE (1 << 0) | ||
651 | |||
652 | # define I965_RCZ_CLOCK_GATE_DISABLE (1 << 30) | ||
653 | /** This bit must always be set on 965G/965GM */ | ||
654 | # define I965_RCC_CLOCK_GATE_DISABLE (1 << 29) | ||
655 | # define I965_RCPB_CLOCK_GATE_DISABLE (1 << 28) | ||
656 | # define I965_DAP_CLOCK_GATE_DISABLE (1 << 27) | ||
657 | # define I965_ROC_CLOCK_GATE_DISABLE (1 << 26) | ||
658 | # define I965_GW_CLOCK_GATE_DISABLE (1 << 25) | ||
659 | # define I965_TD_CLOCK_GATE_DISABLE (1 << 24) | ||
660 | /** This bit must always be set on 965G */ | ||
661 | # define I965_ISC_CLOCK_GATE_DISABLE (1 << 23) | ||
662 | # define I965_IC_CLOCK_GATE_DISABLE (1 << 22) | ||
663 | # define I965_EU_CLOCK_GATE_DISABLE (1 << 21) | ||
664 | # define I965_IF_CLOCK_GATE_DISABLE (1 << 20) | ||
665 | # define I965_TC_CLOCK_GATE_DISABLE (1 << 19) | ||
666 | # define I965_SO_CLOCK_GATE_DISABLE (1 << 17) | ||
667 | # define I965_FBC_CLOCK_GATE_DISABLE (1 << 16) | ||
668 | # define I965_MARI_CLOCK_GATE_DISABLE (1 << 15) | ||
669 | # define I965_MASF_CLOCK_GATE_DISABLE (1 << 14) | ||
670 | # define I965_MAWB_CLOCK_GATE_DISABLE (1 << 13) | ||
671 | # define I965_EM_CLOCK_GATE_DISABLE (1 << 12) | ||
672 | # define I965_UC_CLOCK_GATE_DISABLE (1 << 11) | ||
673 | # define I965_SI_CLOCK_GATE_DISABLE (1 << 6) | ||
674 | # define I965_MT_CLOCK_GATE_DISABLE (1 << 5) | ||
675 | # define I965_PL_CLOCK_GATE_DISABLE (1 << 4) | ||
676 | # define I965_DG_CLOCK_GATE_DISABLE (1 << 3) | ||
677 | # define I965_QC_CLOCK_GATE_DISABLE (1 << 2) | ||
678 | # define I965_FT_CLOCK_GATE_DISABLE (1 << 1) | ||
679 | # define I965_DM_CLOCK_GATE_DISABLE (1 << 0) | ||
680 | |||
681 | #define RENCLK_GATE_D2 0x6208 | ||
682 | #define VF_UNIT_CLOCK_GATE_DISABLE (1 << 9) | ||
683 | #define GS_UNIT_CLOCK_GATE_DISABLE (1 << 7) | ||
684 | #define CL_UNIT_CLOCK_GATE_DISABLE (1 << 6) | ||
685 | #define RAMCLK_GATE_D 0x6210 /* CRL only */ | ||
686 | #define DEUC 0x6214 /* CRL only */ | ||
559 | 687 | ||
560 | /* | 688 | /* |
561 | * Palette regs | 689 | * Palette regs |
@@ -683,6 +811,7 @@ | |||
683 | #define SDVOB_HOTPLUG_INT_EN (1 << 26) | 811 | #define SDVOB_HOTPLUG_INT_EN (1 << 26) |
684 | #define SDVOC_HOTPLUG_INT_EN (1 << 25) | 812 | #define SDVOC_HOTPLUG_INT_EN (1 << 25) |
685 | #define TV_HOTPLUG_INT_EN (1 << 18) | 813 | #define TV_HOTPLUG_INT_EN (1 << 18) |
814 | #define CRT_EOS_INT_EN (1 << 10) | ||
686 | #define CRT_HOTPLUG_INT_EN (1 << 9) | 815 | #define CRT_HOTPLUG_INT_EN (1 << 9) |
687 | #define CRT_HOTPLUG_FORCE_DETECT (1 << 3) | 816 | #define CRT_HOTPLUG_FORCE_DETECT (1 << 3) |
688 | #define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8) | 817 | #define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8) |
@@ -717,6 +846,7 @@ | |||
717 | #define DPC_HOTPLUG_INT_STATUS (1 << 28) | 846 | #define DPC_HOTPLUG_INT_STATUS (1 << 28) |
718 | #define HDMID_HOTPLUG_INT_STATUS (1 << 27) | 847 | #define HDMID_HOTPLUG_INT_STATUS (1 << 27) |
719 | #define DPD_HOTPLUG_INT_STATUS (1 << 27) | 848 | #define DPD_HOTPLUG_INT_STATUS (1 << 27) |
849 | #define CRT_EOS_INT_STATUS (1 << 12) | ||
720 | #define CRT_HOTPLUG_INT_STATUS (1 << 11) | 850 | #define CRT_HOTPLUG_INT_STATUS (1 << 11) |
721 | #define TV_HOTPLUG_INT_STATUS (1 << 10) | 851 | #define TV_HOTPLUG_INT_STATUS (1 << 10) |
722 | #define CRT_HOTPLUG_MONITOR_MASK (3 << 8) | 852 | #define CRT_HOTPLUG_MONITOR_MASK (3 << 8) |
@@ -1586,6 +1716,7 @@ | |||
1586 | #define PIPECONF_PROGRESSIVE (0 << 21) | 1716 | #define PIPECONF_PROGRESSIVE (0 << 21) |
1587 | #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) | 1717 | #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) |
1588 | #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) | 1718 | #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) |
1719 | #define PIPECONF_CXSR_DOWNCLOCK (1<<16) | ||
1589 | #define PIPEASTAT 0x70024 | 1720 | #define PIPEASTAT 0x70024 |
1590 | #define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31) | 1721 | #define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31) |
1591 | #define PIPE_CRC_ERROR_ENABLE (1UL<<29) | 1722 | #define PIPE_CRC_ERROR_ENABLE (1UL<<29) |
@@ -1733,6 +1864,7 @@ | |||
1733 | #define DISPPLANE_NO_LINE_DOUBLE 0 | 1864 | #define DISPPLANE_NO_LINE_DOUBLE 0 |
1734 | #define DISPPLANE_STEREO_POLARITY_FIRST 0 | 1865 | #define DISPPLANE_STEREO_POLARITY_FIRST 0 |
1735 | #define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) | 1866 | #define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) |
1867 | #define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* IGDNG */ | ||
1736 | #define DISPPLANE_TILED (1<<10) | 1868 | #define DISPPLANE_TILED (1<<10) |
1737 | #define DSPAADDR 0x70184 | 1869 | #define DSPAADDR 0x70184 |
1738 | #define DSPASTRIDE 0x70188 | 1870 | #define DSPASTRIDE 0x70188 |
@@ -1913,6 +2045,9 @@ | |||
1913 | #define GTIIR 0x44018 | 2045 | #define GTIIR 0x44018 |
1914 | #define GTIER 0x4401c | 2046 | #define GTIER 0x4401c |
1915 | 2047 | ||
2048 | #define DISP_ARB_CTL 0x45000 | ||
2049 | #define DISP_TILE_SURFACE_SWIZZLING (1<<13) | ||
2050 | |||
1916 | /* PCH */ | 2051 | /* PCH */ |
1917 | 2052 | ||
1918 | /* south display engine interrupt */ | 2053 | /* south display engine interrupt */ |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 1d04e1904ac6..20d4d19f5568 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -461,7 +461,7 @@ int i915_save_state(struct drm_device *dev) | |||
461 | 461 | ||
462 | /* Clock gating state */ | 462 | /* Clock gating state */ |
463 | dev_priv->saveD_STATE = I915_READ(D_STATE); | 463 | dev_priv->saveD_STATE = I915_READ(D_STATE); |
464 | dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS); | 464 | dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); |
465 | 465 | ||
466 | /* Cache mode state */ | 466 | /* Cache mode state */ |
467 | dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); | 467 | dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); |
@@ -588,7 +588,7 @@ int i915_restore_state(struct drm_device *dev) | |||
588 | 588 | ||
589 | /* Clock gating state */ | 589 | /* Clock gating state */ |
590 | I915_WRITE (D_STATE, dev_priv->saveD_STATE); | 590 | I915_WRITE (D_STATE, dev_priv->saveD_STATE); |
591 | I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS); | 591 | I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); |
592 | 592 | ||
593 | /* Cache mode state */ | 593 | /* Cache mode state */ |
594 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); | 594 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 300aee3296c2..1e28c1652fd0 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -59,6 +59,16 @@ find_section(struct bdb_header *bdb, int section_id) | |||
59 | return NULL; | 59 | return NULL; |
60 | } | 60 | } |
61 | 61 | ||
62 | static u16 | ||
63 | get_blocksize(void *p) | ||
64 | { | ||
65 | u16 *block_ptr, block_size; | ||
66 | |||
67 | block_ptr = (u16 *)((char *)p - 2); | ||
68 | block_size = *block_ptr; | ||
69 | return block_size; | ||
70 | } | ||
71 | |||
62 | static void | 72 | static void |
63 | fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, | 73 | fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, |
64 | struct lvds_dvo_timing *dvo_timing) | 74 | struct lvds_dvo_timing *dvo_timing) |
@@ -215,6 +225,41 @@ parse_general_features(struct drm_i915_private *dev_priv, | |||
215 | } | 225 | } |
216 | 226 | ||
217 | static void | 227 | static void |
228 | parse_general_definitions(struct drm_i915_private *dev_priv, | ||
229 | struct bdb_header *bdb) | ||
230 | { | ||
231 | struct bdb_general_definitions *general; | ||
232 | const int crt_bus_map_table[] = { | ||
233 | GPIOB, | ||
234 | GPIOA, | ||
235 | GPIOC, | ||
236 | GPIOD, | ||
237 | GPIOE, | ||
238 | GPIOF, | ||
239 | }; | ||
240 | |||
241 | /* Set sensible defaults in case we can't find the general block | ||
242 | or it is the wrong chipset */ | ||
243 | dev_priv->crt_ddc_bus = -1; | ||
244 | |||
245 | general = find_section(bdb, BDB_GENERAL_DEFINITIONS); | ||
246 | if (general) { | ||
247 | u16 block_size = get_blocksize(general); | ||
248 | if (block_size >= sizeof(*general)) { | ||
249 | int bus_pin = general->crt_ddc_gmbus_pin; | ||
250 | DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin); | ||
251 | if ((bus_pin >= 1) && (bus_pin <= 6)) { | ||
252 | dev_priv->crt_ddc_bus = | ||
253 | crt_bus_map_table[bus_pin-1]; | ||
254 | } | ||
255 | } else { | ||
256 | DRM_DEBUG("BDB_GD too small (%d). Invalid.\n", | ||
257 | block_size); | ||
258 | } | ||
259 | } | ||
260 | } | ||
261 | |||
262 | static void | ||
218 | parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | 263 | parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, |
219 | struct bdb_header *bdb) | 264 | struct bdb_header *bdb) |
220 | { | 265 | { |
@@ -222,7 +267,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
222 | struct bdb_general_definitions *p_defs; | 267 | struct bdb_general_definitions *p_defs; |
223 | struct child_device_config *p_child; | 268 | struct child_device_config *p_child; |
224 | int i, child_device_num, count; | 269 | int i, child_device_num, count; |
225 | u16 block_size, *block_ptr; | 270 | u16 block_size; |
226 | 271 | ||
227 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | 272 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
228 | if (!p_defs) { | 273 | if (!p_defs) { |
@@ -240,8 +285,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
240 | return; | 285 | return; |
241 | } | 286 | } |
242 | /* get the block size of general definitions */ | 287 | /* get the block size of general definitions */ |
243 | block_ptr = (u16 *)((char *)p_defs - 2); | 288 | block_size = get_blocksize(p_defs); |
244 | block_size = *block_ptr; | ||
245 | /* get the number of child device */ | 289 | /* get the number of child device */ |
246 | child_device_num = (block_size - sizeof(*p_defs)) / | 290 | child_device_num = (block_size - sizeof(*p_defs)) / |
247 | sizeof(*p_child); | 291 | sizeof(*p_child); |
@@ -311,8 +355,14 @@ parse_driver_features(struct drm_i915_private *dev_priv, | |||
311 | } | 355 | } |
312 | 356 | ||
313 | driver = find_section(bdb, BDB_DRIVER_FEATURES); | 357 | driver = find_section(bdb, BDB_DRIVER_FEATURES); |
314 | if (driver && driver->lvds_config == BDB_DRIVER_FEATURE_EDP) | 358 | if (!driver) |
359 | return; | ||
360 | |||
361 | if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP) | ||
315 | dev_priv->edp_support = 1; | 362 | dev_priv->edp_support = 1; |
363 | |||
364 | if (driver->dual_frequency) | ||
365 | dev_priv->render_reclock_avail = true; | ||
316 | } | 366 | } |
317 | 367 | ||
318 | /** | 368 | /** |
@@ -362,6 +412,7 @@ intel_init_bios(struct drm_device *dev) | |||
362 | 412 | ||
363 | /* Grab useful general definitions */ | 413 | /* Grab useful general definitions */ |
364 | parse_general_features(dev_priv, bdb); | 414 | parse_general_features(dev_priv, bdb); |
415 | parse_general_definitions(dev_priv, bdb); | ||
365 | parse_lfp_panel_data(dev_priv, bdb); | 416 | parse_lfp_panel_data(dev_priv, bdb); |
366 | parse_sdvo_panel_data(dev_priv, bdb); | 417 | parse_sdvo_panel_data(dev_priv, bdb); |
367 | parse_sdvo_device_mapping(dev_priv, bdb); | 418 | parse_sdvo_device_mapping(dev_priv, bdb); |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 4cf8e2e88a40..88814fa2dfd2 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -64,6 +64,34 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode) | |||
64 | } | 64 | } |
65 | 65 | ||
66 | I915_WRITE(reg, temp); | 66 | I915_WRITE(reg, temp); |
67 | |||
68 | if (IS_IGD(dev)) { | ||
69 | if (mode == DRM_MODE_DPMS_OFF) { | ||
70 | /* turn off DAC */ | ||
71 | temp = I915_READ(PORT_HOTPLUG_EN); | ||
72 | temp &= ~CRT_EOS_INT_EN; | ||
73 | I915_WRITE(PORT_HOTPLUG_EN, temp); | ||
74 | |||
75 | temp = I915_READ(PORT_HOTPLUG_STAT); | ||
76 | if (temp & CRT_EOS_INT_STATUS) | ||
77 | I915_WRITE(PORT_HOTPLUG_STAT, | ||
78 | CRT_EOS_INT_STATUS); | ||
79 | } else { | ||
80 | /* turn on DAC. EOS interrupt must be enabled after DAC | ||
81 | * is enabled, so it sounds not good to enable it in | ||
82 | * i915_driver_irq_postinstall() | ||
83 | * wait 12.5ms after DAC is enabled | ||
84 | */ | ||
85 | msleep(13); | ||
86 | temp = I915_READ(PORT_HOTPLUG_STAT); | ||
87 | if (temp & CRT_EOS_INT_STATUS) | ||
88 | I915_WRITE(PORT_HOTPLUG_STAT, | ||
89 | CRT_EOS_INT_STATUS); | ||
90 | temp = I915_READ(PORT_HOTPLUG_EN); | ||
91 | temp |= CRT_EOS_INT_EN; | ||
92 | I915_WRITE(PORT_HOTPLUG_EN, temp); | ||
93 | } | ||
94 | } | ||
67 | } | 95 | } |
68 | 96 | ||
69 | static int intel_crt_mode_valid(struct drm_connector *connector, | 97 | static int intel_crt_mode_valid(struct drm_connector *connector, |
@@ -508,6 +536,7 @@ void intel_crt_init(struct drm_device *dev) | |||
508 | { | 536 | { |
509 | struct drm_connector *connector; | 537 | struct drm_connector *connector; |
510 | struct intel_output *intel_output; | 538 | struct intel_output *intel_output; |
539 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
511 | u32 i2c_reg; | 540 | u32 i2c_reg; |
512 | 541 | ||
513 | intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); | 542 | intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); |
@@ -527,8 +556,12 @@ void intel_crt_init(struct drm_device *dev) | |||
527 | /* Set up the DDC bus. */ | 556 | /* Set up the DDC bus. */ |
528 | if (IS_IGDNG(dev)) | 557 | if (IS_IGDNG(dev)) |
529 | i2c_reg = PCH_GPIOA; | 558 | i2c_reg = PCH_GPIOA; |
530 | else | 559 | else { |
531 | i2c_reg = GPIOA; | 560 | i2c_reg = GPIOA; |
561 | /* Use VBT information for CRT DDC if available */ | ||
562 | if (dev_priv->crt_ddc_bus != -1) | ||
563 | i2c_reg = dev_priv->crt_ddc_bus; | ||
564 | } | ||
532 | intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); | 565 | intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); |
533 | if (!intel_output->ddc_bus) { | 566 | if (!intel_output->ddc_bus) { |
534 | dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " | 567 | dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " |
@@ -537,6 +570,10 @@ void intel_crt_init(struct drm_device *dev) | |||
537 | } | 570 | } |
538 | 571 | ||
539 | intel_output->type = INTEL_OUTPUT_ANALOG; | 572 | intel_output->type = INTEL_OUTPUT_ANALOG; |
573 | intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
574 | (1 << INTEL_ANALOG_CLONE_BIT) | | ||
575 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
576 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
540 | connector->interlace_allowed = 0; | 577 | connector->interlace_allowed = 0; |
541 | connector->doublescan_allowed = 0; | 578 | connector->doublescan_allowed = 0; |
542 | 579 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5fb7a4f4a427..155719ff99d1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -38,6 +38,7 @@ | |||
38 | 38 | ||
39 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); | 39 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); |
40 | static void intel_update_watermarks(struct drm_device *dev); | 40 | static void intel_update_watermarks(struct drm_device *dev); |
41 | static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule); | ||
41 | 42 | ||
42 | typedef struct { | 43 | typedef struct { |
43 | /* given values */ | 44 | /* given values */ |
@@ -67,6 +68,8 @@ struct intel_limit { | |||
67 | intel_p2_t p2; | 68 | intel_p2_t p2; |
68 | bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, | 69 | bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, |
69 | int, int, intel_clock_t *); | 70 | int, int, intel_clock_t *); |
71 | bool (* find_reduced_pll)(const intel_limit_t *, struct drm_crtc *, | ||
72 | int, int, intel_clock_t *); | ||
70 | }; | 73 | }; |
71 | 74 | ||
72 | #define I8XX_DOT_MIN 25000 | 75 | #define I8XX_DOT_MIN 25000 |
@@ -261,6 +264,9 @@ static bool | |||
261 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 264 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
262 | int target, int refclk, intel_clock_t *best_clock); | 265 | int target, int refclk, intel_clock_t *best_clock); |
263 | static bool | 266 | static bool |
267 | intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
268 | int target, int refclk, intel_clock_t *best_clock); | ||
269 | static bool | ||
264 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 270 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
265 | int target, int refclk, intel_clock_t *best_clock); | 271 | int target, int refclk, intel_clock_t *best_clock); |
266 | static bool | 272 | static bool |
@@ -286,6 +292,7 @@ static const intel_limit_t intel_limits_i8xx_dvo = { | |||
286 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, | 292 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, |
287 | .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, | 293 | .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, |
288 | .find_pll = intel_find_best_PLL, | 294 | .find_pll = intel_find_best_PLL, |
295 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
289 | }; | 296 | }; |
290 | 297 | ||
291 | static const intel_limit_t intel_limits_i8xx_lvds = { | 298 | static const intel_limit_t intel_limits_i8xx_lvds = { |
@@ -300,6 +307,7 @@ static const intel_limit_t intel_limits_i8xx_lvds = { | |||
300 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, | 307 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, |
301 | .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, | 308 | .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, |
302 | .find_pll = intel_find_best_PLL, | 309 | .find_pll = intel_find_best_PLL, |
310 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
303 | }; | 311 | }; |
304 | 312 | ||
305 | static const intel_limit_t intel_limits_i9xx_sdvo = { | 313 | static const intel_limit_t intel_limits_i9xx_sdvo = { |
@@ -314,6 +322,7 @@ static const intel_limit_t intel_limits_i9xx_sdvo = { | |||
314 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, | 322 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, |
315 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, | 323 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, |
316 | .find_pll = intel_find_best_PLL, | 324 | .find_pll = intel_find_best_PLL, |
325 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
317 | }; | 326 | }; |
318 | 327 | ||
319 | static const intel_limit_t intel_limits_i9xx_lvds = { | 328 | static const intel_limit_t intel_limits_i9xx_lvds = { |
@@ -331,6 +340,7 @@ static const intel_limit_t intel_limits_i9xx_lvds = { | |||
331 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, | 340 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, |
332 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, | 341 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, |
333 | .find_pll = intel_find_best_PLL, | 342 | .find_pll = intel_find_best_PLL, |
343 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
334 | }; | 344 | }; |
335 | 345 | ||
336 | /* below parameter and function is for G4X Chipset Family*/ | 346 | /* below parameter and function is for G4X Chipset Family*/ |
@@ -348,6 +358,7 @@ static const intel_limit_t intel_limits_g4x_sdvo = { | |||
348 | .p2_fast = G4X_P2_SDVO_FAST | 358 | .p2_fast = G4X_P2_SDVO_FAST |
349 | }, | 359 | }, |
350 | .find_pll = intel_g4x_find_best_PLL, | 360 | .find_pll = intel_g4x_find_best_PLL, |
361 | .find_reduced_pll = intel_g4x_find_best_PLL, | ||
351 | }; | 362 | }; |
352 | 363 | ||
353 | static const intel_limit_t intel_limits_g4x_hdmi = { | 364 | static const intel_limit_t intel_limits_g4x_hdmi = { |
@@ -364,6 +375,7 @@ static const intel_limit_t intel_limits_g4x_hdmi = { | |||
364 | .p2_fast = G4X_P2_HDMI_DAC_FAST | 375 | .p2_fast = G4X_P2_HDMI_DAC_FAST |
365 | }, | 376 | }, |
366 | .find_pll = intel_g4x_find_best_PLL, | 377 | .find_pll = intel_g4x_find_best_PLL, |
378 | .find_reduced_pll = intel_g4x_find_best_PLL, | ||
367 | }; | 379 | }; |
368 | 380 | ||
369 | static const intel_limit_t intel_limits_g4x_single_channel_lvds = { | 381 | static const intel_limit_t intel_limits_g4x_single_channel_lvds = { |
@@ -388,6 +400,7 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = { | |||
388 | .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST | 400 | .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST |
389 | }, | 401 | }, |
390 | .find_pll = intel_g4x_find_best_PLL, | 402 | .find_pll = intel_g4x_find_best_PLL, |
403 | .find_reduced_pll = intel_g4x_find_best_PLL, | ||
391 | }; | 404 | }; |
392 | 405 | ||
393 | static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { | 406 | static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { |
@@ -412,6 +425,7 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { | |||
412 | .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST | 425 | .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST |
413 | }, | 426 | }, |
414 | .find_pll = intel_g4x_find_best_PLL, | 427 | .find_pll = intel_g4x_find_best_PLL, |
428 | .find_reduced_pll = intel_g4x_find_best_PLL, | ||
415 | }; | 429 | }; |
416 | 430 | ||
417 | static const intel_limit_t intel_limits_g4x_display_port = { | 431 | static const intel_limit_t intel_limits_g4x_display_port = { |
@@ -449,6 +463,7 @@ static const intel_limit_t intel_limits_igd_sdvo = { | |||
449 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, | 463 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, |
450 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, | 464 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, |
451 | .find_pll = intel_find_best_PLL, | 465 | .find_pll = intel_find_best_PLL, |
466 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
452 | }; | 467 | }; |
453 | 468 | ||
454 | static const intel_limit_t intel_limits_igd_lvds = { | 469 | static const intel_limit_t intel_limits_igd_lvds = { |
@@ -464,6 +479,7 @@ static const intel_limit_t intel_limits_igd_lvds = { | |||
464 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, | 479 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, |
465 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, | 480 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, |
466 | .find_pll = intel_find_best_PLL, | 481 | .find_pll = intel_find_best_PLL, |
482 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
467 | }; | 483 | }; |
468 | 484 | ||
469 | static const intel_limit_t intel_limits_igdng_sdvo = { | 485 | static const intel_limit_t intel_limits_igdng_sdvo = { |
@@ -666,7 +682,7 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
666 | intel_clock_t clock; | 682 | intel_clock_t clock; |
667 | int err = target; | 683 | int err = target; |
668 | 684 | ||
669 | if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && | 685 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && |
670 | (I915_READ(LVDS)) != 0) { | 686 | (I915_READ(LVDS)) != 0) { |
671 | /* | 687 | /* |
672 | * For LVDS, if the panel is on, just rely on its current | 688 | * For LVDS, if the panel is on, just rely on its current |
@@ -688,15 +704,16 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
688 | 704 | ||
689 | memset (best_clock, 0, sizeof (*best_clock)); | 705 | memset (best_clock, 0, sizeof (*best_clock)); |
690 | 706 | ||
691 | for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) { | 707 | for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) { |
692 | for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) { | 708 | for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; |
693 | /* m1 is always 0 in IGD */ | 709 | clock.m1++) { |
694 | if (clock.m2 >= clock.m1 && !IS_IGD(dev)) | 710 | for (clock.m2 = limit->m2.min; |
695 | break; | 711 | clock.m2 <= limit->m2.max; clock.m2++) { |
696 | for (clock.n = limit->n.min; clock.n <= limit->n.max; | 712 | /* m1 is always 0 in IGD */ |
697 | clock.n++) { | 713 | if (clock.m2 >= clock.m1 && !IS_IGD(dev)) |
698 | for (clock.p1 = limit->p1.min; | 714 | break; |
699 | clock.p1 <= limit->p1.max; clock.p1++) { | 715 | for (clock.n = limit->n.min; |
716 | clock.n <= limit->n.max; clock.n++) { | ||
700 | int this_err; | 717 | int this_err; |
701 | 718 | ||
702 | intel_clock(dev, refclk, &clock); | 719 | intel_clock(dev, refclk, &clock); |
@@ -717,6 +734,46 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
717 | return (err != target); | 734 | return (err != target); |
718 | } | 735 | } |
719 | 736 | ||
737 | |||
738 | static bool | ||
739 | intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
740 | int target, int refclk, intel_clock_t *best_clock) | ||
741 | |||
742 | { | ||
743 | struct drm_device *dev = crtc->dev; | ||
744 | intel_clock_t clock; | ||
745 | int err = target; | ||
746 | bool found = false; | ||
747 | |||
748 | memcpy(&clock, best_clock, sizeof(intel_clock_t)); | ||
749 | |||
750 | for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) { | ||
751 | for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) { | ||
752 | /* m1 is always 0 in IGD */ | ||
753 | if (clock.m2 >= clock.m1 && !IS_IGD(dev)) | ||
754 | break; | ||
755 | for (clock.n = limit->n.min; clock.n <= limit->n.max; | ||
756 | clock.n++) { | ||
757 | int this_err; | ||
758 | |||
759 | intel_clock(dev, refclk, &clock); | ||
760 | |||
761 | if (!intel_PLL_is_valid(crtc, &clock)) | ||
762 | continue; | ||
763 | |||
764 | this_err = abs(clock.dot - target); | ||
765 | if (this_err < err) { | ||
766 | *best_clock = clock; | ||
767 | err = this_err; | ||
768 | found = true; | ||
769 | } | ||
770 | } | ||
771 | } | ||
772 | } | ||
773 | |||
774 | return found; | ||
775 | } | ||
776 | |||
720 | static bool | 777 | static bool |
721 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 778 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
722 | int target, int refclk, intel_clock_t *best_clock) | 779 | int target, int refclk, intel_clock_t *best_clock) |
@@ -747,7 +804,7 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
747 | max_n = limit->n.max; | 804 | max_n = limit->n.max; |
748 | /* based on hardware requriment prefer smaller n to precision */ | 805 | /* based on hardware requriment prefer smaller n to precision */ |
749 | for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { | 806 | for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { |
750 | /* based on hardware requirment prefere larger m1,m2, p1 */ | 807 | /* based on hardware requirment prefere larger m1,m2 */ |
751 | for (clock.m1 = limit->m1.max; | 808 | for (clock.m1 = limit->m1.max; |
752 | clock.m1 >= limit->m1.min; clock.m1--) { | 809 | clock.m1 >= limit->m1.min; clock.m1--) { |
753 | for (clock.m2 = limit->m2.max; | 810 | for (clock.m2 = limit->m2.max; |
@@ -832,15 +889,14 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
832 | 889 | ||
833 | memset(best_clock, 0, sizeof(*best_clock)); | 890 | memset(best_clock, 0, sizeof(*best_clock)); |
834 | max_n = limit->n.max; | 891 | max_n = limit->n.max; |
835 | /* based on hardware requriment prefer smaller n to precision */ | 892 | for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) { |
836 | for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { | 893 | /* based on hardware requriment prefer smaller n to precision */ |
837 | /* based on hardware requirment prefere larger m1,m2, p1 */ | 894 | for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { |
838 | for (clock.m1 = limit->m1.max; | 895 | /* based on hardware requirment prefere larger m1,m2 */ |
839 | clock.m1 >= limit->m1.min; clock.m1--) { | 896 | for (clock.m1 = limit->m1.max; |
840 | for (clock.m2 = limit->m2.max; | 897 | clock.m1 >= limit->m1.min; clock.m1--) { |
841 | clock.m2 >= limit->m2.min; clock.m2--) { | 898 | for (clock.m2 = limit->m2.max; |
842 | for (clock.p1 = limit->p1.max; | 899 | clock.m2 >= limit->m2.min; clock.m2--) { |
843 | clock.p1 >= limit->p1.min; clock.p1--) { | ||
844 | int this_err; | 900 | int this_err; |
845 | 901 | ||
846 | intel_clock(dev, refclk, &clock); | 902 | intel_clock(dev, refclk, &clock); |
@@ -1008,6 +1064,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1008 | dspcntr &= ~DISPPLANE_TILED; | 1064 | dspcntr &= ~DISPPLANE_TILED; |
1009 | } | 1065 | } |
1010 | 1066 | ||
1067 | if (IS_IGDNG(dev)) | ||
1068 | /* must disable */ | ||
1069 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; | ||
1070 | |||
1011 | I915_WRITE(dspcntr_reg, dspcntr); | 1071 | I915_WRITE(dspcntr_reg, dspcntr); |
1012 | 1072 | ||
1013 | Start = obj_priv->gtt_offset; | 1073 | Start = obj_priv->gtt_offset; |
@@ -1030,8 +1090,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1030 | 1090 | ||
1031 | if (old_fb) { | 1091 | if (old_fb) { |
1032 | intel_fb = to_intel_framebuffer(old_fb); | 1092 | intel_fb = to_intel_framebuffer(old_fb); |
1093 | obj_priv = intel_fb->obj->driver_private; | ||
1033 | i915_gem_object_unpin(intel_fb->obj); | 1094 | i915_gem_object_unpin(intel_fb->obj); |
1034 | } | 1095 | } |
1096 | intel_increase_pllclock(crtc, true); | ||
1097 | |||
1035 | mutex_unlock(&dev->struct_mutex); | 1098 | mutex_unlock(&dev->struct_mutex); |
1036 | 1099 | ||
1037 | if (!dev->primary->master) | 1100 | if (!dev->primary->master) |
@@ -1581,6 +1644,8 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1581 | else | 1644 | else |
1582 | i9xx_crtc_dpms(crtc, mode); | 1645 | i9xx_crtc_dpms(crtc, mode); |
1583 | 1646 | ||
1647 | intel_crtc->dpms_mode = mode; | ||
1648 | |||
1584 | if (!dev->primary->master) | 1649 | if (!dev->primary->master) |
1585 | return; | 1650 | return; |
1586 | 1651 | ||
@@ -1603,8 +1668,6 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1603 | DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); | 1668 | DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); |
1604 | break; | 1669 | break; |
1605 | } | 1670 | } |
1606 | |||
1607 | intel_crtc->dpms_mode = mode; | ||
1608 | } | 1671 | } |
1609 | 1672 | ||
1610 | static void intel_crtc_prepare (struct drm_crtc *crtc) | 1673 | static void intel_crtc_prepare (struct drm_crtc *crtc) |
@@ -2005,7 +2068,21 @@ static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock, | |||
2005 | return; | 2068 | return; |
2006 | } | 2069 | } |
2007 | 2070 | ||
2008 | const static int latency_ns = 3000; /* default for non-igd platforms */ | 2071 | /* |
2072 | * Latency for FIFO fetches is dependent on several factors: | ||
2073 | * - memory configuration (speed, channels) | ||
2074 | * - chipset | ||
2075 | * - current MCH state | ||
2076 | * It can be fairly high in some situations, so here we assume a fairly | ||
2077 | * pessimal value. It's a tradeoff between extra memory fetches (if we | ||
2078 | * set this value too high, the FIFO will fetch frequently to stay full) | ||
2079 | * and power consumption (set it too low to save power and we might see | ||
2080 | * FIFO underruns and display "flicker"). | ||
2081 | * | ||
2082 | * A value of 5us seems to be a good balance; safe for very low end | ||
2083 | * platforms but not overly aggressive on lower latency configs. | ||
2084 | */ | ||
2085 | const static int latency_ns = 5000; | ||
2009 | 2086 | ||
2010 | static int intel_get_fifo_size(struct drm_device *dev, int plane) | 2087 | static int intel_get_fifo_size(struct drm_device *dev, int plane) |
2011 | { | 2088 | { |
@@ -2040,6 +2117,18 @@ static int intel_get_fifo_size(struct drm_device *dev, int plane) | |||
2040 | return size; | 2117 | return size; |
2041 | } | 2118 | } |
2042 | 2119 | ||
2120 | static void g4x_update_wm(struct drm_device *dev) | ||
2121 | { | ||
2122 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2123 | u32 fw_blc_self = I915_READ(FW_BLC_SELF); | ||
2124 | |||
2125 | if (i915_powersave) | ||
2126 | fw_blc_self |= FW_BLC_SELF_EN; | ||
2127 | else | ||
2128 | fw_blc_self &= ~FW_BLC_SELF_EN; | ||
2129 | I915_WRITE(FW_BLC_SELF, fw_blc_self); | ||
2130 | } | ||
2131 | |||
2043 | static void i965_update_wm(struct drm_device *dev) | 2132 | static void i965_update_wm(struct drm_device *dev) |
2044 | { | 2133 | { |
2045 | struct drm_i915_private *dev_priv = dev->dev_private; | 2134 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -2091,7 +2180,8 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
2091 | cwm = 2; | 2180 | cwm = 2; |
2092 | 2181 | ||
2093 | /* Calc sr entries for one plane configs */ | 2182 | /* Calc sr entries for one plane configs */ |
2094 | if (sr_hdisplay && (!planea_clock || !planeb_clock)) { | 2183 | if (HAS_FW_BLC(dev) && sr_hdisplay && |
2184 | (!planea_clock || !planeb_clock)) { | ||
2095 | /* self-refresh has much higher latency */ | 2185 | /* self-refresh has much higher latency */ |
2096 | const static int sr_latency_ns = 6000; | 2186 | const static int sr_latency_ns = 6000; |
2097 | 2187 | ||
@@ -2106,8 +2196,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
2106 | srwm = total_size - sr_entries; | 2196 | srwm = total_size - sr_entries; |
2107 | if (srwm < 0) | 2197 | if (srwm < 0) |
2108 | srwm = 1; | 2198 | srwm = 1; |
2109 | if (IS_I9XX(dev)) | 2199 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f)); |
2110 | I915_WRITE(FW_BLC_SELF, (srwm & 0x3f)); | ||
2111 | } | 2200 | } |
2112 | 2201 | ||
2113 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", | 2202 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", |
@@ -2181,9 +2270,6 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
2181 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; | 2270 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; |
2182 | int enabled = 0, pixel_size = 0; | 2271 | int enabled = 0, pixel_size = 0; |
2183 | 2272 | ||
2184 | if (DSPARB_HWCONTROL(dev)) | ||
2185 | return; | ||
2186 | |||
2187 | /* Get the clock config from both planes */ | 2273 | /* Get the clock config from both planes */ |
2188 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 2274 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
2189 | intel_crtc = to_intel_crtc(crtc); | 2275 | intel_crtc = to_intel_crtc(crtc); |
@@ -2216,7 +2302,9 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
2216 | else if (IS_IGD(dev)) | 2302 | else if (IS_IGD(dev)) |
2217 | igd_disable_cxsr(dev); | 2303 | igd_disable_cxsr(dev); |
2218 | 2304 | ||
2219 | if (IS_I965G(dev)) | 2305 | if (IS_G4X(dev)) |
2306 | g4x_update_wm(dev); | ||
2307 | else if (IS_I965G(dev)) | ||
2220 | i965_update_wm(dev); | 2308 | i965_update_wm(dev); |
2221 | else if (IS_I9XX(dev) || IS_MOBILE(dev)) | 2309 | else if (IS_I9XX(dev) || IS_MOBILE(dev)) |
2222 | i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay, | 2310 | i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay, |
@@ -2250,9 +2338,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2250 | int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; | 2338 | int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; |
2251 | int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; | 2339 | int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; |
2252 | int refclk, num_outputs = 0; | 2340 | int refclk, num_outputs = 0; |
2253 | intel_clock_t clock; | 2341 | intel_clock_t clock, reduced_clock; |
2254 | u32 dpll = 0, fp = 0, dspcntr, pipeconf; | 2342 | u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf; |
2255 | bool ok, is_sdvo = false, is_dvo = false; | 2343 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; |
2256 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; | 2344 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
2257 | bool is_edp = false; | 2345 | bool is_edp = false; |
2258 | struct drm_mode_config *mode_config = &dev->mode_config; | 2346 | struct drm_mode_config *mode_config = &dev->mode_config; |
@@ -2335,6 +2423,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2335 | return -EINVAL; | 2423 | return -EINVAL; |
2336 | } | 2424 | } |
2337 | 2425 | ||
2426 | if (limit->find_reduced_pll && dev_priv->lvds_downclock_avail) { | ||
2427 | memcpy(&reduced_clock, &clock, sizeof(intel_clock_t)); | ||
2428 | has_reduced_clock = limit->find_reduced_pll(limit, crtc, | ||
2429 | (adjusted_mode->clock*3/4), | ||
2430 | refclk, | ||
2431 | &reduced_clock); | ||
2432 | } | ||
2433 | |||
2338 | /* SDVO TV has fixed PLL values depend on its clock range, | 2434 | /* SDVO TV has fixed PLL values depend on its clock range, |
2339 | this mirrors vbios setting. */ | 2435 | this mirrors vbios setting. */ |
2340 | if (is_sdvo && is_tv) { | 2436 | if (is_sdvo && is_tv) { |
@@ -2380,10 +2476,17 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2380 | link_bw, &m_n); | 2476 | link_bw, &m_n); |
2381 | } | 2477 | } |
2382 | 2478 | ||
2383 | if (IS_IGD(dev)) | 2479 | if (IS_IGD(dev)) { |
2384 | fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; | 2480 | fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; |
2385 | else | 2481 | if (has_reduced_clock) |
2482 | fp2 = (1 << reduced_clock.n) << 16 | | ||
2483 | reduced_clock.m1 << 8 | reduced_clock.m2; | ||
2484 | } else { | ||
2386 | fp = clock.n << 16 | clock.m1 << 8 | clock.m2; | 2485 | fp = clock.n << 16 | clock.m1 << 8 | clock.m2; |
2486 | if (has_reduced_clock) | ||
2487 | fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | | ||
2488 | reduced_clock.m2; | ||
2489 | } | ||
2387 | 2490 | ||
2388 | if (!IS_IGDNG(dev)) | 2491 | if (!IS_IGDNG(dev)) |
2389 | dpll = DPLL_VGA_MODE_DIS; | 2492 | dpll = DPLL_VGA_MODE_DIS; |
@@ -2396,7 +2499,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2396 | if (is_sdvo) { | 2499 | if (is_sdvo) { |
2397 | dpll |= DPLL_DVO_HIGH_SPEED; | 2500 | dpll |= DPLL_DVO_HIGH_SPEED; |
2398 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; | 2501 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; |
2399 | if (IS_I945G(dev) || IS_I945GM(dev)) | 2502 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) |
2400 | dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; | 2503 | dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; |
2401 | else if (IS_IGDNG(dev)) | 2504 | else if (IS_IGDNG(dev)) |
2402 | dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; | 2505 | dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; |
@@ -2412,6 +2515,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2412 | /* also FPA1 */ | 2515 | /* also FPA1 */ |
2413 | if (IS_IGDNG(dev)) | 2516 | if (IS_IGDNG(dev)) |
2414 | dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; | 2517 | dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; |
2518 | if (IS_G4X(dev) && has_reduced_clock) | ||
2519 | dpll |= (1 << (reduced_clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; | ||
2415 | } | 2520 | } |
2416 | switch (clock.p2) { | 2521 | switch (clock.p2) { |
2417 | case 5: | 2522 | case 5: |
@@ -2559,6 +2664,22 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2559 | udelay(150); | 2664 | udelay(150); |
2560 | } | 2665 | } |
2561 | 2666 | ||
2667 | if (is_lvds && has_reduced_clock && i915_powersave) { | ||
2668 | I915_WRITE(fp_reg + 4, fp2); | ||
2669 | intel_crtc->lowfreq_avail = true; | ||
2670 | if (HAS_PIPE_CXSR(dev)) { | ||
2671 | DRM_DEBUG("enabling CxSR downclocking\n"); | ||
2672 | pipeconf |= PIPECONF_CXSR_DOWNCLOCK; | ||
2673 | } | ||
2674 | } else { | ||
2675 | I915_WRITE(fp_reg + 4, fp); | ||
2676 | intel_crtc->lowfreq_avail = false; | ||
2677 | if (HAS_PIPE_CXSR(dev)) { | ||
2678 | DRM_DEBUG("disabling CxSR downclocking\n"); | ||
2679 | pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; | ||
2680 | } | ||
2681 | } | ||
2682 | |||
2562 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | | 2683 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | |
2563 | ((adjusted_mode->crtc_htotal - 1) << 16)); | 2684 | ((adjusted_mode->crtc_htotal - 1) << 16)); |
2564 | I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | | 2685 | I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | |
@@ -2602,6 +2723,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2602 | 2723 | ||
2603 | intel_wait_for_vblank(dev); | 2724 | intel_wait_for_vblank(dev); |
2604 | 2725 | ||
2726 | if (IS_IGDNG(dev)) { | ||
2727 | /* enable address swizzle for tiling buffer */ | ||
2728 | temp = I915_READ(DISP_ARB_CTL); | ||
2729 | I915_WRITE(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING); | ||
2730 | } | ||
2731 | |||
2605 | I915_WRITE(dspcntr_reg, dspcntr); | 2732 | I915_WRITE(dspcntr_reg, dspcntr); |
2606 | 2733 | ||
2607 | /* Flush the plane changes */ | 2734 | /* Flush the plane changes */ |
@@ -2755,10 +2882,16 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
2755 | struct drm_device *dev = crtc->dev; | 2882 | struct drm_device *dev = crtc->dev; |
2756 | struct drm_i915_private *dev_priv = dev->dev_private; | 2883 | struct drm_i915_private *dev_priv = dev->dev_private; |
2757 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 2884 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2885 | struct intel_framebuffer *intel_fb; | ||
2758 | int pipe = intel_crtc->pipe; | 2886 | int pipe = intel_crtc->pipe; |
2759 | uint32_t temp = 0; | 2887 | uint32_t temp = 0; |
2760 | uint32_t adder; | 2888 | uint32_t adder; |
2761 | 2889 | ||
2890 | if (crtc->fb) { | ||
2891 | intel_fb = to_intel_framebuffer(crtc->fb); | ||
2892 | intel_mark_busy(dev, intel_fb->obj); | ||
2893 | } | ||
2894 | |||
2762 | if (x < 0) { | 2895 | if (x < 0) { |
2763 | temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; | 2896 | temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; |
2764 | x = -x; | 2897 | x = -x; |
@@ -3056,6 +3189,315 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, | |||
3056 | return mode; | 3189 | return mode; |
3057 | } | 3190 | } |
3058 | 3191 | ||
3192 | #define GPU_IDLE_TIMEOUT 500 /* ms */ | ||
3193 | |||
3194 | /* When this timer fires, we've been idle for awhile */ | ||
3195 | static void intel_gpu_idle_timer(unsigned long arg) | ||
3196 | { | ||
3197 | struct drm_device *dev = (struct drm_device *)arg; | ||
3198 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3199 | |||
3200 | DRM_DEBUG("idle timer fired, downclocking\n"); | ||
3201 | |||
3202 | dev_priv->busy = false; | ||
3203 | |||
3204 | queue_work(dev_priv->wq, &dev_priv->idle_work); | ||
3205 | } | ||
3206 | |||
3207 | void intel_increase_renderclock(struct drm_device *dev, bool schedule) | ||
3208 | { | ||
3209 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3210 | |||
3211 | if (IS_IGDNG(dev)) | ||
3212 | return; | ||
3213 | |||
3214 | if (!dev_priv->render_reclock_avail) { | ||
3215 | DRM_DEBUG("not reclocking render clock\n"); | ||
3216 | return; | ||
3217 | } | ||
3218 | |||
3219 | /* Restore render clock frequency to original value */ | ||
3220 | if (IS_G4X(dev) || IS_I9XX(dev)) | ||
3221 | pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock); | ||
3222 | else if (IS_I85X(dev)) | ||
3223 | pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock); | ||
3224 | DRM_DEBUG("increasing render clock frequency\n"); | ||
3225 | |||
3226 | /* Schedule downclock */ | ||
3227 | if (schedule) | ||
3228 | mod_timer(&dev_priv->idle_timer, jiffies + | ||
3229 | msecs_to_jiffies(GPU_IDLE_TIMEOUT)); | ||
3230 | } | ||
3231 | |||
3232 | void intel_decrease_renderclock(struct drm_device *dev) | ||
3233 | { | ||
3234 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3235 | |||
3236 | if (IS_IGDNG(dev)) | ||
3237 | return; | ||
3238 | |||
3239 | if (!dev_priv->render_reclock_avail) { | ||
3240 | DRM_DEBUG("not reclocking render clock\n"); | ||
3241 | return; | ||
3242 | } | ||
3243 | |||
3244 | if (IS_G4X(dev)) { | ||
3245 | u16 gcfgc; | ||
3246 | |||
3247 | /* Adjust render clock... */ | ||
3248 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3249 | |||
3250 | /* Down to minimum... */ | ||
3251 | gcfgc &= ~GM45_GC_RENDER_CLOCK_MASK; | ||
3252 | gcfgc |= GM45_GC_RENDER_CLOCK_266_MHZ; | ||
3253 | |||
3254 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3255 | } else if (IS_I965G(dev)) { | ||
3256 | u16 gcfgc; | ||
3257 | |||
3258 | /* Adjust render clock... */ | ||
3259 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3260 | |||
3261 | /* Down to minimum... */ | ||
3262 | gcfgc &= ~I965_GC_RENDER_CLOCK_MASK; | ||
3263 | gcfgc |= I965_GC_RENDER_CLOCK_267_MHZ; | ||
3264 | |||
3265 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3266 | } else if (IS_I945G(dev) || IS_I945GM(dev)) { | ||
3267 | u16 gcfgc; | ||
3268 | |||
3269 | /* Adjust render clock... */ | ||
3270 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3271 | |||
3272 | /* Down to minimum... */ | ||
3273 | gcfgc &= ~I945_GC_RENDER_CLOCK_MASK; | ||
3274 | gcfgc |= I945_GC_RENDER_CLOCK_166_MHZ; | ||
3275 | |||
3276 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3277 | } else if (IS_I915G(dev)) { | ||
3278 | u16 gcfgc; | ||
3279 | |||
3280 | /* Adjust render clock... */ | ||
3281 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3282 | |||
3283 | /* Down to minimum... */ | ||
3284 | gcfgc &= ~I915_GC_RENDER_CLOCK_MASK; | ||
3285 | gcfgc |= I915_GC_RENDER_CLOCK_166_MHZ; | ||
3286 | |||
3287 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3288 | } else if (IS_I85X(dev)) { | ||
3289 | u16 hpllcc; | ||
3290 | |||
3291 | /* Adjust render clock... */ | ||
3292 | pci_read_config_word(dev->pdev, HPLLCC, &hpllcc); | ||
3293 | |||
3294 | /* Up to maximum... */ | ||
3295 | hpllcc &= ~GC_CLOCK_CONTROL_MASK; | ||
3296 | hpllcc |= GC_CLOCK_133_200; | ||
3297 | |||
3298 | pci_write_config_word(dev->pdev, HPLLCC, hpllcc); | ||
3299 | } | ||
3300 | DRM_DEBUG("decreasing render clock frequency\n"); | ||
3301 | } | ||
3302 | |||
3303 | /* Note that no increase function is needed for this - increase_renderclock() | ||
3304 | * will also rewrite these bits | ||
3305 | */ | ||
3306 | void intel_decrease_displayclock(struct drm_device *dev) | ||
3307 | { | ||
3308 | if (IS_IGDNG(dev)) | ||
3309 | return; | ||
3310 | |||
3311 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) || | ||
3312 | IS_I915GM(dev)) { | ||
3313 | u16 gcfgc; | ||
3314 | |||
3315 | /* Adjust render clock... */ | ||
3316 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3317 | |||
3318 | /* Down to minimum... */ | ||
3319 | gcfgc &= ~0xf0; | ||
3320 | gcfgc |= 0x80; | ||
3321 | |||
3322 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3323 | } | ||
3324 | } | ||
3325 | |||
3326 | #define CRTC_IDLE_TIMEOUT 1000 /* ms */ | ||
3327 | |||
3328 | static void intel_crtc_idle_timer(unsigned long arg) | ||
3329 | { | ||
3330 | struct intel_crtc *intel_crtc = (struct intel_crtc *)arg; | ||
3331 | struct drm_crtc *crtc = &intel_crtc->base; | ||
3332 | drm_i915_private_t *dev_priv = crtc->dev->dev_private; | ||
3333 | |||
3334 | DRM_DEBUG("idle timer fired, downclocking\n"); | ||
3335 | |||
3336 | intel_crtc->busy = false; | ||
3337 | |||
3338 | queue_work(dev_priv->wq, &dev_priv->idle_work); | ||
3339 | } | ||
3340 | |||
3341 | static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule) | ||
3342 | { | ||
3343 | struct drm_device *dev = crtc->dev; | ||
3344 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3345 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
3346 | int pipe = intel_crtc->pipe; | ||
3347 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | ||
3348 | int dpll = I915_READ(dpll_reg); | ||
3349 | |||
3350 | if (IS_IGDNG(dev)) | ||
3351 | return; | ||
3352 | |||
3353 | if (!dev_priv->lvds_downclock_avail) | ||
3354 | return; | ||
3355 | |||
3356 | if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) { | ||
3357 | DRM_DEBUG("upclocking LVDS\n"); | ||
3358 | |||
3359 | /* Unlock panel regs */ | ||
3360 | I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16)); | ||
3361 | |||
3362 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; | ||
3363 | I915_WRITE(dpll_reg, dpll); | ||
3364 | dpll = I915_READ(dpll_reg); | ||
3365 | intel_wait_for_vblank(dev); | ||
3366 | dpll = I915_READ(dpll_reg); | ||
3367 | if (dpll & DISPLAY_RATE_SELECT_FPA1) | ||
3368 | DRM_DEBUG("failed to upclock LVDS!\n"); | ||
3369 | |||
3370 | /* ...and lock them again */ | ||
3371 | I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3); | ||
3372 | } | ||
3373 | |||
3374 | /* Schedule downclock */ | ||
3375 | if (schedule) | ||
3376 | mod_timer(&intel_crtc->idle_timer, jiffies + | ||
3377 | msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); | ||
3378 | } | ||
3379 | |||
3380 | static void intel_decrease_pllclock(struct drm_crtc *crtc) | ||
3381 | { | ||
3382 | struct drm_device *dev = crtc->dev; | ||
3383 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3384 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
3385 | int pipe = intel_crtc->pipe; | ||
3386 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | ||
3387 | int dpll = I915_READ(dpll_reg); | ||
3388 | |||
3389 | if (IS_IGDNG(dev)) | ||
3390 | return; | ||
3391 | |||
3392 | if (!dev_priv->lvds_downclock_avail) | ||
3393 | return; | ||
3394 | |||
3395 | /* | ||
3396 | * Since this is called by a timer, we should never get here in | ||
3397 | * the manual case. | ||
3398 | */ | ||
3399 | if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { | ||
3400 | DRM_DEBUG("downclocking LVDS\n"); | ||
3401 | |||
3402 | /* Unlock panel regs */ | ||
3403 | I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16)); | ||
3404 | |||
3405 | dpll |= DISPLAY_RATE_SELECT_FPA1; | ||
3406 | I915_WRITE(dpll_reg, dpll); | ||
3407 | dpll = I915_READ(dpll_reg); | ||
3408 | intel_wait_for_vblank(dev); | ||
3409 | dpll = I915_READ(dpll_reg); | ||
3410 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) | ||
3411 | DRM_DEBUG("failed to downclock LVDS!\n"); | ||
3412 | |||
3413 | /* ...and lock them again */ | ||
3414 | I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3); | ||
3415 | } | ||
3416 | |||
3417 | } | ||
3418 | |||
3419 | /** | ||
3420 | * intel_idle_update - adjust clocks for idleness | ||
3421 | * @work: work struct | ||
3422 | * | ||
3423 | * Either the GPU or display (or both) went idle. Check the busy status | ||
3424 | * here and adjust the CRTC and GPU clocks as necessary. | ||
3425 | */ | ||
3426 | static void intel_idle_update(struct work_struct *work) | ||
3427 | { | ||
3428 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, | ||
3429 | idle_work); | ||
3430 | struct drm_device *dev = dev_priv->dev; | ||
3431 | struct drm_crtc *crtc; | ||
3432 | struct intel_crtc *intel_crtc; | ||
3433 | |||
3434 | if (!i915_powersave) | ||
3435 | return; | ||
3436 | |||
3437 | mutex_lock(&dev->struct_mutex); | ||
3438 | |||
3439 | /* GPU isn't processing, downclock it. */ | ||
3440 | if (!dev_priv->busy) { | ||
3441 | intel_decrease_renderclock(dev); | ||
3442 | intel_decrease_displayclock(dev); | ||
3443 | } | ||
3444 | |||
3445 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
3446 | /* Skip inactive CRTCs */ | ||
3447 | if (!crtc->fb) | ||
3448 | continue; | ||
3449 | |||
3450 | intel_crtc = to_intel_crtc(crtc); | ||
3451 | if (!intel_crtc->busy) | ||
3452 | intel_decrease_pllclock(crtc); | ||
3453 | } | ||
3454 | |||
3455 | mutex_unlock(&dev->struct_mutex); | ||
3456 | } | ||
3457 | |||
3458 | /** | ||
3459 | * intel_mark_busy - mark the GPU and possibly the display busy | ||
3460 | * @dev: drm device | ||
3461 | * @obj: object we're operating on | ||
3462 | * | ||
3463 | * Callers can use this function to indicate that the GPU is busy processing | ||
3464 | * commands. If @obj matches one of the CRTC objects (i.e. it's a scanout | ||
3465 | * buffer), we'll also mark the display as busy, so we know to increase its | ||
3466 | * clock frequency. | ||
3467 | */ | ||
3468 | void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj) | ||
3469 | { | ||
3470 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3471 | struct drm_crtc *crtc = NULL; | ||
3472 | struct intel_framebuffer *intel_fb; | ||
3473 | struct intel_crtc *intel_crtc; | ||
3474 | |||
3475 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||
3476 | return; | ||
3477 | |||
3478 | dev_priv->busy = true; | ||
3479 | intel_increase_renderclock(dev, true); | ||
3480 | |||
3481 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
3482 | if (!crtc->fb) | ||
3483 | continue; | ||
3484 | |||
3485 | intel_crtc = to_intel_crtc(crtc); | ||
3486 | intel_fb = to_intel_framebuffer(crtc->fb); | ||
3487 | if (intel_fb->obj == obj) { | ||
3488 | if (!intel_crtc->busy) { | ||
3489 | /* Non-busy -> busy, upclock */ | ||
3490 | intel_increase_pllclock(crtc, true); | ||
3491 | intel_crtc->busy = true; | ||
3492 | } else { | ||
3493 | /* Busy -> busy, put off timer */ | ||
3494 | mod_timer(&intel_crtc->idle_timer, jiffies + | ||
3495 | msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); | ||
3496 | } | ||
3497 | } | ||
3498 | } | ||
3499 | } | ||
3500 | |||
3059 | static void intel_crtc_destroy(struct drm_crtc *crtc) | 3501 | static void intel_crtc_destroy(struct drm_crtc *crtc) |
3060 | { | 3502 | { |
3061 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3503 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
@@ -3105,6 +3547,11 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
3105 | intel_crtc->cursor_addr = 0; | 3547 | intel_crtc->cursor_addr = 0; |
3106 | intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF; | 3548 | intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF; |
3107 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); | 3549 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); |
3550 | |||
3551 | intel_crtc->busy = false; | ||
3552 | |||
3553 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, | ||
3554 | (unsigned long)intel_crtc); | ||
3108 | } | 3555 | } |
3109 | 3556 | ||
3110 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 3557 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
@@ -3112,30 +3559,26 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | |||
3112 | { | 3559 | { |
3113 | drm_i915_private_t *dev_priv = dev->dev_private; | 3560 | drm_i915_private_t *dev_priv = dev->dev_private; |
3114 | struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; | 3561 | struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; |
3115 | struct drm_crtc *crtc = NULL; | 3562 | struct drm_mode_object *drmmode_obj; |
3116 | int pipe = -1; | 3563 | struct intel_crtc *crtc; |
3117 | 3564 | ||
3118 | if (!dev_priv) { | 3565 | if (!dev_priv) { |
3119 | DRM_ERROR("called with no initialization\n"); | 3566 | DRM_ERROR("called with no initialization\n"); |
3120 | return -EINVAL; | 3567 | return -EINVAL; |
3121 | } | 3568 | } |
3122 | 3569 | ||
3123 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3570 | drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id, |
3124 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3571 | DRM_MODE_OBJECT_CRTC); |
3125 | if (crtc->base.id == pipe_from_crtc_id->crtc_id) { | ||
3126 | pipe = intel_crtc->pipe; | ||
3127 | break; | ||
3128 | } | ||
3129 | } | ||
3130 | 3572 | ||
3131 | if (pipe == -1) { | 3573 | if (!drmmode_obj) { |
3132 | DRM_ERROR("no such CRTC id\n"); | 3574 | DRM_ERROR("no such CRTC id\n"); |
3133 | return -EINVAL; | 3575 | return -EINVAL; |
3134 | } | 3576 | } |
3135 | 3577 | ||
3136 | pipe_from_crtc_id->pipe = pipe; | 3578 | crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); |
3579 | pipe_from_crtc_id->pipe = crtc->pipe; | ||
3137 | 3580 | ||
3138 | return 0; | 3581 | return 0; |
3139 | } | 3582 | } |
3140 | 3583 | ||
3141 | struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) | 3584 | struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) |
@@ -3158,7 +3601,7 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask) | |||
3158 | 3601 | ||
3159 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 3602 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
3160 | struct intel_output *intel_output = to_intel_output(connector); | 3603 | struct intel_output *intel_output = to_intel_output(connector); |
3161 | if (type_mask & (1 << intel_output->type)) | 3604 | if (type_mask & intel_output->clone_mask) |
3162 | index_mask |= (1 << entry); | 3605 | index_mask |= (1 << entry); |
3163 | entry++; | 3606 | entry++; |
3164 | } | 3607 | } |
@@ -3206,30 +3649,30 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
3206 | intel_dp_init(dev, PCH_DP_D); | 3649 | intel_dp_init(dev, PCH_DP_D); |
3207 | 3650 | ||
3208 | } else if (IS_I9XX(dev)) { | 3651 | } else if (IS_I9XX(dev)) { |
3209 | int found; | 3652 | bool found = false; |
3210 | u32 reg; | ||
3211 | 3653 | ||
3212 | if (I915_READ(SDVOB) & SDVO_DETECTED) { | 3654 | if (I915_READ(SDVOB) & SDVO_DETECTED) { |
3213 | found = intel_sdvo_init(dev, SDVOB); | 3655 | found = intel_sdvo_init(dev, SDVOB); |
3214 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) | 3656 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) |
3215 | intel_hdmi_init(dev, SDVOB); | 3657 | intel_hdmi_init(dev, SDVOB); |
3658 | |||
3216 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) | 3659 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) |
3217 | intel_dp_init(dev, DP_B); | 3660 | intel_dp_init(dev, DP_B); |
3218 | } | 3661 | } |
3219 | 3662 | ||
3220 | /* Before G4X SDVOC doesn't have its own detect register */ | 3663 | /* Before G4X SDVOC doesn't have its own detect register */ |
3221 | if (IS_G4X(dev)) | ||
3222 | reg = SDVOC; | ||
3223 | else | ||
3224 | reg = SDVOB; | ||
3225 | 3664 | ||
3226 | if (I915_READ(reg) & SDVO_DETECTED) { | 3665 | if (I915_READ(SDVOB) & SDVO_DETECTED) |
3227 | found = intel_sdvo_init(dev, SDVOC); | 3666 | found = intel_sdvo_init(dev, SDVOC); |
3228 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) | 3667 | |
3668 | if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) { | ||
3669 | |||
3670 | if (SUPPORTS_INTEGRATED_HDMI(dev)) | ||
3229 | intel_hdmi_init(dev, SDVOC); | 3671 | intel_hdmi_init(dev, SDVOC); |
3230 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) | 3672 | if (SUPPORTS_INTEGRATED_DP(dev)) |
3231 | intel_dp_init(dev, DP_C); | 3673 | intel_dp_init(dev, DP_C); |
3232 | } | 3674 | } |
3675 | |||
3233 | if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) | 3676 | if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) |
3234 | intel_dp_init(dev, DP_D); | 3677 | intel_dp_init(dev, DP_D); |
3235 | } else | 3678 | } else |
@@ -3241,51 +3684,10 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
3241 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 3684 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
3242 | struct intel_output *intel_output = to_intel_output(connector); | 3685 | struct intel_output *intel_output = to_intel_output(connector); |
3243 | struct drm_encoder *encoder = &intel_output->enc; | 3686 | struct drm_encoder *encoder = &intel_output->enc; |
3244 | int crtc_mask = 0, clone_mask = 0; | ||
3245 | 3687 | ||
3246 | /* valid crtcs */ | 3688 | encoder->possible_crtcs = intel_output->crtc_mask; |
3247 | switch(intel_output->type) { | 3689 | encoder->possible_clones = intel_connector_clones(dev, |
3248 | case INTEL_OUTPUT_HDMI: | 3690 | intel_output->clone_mask); |
3249 | crtc_mask = ((1 << 0)| | ||
3250 | (1 << 1)); | ||
3251 | clone_mask = ((1 << INTEL_OUTPUT_HDMI)); | ||
3252 | break; | ||
3253 | case INTEL_OUTPUT_DVO: | ||
3254 | case INTEL_OUTPUT_SDVO: | ||
3255 | crtc_mask = ((1 << 0)| | ||
3256 | (1 << 1)); | ||
3257 | clone_mask = ((1 << INTEL_OUTPUT_ANALOG) | | ||
3258 | (1 << INTEL_OUTPUT_DVO) | | ||
3259 | (1 << INTEL_OUTPUT_SDVO)); | ||
3260 | break; | ||
3261 | case INTEL_OUTPUT_ANALOG: | ||
3262 | crtc_mask = ((1 << 0)| | ||
3263 | (1 << 1)); | ||
3264 | clone_mask = ((1 << INTEL_OUTPUT_ANALOG) | | ||
3265 | (1 << INTEL_OUTPUT_DVO) | | ||
3266 | (1 << INTEL_OUTPUT_SDVO)); | ||
3267 | break; | ||
3268 | case INTEL_OUTPUT_LVDS: | ||
3269 | crtc_mask = (1 << 1); | ||
3270 | clone_mask = (1 << INTEL_OUTPUT_LVDS); | ||
3271 | break; | ||
3272 | case INTEL_OUTPUT_TVOUT: | ||
3273 | crtc_mask = ((1 << 0) | | ||
3274 | (1 << 1)); | ||
3275 | clone_mask = (1 << INTEL_OUTPUT_TVOUT); | ||
3276 | break; | ||
3277 | case INTEL_OUTPUT_DISPLAYPORT: | ||
3278 | crtc_mask = ((1 << 0) | | ||
3279 | (1 << 1)); | ||
3280 | clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT); | ||
3281 | break; | ||
3282 | case INTEL_OUTPUT_EDP: | ||
3283 | crtc_mask = (1 << 1); | ||
3284 | clone_mask = (1 << INTEL_OUTPUT_EDP); | ||
3285 | break; | ||
3286 | } | ||
3287 | encoder->possible_crtcs = crtc_mask; | ||
3288 | encoder->possible_clones = intel_connector_clones(dev, clone_mask); | ||
3289 | } | 3691 | } |
3290 | } | 3692 | } |
3291 | 3693 | ||
@@ -3377,8 +3779,56 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { | |||
3377 | .fb_changed = intelfb_probe, | 3779 | .fb_changed = intelfb_probe, |
3378 | }; | 3780 | }; |
3379 | 3781 | ||
3782 | void intel_init_clock_gating(struct drm_device *dev) | ||
3783 | { | ||
3784 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3785 | |||
3786 | /* | ||
3787 | * Disable clock gating reported to work incorrectly according to the | ||
3788 | * specs, but enable as much else as we can. | ||
3789 | */ | ||
3790 | if (IS_G4X(dev)) { | ||
3791 | uint32_t dspclk_gate; | ||
3792 | I915_WRITE(RENCLK_GATE_D1, 0); | ||
3793 | I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | | ||
3794 | GS_UNIT_CLOCK_GATE_DISABLE | | ||
3795 | CL_UNIT_CLOCK_GATE_DISABLE); | ||
3796 | I915_WRITE(RAMCLK_GATE_D, 0); | ||
3797 | dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | | ||
3798 | OVRUNIT_CLOCK_GATE_DISABLE | | ||
3799 | OVCUNIT_CLOCK_GATE_DISABLE; | ||
3800 | if (IS_GM45(dev)) | ||
3801 | dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; | ||
3802 | I915_WRITE(DSPCLK_GATE_D, dspclk_gate); | ||
3803 | } else if (IS_I965GM(dev)) { | ||
3804 | I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); | ||
3805 | I915_WRITE(RENCLK_GATE_D2, 0); | ||
3806 | I915_WRITE(DSPCLK_GATE_D, 0); | ||
3807 | I915_WRITE(RAMCLK_GATE_D, 0); | ||
3808 | I915_WRITE16(DEUC, 0); | ||
3809 | } else if (IS_I965G(dev)) { | ||
3810 | I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | | ||
3811 | I965_RCC_CLOCK_GATE_DISABLE | | ||
3812 | I965_RCPB_CLOCK_GATE_DISABLE | | ||
3813 | I965_ISC_CLOCK_GATE_DISABLE | | ||
3814 | I965_FBC_CLOCK_GATE_DISABLE); | ||
3815 | I915_WRITE(RENCLK_GATE_D2, 0); | ||
3816 | } else if (IS_I9XX(dev)) { | ||
3817 | u32 dstate = I915_READ(D_STATE); | ||
3818 | |||
3819 | dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | | ||
3820 | DSTATE_DOT_CLOCK_GATING; | ||
3821 | I915_WRITE(D_STATE, dstate); | ||
3822 | } else if (IS_I855(dev) || IS_I865G(dev)) { | ||
3823 | I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); | ||
3824 | } else if (IS_I830(dev)) { | ||
3825 | I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); | ||
3826 | } | ||
3827 | } | ||
3828 | |||
3380 | void intel_modeset_init(struct drm_device *dev) | 3829 | void intel_modeset_init(struct drm_device *dev) |
3381 | { | 3830 | { |
3831 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3382 | int num_pipe; | 3832 | int num_pipe; |
3383 | int i; | 3833 | int i; |
3384 | 3834 | ||
@@ -3413,15 +3863,47 @@ void intel_modeset_init(struct drm_device *dev) | |||
3413 | DRM_DEBUG("%d display pipe%s available.\n", | 3863 | DRM_DEBUG("%d display pipe%s available.\n", |
3414 | num_pipe, num_pipe > 1 ? "s" : ""); | 3864 | num_pipe, num_pipe > 1 ? "s" : ""); |
3415 | 3865 | ||
3866 | if (IS_I85X(dev)) | ||
3867 | pci_read_config_word(dev->pdev, HPLLCC, &dev_priv->orig_clock); | ||
3868 | else if (IS_I9XX(dev) || IS_G4X(dev)) | ||
3869 | pci_read_config_word(dev->pdev, GCFGC, &dev_priv->orig_clock); | ||
3870 | |||
3416 | for (i = 0; i < num_pipe; i++) { | 3871 | for (i = 0; i < num_pipe; i++) { |
3417 | intel_crtc_init(dev, i); | 3872 | intel_crtc_init(dev, i); |
3418 | } | 3873 | } |
3419 | 3874 | ||
3420 | intel_setup_outputs(dev); | 3875 | intel_setup_outputs(dev); |
3876 | |||
3877 | intel_init_clock_gating(dev); | ||
3878 | |||
3879 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); | ||
3880 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, | ||
3881 | (unsigned long)dev); | ||
3421 | } | 3882 | } |
3422 | 3883 | ||
3423 | void intel_modeset_cleanup(struct drm_device *dev) | 3884 | void intel_modeset_cleanup(struct drm_device *dev) |
3424 | { | 3885 | { |
3886 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3887 | struct drm_crtc *crtc; | ||
3888 | struct intel_crtc *intel_crtc; | ||
3889 | |||
3890 | mutex_lock(&dev->struct_mutex); | ||
3891 | |||
3892 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
3893 | /* Skip inactive CRTCs */ | ||
3894 | if (!crtc->fb) | ||
3895 | continue; | ||
3896 | |||
3897 | intel_crtc = to_intel_crtc(crtc); | ||
3898 | intel_increase_pllclock(crtc, false); | ||
3899 | del_timer_sync(&intel_crtc->idle_timer); | ||
3900 | } | ||
3901 | |||
3902 | intel_increase_renderclock(dev, false); | ||
3903 | del_timer_sync(&dev_priv->idle_timer); | ||
3904 | |||
3905 | mutex_unlock(&dev->struct_mutex); | ||
3906 | |||
3425 | drm_mode_config_cleanup(dev); | 3907 | drm_mode_config_cleanup(dev); |
3426 | } | 3908 | } |
3427 | 3909 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a6ff15ac548a..f2afc4af4bc9 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1254,6 +1254,18 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1254 | else | 1254 | else |
1255 | intel_output->type = INTEL_OUTPUT_DISPLAYPORT; | 1255 | intel_output->type = INTEL_OUTPUT_DISPLAYPORT; |
1256 | 1256 | ||
1257 | if (output_reg == DP_B) | ||
1258 | intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); | ||
1259 | else if (output_reg == DP_C) | ||
1260 | intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); | ||
1261 | else if (output_reg == DP_D) | ||
1262 | intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); | ||
1263 | |||
1264 | if (IS_eDP(intel_output)) { | ||
1265 | intel_output->crtc_mask = (1 << 1); | ||
1266 | intel_output->clone_mask = (1 << INTEL_OUTPUT_EDP); | ||
1267 | } else | ||
1268 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
1257 | connector->interlace_allowed = true; | 1269 | connector->interlace_allowed = true; |
1258 | connector->doublescan_allowed = 0; | 1270 | connector->doublescan_allowed = 0; |
1259 | 1271 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 38910f8f30ed..b9e47f1e1cc0 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -57,6 +57,24 @@ | |||
57 | #define INTEL_OUTPUT_DISPLAYPORT 7 | 57 | #define INTEL_OUTPUT_DISPLAYPORT 7 |
58 | #define INTEL_OUTPUT_EDP 8 | 58 | #define INTEL_OUTPUT_EDP 8 |
59 | 59 | ||
60 | /* Intel Pipe Clone Bit */ | ||
61 | #define INTEL_HDMIB_CLONE_BIT 1 | ||
62 | #define INTEL_HDMIC_CLONE_BIT 2 | ||
63 | #define INTEL_HDMID_CLONE_BIT 3 | ||
64 | #define INTEL_HDMIE_CLONE_BIT 4 | ||
65 | #define INTEL_HDMIF_CLONE_BIT 5 | ||
66 | #define INTEL_SDVO_NON_TV_CLONE_BIT 6 | ||
67 | #define INTEL_SDVO_TV_CLONE_BIT 7 | ||
68 | #define INTEL_SDVO_LVDS_CLONE_BIT 8 | ||
69 | #define INTEL_ANALOG_CLONE_BIT 9 | ||
70 | #define INTEL_TV_CLONE_BIT 10 | ||
71 | #define INTEL_DP_B_CLONE_BIT 11 | ||
72 | #define INTEL_DP_C_CLONE_BIT 12 | ||
73 | #define INTEL_DP_D_CLONE_BIT 13 | ||
74 | #define INTEL_LVDS_CLONE_BIT 14 | ||
75 | #define INTEL_DVO_TMDS_CLONE_BIT 15 | ||
76 | #define INTEL_DVO_LVDS_CLONE_BIT 16 | ||
77 | |||
60 | #define INTEL_DVO_CHIP_NONE 0 | 78 | #define INTEL_DVO_CHIP_NONE 0 |
61 | #define INTEL_DVO_CHIP_LVDS 1 | 79 | #define INTEL_DVO_CHIP_LVDS 1 |
62 | #define INTEL_DVO_CHIP_TMDS 2 | 80 | #define INTEL_DVO_CHIP_TMDS 2 |
@@ -86,6 +104,8 @@ struct intel_output { | |||
86 | bool needs_tv_clock; | 104 | bool needs_tv_clock; |
87 | void *dev_priv; | 105 | void *dev_priv; |
88 | void (*hot_plug)(struct intel_output *); | 106 | void (*hot_plug)(struct intel_output *); |
107 | int crtc_mask; | ||
108 | int clone_mask; | ||
89 | }; | 109 | }; |
90 | 110 | ||
91 | struct intel_crtc { | 111 | struct intel_crtc { |
@@ -96,6 +116,9 @@ struct intel_crtc { | |||
96 | uint32_t cursor_addr; | 116 | uint32_t cursor_addr; |
97 | u8 lut_r[256], lut_g[256], lut_b[256]; | 117 | u8 lut_r[256], lut_g[256], lut_b[256]; |
98 | int dpms_mode; | 118 | int dpms_mode; |
119 | bool busy; /* is scanout buffer being updated frequently? */ | ||
120 | struct timer_list idle_timer; | ||
121 | bool lowfreq_avail; | ||
99 | }; | 122 | }; |
100 | 123 | ||
101 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) | 124 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) |
@@ -114,6 +137,7 @@ extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); | |||
114 | extern bool intel_sdvo_init(struct drm_device *dev, int output_device); | 137 | extern bool intel_sdvo_init(struct drm_device *dev, int output_device); |
115 | extern void intel_dvo_init(struct drm_device *dev); | 138 | extern void intel_dvo_init(struct drm_device *dev); |
116 | extern void intel_tv_init(struct drm_device *dev); | 139 | extern void intel_tv_init(struct drm_device *dev); |
140 | extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj); | ||
117 | extern void intel_lvds_init(struct drm_device *dev); | 141 | extern void intel_lvds_init(struct drm_device *dev); |
118 | extern void intel_dp_init(struct drm_device *dev, int dp_reg); | 142 | extern void intel_dp_init(struct drm_device *dev, int dp_reg); |
119 | void | 143 | void |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 13bff20930e8..a4d2606de778 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -435,14 +435,20 @@ void intel_dvo_init(struct drm_device *dev) | |||
435 | continue; | 435 | continue; |
436 | 436 | ||
437 | intel_output->type = INTEL_OUTPUT_DVO; | 437 | intel_output->type = INTEL_OUTPUT_DVO; |
438 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
438 | switch (dvo->type) { | 439 | switch (dvo->type) { |
439 | case INTEL_DVO_CHIP_TMDS: | 440 | case INTEL_DVO_CHIP_TMDS: |
441 | intel_output->clone_mask = | ||
442 | (1 << INTEL_DVO_TMDS_CLONE_BIT) | | ||
443 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
440 | drm_connector_init(dev, connector, | 444 | drm_connector_init(dev, connector, |
441 | &intel_dvo_connector_funcs, | 445 | &intel_dvo_connector_funcs, |
442 | DRM_MODE_CONNECTOR_DVII); | 446 | DRM_MODE_CONNECTOR_DVII); |
443 | encoder_type = DRM_MODE_ENCODER_TMDS; | 447 | encoder_type = DRM_MODE_ENCODER_TMDS; |
444 | break; | 448 | break; |
445 | case INTEL_DVO_CHIP_LVDS: | 449 | case INTEL_DVO_CHIP_LVDS: |
450 | intel_output->clone_mask = | ||
451 | (1 << INTEL_DVO_LVDS_CLONE_BIT); | ||
446 | drm_connector_init(dev, connector, | 452 | drm_connector_init(dev, connector, |
447 | &intel_dvo_connector_funcs, | 453 | &intel_dvo_connector_funcs, |
448 | DRM_MODE_CONNECTOR_LVDS); | 454 | DRM_MODE_CONNECTOR_LVDS); |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1842290cded3..fa304e136010 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -230,22 +230,28 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
230 | 230 | ||
231 | connector->interlace_allowed = 0; | 231 | connector->interlace_allowed = 0; |
232 | connector->doublescan_allowed = 0; | 232 | connector->doublescan_allowed = 0; |
233 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
233 | 234 | ||
234 | /* Set up the DDC bus. */ | 235 | /* Set up the DDC bus. */ |
235 | if (sdvox_reg == SDVOB) | 236 | if (sdvox_reg == SDVOB) { |
237 | intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); | ||
236 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); | 238 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); |
237 | else if (sdvox_reg == SDVOC) | 239 | } else if (sdvox_reg == SDVOC) { |
240 | intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); | ||
238 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); | 241 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); |
239 | else if (sdvox_reg == HDMIB) | 242 | } else if (sdvox_reg == HDMIB) { |
243 | intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); | ||
240 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, | 244 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, |
241 | "HDMIB"); | 245 | "HDMIB"); |
242 | else if (sdvox_reg == HDMIC) | 246 | } else if (sdvox_reg == HDMIC) { |
247 | intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); | ||
243 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, | 248 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, |
244 | "HDMIC"); | 249 | "HDMIC"); |
245 | else if (sdvox_reg == HDMID) | 250 | } else if (sdvox_reg == HDMID) { |
251 | intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); | ||
246 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, | 252 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, |
247 | "HDMID"); | 253 | "HDMID"); |
248 | 254 | } | |
249 | if (!intel_output->ddc_bus) | 255 | if (!intel_output->ddc_bus) |
250 | goto err_connector; | 256 | goto err_connector; |
251 | 257 | ||
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 62b8bead7652..c7eab724c418 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -42,11 +42,11 @@ void intel_i2c_quirk_set(struct drm_device *dev, bool enable) | |||
42 | if (!IS_IGD(dev)) | 42 | if (!IS_IGD(dev)) |
43 | return; | 43 | return; |
44 | if (enable) | 44 | if (enable) |
45 | I915_WRITE(CG_2D_DIS, | 45 | I915_WRITE(DSPCLK_GATE_D, |
46 | I915_READ(CG_2D_DIS) | DPCUNIT_CLOCK_GATE_DISABLE); | 46 | I915_READ(DSPCLK_GATE_D) | DPCUNIT_CLOCK_GATE_DISABLE); |
47 | else | 47 | else |
48 | I915_WRITE(CG_2D_DIS, | 48 | I915_WRITE(DSPCLK_GATE_D, |
49 | I915_READ(CG_2D_DIS) & (~DPCUNIT_CLOCK_GATE_DISABLE)); | 49 | I915_READ(DSPCLK_GATE_D) & (~DPCUNIT_CLOCK_GATE_DISABLE)); |
50 | } | 50 | } |
51 | 51 | ||
52 | /* | 52 | /* |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index b78c550ae866..dafc0da1c256 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -904,6 +904,8 @@ void intel_lvds_init(struct drm_device *dev) | |||
904 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 904 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); |
905 | intel_output->type = INTEL_OUTPUT_LVDS; | 905 | intel_output->type = INTEL_OUTPUT_LVDS; |
906 | 906 | ||
907 | intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); | ||
908 | intel_output->crtc_mask = (1 << 1); | ||
907 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); | 909 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); |
908 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); | 910 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); |
909 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | 911 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 91238f0c39a5..0bf28efcf2c1 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -37,6 +37,19 @@ | |||
37 | #include "intel_sdvo_regs.h" | 37 | #include "intel_sdvo_regs.h" |
38 | 38 | ||
39 | #undef SDVO_DEBUG | 39 | #undef SDVO_DEBUG |
40 | |||
41 | static char *tv_format_names[] = { | ||
42 | "NTSC_M" , "NTSC_J" , "NTSC_443", | ||
43 | "PAL_B" , "PAL_D" , "PAL_G" , | ||
44 | "PAL_H" , "PAL_I" , "PAL_M" , | ||
45 | "PAL_N" , "PAL_NC" , "PAL_60" , | ||
46 | "SECAM_B" , "SECAM_D" , "SECAM_G" , | ||
47 | "SECAM_K" , "SECAM_K1", "SECAM_L" , | ||
48 | "SECAM_60" | ||
49 | }; | ||
50 | |||
51 | #define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) | ||
52 | |||
40 | struct intel_sdvo_priv { | 53 | struct intel_sdvo_priv { |
41 | u8 slave_addr; | 54 | u8 slave_addr; |
42 | 55 | ||
@@ -70,6 +83,15 @@ struct intel_sdvo_priv { | |||
70 | */ | 83 | */ |
71 | bool is_tv; | 84 | bool is_tv; |
72 | 85 | ||
86 | /* This is for current tv format name */ | ||
87 | char *tv_format_name; | ||
88 | |||
89 | /* This contains all current supported TV format */ | ||
90 | char *tv_format_supported[TV_FORMAT_NUM]; | ||
91 | int format_supported_num; | ||
92 | struct drm_property *tv_format_property; | ||
93 | struct drm_property *tv_format_name_property[TV_FORMAT_NUM]; | ||
94 | |||
73 | /** | 95 | /** |
74 | * This is set if we treat the device as HDMI, instead of DVI. | 96 | * This is set if we treat the device as HDMI, instead of DVI. |
75 | */ | 97 | */ |
@@ -96,14 +118,6 @@ struct intel_sdvo_priv { | |||
96 | */ | 118 | */ |
97 | struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; | 119 | struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; |
98 | 120 | ||
99 | /** | ||
100 | * Current selected TV format. | ||
101 | * | ||
102 | * This is stored in the same structure that's passed to the device, for | ||
103 | * convenience. | ||
104 | */ | ||
105 | struct intel_sdvo_tv_format tv_format; | ||
106 | |||
107 | /* | 121 | /* |
108 | * supported encoding mode, used to determine whether HDMI is | 122 | * supported encoding mode, used to determine whether HDMI is |
109 | * supported | 123 | * supported |
@@ -113,6 +127,9 @@ struct intel_sdvo_priv { | |||
113 | /* DDC bus used by this SDVO output */ | 127 | /* DDC bus used by this SDVO output */ |
114 | uint8_t ddc_bus; | 128 | uint8_t ddc_bus; |
115 | 129 | ||
130 | /* Mac mini hack -- use the same DDC as the analog connector */ | ||
131 | struct i2c_adapter *analog_ddc_bus; | ||
132 | |||
116 | int save_sdvo_mult; | 133 | int save_sdvo_mult; |
117 | u16 save_active_outputs; | 134 | u16 save_active_outputs; |
118 | struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; | 135 | struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; |
@@ -944,23 +961,28 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output, | |||
944 | 961 | ||
945 | static void intel_sdvo_set_tv_format(struct intel_output *output) | 962 | static void intel_sdvo_set_tv_format(struct intel_output *output) |
946 | { | 963 | { |
964 | |||
965 | struct intel_sdvo_tv_format format; | ||
947 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 966 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; |
948 | struct intel_sdvo_tv_format *format, unset; | 967 | uint32_t format_map, i; |
949 | u8 status; | 968 | uint8_t status; |
950 | 969 | ||
951 | format = &sdvo_priv->tv_format; | 970 | for (i = 0; i < TV_FORMAT_NUM; i++) |
952 | memset(&unset, 0, sizeof(unset)); | 971 | if (tv_format_names[i] == sdvo_priv->tv_format_name) |
953 | if (memcmp(format, &unset, sizeof(*format))) { | 972 | break; |
954 | DRM_DEBUG_KMS("%s: Choosing default TV format of NTSC-M\n", | 973 | |
955 | SDVO_NAME(sdvo_priv)); | 974 | format_map = 1 << i; |
956 | format->ntsc_m = 1; | 975 | memset(&format, 0, sizeof(format)); |
957 | intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, format, | 976 | memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? |
958 | sizeof(*format)); | 977 | sizeof(format) : sizeof(format_map)); |
959 | status = intel_sdvo_read_response(output, NULL, 0); | 978 | |
960 | if (status != SDVO_CMD_STATUS_SUCCESS) | 979 | intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map, |
961 | DRM_DEBUG_KMS("%s: Failed to set TV format\n", | 980 | sizeof(format)); |
962 | SDVO_NAME(sdvo_priv)); | 981 | |
963 | } | 982 | status = intel_sdvo_read_response(output, NULL, 0); |
983 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
984 | DRM_DEBUG("%s: Failed to set TV format\n", | ||
985 | SDVO_NAME(sdvo_priv)); | ||
964 | } | 986 | } |
965 | 987 | ||
966 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | 988 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, |
@@ -1457,7 +1479,7 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output) | |||
1457 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) | 1479 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) |
1458 | caps++; | 1480 | caps++; |
1459 | if (sdvo_priv->caps.output_flags & | 1481 | if (sdvo_priv->caps.output_flags & |
1460 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID0)) | 1482 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1)) |
1461 | caps++; | 1483 | caps++; |
1462 | if (sdvo_priv->caps.output_flags & | 1484 | if (sdvo_priv->caps.output_flags & |
1463 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) | 1485 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) |
@@ -1477,6 +1499,36 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output) | |||
1477 | return (caps > 1); | 1499 | return (caps > 1); |
1478 | } | 1500 | } |
1479 | 1501 | ||
1502 | static struct drm_connector * | ||
1503 | intel_find_analog_connector(struct drm_device *dev) | ||
1504 | { | ||
1505 | struct drm_connector *connector; | ||
1506 | struct intel_output *intel_output; | ||
1507 | |||
1508 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
1509 | intel_output = to_intel_output(connector); | ||
1510 | if (intel_output->type == INTEL_OUTPUT_ANALOG) | ||
1511 | return connector; | ||
1512 | } | ||
1513 | return NULL; | ||
1514 | } | ||
1515 | |||
1516 | static int | ||
1517 | intel_analog_is_connected(struct drm_device *dev) | ||
1518 | { | ||
1519 | struct drm_connector *analog_connector; | ||
1520 | analog_connector = intel_find_analog_connector(dev); | ||
1521 | |||
1522 | if (!analog_connector) | ||
1523 | return false; | ||
1524 | |||
1525 | if (analog_connector->funcs->detect(analog_connector) == | ||
1526 | connector_status_disconnected) | ||
1527 | return false; | ||
1528 | |||
1529 | return true; | ||
1530 | } | ||
1531 | |||
1480 | enum drm_connector_status | 1532 | enum drm_connector_status |
1481 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | 1533 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) |
1482 | { | 1534 | { |
@@ -1487,6 +1539,15 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1487 | 1539 | ||
1488 | edid = drm_get_edid(&intel_output->base, | 1540 | edid = drm_get_edid(&intel_output->base, |
1489 | intel_output->ddc_bus); | 1541 | intel_output->ddc_bus); |
1542 | |||
1543 | /* when there is no edid and no monitor is connected with VGA | ||
1544 | * port, try to use the CRT ddc to read the EDID for DVI-connector | ||
1545 | */ | ||
1546 | if (edid == NULL && | ||
1547 | sdvo_priv->analog_ddc_bus && | ||
1548 | !intel_analog_is_connected(intel_output->base.dev)) | ||
1549 | edid = drm_get_edid(&intel_output->base, | ||
1550 | sdvo_priv->analog_ddc_bus); | ||
1490 | if (edid != NULL) { | 1551 | if (edid != NULL) { |
1491 | /* Don't report the output as connected if it's a DVI-I | 1552 | /* Don't report the output as connected if it's a DVI-I |
1492 | * connector with a non-digital EDID coming out. | 1553 | * connector with a non-digital EDID coming out. |
@@ -1515,7 +1576,8 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1515 | struct intel_output *intel_output = to_intel_output(connector); | 1576 | struct intel_output *intel_output = to_intel_output(connector); |
1516 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1577 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; |
1517 | 1578 | ||
1518 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | 1579 | intel_sdvo_write_cmd(intel_output, |
1580 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | ||
1519 | status = intel_sdvo_read_response(intel_output, &response, 2); | 1581 | status = intel_sdvo_read_response(intel_output, &response, 2); |
1520 | 1582 | ||
1521 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); | 1583 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); |
@@ -1539,50 +1601,32 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1539 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1601 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
1540 | { | 1602 | { |
1541 | struct intel_output *intel_output = to_intel_output(connector); | 1603 | struct intel_output *intel_output = to_intel_output(connector); |
1604 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1605 | int num_modes; | ||
1542 | 1606 | ||
1543 | /* set the bus switch and get the modes */ | 1607 | /* set the bus switch and get the modes */ |
1544 | intel_ddc_get_modes(intel_output); | 1608 | num_modes = intel_ddc_get_modes(intel_output); |
1545 | 1609 | ||
1546 | #if 0 | 1610 | /* |
1547 | struct drm_device *dev = encoder->dev; | 1611 | * Mac mini hack. On this device, the DVI-I connector shares one DDC |
1548 | struct drm_i915_private *dev_priv = dev->dev_private; | 1612 | * link between analog and digital outputs. So, if the regular SDVO |
1549 | /* Mac mini hack. On this device, I get DDC through the analog, which | 1613 | * DDC fails, check to see if the analog output is disconnected, in |
1550 | * load-detects as disconnected. I fail to DDC through the SDVO DDC, | 1614 | * which case we'll look there for the digital DDC data. |
1551 | * but it does load-detect as connected. So, just steal the DDC bits | ||
1552 | * from analog when we fail at finding it the right way. | ||
1553 | */ | 1615 | */ |
1554 | crt = xf86_config->output[0]; | 1616 | if (num_modes == 0 && |
1555 | intel_output = crt->driver_private; | 1617 | sdvo_priv->analog_ddc_bus && |
1556 | if (intel_output->type == I830_OUTPUT_ANALOG && | 1618 | !intel_analog_is_connected(intel_output->base.dev)) { |
1557 | crt->funcs->detect(crt) == XF86OutputStatusDisconnected) { | 1619 | struct i2c_adapter *digital_ddc_bus; |
1558 | I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A"); | ||
1559 | edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus); | ||
1560 | xf86DestroyI2CBusRec(intel_output->pDDCBus, true, true); | ||
1561 | } | ||
1562 | if (edid_mon) { | ||
1563 | xf86OutputSetEDID(output, edid_mon); | ||
1564 | modes = xf86OutputGetEDIDModes(output); | ||
1565 | } | ||
1566 | #endif | ||
1567 | } | ||
1568 | 1620 | ||
1569 | /** | 1621 | /* Switch to the analog ddc bus and try that |
1570 | * This function checks the current TV format, and chooses a default if | 1622 | */ |
1571 | * it hasn't been set. | 1623 | digital_ddc_bus = intel_output->ddc_bus; |
1572 | */ | 1624 | intel_output->ddc_bus = sdvo_priv->analog_ddc_bus; |
1573 | static void | ||
1574 | intel_sdvo_check_tv_format(struct intel_output *output) | ||
1575 | { | ||
1576 | struct intel_sdvo_priv *dev_priv = output->dev_priv; | ||
1577 | struct intel_sdvo_tv_format format; | ||
1578 | uint8_t status; | ||
1579 | 1625 | ||
1580 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0); | 1626 | (void) intel_ddc_get_modes(intel_output); |
1581 | status = intel_sdvo_read_response(output, &format, sizeof(format)); | ||
1582 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
1583 | return; | ||
1584 | 1627 | ||
1585 | memcpy(&dev_priv->tv_format, &format, sizeof(format)); | 1628 | intel_output->ddc_bus = digital_ddc_bus; |
1629 | } | ||
1586 | } | 1630 | } |
1587 | 1631 | ||
1588 | /* | 1632 | /* |
@@ -1655,17 +1699,26 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1655 | struct intel_output *output = to_intel_output(connector); | 1699 | struct intel_output *output = to_intel_output(connector); |
1656 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 1700 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; |
1657 | struct intel_sdvo_sdtv_resolution_request tv_res; | 1701 | struct intel_sdvo_sdtv_resolution_request tv_res; |
1658 | uint32_t reply = 0; | 1702 | uint32_t reply = 0, format_map = 0; |
1703 | int i; | ||
1659 | uint8_t status; | 1704 | uint8_t status; |
1660 | int i = 0; | ||
1661 | 1705 | ||
1662 | intel_sdvo_check_tv_format(output); | ||
1663 | 1706 | ||
1664 | /* Read the list of supported input resolutions for the selected TV | 1707 | /* Read the list of supported input resolutions for the selected TV |
1665 | * format. | 1708 | * format. |
1666 | */ | 1709 | */ |
1667 | memset(&tv_res, 0, sizeof(tv_res)); | 1710 | for (i = 0; i < TV_FORMAT_NUM; i++) |
1668 | memcpy(&tv_res, &sdvo_priv->tv_format, sizeof(tv_res)); | 1711 | if (tv_format_names[i] == sdvo_priv->tv_format_name) |
1712 | break; | ||
1713 | |||
1714 | format_map = (1 << i); | ||
1715 | memcpy(&tv_res, &format_map, | ||
1716 | sizeof(struct intel_sdvo_sdtv_resolution_request) > | ||
1717 | sizeof(format_map) ? sizeof(format_map) : | ||
1718 | sizeof(struct intel_sdvo_sdtv_resolution_request)); | ||
1719 | |||
1720 | intel_sdvo_set_target_output(output, sdvo_priv->controlled_output); | ||
1721 | |||
1669 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, | 1722 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, |
1670 | &tv_res, sizeof(tv_res)); | 1723 | &tv_res, sizeof(tv_res)); |
1671 | status = intel_sdvo_read_response(output, &reply, 3); | 1724 | status = intel_sdvo_read_response(output, &reply, 3); |
@@ -1680,6 +1733,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1680 | if (nmode) | 1733 | if (nmode) |
1681 | drm_mode_probed_add(connector, nmode); | 1734 | drm_mode_probed_add(connector, nmode); |
1682 | } | 1735 | } |
1736 | |||
1683 | } | 1737 | } |
1684 | 1738 | ||
1685 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | 1739 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
@@ -1747,17 +1801,62 @@ static void intel_sdvo_destroy(struct drm_connector *connector) | |||
1747 | intel_i2c_destroy(intel_output->i2c_bus); | 1801 | intel_i2c_destroy(intel_output->i2c_bus); |
1748 | if (intel_output->ddc_bus) | 1802 | if (intel_output->ddc_bus) |
1749 | intel_i2c_destroy(intel_output->ddc_bus); | 1803 | intel_i2c_destroy(intel_output->ddc_bus); |
1804 | if (sdvo_priv->analog_ddc_bus) | ||
1805 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | ||
1750 | 1806 | ||
1751 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | 1807 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) |
1752 | drm_mode_destroy(connector->dev, | 1808 | drm_mode_destroy(connector->dev, |
1753 | sdvo_priv->sdvo_lvds_fixed_mode); | 1809 | sdvo_priv->sdvo_lvds_fixed_mode); |
1754 | 1810 | ||
1811 | if (sdvo_priv->tv_format_property) | ||
1812 | drm_property_destroy(connector->dev, | ||
1813 | sdvo_priv->tv_format_property); | ||
1814 | |||
1755 | drm_sysfs_connector_remove(connector); | 1815 | drm_sysfs_connector_remove(connector); |
1756 | drm_connector_cleanup(connector); | 1816 | drm_connector_cleanup(connector); |
1757 | 1817 | ||
1758 | kfree(intel_output); | 1818 | kfree(intel_output); |
1759 | } | 1819 | } |
1760 | 1820 | ||
1821 | static int | ||
1822 | intel_sdvo_set_property(struct drm_connector *connector, | ||
1823 | struct drm_property *property, | ||
1824 | uint64_t val) | ||
1825 | { | ||
1826 | struct intel_output *intel_output = to_intel_output(connector); | ||
1827 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1828 | struct drm_encoder *encoder = &intel_output->enc; | ||
1829 | struct drm_crtc *crtc = encoder->crtc; | ||
1830 | int ret = 0; | ||
1831 | bool changed = false; | ||
1832 | |||
1833 | ret = drm_connector_property_set_value(connector, property, val); | ||
1834 | if (ret < 0) | ||
1835 | goto out; | ||
1836 | |||
1837 | if (property == sdvo_priv->tv_format_property) { | ||
1838 | if (val >= TV_FORMAT_NUM) { | ||
1839 | ret = -EINVAL; | ||
1840 | goto out; | ||
1841 | } | ||
1842 | if (sdvo_priv->tv_format_name == | ||
1843 | sdvo_priv->tv_format_supported[val]) | ||
1844 | goto out; | ||
1845 | |||
1846 | sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[val]; | ||
1847 | changed = true; | ||
1848 | } else { | ||
1849 | ret = -EINVAL; | ||
1850 | goto out; | ||
1851 | } | ||
1852 | |||
1853 | if (changed && crtc) | ||
1854 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, | ||
1855 | crtc->y, crtc->fb); | ||
1856 | out: | ||
1857 | return ret; | ||
1858 | } | ||
1859 | |||
1761 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { | 1860 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { |
1762 | .dpms = intel_sdvo_dpms, | 1861 | .dpms = intel_sdvo_dpms, |
1763 | .mode_fixup = intel_sdvo_mode_fixup, | 1862 | .mode_fixup = intel_sdvo_mode_fixup, |
@@ -1772,6 +1871,7 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = { | |||
1772 | .restore = intel_sdvo_restore, | 1871 | .restore = intel_sdvo_restore, |
1773 | .detect = intel_sdvo_detect, | 1872 | .detect = intel_sdvo_detect, |
1774 | .fill_modes = drm_helper_probe_single_connector_modes, | 1873 | .fill_modes = drm_helper_probe_single_connector_modes, |
1874 | .set_property = intel_sdvo_set_property, | ||
1775 | .destroy = intel_sdvo_destroy, | 1875 | .destroy = intel_sdvo_destroy, |
1776 | }; | 1876 | }; |
1777 | 1877 | ||
@@ -1966,6 +2066,9 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
1966 | intel_sdvo_set_colorimetry(intel_output, | 2066 | intel_sdvo_set_colorimetry(intel_output, |
1967 | SDVO_COLORIMETRY_RGB256); | 2067 | SDVO_COLORIMETRY_RGB256); |
1968 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 2068 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
2069 | intel_output->clone_mask = | ||
2070 | (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
2071 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
1969 | } | 2072 | } |
1970 | } else if (flags & SDVO_OUTPUT_SVID0) { | 2073 | } else if (flags & SDVO_OUTPUT_SVID0) { |
1971 | 2074 | ||
@@ -1974,11 +2077,14 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
1974 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | 2077 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; |
1975 | sdvo_priv->is_tv = true; | 2078 | sdvo_priv->is_tv = true; |
1976 | intel_output->needs_tv_clock = true; | 2079 | intel_output->needs_tv_clock = true; |
2080 | intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | ||
1977 | } else if (flags & SDVO_OUTPUT_RGB0) { | 2081 | } else if (flags & SDVO_OUTPUT_RGB0) { |
1978 | 2082 | ||
1979 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; | 2083 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; |
1980 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | 2084 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; |
1981 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | 2085 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; |
2086 | intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
2087 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
1982 | } else if (flags & SDVO_OUTPUT_RGB1) { | 2088 | } else if (flags & SDVO_OUTPUT_RGB1) { |
1983 | 2089 | ||
1984 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; | 2090 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; |
@@ -1990,12 +2096,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
1990 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | 2096 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; |
1991 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | 2097 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; |
1992 | sdvo_priv->is_lvds = true; | 2098 | sdvo_priv->is_lvds = true; |
2099 | intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | ||
2100 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
1993 | } else if (flags & SDVO_OUTPUT_LVDS1) { | 2101 | } else if (flags & SDVO_OUTPUT_LVDS1) { |
1994 | 2102 | ||
1995 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; | 2103 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; |
1996 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | 2104 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; |
1997 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | 2105 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; |
1998 | sdvo_priv->is_lvds = true; | 2106 | sdvo_priv->is_lvds = true; |
2107 | intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | ||
2108 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
1999 | } else { | 2109 | } else { |
2000 | 2110 | ||
2001 | unsigned char bytes[2]; | 2111 | unsigned char bytes[2]; |
@@ -2007,6 +2117,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
2007 | bytes[0], bytes[1]); | 2117 | bytes[0], bytes[1]); |
2008 | ret = false; | 2118 | ret = false; |
2009 | } | 2119 | } |
2120 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
2010 | 2121 | ||
2011 | if (ret && registered) | 2122 | if (ret && registered) |
2012 | ret = drm_sysfs_connector_add(connector) == 0 ? true : false; | 2123 | ret = drm_sysfs_connector_add(connector) == 0 ? true : false; |
@@ -2016,6 +2127,55 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
2016 | 2127 | ||
2017 | } | 2128 | } |
2018 | 2129 | ||
2130 | static void intel_sdvo_tv_create_property(struct drm_connector *connector) | ||
2131 | { | ||
2132 | struct intel_output *intel_output = to_intel_output(connector); | ||
2133 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
2134 | struct intel_sdvo_tv_format format; | ||
2135 | uint32_t format_map, i; | ||
2136 | uint8_t status; | ||
2137 | |||
2138 | intel_sdvo_set_target_output(intel_output, | ||
2139 | sdvo_priv->controlled_output); | ||
2140 | |||
2141 | intel_sdvo_write_cmd(intel_output, | ||
2142 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); | ||
2143 | status = intel_sdvo_read_response(intel_output, | ||
2144 | &format, sizeof(format)); | ||
2145 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
2146 | return; | ||
2147 | |||
2148 | memcpy(&format_map, &format, sizeof(format) > sizeof(format_map) ? | ||
2149 | sizeof(format_map) : sizeof(format)); | ||
2150 | |||
2151 | if (format_map == 0) | ||
2152 | return; | ||
2153 | |||
2154 | sdvo_priv->format_supported_num = 0; | ||
2155 | for (i = 0 ; i < TV_FORMAT_NUM; i++) | ||
2156 | if (format_map & (1 << i)) { | ||
2157 | sdvo_priv->tv_format_supported | ||
2158 | [sdvo_priv->format_supported_num++] = | ||
2159 | tv_format_names[i]; | ||
2160 | } | ||
2161 | |||
2162 | |||
2163 | sdvo_priv->tv_format_property = | ||
2164 | drm_property_create( | ||
2165 | connector->dev, DRM_MODE_PROP_ENUM, | ||
2166 | "mode", sdvo_priv->format_supported_num); | ||
2167 | |||
2168 | for (i = 0; i < sdvo_priv->format_supported_num; i++) | ||
2169 | drm_property_add_enum( | ||
2170 | sdvo_priv->tv_format_property, i, | ||
2171 | i, sdvo_priv->tv_format_supported[i]); | ||
2172 | |||
2173 | sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[0]; | ||
2174 | drm_connector_attach_property( | ||
2175 | connector, sdvo_priv->tv_format_property, 0); | ||
2176 | |||
2177 | } | ||
2178 | |||
2019 | bool intel_sdvo_init(struct drm_device *dev, int output_device) | 2179 | bool intel_sdvo_init(struct drm_device *dev, int output_device) |
2020 | { | 2180 | { |
2021 | struct drm_connector *connector; | 2181 | struct drm_connector *connector; |
@@ -2060,10 +2220,15 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
2060 | } | 2220 | } |
2061 | 2221 | ||
2062 | /* setup the DDC bus. */ | 2222 | /* setup the DDC bus. */ |
2063 | if (output_device == SDVOB) | 2223 | if (output_device == SDVOB) { |
2064 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); | 2224 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); |
2065 | else | 2225 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, |
2226 | "SDVOB/VGA DDC BUS"); | ||
2227 | } else { | ||
2066 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); | 2228 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); |
2229 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, | ||
2230 | "SDVOC/VGA DDC BUS"); | ||
2231 | } | ||
2067 | 2232 | ||
2068 | if (intel_output->ddc_bus == NULL) | 2233 | if (intel_output->ddc_bus == NULL) |
2069 | goto err_i2c; | 2234 | goto err_i2c; |
@@ -2097,6 +2262,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
2097 | drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); | 2262 | drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); |
2098 | 2263 | ||
2099 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 2264 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); |
2265 | if (sdvo_priv->is_tv) | ||
2266 | intel_sdvo_tv_create_property(connector); | ||
2100 | drm_sysfs_connector_add(connector); | 2267 | drm_sysfs_connector_add(connector); |
2101 | 2268 | ||
2102 | intel_sdvo_select_ddc_bus(sdvo_priv); | 2269 | intel_sdvo_select_ddc_bus(sdvo_priv); |
@@ -2129,6 +2296,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
2129 | return true; | 2296 | return true; |
2130 | 2297 | ||
2131 | err_i2c: | 2298 | err_i2c: |
2299 | if (sdvo_priv->analog_ddc_bus != NULL) | ||
2300 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | ||
2132 | if (intel_output->ddc_bus != NULL) | 2301 | if (intel_output->ddc_bus != NULL) |
2133 | intel_i2c_destroy(intel_output->ddc_bus); | 2302 | intel_i2c_destroy(intel_output->ddc_bus); |
2134 | if (intel_output->i2c_bus != NULL) | 2303 | if (intel_output->i2c_bus != NULL) |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index da4ab4dc1630..a6c686cded54 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1437,6 +1437,35 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) | |||
1437 | return type; | 1437 | return type; |
1438 | } | 1438 | } |
1439 | 1439 | ||
1440 | /* | ||
1441 | * Here we set accurate tv format according to connector type | ||
1442 | * i.e Component TV should not be assigned by NTSC or PAL | ||
1443 | */ | ||
1444 | static void intel_tv_find_better_format(struct drm_connector *connector) | ||
1445 | { | ||
1446 | struct intel_output *intel_output = to_intel_output(connector); | ||
1447 | struct intel_tv_priv *tv_priv = intel_output->dev_priv; | ||
1448 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); | ||
1449 | int i; | ||
1450 | |||
1451 | if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == | ||
1452 | tv_mode->component_only) | ||
1453 | return; | ||
1454 | |||
1455 | |||
1456 | for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) { | ||
1457 | tv_mode = tv_modes + i; | ||
1458 | |||
1459 | if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == | ||
1460 | tv_mode->component_only) | ||
1461 | break; | ||
1462 | } | ||
1463 | |||
1464 | tv_priv->tv_format = tv_mode->name; | ||
1465 | drm_connector_property_set_value(connector, | ||
1466 | connector->dev->mode_config.tv_mode_property, i); | ||
1467 | } | ||
1468 | |||
1440 | /** | 1469 | /** |
1441 | * Detect the TV connection. | 1470 | * Detect the TV connection. |
1442 | * | 1471 | * |
@@ -1473,6 +1502,7 @@ intel_tv_detect(struct drm_connector *connector) | |||
1473 | if (type < 0) | 1502 | if (type < 0) |
1474 | return connector_status_disconnected; | 1503 | return connector_status_disconnected; |
1475 | 1504 | ||
1505 | intel_tv_find_better_format(connector); | ||
1476 | return connector_status_connected; | 1506 | return connector_status_connected; |
1477 | } | 1507 | } |
1478 | 1508 | ||
@@ -1718,6 +1748,7 @@ intel_tv_init(struct drm_device *dev) | |||
1718 | if (!intel_output) { | 1748 | if (!intel_output) { |
1719 | return; | 1749 | return; |
1720 | } | 1750 | } |
1751 | |||
1721 | connector = &intel_output->base; | 1752 | connector = &intel_output->base; |
1722 | 1753 | ||
1723 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1754 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
@@ -1729,6 +1760,7 @@ intel_tv_init(struct drm_device *dev) | |||
1729 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 1760 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); |
1730 | tv_priv = (struct intel_tv_priv *)(intel_output + 1); | 1761 | tv_priv = (struct intel_tv_priv *)(intel_output + 1); |
1731 | intel_output->type = INTEL_OUTPUT_TVOUT; | 1762 | intel_output->type = INTEL_OUTPUT_TVOUT; |
1763 | intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT); | ||
1732 | intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); | 1764 | intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); |
1733 | intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); | 1765 | intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); |
1734 | intel_output->dev_priv = tv_priv; | 1766 | intel_output->dev_priv = tv_priv; |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 639d5b216eed..44f34f8e2b32 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -1140,6 +1140,16 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1140 | tmp |= tile_flags; | 1140 | tmp |= tile_flags; |
1141 | ib[idx] = tmp; | 1141 | ib[idx] = tmp; |
1142 | break; | 1142 | break; |
1143 | case RADEON_RB3D_ZPASS_ADDR: | ||
1144 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
1145 | if (r) { | ||
1146 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | ||
1147 | idx, reg); | ||
1148 | r100_cs_dump_packet(p, pkt); | ||
1149 | return r; | ||
1150 | } | ||
1151 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | ||
1152 | break; | ||
1143 | default: | 1153 | default: |
1144 | /* FIXME: we don't want to allow anyothers packet */ | 1154 | /* FIXME: we don't want to allow anyothers packet */ |
1145 | break; | 1155 | break; |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 482d6b296b74..9f2460cf9dbc 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -450,6 +450,7 @@ void r300_gpu_init(struct radeon_device *rdev) | |||
450 | /* rv350,rv370,rv380 */ | 450 | /* rv350,rv370,rv380 */ |
451 | rdev->num_gb_pipes = 1; | 451 | rdev->num_gb_pipes = 1; |
452 | } | 452 | } |
453 | rdev->num_z_pipes = 1; | ||
453 | gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); | 454 | gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); |
454 | switch (rdev->num_gb_pipes) { | 455 | switch (rdev->num_gb_pipes) { |
455 | case 2: | 456 | case 2: |
@@ -488,7 +489,8 @@ void r300_gpu_init(struct radeon_device *rdev) | |||
488 | printk(KERN_WARNING "Failed to wait MC idle while " | 489 | printk(KERN_WARNING "Failed to wait MC idle while " |
489 | "programming pipes. Bad things might happen.\n"); | 490 | "programming pipes. Bad things might happen.\n"); |
490 | } | 491 | } |
491 | DRM_INFO("radeon: %d pipes initialized.\n", rdev->num_gb_pipes); | 492 | DRM_INFO("radeon: %d quad pipes, %d Z pipes initialized.\n", |
493 | rdev->num_gb_pipes, rdev->num_z_pipes); | ||
492 | } | 494 | } |
493 | 495 | ||
494 | int r300_ga_reset(struct radeon_device *rdev) | 496 | int r300_ga_reset(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index dea497a979f2..97426a6f370f 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
@@ -165,7 +165,18 @@ void r420_pipes_init(struct radeon_device *rdev) | |||
165 | printk(KERN_WARNING "Failed to wait GUI idle while " | 165 | printk(KERN_WARNING "Failed to wait GUI idle while " |
166 | "programming pipes. Bad things might happen.\n"); | 166 | "programming pipes. Bad things might happen.\n"); |
167 | } | 167 | } |
168 | DRM_INFO("radeon: %d pipes initialized.\n", rdev->num_gb_pipes); | 168 | |
169 | if (rdev->family == CHIP_RV530) { | ||
170 | tmp = RREG32(RV530_GB_PIPE_SELECT2); | ||
171 | if ((tmp & 3) == 3) | ||
172 | rdev->num_z_pipes = 2; | ||
173 | else | ||
174 | rdev->num_z_pipes = 1; | ||
175 | } else | ||
176 | rdev->num_z_pipes = 1; | ||
177 | |||
178 | DRM_INFO("radeon: %d quad pipes, %d z pipes initialized.\n", | ||
179 | rdev->num_gb_pipes, rdev->num_z_pipes); | ||
169 | } | 180 | } |
170 | 181 | ||
171 | void r420_gpu_init(struct radeon_device *rdev) | 182 | void r420_gpu_init(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 09fb0b6ec7dd..ebd6b0f7bdff 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c | |||
@@ -177,7 +177,6 @@ void r520_gpu_init(struct radeon_device *rdev) | |||
177 | */ | 177 | */ |
178 | /* workaround for RV530 */ | 178 | /* workaround for RV530 */ |
179 | if (rdev->family == CHIP_RV530) { | 179 | if (rdev->family == CHIP_RV530) { |
180 | WREG32(0x4124, 1); | ||
181 | WREG32(0x4128, 0xFF); | 180 | WREG32(0x4128, 0xFF); |
182 | } | 181 | } |
183 | r420_pipes_init(rdev); | 182 | r420_pipes_init(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 1041a7c28051..149974d13aa2 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -655,6 +655,7 @@ struct radeon_device { | |||
655 | int usec_timeout; | 655 | int usec_timeout; |
656 | enum radeon_pll_errata pll_errata; | 656 | enum radeon_pll_errata pll_errata; |
657 | int num_gb_pipes; | 657 | int num_gb_pipes; |
658 | int num_z_pipes; | ||
658 | int disp_priority; | 659 | int disp_priority; |
659 | /* BIOS */ | 660 | /* BIOS */ |
660 | uint8_t *bios; | 661 | uint8_t *bios; |
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 6b6cc8434d3c..fa063d0cfb63 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -421,6 +421,15 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv) | |||
421 | { | 421 | { |
422 | uint32_t gb_tile_config, gb_pipe_sel = 0; | 422 | uint32_t gb_tile_config, gb_pipe_sel = 0; |
423 | 423 | ||
424 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) { | ||
425 | uint32_t z_pipe_sel = RADEON_READ(RV530_GB_PIPE_SELECT2); | ||
426 | if ((z_pipe_sel & 3) == 3) | ||
427 | dev_priv->num_z_pipes = 2; | ||
428 | else | ||
429 | dev_priv->num_z_pipes = 1; | ||
430 | } else | ||
431 | dev_priv->num_z_pipes = 1; | ||
432 | |||
424 | /* RS4xx/RS6xx/R4xx/R5xx */ | 433 | /* RS4xx/RS6xx/R4xx/R5xx */ |
425 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) { | 434 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) { |
426 | gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT); | 435 | gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 45a6ad997f5f..40294a07976f 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
@@ -103,9 +103,10 @@ | |||
103 | * 1.28- Add support for VBL on CRTC2 | 103 | * 1.28- Add support for VBL on CRTC2 |
104 | * 1.29- R500 3D cmd buffer support | 104 | * 1.29- R500 3D cmd buffer support |
105 | * 1.30- Add support for occlusion queries | 105 | * 1.30- Add support for occlusion queries |
106 | * 1.31- Add support for num Z pipes from GET_PARAM | ||
106 | */ | 107 | */ |
107 | #define DRIVER_MAJOR 1 | 108 | #define DRIVER_MAJOR 1 |
108 | #define DRIVER_MINOR 30 | 109 | #define DRIVER_MINOR 31 |
109 | #define DRIVER_PATCHLEVEL 0 | 110 | #define DRIVER_PATCHLEVEL 0 |
110 | 111 | ||
111 | /* | 112 | /* |
@@ -332,6 +333,7 @@ typedef struct drm_radeon_private { | |||
332 | resource_size_t fb_aper_offset; | 333 | resource_size_t fb_aper_offset; |
333 | 334 | ||
334 | int num_gb_pipes; | 335 | int num_gb_pipes; |
336 | int num_z_pipes; | ||
335 | int track_flush; | 337 | int track_flush; |
336 | drm_local_map_t *mmio; | 338 | drm_local_map_t *mmio; |
337 | 339 | ||
@@ -694,6 +696,7 @@ extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pciga | |||
694 | 696 | ||
695 | /* pipe config regs */ | 697 | /* pipe config regs */ |
696 | #define R400_GB_PIPE_SELECT 0x402c | 698 | #define R400_GB_PIPE_SELECT 0x402c |
699 | #define RV530_GB_PIPE_SELECT2 0x4124 | ||
697 | #define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */ | 700 | #define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */ |
698 | #define R300_GB_TILE_CONFIG 0x4018 | 701 | #define R300_GB_TILE_CONFIG 0x4018 |
699 | # define R300_ENABLE_TILING (1 << 0) | 702 | # define R300_ENABLE_TILING (1 << 0) |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index d4ceff13bbb1..d880edf254db 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -274,16 +274,22 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
274 | } | 274 | } |
275 | robj = gobj->driver_private; | 275 | robj = gobj->driver_private; |
276 | r = radeon_object_busy_domain(robj, &cur_placement); | 276 | r = radeon_object_busy_domain(robj, &cur_placement); |
277 | if (cur_placement == TTM_PL_VRAM) | 277 | switch (cur_placement) { |
278 | case TTM_PL_VRAM: | ||
278 | args->domain = RADEON_GEM_DOMAIN_VRAM; | 279 | args->domain = RADEON_GEM_DOMAIN_VRAM; |
279 | if (cur_placement == TTM_PL_FLAG_TT) | 280 | break; |
281 | case TTM_PL_TT: | ||
280 | args->domain = RADEON_GEM_DOMAIN_GTT; | 282 | args->domain = RADEON_GEM_DOMAIN_GTT; |
281 | if (cur_placement == TTM_PL_FLAG_SYSTEM) | 283 | break; |
284 | case TTM_PL_SYSTEM: | ||
282 | args->domain = RADEON_GEM_DOMAIN_CPU; | 285 | args->domain = RADEON_GEM_DOMAIN_CPU; |
286 | default: | ||
287 | break; | ||
288 | } | ||
283 | mutex_lock(&dev->struct_mutex); | 289 | mutex_lock(&dev->struct_mutex); |
284 | drm_gem_object_unreference(gobj); | 290 | drm_gem_object_unreference(gobj); |
285 | mutex_unlock(&dev->struct_mutex); | 291 | mutex_unlock(&dev->struct_mutex); |
286 | return 0; | 292 | return r; |
287 | } | 293 | } |
288 | 294 | ||
289 | int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, | 295 | int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index d2764bf6b2a2..dce09ada32bc 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -95,6 +95,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
95 | case RADEON_INFO_NUM_GB_PIPES: | 95 | case RADEON_INFO_NUM_GB_PIPES: |
96 | value = rdev->num_gb_pipes; | 96 | value = rdev->num_gb_pipes; |
97 | break; | 97 | break; |
98 | case RADEON_INFO_NUM_Z_PIPES: | ||
99 | value = rdev->num_z_pipes; | ||
100 | break; | ||
98 | default: | 101 | default: |
99 | DRM_DEBUG("Invalid request %d\n", info->request); | 102 | DRM_DEBUG("Invalid request %d\n", info->request); |
100 | return -EINVAL; | 103 | return -EINVAL; |
@@ -318,5 +321,6 @@ struct drm_ioctl_desc radeon_ioctls_kms[] = { | |||
318 | DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH), | 321 | DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH), |
319 | DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH), | 322 | DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH), |
320 | DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH), | 323 | DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH), |
324 | DRM_IOCTL_DEF(DRM_RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH), | ||
321 | }; | 325 | }; |
322 | int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); | 326 | int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index 5a098f304edb..4df43f62c678 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
@@ -2337,6 +2337,9 @@ | |||
2337 | # define RADEON_RE_WIDTH_SHIFT 0 | 2337 | # define RADEON_RE_WIDTH_SHIFT 0 |
2338 | # define RADEON_RE_HEIGHT_SHIFT 16 | 2338 | # define RADEON_RE_HEIGHT_SHIFT 16 |
2339 | 2339 | ||
2340 | #define RADEON_RB3D_ZPASS_DATA 0x3290 | ||
2341 | #define RADEON_RB3D_ZPASS_ADDR 0x3294 | ||
2342 | |||
2340 | #define RADEON_SE_CNTL 0x1c4c | 2343 | #define RADEON_SE_CNTL 0x1c4c |
2341 | # define RADEON_FFACE_CULL_CW (0 << 0) | 2344 | # define RADEON_FFACE_CULL_CW (0 << 0) |
2342 | # define RADEON_FFACE_CULL_CCW (1 << 0) | 2345 | # define RADEON_FFACE_CULL_CCW (1 << 0) |
@@ -3571,4 +3574,6 @@ | |||
3571 | #define RADEON_SCRATCH_REG4 0x15f0 | 3574 | #define RADEON_SCRATCH_REG4 0x15f0 |
3572 | #define RADEON_SCRATCH_REG5 0x15f4 | 3575 | #define RADEON_SCRATCH_REG5 0x15f4 |
3573 | 3576 | ||
3577 | #define RV530_GB_PIPE_SELECT2 0x4124 | ||
3578 | |||
3574 | #endif | 3579 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 46645f3e0328..2882f40d5ec5 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -3081,6 +3081,9 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil | |||
3081 | case RADEON_PARAM_NUM_GB_PIPES: | 3081 | case RADEON_PARAM_NUM_GB_PIPES: |
3082 | value = dev_priv->num_gb_pipes; | 3082 | value = dev_priv->num_gb_pipes; |
3083 | break; | 3083 | break; |
3084 | case RADEON_PARAM_NUM_Z_PIPES: | ||
3085 | value = dev_priv->num_z_pipes; | ||
3086 | break; | ||
3084 | default: | 3087 | default: |
3085 | DRM_DEBUG("Invalid parameter %d\n", param->param); | 3088 | DRM_DEBUG("Invalid parameter %d\n", param->param); |
3086 | return -EINVAL; | 3089 | return -EINVAL; |