summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@openedhand.com>2008-10-09 17:00:45 +0000
committerSamuel Ortiz <sameo@openedhand.com>2008-10-09 17:00:45 +0000
commitd89d52d3ec86cf95dd93bb78c9b0ab537200e180 (patch)
treeac2667cd2ffa466be3f333c032045b9e3a8805d2 /meta
parent3d40acdf3e5e6d7da75862fa309b58f0d555141a (diff)
downloadpoky-d89d52d3ec86cf95dd93bb78c9b0ab537200e180.tar.gz
linux-moblin: 2.6.27-rc6 kernel
That includes the fastboot patches. An eee boots in 10s with that kernel. git-svn-id: https://svn.o-hand.com/repos/poky/trunk@5470 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'meta')
-rw-r--r--meta/packages/linux/linux-dummy.bb2
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0001-drm-remove-define-for-non-linux-systems.patch48
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0002-i915-remove-settable-use_mi_batchbuffer_start.patch60
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0003-i915-Ignore-X-server-provided-mmio-address.patch41
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0004-i915-Use-more-consistent-names-for-regs-and-store.patch2746
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch424
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch46
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0007-i915-Initialize-hardware-status-page-at-device-load.patch137
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0008-Add-Intel-ACPI-IGD-OpRegion-support.patch572
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0009-drm-fix-sysfs-error-path.patch23
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0010-i915-separate-suspend-resume-functions.patch1079
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0011-drm-vblank-rework.patch1534
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0012-Export-shmem_file_setup-for-DRM-GEM.patch25
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch24
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch5483
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0015-i915-Add-chip-set-ID-param.patch35
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch205
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0017-i915-Make-use-of-sarea_priv-conditional.patch147
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch44
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch32
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch23
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch23
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch58
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0023-drm-clean-up-many-sparse-warnings-in-i915.patch192
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0024-fastboot-create-a-asynchronous-initlevel.patch136
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch62
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch54
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch40
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0028-fastboot-sync-the-async-execution-before-late_initc.patch95
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0029-fastboot-make-fastboot-a-config-option.patch56
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch67
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch41
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0032-fastboot-remove-wait-for-all-devices-before-mounti.patch44
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch32
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0034-fastboot-fix-typo-in-init-Kconfig-text.patch29
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0035-fastboot-remove-duplicate-unpack_to_rootfs.patch161
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0036-warning-fix-init-do_mounts_md-c.patch82
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0037-init-initramfs.c-unused-function-when-compiling-wit.patch37
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch38
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0039-Add-a-script-to-visualize-the-kernel-boot-process.patch183
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch91
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0041-r8169-8101e.patch940
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/0042-intelfb-945gme.patch153
-rw-r--r--meta/packages/linux/linux-moblin-2.6.27-rc6/defconfig-eee9012407
-rw-r--r--meta/packages/linux/linux-moblin.inc2
-rw-r--r--meta/packages/linux/linux-moblin_2.6.27-rc1.bb2
-rw-r--r--meta/packages/linux/linux-moblin_2.6.27-rc6.bb54
47 files changed, 17805 insertions, 4 deletions
diff --git a/meta/packages/linux/linux-dummy.bb b/meta/packages/linux/linux-dummy.bb
index a3e3af4c66..8d0686a2d2 100644
--- a/meta/packages/linux/linux-dummy.bb
+++ b/meta/packages/linux/linux-dummy.bb
@@ -9,7 +9,7 @@ PACKAGES_DYNAMIC += "kernel-image-*"
9 9
10#COMPATIBLE_MACHINE = "your_machine" 10#COMPATIBLE_MACHINE = "your_machine"
11 11
12PR = "r0" 12PR = "r1"
13 13
14SRC_URI = "" 14SRC_URI = ""
15 15
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0001-drm-remove-define-for-non-linux-systems.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0001-drm-remove-define-for-non-linux-systems.patch
new file mode 100644
index 0000000000..588c1af70b
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0001-drm-remove-define-for-non-linux-systems.patch
@@ -0,0 +1,48 @@
1commit 2e6ec7cdc09f36be1cbe9aeaccfc45f307fc0060
2Author: Carlos R. Mafra <crmafra2@gmail.com>
3Date: Wed Jul 30 12:29:37 2008 -0700
4
5 drm: remove #define's for non-linux systems
6
7 There is no point in considering FreeBSD et al. in the linux kernel
8 source code.
9
10 Signed-off-by: Carlos R. Mafra <crmafra@gmail.com>
11 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
12 Signed-off-by: Dave Airlie <airlied@redhat.com>
13
14diff --git a/include/drm/drm.h b/include/drm/drm.h
15index 38d3c6b..0864c69 100644
16--- a/include/drm/drm.h
17+++ b/include/drm/drm.h
18@@ -36,7 +36,6 @@
19 #ifndef _DRM_H_
20 #define _DRM_H_
21
22-#if defined(__linux__)
23 #if defined(__KERNEL__)
24 #endif
25 #include <asm/ioctl.h> /* For _IO* macros */
26@@ -46,22 +45,6 @@
27 #define DRM_IOC_WRITE _IOC_WRITE
28 #define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE
29 #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
30-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
31-#if defined(__FreeBSD__) && defined(IN_MODULE)
32-/* Prevent name collision when including sys/ioccom.h */
33-#undef ioctl
34-#include <sys/ioccom.h>
35-#define ioctl(a,b,c) xf86ioctl(a,b,c)
36-#else
37-#include <sys/ioccom.h>
38-#endif /* __FreeBSD__ && xf86ioctl */
39-#define DRM_IOCTL_NR(n) ((n) & 0xff)
40-#define DRM_IOC_VOID IOC_VOID
41-#define DRM_IOC_READ IOC_OUT
42-#define DRM_IOC_WRITE IOC_IN
43-#define DRM_IOC_READWRITE IOC_INOUT
44-#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
45-#endif
46
47 #define DRM_MAJOR 226
48 #define DRM_MAX_MINOR 15
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0002-i915-remove-settable-use_mi_batchbuffer_start.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0002-i915-remove-settable-use_mi_batchbuffer_start.patch
new file mode 100644
index 0000000000..f3c41f7cbd
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0002-i915-remove-settable-use_mi_batchbuffer_start.patch
@@ -0,0 +1,60 @@
1commit 91019197abbfde388d0b71b0fc8979a936c23fe3
2Author: Keith Packard <keithp@keithp.com>
3Date: Wed Jul 30 12:28:47 2008 -0700
4
5 i915: remove settable use_mi_batchbuffer_start
6
7 The driver can know what hardware requires MI_BATCH_BUFFER vs
8 MI_BATCH_BUFFER_START; there's no reason to let user mode configure this.
9
10 Signed-off-by: Eric Anholt <eric@anholt.net>
11 Signed-off-by: Dave Airlie <airlied@redhat.com>
12
13diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
14index 8897434..24adbde 100644
15--- a/drivers/gpu/drm/i915/i915_dma.c
16+++ b/drivers/gpu/drm/i915/i915_dma.c
17@@ -159,13 +159,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
18 dev_priv->current_page = 0;
19 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
20
21- /* We are using separate values as placeholders for mechanisms for
22- * private backbuffer/depthbuffer usage.
23- */
24- dev_priv->use_mi_batchbuffer_start = 0;
25- if (IS_I965G(dev)) /* 965 doesn't support older method */
26- dev_priv->use_mi_batchbuffer_start = 1;
27-
28 /* Allow hardware batchbuffers unless told otherwise.
29 */
30 dev_priv->allow_batchbuffer = 1;
31@@ -486,7 +479,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
32 return ret;
33 }
34
35- if (dev_priv->use_mi_batchbuffer_start) {
36+ if (!IS_I830(dev) && !IS_845G(dev)) {
37 BEGIN_LP_RING(2);
38 if (IS_I965G(dev)) {
39 OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
40@@ -697,8 +690,6 @@ static int i915_setparam(struct drm_device *dev, void *data,
41
42 switch (param->param) {
43 case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
44- if (!IS_I965G(dev))
45- dev_priv->use_mi_batchbuffer_start = param->value;
46 break;
47 case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
48 dev_priv->tex_lru_log_granularity = param->value;
49diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
50index d7326d9..2d441d3 100644
51--- a/drivers/gpu/drm/i915/i915_drv.h
52+++ b/drivers/gpu/drm/i915/i915_drv.h
53@@ -99,7 +99,6 @@ typedef struct drm_i915_private {
54 int front_offset;
55 int current_page;
56 int page_flipping;
57- int use_mi_batchbuffer_start;
58
59 wait_queue_head_t irq_queue;
60 atomic_t irq_received;
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0003-i915-Ignore-X-server-provided-mmio-address.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0003-i915-Ignore-X-server-provided-mmio-address.patch
new file mode 100644
index 0000000000..9f7e0b4bcd
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0003-i915-Ignore-X-server-provided-mmio-address.patch
@@ -0,0 +1,41 @@
1commit 20ae3cf7d4a9ae8d23bcffa67c9a34fc2640d217
2Author: Keith Packard <keithp@keithp.com>
3Date: Wed Jul 30 12:36:08 2008 -0700
4
5 i915: Ignore X server provided mmio address
6
7 It is already correctly detected by the kernel for use in suspend/resume.
8
9 Signed-off-by: Eric Anholt <eric@anholt.net>
10 Signed-off-by: Dave Airlie <airlied@redhat.com>
11
12diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
13index 24adbde..01a869b 100644
14--- a/drivers/gpu/drm/i915/i915_dma.c
15+++ b/drivers/gpu/drm/i915/i915_dma.c
16@@ -121,13 +121,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
17 return -EINVAL;
18 }
19
20- dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
21- if (!dev_priv->mmio_map) {
22- i915_dma_cleanup(dev);
23- DRM_ERROR("can not find mmio map!\n");
24- return -EINVAL;
25- }
26-
27 dev_priv->sarea_priv = (drm_i915_sarea_t *)
28 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
29
30@@ -194,11 +187,6 @@ static int i915_dma_resume(struct drm_device * dev)
31 return -EINVAL;
32 }
33
34- if (!dev_priv->mmio_map) {
35- DRM_ERROR("can not find mmio map!\n");
36- return -EINVAL;
37- }
38-
39 if (dev_priv->ring.map.handle == NULL) {
40 DRM_ERROR("can not ioremap virtual address for"
41 " ring buffer\n");
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0004-i915-Use-more-consistent-names-for-regs-and-store.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0004-i915-Use-more-consistent-names-for-regs-and-store.patch
new file mode 100644
index 0000000000..f7a310ea60
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0004-i915-Use-more-consistent-names-for-regs-and-store.patch
@@ -0,0 +1,2746 @@
1commit 573e91575687018b4307f53a50f4da0084dbdf3d
2Author: Jesse Barnes <jbarnes@virtuousgeek.org>
3Date: Tue Jul 29 11:54:06 2008 -0700
4
5 i915: Use more consistent names for regs, and store them in a separate file.
6
7 Signed-off-by: Eric Anholt <eric@anholt.net>
8 Signed-off-by: Dave Airlie <airlied@redhat.com>
9
10diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
11index 01a869b..7be580b 100644
12--- a/drivers/gpu/drm/i915/i915_dma.c
13+++ b/drivers/gpu/drm/i915/i915_dma.c
14@@ -40,11 +40,11 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
15 {
16 drm_i915_private_t *dev_priv = dev->dev_private;
17 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
18- u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
19+ u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
20 int i;
21
22 for (i = 0; i < 10000; i++) {
23- ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
24+ ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
25 ring->space = ring->head - (ring->tail + 8);
26 if (ring->space < 0)
27 ring->space += ring->Size;
28@@ -67,8 +67,8 @@ void i915_kernel_lost_context(struct drm_device * dev)
29 drm_i915_private_t *dev_priv = dev->dev_private;
30 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
31
32- ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
33- ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
34+ ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
35+ ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
36 ring->space = ring->head - (ring->tail + 8);
37 if (ring->space < 0)
38 ring->space += ring->Size;
39@@ -98,13 +98,13 @@ static int i915_dma_cleanup(struct drm_device * dev)
40 drm_pci_free(dev, dev_priv->status_page_dmah);
41 dev_priv->status_page_dmah = NULL;
42 /* Need to rewrite hardware status page */
43- I915_WRITE(0x02080, 0x1ffff000);
44+ I915_WRITE(HWS_PGA, 0x1ffff000);
45 }
46
47 if (dev_priv->status_gfx_addr) {
48 dev_priv->status_gfx_addr = 0;
49 drm_core_ioremapfree(&dev_priv->hws_map, dev);
50- I915_WRITE(0x2080, 0x1ffff000);
51+ I915_WRITE(HWS_PGA, 0x1ffff000);
52 }
53
54 return 0;
55@@ -170,7 +170,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
56 dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
57
58 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
59- I915_WRITE(0x02080, dev_priv->dma_status_page);
60+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
61 }
62 DRM_DEBUG("Enabled hardware status page\n");
63 return 0;
64@@ -201,9 +201,9 @@ static int i915_dma_resume(struct drm_device * dev)
65 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
66
67 if (dev_priv->status_gfx_addr != 0)
68- I915_WRITE(0x02080, dev_priv->status_gfx_addr);
69+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
70 else
71- I915_WRITE(0x02080, dev_priv->dma_status_page);
72+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
73 DRM_DEBUG("Enabled hardware status page\n");
74
75 return 0;
76@@ -402,8 +402,8 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
77 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
78
79 BEGIN_LP_RING(4);
80- OUT_RING(CMD_STORE_DWORD_IDX);
81- OUT_RING(20);
82+ OUT_RING(MI_STORE_DWORD_INDEX);
83+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
84 OUT_RING(dev_priv->counter);
85 OUT_RING(0);
86 ADVANCE_LP_RING();
87@@ -505,7 +505,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
88 i915_kernel_lost_context(dev);
89
90 BEGIN_LP_RING(2);
91- OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
92+ OUT_RING(MI_FLUSH | MI_READ_FLUSH);
93 OUT_RING(0);
94 ADVANCE_LP_RING();
95
96@@ -530,8 +530,8 @@ static int i915_dispatch_flip(struct drm_device * dev)
97 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++;
98
99 BEGIN_LP_RING(4);
100- OUT_RING(CMD_STORE_DWORD_IDX);
101- OUT_RING(20);
102+ OUT_RING(MI_STORE_DWORD_INDEX);
103+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
104 OUT_RING(dev_priv->counter);
105 OUT_RING(0);
106 ADVANCE_LP_RING();
107@@ -728,8 +728,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
108 dev_priv->hw_status_page = dev_priv->hws_map.handle;
109
110 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
111- I915_WRITE(0x02080, dev_priv->status_gfx_addr);
112- DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n",
113+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
114+ DRM_DEBUG("load hws HWS_PGA with gfx mem 0x%x\n",
115 dev_priv->status_gfx_addr);
116 DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
117 return 0;
118diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
119index 93aed1c..6c99aab 100644
120--- a/drivers/gpu/drm/i915/i915_drv.c
121+++ b/drivers/gpu/drm/i915/i915_drv.c
122@@ -279,13 +279,13 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
123 dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
124 dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
125 dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
126- dev_priv->saveDSPABASE = I915_READ(DSPABASE);
127+ dev_priv->saveDSPAADDR = I915_READ(DSPAADDR);
128 if (IS_I965G(dev)) {
129 dev_priv->saveDSPASURF = I915_READ(DSPASURF);
130 dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
131 }
132 i915_save_palette(dev, PIPE_A);
133- dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT);
134+ dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT);
135
136 /* Pipe & plane B info */
137 dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
138@@ -307,13 +307,13 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
139 dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
140 dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
141 dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
142- dev_priv->saveDSPBBASE = I915_READ(DSPBBASE);
143+ dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
144 if (IS_I965GM(dev) || IS_IGD_GM(dev)) {
145 dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
146 dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
147 }
148 i915_save_palette(dev, PIPE_B);
149- dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT);
150+ dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
151
152 /* CRT state */
153 dev_priv->saveADPA = I915_READ(ADPA);
154@@ -328,9 +328,9 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
155 dev_priv->saveLVDS = I915_READ(LVDS);
156 if (!IS_I830(dev) && !IS_845G(dev))
157 dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
158- dev_priv->saveLVDSPP_ON = I915_READ(LVDSPP_ON);
159- dev_priv->saveLVDSPP_OFF = I915_READ(LVDSPP_OFF);
160- dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE);
161+ dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
162+ dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
163+ dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
164
165 /* FIXME: save TV & SDVO state */
166
167@@ -341,19 +341,19 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
168 dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
169
170 /* Interrupt state */
171- dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R);
172- dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R);
173- dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R);
174+ dev_priv->saveIIR = I915_READ(IIR);
175+ dev_priv->saveIER = I915_READ(IER);
176+ dev_priv->saveIMR = I915_READ(IMR);
177
178 /* VGA state */
179- dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0);
180- dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1);
181- dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV);
182+ dev_priv->saveVGA0 = I915_READ(VGA0);
183+ dev_priv->saveVGA1 = I915_READ(VGA1);
184+ dev_priv->saveVGA_PD = I915_READ(VGA_PD);
185 dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
186
187 /* Clock gating state */
188 dev_priv->saveD_STATE = I915_READ(D_STATE);
189- dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
190+ dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
191
192 /* Cache mode state */
193 dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
194@@ -363,7 +363,7 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
195
196 /* Scratch space */
197 for (i = 0; i < 16; i++) {
198- dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2));
199+ dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2));
200 dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
201 }
202 for (i = 0; i < 3; i++)
203@@ -424,7 +424,7 @@ static int i915_resume(struct drm_device *dev)
204 I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
205 I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
206 I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
207- I915_WRITE(DSPABASE, dev_priv->saveDSPABASE);
208+ I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR);
209 I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
210 if (IS_I965G(dev)) {
211 I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
212@@ -436,7 +436,7 @@ static int i915_resume(struct drm_device *dev)
213 i915_restore_palette(dev, PIPE_A);
214 /* Enable the plane */
215 I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
216- I915_WRITE(DSPABASE, I915_READ(DSPABASE));
217+ I915_WRITE(DSPAADDR, I915_READ(DSPAADDR));
218
219 /* Pipe & plane B info */
220 if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
221@@ -466,7 +466,7 @@ static int i915_resume(struct drm_device *dev)
222 I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
223 I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
224 I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
225- I915_WRITE(DSPBBASE, dev_priv->saveDSPBBASE);
226+ I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR);
227 I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
228 if (IS_I965G(dev)) {
229 I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
230@@ -478,7 +478,7 @@ static int i915_resume(struct drm_device *dev)
231 i915_restore_palette(dev, PIPE_B);
232 /* Enable the plane */
233 I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
234- I915_WRITE(DSPBBASE, I915_READ(DSPBBASE));
235+ I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
236
237 /* CRT state */
238 I915_WRITE(ADPA, dev_priv->saveADPA);
239@@ -493,9 +493,9 @@ static int i915_resume(struct drm_device *dev)
240
241 I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
242 I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
243- I915_WRITE(LVDSPP_ON, dev_priv->saveLVDSPP_ON);
244- I915_WRITE(LVDSPP_OFF, dev_priv->saveLVDSPP_OFF);
245- I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE);
246+ I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
247+ I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
248+ I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
249 I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
250
251 /* FIXME: restore TV & SDVO state */
252@@ -508,14 +508,14 @@ static int i915_resume(struct drm_device *dev)
253
254 /* VGA state */
255 I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
256- I915_WRITE(VCLK_DIVISOR_VGA0, dev_priv->saveVCLK_DIVISOR_VGA0);
257- I915_WRITE(VCLK_DIVISOR_VGA1, dev_priv->saveVCLK_DIVISOR_VGA1);
258- I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV);
259+ I915_WRITE(VGA0, dev_priv->saveVGA0);
260+ I915_WRITE(VGA1, dev_priv->saveVGA1);
261+ I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
262 udelay(150);
263
264 /* Clock gating state */
265 I915_WRITE (D_STATE, dev_priv->saveD_STATE);
266- I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
267+ I915_WRITE(CG_2D_DIS, dev_priv->saveCG_2D_DIS);
268
269 /* Cache mode state */
270 I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
271@@ -524,7 +524,7 @@ static int i915_resume(struct drm_device *dev)
272 I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
273
274 for (i = 0; i < 16; i++) {
275- I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]);
276+ I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
277 I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
278 }
279 for (i = 0; i < 3; i++)
280diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
281index 2d441d3..afb51a3 100644
282--- a/drivers/gpu/drm/i915/i915_drv.h
283+++ b/drivers/gpu/drm/i915/i915_drv.h
284@@ -30,6 +30,8 @@
285 #ifndef _I915_DRV_H_
286 #define _I915_DRV_H_
287
288+#include "i915_reg.h"
289+
290 /* General customization:
291 */
292
293@@ -138,7 +140,7 @@ typedef struct drm_i915_private {
294 u32 saveDSPASTRIDE;
295 u32 saveDSPASIZE;
296 u32 saveDSPAPOS;
297- u32 saveDSPABASE;
298+ u32 saveDSPAADDR;
299 u32 saveDSPASURF;
300 u32 saveDSPATILEOFF;
301 u32 savePFIT_PGM_RATIOS;
302@@ -159,24 +161,24 @@ typedef struct drm_i915_private {
303 u32 saveDSPBSTRIDE;
304 u32 saveDSPBSIZE;
305 u32 saveDSPBPOS;
306- u32 saveDSPBBASE;
307+ u32 saveDSPBADDR;
308 u32 saveDSPBSURF;
309 u32 saveDSPBTILEOFF;
310- u32 saveVCLK_DIVISOR_VGA0;
311- u32 saveVCLK_DIVISOR_VGA1;
312- u32 saveVCLK_POST_DIV;
313+ u32 saveVGA0;
314+ u32 saveVGA1;
315+ u32 saveVGA_PD;
316 u32 saveVGACNTRL;
317 u32 saveADPA;
318 u32 saveLVDS;
319- u32 saveLVDSPP_ON;
320- u32 saveLVDSPP_OFF;
321+ u32 savePP_ON_DELAYS;
322+ u32 savePP_OFF_DELAYS;
323 u32 saveDVOA;
324 u32 saveDVOB;
325 u32 saveDVOC;
326 u32 savePP_ON;
327 u32 savePP_OFF;
328 u32 savePP_CONTROL;
329- u32 savePP_CYCLE;
330+ u32 savePP_DIVISOR;
331 u32 savePFIT_CONTROL;
332 u32 save_palette_a[256];
333 u32 save_palette_b[256];
334@@ -189,7 +191,7 @@ typedef struct drm_i915_private {
335 u32 saveIMR;
336 u32 saveCACHE_MODE_0;
337 u32 saveD_STATE;
338- u32 saveDSPCLK_GATE_D;
339+ u32 saveCG_2D_DIS;
340 u32 saveMI_ARB_STATE;
341 u32 saveSWF0[16];
342 u32 saveSWF1[16];
343@@ -283,816 +285,26 @@ extern void i915_mem_release(struct drm_device * dev,
344 if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \
345 dev_priv->ring.tail = outring; \
346 dev_priv->ring.space -= outcount * 4; \
347- I915_WRITE(LP_RING + RING_TAIL, outring); \
348+ I915_WRITE(PRB0_TAIL, outring); \
349 } while(0)
350
351-extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
352-
353-/* Extended config space */
354-#define LBB 0xf4
355-
356-/* VGA stuff */
357-
358-#define VGA_ST01_MDA 0x3ba
359-#define VGA_ST01_CGA 0x3da
360-
361-#define VGA_MSR_WRITE 0x3c2
362-#define VGA_MSR_READ 0x3cc
363-#define VGA_MSR_MEM_EN (1<<1)
364-#define VGA_MSR_CGA_MODE (1<<0)
365-
366-#define VGA_SR_INDEX 0x3c4
367-#define VGA_SR_DATA 0x3c5
368-
369-#define VGA_AR_INDEX 0x3c0
370-#define VGA_AR_VID_EN (1<<5)
371-#define VGA_AR_DATA_WRITE 0x3c0
372-#define VGA_AR_DATA_READ 0x3c1
373-
374-#define VGA_GR_INDEX 0x3ce
375-#define VGA_GR_DATA 0x3cf
376-/* GR05 */
377-#define VGA_GR_MEM_READ_MODE_SHIFT 3
378-#define VGA_GR_MEM_READ_MODE_PLANE 1
379-/* GR06 */
380-#define VGA_GR_MEM_MODE_MASK 0xc
381-#define VGA_GR_MEM_MODE_SHIFT 2
382-#define VGA_GR_MEM_A0000_AFFFF 0
383-#define VGA_GR_MEM_A0000_BFFFF 1
384-#define VGA_GR_MEM_B0000_B7FFF 2
385-#define VGA_GR_MEM_B0000_BFFFF 3
386-
387-#define VGA_DACMASK 0x3c6
388-#define VGA_DACRX 0x3c7
389-#define VGA_DACWX 0x3c8
390-#define VGA_DACDATA 0x3c9
391-
392-#define VGA_CR_INDEX_MDA 0x3b4
393-#define VGA_CR_DATA_MDA 0x3b5
394-#define VGA_CR_INDEX_CGA 0x3d4
395-#define VGA_CR_DATA_CGA 0x3d5
396-
397-#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
398-#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
399-#define CMD_REPORT_HEAD (7<<23)
400-#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
401-#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
402-
403-#define INST_PARSER_CLIENT 0x00000000
404-#define INST_OP_FLUSH 0x02000000
405-#define INST_FLUSH_MAP_CACHE 0x00000001
406-
407-#define BB1_START_ADDR_MASK (~0x7)
408-#define BB1_PROTECTED (1<<0)
409-#define BB1_UNPROTECTED (0<<0)
410-#define BB2_END_ADDR_MASK (~0x7)
411-
412-/* Framebuffer compression */
413-#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
414-#define FBC_LL_BASE 0x03204 /* 4k page aligned */
415-#define FBC_CONTROL 0x03208
416-#define FBC_CTL_EN (1<<31)
417-#define FBC_CTL_PERIODIC (1<<30)
418-#define FBC_CTL_INTERVAL_SHIFT (16)
419-#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
420-#define FBC_CTL_STRIDE_SHIFT (5)
421-#define FBC_CTL_FENCENO (1<<0)
422-#define FBC_COMMAND 0x0320c
423-#define FBC_CMD_COMPRESS (1<<0)
424-#define FBC_STATUS 0x03210
425-#define FBC_STAT_COMPRESSING (1<<31)
426-#define FBC_STAT_COMPRESSED (1<<30)
427-#define FBC_STAT_MODIFIED (1<<29)
428-#define FBC_STAT_CURRENT_LINE (1<<0)
429-#define FBC_CONTROL2 0x03214
430-#define FBC_CTL_FENCE_DBL (0<<4)
431-#define FBC_CTL_IDLE_IMM (0<<2)
432-#define FBC_CTL_IDLE_FULL (1<<2)
433-#define FBC_CTL_IDLE_LINE (2<<2)
434-#define FBC_CTL_IDLE_DEBUG (3<<2)
435-#define FBC_CTL_CPU_FENCE (1<<1)
436-#define FBC_CTL_PLANEA (0<<0)
437-#define FBC_CTL_PLANEB (1<<0)
438-#define FBC_FENCE_OFF 0x0321b
439-
440-#define FBC_LL_SIZE (1536)
441-#define FBC_LL_PAD (32)
442-
443-/* Interrupt bits:
444- */
445-#define USER_INT_FLAG (1<<1)
446-#define VSYNC_PIPEB_FLAG (1<<5)
447-#define VSYNC_PIPEA_FLAG (1<<7)
448-#define HWB_OOM_FLAG (1<<13) /* binner out of memory */
449-
450-#define I915REG_HWSTAM 0x02098
451-#define I915REG_INT_IDENTITY_R 0x020a4
452-#define I915REG_INT_MASK_R 0x020a8
453-#define I915REG_INT_ENABLE_R 0x020a0
454-
455-#define I915REG_PIPEASTAT 0x70024
456-#define I915REG_PIPEBSTAT 0x71024
457-
458-#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
459-#define I915_VBLANK_CLEAR (1UL<<1)
460-
461-#define SRX_INDEX 0x3c4
462-#define SRX_DATA 0x3c5
463-#define SR01 1
464-#define SR01_SCREEN_OFF (1<<5)
465-
466-#define PPCR 0x61204
467-#define PPCR_ON (1<<0)
468-
469-#define DVOB 0x61140
470-#define DVOB_ON (1<<31)
471-#define DVOC 0x61160
472-#define DVOC_ON (1<<31)
473-#define LVDS 0x61180
474-#define LVDS_ON (1<<31)
475-
476-#define ADPA 0x61100
477-#define ADPA_DPMS_MASK (~(3<<10))
478-#define ADPA_DPMS_ON (0<<10)
479-#define ADPA_DPMS_SUSPEND (1<<10)
480-#define ADPA_DPMS_STANDBY (2<<10)
481-#define ADPA_DPMS_OFF (3<<10)
482-
483-#define NOPID 0x2094
484-#define LP_RING 0x2030
485-#define HP_RING 0x2040
486-/* The binner has its own ring buffer:
487- */
488-#define HWB_RING 0x2400
489-
490-#define RING_TAIL 0x00
491-#define TAIL_ADDR 0x001FFFF8
492-#define RING_HEAD 0x04
493-#define HEAD_WRAP_COUNT 0xFFE00000
494-#define HEAD_WRAP_ONE 0x00200000
495-#define HEAD_ADDR 0x001FFFFC
496-#define RING_START 0x08
497-#define START_ADDR 0x0xFFFFF000
498-#define RING_LEN 0x0C
499-#define RING_NR_PAGES 0x001FF000
500-#define RING_REPORT_MASK 0x00000006
501-#define RING_REPORT_64K 0x00000002
502-#define RING_REPORT_128K 0x00000004
503-#define RING_NO_REPORT 0x00000000
504-#define RING_VALID_MASK 0x00000001
505-#define RING_VALID 0x00000001
506-#define RING_INVALID 0x00000000
507-
508-/* Instruction parser error reg:
509- */
510-#define IPEIR 0x2088
511-
512-/* Scratch pad debug 0 reg:
513- */
514-#define SCPD0 0x209c
515-
516-/* Error status reg:
517- */
518-#define ESR 0x20b8
519-
520-/* Secondary DMA fetch address debug reg:
521- */
522-#define DMA_FADD_S 0x20d4
523-
524-/* Memory Interface Arbitration State
525- */
526-#define MI_ARB_STATE 0x20e4
527-
528-/* Cache mode 0 reg.
529- * - Manipulating render cache behaviour is central
530- * to the concept of zone rendering, tuning this reg can help avoid
531- * unnecessary render cache reads and even writes (for z/stencil)
532- * at beginning and end of scene.
533- *
534- * - To change a bit, write to this reg with a mask bit set and the
535- * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set.
536- */
537-#define Cache_Mode_0 0x2120
538-#define CACHE_MODE_0 0x2120
539-#define CM0_MASK_SHIFT 16
540-#define CM0_IZ_OPT_DISABLE (1<<6)
541-#define CM0_ZR_OPT_DISABLE (1<<5)
542-#define CM0_DEPTH_EVICT_DISABLE (1<<4)
543-#define CM0_COLOR_EVICT_DISABLE (1<<3)
544-#define CM0_DEPTH_WRITE_DISABLE (1<<1)
545-#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
546-
547-
548-/* Graphics flush control. A CPU write flushes the GWB of all writes.
549- * The data is discarded.
550- */
551-#define GFX_FLSH_CNTL 0x2170
552-
553-/* Binner control. Defines the location of the bin pointer list:
554- */
555-#define BINCTL 0x2420
556-#define BC_MASK (1 << 9)
557-
558-/* Binned scene info.
559- */
560-#define BINSCENE 0x2428
561-#define BS_OP_LOAD (1 << 8)
562-#define BS_MASK (1 << 22)
563-
564-/* Bin command parser debug reg:
565- */
566-#define BCPD 0x2480
567-
568-/* Bin memory control debug reg:
569- */
570-#define BMCD 0x2484
571-
572-/* Bin data cache debug reg:
573- */
574-#define BDCD 0x2488
575-
576-/* Binner pointer cache debug reg:
577- */
578-#define BPCD 0x248c
579-
580-/* Binner scratch pad debug reg:
581- */
582-#define BINSKPD 0x24f0
583-
584-/* HWB scratch pad debug reg:
585- */
586-#define HWBSKPD 0x24f4
587-
588-/* Binner memory pool reg:
589- */
590-#define BMP_BUFFER 0x2430
591-#define BMP_PAGE_SIZE_4K (0 << 10)
592-#define BMP_BUFFER_SIZE_SHIFT 1
593-#define BMP_ENABLE (1 << 0)
594-
595-/* Get/put memory from the binner memory pool:
596- */
597-#define BMP_GET 0x2438
598-#define BMP_PUT 0x2440
599-#define BMP_OFFSET_SHIFT 5
600-
601-/* 3D state packets:
602- */
603-#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
604-
605-#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
606-#define SC_UPDATE_SCISSOR (0x1<<1)
607-#define SC_ENABLE_MASK (0x1<<0)
608-#define SC_ENABLE (0x1<<0)
609-
610-#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
611-
612-#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
613-#define SCI_YMIN_MASK (0xffff<<16)
614-#define SCI_XMIN_MASK (0xffff<<0)
615-#define SCI_YMAX_MASK (0xffff<<16)
616-#define SCI_XMAX_MASK (0xffff<<0)
617-
618-#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
619-#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
620-#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
621-#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
622-#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
623-#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
624-#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
625-
626-#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
627-
628-#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
629-#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
630-#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
631-#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
632-#define XY_SRC_COPY_BLT_SRC_TILED (1<<15)
633-#define XY_SRC_COPY_BLT_DST_TILED (1<<11)
634-
635-#define MI_BATCH_BUFFER ((0x30<<23)|1)
636-#define MI_BATCH_BUFFER_START (0x31<<23)
637-#define MI_BATCH_BUFFER_END (0xA<<23)
638-#define MI_BATCH_NON_SECURE (1)
639-#define MI_BATCH_NON_SECURE_I965 (1<<8)
640-
641-#define MI_WAIT_FOR_EVENT ((0x3<<23))
642-#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
643-#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
644-#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
645-
646-#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23))
647-
648-#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
649-#define ASYNC_FLIP (1<<22)
650-#define DISPLAY_PLANE_A (0<<20)
651-#define DISPLAY_PLANE_B (1<<20)
652-
653-/* Display regs */
654-#define DSPACNTR 0x70180
655-#define DSPBCNTR 0x71180
656-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
657-
658-/* Define the region of interest for the binner:
659- */
660-#define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4)
661-
662-#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
663-
664-#define CMD_MI_FLUSH (0x04 << 23)
665-#define MI_NO_WRITE_FLUSH (1 << 2)
666-#define MI_READ_FLUSH (1 << 0)
667-#define MI_EXE_FLUSH (1 << 1)
668-#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
669-#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
670-
671-#define BREADCRUMB_BITS 31
672-#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
673-
674-#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5])
675-#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
676-
677-#define BLC_PWM_CTL 0x61254
678-#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
679-
680-#define BLC_PWM_CTL2 0x61250
681 /**
682- * This is the most significant 15 bits of the number of backlight cycles in a
683- * complete cycle of the modulated backlight control.
684+ * Reads a dword out of the status page, which is written to from the command
685+ * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or
686+ * MI_STORE_DATA_IMM.
687 *
688- * The actual value is this field multiplied by two.
689- */
690-#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
691-#define BLM_LEGACY_MODE (1 << 16)
692-/**
693- * This is the number of cycles out of the backlight modulation cycle for which
694- * the backlight is on.
695+ * The following dwords have a reserved meaning:
696+ * 0: ISR copy, updated when an ISR bit not set in the HWSTAM changes.
697+ * 4: ring 0 head pointer
698+ * 5: ring 1 head pointer (915-class)
699+ * 6: ring 2 head pointer (915-class)
700 *
701- * This field must be no greater than the number of cycles in the complete
702- * backlight modulation cycle.
703- */
704-#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
705-#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
706-
707-#define I915_GCFGC 0xf0
708-#define I915_LOW_FREQUENCY_ENABLE (1 << 7)
709-#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
710-#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4)
711-#define I915_DISPLAY_CLOCK_MASK (7 << 4)
712-
713-#define I855_HPLLCC 0xc0
714-#define I855_CLOCK_CONTROL_MASK (3 << 0)
715-#define I855_CLOCK_133_200 (0 << 0)
716-#define I855_CLOCK_100_200 (1 << 0)
717-#define I855_CLOCK_100_133 (2 << 0)
718-#define I855_CLOCK_166_250 (3 << 0)
719-
720-/* p317, 319
721+ * The area from dword 0x10 to 0x3ff is available for driver usage.
722 */
723-#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */
724-#define VCLK2_VCO_N 0x600a
725-#define VCLK2_VCO_DIV_SEL 0x6012
726-
727-#define VCLK_DIVISOR_VGA0 0x6000
728-#define VCLK_DIVISOR_VGA1 0x6004
729-#define VCLK_POST_DIV 0x6010
730-/** Selects a post divisor of 4 instead of 2. */
731-# define VGA1_PD_P2_DIV_4 (1 << 15)
732-/** Overrides the p2 post divisor field */
733-# define VGA1_PD_P1_DIV_2 (1 << 13)
734-# define VGA1_PD_P1_SHIFT 8
735-/** P1 value is 2 greater than this field */
736-# define VGA1_PD_P1_MASK (0x1f << 8)
737-/** Selects a post divisor of 4 instead of 2. */
738-# define VGA0_PD_P2_DIV_4 (1 << 7)
739-/** Overrides the p2 post divisor field */
740-# define VGA0_PD_P1_DIV_2 (1 << 5)
741-# define VGA0_PD_P1_SHIFT 0
742-/** P1 value is 2 greater than this field */
743-# define VGA0_PD_P1_MASK (0x1f << 0)
744-
745-/* PCI D state control register */
746-#define D_STATE 0x6104
747-#define DSPCLK_GATE_D 0x6200
748-
749-/* I830 CRTC registers */
750-#define HTOTAL_A 0x60000
751-#define HBLANK_A 0x60004
752-#define HSYNC_A 0x60008
753-#define VTOTAL_A 0x6000c
754-#define VBLANK_A 0x60010
755-#define VSYNC_A 0x60014
756-#define PIPEASRC 0x6001c
757-#define BCLRPAT_A 0x60020
758-#define VSYNCSHIFT_A 0x60028
759-
760-#define HTOTAL_B 0x61000
761-#define HBLANK_B 0x61004
762-#define HSYNC_B 0x61008
763-#define VTOTAL_B 0x6100c
764-#define VBLANK_B 0x61010
765-#define VSYNC_B 0x61014
766-#define PIPEBSRC 0x6101c
767-#define BCLRPAT_B 0x61020
768-#define VSYNCSHIFT_B 0x61028
769-
770-#define PP_STATUS 0x61200
771-# define PP_ON (1 << 31)
772-/**
773- * Indicates that all dependencies of the panel are on:
774- *
775- * - PLL enabled
776- * - pipe enabled
777- * - LVDS/DVOB/DVOC on
778- */
779-# define PP_READY (1 << 30)
780-# define PP_SEQUENCE_NONE (0 << 28)
781-# define PP_SEQUENCE_ON (1 << 28)
782-# define PP_SEQUENCE_OFF (2 << 28)
783-# define PP_SEQUENCE_MASK 0x30000000
784-#define PP_CONTROL 0x61204
785-# define POWER_TARGET_ON (1 << 0)
786-
787-#define LVDSPP_ON 0x61208
788-#define LVDSPP_OFF 0x6120c
789-#define PP_CYCLE 0x61210
790-
791-#define PFIT_CONTROL 0x61230
792-# define PFIT_ENABLE (1 << 31)
793-# define PFIT_PIPE_MASK (3 << 29)
794-# define PFIT_PIPE_SHIFT 29
795-# define VERT_INTERP_DISABLE (0 << 10)
796-# define VERT_INTERP_BILINEAR (1 << 10)
797-# define VERT_INTERP_MASK (3 << 10)
798-# define VERT_AUTO_SCALE (1 << 9)
799-# define HORIZ_INTERP_DISABLE (0 << 6)
800-# define HORIZ_INTERP_BILINEAR (1 << 6)
801-# define HORIZ_INTERP_MASK (3 << 6)
802-# define HORIZ_AUTO_SCALE (1 << 5)
803-# define PANEL_8TO6_DITHER_ENABLE (1 << 3)
804-
805-#define PFIT_PGM_RATIOS 0x61234
806-# define PFIT_VERT_SCALE_MASK 0xfff00000
807-# define PFIT_HORIZ_SCALE_MASK 0x0000fff0
808-
809-#define PFIT_AUTO_RATIOS 0x61238
810-
811-
812-#define DPLL_A 0x06014
813-#define DPLL_B 0x06018
814-# define DPLL_VCO_ENABLE (1 << 31)
815-# define DPLL_DVO_HIGH_SPEED (1 << 30)
816-# define DPLL_SYNCLOCK_ENABLE (1 << 29)
817-# define DPLL_VGA_MODE_DIS (1 << 28)
818-# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
819-# define DPLLB_MODE_LVDS (2 << 26) /* i915 */
820-# define DPLL_MODE_MASK (3 << 26)
821-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
822-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
823-# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
824-# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
825-# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
826-# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
827-/**
828- * The i830 generation, in DAC/serial mode, defines p1 as two plus this
829- * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
830- */
831-# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
832-/**
833- * The i830 generation, in LVDS mode, defines P1 as the bit number set within
834- * this field (only one bit may be set).
835- */
836-# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
837-# define DPLL_FPA01_P1_POST_DIV_SHIFT 16
838-# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */
839-# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
840-# define PLL_REF_INPUT_DREFCLK (0 << 13)
841-# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
842-# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
843-# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
844-# define PLL_REF_INPUT_MASK (3 << 13)
845-# define PLL_LOAD_PULSE_PHASE_SHIFT 9
846-/*
847- * Parallel to Serial Load Pulse phase selection.
848- * Selects the phase for the 10X DPLL clock for the PCIe
849- * digital display port. The range is 4 to 13; 10 or more
850- * is just a flip delay. The default is 6
851- */
852-# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
853-# define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
854-
855-/**
856- * SDVO multiplier for 945G/GM. Not used on 965.
857- *
858- * \sa DPLL_MD_UDI_MULTIPLIER_MASK
859- */
860-# define SDVO_MULTIPLIER_MASK 0x000000ff
861-# define SDVO_MULTIPLIER_SHIFT_HIRES 4
862-# define SDVO_MULTIPLIER_SHIFT_VGA 0
863-
864-/** @defgroup DPLL_MD
865- * @{
866- */
867-/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */
868-#define DPLL_A_MD 0x0601c
869-/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */
870-#define DPLL_B_MD 0x06020
871-/**
872- * UDI pixel divider, controlling how many pixels are stuffed into a packet.
873- *
874- * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
875- */
876-# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
877-# define DPLL_MD_UDI_DIVIDER_SHIFT 24
878-/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
879-# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
880-# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
881-/**
882- * SDVO/UDI pixel multiplier.
883- *
884- * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
885- * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
886- * modes, the bus rate would be below the limits, so SDVO allows for stuffing
887- * dummy bytes in the datastream at an increased clock rate, with both sides of
888- * the link knowing how many bytes are fill.
889- *
890- * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
891- * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
892- * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
893- * through an SDVO command.
894- *
895- * This register field has values of multiplication factor minus 1, with
896- * a maximum multiplier of 5 for SDVO.
897- */
898-# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
899-# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
900-/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
901- * This best be set to the default value (3) or the CRT won't work. No,
902- * I don't entirely understand what this does...
903- */
904-# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
905-# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
906-/** @} */
907-
908-#define DPLL_TEST 0x606c
909-# define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
910-# define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
911-# define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
912-# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
913-# define DPLLB_TEST_N_BYPASS (1 << 19)
914-# define DPLLB_TEST_M_BYPASS (1 << 18)
915-# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
916-# define DPLLA_TEST_N_BYPASS (1 << 3)
917-# define DPLLA_TEST_M_BYPASS (1 << 2)
918-# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
919-
920-#define ADPA 0x61100
921-#define ADPA_DAC_ENABLE (1<<31)
922-#define ADPA_DAC_DISABLE 0
923-#define ADPA_PIPE_SELECT_MASK (1<<30)
924-#define ADPA_PIPE_A_SELECT 0
925-#define ADPA_PIPE_B_SELECT (1<<30)
926-#define ADPA_USE_VGA_HVPOLARITY (1<<15)
927-#define ADPA_SETS_HVPOLARITY 0
928-#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
929-#define ADPA_VSYNC_CNTL_ENABLE 0
930-#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
931-#define ADPA_HSYNC_CNTL_ENABLE 0
932-#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
933-#define ADPA_VSYNC_ACTIVE_LOW 0
934-#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
935-#define ADPA_HSYNC_ACTIVE_LOW 0
936-
937-#define FPA0 0x06040
938-#define FPA1 0x06044
939-#define FPB0 0x06048
940-#define FPB1 0x0604c
941-# define FP_N_DIV_MASK 0x003f0000
942-# define FP_N_DIV_SHIFT 16
943-# define FP_M1_DIV_MASK 0x00003f00
944-# define FP_M1_DIV_SHIFT 8
945-# define FP_M2_DIV_MASK 0x0000003f
946-# define FP_M2_DIV_SHIFT 0
947-
948-
949-#define PORT_HOTPLUG_EN 0x61110
950-# define SDVOB_HOTPLUG_INT_EN (1 << 26)
951-# define SDVOC_HOTPLUG_INT_EN (1 << 25)
952-# define TV_HOTPLUG_INT_EN (1 << 18)
953-# define CRT_HOTPLUG_INT_EN (1 << 9)
954-# define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
955-
956-#define PORT_HOTPLUG_STAT 0x61114
957-# define CRT_HOTPLUG_INT_STATUS (1 << 11)
958-# define TV_HOTPLUG_INT_STATUS (1 << 10)
959-# define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
960-# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
961-# define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
962-# define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
963-# define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
964-# define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
965-
966-#define SDVOB 0x61140
967-#define SDVOC 0x61160
968-#define SDVO_ENABLE (1 << 31)
969-#define SDVO_PIPE_B_SELECT (1 << 30)
970-#define SDVO_STALL_SELECT (1 << 29)
971-#define SDVO_INTERRUPT_ENABLE (1 << 26)
972-/**
973- * 915G/GM SDVO pixel multiplier.
974- *
975- * Programmed value is multiplier - 1, up to 5x.
976- *
977- * \sa DPLL_MD_UDI_MULTIPLIER_MASK
978- */
979-#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
980-#define SDVO_PORT_MULTIPLY_SHIFT 23
981-#define SDVO_PHASE_SELECT_MASK (15 << 19)
982-#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
983-#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
984-#define SDVOC_GANG_MODE (1 << 16)
985-#define SDVO_BORDER_ENABLE (1 << 7)
986-#define SDVOB_PCIE_CONCURRENCY (1 << 3)
987-#define SDVO_DETECTED (1 << 2)
988-/* Bits to be preserved when writing */
989-#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14))
990-#define SDVOC_PRESERVE_MASK (1 << 17)
991-
992-/** @defgroup LVDS
993- * @{
994- */
995-/**
996- * This register controls the LVDS output enable, pipe selection, and data
997- * format selection.
998- *
999- * All of the clock/data pairs are force powered down by power sequencing.
1000- */
1001-#define LVDS 0x61180
1002-/**
1003- * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
1004- * the DPLL semantics change when the LVDS is assigned to that pipe.
1005- */
1006-# define LVDS_PORT_EN (1 << 31)
1007-/** Selects pipe B for LVDS data. Must be set on pre-965. */
1008-# define LVDS_PIPEB_SELECT (1 << 30)
1009-
1010-/**
1011- * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
1012- * pixel.
1013- */
1014-# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
1015-# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
1016-# define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
1017-/**
1018- * Controls the A3 data pair, which contains the additional LSBs for 24 bit
1019- * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
1020- * on.
1021- */
1022-# define LVDS_A3_POWER_MASK (3 << 6)
1023-# define LVDS_A3_POWER_DOWN (0 << 6)
1024-# define LVDS_A3_POWER_UP (3 << 6)
1025-/**
1026- * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
1027- * is set.
1028- */
1029-# define LVDS_CLKB_POWER_MASK (3 << 4)
1030-# define LVDS_CLKB_POWER_DOWN (0 << 4)
1031-# define LVDS_CLKB_POWER_UP (3 << 4)
1032-
1033-/**
1034- * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
1035- * setting for whether we are in dual-channel mode. The B3 pair will
1036- * additionally only be powered up when LVDS_A3_POWER_UP is set.
1037- */
1038-# define LVDS_B0B3_POWER_MASK (3 << 2)
1039-# define LVDS_B0B3_POWER_DOWN (0 << 2)
1040-# define LVDS_B0B3_POWER_UP (3 << 2)
1041-
1042-#define PIPEACONF 0x70008
1043-#define PIPEACONF_ENABLE (1<<31)
1044-#define PIPEACONF_DISABLE 0
1045-#define PIPEACONF_DOUBLE_WIDE (1<<30)
1046-#define I965_PIPECONF_ACTIVE (1<<30)
1047-#define PIPEACONF_SINGLE_WIDE 0
1048-#define PIPEACONF_PIPE_UNLOCKED 0
1049-#define PIPEACONF_PIPE_LOCKED (1<<25)
1050-#define PIPEACONF_PALETTE 0
1051-#define PIPEACONF_GAMMA (1<<24)
1052-#define PIPECONF_FORCE_BORDER (1<<25)
1053-#define PIPECONF_PROGRESSIVE (0 << 21)
1054-#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
1055-#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
1056-
1057-#define DSPARB 0x70030
1058-#define DSPARB_CSTART_MASK (0x7f << 7)
1059-#define DSPARB_CSTART_SHIFT 7
1060-#define DSPARB_BSTART_MASK (0x7f)
1061-#define DSPARB_BSTART_SHIFT 0
1062-
1063-#define PIPEBCONF 0x71008
1064-#define PIPEBCONF_ENABLE (1<<31)
1065-#define PIPEBCONF_DISABLE 0
1066-#define PIPEBCONF_DOUBLE_WIDE (1<<30)
1067-#define PIPEBCONF_DISABLE 0
1068-#define PIPEBCONF_GAMMA (1<<24)
1069-#define PIPEBCONF_PALETTE 0
1070-
1071-#define PIPEBGCMAXRED 0x71010
1072-#define PIPEBGCMAXGREEN 0x71014
1073-#define PIPEBGCMAXBLUE 0x71018
1074-#define PIPEBSTAT 0x71024
1075-#define PIPEBFRAMEHIGH 0x71040
1076-#define PIPEBFRAMEPIXEL 0x71044
1077-
1078-#define DSPACNTR 0x70180
1079-#define DSPBCNTR 0x71180
1080-#define DISPLAY_PLANE_ENABLE (1<<31)
1081-#define DISPLAY_PLANE_DISABLE 0
1082-#define DISPPLANE_GAMMA_ENABLE (1<<30)
1083-#define DISPPLANE_GAMMA_DISABLE 0
1084-#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
1085-#define DISPPLANE_8BPP (0x2<<26)
1086-#define DISPPLANE_15_16BPP (0x4<<26)
1087-#define DISPPLANE_16BPP (0x5<<26)
1088-#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
1089-#define DISPPLANE_32BPP (0x7<<26)
1090-#define DISPPLANE_STEREO_ENABLE (1<<25)
1091-#define DISPPLANE_STEREO_DISABLE 0
1092-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
1093-#define DISPPLANE_SEL_PIPE_A 0
1094-#define DISPPLANE_SEL_PIPE_B (1<<24)
1095-#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
1096-#define DISPPLANE_SRC_KEY_DISABLE 0
1097-#define DISPPLANE_LINE_DOUBLE (1<<20)
1098-#define DISPPLANE_NO_LINE_DOUBLE 0
1099-#define DISPPLANE_STEREO_POLARITY_FIRST 0
1100-#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
1101-/* plane B only */
1102-#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
1103-#define DISPPLANE_ALPHA_TRANS_DISABLE 0
1104-#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0
1105-#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
1106-
1107-#define DSPABASE 0x70184
1108-#define DSPASTRIDE 0x70188
1109-
1110-#define DSPBBASE 0x71184
1111-#define DSPBADDR DSPBBASE
1112-#define DSPBSTRIDE 0x71188
1113-
1114-#define DSPAKEYVAL 0x70194
1115-#define DSPAKEYMASK 0x70198
1116-
1117-#define DSPAPOS 0x7018C /* reserved */
1118-#define DSPASIZE 0x70190
1119-#define DSPBPOS 0x7118C
1120-#define DSPBSIZE 0x71190
1121-
1122-#define DSPASURF 0x7019C
1123-#define DSPATILEOFF 0x701A4
1124-
1125-#define DSPBSURF 0x7119C
1126-#define DSPBTILEOFF 0x711A4
1127-
1128-#define VGACNTRL 0x71400
1129-# define VGA_DISP_DISABLE (1 << 31)
1130-# define VGA_2X_MODE (1 << 30)
1131-# define VGA_PIPE_B_SELECT (1 << 29)
1132-
1133-/*
1134- * Some BIOS scratch area registers. The 845 (and 830?) store the amount
1135- * of video memory available to the BIOS in SWF1.
1136- */
1137-
1138-#define SWF0 0x71410
1139-
1140-/*
1141- * 855 scratch registers.
1142- */
1143-#define SWF10 0x70410
1144-
1145-#define SWF30 0x72414
1146-
1147-/*
1148- * Overlay registers. These are overlay registers accessed via MMIO.
1149- * Those loaded via the overlay register page are defined in i830_video.c.
1150- */
1151-#define OVADD 0x30000
1152-
1153-#define DOVSTA 0x30008
1154-#define OC_BUF (0x3<<20)
1155+#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
1156+#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5)
1157
1158-#define OGAMC5 0x30010
1159-#define OGAMC4 0x30014
1160-#define OGAMC3 0x30018
1161-#define OGAMC2 0x3001c
1162-#define OGAMC1 0x30020
1163-#define OGAMC0 0x30024
1164-/*
1165- * Palette registers
1166- */
1167-#define PALETTE_A 0x0a000
1168-#define PALETTE_B 0x0a800
1169+extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1170
1171 #define IS_I830(dev) ((dev)->pci_device == 0x3577)
1172 #define IS_845G(dev) ((dev)->pci_device == 0x2562)
1173diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
1174index df03611..4a2de78 100644
1175--- a/drivers/gpu/drm/i915/i915_irq.c
1176+++ b/drivers/gpu/drm/i915/i915_irq.c
1177@@ -31,10 +31,6 @@
1178 #include "i915_drm.h"
1179 #include "i915_drv.h"
1180
1181-#define USER_INT_FLAG (1<<1)
1182-#define VSYNC_PIPEB_FLAG (1<<5)
1183-#define VSYNC_PIPEA_FLAG (1<<7)
1184-
1185 #define MAX_NOPID ((u32)~0)
1186
1187 /**
1188@@ -236,40 +232,43 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
1189 u16 temp;
1190 u32 pipea_stats, pipeb_stats;
1191
1192- pipea_stats = I915_READ(I915REG_PIPEASTAT);
1193- pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
1194+ pipea_stats = I915_READ(PIPEASTAT);
1195+ pipeb_stats = I915_READ(PIPEBSTAT);
1196
1197- temp = I915_READ16(I915REG_INT_IDENTITY_R);
1198+ temp = I915_READ16(IIR);
1199
1200- temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG);
1201+ temp &= (I915_USER_INTERRUPT |
1202+ I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
1203+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT);
1204
1205 DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
1206
1207 if (temp == 0)
1208 return IRQ_NONE;
1209
1210- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
1211- (void) I915_READ16(I915REG_INT_IDENTITY_R);
1212+ I915_WRITE16(IIR, temp);
1213+ (void) I915_READ16(IIR);
1214 DRM_READMEMORYBARRIER();
1215
1216 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
1217
1218- if (temp & USER_INT_FLAG)
1219+ if (temp & I915_USER_INTERRUPT)
1220 DRM_WAKEUP(&dev_priv->irq_queue);
1221
1222- if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
1223+ if (temp & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
1224+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
1225 int vblank_pipe = dev_priv->vblank_pipe;
1226
1227 if ((vblank_pipe &
1228 (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
1229 == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
1230- if (temp & VSYNC_PIPEA_FLAG)
1231+ if (temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
1232 atomic_inc(&dev->vbl_received);
1233- if (temp & VSYNC_PIPEB_FLAG)
1234+ if (temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
1235 atomic_inc(&dev->vbl_received2);
1236- } else if (((temp & VSYNC_PIPEA_FLAG) &&
1237+ } else if (((temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
1238 (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
1239- ((temp & VSYNC_PIPEB_FLAG) &&
1240+ ((temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
1241 (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
1242 atomic_inc(&dev->vbl_received);
1243
1244@@ -278,12 +277,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
1245
1246 if (dev_priv->swaps_pending > 0)
1247 drm_locked_tasklet(dev, i915_vblank_tasklet);
1248- I915_WRITE(I915REG_PIPEASTAT,
1249+ I915_WRITE(PIPEASTAT,
1250 pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
1251- I915_VBLANK_CLEAR);
1252- I915_WRITE(I915REG_PIPEBSTAT,
1253+ PIPE_VBLANK_INTERRUPT_STATUS);
1254+ I915_WRITE(PIPEBSTAT,
1255 pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
1256- I915_VBLANK_CLEAR);
1257+ PIPE_VBLANK_INTERRUPT_STATUS);
1258 }
1259
1260 return IRQ_HANDLED;
1261@@ -304,12 +303,12 @@ static int i915_emit_irq(struct drm_device * dev)
1262 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
1263
1264 BEGIN_LP_RING(6);
1265- OUT_RING(CMD_STORE_DWORD_IDX);
1266- OUT_RING(20);
1267+ OUT_RING(MI_STORE_DWORD_INDEX);
1268+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
1269 OUT_RING(dev_priv->counter);
1270 OUT_RING(0);
1271 OUT_RING(0);
1272- OUT_RING(GFX_OP_USER_INTERRUPT);
1273+ OUT_RING(MI_USER_INTERRUPT);
1274 ADVANCE_LP_RING();
1275
1276 return dev_priv->counter;
1277@@ -421,11 +420,11 @@ static void i915_enable_interrupt (struct drm_device *dev)
1278
1279 flag = 0;
1280 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
1281- flag |= VSYNC_PIPEA_FLAG;
1282+ flag |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1283 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
1284- flag |= VSYNC_PIPEB_FLAG;
1285+ flag |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1286
1287- I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag);
1288+ I915_WRITE16(IER, I915_USER_INTERRUPT | flag);
1289 }
1290
1291 /* Set the vblank monitor pipe
1292@@ -465,11 +464,11 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
1293 return -EINVAL;
1294 }
1295
1296- flag = I915_READ(I915REG_INT_ENABLE_R);
1297+ flag = I915_READ(IER);
1298 pipe->pipe = 0;
1299- if (flag & VSYNC_PIPEA_FLAG)
1300+ if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
1301 pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
1302- if (flag & VSYNC_PIPEB_FLAG)
1303+ if (flag & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
1304 pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
1305
1306 return 0;
1307@@ -587,9 +586,9 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
1308 {
1309 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1310
1311- I915_WRITE16(I915REG_HWSTAM, 0xfffe);
1312- I915_WRITE16(I915REG_INT_MASK_R, 0x0);
1313- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
1314+ I915_WRITE16(HWSTAM, 0xfffe);
1315+ I915_WRITE16(IMR, 0x0);
1316+ I915_WRITE16(IER, 0x0);
1317 }
1318
1319 void i915_driver_irq_postinstall(struct drm_device * dev)
1320@@ -614,10 +613,10 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
1321 if (!dev_priv)
1322 return;
1323
1324- I915_WRITE16(I915REG_HWSTAM, 0xffff);
1325- I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
1326- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
1327+ I915_WRITE16(HWSTAM, 0xffff);
1328+ I915_WRITE16(IMR, 0xffff);
1329+ I915_WRITE16(IER, 0x0);
1330
1331- temp = I915_READ16(I915REG_INT_IDENTITY_R);
1332- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
1333+ temp = I915_READ16(IIR);
1334+ I915_WRITE16(IIR, temp);
1335 }
1336diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
1337new file mode 100644
1338index 0000000..477c64e
1339--- /dev/null
1340+++ b/drivers/gpu/drm/i915/i915_reg.h
1341@@ -0,0 +1,1405 @@
1342+/* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
1343+ * All Rights Reserved.
1344+ *
1345+ * Permission is hereby granted, free of charge, to any person obtaining a
1346+ * copy of this software and associated documentation files (the
1347+ * "Software"), to deal in the Software without restriction, including
1348+ * without limitation the rights to use, copy, modify, merge, publish,
1349+ * distribute, sub license, and/or sell copies of the Software, and to
1350+ * permit persons to whom the Software is furnished to do so, subject to
1351+ * the following conditions:
1352+ *
1353+ * The above copyright notice and this permission notice (including the
1354+ * next paragraph) shall be included in all copies or substantial portions
1355+ * of the Software.
1356+ *
1357+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1358+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1359+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
1360+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
1361+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1362+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1363+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1364+ */
1365+
1366+#ifndef _I915_REG_H_
1367+#define _I915_REG_H_
1368+
1369+/* MCH MMIO space */
1370+/** 915-945 and GM965 MCH register controlling DRAM channel access */
1371+#define DCC 0x200
1372+#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
1373+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
1374+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
1375+#define DCC_ADDRESSING_MODE_MASK (3 << 0)
1376+#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
1377+
1378+/** 965 MCH register controlling DRAM channel configuration */
1379+#define CHDECMISC 0x111
1380+#define CHDECMISC_FLEXMEMORY (1 << 1)
1381+
1382+/*
1383+ * The Bridge device's PCI config space has information about the
1384+ * fb aperture size and the amount of pre-reserved memory.
1385+ */
1386+#define INTEL_GMCH_CTRL 0x52
1387+#define INTEL_GMCH_ENABLED 0x4
1388+#define INTEL_GMCH_MEM_MASK 0x1
1389+#define INTEL_GMCH_MEM_64M 0x1
1390+#define INTEL_GMCH_MEM_128M 0
1391+
1392+#define INTEL_855_GMCH_GMS_MASK (0x7 << 4)
1393+#define INTEL_855_GMCH_GMS_DISABLED (0x0 << 4)
1394+#define INTEL_855_GMCH_GMS_STOLEN_1M (0x1 << 4)
1395+#define INTEL_855_GMCH_GMS_STOLEN_4M (0x2 << 4)
1396+#define INTEL_855_GMCH_GMS_STOLEN_8M (0x3 << 4)
1397+#define INTEL_855_GMCH_GMS_STOLEN_16M (0x4 << 4)
1398+#define INTEL_855_GMCH_GMS_STOLEN_32M (0x5 << 4)
1399+
1400+#define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4)
1401+#define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
1402+
1403+/* PCI config space */
1404+
1405+#define HPLLCC 0xc0 /* 855 only */
1406+#define GC_CLOCK_CONTROL_MASK (3 << 0)
1407+#define GC_CLOCK_133_200 (0 << 0)
1408+#define GC_CLOCK_100_200 (1 << 0)
1409+#define GC_CLOCK_100_133 (2 << 0)
1410+#define GC_CLOCK_166_250 (3 << 0)
1411+#define GCFGC 0xf0 /* 915+ only */
1412+#define GC_LOW_FREQUENCY_ENABLE (1 << 7)
1413+#define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
1414+#define GC_DISPLAY_CLOCK_333_MHZ (4 << 4)
1415+#define GC_DISPLAY_CLOCK_MASK (7 << 4)
1416+#define LBB 0xf4
1417+
1418+/* VGA stuff */
1419+
1420+#define VGA_ST01_MDA 0x3ba
1421+#define VGA_ST01_CGA 0x3da
1422+
1423+#define VGA_MSR_WRITE 0x3c2
1424+#define VGA_MSR_READ 0x3cc
1425+#define VGA_MSR_MEM_EN (1<<1)
1426+#define VGA_MSR_CGA_MODE (1<<0)
1427+
1428+#define VGA_SR_INDEX 0x3c4
1429+#define VGA_SR_DATA 0x3c5
1430+
1431+#define VGA_AR_INDEX 0x3c0
1432+#define VGA_AR_VID_EN (1<<5)
1433+#define VGA_AR_DATA_WRITE 0x3c0
1434+#define VGA_AR_DATA_READ 0x3c1
1435+
1436+#define VGA_GR_INDEX 0x3ce
1437+#define VGA_GR_DATA 0x3cf
1438+/* GR05 */
1439+#define VGA_GR_MEM_READ_MODE_SHIFT 3
1440+#define VGA_GR_MEM_READ_MODE_PLANE 1
1441+/* GR06 */
1442+#define VGA_GR_MEM_MODE_MASK 0xc
1443+#define VGA_GR_MEM_MODE_SHIFT 2
1444+#define VGA_GR_MEM_A0000_AFFFF 0
1445+#define VGA_GR_MEM_A0000_BFFFF 1
1446+#define VGA_GR_MEM_B0000_B7FFF 2
1447+#define VGA_GR_MEM_B0000_BFFFF 3
1448+
1449+#define VGA_DACMASK 0x3c6
1450+#define VGA_DACRX 0x3c7
1451+#define VGA_DACWX 0x3c8
1452+#define VGA_DACDATA 0x3c9
1453+
1454+#define VGA_CR_INDEX_MDA 0x3b4
1455+#define VGA_CR_DATA_MDA 0x3b5
1456+#define VGA_CR_INDEX_CGA 0x3d4
1457+#define VGA_CR_DATA_CGA 0x3d5
1458+
1459+/*
1460+ * Memory interface instructions used by the kernel
1461+ */
1462+#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
1463+
1464+#define MI_NOOP MI_INSTR(0, 0)
1465+#define MI_USER_INTERRUPT MI_INSTR(0x02, 0)
1466+#define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0)
1467+#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
1468+#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
1469+#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
1470+#define MI_FLUSH MI_INSTR(0x04, 0)
1471+#define MI_READ_FLUSH (1 << 0)
1472+#define MI_EXE_FLUSH (1 << 1)
1473+#define MI_NO_WRITE_FLUSH (1 << 2)
1474+#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
1475+#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
1476+#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0)
1477+#define MI_REPORT_HEAD MI_INSTR(0x07, 0)
1478+#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
1479+#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
1480+#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
1481+#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
1482+#define MI_STORE_DWORD_INDEX_SHIFT 2
1483+#define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1)
1484+#define MI_BATCH_BUFFER MI_INSTR(0x30, 1)
1485+#define MI_BATCH_NON_SECURE (1)
1486+#define MI_BATCH_NON_SECURE_I965 (1<<8)
1487+#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0)
1488+
1489+/*
1490+ * 3D instructions used by the kernel
1491+ */
1492+#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags))
1493+
1494+#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
1495+#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
1496+#define SC_UPDATE_SCISSOR (0x1<<1)
1497+#define SC_ENABLE_MASK (0x1<<0)
1498+#define SC_ENABLE (0x1<<0)
1499+#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
1500+#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
1501+#define SCI_YMIN_MASK (0xffff<<16)
1502+#define SCI_XMIN_MASK (0xffff<<0)
1503+#define SCI_YMAX_MASK (0xffff<<16)
1504+#define SCI_XMAX_MASK (0xffff<<0)
1505+#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
1506+#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
1507+#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
1508+#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
1509+#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
1510+#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
1511+#define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
1512+#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
1513+#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
1514+#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
1515+#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
1516+#define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5)
1517+#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
1518+#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
1519+#define BLT_DEPTH_8 (0<<24)
1520+#define BLT_DEPTH_16_565 (1<<24)
1521+#define BLT_DEPTH_16_1555 (2<<24)
1522+#define BLT_DEPTH_32 (3<<24)
1523+#define BLT_ROP_GXCOPY (0xcc<<16)
1524+#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */
1525+#define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */
1526+#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
1527+#define ASYNC_FLIP (1<<22)
1528+#define DISPLAY_PLANE_A (0<<20)
1529+#define DISPLAY_PLANE_B (1<<20)
1530+
1531+/*
1532+ * Instruction and interrupt control regs
1533+ */
1534+
1535+#define PRB0_TAIL 0x02030
1536+#define PRB0_HEAD 0x02034
1537+#define PRB0_START 0x02038
1538+#define PRB0_CTL 0x0203c
1539+#define TAIL_ADDR 0x001FFFF8
1540+#define HEAD_WRAP_COUNT 0xFFE00000
1541+#define HEAD_WRAP_ONE 0x00200000
1542+#define HEAD_ADDR 0x001FFFFC
1543+#define RING_NR_PAGES 0x001FF000
1544+#define RING_REPORT_MASK 0x00000006
1545+#define RING_REPORT_64K 0x00000002
1546+#define RING_REPORT_128K 0x00000004
1547+#define RING_NO_REPORT 0x00000000
1548+#define RING_VALID_MASK 0x00000001
1549+#define RING_VALID 0x00000001
1550+#define RING_INVALID 0x00000000
1551+#define PRB1_TAIL 0x02040 /* 915+ only */
1552+#define PRB1_HEAD 0x02044 /* 915+ only */
1553+#define PRB1_START 0x02048 /* 915+ only */
1554+#define PRB1_CTL 0x0204c /* 915+ only */
1555+#define ACTHD_I965 0x02074
1556+#define HWS_PGA 0x02080
1557+#define HWS_ADDRESS_MASK 0xfffff000
1558+#define HWS_START_ADDRESS_SHIFT 4
1559+#define IPEIR 0x02088
1560+#define NOPID 0x02094
1561+#define HWSTAM 0x02098
1562+#define SCPD0 0x0209c /* 915+ only */
1563+#define IER 0x020a0
1564+#define IIR 0x020a4
1565+#define IMR 0x020a8
1566+#define ISR 0x020ac
1567+#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18)
1568+#define I915_DISPLAY_PORT_INTERRUPT (1<<17)
1569+#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15)
1570+#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14)
1571+#define I915_HWB_OOM_INTERRUPT (1<<13)
1572+#define I915_SYNC_STATUS_INTERRUPT (1<<12)
1573+#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11)
1574+#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10)
1575+#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9)
1576+#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8)
1577+#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7)
1578+#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6)
1579+#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5)
1580+#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4)
1581+#define I915_DEBUG_INTERRUPT (1<<2)
1582+#define I915_USER_INTERRUPT (1<<1)
1583+#define I915_ASLE_INTERRUPT (1<<0)
1584+#define EIR 0x020b0
1585+#define EMR 0x020b4
1586+#define ESR 0x020b8
1587+#define INSTPM 0x020c0
1588+#define ACTHD 0x020c8
1589+#define FW_BLC 0x020d8
1590+#define FW_BLC_SELF 0x020e0 /* 915+ only */
1591+#define MI_ARB_STATE 0x020e4 /* 915+ only */
1592+#define CACHE_MODE_0 0x02120 /* 915+ only */
1593+#define CM0_MASK_SHIFT 16
1594+#define CM0_IZ_OPT_DISABLE (1<<6)
1595+#define CM0_ZR_OPT_DISABLE (1<<5)
1596+#define CM0_DEPTH_EVICT_DISABLE (1<<4)
1597+#define CM0_COLOR_EVICT_DISABLE (1<<3)
1598+#define CM0_DEPTH_WRITE_DISABLE (1<<1)
1599+#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
1600+#define GFX_FLSH_CNTL 0x02170 /* 915+ only */
1601+
1602+/*
1603+ * Framebuffer compression (915+ only)
1604+ */
1605+
1606+#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
1607+#define FBC_LL_BASE 0x03204 /* 4k page aligned */
1608+#define FBC_CONTROL 0x03208
1609+#define FBC_CTL_EN (1<<31)
1610+#define FBC_CTL_PERIODIC (1<<30)
1611+#define FBC_CTL_INTERVAL_SHIFT (16)
1612+#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
1613+#define FBC_CTL_STRIDE_SHIFT (5)
1614+#define FBC_CTL_FENCENO (1<<0)
1615+#define FBC_COMMAND 0x0320c
1616+#define FBC_CMD_COMPRESS (1<<0)
1617+#define FBC_STATUS 0x03210
1618+#define FBC_STAT_COMPRESSING (1<<31)
1619+#define FBC_STAT_COMPRESSED (1<<30)
1620+#define FBC_STAT_MODIFIED (1<<29)
1621+#define FBC_STAT_CURRENT_LINE (1<<0)
1622+#define FBC_CONTROL2 0x03214
1623+#define FBC_CTL_FENCE_DBL (0<<4)
1624+#define FBC_CTL_IDLE_IMM (0<<2)
1625+#define FBC_CTL_IDLE_FULL (1<<2)
1626+#define FBC_CTL_IDLE_LINE (2<<2)
1627+#define FBC_CTL_IDLE_DEBUG (3<<2)
1628+#define FBC_CTL_CPU_FENCE (1<<1)
1629+#define FBC_CTL_PLANEA (0<<0)
1630+#define FBC_CTL_PLANEB (1<<0)
1631+#define FBC_FENCE_OFF 0x0321b
1632+
1633+#define FBC_LL_SIZE (1536)
1634+
1635+/*
1636+ * GPIO regs
1637+ */
1638+#define GPIOA 0x5010
1639+#define GPIOB 0x5014
1640+#define GPIOC 0x5018
1641+#define GPIOD 0x501c
1642+#define GPIOE 0x5020
1643+#define GPIOF 0x5024
1644+#define GPIOG 0x5028
1645+#define GPIOH 0x502c
1646+# define GPIO_CLOCK_DIR_MASK (1 << 0)
1647+# define GPIO_CLOCK_DIR_IN (0 << 1)
1648+# define GPIO_CLOCK_DIR_OUT (1 << 1)
1649+# define GPIO_CLOCK_VAL_MASK (1 << 2)
1650+# define GPIO_CLOCK_VAL_OUT (1 << 3)
1651+# define GPIO_CLOCK_VAL_IN (1 << 4)
1652+# define GPIO_CLOCK_PULLUP_DISABLE (1 << 5)
1653+# define GPIO_DATA_DIR_MASK (1 << 8)
1654+# define GPIO_DATA_DIR_IN (0 << 9)
1655+# define GPIO_DATA_DIR_OUT (1 << 9)
1656+# define GPIO_DATA_VAL_MASK (1 << 10)
1657+# define GPIO_DATA_VAL_OUT (1 << 11)
1658+# define GPIO_DATA_VAL_IN (1 << 12)
1659+# define GPIO_DATA_PULLUP_DISABLE (1 << 13)
1660+
1661+/*
1662+ * Clock control & power management
1663+ */
1664+
1665+#define VGA0 0x6000
1666+#define VGA1 0x6004
1667+#define VGA_PD 0x6010
1668+#define VGA0_PD_P2_DIV_4 (1 << 7)
1669+#define VGA0_PD_P1_DIV_2 (1 << 5)
1670+#define VGA0_PD_P1_SHIFT 0
1671+#define VGA0_PD_P1_MASK (0x1f << 0)
1672+#define VGA1_PD_P2_DIV_4 (1 << 15)
1673+#define VGA1_PD_P1_DIV_2 (1 << 13)
1674+#define VGA1_PD_P1_SHIFT 8
1675+#define VGA1_PD_P1_MASK (0x1f << 8)
1676+#define DPLL_A 0x06014
1677+#define DPLL_B 0x06018
1678+#define DPLL_VCO_ENABLE (1 << 31)
1679+#define DPLL_DVO_HIGH_SPEED (1 << 30)
1680+#define DPLL_SYNCLOCK_ENABLE (1 << 29)
1681+#define DPLL_VGA_MODE_DIS (1 << 28)
1682+#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
1683+#define DPLLB_MODE_LVDS (2 << 26) /* i915 */
1684+#define DPLL_MODE_MASK (3 << 26)
1685+#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
1686+#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
1687+#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
1688+#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
1689+#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
1690+#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
1691+
1692+#define I915_FIFO_UNDERRUN_STATUS (1UL<<31)
1693+#define I915_CRC_ERROR_ENABLE (1UL<<29)
1694+#define I915_CRC_DONE_ENABLE (1UL<<28)
1695+#define I915_GMBUS_EVENT_ENABLE (1UL<<27)
1696+#define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25)
1697+#define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
1698+#define I915_DPST_EVENT_ENABLE (1UL<<23)
1699+#define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
1700+#define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
1701+#define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
1702+#define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
1703+#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
1704+#define I915_OVERLAY_UPDATED_ENABLE (1UL<<16)
1705+#define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
1706+#define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
1707+#define I915_GMBUS_INTERRUPT_STATUS (1UL<<11)
1708+#define I915_VSYNC_INTERRUPT_STATUS (1UL<<9)
1709+#define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
1710+#define I915_DPST_EVENT_STATUS (1UL<<7)
1711+#define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6)
1712+#define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
1713+#define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
1714+#define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
1715+#define I915_VBLANK_INTERRUPT_STATUS (1UL<<1)
1716+#define I915_OVERLAY_UPDATED_STATUS (1UL<<0)
1717+
1718+#define SRX_INDEX 0x3c4
1719+#define SRX_DATA 0x3c5
1720+#define SR01 1
1721+#define SR01_SCREEN_OFF (1<<5)
1722+
1723+#define PPCR 0x61204
1724+#define PPCR_ON (1<<0)
1725+
1726+#define DVOB 0x61140
1727+#define DVOB_ON (1<<31)
1728+#define DVOC 0x61160
1729+#define DVOC_ON (1<<31)
1730+#define LVDS 0x61180
1731+#define LVDS_ON (1<<31)
1732+
1733+#define ADPA 0x61100
1734+#define ADPA_DPMS_MASK (~(3<<10))
1735+#define ADPA_DPMS_ON (0<<10)
1736+#define ADPA_DPMS_SUSPEND (1<<10)
1737+#define ADPA_DPMS_STANDBY (2<<10)
1738+#define ADPA_DPMS_OFF (3<<10)
1739+
1740+#define RING_TAIL 0x00
1741+#define TAIL_ADDR 0x001FFFF8
1742+#define RING_HEAD 0x04
1743+#define HEAD_WRAP_COUNT 0xFFE00000
1744+#define HEAD_WRAP_ONE 0x00200000
1745+#define HEAD_ADDR 0x001FFFFC
1746+#define RING_START 0x08
1747+#define START_ADDR 0xFFFFF000
1748+#define RING_LEN 0x0C
1749+#define RING_NR_PAGES 0x001FF000
1750+#define RING_REPORT_MASK 0x00000006
1751+#define RING_REPORT_64K 0x00000002
1752+#define RING_REPORT_128K 0x00000004
1753+#define RING_NO_REPORT 0x00000000
1754+#define RING_VALID_MASK 0x00000001
1755+#define RING_VALID 0x00000001
1756+#define RING_INVALID 0x00000000
1757+
1758+/* Scratch pad debug 0 reg:
1759+ */
1760+#define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
1761+/*
1762+ * The i830 generation, in LVDS mode, defines P1 as the bit number set within
1763+ * this field (only one bit may be set).
1764+ */
1765+#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
1766+#define DPLL_FPA01_P1_POST_DIV_SHIFT 16
1767+/* i830, required in DVO non-gang */
1768+#define PLL_P2_DIVIDE_BY_4 (1 << 23)
1769+#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
1770+#define PLL_REF_INPUT_DREFCLK (0 << 13)
1771+#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
1772+#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
1773+#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
1774+#define PLL_REF_INPUT_MASK (3 << 13)
1775+#define PLL_LOAD_PULSE_PHASE_SHIFT 9
1776+/*
1777+ * Parallel to Serial Load Pulse phase selection.
1778+ * Selects the phase for the 10X DPLL clock for the PCIe
1779+ * digital display port. The range is 4 to 13; 10 or more
1780+ * is just a flip delay. The default is 6
1781+ */
1782+#define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
1783+#define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
1784+/*
1785+ * SDVO multiplier for 945G/GM. Not used on 965.
1786+ */
1787+#define SDVO_MULTIPLIER_MASK 0x000000ff
1788+#define SDVO_MULTIPLIER_SHIFT_HIRES 4
1789+#define SDVO_MULTIPLIER_SHIFT_VGA 0
1790+#define DPLL_A_MD 0x0601c /* 965+ only */
1791+/*
1792+ * UDI pixel divider, controlling how many pixels are stuffed into a packet.
1793+ *
1794+ * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
1795+ */
1796+#define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
1797+#define DPLL_MD_UDI_DIVIDER_SHIFT 24
1798+/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
1799+#define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
1800+#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
1801+/*
1802+ * SDVO/UDI pixel multiplier.
1803+ *
1804+ * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
1805+ * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
1806+ * modes, the bus rate would be below the limits, so SDVO allows for stuffing
1807+ * dummy bytes in the datastream at an increased clock rate, with both sides of
1808+ * the link knowing how many bytes are fill.
1809+ *
1810+ * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
1811+ * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
1812+ * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
1813+ * through an SDVO command.
1814+ *
1815+ * This register field has values of multiplication factor minus 1, with
1816+ * a maximum multiplier of 5 for SDVO.
1817+ */
1818+#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
1819+#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
1820+/*
1821+ * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
1822+ * This best be set to the default value (3) or the CRT won't work. No,
1823+ * I don't entirely understand what this does...
1824+ */
1825+#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
1826+#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
1827+#define DPLL_B_MD 0x06020 /* 965+ only */
1828+#define FPA0 0x06040
1829+#define FPA1 0x06044
1830+#define FPB0 0x06048
1831+#define FPB1 0x0604c
1832+#define FP_N_DIV_MASK 0x003f0000
1833+#define FP_N_DIV_SHIFT 16
1834+#define FP_M1_DIV_MASK 0x00003f00
1835+#define FP_M1_DIV_SHIFT 8
1836+#define FP_M2_DIV_MASK 0x0000003f
1837+#define FP_M2_DIV_SHIFT 0
1838+#define DPLL_TEST 0x606c
1839+#define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
1840+#define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
1841+#define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
1842+#define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
1843+#define DPLLB_TEST_N_BYPASS (1 << 19)
1844+#define DPLLB_TEST_M_BYPASS (1 << 18)
1845+#define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
1846+#define DPLLA_TEST_N_BYPASS (1 << 3)
1847+#define DPLLA_TEST_M_BYPASS (1 << 2)
1848+#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
1849+#define D_STATE 0x6104
1850+#define CG_2D_DIS 0x6200
1851+#define CG_3D_DIS 0x6204
1852+
1853+/*
1854+ * Palette regs
1855+ */
1856+
1857+#define PALETTE_A 0x0a000
1858+#define PALETTE_B 0x0a800
1859+
1860+/*
1861+ * Overlay regs
1862+ */
1863+
1864+#define OVADD 0x30000
1865+#define DOVSTA 0x30008
1866+#define OC_BUF (0x3<<20)
1867+#define OGAMC5 0x30010
1868+#define OGAMC4 0x30014
1869+#define OGAMC3 0x30018
1870+#define OGAMC2 0x3001c
1871+#define OGAMC1 0x30020
1872+#define OGAMC0 0x30024
1873+
1874+/*
1875+ * Display engine regs
1876+ */
1877+
1878+/* Pipe A timing regs */
1879+#define HTOTAL_A 0x60000
1880+#define HBLANK_A 0x60004
1881+#define HSYNC_A 0x60008
1882+#define VTOTAL_A 0x6000c
1883+#define VBLANK_A 0x60010
1884+#define VSYNC_A 0x60014
1885+#define PIPEASRC 0x6001c
1886+#define BCLRPAT_A 0x60020
1887+
1888+/* Pipe B timing regs */
1889+#define HTOTAL_B 0x61000
1890+#define HBLANK_B 0x61004
1891+#define HSYNC_B 0x61008
1892+#define VTOTAL_B 0x6100c
1893+#define VBLANK_B 0x61010
1894+#define VSYNC_B 0x61014
1895+#define PIPEBSRC 0x6101c
1896+#define BCLRPAT_B 0x61020
1897+
1898+/* VGA port control */
1899+#define ADPA 0x61100
1900+#define ADPA_DAC_ENABLE (1<<31)
1901+#define ADPA_DAC_DISABLE 0
1902+#define ADPA_PIPE_SELECT_MASK (1<<30)
1903+#define ADPA_PIPE_A_SELECT 0
1904+#define ADPA_PIPE_B_SELECT (1<<30)
1905+#define ADPA_USE_VGA_HVPOLARITY (1<<15)
1906+#define ADPA_SETS_HVPOLARITY 0
1907+#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
1908+#define ADPA_VSYNC_CNTL_ENABLE 0
1909+#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
1910+#define ADPA_HSYNC_CNTL_ENABLE 0
1911+#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
1912+#define ADPA_VSYNC_ACTIVE_LOW 0
1913+#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
1914+#define ADPA_HSYNC_ACTIVE_LOW 0
1915+#define ADPA_DPMS_MASK (~(3<<10))
1916+#define ADPA_DPMS_ON (0<<10)
1917+#define ADPA_DPMS_SUSPEND (1<<10)
1918+#define ADPA_DPMS_STANDBY (2<<10)
1919+#define ADPA_DPMS_OFF (3<<10)
1920+
1921+/* Hotplug control (945+ only) */
1922+#define PORT_HOTPLUG_EN 0x61110
1923+#define SDVOB_HOTPLUG_INT_EN (1 << 26)
1924+#define SDVOC_HOTPLUG_INT_EN (1 << 25)
1925+#define TV_HOTPLUG_INT_EN (1 << 18)
1926+#define CRT_HOTPLUG_INT_EN (1 << 9)
1927+#define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
1928+
1929+#define PORT_HOTPLUG_STAT 0x61114
1930+#define CRT_HOTPLUG_INT_STATUS (1 << 11)
1931+#define TV_HOTPLUG_INT_STATUS (1 << 10)
1932+#define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
1933+#define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
1934+#define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
1935+#define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
1936+#define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
1937+#define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
1938+
1939+/* SDVO port control */
1940+#define SDVOB 0x61140
1941+#define SDVOC 0x61160
1942+#define SDVO_ENABLE (1 << 31)
1943+#define SDVO_PIPE_B_SELECT (1 << 30)
1944+#define SDVO_STALL_SELECT (1 << 29)
1945+#define SDVO_INTERRUPT_ENABLE (1 << 26)
1946+/**
1947+ * 915G/GM SDVO pixel multiplier.
1948+ *
1949+ * Programmed value is multiplier - 1, up to 5x.
1950+ *
1951+ * \sa DPLL_MD_UDI_MULTIPLIER_MASK
1952+ */
1953+#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
1954+#define SDVO_PORT_MULTIPLY_SHIFT 23
1955+#define SDVO_PHASE_SELECT_MASK (15 << 19)
1956+#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
1957+#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
1958+#define SDVOC_GANG_MODE (1 << 16)
1959+#define SDVO_BORDER_ENABLE (1 << 7)
1960+#define SDVOB_PCIE_CONCURRENCY (1 << 3)
1961+#define SDVO_DETECTED (1 << 2)
1962+/* Bits to be preserved when writing */
1963+#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26))
1964+#define SDVOC_PRESERVE_MASK ((1 << 17) | (1 << 26))
1965+
1966+/* DVO port control */
1967+#define DVOA 0x61120
1968+#define DVOB 0x61140
1969+#define DVOC 0x61160
1970+#define DVO_ENABLE (1 << 31)
1971+#define DVO_PIPE_B_SELECT (1 << 30)
1972+#define DVO_PIPE_STALL_UNUSED (0 << 28)
1973+#define DVO_PIPE_STALL (1 << 28)
1974+#define DVO_PIPE_STALL_TV (2 << 28)
1975+#define DVO_PIPE_STALL_MASK (3 << 28)
1976+#define DVO_USE_VGA_SYNC (1 << 15)
1977+#define DVO_DATA_ORDER_I740 (0 << 14)
1978+#define DVO_DATA_ORDER_FP (1 << 14)
1979+#define DVO_VSYNC_DISABLE (1 << 11)
1980+#define DVO_HSYNC_DISABLE (1 << 10)
1981+#define DVO_VSYNC_TRISTATE (1 << 9)
1982+#define DVO_HSYNC_TRISTATE (1 << 8)
1983+#define DVO_BORDER_ENABLE (1 << 7)
1984+#define DVO_DATA_ORDER_GBRG (1 << 6)
1985+#define DVO_DATA_ORDER_RGGB (0 << 6)
1986+#define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6)
1987+#define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6)
1988+#define DVO_VSYNC_ACTIVE_HIGH (1 << 4)
1989+#define DVO_HSYNC_ACTIVE_HIGH (1 << 3)
1990+#define DVO_BLANK_ACTIVE_HIGH (1 << 2)
1991+#define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */
1992+#define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */
1993+#define DVO_PRESERVE_MASK (0x7<<24)
1994+#define DVOA_SRCDIM 0x61124
1995+#define DVOB_SRCDIM 0x61144
1996+#define DVOC_SRCDIM 0x61164
1997+#define DVO_SRCDIM_HORIZONTAL_SHIFT 12
1998+#define DVO_SRCDIM_VERTICAL_SHIFT 0
1999+
2000+/* LVDS port control */
2001+#define LVDS 0x61180
2002+/*
2003+ * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
2004+ * the DPLL semantics change when the LVDS is assigned to that pipe.
2005+ */
2006+#define LVDS_PORT_EN (1 << 31)
2007+/* Selects pipe B for LVDS data. Must be set on pre-965. */
2008+#define LVDS_PIPEB_SELECT (1 << 30)
2009+/*
2010+ * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
2011+ * pixel.
2012+ */
2013+#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
2014+#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
2015+#define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
2016+/*
2017+ * Controls the A3 data pair, which contains the additional LSBs for 24 bit
2018+ * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
2019+ * on.
2020+ */
2021+#define LVDS_A3_POWER_MASK (3 << 6)
2022+#define LVDS_A3_POWER_DOWN (0 << 6)
2023+#define LVDS_A3_POWER_UP (3 << 6)
2024+/*
2025+ * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
2026+ * is set.
2027+ */
2028+#define LVDS_CLKB_POWER_MASK (3 << 4)
2029+#define LVDS_CLKB_POWER_DOWN (0 << 4)
2030+#define LVDS_CLKB_POWER_UP (3 << 4)
2031+/*
2032+ * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
2033+ * setting for whether we are in dual-channel mode. The B3 pair will
2034+ * additionally only be powered up when LVDS_A3_POWER_UP is set.
2035+ */
2036+#define LVDS_B0B3_POWER_MASK (3 << 2)
2037+#define LVDS_B0B3_POWER_DOWN (0 << 2)
2038+#define LVDS_B0B3_POWER_UP (3 << 2)
2039+
2040+/* Panel power sequencing */
2041+#define PP_STATUS 0x61200
2042+#define PP_ON (1 << 31)
2043+/*
2044+ * Indicates that all dependencies of the panel are on:
2045+ *
2046+ * - PLL enabled
2047+ * - pipe enabled
2048+ * - LVDS/DVOB/DVOC on
2049+ */
2050+#define PP_READY (1 << 30)
2051+#define PP_SEQUENCE_NONE (0 << 28)
2052+#define PP_SEQUENCE_ON (1 << 28)
2053+#define PP_SEQUENCE_OFF (2 << 28)
2054+#define PP_SEQUENCE_MASK 0x30000000
2055+#define PP_CONTROL 0x61204
2056+#define POWER_TARGET_ON (1 << 0)
2057+#define PP_ON_DELAYS 0x61208
2058+#define PP_OFF_DELAYS 0x6120c
2059+#define PP_DIVISOR 0x61210
2060+
2061+/* Panel fitting */
2062+#define PFIT_CONTROL 0x61230
2063+#define PFIT_ENABLE (1 << 31)
2064+#define PFIT_PIPE_MASK (3 << 29)
2065+#define PFIT_PIPE_SHIFT 29
2066+#define VERT_INTERP_DISABLE (0 << 10)
2067+#define VERT_INTERP_BILINEAR (1 << 10)
2068+#define VERT_INTERP_MASK (3 << 10)
2069+#define VERT_AUTO_SCALE (1 << 9)
2070+#define HORIZ_INTERP_DISABLE (0 << 6)
2071+#define HORIZ_INTERP_BILINEAR (1 << 6)
2072+#define HORIZ_INTERP_MASK (3 << 6)
2073+#define HORIZ_AUTO_SCALE (1 << 5)
2074+#define PANEL_8TO6_DITHER_ENABLE (1 << 3)
2075+#define PFIT_PGM_RATIOS 0x61234
2076+#define PFIT_VERT_SCALE_MASK 0xfff00000
2077+#define PFIT_HORIZ_SCALE_MASK 0x0000fff0
2078+#define PFIT_AUTO_RATIOS 0x61238
2079+
2080+/* Backlight control */
2081+#define BLC_PWM_CTL 0x61254
2082+#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
2083+#define BLC_PWM_CTL2 0x61250 /* 965+ only */
2084+/*
2085+ * This is the most significant 15 bits of the number of backlight cycles in a
2086+ * complete cycle of the modulated backlight control.
2087+ *
2088+ * The actual value is this field multiplied by two.
2089+ */
2090+#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
2091+#define BLM_LEGACY_MODE (1 << 16)
2092+/*
2093+ * This is the number of cycles out of the backlight modulation cycle for which
2094+ * the backlight is on.
2095+ *
2096+ * This field must be no greater than the number of cycles in the complete
2097+ * backlight modulation cycle.
2098+ */
2099+#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
2100+#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
2101+
2102+/* TV port control */
2103+#define TV_CTL 0x68000
2104+/** Enables the TV encoder */
2105+# define TV_ENC_ENABLE (1 << 31)
2106+/** Sources the TV encoder input from pipe B instead of A. */
2107+# define TV_ENC_PIPEB_SELECT (1 << 30)
2108+/** Outputs composite video (DAC A only) */
2109+# define TV_ENC_OUTPUT_COMPOSITE (0 << 28)
2110+/** Outputs SVideo video (DAC B/C) */
2111+# define TV_ENC_OUTPUT_SVIDEO (1 << 28)
2112+/** Outputs Component video (DAC A/B/C) */
2113+# define TV_ENC_OUTPUT_COMPONENT (2 << 28)
2114+/** Outputs Composite and SVideo (DAC A/B/C) */
2115+# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28)
2116+# define TV_TRILEVEL_SYNC (1 << 21)
2117+/** Enables slow sync generation (945GM only) */
2118+# define TV_SLOW_SYNC (1 << 20)
2119+/** Selects 4x oversampling for 480i and 576p */
2120+# define TV_OVERSAMPLE_4X (0 << 18)
2121+/** Selects 2x oversampling for 720p and 1080i */
2122+# define TV_OVERSAMPLE_2X (1 << 18)
2123+/** Selects no oversampling for 1080p */
2124+# define TV_OVERSAMPLE_NONE (2 << 18)
2125+/** Selects 8x oversampling */
2126+# define TV_OVERSAMPLE_8X (3 << 18)
2127+/** Selects progressive mode rather than interlaced */
2128+# define TV_PROGRESSIVE (1 << 17)
2129+/** Sets the colorburst to PAL mode. Required for non-M PAL modes. */
2130+# define TV_PAL_BURST (1 << 16)
2131+/** Field for setting delay of Y compared to C */
2132+# define TV_YC_SKEW_MASK (7 << 12)
2133+/** Enables a fix for 480p/576p standard definition modes on the 915GM only */
2134+# define TV_ENC_SDP_FIX (1 << 11)
2135+/**
2136+ * Enables a fix for the 915GM only.
2137+ *
2138+ * Not sure what it does.
2139+ */
2140+# define TV_ENC_C0_FIX (1 << 10)
2141+/** Bits that must be preserved by software */
2142+# define TV_CTL_SAVE ((3 << 8) | (3 << 6))
2143+# define TV_FUSE_STATE_MASK (3 << 4)
2144+/** Read-only state that reports all features enabled */
2145+# define TV_FUSE_STATE_ENABLED (0 << 4)
2146+/** Read-only state that reports that Macrovision is disabled in hardware*/
2147+# define TV_FUSE_STATE_NO_MACROVISION (1 << 4)
2148+/** Read-only state that reports that TV-out is disabled in hardware. */
2149+# define TV_FUSE_STATE_DISABLED (2 << 4)
2150+/** Normal operation */
2151+# define TV_TEST_MODE_NORMAL (0 << 0)
2152+/** Encoder test pattern 1 - combo pattern */
2153+# define TV_TEST_MODE_PATTERN_1 (1 << 0)
2154+/** Encoder test pattern 2 - full screen vertical 75% color bars */
2155+# define TV_TEST_MODE_PATTERN_2 (2 << 0)
2156+/** Encoder test pattern 3 - full screen horizontal 75% color bars */
2157+# define TV_TEST_MODE_PATTERN_3 (3 << 0)
2158+/** Encoder test pattern 4 - random noise */
2159+# define TV_TEST_MODE_PATTERN_4 (4 << 0)
2160+/** Encoder test pattern 5 - linear color ramps */
2161+# define TV_TEST_MODE_PATTERN_5 (5 << 0)
2162+/**
2163+ * This test mode forces the DACs to 50% of full output.
2164+ *
2165+ * This is used for load detection in combination with TVDAC_SENSE_MASK
2166+ */
2167+# define TV_TEST_MODE_MONITOR_DETECT (7 << 0)
2168+# define TV_TEST_MODE_MASK (7 << 0)
2169+
2170+#define TV_DAC 0x68004
2171+/**
2172+ * Reports that DAC state change logic has reported change (RO).
2173+ *
2174+ * This gets cleared when TV_DAC_STATE_EN is cleared
2175+*/
2176+# define TVDAC_STATE_CHG (1 << 31)
2177+# define TVDAC_SENSE_MASK (7 << 28)
2178+/** Reports that DAC A voltage is above the detect threshold */
2179+# define TVDAC_A_SENSE (1 << 30)
2180+/** Reports that DAC B voltage is above the detect threshold */
2181+# define TVDAC_B_SENSE (1 << 29)
2182+/** Reports that DAC C voltage is above the detect threshold */
2183+# define TVDAC_C_SENSE (1 << 28)
2184+/**
2185+ * Enables DAC state detection logic, for load-based TV detection.
2186+ *
2187+ * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set
2188+ * to off, for load detection to work.
2189+ */
2190+# define TVDAC_STATE_CHG_EN (1 << 27)
2191+/** Sets the DAC A sense value to high */
2192+# define TVDAC_A_SENSE_CTL (1 << 26)
2193+/** Sets the DAC B sense value to high */
2194+# define TVDAC_B_SENSE_CTL (1 << 25)
2195+/** Sets the DAC C sense value to high */
2196+# define TVDAC_C_SENSE_CTL (1 << 24)
2197+/** Overrides the ENC_ENABLE and DAC voltage levels */
2198+# define DAC_CTL_OVERRIDE (1 << 7)
2199+/** Sets the slew rate. Must be preserved in software */
2200+# define ENC_TVDAC_SLEW_FAST (1 << 6)
2201+# define DAC_A_1_3_V (0 << 4)
2202+# define DAC_A_1_1_V (1 << 4)
2203+# define DAC_A_0_7_V (2 << 4)
2204+# define DAC_A_OFF (3 << 4)
2205+# define DAC_B_1_3_V (0 << 2)
2206+# define DAC_B_1_1_V (1 << 2)
2207+# define DAC_B_0_7_V (2 << 2)
2208+# define DAC_B_OFF (3 << 2)
2209+# define DAC_C_1_3_V (0 << 0)
2210+# define DAC_C_1_1_V (1 << 0)
2211+# define DAC_C_0_7_V (2 << 0)
2212+# define DAC_C_OFF (3 << 0)
2213+
2214+/**
2215+ * CSC coefficients are stored in a floating point format with 9 bits of
2216+ * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n,
2217+ * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with
2218+ * -1 (0x3) being the only legal negative value.
2219+ */
2220+#define TV_CSC_Y 0x68010
2221+# define TV_RY_MASK 0x07ff0000
2222+# define TV_RY_SHIFT 16
2223+# define TV_GY_MASK 0x00000fff
2224+# define TV_GY_SHIFT 0
2225+
2226+#define TV_CSC_Y2 0x68014
2227+# define TV_BY_MASK 0x07ff0000
2228+# define TV_BY_SHIFT 16
2229+/**
2230+ * Y attenuation for component video.
2231+ *
2232+ * Stored in 1.9 fixed point.
2233+ */
2234+# define TV_AY_MASK 0x000003ff
2235+# define TV_AY_SHIFT 0
2236+
2237+#define TV_CSC_U 0x68018
2238+# define TV_RU_MASK 0x07ff0000
2239+# define TV_RU_SHIFT 16
2240+# define TV_GU_MASK 0x000007ff
2241+# define TV_GU_SHIFT 0
2242+
2243+#define TV_CSC_U2 0x6801c
2244+# define TV_BU_MASK 0x07ff0000
2245+# define TV_BU_SHIFT 16
2246+/**
2247+ * U attenuation for component video.
2248+ *
2249+ * Stored in 1.9 fixed point.
2250+ */
2251+# define TV_AU_MASK 0x000003ff
2252+# define TV_AU_SHIFT 0
2253+
2254+#define TV_CSC_V 0x68020
2255+# define TV_RV_MASK 0x0fff0000
2256+# define TV_RV_SHIFT 16
2257+# define TV_GV_MASK 0x000007ff
2258+# define TV_GV_SHIFT 0
2259+
2260+#define TV_CSC_V2 0x68024
2261+# define TV_BV_MASK 0x07ff0000
2262+# define TV_BV_SHIFT 16
2263+/**
2264+ * V attenuation for component video.
2265+ *
2266+ * Stored in 1.9 fixed point.
2267+ */
2268+# define TV_AV_MASK 0x000007ff
2269+# define TV_AV_SHIFT 0
2270+
2271+#define TV_CLR_KNOBS 0x68028
2272+/** 2s-complement brightness adjustment */
2273+# define TV_BRIGHTNESS_MASK 0xff000000
2274+# define TV_BRIGHTNESS_SHIFT 24
2275+/** Contrast adjustment, as a 2.6 unsigned floating point number */
2276+# define TV_CONTRAST_MASK 0x00ff0000
2277+# define TV_CONTRAST_SHIFT 16
2278+/** Saturation adjustment, as a 2.6 unsigned floating point number */
2279+# define TV_SATURATION_MASK 0x0000ff00
2280+# define TV_SATURATION_SHIFT 8
2281+/** Hue adjustment, as an integer phase angle in degrees */
2282+# define TV_HUE_MASK 0x000000ff
2283+# define TV_HUE_SHIFT 0
2284+
2285+#define TV_CLR_LEVEL 0x6802c
2286+/** Controls the DAC level for black */
2287+# define TV_BLACK_LEVEL_MASK 0x01ff0000
2288+# define TV_BLACK_LEVEL_SHIFT 16
2289+/** Controls the DAC level for blanking */
2290+# define TV_BLANK_LEVEL_MASK 0x000001ff
2291+# define TV_BLANK_LEVEL_SHIFT 0
2292+
2293+#define TV_H_CTL_1 0x68030
2294+/** Number of pixels in the hsync. */
2295+# define TV_HSYNC_END_MASK 0x1fff0000
2296+# define TV_HSYNC_END_SHIFT 16
2297+/** Total number of pixels minus one in the line (display and blanking). */
2298+# define TV_HTOTAL_MASK 0x00001fff
2299+# define TV_HTOTAL_SHIFT 0
2300+
2301+#define TV_H_CTL_2 0x68034
2302+/** Enables the colorburst (needed for non-component color) */
2303+# define TV_BURST_ENA (1 << 31)
2304+/** Offset of the colorburst from the start of hsync, in pixels minus one. */
2305+# define TV_HBURST_START_SHIFT 16
2306+# define TV_HBURST_START_MASK 0x1fff0000
2307+/** Length of the colorburst */
2308+# define TV_HBURST_LEN_SHIFT 0
2309+# define TV_HBURST_LEN_MASK 0x0001fff
2310+
2311+#define TV_H_CTL_3 0x68038
2312+/** End of hblank, measured in pixels minus one from start of hsync */
2313+# define TV_HBLANK_END_SHIFT 16
2314+# define TV_HBLANK_END_MASK 0x1fff0000
2315+/** Start of hblank, measured in pixels minus one from start of hsync */
2316+# define TV_HBLANK_START_SHIFT 0
2317+# define TV_HBLANK_START_MASK 0x0001fff
2318+
2319+#define TV_V_CTL_1 0x6803c
2320+/** XXX */
2321+# define TV_NBR_END_SHIFT 16
2322+# define TV_NBR_END_MASK 0x07ff0000
2323+/** XXX */
2324+# define TV_VI_END_F1_SHIFT 8
2325+# define TV_VI_END_F1_MASK 0x00003f00
2326+/** XXX */
2327+# define TV_VI_END_F2_SHIFT 0
2328+# define TV_VI_END_F2_MASK 0x0000003f
2329+
2330+#define TV_V_CTL_2 0x68040
2331+/** Length of vsync, in half lines */
2332+# define TV_VSYNC_LEN_MASK 0x07ff0000
2333+# define TV_VSYNC_LEN_SHIFT 16
2334+/** Offset of the start of vsync in field 1, measured in one less than the
2335+ * number of half lines.
2336+ */
2337+# define TV_VSYNC_START_F1_MASK 0x00007f00
2338+# define TV_VSYNC_START_F1_SHIFT 8
2339+/**
2340+ * Offset of the start of vsync in field 2, measured in one less than the
2341+ * number of half lines.
2342+ */
2343+# define TV_VSYNC_START_F2_MASK 0x0000007f
2344+# define TV_VSYNC_START_F2_SHIFT 0
2345+
2346+#define TV_V_CTL_3 0x68044
2347+/** Enables generation of the equalization signal */
2348+# define TV_EQUAL_ENA (1 << 31)
2349+/** Length of vsync, in half lines */
2350+# define TV_VEQ_LEN_MASK 0x007f0000
2351+# define TV_VEQ_LEN_SHIFT 16
2352+/** Offset of the start of equalization in field 1, measured in one less than
2353+ * the number of half lines.
2354+ */
2355+# define TV_VEQ_START_F1_MASK 0x0007f00
2356+# define TV_VEQ_START_F1_SHIFT 8
2357+/**
2358+ * Offset of the start of equalization in field 2, measured in one less than
2359+ * the number of half lines.
2360+ */
2361+# define TV_VEQ_START_F2_MASK 0x000007f
2362+# define TV_VEQ_START_F2_SHIFT 0
2363+
2364+#define TV_V_CTL_4 0x68048
2365+/**
2366+ * Offset to start of vertical colorburst, measured in one less than the
2367+ * number of lines from vertical start.
2368+ */
2369+# define TV_VBURST_START_F1_MASK 0x003f0000
2370+# define TV_VBURST_START_F1_SHIFT 16
2371+/**
2372+ * Offset to the end of vertical colorburst, measured in one less than the
2373+ * number of lines from the start of NBR.
2374+ */
2375+# define TV_VBURST_END_F1_MASK 0x000000ff
2376+# define TV_VBURST_END_F1_SHIFT 0
2377+
2378+#define TV_V_CTL_5 0x6804c
2379+/**
2380+ * Offset to start of vertical colorburst, measured in one less than the
2381+ * number of lines from vertical start.
2382+ */
2383+# define TV_VBURST_START_F2_MASK 0x003f0000
2384+# define TV_VBURST_START_F2_SHIFT 16
2385+/**
2386+ * Offset to the end of vertical colorburst, measured in one less than the
2387+ * number of lines from the start of NBR.
2388+ */
2389+# define TV_VBURST_END_F2_MASK 0x000000ff
2390+# define TV_VBURST_END_F2_SHIFT 0
2391+
2392+#define TV_V_CTL_6 0x68050
2393+/**
2394+ * Offset to start of vertical colorburst, measured in one less than the
2395+ * number of lines from vertical start.
2396+ */
2397+# define TV_VBURST_START_F3_MASK 0x003f0000
2398+# define TV_VBURST_START_F3_SHIFT 16
2399+/**
2400+ * Offset to the end of vertical colorburst, measured in one less than the
2401+ * number of lines from the start of NBR.
2402+ */
2403+# define TV_VBURST_END_F3_MASK 0x000000ff
2404+# define TV_VBURST_END_F3_SHIFT 0
2405+
2406+#define TV_V_CTL_7 0x68054
2407+/**
2408+ * Offset to start of vertical colorburst, measured in one less than the
2409+ * number of lines from vertical start.
2410+ */
2411+# define TV_VBURST_START_F4_MASK 0x003f0000
2412+# define TV_VBURST_START_F4_SHIFT 16
2413+/**
2414+ * Offset to the end of vertical colorburst, measured in one less than the
2415+ * number of lines from the start of NBR.
2416+ */
2417+# define TV_VBURST_END_F4_MASK 0x000000ff
2418+# define TV_VBURST_END_F4_SHIFT 0
2419+
2420+#define TV_SC_CTL_1 0x68060
2421+/** Turns on the first subcarrier phase generation DDA */
2422+# define TV_SC_DDA1_EN (1 << 31)
2423+/** Turns on the first subcarrier phase generation DDA */
2424+# define TV_SC_DDA2_EN (1 << 30)
2425+/** Turns on the first subcarrier phase generation DDA */
2426+# define TV_SC_DDA3_EN (1 << 29)
2427+/** Sets the subcarrier DDA to reset frequency every other field */
2428+# define TV_SC_RESET_EVERY_2 (0 << 24)
2429+/** Sets the subcarrier DDA to reset frequency every fourth field */
2430+# define TV_SC_RESET_EVERY_4 (1 << 24)
2431+/** Sets the subcarrier DDA to reset frequency every eighth field */
2432+# define TV_SC_RESET_EVERY_8 (2 << 24)
2433+/** Sets the subcarrier DDA to never reset the frequency */
2434+# define TV_SC_RESET_NEVER (3 << 24)
2435+/** Sets the peak amplitude of the colorburst.*/
2436+# define TV_BURST_LEVEL_MASK 0x00ff0000
2437+# define TV_BURST_LEVEL_SHIFT 16
2438+/** Sets the increment of the first subcarrier phase generation DDA */
2439+# define TV_SCDDA1_INC_MASK 0x00000fff
2440+# define TV_SCDDA1_INC_SHIFT 0
2441+
2442+#define TV_SC_CTL_2 0x68064
2443+/** Sets the rollover for the second subcarrier phase generation DDA */
2444+# define TV_SCDDA2_SIZE_MASK 0x7fff0000
2445+# define TV_SCDDA2_SIZE_SHIFT 16
2446+/** Sets the increent of the second subcarrier phase generation DDA */
2447+# define TV_SCDDA2_INC_MASK 0x00007fff
2448+# define TV_SCDDA2_INC_SHIFT 0
2449+
2450+#define TV_SC_CTL_3 0x68068
2451+/** Sets the rollover for the third subcarrier phase generation DDA */
2452+# define TV_SCDDA3_SIZE_MASK 0x7fff0000
2453+# define TV_SCDDA3_SIZE_SHIFT 16
2454+/** Sets the increent of the third subcarrier phase generation DDA */
2455+# define TV_SCDDA3_INC_MASK 0x00007fff
2456+# define TV_SCDDA3_INC_SHIFT 0
2457+
2458+#define TV_WIN_POS 0x68070
2459+/** X coordinate of the display from the start of horizontal active */
2460+# define TV_XPOS_MASK 0x1fff0000
2461+# define TV_XPOS_SHIFT 16
2462+/** Y coordinate of the display from the start of vertical active (NBR) */
2463+# define TV_YPOS_MASK 0x00000fff
2464+# define TV_YPOS_SHIFT 0
2465+
2466+#define TV_WIN_SIZE 0x68074
2467+/** Horizontal size of the display window, measured in pixels*/
2468+# define TV_XSIZE_MASK 0x1fff0000
2469+# define TV_XSIZE_SHIFT 16
2470+/**
2471+ * Vertical size of the display window, measured in pixels.
2472+ *
2473+ * Must be even for interlaced modes.
2474+ */
2475+# define TV_YSIZE_MASK 0x00000fff
2476+# define TV_YSIZE_SHIFT 0
2477+
2478+#define TV_FILTER_CTL_1 0x68080
2479+/**
2480+ * Enables automatic scaling calculation.
2481+ *
2482+ * If set, the rest of the registers are ignored, and the calculated values can
2483+ * be read back from the register.
2484+ */
2485+# define TV_AUTO_SCALE (1 << 31)
2486+/**
2487+ * Disables the vertical filter.
2488+ *
2489+ * This is required on modes more than 1024 pixels wide */
2490+# define TV_V_FILTER_BYPASS (1 << 29)
2491+/** Enables adaptive vertical filtering */
2492+# define TV_VADAPT (1 << 28)
2493+# define TV_VADAPT_MODE_MASK (3 << 26)
2494+/** Selects the least adaptive vertical filtering mode */
2495+# define TV_VADAPT_MODE_LEAST (0 << 26)
2496+/** Selects the moderately adaptive vertical filtering mode */
2497+# define TV_VADAPT_MODE_MODERATE (1 << 26)
2498+/** Selects the most adaptive vertical filtering mode */
2499+# define TV_VADAPT_MODE_MOST (3 << 26)
2500+/**
2501+ * Sets the horizontal scaling factor.
2502+ *
2503+ * This should be the fractional part of the horizontal scaling factor divided
2504+ * by the oversampling rate. TV_HSCALE should be less than 1, and set to:
2505+ *
2506+ * (src width - 1) / ((oversample * dest width) - 1)
2507+ */
2508+# define TV_HSCALE_FRAC_MASK 0x00003fff
2509+# define TV_HSCALE_FRAC_SHIFT 0
2510+
2511+#define TV_FILTER_CTL_2 0x68084
2512+/**
2513+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
2514+ *
2515+ * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1)
2516+ */
2517+# define TV_VSCALE_INT_MASK 0x00038000
2518+# define TV_VSCALE_INT_SHIFT 15
2519+/**
2520+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
2521+ *
2522+ * \sa TV_VSCALE_INT_MASK
2523+ */
2524+# define TV_VSCALE_FRAC_MASK 0x00007fff
2525+# define TV_VSCALE_FRAC_SHIFT 0
2526+
2527+#define TV_FILTER_CTL_3 0x68088
2528+/**
2529+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
2530+ *
2531+ * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1))
2532+ *
2533+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
2534+ */
2535+# define TV_VSCALE_IP_INT_MASK 0x00038000
2536+# define TV_VSCALE_IP_INT_SHIFT 15
2537+/**
2538+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
2539+ *
2540+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
2541+ *
2542+ * \sa TV_VSCALE_IP_INT_MASK
2543+ */
2544+# define TV_VSCALE_IP_FRAC_MASK 0x00007fff
2545+# define TV_VSCALE_IP_FRAC_SHIFT 0
2546+
2547+#define TV_CC_CONTROL 0x68090
2548+# define TV_CC_ENABLE (1 << 31)
2549+/**
2550+ * Specifies which field to send the CC data in.
2551+ *
2552+ * CC data is usually sent in field 0.
2553+ */
2554+# define TV_CC_FID_MASK (1 << 27)
2555+# define TV_CC_FID_SHIFT 27
2556+/** Sets the horizontal position of the CC data. Usually 135. */
2557+# define TV_CC_HOFF_MASK 0x03ff0000
2558+# define TV_CC_HOFF_SHIFT 16
2559+/** Sets the vertical position of the CC data. Usually 21 */
2560+# define TV_CC_LINE_MASK 0x0000003f
2561+# define TV_CC_LINE_SHIFT 0
2562+
2563+#define TV_CC_DATA 0x68094
2564+# define TV_CC_RDY (1 << 31)
2565+/** Second word of CC data to be transmitted. */
2566+# define TV_CC_DATA_2_MASK 0x007f0000
2567+# define TV_CC_DATA_2_SHIFT 16
2568+/** First word of CC data to be transmitted. */
2569+# define TV_CC_DATA_1_MASK 0x0000007f
2570+# define TV_CC_DATA_1_SHIFT 0
2571+
2572+#define TV_H_LUMA_0 0x68100
2573+#define TV_H_LUMA_59 0x681ec
2574+#define TV_H_CHROMA_0 0x68200
2575+#define TV_H_CHROMA_59 0x682ec
2576+#define TV_V_LUMA_0 0x68300
2577+#define TV_V_LUMA_42 0x683a8
2578+#define TV_V_CHROMA_0 0x68400
2579+#define TV_V_CHROMA_42 0x684a8
2580+
2581+/* Display & cursor control */
2582+
2583+/* Pipe A */
2584+#define PIPEADSL 0x70000
2585+#define PIPEACONF 0x70008
2586+#define PIPEACONF_ENABLE (1<<31)
2587+#define PIPEACONF_DISABLE 0
2588+#define PIPEACONF_DOUBLE_WIDE (1<<30)
2589+#define I965_PIPECONF_ACTIVE (1<<30)
2590+#define PIPEACONF_SINGLE_WIDE 0
2591+#define PIPEACONF_PIPE_UNLOCKED 0
2592+#define PIPEACONF_PIPE_LOCKED (1<<25)
2593+#define PIPEACONF_PALETTE 0
2594+#define PIPEACONF_GAMMA (1<<24)
2595+#define PIPECONF_FORCE_BORDER (1<<25)
2596+#define PIPECONF_PROGRESSIVE (0 << 21)
2597+#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
2598+#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
2599+#define PIPEASTAT 0x70024
2600+#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31)
2601+#define PIPE_CRC_ERROR_ENABLE (1UL<<29)
2602+#define PIPE_CRC_DONE_ENABLE (1UL<<28)
2603+#define PIPE_GMBUS_EVENT_ENABLE (1UL<<27)
2604+#define PIPE_HOTPLUG_INTERRUPT_ENABLE (1UL<<26)
2605+#define PIPE_VSYNC_INTERRUPT_ENABLE (1UL<<25)
2606+#define PIPE_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
2607+#define PIPE_DPST_EVENT_ENABLE (1UL<<23)
2608+#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
2609+#define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
2610+#define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
2611+#define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */
2612+#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
2613+#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17)
2614+#define PIPE_OVERLAY_UPDATED_ENABLE (1UL<<16)
2615+#define PIPE_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
2616+#define PIPE_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
2617+#define PIPE_GMBUS_INTERRUPT_STATUS (1UL<<11)
2618+#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10)
2619+#define PIPE_VSYNC_INTERRUPT_STATUS (1UL<<9)
2620+#define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
2621+#define PIPE_DPST_EVENT_STATUS (1UL<<7)
2622+#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6)
2623+#define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
2624+#define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
2625+#define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */
2626+#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
2627+#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
2628+#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0)
2629+
2630+#define DSPARB 0x70030
2631+#define DSPARB_CSTART_MASK (0x7f << 7)
2632+#define DSPARB_CSTART_SHIFT 7
2633+#define DSPARB_BSTART_MASK (0x7f)
2634+#define DSPARB_BSTART_SHIFT 0
2635+/*
2636+ * The two pipe frame counter registers are not synchronized, so
2637+ * reading a stable value is somewhat tricky. The following code
2638+ * should work:
2639+ *
2640+ * do {
2641+ * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
2642+ * PIPE_FRAME_HIGH_SHIFT;
2643+ * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >>
2644+ * PIPE_FRAME_LOW_SHIFT);
2645+ * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
2646+ * PIPE_FRAME_HIGH_SHIFT);
2647+ * } while (high1 != high2);
2648+ * frame = (high1 << 8) | low1;
2649+ */
2650+#define PIPEAFRAMEHIGH 0x70040
2651+#define PIPE_FRAME_HIGH_MASK 0x0000ffff
2652+#define PIPE_FRAME_HIGH_SHIFT 0
2653+#define PIPEAFRAMEPIXEL 0x70044
2654+#define PIPE_FRAME_LOW_MASK 0xff000000
2655+#define PIPE_FRAME_LOW_SHIFT 24
2656+#define PIPE_PIXEL_MASK 0x00ffffff
2657+#define PIPE_PIXEL_SHIFT 0
2658+
2659+/* Cursor A & B regs */
2660+#define CURACNTR 0x70080
2661+#define CURSOR_MODE_DISABLE 0x00
2662+#define CURSOR_MODE_64_32B_AX 0x07
2663+#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
2664+#define MCURSOR_GAMMA_ENABLE (1 << 26)
2665+#define CURABASE 0x70084
2666+#define CURAPOS 0x70088
2667+#define CURSOR_POS_MASK 0x007FF
2668+#define CURSOR_POS_SIGN 0x8000
2669+#define CURSOR_X_SHIFT 0
2670+#define CURSOR_Y_SHIFT 16
2671+#define CURBCNTR 0x700c0
2672+#define CURBBASE 0x700c4
2673+#define CURBPOS 0x700c8
2674+
2675+/* Display A control */
2676+#define DSPACNTR 0x70180
2677+#define DISPLAY_PLANE_ENABLE (1<<31)
2678+#define DISPLAY_PLANE_DISABLE 0
2679+#define DISPPLANE_GAMMA_ENABLE (1<<30)
2680+#define DISPPLANE_GAMMA_DISABLE 0
2681+#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
2682+#define DISPPLANE_8BPP (0x2<<26)
2683+#define DISPPLANE_15_16BPP (0x4<<26)
2684+#define DISPPLANE_16BPP (0x5<<26)
2685+#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
2686+#define DISPPLANE_32BPP (0x7<<26)
2687+#define DISPPLANE_STEREO_ENABLE (1<<25)
2688+#define DISPPLANE_STEREO_DISABLE 0
2689+#define DISPPLANE_SEL_PIPE_MASK (1<<24)
2690+#define DISPPLANE_SEL_PIPE_A 0
2691+#define DISPPLANE_SEL_PIPE_B (1<<24)
2692+#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
2693+#define DISPPLANE_SRC_KEY_DISABLE 0
2694+#define DISPPLANE_LINE_DOUBLE (1<<20)
2695+#define DISPPLANE_NO_LINE_DOUBLE 0
2696+#define DISPPLANE_STEREO_POLARITY_FIRST 0
2697+#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
2698+#define DSPAADDR 0x70184
2699+#define DSPASTRIDE 0x70188
2700+#define DSPAPOS 0x7018C /* reserved */
2701+#define DSPASIZE 0x70190
2702+#define DSPASURF 0x7019C /* 965+ only */
2703+#define DSPATILEOFF 0x701A4 /* 965+ only */
2704+
2705+/* VBIOS flags */
2706+#define SWF00 0x71410
2707+#define SWF01 0x71414
2708+#define SWF02 0x71418
2709+#define SWF03 0x7141c
2710+#define SWF04 0x71420
2711+#define SWF05 0x71424
2712+#define SWF06 0x71428
2713+#define SWF10 0x70410
2714+#define SWF11 0x70414
2715+#define SWF14 0x71420
2716+#define SWF30 0x72414
2717+#define SWF31 0x72418
2718+#define SWF32 0x7241c
2719+
2720+/* Pipe B */
2721+#define PIPEBDSL 0x71000
2722+#define PIPEBCONF 0x71008
2723+#define PIPEBSTAT 0x71024
2724+#define PIPEBFRAMEHIGH 0x71040
2725+#define PIPEBFRAMEPIXEL 0x71044
2726+
2727+/* Display B control */
2728+#define DSPBCNTR 0x71180
2729+#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
2730+#define DISPPLANE_ALPHA_TRANS_DISABLE 0
2731+#define DISPPLANE_SPRITE_ABOVE_DISPLAY 0
2732+#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
2733+#define DSPBADDR 0x71184
2734+#define DSPBSTRIDE 0x71188
2735+#define DSPBPOS 0x7118C
2736+#define DSPBSIZE 0x71190
2737+#define DSPBSURF 0x7119C
2738+#define DSPBTILEOFF 0x711A4
2739+
2740+/* VBIOS regs */
2741+#define VGACNTRL 0x71400
2742+# define VGA_DISP_DISABLE (1 << 31)
2743+# define VGA_2X_MODE (1 << 30)
2744+# define VGA_PIPE_B_SELECT (1 << 29)
2745+
2746+#endif /* _I915_REG_H_ */
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch
new file mode 100644
index 0000000000..9337475c31
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch
@@ -0,0 +1,424 @@
1commit 4f99970852559935b27bc634318f34c18c5fd143
2Author: Eric Anholt <eric@anholt.net>
3Date: Tue Jul 29 12:10:39 2008 -0700
4
5 i915: Add support for MSI and interrupt mitigation.
6
7 Previous attempts at interrupt mitigation had been foiled by i915_wait_irq's
8 failure to update the sarea seqno value when the status page indicated that
9 the seqno had already been passed. MSI support has been seen to cut CPU
10 costs by up to 40% in some workloads by avoiding other expensive interrupt
11 handlers for frequent graphics interrupts.
12
13 Signed-off-by: Eric Anholt <eric@anholt.net>
14 Signed-off-by: Dave Airlie <airlied@redhat.com>
15
16diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
17index 53f0e5a..61ed515 100644
18--- a/drivers/gpu/drm/drm_irq.c
19+++ b/drivers/gpu/drm/drm_irq.c
20@@ -63,7 +63,7 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
21 p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
22 return -EINVAL;
23
24- p->irq = dev->irq;
25+ p->irq = dev->pdev->irq;
26
27 DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
28 p->irq);
29@@ -89,7 +89,7 @@ static int drm_irq_install(struct drm_device * dev)
30 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
31 return -EINVAL;
32
33- if (dev->irq == 0)
34+ if (dev->pdev->irq == 0)
35 return -EINVAL;
36
37 mutex_lock(&dev->struct_mutex);
38@@ -107,7 +107,7 @@ static int drm_irq_install(struct drm_device * dev)
39 dev->irq_enabled = 1;
40 mutex_unlock(&dev->struct_mutex);
41
42- DRM_DEBUG("irq=%d\n", dev->irq);
43+ DRM_DEBUG("irq=%d\n", dev->pdev->irq);
44
45 if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
46 init_waitqueue_head(&dev->vbl_queue);
47@@ -127,8 +127,12 @@ static int drm_irq_install(struct drm_device * dev)
48 if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
49 sh_flags = IRQF_SHARED;
50
51- ret = request_irq(dev->irq, dev->driver->irq_handler,
52+ ret = request_irq(dev->pdev->irq, dev->driver->irq_handler,
53 sh_flags, dev->devname, dev);
54+ /* Expose the device irq number to drivers that want to export it for
55+ * whatever reason.
56+ */
57+ dev->irq = dev->pdev->irq;
58 if (ret < 0) {
59 mutex_lock(&dev->struct_mutex);
60 dev->irq_enabled = 0;
61@@ -164,11 +168,11 @@ int drm_irq_uninstall(struct drm_device * dev)
62 if (!irq_enabled)
63 return -EINVAL;
64
65- DRM_DEBUG("irq=%d\n", dev->irq);
66+ DRM_DEBUG("irq=%d\n", dev->pdev->irq);
67
68 dev->driver->irq_uninstall(dev);
69
70- free_irq(dev->irq, dev);
71+ free_irq(dev->pdev->irq, dev);
72
73 dev->locked_tasklet_func = NULL;
74
75@@ -201,7 +205,7 @@ int drm_control(struct drm_device *dev, void *data,
76 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
77 return 0;
78 if (dev->if_version < DRM_IF_VERSION(1, 2) &&
79- ctl->irq != dev->irq)
80+ ctl->irq != dev->pdev->irq)
81 return -EINVAL;
82 return drm_irq_install(dev);
83 case DRM_UNINST_HANDLER:
84@@ -239,7 +243,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
85 int ret = 0;
86 unsigned int flags, seq;
87
88- if ((!dev->irq) || (!dev->irq_enabled))
89+ if ((!dev->pdev->irq) || (!dev->irq_enabled))
90 return -EINVAL;
91
92 if (vblwait->request.type &
93diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
94index 7be580b..10bfb0c 100644
95--- a/drivers/gpu/drm/i915/i915_dma.c
96+++ b/drivers/gpu/drm/i915/i915_dma.c
97@@ -84,7 +84,7 @@ static int i915_dma_cleanup(struct drm_device * dev)
98 * may not have been called from userspace and after dev_private
99 * is freed, it's too late.
100 */
101- if (dev->irq)
102+ if (dev->irq_enabled)
103 drm_irq_uninstall(dev);
104
105 if (dev_priv->ring.virtual_start) {
106@@ -644,7 +644,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
107
108 switch (param->param) {
109 case I915_PARAM_IRQ_ACTIVE:
110- value = dev->irq ? 1 : 0;
111+ value = dev->irq_enabled;
112 break;
113 case I915_PARAM_ALLOW_BATCHBUFFER:
114 value = dev_priv->allow_batchbuffer ? 1 : 0;
115@@ -763,6 +763,20 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
116 ret = drm_addmap(dev, base, size, _DRM_REGISTERS,
117 _DRM_KERNEL | _DRM_DRIVER,
118 &dev_priv->mmio_map);
119+
120+
121+ /* On the 945G/GM, the chipset reports the MSI capability on the
122+ * integrated graphics even though the support isn't actually there
123+ * according to the published specs. It doesn't appear to function
124+ * correctly in testing on 945G.
125+ * This may be a side effect of MSI having been made available for PEG
126+ * and the registers being closely associated.
127+ */
128+ if (!IS_I945G(dev) && !IS_I945GM(dev))
129+ pci_enable_msi(dev->pdev);
130+
131+ spin_lock_init(&dev_priv->user_irq_lock);
132+
133 return ret;
134 }
135
136@@ -770,6 +784,9 @@ int i915_driver_unload(struct drm_device *dev)
137 {
138 struct drm_i915_private *dev_priv = dev->dev_private;
139
140+ if (dev->pdev->msi_enabled)
141+ pci_disable_msi(dev->pdev);
142+
143 if (dev_priv->mmio_map)
144 drm_rmmap(dev, dev_priv->mmio_map);
145
146diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
147index afb51a3..8daf0d8 100644
148--- a/drivers/gpu/drm/i915/i915_drv.h
149+++ b/drivers/gpu/drm/i915/i915_drv.h
150@@ -105,6 +105,12 @@ typedef struct drm_i915_private {
151 wait_queue_head_t irq_queue;
152 atomic_t irq_received;
153 atomic_t irq_emitted;
154+ /** Protects user_irq_refcount and irq_mask_reg */
155+ spinlock_t user_irq_lock;
156+ /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
157+ int user_irq_refcount;
158+ /** Cached value of IMR to avoid reads in updating the bitfield */
159+ u32 irq_mask_reg;
160
161 int tex_lru_log_granularity;
162 int allow_batchbuffer;
163diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
164index 4a2de78..24d11ed 100644
165--- a/drivers/gpu/drm/i915/i915_irq.c
166+++ b/drivers/gpu/drm/i915/i915_irq.c
167@@ -33,6 +33,31 @@
168
169 #define MAX_NOPID ((u32)~0)
170
171+/** These are the interrupts used by the driver */
172+#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
173+ I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | \
174+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
175+
176+static inline void
177+i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
178+{
179+ if ((dev_priv->irq_mask_reg & mask) != 0) {
180+ dev_priv->irq_mask_reg &= ~mask;
181+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
182+ (void) I915_READ(IMR);
183+ }
184+}
185+
186+static inline void
187+i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
188+{
189+ if ((dev_priv->irq_mask_reg & mask) != mask) {
190+ dev_priv->irq_mask_reg |= mask;
191+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
192+ (void) I915_READ(IMR);
193+ }
194+}
195+
196 /**
197 * Emit blits for scheduled buffer swaps.
198 *
199@@ -229,46 +254,50 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
200 {
201 struct drm_device *dev = (struct drm_device *) arg;
202 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
203- u16 temp;
204 u32 pipea_stats, pipeb_stats;
205+ u32 iir;
206
207 pipea_stats = I915_READ(PIPEASTAT);
208 pipeb_stats = I915_READ(PIPEBSTAT);
209
210- temp = I915_READ16(IIR);
211-
212- temp &= (I915_USER_INTERRUPT |
213- I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
214- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT);
215+ if (dev->pdev->msi_enabled)
216+ I915_WRITE(IMR, ~0);
217+ iir = I915_READ(IIR);
218
219- DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
220+ DRM_DEBUG("iir=%08x\n", iir);
221
222- if (temp == 0)
223+ if (iir == 0) {
224+ if (dev->pdev->msi_enabled) {
225+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
226+ (void) I915_READ(IMR);
227+ }
228 return IRQ_NONE;
229+ }
230
231- I915_WRITE16(IIR, temp);
232- (void) I915_READ16(IIR);
233- DRM_READMEMORYBARRIER();
234+ I915_WRITE(IIR, iir);
235+ if (dev->pdev->msi_enabled)
236+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
237+ (void) I915_READ(IIR); /* Flush posted writes */
238
239 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
240
241- if (temp & I915_USER_INTERRUPT)
242+ if (iir & I915_USER_INTERRUPT)
243 DRM_WAKEUP(&dev_priv->irq_queue);
244
245- if (temp & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
246- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
247+ if (iir & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
248+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
249 int vblank_pipe = dev_priv->vblank_pipe;
250
251 if ((vblank_pipe &
252 (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
253 == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
254- if (temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
255+ if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
256 atomic_inc(&dev->vbl_received);
257- if (temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
258+ if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
259 atomic_inc(&dev->vbl_received2);
260- } else if (((temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
261+ } else if (((iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
262 (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
263- ((temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
264+ ((iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
265 (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
266 atomic_inc(&dev->vbl_received);
267
268@@ -314,6 +343,27 @@ static int i915_emit_irq(struct drm_device * dev)
269 return dev_priv->counter;
270 }
271
272+static void i915_user_irq_get(struct drm_device *dev)
273+{
274+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
275+
276+ spin_lock(&dev_priv->user_irq_lock);
277+ if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1))
278+ i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
279+ spin_unlock(&dev_priv->user_irq_lock);
280+}
281+
282+static void i915_user_irq_put(struct drm_device *dev)
283+{
284+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
285+
286+ spin_lock(&dev_priv->user_irq_lock);
287+ BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
288+ if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0))
289+ i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
290+ spin_unlock(&dev_priv->user_irq_lock);
291+}
292+
293 static int i915_wait_irq(struct drm_device * dev, int irq_nr)
294 {
295 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
296@@ -322,13 +372,17 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
297 DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
298 READ_BREADCRUMB(dev_priv));
299
300- if (READ_BREADCRUMB(dev_priv) >= irq_nr)
301+ if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
302+ dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
303 return 0;
304+ }
305
306 dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
307
308+ i915_user_irq_get(dev);
309 DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
310 READ_BREADCRUMB(dev_priv) >= irq_nr);
311+ i915_user_irq_put(dev);
312
313 if (ret == -EBUSY) {
314 DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
315@@ -413,20 +467,6 @@ int i915_irq_wait(struct drm_device *dev, void *data,
316 return i915_wait_irq(dev, irqwait->irq_seq);
317 }
318
319-static void i915_enable_interrupt (struct drm_device *dev)
320-{
321- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
322- u16 flag;
323-
324- flag = 0;
325- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
326- flag |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
327- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
328- flag |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
329-
330- I915_WRITE16(IER, I915_USER_INTERRUPT | flag);
331-}
332-
333 /* Set the vblank monitor pipe
334 */
335 int i915_vblank_pipe_set(struct drm_device *dev, void *data,
336@@ -434,6 +474,7 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data,
337 {
338 drm_i915_private_t *dev_priv = dev->dev_private;
339 drm_i915_vblank_pipe_t *pipe = data;
340+ u32 enable_mask = 0, disable_mask = 0;
341
342 if (!dev_priv) {
343 DRM_ERROR("called with no initialization\n");
344@@ -445,9 +486,20 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data,
345 return -EINVAL;
346 }
347
348- dev_priv->vblank_pipe = pipe->pipe;
349+ if (pipe->pipe & DRM_I915_VBLANK_PIPE_A)
350+ enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
351+ else
352+ disable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
353+
354+ if (pipe->pipe & DRM_I915_VBLANK_PIPE_B)
355+ enable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
356+ else
357+ disable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
358
359- i915_enable_interrupt (dev);
360+ i915_enable_irq(dev_priv, enable_mask);
361+ i915_disable_irq(dev_priv, disable_mask);
362+
363+ dev_priv->vblank_pipe = pipe->pipe;
364
365 return 0;
366 }
367@@ -464,7 +516,7 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
368 return -EINVAL;
369 }
370
371- flag = I915_READ(IER);
372+ flag = I915_READ(IMR);
373 pipe->pipe = 0;
374 if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
375 pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
376@@ -586,9 +638,9 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
377 {
378 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
379
380- I915_WRITE16(HWSTAM, 0xfffe);
381- I915_WRITE16(IMR, 0x0);
382- I915_WRITE16(IER, 0x0);
383+ I915_WRITE(HWSTAM, 0xfffe);
384+ I915_WRITE(IMR, 0x0);
385+ I915_WRITE(IER, 0x0);
386 }
387
388 void i915_driver_irq_postinstall(struct drm_device * dev)
389@@ -601,7 +653,18 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
390
391 if (!dev_priv->vblank_pipe)
392 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
393- i915_enable_interrupt(dev);
394+
395+ /* Set initial unmasked IRQs to just the selected vblank pipes. */
396+ dev_priv->irq_mask_reg = ~0;
397+ if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
398+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
399+ if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
400+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
401+
402+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
403+ I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
404+ (void) I915_READ(IER);
405+
406 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
407 }
408
409@@ -613,10 +676,10 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
410 if (!dev_priv)
411 return;
412
413- I915_WRITE16(HWSTAM, 0xffff);
414- I915_WRITE16(IMR, 0xffff);
415- I915_WRITE16(IER, 0x0);
416+ I915_WRITE(HWSTAM, 0xffff);
417+ I915_WRITE(IMR, 0xffff);
418+ I915_WRITE(IER, 0x0);
419
420- temp = I915_READ16(IIR);
421- I915_WRITE16(IIR, temp);
422+ temp = I915_READ(IIR);
423+ I915_WRITE(IIR, temp);
424 }
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch
new file mode 100644
index 0000000000..8736250f00
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch
@@ -0,0 +1,46 @@
1commit 1236e8610ab9c6f9f8297e60530bedb2640c7224
2Author: Keith Packard <keithp@keithp.com>
3Date: Wed Jul 30 12:21:20 2008 -0700
4
5 i915: Track progress inside of batchbuffers for determining wedgedness.
6
7 This avoids early termination for long-running commands.
8
9 Signed-off-by: Eric Anholt <eric@anholt.net>
10 Signed-off-by: Dave Airlie <airlied@redhat.com>
11
12diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
13index 10bfb0c..4c72a01 100644
14--- a/drivers/gpu/drm/i915/i915_dma.c
15+++ b/drivers/gpu/drm/i915/i915_dma.c
16@@ -40,11 +40,15 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
17 {
18 drm_i915_private_t *dev_priv = dev->dev_private;
19 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
20+ u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
21+ u32 last_acthd = I915_READ(acthd_reg);
22+ u32 acthd;
23 u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
24 int i;
25
26- for (i = 0; i < 10000; i++) {
27+ for (i = 0; i < 100000; i++) {
28 ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
29+ acthd = I915_READ(acthd_reg);
30 ring->space = ring->head - (ring->tail + 8);
31 if (ring->space < 0)
32 ring->space += ring->Size;
33@@ -55,8 +59,13 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
34
35 if (ring->head != last_head)
36 i = 0;
37+ if (acthd != last_acthd)
38+ i = 0;
39
40 last_head = ring->head;
41+ last_acthd = acthd;
42+ msleep_interruptible(10);
43+
44 }
45
46 return -EBUSY;
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0007-i915-Initialize-hardware-status-page-at-device-load.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0007-i915-Initialize-hardware-status-page-at-device-load.patch
new file mode 100644
index 0000000000..79f068f422
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0007-i915-Initialize-hardware-status-page-at-device-load.patch
@@ -0,0 +1,137 @@
1commit 75fed4ae8454aa975c274b2585ec2287dd15773d
2Author: Keith Packard <keithp@keithp.com>
3Date: Wed Jul 30 13:03:43 2008 -0700
4
5 i915: Initialize hardware status page at device load when possible.
6
7 Some chips were unstable with repeated setup/teardown of the hardware status
8 page.
9
10 Signed-off-by: Eric Anholt <eric@anholt.net>
11 Signed-off-by: Dave Airlie <airlied@redhat.com>
12
13diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
14index 4c72a01..b3c4ac9 100644
15--- a/drivers/gpu/drm/i915/i915_dma.c
16+++ b/drivers/gpu/drm/i915/i915_dma.c
17@@ -71,6 +71,52 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
18 return -EBUSY;
19 }
20
21+/**
22+ * Sets up the hardware status page for devices that need a physical address
23+ * in the register.
24+ */
25+int i915_init_phys_hws(struct drm_device *dev)
26+{
27+ drm_i915_private_t *dev_priv = dev->dev_private;
28+ /* Program Hardware Status Page */
29+ dev_priv->status_page_dmah =
30+ drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
31+
32+ if (!dev_priv->status_page_dmah) {
33+ DRM_ERROR("Can not allocate hardware status page\n");
34+ return -ENOMEM;
35+ }
36+ dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
37+ dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
38+
39+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
40+
41+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
42+ DRM_DEBUG("Enabled hardware status page\n");
43+ return 0;
44+}
45+
46+/**
47+ * Frees the hardware status page, whether it's a physical address or a virtual
48+ * address set up by the X Server.
49+ */
50+void i915_free_hws(struct drm_device *dev)
51+{
52+ drm_i915_private_t *dev_priv = dev->dev_private;
53+ if (dev_priv->status_page_dmah) {
54+ drm_pci_free(dev, dev_priv->status_page_dmah);
55+ dev_priv->status_page_dmah = NULL;
56+ }
57+
58+ if (dev_priv->status_gfx_addr) {
59+ dev_priv->status_gfx_addr = 0;
60+ drm_core_ioremapfree(&dev_priv->hws_map, dev);
61+ }
62+
63+ /* Need to rewrite hardware status page */
64+ I915_WRITE(HWS_PGA, 0x1ffff000);
65+}
66+
67 void i915_kernel_lost_context(struct drm_device * dev)
68 {
69 drm_i915_private_t *dev_priv = dev->dev_private;
70@@ -103,18 +149,9 @@ static int i915_dma_cleanup(struct drm_device * dev)
71 dev_priv->ring.map.size = 0;
72 }
73
74- if (dev_priv->status_page_dmah) {
75- drm_pci_free(dev, dev_priv->status_page_dmah);
76- dev_priv->status_page_dmah = NULL;
77- /* Need to rewrite hardware status page */
78- I915_WRITE(HWS_PGA, 0x1ffff000);
79- }
80-
81- if (dev_priv->status_gfx_addr) {
82- dev_priv->status_gfx_addr = 0;
83- drm_core_ioremapfree(&dev_priv->hws_map, dev);
84- I915_WRITE(HWS_PGA, 0x1ffff000);
85- }
86+ /* Clear the HWS virtual address at teardown */
87+ if (I915_NEED_GFX_HWS(dev))
88+ i915_free_hws(dev);
89
90 return 0;
91 }
92@@ -165,23 +202,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
93 */
94 dev_priv->allow_batchbuffer = 1;
95
96- /* Program Hardware Status Page */
97- if (!I915_NEED_GFX_HWS(dev)) {
98- dev_priv->status_page_dmah =
99- drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
100-
101- if (!dev_priv->status_page_dmah) {
102- i915_dma_cleanup(dev);
103- DRM_ERROR("Can not allocate hardware status page\n");
104- return -ENOMEM;
105- }
106- dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
107- dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
108-
109- memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
110- I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
111- }
112- DRM_DEBUG("Enabled hardware status page\n");
113 return 0;
114 }
115
116@@ -773,6 +793,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
117 _DRM_KERNEL | _DRM_DRIVER,
118 &dev_priv->mmio_map);
119
120+ /* Init HWS */
121+ if (!I915_NEED_GFX_HWS(dev)) {
122+ ret = i915_init_phys_hws(dev);
123+ if (ret != 0)
124+ return ret;
125+ }
126
127 /* On the 945G/GM, the chipset reports the MSI capability on the
128 * integrated graphics even though the support isn't actually there
129@@ -796,6 +822,8 @@ int i915_driver_unload(struct drm_device *dev)
130 if (dev->pdev->msi_enabled)
131 pci_disable_msi(dev->pdev);
132
133+ i915_free_hws(dev);
134+
135 if (dev_priv->mmio_map)
136 drm_rmmap(dev, dev_priv->mmio_map);
137
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0008-Add-Intel-ACPI-IGD-OpRegion-support.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0008-Add-Intel-ACPI-IGD-OpRegion-support.patch
new file mode 100644
index 0000000000..afa6f96345
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0008-Add-Intel-ACPI-IGD-OpRegion-support.patch
@@ -0,0 +1,572 @@
1commit 91c2ebb8e78aa64f4807399b506ec0090ae5f3d6
2Author: Matthew Garrett <mjg59@srcf.ucam.org>
3Date: Tue Aug 5 19:37:25 2008 +0100
4
5 Add Intel ACPI IGD OpRegion support
6
7 This adds the support necessary for allowing ACPI backlight control to
8 work on some newer Intel-based graphics systems. Tested on Thinkpad T61
9 and HP 2510p hardware.
10
11 Signed-off-by: Matthew Garrett <mjg@redhat.com>
12 Signed-off-by: Dave Airlie <airlied@linux.ie>
13
14diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
15index a9e6046..b032808 100644
16--- a/drivers/gpu/drm/i915/Makefile
17+++ b/drivers/gpu/drm/i915/Makefile
18@@ -3,7 +3,7 @@
19 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
20
21 ccflags-y := -Iinclude/drm
22-i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
23+i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o
24
25 i915-$(CONFIG_COMPAT) += i915_ioc32.o
26
27diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
28index b3c4ac9..cead62f 100644
29--- a/drivers/gpu/drm/i915/i915_dma.c
30+++ b/drivers/gpu/drm/i915/i915_dma.c
31@@ -810,6 +810,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
32 if (!IS_I945G(dev) && !IS_I945GM(dev))
33 pci_enable_msi(dev->pdev);
34
35+ intel_opregion_init(dev);
36+
37 spin_lock_init(&dev_priv->user_irq_lock);
38
39 return ret;
40@@ -827,6 +829,8 @@ int i915_driver_unload(struct drm_device *dev)
41 if (dev_priv->mmio_map)
42 drm_rmmap(dev, dev_priv->mmio_map);
43
44+ intel_opregion_free(dev);
45+
46 drm_free(dev->dev_private, sizeof(drm_i915_private_t),
47 DRM_MEM_DRIVER);
48
49diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
50index 6c99aab..d95eca2 100644
51--- a/drivers/gpu/drm/i915/i915_drv.c
52+++ b/drivers/gpu/drm/i915/i915_drv.c
53@@ -371,6 +371,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
54
55 i915_save_vga(dev);
56
57+ intel_opregion_free(dev);
58+
59 if (state.event == PM_EVENT_SUSPEND) {
60 /* Shut down the device */
61 pci_disable_device(dev->pdev);
62@@ -532,6 +534,8 @@ static int i915_resume(struct drm_device *dev)
63
64 i915_restore_vga(dev);
65
66+ intel_opregion_init(dev);
67+
68 return 0;
69 }
70
71diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
72index 8daf0d8..e4bd01c 100644
73--- a/drivers/gpu/drm/i915/i915_drv.h
74+++ b/drivers/gpu/drm/i915/i915_drv.h
75@@ -82,6 +82,14 @@ typedef struct _drm_i915_vbl_swap {
76 unsigned int sequence;
77 } drm_i915_vbl_swap_t;
78
79+struct intel_opregion {
80+ struct opregion_header *header;
81+ struct opregion_acpi *acpi;
82+ struct opregion_swsci *swsci;
83+ struct opregion_asle *asle;
84+ int enabled;
85+};
86+
87 typedef struct drm_i915_private {
88 drm_local_map_t *sarea;
89 drm_local_map_t *mmio_map;
90@@ -122,6 +130,8 @@ typedef struct drm_i915_private {
91 drm_i915_vbl_swap_t vbl_swaps;
92 unsigned int swaps_pending;
93
94+ struct intel_opregion opregion;
95+
96 /* Register state */
97 u8 saveLBB;
98 u32 saveDSPACNTR;
99@@ -244,6 +254,7 @@ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
100 struct drm_file *file_priv);
101 extern int i915_vblank_swap(struct drm_device *dev, void *data,
102 struct drm_file *file_priv);
103+extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
104
105 /* i915_mem.c */
106 extern int i915_mem_alloc(struct drm_device *dev, void *data,
107@@ -258,6 +269,12 @@ extern void i915_mem_takedown(struct mem_block **heap);
108 extern void i915_mem_release(struct drm_device * dev,
109 struct drm_file *file_priv, struct mem_block *heap);
110
111+/* i915_opregion.c */
112+extern int intel_opregion_init(struct drm_device *dev);
113+extern void intel_opregion_free(struct drm_device *dev);
114+extern void opregion_asle_intr(struct drm_device *dev);
115+extern void opregion_enable_asle(struct drm_device *dev);
116+
117 #define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
118 #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
119 #define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
120diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
121index 24d11ed..ae7d3a8 100644
122--- a/drivers/gpu/drm/i915/i915_irq.c
123+++ b/drivers/gpu/drm/i915/i915_irq.c
124@@ -36,9 +36,11 @@
125 /** These are the interrupts used by the driver */
126 #define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
127 I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | \
128- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
129+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT | \
130+ I915_ASLE_INTERRUPT | \
131+ I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
132
133-static inline void
134+void
135 i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
136 {
137 if ((dev_priv->irq_mask_reg & mask) != 0) {
138@@ -274,6 +276,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
139 return IRQ_NONE;
140 }
141
142+ I915_WRITE(PIPEASTAT, pipea_stats);
143+ I915_WRITE(PIPEBSTAT, pipeb_stats);
144+
145 I915_WRITE(IIR, iir);
146 if (dev->pdev->msi_enabled)
147 I915_WRITE(IMR, dev_priv->irq_mask_reg);
148@@ -306,14 +311,14 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
149
150 if (dev_priv->swaps_pending > 0)
151 drm_locked_tasklet(dev, i915_vblank_tasklet);
152- I915_WRITE(PIPEASTAT,
153- pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
154- PIPE_VBLANK_INTERRUPT_STATUS);
155- I915_WRITE(PIPEBSTAT,
156- pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
157- PIPE_VBLANK_INTERRUPT_STATUS);
158 }
159
160+ if (iir & I915_ASLE_INTERRUPT)
161+ opregion_asle_intr(dev);
162+
163+ if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
164+ opregion_asle_intr(dev);
165+
166 return IRQ_HANDLED;
167 }
168
169@@ -661,10 +666,14 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
170 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
171 dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
172
173+ dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK;
174+
175 I915_WRITE(IMR, dev_priv->irq_mask_reg);
176 I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
177 (void) I915_READ(IER);
178
179+ opregion_enable_asle(dev);
180+
181 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
182 }
183
184diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
185new file mode 100644
186index 0000000..1787a0c
187--- /dev/null
188+++ b/drivers/gpu/drm/i915/i915_opregion.c
189@@ -0,0 +1,371 @@
190+/*
191+ * Copyright 2008 Intel Corporation <hong.liu@intel.com>
192+ * Copyright 2008 Red Hat <mjg@redhat.com>
193+ *
194+ * Permission is hereby granted, free of charge, to any person obtaining
195+ * a copy of this software and associated documentation files (the
196+ * "Software"), to deal in the Software without restriction, including
197+ * without limitation the rights to use, copy, modify, merge, publish,
198+ * distribute, sub license, and/or sell copies of the Software, and to
199+ * permit persons to whom the Software is furnished to do so, subject to
200+ * the following conditions:
201+ *
202+ * The above copyright notice and this permission notice (including the
203+ * next paragraph) shall be included in all copies or substantial
204+ * portions of the Software.
205+ *
206+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
207+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
208+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
209+ * NON-INFRINGEMENT. IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE
210+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
211+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
212+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
213+ * SOFTWARE.
214+ *
215+ */
216+
217+#include <linux/acpi.h>
218+
219+#include "drmP.h"
220+#include "i915_drm.h"
221+#include "i915_drv.h"
222+
223+#define PCI_ASLE 0xe4
224+#define PCI_LBPC 0xf4
225+#define PCI_ASLS 0xfc
226+
227+#define OPREGION_SZ (8*1024)
228+#define OPREGION_HEADER_OFFSET 0
229+#define OPREGION_ACPI_OFFSET 0x100
230+#define OPREGION_SWSCI_OFFSET 0x200
231+#define OPREGION_ASLE_OFFSET 0x300
232+#define OPREGION_VBT_OFFSET 0x1000
233+
234+#define OPREGION_SIGNATURE "IntelGraphicsMem"
235+#define MBOX_ACPI (1<<0)
236+#define MBOX_SWSCI (1<<1)
237+#define MBOX_ASLE (1<<2)
238+
239+struct opregion_header {
240+ u8 signature[16];
241+ u32 size;
242+ u32 opregion_ver;
243+ u8 bios_ver[32];
244+ u8 vbios_ver[16];
245+ u8 driver_ver[16];
246+ u32 mboxes;
247+ u8 reserved[164];
248+} __attribute__((packed));
249+
250+/* OpRegion mailbox #1: public ACPI methods */
251+struct opregion_acpi {
252+ u32 drdy; /* driver readiness */
253+ u32 csts; /* notification status */
254+ u32 cevt; /* current event */
255+ u8 rsvd1[20];
256+ u32 didl[8]; /* supported display devices ID list */
257+ u32 cpdl[8]; /* currently presented display list */
258+ u32 cadl[8]; /* currently active display list */
259+ u32 nadl[8]; /* next active devices list */
260+ u32 aslp; /* ASL sleep time-out */
261+ u32 tidx; /* toggle table index */
262+ u32 chpd; /* current hotplug enable indicator */
263+ u32 clid; /* current lid state*/
264+ u32 cdck; /* current docking state */
265+ u32 sxsw; /* Sx state resume */
266+ u32 evts; /* ASL supported events */
267+ u32 cnot; /* current OS notification */
268+ u32 nrdy; /* driver status */
269+ u8 rsvd2[60];
270+} __attribute__((packed));
271+
272+/* OpRegion mailbox #2: SWSCI */
273+struct opregion_swsci {
274+ u32 scic; /* SWSCI command|status|data */
275+ u32 parm; /* command parameters */
276+ u32 dslp; /* driver sleep time-out */
277+ u8 rsvd[244];
278+} __attribute__((packed));
279+
280+/* OpRegion mailbox #3: ASLE */
281+struct opregion_asle {
282+ u32 ardy; /* driver readiness */
283+ u32 aslc; /* ASLE interrupt command */
284+ u32 tche; /* technology enabled indicator */
285+ u32 alsi; /* current ALS illuminance reading */
286+ u32 bclp; /* backlight brightness to set */
287+ u32 pfit; /* panel fitting state */
288+ u32 cblv; /* current brightness level */
289+ u16 bclm[20]; /* backlight level duty cycle mapping table */
290+ u32 cpfm; /* current panel fitting mode */
291+ u32 epfm; /* enabled panel fitting modes */
292+ u8 plut[74]; /* panel LUT and identifier */
293+ u32 pfmb; /* PWM freq and min brightness */
294+ u8 rsvd[102];
295+} __attribute__((packed));
296+
297+/* ASLE irq request bits */
298+#define ASLE_SET_ALS_ILLUM (1 << 0)
299+#define ASLE_SET_BACKLIGHT (1 << 1)
300+#define ASLE_SET_PFIT (1 << 2)
301+#define ASLE_SET_PWM_FREQ (1 << 3)
302+#define ASLE_REQ_MSK 0xf
303+
304+/* response bits of ASLE irq request */
305+#define ASLE_ALS_ILLUM_FAIL (2<<10)
306+#define ASLE_BACKLIGHT_FAIL (2<<12)
307+#define ASLE_PFIT_FAIL (2<<14)
308+#define ASLE_PWM_FREQ_FAIL (2<<16)
309+
310+/* ASLE backlight brightness to set */
311+#define ASLE_BCLP_VALID (1<<31)
312+#define ASLE_BCLP_MSK (~(1<<31))
313+
314+/* ASLE panel fitting request */
315+#define ASLE_PFIT_VALID (1<<31)
316+#define ASLE_PFIT_CENTER (1<<0)
317+#define ASLE_PFIT_STRETCH_TEXT (1<<1)
318+#define ASLE_PFIT_STRETCH_GFX (1<<2)
319+
320+/* PWM frequency and minimum brightness */
321+#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
322+#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
323+#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
324+#define ASLE_PFMB_PWM_VALID (1<<31)
325+
326+#define ASLE_CBLV_VALID (1<<31)
327+
328+static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
329+{
330+ struct drm_i915_private *dev_priv = dev->dev_private;
331+ struct opregion_asle *asle = dev_priv->opregion.asle;
332+ u32 blc_pwm_ctl, blc_pwm_ctl2;
333+
334+ if (!(bclp & ASLE_BCLP_VALID))
335+ return ASLE_BACKLIGHT_FAIL;
336+
337+ bclp &= ASLE_BCLP_MSK;
338+ if (bclp < 0 || bclp > 255)
339+ return ASLE_BACKLIGHT_FAIL;
340+
341+ blc_pwm_ctl = I915_READ(BLC_PWM_CTL);
342+ blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
343+ blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2);
344+
345+ if (blc_pwm_ctl2 & BLM_COMBINATION_MODE)
346+ pci_write_config_dword(dev->pdev, PCI_LBPC, bclp);
347+ else
348+ I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | ((bclp * 0x101)-1));
349+
350+ asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID;
351+
352+ return 0;
353+}
354+
355+static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi)
356+{
357+ /* alsi is the current ALS reading in lux. 0 indicates below sensor
358+ range, 0xffff indicates above sensor range. 1-0xfffe are valid */
359+ return 0;
360+}
361+
362+static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb)
363+{
364+ struct drm_i915_private *dev_priv = dev->dev_private;
365+ if (pfmb & ASLE_PFMB_PWM_VALID) {
366+ u32 blc_pwm_ctl = I915_READ(BLC_PWM_CTL);
367+ u32 pwm = pfmb & ASLE_PFMB_PWM_MASK;
368+ blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK;
369+ pwm = pwm >> 9;
370+ /* FIXME - what do we do with the PWM? */
371+ }
372+ return 0;
373+}
374+
375+static u32 asle_set_pfit(struct drm_device *dev, u32 pfit)
376+{
377+ /* Panel fitting is currently controlled by the X code, so this is a
378+ noop until modesetting support works fully */
379+ if (!(pfit & ASLE_PFIT_VALID))
380+ return ASLE_PFIT_FAIL;
381+ return 0;
382+}
383+
384+void opregion_asle_intr(struct drm_device *dev)
385+{
386+ struct drm_i915_private *dev_priv = dev->dev_private;
387+ struct opregion_asle *asle = dev_priv->opregion.asle;
388+ u32 asle_stat = 0;
389+ u32 asle_req;
390+
391+ if (!asle)
392+ return;
393+
394+ asle_req = asle->aslc & ASLE_REQ_MSK;
395+
396+ if (!asle_req) {
397+ DRM_DEBUG("non asle set request??\n");
398+ return;
399+ }
400+
401+ if (asle_req & ASLE_SET_ALS_ILLUM)
402+ asle_stat |= asle_set_als_illum(dev, asle->alsi);
403+
404+ if (asle_req & ASLE_SET_BACKLIGHT)
405+ asle_stat |= asle_set_backlight(dev, asle->bclp);
406+
407+ if (asle_req & ASLE_SET_PFIT)
408+ asle_stat |= asle_set_pfit(dev, asle->pfit);
409+
410+ if (asle_req & ASLE_SET_PWM_FREQ)
411+ asle_stat |= asle_set_pwm_freq(dev, asle->pfmb);
412+
413+ asle->aslc = asle_stat;
414+}
415+
416+#define ASLE_ALS_EN (1<<0)
417+#define ASLE_BLC_EN (1<<1)
418+#define ASLE_PFIT_EN (1<<2)
419+#define ASLE_PFMB_EN (1<<3)
420+
421+void opregion_enable_asle(struct drm_device *dev)
422+{
423+ struct drm_i915_private *dev_priv = dev->dev_private;
424+ struct opregion_asle *asle = dev_priv->opregion.asle;
425+
426+ if (asle) {
427+ u32 pipeb_stats = I915_READ(PIPEBSTAT);
428+ if (IS_MOBILE(dev)) {
429+ /* Many devices trigger events with a write to the
430+ legacy backlight controller, so we need to ensure
431+ that it's able to generate interrupts */
432+ I915_WRITE(PIPEBSTAT, pipeb_stats |=
433+ I915_LEGACY_BLC_EVENT_ENABLE);
434+ i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT |
435+ I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
436+ } else
437+ i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT);
438+
439+ asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN |
440+ ASLE_PFMB_EN;
441+ asle->ardy = 1;
442+ }
443+}
444+
445+#define ACPI_EV_DISPLAY_SWITCH (1<<0)
446+#define ACPI_EV_LID (1<<1)
447+#define ACPI_EV_DOCK (1<<2)
448+
449+static struct intel_opregion *system_opregion;
450+
451+int intel_opregion_video_event(struct notifier_block *nb, unsigned long val,
452+ void *data)
453+{
454+ /* The only video events relevant to opregion are 0x80. These indicate
455+ either a docking event, lid switch or display switch request. In
456+ Linux, these are handled by the dock, button and video drivers.
457+ We might want to fix the video driver to be opregion-aware in
458+ future, but right now we just indicate to the firmware that the
459+ request has been handled */
460+
461+ struct opregion_acpi *acpi;
462+
463+ if (!system_opregion)
464+ return NOTIFY_DONE;
465+
466+ acpi = system_opregion->acpi;
467+ acpi->csts = 0;
468+
469+ return NOTIFY_OK;
470+}
471+
472+static struct notifier_block intel_opregion_notifier = {
473+ .notifier_call = intel_opregion_video_event,
474+};
475+
476+int intel_opregion_init(struct drm_device *dev)
477+{
478+ struct drm_i915_private *dev_priv = dev->dev_private;
479+ struct intel_opregion *opregion = &dev_priv->opregion;
480+ void *base;
481+ u32 asls, mboxes;
482+ int err = 0;
483+
484+ pci_read_config_dword(dev->pdev, PCI_ASLS, &asls);
485+ DRM_DEBUG("graphic opregion physical addr: 0x%x\n", asls);
486+ if (asls == 0) {
487+ DRM_DEBUG("ACPI OpRegion not supported!\n");
488+ return -ENOTSUPP;
489+ }
490+
491+ base = ioremap(asls, OPREGION_SZ);
492+ if (!base)
493+ return -ENOMEM;
494+
495+ opregion->header = base;
496+ if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) {
497+ DRM_DEBUG("opregion signature mismatch\n");
498+ err = -EINVAL;
499+ goto err_out;
500+ }
501+
502+ mboxes = opregion->header->mboxes;
503+ if (mboxes & MBOX_ACPI) {
504+ DRM_DEBUG("Public ACPI methods supported\n");
505+ opregion->acpi = base + OPREGION_ACPI_OFFSET;
506+ } else {
507+ DRM_DEBUG("Public ACPI methods not supported\n");
508+ err = -ENOTSUPP;
509+ goto err_out;
510+ }
511+ opregion->enabled = 1;
512+
513+ if (mboxes & MBOX_SWSCI) {
514+ DRM_DEBUG("SWSCI supported\n");
515+ opregion->swsci = base + OPREGION_SWSCI_OFFSET;
516+ }
517+ if (mboxes & MBOX_ASLE) {
518+ DRM_DEBUG("ASLE supported\n");
519+ opregion->asle = base + OPREGION_ASLE_OFFSET;
520+ }
521+
522+ /* Notify BIOS we are ready to handle ACPI video ext notifs.
523+ * Right now, all the events are handled by the ACPI video module.
524+ * We don't actually need to do anything with them. */
525+ opregion->acpi->csts = 0;
526+ opregion->acpi->drdy = 1;
527+
528+ system_opregion = opregion;
529+ register_acpi_notifier(&intel_opregion_notifier);
530+
531+ return 0;
532+
533+err_out:
534+ iounmap(opregion->header);
535+ opregion->header = NULL;
536+ return err;
537+}
538+
539+void intel_opregion_free(struct drm_device *dev)
540+{
541+ struct drm_i915_private *dev_priv = dev->dev_private;
542+ struct intel_opregion *opregion = &dev_priv->opregion;
543+
544+ if (!opregion->enabled)
545+ return;
546+
547+ opregion->acpi->drdy = 0;
548+
549+ system_opregion = NULL;
550+ unregister_acpi_notifier(&intel_opregion_notifier);
551+
552+ /* just clear all opregion memory pointers now */
553+ iounmap(opregion->header);
554+ opregion->header = NULL;
555+ opregion->acpi = NULL;
556+ opregion->swsci = NULL;
557+ opregion->asle = NULL;
558+
559+ opregion->enabled = 0;
560+}
561diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
562index 477c64e..43ad2cb 100644
563--- a/drivers/gpu/drm/i915/i915_reg.h
564+++ b/drivers/gpu/drm/i915/i915_reg.h
565@@ -740,6 +740,7 @@
566 #define BLC_PWM_CTL 0x61254
567 #define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
568 #define BLC_PWM_CTL2 0x61250 /* 965+ only */
569+#define BLM_COMBINATION_MODE (1 << 30)
570 /*
571 * This is the most significant 15 bits of the number of backlight cycles in a
572 * complete cycle of the modulated backlight control.
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0009-drm-fix-sysfs-error-path.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0009-drm-fix-sysfs-error-path.patch
new file mode 100644
index 0000000000..8dea824804
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0009-drm-fix-sysfs-error-path.patch
@@ -0,0 +1,23 @@
1commit 2e9c9eedfe0be777c051a2198dddf459adcc407b
2Author: Dave Airlie <airlied@redhat.com>
3Date: Tue Sep 2 10:06:06 2008 +1000
4
5 drm: fix sysfs error path.
6
7 Pointed out by Roel Kluin on dri-devel.
8
9 Signed-off-by: Dave Airlie <airlied@redhat.com>
10
11diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
12index af211a0..1611b9b 100644
13--- a/drivers/gpu/drm/drm_sysfs.c
14+++ b/drivers/gpu/drm/drm_sysfs.c
15@@ -184,7 +184,7 @@ int drm_sysfs_device_add(struct drm_minor *minor)
16 err_out_files:
17 if (i > 0)
18 for (j = 0; j < i; j++)
19- device_remove_file(&minor->kdev, &device_attrs[i]);
20+ device_remove_file(&minor->kdev, &device_attrs[j]);
21 device_unregister(&minor->kdev);
22 err_out:
23
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0010-i915-separate-suspend-resume-functions.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0010-i915-separate-suspend-resume-functions.patch
new file mode 100644
index 0000000000..897d50c39b
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0010-i915-separate-suspend-resume-functions.patch
@@ -0,0 +1,1079 @@
1commit a850828c640735fb410c782717c9eb7f8474e356
2Author: Jesse Barnes <jbarnes@virtuousgeek.org>
3Date: Mon Aug 25 15:11:06 2008 -0700
4
5 separate i915 suspend/resume functions into their own file
6
7 [Patch against drm-next. Consider this a trial balloon for our new Linux
8 development model.]
9
10 This is a big chunk of code. Separating it out makes it easier to change
11 without churn on the main i915_drv.c file (and there will be churn as we
12 fix bugs and add things like kernel mode setting). Also makes it easier
13 to share this file with BSD.
14
15 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
16 Signed-off-by: Dave Airlie <airlied@redhat.com>
17
18diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
19index b032808..c4bbda6 100644
20--- a/drivers/gpu/drm/i915/Makefile
21+++ b/drivers/gpu/drm/i915/Makefile
22@@ -3,7 +3,8 @@
23 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
24
25 ccflags-y := -Iinclude/drm
26-i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o
27+i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o \
28+ i915_suspend.o
29
30 i915-$(CONFIG_COMPAT) += i915_ioc32.o
31
32diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
33index d95eca2..eff66ed 100644
34--- a/drivers/gpu/drm/i915/i915_drv.c
35+++ b/drivers/gpu/drm/i915/i915_drv.c
36@@ -38,211 +38,9 @@ static struct pci_device_id pciidlist[] = {
37 i915_PCI_IDS
38 };
39
40-enum pipe {
41- PIPE_A = 0,
42- PIPE_B,
43-};
44-
45-static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
46-{
47- struct drm_i915_private *dev_priv = dev->dev_private;
48-
49- if (pipe == PIPE_A)
50- return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE);
51- else
52- return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE);
53-}
54-
55-static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
56-{
57- struct drm_i915_private *dev_priv = dev->dev_private;
58- unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
59- u32 *array;
60- int i;
61-
62- if (!i915_pipe_enabled(dev, pipe))
63- return;
64-
65- if (pipe == PIPE_A)
66- array = dev_priv->save_palette_a;
67- else
68- array = dev_priv->save_palette_b;
69-
70- for(i = 0; i < 256; i++)
71- array[i] = I915_READ(reg + (i << 2));
72-}
73-
74-static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)
75-{
76- struct drm_i915_private *dev_priv = dev->dev_private;
77- unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
78- u32 *array;
79- int i;
80-
81- if (!i915_pipe_enabled(dev, pipe))
82- return;
83-
84- if (pipe == PIPE_A)
85- array = dev_priv->save_palette_a;
86- else
87- array = dev_priv->save_palette_b;
88-
89- for(i = 0; i < 256; i++)
90- I915_WRITE(reg + (i << 2), array[i]);
91-}
92-
93-static u8 i915_read_indexed(u16 index_port, u16 data_port, u8 reg)
94-{
95- outb(reg, index_port);
96- return inb(data_port);
97-}
98-
99-static u8 i915_read_ar(u16 st01, u8 reg, u16 palette_enable)
100-{
101- inb(st01);
102- outb(palette_enable | reg, VGA_AR_INDEX);
103- return inb(VGA_AR_DATA_READ);
104-}
105-
106-static void i915_write_ar(u8 st01, u8 reg, u8 val, u16 palette_enable)
107-{
108- inb(st01);
109- outb(palette_enable | reg, VGA_AR_INDEX);
110- outb(val, VGA_AR_DATA_WRITE);
111-}
112-
113-static void i915_write_indexed(u16 index_port, u16 data_port, u8 reg, u8 val)
114-{
115- outb(reg, index_port);
116- outb(val, data_port);
117-}
118-
119-static void i915_save_vga(struct drm_device *dev)
120-{
121- struct drm_i915_private *dev_priv = dev->dev_private;
122- int i;
123- u16 cr_index, cr_data, st01;
124-
125- /* VGA color palette registers */
126- dev_priv->saveDACMASK = inb(VGA_DACMASK);
127- /* DACCRX automatically increments during read */
128- outb(0, VGA_DACRX);
129- /* Read 3 bytes of color data from each index */
130- for (i = 0; i < 256 * 3; i++)
131- dev_priv->saveDACDATA[i] = inb(VGA_DACDATA);
132-
133- /* MSR bits */
134- dev_priv->saveMSR = inb(VGA_MSR_READ);
135- if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
136- cr_index = VGA_CR_INDEX_CGA;
137- cr_data = VGA_CR_DATA_CGA;
138- st01 = VGA_ST01_CGA;
139- } else {
140- cr_index = VGA_CR_INDEX_MDA;
141- cr_data = VGA_CR_DATA_MDA;
142- st01 = VGA_ST01_MDA;
143- }
144-
145- /* CRT controller regs */
146- i915_write_indexed(cr_index, cr_data, 0x11,
147- i915_read_indexed(cr_index, cr_data, 0x11) &
148- (~0x80));
149- for (i = 0; i <= 0x24; i++)
150- dev_priv->saveCR[i] =
151- i915_read_indexed(cr_index, cr_data, i);
152- /* Make sure we don't turn off CR group 0 writes */
153- dev_priv->saveCR[0x11] &= ~0x80;
154-
155- /* Attribute controller registers */
156- inb(st01);
157- dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX);
158- for (i = 0; i <= 0x14; i++)
159- dev_priv->saveAR[i] = i915_read_ar(st01, i, 0);
160- inb(st01);
161- outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX);
162- inb(st01);
163-
164- /* Graphics controller registers */
165- for (i = 0; i < 9; i++)
166- dev_priv->saveGR[i] =
167- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, i);
168-
169- dev_priv->saveGR[0x10] =
170- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10);
171- dev_priv->saveGR[0x11] =
172- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11);
173- dev_priv->saveGR[0x18] =
174- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18);
175-
176- /* Sequencer registers */
177- for (i = 0; i < 8; i++)
178- dev_priv->saveSR[i] =
179- i915_read_indexed(VGA_SR_INDEX, VGA_SR_DATA, i);
180-}
181-
182-static void i915_restore_vga(struct drm_device *dev)
183-{
184- struct drm_i915_private *dev_priv = dev->dev_private;
185- int i;
186- u16 cr_index, cr_data, st01;
187-
188- /* MSR bits */
189- outb(dev_priv->saveMSR, VGA_MSR_WRITE);
190- if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
191- cr_index = VGA_CR_INDEX_CGA;
192- cr_data = VGA_CR_DATA_CGA;
193- st01 = VGA_ST01_CGA;
194- } else {
195- cr_index = VGA_CR_INDEX_MDA;
196- cr_data = VGA_CR_DATA_MDA;
197- st01 = VGA_ST01_MDA;
198- }
199-
200- /* Sequencer registers, don't write SR07 */
201- for (i = 0; i < 7; i++)
202- i915_write_indexed(VGA_SR_INDEX, VGA_SR_DATA, i,
203- dev_priv->saveSR[i]);
204-
205- /* CRT controller regs */
206- /* Enable CR group 0 writes */
207- i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]);
208- for (i = 0; i <= 0x24; i++)
209- i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]);
210-
211- /* Graphics controller regs */
212- for (i = 0; i < 9; i++)
213- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, i,
214- dev_priv->saveGR[i]);
215-
216- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10,
217- dev_priv->saveGR[0x10]);
218- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11,
219- dev_priv->saveGR[0x11]);
220- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18,
221- dev_priv->saveGR[0x18]);
222-
223- /* Attribute controller registers */
224- inb(st01);
225- for (i = 0; i <= 0x14; i++)
226- i915_write_ar(st01, i, dev_priv->saveAR[i], 0);
227- inb(st01); /* switch back to index mode */
228- outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX);
229- inb(st01);
230-
231- /* VGA color palette registers */
232- outb(dev_priv->saveDACMASK, VGA_DACMASK);
233- /* DACCRX automatically increments during read */
234- outb(0, VGA_DACWX);
235- /* Read 3 bytes of color data from each index */
236- for (i = 0; i < 256 * 3; i++)
237- outb(dev_priv->saveDACDATA[i], VGA_DACDATA);
238-
239-}
240-
241 static int i915_suspend(struct drm_device *dev, pm_message_t state)
242 {
243 struct drm_i915_private *dev_priv = dev->dev_private;
244- int i;
245
246 if (!dev || !dev_priv) {
247 printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv);
248@@ -254,122 +52,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
249 return 0;
250
251 pci_save_state(dev->pdev);
252- pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
253-
254- /* Display arbitration control */
255- dev_priv->saveDSPARB = I915_READ(DSPARB);
256-
257- /* Pipe & plane A info */
258- dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
259- dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
260- dev_priv->saveFPA0 = I915_READ(FPA0);
261- dev_priv->saveFPA1 = I915_READ(FPA1);
262- dev_priv->saveDPLL_A = I915_READ(DPLL_A);
263- if (IS_I965G(dev))
264- dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
265- dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
266- dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
267- dev_priv->saveHSYNC_A = I915_READ(HSYNC_A);
268- dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
269- dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
270- dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
271- dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
272-
273- dev_priv->saveDSPACNTR = I915_READ(DSPACNTR);
274- dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
275- dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
276- dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
277- dev_priv->saveDSPAADDR = I915_READ(DSPAADDR);
278- if (IS_I965G(dev)) {
279- dev_priv->saveDSPASURF = I915_READ(DSPASURF);
280- dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
281- }
282- i915_save_palette(dev, PIPE_A);
283- dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT);
284-
285- /* Pipe & plane B info */
286- dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
287- dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
288- dev_priv->saveFPB0 = I915_READ(FPB0);
289- dev_priv->saveFPB1 = I915_READ(FPB1);
290- dev_priv->saveDPLL_B = I915_READ(DPLL_B);
291- if (IS_I965G(dev))
292- dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
293- dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
294- dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
295- dev_priv->saveHSYNC_B = I915_READ(HSYNC_B);
296- dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
297- dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
298- dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
299- dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
300-
301- dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR);
302- dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
303- dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
304- dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
305- dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
306- if (IS_I965GM(dev) || IS_IGD_GM(dev)) {
307- dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
308- dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
309- }
310- i915_save_palette(dev, PIPE_B);
311- dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
312-
313- /* CRT state */
314- dev_priv->saveADPA = I915_READ(ADPA);
315
316- /* LVDS state */
317- dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
318- dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
319- dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
320- if (IS_I965G(dev))
321- dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
322- if (IS_MOBILE(dev) && !IS_I830(dev))
323- dev_priv->saveLVDS = I915_READ(LVDS);
324- if (!IS_I830(dev) && !IS_845G(dev))
325- dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
326- dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
327- dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
328- dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
329-
330- /* FIXME: save TV & SDVO state */
331-
332- /* FBC state */
333- dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
334- dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
335- dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
336- dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
337-
338- /* Interrupt state */
339- dev_priv->saveIIR = I915_READ(IIR);
340- dev_priv->saveIER = I915_READ(IER);
341- dev_priv->saveIMR = I915_READ(IMR);
342-
343- /* VGA state */
344- dev_priv->saveVGA0 = I915_READ(VGA0);
345- dev_priv->saveVGA1 = I915_READ(VGA1);
346- dev_priv->saveVGA_PD = I915_READ(VGA_PD);
347- dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
348-
349- /* Clock gating state */
350- dev_priv->saveD_STATE = I915_READ(D_STATE);
351- dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
352-
353- /* Cache mode state */
354- dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
355-
356- /* Memory Arbitration state */
357- dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
358-
359- /* Scratch space */
360- for (i = 0; i < 16; i++) {
361- dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2));
362- dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
363- }
364- for (i = 0; i < 3; i++)
365- dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
366-
367- i915_save_vga(dev);
368+ i915_save_state(dev);
369
370 intel_opregion_free(dev);
371
372@@ -384,155 +68,13 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
373
374 static int i915_resume(struct drm_device *dev)
375 {
376- struct drm_i915_private *dev_priv = dev->dev_private;
377- int i;
378-
379 pci_set_power_state(dev->pdev, PCI_D0);
380 pci_restore_state(dev->pdev);
381 if (pci_enable_device(dev->pdev))
382 return -1;
383 pci_set_master(dev->pdev);
384
385- pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
386-
387- I915_WRITE(DSPARB, dev_priv->saveDSPARB);
388-
389- /* Pipe & plane A info */
390- /* Prime the clock */
391- if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
392- I915_WRITE(DPLL_A, dev_priv->saveDPLL_A &
393- ~DPLL_VCO_ENABLE);
394- udelay(150);
395- }
396- I915_WRITE(FPA0, dev_priv->saveFPA0);
397- I915_WRITE(FPA1, dev_priv->saveFPA1);
398- /* Actually enable it */
399- I915_WRITE(DPLL_A, dev_priv->saveDPLL_A);
400- udelay(150);
401- if (IS_I965G(dev))
402- I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
403- udelay(150);
404-
405- /* Restore mode */
406- I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A);
407- I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A);
408- I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A);
409- I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
410- I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
411- I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
412- I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
413-
414- /* Restore plane info */
415- I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
416- I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
417- I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
418- I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR);
419- I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
420- if (IS_I965G(dev)) {
421- I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
422- I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
423- }
424-
425- I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
426-
427- i915_restore_palette(dev, PIPE_A);
428- /* Enable the plane */
429- I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
430- I915_WRITE(DSPAADDR, I915_READ(DSPAADDR));
431-
432- /* Pipe & plane B info */
433- if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
434- I915_WRITE(DPLL_B, dev_priv->saveDPLL_B &
435- ~DPLL_VCO_ENABLE);
436- udelay(150);
437- }
438- I915_WRITE(FPB0, dev_priv->saveFPB0);
439- I915_WRITE(FPB1, dev_priv->saveFPB1);
440- /* Actually enable it */
441- I915_WRITE(DPLL_B, dev_priv->saveDPLL_B);
442- udelay(150);
443- if (IS_I965G(dev))
444- I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
445- udelay(150);
446-
447- /* Restore mode */
448- I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B);
449- I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B);
450- I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B);
451- I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
452- I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
453- I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
454- I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
455-
456- /* Restore plane info */
457- I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
458- I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
459- I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
460- I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR);
461- I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
462- if (IS_I965G(dev)) {
463- I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
464- I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
465- }
466-
467- I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
468-
469- i915_restore_palette(dev, PIPE_B);
470- /* Enable the plane */
471- I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
472- I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
473-
474- /* CRT state */
475- I915_WRITE(ADPA, dev_priv->saveADPA);
476-
477- /* LVDS state */
478- if (IS_I965G(dev))
479- I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
480- if (IS_MOBILE(dev) && !IS_I830(dev))
481- I915_WRITE(LVDS, dev_priv->saveLVDS);
482- if (!IS_I830(dev) && !IS_845G(dev))
483- I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
484-
485- I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
486- I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
487- I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
488- I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
489- I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
490- I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
491-
492- /* FIXME: restore TV & SDVO state */
493-
494- /* FBC info */
495- I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
496- I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
497- I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
498- I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
499-
500- /* VGA state */
501- I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
502- I915_WRITE(VGA0, dev_priv->saveVGA0);
503- I915_WRITE(VGA1, dev_priv->saveVGA1);
504- I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
505- udelay(150);
506-
507- /* Clock gating state */
508- I915_WRITE (D_STATE, dev_priv->saveD_STATE);
509- I915_WRITE(CG_2D_DIS, dev_priv->saveCG_2D_DIS);
510-
511- /* Cache mode state */
512- I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
513-
514- /* Memory arbitration state */
515- I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
516-
517- for (i = 0; i < 16; i++) {
518- I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
519- I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
520- }
521- for (i = 0; i < 3; i++)
522- I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
523-
524- i915_restore_vga(dev);
525+ i915_restore_state(dev);
526
527 intel_opregion_init(dev);
528
529diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
530index e4bd01c..a82b487 100644
531--- a/drivers/gpu/drm/i915/i915_drv.h
532+++ b/drivers/gpu/drm/i915/i915_drv.h
533@@ -41,6 +41,11 @@
534 #define DRIVER_DESC "Intel Graphics"
535 #define DRIVER_DATE "20060119"
536
537+enum pipe {
538+ PIPE_A = 0,
539+ PIPE_B,
540+};
541+
542 /* Interface history:
543 *
544 * 1.1: Original.
545@@ -269,6 +274,10 @@ extern void i915_mem_takedown(struct mem_block **heap);
546 extern void i915_mem_release(struct drm_device * dev,
547 struct drm_file *file_priv, struct mem_block *heap);
548
549+/* i915_suspend.c */
550+extern int i915_save_state(struct drm_device *dev);
551+extern int i915_restore_state(struct drm_device *dev);
552+
553 /* i915_opregion.c */
554 extern int intel_opregion_init(struct drm_device *dev);
555 extern void intel_opregion_free(struct drm_device *dev);
556@@ -279,6 +288,8 @@ extern void opregion_enable_asle(struct drm_device *dev);
557 #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
558 #define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
559 #define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val))
560+#define I915_READ8(reg) DRM_READ8(dev_priv->mmio_map, (reg))
561+#define I915_WRITE8(reg,val) DRM_WRITE8(dev_priv->mmio_map, (reg), (val))
562
563 #define I915_VERBOSE 0
564
565diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
566new file mode 100644
567index 0000000..e0c1fe4
568--- /dev/null
569+++ b/drivers/gpu/drm/i915/i915_suspend.c
570@@ -0,0 +1,509 @@
571+/*
572+ *
573+ * Copyright 2008 (c) Intel Corporation
574+ * Jesse Barnes <jbarnes@virtuousgeek.org>
575+ *
576+ * Permission is hereby granted, free of charge, to any person obtaining a
577+ * copy of this software and associated documentation files (the
578+ * "Software"), to deal in the Software without restriction, including
579+ * without limitation the rights to use, copy, modify, merge, publish,
580+ * distribute, sub license, and/or sell copies of the Software, and to
581+ * permit persons to whom the Software is furnished to do so, subject to
582+ * the following conditions:
583+ *
584+ * The above copyright notice and this permission notice (including the
585+ * next paragraph) shall be included in all copies or substantial portions
586+ * of the Software.
587+ *
588+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
589+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
590+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
591+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
592+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
593+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
594+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
595+ */
596+
597+#include "drmP.h"
598+#include "drm.h"
599+#include "i915_drm.h"
600+#include "i915_drv.h"
601+
602+static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
603+{
604+ struct drm_i915_private *dev_priv = dev->dev_private;
605+
606+ if (pipe == PIPE_A)
607+ return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE);
608+ else
609+ return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE);
610+}
611+
612+static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
613+{
614+ struct drm_i915_private *dev_priv = dev->dev_private;
615+ unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
616+ u32 *array;
617+ int i;
618+
619+ if (!i915_pipe_enabled(dev, pipe))
620+ return;
621+
622+ if (pipe == PIPE_A)
623+ array = dev_priv->save_palette_a;
624+ else
625+ array = dev_priv->save_palette_b;
626+
627+ for(i = 0; i < 256; i++)
628+ array[i] = I915_READ(reg + (i << 2));
629+}
630+
631+static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)
632+{
633+ struct drm_i915_private *dev_priv = dev->dev_private;
634+ unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
635+ u32 *array;
636+ int i;
637+
638+ if (!i915_pipe_enabled(dev, pipe))
639+ return;
640+
641+ if (pipe == PIPE_A)
642+ array = dev_priv->save_palette_a;
643+ else
644+ array = dev_priv->save_palette_b;
645+
646+ for(i = 0; i < 256; i++)
647+ I915_WRITE(reg + (i << 2), array[i]);
648+}
649+
650+static u8 i915_read_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg)
651+{
652+ struct drm_i915_private *dev_priv = dev->dev_private;
653+
654+ I915_WRITE8(index_port, reg);
655+ return I915_READ8(data_port);
656+}
657+
658+static u8 i915_read_ar(struct drm_device *dev, u16 st01, u8 reg, u16 palette_enable)
659+{
660+ struct drm_i915_private *dev_priv = dev->dev_private;
661+
662+ I915_READ8(st01);
663+ I915_WRITE8(VGA_AR_INDEX, palette_enable | reg);
664+ return I915_READ8(VGA_AR_DATA_READ);
665+}
666+
667+static void i915_write_ar(struct drm_device *dev, u16 st01, u8 reg, u8 val, u16 palette_enable)
668+{
669+ struct drm_i915_private *dev_priv = dev->dev_private;
670+
671+ I915_READ8(st01);
672+ I915_WRITE8(VGA_AR_INDEX, palette_enable | reg);
673+ I915_WRITE8(VGA_AR_DATA_WRITE, val);
674+}
675+
676+static void i915_write_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg, u8 val)
677+{
678+ struct drm_i915_private *dev_priv = dev->dev_private;
679+
680+ I915_WRITE8(index_port, reg);
681+ I915_WRITE8(data_port, val);
682+}
683+
684+static void i915_save_vga(struct drm_device *dev)
685+{
686+ struct drm_i915_private *dev_priv = dev->dev_private;
687+ int i;
688+ u16 cr_index, cr_data, st01;
689+
690+ /* VGA color palette registers */
691+ dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK);
692+ /* DACCRX automatically increments during read */
693+ I915_WRITE8(VGA_DACRX, 0);
694+ /* Read 3 bytes of color data from each index */
695+ for (i = 0; i < 256 * 3; i++)
696+ dev_priv->saveDACDATA[i] = I915_READ8(VGA_DACDATA);
697+
698+ /* MSR bits */
699+ dev_priv->saveMSR = I915_READ8(VGA_MSR_READ);
700+ if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
701+ cr_index = VGA_CR_INDEX_CGA;
702+ cr_data = VGA_CR_DATA_CGA;
703+ st01 = VGA_ST01_CGA;
704+ } else {
705+ cr_index = VGA_CR_INDEX_MDA;
706+ cr_data = VGA_CR_DATA_MDA;
707+ st01 = VGA_ST01_MDA;
708+ }
709+
710+ /* CRT controller regs */
711+ i915_write_indexed(dev, cr_index, cr_data, 0x11,
712+ i915_read_indexed(dev, cr_index, cr_data, 0x11) &
713+ (~0x80));
714+ for (i = 0; i <= 0x24; i++)
715+ dev_priv->saveCR[i] =
716+ i915_read_indexed(dev, cr_index, cr_data, i);
717+ /* Make sure we don't turn off CR group 0 writes */
718+ dev_priv->saveCR[0x11] &= ~0x80;
719+
720+ /* Attribute controller registers */
721+ I915_READ8(st01);
722+ dev_priv->saveAR_INDEX = I915_READ8(VGA_AR_INDEX);
723+ for (i = 0; i <= 0x14; i++)
724+ dev_priv->saveAR[i] = i915_read_ar(dev, st01, i, 0);
725+ I915_READ8(st01);
726+ I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX);
727+ I915_READ8(st01);
728+
729+ /* Graphics controller registers */
730+ for (i = 0; i < 9; i++)
731+ dev_priv->saveGR[i] =
732+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i);
733+
734+ dev_priv->saveGR[0x10] =
735+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10);
736+ dev_priv->saveGR[0x11] =
737+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11);
738+ dev_priv->saveGR[0x18] =
739+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18);
740+
741+ /* Sequencer registers */
742+ for (i = 0; i < 8; i++)
743+ dev_priv->saveSR[i] =
744+ i915_read_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i);
745+}
746+
747+static void i915_restore_vga(struct drm_device *dev)
748+{
749+ struct drm_i915_private *dev_priv = dev->dev_private;
750+ int i;
751+ u16 cr_index, cr_data, st01;
752+
753+ /* MSR bits */
754+ I915_WRITE8(VGA_MSR_WRITE, dev_priv->saveMSR);
755+ if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
756+ cr_index = VGA_CR_INDEX_CGA;
757+ cr_data = VGA_CR_DATA_CGA;
758+ st01 = VGA_ST01_CGA;
759+ } else {
760+ cr_index = VGA_CR_INDEX_MDA;
761+ cr_data = VGA_CR_DATA_MDA;
762+ st01 = VGA_ST01_MDA;
763+ }
764+
765+ /* Sequencer registers, don't write SR07 */
766+ for (i = 0; i < 7; i++)
767+ i915_write_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i,
768+ dev_priv->saveSR[i]);
769+
770+ /* CRT controller regs */
771+ /* Enable CR group 0 writes */
772+ i915_write_indexed(dev, cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]);
773+ for (i = 0; i <= 0x24; i++)
774+ i915_write_indexed(dev, cr_index, cr_data, i, dev_priv->saveCR[i]);
775+
776+ /* Graphics controller regs */
777+ for (i = 0; i < 9; i++)
778+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i,
779+ dev_priv->saveGR[i]);
780+
781+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10,
782+ dev_priv->saveGR[0x10]);
783+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11,
784+ dev_priv->saveGR[0x11]);
785+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18,
786+ dev_priv->saveGR[0x18]);
787+
788+ /* Attribute controller registers */
789+ I915_READ8(st01); /* switch back to index mode */
790+ for (i = 0; i <= 0x14; i++)
791+ i915_write_ar(dev, st01, i, dev_priv->saveAR[i], 0);
792+ I915_READ8(st01); /* switch back to index mode */
793+ I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX | 0x20);
794+ I915_READ8(st01);
795+
796+ /* VGA color palette registers */
797+ I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK);
798+ /* DACCRX automatically increments during read */
799+ I915_WRITE8(VGA_DACWX, 0);
800+ /* Read 3 bytes of color data from each index */
801+ for (i = 0; i < 256 * 3; i++)
802+ I915_WRITE8(VGA_DACDATA, dev_priv->saveDACDATA[i]);
803+
804+}
805+
806+int i915_save_state(struct drm_device *dev)
807+{
808+ struct drm_i915_private *dev_priv = dev->dev_private;
809+ int i;
810+
811+ pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
812+
813+ /* Display arbitration control */
814+ dev_priv->saveDSPARB = I915_READ(DSPARB);
815+
816+ /* Pipe & plane A info */
817+ dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
818+ dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
819+ dev_priv->saveFPA0 = I915_READ(FPA0);
820+ dev_priv->saveFPA1 = I915_READ(FPA1);
821+ dev_priv->saveDPLL_A = I915_READ(DPLL_A);
822+ if (IS_I965G(dev))
823+ dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
824+ dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
825+ dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
826+ dev_priv->saveHSYNC_A = I915_READ(HSYNC_A);
827+ dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
828+ dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
829+ dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
830+ dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
831+
832+ dev_priv->saveDSPACNTR = I915_READ(DSPACNTR);
833+ dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
834+ dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
835+ dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
836+ dev_priv->saveDSPAADDR = I915_READ(DSPAADDR);
837+ if (IS_I965G(dev)) {
838+ dev_priv->saveDSPASURF = I915_READ(DSPASURF);
839+ dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
840+ }
841+ i915_save_palette(dev, PIPE_A);
842+ dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT);
843+
844+ /* Pipe & plane B info */
845+ dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
846+ dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
847+ dev_priv->saveFPB0 = I915_READ(FPB0);
848+ dev_priv->saveFPB1 = I915_READ(FPB1);
849+ dev_priv->saveDPLL_B = I915_READ(DPLL_B);
850+ if (IS_I965G(dev))
851+ dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
852+ dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
853+ dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
854+ dev_priv->saveHSYNC_B = I915_READ(HSYNC_B);
855+ dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
856+ dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
857+ dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
858+ dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
859+
860+ dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR);
861+ dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
862+ dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
863+ dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
864+ dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
865+ if (IS_I965GM(dev) || IS_IGD_GM(dev)) {
866+ dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
867+ dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
868+ }
869+ i915_save_palette(dev, PIPE_B);
870+ dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
871+
872+ /* CRT state */
873+ dev_priv->saveADPA = I915_READ(ADPA);
874+
875+ /* LVDS state */
876+ dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
877+ dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
878+ dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
879+ if (IS_I965G(dev))
880+ dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
881+ if (IS_MOBILE(dev) && !IS_I830(dev))
882+ dev_priv->saveLVDS = I915_READ(LVDS);
883+ if (!IS_I830(dev) && !IS_845G(dev))
884+ dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
885+ dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
886+ dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
887+ dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
888+
889+ /* FIXME: save TV & SDVO state */
890+
891+ /* FBC state */
892+ dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
893+ dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
894+ dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
895+ dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
896+
897+ /* Interrupt state */
898+ dev_priv->saveIIR = I915_READ(IIR);
899+ dev_priv->saveIER = I915_READ(IER);
900+ dev_priv->saveIMR = I915_READ(IMR);
901+
902+ /* VGA state */
903+ dev_priv->saveVGA0 = I915_READ(VGA0);
904+ dev_priv->saveVGA1 = I915_READ(VGA1);
905+ dev_priv->saveVGA_PD = I915_READ(VGA_PD);
906+ dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
907+
908+ /* Clock gating state */
909+ dev_priv->saveD_STATE = I915_READ(D_STATE);
910+ dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
911+
912+ /* Cache mode state */
913+ dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
914+
915+ /* Memory Arbitration state */
916+ dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
917+
918+ /* Scratch space */
919+ for (i = 0; i < 16; i++) {
920+ dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2));
921+ dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
922+ }
923+ for (i = 0; i < 3; i++)
924+ dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
925+
926+ i915_save_vga(dev);
927+
928+ return 0;
929+}
930+
931+int i915_restore_state(struct drm_device *dev)
932+{
933+ struct drm_i915_private *dev_priv = dev->dev_private;
934+ int i;
935+
936+ pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
937+
938+ I915_WRITE(DSPARB, dev_priv->saveDSPARB);
939+
940+ /* Pipe & plane A info */
941+ /* Prime the clock */
942+ if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
943+ I915_WRITE(DPLL_A, dev_priv->saveDPLL_A &
944+ ~DPLL_VCO_ENABLE);
945+ DRM_UDELAY(150);
946+ }
947+ I915_WRITE(FPA0, dev_priv->saveFPA0);
948+ I915_WRITE(FPA1, dev_priv->saveFPA1);
949+ /* Actually enable it */
950+ I915_WRITE(DPLL_A, dev_priv->saveDPLL_A);
951+ DRM_UDELAY(150);
952+ if (IS_I965G(dev))
953+ I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
954+ DRM_UDELAY(150);
955+
956+ /* Restore mode */
957+ I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A);
958+ I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A);
959+ I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A);
960+ I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
961+ I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
962+ I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
963+ I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
964+
965+ /* Restore plane info */
966+ I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
967+ I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
968+ I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
969+ I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR);
970+ I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
971+ if (IS_I965G(dev)) {
972+ I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
973+ I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
974+ }
975+
976+ I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
977+
978+ i915_restore_palette(dev, PIPE_A);
979+ /* Enable the plane */
980+ I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
981+ I915_WRITE(DSPAADDR, I915_READ(DSPAADDR));
982+
983+ /* Pipe & plane B info */
984+ if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
985+ I915_WRITE(DPLL_B, dev_priv->saveDPLL_B &
986+ ~DPLL_VCO_ENABLE);
987+ DRM_UDELAY(150);
988+ }
989+ I915_WRITE(FPB0, dev_priv->saveFPB0);
990+ I915_WRITE(FPB1, dev_priv->saveFPB1);
991+ /* Actually enable it */
992+ I915_WRITE(DPLL_B, dev_priv->saveDPLL_B);
993+ DRM_UDELAY(150);
994+ if (IS_I965G(dev))
995+ I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
996+ DRM_UDELAY(150);
997+
998+ /* Restore mode */
999+ I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B);
1000+ I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B);
1001+ I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B);
1002+ I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
1003+ I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
1004+ I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
1005+ I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
1006+
1007+ /* Restore plane info */
1008+ I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
1009+ I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
1010+ I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
1011+ I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR);
1012+ I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
1013+ if (IS_I965G(dev)) {
1014+ I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
1015+ I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
1016+ }
1017+
1018+ I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
1019+
1020+ i915_restore_palette(dev, PIPE_B);
1021+ /* Enable the plane */
1022+ I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
1023+ I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
1024+
1025+ /* CRT state */
1026+ I915_WRITE(ADPA, dev_priv->saveADPA);
1027+
1028+ /* LVDS state */
1029+ if (IS_I965G(dev))
1030+ I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
1031+ if (IS_MOBILE(dev) && !IS_I830(dev))
1032+ I915_WRITE(LVDS, dev_priv->saveLVDS);
1033+ if (!IS_I830(dev) && !IS_845G(dev))
1034+ I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
1035+
1036+ I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
1037+ I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
1038+ I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
1039+ I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
1040+ I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
1041+ I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
1042+
1043+ /* FIXME: restore TV & SDVO state */
1044+
1045+ /* FBC info */
1046+ I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
1047+ I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
1048+ I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
1049+ I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
1050+
1051+ /* VGA state */
1052+ I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
1053+ I915_WRITE(VGA0, dev_priv->saveVGA0);
1054+ I915_WRITE(VGA1, dev_priv->saveVGA1);
1055+ I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
1056+ DRM_UDELAY(150);
1057+
1058+ /* Clock gating state */
1059+ I915_WRITE (D_STATE, dev_priv->saveD_STATE);
1060+ I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS);
1061+
1062+ /* Cache mode state */
1063+ I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
1064+
1065+ /* Memory arbitration state */
1066+ I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
1067+
1068+ for (i = 0; i < 16; i++) {
1069+ I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
1070+ I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
1071+ }
1072+ for (i = 0; i < 3; i++)
1073+ I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
1074+
1075+ i915_restore_vga(dev);
1076+
1077+ return 0;
1078+}
1079+
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0011-drm-vblank-rework.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0011-drm-vblank-rework.patch
new file mode 100644
index 0000000000..6161a71f04
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0011-drm-vblank-rework.patch
@@ -0,0 +1,1534 @@
1commit 2aebb4e4e62d09b4a95be7be7c24a7f6528385b7
2Author: Jesse Barnes <jbarnes@virtuousgeek.org>
3Date: Tue Sep 30 12:14:26 2008 -0700
4
5 drm: Rework vblank-wait handling to allow interrupt reduction.
6
7 Previously, drivers supporting vblank interrupt waits would run the interrupt
8 all the time, or all the time that any 3d client was running, preventing the
9 CPU from sleeping for long when the system was otherwise idle. Now, interrupts
10 are disabled any time that no client is waiting on a vblank event. The new
11 method uses vblank counters on the chipsets when the interrupts are turned
12 off, rather than counting interrupts, so that we can continue to present
13 accurate vblank numbers.
14
15 Co-author: Michel Dänzer <michel@tungstengraphics.com>
16 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
17 Signed-off-by: Eric Anholt <eric@anholt.net>
18 Signed-off-by: Dave Airlie <airlied@redhat.com>
19
20diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
21index 452c2d8..fb45fe7 100644
22--- a/drivers/gpu/drm/drm_drv.c
23+++ b/drivers/gpu/drm/drm_drv.c
24@@ -116,6 +116,8 @@ static struct drm_ioctl_desc drm_ioctls[] = {
25
26 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
27
28+ DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
29+
30 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
31 };
32
33diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
34index 61ed515..d0c13d9 100644
35--- a/drivers/gpu/drm/drm_irq.c
36+++ b/drivers/gpu/drm/drm_irq.c
37@@ -71,19 +71,131 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
38 return 0;
39 }
40
41+static void vblank_disable_fn(unsigned long arg)
42+{
43+ struct drm_device *dev = (struct drm_device *)arg;
44+ unsigned long irqflags;
45+ int i;
46+
47+ if (!dev->vblank_disable_allowed)
48+ return;
49+
50+ for (i = 0; i < dev->num_crtcs; i++) {
51+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
52+ if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
53+ dev->vblank_enabled[i]) {
54+ DRM_DEBUG("disabling vblank on crtc %d\n", i);
55+ dev->last_vblank[i] =
56+ dev->driver->get_vblank_counter(dev, i);
57+ dev->driver->disable_vblank(dev, i);
58+ dev->vblank_enabled[i] = 0;
59+ }
60+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
61+ }
62+}
63+
64+static void drm_vblank_cleanup(struct drm_device *dev)
65+{
66+ /* Bail if the driver didn't call drm_vblank_init() */
67+ if (dev->num_crtcs == 0)
68+ return;
69+
70+ del_timer(&dev->vblank_disable_timer);
71+
72+ vblank_disable_fn((unsigned long)dev);
73+
74+ drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs,
75+ DRM_MEM_DRIVER);
76+ drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs,
77+ DRM_MEM_DRIVER);
78+ drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) *
79+ dev->num_crtcs, DRM_MEM_DRIVER);
80+ drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
81+ dev->num_crtcs, DRM_MEM_DRIVER);
82+ drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) *
83+ dev->num_crtcs, DRM_MEM_DRIVER);
84+ drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs,
85+ DRM_MEM_DRIVER);
86+ drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) *
87+ dev->num_crtcs, DRM_MEM_DRIVER);
88+
89+ dev->num_crtcs = 0;
90+}
91+
92+int drm_vblank_init(struct drm_device *dev, int num_crtcs)
93+{
94+ int i, ret = -ENOMEM;
95+
96+ setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
97+ (unsigned long)dev);
98+ spin_lock_init(&dev->vbl_lock);
99+ atomic_set(&dev->vbl_signal_pending, 0);
100+ dev->num_crtcs = num_crtcs;
101+
102+ dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs,
103+ DRM_MEM_DRIVER);
104+ if (!dev->vbl_queue)
105+ goto err;
106+
107+ dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs,
108+ DRM_MEM_DRIVER);
109+ if (!dev->vbl_sigs)
110+ goto err;
111+
112+ dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
113+ DRM_MEM_DRIVER);
114+ if (!dev->_vblank_count)
115+ goto err;
116+
117+ dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs,
118+ DRM_MEM_DRIVER);
119+ if (!dev->vblank_refcount)
120+ goto err;
121+
122+ dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int),
123+ DRM_MEM_DRIVER);
124+ if (!dev->vblank_enabled)
125+ goto err;
126+
127+ dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER);
128+ if (!dev->last_vblank)
129+ goto err;
130+
131+ dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int),
132+ DRM_MEM_DRIVER);
133+ if (!dev->vblank_inmodeset)
134+ goto err;
135+
136+ /* Zero per-crtc vblank stuff */
137+ for (i = 0; i < num_crtcs; i++) {
138+ init_waitqueue_head(&dev->vbl_queue[i]);
139+ INIT_LIST_HEAD(&dev->vbl_sigs[i]);
140+ atomic_set(&dev->_vblank_count[i], 0);
141+ atomic_set(&dev->vblank_refcount[i], 0);
142+ }
143+
144+ dev->vblank_disable_allowed = 0;
145+
146+ return 0;
147+
148+err:
149+ drm_vblank_cleanup(dev);
150+ return ret;
151+}
152+EXPORT_SYMBOL(drm_vblank_init);
153+
154 /**
155 * Install IRQ handler.
156 *
157 * \param dev DRM device.
158- * \param irq IRQ number.
159 *
160- * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver
161+ * Initializes the IRQ related data. Installs the handler, calling the driver
162 * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
163 * before and after the installation.
164 */
165-static int drm_irq_install(struct drm_device * dev)
166+int drm_irq_install(struct drm_device *dev)
167 {
168- int ret;
169+ int ret = 0;
170 unsigned long sh_flags = 0;
171
172 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
173@@ -109,17 +221,6 @@ static int drm_irq_install(struct drm_device * dev)
174
175 DRM_DEBUG("irq=%d\n", dev->pdev->irq);
176
177- if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
178- init_waitqueue_head(&dev->vbl_queue);
179-
180- spin_lock_init(&dev->vbl_lock);
181-
182- INIT_LIST_HEAD(&dev->vbl_sigs);
183- INIT_LIST_HEAD(&dev->vbl_sigs2);
184-
185- dev->vbl_pending = 0;
186- }
187-
188 /* Before installing handler */
189 dev->driver->irq_preinstall(dev);
190
191@@ -141,10 +242,16 @@ static int drm_irq_install(struct drm_device * dev)
192 }
193
194 /* After installing handler */
195- dev->driver->irq_postinstall(dev);
196+ ret = dev->driver->irq_postinstall(dev);
197+ if (ret < 0) {
198+ mutex_lock(&dev->struct_mutex);
199+ dev->irq_enabled = 0;
200+ mutex_unlock(&dev->struct_mutex);
201+ }
202
203- return 0;
204+ return ret;
205 }
206+EXPORT_SYMBOL(drm_irq_install);
207
208 /**
209 * Uninstall the IRQ handler.
210@@ -174,11 +281,12 @@ int drm_irq_uninstall(struct drm_device * dev)
211
212 free_irq(dev->pdev->irq, dev);
213
214+ drm_vblank_cleanup(dev);
215+
216 dev->locked_tasklet_func = NULL;
217
218 return 0;
219 }
220-
221 EXPORT_SYMBOL(drm_irq_uninstall);
222
223 /**
224@@ -218,6 +326,174 @@ int drm_control(struct drm_device *dev, void *data,
225 }
226
227 /**
228+ * drm_vblank_count - retrieve "cooked" vblank counter value
229+ * @dev: DRM device
230+ * @crtc: which counter to retrieve
231+ *
232+ * Fetches the "cooked" vblank count value that represents the number of
233+ * vblank events since the system was booted, including lost events due to
234+ * modesetting activity.
235+ */
236+u32 drm_vblank_count(struct drm_device *dev, int crtc)
237+{
238+ return atomic_read(&dev->_vblank_count[crtc]);
239+}
240+EXPORT_SYMBOL(drm_vblank_count);
241+
242+/**
243+ * drm_update_vblank_count - update the master vblank counter
244+ * @dev: DRM device
245+ * @crtc: counter to update
246+ *
247+ * Call back into the driver to update the appropriate vblank counter
248+ * (specified by @crtc). Deal with wraparound, if it occurred, and
249+ * update the last read value so we can deal with wraparound on the next
250+ * call if necessary.
251+ *
252+ * Only necessary when going from off->on, to account for frames we
253+ * didn't get an interrupt for.
254+ *
255+ * Note: caller must hold dev->vbl_lock since this reads & writes
256+ * device vblank fields.
257+ */
258+static void drm_update_vblank_count(struct drm_device *dev, int crtc)
259+{
260+ u32 cur_vblank, diff;
261+
262+ /*
263+ * Interrupts were disabled prior to this call, so deal with counter
264+ * wrap if needed.
265+ * NOTE! It's possible we lost a full dev->max_vblank_count events
266+ * here if the register is small or we had vblank interrupts off for
267+ * a long time.
268+ */
269+ cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
270+ diff = cur_vblank - dev->last_vblank[crtc];
271+ if (cur_vblank < dev->last_vblank[crtc]) {
272+ diff += dev->max_vblank_count;
273+
274+ DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
275+ crtc, dev->last_vblank[crtc], cur_vblank, diff);
276+ }
277+
278+ DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
279+ crtc, diff);
280+
281+ atomic_add(diff, &dev->_vblank_count[crtc]);
282+}
283+
284+/**
285+ * drm_vblank_get - get a reference count on vblank events
286+ * @dev: DRM device
287+ * @crtc: which CRTC to own
288+ *
289+ * Acquire a reference count on vblank events to avoid having them disabled
290+ * while in use.
291+ *
292+ * RETURNS
293+ * Zero on success, nonzero on failure.
294+ */
295+int drm_vblank_get(struct drm_device *dev, int crtc)
296+{
297+ unsigned long irqflags;
298+ int ret = 0;
299+
300+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
301+ /* Going from 0->1 means we have to enable interrupts again */
302+ if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 &&
303+ !dev->vblank_enabled[crtc]) {
304+ ret = dev->driver->enable_vblank(dev, crtc);
305+ DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
306+ if (ret)
307+ atomic_dec(&dev->vblank_refcount[crtc]);
308+ else {
309+ dev->vblank_enabled[crtc] = 1;
310+ drm_update_vblank_count(dev, crtc);
311+ }
312+ }
313+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
314+
315+ return ret;
316+}
317+EXPORT_SYMBOL(drm_vblank_get);
318+
319+/**
320+ * drm_vblank_put - give up ownership of vblank events
321+ * @dev: DRM device
322+ * @crtc: which counter to give up
323+ *
324+ * Release ownership of a given vblank counter, turning off interrupts
325+ * if possible.
326+ */
327+void drm_vblank_put(struct drm_device *dev, int crtc)
328+{
329+ /* Last user schedules interrupt disable */
330+ if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
331+ mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
332+}
333+EXPORT_SYMBOL(drm_vblank_put);
334+
335+/**
336+ * drm_modeset_ctl - handle vblank event counter changes across mode switch
337+ * @DRM_IOCTL_ARGS: standard ioctl arguments
338+ *
339+ * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
340+ * ioctls around modesetting so that any lost vblank events are accounted for.
341+ *
342+ * Generally the counter will reset across mode sets. If interrupts are
343+ * enabled around this call, we don't have to do anything since the counter
344+ * will have already been incremented.
345+ */
346+int drm_modeset_ctl(struct drm_device *dev, void *data,
347+ struct drm_file *file_priv)
348+{
349+ struct drm_modeset_ctl *modeset = data;
350+ unsigned long irqflags;
351+ int crtc, ret = 0;
352+
353+ /* If drm_vblank_init() hasn't been called yet, just no-op */
354+ if (!dev->num_crtcs)
355+ goto out;
356+
357+ crtc = modeset->crtc;
358+ if (crtc >= dev->num_crtcs) {
359+ ret = -EINVAL;
360+ goto out;
361+ }
362+
363+ /*
364+ * To avoid all the problems that might happen if interrupts
365+ * were enabled/disabled around or between these calls, we just
366+ * have the kernel take a reference on the CRTC (just once though
367+ * to avoid corrupting the count if multiple, mismatch calls occur),
368+ * so that interrupts remain enabled in the interim.
369+ */
370+ switch (modeset->cmd) {
371+ case _DRM_PRE_MODESET:
372+ if (!dev->vblank_inmodeset[crtc]) {
373+ dev->vblank_inmodeset[crtc] = 1;
374+ drm_vblank_get(dev, crtc);
375+ }
376+ break;
377+ case _DRM_POST_MODESET:
378+ if (dev->vblank_inmodeset[crtc]) {
379+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
380+ dev->vblank_disable_allowed = 1;
381+ dev->vblank_inmodeset[crtc] = 0;
382+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
383+ drm_vblank_put(dev, crtc);
384+ }
385+ break;
386+ default:
387+ ret = -EINVAL;
388+ break;
389+ }
390+
391+out:
392+ return ret;
393+}
394+
395+/**
396 * Wait for VBLANK.
397 *
398 * \param inode device inode.
399@@ -236,12 +512,12 @@ int drm_control(struct drm_device *dev, void *data,
400 *
401 * If a signal is not requested, then calls vblank_wait().
402 */
403-int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv)
404+int drm_wait_vblank(struct drm_device *dev, void *data,
405+ struct drm_file *file_priv)
406 {
407 union drm_wait_vblank *vblwait = data;
408- struct timeval now;
409 int ret = 0;
410- unsigned int flags, seq;
411+ unsigned int flags, seq, crtc;
412
413 if ((!dev->pdev->irq) || (!dev->irq_enabled))
414 return -EINVAL;
415@@ -255,13 +531,17 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
416 }
417
418 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
419+ crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
420
421- if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ?
422- DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
423+ if (crtc >= dev->num_crtcs)
424 return -EINVAL;
425
426- seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2
427- : &dev->vbl_received);
428+ ret = drm_vblank_get(dev, crtc);
429+ if (ret) {
430+ DRM_ERROR("failed to acquire vblank counter, %d\n", ret);
431+ return ret;
432+ }
433+ seq = drm_vblank_count(dev, crtc);
434
435 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
436 case _DRM_VBLANK_RELATIVE:
437@@ -270,7 +550,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
438 case _DRM_VBLANK_ABSOLUTE:
439 break;
440 default:
441- return -EINVAL;
442+ ret = -EINVAL;
443+ goto done;
444 }
445
446 if ((flags & _DRM_VBLANK_NEXTONMISS) &&
447@@ -280,8 +561,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
448
449 if (flags & _DRM_VBLANK_SIGNAL) {
450 unsigned long irqflags;
451- struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY)
452- ? &dev->vbl_sigs2 : &dev->vbl_sigs;
453+ struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
454 struct drm_vbl_sig *vbl_sig;
455
456 spin_lock_irqsave(&dev->vbl_lock, irqflags);
457@@ -302,22 +582,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
458 }
459 }
460
461- if (dev->vbl_pending >= 100) {
462+ if (atomic_read(&dev->vbl_signal_pending) >= 100) {
463 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
464- return -EBUSY;
465+ ret = -EBUSY;
466+ goto done;
467 }
468
469- dev->vbl_pending++;
470-
471 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
472
473- if (!
474- (vbl_sig =
475- drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) {
476- return -ENOMEM;
477+ vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
478+ DRM_MEM_DRIVER);
479+ if (!vbl_sig) {
480+ ret = -ENOMEM;
481+ goto done;
482+ }
483+
484+ ret = drm_vblank_get(dev, crtc);
485+ if (ret) {
486+ drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
487+ DRM_MEM_DRIVER);
488+ return ret;
489 }
490
491- memset((void *)vbl_sig, 0, sizeof(*vbl_sig));
492+ atomic_inc(&dev->vbl_signal_pending);
493
494 vbl_sig->sequence = vblwait->request.sequence;
495 vbl_sig->info.si_signo = vblwait->request.signal;
496@@ -331,20 +618,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
497
498 vblwait->reply.sequence = seq;
499 } else {
500- if (flags & _DRM_VBLANK_SECONDARY) {
501- if (dev->driver->vblank_wait2)
502- ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence);
503- } else if (dev->driver->vblank_wait)
504- ret =
505- dev->driver->vblank_wait(dev,
506- &vblwait->request.sequence);
507-
508- do_gettimeofday(&now);
509- vblwait->reply.tval_sec = now.tv_sec;
510- vblwait->reply.tval_usec = now.tv_usec;
511+ DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
512+ vblwait->request.sequence, crtc);
513+ DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
514+ ((drm_vblank_count(dev, crtc)
515+ - vblwait->request.sequence) <= (1 << 23)));
516+
517+ if (ret != -EINTR) {
518+ struct timeval now;
519+
520+ do_gettimeofday(&now);
521+
522+ vblwait->reply.tval_sec = now.tv_sec;
523+ vblwait->reply.tval_usec = now.tv_usec;
524+ vblwait->reply.sequence = drm_vblank_count(dev, crtc);
525+ DRM_DEBUG("returning %d to client\n",
526+ vblwait->reply.sequence);
527+ } else {
528+ DRM_DEBUG("vblank wait interrupted by signal\n");
529+ }
530 }
531
532- done:
533+done:
534+ drm_vblank_put(dev, crtc);
535 return ret;
536 }
537
538@@ -352,44 +648,57 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
539 * Send the VBLANK signals.
540 *
541 * \param dev DRM device.
542+ * \param crtc CRTC where the vblank event occurred
543 *
544 * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
545 *
546 * If a signal is not requested, then calls vblank_wait().
547 */
548-void drm_vbl_send_signals(struct drm_device * dev)
549+static void drm_vbl_send_signals(struct drm_device *dev, int crtc)
550 {
551+ struct drm_vbl_sig *vbl_sig, *tmp;
552+ struct list_head *vbl_sigs;
553+ unsigned int vbl_seq;
554 unsigned long flags;
555- int i;
556
557 spin_lock_irqsave(&dev->vbl_lock, flags);
558
559- for (i = 0; i < 2; i++) {
560- struct drm_vbl_sig *vbl_sig, *tmp;
561- struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs;
562- unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 :
563- &dev->vbl_received);
564+ vbl_sigs = &dev->vbl_sigs[crtc];
565+ vbl_seq = drm_vblank_count(dev, crtc);
566
567- list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
568- if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
569- vbl_sig->info.si_code = vbl_seq;
570- send_sig_info(vbl_sig->info.si_signo,
571- &vbl_sig->info, vbl_sig->task);
572+ list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
573+ if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
574+ vbl_sig->info.si_code = vbl_seq;
575+ send_sig_info(vbl_sig->info.si_signo,
576+ &vbl_sig->info, vbl_sig->task);
577
578- list_del(&vbl_sig->head);
579-
580- drm_free(vbl_sig, sizeof(*vbl_sig),
581- DRM_MEM_DRIVER);
582+ list_del(&vbl_sig->head);
583
584- dev->vbl_pending--;
585- }
586- }
587+ drm_free(vbl_sig, sizeof(*vbl_sig),
588+ DRM_MEM_DRIVER);
589+ atomic_dec(&dev->vbl_signal_pending);
590+ drm_vblank_put(dev, crtc);
591+ }
592 }
593
594 spin_unlock_irqrestore(&dev->vbl_lock, flags);
595 }
596
597-EXPORT_SYMBOL(drm_vbl_send_signals);
598+/**
599+ * drm_handle_vblank - handle a vblank event
600+ * @dev: DRM device
601+ * @crtc: where this event occurred
602+ *
603+ * Drivers should call this routine in their vblank interrupt handlers to
604+ * update the vblank counter and send any signals that may be pending.
605+ */
606+void drm_handle_vblank(struct drm_device *dev, int crtc)
607+{
608+ atomic_inc(&dev->_vblank_count[crtc]);
609+ DRM_WAKEUP(&dev->vbl_queue[crtc]);
610+ drm_vbl_send_signals(dev, crtc);
611+}
612+EXPORT_SYMBOL(drm_handle_vblank);
613
614 /**
615 * Tasklet wrapper function.
616diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
617index cead62f..8609ec2 100644
618--- a/drivers/gpu/drm/i915/i915_dma.c
619+++ b/drivers/gpu/drm/i915/i915_dma.c
620@@ -673,7 +673,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
621
622 switch (param->param) {
623 case I915_PARAM_IRQ_ACTIVE:
624- value = dev->irq_enabled;
625+ value = dev->pdev->irq ? 1 : 0;
626 break;
627 case I915_PARAM_ALLOW_BATCHBUFFER:
628 value = dev_priv->allow_batchbuffer ? 1 : 0;
629@@ -808,7 +808,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
630 * and the registers being closely associated.
631 */
632 if (!IS_I945G(dev) && !IS_I945GM(dev))
633- pci_enable_msi(dev->pdev);
634+ if (pci_enable_msi(dev->pdev))
635+ DRM_ERROR("failed to enable MSI\n");
636
637 intel_opregion_init(dev);
638
639diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
640index eff66ed..37af03f 100644
641--- a/drivers/gpu/drm/i915/i915_drv.c
642+++ b/drivers/gpu/drm/i915/i915_drv.c
643@@ -85,10 +85,8 @@ static struct drm_driver driver = {
644 /* don't use mtrr's here, the Xserver or user space app should
645 * deal with them for intel hardware.
646 */
647- .driver_features =
648- DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
649- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL |
650- DRIVER_IRQ_VBL2,
651+ .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP |
652+ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
653 .load = i915_driver_load,
654 .unload = i915_driver_unload,
655 .lastclose = i915_driver_lastclose,
656@@ -96,8 +94,9 @@ static struct drm_driver driver = {
657 .suspend = i915_suspend,
658 .resume = i915_resume,
659 .device_is_agp = i915_driver_device_is_agp,
660- .vblank_wait = i915_driver_vblank_wait,
661- .vblank_wait2 = i915_driver_vblank_wait2,
662+ .get_vblank_counter = i915_get_vblank_counter,
663+ .enable_vblank = i915_enable_vblank,
664+ .disable_vblank = i915_disable_vblank,
665 .irq_preinstall = i915_driver_irq_preinstall,
666 .irq_postinstall = i915_driver_irq_postinstall,
667 .irq_uninstall = i915_driver_irq_uninstall,
668diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
669index 71326ca..d1a02be 100644
670--- a/drivers/gpu/drm/i915/i915_drv.h
671+++ b/drivers/gpu/drm/i915/i915_drv.h
672@@ -83,10 +83,15 @@ struct mem_block {
673 typedef struct _drm_i915_vbl_swap {
674 struct list_head head;
675 drm_drawable_t drw_id;
676- unsigned int pipe;
677+ unsigned int plane;
678 unsigned int sequence;
679 } drm_i915_vbl_swap_t;
680
681+struct opregion_header;
682+struct opregion_acpi;
683+struct opregion_swsci;
684+struct opregion_asle;
685+
686 struct intel_opregion {
687 struct opregion_header *header;
688 struct opregion_acpi *acpi;
689@@ -105,7 +110,7 @@ typedef struct drm_i915_private {
690 drm_dma_handle_t *status_page_dmah;
691 void *hw_status_page;
692 dma_addr_t dma_status_page;
693- unsigned long counter;
694+ uint32_t counter;
695 unsigned int status_gfx_addr;
696 drm_local_map_t hws_map;
697
698@@ -247,16 +252,17 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,
699 extern int i915_irq_wait(struct drm_device *dev, void *data,
700 struct drm_file *file_priv);
701
702-extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
703-extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
704 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
705 extern void i915_driver_irq_preinstall(struct drm_device * dev);
706-extern void i915_driver_irq_postinstall(struct drm_device * dev);
707+extern int i915_driver_irq_postinstall(struct drm_device *dev);
708 extern void i915_driver_irq_uninstall(struct drm_device * dev);
709 extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
710 struct drm_file *file_priv);
711 extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
712 struct drm_file *file_priv);
713+extern int i915_enable_vblank(struct drm_device *dev, int crtc);
714+extern void i915_disable_vblank(struct drm_device *dev, int crtc);
715+extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
716 extern int i915_vblank_swap(struct drm_device *dev, void *data,
717 struct drm_file *file_priv);
718 extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
719@@ -278,6 +284,10 @@ extern void i915_mem_release(struct drm_device * dev,
720 extern int i915_save_state(struct drm_device *dev);
721 extern int i915_restore_state(struct drm_device *dev);
722
723+/* i915_suspend.c */
724+extern int i915_save_state(struct drm_device *dev);
725+extern int i915_restore_state(struct drm_device *dev);
726+
727 /* i915_opregion.c */
728 extern int intel_opregion_init(struct drm_device *dev);
729 extern void intel_opregion_free(struct drm_device *dev);
730diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
731index ae7d3a8..f875959 100644
732--- a/drivers/gpu/drm/i915/i915_irq.c
733+++ b/drivers/gpu/drm/i915/i915_irq.c
734@@ -35,9 +35,8 @@
735
736 /** These are the interrupts used by the driver */
737 #define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
738- I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | \
739- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT | \
740 I915_ASLE_INTERRUPT | \
741+ I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
742 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
743
744 void
745@@ -61,6 +60,64 @@ i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
746 }
747
748 /**
749+ * i915_get_pipe - return the the pipe associated with a given plane
750+ * @dev: DRM device
751+ * @plane: plane to look for
752+ *
753+ * The Intel Mesa & 2D drivers call the vblank routines with a plane number
754+ * rather than a pipe number, since they may not always be equal. This routine
755+ * maps the given @plane back to a pipe number.
756+ */
757+static int
758+i915_get_pipe(struct drm_device *dev, int plane)
759+{
760+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
761+ u32 dspcntr;
762+
763+ dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
764+
765+ return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0;
766+}
767+
768+/**
769+ * i915_get_plane - return the the plane associated with a given pipe
770+ * @dev: DRM device
771+ * @pipe: pipe to look for
772+ *
773+ * The Intel Mesa & 2D drivers call the vblank routines with a plane number
774+ * rather than a plane number, since they may not always be equal. This routine
775+ * maps the given @pipe back to a plane number.
776+ */
777+static int
778+i915_get_plane(struct drm_device *dev, int pipe)
779+{
780+ if (i915_get_pipe(dev, 0) == pipe)
781+ return 0;
782+ return 1;
783+}
784+
785+/**
786+ * i915_pipe_enabled - check if a pipe is enabled
787+ * @dev: DRM device
788+ * @pipe: pipe to check
789+ *
790+ * Reading certain registers when the pipe is disabled can hang the chip.
791+ * Use this routine to make sure the PLL is running and the pipe is active
792+ * before reading such registers if unsure.
793+ */
794+static int
795+i915_pipe_enabled(struct drm_device *dev, int pipe)
796+{
797+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
798+ unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
799+
800+ if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
801+ return 1;
802+
803+ return 0;
804+}
805+
806+/**
807 * Emit blits for scheduled buffer swaps.
808 *
809 * This function will be called with the HW lock held.
810@@ -71,8 +128,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
811 unsigned long irqflags;
812 struct list_head *list, *tmp, hits, *hit;
813 int nhits, nrects, slice[2], upper[2], lower[2], i;
814- unsigned counter[2] = { atomic_read(&dev->vbl_received),
815- atomic_read(&dev->vbl_received2) };
816+ unsigned counter[2];
817 struct drm_drawable_info *drw;
818 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
819 u32 cpp = dev_priv->cpp;
820@@ -94,6 +150,9 @@ static void i915_vblank_tasklet(struct drm_device *dev)
821 src_pitch >>= 2;
822 }
823
824+ counter[0] = drm_vblank_count(dev, 0);
825+ counter[1] = drm_vblank_count(dev, 1);
826+
827 DRM_DEBUG("\n");
828
829 INIT_LIST_HEAD(&hits);
830@@ -106,12 +165,14 @@ static void i915_vblank_tasklet(struct drm_device *dev)
831 list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
832 drm_i915_vbl_swap_t *vbl_swap =
833 list_entry(list, drm_i915_vbl_swap_t, head);
834+ int pipe = i915_get_pipe(dev, vbl_swap->plane);
835
836- if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23))
837+ if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
838 continue;
839
840 list_del(list);
841 dev_priv->swaps_pending--;
842+ drm_vblank_put(dev, pipe);
843
844 spin_unlock(&dev_priv->swaps_lock);
845 spin_lock(&dev->drw_lock);
846@@ -204,7 +265,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
847 drm_i915_vbl_swap_t *swap_hit =
848 list_entry(hit, drm_i915_vbl_swap_t, head);
849 struct drm_clip_rect *rect;
850- int num_rects, pipe;
851+ int num_rects, plane;
852 unsigned short top, bottom;
853
854 drw = drm_get_drawable_info(dev, swap_hit->drw_id);
855@@ -213,9 +274,9 @@ static void i915_vblank_tasklet(struct drm_device *dev)
856 continue;
857
858 rect = drw->rects;
859- pipe = swap_hit->pipe;
860- top = upper[pipe];
861- bottom = lower[pipe];
862+ plane = swap_hit->plane;
863+ top = upper[plane];
864+ bottom = lower[plane];
865
866 for (num_rects = drw->num_rects; num_rects--; rect++) {
867 int y1 = max(rect->y1, top);
868@@ -252,22 +313,54 @@ static void i915_vblank_tasklet(struct drm_device *dev)
869 }
870 }
871
872+u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
873+{
874+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
875+ unsigned long high_frame;
876+ unsigned long low_frame;
877+ u32 high1, high2, low, count;
878+ int pipe;
879+
880+ pipe = i915_get_pipe(dev, plane);
881+ high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
882+ low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
883+
884+ if (!i915_pipe_enabled(dev, pipe)) {
885+ DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
886+ return 0;
887+ }
888+
889+ /*
890+ * High & low register fields aren't synchronized, so make sure
891+ * we get a low value that's stable across two reads of the high
892+ * register.
893+ */
894+ do {
895+ high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
896+ PIPE_FRAME_HIGH_SHIFT);
897+ low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
898+ PIPE_FRAME_LOW_SHIFT);
899+ high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
900+ PIPE_FRAME_HIGH_SHIFT);
901+ } while (high1 != high2);
902+
903+ count = (high1 << 8) | low;
904+
905+ return count;
906+}
907+
908 irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
909 {
910 struct drm_device *dev = (struct drm_device *) arg;
911 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
912- u32 pipea_stats, pipeb_stats;
913 u32 iir;
914-
915- pipea_stats = I915_READ(PIPEASTAT);
916- pipeb_stats = I915_READ(PIPEBSTAT);
917+ u32 pipea_stats, pipeb_stats;
918+ int vblank = 0;
919
920 if (dev->pdev->msi_enabled)
921 I915_WRITE(IMR, ~0);
922 iir = I915_READ(IIR);
923
924- DRM_DEBUG("iir=%08x\n", iir);
925-
926 if (iir == 0) {
927 if (dev->pdev->msi_enabled) {
928 I915_WRITE(IMR, dev_priv->irq_mask_reg);
929@@ -276,48 +369,56 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
930 return IRQ_NONE;
931 }
932
933- I915_WRITE(PIPEASTAT, pipea_stats);
934- I915_WRITE(PIPEBSTAT, pipeb_stats);
935-
936- I915_WRITE(IIR, iir);
937- if (dev->pdev->msi_enabled)
938- I915_WRITE(IMR, dev_priv->irq_mask_reg);
939- (void) I915_READ(IIR); /* Flush posted writes */
940-
941- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
942-
943- if (iir & I915_USER_INTERRUPT)
944- DRM_WAKEUP(&dev_priv->irq_queue);
945-
946- if (iir & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
947- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
948- int vblank_pipe = dev_priv->vblank_pipe;
949-
950- if ((vblank_pipe &
951- (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
952- == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
953- if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
954- atomic_inc(&dev->vbl_received);
955- if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
956- atomic_inc(&dev->vbl_received2);
957- } else if (((iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
958- (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
959- ((iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
960- (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
961- atomic_inc(&dev->vbl_received);
962+ /*
963+ * Clear the PIPE(A|B)STAT regs before the IIR otherwise
964+ * we may get extra interrupts.
965+ */
966+ if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
967+ pipea_stats = I915_READ(PIPEASTAT);
968+ if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A))
969+ pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
970+ PIPE_VBLANK_INTERRUPT_ENABLE);
971+ else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
972+ PIPE_VBLANK_INTERRUPT_STATUS)) {
973+ vblank++;
974+ drm_handle_vblank(dev, i915_get_plane(dev, 0));
975+ }
976
977- DRM_WAKEUP(&dev->vbl_queue);
978- drm_vbl_send_signals(dev);
979+ I915_WRITE(PIPEASTAT, pipea_stats);
980+ }
981+ if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
982+ pipeb_stats = I915_READ(PIPEBSTAT);
983+ /* Ack the event */
984+ I915_WRITE(PIPEBSTAT, pipeb_stats);
985+
986+ /* The vblank interrupt gets enabled even if we didn't ask for
987+ it, so make sure it's shut down again */
988+ if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B))
989+ pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
990+ PIPE_VBLANK_INTERRUPT_ENABLE);
991+ else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
992+ PIPE_VBLANK_INTERRUPT_STATUS)) {
993+ vblank++;
994+ drm_handle_vblank(dev, i915_get_plane(dev, 1));
995+ }
996
997- if (dev_priv->swaps_pending > 0)
998- drm_locked_tasklet(dev, i915_vblank_tasklet);
999+ if (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS)
1000+ opregion_asle_intr(dev);
1001+ I915_WRITE(PIPEBSTAT, pipeb_stats);
1002 }
1003
1004 if (iir & I915_ASLE_INTERRUPT)
1005 opregion_asle_intr(dev);
1006
1007- if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
1008- opregion_asle_intr(dev);
1009+ dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
1010+
1011+ if (dev->pdev->msi_enabled)
1012+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
1013+ I915_WRITE(IIR, iir);
1014+ (void) I915_READ(IIR);
1015+
1016+ if (vblank && dev_priv->swaps_pending > 0)
1017+ drm_locked_tasklet(dev, i915_vblank_tasklet);
1018
1019 return IRQ_HANDLED;
1020 }
1021@@ -358,7 +459,7 @@ static void i915_user_irq_get(struct drm_device *dev)
1022 spin_unlock(&dev_priv->user_irq_lock);
1023 }
1024
1025-static void i915_user_irq_put(struct drm_device *dev)
1026+void i915_user_irq_put(struct drm_device *dev)
1027 {
1028 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1029
1030@@ -395,41 +496,10 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
1031 }
1032
1033 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
1034- return ret;
1035-}
1036-
1037-static int i915_driver_vblank_do_wait(struct drm_device *dev, unsigned int *sequence,
1038- atomic_t *counter)
1039-{
1040- drm_i915_private_t *dev_priv = dev->dev_private;
1041- unsigned int cur_vblank;
1042- int ret = 0;
1043-
1044- if (!dev_priv) {
1045- DRM_ERROR("called with no initialization\n");
1046- return -EINVAL;
1047- }
1048-
1049- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
1050- (((cur_vblank = atomic_read(counter))
1051- - *sequence) <= (1<<23)));
1052-
1053- *sequence = cur_vblank;
1054
1055 return ret;
1056 }
1057
1058-
1059-int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
1060-{
1061- return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received);
1062-}
1063-
1064-int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
1065-{
1066- return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2);
1067-}
1068-
1069 /* Needs the lock as it touches the ring.
1070 */
1071 int i915_irq_emit(struct drm_device *dev, void *data,
1072@@ -472,40 +542,88 @@ int i915_irq_wait(struct drm_device *dev, void *data,
1073 return i915_wait_irq(dev, irqwait->irq_seq);
1074 }
1075
1076+int i915_enable_vblank(struct drm_device *dev, int plane)
1077+{
1078+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1079+ int pipe = i915_get_pipe(dev, plane);
1080+ u32 pipestat_reg = 0;
1081+ u32 pipestat;
1082+
1083+ switch (pipe) {
1084+ case 0:
1085+ pipestat_reg = PIPEASTAT;
1086+ i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT);
1087+ break;
1088+ case 1:
1089+ pipestat_reg = PIPEBSTAT;
1090+ i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
1091+ break;
1092+ default:
1093+ DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
1094+ pipe);
1095+ break;
1096+ }
1097+
1098+ if (pipestat_reg) {
1099+ pipestat = I915_READ(pipestat_reg);
1100+ if (IS_I965G(dev))
1101+ pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE;
1102+ else
1103+ pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE;
1104+ /* Clear any stale interrupt status */
1105+ pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
1106+ PIPE_VBLANK_INTERRUPT_STATUS);
1107+ I915_WRITE(pipestat_reg, pipestat);
1108+ }
1109+
1110+ return 0;
1111+}
1112+
1113+void i915_disable_vblank(struct drm_device *dev, int plane)
1114+{
1115+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1116+ int pipe = i915_get_pipe(dev, plane);
1117+ u32 pipestat_reg = 0;
1118+ u32 pipestat;
1119+
1120+ switch (pipe) {
1121+ case 0:
1122+ pipestat_reg = PIPEASTAT;
1123+ i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT);
1124+ break;
1125+ case 1:
1126+ pipestat_reg = PIPEBSTAT;
1127+ i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
1128+ break;
1129+ default:
1130+ DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
1131+ pipe);
1132+ break;
1133+ }
1134+
1135+ if (pipestat_reg) {
1136+ pipestat = I915_READ(pipestat_reg);
1137+ pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
1138+ PIPE_VBLANK_INTERRUPT_ENABLE);
1139+ /* Clear any stale interrupt status */
1140+ pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
1141+ PIPE_VBLANK_INTERRUPT_STATUS);
1142+ I915_WRITE(pipestat_reg, pipestat);
1143+ }
1144+}
1145+
1146 /* Set the vblank monitor pipe
1147 */
1148 int i915_vblank_pipe_set(struct drm_device *dev, void *data,
1149 struct drm_file *file_priv)
1150 {
1151 drm_i915_private_t *dev_priv = dev->dev_private;
1152- drm_i915_vblank_pipe_t *pipe = data;
1153- u32 enable_mask = 0, disable_mask = 0;
1154
1155 if (!dev_priv) {
1156 DRM_ERROR("called with no initialization\n");
1157 return -EINVAL;
1158 }
1159
1160- if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
1161- DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe);
1162- return -EINVAL;
1163- }
1164-
1165- if (pipe->pipe & DRM_I915_VBLANK_PIPE_A)
1166- enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1167- else
1168- disable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1169-
1170- if (pipe->pipe & DRM_I915_VBLANK_PIPE_B)
1171- enable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1172- else
1173- disable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1174-
1175- i915_enable_irq(dev_priv, enable_mask);
1176- i915_disable_irq(dev_priv, disable_mask);
1177-
1178- dev_priv->vblank_pipe = pipe->pipe;
1179-
1180 return 0;
1181 }
1182
1183@@ -514,19 +632,13 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
1184 {
1185 drm_i915_private_t *dev_priv = dev->dev_private;
1186 drm_i915_vblank_pipe_t *pipe = data;
1187- u16 flag;
1188
1189 if (!dev_priv) {
1190 DRM_ERROR("called with no initialization\n");
1191 return -EINVAL;
1192 }
1193
1194- flag = I915_READ(IMR);
1195- pipe->pipe = 0;
1196- if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
1197- pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
1198- if (flag & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
1199- pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
1200+ pipe->pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
1201
1202 return 0;
1203 }
1204@@ -540,9 +652,10 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1205 drm_i915_private_t *dev_priv = dev->dev_private;
1206 drm_i915_vblank_swap_t *swap = data;
1207 drm_i915_vbl_swap_t *vbl_swap;
1208- unsigned int pipe, seqtype, curseq;
1209+ unsigned int pipe, seqtype, curseq, plane;
1210 unsigned long irqflags;
1211 struct list_head *list;
1212+ int ret;
1213
1214 if (!dev_priv) {
1215 DRM_ERROR("%s called with no initialization\n", __func__);
1216@@ -560,7 +673,8 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1217 return -EINVAL;
1218 }
1219
1220- pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
1221+ plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
1222+ pipe = i915_get_pipe(dev, plane);
1223
1224 seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
1225
1226@@ -579,7 +693,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1227
1228 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
1229
1230- curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received);
1231+ /*
1232+ * We take the ref here and put it when the swap actually completes
1233+ * in the tasklet.
1234+ */
1235+ ret = drm_vblank_get(dev, pipe);
1236+ if (ret)
1237+ return ret;
1238+ curseq = drm_vblank_count(dev, pipe);
1239
1240 if (seqtype == _DRM_VBLANK_RELATIVE)
1241 swap->sequence += curseq;
1242@@ -589,6 +710,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1243 swap->sequence = curseq + 1;
1244 } else {
1245 DRM_DEBUG("Missed target sequence\n");
1246+ drm_vblank_put(dev, pipe);
1247 return -EINVAL;
1248 }
1249 }
1250@@ -599,7 +721,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1251 vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
1252
1253 if (vbl_swap->drw_id == swap->drawable &&
1254- vbl_swap->pipe == pipe &&
1255+ vbl_swap->plane == plane &&
1256 vbl_swap->sequence == swap->sequence) {
1257 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
1258 DRM_DEBUG("Already scheduled\n");
1259@@ -611,6 +733,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1260
1261 if (dev_priv->swaps_pending >= 100) {
1262 DRM_DEBUG("Too many swaps queued\n");
1263+ drm_vblank_put(dev, pipe);
1264 return -EBUSY;
1265 }
1266
1267@@ -618,13 +741,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1268
1269 if (!vbl_swap) {
1270 DRM_ERROR("Failed to allocate memory to queue swap\n");
1271+ drm_vblank_put(dev, pipe);
1272 return -ENOMEM;
1273 }
1274
1275 DRM_DEBUG("\n");
1276
1277 vbl_swap->drw_id = swap->drawable;
1278- vbl_swap->pipe = pipe;
1279+ vbl_swap->plane = plane;
1280 vbl_swap->sequence = swap->sequence;
1281
1282 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
1283@@ -643,28 +767,32 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
1284 {
1285 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1286
1287- I915_WRITE(HWSTAM, 0xfffe);
1288- I915_WRITE(IMR, 0x0);
1289+ I915_WRITE(HWSTAM, 0xeffe);
1290+ I915_WRITE(IMR, 0xffffffff);
1291 I915_WRITE(IER, 0x0);
1292 }
1293
1294-void i915_driver_irq_postinstall(struct drm_device * dev)
1295+int i915_driver_irq_postinstall(struct drm_device *dev)
1296 {
1297 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1298+ int ret, num_pipes = 2;
1299
1300 spin_lock_init(&dev_priv->swaps_lock);
1301 INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
1302 dev_priv->swaps_pending = 0;
1303
1304- if (!dev_priv->vblank_pipe)
1305- dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
1306-
1307 /* Set initial unmasked IRQs to just the selected vblank pipes. */
1308 dev_priv->irq_mask_reg = ~0;
1309- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
1310- dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1311- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
1312- dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1313+
1314+ ret = drm_vblank_init(dev, num_pipes);
1315+ if (ret)
1316+ return ret;
1317+
1318+ dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
1319+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1320+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1321+
1322+ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
1323
1324 dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK;
1325
1326@@ -673,22 +801,29 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
1327 (void) I915_READ(IER);
1328
1329 opregion_enable_asle(dev);
1330-
1331 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
1332+
1333+ return 0;
1334 }
1335
1336 void i915_driver_irq_uninstall(struct drm_device * dev)
1337 {
1338 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1339- u16 temp;
1340+ u32 temp;
1341
1342 if (!dev_priv)
1343 return;
1344
1345- I915_WRITE(HWSTAM, 0xffff);
1346- I915_WRITE(IMR, 0xffff);
1347+ dev_priv->vblank_pipe = 0;
1348+
1349+ I915_WRITE(HWSTAM, 0xffffffff);
1350+ I915_WRITE(IMR, 0xffffffff);
1351 I915_WRITE(IER, 0x0);
1352
1353+ temp = I915_READ(PIPEASTAT);
1354+ I915_WRITE(PIPEASTAT, temp);
1355+ temp = I915_READ(PIPEBSTAT);
1356+ I915_WRITE(PIPEBSTAT, temp);
1357 temp = I915_READ(IIR);
1358 I915_WRITE(IIR, temp);
1359 }
1360diff --git a/include/drm/drm.h b/include/drm/drm.h
1361index 0864c69..15e5503 100644
1362--- a/include/drm/drm.h
1363+++ b/include/drm/drm.h
1364@@ -454,6 +454,7 @@ struct drm_irq_busid {
1365 enum drm_vblank_seq_type {
1366 _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
1367 _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
1368+ _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
1369 _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
1370 _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
1371 _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
1372@@ -486,6 +487,19 @@ union drm_wait_vblank {
1373 struct drm_wait_vblank_reply reply;
1374 };
1375
1376+#define _DRM_PRE_MODESET 1
1377+#define _DRM_POST_MODESET 2
1378+
1379+/**
1380+ * DRM_IOCTL_MODESET_CTL ioctl argument type
1381+ *
1382+ * \sa drmModesetCtl().
1383+ */
1384+struct drm_modeset_ctl {
1385+ uint32_t crtc;
1386+ uint32_t cmd;
1387+};
1388+
1389 /**
1390 * DRM_IOCTL_AGP_ENABLE ioctl argument type.
1391 *
1392@@ -570,6 +584,7 @@ struct drm_set_version {
1393 #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
1394 #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
1395 #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
1396+#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
1397
1398 #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
1399 #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
1400diff --git a/include/drm/drmP.h b/include/drm/drmP.h
1401index 1c1b13e..e79ce07 100644
1402--- a/include/drm/drmP.h
1403+++ b/include/drm/drmP.h
1404@@ -580,11 +580,54 @@ struct drm_driver {
1405 int (*kernel_context_switch) (struct drm_device *dev, int old,
1406 int new);
1407 void (*kernel_context_switch_unlock) (struct drm_device *dev);
1408- int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence);
1409- int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence);
1410 int (*dri_library_name) (struct drm_device *dev, char *buf);
1411
1412 /**
1413+ * get_vblank_counter - get raw hardware vblank counter
1414+ * @dev: DRM device
1415+ * @crtc: counter to fetch
1416+ *
1417+ * Driver callback for fetching a raw hardware vblank counter
1418+ * for @crtc. If a device doesn't have a hardware counter, the
1419+ * driver can simply return the value of drm_vblank_count and
1420+ * make the enable_vblank() and disable_vblank() hooks into no-ops,
1421+ * leaving interrupts enabled at all times.
1422+ *
1423+ * Wraparound handling and loss of events due to modesetting is dealt
1424+ * with in the DRM core code.
1425+ *
1426+ * RETURNS
1427+ * Raw vblank counter value.
1428+ */
1429+ u32 (*get_vblank_counter) (struct drm_device *dev, int crtc);
1430+
1431+ /**
1432+ * enable_vblank - enable vblank interrupt events
1433+ * @dev: DRM device
1434+ * @crtc: which irq to enable
1435+ *
1436+ * Enable vblank interrupts for @crtc. If the device doesn't have
1437+ * a hardware vblank counter, this routine should be a no-op, since
1438+ * interrupts will have to stay on to keep the count accurate.
1439+ *
1440+ * RETURNS
1441+ * Zero on success, appropriate errno if the given @crtc's vblank
1442+ * interrupt cannot be enabled.
1443+ */
1444+ int (*enable_vblank) (struct drm_device *dev, int crtc);
1445+
1446+ /**
1447+ * disable_vblank - disable vblank interrupt events
1448+ * @dev: DRM device
1449+ * @crtc: which irq to enable
1450+ *
1451+ * Disable vblank interrupts for @crtc. If the device doesn't have
1452+ * a hardware vblank counter, this routine should be a no-op, since
1453+ * interrupts will have to stay on to keep the count accurate.
1454+ */
1455+ void (*disable_vblank) (struct drm_device *dev, int crtc);
1456+
1457+ /**
1458 * Called by \c drm_device_is_agp. Typically used to determine if a
1459 * card is really attached to AGP or not.
1460 *
1461@@ -601,7 +644,7 @@ struct drm_driver {
1462
1463 irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
1464 void (*irq_preinstall) (struct drm_device *dev);
1465- void (*irq_postinstall) (struct drm_device *dev);
1466+ int (*irq_postinstall) (struct drm_device *dev);
1467 void (*irq_uninstall) (struct drm_device *dev);
1468 void (*reclaim_buffers) (struct drm_device *dev,
1469 struct drm_file * file_priv);
1470@@ -730,13 +773,28 @@ struct drm_device {
1471 /** \name VBLANK IRQ support */
1472 /*@{ */
1473
1474- wait_queue_head_t vbl_queue; /**< VBLANK wait queue */
1475- atomic_t vbl_received;
1476- atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */
1477+ /*
1478+ * At load time, disabling the vblank interrupt won't be allowed since
1479+ * old clients may not call the modeset ioctl and therefore misbehave.
1480+ * Once the modeset ioctl *has* been called though, we can safely
1481+ * disable them when unused.
1482+ */
1483+ int vblank_disable_allowed;
1484+
1485+ wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */
1486+ atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */
1487 spinlock_t vbl_lock;
1488- struct list_head vbl_sigs; /**< signal list to send on VBLANK */
1489- struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */
1490- unsigned int vbl_pending;
1491+ struct list_head *vbl_sigs; /**< signal list to send on VBLANK */
1492+ atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/
1493+ atomic_t *vblank_refcount; /* number of users of vblank interruptsper crtc */
1494+ u32 *last_vblank; /* protected by dev->vbl_lock, used */
1495+ /* for wraparound handling */
1496+ int *vblank_enabled; /* so we don't call enable more than
1497+ once per disable */
1498+ int *vblank_inmodeset; /* Display driver is setting mode */
1499+ struct timer_list vblank_disable_timer;
1500+
1501+ u32 max_vblank_count; /**< size of vblank counter register */
1502 spinlock_t tasklet_lock; /**< For drm_locked_tasklet */
1503 void (*locked_tasklet_func)(struct drm_device *dev);
1504
1505@@ -757,6 +815,7 @@ struct drm_device {
1506 struct pci_controller *hose;
1507 #endif
1508 struct drm_sg_mem *sg; /**< Scatter gather memory */
1509+ int num_crtcs; /**< Number of CRTCs on this device */
1510 void *dev_private; /**< device private data */
1511 struct drm_sigdata sigdata; /**< For block_all_signals */
1512 sigset_t sigmask;
1513@@ -990,10 +1049,19 @@ extern void drm_driver_irq_preinstall(struct drm_device *dev);
1514 extern void drm_driver_irq_postinstall(struct drm_device *dev);
1515 extern void drm_driver_irq_uninstall(struct drm_device *dev);
1516
1517+extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);
1518 extern int drm_wait_vblank(struct drm_device *dev, void *data,
1519- struct drm_file *file_priv);
1520+ struct drm_file *filp);
1521 extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq);
1522-extern void drm_vbl_send_signals(struct drm_device *dev);
1523+extern void drm_locked_tasklet(struct drm_device *dev,
1524+ void(*func)(struct drm_device *));
1525+extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
1526+extern void drm_handle_vblank(struct drm_device *dev, int crtc);
1527+extern int drm_vblank_get(struct drm_device *dev, int crtc);
1528+extern void drm_vblank_put(struct drm_device *dev, int crtc);
1529+/* Modesetting support */
1530+extern int drm_modeset_ctl(struct drm_device *dev, void *data,
1531+ struct drm_file *file_priv);
1532 extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*));
1533
1534 /* AGP/GART support (drm_agpsupport.h) */
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0012-Export-shmem_file_setup-for-DRM-GEM.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0012-Export-shmem_file_setup-for-DRM-GEM.patch
new file mode 100644
index 0000000000..642d89ba76
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0012-Export-shmem_file_setup-for-DRM-GEM.patch
@@ -0,0 +1,25 @@
1commit 48e13db26a25ebaf61f1fc28f612d6b35ddf1965
2Author: Keith Packard <keithp@keithp.com>
3Date: Fri Jun 20 00:08:06 2008 -0700
4
5 Export shmem_file_setup for DRM-GEM
6
7 GEM needs to create shmem files to back buffer objects. Though currently
8 creation of files for objects could have been driven from userland, the
9 modesetting work will require allocation of buffer objects before userland
10 is running, for boot-time message display.
11
12 Signed-off-by: Eric Anholt <eric@anholt.net>
13
14diff --git a/mm/shmem.c b/mm/shmem.c
15index 04fb4f1..515909d 100644
16--- a/mm/shmem.c
17+++ b/mm/shmem.c
18@@ -2582,6 +2582,7 @@ put_memory:
19 shmem_unacct_size(flags, size);
20 return ERR_PTR(error);
21 }
22+EXPORT_SYMBOL(shmem_file_setup);
23
24 /**
25 * shmem_zero_setup - setup a shared anonymous mapping
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch
new file mode 100644
index 0000000000..cc90d46262
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch
@@ -0,0 +1,24 @@
1commit 25eaa97fc74b225e13cf11ed8d770192ddc9355d
2Author: Eric Anholt <eric@anholt.net>
3Date: Thu Aug 21 12:53:33 2008 -0700
4
5 Export kmap_atomic_pfn for DRM-GEM.
6
7 The driver would like to map IO space directly for copying data in when
8 appropriate, to avoid CPU cache flushing for streaming writes.
9 kmap_atomic_pfn lets us avoid IPIs associated with ioremap for this process.
10
11 Signed-off-by: Eric Anholt <eric@anholt.net>
12
13diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
14index 165c871..d52e91d 100644
15--- a/arch/x86/mm/highmem_32.c
16+++ b/arch/x86/mm/highmem_32.c
17@@ -137,6 +137,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
18
19 return (void*) vaddr;
20 }
21+EXPORT_SYMBOL(kmap_atomic_pfn);
22
23 struct page *kmap_atomic_to_page(void *ptr)
24 {
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch
new file mode 100644
index 0000000000..95cca5d0c6
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch
@@ -0,0 +1,5483 @@
1commit c97398223c6a505fac2c783a624dc80e0aa5d5d0
2Author: Eric Anholt <eric@anholt.net>
3Date: Wed Jul 30 12:06:12 2008 -0700
4
5 drm: Add GEM ("graphics execution manager") to i915 driver.
6
7 GEM allows the creation of persistent buffer objects accessible by the
8 graphics device through new ioctls for managing execution of commands on the
9 device. The userland API is almost entirely driver-specific to ensure that
10 any driver building on this model can easily map the interface to individual
11 driver requirements.
12
13 GEM is used by the 2d driver for managing its internal state allocations and
14 will be used for pixmap storage to reduce memory consumption and enable
15 zero-copy GLX_EXT_texture_from_pixmap, and in the 3d driver is used to enable
16 GL_EXT_framebuffer_object and GL_ARB_pixel_buffer_object.
17
18 Signed-off-by: Eric Anholt <eric@anholt.net>
19
20diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
21index e9f9a97..74da994 100644
22--- a/drivers/gpu/drm/Makefile
23+++ b/drivers/gpu/drm/Makefile
24@@ -4,8 +4,9 @@
25
26 ccflags-y := -Iinclude/drm
27
28-drm-y := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
29- drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \
30+drm-y := drm_auth.o drm_bufs.o drm_cache.o \
31+ drm_context.o drm_dma.o drm_drawable.o \
32+ drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
33 drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
34 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
35 drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o
36diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c
37index aefa5ac..2639be2 100644
38--- a/drivers/gpu/drm/drm_agpsupport.c
39+++ b/drivers/gpu/drm/drm_agpsupport.c
40@@ -33,6 +33,7 @@
41
42 #include "drmP.h"
43 #include <linux/module.h>
44+#include <asm/agp.h>
45
46 #if __OS_HAS_AGP
47
48@@ -452,4 +453,52 @@ int drm_agp_unbind_memory(DRM_AGP_MEM * handle)
49 return agp_unbind_memory(handle);
50 }
51
52-#endif /* __OS_HAS_AGP */
53+/**
54+ * Binds a collection of pages into AGP memory at the given offset, returning
55+ * the AGP memory structure containing them.
56+ *
57+ * No reference is held on the pages during this time -- it is up to the
58+ * caller to handle that.
59+ */
60+DRM_AGP_MEM *
61+drm_agp_bind_pages(struct drm_device *dev,
62+ struct page **pages,
63+ unsigned long num_pages,
64+ uint32_t gtt_offset)
65+{
66+ DRM_AGP_MEM *mem;
67+ int ret, i;
68+
69+ DRM_DEBUG("\n");
70+
71+ mem = drm_agp_allocate_memory(dev->agp->bridge, num_pages,
72+ AGP_USER_MEMORY);
73+ if (mem == NULL) {
74+ DRM_ERROR("Failed to allocate memory for %ld pages\n",
75+ num_pages);
76+ return NULL;
77+ }
78+
79+ for (i = 0; i < num_pages; i++)
80+ mem->memory[i] = phys_to_gart(page_to_phys(pages[i]));
81+ mem->page_count = num_pages;
82+
83+ mem->is_flushed = true;
84+ ret = drm_agp_bind_memory(mem, gtt_offset / PAGE_SIZE);
85+ if (ret != 0) {
86+ DRM_ERROR("Failed to bind AGP memory: %d\n", ret);
87+ agp_free_memory(mem);
88+ return NULL;
89+ }
90+
91+ return mem;
92+}
93+EXPORT_SYMBOL(drm_agp_bind_pages);
94+
95+void drm_agp_chipset_flush(struct drm_device *dev)
96+{
97+ agp_flush_chipset(dev->agp->bridge);
98+}
99+EXPORT_SYMBOL(drm_agp_chipset_flush);
100+
101+#endif /* __OS_HAS_AGP */
102diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
103new file mode 100644
104index 0000000..9475f7d
105--- /dev/null
106+++ b/drivers/gpu/drm/drm_cache.c
107@@ -0,0 +1,76 @@
108+/**************************************************************************
109+ *
110+ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
111+ * All Rights Reserved.
112+ *
113+ * Permission is hereby granted, free of charge, to any person obtaining a
114+ * copy of this software and associated documentation files (the
115+ * "Software"), to deal in the Software without restriction, including
116+ * without limitation the rights to use, copy, modify, merge, publish,
117+ * distribute, sub license, and/or sell copies of the Software, and to
118+ * permit persons to whom the Software is furnished to do so, subject to
119+ * the following conditions:
120+ *
121+ * The above copyright notice and this permission notice (including the
122+ * next paragraph) shall be included in all copies or substantial portions
123+ * of the Software.
124+ *
125+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
126+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
127+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
128+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
129+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
130+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
131+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
132+ *
133+ **************************************************************************/
134+/*
135+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
136+ */
137+
138+#include "drmP.h"
139+
140+#if defined(CONFIG_X86)
141+static void
142+drm_clflush_page(struct page *page)
143+{
144+ uint8_t *page_virtual;
145+ unsigned int i;
146+
147+ if (unlikely(page == NULL))
148+ return;
149+
150+ page_virtual = kmap_atomic(page, KM_USER0);
151+ for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
152+ clflush(page_virtual + i);
153+ kunmap_atomic(page_virtual, KM_USER0);
154+}
155+#endif
156+
157+static void
158+drm_clflush_ipi_handler(void *null)
159+{
160+ wbinvd();
161+}
162+
163+void
164+drm_clflush_pages(struct page *pages[], unsigned long num_pages)
165+{
166+
167+#if defined(CONFIG_X86)
168+ if (cpu_has_clflush) {
169+ unsigned long i;
170+
171+ mb();
172+ for (i = 0; i < num_pages; ++i)
173+ drm_clflush_page(*pages++);
174+ mb();
175+
176+ return;
177+ }
178+#endif
179+
180+ if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0)
181+ DRM_ERROR("Timed out waiting for cache flush.\n");
182+}
183+EXPORT_SYMBOL(drm_clflush_pages);
184diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
185index fb45fe7..96f416a 100644
186--- a/drivers/gpu/drm/drm_drv.c
187+++ b/drivers/gpu/drm/drm_drv.c
188@@ -119,6 +119,10 @@ static struct drm_ioctl_desc drm_ioctls[] = {
189 DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
190
191 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
192+
193+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0),
194+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH),
195+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH),
196 };
197
198 #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
199diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
200index dcf8b4d..0d46627 100644
201--- a/drivers/gpu/drm/drm_fops.c
202+++ b/drivers/gpu/drm/drm_fops.c
203@@ -256,6 +256,9 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
204
205 INIT_LIST_HEAD(&priv->lhead);
206
207+ if (dev->driver->driver_features & DRIVER_GEM)
208+ drm_gem_open(dev, priv);
209+
210 if (dev->driver->open) {
211 ret = dev->driver->open(dev, priv);
212 if (ret < 0)
213@@ -400,6 +403,9 @@ int drm_release(struct inode *inode, struct file *filp)
214 dev->driver->reclaim_buffers(dev, file_priv);
215 }
216
217+ if (dev->driver->driver_features & DRIVER_GEM)
218+ drm_gem_release(dev, file_priv);
219+
220 drm_fasync(-1, filp, 0);
221
222 mutex_lock(&dev->ctxlist_mutex);
223diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
224new file mode 100644
225index 0000000..434155b
226--- /dev/null
227+++ b/drivers/gpu/drm/drm_gem.c
228@@ -0,0 +1,420 @@
229+/*
230+ * Copyright © 2008 Intel Corporation
231+ *
232+ * Permission is hereby granted, free of charge, to any person obtaining a
233+ * copy of this software and associated documentation files (the "Software"),
234+ * to deal in the Software without restriction, including without limitation
235+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
236+ * and/or sell copies of the Software, and to permit persons to whom the
237+ * Software is furnished to do so, subject to the following conditions:
238+ *
239+ * The above copyright notice and this permission notice (including the next
240+ * paragraph) shall be included in all copies or substantial portions of the
241+ * Software.
242+ *
243+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
244+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
245+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
246+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
247+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
248+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
249+ * IN THE SOFTWARE.
250+ *
251+ * Authors:
252+ * Eric Anholt <eric@anholt.net>
253+ *
254+ */
255+
256+#include <linux/types.h>
257+#include <linux/slab.h>
258+#include <linux/mm.h>
259+#include <linux/uaccess.h>
260+#include <linux/fs.h>
261+#include <linux/file.h>
262+#include <linux/module.h>
263+#include <linux/mman.h>
264+#include <linux/pagemap.h>
265+#include "drmP.h"
266+
267+/** @file drm_gem.c
268+ *
269+ * This file provides some of the base ioctls and library routines for
270+ * the graphics memory manager implemented by each device driver.
271+ *
272+ * Because various devices have different requirements in terms of
273+ * synchronization and migration strategies, implementing that is left up to
274+ * the driver, and all that the general API provides should be generic --
275+ * allocating objects, reading/writing data with the cpu, freeing objects.
276+ * Even there, platform-dependent optimizations for reading/writing data with
277+ * the CPU mean we'll likely hook those out to driver-specific calls. However,
278+ * the DRI2 implementation wants to have at least allocate/mmap be generic.
279+ *
280+ * The goal was to have swap-backed object allocation managed through
281+ * struct file. However, file descriptors as handles to a struct file have
282+ * two major failings:
283+ * - Process limits prevent more than 1024 or so being used at a time by
284+ * default.
285+ * - Inability to allocate high fds will aggravate the X Server's select()
286+ * handling, and likely that of many GL client applications as well.
287+ *
288+ * This led to a plan of using our own integer IDs (called handles, following
289+ * DRM terminology) to mimic fds, and implement the fd syscalls we need as
290+ * ioctls. The objects themselves will still include the struct file so
291+ * that we can transition to fds if the required kernel infrastructure shows
292+ * up at a later date, and as our interface with shmfs for memory allocation.
293+ */
294+
295+/**
296+ * Initialize the GEM device fields
297+ */
298+
299+int
300+drm_gem_init(struct drm_device *dev)
301+{
302+ spin_lock_init(&dev->object_name_lock);
303+ idr_init(&dev->object_name_idr);
304+ atomic_set(&dev->object_count, 0);
305+ atomic_set(&dev->object_memory, 0);
306+ atomic_set(&dev->pin_count, 0);
307+ atomic_set(&dev->pin_memory, 0);
308+ atomic_set(&dev->gtt_count, 0);
309+ atomic_set(&dev->gtt_memory, 0);
310+ return 0;
311+}
312+
313+/**
314+ * Allocate a GEM object of the specified size with shmfs backing store
315+ */
316+struct drm_gem_object *
317+drm_gem_object_alloc(struct drm_device *dev, size_t size)
318+{
319+ struct drm_gem_object *obj;
320+
321+ BUG_ON((size & (PAGE_SIZE - 1)) != 0);
322+
323+ obj = kcalloc(1, sizeof(*obj), GFP_KERNEL);
324+
325+ obj->dev = dev;
326+ obj->filp = shmem_file_setup("drm mm object", size, 0);
327+ if (IS_ERR(obj->filp)) {
328+ kfree(obj);
329+ return NULL;
330+ }
331+
332+ kref_init(&obj->refcount);
333+ kref_init(&obj->handlecount);
334+ obj->size = size;
335+ if (dev->driver->gem_init_object != NULL &&
336+ dev->driver->gem_init_object(obj) != 0) {
337+ fput(obj->filp);
338+ kfree(obj);
339+ return NULL;
340+ }
341+ atomic_inc(&dev->object_count);
342+ atomic_add(obj->size, &dev->object_memory);
343+ return obj;
344+}
345+EXPORT_SYMBOL(drm_gem_object_alloc);
346+
347+/**
348+ * Removes the mapping from handle to filp for this object.
349+ */
350+static int
351+drm_gem_handle_delete(struct drm_file *filp, int handle)
352+{
353+ struct drm_device *dev;
354+ struct drm_gem_object *obj;
355+
356+ /* This is gross. The idr system doesn't let us try a delete and
357+ * return an error code. It just spews if you fail at deleting.
358+ * So, we have to grab a lock around finding the object and then
359+ * doing the delete on it and dropping the refcount, or the user
360+ * could race us to double-decrement the refcount and cause a
361+ * use-after-free later. Given the frequency of our handle lookups,
362+ * we may want to use ida for number allocation and a hash table
363+ * for the pointers, anyway.
364+ */
365+ spin_lock(&filp->table_lock);
366+
367+ /* Check if we currently have a reference on the object */
368+ obj = idr_find(&filp->object_idr, handle);
369+ if (obj == NULL) {
370+ spin_unlock(&filp->table_lock);
371+ return -EINVAL;
372+ }
373+ dev = obj->dev;
374+
375+ /* Release reference and decrement refcount. */
376+ idr_remove(&filp->object_idr, handle);
377+ spin_unlock(&filp->table_lock);
378+
379+ mutex_lock(&dev->struct_mutex);
380+ drm_gem_object_handle_unreference(obj);
381+ mutex_unlock(&dev->struct_mutex);
382+
383+ return 0;
384+}
385+
386+/**
387+ * Create a handle for this object. This adds a handle reference
388+ * to the object, which includes a regular reference count. Callers
389+ * will likely want to dereference the object afterwards.
390+ */
391+int
392+drm_gem_handle_create(struct drm_file *file_priv,
393+ struct drm_gem_object *obj,
394+ int *handlep)
395+{
396+ int ret;
397+
398+ /*
399+ * Get the user-visible handle using idr.
400+ */
401+again:
402+ /* ensure there is space available to allocate a handle */
403+ if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0)
404+ return -ENOMEM;
405+
406+ /* do the allocation under our spinlock */
407+ spin_lock(&file_priv->table_lock);
408+ ret = idr_get_new_above(&file_priv->object_idr, obj, 1, handlep);
409+ spin_unlock(&file_priv->table_lock);
410+ if (ret == -EAGAIN)
411+ goto again;
412+
413+ if (ret != 0)
414+ return ret;
415+
416+ drm_gem_object_handle_reference(obj);
417+ return 0;
418+}
419+EXPORT_SYMBOL(drm_gem_handle_create);
420+
421+/** Returns a reference to the object named by the handle. */
422+struct drm_gem_object *
423+drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
424+ int handle)
425+{
426+ struct drm_gem_object *obj;
427+
428+ spin_lock(&filp->table_lock);
429+
430+ /* Check if we currently have a reference on the object */
431+ obj = idr_find(&filp->object_idr, handle);
432+ if (obj == NULL) {
433+ spin_unlock(&filp->table_lock);
434+ return NULL;
435+ }
436+
437+ drm_gem_object_reference(obj);
438+
439+ spin_unlock(&filp->table_lock);
440+
441+ return obj;
442+}
443+EXPORT_SYMBOL(drm_gem_object_lookup);
444+
445+/**
446+ * Releases the handle to an mm object.
447+ */
448+int
449+drm_gem_close_ioctl(struct drm_device *dev, void *data,
450+ struct drm_file *file_priv)
451+{
452+ struct drm_gem_close *args = data;
453+ int ret;
454+
455+ if (!(dev->driver->driver_features & DRIVER_GEM))
456+ return -ENODEV;
457+
458+ ret = drm_gem_handle_delete(file_priv, args->handle);
459+
460+ return ret;
461+}
462+
463+/**
464+ * Create a global name for an object, returning the name.
465+ *
466+ * Note that the name does not hold a reference; when the object
467+ * is freed, the name goes away.
468+ */
469+int
470+drm_gem_flink_ioctl(struct drm_device *dev, void *data,
471+ struct drm_file *file_priv)
472+{
473+ struct drm_gem_flink *args = data;
474+ struct drm_gem_object *obj;
475+ int ret;
476+
477+ if (!(dev->driver->driver_features & DRIVER_GEM))
478+ return -ENODEV;
479+
480+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
481+ if (obj == NULL)
482+ return -EINVAL;
483+
484+again:
485+ if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0)
486+ return -ENOMEM;
487+
488+ spin_lock(&dev->object_name_lock);
489+ if (obj->name) {
490+ spin_unlock(&dev->object_name_lock);
491+ return -EEXIST;
492+ }
493+ ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
494+ &obj->name);
495+ spin_unlock(&dev->object_name_lock);
496+ if (ret == -EAGAIN)
497+ goto again;
498+
499+ if (ret != 0) {
500+ mutex_lock(&dev->struct_mutex);
501+ drm_gem_object_unreference(obj);
502+ mutex_unlock(&dev->struct_mutex);
503+ return ret;
504+ }
505+
506+ /*
507+ * Leave the reference from the lookup around as the
508+ * name table now holds one
509+ */
510+ args->name = (uint64_t) obj->name;
511+
512+ return 0;
513+}
514+
515+/**
516+ * Open an object using the global name, returning a handle and the size.
517+ *
518+ * This handle (of course) holds a reference to the object, so the object
519+ * will not go away until the handle is deleted.
520+ */
521+int
522+drm_gem_open_ioctl(struct drm_device *dev, void *data,
523+ struct drm_file *file_priv)
524+{
525+ struct drm_gem_open *args = data;
526+ struct drm_gem_object *obj;
527+ int ret;
528+ int handle;
529+
530+ if (!(dev->driver->driver_features & DRIVER_GEM))
531+ return -ENODEV;
532+
533+ spin_lock(&dev->object_name_lock);
534+ obj = idr_find(&dev->object_name_idr, (int) args->name);
535+ if (obj)
536+ drm_gem_object_reference(obj);
537+ spin_unlock(&dev->object_name_lock);
538+ if (!obj)
539+ return -ENOENT;
540+
541+ ret = drm_gem_handle_create(file_priv, obj, &handle);
542+ mutex_lock(&dev->struct_mutex);
543+ drm_gem_object_unreference(obj);
544+ mutex_unlock(&dev->struct_mutex);
545+ if (ret)
546+ return ret;
547+
548+ args->handle = handle;
549+ args->size = obj->size;
550+
551+ return 0;
552+}
553+
554+/**
555+ * Called at device open time, sets up the structure for handling refcounting
556+ * of mm objects.
557+ */
558+void
559+drm_gem_open(struct drm_device *dev, struct drm_file *file_private)
560+{
561+ idr_init(&file_private->object_idr);
562+ spin_lock_init(&file_private->table_lock);
563+}
564+
565+/**
566+ * Called at device close to release the file's
567+ * handle references on objects.
568+ */
569+static int
570+drm_gem_object_release_handle(int id, void *ptr, void *data)
571+{
572+ struct drm_gem_object *obj = ptr;
573+
574+ drm_gem_object_handle_unreference(obj);
575+
576+ return 0;
577+}
578+
579+/**
580+ * Called at close time when the filp is going away.
581+ *
582+ * Releases any remaining references on objects by this filp.
583+ */
584+void
585+drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
586+{
587+ mutex_lock(&dev->struct_mutex);
588+ idr_for_each(&file_private->object_idr,
589+ &drm_gem_object_release_handle, NULL);
590+
591+ idr_destroy(&file_private->object_idr);
592+ mutex_unlock(&dev->struct_mutex);
593+}
594+
595+/**
596+ * Called after the last reference to the object has been lost.
597+ *
598+ * Frees the object
599+ */
600+void
601+drm_gem_object_free(struct kref *kref)
602+{
603+ struct drm_gem_object *obj = (struct drm_gem_object *) kref;
604+ struct drm_device *dev = obj->dev;
605+
606+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
607+
608+ if (dev->driver->gem_free_object != NULL)
609+ dev->driver->gem_free_object(obj);
610+
611+ fput(obj->filp);
612+ atomic_dec(&dev->object_count);
613+ atomic_sub(obj->size, &dev->object_memory);
614+ kfree(obj);
615+}
616+EXPORT_SYMBOL(drm_gem_object_free);
617+
618+/**
619+ * Called after the last handle to the object has been closed
620+ *
621+ * Removes any name for the object. Note that this must be
622+ * called before drm_gem_object_free or we'll be touching
623+ * freed memory
624+ */
625+void
626+drm_gem_object_handle_free(struct kref *kref)
627+{
628+ struct drm_gem_object *obj = container_of(kref,
629+ struct drm_gem_object,
630+ handlecount);
631+ struct drm_device *dev = obj->dev;
632+
633+ /* Remove any name for this object */
634+ spin_lock(&dev->object_name_lock);
635+ if (obj->name) {
636+ idr_remove(&dev->object_name_idr, obj->name);
637+ spin_unlock(&dev->object_name_lock);
638+ /*
639+ * The object name held a reference to this object, drop
640+ * that now.
641+ */
642+ drm_gem_object_unreference(obj);
643+ } else
644+ spin_unlock(&dev->object_name_lock);
645+
646+}
647+EXPORT_SYMBOL(drm_gem_object_handle_free);
648+
649diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c
650index 0177012..803bc9e 100644
651--- a/drivers/gpu/drm/drm_memory.c
652+++ b/drivers/gpu/drm/drm_memory.c
653@@ -133,6 +133,7 @@ int drm_free_agp(DRM_AGP_MEM * handle, int pages)
654 {
655 return drm_agp_free_memory(handle) ? 0 : -EINVAL;
656 }
657+EXPORT_SYMBOL(drm_free_agp);
658
659 /** Wrapper around agp_bind_memory() */
660 int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start)
661@@ -145,6 +146,7 @@ int drm_unbind_agp(DRM_AGP_MEM * handle)
662 {
663 return drm_agp_unbind_memory(handle);
664 }
665+EXPORT_SYMBOL(drm_unbind_agp);
666
667 #else /* __OS_HAS_AGP */
668 static inline void *agp_remap(unsigned long offset, unsigned long size,
669diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
670index dcff9e9..217ad7d 100644
671--- a/drivers/gpu/drm/drm_mm.c
672+++ b/drivers/gpu/drm/drm_mm.c
673@@ -169,6 +169,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent,
674
675 return child;
676 }
677+EXPORT_SYMBOL(drm_mm_get_block);
678
679 /*
680 * Put a block. Merge with the previous and / or next block if they are free.
681@@ -217,6 +218,7 @@ void drm_mm_put_block(struct drm_mm_node * cur)
682 drm_free(cur, sizeof(*cur), DRM_MEM_MM);
683 }
684 }
685+EXPORT_SYMBOL(drm_mm_put_block);
686
687 struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm,
688 unsigned long size,
689@@ -265,6 +267,7 @@ int drm_mm_clean(struct drm_mm * mm)
690
691 return (head->next->next == head);
692 }
693+EXPORT_SYMBOL(drm_mm_search_free);
694
695 int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
696 {
697@@ -273,7 +276,7 @@ int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
698
699 return drm_mm_create_tail_node(mm, start, size);
700 }
701-
702+EXPORT_SYMBOL(drm_mm_init);
703
704 void drm_mm_takedown(struct drm_mm * mm)
705 {
706diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c
707index 93b1e04..d490db4 100644
708--- a/drivers/gpu/drm/drm_proc.c
709+++ b/drivers/gpu/drm/drm_proc.c
710@@ -49,6 +49,10 @@ static int drm_queues_info(char *buf, char **start, off_t offset,
711 int request, int *eof, void *data);
712 static int drm_bufs_info(char *buf, char **start, off_t offset,
713 int request, int *eof, void *data);
714+static int drm_gem_name_info(char *buf, char **start, off_t offset,
715+ int request, int *eof, void *data);
716+static int drm_gem_object_info(char *buf, char **start, off_t offset,
717+ int request, int *eof, void *data);
718 #if DRM_DEBUG_CODE
719 static int drm_vma_info(char *buf, char **start, off_t offset,
720 int request, int *eof, void *data);
721@@ -60,13 +64,16 @@ static int drm_vma_info(char *buf, char **start, off_t offset,
722 static struct drm_proc_list {
723 const char *name; /**< file name */
724 int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/
725+ u32 driver_features; /**< Required driver features for this entry */
726 } drm_proc_list[] = {
727- {"name", drm_name_info},
728- {"mem", drm_mem_info},
729- {"vm", drm_vm_info},
730- {"clients", drm_clients_info},
731- {"queues", drm_queues_info},
732- {"bufs", drm_bufs_info},
733+ {"name", drm_name_info, 0},
734+ {"mem", drm_mem_info, 0},
735+ {"vm", drm_vm_info, 0},
736+ {"clients", drm_clients_info, 0},
737+ {"queues", drm_queues_info, 0},
738+ {"bufs", drm_bufs_info, 0},
739+ {"gem_names", drm_gem_name_info, DRIVER_GEM},
740+ {"gem_objects", drm_gem_object_info, DRIVER_GEM},
741 #if DRM_DEBUG_CODE
742 {"vma", drm_vma_info},
743 #endif
744@@ -90,8 +97,9 @@ static struct drm_proc_list {
745 int drm_proc_init(struct drm_minor *minor, int minor_id,
746 struct proc_dir_entry *root)
747 {
748+ struct drm_device *dev = minor->dev;
749 struct proc_dir_entry *ent;
750- int i, j;
751+ int i, j, ret;
752 char name[64];
753
754 sprintf(name, "%d", minor_id);
755@@ -102,23 +110,42 @@ int drm_proc_init(struct drm_minor *minor, int minor_id,
756 }
757
758 for (i = 0; i < DRM_PROC_ENTRIES; i++) {
759+ u32 features = drm_proc_list[i].driver_features;
760+
761+ if (features != 0 &&
762+ (dev->driver->driver_features & features) != features)
763+ continue;
764+
765 ent = create_proc_entry(drm_proc_list[i].name,
766 S_IFREG | S_IRUGO, minor->dev_root);
767 if (!ent) {
768 DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
769 name, drm_proc_list[i].name);
770- for (j = 0; j < i; j++)
771- remove_proc_entry(drm_proc_list[i].name,
772- minor->dev_root);
773- remove_proc_entry(name, root);
774- minor->dev_root = NULL;
775- return -1;
776+ ret = -1;
777+ goto fail;
778 }
779 ent->read_proc = drm_proc_list[i].f;
780 ent->data = minor;
781 }
782
783+ if (dev->driver->proc_init) {
784+ ret = dev->driver->proc_init(minor);
785+ if (ret) {
786+ DRM_ERROR("DRM: Driver failed to initialize "
787+ "/proc/dri.\n");
788+ goto fail;
789+ }
790+ }
791+
792 return 0;
793+ fail:
794+
795+ for (j = 0; j < i; j++)
796+ remove_proc_entry(drm_proc_list[i].name,
797+ minor->dev_root);
798+ remove_proc_entry(name, root);
799+ minor->dev_root = NULL;
800+ return ret;
801 }
802
803 /**
804@@ -133,12 +160,16 @@ int drm_proc_init(struct drm_minor *minor, int minor_id,
805 */
806 int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
807 {
808+ struct drm_device *dev = minor->dev;
809 int i;
810 char name[64];
811
812 if (!root || !minor->dev_root)
813 return 0;
814
815+ if (dev->driver->proc_cleanup)
816+ dev->driver->proc_cleanup(minor);
817+
818 for (i = 0; i < DRM_PROC_ENTRIES; i++)
819 remove_proc_entry(drm_proc_list[i].name, minor->dev_root);
820 sprintf(name, "%d", minor->index);
821@@ -480,6 +511,84 @@ static int drm_clients_info(char *buf, char **start, off_t offset,
822 return ret;
823 }
824
825+struct drm_gem_name_info_data {
826+ int len;
827+ char *buf;
828+ int eof;
829+};
830+
831+static int drm_gem_one_name_info(int id, void *ptr, void *data)
832+{
833+ struct drm_gem_object *obj = ptr;
834+ struct drm_gem_name_info_data *nid = data;
835+
836+ DRM_INFO("name %d size %d\n", obj->name, obj->size);
837+ if (nid->eof)
838+ return 0;
839+
840+ nid->len += sprintf(&nid->buf[nid->len],
841+ "%6d%9d%8d%9d\n",
842+ obj->name, obj->size,
843+ atomic_read(&obj->handlecount.refcount),
844+ atomic_read(&obj->refcount.refcount));
845+ if (nid->len > DRM_PROC_LIMIT) {
846+ nid->eof = 1;
847+ return 0;
848+ }
849+ return 0;
850+}
851+
852+static int drm_gem_name_info(char *buf, char **start, off_t offset,
853+ int request, int *eof, void *data)
854+{
855+ struct drm_minor *minor = (struct drm_minor *) data;
856+ struct drm_device *dev = minor->dev;
857+ struct drm_gem_name_info_data nid;
858+
859+ if (offset > DRM_PROC_LIMIT) {
860+ *eof = 1;
861+ return 0;
862+ }
863+
864+ nid.len = sprintf(buf, " name size handles refcount\n");
865+ nid.buf = buf;
866+ nid.eof = 0;
867+ idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, &nid);
868+
869+ *start = &buf[offset];
870+ *eof = 0;
871+ if (nid.len > request + offset)
872+ return request;
873+ *eof = 1;
874+ return nid.len - offset;
875+}
876+
877+static int drm_gem_object_info(char *buf, char **start, off_t offset,
878+ int request, int *eof, void *data)
879+{
880+ struct drm_minor *minor = (struct drm_minor *) data;
881+ struct drm_device *dev = minor->dev;
882+ int len = 0;
883+
884+ if (offset > DRM_PROC_LIMIT) {
885+ *eof = 1;
886+ return 0;
887+ }
888+
889+ *start = &buf[offset];
890+ *eof = 0;
891+ DRM_PROC_PRINT("%d objects\n", atomic_read(&dev->object_count));
892+ DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory));
893+ DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count));
894+ DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory));
895+ DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory));
896+ DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total);
897+ if (len > request + offset)
898+ return request;
899+ *eof = 1;
900+ return len - offset;
901+}
902+
903 #if DRM_DEBUG_CODE
904
905 static int drm__vma_info(char *buf, char **start, off_t offset, int request,
906diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
907index c2f584f..82f4657 100644
908--- a/drivers/gpu/drm/drm_stub.c
909+++ b/drivers/gpu/drm/drm_stub.c
910@@ -152,6 +152,15 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
911 goto error_out_unreg;
912 }
913
914+ if (driver->driver_features & DRIVER_GEM) {
915+ retcode = drm_gem_init(dev);
916+ if (retcode) {
917+ DRM_ERROR("Cannot initialize graphics execution "
918+ "manager (GEM)\n");
919+ goto error_out_unreg;
920+ }
921+ }
922+
923 return 0;
924
925 error_out_unreg:
926@@ -317,6 +326,7 @@ int drm_put_dev(struct drm_device * dev)
927 int drm_put_minor(struct drm_minor **minor_p)
928 {
929 struct drm_minor *minor = *minor_p;
930+
931 DRM_DEBUG("release secondary minor %d\n", minor->index);
932
933 if (minor->type == DRM_MINOR_LEGACY)
934diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
935index c4bbda6..5ba78e4 100644
936--- a/drivers/gpu/drm/i915/Makefile
937+++ b/drivers/gpu/drm/i915/Makefile
938@@ -4,7 +4,11 @@
939
940 ccflags-y := -Iinclude/drm
941 i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o \
942- i915_suspend.o
943+ i915_suspend.o \
944+ i915_gem.o \
945+ i915_gem_debug.o \
946+ i915_gem_proc.o \
947+ i915_gem_tiling.o
948
949 i915-$(CONFIG_COMPAT) += i915_ioc32.o
950
951diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
952index 8609ec2..3b5aa74 100644
953--- a/drivers/gpu/drm/i915/i915_dma.c
954+++ b/drivers/gpu/drm/i915/i915_dma.c
955@@ -170,24 +170,31 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
956 dev_priv->sarea_priv = (drm_i915_sarea_t *)
957 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
958
959- dev_priv->ring.Start = init->ring_start;
960- dev_priv->ring.End = init->ring_end;
961- dev_priv->ring.Size = init->ring_size;
962- dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
963+ if (init->ring_size != 0) {
964+ if (dev_priv->ring.ring_obj != NULL) {
965+ i915_dma_cleanup(dev);
966+ DRM_ERROR("Client tried to initialize ringbuffer in "
967+ "GEM mode\n");
968+ return -EINVAL;
969+ }
970
971- dev_priv->ring.map.offset = init->ring_start;
972- dev_priv->ring.map.size = init->ring_size;
973- dev_priv->ring.map.type = 0;
974- dev_priv->ring.map.flags = 0;
975- dev_priv->ring.map.mtrr = 0;
976+ dev_priv->ring.Size = init->ring_size;
977+ dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
978
979- drm_core_ioremap(&dev_priv->ring.map, dev);
980+ dev_priv->ring.map.offset = init->ring_start;
981+ dev_priv->ring.map.size = init->ring_size;
982+ dev_priv->ring.map.type = 0;
983+ dev_priv->ring.map.flags = 0;
984+ dev_priv->ring.map.mtrr = 0;
985
986- if (dev_priv->ring.map.handle == NULL) {
987- i915_dma_cleanup(dev);
988- DRM_ERROR("can not ioremap virtual address for"
989- " ring buffer\n");
990- return -ENOMEM;
991+ drm_core_ioremap(&dev_priv->ring.map, dev);
992+
993+ if (dev_priv->ring.map.handle == NULL) {
994+ i915_dma_cleanup(dev);
995+ DRM_ERROR("can not ioremap virtual address for"
996+ " ring buffer\n");
997+ return -ENOMEM;
998+ }
999 }
1000
1001 dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
1002@@ -377,9 +384,10 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor
1003 return 0;
1004 }
1005
1006-static int i915_emit_box(struct drm_device * dev,
1007- struct drm_clip_rect __user * boxes,
1008- int i, int DR1, int DR4)
1009+int
1010+i915_emit_box(struct drm_device *dev,
1011+ struct drm_clip_rect __user *boxes,
1012+ int i, int DR1, int DR4)
1013 {
1014 drm_i915_private_t *dev_priv = dev->dev_private;
1015 struct drm_clip_rect box;
1016@@ -681,6 +689,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
1017 case I915_PARAM_LAST_DISPATCH:
1018 value = READ_BREADCRUMB(dev_priv);
1019 break;
1020+ case I915_PARAM_HAS_GEM:
1021+ value = 1;
1022+ break;
1023 default:
1024 DRM_ERROR("Unknown parameter %d\n", param->param);
1025 return -EINVAL;
1026@@ -784,6 +795,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1027 memset(dev_priv, 0, sizeof(drm_i915_private_t));
1028
1029 dev->dev_private = (void *)dev_priv;
1030+ dev_priv->dev = dev;
1031
1032 /* Add register map (needed for suspend/resume) */
1033 base = drm_get_resource_start(dev, mmio_bar);
1034@@ -793,6 +805,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1035 _DRM_KERNEL | _DRM_DRIVER,
1036 &dev_priv->mmio_map);
1037
1038+ i915_gem_load(dev);
1039+
1040 /* Init HWS */
1041 if (!I915_NEED_GFX_HWS(dev)) {
1042 ret = i915_init_phys_hws(dev);
1043@@ -838,6 +852,25 @@ int i915_driver_unload(struct drm_device *dev)
1044 return 0;
1045 }
1046
1047+int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
1048+{
1049+ struct drm_i915_file_private *i915_file_priv;
1050+
1051+ DRM_DEBUG("\n");
1052+ i915_file_priv = (struct drm_i915_file_private *)
1053+ drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES);
1054+
1055+ if (!i915_file_priv)
1056+ return -ENOMEM;
1057+
1058+ file_priv->driver_priv = i915_file_priv;
1059+
1060+ i915_file_priv->mm.last_gem_seqno = 0;
1061+ i915_file_priv->mm.last_gem_throttle_seqno = 0;
1062+
1063+ return 0;
1064+}
1065+
1066 void i915_driver_lastclose(struct drm_device * dev)
1067 {
1068 drm_i915_private_t *dev_priv = dev->dev_private;
1069@@ -845,6 +878,8 @@ void i915_driver_lastclose(struct drm_device * dev)
1070 if (!dev_priv)
1071 return;
1072
1073+ i915_gem_lastclose(dev);
1074+
1075 if (dev_priv->agp_heap)
1076 i915_mem_takedown(&(dev_priv->agp_heap));
1077
1078@@ -857,6 +892,13 @@ void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
1079 i915_mem_release(dev, file_priv, dev_priv->agp_heap);
1080 }
1081
1082+void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
1083+{
1084+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
1085+
1086+ drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES);
1087+}
1088+
1089 struct drm_ioctl_desc i915_ioctls[] = {
1090 DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1091 DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
1092@@ -875,6 +917,22 @@ struct drm_ioctl_desc i915_ioctls[] = {
1093 DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ),
1094 DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
1095 DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH),
1096+ DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH),
1097+ DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
1098+ DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
1099+ DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
1100+ DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH),
1101+ DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH),
1102+ DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH),
1103+ DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH),
1104+ DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0),
1105+ DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0),
1106+ DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
1107+ DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
1108+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
1109+ DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0),
1110+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
1111+ DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
1112 };
1113
1114 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
1115diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
1116index 37af03f..a80ead2 100644
1117--- a/drivers/gpu/drm/i915/i915_drv.c
1118+++ b/drivers/gpu/drm/i915/i915_drv.c
1119@@ -85,12 +85,15 @@ static struct drm_driver driver = {
1120 /* don't use mtrr's here, the Xserver or user space app should
1121 * deal with them for intel hardware.
1122 */
1123- .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP |
1124- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
1125+ .driver_features =
1126+ DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
1127+ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM,
1128 .load = i915_driver_load,
1129 .unload = i915_driver_unload,
1130+ .open = i915_driver_open,
1131 .lastclose = i915_driver_lastclose,
1132 .preclose = i915_driver_preclose,
1133+ .postclose = i915_driver_postclose,
1134 .suspend = i915_suspend,
1135 .resume = i915_resume,
1136 .device_is_agp = i915_driver_device_is_agp,
1137@@ -104,6 +107,10 @@ static struct drm_driver driver = {
1138 .reclaim_buffers = drm_core_reclaim_buffers,
1139 .get_map_ofs = drm_core_get_map_ofs,
1140 .get_reg_ofs = drm_core_get_reg_ofs,
1141+ .proc_init = i915_gem_proc_init,
1142+ .proc_cleanup = i915_gem_proc_cleanup,
1143+ .gem_init_object = i915_gem_init_object,
1144+ .gem_free_object = i915_gem_free_object,
1145 .ioctls = i915_ioctls,
1146 .fops = {
1147 .owner = THIS_MODULE,
1148diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
1149index d1a02be..87b071a 100644
1150--- a/drivers/gpu/drm/i915/i915_drv.h
1151+++ b/drivers/gpu/drm/i915/i915_drv.h
1152@@ -39,7 +39,7 @@
1153
1154 #define DRIVER_NAME "i915"
1155 #define DRIVER_DESC "Intel Graphics"
1156-#define DRIVER_DATE "20060119"
1157+#define DRIVER_DATE "20080730"
1158
1159 enum pipe {
1160 PIPE_A = 0,
1161@@ -60,16 +60,23 @@ enum pipe {
1162 #define DRIVER_MINOR 6
1163 #define DRIVER_PATCHLEVEL 0
1164
1165+#define WATCH_COHERENCY 0
1166+#define WATCH_BUF 0
1167+#define WATCH_EXEC 0
1168+#define WATCH_LRU 0
1169+#define WATCH_RELOC 0
1170+#define WATCH_INACTIVE 0
1171+#define WATCH_PWRITE 0
1172+
1173 typedef struct _drm_i915_ring_buffer {
1174 int tail_mask;
1175- unsigned long Start;
1176- unsigned long End;
1177 unsigned long Size;
1178 u8 *virtual_start;
1179 int head;
1180 int tail;
1181 int space;
1182 drm_local_map_t map;
1183+ struct drm_gem_object *ring_obj;
1184 } drm_i915_ring_buffer_t;
1185
1186 struct mem_block {
1187@@ -101,6 +108,8 @@ struct intel_opregion {
1188 };
1189
1190 typedef struct drm_i915_private {
1191+ struct drm_device *dev;
1192+
1193 drm_local_map_t *sarea;
1194 drm_local_map_t *mmio_map;
1195
1196@@ -113,6 +122,7 @@ typedef struct drm_i915_private {
1197 uint32_t counter;
1198 unsigned int status_gfx_addr;
1199 drm_local_map_t hws_map;
1200+ struct drm_gem_object *hws_obj;
1201
1202 unsigned int cpp;
1203 int back_offset;
1204@@ -122,7 +132,6 @@ typedef struct drm_i915_private {
1205
1206 wait_queue_head_t irq_queue;
1207 atomic_t irq_received;
1208- atomic_t irq_emitted;
1209 /** Protects user_irq_refcount and irq_mask_reg */
1210 spinlock_t user_irq_lock;
1211 /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
1212@@ -230,8 +239,174 @@ typedef struct drm_i915_private {
1213 u8 saveDACMASK;
1214 u8 saveDACDATA[256*3]; /* 256 3-byte colors */
1215 u8 saveCR[37];
1216+
1217+ struct {
1218+ struct drm_mm gtt_space;
1219+
1220+ /**
1221+ * List of objects currently involved in rendering from the
1222+ * ringbuffer.
1223+ *
1224+ * A reference is held on the buffer while on this list.
1225+ */
1226+ struct list_head active_list;
1227+
1228+ /**
1229+ * List of objects which are not in the ringbuffer but which
1230+ * still have a write_domain which needs to be flushed before
1231+ * unbinding.
1232+ *
1233+ * A reference is held on the buffer while on this list.
1234+ */
1235+ struct list_head flushing_list;
1236+
1237+ /**
1238+ * LRU list of objects which are not in the ringbuffer and
1239+ * are ready to unbind, but are still in the GTT.
1240+ *
1241+ * A reference is not held on the buffer while on this list,
1242+ * as merely being GTT-bound shouldn't prevent its being
1243+ * freed, and we'll pull it off the list in the free path.
1244+ */
1245+ struct list_head inactive_list;
1246+
1247+ /**
1248+ * List of breadcrumbs associated with GPU requests currently
1249+ * outstanding.
1250+ */
1251+ struct list_head request_list;
1252+
1253+ /**
1254+ * We leave the user IRQ off as much as possible,
1255+ * but this means that requests will finish and never
1256+ * be retired once the system goes idle. Set a timer to
1257+ * fire periodically while the ring is running. When it
1258+ * fires, go retire requests.
1259+ */
1260+ struct delayed_work retire_work;
1261+
1262+ uint32_t next_gem_seqno;
1263+
1264+ /**
1265+ * Waiting sequence number, if any
1266+ */
1267+ uint32_t waiting_gem_seqno;
1268+
1269+ /**
1270+ * Last seq seen at irq time
1271+ */
1272+ uint32_t irq_gem_seqno;
1273+
1274+ /**
1275+ * Flag if the X Server, and thus DRM, is not currently in
1276+ * control of the device.
1277+ *
1278+ * This is set between LeaveVT and EnterVT. It needs to be
1279+ * replaced with a semaphore. It also needs to be
1280+ * transitioned away from for kernel modesetting.
1281+ */
1282+ int suspended;
1283+
1284+ /**
1285+ * Flag if the hardware appears to be wedged.
1286+ *
1287+ * This is set when attempts to idle the device timeout.
1288+ * It prevents command submission from occuring and makes
1289+ * every pending request fail
1290+ */
1291+ int wedged;
1292+
1293+ /** Bit 6 swizzling required for X tiling */
1294+ uint32_t bit_6_swizzle_x;
1295+ /** Bit 6 swizzling required for Y tiling */
1296+ uint32_t bit_6_swizzle_y;
1297+ } mm;
1298 } drm_i915_private_t;
1299
1300+/** driver private structure attached to each drm_gem_object */
1301+struct drm_i915_gem_object {
1302+ struct drm_gem_object *obj;
1303+
1304+ /** Current space allocated to this object in the GTT, if any. */
1305+ struct drm_mm_node *gtt_space;
1306+
1307+ /** This object's place on the active/flushing/inactive lists */
1308+ struct list_head list;
1309+
1310+ /**
1311+ * This is set if the object is on the active or flushing lists
1312+ * (has pending rendering), and is not set if it's on inactive (ready
1313+ * to be unbound).
1314+ */
1315+ int active;
1316+
1317+ /**
1318+ * This is set if the object has been written to since last bound
1319+ * to the GTT
1320+ */
1321+ int dirty;
1322+
1323+ /** AGP memory structure for our GTT binding. */
1324+ DRM_AGP_MEM *agp_mem;
1325+
1326+ struct page **page_list;
1327+
1328+ /**
1329+ * Current offset of the object in GTT space.
1330+ *
1331+ * This is the same as gtt_space->start
1332+ */
1333+ uint32_t gtt_offset;
1334+
1335+ /** Boolean whether this object has a valid gtt offset. */
1336+ int gtt_bound;
1337+
1338+ /** How many users have pinned this object in GTT space */
1339+ int pin_count;
1340+
1341+ /** Breadcrumb of last rendering to the buffer. */
1342+ uint32_t last_rendering_seqno;
1343+
1344+ /** Current tiling mode for the object. */
1345+ uint32_t tiling_mode;
1346+
1347+ /**
1348+ * Flagging of which individual pages are valid in GEM_DOMAIN_CPU when
1349+ * GEM_DOMAIN_CPU is not in the object's read domain.
1350+ */
1351+ uint8_t *page_cpu_valid;
1352+};
1353+
1354+/**
1355+ * Request queue structure.
1356+ *
1357+ * The request queue allows us to note sequence numbers that have been emitted
1358+ * and may be associated with active buffers to be retired.
1359+ *
1360+ * By keeping this list, we can avoid having to do questionable
1361+ * sequence-number comparisons on buffer last_rendering_seqnos, and associate
1362+ * an emission time with seqnos for tracking how far ahead of the GPU we are.
1363+ */
1364+struct drm_i915_gem_request {
1365+ /** GEM sequence number associated with this request. */
1366+ uint32_t seqno;
1367+
1368+ /** Time at which this request was emitted, in jiffies. */
1369+ unsigned long emitted_jiffies;
1370+
1371+ /** Cache domains that were flushed at the start of the request. */
1372+ uint32_t flush_domains;
1373+
1374+ struct list_head list;
1375+};
1376+
1377+struct drm_i915_file_private {
1378+ struct {
1379+ uint32_t last_gem_seqno;
1380+ uint32_t last_gem_throttle_seqno;
1381+ } mm;
1382+};
1383+
1384 extern struct drm_ioctl_desc i915_ioctls[];
1385 extern int i915_max_ioctl;
1386
1387@@ -239,18 +414,26 @@ extern int i915_max_ioctl;
1388 extern void i915_kernel_lost_context(struct drm_device * dev);
1389 extern int i915_driver_load(struct drm_device *, unsigned long flags);
1390 extern int i915_driver_unload(struct drm_device *);
1391+extern int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv);
1392 extern void i915_driver_lastclose(struct drm_device * dev);
1393 extern void i915_driver_preclose(struct drm_device *dev,
1394 struct drm_file *file_priv);
1395+extern void i915_driver_postclose(struct drm_device *dev,
1396+ struct drm_file *file_priv);
1397 extern int i915_driver_device_is_agp(struct drm_device * dev);
1398 extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
1399 unsigned long arg);
1400+extern int i915_emit_box(struct drm_device *dev,
1401+ struct drm_clip_rect __user *boxes,
1402+ int i, int DR1, int DR4);
1403
1404 /* i915_irq.c */
1405 extern int i915_irq_emit(struct drm_device *dev, void *data,
1406 struct drm_file *file_priv);
1407 extern int i915_irq_wait(struct drm_device *dev, void *data,
1408 struct drm_file *file_priv);
1409+void i915_user_irq_get(struct drm_device *dev);
1410+void i915_user_irq_put(struct drm_device *dev);
1411
1412 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
1413 extern void i915_driver_irq_preinstall(struct drm_device * dev);
1414@@ -279,6 +462,67 @@ extern int i915_mem_destroy_heap(struct drm_device *dev, void *data,
1415 extern void i915_mem_takedown(struct mem_block **heap);
1416 extern void i915_mem_release(struct drm_device * dev,
1417 struct drm_file *file_priv, struct mem_block *heap);
1418+/* i915_gem.c */
1419+int i915_gem_init_ioctl(struct drm_device *dev, void *data,
1420+ struct drm_file *file_priv);
1421+int i915_gem_create_ioctl(struct drm_device *dev, void *data,
1422+ struct drm_file *file_priv);
1423+int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
1424+ struct drm_file *file_priv);
1425+int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
1426+ struct drm_file *file_priv);
1427+int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
1428+ struct drm_file *file_priv);
1429+int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1430+ struct drm_file *file_priv);
1431+int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
1432+ struct drm_file *file_priv);
1433+int i915_gem_execbuffer(struct drm_device *dev, void *data,
1434+ struct drm_file *file_priv);
1435+int i915_gem_pin_ioctl(struct drm_device *dev, void *data,
1436+ struct drm_file *file_priv);
1437+int i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
1438+ struct drm_file *file_priv);
1439+int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
1440+ struct drm_file *file_priv);
1441+int i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
1442+ struct drm_file *file_priv);
1443+int i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
1444+ struct drm_file *file_priv);
1445+int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
1446+ struct drm_file *file_priv);
1447+int i915_gem_set_tiling(struct drm_device *dev, void *data,
1448+ struct drm_file *file_priv);
1449+int i915_gem_get_tiling(struct drm_device *dev, void *data,
1450+ struct drm_file *file_priv);
1451+void i915_gem_load(struct drm_device *dev);
1452+int i915_gem_proc_init(struct drm_minor *minor);
1453+void i915_gem_proc_cleanup(struct drm_minor *minor);
1454+int i915_gem_init_object(struct drm_gem_object *obj);
1455+void i915_gem_free_object(struct drm_gem_object *obj);
1456+int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
1457+void i915_gem_object_unpin(struct drm_gem_object *obj);
1458+void i915_gem_lastclose(struct drm_device *dev);
1459+uint32_t i915_get_gem_seqno(struct drm_device *dev);
1460+void i915_gem_retire_requests(struct drm_device *dev);
1461+void i915_gem_retire_work_handler(struct work_struct *work);
1462+void i915_gem_clflush_object(struct drm_gem_object *obj);
1463+
1464+/* i915_gem_tiling.c */
1465+void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
1466+
1467+/* i915_gem_debug.c */
1468+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
1469+ const char *where, uint32_t mark);
1470+#if WATCH_INACTIVE
1471+void i915_verify_inactive(struct drm_device *dev, char *file, int line);
1472+#else
1473+#define i915_verify_inactive(dev, file, line)
1474+#endif
1475+void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle);
1476+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
1477+ const char *where, uint32_t mark);
1478+void i915_dump_lru(struct drm_device *dev, const char *where);
1479
1480 /* i915_suspend.c */
1481 extern int i915_save_state(struct drm_device *dev);
1482@@ -347,6 +591,7 @@ extern void opregion_enable_asle(struct drm_device *dev);
1483 */
1484 #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
1485 #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5)
1486+#define I915_GEM_HWS_INDEX 0x10
1487
1488 extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1489
1490diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
1491new file mode 100644
1492index 0000000..90ae8a0
1493--- /dev/null
1494+++ b/drivers/gpu/drm/i915/i915_gem.c
1495@@ -0,0 +1,2497 @@
1496+/*
1497+ * Copyright © 2008 Intel Corporation
1498+ *
1499+ * Permission is hereby granted, free of charge, to any person obtaining a
1500+ * copy of this software and associated documentation files (the "Software"),
1501+ * to deal in the Software without restriction, including without limitation
1502+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1503+ * and/or sell copies of the Software, and to permit persons to whom the
1504+ * Software is furnished to do so, subject to the following conditions:
1505+ *
1506+ * The above copyright notice and this permission notice (including the next
1507+ * paragraph) shall be included in all copies or substantial portions of the
1508+ * Software.
1509+ *
1510+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1511+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1512+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1513+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1514+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1515+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
1516+ * IN THE SOFTWARE.
1517+ *
1518+ * Authors:
1519+ * Eric Anholt <eric@anholt.net>
1520+ *
1521+ */
1522+
1523+#include "drmP.h"
1524+#include "drm.h"
1525+#include "i915_drm.h"
1526+#include "i915_drv.h"
1527+#include <linux/swap.h>
1528+
1529+static int
1530+i915_gem_object_set_domain(struct drm_gem_object *obj,
1531+ uint32_t read_domains,
1532+ uint32_t write_domain);
1533+static int
1534+i915_gem_object_set_domain_range(struct drm_gem_object *obj,
1535+ uint64_t offset,
1536+ uint64_t size,
1537+ uint32_t read_domains,
1538+ uint32_t write_domain);
1539+static int
1540+i915_gem_set_domain(struct drm_gem_object *obj,
1541+ struct drm_file *file_priv,
1542+ uint32_t read_domains,
1543+ uint32_t write_domain);
1544+static int i915_gem_object_get_page_list(struct drm_gem_object *obj);
1545+static void i915_gem_object_free_page_list(struct drm_gem_object *obj);
1546+static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
1547+
1548+int
1549+i915_gem_init_ioctl(struct drm_device *dev, void *data,
1550+ struct drm_file *file_priv)
1551+{
1552+ drm_i915_private_t *dev_priv = dev->dev_private;
1553+ struct drm_i915_gem_init *args = data;
1554+
1555+ mutex_lock(&dev->struct_mutex);
1556+
1557+ if (args->gtt_start >= args->gtt_end ||
1558+ (args->gtt_start & (PAGE_SIZE - 1)) != 0 ||
1559+ (args->gtt_end & (PAGE_SIZE - 1)) != 0) {
1560+ mutex_unlock(&dev->struct_mutex);
1561+ return -EINVAL;
1562+ }
1563+
1564+ drm_mm_init(&dev_priv->mm.gtt_space, args->gtt_start,
1565+ args->gtt_end - args->gtt_start);
1566+
1567+ dev->gtt_total = (uint32_t) (args->gtt_end - args->gtt_start);
1568+
1569+ mutex_unlock(&dev->struct_mutex);
1570+
1571+ return 0;
1572+}
1573+
1574+
1575+/**
1576+ * Creates a new mm object and returns a handle to it.
1577+ */
1578+int
1579+i915_gem_create_ioctl(struct drm_device *dev, void *data,
1580+ struct drm_file *file_priv)
1581+{
1582+ struct drm_i915_gem_create *args = data;
1583+ struct drm_gem_object *obj;
1584+ int handle, ret;
1585+
1586+ args->size = roundup(args->size, PAGE_SIZE);
1587+
1588+ /* Allocate the new object */
1589+ obj = drm_gem_object_alloc(dev, args->size);
1590+ if (obj == NULL)
1591+ return -ENOMEM;
1592+
1593+ ret = drm_gem_handle_create(file_priv, obj, &handle);
1594+ mutex_lock(&dev->struct_mutex);
1595+ drm_gem_object_handle_unreference(obj);
1596+ mutex_unlock(&dev->struct_mutex);
1597+
1598+ if (ret)
1599+ return ret;
1600+
1601+ args->handle = handle;
1602+
1603+ return 0;
1604+}
1605+
1606+/**
1607+ * Reads data from the object referenced by handle.
1608+ *
1609+ * On error, the contents of *data are undefined.
1610+ */
1611+int
1612+i915_gem_pread_ioctl(struct drm_device *dev, void *data,
1613+ struct drm_file *file_priv)
1614+{
1615+ struct drm_i915_gem_pread *args = data;
1616+ struct drm_gem_object *obj;
1617+ struct drm_i915_gem_object *obj_priv;
1618+ ssize_t read;
1619+ loff_t offset;
1620+ int ret;
1621+
1622+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1623+ if (obj == NULL)
1624+ return -EBADF;
1625+ obj_priv = obj->driver_private;
1626+
1627+ /* Bounds check source.
1628+ *
1629+ * XXX: This could use review for overflow issues...
1630+ */
1631+ if (args->offset > obj->size || args->size > obj->size ||
1632+ args->offset + args->size > obj->size) {
1633+ drm_gem_object_unreference(obj);
1634+ return -EINVAL;
1635+ }
1636+
1637+ mutex_lock(&dev->struct_mutex);
1638+
1639+ ret = i915_gem_object_set_domain_range(obj, args->offset, args->size,
1640+ I915_GEM_DOMAIN_CPU, 0);
1641+ if (ret != 0) {
1642+ drm_gem_object_unreference(obj);
1643+ mutex_unlock(&dev->struct_mutex);
1644+ }
1645+
1646+ offset = args->offset;
1647+
1648+ read = vfs_read(obj->filp, (char __user *)(uintptr_t)args->data_ptr,
1649+ args->size, &offset);
1650+ if (read != args->size) {
1651+ drm_gem_object_unreference(obj);
1652+ mutex_unlock(&dev->struct_mutex);
1653+ if (read < 0)
1654+ return read;
1655+ else
1656+ return -EINVAL;
1657+ }
1658+
1659+ drm_gem_object_unreference(obj);
1660+ mutex_unlock(&dev->struct_mutex);
1661+
1662+ return 0;
1663+}
1664+
1665+static int
1666+i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
1667+ struct drm_i915_gem_pwrite *args,
1668+ struct drm_file *file_priv)
1669+{
1670+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1671+ ssize_t remain;
1672+ loff_t offset;
1673+ char __user *user_data;
1674+ char *vaddr;
1675+ int i, o, l;
1676+ int ret = 0;
1677+ unsigned long pfn;
1678+ unsigned long unwritten;
1679+
1680+ user_data = (char __user *) (uintptr_t) args->data_ptr;
1681+ remain = args->size;
1682+ if (!access_ok(VERIFY_READ, user_data, remain))
1683+ return -EFAULT;
1684+
1685+
1686+ mutex_lock(&dev->struct_mutex);
1687+ ret = i915_gem_object_pin(obj, 0);
1688+ if (ret) {
1689+ mutex_unlock(&dev->struct_mutex);
1690+ return ret;
1691+ }
1692+ ret = i915_gem_set_domain(obj, file_priv,
1693+ I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
1694+ if (ret)
1695+ goto fail;
1696+
1697+ obj_priv = obj->driver_private;
1698+ offset = obj_priv->gtt_offset + args->offset;
1699+ obj_priv->dirty = 1;
1700+
1701+ while (remain > 0) {
1702+ /* Operation in this page
1703+ *
1704+ * i = page number
1705+ * o = offset within page
1706+ * l = bytes to copy
1707+ */
1708+ i = offset >> PAGE_SHIFT;
1709+ o = offset & (PAGE_SIZE-1);
1710+ l = remain;
1711+ if ((o + l) > PAGE_SIZE)
1712+ l = PAGE_SIZE - o;
1713+
1714+ pfn = (dev->agp->base >> PAGE_SHIFT) + i;
1715+
1716+#ifdef CONFIG_HIGHMEM
1717+ /* kmap_atomic can't map IO pages on non-HIGHMEM kernels
1718+ */
1719+ vaddr = kmap_atomic_pfn(pfn, KM_USER0);
1720+#if WATCH_PWRITE
1721+ DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n",
1722+ i, o, l, pfn, vaddr);
1723+#endif
1724+ unwritten = __copy_from_user_inatomic_nocache(vaddr + o,
1725+ user_data, l);
1726+ kunmap_atomic(vaddr, KM_USER0);
1727+
1728+ if (unwritten)
1729+#endif /* CONFIG_HIGHMEM */
1730+ {
1731+ vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
1732+#if WATCH_PWRITE
1733+ DRM_INFO("pwrite slow i %d o %d l %d "
1734+ "pfn %ld vaddr %p\n",
1735+ i, o, l, pfn, vaddr);
1736+#endif
1737+ if (vaddr == NULL) {
1738+ ret = -EFAULT;
1739+ goto fail;
1740+ }
1741+ unwritten = __copy_from_user(vaddr + o, user_data, l);
1742+#if WATCH_PWRITE
1743+ DRM_INFO("unwritten %ld\n", unwritten);
1744+#endif
1745+ iounmap(vaddr);
1746+ if (unwritten) {
1747+ ret = -EFAULT;
1748+ goto fail;
1749+ }
1750+ }
1751+
1752+ remain -= l;
1753+ user_data += l;
1754+ offset += l;
1755+ }
1756+#if WATCH_PWRITE && 1
1757+ i915_gem_clflush_object(obj);
1758+ i915_gem_dump_object(obj, args->offset + args->size, __func__, ~0);
1759+ i915_gem_clflush_object(obj);
1760+#endif
1761+
1762+fail:
1763+ i915_gem_object_unpin(obj);
1764+ mutex_unlock(&dev->struct_mutex);
1765+
1766+ return ret;
1767+}
1768+
1769+int
1770+i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
1771+ struct drm_i915_gem_pwrite *args,
1772+ struct drm_file *file_priv)
1773+{
1774+ int ret;
1775+ loff_t offset;
1776+ ssize_t written;
1777+
1778+ mutex_lock(&dev->struct_mutex);
1779+
1780+ ret = i915_gem_set_domain(obj, file_priv,
1781+ I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
1782+ if (ret) {
1783+ mutex_unlock(&dev->struct_mutex);
1784+ return ret;
1785+ }
1786+
1787+ offset = args->offset;
1788+
1789+ written = vfs_write(obj->filp,
1790+ (char __user *)(uintptr_t) args->data_ptr,
1791+ args->size, &offset);
1792+ if (written != args->size) {
1793+ mutex_unlock(&dev->struct_mutex);
1794+ if (written < 0)
1795+ return written;
1796+ else
1797+ return -EINVAL;
1798+ }
1799+
1800+ mutex_unlock(&dev->struct_mutex);
1801+
1802+ return 0;
1803+}
1804+
1805+/**
1806+ * Writes data to the object referenced by handle.
1807+ *
1808+ * On error, the contents of the buffer that were to be modified are undefined.
1809+ */
1810+int
1811+i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
1812+ struct drm_file *file_priv)
1813+{
1814+ struct drm_i915_gem_pwrite *args = data;
1815+ struct drm_gem_object *obj;
1816+ struct drm_i915_gem_object *obj_priv;
1817+ int ret = 0;
1818+
1819+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1820+ if (obj == NULL)
1821+ return -EBADF;
1822+ obj_priv = obj->driver_private;
1823+
1824+ /* Bounds check destination.
1825+ *
1826+ * XXX: This could use review for overflow issues...
1827+ */
1828+ if (args->offset > obj->size || args->size > obj->size ||
1829+ args->offset + args->size > obj->size) {
1830+ drm_gem_object_unreference(obj);
1831+ return -EINVAL;
1832+ }
1833+
1834+ /* We can only do the GTT pwrite on untiled buffers, as otherwise
1835+ * it would end up going through the fenced access, and we'll get
1836+ * different detiling behavior between reading and writing.
1837+ * pread/pwrite currently are reading and writing from the CPU
1838+ * perspective, requiring manual detiling by the client.
1839+ */
1840+ if (obj_priv->tiling_mode == I915_TILING_NONE &&
1841+ dev->gtt_total != 0)
1842+ ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv);
1843+ else
1844+ ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv);
1845+
1846+#if WATCH_PWRITE
1847+ if (ret)
1848+ DRM_INFO("pwrite failed %d\n", ret);
1849+#endif
1850+
1851+ drm_gem_object_unreference(obj);
1852+
1853+ return ret;
1854+}
1855+
1856+/**
1857+ * Called when user space prepares to use an object
1858+ */
1859+int
1860+i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1861+ struct drm_file *file_priv)
1862+{
1863+ struct drm_i915_gem_set_domain *args = data;
1864+ struct drm_gem_object *obj;
1865+ int ret;
1866+
1867+ if (!(dev->driver->driver_features & DRIVER_GEM))
1868+ return -ENODEV;
1869+
1870+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1871+ if (obj == NULL)
1872+ return -EBADF;
1873+
1874+ mutex_lock(&dev->struct_mutex);
1875+#if WATCH_BUF
1876+ DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n",
1877+ obj, obj->size, args->read_domains, args->write_domain);
1878+#endif
1879+ ret = i915_gem_set_domain(obj, file_priv,
1880+ args->read_domains, args->write_domain);
1881+ drm_gem_object_unreference(obj);
1882+ mutex_unlock(&dev->struct_mutex);
1883+ return ret;
1884+}
1885+
1886+/**
1887+ * Called when user space has done writes to this buffer
1888+ */
1889+int
1890+i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
1891+ struct drm_file *file_priv)
1892+{
1893+ struct drm_i915_gem_sw_finish *args = data;
1894+ struct drm_gem_object *obj;
1895+ struct drm_i915_gem_object *obj_priv;
1896+ int ret = 0;
1897+
1898+ if (!(dev->driver->driver_features & DRIVER_GEM))
1899+ return -ENODEV;
1900+
1901+ mutex_lock(&dev->struct_mutex);
1902+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1903+ if (obj == NULL) {
1904+ mutex_unlock(&dev->struct_mutex);
1905+ return -EBADF;
1906+ }
1907+
1908+#if WATCH_BUF
1909+ DRM_INFO("%s: sw_finish %d (%p %d)\n",
1910+ __func__, args->handle, obj, obj->size);
1911+#endif
1912+ obj_priv = obj->driver_private;
1913+
1914+ /* Pinned buffers may be scanout, so flush the cache */
1915+ if ((obj->write_domain & I915_GEM_DOMAIN_CPU) && obj_priv->pin_count) {
1916+ i915_gem_clflush_object(obj);
1917+ drm_agp_chipset_flush(dev);
1918+ }
1919+ drm_gem_object_unreference(obj);
1920+ mutex_unlock(&dev->struct_mutex);
1921+ return ret;
1922+}
1923+
1924+/**
1925+ * Maps the contents of an object, returning the address it is mapped
1926+ * into.
1927+ *
1928+ * While the mapping holds a reference on the contents of the object, it doesn't
1929+ * imply a ref on the object itself.
1930+ */
1931+int
1932+i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
1933+ struct drm_file *file_priv)
1934+{
1935+ struct drm_i915_gem_mmap *args = data;
1936+ struct drm_gem_object *obj;
1937+ loff_t offset;
1938+ unsigned long addr;
1939+
1940+ if (!(dev->driver->driver_features & DRIVER_GEM))
1941+ return -ENODEV;
1942+
1943+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1944+ if (obj == NULL)
1945+ return -EBADF;
1946+
1947+ offset = args->offset;
1948+
1949+ down_write(&current->mm->mmap_sem);
1950+ addr = do_mmap(obj->filp, 0, args->size,
1951+ PROT_READ | PROT_WRITE, MAP_SHARED,
1952+ args->offset);
1953+ up_write(&current->mm->mmap_sem);
1954+ mutex_lock(&dev->struct_mutex);
1955+ drm_gem_object_unreference(obj);
1956+ mutex_unlock(&dev->struct_mutex);
1957+ if (IS_ERR((void *)addr))
1958+ return addr;
1959+
1960+ args->addr_ptr = (uint64_t) addr;
1961+
1962+ return 0;
1963+}
1964+
1965+static void
1966+i915_gem_object_free_page_list(struct drm_gem_object *obj)
1967+{
1968+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1969+ int page_count = obj->size / PAGE_SIZE;
1970+ int i;
1971+
1972+ if (obj_priv->page_list == NULL)
1973+ return;
1974+
1975+
1976+ for (i = 0; i < page_count; i++)
1977+ if (obj_priv->page_list[i] != NULL) {
1978+ if (obj_priv->dirty)
1979+ set_page_dirty(obj_priv->page_list[i]);
1980+ mark_page_accessed(obj_priv->page_list[i]);
1981+ page_cache_release(obj_priv->page_list[i]);
1982+ }
1983+ obj_priv->dirty = 0;
1984+
1985+ drm_free(obj_priv->page_list,
1986+ page_count * sizeof(struct page *),
1987+ DRM_MEM_DRIVER);
1988+ obj_priv->page_list = NULL;
1989+}
1990+
1991+static void
1992+i915_gem_object_move_to_active(struct drm_gem_object *obj)
1993+{
1994+ struct drm_device *dev = obj->dev;
1995+ drm_i915_private_t *dev_priv = dev->dev_private;
1996+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1997+
1998+ /* Add a reference if we're newly entering the active list. */
1999+ if (!obj_priv->active) {
2000+ drm_gem_object_reference(obj);
2001+ obj_priv->active = 1;
2002+ }
2003+ /* Move from whatever list we were on to the tail of execution. */
2004+ list_move_tail(&obj_priv->list,
2005+ &dev_priv->mm.active_list);
2006+}
2007+
2008+
2009+static void
2010+i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
2011+{
2012+ struct drm_device *dev = obj->dev;
2013+ drm_i915_private_t *dev_priv = dev->dev_private;
2014+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2015+
2016+ i915_verify_inactive(dev, __FILE__, __LINE__);
2017+ if (obj_priv->pin_count != 0)
2018+ list_del_init(&obj_priv->list);
2019+ else
2020+ list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
2021+
2022+ if (obj_priv->active) {
2023+ obj_priv->active = 0;
2024+ drm_gem_object_unreference(obj);
2025+ }
2026+ i915_verify_inactive(dev, __FILE__, __LINE__);
2027+}
2028+
2029+/**
2030+ * Creates a new sequence number, emitting a write of it to the status page
2031+ * plus an interrupt, which will trigger i915_user_interrupt_handler.
2032+ *
2033+ * Must be called with struct_lock held.
2034+ *
2035+ * Returned sequence numbers are nonzero on success.
2036+ */
2037+static uint32_t
2038+i915_add_request(struct drm_device *dev, uint32_t flush_domains)
2039+{
2040+ drm_i915_private_t *dev_priv = dev->dev_private;
2041+ struct drm_i915_gem_request *request;
2042+ uint32_t seqno;
2043+ int was_empty;
2044+ RING_LOCALS;
2045+
2046+ request = drm_calloc(1, sizeof(*request), DRM_MEM_DRIVER);
2047+ if (request == NULL)
2048+ return 0;
2049+
2050+ /* Grab the seqno we're going to make this request be, and bump the
2051+ * next (skipping 0 so it can be the reserved no-seqno value).
2052+ */
2053+ seqno = dev_priv->mm.next_gem_seqno;
2054+ dev_priv->mm.next_gem_seqno++;
2055+ if (dev_priv->mm.next_gem_seqno == 0)
2056+ dev_priv->mm.next_gem_seqno++;
2057+
2058+ BEGIN_LP_RING(4);
2059+ OUT_RING(MI_STORE_DWORD_INDEX);
2060+ OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
2061+ OUT_RING(seqno);
2062+
2063+ OUT_RING(MI_USER_INTERRUPT);
2064+ ADVANCE_LP_RING();
2065+
2066+ DRM_DEBUG("%d\n", seqno);
2067+
2068+ request->seqno = seqno;
2069+ request->emitted_jiffies = jiffies;
2070+ request->flush_domains = flush_domains;
2071+ was_empty = list_empty(&dev_priv->mm.request_list);
2072+ list_add_tail(&request->list, &dev_priv->mm.request_list);
2073+
2074+ if (was_empty)
2075+ schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
2076+ return seqno;
2077+}
2078+
2079+/**
2080+ * Command execution barrier
2081+ *
2082+ * Ensures that all commands in the ring are finished
2083+ * before signalling the CPU
2084+ */
2085+uint32_t
2086+i915_retire_commands(struct drm_device *dev)
2087+{
2088+ drm_i915_private_t *dev_priv = dev->dev_private;
2089+ uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
2090+ uint32_t flush_domains = 0;
2091+ RING_LOCALS;
2092+
2093+ /* The sampler always gets flushed on i965 (sigh) */
2094+ if (IS_I965G(dev))
2095+ flush_domains |= I915_GEM_DOMAIN_SAMPLER;
2096+ BEGIN_LP_RING(2);
2097+ OUT_RING(cmd);
2098+ OUT_RING(0); /* noop */
2099+ ADVANCE_LP_RING();
2100+ return flush_domains;
2101+}
2102+
2103+/**
2104+ * Moves buffers associated only with the given active seqno from the active
2105+ * to inactive list, potentially freeing them.
2106+ */
2107+static void
2108+i915_gem_retire_request(struct drm_device *dev,
2109+ struct drm_i915_gem_request *request)
2110+{
2111+ drm_i915_private_t *dev_priv = dev->dev_private;
2112+
2113+ /* Move any buffers on the active list that are no longer referenced
2114+ * by the ringbuffer to the flushing/inactive lists as appropriate.
2115+ */
2116+ while (!list_empty(&dev_priv->mm.active_list)) {
2117+ struct drm_gem_object *obj;
2118+ struct drm_i915_gem_object *obj_priv;
2119+
2120+ obj_priv = list_first_entry(&dev_priv->mm.active_list,
2121+ struct drm_i915_gem_object,
2122+ list);
2123+ obj = obj_priv->obj;
2124+
2125+ /* If the seqno being retired doesn't match the oldest in the
2126+ * list, then the oldest in the list must still be newer than
2127+ * this seqno.
2128+ */
2129+ if (obj_priv->last_rendering_seqno != request->seqno)
2130+ return;
2131+#if WATCH_LRU
2132+ DRM_INFO("%s: retire %d moves to inactive list %p\n",
2133+ __func__, request->seqno, obj);
2134+#endif
2135+
2136+ if (obj->write_domain != 0) {
2137+ list_move_tail(&obj_priv->list,
2138+ &dev_priv->mm.flushing_list);
2139+ } else {
2140+ i915_gem_object_move_to_inactive(obj);
2141+ }
2142+ }
2143+
2144+ if (request->flush_domains != 0) {
2145+ struct drm_i915_gem_object *obj_priv, *next;
2146+
2147+ /* Clear the write domain and activity from any buffers
2148+ * that are just waiting for a flush matching the one retired.
2149+ */
2150+ list_for_each_entry_safe(obj_priv, next,
2151+ &dev_priv->mm.flushing_list, list) {
2152+ struct drm_gem_object *obj = obj_priv->obj;
2153+
2154+ if (obj->write_domain & request->flush_domains) {
2155+ obj->write_domain = 0;
2156+ i915_gem_object_move_to_inactive(obj);
2157+ }
2158+ }
2159+
2160+ }
2161+}
2162+
2163+/**
2164+ * Returns true if seq1 is later than seq2.
2165+ */
2166+static int
2167+i915_seqno_passed(uint32_t seq1, uint32_t seq2)
2168+{
2169+ return (int32_t)(seq1 - seq2) >= 0;
2170+}
2171+
2172+uint32_t
2173+i915_get_gem_seqno(struct drm_device *dev)
2174+{
2175+ drm_i915_private_t *dev_priv = dev->dev_private;
2176+
2177+ return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
2178+}
2179+
2180+/**
2181+ * This function clears the request list as sequence numbers are passed.
2182+ */
2183+void
2184+i915_gem_retire_requests(struct drm_device *dev)
2185+{
2186+ drm_i915_private_t *dev_priv = dev->dev_private;
2187+ uint32_t seqno;
2188+
2189+ seqno = i915_get_gem_seqno(dev);
2190+
2191+ while (!list_empty(&dev_priv->mm.request_list)) {
2192+ struct drm_i915_gem_request *request;
2193+ uint32_t retiring_seqno;
2194+
2195+ request = list_first_entry(&dev_priv->mm.request_list,
2196+ struct drm_i915_gem_request,
2197+ list);
2198+ retiring_seqno = request->seqno;
2199+
2200+ if (i915_seqno_passed(seqno, retiring_seqno) ||
2201+ dev_priv->mm.wedged) {
2202+ i915_gem_retire_request(dev, request);
2203+
2204+ list_del(&request->list);
2205+ drm_free(request, sizeof(*request), DRM_MEM_DRIVER);
2206+ } else
2207+ break;
2208+ }
2209+}
2210+
2211+void
2212+i915_gem_retire_work_handler(struct work_struct *work)
2213+{
2214+ drm_i915_private_t *dev_priv;
2215+ struct drm_device *dev;
2216+
2217+ dev_priv = container_of(work, drm_i915_private_t,
2218+ mm.retire_work.work);
2219+ dev = dev_priv->dev;
2220+
2221+ mutex_lock(&dev->struct_mutex);
2222+ i915_gem_retire_requests(dev);
2223+ if (!list_empty(&dev_priv->mm.request_list))
2224+ schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
2225+ mutex_unlock(&dev->struct_mutex);
2226+}
2227+
2228+/**
2229+ * Waits for a sequence number to be signaled, and cleans up the
2230+ * request and object lists appropriately for that event.
2231+ */
2232+int
2233+i915_wait_request(struct drm_device *dev, uint32_t seqno)
2234+{
2235+ drm_i915_private_t *dev_priv = dev->dev_private;
2236+ int ret = 0;
2237+
2238+ BUG_ON(seqno == 0);
2239+
2240+ if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
2241+ dev_priv->mm.waiting_gem_seqno = seqno;
2242+ i915_user_irq_get(dev);
2243+ ret = wait_event_interruptible(dev_priv->irq_queue,
2244+ i915_seqno_passed(i915_get_gem_seqno(dev),
2245+ seqno) ||
2246+ dev_priv->mm.wedged);
2247+ i915_user_irq_put(dev);
2248+ dev_priv->mm.waiting_gem_seqno = 0;
2249+ }
2250+ if (dev_priv->mm.wedged)
2251+ ret = -EIO;
2252+
2253+ if (ret && ret != -ERESTARTSYS)
2254+ DRM_ERROR("%s returns %d (awaiting %d at %d)\n",
2255+ __func__, ret, seqno, i915_get_gem_seqno(dev));
2256+
2257+ /* Directly dispatch request retiring. While we have the work queue
2258+ * to handle this, the waiter on a request often wants an associated
2259+ * buffer to have made it to the inactive list, and we would need
2260+ * a separate wait queue to handle that.
2261+ */
2262+ if (ret == 0)
2263+ i915_gem_retire_requests(dev);
2264+
2265+ return ret;
2266+}
2267+
2268+static void
2269+i915_gem_flush(struct drm_device *dev,
2270+ uint32_t invalidate_domains,
2271+ uint32_t flush_domains)
2272+{
2273+ drm_i915_private_t *dev_priv = dev->dev_private;
2274+ uint32_t cmd;
2275+ RING_LOCALS;
2276+
2277+#if WATCH_EXEC
2278+ DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
2279+ invalidate_domains, flush_domains);
2280+#endif
2281+
2282+ if (flush_domains & I915_GEM_DOMAIN_CPU)
2283+ drm_agp_chipset_flush(dev);
2284+
2285+ if ((invalidate_domains | flush_domains) & ~(I915_GEM_DOMAIN_CPU |
2286+ I915_GEM_DOMAIN_GTT)) {
2287+ /*
2288+ * read/write caches:
2289+ *
2290+ * I915_GEM_DOMAIN_RENDER is always invalidated, but is
2291+ * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is
2292+ * also flushed at 2d versus 3d pipeline switches.
2293+ *
2294+ * read-only caches:
2295+ *
2296+ * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
2297+ * MI_READ_FLUSH is set, and is always flushed on 965.
2298+ *
2299+ * I915_GEM_DOMAIN_COMMAND may not exist?
2300+ *
2301+ * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
2302+ * invalidated when MI_EXE_FLUSH is set.
2303+ *
2304+ * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
2305+ * invalidated with every MI_FLUSH.
2306+ *
2307+ * TLBs:
2308+ *
2309+ * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
2310+ * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
2311+ * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
2312+ * are flushed at any MI_FLUSH.
2313+ */
2314+
2315+ cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
2316+ if ((invalidate_domains|flush_domains) &
2317+ I915_GEM_DOMAIN_RENDER)
2318+ cmd &= ~MI_NO_WRITE_FLUSH;
2319+ if (!IS_I965G(dev)) {
2320+ /*
2321+ * On the 965, the sampler cache always gets flushed
2322+ * and this bit is reserved.
2323+ */
2324+ if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
2325+ cmd |= MI_READ_FLUSH;
2326+ }
2327+ if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
2328+ cmd |= MI_EXE_FLUSH;
2329+
2330+#if WATCH_EXEC
2331+ DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
2332+#endif
2333+ BEGIN_LP_RING(2);
2334+ OUT_RING(cmd);
2335+ OUT_RING(0); /* noop */
2336+ ADVANCE_LP_RING();
2337+ }
2338+}
2339+
2340+/**
2341+ * Ensures that all rendering to the object has completed and the object is
2342+ * safe to unbind from the GTT or access from the CPU.
2343+ */
2344+static int
2345+i915_gem_object_wait_rendering(struct drm_gem_object *obj)
2346+{
2347+ struct drm_device *dev = obj->dev;
2348+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2349+ int ret;
2350+
2351+ /* If there are writes queued to the buffer, flush and
2352+ * create a new seqno to wait for.
2353+ */
2354+ if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) {
2355+ uint32_t write_domain = obj->write_domain;
2356+#if WATCH_BUF
2357+ DRM_INFO("%s: flushing object %p from write domain %08x\n",
2358+ __func__, obj, write_domain);
2359+#endif
2360+ i915_gem_flush(dev, 0, write_domain);
2361+
2362+ i915_gem_object_move_to_active(obj);
2363+ obj_priv->last_rendering_seqno = i915_add_request(dev,
2364+ write_domain);
2365+ BUG_ON(obj_priv->last_rendering_seqno == 0);
2366+#if WATCH_LRU
2367+ DRM_INFO("%s: flush moves to exec list %p\n", __func__, obj);
2368+#endif
2369+ }
2370+
2371+ /* If there is rendering queued on the buffer being evicted, wait for
2372+ * it.
2373+ */
2374+ if (obj_priv->active) {
2375+#if WATCH_BUF
2376+ DRM_INFO("%s: object %p wait for seqno %08x\n",
2377+ __func__, obj, obj_priv->last_rendering_seqno);
2378+#endif
2379+ ret = i915_wait_request(dev, obj_priv->last_rendering_seqno);
2380+ if (ret != 0)
2381+ return ret;
2382+ }
2383+
2384+ return 0;
2385+}
2386+
2387+/**
2388+ * Unbinds an object from the GTT aperture.
2389+ */
2390+static int
2391+i915_gem_object_unbind(struct drm_gem_object *obj)
2392+{
2393+ struct drm_device *dev = obj->dev;
2394+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2395+ int ret = 0;
2396+
2397+#if WATCH_BUF
2398+ DRM_INFO("%s:%d %p\n", __func__, __LINE__, obj);
2399+ DRM_INFO("gtt_space %p\n", obj_priv->gtt_space);
2400+#endif
2401+ if (obj_priv->gtt_space == NULL)
2402+ return 0;
2403+
2404+ if (obj_priv->pin_count != 0) {
2405+ DRM_ERROR("Attempting to unbind pinned buffer\n");
2406+ return -EINVAL;
2407+ }
2408+
2409+ /* Wait for any rendering to complete
2410+ */
2411+ ret = i915_gem_object_wait_rendering(obj);
2412+ if (ret) {
2413+ DRM_ERROR("wait_rendering failed: %d\n", ret);
2414+ return ret;
2415+ }
2416+
2417+ /* Move the object to the CPU domain to ensure that
2418+ * any possible CPU writes while it's not in the GTT
2419+ * are flushed when we go to remap it. This will
2420+ * also ensure that all pending GPU writes are finished
2421+ * before we unbind.
2422+ */
2423+ ret = i915_gem_object_set_domain(obj, I915_GEM_DOMAIN_CPU,
2424+ I915_GEM_DOMAIN_CPU);
2425+ if (ret) {
2426+ DRM_ERROR("set_domain failed: %d\n", ret);
2427+ return ret;
2428+ }
2429+
2430+ if (obj_priv->agp_mem != NULL) {
2431+ drm_unbind_agp(obj_priv->agp_mem);
2432+ drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE);
2433+ obj_priv->agp_mem = NULL;
2434+ }
2435+
2436+ BUG_ON(obj_priv->active);
2437+
2438+ i915_gem_object_free_page_list(obj);
2439+
2440+ if (obj_priv->gtt_space) {
2441+ atomic_dec(&dev->gtt_count);
2442+ atomic_sub(obj->size, &dev->gtt_memory);
2443+
2444+ drm_mm_put_block(obj_priv->gtt_space);
2445+ obj_priv->gtt_space = NULL;
2446+ }
2447+
2448+ /* Remove ourselves from the LRU list if present. */
2449+ if (!list_empty(&obj_priv->list))
2450+ list_del_init(&obj_priv->list);
2451+
2452+ return 0;
2453+}
2454+
2455+static int
2456+i915_gem_evict_something(struct drm_device *dev)
2457+{
2458+ drm_i915_private_t *dev_priv = dev->dev_private;
2459+ struct drm_gem_object *obj;
2460+ struct drm_i915_gem_object *obj_priv;
2461+ int ret = 0;
2462+
2463+ for (;;) {
2464+ /* If there's an inactive buffer available now, grab it
2465+ * and be done.
2466+ */
2467+ if (!list_empty(&dev_priv->mm.inactive_list)) {
2468+ obj_priv = list_first_entry(&dev_priv->mm.inactive_list,
2469+ struct drm_i915_gem_object,
2470+ list);
2471+ obj = obj_priv->obj;
2472+ BUG_ON(obj_priv->pin_count != 0);
2473+#if WATCH_LRU
2474+ DRM_INFO("%s: evicting %p\n", __func__, obj);
2475+#endif
2476+ BUG_ON(obj_priv->active);
2477+
2478+ /* Wait on the rendering and unbind the buffer. */
2479+ ret = i915_gem_object_unbind(obj);
2480+ break;
2481+ }
2482+
2483+ /* If we didn't get anything, but the ring is still processing
2484+ * things, wait for one of those things to finish and hopefully
2485+ * leave us a buffer to evict.
2486+ */
2487+ if (!list_empty(&dev_priv->mm.request_list)) {
2488+ struct drm_i915_gem_request *request;
2489+
2490+ request = list_first_entry(&dev_priv->mm.request_list,
2491+ struct drm_i915_gem_request,
2492+ list);
2493+
2494+ ret = i915_wait_request(dev, request->seqno);
2495+ if (ret)
2496+ break;
2497+
2498+ /* if waiting caused an object to become inactive,
2499+ * then loop around and wait for it. Otherwise, we
2500+ * assume that waiting freed and unbound something,
2501+ * so there should now be some space in the GTT
2502+ */
2503+ if (!list_empty(&dev_priv->mm.inactive_list))
2504+ continue;
2505+ break;
2506+ }
2507+
2508+ /* If we didn't have anything on the request list but there
2509+ * are buffers awaiting a flush, emit one and try again.
2510+ * When we wait on it, those buffers waiting for that flush
2511+ * will get moved to inactive.
2512+ */
2513+ if (!list_empty(&dev_priv->mm.flushing_list)) {
2514+ obj_priv = list_first_entry(&dev_priv->mm.flushing_list,
2515+ struct drm_i915_gem_object,
2516+ list);
2517+ obj = obj_priv->obj;
2518+
2519+ i915_gem_flush(dev,
2520+ obj->write_domain,
2521+ obj->write_domain);
2522+ i915_add_request(dev, obj->write_domain);
2523+
2524+ obj = NULL;
2525+ continue;
2526+ }
2527+
2528+ DRM_ERROR("inactive empty %d request empty %d "
2529+ "flushing empty %d\n",
2530+ list_empty(&dev_priv->mm.inactive_list),
2531+ list_empty(&dev_priv->mm.request_list),
2532+ list_empty(&dev_priv->mm.flushing_list));
2533+ /* If we didn't do any of the above, there's nothing to be done
2534+ * and we just can't fit it in.
2535+ */
2536+ return -ENOMEM;
2537+ }
2538+ return ret;
2539+}
2540+
2541+static int
2542+i915_gem_object_get_page_list(struct drm_gem_object *obj)
2543+{
2544+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2545+ int page_count, i;
2546+ struct address_space *mapping;
2547+ struct inode *inode;
2548+ struct page *page;
2549+ int ret;
2550+
2551+ if (obj_priv->page_list)
2552+ return 0;
2553+
2554+ /* Get the list of pages out of our struct file. They'll be pinned
2555+ * at this point until we release them.
2556+ */
2557+ page_count = obj->size / PAGE_SIZE;
2558+ BUG_ON(obj_priv->page_list != NULL);
2559+ obj_priv->page_list = drm_calloc(page_count, sizeof(struct page *),
2560+ DRM_MEM_DRIVER);
2561+ if (obj_priv->page_list == NULL) {
2562+ DRM_ERROR("Faled to allocate page list\n");
2563+ return -ENOMEM;
2564+ }
2565+
2566+ inode = obj->filp->f_path.dentry->d_inode;
2567+ mapping = inode->i_mapping;
2568+ for (i = 0; i < page_count; i++) {
2569+ page = read_mapping_page(mapping, i, NULL);
2570+ if (IS_ERR(page)) {
2571+ ret = PTR_ERR(page);
2572+ DRM_ERROR("read_mapping_page failed: %d\n", ret);
2573+ i915_gem_object_free_page_list(obj);
2574+ return ret;
2575+ }
2576+ obj_priv->page_list[i] = page;
2577+ }
2578+ return 0;
2579+}
2580+
2581+/**
2582+ * Finds free space in the GTT aperture and binds the object there.
2583+ */
2584+static int
2585+i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2586+{
2587+ struct drm_device *dev = obj->dev;
2588+ drm_i915_private_t *dev_priv = dev->dev_private;
2589+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2590+ struct drm_mm_node *free_space;
2591+ int page_count, ret;
2592+
2593+ if (alignment == 0)
2594+ alignment = PAGE_SIZE;
2595+ if (alignment & (PAGE_SIZE - 1)) {
2596+ DRM_ERROR("Invalid object alignment requested %u\n", alignment);
2597+ return -EINVAL;
2598+ }
2599+
2600+ search_free:
2601+ free_space = drm_mm_search_free(&dev_priv->mm.gtt_space,
2602+ obj->size, alignment, 0);
2603+ if (free_space != NULL) {
2604+ obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size,
2605+ alignment);
2606+ if (obj_priv->gtt_space != NULL) {
2607+ obj_priv->gtt_space->private = obj;
2608+ obj_priv->gtt_offset = obj_priv->gtt_space->start;
2609+ }
2610+ }
2611+ if (obj_priv->gtt_space == NULL) {
2612+ /* If the gtt is empty and we're still having trouble
2613+ * fitting our object in, we're out of memory.
2614+ */
2615+#if WATCH_LRU
2616+ DRM_INFO("%s: GTT full, evicting something\n", __func__);
2617+#endif
2618+ if (list_empty(&dev_priv->mm.inactive_list) &&
2619+ list_empty(&dev_priv->mm.flushing_list) &&
2620+ list_empty(&dev_priv->mm.active_list)) {
2621+ DRM_ERROR("GTT full, but LRU list empty\n");
2622+ return -ENOMEM;
2623+ }
2624+
2625+ ret = i915_gem_evict_something(dev);
2626+ if (ret != 0) {
2627+ DRM_ERROR("Failed to evict a buffer %d\n", ret);
2628+ return ret;
2629+ }
2630+ goto search_free;
2631+ }
2632+
2633+#if WATCH_BUF
2634+ DRM_INFO("Binding object of size %d at 0x%08x\n",
2635+ obj->size, obj_priv->gtt_offset);
2636+#endif
2637+ ret = i915_gem_object_get_page_list(obj);
2638+ if (ret) {
2639+ drm_mm_put_block(obj_priv->gtt_space);
2640+ obj_priv->gtt_space = NULL;
2641+ return ret;
2642+ }
2643+
2644+ page_count = obj->size / PAGE_SIZE;
2645+ /* Create an AGP memory structure pointing at our pages, and bind it
2646+ * into the GTT.
2647+ */
2648+ obj_priv->agp_mem = drm_agp_bind_pages(dev,
2649+ obj_priv->page_list,
2650+ page_count,
2651+ obj_priv->gtt_offset);
2652+ if (obj_priv->agp_mem == NULL) {
2653+ i915_gem_object_free_page_list(obj);
2654+ drm_mm_put_block(obj_priv->gtt_space);
2655+ obj_priv->gtt_space = NULL;
2656+ return -ENOMEM;
2657+ }
2658+ atomic_inc(&dev->gtt_count);
2659+ atomic_add(obj->size, &dev->gtt_memory);
2660+
2661+ /* Assert that the object is not currently in any GPU domain. As it
2662+ * wasn't in the GTT, there shouldn't be any way it could have been in
2663+ * a GPU cache
2664+ */
2665+ BUG_ON(obj->read_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
2666+ BUG_ON(obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
2667+
2668+ return 0;
2669+}
2670+
2671+void
2672+i915_gem_clflush_object(struct drm_gem_object *obj)
2673+{
2674+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2675+
2676+ /* If we don't have a page list set up, then we're not pinned
2677+ * to GPU, and we can ignore the cache flush because it'll happen
2678+ * again at bind time.
2679+ */
2680+ if (obj_priv->page_list == NULL)
2681+ return;
2682+
2683+ drm_clflush_pages(obj_priv->page_list, obj->size / PAGE_SIZE);
2684+}
2685+
2686+/*
2687+ * Set the next domain for the specified object. This
2688+ * may not actually perform the necessary flushing/invaliding though,
2689+ * as that may want to be batched with other set_domain operations
2690+ *
2691+ * This is (we hope) the only really tricky part of gem. The goal
2692+ * is fairly simple -- track which caches hold bits of the object
2693+ * and make sure they remain coherent. A few concrete examples may
2694+ * help to explain how it works. For shorthand, we use the notation
2695+ * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the
2696+ * a pair of read and write domain masks.
2697+ *
2698+ * Case 1: the batch buffer
2699+ *
2700+ * 1. Allocated
2701+ * 2. Written by CPU
2702+ * 3. Mapped to GTT
2703+ * 4. Read by GPU
2704+ * 5. Unmapped from GTT
2705+ * 6. Freed
2706+ *
2707+ * Let's take these a step at a time
2708+ *
2709+ * 1. Allocated
2710+ * Pages allocated from the kernel may still have
2711+ * cache contents, so we set them to (CPU, CPU) always.
2712+ * 2. Written by CPU (using pwrite)
2713+ * The pwrite function calls set_domain (CPU, CPU) and
2714+ * this function does nothing (as nothing changes)
2715+ * 3. Mapped by GTT
2716+ * This function asserts that the object is not
2717+ * currently in any GPU-based read or write domains
2718+ * 4. Read by GPU
2719+ * i915_gem_execbuffer calls set_domain (COMMAND, 0).
2720+ * As write_domain is zero, this function adds in the
2721+ * current read domains (CPU+COMMAND, 0).
2722+ * flush_domains is set to CPU.
2723+ * invalidate_domains is set to COMMAND
2724+ * clflush is run to get data out of the CPU caches
2725+ * then i915_dev_set_domain calls i915_gem_flush to
2726+ * emit an MI_FLUSH and drm_agp_chipset_flush
2727+ * 5. Unmapped from GTT
2728+ * i915_gem_object_unbind calls set_domain (CPU, CPU)
2729+ * flush_domains and invalidate_domains end up both zero
2730+ * so no flushing/invalidating happens
2731+ * 6. Freed
2732+ * yay, done
2733+ *
2734+ * Case 2: The shared render buffer
2735+ *
2736+ * 1. Allocated
2737+ * 2. Mapped to GTT
2738+ * 3. Read/written by GPU
2739+ * 4. set_domain to (CPU,CPU)
2740+ * 5. Read/written by CPU
2741+ * 6. Read/written by GPU
2742+ *
2743+ * 1. Allocated
2744+ * Same as last example, (CPU, CPU)
2745+ * 2. Mapped to GTT
2746+ * Nothing changes (assertions find that it is not in the GPU)
2747+ * 3. Read/written by GPU
2748+ * execbuffer calls set_domain (RENDER, RENDER)
2749+ * flush_domains gets CPU
2750+ * invalidate_domains gets GPU
2751+ * clflush (obj)
2752+ * MI_FLUSH and drm_agp_chipset_flush
2753+ * 4. set_domain (CPU, CPU)
2754+ * flush_domains gets GPU
2755+ * invalidate_domains gets CPU
2756+ * wait_rendering (obj) to make sure all drawing is complete.
2757+ * This will include an MI_FLUSH to get the data from GPU
2758+ * to memory
2759+ * clflush (obj) to invalidate the CPU cache
2760+ * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?)
2761+ * 5. Read/written by CPU
2762+ * cache lines are loaded and dirtied
2763+ * 6. Read written by GPU
2764+ * Same as last GPU access
2765+ *
2766+ * Case 3: The constant buffer
2767+ *
2768+ * 1. Allocated
2769+ * 2. Written by CPU
2770+ * 3. Read by GPU
2771+ * 4. Updated (written) by CPU again
2772+ * 5. Read by GPU
2773+ *
2774+ * 1. Allocated
2775+ * (CPU, CPU)
2776+ * 2. Written by CPU
2777+ * (CPU, CPU)
2778+ * 3. Read by GPU
2779+ * (CPU+RENDER, 0)
2780+ * flush_domains = CPU
2781+ * invalidate_domains = RENDER
2782+ * clflush (obj)
2783+ * MI_FLUSH
2784+ * drm_agp_chipset_flush
2785+ * 4. Updated (written) by CPU again
2786+ * (CPU, CPU)
2787+ * flush_domains = 0 (no previous write domain)
2788+ * invalidate_domains = 0 (no new read domains)
2789+ * 5. Read by GPU
2790+ * (CPU+RENDER, 0)
2791+ * flush_domains = CPU
2792+ * invalidate_domains = RENDER
2793+ * clflush (obj)
2794+ * MI_FLUSH
2795+ * drm_agp_chipset_flush
2796+ */
2797+static int
2798+i915_gem_object_set_domain(struct drm_gem_object *obj,
2799+ uint32_t read_domains,
2800+ uint32_t write_domain)
2801+{
2802+ struct drm_device *dev = obj->dev;
2803+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2804+ uint32_t invalidate_domains = 0;
2805+ uint32_t flush_domains = 0;
2806+ int ret;
2807+
2808+#if WATCH_BUF
2809+ DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
2810+ __func__, obj,
2811+ obj->read_domains, read_domains,
2812+ obj->write_domain, write_domain);
2813+#endif
2814+ /*
2815+ * If the object isn't moving to a new write domain,
2816+ * let the object stay in multiple read domains
2817+ */
2818+ if (write_domain == 0)
2819+ read_domains |= obj->read_domains;
2820+ else
2821+ obj_priv->dirty = 1;
2822+
2823+ /*
2824+ * Flush the current write domain if
2825+ * the new read domains don't match. Invalidate
2826+ * any read domains which differ from the old
2827+ * write domain
2828+ */
2829+ if (obj->write_domain && obj->write_domain != read_domains) {
2830+ flush_domains |= obj->write_domain;
2831+ invalidate_domains |= read_domains & ~obj->write_domain;
2832+ }
2833+ /*
2834+ * Invalidate any read caches which may have
2835+ * stale data. That is, any new read domains.
2836+ */
2837+ invalidate_domains |= read_domains & ~obj->read_domains;
2838+ if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) {
2839+#if WATCH_BUF
2840+ DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n",
2841+ __func__, flush_domains, invalidate_domains);
2842+#endif
2843+ /*
2844+ * If we're invaliding the CPU cache and flushing a GPU cache,
2845+ * then pause for rendering so that the GPU caches will be
2846+ * flushed before the cpu cache is invalidated
2847+ */
2848+ if ((invalidate_domains & I915_GEM_DOMAIN_CPU) &&
2849+ (flush_domains & ~(I915_GEM_DOMAIN_CPU |
2850+ I915_GEM_DOMAIN_GTT))) {
2851+ ret = i915_gem_object_wait_rendering(obj);
2852+ if (ret)
2853+ return ret;
2854+ }
2855+ i915_gem_clflush_object(obj);
2856+ }
2857+
2858+ if ((write_domain | flush_domains) != 0)
2859+ obj->write_domain = write_domain;
2860+
2861+ /* If we're invalidating the CPU domain, clear the per-page CPU
2862+ * domain list as well.
2863+ */
2864+ if (obj_priv->page_cpu_valid != NULL &&
2865+ (write_domain != 0 ||
2866+ read_domains & I915_GEM_DOMAIN_CPU)) {
2867+ drm_free(obj_priv->page_cpu_valid, obj->size / PAGE_SIZE,
2868+ DRM_MEM_DRIVER);
2869+ obj_priv->page_cpu_valid = NULL;
2870+ }
2871+ obj->read_domains = read_domains;
2872+
2873+ dev->invalidate_domains |= invalidate_domains;
2874+ dev->flush_domains |= flush_domains;
2875+#if WATCH_BUF
2876+ DRM_INFO("%s: read %08x write %08x invalidate %08x flush %08x\n",
2877+ __func__,
2878+ obj->read_domains, obj->write_domain,
2879+ dev->invalidate_domains, dev->flush_domains);
2880+#endif
2881+ return 0;
2882+}
2883+
2884+/**
2885+ * Set the read/write domain on a range of the object.
2886+ *
2887+ * Currently only implemented for CPU reads, otherwise drops to normal
2888+ * i915_gem_object_set_domain().
2889+ */
2890+static int
2891+i915_gem_object_set_domain_range(struct drm_gem_object *obj,
2892+ uint64_t offset,
2893+ uint64_t size,
2894+ uint32_t read_domains,
2895+ uint32_t write_domain)
2896+{
2897+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2898+ int ret, i;
2899+
2900+ if (obj->read_domains & I915_GEM_DOMAIN_CPU)
2901+ return 0;
2902+
2903+ if (read_domains != I915_GEM_DOMAIN_CPU ||
2904+ write_domain != 0)
2905+ return i915_gem_object_set_domain(obj,
2906+ read_domains, write_domain);
2907+
2908+ /* Wait on any GPU rendering to the object to be flushed. */
2909+ if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) {
2910+ ret = i915_gem_object_wait_rendering(obj);
2911+ if (ret)
2912+ return ret;
2913+ }
2914+
2915+ if (obj_priv->page_cpu_valid == NULL) {
2916+ obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE,
2917+ DRM_MEM_DRIVER);
2918+ }
2919+
2920+ /* Flush the cache on any pages that are still invalid from the CPU's
2921+ * perspective.
2922+ */
2923+ for (i = offset / PAGE_SIZE; i <= (offset + size - 1) / PAGE_SIZE; i++) {
2924+ if (obj_priv->page_cpu_valid[i])
2925+ continue;
2926+
2927+ drm_clflush_pages(obj_priv->page_list + i, 1);
2928+
2929+ obj_priv->page_cpu_valid[i] = 1;
2930+ }
2931+
2932+ return 0;
2933+}
2934+
2935+/**
2936+ * Once all of the objects have been set in the proper domain,
2937+ * perform the necessary flush and invalidate operations.
2938+ *
2939+ * Returns the write domains flushed, for use in flush tracking.
2940+ */
2941+static uint32_t
2942+i915_gem_dev_set_domain(struct drm_device *dev)
2943+{
2944+ uint32_t flush_domains = dev->flush_domains;
2945+
2946+ /*
2947+ * Now that all the buffers are synced to the proper domains,
2948+ * flush and invalidate the collected domains
2949+ */
2950+ if (dev->invalidate_domains | dev->flush_domains) {
2951+#if WATCH_EXEC
2952+ DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
2953+ __func__,
2954+ dev->invalidate_domains,
2955+ dev->flush_domains);
2956+#endif
2957+ i915_gem_flush(dev,
2958+ dev->invalidate_domains,
2959+ dev->flush_domains);
2960+ dev->invalidate_domains = 0;
2961+ dev->flush_domains = 0;
2962+ }
2963+
2964+ return flush_domains;
2965+}
2966+
2967+/**
2968+ * Pin an object to the GTT and evaluate the relocations landing in it.
2969+ */
2970+static int
2971+i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
2972+ struct drm_file *file_priv,
2973+ struct drm_i915_gem_exec_object *entry)
2974+{
2975+ struct drm_device *dev = obj->dev;
2976+ struct drm_i915_gem_relocation_entry reloc;
2977+ struct drm_i915_gem_relocation_entry __user *relocs;
2978+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2979+ int i, ret;
2980+ uint32_t last_reloc_offset = -1;
2981+ void *reloc_page = NULL;
2982+
2983+ /* Choose the GTT offset for our buffer and put it there. */
2984+ ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment);
2985+ if (ret)
2986+ return ret;
2987+
2988+ entry->offset = obj_priv->gtt_offset;
2989+
2990+ relocs = (struct drm_i915_gem_relocation_entry __user *)
2991+ (uintptr_t) entry->relocs_ptr;
2992+ /* Apply the relocations, using the GTT aperture to avoid cache
2993+ * flushing requirements.
2994+ */
2995+ for (i = 0; i < entry->relocation_count; i++) {
2996+ struct drm_gem_object *target_obj;
2997+ struct drm_i915_gem_object *target_obj_priv;
2998+ uint32_t reloc_val, reloc_offset, *reloc_entry;
2999+ int ret;
3000+
3001+ ret = copy_from_user(&reloc, relocs + i, sizeof(reloc));
3002+ if (ret != 0) {
3003+ i915_gem_object_unpin(obj);
3004+ return ret;
3005+ }
3006+
3007+ target_obj = drm_gem_object_lookup(obj->dev, file_priv,
3008+ reloc.target_handle);
3009+ if (target_obj == NULL) {
3010+ i915_gem_object_unpin(obj);
3011+ return -EBADF;
3012+ }
3013+ target_obj_priv = target_obj->driver_private;
3014+
3015+ /* The target buffer should have appeared before us in the
3016+ * exec_object list, so it should have a GTT space bound by now.
3017+ */
3018+ if (target_obj_priv->gtt_space == NULL) {
3019+ DRM_ERROR("No GTT space found for object %d\n",
3020+ reloc.target_handle);
3021+ drm_gem_object_unreference(target_obj);
3022+ i915_gem_object_unpin(obj);
3023+ return -EINVAL;
3024+ }
3025+
3026+ if (reloc.offset > obj->size - 4) {
3027+ DRM_ERROR("Relocation beyond object bounds: "
3028+ "obj %p target %d offset %d size %d.\n",
3029+ obj, reloc.target_handle,
3030+ (int) reloc.offset, (int) obj->size);
3031+ drm_gem_object_unreference(target_obj);
3032+ i915_gem_object_unpin(obj);
3033+ return -EINVAL;
3034+ }
3035+ if (reloc.offset & 3) {
3036+ DRM_ERROR("Relocation not 4-byte aligned: "
3037+ "obj %p target %d offset %d.\n",
3038+ obj, reloc.target_handle,
3039+ (int) reloc.offset);
3040+ drm_gem_object_unreference(target_obj);
3041+ i915_gem_object_unpin(obj);
3042+ return -EINVAL;
3043+ }
3044+
3045+ if (reloc.write_domain && target_obj->pending_write_domain &&
3046+ reloc.write_domain != target_obj->pending_write_domain) {
3047+ DRM_ERROR("Write domain conflict: "
3048+ "obj %p target %d offset %d "
3049+ "new %08x old %08x\n",
3050+ obj, reloc.target_handle,
3051+ (int) reloc.offset,
3052+ reloc.write_domain,
3053+ target_obj->pending_write_domain);
3054+ drm_gem_object_unreference(target_obj);
3055+ i915_gem_object_unpin(obj);
3056+ return -EINVAL;
3057+ }
3058+
3059+#if WATCH_RELOC
3060+ DRM_INFO("%s: obj %p offset %08x target %d "
3061+ "read %08x write %08x gtt %08x "
3062+ "presumed %08x delta %08x\n",
3063+ __func__,
3064+ obj,
3065+ (int) reloc.offset,
3066+ (int) reloc.target_handle,
3067+ (int) reloc.read_domains,
3068+ (int) reloc.write_domain,
3069+ (int) target_obj_priv->gtt_offset,
3070+ (int) reloc.presumed_offset,
3071+ reloc.delta);
3072+#endif
3073+
3074+ target_obj->pending_read_domains |= reloc.read_domains;
3075+ target_obj->pending_write_domain |= reloc.write_domain;
3076+
3077+ /* If the relocation already has the right value in it, no
3078+ * more work needs to be done.
3079+ */
3080+ if (target_obj_priv->gtt_offset == reloc.presumed_offset) {
3081+ drm_gem_object_unreference(target_obj);
3082+ continue;
3083+ }
3084+
3085+ /* Now that we're going to actually write some data in,
3086+ * make sure that any rendering using this buffer's contents
3087+ * is completed.
3088+ */
3089+ i915_gem_object_wait_rendering(obj);
3090+
3091+ /* As we're writing through the gtt, flush
3092+ * any CPU writes before we write the relocations
3093+ */
3094+ if (obj->write_domain & I915_GEM_DOMAIN_CPU) {
3095+ i915_gem_clflush_object(obj);
3096+ drm_agp_chipset_flush(dev);
3097+ obj->write_domain = 0;
3098+ }
3099+
3100+ /* Map the page containing the relocation we're going to
3101+ * perform.
3102+ */
3103+ reloc_offset = obj_priv->gtt_offset + reloc.offset;
3104+ if (reloc_page == NULL ||
3105+ (last_reloc_offset & ~(PAGE_SIZE - 1)) !=
3106+ (reloc_offset & ~(PAGE_SIZE - 1))) {
3107+ if (reloc_page != NULL)
3108+ iounmap(reloc_page);
3109+
3110+ reloc_page = ioremap(dev->agp->base +
3111+ (reloc_offset & ~(PAGE_SIZE - 1)),
3112+ PAGE_SIZE);
3113+ last_reloc_offset = reloc_offset;
3114+ if (reloc_page == NULL) {
3115+ drm_gem_object_unreference(target_obj);
3116+ i915_gem_object_unpin(obj);
3117+ return -ENOMEM;
3118+ }
3119+ }
3120+
3121+ reloc_entry = (uint32_t *)((char *)reloc_page +
3122+ (reloc_offset & (PAGE_SIZE - 1)));
3123+ reloc_val = target_obj_priv->gtt_offset + reloc.delta;
3124+
3125+#if WATCH_BUF
3126+ DRM_INFO("Applied relocation: %p@0x%08x %08x -> %08x\n",
3127+ obj, (unsigned int) reloc.offset,
3128+ readl(reloc_entry), reloc_val);
3129+#endif
3130+ writel(reloc_val, reloc_entry);
3131+
3132+ /* Write the updated presumed offset for this entry back out
3133+ * to the user.
3134+ */
3135+ reloc.presumed_offset = target_obj_priv->gtt_offset;
3136+ ret = copy_to_user(relocs + i, &reloc, sizeof(reloc));
3137+ if (ret != 0) {
3138+ drm_gem_object_unreference(target_obj);
3139+ i915_gem_object_unpin(obj);
3140+ return ret;
3141+ }
3142+
3143+ drm_gem_object_unreference(target_obj);
3144+ }
3145+
3146+ if (reloc_page != NULL)
3147+ iounmap(reloc_page);
3148+
3149+#if WATCH_BUF
3150+ if (0)
3151+ i915_gem_dump_object(obj, 128, __func__, ~0);
3152+#endif
3153+ return 0;
3154+}
3155+
3156+/** Dispatch a batchbuffer to the ring
3157+ */
3158+static int
3159+i915_dispatch_gem_execbuffer(struct drm_device *dev,
3160+ struct drm_i915_gem_execbuffer *exec,
3161+ uint64_t exec_offset)
3162+{
3163+ drm_i915_private_t *dev_priv = dev->dev_private;
3164+ struct drm_clip_rect __user *boxes = (struct drm_clip_rect __user *)
3165+ (uintptr_t) exec->cliprects_ptr;
3166+ int nbox = exec->num_cliprects;
3167+ int i = 0, count;
3168+ uint32_t exec_start, exec_len;
3169+ RING_LOCALS;
3170+
3171+ exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
3172+ exec_len = (uint32_t) exec->batch_len;
3173+
3174+ if ((exec_start | exec_len) & 0x7) {
3175+ DRM_ERROR("alignment\n");
3176+ return -EINVAL;
3177+ }
3178+
3179+ if (!exec_start)
3180+ return -EINVAL;
3181+
3182+ count = nbox ? nbox : 1;
3183+
3184+ for (i = 0; i < count; i++) {
3185+ if (i < nbox) {
3186+ int ret = i915_emit_box(dev, boxes, i,
3187+ exec->DR1, exec->DR4);
3188+ if (ret)
3189+ return ret;
3190+ }
3191+
3192+ if (IS_I830(dev) || IS_845G(dev)) {
3193+ BEGIN_LP_RING(4);
3194+ OUT_RING(MI_BATCH_BUFFER);
3195+ OUT_RING(exec_start | MI_BATCH_NON_SECURE);
3196+ OUT_RING(exec_start + exec_len - 4);
3197+ OUT_RING(0);
3198+ ADVANCE_LP_RING();
3199+ } else {
3200+ BEGIN_LP_RING(2);
3201+ if (IS_I965G(dev)) {
3202+ OUT_RING(MI_BATCH_BUFFER_START |
3203+ (2 << 6) |
3204+ MI_BATCH_NON_SECURE_I965);
3205+ OUT_RING(exec_start);
3206+ } else {
3207+ OUT_RING(MI_BATCH_BUFFER_START |
3208+ (2 << 6));
3209+ OUT_RING(exec_start | MI_BATCH_NON_SECURE);
3210+ }
3211+ ADVANCE_LP_RING();
3212+ }
3213+ }
3214+
3215+ /* XXX breadcrumb */
3216+ return 0;
3217+}
3218+
3219+/* Throttle our rendering by waiting until the ring has completed our requests
3220+ * emitted over 20 msec ago.
3221+ *
3222+ * This should get us reasonable parallelism between CPU and GPU but also
3223+ * relatively low latency when blocking on a particular request to finish.
3224+ */
3225+static int
3226+i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv)
3227+{
3228+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
3229+ int ret = 0;
3230+ uint32_t seqno;
3231+
3232+ mutex_lock(&dev->struct_mutex);
3233+ seqno = i915_file_priv->mm.last_gem_throttle_seqno;
3234+ i915_file_priv->mm.last_gem_throttle_seqno =
3235+ i915_file_priv->mm.last_gem_seqno;
3236+ if (seqno)
3237+ ret = i915_wait_request(dev, seqno);
3238+ mutex_unlock(&dev->struct_mutex);
3239+ return ret;
3240+}
3241+
3242+int
3243+i915_gem_execbuffer(struct drm_device *dev, void *data,
3244+ struct drm_file *file_priv)
3245+{
3246+ drm_i915_private_t *dev_priv = dev->dev_private;
3247+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
3248+ struct drm_i915_gem_execbuffer *args = data;
3249+ struct drm_i915_gem_exec_object *exec_list = NULL;
3250+ struct drm_gem_object **object_list = NULL;
3251+ struct drm_gem_object *batch_obj;
3252+ int ret, i, pinned = 0;
3253+ uint64_t exec_offset;
3254+ uint32_t seqno, flush_domains;
3255+
3256+#if WATCH_EXEC
3257+ DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
3258+ (int) args->buffers_ptr, args->buffer_count, args->batch_len);
3259+#endif
3260+
3261+ /* Copy in the exec list from userland */
3262+ exec_list = drm_calloc(sizeof(*exec_list), args->buffer_count,
3263+ DRM_MEM_DRIVER);
3264+ object_list = drm_calloc(sizeof(*object_list), args->buffer_count,
3265+ DRM_MEM_DRIVER);
3266+ if (exec_list == NULL || object_list == NULL) {
3267+ DRM_ERROR("Failed to allocate exec or object list "
3268+ "for %d buffers\n",
3269+ args->buffer_count);
3270+ ret = -ENOMEM;
3271+ goto pre_mutex_err;
3272+ }
3273+ ret = copy_from_user(exec_list,
3274+ (struct drm_i915_relocation_entry __user *)
3275+ (uintptr_t) args->buffers_ptr,
3276+ sizeof(*exec_list) * args->buffer_count);
3277+ if (ret != 0) {
3278+ DRM_ERROR("copy %d exec entries failed %d\n",
3279+ args->buffer_count, ret);
3280+ goto pre_mutex_err;
3281+ }
3282+
3283+ mutex_lock(&dev->struct_mutex);
3284+
3285+ i915_verify_inactive(dev, __FILE__, __LINE__);
3286+
3287+ if (dev_priv->mm.wedged) {
3288+ DRM_ERROR("Execbuf while wedged\n");
3289+ mutex_unlock(&dev->struct_mutex);
3290+ return -EIO;
3291+ }
3292+
3293+ if (dev_priv->mm.suspended) {
3294+ DRM_ERROR("Execbuf while VT-switched.\n");
3295+ mutex_unlock(&dev->struct_mutex);
3296+ return -EBUSY;
3297+ }
3298+
3299+ /* Zero the gloabl flush/invalidate flags. These
3300+ * will be modified as each object is bound to the
3301+ * gtt
3302+ */
3303+ dev->invalidate_domains = 0;
3304+ dev->flush_domains = 0;
3305+
3306+ /* Look up object handles and perform the relocations */
3307+ for (i = 0; i < args->buffer_count; i++) {
3308+ object_list[i] = drm_gem_object_lookup(dev, file_priv,
3309+ exec_list[i].handle);
3310+ if (object_list[i] == NULL) {
3311+ DRM_ERROR("Invalid object handle %d at index %d\n",
3312+ exec_list[i].handle, i);
3313+ ret = -EBADF;
3314+ goto err;
3315+ }
3316+
3317+ object_list[i]->pending_read_domains = 0;
3318+ object_list[i]->pending_write_domain = 0;
3319+ ret = i915_gem_object_pin_and_relocate(object_list[i],
3320+ file_priv,
3321+ &exec_list[i]);
3322+ if (ret) {
3323+ DRM_ERROR("object bind and relocate failed %d\n", ret);
3324+ goto err;
3325+ }
3326+ pinned = i + 1;
3327+ }
3328+
3329+ /* Set the pending read domains for the batch buffer to COMMAND */
3330+ batch_obj = object_list[args->buffer_count-1];
3331+ batch_obj->pending_read_domains = I915_GEM_DOMAIN_COMMAND;
3332+ batch_obj->pending_write_domain = 0;
3333+
3334+ i915_verify_inactive(dev, __FILE__, __LINE__);
3335+
3336+ for (i = 0; i < args->buffer_count; i++) {
3337+ struct drm_gem_object *obj = object_list[i];
3338+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3339+
3340+ if (obj_priv->gtt_space == NULL) {
3341+ /* We evicted the buffer in the process of validating
3342+ * our set of buffers in. We could try to recover by
3343+ * kicking them everything out and trying again from
3344+ * the start.
3345+ */
3346+ ret = -ENOMEM;
3347+ goto err;
3348+ }
3349+
3350+ /* make sure all previous memory operations have passed */
3351+ ret = i915_gem_object_set_domain(obj,
3352+ obj->pending_read_domains,
3353+ obj->pending_write_domain);
3354+ if (ret)
3355+ goto err;
3356+ }
3357+
3358+ i915_verify_inactive(dev, __FILE__, __LINE__);
3359+
3360+ /* Flush/invalidate caches and chipset buffer */
3361+ flush_domains = i915_gem_dev_set_domain(dev);
3362+
3363+ i915_verify_inactive(dev, __FILE__, __LINE__);
3364+
3365+#if WATCH_COHERENCY
3366+ for (i = 0; i < args->buffer_count; i++) {
3367+ i915_gem_object_check_coherency(object_list[i],
3368+ exec_list[i].handle);
3369+ }
3370+#endif
3371+
3372+ exec_offset = exec_list[args->buffer_count - 1].offset;
3373+
3374+#if WATCH_EXEC
3375+ i915_gem_dump_object(object_list[args->buffer_count - 1],
3376+ args->batch_len,
3377+ __func__,
3378+ ~0);
3379+#endif
3380+
3381+ (void)i915_add_request(dev, flush_domains);
3382+
3383+ /* Exec the batchbuffer */
3384+ ret = i915_dispatch_gem_execbuffer(dev, args, exec_offset);
3385+ if (ret) {
3386+ DRM_ERROR("dispatch failed %d\n", ret);
3387+ goto err;
3388+ }
3389+
3390+ /*
3391+ * Ensure that the commands in the batch buffer are
3392+ * finished before the interrupt fires
3393+ */
3394+ flush_domains = i915_retire_commands(dev);
3395+
3396+ i915_verify_inactive(dev, __FILE__, __LINE__);
3397+
3398+ /*
3399+ * Get a seqno representing the execution of the current buffer,
3400+ * which we can wait on. We would like to mitigate these interrupts,
3401+ * likely by only creating seqnos occasionally (so that we have
3402+ * *some* interrupts representing completion of buffers that we can
3403+ * wait on when trying to clear up gtt space).
3404+ */
3405+ seqno = i915_add_request(dev, flush_domains);
3406+ BUG_ON(seqno == 0);
3407+ i915_file_priv->mm.last_gem_seqno = seqno;
3408+ for (i = 0; i < args->buffer_count; i++) {
3409+ struct drm_gem_object *obj = object_list[i];
3410+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3411+
3412+ i915_gem_object_move_to_active(obj);
3413+ obj_priv->last_rendering_seqno = seqno;
3414+#if WATCH_LRU
3415+ DRM_INFO("%s: move to exec list %p\n", __func__, obj);
3416+#endif
3417+ }
3418+#if WATCH_LRU
3419+ i915_dump_lru(dev, __func__);
3420+#endif
3421+
3422+ i915_verify_inactive(dev, __FILE__, __LINE__);
3423+
3424+ /* Copy the new buffer offsets back to the user's exec list. */
3425+ ret = copy_to_user((struct drm_i915_relocation_entry __user *)
3426+ (uintptr_t) args->buffers_ptr,
3427+ exec_list,
3428+ sizeof(*exec_list) * args->buffer_count);
3429+ if (ret)
3430+ DRM_ERROR("failed to copy %d exec entries "
3431+ "back to user (%d)\n",
3432+ args->buffer_count, ret);
3433+err:
3434+ if (object_list != NULL) {
3435+ for (i = 0; i < pinned; i++)
3436+ i915_gem_object_unpin(object_list[i]);
3437+
3438+ for (i = 0; i < args->buffer_count; i++)
3439+ drm_gem_object_unreference(object_list[i]);
3440+ }
3441+ mutex_unlock(&dev->struct_mutex);
3442+
3443+pre_mutex_err:
3444+ drm_free(object_list, sizeof(*object_list) * args->buffer_count,
3445+ DRM_MEM_DRIVER);
3446+ drm_free(exec_list, sizeof(*exec_list) * args->buffer_count,
3447+ DRM_MEM_DRIVER);
3448+
3449+ return ret;
3450+}
3451+
3452+int
3453+i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
3454+{
3455+ struct drm_device *dev = obj->dev;
3456+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3457+ int ret;
3458+
3459+ i915_verify_inactive(dev, __FILE__, __LINE__);
3460+ if (obj_priv->gtt_space == NULL) {
3461+ ret = i915_gem_object_bind_to_gtt(obj, alignment);
3462+ if (ret != 0) {
3463+ DRM_ERROR("Failure to bind: %d", ret);
3464+ return ret;
3465+ }
3466+ }
3467+ obj_priv->pin_count++;
3468+
3469+ /* If the object is not active and not pending a flush,
3470+ * remove it from the inactive list
3471+ */
3472+ if (obj_priv->pin_count == 1) {
3473+ atomic_inc(&dev->pin_count);
3474+ atomic_add(obj->size, &dev->pin_memory);
3475+ if (!obj_priv->active &&
3476+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
3477+ I915_GEM_DOMAIN_GTT)) == 0 &&
3478+ !list_empty(&obj_priv->list))
3479+ list_del_init(&obj_priv->list);
3480+ }
3481+ i915_verify_inactive(dev, __FILE__, __LINE__);
3482+
3483+ return 0;
3484+}
3485+
3486+void
3487+i915_gem_object_unpin(struct drm_gem_object *obj)
3488+{
3489+ struct drm_device *dev = obj->dev;
3490+ drm_i915_private_t *dev_priv = dev->dev_private;
3491+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3492+
3493+ i915_verify_inactive(dev, __FILE__, __LINE__);
3494+ obj_priv->pin_count--;
3495+ BUG_ON(obj_priv->pin_count < 0);
3496+ BUG_ON(obj_priv->gtt_space == NULL);
3497+
3498+ /* If the object is no longer pinned, and is
3499+ * neither active nor being flushed, then stick it on
3500+ * the inactive list
3501+ */
3502+ if (obj_priv->pin_count == 0) {
3503+ if (!obj_priv->active &&
3504+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
3505+ I915_GEM_DOMAIN_GTT)) == 0)
3506+ list_move_tail(&obj_priv->list,
3507+ &dev_priv->mm.inactive_list);
3508+ atomic_dec(&dev->pin_count);
3509+ atomic_sub(obj->size, &dev->pin_memory);
3510+ }
3511+ i915_verify_inactive(dev, __FILE__, __LINE__);
3512+}
3513+
3514+int
3515+i915_gem_pin_ioctl(struct drm_device *dev, void *data,
3516+ struct drm_file *file_priv)
3517+{
3518+ struct drm_i915_gem_pin *args = data;
3519+ struct drm_gem_object *obj;
3520+ struct drm_i915_gem_object *obj_priv;
3521+ int ret;
3522+
3523+ mutex_lock(&dev->struct_mutex);
3524+
3525+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3526+ if (obj == NULL) {
3527+ DRM_ERROR("Bad handle in i915_gem_pin_ioctl(): %d\n",
3528+ args->handle);
3529+ mutex_unlock(&dev->struct_mutex);
3530+ return -EBADF;
3531+ }
3532+ obj_priv = obj->driver_private;
3533+
3534+ ret = i915_gem_object_pin(obj, args->alignment);
3535+ if (ret != 0) {
3536+ drm_gem_object_unreference(obj);
3537+ mutex_unlock(&dev->struct_mutex);
3538+ return ret;
3539+ }
3540+
3541+ /* XXX - flush the CPU caches for pinned objects
3542+ * as the X server doesn't manage domains yet
3543+ */
3544+ if (obj->write_domain & I915_GEM_DOMAIN_CPU) {
3545+ i915_gem_clflush_object(obj);
3546+ drm_agp_chipset_flush(dev);
3547+ obj->write_domain = 0;
3548+ }
3549+ args->offset = obj_priv->gtt_offset;
3550+ drm_gem_object_unreference(obj);
3551+ mutex_unlock(&dev->struct_mutex);
3552+
3553+ return 0;
3554+}
3555+
3556+int
3557+i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
3558+ struct drm_file *file_priv)
3559+{
3560+ struct drm_i915_gem_pin *args = data;
3561+ struct drm_gem_object *obj;
3562+
3563+ mutex_lock(&dev->struct_mutex);
3564+
3565+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3566+ if (obj == NULL) {
3567+ DRM_ERROR("Bad handle in i915_gem_unpin_ioctl(): %d\n",
3568+ args->handle);
3569+ mutex_unlock(&dev->struct_mutex);
3570+ return -EBADF;
3571+ }
3572+
3573+ i915_gem_object_unpin(obj);
3574+
3575+ drm_gem_object_unreference(obj);
3576+ mutex_unlock(&dev->struct_mutex);
3577+ return 0;
3578+}
3579+
3580+int
3581+i915_gem_busy_ioctl(struct drm_device *dev, void *data,
3582+ struct drm_file *file_priv)
3583+{
3584+ struct drm_i915_gem_busy *args = data;
3585+ struct drm_gem_object *obj;
3586+ struct drm_i915_gem_object *obj_priv;
3587+
3588+ mutex_lock(&dev->struct_mutex);
3589+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3590+ if (obj == NULL) {
3591+ DRM_ERROR("Bad handle in i915_gem_busy_ioctl(): %d\n",
3592+ args->handle);
3593+ mutex_unlock(&dev->struct_mutex);
3594+ return -EBADF;
3595+ }
3596+
3597+ obj_priv = obj->driver_private;
3598+ args->busy = obj_priv->active;
3599+
3600+ drm_gem_object_unreference(obj);
3601+ mutex_unlock(&dev->struct_mutex);
3602+ return 0;
3603+}
3604+
3605+int
3606+i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
3607+ struct drm_file *file_priv)
3608+{
3609+ return i915_gem_ring_throttle(dev, file_priv);
3610+}
3611+
3612+int i915_gem_init_object(struct drm_gem_object *obj)
3613+{
3614+ struct drm_i915_gem_object *obj_priv;
3615+
3616+ obj_priv = drm_calloc(1, sizeof(*obj_priv), DRM_MEM_DRIVER);
3617+ if (obj_priv == NULL)
3618+ return -ENOMEM;
3619+
3620+ /*
3621+ * We've just allocated pages from the kernel,
3622+ * so they've just been written by the CPU with
3623+ * zeros. They'll need to be clflushed before we
3624+ * use them with the GPU.
3625+ */
3626+ obj->write_domain = I915_GEM_DOMAIN_CPU;
3627+ obj->read_domains = I915_GEM_DOMAIN_CPU;
3628+
3629+ obj->driver_private = obj_priv;
3630+ obj_priv->obj = obj;
3631+ INIT_LIST_HEAD(&obj_priv->list);
3632+ return 0;
3633+}
3634+
3635+void i915_gem_free_object(struct drm_gem_object *obj)
3636+{
3637+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3638+
3639+ while (obj_priv->pin_count > 0)
3640+ i915_gem_object_unpin(obj);
3641+
3642+ i915_gem_object_unbind(obj);
3643+
3644+ drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER);
3645+ drm_free(obj->driver_private, 1, DRM_MEM_DRIVER);
3646+}
3647+
3648+static int
3649+i915_gem_set_domain(struct drm_gem_object *obj,
3650+ struct drm_file *file_priv,
3651+ uint32_t read_domains,
3652+ uint32_t write_domain)
3653+{
3654+ struct drm_device *dev = obj->dev;
3655+ int ret;
3656+ uint32_t flush_domains;
3657+
3658+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
3659+
3660+ ret = i915_gem_object_set_domain(obj, read_domains, write_domain);
3661+ if (ret)
3662+ return ret;
3663+ flush_domains = i915_gem_dev_set_domain(obj->dev);
3664+
3665+ if (flush_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT))
3666+ (void) i915_add_request(dev, flush_domains);
3667+
3668+ return 0;
3669+}
3670+
3671+/** Unbinds all objects that are on the given buffer list. */
3672+static int
3673+i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head)
3674+{
3675+ struct drm_gem_object *obj;
3676+ struct drm_i915_gem_object *obj_priv;
3677+ int ret;
3678+
3679+ while (!list_empty(head)) {
3680+ obj_priv = list_first_entry(head,
3681+ struct drm_i915_gem_object,
3682+ list);
3683+ obj = obj_priv->obj;
3684+
3685+ if (obj_priv->pin_count != 0) {
3686+ DRM_ERROR("Pinned object in unbind list\n");
3687+ mutex_unlock(&dev->struct_mutex);
3688+ return -EINVAL;
3689+ }
3690+
3691+ ret = i915_gem_object_unbind(obj);
3692+ if (ret != 0) {
3693+ DRM_ERROR("Error unbinding object in LeaveVT: %d\n",
3694+ ret);
3695+ mutex_unlock(&dev->struct_mutex);
3696+ return ret;
3697+ }
3698+ }
3699+
3700+
3701+ return 0;
3702+}
3703+
3704+static int
3705+i915_gem_idle(struct drm_device *dev)
3706+{
3707+ drm_i915_private_t *dev_priv = dev->dev_private;
3708+ uint32_t seqno, cur_seqno, last_seqno;
3709+ int stuck, ret;
3710+
3711+ if (dev_priv->mm.suspended)
3712+ return 0;
3713+
3714+ /* Hack! Don't let anybody do execbuf while we don't control the chip.
3715+ * We need to replace this with a semaphore, or something.
3716+ */
3717+ dev_priv->mm.suspended = 1;
3718+
3719+ i915_kernel_lost_context(dev);
3720+
3721+ /* Flush the GPU along with all non-CPU write domains
3722+ */
3723+ i915_gem_flush(dev, ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT),
3724+ ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
3725+ seqno = i915_add_request(dev, ~(I915_GEM_DOMAIN_CPU |
3726+ I915_GEM_DOMAIN_GTT));
3727+
3728+ if (seqno == 0) {
3729+ mutex_unlock(&dev->struct_mutex);
3730+ return -ENOMEM;
3731+ }
3732+
3733+ dev_priv->mm.waiting_gem_seqno = seqno;
3734+ last_seqno = 0;
3735+ stuck = 0;
3736+ for (;;) {
3737+ cur_seqno = i915_get_gem_seqno(dev);
3738+ if (i915_seqno_passed(cur_seqno, seqno))
3739+ break;
3740+ if (last_seqno == cur_seqno) {
3741+ if (stuck++ > 100) {
3742+ DRM_ERROR("hardware wedged\n");
3743+ dev_priv->mm.wedged = 1;
3744+ DRM_WAKEUP(&dev_priv->irq_queue);
3745+ break;
3746+ }
3747+ }
3748+ msleep(10);
3749+ last_seqno = cur_seqno;
3750+ }
3751+ dev_priv->mm.waiting_gem_seqno = 0;
3752+
3753+ i915_gem_retire_requests(dev);
3754+
3755+ /* Active and flushing should now be empty as we've
3756+ * waited for a sequence higher than any pending execbuffer
3757+ */
3758+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3759+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3760+
3761+ /* Request should now be empty as we've also waited
3762+ * for the last request in the list
3763+ */
3764+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3765+
3766+ /* Move all buffers out of the GTT. */
3767+ ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list);
3768+ if (ret)
3769+ return ret;
3770+
3771+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3772+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3773+ BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
3774+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3775+ return 0;
3776+}
3777+
3778+static int
3779+i915_gem_init_hws(struct drm_device *dev)
3780+{
3781+ drm_i915_private_t *dev_priv = dev->dev_private;
3782+ struct drm_gem_object *obj;
3783+ struct drm_i915_gem_object *obj_priv;
3784+ int ret;
3785+
3786+ /* If we need a physical address for the status page, it's already
3787+ * initialized at driver load time.
3788+ */
3789+ if (!I915_NEED_GFX_HWS(dev))
3790+ return 0;
3791+
3792+ obj = drm_gem_object_alloc(dev, 4096);
3793+ if (obj == NULL) {
3794+ DRM_ERROR("Failed to allocate status page\n");
3795+ return -ENOMEM;
3796+ }
3797+ obj_priv = obj->driver_private;
3798+
3799+ ret = i915_gem_object_pin(obj, 4096);
3800+ if (ret != 0) {
3801+ drm_gem_object_unreference(obj);
3802+ return ret;
3803+ }
3804+
3805+ dev_priv->status_gfx_addr = obj_priv->gtt_offset;
3806+ dev_priv->hws_map.offset = dev->agp->base + obj_priv->gtt_offset;
3807+ dev_priv->hws_map.size = 4096;
3808+ dev_priv->hws_map.type = 0;
3809+ dev_priv->hws_map.flags = 0;
3810+ dev_priv->hws_map.mtrr = 0;
3811+
3812+ drm_core_ioremap(&dev_priv->hws_map, dev);
3813+ if (dev_priv->hws_map.handle == NULL) {
3814+ DRM_ERROR("Failed to map status page.\n");
3815+ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3816+ drm_gem_object_unreference(obj);
3817+ return -EINVAL;
3818+ }
3819+ dev_priv->hws_obj = obj;
3820+ dev_priv->hw_status_page = dev_priv->hws_map.handle;
3821+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
3822+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
3823+ DRM_DEBUG("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
3824+
3825+ return 0;
3826+}
3827+
3828+static int
3829+i915_gem_init_ringbuffer(struct drm_device *dev)
3830+{
3831+ drm_i915_private_t *dev_priv = dev->dev_private;
3832+ struct drm_gem_object *obj;
3833+ struct drm_i915_gem_object *obj_priv;
3834+ int ret;
3835+
3836+ ret = i915_gem_init_hws(dev);
3837+ if (ret != 0)
3838+ return ret;
3839+
3840+ obj = drm_gem_object_alloc(dev, 128 * 1024);
3841+ if (obj == NULL) {
3842+ DRM_ERROR("Failed to allocate ringbuffer\n");
3843+ return -ENOMEM;
3844+ }
3845+ obj_priv = obj->driver_private;
3846+
3847+ ret = i915_gem_object_pin(obj, 4096);
3848+ if (ret != 0) {
3849+ drm_gem_object_unreference(obj);
3850+ return ret;
3851+ }
3852+
3853+ /* Set up the kernel mapping for the ring. */
3854+ dev_priv->ring.Size = obj->size;
3855+ dev_priv->ring.tail_mask = obj->size - 1;
3856+
3857+ dev_priv->ring.map.offset = dev->agp->base + obj_priv->gtt_offset;
3858+ dev_priv->ring.map.size = obj->size;
3859+ dev_priv->ring.map.type = 0;
3860+ dev_priv->ring.map.flags = 0;
3861+ dev_priv->ring.map.mtrr = 0;
3862+
3863+ drm_core_ioremap(&dev_priv->ring.map, dev);
3864+ if (dev_priv->ring.map.handle == NULL) {
3865+ DRM_ERROR("Failed to map ringbuffer.\n");
3866+ memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3867+ drm_gem_object_unreference(obj);
3868+ return -EINVAL;
3869+ }
3870+ dev_priv->ring.ring_obj = obj;
3871+ dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
3872+
3873+ /* Stop the ring if it's running. */
3874+ I915_WRITE(PRB0_CTL, 0);
3875+ I915_WRITE(PRB0_HEAD, 0);
3876+ I915_WRITE(PRB0_TAIL, 0);
3877+ I915_WRITE(PRB0_START, 0);
3878+
3879+ /* Initialize the ring. */
3880+ I915_WRITE(PRB0_START, obj_priv->gtt_offset);
3881+ I915_WRITE(PRB0_CTL,
3882+ ((obj->size - 4096) & RING_NR_PAGES) |
3883+ RING_NO_REPORT |
3884+ RING_VALID);
3885+
3886+ /* Update our cache of the ring state */
3887+ i915_kernel_lost_context(dev);
3888+
3889+ return 0;
3890+}
3891+
3892+static void
3893+i915_gem_cleanup_ringbuffer(struct drm_device *dev)
3894+{
3895+ drm_i915_private_t *dev_priv = dev->dev_private;
3896+
3897+ if (dev_priv->ring.ring_obj == NULL)
3898+ return;
3899+
3900+ drm_core_ioremapfree(&dev_priv->ring.map, dev);
3901+
3902+ i915_gem_object_unpin(dev_priv->ring.ring_obj);
3903+ drm_gem_object_unreference(dev_priv->ring.ring_obj);
3904+ dev_priv->ring.ring_obj = NULL;
3905+ memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3906+
3907+ if (dev_priv->hws_obj != NULL) {
3908+ i915_gem_object_unpin(dev_priv->hws_obj);
3909+ drm_gem_object_unreference(dev_priv->hws_obj);
3910+ dev_priv->hws_obj = NULL;
3911+ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3912+
3913+ /* Write high address into HWS_PGA when disabling. */
3914+ I915_WRITE(HWS_PGA, 0x1ffff000);
3915+ }
3916+}
3917+
3918+int
3919+i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
3920+ struct drm_file *file_priv)
3921+{
3922+ drm_i915_private_t *dev_priv = dev->dev_private;
3923+ int ret;
3924+
3925+ if (dev_priv->mm.wedged) {
3926+ DRM_ERROR("Reenabling wedged hardware, good luck\n");
3927+ dev_priv->mm.wedged = 0;
3928+ }
3929+
3930+ ret = i915_gem_init_ringbuffer(dev);
3931+ if (ret != 0)
3932+ return ret;
3933+
3934+ mutex_lock(&dev->struct_mutex);
3935+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3936+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3937+ BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
3938+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3939+ dev_priv->mm.suspended = 0;
3940+ mutex_unlock(&dev->struct_mutex);
3941+ return 0;
3942+}
3943+
3944+int
3945+i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
3946+ struct drm_file *file_priv)
3947+{
3948+ int ret;
3949+
3950+ mutex_lock(&dev->struct_mutex);
3951+ ret = i915_gem_idle(dev);
3952+ if (ret == 0)
3953+ i915_gem_cleanup_ringbuffer(dev);
3954+ mutex_unlock(&dev->struct_mutex);
3955+
3956+ return 0;
3957+}
3958+
3959+void
3960+i915_gem_lastclose(struct drm_device *dev)
3961+{
3962+ int ret;
3963+ drm_i915_private_t *dev_priv = dev->dev_private;
3964+
3965+ mutex_lock(&dev->struct_mutex);
3966+
3967+ if (dev_priv->ring.ring_obj != NULL) {
3968+ ret = i915_gem_idle(dev);
3969+ if (ret)
3970+ DRM_ERROR("failed to idle hardware: %d\n", ret);
3971+
3972+ i915_gem_cleanup_ringbuffer(dev);
3973+ }
3974+
3975+ mutex_unlock(&dev->struct_mutex);
3976+}
3977+
3978+void
3979+i915_gem_load(struct drm_device *dev)
3980+{
3981+ drm_i915_private_t *dev_priv = dev->dev_private;
3982+
3983+ INIT_LIST_HEAD(&dev_priv->mm.active_list);
3984+ INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
3985+ INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
3986+ INIT_LIST_HEAD(&dev_priv->mm.request_list);
3987+ INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
3988+ i915_gem_retire_work_handler);
3989+ dev_priv->mm.next_gem_seqno = 1;
3990+
3991+ i915_gem_detect_bit_6_swizzle(dev);
3992+}
3993diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c
3994new file mode 100644
3995index 0000000..131c088
3996--- /dev/null
3997+++ b/drivers/gpu/drm/i915/i915_gem_debug.c
3998@@ -0,0 +1,201 @@
3999+/*
4000+ * Copyright © 2008 Intel Corporation
4001+ *
4002+ * Permission is hereby granted, free of charge, to any person obtaining a
4003+ * copy of this software and associated documentation files (the "Software"),
4004+ * to deal in the Software without restriction, including without limitation
4005+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4006+ * and/or sell copies of the Software, and to permit persons to whom the
4007+ * Software is furnished to do so, subject to the following conditions:
4008+ *
4009+ * The above copyright notice and this permission notice (including the next
4010+ * paragraph) shall be included in all copies or substantial portions of the
4011+ * Software.
4012+ *
4013+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4014+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4015+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4016+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4017+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4018+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
4019+ * IN THE SOFTWARE.
4020+ *
4021+ * Authors:
4022+ * Keith Packard <keithp@keithp.com>
4023+ *
4024+ */
4025+
4026+#include "drmP.h"
4027+#include "drm.h"
4028+#include "i915_drm.h"
4029+#include "i915_drv.h"
4030+
4031+#if WATCH_INACTIVE
4032+void
4033+i915_verify_inactive(struct drm_device *dev, char *file, int line)
4034+{
4035+ drm_i915_private_t *dev_priv = dev->dev_private;
4036+ struct drm_gem_object *obj;
4037+ struct drm_i915_gem_object *obj_priv;
4038+
4039+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
4040+ obj = obj_priv->obj;
4041+ if (obj_priv->pin_count || obj_priv->active ||
4042+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
4043+ I915_GEM_DOMAIN_GTT)))
4044+ DRM_ERROR("inactive %p (p %d a %d w %x) %s:%d\n",
4045+ obj,
4046+ obj_priv->pin_count, obj_priv->active,
4047+ obj->write_domain, file, line);
4048+ }
4049+}
4050+#endif /* WATCH_INACTIVE */
4051+
4052+
4053+#if WATCH_BUF | WATCH_EXEC | WATCH_PWRITE
4054+static void
4055+i915_gem_dump_page(struct page *page, uint32_t start, uint32_t end,
4056+ uint32_t bias, uint32_t mark)
4057+{
4058+ uint32_t *mem = kmap_atomic(page, KM_USER0);
4059+ int i;
4060+ for (i = start; i < end; i += 4)
4061+ DRM_INFO("%08x: %08x%s\n",
4062+ (int) (bias + i), mem[i / 4],
4063+ (bias + i == mark) ? " ********" : "");
4064+ kunmap_atomic(mem, KM_USER0);
4065+ /* give syslog time to catch up */
4066+ msleep(1);
4067+}
4068+
4069+void
4070+i915_gem_dump_object(struct drm_gem_object *obj, int len,
4071+ const char *where, uint32_t mark)
4072+{
4073+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
4074+ int page;
4075+
4076+ DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset);
4077+ for (page = 0; page < (len + PAGE_SIZE-1) / PAGE_SIZE; page++) {
4078+ int page_len, chunk, chunk_len;
4079+
4080+ page_len = len - page * PAGE_SIZE;
4081+ if (page_len > PAGE_SIZE)
4082+ page_len = PAGE_SIZE;
4083+
4084+ for (chunk = 0; chunk < page_len; chunk += 128) {
4085+ chunk_len = page_len - chunk;
4086+ if (chunk_len > 128)
4087+ chunk_len = 128;
4088+ i915_gem_dump_page(obj_priv->page_list[page],
4089+ chunk, chunk + chunk_len,
4090+ obj_priv->gtt_offset +
4091+ page * PAGE_SIZE,
4092+ mark);
4093+ }
4094+ }
4095+}
4096+#endif
4097+
4098+#if WATCH_LRU
4099+void
4100+i915_dump_lru(struct drm_device *dev, const char *where)
4101+{
4102+ drm_i915_private_t *dev_priv = dev->dev_private;
4103+ struct drm_i915_gem_object *obj_priv;
4104+
4105+ DRM_INFO("active list %s {\n", where);
4106+ list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
4107+ list)
4108+ {
4109+ DRM_INFO(" %p: %08x\n", obj_priv,
4110+ obj_priv->last_rendering_seqno);
4111+ }
4112+ DRM_INFO("}\n");
4113+ DRM_INFO("flushing list %s {\n", where);
4114+ list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
4115+ list)
4116+ {
4117+ DRM_INFO(" %p: %08x\n", obj_priv,
4118+ obj_priv->last_rendering_seqno);
4119+ }
4120+ DRM_INFO("}\n");
4121+ DRM_INFO("inactive %s {\n", where);
4122+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
4123+ DRM_INFO(" %p: %08x\n", obj_priv,
4124+ obj_priv->last_rendering_seqno);
4125+ }
4126+ DRM_INFO("}\n");
4127+}
4128+#endif
4129+
4130+
4131+#if WATCH_COHERENCY
4132+void
4133+i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle)
4134+{
4135+ struct drm_device *dev = obj->dev;
4136+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
4137+ int page;
4138+ uint32_t *gtt_mapping;
4139+ uint32_t *backing_map = NULL;
4140+ int bad_count = 0;
4141+
4142+ DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %dkb):\n",
4143+ __func__, obj, obj_priv->gtt_offset, handle,
4144+ obj->size / 1024);
4145+
4146+ gtt_mapping = ioremap(dev->agp->base + obj_priv->gtt_offset,
4147+ obj->size);
4148+ if (gtt_mapping == NULL) {
4149+ DRM_ERROR("failed to map GTT space\n");
4150+ return;
4151+ }
4152+
4153+ for (page = 0; page < obj->size / PAGE_SIZE; page++) {
4154+ int i;
4155+
4156+ backing_map = kmap_atomic(obj_priv->page_list[page], KM_USER0);
4157+
4158+ if (backing_map == NULL) {
4159+ DRM_ERROR("failed to map backing page\n");
4160+ goto out;
4161+ }
4162+
4163+ for (i = 0; i < PAGE_SIZE / 4; i++) {
4164+ uint32_t cpuval = backing_map[i];
4165+ uint32_t gttval = readl(gtt_mapping +
4166+ page * 1024 + i);
4167+
4168+ if (cpuval != gttval) {
4169+ DRM_INFO("incoherent CPU vs GPU at 0x%08x: "
4170+ "0x%08x vs 0x%08x\n",
4171+ (int)(obj_priv->gtt_offset +
4172+ page * PAGE_SIZE + i * 4),
4173+ cpuval, gttval);
4174+ if (bad_count++ >= 8) {
4175+ DRM_INFO("...\n");
4176+ goto out;
4177+ }
4178+ }
4179+ }
4180+ kunmap_atomic(backing_map, KM_USER0);
4181+ backing_map = NULL;
4182+ }
4183+
4184+ out:
4185+ if (backing_map != NULL)
4186+ kunmap_atomic(backing_map, KM_USER0);
4187+ iounmap(gtt_mapping);
4188+
4189+ /* give syslog time to catch up */
4190+ msleep(1);
4191+
4192+ /* Directly flush the object, since we just loaded values with the CPU
4193+ * from the backing pages and we don't want to disturb the cache
4194+ * management that we're trying to observe.
4195+ */
4196+
4197+ i915_gem_clflush_object(obj);
4198+}
4199+#endif
4200diff --git a/drivers/gpu/drm/i915/i915_gem_proc.c b/drivers/gpu/drm/i915/i915_gem_proc.c
4201new file mode 100644
4202index 0000000..15d4160
4203--- /dev/null
4204+++ b/drivers/gpu/drm/i915/i915_gem_proc.c
4205@@ -0,0 +1,292 @@
4206+/*
4207+ * Copyright © 2008 Intel Corporation
4208+ *
4209+ * Permission is hereby granted, free of charge, to any person obtaining a
4210+ * copy of this software and associated documentation files (the "Software"),
4211+ * to deal in the Software without restriction, including without limitation
4212+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4213+ * and/or sell copies of the Software, and to permit persons to whom the
4214+ * Software is furnished to do so, subject to the following conditions:
4215+ *
4216+ * The above copyright notice and this permission notice (including the next
4217+ * paragraph) shall be included in all copies or substantial portions of the
4218+ * Software.
4219+ *
4220+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4221+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4222+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4223+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4224+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4225+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
4226+ * IN THE SOFTWARE.
4227+ *
4228+ * Authors:
4229+ * Eric Anholt <eric@anholt.net>
4230+ * Keith Packard <keithp@keithp.com>
4231+ *
4232+ */
4233+
4234+#include "drmP.h"
4235+#include "drm.h"
4236+#include "i915_drm.h"
4237+#include "i915_drv.h"
4238+
4239+static int i915_gem_active_info(char *buf, char **start, off_t offset,
4240+ int request, int *eof, void *data)
4241+{
4242+ struct drm_minor *minor = (struct drm_minor *) data;
4243+ struct drm_device *dev = minor->dev;
4244+ drm_i915_private_t *dev_priv = dev->dev_private;
4245+ struct drm_i915_gem_object *obj_priv;
4246+ int len = 0;
4247+
4248+ if (offset > DRM_PROC_LIMIT) {
4249+ *eof = 1;
4250+ return 0;
4251+ }
4252+
4253+ *start = &buf[offset];
4254+ *eof = 0;
4255+ DRM_PROC_PRINT("Active:\n");
4256+ list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
4257+ list)
4258+ {
4259+ struct drm_gem_object *obj = obj_priv->obj;
4260+ if (obj->name) {
4261+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4262+ obj, obj->name,
4263+ obj->read_domains, obj->write_domain,
4264+ obj_priv->last_rendering_seqno);
4265+ } else {
4266+ DRM_PROC_PRINT(" %p: %08x %08x %d\n",
4267+ obj,
4268+ obj->read_domains, obj->write_domain,
4269+ obj_priv->last_rendering_seqno);
4270+ }
4271+ }
4272+ if (len > request + offset)
4273+ return request;
4274+ *eof = 1;
4275+ return len - offset;
4276+}
4277+
4278+static int i915_gem_flushing_info(char *buf, char **start, off_t offset,
4279+ int request, int *eof, void *data)
4280+{
4281+ struct drm_minor *minor = (struct drm_minor *) data;
4282+ struct drm_device *dev = minor->dev;
4283+ drm_i915_private_t *dev_priv = dev->dev_private;
4284+ struct drm_i915_gem_object *obj_priv;
4285+ int len = 0;
4286+
4287+ if (offset > DRM_PROC_LIMIT) {
4288+ *eof = 1;
4289+ return 0;
4290+ }
4291+
4292+ *start = &buf[offset];
4293+ *eof = 0;
4294+ DRM_PROC_PRINT("Flushing:\n");
4295+ list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
4296+ list)
4297+ {
4298+ struct drm_gem_object *obj = obj_priv->obj;
4299+ if (obj->name) {
4300+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4301+ obj, obj->name,
4302+ obj->read_domains, obj->write_domain,
4303+ obj_priv->last_rendering_seqno);
4304+ } else {
4305+ DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
4306+ obj->read_domains, obj->write_domain,
4307+ obj_priv->last_rendering_seqno);
4308+ }
4309+ }
4310+ if (len > request + offset)
4311+ return request;
4312+ *eof = 1;
4313+ return len - offset;
4314+}
4315+
4316+static int i915_gem_inactive_info(char *buf, char **start, off_t offset,
4317+ int request, int *eof, void *data)
4318+{
4319+ struct drm_minor *minor = (struct drm_minor *) data;
4320+ struct drm_device *dev = minor->dev;
4321+ drm_i915_private_t *dev_priv = dev->dev_private;
4322+ struct drm_i915_gem_object *obj_priv;
4323+ int len = 0;
4324+
4325+ if (offset > DRM_PROC_LIMIT) {
4326+ *eof = 1;
4327+ return 0;
4328+ }
4329+
4330+ *start = &buf[offset];
4331+ *eof = 0;
4332+ DRM_PROC_PRINT("Inactive:\n");
4333+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list,
4334+ list)
4335+ {
4336+ struct drm_gem_object *obj = obj_priv->obj;
4337+ if (obj->name) {
4338+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4339+ obj, obj->name,
4340+ obj->read_domains, obj->write_domain,
4341+ obj_priv->last_rendering_seqno);
4342+ } else {
4343+ DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
4344+ obj->read_domains, obj->write_domain,
4345+ obj_priv->last_rendering_seqno);
4346+ }
4347+ }
4348+ if (len > request + offset)
4349+ return request;
4350+ *eof = 1;
4351+ return len - offset;
4352+}
4353+
4354+static int i915_gem_request_info(char *buf, char **start, off_t offset,
4355+ int request, int *eof, void *data)
4356+{
4357+ struct drm_minor *minor = (struct drm_minor *) data;
4358+ struct drm_device *dev = minor->dev;
4359+ drm_i915_private_t *dev_priv = dev->dev_private;
4360+ struct drm_i915_gem_request *gem_request;
4361+ int len = 0;
4362+
4363+ if (offset > DRM_PROC_LIMIT) {
4364+ *eof = 1;
4365+ return 0;
4366+ }
4367+
4368+ *start = &buf[offset];
4369+ *eof = 0;
4370+ DRM_PROC_PRINT("Request:\n");
4371+ list_for_each_entry(gem_request, &dev_priv->mm.request_list,
4372+ list)
4373+ {
4374+ DRM_PROC_PRINT(" %d @ %d %08x\n",
4375+ gem_request->seqno,
4376+ (int) (jiffies - gem_request->emitted_jiffies),
4377+ gem_request->flush_domains);
4378+ }
4379+ if (len > request + offset)
4380+ return request;
4381+ *eof = 1;
4382+ return len - offset;
4383+}
4384+
4385+static int i915_gem_seqno_info(char *buf, char **start, off_t offset,
4386+ int request, int *eof, void *data)
4387+{
4388+ struct drm_minor *minor = (struct drm_minor *) data;
4389+ struct drm_device *dev = minor->dev;
4390+ drm_i915_private_t *dev_priv = dev->dev_private;
4391+ int len = 0;
4392+
4393+ if (offset > DRM_PROC_LIMIT) {
4394+ *eof = 1;
4395+ return 0;
4396+ }
4397+
4398+ *start = &buf[offset];
4399+ *eof = 0;
4400+ DRM_PROC_PRINT("Current sequence: %d\n", i915_get_gem_seqno(dev));
4401+ DRM_PROC_PRINT("Waiter sequence: %d\n",
4402+ dev_priv->mm.waiting_gem_seqno);
4403+ DRM_PROC_PRINT("IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno);
4404+ if (len > request + offset)
4405+ return request;
4406+ *eof = 1;
4407+ return len - offset;
4408+}
4409+
4410+
4411+static int i915_interrupt_info(char *buf, char **start, off_t offset,
4412+ int request, int *eof, void *data)
4413+{
4414+ struct drm_minor *minor = (struct drm_minor *) data;
4415+ struct drm_device *dev = minor->dev;
4416+ drm_i915_private_t *dev_priv = dev->dev_private;
4417+ int len = 0;
4418+
4419+ if (offset > DRM_PROC_LIMIT) {
4420+ *eof = 1;
4421+ return 0;
4422+ }
4423+
4424+ *start = &buf[offset];
4425+ *eof = 0;
4426+ DRM_PROC_PRINT("Interrupt enable: %08x\n",
4427+ I915_READ(IER));
4428+ DRM_PROC_PRINT("Interrupt identity: %08x\n",
4429+ I915_READ(IIR));
4430+ DRM_PROC_PRINT("Interrupt mask: %08x\n",
4431+ I915_READ(IMR));
4432+ DRM_PROC_PRINT("Pipe A stat: %08x\n",
4433+ I915_READ(PIPEASTAT));
4434+ DRM_PROC_PRINT("Pipe B stat: %08x\n",
4435+ I915_READ(PIPEBSTAT));
4436+ DRM_PROC_PRINT("Interrupts received: %d\n",
4437+ atomic_read(&dev_priv->irq_received));
4438+ DRM_PROC_PRINT("Current sequence: %d\n",
4439+ i915_get_gem_seqno(dev));
4440+ DRM_PROC_PRINT("Waiter sequence: %d\n",
4441+ dev_priv->mm.waiting_gem_seqno);
4442+ DRM_PROC_PRINT("IRQ sequence: %d\n",
4443+ dev_priv->mm.irq_gem_seqno);
4444+ if (len > request + offset)
4445+ return request;
4446+ *eof = 1;
4447+ return len - offset;
4448+}
4449+
4450+static struct drm_proc_list {
4451+ /** file name */
4452+ const char *name;
4453+ /** proc callback*/
4454+ int (*f) (char *, char **, off_t, int, int *, void *);
4455+} i915_gem_proc_list[] = {
4456+ {"i915_gem_active", i915_gem_active_info},
4457+ {"i915_gem_flushing", i915_gem_flushing_info},
4458+ {"i915_gem_inactive", i915_gem_inactive_info},
4459+ {"i915_gem_request", i915_gem_request_info},
4460+ {"i915_gem_seqno", i915_gem_seqno_info},
4461+ {"i915_gem_interrupt", i915_interrupt_info},
4462+};
4463+
4464+#define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list)
4465+
4466+int i915_gem_proc_init(struct drm_minor *minor)
4467+{
4468+ struct proc_dir_entry *ent;
4469+ int i, j;
4470+
4471+ for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) {
4472+ ent = create_proc_entry(i915_gem_proc_list[i].name,
4473+ S_IFREG | S_IRUGO, minor->dev_root);
4474+ if (!ent) {
4475+ DRM_ERROR("Cannot create /proc/dri/.../%s\n",
4476+ i915_gem_proc_list[i].name);
4477+ for (j = 0; j < i; j++)
4478+ remove_proc_entry(i915_gem_proc_list[i].name,
4479+ minor->dev_root);
4480+ return -1;
4481+ }
4482+ ent->read_proc = i915_gem_proc_list[i].f;
4483+ ent->data = minor;
4484+ }
4485+ return 0;
4486+}
4487+
4488+void i915_gem_proc_cleanup(struct drm_minor *minor)
4489+{
4490+ int i;
4491+
4492+ if (!minor->dev_root)
4493+ return;
4494+
4495+ for (i = 0; i < I915_GEM_PROC_ENTRIES; i++)
4496+ remove_proc_entry(i915_gem_proc_list[i].name, minor->dev_root);
4497+}
4498diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
4499new file mode 100644
4500index 0000000..0c1b3a0
4501--- /dev/null
4502+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
4503@@ -0,0 +1,256 @@
4504+/*
4505+ * Copyright © 2008 Intel Corporation
4506+ *
4507+ * Permission is hereby granted, free of charge, to any person obtaining a
4508+ * copy of this software and associated documentation files (the "Software"),
4509+ * to deal in the Software without restriction, including without limitation
4510+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4511+ * and/or sell copies of the Software, and to permit persons to whom the
4512+ * Software is furnished to do so, subject to the following conditions:
4513+ *
4514+ * The above copyright notice and this permission notice (including the next
4515+ * paragraph) shall be included in all copies or substantial portions of the
4516+ * Software.
4517+ *
4518+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4519+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4520+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4521+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4522+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4523+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
4524+ * IN THE SOFTWARE.
4525+ *
4526+ * Authors:
4527+ * Eric Anholt <eric@anholt.net>
4528+ *
4529+ */
4530+
4531+#include "drmP.h"
4532+#include "drm.h"
4533+#include "i915_drm.h"
4534+#include "i915_drv.h"
4535+
4536+/** @file i915_gem_tiling.c
4537+ *
4538+ * Support for managing tiling state of buffer objects.
4539+ *
4540+ * The idea behind tiling is to increase cache hit rates by rearranging
4541+ * pixel data so that a group of pixel accesses are in the same cacheline.
4542+ * Performance improvement from doing this on the back/depth buffer are on
4543+ * the order of 30%.
4544+ *
4545+ * Intel architectures make this somewhat more complicated, though, by
4546+ * adjustments made to addressing of data when the memory is in interleaved
4547+ * mode (matched pairs of DIMMS) to improve memory bandwidth.
4548+ * For interleaved memory, the CPU sends every sequential 64 bytes
4549+ * to an alternate memory channel so it can get the bandwidth from both.
4550+ *
4551+ * The GPU also rearranges its accesses for increased bandwidth to interleaved
4552+ * memory, and it matches what the CPU does for non-tiled. However, when tiled
4553+ * it does it a little differently, since one walks addresses not just in the
4554+ * X direction but also Y. So, along with alternating channels when bit
4555+ * 6 of the address flips, it also alternates when other bits flip -- Bits 9
4556+ * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines)
4557+ * are common to both the 915 and 965-class hardware.
4558+ *
4559+ * The CPU also sometimes XORs in higher bits as well, to improve
4560+ * bandwidth doing strided access like we do so frequently in graphics. This
4561+ * is called "Channel XOR Randomization" in the MCH documentation. The result
4562+ * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address
4563+ * decode.
4564+ *
4565+ * All of this bit 6 XORing has an effect on our memory management,
4566+ * as we need to make sure that the 3d driver can correctly address object
4567+ * contents.
4568+ *
4569+ * If we don't have interleaved memory, all tiling is safe and no swizzling is
4570+ * required.
4571+ *
4572+ * When bit 17 is XORed in, we simply refuse to tile at all. Bit
4573+ * 17 is not just a page offset, so as we page an objet out and back in,
4574+ * individual pages in it will have different bit 17 addresses, resulting in
4575+ * each 64 bytes being swapped with its neighbor!
4576+ *
4577+ * Otherwise, if interleaved, we have to tell the 3d driver what the address
4578+ * swizzling it needs to do is, since it's writing with the CPU to the pages
4579+ * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the
4580+ * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling
4581+ * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order
4582+ * to match what the GPU expects.
4583+ */
4584+
4585+/**
4586+ * Detects bit 6 swizzling of address lookup between IGD access and CPU
4587+ * access through main memory.
4588+ */
4589+void
4590+i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
4591+{
4592+ drm_i915_private_t *dev_priv = dev->dev_private;
4593+ uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4594+ uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4595+
4596+ if (!IS_I9XX(dev)) {
4597+ /* As far as we know, the 865 doesn't have these bit 6
4598+ * swizzling issues.
4599+ */
4600+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4601+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4602+ } else if (!IS_I965G(dev) || IS_I965GM(dev)) {
4603+ uint32_t dcc;
4604+
4605+ /* On 915-945 and GM965, channel interleave by the CPU is
4606+ * determined by DCC. The CPU will alternate based on bit 6
4607+ * in interleaved mode, and the GPU will then also alternate
4608+ * on bit 6, 9, and 10 for X, but the CPU may also optionally
4609+ * alternate based on bit 17 (XOR not disabled and XOR
4610+ * bit == 17).
4611+ */
4612+ dcc = I915_READ(DCC);
4613+ switch (dcc & DCC_ADDRESSING_MODE_MASK) {
4614+ case DCC_ADDRESSING_MODE_SINGLE_CHANNEL:
4615+ case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC:
4616+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4617+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4618+ break;
4619+ case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
4620+ if (IS_I915G(dev) || IS_I915GM(dev) ||
4621+ dcc & DCC_CHANNEL_XOR_DISABLE) {
4622+ swizzle_x = I915_BIT_6_SWIZZLE_9_10;
4623+ swizzle_y = I915_BIT_6_SWIZZLE_9;
4624+ } else if (IS_I965GM(dev)) {
4625+ /* GM965 only does bit 11-based channel
4626+ * randomization
4627+ */
4628+ swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
4629+ swizzle_y = I915_BIT_6_SWIZZLE_9_11;
4630+ } else {
4631+ /* Bit 17 or perhaps other swizzling */
4632+ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4633+ swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4634+ }
4635+ break;
4636+ }
4637+ if (dcc == 0xffffffff) {
4638+ DRM_ERROR("Couldn't read from MCHBAR. "
4639+ "Disabling tiling.\n");
4640+ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4641+ swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4642+ }
4643+ } else {
4644+ /* The 965, G33, and newer, have a very flexible memory
4645+ * configuration. It will enable dual-channel mode
4646+ * (interleaving) on as much memory as it can, and the GPU
4647+ * will additionally sometimes enable different bit 6
4648+ * swizzling for tiled objects from the CPU.
4649+ *
4650+ * Here's what I found on the G965:
4651+ * slot fill memory size swizzling
4652+ * 0A 0B 1A 1B 1-ch 2-ch
4653+ * 512 0 0 0 512 0 O
4654+ * 512 0 512 0 16 1008 X
4655+ * 512 0 0 512 16 1008 X
4656+ * 0 512 0 512 16 1008 X
4657+ * 1024 1024 1024 0 2048 1024 O
4658+ *
4659+ * We could probably detect this based on either the DRB
4660+ * matching, which was the case for the swizzling required in
4661+ * the table above, or from the 1-ch value being less than
4662+ * the minimum size of a rank.
4663+ */
4664+ if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) {
4665+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4666+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4667+ } else {
4668+ swizzle_x = I915_BIT_6_SWIZZLE_9_10;
4669+ swizzle_y = I915_BIT_6_SWIZZLE_9;
4670+ }
4671+ }
4672+
4673+ dev_priv->mm.bit_6_swizzle_x = swizzle_x;
4674+ dev_priv->mm.bit_6_swizzle_y = swizzle_y;
4675+}
4676+
4677+/**
4678+ * Sets the tiling mode of an object, returning the required swizzling of
4679+ * bit 6 of addresses in the object.
4680+ */
4681+int
4682+i915_gem_set_tiling(struct drm_device *dev, void *data,
4683+ struct drm_file *file_priv)
4684+{
4685+ struct drm_i915_gem_set_tiling *args = data;
4686+ drm_i915_private_t *dev_priv = dev->dev_private;
4687+ struct drm_gem_object *obj;
4688+ struct drm_i915_gem_object *obj_priv;
4689+
4690+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4691+ if (obj == NULL)
4692+ return -EINVAL;
4693+ obj_priv = obj->driver_private;
4694+
4695+ mutex_lock(&dev->struct_mutex);
4696+
4697+ if (args->tiling_mode == I915_TILING_NONE) {
4698+ obj_priv->tiling_mode = I915_TILING_NONE;
4699+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4700+ } else {
4701+ if (args->tiling_mode == I915_TILING_X)
4702+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
4703+ else
4704+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
4705+ /* If we can't handle the swizzling, make it untiled. */
4706+ if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
4707+ args->tiling_mode = I915_TILING_NONE;
4708+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4709+ }
4710+ }
4711+ obj_priv->tiling_mode = args->tiling_mode;
4712+
4713+ mutex_unlock(&dev->struct_mutex);
4714+
4715+ drm_gem_object_unreference(obj);
4716+
4717+ return 0;
4718+}
4719+
4720+/**
4721+ * Returns the current tiling mode and required bit 6 swizzling for the object.
4722+ */
4723+int
4724+i915_gem_get_tiling(struct drm_device *dev, void *data,
4725+ struct drm_file *file_priv)
4726+{
4727+ struct drm_i915_gem_get_tiling *args = data;
4728+ drm_i915_private_t *dev_priv = dev->dev_private;
4729+ struct drm_gem_object *obj;
4730+ struct drm_i915_gem_object *obj_priv;
4731+
4732+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4733+ if (obj == NULL)
4734+ return -EINVAL;
4735+ obj_priv = obj->driver_private;
4736+
4737+ mutex_lock(&dev->struct_mutex);
4738+
4739+ args->tiling_mode = obj_priv->tiling_mode;
4740+ switch (obj_priv->tiling_mode) {
4741+ case I915_TILING_X:
4742+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
4743+ break;
4744+ case I915_TILING_Y:
4745+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
4746+ break;
4747+ case I915_TILING_NONE:
4748+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4749+ break;
4750+ default:
4751+ DRM_ERROR("unknown tiling mode\n");
4752+ }
4753+
4754+ mutex_unlock(&dev->struct_mutex);
4755+
4756+ drm_gem_object_unreference(obj);
4757+
4758+ return 0;
4759+}
4760diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
4761index f875959..f295bdf 100644
4762--- a/drivers/gpu/drm/i915/i915_irq.c
4763+++ b/drivers/gpu/drm/i915/i915_irq.c
4764@@ -407,15 +407,20 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
4765 I915_WRITE(PIPEBSTAT, pipeb_stats);
4766 }
4767
4768- if (iir & I915_ASLE_INTERRUPT)
4769- opregion_asle_intr(dev);
4770+ I915_WRITE(IIR, iir);
4771+ if (dev->pdev->msi_enabled)
4772+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
4773+ (void) I915_READ(IIR); /* Flush posted writes */
4774
4775 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
4776
4777- if (dev->pdev->msi_enabled)
4778- I915_WRITE(IMR, dev_priv->irq_mask_reg);
4779- I915_WRITE(IIR, iir);
4780- (void) I915_READ(IIR);
4781+ if (iir & I915_USER_INTERRUPT) {
4782+ dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
4783+ DRM_WAKEUP(&dev_priv->irq_queue);
4784+ }
4785+
4786+ if (iir & I915_ASLE_INTERRUPT)
4787+ opregion_asle_intr(dev);
4788
4789 if (vblank && dev_priv->swaps_pending > 0)
4790 drm_locked_tasklet(dev, i915_vblank_tasklet);
4791@@ -449,7 +454,7 @@ static int i915_emit_irq(struct drm_device * dev)
4792 return dev_priv->counter;
4793 }
4794
4795-static void i915_user_irq_get(struct drm_device *dev)
4796+void i915_user_irq_get(struct drm_device *dev)
4797 {
4798 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
4799
4800diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
4801index 43ad2cb..5c2d9f2 100644
4802--- a/drivers/gpu/drm/i915/i915_reg.h
4803+++ b/drivers/gpu/drm/i915/i915_reg.h
4804@@ -25,19 +25,6 @@
4805 #ifndef _I915_REG_H_
4806 #define _I915_REG_H_
4807
4808-/* MCH MMIO space */
4809-/** 915-945 and GM965 MCH register controlling DRAM channel access */
4810-#define DCC 0x200
4811-#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
4812-#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
4813-#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
4814-#define DCC_ADDRESSING_MODE_MASK (3 << 0)
4815-#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
4816-
4817-/** 965 MCH register controlling DRAM channel configuration */
4818-#define CHDECMISC 0x111
4819-#define CHDECMISC_FLEXMEMORY (1 << 1)
4820-
4821 /*
4822 * The Bridge device's PCI config space has information about the
4823 * fb aperture size and the amount of pre-reserved memory.
4824@@ -516,6 +503,30 @@
4825 #define PALETTE_A 0x0a000
4826 #define PALETTE_B 0x0a800
4827
4828+/* MCH MMIO space */
4829+
4830+/*
4831+ * MCHBAR mirror.
4832+ *
4833+ * This mirrors the MCHBAR MMIO space whose location is determined by
4834+ * device 0 function 0's pci config register 0x44 or 0x48 and matches it in
4835+ * every way. It is not accessible from the CP register read instructions.
4836+ *
4837+ */
4838+#define MCHBAR_MIRROR_BASE 0x10000
4839+
4840+/** 915-945 and GM965 MCH register controlling DRAM channel access */
4841+#define DCC 0x10200
4842+#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
4843+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
4844+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
4845+#define DCC_ADDRESSING_MODE_MASK (3 << 0)
4846+#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
4847+
4848+/** 965 MCH register controlling DRAM channel configuration */
4849+#define C0DRB3 0x10206
4850+#define C1DRB3 0x10606
4851+
4852 /*
4853 * Overlay regs
4854 */
4855diff --git a/include/drm/drm.h b/include/drm/drm.h
4856index 15e5503..f46ba4b 100644
4857--- a/include/drm/drm.h
4858+++ b/include/drm/drm.h
4859@@ -570,6 +570,34 @@ struct drm_set_version {
4860 int drm_dd_minor;
4861 };
4862
4863+/** DRM_IOCTL_GEM_CLOSE ioctl argument type */
4864+struct drm_gem_close {
4865+ /** Handle of the object to be closed. */
4866+ uint32_t handle;
4867+ uint32_t pad;
4868+};
4869+
4870+/** DRM_IOCTL_GEM_FLINK ioctl argument type */
4871+struct drm_gem_flink {
4872+ /** Handle for the object being named */
4873+ uint32_t handle;
4874+
4875+ /** Returned global name */
4876+ uint32_t name;
4877+};
4878+
4879+/** DRM_IOCTL_GEM_OPEN ioctl argument type */
4880+struct drm_gem_open {
4881+ /** Name of object being opened */
4882+ uint32_t name;
4883+
4884+ /** Returned handle for the object */
4885+ uint32_t handle;
4886+
4887+ /** Returned size of the object */
4888+ uint64_t size;
4889+};
4890+
4891 #define DRM_IOCTL_BASE 'd'
4892 #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
4893 #define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
4894@@ -585,6 +613,9 @@ struct drm_set_version {
4895 #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
4896 #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
4897 #define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
4898+#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close)
4899+#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink)
4900+#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open)
4901
4902 #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
4903 #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
4904diff --git a/include/drm/drmP.h b/include/drm/drmP.h
4905index e79ce07..1469a1b 100644
4906--- a/include/drm/drmP.h
4907+++ b/include/drm/drmP.h
4908@@ -104,6 +104,7 @@ struct drm_device;
4909 #define DRIVER_DMA_QUEUE 0x200
4910 #define DRIVER_FB_DMA 0x400
4911 #define DRIVER_IRQ_VBL2 0x800
4912+#define DRIVER_GEM 0x1000
4913
4914 /***********************************************************************/
4915 /** \name Begin the DRM... */
4916@@ -387,6 +388,10 @@ struct drm_file {
4917 struct drm_minor *minor;
4918 int remove_auth_on_close;
4919 unsigned long lock_count;
4920+ /** Mapping of mm object handles to object pointers. */
4921+ struct idr object_idr;
4922+ /** Lock for synchronization of access to object_idr. */
4923+ spinlock_t table_lock;
4924 struct file *filp;
4925 void *driver_priv;
4926 };
4927@@ -558,6 +563,56 @@ struct drm_ati_pcigart_info {
4928 };
4929
4930 /**
4931+ * This structure defines the drm_mm memory object, which will be used by the
4932+ * DRM for its buffer objects.
4933+ */
4934+struct drm_gem_object {
4935+ /** Reference count of this object */
4936+ struct kref refcount;
4937+
4938+ /** Handle count of this object. Each handle also holds a reference */
4939+ struct kref handlecount;
4940+
4941+ /** Related drm device */
4942+ struct drm_device *dev;
4943+
4944+ /** File representing the shmem storage */
4945+ struct file *filp;
4946+
4947+ /**
4948+ * Size of the object, in bytes. Immutable over the object's
4949+ * lifetime.
4950+ */
4951+ size_t size;
4952+
4953+ /**
4954+ * Global name for this object, starts at 1. 0 means unnamed.
4955+ * Access is covered by the object_name_lock in the related drm_device
4956+ */
4957+ int name;
4958+
4959+ /**
4960+ * Memory domains. These monitor which caches contain read/write data
4961+ * related to the object. When transitioning from one set of domains
4962+ * to another, the driver is called to ensure that caches are suitably
4963+ * flushed and invalidated
4964+ */
4965+ uint32_t read_domains;
4966+ uint32_t write_domain;
4967+
4968+ /**
4969+ * While validating an exec operation, the
4970+ * new read/write domain values are computed here.
4971+ * They will be transferred to the above values
4972+ * at the point that any cache flushing occurs
4973+ */
4974+ uint32_t pending_read_domains;
4975+ uint32_t pending_write_domain;
4976+
4977+ void *driver_private;
4978+};
4979+
4980+/**
4981 * DRM driver structure. This structure represent the common code for
4982 * a family of cards. There will one drm_device for each card present
4983 * in this family
4984@@ -657,6 +712,18 @@ struct drm_driver {
4985 void (*set_version) (struct drm_device *dev,
4986 struct drm_set_version *sv);
4987
4988+ int (*proc_init)(struct drm_minor *minor);
4989+ void (*proc_cleanup)(struct drm_minor *minor);
4990+
4991+ /**
4992+ * Driver-specific constructor for drm_gem_objects, to set up
4993+ * obj->driver_private.
4994+ *
4995+ * Returns 0 on success.
4996+ */
4997+ int (*gem_init_object) (struct drm_gem_object *obj);
4998+ void (*gem_free_object) (struct drm_gem_object *obj);
4999+
5000 int major;
5001 int minor;
5002 int patchlevel;
5003@@ -830,6 +897,22 @@ struct drm_device {
5004 spinlock_t drw_lock;
5005 struct idr drw_idr;
5006 /*@} */
5007+
5008+ /** \name GEM information */
5009+ /*@{ */
5010+ spinlock_t object_name_lock;
5011+ struct idr object_name_idr;
5012+ atomic_t object_count;
5013+ atomic_t object_memory;
5014+ atomic_t pin_count;
5015+ atomic_t pin_memory;
5016+ atomic_t gtt_count;
5017+ atomic_t gtt_memory;
5018+ uint32_t gtt_total;
5019+ uint32_t invalidate_domains; /* domains pending invalidation */
5020+ uint32_t flush_domains; /* domains pending flush */
5021+ /*@} */
5022+
5023 };
5024
5025 static __inline__ int drm_core_check_feature(struct drm_device *dev,
5026@@ -926,6 +1009,10 @@ extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area);
5027 extern DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type);
5028 extern int drm_free_agp(DRM_AGP_MEM * handle, int pages);
5029 extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start);
5030+extern DRM_AGP_MEM *drm_agp_bind_pages(struct drm_device *dev,
5031+ struct page **pages,
5032+ unsigned long num_pages,
5033+ uint32_t gtt_offset);
5034 extern int drm_unbind_agp(DRM_AGP_MEM * handle);
5035
5036 /* Misc. IOCTL support (drm_ioctl.h) */
5037@@ -988,6 +1075,9 @@ extern int drm_getmagic(struct drm_device *dev, void *data,
5038 extern int drm_authmagic(struct drm_device *dev, void *data,
5039 struct drm_file *file_priv);
5040
5041+/* Cache management (drm_cache.c) */
5042+void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
5043+
5044 /* Locking IOCTL support (drm_lock.h) */
5045 extern int drm_lock(struct drm_device *dev, void *data,
5046 struct drm_file *file_priv);
5047@@ -1094,6 +1184,7 @@ extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size
5048 extern int drm_agp_free_memory(DRM_AGP_MEM * handle);
5049 extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start);
5050 extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
5051+extern void drm_agp_chipset_flush(struct drm_device *dev);
5052
5053 /* Stub support (drm_stub.h) */
5054 extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
5055@@ -1156,6 +1247,66 @@ extern unsigned long drm_mm_tail_space(struct drm_mm *mm);
5056 extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size);
5057 extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size);
5058
5059+/* Graphics Execution Manager library functions (drm_gem.c) */
5060+int drm_gem_init(struct drm_device *dev);
5061+void drm_gem_object_free(struct kref *kref);
5062+struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev,
5063+ size_t size);
5064+void drm_gem_object_handle_free(struct kref *kref);
5065+
5066+static inline void
5067+drm_gem_object_reference(struct drm_gem_object *obj)
5068+{
5069+ kref_get(&obj->refcount);
5070+}
5071+
5072+static inline void
5073+drm_gem_object_unreference(struct drm_gem_object *obj)
5074+{
5075+ if (obj == NULL)
5076+ return;
5077+
5078+ kref_put(&obj->refcount, drm_gem_object_free);
5079+}
5080+
5081+int drm_gem_handle_create(struct drm_file *file_priv,
5082+ struct drm_gem_object *obj,
5083+ int *handlep);
5084+
5085+static inline void
5086+drm_gem_object_handle_reference(struct drm_gem_object *obj)
5087+{
5088+ drm_gem_object_reference(obj);
5089+ kref_get(&obj->handlecount);
5090+}
5091+
5092+static inline void
5093+drm_gem_object_handle_unreference(struct drm_gem_object *obj)
5094+{
5095+ if (obj == NULL)
5096+ return;
5097+
5098+ /*
5099+ * Must bump handle count first as this may be the last
5100+ * ref, in which case the object would disappear before we
5101+ * checked for a name
5102+ */
5103+ kref_put(&obj->handlecount, drm_gem_object_handle_free);
5104+ drm_gem_object_unreference(obj);
5105+}
5106+
5107+struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev,
5108+ struct drm_file *filp,
5109+ int handle);
5110+int drm_gem_close_ioctl(struct drm_device *dev, void *data,
5111+ struct drm_file *file_priv);
5112+int drm_gem_flink_ioctl(struct drm_device *dev, void *data,
5113+ struct drm_file *file_priv);
5114+int drm_gem_open_ioctl(struct drm_device *dev, void *data,
5115+ struct drm_file *file_priv);
5116+void drm_gem_open(struct drm_device *dev, struct drm_file *file_private);
5117+void drm_gem_release(struct drm_device *dev, struct drm_file *file_private);
5118+
5119 extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev);
5120 extern void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev);
5121 extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev);
5122diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
5123index 05c66cf..59d08fc 100644
5124--- a/include/drm/i915_drm.h
5125+++ b/include/drm/i915_drm.h
5126@@ -143,6 +143,22 @@ typedef struct _drm_i915_sarea {
5127 #define DRM_I915_GET_VBLANK_PIPE 0x0e
5128 #define DRM_I915_VBLANK_SWAP 0x0f
5129 #define DRM_I915_HWS_ADDR 0x11
5130+#define DRM_I915_GEM_INIT 0x13
5131+#define DRM_I915_GEM_EXECBUFFER 0x14
5132+#define DRM_I915_GEM_PIN 0x15
5133+#define DRM_I915_GEM_UNPIN 0x16
5134+#define DRM_I915_GEM_BUSY 0x17
5135+#define DRM_I915_GEM_THROTTLE 0x18
5136+#define DRM_I915_GEM_ENTERVT 0x19
5137+#define DRM_I915_GEM_LEAVEVT 0x1a
5138+#define DRM_I915_GEM_CREATE 0x1b
5139+#define DRM_I915_GEM_PREAD 0x1c
5140+#define DRM_I915_GEM_PWRITE 0x1d
5141+#define DRM_I915_GEM_MMAP 0x1e
5142+#define DRM_I915_GEM_SET_DOMAIN 0x1f
5143+#define DRM_I915_GEM_SW_FINISH 0x20
5144+#define DRM_I915_GEM_SET_TILING 0x21
5145+#define DRM_I915_GEM_GET_TILING 0x22
5146
5147 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
5148 #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
5149@@ -160,6 +176,20 @@ typedef struct _drm_i915_sarea {
5150 #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
5151 #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
5152 #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
5153+#define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
5154+#define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
5155+#define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
5156+#define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE)
5157+#define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
5158+#define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
5159+#define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
5160+#define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
5161+#define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
5162+#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
5163+#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
5164+#define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
5165+#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
5166+#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
5167
5168 /* Allow drivers to submit batchbuffers directly to hardware, relying
5169 * on the security mechanisms provided by hardware.
5170@@ -200,6 +230,7 @@ typedef struct drm_i915_irq_wait {
5171 #define I915_PARAM_IRQ_ACTIVE 1
5172 #define I915_PARAM_ALLOW_BATCHBUFFER 2
5173 #define I915_PARAM_LAST_DISPATCH 3
5174+#define I915_PARAM_HAS_GEM 5
5175
5176 typedef struct drm_i915_getparam {
5177 int param;
5178@@ -267,4 +298,305 @@ typedef struct drm_i915_hws_addr {
5179 uint64_t addr;
5180 } drm_i915_hws_addr_t;
5181
5182+struct drm_i915_gem_init {
5183+ /**
5184+ * Beginning offset in the GTT to be managed by the DRM memory
5185+ * manager.
5186+ */
5187+ uint64_t gtt_start;
5188+ /**
5189+ * Ending offset in the GTT to be managed by the DRM memory
5190+ * manager.
5191+ */
5192+ uint64_t gtt_end;
5193+};
5194+
5195+struct drm_i915_gem_create {
5196+ /**
5197+ * Requested size for the object.
5198+ *
5199+ * The (page-aligned) allocated size for the object will be returned.
5200+ */
5201+ uint64_t size;
5202+ /**
5203+ * Returned handle for the object.
5204+ *
5205+ * Object handles are nonzero.
5206+ */
5207+ uint32_t handle;
5208+ uint32_t pad;
5209+};
5210+
5211+struct drm_i915_gem_pread {
5212+ /** Handle for the object being read. */
5213+ uint32_t handle;
5214+ uint32_t pad;
5215+ /** Offset into the object to read from */
5216+ uint64_t offset;
5217+ /** Length of data to read */
5218+ uint64_t size;
5219+ /**
5220+ * Pointer to write the data into.
5221+ *
5222+ * This is a fixed-size type for 32/64 compatibility.
5223+ */
5224+ uint64_t data_ptr;
5225+};
5226+
5227+struct drm_i915_gem_pwrite {
5228+ /** Handle for the object being written to. */
5229+ uint32_t handle;
5230+ uint32_t pad;
5231+ /** Offset into the object to write to */
5232+ uint64_t offset;
5233+ /** Length of data to write */
5234+ uint64_t size;
5235+ /**
5236+ * Pointer to read the data from.
5237+ *
5238+ * This is a fixed-size type for 32/64 compatibility.
5239+ */
5240+ uint64_t data_ptr;
5241+};
5242+
5243+struct drm_i915_gem_mmap {
5244+ /** Handle for the object being mapped. */
5245+ uint32_t handle;
5246+ uint32_t pad;
5247+ /** Offset in the object to map. */
5248+ uint64_t offset;
5249+ /**
5250+ * Length of data to map.
5251+ *
5252+ * The value will be page-aligned.
5253+ */
5254+ uint64_t size;
5255+ /**
5256+ * Returned pointer the data was mapped at.
5257+ *
5258+ * This is a fixed-size type for 32/64 compatibility.
5259+ */
5260+ uint64_t addr_ptr;
5261+};
5262+
5263+struct drm_i915_gem_set_domain {
5264+ /** Handle for the object */
5265+ uint32_t handle;
5266+
5267+ /** New read domains */
5268+ uint32_t read_domains;
5269+
5270+ /** New write domain */
5271+ uint32_t write_domain;
5272+};
5273+
5274+struct drm_i915_gem_sw_finish {
5275+ /** Handle for the object */
5276+ uint32_t handle;
5277+};
5278+
5279+struct drm_i915_gem_relocation_entry {
5280+ /**
5281+ * Handle of the buffer being pointed to by this relocation entry.
5282+ *
5283+ * It's appealing to make this be an index into the mm_validate_entry
5284+ * list to refer to the buffer, but this allows the driver to create
5285+ * a relocation list for state buffers and not re-write it per
5286+ * exec using the buffer.
5287+ */
5288+ uint32_t target_handle;
5289+
5290+ /**
5291+ * Value to be added to the offset of the target buffer to make up
5292+ * the relocation entry.
5293+ */
5294+ uint32_t delta;
5295+
5296+ /** Offset in the buffer the relocation entry will be written into */
5297+ uint64_t offset;
5298+
5299+ /**
5300+ * Offset value of the target buffer that the relocation entry was last
5301+ * written as.
5302+ *
5303+ * If the buffer has the same offset as last time, we can skip syncing
5304+ * and writing the relocation. This value is written back out by
5305+ * the execbuffer ioctl when the relocation is written.
5306+ */
5307+ uint64_t presumed_offset;
5308+
5309+ /**
5310+ * Target memory domains read by this operation.
5311+ */
5312+ uint32_t read_domains;
5313+
5314+ /**
5315+ * Target memory domains written by this operation.
5316+ *
5317+ * Note that only one domain may be written by the whole
5318+ * execbuffer operation, so that where there are conflicts,
5319+ * the application will get -EINVAL back.
5320+ */
5321+ uint32_t write_domain;
5322+};
5323+
5324+/** @{
5325+ * Intel memory domains
5326+ *
5327+ * Most of these just align with the various caches in
5328+ * the system and are used to flush and invalidate as
5329+ * objects end up cached in different domains.
5330+ */
5331+/** CPU cache */
5332+#define I915_GEM_DOMAIN_CPU 0x00000001
5333+/** Render cache, used by 2D and 3D drawing */
5334+#define I915_GEM_DOMAIN_RENDER 0x00000002
5335+/** Sampler cache, used by texture engine */
5336+#define I915_GEM_DOMAIN_SAMPLER 0x00000004
5337+/** Command queue, used to load batch buffers */
5338+#define I915_GEM_DOMAIN_COMMAND 0x00000008
5339+/** Instruction cache, used by shader programs */
5340+#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010
5341+/** Vertex address cache */
5342+#define I915_GEM_DOMAIN_VERTEX 0x00000020
5343+/** GTT domain - aperture and scanout */
5344+#define I915_GEM_DOMAIN_GTT 0x00000040
5345+/** @} */
5346+
5347+struct drm_i915_gem_exec_object {
5348+ /**
5349+ * User's handle for a buffer to be bound into the GTT for this
5350+ * operation.
5351+ */
5352+ uint32_t handle;
5353+
5354+ /** Number of relocations to be performed on this buffer */
5355+ uint32_t relocation_count;
5356+ /**
5357+ * Pointer to array of struct drm_i915_gem_relocation_entry containing
5358+ * the relocations to be performed in this buffer.
5359+ */
5360+ uint64_t relocs_ptr;
5361+
5362+ /** Required alignment in graphics aperture */
5363+ uint64_t alignment;
5364+
5365+ /**
5366+ * Returned value of the updated offset of the object, for future
5367+ * presumed_offset writes.
5368+ */
5369+ uint64_t offset;
5370+};
5371+
5372+struct drm_i915_gem_execbuffer {
5373+ /**
5374+ * List of buffers to be validated with their relocations to be
5375+ * performend on them.
5376+ *
5377+ * This is a pointer to an array of struct drm_i915_gem_validate_entry.
5378+ *
5379+ * These buffers must be listed in an order such that all relocations
5380+ * a buffer is performing refer to buffers that have already appeared
5381+ * in the validate list.
5382+ */
5383+ uint64_t buffers_ptr;
5384+ uint32_t buffer_count;
5385+
5386+ /** Offset in the batchbuffer to start execution from. */
5387+ uint32_t batch_start_offset;
5388+ /** Bytes used in batchbuffer from batch_start_offset */
5389+ uint32_t batch_len;
5390+ uint32_t DR1;
5391+ uint32_t DR4;
5392+ uint32_t num_cliprects;
5393+ /** This is a struct drm_clip_rect *cliprects */
5394+ uint64_t cliprects_ptr;
5395+};
5396+
5397+struct drm_i915_gem_pin {
5398+ /** Handle of the buffer to be pinned. */
5399+ uint32_t handle;
5400+ uint32_t pad;
5401+
5402+ /** alignment required within the aperture */
5403+ uint64_t alignment;
5404+
5405+ /** Returned GTT offset of the buffer. */
5406+ uint64_t offset;
5407+};
5408+
5409+struct drm_i915_gem_unpin {
5410+ /** Handle of the buffer to be unpinned. */
5411+ uint32_t handle;
5412+ uint32_t pad;
5413+};
5414+
5415+struct drm_i915_gem_busy {
5416+ /** Handle of the buffer to check for busy */
5417+ uint32_t handle;
5418+
5419+ /** Return busy status (1 if busy, 0 if idle) */
5420+ uint32_t busy;
5421+};
5422+
5423+#define I915_TILING_NONE 0
5424+#define I915_TILING_X 1
5425+#define I915_TILING_Y 2
5426+
5427+#define I915_BIT_6_SWIZZLE_NONE 0
5428+#define I915_BIT_6_SWIZZLE_9 1
5429+#define I915_BIT_6_SWIZZLE_9_10 2
5430+#define I915_BIT_6_SWIZZLE_9_11 3
5431+#define I915_BIT_6_SWIZZLE_9_10_11 4
5432+/* Not seen by userland */
5433+#define I915_BIT_6_SWIZZLE_UNKNOWN 5
5434+
5435+struct drm_i915_gem_set_tiling {
5436+ /** Handle of the buffer to have its tiling state updated */
5437+ uint32_t handle;
5438+
5439+ /**
5440+ * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
5441+ * I915_TILING_Y).
5442+ *
5443+ * This value is to be set on request, and will be updated by the
5444+ * kernel on successful return with the actual chosen tiling layout.
5445+ *
5446+ * The tiling mode may be demoted to I915_TILING_NONE when the system
5447+ * has bit 6 swizzling that can't be managed correctly by GEM.
5448+ *
5449+ * Buffer contents become undefined when changing tiling_mode.
5450+ */
5451+ uint32_t tiling_mode;
5452+
5453+ /**
5454+ * Stride in bytes for the object when in I915_TILING_X or
5455+ * I915_TILING_Y.
5456+ */
5457+ uint32_t stride;
5458+
5459+ /**
5460+ * Returned address bit 6 swizzling required for CPU access through
5461+ * mmap mapping.
5462+ */
5463+ uint32_t swizzle_mode;
5464+};
5465+
5466+struct drm_i915_gem_get_tiling {
5467+ /** Handle of the buffer to get tiling state for. */
5468+ uint32_t handle;
5469+
5470+ /**
5471+ * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
5472+ * I915_TILING_Y).
5473+ */
5474+ uint32_t tiling_mode;
5475+
5476+ /**
5477+ * Returned address bit 6 swizzling required for CPU access through
5478+ * mmap mapping.
5479+ */
5480+ uint32_t swizzle_mode;
5481+};
5482+
5483 #endif /* _I915_DRM_H_ */
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0015-i915-Add-chip-set-ID-param.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0015-i915-Add-chip-set-ID-param.patch
new file mode 100644
index 0000000000..c3bf8ebd13
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0015-i915-Add-chip-set-ID-param.patch
@@ -0,0 +1,35 @@
1commit 26ead293ddf664f33dc0ba12b726887c40ce3957
2Author: Kristian Høgsberg <krh@redhat.com>
3Date: Wed Aug 20 11:08:52 2008 -0400
4
5 i915: Add chip set ID param.
6
7 Signed-off-by: Kristian Høgsberg <krh@redhat.com>
8 Signed-off-by: Eric Anholt <eric@anholt.net>
9
10diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
11index 3b5aa74..205d21e 100644
12--- a/drivers/gpu/drm/i915/i915_dma.c
13+++ b/drivers/gpu/drm/i915/i915_dma.c
14@@ -689,6 +689,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
15 case I915_PARAM_LAST_DISPATCH:
16 value = READ_BREADCRUMB(dev_priv);
17 break;
18+ case I915_PARAM_CHIPSET_ID:
19+ value = dev->pci_device;
20+ break;
21 case I915_PARAM_HAS_GEM:
22 value = 1;
23 break;
24diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
25index 59d08fc..eb4b350 100644
26--- a/include/drm/i915_drm.h
27+++ b/include/drm/i915_drm.h
28@@ -230,6 +230,7 @@ typedef struct drm_i915_irq_wait {
29 #define I915_PARAM_IRQ_ACTIVE 1
30 #define I915_PARAM_ALLOW_BATCHBUFFER 2
31 #define I915_PARAM_LAST_DISPATCH 3
32+#define I915_PARAM_CHIPSET_ID 4
33 #define I915_PARAM_HAS_GEM 5
34
35 typedef struct drm_i915_getparam {
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch
new file mode 100644
index 0000000000..910f37e9c5
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch
@@ -0,0 +1,205 @@
1commit 8a524209fce67d3b6d2e831b5dad4eced796ce98
2Author: Eric Anholt <eric@anholt.net>
3Date: Mon Sep 1 16:45:29 2008 -0700
4
5 i915: Use struct_mutex to protect ring in GEM mode.
6
7 In the conversion for GEM, we had stopped using the hardware lock to protect
8 ring usage, since it was all internal to the DRM now. However, some paths
9 weren't converted to using struct_mutex to prevent multiple threads from
10 concurrently working on the ring, in particular between the vblank swap handler
11 and ioctls.
12
13 Signed-off-by: Eric Anholt <eric@anholt.net>
14
15diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
16index 205d21e..25f59c1 100644
17--- a/drivers/gpu/drm/i915/i915_dma.c
18+++ b/drivers/gpu/drm/i915/i915_dma.c
19@@ -588,9 +588,15 @@ static int i915_quiescent(struct drm_device * dev)
20 static int i915_flush_ioctl(struct drm_device *dev, void *data,
21 struct drm_file *file_priv)
22 {
23- LOCK_TEST_WITH_RETURN(dev, file_priv);
24+ int ret;
25+
26+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
27
28- return i915_quiescent(dev);
29+ mutex_lock(&dev->struct_mutex);
30+ ret = i915_quiescent(dev);
31+ mutex_unlock(&dev->struct_mutex);
32+
33+ return ret;
34 }
35
36 static int i915_batchbuffer(struct drm_device *dev, void *data,
37@@ -611,14 +617,16 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
38 DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n",
39 batch->start, batch->used, batch->num_cliprects);
40
41- LOCK_TEST_WITH_RETURN(dev, file_priv);
42+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
43
44 if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
45 batch->num_cliprects *
46 sizeof(struct drm_clip_rect)))
47 return -EFAULT;
48
49+ mutex_lock(&dev->struct_mutex);
50 ret = i915_dispatch_batchbuffer(dev, batch);
51+ mutex_unlock(&dev->struct_mutex);
52
53 sarea_priv->last_dispatch = (int)hw_status[5];
54 return ret;
55@@ -637,7 +645,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
56 DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
57 cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects);
58
59- LOCK_TEST_WITH_RETURN(dev, file_priv);
60+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
61
62 if (cmdbuf->num_cliprects &&
63 DRM_VERIFYAREA_READ(cmdbuf->cliprects,
64@@ -647,7 +655,9 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
65 return -EFAULT;
66 }
67
68+ mutex_lock(&dev->struct_mutex);
69 ret = i915_dispatch_cmdbuffer(dev, cmdbuf);
70+ mutex_unlock(&dev->struct_mutex);
71 if (ret) {
72 DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
73 return ret;
74@@ -660,11 +670,17 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
75 static int i915_flip_bufs(struct drm_device *dev, void *data,
76 struct drm_file *file_priv)
77 {
78+ int ret;
79+
80 DRM_DEBUG("%s\n", __FUNCTION__);
81
82- LOCK_TEST_WITH_RETURN(dev, file_priv);
83+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
84
85- return i915_dispatch_flip(dev);
86+ mutex_lock(&dev->struct_mutex);
87+ ret = i915_dispatch_flip(dev);
88+ mutex_unlock(&dev->struct_mutex);
89+
90+ return ret;
91 }
92
93 static int i915_getparam(struct drm_device *dev, void *data,
94diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
95index 87b071a..8547f0a 100644
96--- a/drivers/gpu/drm/i915/i915_drv.h
97+++ b/drivers/gpu/drm/i915/i915_drv.h
98@@ -285,6 +285,9 @@ typedef struct drm_i915_private {
99 */
100 struct delayed_work retire_work;
101
102+ /** Work task for vblank-related ring access */
103+ struct work_struct vblank_work;
104+
105 uint32_t next_gem_seqno;
106
107 /**
108@@ -435,6 +438,7 @@ extern int i915_irq_wait(struct drm_device *dev, void *data,
109 void i915_user_irq_get(struct drm_device *dev);
110 void i915_user_irq_put(struct drm_device *dev);
111
112+extern void i915_gem_vblank_work_handler(struct work_struct *work);
113 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
114 extern void i915_driver_irq_preinstall(struct drm_device * dev);
115 extern int i915_driver_irq_postinstall(struct drm_device *dev);
116@@ -538,6 +542,17 @@ extern void intel_opregion_free(struct drm_device *dev);
117 extern void opregion_asle_intr(struct drm_device *dev);
118 extern void opregion_enable_asle(struct drm_device *dev);
119
120+/**
121+ * Lock test for when it's just for synchronization of ring access.
122+ *
123+ * In that case, we don't need to do it when GEM is initialized as nobody else
124+ * has access to the ring.
125+ */
126+#define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \
127+ if (((drm_i915_private_t *)dev->dev_private)->ring.ring_obj == NULL) \
128+ LOCK_TEST_WITH_RETURN(dev, file_priv); \
129+} while (0)
130+
131 #define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
132 #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
133 #define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
134diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
135index 90ae8a0..bb6e5a3 100644
136--- a/drivers/gpu/drm/i915/i915_gem.c
137+++ b/drivers/gpu/drm/i915/i915_gem.c
138@@ -2491,6 +2491,8 @@ i915_gem_load(struct drm_device *dev)
139 INIT_LIST_HEAD(&dev_priv->mm.request_list);
140 INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
141 i915_gem_retire_work_handler);
142+ INIT_WORK(&dev_priv->mm.vblank_work,
143+ i915_gem_vblank_work_handler);
144 dev_priv->mm.next_gem_seqno = 1;
145
146 i915_gem_detect_bit_6_swizzle(dev);
147diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
148index f295bdf..d04c526 100644
149--- a/drivers/gpu/drm/i915/i915_irq.c
150+++ b/drivers/gpu/drm/i915/i915_irq.c
151@@ -349,6 +349,21 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
152 return count;
153 }
154
155+void
156+i915_gem_vblank_work_handler(struct work_struct *work)
157+{
158+ drm_i915_private_t *dev_priv;
159+ struct drm_device *dev;
160+
161+ dev_priv = container_of(work, drm_i915_private_t,
162+ mm.vblank_work);
163+ dev = dev_priv->dev;
164+
165+ mutex_lock(&dev->struct_mutex);
166+ i915_vblank_tasklet(dev);
167+ mutex_unlock(&dev->struct_mutex);
168+}
169+
170 irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
171 {
172 struct drm_device *dev = (struct drm_device *) arg;
173@@ -422,8 +437,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
174 if (iir & I915_ASLE_INTERRUPT)
175 opregion_asle_intr(dev);
176
177- if (vblank && dev_priv->swaps_pending > 0)
178- drm_locked_tasklet(dev, i915_vblank_tasklet);
179+ if (vblank && dev_priv->swaps_pending > 0) {
180+ if (dev_priv->ring.ring_obj == NULL)
181+ drm_locked_tasklet(dev, i915_vblank_tasklet);
182+ else
183+ schedule_work(&dev_priv->mm.vblank_work);
184+ }
185
186 return IRQ_HANDLED;
187 }
188@@ -514,14 +533,15 @@ int i915_irq_emit(struct drm_device *dev, void *data,
189 drm_i915_irq_emit_t *emit = data;
190 int result;
191
192- LOCK_TEST_WITH_RETURN(dev, file_priv);
193+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
194
195 if (!dev_priv) {
196 DRM_ERROR("called with no initialization\n");
197 return -EINVAL;
198 }
199-
200+ mutex_lock(&dev->struct_mutex);
201 result = i915_emit_irq(dev);
202+ mutex_unlock(&dev->struct_mutex);
203
204 if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
205 DRM_ERROR("copy_to_user\n");
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0017-i915-Make-use-of-sarea_priv-conditional.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0017-i915-Make-use-of-sarea_priv-conditional.patch
new file mode 100644
index 0000000000..542b69dd52
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0017-i915-Make-use-of-sarea_priv-conditional.patch
@@ -0,0 +1,147 @@
1commit 69749cf99189a8a78de201ac24990c91ee111469
2Author: Kristian Høgsberg <krh@redhat.com>
3Date: Wed Aug 20 11:20:13 2008 -0400
4
5 i915: Make use of sarea_priv conditional.
6
7 We fail ioctls that depend on the sarea_priv with EINVAL.
8
9 Signed-off-by: Kristian Høgsberg <krh@redhat.com>
10 Signed-off-by: Eric Anholt <eric@anholt.net>
11
12diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
13index 25f59c1..dbd3f49 100644
14--- a/drivers/gpu/drm/i915/i915_dma.c
15+++ b/drivers/gpu/drm/i915/i915_dma.c
16@@ -55,7 +55,8 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
17 if (ring->space >= n)
18 return 0;
19
20- dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
21+ if (dev_priv->sarea_priv)
22+ dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
23
24 if (ring->head != last_head)
25 i = 0;
26@@ -128,7 +129,7 @@ void i915_kernel_lost_context(struct drm_device * dev)
27 if (ring->space < 0)
28 ring->space += ring->Size;
29
30- if (ring->head == ring->tail)
31+ if (ring->head == ring->tail && dev_priv->sarea_priv)
32 dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
33 }
34
35@@ -433,10 +434,11 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
36 drm_i915_private_t *dev_priv = dev->dev_private;
37 RING_LOCALS;
38
39- dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
40-
41+ dev_priv->counter++;
42 if (dev_priv->counter > 0x7FFFFFFFUL)
43- dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
44+ dev_priv->counter = 0;
45+ if (dev_priv->sarea_priv)
46+ dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
47
48 BEGIN_LP_RING(4);
49 OUT_RING(MI_STORE_DWORD_INDEX);
50@@ -534,6 +536,9 @@ static int i915_dispatch_flip(struct drm_device * dev)
51 drm_i915_private_t *dev_priv = dev->dev_private;
52 RING_LOCALS;
53
54+ if (!dev_priv->sarea_priv)
55+ return -EINVAL;
56+
57 DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
58 __FUNCTION__,
59 dev_priv->current_page,
60@@ -628,7 +633,8 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
61 ret = i915_dispatch_batchbuffer(dev, batch);
62 mutex_unlock(&dev->struct_mutex);
63
64- sarea_priv->last_dispatch = (int)hw_status[5];
65+ if (sarea_priv)
66+ sarea_priv->last_dispatch = (int)hw_status[5];
67 return ret;
68 }
69
70@@ -663,7 +669,8 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
71 return ret;
72 }
73
74- sarea_priv->last_dispatch = (int)hw_status[5];
75+ if (sarea_priv)
76+ sarea_priv->last_dispatch = (int)hw_status[5];
77 return 0;
78 }
79
80diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
81index d04c526..ef03a59 100644
82--- a/drivers/gpu/drm/i915/i915_irq.c
83+++ b/drivers/gpu/drm/i915/i915_irq.c
84@@ -427,7 +427,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
85 I915_WRITE(IMR, dev_priv->irq_mask_reg);
86 (void) I915_READ(IIR); /* Flush posted writes */
87
88- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
89+ if (dev_priv->sarea_priv)
90+ dev_priv->sarea_priv->last_dispatch =
91+ READ_BREADCRUMB(dev_priv);
92
93 if (iir & I915_USER_INTERRUPT) {
94 dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
95@@ -456,10 +458,11 @@ static int i915_emit_irq(struct drm_device * dev)
96
97 DRM_DEBUG("\n");
98
99- dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
100-
101+ dev_priv->counter++;
102 if (dev_priv->counter > 0x7FFFFFFFUL)
103- dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
104+ dev_priv->counter = 1;
105+ if (dev_priv->sarea_priv)
106+ dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
107
108 BEGIN_LP_RING(6);
109 OUT_RING(MI_STORE_DWORD_INDEX);
110@@ -503,11 +506,15 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
111 READ_BREADCRUMB(dev_priv));
112
113 if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
114- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
115+ if (dev_priv->sarea_priv) {
116+ dev_priv->sarea_priv->last_dispatch =
117+ READ_BREADCRUMB(dev_priv);
118+ }
119 return 0;
120 }
121
122- dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
123+ if (dev_priv->sarea_priv)
124+ dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
125
126 i915_user_irq_get(dev);
127 DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
128@@ -519,7 +526,9 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
129 READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
130 }
131
132- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
133+ if (dev_priv->sarea_priv)
134+ dev_priv->sarea_priv->last_dispatch =
135+ READ_BREADCRUMB(dev_priv);
136
137 return ret;
138 }
139@@ -682,7 +691,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
140 struct list_head *list;
141 int ret;
142
143- if (!dev_priv) {
144+ if (!dev_priv || !dev_priv->sarea_priv) {
145 DRM_ERROR("%s called with no initialization\n", __func__);
146 return -EINVAL;
147 }
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch
new file mode 100644
index 0000000000..3593fa5826
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch
@@ -0,0 +1,44 @@
1commit 7ad6d5861b04bbb2cdc36d1dcf8989e16f86e659
2Author: Kristian Høgsberg <krh@redhat.com>
3Date: Wed Aug 20 11:04:27 2008 -0400
4
5 i915 gem: install and uninstall irq handler in entervt and leavevt ioctls.
6
7 Signed-off-by: Kristian Høgsberg <krh@redhat.com>
8 Signed-off-by: Eric Anholt <eric@anholt.net>
9
10diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
11index bb6e5a3..5fe5034 100644
12--- a/drivers/gpu/drm/i915/i915_gem.c
13+++ b/drivers/gpu/drm/i915/i915_gem.c
14@@ -2443,6 +2443,9 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
15 BUG_ON(!list_empty(&dev_priv->mm.request_list));
16 dev_priv->mm.suspended = 0;
17 mutex_unlock(&dev->struct_mutex);
18+
19+ drm_irq_install(dev);
20+
21 return 0;
22 }
23
24@@ -2458,6 +2461,8 @@ i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
25 i915_gem_cleanup_ringbuffer(dev);
26 mutex_unlock(&dev->struct_mutex);
27
28+ drm_irq_uninstall(dev);
29+
30 return 0;
31 }
32
33diff --git a/include/drm/drmP.h b/include/drm/drmP.h
34index 1469a1b..51ee72c 100644
35--- a/include/drm/drmP.h
36+++ b/include/drm/drmP.h
37@@ -1134,6 +1134,7 @@ extern void drm_core_reclaim_buffers(struct drm_device *dev,
38 extern int drm_control(struct drm_device *dev, void *data,
39 struct drm_file *file_priv);
40 extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
41+extern int drm_irq_install(struct drm_device *dev);
42 extern int drm_irq_uninstall(struct drm_device *dev);
43 extern void drm_driver_irq_preinstall(struct drm_device *dev);
44 extern void drm_driver_irq_postinstall(struct drm_device *dev);
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch
new file mode 100644
index 0000000000..6de4514e28
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch
@@ -0,0 +1,32 @@
1commit c3de45b0488762a9161e9b9e8bf419f63c100c47
2Author: Eric Anholt <eric@anholt.net>
3Date: Tue Sep 9 11:40:34 2008 -0700
4
5 DRM: Return -EBADF on bad object in flink, and return curent name if it exists.
6
7 Signed-off-by: Eric Anholt <eric@anholt.net>
8
9diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
10index 434155b..ccd1afd 100644
11--- a/drivers/gpu/drm/drm_gem.c
12+++ b/drivers/gpu/drm/drm_gem.c
13@@ -251,7 +251,7 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
14
15 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
16 if (obj == NULL)
17- return -EINVAL;
18+ return -EBADF;
19
20 again:
21 if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0)
22@@ -259,8 +259,9 @@ again:
23
24 spin_lock(&dev->object_name_lock);
25 if (obj->name) {
26+ args->name = obj->name;
27 spin_unlock(&dev->object_name_lock);
28- return -EEXIST;
29+ return 0;
30 }
31 ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
32 &obj->name);
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch
new file mode 100644
index 0000000000..7080907cde
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch
@@ -0,0 +1,23 @@
1commit 880db7a8dbed226d638b3a48aa1a3996f8624911
2Author: Eric Anholt <eric@anholt.net>
3Date: Wed Sep 10 14:22:49 2008 -0700
4
5 drm: Avoid oops in GEM execbuffers with bad arguments.
6
7 Signed-off-by: Eric Anholt <eric@anholt.net>
8
9diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
10index 5fe5034..29d9d21 100644
11--- a/drivers/gpu/drm/i915/i915_gem.c
12+++ b/drivers/gpu/drm/i915/i915_gem.c
13@@ -1763,6 +1763,10 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
14 (int) args->buffers_ptr, args->buffer_count, args->batch_len);
15 #endif
16
17+ if (args->buffer_count < 1) {
18+ DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
19+ return -EINVAL;
20+ }
21 /* Copy in the exec list from userland */
22 exec_list = drm_calloc(sizeof(*exec_list), args->buffer_count,
23 DRM_MEM_DRIVER);
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch
new file mode 100644
index 0000000000..f5481d7d85
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch
@@ -0,0 +1,23 @@
1commit 930469634910fa87c21f0a7423c98b270d35d8c6
2Author: Eric Anholt <eric@anholt.net>
3Date: Mon Sep 15 13:13:34 2008 -0700
4
5 drm: G33-class hardware has a newer 965-style MCH (no DCC register).
6
7 Fixes bad software fallback rendering in Mesa in dual-channel configurations.
8
9 d9a2470012588dc5313a5ac8bb2f03575af00e99
10
11diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
12index 0c1b3a0..6b3f1e4 100644
13--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
14+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
15@@ -96,7 +96,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
16 */
17 swizzle_x = I915_BIT_6_SWIZZLE_NONE;
18 swizzle_y = I915_BIT_6_SWIZZLE_NONE;
19- } else if (!IS_I965G(dev) || IS_I965GM(dev)) {
20+ } else if ((!IS_I965G(dev) && !IS_G33(dev)) || IS_I965GM(dev)) {
21 uint32_t dcc;
22
23 /* On 915-945 and GM965, channel interleave by the CPU is
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch
new file mode 100644
index 0000000000..8e6cbe95a4
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch
@@ -0,0 +1,58 @@
1commit d9f2382adde582f8792ad96e9570716bcbea21a0
2Author: Eric Anholt <eric@anholt.net>
3Date: Tue Sep 23 14:50:57 2008 -0700
4
5 drm: Use ioremap_wc in i915_driver instead of ioremap, since we always want WC.
6
7 Fixes failure to map the ringbuffer when PAT tells us we don't get to do
8 uncached on something that's already mapped WC, or something along those lines.
9
10 Signed-off-by: Eric Anholt <eric@anholt.net>
11
12diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
13index 29d9d21..6ecfd10 100644
14--- a/drivers/gpu/drm/i915/i915_gem.c
15+++ b/drivers/gpu/drm/i915/i915_gem.c
16@@ -233,7 +233,7 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
17 if (unwritten)
18 #endif /* CONFIG_HIGHMEM */
19 {
20- vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
21+ vaddr = ioremap_wc(pfn << PAGE_SHIFT, PAGE_SIZE);
22 #if WATCH_PWRITE
23 DRM_INFO("pwrite slow i %d o %d l %d "
24 "pfn %ld vaddr %p\n",
25@@ -1612,9 +1612,10 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
26 if (reloc_page != NULL)
27 iounmap(reloc_page);
28
29- reloc_page = ioremap(dev->agp->base +
30- (reloc_offset & ~(PAGE_SIZE - 1)),
31- PAGE_SIZE);
32+ reloc_page = ioremap_wc(dev->agp->base +
33+ (reloc_offset &
34+ ~(PAGE_SIZE - 1)),
35+ PAGE_SIZE);
36 last_reloc_offset = reloc_offset;
37 if (reloc_page == NULL) {
38 drm_gem_object_unreference(target_obj);
39@@ -2318,7 +2319,9 @@ i915_gem_init_hws(struct drm_device *dev)
40 dev_priv->hws_map.flags = 0;
41 dev_priv->hws_map.mtrr = 0;
42
43- drm_core_ioremap(&dev_priv->hws_map, dev);
44+ /* Ioremapping here is the wrong thing to do. We want cached access.
45+ */
46+ drm_core_ioremap_wc(&dev_priv->hws_map, dev);
47 if (dev_priv->hws_map.handle == NULL) {
48 DRM_ERROR("Failed to map status page.\n");
49 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
50@@ -2369,7 +2372,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
51 dev_priv->ring.map.flags = 0;
52 dev_priv->ring.map.mtrr = 0;
53
54- drm_core_ioremap(&dev_priv->ring.map, dev);
55+ drm_core_ioremap_wc(&dev_priv->ring.map, dev);
56 if (dev_priv->ring.map.handle == NULL) {
57 DRM_ERROR("Failed to map ringbuffer.\n");
58 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0023-drm-clean-up-many-sparse-warnings-in-i915.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0023-drm-clean-up-many-sparse-warnings-in-i915.patch
new file mode 100644
index 0000000000..236b161587
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0023-drm-clean-up-many-sparse-warnings-in-i915.patch
@@ -0,0 +1,192 @@
1commit 034994cfffbb2371b720e3f49378031ebc12645e
2Author: Eric Anholt <eric@anholt.net>
3Date: Thu Oct 2 12:24:47 2008 -0700
4
5 drm: Clean up many sparse warnings in i915.
6
7 Signed-off-by: Eric Anholt <eric@anholt.net>
8
9diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
10index dbd3f49..814cc12 100644
11--- a/drivers/gpu/drm/i915/i915_dma.c
12+++ b/drivers/gpu/drm/i915/i915_dma.c
13@@ -76,7 +76,7 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
14 * Sets up the hardware status page for devices that need a physical address
15 * in the register.
16 */
17-int i915_init_phys_hws(struct drm_device *dev)
18+static int i915_init_phys_hws(struct drm_device *dev)
19 {
20 drm_i915_private_t *dev_priv = dev->dev_private;
21 /* Program Hardware Status Page */
22@@ -101,7 +101,7 @@ int i915_init_phys_hws(struct drm_device *dev)
23 * Frees the hardware status page, whether it's a physical address or a virtual
24 * address set up by the X Server.
25 */
26-void i915_free_hws(struct drm_device *dev)
27+static void i915_free_hws(struct drm_device *dev)
28 {
29 drm_i915_private_t *dev_priv = dev->dev_private;
30 if (dev_priv->status_page_dmah) {
31@@ -145,8 +145,8 @@ static int i915_dma_cleanup(struct drm_device * dev)
32
33 if (dev_priv->ring.virtual_start) {
34 drm_core_ioremapfree(&dev_priv->ring.map, dev);
35- dev_priv->ring.virtual_start = 0;
36- dev_priv->ring.map.handle = 0;
37+ dev_priv->ring.virtual_start = NULL;
38+ dev_priv->ring.map.handle = NULL;
39 dev_priv->ring.map.size = 0;
40 }
41
42@@ -827,9 +827,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
43 base = drm_get_resource_start(dev, mmio_bar);
44 size = drm_get_resource_len(dev, mmio_bar);
45
46- ret = drm_addmap(dev, base, size, _DRM_REGISTERS,
47- _DRM_KERNEL | _DRM_DRIVER,
48- &dev_priv->mmio_map);
49+ dev_priv->regs = ioremap(base, size);
50
51 i915_gem_load(dev);
52
53@@ -867,8 +865,8 @@ int i915_driver_unload(struct drm_device *dev)
54
55 i915_free_hws(dev);
56
57- if (dev_priv->mmio_map)
58- drm_rmmap(dev, dev_priv->mmio_map);
59+ if (dev_priv->regs != NULL)
60+ iounmap(dev_priv->regs);
61
62 intel_opregion_free(dev);
63
64diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
65index 8547f0a..b184d54 100644
66--- a/drivers/gpu/drm/i915/i915_drv.h
67+++ b/drivers/gpu/drm/i915/i915_drv.h
68@@ -110,8 +110,8 @@ struct intel_opregion {
69 typedef struct drm_i915_private {
70 struct drm_device *dev;
71
72+ void __iomem *regs;
73 drm_local_map_t *sarea;
74- drm_local_map_t *mmio_map;
75
76 drm_i915_sarea_t *sarea_priv;
77 drm_i915_ring_buffer_t ring;
78@@ -553,12 +553,12 @@ extern void opregion_enable_asle(struct drm_device *dev);
79 LOCK_TEST_WITH_RETURN(dev, file_priv); \
80 } while (0)
81
82-#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
83-#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
84-#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
85-#define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val))
86-#define I915_READ8(reg) DRM_READ8(dev_priv->mmio_map, (reg))
87-#define I915_WRITE8(reg,val) DRM_WRITE8(dev_priv->mmio_map, (reg), (val))
88+#define I915_READ(reg) readl(dev_priv->regs + (reg))
89+#define I915_WRITE(reg,val) writel(val, dev_priv->regs + (reg))
90+#define I915_READ16(reg) readw(dev_priv->regs + (reg))
91+#define I915_WRITE16(reg,val) writel(val, dev_priv->regs + (reg))
92+#define I915_READ8(reg) readb(dev_priv->regs + (reg))
93+#define I915_WRITE8(reg,val) writeb(val, dev_priv->regs + (reg))
94
95 #define I915_VERBOSE 0
96
97diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
98index 6ecfd10..6a89449 100644
99--- a/drivers/gpu/drm/i915/i915_gem.c
100+++ b/drivers/gpu/drm/i915/i915_gem.c
101@@ -176,7 +176,8 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
102 ssize_t remain;
103 loff_t offset;
104 char __user *user_data;
105- char *vaddr;
106+ char __iomem *vaddr;
107+ char *vaddr_atomic;
108 int i, o, l;
109 int ret = 0;
110 unsigned long pfn;
111@@ -219,16 +220,20 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
112 pfn = (dev->agp->base >> PAGE_SHIFT) + i;
113
114 #ifdef CONFIG_HIGHMEM
115- /* kmap_atomic can't map IO pages on non-HIGHMEM kernels
116+ /* This is a workaround for the low performance of iounmap
117+ * (approximate 10% cpu cost on normal 3D workloads).
118+ * kmap_atomic on HIGHMEM kernels happens to let us map card
119+ * memory without taking IPIs. When the vmap rework lands
120+ * we should be able to dump this hack.
121 */
122- vaddr = kmap_atomic_pfn(pfn, KM_USER0);
123+ vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0);
124 #if WATCH_PWRITE
125 DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n",
126- i, o, l, pfn, vaddr);
127+ i, o, l, pfn, vaddr_atomic);
128 #endif
129- unwritten = __copy_from_user_inatomic_nocache(vaddr + o,
130+ unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o,
131 user_data, l);
132- kunmap_atomic(vaddr, KM_USER0);
133+ kunmap_atomic(vaddr_atomic, KM_USER0);
134
135 if (unwritten)
136 #endif /* CONFIG_HIGHMEM */
137@@ -271,7 +276,7 @@ fail:
138 return ret;
139 }
140
141-int
142+static int
143 i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
144 struct drm_i915_gem_pwrite *args,
145 struct drm_file *file_priv)
146@@ -587,7 +592,7 @@ i915_add_request(struct drm_device *dev, uint32_t flush_domains)
147 * Ensures that all commands in the ring are finished
148 * before signalling the CPU
149 */
150-uint32_t
151+static uint32_t
152 i915_retire_commands(struct drm_device *dev)
153 {
154 drm_i915_private_t *dev_priv = dev->dev_private;
155@@ -734,7 +739,7 @@ i915_gem_retire_work_handler(struct work_struct *work)
156 * Waits for a sequence number to be signaled, and cleans up the
157 * request and object lists appropriately for that event.
158 */
159-int
160+static int
161 i915_wait_request(struct drm_device *dev, uint32_t seqno)
162 {
163 drm_i915_private_t *dev_priv = dev->dev_private;
164@@ -1483,7 +1488,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
165 struct drm_i915_gem_object *obj_priv = obj->driver_private;
166 int i, ret;
167 uint32_t last_reloc_offset = -1;
168- void *reloc_page = NULL;
169+ void __iomem *reloc_page = NULL;
170
171 /* Choose the GTT offset for our buffer and put it there. */
172 ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment);
173@@ -1500,8 +1505,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
174 for (i = 0; i < entry->relocation_count; i++) {
175 struct drm_gem_object *target_obj;
176 struct drm_i915_gem_object *target_obj_priv;
177- uint32_t reloc_val, reloc_offset, *reloc_entry;
178- int ret;
179+ uint32_t reloc_val, reloc_offset;
180+ uint32_t __iomem *reloc_entry;
181
182 ret = copy_from_user(&reloc, relocs + i, sizeof(reloc));
183 if (ret != 0) {
184@@ -1624,7 +1629,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
185 }
186 }
187
188- reloc_entry = (uint32_t *)((char *)reloc_page +
189+ reloc_entry = (uint32_t __iomem *)(reloc_page +
190 (reloc_offset & (PAGE_SIZE - 1)));
191 reloc_val = target_obj_priv->gtt_offset + reloc.delta;
192
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0024-fastboot-create-a-asynchronous-initlevel.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0024-fastboot-create-a-asynchronous-initlevel.patch
new file mode 100644
index 0000000000..7c19053b0e
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0024-fastboot-create-a-asynchronous-initlevel.patch
@@ -0,0 +1,136 @@
1From ac9103dd8e4dc65c110d6cba9a3380c6c617ffa7 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Fri, 18 Jul 2008 15:16:08 -0700
4Subject: [PATCH] fastboot: create a "asynchronous" initlevel
5
6This patch creates an asynchronous initlevel (6a) which is at the same
7level as the normal device initcalls, but with the difference that they
8are run asynchronous from all the other initcalls. The purpose of this
9*selective* level is that we can move long waiting inits that are not
10boot-critical to this level one at a time.
11
12To keep things not totally insane, the asynchronous initcalls are async
13to the other initcalls, but are still ordered to themselves; think of it
14as "bottom-half-not-softirq". This has the benefit that async drivers
15still have stable device ordering between them.
16
17Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
18Signed-off-by: Ingo Molnar <mingo@elte.hu>
19---
20 include/asm-generic/vmlinux.lds.h | 3 +++
21 include/linux/init.h | 6 ++++++
22 init/main.c | 36 +++++++++++++++++++++++++++++++++---
23 3 files changed, 42 insertions(+), 3 deletions(-)
24
25diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
26index 729f6b0..39c1afc 100644
27--- a/include/asm-generic/vmlinux.lds.h
28+++ b/include/asm-generic/vmlinux.lds.h
29@@ -372,6 +372,9 @@
30 *(.initcall5.init) \
31 *(.initcall5s.init) \
32 *(.initcallrootfs.init) \
33+ __async_initcall_start = .; \
34+ *(.initcall6a.init) \
35+ __async_initcall_end = .; \
36 *(.initcall6.init) \
37 *(.initcall6s.init) \
38 *(.initcall7.init) \
39diff --git a/include/linux/init.h b/include/linux/init.h
40index 21d658c..75db909 100644
41--- a/include/linux/init.h
42+++ b/include/linux/init.h
43@@ -197,11 +197,13 @@
44 #define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
45 #define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs)
46 #define device_initcall(fn) __define_initcall("6",fn,6)
47+#define device_initcall_async(fn) __define_initcall("6a", fn, 6a)
48 #define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
49 #define late_initcall(fn) __define_initcall("7",fn,7)
50 #define late_initcall_sync(fn) __define_initcall("7s",fn,7s)
51
52 #define __initcall(fn) device_initcall(fn)
53+#define __initcall_async(fn) device_initcall_async(fn)
54
55 #define __exitcall(fn) \
56 static exitcall_t __exitcall_##fn __exit_call = fn
57@@ -257,6 +259,7 @@
58 * be one per module.
59 */
60 #define module_init(x) __initcall(x);
61+#define module_init_async(x) __initcall_async(x);
62
63 /**
64 * module_exit() - driver exit entry point
65@@ -279,10 +282,13 @@
66 #define subsys_initcall(fn) module_init(fn)
67 #define fs_initcall(fn) module_init(fn)
68 #define device_initcall(fn) module_init(fn)
69+#define device_initcall_async(fn) module_init(fn)
70 #define late_initcall(fn) module_init(fn)
71
72 #define security_initcall(fn) module_init(fn)
73
74+#define module_init_async(fn) module_init(fn)
75+
76 /* Each module must use one module_init(). */
77 #define module_init(initfn) \
78 static inline initcall_t __inittest(void) \
79diff --git a/init/main.c b/init/main.c
80index edeace0..6961de2 100644
81--- a/init/main.c
82+++ b/init/main.c
83@@ -746,18 +746,47 @@
84
85
86 extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
87+extern initcall_t __async_initcall_start[], __async_initcall_end[];
88
89-static void __init do_initcalls(void)
90+static void __init do_async_initcalls(struct work_struct *dummy)
91 {
92 initcall_t *call;
93
94- for (call = __early_initcall_end; call < __initcall_end; call++)
95+ for (call = __async_initcall_start; call < __async_initcall_end; call++)
96 do_one_initcall(*call);
97+}
98+
99+static struct workqueue_struct *async_init_wq;
100+
101+static void __init do_initcalls(void)
102+{
103+ initcall_t *call;
104+ static DECLARE_WORK(async_work, do_async_initcalls);
105+ int phase = 0; /* 0 = levels 0 - 6, 1 = level 6a, 2 = after level 6a */
106+
107+ async_init_wq = create_singlethread_workqueue("kasyncinit");
108+
109+ for (call = __early_initcall_end; call < __initcall_end; call++) {
110+ if (phase == 0 && call >= __async_initcall_start) {
111+ phase = 1;
112+ queue_work(async_init_wq, &async_work);
113+ }
114+ if (phase == 1 && call >= __async_initcall_end)
115+ phase = 2;
116+ if (phase != 1)
117+ do_one_initcall(*call);
118+ }
119
120- /* Make sure there is no pending stuff from the initcall sequence */
121+ /*
122+ * Make sure there is no pending stuff from the initcall sequence,
123+ * including the async initcalls
124+ */
125 flush_scheduled_work();
126+ flush_workqueue(async_init_wq);
127+ destroy_workqueue(async_init_wq);
128 }
129
130+
131 /*
132 * Ok, the machine is now initialized. None of the devices
133 * have been touched yet, but the CPU subsystem is up and
134--
1351.5.4.3
136
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch
new file mode 100644
index 0000000000..75d4151b3b
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch
@@ -0,0 +1,62 @@
1From d1a26186ee222329a797bb0b2c8e2b5bc7d94d42 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Fri, 18 Jul 2008 15:16:53 -0700
4Subject: [PATCH] fastboot: turn the USB hostcontroller initcalls into async initcalls
5
6the USB host controller init calls take a long time, mostly due to a
7"minimally 100 msec" delay *per port* during initialization.
8These are prime candidates for going in parallel to everything else.
9
10The USB device ordering is not affected by this due to the
11serialized-within-eachother property of async initcalls.
12
13Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
14Signed-off-by: Ingo Molnar <mingo@elte.hu>
15---
16 drivers/usb/host/ehci-hcd.c | 2 +-
17 drivers/usb/host/ohci-hcd.c | 2 +-
18 drivers/usb/host/uhci-hcd.c | 2 +-
19 3 files changed, 3 insertions(+), 3 deletions(-)
20
21diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
22index 369a8a5..8f84b17 100644
23--- a/drivers/usb/host/ehci-hcd.c
24+++ b/drivers/usb/host/ehci-hcd.c
25@@ -1101,7 +1101,7 @@ clean0:
26 #endif
27 return retval;
28 }
29-module_init(ehci_hcd_init);
30+module_init_async(ehci_hcd_init);
31
32 static void __exit ehci_hcd_cleanup(void)
33 {
34diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
35index a8160d6..e060ed1 100644
36--- a/drivers/usb/host/ohci-hcd.c
37+++ b/drivers/usb/host/ohci-hcd.c
38@@ -1165,7 +1165,7 @@ static int __init ohci_hcd_mod_init(void)
39
40 return retval;
41 }
42-module_init(ohci_hcd_mod_init);
43+module_init_async(ohci_hcd_mod_init);
44
45 static void __exit ohci_hcd_mod_exit(void)
46 {
47diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
48index 3a7bfe7..f2a05ac 100644
49--- a/drivers/usb/host/uhci-hcd.c
50+++ b/drivers/usb/host/uhci-hcd.c
51@@ -999,7 +999,7 @@ static void __exit uhci_hcd_cleanup(void)
52 kfree(errbuf);
53 }
54
55-module_init(uhci_hcd_init);
56+module_init_async(uhci_hcd_init);
57 module_exit(uhci_hcd_cleanup);
58
59 MODULE_AUTHOR(DRIVER_AUTHOR);
60--
611.5.4.3
62
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch
new file mode 100644
index 0000000000..efd8ca9c9c
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch
@@ -0,0 +1,54 @@
1From 60ddc2e5c44b4b9f5fcb440065469eacbeabf5eb Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Fri, 18 Jul 2008 15:17:35 -0700
4Subject: [PATCH] fastboot: convert a few non-critical ACPI drivers to async initcalls
5
6This patch converts a few non-critical ACPI drivers to async initcalls;
7these initcalls (battery, button and thermal) tend to take quite a bit of
8time (100's of milliseconds) due to the hardware they need to talk to,
9but are otherwise clearly non-essential for the boot process.
10
11Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
12Signed-off-by: Ingo Molnar <mingo@elte.hu>
13---
14 drivers/acpi/battery.c | 2 +-
15 drivers/acpi/button.c | 2 +-
16 drivers/acpi/thermal.c | 2 +-
17 3 files changed, 3 insertions(+), 3 deletions(-)
18
19diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
20index b1c723f..d5d30ca 100644
21--- a/drivers/acpi/battery.c
22+++ b/drivers/acpi/battery.c
23@@ -904,5 +904,5 @@ static void __exit acpi_battery_exit(void)
24 #endif
25 }
26
27-module_init(acpi_battery_init);
28+module_init_async(acpi_battery_init);
29 module_exit(acpi_battery_exit);
30diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
31index 1dfec41..46b3805 100644
32--- a/drivers/acpi/button.c
33+++ b/drivers/acpi/button.c
34@@ -545,5 +545,5 @@ static void __exit acpi_button_exit(void)
35 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
36 }
37
38-module_init(acpi_button_init);
39+module_init_async(acpi_button_init);
40 module_exit(acpi_button_exit);
41diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
42index 84c795f..1f529af 100644
43--- a/drivers/acpi/thermal.c
44+++ b/drivers/acpi/thermal.c
45@@ -1833,5 +1833,5 @@ static void __exit acpi_thermal_exit(void)
46 return;
47 }
48
49-module_init(acpi_thermal_init);
50+module_init_async(acpi_thermal_init);
51 module_exit(acpi_thermal_exit);
52--
531.5.4.3
54
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch
new file mode 100644
index 0000000000..129823b6ce
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch
@@ -0,0 +1,40 @@
1From 3e6558b693dd1e69e3177bc248977f067a769f14 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 08:59:24 -0700
4Subject: [PATCH] fastboot: hold the BKL over the async init call sequence
5
6Regular init calls are called with the BKL held; make sure
7the async init calls are also called with the BKL held.
8While this reduces parallelism a little, it does provide
9lock-for-lock compatibility. The hit to prallelism isn't too
10bad, most of the init calls are done immediately or actually
11block for their delays.
12
13Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
14Signed-off-by: Ingo Molnar <mingo@elte.hu>
15---
16 init/main.c | 6 ++++++
17 1 files changed, 6 insertions(+), 0 deletions(-)
18
19diff --git a/init/main.c b/init/main.c
20index 6961de2..9e2aee8 100644
21--- a/init/main.c
22+++ b/init/main.c
23@@ -744,8 +744,14 @@ static void __init do_async_initcalls(struct work_struct *dummy)
24 {
25 initcall_t *call;
26
27+ /*
28+ * For compatibility with normal init calls... take the BKL
29+ * not pretty, not desirable, but compatibility first
30+ */
31+ lock_kernel();
32 for (call = __async_initcall_start; call < __async_initcall_end; call++)
33 do_one_initcall(*call);
34+ unlock_kernel();
35 }
36
37 static struct workqueue_struct *async_init_wq;
38--
391.5.4.3
40
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0028-fastboot-sync-the-async-execution-before-late_initc.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0028-fastboot-sync-the-async-execution-before-late_initc.patch
new file mode 100644
index 0000000000..0700fb3189
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0028-fastboot-sync-the-async-execution-before-late_initc.patch
@@ -0,0 +1,95 @@
1From 660625fb93f2fc0e633da9cb71d13d895b385f64 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 09:00:41 -0700
4Subject: [PATCH] fastboot: sync the async execution before late_initcall and move level 6s (sync) first
5
6Rene Herman points out several cases where it's basically needed to have
7all level 6/6a/6s calls done before the level 7 (late_initcall) code
8runs. This patch adds a sync point in the transition from the 6's to the
97's.
10
11Second, this patch makes sure that level 6s (sync) happens before the
12async code starts, and puts a user in driver/pci in this category that
13needs to happen before device init.
14
15Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
16Signed-off-by: Ingo Molnar <mingo@elte.hu>
17---
18 drivers/pci/pci.c | 2 +-
19 include/asm-generic/vmlinux.lds.h | 3 ++-
20 init/main.c | 14 +++++++++++++-
21 3 files changed, 16 insertions(+), 3 deletions(-)
22
23diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
24index 44a46c9..d75295d 100644
25--- a/drivers/pci/pci.c
26+++ b/drivers/pci/pci.c
27@@ -1889,7 +1889,7 @@ static int __devinit pci_setup(char *str)
28 }
29 early_param("pci", pci_setup);
30
31-device_initcall(pci_init);
32+device_initcall_sync(pci_init);
33
34 EXPORT_SYMBOL(pci_reenable_device);
35 EXPORT_SYMBOL(pci_enable_device_io);
36diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
37index 39c1afc..020c641 100644
38--- a/include/asm-generic/vmlinux.lds.h
39+++ b/include/asm-generic/vmlinux.lds.h
40@@ -372,11 +372,12 @@
41 *(.initcall5.init) \
42 *(.initcall5s.init) \
43 *(.initcallrootfs.init) \
44+ *(.initcall6s.init) \
45 __async_initcall_start = .; \
46 *(.initcall6a.init) \
47 __async_initcall_end = .; \
48 *(.initcall6.init) \
49- *(.initcall6s.init) \
50+ __device_initcall_end = .; \
51 *(.initcall7.init) \
52 *(.initcall7s.init)
53
54diff --git a/init/main.c b/init/main.c
55index 9e2aee8..6be1756 100644
56--- a/init/main.c
57+++ b/init/main.c
58@@ -739,6 +739,7 @@ static void __init do_one_initcall(initcall_t fn)
59
60 extern initcall_t __initcall_start[], __initcall_end[];
61 extern initcall_t __async_initcall_start[], __async_initcall_end[];
62+extern initcall_t __device_initcall_end[];
63
64 static void __init do_async_initcalls(struct work_struct *dummy)
65 {
66@@ -762,7 +763,13 @@ static void __init do_initcalls(void)
67 {
68 initcall_t *call;
69 static DECLARE_WORK(async_work, do_async_initcalls);
70- int phase = 0; /* 0 = levels 0 - 6, 1 = level 6a, 2 = after level 6a */
71+ /*
72+ * 0 = levels 0 - 6,
73+ * 1 = level 6a,
74+ * 2 = after level 6a,
75+ * 3 = after level 6
76+ */
77+ int phase = 0;
78
79 async_init_wq = create_singlethread_workqueue("kasyncinit");
80
81@@ -773,6 +780,11 @@ static void __init do_initcalls(void)
82 }
83 if (phase == 1 && call >= __async_initcall_end)
84 phase = 2;
85+ if (phase == 2 && call >= __device_initcall_end) {
86+ phase = 3;
87+ /* make sure all async work is done before level 7 */
88+ flush_workqueue(async_init_wq);
89+ }
90 if (phase != 1)
91 do_one_initcall(*call);
92 }
93--
941.5.4.3
95
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0029-fastboot-make-fastboot-a-config-option.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0029-fastboot-make-fastboot-a-config-option.patch
new file mode 100644
index 0000000000..faf9622091
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0029-fastboot-make-fastboot-a-config-option.patch
@@ -0,0 +1,56 @@
1From 50b6962016b824dfac254b8f36fc6cac301c8a8d Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 10:20:49 -0700
4Subject: [PATCH] fastboot: make fastboot a config option
5
6to mitigate the risks of async bootup, make fastboot a configuration
7option...
8
9Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
10Signed-off-by: Ingo Molnar <mingo@elte.hu>
11---
12 init/Kconfig | 11 +++++++++++
13 init/main.c | 4 ++++
14 2 files changed, 15 insertions(+), 0 deletions(-)
15
16diff --git a/init/Kconfig b/init/Kconfig
17index 6199d11..7545c8b 100644
18--- a/init/Kconfig
19+++ b/init/Kconfig
20@@ -524,6 +524,17 @@ config CC_OPTIMIZE_FOR_SIZE
21
22 If unsure, say N.
23
24+config FASTBOOT
25+ bool "Fast boot support"
26+ help
27+ The fastboot option will cause the kernel to try to optimize
28+ for faster boot.
29+
30+ This includes doing some of the device initialization asynchronous
31+ as well as opportunistically trying to mount the root fs early.
32+
33+ If unsure, say N.
34+
35 config SYSCTL
36 bool
37
38diff --git a/init/main.c b/init/main.c
39index 6be1756..bb97add 100644
40--- a/init/main.c
41+++ b/init/main.c
42@@ -776,7 +776,11 @@ static void __init do_initcalls(void)
43 for (call = __initcall_start; call < __initcall_end; call++) {
44 if (phase == 0 && call >= __async_initcall_start) {
45 phase = 1;
46+#ifdef CONFIG_FASTBOOT
47 queue_work(async_init_wq, &async_work);
48+#else
49+ do_async_initcalls(NULL);
50+#endif
51 }
52 if (phase == 1 && call >= __async_initcall_end)
53 phase = 2;
54--
551.5.4.3
56
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch
new file mode 100644
index 0000000000..e2c3737935
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch
@@ -0,0 +1,67 @@
1From db62cd29f9b9142c19c574ca00916f66ff22ed4a Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 13:01:28 -0700
4Subject: [PATCH] fastboot: retry mounting the root fs if we can't find init
5
6currently we wait until all device init is done before trying to mount
7the root fs, and to consequently execute init.
8
9In preparation for relaxing the first delay, this patch adds a retry
10attempt in case /sbin/init is not found. Before retrying, the code
11will wait for all device init to complete.
12
13While this patch by itself doesn't gain boot time yet (it needs follow on
14patches), the alternative already is to panic()...
15
16Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
17---
18 init/main.c | 19 +++++++++++++++++++
19 1 files changed, 19 insertions(+), 0 deletions(-)
20
21diff --git a/init/main.c b/init/main.c
22index 3575b84..73785a4 100644
23--- a/init/main.c
24+++ b/init/main.c
25@@ -853,6 +853,7 @@ static void run_init_process(char *init_filename)
26 */
27 static int noinline init_post(void)
28 {
29+ int retry_count = 1;
30 free_initmem();
31 unlock_kernel();
32 mark_rodata_ro();
33@@ -873,6 +874,7 @@ static int noinline init_post(void)
34 ramdisk_execute_command);
35 }
36
37+retry:
38 /*
39 * We try each of these until one succeeds.
40 *
41@@ -885,6 +887,23 @@ static int noinline init_post(void)
42 "defaults...\n", execute_command);
43 }
44 run_init_process("/sbin/init");
45+
46+ if (retry_count > 0) {
47+ retry_count--;
48+ /*
49+ * We haven't found init yet... potentially because the device
50+ * is still being probed. We need to
51+ * - flush keventd and friends
52+ * - wait for the known devices to complete their probing
53+ * - try to mount the root fs again
54+ */
55+ flush_scheduled_work();
56+ while (driver_probe_done() != 0)
57+ msleep(100);
58+ prepare_namespace();
59+ goto retry;
60+ }
61+
62 run_init_process("/etc/init");
63 run_init_process("/bin/init");
64 run_init_process("/bin/sh");
65--
661.5.4.3
67
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch
new file mode 100644
index 0000000000..03b3b82202
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch
@@ -0,0 +1,41 @@
1From b52c36a95ed8026b6925fe8595ebcab6921ae62d Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 13:07:09 -0700
4Subject: [PATCH] fastboot: make the raid autodetect code wait for all devices to init
5
6The raid autodetect code really needs to have all devices probed before
7it can detect raid arrays; not doing so would give rather messy situations
8where arrays would get detected as degraded while they shouldn't be etc.
9
10This is in preparation of removing the "wait for everything to init"
11code that makes everyone pay, not just raid users.
12
13Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
14---
15 init/do_mounts_md.c | 7 +++++++
16 1 files changed, 7 insertions(+), 0 deletions(-)
17
18diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
19index 693d246..c0412a9 100644
20--- a/init/do_mounts_md.c
21+++ b/init/do_mounts_md.c
22@@ -267,9 +267,16 @@ __setup("md=", md_setup);
23 void __init md_run_setup(void)
24 {
25 create_dev("/dev/md0", MKDEV(MD_MAJOR, 0));
26+
27 if (raid_noautodetect)
28 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
29 else {
30+ /*
31+ * Since we don't want to detect and use half a raid array, we need to
32+ * wait for the known devices to complete their probing
33+ */
34+ while (driver_probe_done() != 0)
35+ msleep(100);
36 int fd = sys_open("/dev/md0", 0, 0);
37 if (fd >= 0) {
38 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
39--
401.5.4.3
41
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0032-fastboot-remove-wait-for-all-devices-before-mounti.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0032-fastboot-remove-wait-for-all-devices-before-mounti.patch
new file mode 100644
index 0000000000..4e9be15e1d
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0032-fastboot-remove-wait-for-all-devices-before-mounti.patch
@@ -0,0 +1,44 @@
1From 1b5a2bd0602010398cb473d1b821a9f1c1399caf Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 13:12:16 -0700
4Subject: [PATCH] fastboot: remove "wait for all devices before mounting root" delay
5
6In the non-initrd case, we wait for all devices to finish their
7probing before we try to mount the rootfs.
8In practice, this means that we end up waiting 2 extra seconds for
9the PS/2 mouse probing even though the root holding device has been
10ready since a long time.
11
12The previous two patches in this series made the RAID autodetect code
13do it's own "wait for probing to be done" code, and added
14"wait and retry" functionality in case the root device isn't actually
15available.
16
17These two changes should make it safe to remove the delay itself,
18and this patch does this. On my test laptop, this reduces the boot time
19by 2 seconds (kernel time goes from 3.9 to 1.9 seconds).
20
21Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
22---
23 init/do_mounts.c | 2 ++
24 1 files changed, 2 insertions(+), 0 deletions(-)
25
26diff --git a/init/do_mounts.c b/init/do_mounts.c
27index a1de1bf..c984fab 100644
28--- a/init/do_mounts.c
29+++ b/init/do_mounts.c
30@@ -364,9 +364,11 @@ void __init prepare_namespace(void)
31 ssleep(root_delay);
32 }
33
34+#ifndef CONFIG_FASTBOOT
35 /* wait for the known devices to complete their probing */
36 while (driver_probe_done() != 0)
37 msleep(100);
38+#endif
39
40 md_run_setup();
41
42--
431.5.4.3
44
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch
new file mode 100644
index 0000000000..55c6c1adae
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch
@@ -0,0 +1,32 @@
1From 799d0da9e645258b9d1ae11d4aac73c9474906e3 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 16:30:29 -0700
4Subject: [PATCH] fastboot: make the RAID autostart code print a message just before waiting
5
6As requested/suggested by Neil Brown: make the raid code print that it's
7about to wait for probing to be done as well as give a suggestion on how
8to disable the probing if the user doesn't use raid.
9
10Signed-off-by: Arjan van de Ven <arjan@linux.intel.com
11---
12 init/do_mounts_md.c | 4 +++-
13 1 files changed, 3 insertions(+), 1 deletions(-)
14
15diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
16index c0412a9..1ec5c41 100644
17--- a/init/do_mounts_md.c
18+++ b/init/do_mounts_md.c
19@@ -275,7 +275,9 @@ void __init md_run_setup(void)
20 * Since we don't want to detect and use half a raid array, we need to
21 * wait for the known devices to complete their probing
22 */
23- while (driver_probe_done() != 0)
24+ printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n");
25+ printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n");
26+ while (driver_probe_done() < 0)
27 msleep(100);
28 int fd = sys_open("/dev/md0", 0, 0);
29 if (fd >= 0) {
30--
311.5.4.3
32
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0034-fastboot-fix-typo-in-init-Kconfig-text.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0034-fastboot-fix-typo-in-init-Kconfig-text.patch
new file mode 100644
index 0000000000..7426293549
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0034-fastboot-fix-typo-in-init-Kconfig-text.patch
@@ -0,0 +1,29 @@
1From 1a23ed42e1baf0481cc70c2f71d97b0bf0f1be70 Mon Sep 17 00:00:00 2001
2From: Ingo Molnar <mingo@elte.hu>
3Date: Thu, 31 Jul 2008 12:52:29 +0200
4Subject: [PATCH] fastboot: fix typo in init/Kconfig text
5
6noticed by Randy Dunlap.
7
8Reported-by: Randy Dunlap <randy.dunlap@oracle.com>
9Signed-off-by: Ingo Molnar <mingo@elte.hu>
10---
11 init/Kconfig | 2 +-
12 1 files changed, 1 insertions(+), 1 deletions(-)
13
14diff --git a/init/Kconfig b/init/Kconfig
15index 4f73780..6b4de4d 100644
16--- a/init/Kconfig
17+++ b/init/Kconfig
18@@ -530,7 +530,7 @@ config FASTBOOT
19 The fastboot option will cause the kernel to try to optimize
20 for faster boot.
21
22- This includes doing some of the device initialization asynchronous
23+ This includes doing some of the device initialization asynchronously
24 as well as opportunistically trying to mount the root fs early.
25
26 If unsure, say N.
27--
281.5.4.3
29
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0035-fastboot-remove-duplicate-unpack_to_rootfs.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0035-fastboot-remove-duplicate-unpack_to_rootfs.patch
new file mode 100644
index 0000000000..b8af74eaf2
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0035-fastboot-remove-duplicate-unpack_to_rootfs.patch
@@ -0,0 +1,161 @@
1From 8929dda869d51b953c8f300864da62297db8a74e Mon Sep 17 00:00:00 2001
2From: Li, Shaohua <shaohua.li@intel.com>
3Date: Wed, 13 Aug 2008 17:26:01 +0800
4Subject: [PATCH] fastboot: remove duplicate unpack_to_rootfs()
5
6we check if initrd is initramfs first and then do real unpack. The
7check isn't required, we can directly do unpack. If initrd isn't
8initramfs, we can remove garbage. In my laptop, this saves 0.1s boot
9time. This penalizes non-initramfs case, but now initramfs is mostly
10widely used.
11
12Signed-off-by: Shaohua Li <shaohua.li@intel.com>
13Acked-by: Arjan van de Ven <arjan@infradead.org>
14Signed-off-by: Ingo Molnar <mingo@elte.hu>
15---
16 init/initramfs.c | 71 ++++++++++++++++++++++++++++++++++++++++++-----------
17 1 files changed, 56 insertions(+), 15 deletions(-)
18
19diff --git a/init/initramfs.c b/init/initramfs.c
20index 644fc01..da8d030 100644
21--- a/init/initramfs.c
22+++ b/init/initramfs.c
23@@ -5,6 +5,7 @@
24 #include <linux/fcntl.h>
25 #include <linux/delay.h>
26 #include <linux/string.h>
27+#include <linux/dirent.h>
28 #include <linux/syscalls.h>
29
30 static __initdata char *message;
31@@ -121,8 +122,6 @@ static __initdata char *victim;
32 static __initdata unsigned count;
33 static __initdata loff_t this_header, next_header;
34
35-static __initdata int dry_run;
36-
37 static inline void __init eat(unsigned n)
38 {
39 victim += n;
40@@ -183,10 +182,6 @@ static int __init do_header(void)
41 parse_header(collected);
42 next_header = this_header + N_ALIGN(name_len) + body_len;
43 next_header = (next_header + 3) & ~3;
44- if (dry_run) {
45- read_into(name_buf, N_ALIGN(name_len), GotName);
46- return 0;
47- }
48 state = SkipIt;
49 if (name_len <= 0 || name_len > PATH_MAX)
50 return 0;
51@@ -257,8 +252,6 @@ static int __init do_name(void)
52 free_hash();
53 return 0;
54 }
55- if (dry_run)
56- return 0;
57 clean_path(collected, mode);
58 if (S_ISREG(mode)) {
59 int ml = maybe_link();
60@@ -423,10 +416,9 @@ static void __init flush_window(void)
61 outcnt = 0;
62 }
63
64-static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
65+static char * __init unpack_to_rootfs(char *buf, unsigned len)
66 {
67 int written;
68- dry_run = check_only;
69 header_buf = kmalloc(110, GFP_KERNEL);
70 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
71 name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
72@@ -520,10 +512,57 @@ skip:
73 initrd_end = 0;
74 }
75
76+#define BUF_SIZE 1024
77+static void __init clean_rootfs(void)
78+{
79+ int fd;
80+ void *buf;
81+ struct linux_dirent64 *dirp;
82+ int count;
83+
84+ fd = sys_open("/", O_RDONLY, 0);
85+ WARN_ON(fd < 0);
86+ if (fd < 0)
87+ return;
88+ buf = kzalloc(BUF_SIZE, GFP_KERNEL);
89+ WARN_ON(!buf);
90+ if (!buf) {
91+ sys_close(fd);
92+ return;
93+ }
94+
95+ dirp = buf;
96+ count = sys_getdents64(fd, dirp, BUF_SIZE);
97+ while (count > 0) {
98+ while (count > 0) {
99+ struct stat st;
100+ int ret;
101+
102+ ret = sys_newlstat(dirp->d_name, &st);
103+ WARN_ON_ONCE(ret);
104+ if (!ret) {
105+ if (S_ISDIR(st.st_mode))
106+ sys_rmdir(dirp->d_name);
107+ else
108+ sys_unlink(dirp->d_name);
109+ }
110+
111+ count -= dirp->d_reclen;
112+ dirp = (void *)dirp + dirp->d_reclen;
113+ }
114+ dirp = buf;
115+ memset(buf, 0, BUF_SIZE);
116+ count = sys_getdents64(fd, dirp, BUF_SIZE);
117+ }
118+
119+ sys_close(fd);
120+ kfree(buf);
121+}
122+
123 static int __init populate_rootfs(void)
124 {
125 char *err = unpack_to_rootfs(__initramfs_start,
126- __initramfs_end - __initramfs_start, 0);
127+ __initramfs_end - __initramfs_start);
128 if (err)
129 panic(err);
130 if (initrd_start) {
131@@ -531,13 +570,15 @@ static int __init populate_rootfs(void)
132 int fd;
133 printk(KERN_INFO "checking if image is initramfs...");
134 err = unpack_to_rootfs((char *)initrd_start,
135- initrd_end - initrd_start, 1);
136+ initrd_end - initrd_start);
137 if (!err) {
138 printk(" it is\n");
139- unpack_to_rootfs((char *)initrd_start,
140- initrd_end - initrd_start, 0);
141 free_initrd();
142 return 0;
143+ } else {
144+ clean_rootfs();
145+ unpack_to_rootfs(__initramfs_start,
146+ __initramfs_end - __initramfs_start);
147 }
148 printk("it isn't (%s); looks like an initrd\n", err);
149 fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 0700);
150@@ -550,7 +591,7 @@ static int __init populate_rootfs(void)
151 #else
152 printk(KERN_INFO "Unpacking initramfs...");
153 err = unpack_to_rootfs((char *)initrd_start,
154- initrd_end - initrd_start, 0);
155+ initrd_end - initrd_start);
156 if (err)
157 panic(err);
158 printk(" done\n");
159--
1601.5.4.3
161
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0036-warning-fix-init-do_mounts_md-c.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0036-warning-fix-init-do_mounts_md-c.patch
new file mode 100644
index 0000000000..9ba44a892d
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0036-warning-fix-init-do_mounts_md-c.patch
@@ -0,0 +1,82 @@
1From fa3038625d7df2a1244c5b753069e7fdf99af3b5 Mon Sep 17 00:00:00 2001
2From: Ingo Molnar <mingo@elte.hu>
3Date: Mon, 18 Aug 2008 12:54:00 +0200
4Subject: [PATCH] warning: fix init do_mounts_md c
5MIME-Version: 1.0
6Content-Type: text/plain; charset=utf-8
7Content-Transfer-Encoding: 8bit
8
9fix warning:
10
11 init/do_mounts_md.c: In function ‘md_run_setup’:
12 init/do_mounts_md.c:282: warning: ISO C90 forbids mixed declarations and code
13
14also, use the opportunity to put the RAID autodetection code
15into a separate function - this also solves a checkpatch style warning.
16
17No code changed:
18
19md5:
20 aa36a35faef371b05f1974ad583bdbbd do_mounts_md.o.before.asm
21 aa36a35faef371b05f1974ad583bdbbd do_mounts_md.o.after.asm
22
23Signed-off-by: Ingo Molnar <mingo@elte.hu>
24---
25 init/do_mounts_md.c | 36 +++++++++++++++++++++---------------
26 1 files changed, 21 insertions(+), 15 deletions(-)
27
28diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
29index 1ec5c41..c0dfd3c 100644
30--- a/init/do_mounts_md.c
31+++ b/init/do_mounts_md.c
32@@ -264,26 +264,32 @@ static int __init raid_setup(char *str)
33 __setup("raid=", raid_setup);
34 __setup("md=", md_setup);
35
36+static void autodetect_raid(void)
37+{
38+ int fd;
39+
40+ /*
41+ * Since we don't want to detect and use half a raid array, we need to
42+ * wait for the known devices to complete their probing
43+ */
44+ printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n");
45+ printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n");
46+ while (driver_probe_done() < 0)
47+ msleep(100);
48+ fd = sys_open("/dev/md0", 0, 0);
49+ if (fd >= 0) {
50+ sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
51+ sys_close(fd);
52+ }
53+}
54+
55 void __init md_run_setup(void)
56 {
57 create_dev("/dev/md0", MKDEV(MD_MAJOR, 0));
58
59 if (raid_noautodetect)
60 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
61- else {
62- /*
63- * Since we don't want to detect and use half a raid array, we need to
64- * wait for the known devices to complete their probing
65- */
66- printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n");
67- printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n");
68- while (driver_probe_done() < 0)
69- msleep(100);
70- int fd = sys_open("/dev/md0", 0, 0);
71- if (fd >= 0) {
72- sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
73- sys_close(fd);
74- }
75- }
76+ else
77+ autodetect_raid();
78 md_setup_drive();
79 }
80--
811.5.4.3
82
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0037-init-initramfs.c-unused-function-when-compiling-wit.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0037-init-initramfs.c-unused-function-when-compiling-wit.patch
new file mode 100644
index 0000000000..159f988670
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0037-init-initramfs.c-unused-function-when-compiling-wit.patch
@@ -0,0 +1,37 @@
1From b4931e6c151acad06b4c12dc7cdb634366d7d27a Mon Sep 17 00:00:00 2001
2From: Steven Noonan <steven@uplinklabs.net>
3Date: Mon, 8 Sep 2008 16:19:10 -0700
4Subject: [PATCH] init/initramfs.c: unused function when compiling without CONFIG_BLK_DEV_RAM
5
6Fixing compiler warning when the kernel isn't compiled with support
7for RAM block devices enabled.
8
9Signed-off-by: Steven Noonan <steven@uplinklabs.net>
10Signed-off-by: Ingo Molnar <mingo@elte.hu>
11---
12 init/initramfs.c | 2 ++
13 1 files changed, 2 insertions(+), 0 deletions(-)
14
15diff --git a/init/initramfs.c b/init/initramfs.c
16index da8d030..2f056e2 100644
17--- a/init/initramfs.c
18+++ b/init/initramfs.c
19@@ -512,6 +512,7 @@ skip:
20 initrd_end = 0;
21 }
22
23+#ifdef CONFIG_BLK_DEV_RAM
24 #define BUF_SIZE 1024
25 static void __init clean_rootfs(void)
26 {
27@@ -558,6 +559,7 @@ static void __init clean_rootfs(void)
28 sys_close(fd);
29 kfree(buf);
30 }
31+#endif
32
33 static int __init populate_rootfs(void)
34 {
35--
361.5.4.3
37
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch
new file mode 100644
index 0000000000..8d1e3f22f1
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch
@@ -0,0 +1,38 @@
1From 5e4f25d1f43991324794657655bbbc43983522a2 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@infradead.org>
3Date: Wed, 10 Sep 2008 08:25:34 -0700
4Subject: [PATCH] fastboot: fix blackfin breakage due to vmlinux.lds change
5
6As reported by Mike Frysinger, the vmlinux.lds changes should
7have used VMLINUX_SYMBOL()...
8
9Reported-by: Mike Frysinger <vapier.adi@gmail.com>
10Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
11Acked-by: Bryan Wu <cooloney@kernel.org>
12Signed-off-by: Ingo Molnar <mingo@elte.hu>
13---
14 include/asm-generic/vmlinux.lds.h | 6 +++---
15 1 files changed, 3 insertions(+), 3 deletions(-)
16
17diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
18index b9be858..ccabc4e 100644
19--- a/include/asm-generic/vmlinux.lds.h
20+++ b/include/asm-generic/vmlinux.lds.h
21@@ -377,11 +377,11 @@
22 *(.initcall5s.init) \
23 *(.initcallrootfs.init) \
24 *(.initcall6s.init) \
25- __async_initcall_start = .; \
26+ VMLINUX_SYMBOL(__async_initcall_start) = .; \
27 *(.initcall6a.init) \
28- __async_initcall_end = .; \
29+ VMLINUX_SYMBOL(__async_initcall_end) = .; \
30 *(.initcall6.init) \
31- __device_initcall_end = .; \
32+ VMLINUX_SYMBOL(__device_initcall_end) = .; \
33 *(.initcall7.init) \
34 *(.initcall7s.init)
35
36--
371.5.4.3
38
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0039-Add-a-script-to-visualize-the-kernel-boot-process.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0039-Add-a-script-to-visualize-the-kernel-boot-process.patch
new file mode 100644
index 0000000000..da72d3bb75
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0039-Add-a-script-to-visualize-the-kernel-boot-process.patch
@@ -0,0 +1,183 @@
1From 77e9695b9d5c9ce761dedc193045d9cb64b8e245 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sat, 13 Sep 2008 09:36:06 -0700
4Subject: [PATCH] Add a script to visualize the kernel boot process / time
5
6When optimizing the kernel boot time, it's very valuable to visualize
7what is going on at which time. In addition, with the fastboot asynchronous
8initcall level, it's very valuable to see which initcall gets run where
9and when.
10
11This patch adds a script to turn a dmesg into a SVG graph (that can be
12shown with tools such as InkScape, Gimp or Firefox) and a small change
13to the initcall code to print the PID of the thread calling the initcall
14(so that the script can work out the parallelism).
15
16Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
17---
18 init/main.c | 3 +-
19 scripts/bootgraph.pl | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++
20 2 files changed, 140 insertions(+), 1 deletions(-)
21 create mode 100644 scripts/bootgraph.pl
22
23diff --git a/init/main.c b/init/main.c
24index a1b95f3..14f2609 100644
25--- a/init/main.c
26+++ b/init/main.c
27@@ -708,7 +708,8 @@ int do_one_initcall(initcall_t fn)
28 int result;
29
30 if (initcall_debug) {
31- print_fn_descriptor_symbol("calling %s\n", fn);
32+ print_fn_descriptor_symbol("calling %s", fn);
33+ printk(" @ %i\n", task_pid_nr(current));
34 t0 = ktime_get();
35 }
36
37diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl
38new file mode 100644
39index 0000000..d459b8b
40--- /dev/null
41+++ b/scripts/bootgraph.pl
42@@ -0,0 +1,138 @@
43+#!/usr/bin/perl
44+
45+# Copyright 2008, Intel Corporation
46+#
47+# This file is part of the Linux kernel
48+#
49+# This program file is free software; you can redistribute it and/or modify it
50+# under the terms of the GNU General Public License as published by the
51+# Free Software Foundation; version 2 of the License.
52+#
53+# This program is distributed in the hope that it will be useful, but WITHOUT
54+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
55+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
56+# for more details.
57+#
58+# You should have received a copy of the GNU General Public License
59+# along with this program in a file named COPYING; if not, write to the
60+# Free Software Foundation, Inc.,
61+# 51 Franklin Street, Fifth Floor,
62+# Boston, MA 02110-1301 USA
63+#
64+# Authors:
65+# Arjan van de Ven <arjan@linux.intel.com>
66+
67+
68+#
69+# This script turns a dmesg output into a SVG graphic that shows which
70+# functions take how much time. You can view SVG graphics with various
71+# programs, including Inkscape, The Gimp and Firefox.
72+#
73+#
74+# For this script to work, the kernel needs to be compiled with the
75+# CONFIG_PRINTK_TIME configuration option enabled, and with
76+# "initcall_debug" passed on the kernel command line.
77+#
78+# usage:
79+# dmesg | perl scripts/bootgraph.pl > output.svg
80+#
81+
82+my @rows;
83+my %start, %end, %row;
84+my $done = 0;
85+my $rowcount = 0;
86+my $maxtime = 0;
87+my $count = 0;
88+while (<>) {
89+ my $line = $_;
90+ if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z\_]+)\+/) {
91+ my $func = $2;
92+ if ($done == 0) {
93+ $start{$func} = $1;
94+ }
95+ $row{$func} = 1;
96+ if ($line =~ /\@ ([0-9]+)/) {
97+ my $pid = $1;
98+ if (!defined($rows[$pid])) {
99+ $rowcount = $rowcount + 1;
100+ $rows[$pid] = $rowcount;
101+ }
102+ $row{$func} = $rows[$pid];
103+ }
104+ $count = $count + 1;
105+ }
106+
107+ if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z\_]+)\+.*returned/) {
108+ if ($done == 0) {
109+ $end{$2} = $1;
110+ $maxtime = $1;
111+ }
112+ }
113+ if ($line =~ /Write protecting the/) {
114+ $done = 1;
115+ }
116+}
117+
118+if ($count == 0) {
119+ print "No data found in the dmesg. Make sure CONFIG_PRINTK_TIME is enabled and\n";
120+ print "that initcall_debug is passed on the kernel command line.\n\n";
121+ print "Usage: \n";
122+ print " dmesg | perl scripts/bootgraph.pl > output.svg\n\n";
123+ exit;
124+}
125+
126+print "<?xml version=\"1.0\" standalone=\"no\"?> \n";
127+print "<svg width=\"1000\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
128+
129+my @styles;
130+
131+$styles[0] = "fill:rgb(0,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
132+$styles[1] = "fill:rgb(0,255,0);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
133+$styles[2] = "fill:rgb(255,0,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
134+$styles[3] = "fill:rgb(255,255,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
135+$styles[4] = "fill:rgb(255,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
136+$styles[5] = "fill:rgb(0,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
137+$styles[6] = "fill:rgb(0,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
138+$styles[7] = "fill:rgb(0,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
139+$styles[8] = "fill:rgb(255,0,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
140+$styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
141+$styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
142+$styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
143+
144+my $mult = 950.0 / $maxtime;
145+my $threshold = 0.0500 / $maxtime;
146+my $stylecounter = 0;
147+while (($key,$value) = each %start) {
148+ my $duration = $end{$key} - $start{$key};
149+
150+ if ($duration >= $threshold) {
151+ my $s, $s2, $e, $y;
152+ $s = $value * $mult;
153+ $s2 = $s + 6;
154+ $e = $end{$key} * $mult;
155+ $w = $e - $s;
156+
157+ $y = $row{$key} * 150;
158+ $y2 = $y + 4;
159+
160+ $style = $styles[$stylecounter];
161+ $stylecounter = $stylecounter + 1;
162+ if ($stylecounter > 11) {
163+ $stylecounter = 0;
164+ };
165+
166+ print "<rect x=\"$s\" width=\"$w\" y=\"$y\" height=\"145\" style=\"$style\"/>\n";
167+ print "<text transform=\"translate($s2,$y2) rotate(90)\">$key</text>\n";
168+ }
169+}
170+
171+
172+# print the time line on top
173+my $time = 0.0;
174+while ($time < $maxtime) {
175+ my $s2 = $time * $mult;
176+ print "<text transform=\"translate($s2,89) rotate(90)\">$time</text>\n";
177+ $time = $time + 0.1;
178+}
179+
180+print "</svg>\n";
181--
1821.5.4.3
183
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch
new file mode 100644
index 0000000000..0daba9d2cf
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch
@@ -0,0 +1,91 @@
1From 5470e09b98074974316bbf98c8b8da01d670c2a4 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 14 Sep 2008 15:30:52 -0700
4Subject: [PATCH] fastboot: fix issues and improve output of bootgraph.pl
5
6David Sanders reported some issues with bootgraph.pl's display
7of his sytems bootup; this commit fixes these by scaling the graph
8not from 0 - end time but from the first initcall to the end time;
9the minimum display size etc also now need to scale with this, as does
10the axis display.
11
12Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
13---
14 scripts/bootgraph.pl | 25 +++++++++++++++++--------
15 1 files changed, 17 insertions(+), 8 deletions(-)
16
17diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl
18index d459b8b..4e5f4ab 100644
19--- a/scripts/bootgraph.pl
20+++ b/scripts/bootgraph.pl
21@@ -42,6 +42,7 @@ my %start, %end, %row;
22 my $done = 0;
23 my $rowcount = 0;
24 my $maxtime = 0;
25+my $firsttime = 100;
26 my $count = 0;
27 while (<>) {
28 my $line = $_;
29@@ -49,6 +50,9 @@ while (<>) {
30 my $func = $2;
31 if ($done == 0) {
32 $start{$func} = $1;
33+ if ($1 < $firsttime) {
34+ $firsttime = $1;
35+ }
36 }
37 $row{$func} = 1;
38 if ($line =~ /\@ ([0-9]+)/) {
39@@ -71,6 +75,9 @@ while (<>) {
40 if ($line =~ /Write protecting the/) {
41 $done = 1;
42 }
43+ if ($line =~ /Freeing unused kernel memory/) {
44+ $done = 1;
45+ }
46 }
47
48 if ($count == 0) {
49@@ -99,17 +106,17 @@ $styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0
50 $styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
51 $styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
52
53-my $mult = 950.0 / $maxtime;
54-my $threshold = 0.0500 / $maxtime;
55+my $mult = 950.0 / ($maxtime - $firsttime);
56+my $threshold = ($maxtime - $firsttime) / 60.0;
57 my $stylecounter = 0;
58 while (($key,$value) = each %start) {
59 my $duration = $end{$key} - $start{$key};
60
61 if ($duration >= $threshold) {
62 my $s, $s2, $e, $y;
63- $s = $value * $mult;
64+ $s = ($value - $firsttime) * $mult;
65 $s2 = $s + 6;
66- $e = $end{$key} * $mult;
67+ $e = ($end{$key} - $firsttime) * $mult;
68 $w = $e - $s;
69
70 $y = $row{$key} * 150;
71@@ -128,11 +135,13 @@ while (($key,$value) = each %start) {
72
73
74 # print the time line on top
75-my $time = 0.0;
76+my $time = $firsttime;
77+my $step = ($maxtime - $firsttime) / 15;
78 while ($time < $maxtime) {
79- my $s2 = $time * $mult;
80- print "<text transform=\"translate($s2,89) rotate(90)\">$time</text>\n";
81- $time = $time + 0.1;
82+ my $s2 = ($time - $firsttime) * $mult;
83+ my $tm = int($time * 100) / 100.0;
84+ print "<text transform=\"translate($s2,89) rotate(90)\">$tm</text>\n";
85+ $time = $time + $step;
86 }
87
88 print "</svg>\n";
89--
901.5.4.3
91
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0041-r8169-8101e.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0041-r8169-8101e.patch
new file mode 100644
index 0000000000..781c9a127e
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0041-r8169-8101e.patch
@@ -0,0 +1,940 @@
1From 771c0d99c0ab3ca7f1a9bc400e8259171b518d5f Mon Sep 17 00:00:00 2001
2From: Francois Romieu <romieu@fr.zoreil.com>
3Date: Thu, 21 Aug 2008 23:20:40 +0200
4Subject: [PATCH] r8169: fix RxMissed register access
5
6- the register location is defined for the 8169 chipset only and
7 there is no 8169 beyond RTL_GIGA_MAC_VER_06
8- only the lower 3 bytes of the register are valid
9
10Fixes:
111. http://bugzilla.kernel.org/show_bug.cgi?id=10180
122. http://bugzilla.kernel.org/show_bug.cgi?id=11062 (bits of)
13
14Tested by Hermann Gausterer and Adam Huffman.
15
16Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
17Cc: Edward Hsu <edward_hsu@realtek.com.tw>
18---
19 drivers/net/r8169.c | 25 ++++++++++++++-----------
20 1 files changed, 14 insertions(+), 11 deletions(-)
21
22diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
23index 0f6f974..4190ee7 100644
24--- a/drivers/net/r8169.c
25+++ b/drivers/net/r8169.c
26@@ -2099,8 +2099,6 @@ static void rtl_hw_start_8168(struct net_device *dev)
27
28 RTL_R8(IntrMask);
29
30- RTL_W32(RxMissed, 0);
31-
32 rtl_set_rx_mode(dev);
33
34 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
35@@ -2143,8 +2141,6 @@ static void rtl_hw_start_8101(struct net_device *dev)
36
37 RTL_R8(IntrMask);
38
39- RTL_W32(RxMissed, 0);
40-
41 rtl_set_rx_mode(dev);
42
43 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
44@@ -2922,6 +2918,17 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
45 return work_done;
46 }
47
48+static void rtl8169_rx_missed(struct net_device *dev, void __iomem *ioaddr)
49+{
50+ struct rtl8169_private *tp = netdev_priv(dev);
51+
52+ if (tp->mac_version > RTL_GIGA_MAC_VER_06)
53+ return;
54+
55+ dev->stats.rx_missed_errors += (RTL_R32(RxMissed) & 0xffffff);
56+ RTL_W32(RxMissed, 0);
57+}
58+
59 static void rtl8169_down(struct net_device *dev)
60 {
61 struct rtl8169_private *tp = netdev_priv(dev);
62@@ -2939,9 +2946,7 @@ core_down:
63
64 rtl8169_asic_down(ioaddr);
65
66- /* Update the error counts. */
67- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
68- RTL_W32(RxMissed, 0);
69+ rtl8169_rx_missed(dev, ioaddr);
70
71 spin_unlock_irq(&tp->lock);
72
73@@ -3063,8 +3068,7 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
74
75 if (netif_running(dev)) {
76 spin_lock_irqsave(&tp->lock, flags);
77- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
78- RTL_W32(RxMissed, 0);
79+ rtl8169_rx_missed(dev, ioaddr);
80 spin_unlock_irqrestore(&tp->lock, flags);
81 }
82
83@@ -3089,8 +3093,7 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
84
85 rtl8169_asic_down(ioaddr);
86
87- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
88- RTL_W32(RxMissed, 0);
89+ rtl8169_rx_missed(dev, ioaddr);
90
91 spin_unlock_irq(&tp->lock);
92
93--
941.5.3.3
95
96From 6ee4bc96d446a9c466a18b715c7ab2d662c03ebd Mon Sep 17 00:00:00 2001
97From: Francois Romieu <romieu@fr.zoreil.com>
98Date: Sat, 26 Jul 2008 14:26:06 +0200
99Subject: [PATCH] r8169: get ethtool settings through the generic mii helper
100
101It avoids to report unsupported link capabilities with
102the fast-ethernet only 8101/8102.
103
104Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
105Tested-by: Martin Capitanio <martin@capitanio.org>
106Fixed-by: Ivan Vecera <ivecera@redhat.com>
107Cc: Edward Hsu <edward_hsu@realtek.com.tw>
108---
109 drivers/net/r8169.c | 99 +++++++++++++++++++++++---------------------------
110 1 files changed, 46 insertions(+), 53 deletions(-)
111
112diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
113index 4190ee7..7e026a6 100644
114--- a/drivers/net/r8169.c
115+++ b/drivers/net/r8169.c
116@@ -370,8 +370,9 @@ struct ring_info {
117 };
118
119 enum features {
120- RTL_FEATURE_WOL = (1 << 0),
121- RTL_FEATURE_MSI = (1 << 1),
122+ RTL_FEATURE_WOL = (1 << 0),
123+ RTL_FEATURE_MSI = (1 << 1),
124+ RTL_FEATURE_GMII = (1 << 2),
125 };
126
127 struct rtl8169_private {
128@@ -406,13 +407,15 @@ struct rtl8169_private {
129 struct vlan_group *vlgrp;
130 #endif
131 int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
132- void (*get_settings)(struct net_device *, struct ethtool_cmd *);
133+ int (*get_settings)(struct net_device *, struct ethtool_cmd *);
134 void (*phy_reset_enable)(void __iomem *);
135 void (*hw_start)(struct net_device *);
136 unsigned int (*phy_reset_pending)(void __iomem *);
137 unsigned int (*link_ok)(void __iomem *);
138 struct delayed_work task;
139 unsigned features;
140+
141+ struct mii_if_info mii;
142 };
143
144 MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
145@@ -482,6 +485,23 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
146 return value;
147 }
148
149+static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
150+ int val)
151+{
152+ struct rtl8169_private *tp = netdev_priv(dev);
153+ void __iomem *ioaddr = tp->mmio_addr;
154+
155+ mdio_write(ioaddr, location, val);
156+}
157+
158+static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
159+{
160+ struct rtl8169_private *tp = netdev_priv(dev);
161+ void __iomem *ioaddr = tp->mmio_addr;
162+
163+ return mdio_read(ioaddr, location);
164+}
165+
166 static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
167 {
168 RTL_W16(IntrMask, 0x0000);
169@@ -850,7 +870,7 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
170
171 #endif
172
173-static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
174+static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
175 {
176 struct rtl8169_private *tp = netdev_priv(dev);
177 void __iomem *ioaddr = tp->mmio_addr;
178@@ -867,65 +887,29 @@ static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
179
180 cmd->speed = SPEED_1000;
181 cmd->duplex = DUPLEX_FULL; /* Always set */
182+
183+ return 0;
184 }
185
186-static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
187+static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
188 {
189 struct rtl8169_private *tp = netdev_priv(dev);
190- void __iomem *ioaddr = tp->mmio_addr;
191- u8 status;
192-
193- cmd->supported = SUPPORTED_10baseT_Half |
194- SUPPORTED_10baseT_Full |
195- SUPPORTED_100baseT_Half |
196- SUPPORTED_100baseT_Full |
197- SUPPORTED_1000baseT_Full |
198- SUPPORTED_Autoneg |
199- SUPPORTED_TP;
200-
201- cmd->autoneg = 1;
202- cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
203-
204- if (tp->phy_auto_nego_reg & ADVERTISE_10HALF)
205- cmd->advertising |= ADVERTISED_10baseT_Half;
206- if (tp->phy_auto_nego_reg & ADVERTISE_10FULL)
207- cmd->advertising |= ADVERTISED_10baseT_Full;
208- if (tp->phy_auto_nego_reg & ADVERTISE_100HALF)
209- cmd->advertising |= ADVERTISED_100baseT_Half;
210- if (tp->phy_auto_nego_reg & ADVERTISE_100FULL)
211- cmd->advertising |= ADVERTISED_100baseT_Full;
212- if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)
213- cmd->advertising |= ADVERTISED_1000baseT_Full;
214-
215- status = RTL_R8(PHYstatus);
216-
217- if (status & _1000bpsF)
218- cmd->speed = SPEED_1000;
219- else if (status & _100bps)
220- cmd->speed = SPEED_100;
221- else if (status & _10bps)
222- cmd->speed = SPEED_10;
223-
224- if (status & TxFlowCtrl)
225- cmd->advertising |= ADVERTISED_Asym_Pause;
226- if (status & RxFlowCtrl)
227- cmd->advertising |= ADVERTISED_Pause;
228-
229- cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
230- DUPLEX_FULL : DUPLEX_HALF;
231+
232+ return mii_ethtool_gset(&tp->mii, cmd);
233 }
234
235 static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
236 {
237 struct rtl8169_private *tp = netdev_priv(dev);
238 unsigned long flags;
239+ int rc;
240
241 spin_lock_irqsave(&tp->lock, flags);
242
243- tp->get_settings(dev, cmd);
244+ rc = tp->get_settings(dev, cmd);
245
246 spin_unlock_irqrestore(&tp->lock, flags);
247- return 0;
248+ return rc;
249 }
250
251 static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
252@@ -1513,7 +1497,7 @@ static const struct rtl_cfg_info {
253 unsigned int align;
254 u16 intr_event;
255 u16 napi_event;
256- unsigned msi;
257+ unsigned features;
258 } rtl_cfg_infos [] = {
259 [RTL_CFG_0] = {
260 .hw_start = rtl_hw_start_8169,
261@@ -1522,7 +1506,7 @@ static const struct rtl_cfg_info {
262 .intr_event = SYSErr | LinkChg | RxOverflow |
263 RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
264 .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
265- .msi = 0
266+ .features = RTL_FEATURE_GMII
267 },
268 [RTL_CFG_1] = {
269 .hw_start = rtl_hw_start_8168,
270@@ -1531,7 +1515,7 @@ static const struct rtl_cfg_info {
271 .intr_event = SYSErr | LinkChg | RxOverflow |
272 TxErr | TxOK | RxOK | RxErr,
273 .napi_event = TxErr | TxOK | RxOK | RxOverflow,
274- .msi = RTL_FEATURE_MSI
275+ .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI
276 },
277 [RTL_CFG_2] = {
278 .hw_start = rtl_hw_start_8101,
279@@ -1540,7 +1524,7 @@ static const struct rtl_cfg_info {
280 .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout |
281 RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
282 .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
283- .msi = RTL_FEATURE_MSI
284+ .features = RTL_FEATURE_MSI
285 }
286 };
287
288@@ -1552,7 +1536,7 @@ static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr,
289 u8 cfg2;
290
291 cfg2 = RTL_R8(Config2) & ~MSIEnable;
292- if (cfg->msi) {
293+ if (cfg->features & RTL_FEATURE_MSI) {
294 if (pci_enable_msi(pdev)) {
295 dev_info(&pdev->dev, "no MSI. Back to INTx.\n");
296 } else {
297@@ -1578,6 +1562,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
298 const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
299 const unsigned int region = cfg->region;
300 struct rtl8169_private *tp;
301+ struct mii_if_info *mii;
302 struct net_device *dev;
303 void __iomem *ioaddr;
304 unsigned int i;
305@@ -1602,6 +1587,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
306 tp->pci_dev = pdev;
307 tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
308
309+ mii = &tp->mii;
310+ mii->dev = dev;
311+ mii->mdio_read = rtl_mdio_read;
312+ mii->mdio_write = rtl_mdio_write;
313+ mii->phy_id_mask = 0x1f;
314+ mii->reg_num_mask = 0x1f;
315+ mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII);
316+
317 /* enable device (incl. PCI PM wakeup and hotplug setup) */
318 rc = pci_enable_device(pdev);
319 if (rc < 0) {
320--
3211.5.3.3
322
323From ef60b2a38e223a331e13ef503aee7cd5d4d5c12c Mon Sep 17 00:00:00 2001
324From: Hugh Dickins <hugh@veritas.com>
325Date: Mon, 8 Sep 2008 21:49:01 +0100
326Subject: [PATCH] r8169: select MII in Kconfig
327
328drivers/built-in.o: In function `rtl8169_gset_xmii':
329r8169.c:(.text+0x82259): undefined reference to `mii_ethtool_gset'
330suggests that the r8169 driver now needs to select MII.
331
332Signed-off-by: Hugh Dickins <hugh@veritas.com>
333Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
334Cc: Edward Hsu <edward_hsu@realtek.com.tw>
335---
336 drivers/net/Kconfig | 1 +
337 1 files changed, 1 insertions(+), 0 deletions(-)
338
339diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
340index 4a11296..60a0453 100644
341--- a/drivers/net/Kconfig
342+++ b/drivers/net/Kconfig
343@@ -2046,6 +2046,7 @@ config R8169
344 tristate "Realtek 8169 gigabit ethernet support"
345 depends on PCI
346 select CRC32
347+ select MII
348 ---help---
349 Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
350
351--
3521.5.3.3
353
354From bca31864fca6004c4a4a9bd549e95c93b3c3bb10 Mon Sep 17 00:00:00 2001
355From: Francois Romieu <romieu@fr.zoreil.com>
356Date: Sat, 2 Aug 2008 15:50:02 +0200
357Subject: [PATCH] r8169: Tx performance tweak helper
358
359Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
360Cc: Edward Hsu <edward_hsu@realtek.com.tw>
361---
362 drivers/net/r8169.c | 15 ++++++++++-----
363 1 files changed, 10 insertions(+), 5 deletions(-)
364
365diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
366index 7e026a6..eea96fb 100644
367--- a/drivers/net/r8169.c
368+++ b/drivers/net/r8169.c
369@@ -2054,12 +2054,20 @@ static void rtl_hw_start_8169(struct net_device *dev)
370 RTL_W16(IntrMask, tp->intr_event);
371 }
372
373+static void rtl_tx_performance_tweak(struct pci_dev *pdev, u8 force)
374+{
375+ u8 ctl;
376+
377+ pci_read_config_byte(pdev, 0x69, &ctl);
378+ ctl = (ctl & ~0x70) | force;
379+ pci_write_config_byte(pdev, 0x69, ctl);
380+}
381+
382 static void rtl_hw_start_8168(struct net_device *dev)
383 {
384 struct rtl8169_private *tp = netdev_priv(dev);
385 void __iomem *ioaddr = tp->mmio_addr;
386 struct pci_dev *pdev = tp->pci_dev;
387- u8 ctl;
388
389 RTL_W8(Cfg9346, Cfg9346_Unlock);
390
391@@ -2073,10 +2081,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
392
393 RTL_W16(CPlusCmd, tp->cp_cmd);
394
395- /* Tx performance tweak. */
396- pci_read_config_byte(pdev, 0x69, &ctl);
397- ctl = (ctl & ~0x70) | 0x50;
398- pci_write_config_byte(pdev, 0x69, ctl);
399+ rtl_tx_performance_tweak(pdev, 0x50);
400
401 RTL_W16(IntrMitigate, 0x5151);
402
403--
4041.5.3.3
405
406From 7a929ae7d5a3618f56bf1ccaf8c62df628e820aa Mon Sep 17 00:00:00 2001
407From: Francois Romieu <romieu@fr.zoreil.com>
408Date: Sat, 5 Jul 2008 00:21:15 +0200
409Subject: [PATCH] r8169: use pci_find_capability for the PCI-E features
410
411Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
412Cc: Edward Hsu <edward_hsu@realtek.com.tw>
413---
414 drivers/net/r8169.c | 32 ++++++++++++++++++++++++--------
415 1 files changed, 24 insertions(+), 8 deletions(-)
416
417diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
418index eea96fb..5c00522 100644
419--- a/drivers/net/r8169.c
420+++ b/drivers/net/r8169.c
421@@ -61,6 +61,7 @@ static const int multicast_filter_limit = 32;
422 /* MAC address length */
423 #define MAC_ADDR_LEN 6
424
425+#define MAX_READ_REQUEST_SHIFT 12
426 #define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */
427 #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
428 #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
429@@ -412,6 +413,7 @@ struct rtl8169_private {
430 void (*hw_start)(struct net_device *);
431 unsigned int (*phy_reset_pending)(void __iomem *);
432 unsigned int (*link_ok)(void __iomem *);
433+ int pcie_cap;
434 struct delayed_work task;
435 unsigned features;
436
437@@ -1663,6 +1665,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
438 goto err_out_free_res_4;
439 }
440
441+ tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
442+ if (!tp->pcie_cap && netif_msg_probe(tp))
443+ dev_info(&pdev->dev, "no PCI Express capability\n");
444+
445 /* Unneeded ? Don't mess with Mrs. Murphy. */
446 rtl8169_irq_mask_and_ack(ioaddr);
447
448@@ -2054,13 +2060,19 @@ static void rtl_hw_start_8169(struct net_device *dev)
449 RTL_W16(IntrMask, tp->intr_event);
450 }
451
452-static void rtl_tx_performance_tweak(struct pci_dev *pdev, u8 force)
453+static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
454 {
455- u8 ctl;
456+ struct net_device *dev = pci_get_drvdata(pdev);
457+ struct rtl8169_private *tp = netdev_priv(dev);
458+ int cap = tp->pcie_cap;
459+
460+ if (cap) {
461+ u16 ctl;
462
463- pci_read_config_byte(pdev, 0x69, &ctl);
464- ctl = (ctl & ~0x70) | force;
465- pci_write_config_byte(pdev, 0x69, ctl);
466+ pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
467+ ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force;
468+ pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
469+ }
470 }
471
472 static void rtl_hw_start_8168(struct net_device *dev)
473@@ -2081,7 +2093,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
474
475 RTL_W16(CPlusCmd, tp->cp_cmd);
476
477- rtl_tx_performance_tweak(pdev, 0x50);
478+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
479
480 RTL_W16(IntrMitigate, 0x5151);
481
482@@ -2114,8 +2126,12 @@ static void rtl_hw_start_8101(struct net_device *dev)
483
484 if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
485 (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
486- pci_write_config_word(pdev, 0x68, 0x00);
487- pci_write_config_word(pdev, 0x69, 0x08);
488+ int cap = tp->pcie_cap;
489+
490+ if (cap) {
491+ pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL,
492+ PCI_EXP_DEVCTL_NOSNOOP_EN);
493+ }
494 }
495
496 RTL_W8(Cfg9346, Cfg9346_Unlock);
497--
4981.5.3.3
499
500From ba648bdcbca93084360d348eb43dde4b19b2489e Mon Sep 17 00:00:00 2001
501From: Francois Romieu <romieu@fr.zoreil.com>
502Date: Sun, 1 Jun 2008 22:37:49 +0200
503Subject: [PATCH] r8169: add 8168/8101 registers description
504
505Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
506Cc: Edward Hsu <edward_hsu@realtek.com.tw>
507---
508 drivers/net/r8169.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
509 1 files changed, 43 insertions(+), 4 deletions(-)
510
511diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
512index 5c00522..0b8db03 100644
513--- a/drivers/net/r8169.c
514+++ b/drivers/net/r8169.c
515@@ -197,9 +197,6 @@ enum rtl_registers {
516 Config5 = 0x56,
517 MultiIntr = 0x5c,
518 PHYAR = 0x60,
519- TBICSR = 0x64,
520- TBI_ANAR = 0x68,
521- TBI_LPAR = 0x6a,
522 PHYstatus = 0x6c,
523 RxMaxSize = 0xda,
524 CPlusCmd = 0xe0,
525@@ -213,6 +210,32 @@ enum rtl_registers {
526 FuncForceEvent = 0xfc,
527 };
528
529+enum rtl8110_registers {
530+ TBICSR = 0x64,
531+ TBI_ANAR = 0x68,
532+ TBI_LPAR = 0x6a,
533+};
534+
535+enum rtl8168_8101_registers {
536+ CSIDR = 0x64,
537+ CSIAR = 0x68,
538+#define CSIAR_FLAG 0x80000000
539+#define CSIAR_WRITE_CMD 0x80000000
540+#define CSIAR_BYTE_ENABLE 0x0f
541+#define CSIAR_BYTE_ENABLE_SHIFT 12
542+#define CSIAR_ADDR_MASK 0x0fff
543+
544+ EPHYAR = 0x80,
545+#define EPHYAR_FLAG 0x80000000
546+#define EPHYAR_WRITE_CMD 0x80000000
547+#define EPHYAR_REG_MASK 0x1f
548+#define EPHYAR_REG_SHIFT 16
549+#define EPHYAR_DATA_MASK 0xffff
550+ DBG_REG = 0xd1,
551+#define FIX_NAK_1 (1 << 4)
552+#define FIX_NAK_2 (1 << 3)
553+};
554+
555 enum rtl_register_content {
556 /* InterruptStatusBits */
557 SYSErr = 0x8000,
558@@ -266,7 +289,13 @@ enum rtl_register_content {
559 TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
560
561 /* Config1 register p.24 */
562+ LEDS1 = (1 << 7),
563+ LEDS0 = (1 << 6),
564 MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */
565+ Speed_down = (1 << 4),
566+ MEMMAP = (1 << 3),
567+ IOMAP = (1 << 2),
568+ VPD = (1 << 1),
569 PMEnable = (1 << 0), /* Power Management Enable */
570
571 /* Config2 register p. 25 */
572@@ -276,6 +305,7 @@ enum rtl_register_content {
573 /* Config3 register p.25 */
574 MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */
575 LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */
576+ Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */
577
578 /* Config5 register p.27 */
579 BWF = (1 << 6), /* Accept Broadcast wakeup frame */
580@@ -293,7 +323,16 @@ enum rtl_register_content {
581 TBINwComplete = 0x01000000,
582
583 /* CPlusCmd p.31 */
584- PktCntrDisable = (1 << 7), // 8168
585+ EnableBist = (1 << 15), // 8168 8101
586+ Mac_dbgo_oe = (1 << 14), // 8168 8101
587+ Normal_mode = (1 << 13), // unused
588+ Force_half_dup = (1 << 12), // 8168 8101
589+ Force_rxflow_en = (1 << 11), // 8168 8101
590+ Force_txflow_en = (1 << 10), // 8168 8101
591+ Cxpl_dbg_sel = (1 << 9), // 8168 8101
592+ ASF = (1 << 8), // 8168 8101
593+ PktCntrDisable = (1 << 7), // 8168 8101
594+ Mac_dbgo_sel = 0x001c, // 8168
595 RxVlan = (1 << 6),
596 RxChkSum = (1 << 5),
597 PCIDAC = (1 << 4),
598--
5991.5.3.3
600
601From 61650c9e3d637b0990d9f26b1421ac4b55f5c744 Mon Sep 17 00:00:00 2001
602From: Francois Romieu <romieu@fr.zoreil.com>
603Date: Sat, 2 Aug 2008 20:44:13 +0200
604Subject: [PATCH] r8169: add hw start helpers for the 8168 and the 8101
605
606This commit triggers three 'defined but not used' warnings but
607I prefer avoiding to tie these helpers to a specific change in
608the hw start sequences of the 8168 or of the 8101.
609
610Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
611Cc: Edward Hsu <edward_hsu@realtek.com.tw>
612---
613 drivers/net/r8169.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++
614 1 files changed, 96 insertions(+), 0 deletions(-)
615
616diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
617index 0b8db03..52eba5c 100644
618--- a/drivers/net/r8169.c
619+++ b/drivers/net/r8169.c
620@@ -526,6 +526,11 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
621 return value;
622 }
623
624+static void mdio_patch(void __iomem *ioaddr, int reg_addr, int value)
625+{
626+ mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value);
627+}
628+
629 static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
630 int val)
631 {
632@@ -543,6 +548,72 @@ static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
633 return mdio_read(ioaddr, location);
634 }
635
636+static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value)
637+{
638+ unsigned int i;
639+
640+ RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
641+ (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
642+
643+ for (i = 0; i < 100; i++) {
644+ if (!(RTL_R32(EPHYAR) & EPHYAR_FLAG))
645+ break;
646+ udelay(10);
647+ }
648+}
649+
650+static u16 rtl_ephy_read(void __iomem *ioaddr, int reg_addr)
651+{
652+ u16 value = 0xffff;
653+ unsigned int i;
654+
655+ RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
656+
657+ for (i = 0; i < 100; i++) {
658+ if (RTL_R32(EPHYAR) & EPHYAR_FLAG) {
659+ value = RTL_R32(EPHYAR) & EPHYAR_DATA_MASK;
660+ break;
661+ }
662+ udelay(10);
663+ }
664+
665+ return value;
666+}
667+
668+static void rtl_csi_write(void __iomem *ioaddr, int addr, int value)
669+{
670+ unsigned int i;
671+
672+ RTL_W32(CSIDR, value);
673+ RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
674+ CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
675+
676+ for (i = 0; i < 100; i++) {
677+ if (!(RTL_R32(CSIAR) & CSIAR_FLAG))
678+ break;
679+ udelay(10);
680+ }
681+}
682+
683+static u32 rtl_csi_read(void __iomem *ioaddr, int addr)
684+{
685+ u32 value = ~0x00;
686+ unsigned int i;
687+
688+ RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) |
689+ CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
690+
691+ for (i = 0; i < 100; i++) {
692+ if (RTL_R32(CSIAR) & CSIAR_FLAG) {
693+ value = RTL_R32(CSIDR);
694+ break;
695+ }
696+ udelay(10);
697+ }
698+
699+ return value;
700+}
701+
702 static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
703 {
704 RTL_W16(IntrMask, 0x0000);
705@@ -2114,6 +2185,31 @@ static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
706 }
707 }
708
709+static void rtl_csi_access_enable(void __iomem *ioaddr)
710+{
711+ u32 csi;
712+
713+ csi = rtl_csi_read(ioaddr, 0x070c) & 0x00ffffff;
714+ rtl_csi_write(ioaddr, 0x070c, csi | 0x27000000);
715+}
716+
717+struct ephy_info {
718+ unsigned int offset;
719+ u16 mask;
720+ u16 bits;
721+};
722+
723+static void rtl_ephy_init(void __iomem *ioaddr, struct ephy_info *e, int len)
724+{
725+ u16 w;
726+
727+ while (len-- > 0) {
728+ w = (rtl_ephy_read(ioaddr, e->offset) & ~e->mask) | e->bits;
729+ rtl_ephy_write(ioaddr, e->offset, w);
730+ e++;
731+ }
732+}
733+
734 static void rtl_hw_start_8168(struct net_device *dev)
735 {
736 struct rtl8169_private *tp = netdev_priv(dev);
737--
7381.5.3.3
739
740From 81fbfc404f2a13646bee46fa98545c0023e3a67a Mon Sep 17 00:00:00 2001
741From: Francois Romieu <romieu@fr.zoreil.com>
742Date: Sat, 2 Aug 2008 21:08:49 +0200
743Subject: [PATCH] r8169: additional 8101 and 8102 support
744
745Signed-off-by: Ivan Vecera <ivecera@redhat.com>
746Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
747Cc: Edward Hsu <edward_hsu@realtek.com.tw>
748---
749 drivers/net/r8169.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++-
750 1 files changed, 122 insertions(+), 2 deletions(-)
751
752diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
753index 52eba5c..f28c202 100644
754--- a/drivers/net/r8169.c
755+++ b/drivers/net/r8169.c
756@@ -96,6 +96,10 @@ enum mac_version {
757 RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
758 RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
759 RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
760+ RTL_GIGA_MAC_VER_07 = 0x07, // 8102e
761+ RTL_GIGA_MAC_VER_08 = 0x08, // 8102e
762+ RTL_GIGA_MAC_VER_09 = 0x09, // 8102e
763+ RTL_GIGA_MAC_VER_10 = 0x0a, // 8101e
764 RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
765 RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be
766 RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb
767@@ -122,6 +126,10 @@ static const struct {
768 _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
769 _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
770 _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe
771+ _R("RTL8102e", RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E
772+ _R("RTL8102e", RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E
773+ _R("RTL8102e", RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E
774+ _R("RTL8101e", RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E
775 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
776 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
777 _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
778@@ -837,8 +845,12 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
779 }
780 }
781
782- /* The 8100e/8101e do Fast Ethernet only. */
783- if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
784+ /* The 8100e/8101e/8102e do Fast Ethernet only. */
785+ if ((tp->mac_version == RTL_GIGA_MAC_VER_07) ||
786+ (tp->mac_version == RTL_GIGA_MAC_VER_08) ||
787+ (tp->mac_version == RTL_GIGA_MAC_VER_09) ||
788+ (tp->mac_version == RTL_GIGA_MAC_VER_10) ||
789+ (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
790 (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
791 (tp->mac_version == RTL_GIGA_MAC_VER_15) ||
792 (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
793@@ -1212,8 +1224,17 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
794 { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 },
795
796 /* 8101 family. */
797+ { 0x7cf00000, 0x34a00000, RTL_GIGA_MAC_VER_09 },
798+ { 0x7cf00000, 0x24a00000, RTL_GIGA_MAC_VER_09 },
799+ { 0x7cf00000, 0x34900000, RTL_GIGA_MAC_VER_08 },
800+ { 0x7cf00000, 0x24900000, RTL_GIGA_MAC_VER_08 },
801+ { 0x7cf00000, 0x34800000, RTL_GIGA_MAC_VER_07 },
802+ { 0x7cf00000, 0x24800000, RTL_GIGA_MAC_VER_07 },
803 { 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 },
804+ { 0x7cf00000, 0x34300000, RTL_GIGA_MAC_VER_10 },
805 { 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 },
806+ { 0x7c800000, 0x34800000, RTL_GIGA_MAC_VER_09 },
807+ { 0x7c800000, 0x24800000, RTL_GIGA_MAC_VER_09 },
808 { 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 },
809 /* FIXME: where did these entries come from ? -- FR */
810 { 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 },
811@@ -1375,6 +1396,22 @@ static void rtl8168cx_hw_phy_config(void __iomem *ioaddr)
812 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
813 }
814
815+static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
816+{
817+ struct phy_reg phy_reg_init[] = {
818+ { 0x1f, 0x0003 },
819+ { 0x08, 0x441d },
820+ { 0x01, 0x9100 },
821+ { 0x1f, 0x0000 }
822+ };
823+
824+ mdio_write(ioaddr, 0x1f, 0x0000);
825+ mdio_patch(ioaddr, 0x11, 1 << 12);
826+ mdio_patch(ioaddr, 0x19, 1 << 13);
827+
828+ rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
829+}
830+
831 static void rtl_hw_phy_config(struct net_device *dev)
832 {
833 struct rtl8169_private *tp = netdev_priv(dev);
834@@ -1392,6 +1429,11 @@ static void rtl_hw_phy_config(struct net_device *dev)
835 case RTL_GIGA_MAC_VER_04:
836 rtl8169sb_hw_phy_config(ioaddr);
837 break;
838+ case RTL_GIGA_MAC_VER_07:
839+ case RTL_GIGA_MAC_VER_08:
840+ case RTL_GIGA_MAC_VER_09:
841+ rtl8102e_hw_phy_config(ioaddr);
842+ break;
843 case RTL_GIGA_MAC_VER_18:
844 rtl8168cp_hw_phy_config(ioaddr);
845 break;
846@@ -2253,6 +2295,70 @@ static void rtl_hw_start_8168(struct net_device *dev)
847 RTL_W16(IntrMask, tp->intr_event);
848 }
849
850+#define R810X_CPCMD_QUIRK_MASK (\
851+ EnableBist | \
852+ Mac_dbgo_oe | \
853+ Force_half_dup | \
854+ Force_half_dup | \
855+ Force_txflow_en | \
856+ Cxpl_dbg_sel | \
857+ ASF | \
858+ PktCntrDisable | \
859+ PCIDAC | \
860+ PCIMulRW)
861+
862+static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev)
863+{
864+ static struct ephy_info e_info_8102e_1[] = {
865+ { 0x01, 0, 0x6e65 },
866+ { 0x02, 0, 0x091f },
867+ { 0x03, 0, 0xc2f9 },
868+ { 0x06, 0, 0xafb5 },
869+ { 0x07, 0, 0x0e00 },
870+ { 0x19, 0, 0xec80 },
871+ { 0x01, 0, 0x2e65 },
872+ { 0x01, 0, 0x6e65 }
873+ };
874+ u8 cfg1;
875+
876+ rtl_csi_access_enable(ioaddr);
877+
878+ RTL_W8(DBG_REG, FIX_NAK_1);
879+
880+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
881+
882+ RTL_W8(Config1,
883+ LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable);
884+ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
885+
886+ cfg1 = RTL_R8(Config1);
887+ if ((cfg1 & LEDS0) && (cfg1 & LEDS1))
888+ RTL_W8(Config1, cfg1 & ~LEDS0);
889+
890+ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);
891+
892+ rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1));
893+}
894+
895+static void rtl_hw_start_8102e_2(void __iomem *ioaddr, struct pci_dev *pdev)
896+{
897+ rtl_csi_access_enable(ioaddr);
898+
899+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
900+
901+ RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable);
902+ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
903+
904+ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);
905+}
906+
907+static void rtl_hw_start_8102e_3(void __iomem *ioaddr, struct pci_dev *pdev)
908+{
909+ rtl_hw_start_8102e_2(ioaddr, pdev);
910+
911+ rtl_ephy_write(ioaddr, 0x03, 0xc2f9);
912+}
913+
914 static void rtl_hw_start_8101(struct net_device *dev)
915 {
916 struct rtl8169_private *tp = netdev_priv(dev);
917@@ -2269,6 +2375,20 @@ static void rtl_hw_start_8101(struct net_device *dev)
918 }
919 }
920
921+ switch (tp->mac_version) {
922+ case RTL_GIGA_MAC_VER_07:
923+ rtl_hw_start_8102e_1(ioaddr, pdev);
924+ break;
925+
926+ case RTL_GIGA_MAC_VER_08:
927+ rtl_hw_start_8102e_3(ioaddr, pdev);
928+ break;
929+
930+ case RTL_GIGA_MAC_VER_09:
931+ rtl_hw_start_8102e_2(ioaddr, pdev);
932+ break;
933+ }
934+
935 RTL_W8(Cfg9346, Cfg9346_Unlock);
936
937 RTL_W8(EarlyTxThres, EarlyTxThld);
938--
9391.5.3.3
940
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0042-intelfb-945gme.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0042-intelfb-945gme.patch
new file mode 100644
index 0000000000..15ebe56328
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0042-intelfb-945gme.patch
@@ -0,0 +1,153 @@
1The following patch adds support for Intel's 945GME graphics chip to
2the intelfb driver. I have assumed that the 945GME is identical to the
3already-supported 945GM apart from its PCI IDs; this is based on a quick
4look at the X driver for these chips which seems to treat them
5identically.
6
7Signed-off-by: Phil Endecott <spam_from_intelfb@chezphil.org>
8
9---
10
11The 945GME is used in the ASUS Eee 901, and I coded this in the hope that
12I'd be able to use it to get a console at the native 1024x600 resolution
13which is not known to the BIOS. I realised too late that the intelfb
14driver does not support mode changing on laptops, so it won't be any
15use for me. But rather than throw it away I will post it here as
16essentially "untested"; maybe someone who knows more about this driver,
17and with more useful hardware to test on, can pick it up.
18
19diff --git a/Documentation/fb/intelfb.txt b/Documentation/fb/intelfb.txt
20index 27a3160..dd9e944 100644
21--- a/Documentation/fb/intelfb.txt
22+++ b/Documentation/fb/intelfb.txt
23@@ -14,6 +14,7 @@ graphics devices. These would include:
24 Intel 915GM
25 Intel 945G
26 Intel 945GM
27+ Intel 945GME
28 Intel 965G
29 Intel 965GM
30
31diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
32index 3325fbd..a50bea6 100644
33--- a/drivers/video/intelfb/intelfb.h
34+++ b/drivers/video/intelfb/intelfb.h
35@@ -12,9 +12,9 @@
36 #endif
37
38 /*** Version/name ***/
39-#define INTELFB_VERSION "0.9.5"
40+#define INTELFB_VERSION "0.9.6"
41 #define INTELFB_MODULE_NAME "intelfb"
42-#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM"
43+#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/945GME/965G/965GM"
44
45
46 /*** Debug/feature defines ***/
47@@ -58,6 +58,7 @@
48 #define PCI_DEVICE_ID_INTEL_915GM 0x2592
49 #define PCI_DEVICE_ID_INTEL_945G 0x2772
50 #define PCI_DEVICE_ID_INTEL_945GM 0x27A2
51+#define PCI_DEVICE_ID_INTEL_945GME 0x27AE
52 #define PCI_DEVICE_ID_INTEL_965G 0x29A2
53 #define PCI_DEVICE_ID_INTEL_965GM 0x2A02
54
55@@ -160,6 +161,7 @@ enum intel_chips {
56 INTEL_915GM,
57 INTEL_945G,
58 INTEL_945GM,
59+ INTEL_945GME,
60 INTEL_965G,
61 INTEL_965GM,
62 };
63@@ -363,6 +365,7 @@ struct intelfb_info {
64 ((dinfo)->chipset == INTEL_915GM) || \
65 ((dinfo)->chipset == INTEL_945G) || \
66 ((dinfo)->chipset == INTEL_945GM) || \
67+ ((dinfo)->chipset == INTEL_945GME) || \
68 ((dinfo)->chipset == INTEL_965G) || \
69 ((dinfo)->chipset == INTEL_965GM))
70
71diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
72index fcf9fad..5d896b8 100644
73--- a/drivers/video/intelfb/intelfb_i2c.c
74+++ b/drivers/video/intelfb/intelfb_i2c.c
75@@ -171,6 +171,7 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
76 /* has some LVDS + tv-out */
77 case INTEL_945G:
78 case INTEL_945GM:
79+ case INTEL_945GME:
80 case INTEL_965G:
81 case INTEL_965GM:
82 /* SDVO ports have a single control bus - 2 devices */
83diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
84index e44303f..a09e236 100644
85--- a/drivers/video/intelfb/intelfbdrv.c
86+++ b/drivers/video/intelfb/intelfbdrv.c
87@@ -2,7 +2,7 @@
88 * intelfb
89 *
90 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/
91- * 945G/945GM/965G/965GM integrated graphics chips.
92+ * 945G/945GM/945GME/965G/965GM integrated graphics chips.
93 *
94 * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
95 * 2004 Sylvain Meyer
96@@ -102,6 +102,9 @@
97 *
98 * 04/2008 - Version 0.9.5
99 * Add support for 965G/965GM. (Maik Broemme <mbroemme@plusserver.de>)
100+ *
101+ * 08/2008 - Version 0.9.6
102+ * Add support for 945GME. (Phil Endecott <spam_from_intelfb@chezphil.org>)
103 */
104
105 #include <linux/module.h>
106@@ -183,6 +186,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = {
107 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
108 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G },
109 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM },
110+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GME, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GME },
111 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965G },
112 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965GM },
113 { 0, }
114@@ -555,6 +559,7 @@ static int __devinit intelfb_pci_register(struct pci_dev *pdev,
115 (ent->device == PCI_DEVICE_ID_INTEL_915GM) ||
116 (ent->device == PCI_DEVICE_ID_INTEL_945G) ||
117 (ent->device == PCI_DEVICE_ID_INTEL_945GM) ||
118+ (ent->device == PCI_DEVICE_ID_INTEL_945GME) ||
119 (ent->device == PCI_DEVICE_ID_INTEL_965G) ||
120 (ent->device == PCI_DEVICE_ID_INTEL_965GM)) {
121
122diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
123index 8e6d6a4..8b26b27 100644
124--- a/drivers/video/intelfb/intelfbhw.c
125+++ b/drivers/video/intelfb/intelfbhw.c
126@@ -143,6 +143,12 @@ int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
127 dinfo->mobile = 1;
128 dinfo->pll_index = PLLS_I9xx;
129 return 0;
130+ case PCI_DEVICE_ID_INTEL_945GME:
131+ dinfo->name = "Intel(R) 945GME";
132+ dinfo->chipset = INTEL_945GME;
133+ dinfo->mobile = 1;
134+ dinfo->pll_index = PLLS_I9xx;
135+ return 0;
136 case PCI_DEVICE_ID_INTEL_965G:
137 dinfo->name = "Intel(R) 965G";
138 dinfo->chipset = INTEL_965G;
139@@ -186,6 +192,7 @@ int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
140 case PCI_DEVICE_ID_INTEL_915GM:
141 case PCI_DEVICE_ID_INTEL_945G:
142 case PCI_DEVICE_ID_INTEL_945GM:
143+ case PCI_DEVICE_ID_INTEL_945GME:
144 case PCI_DEVICE_ID_INTEL_965G:
145 case PCI_DEVICE_ID_INTEL_965GM:
146 /* 915, 945 and 965 chipsets support a 256MB aperture.
147
148
149--
150To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
151the body of a message to majordomo@vger.kernel.org
152More majordomo info at http://vger.kernel.org/majordomo-info.html
153Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/defconfig-eee901 b/meta/packages/linux/linux-moblin-2.6.27-rc6/defconfig-eee901
new file mode 100644
index 0000000000..02c1a32f8a
--- /dev/null
+++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/defconfig-eee901
@@ -0,0 +1,2407 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.27-rc6
4# Thu Oct 9 14:48:08 2008
5#
6# CONFIG_64BIT is not set
7CONFIG_X86_32=y
8# CONFIG_X86_64 is not set
9CONFIG_X86=y
10CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
11# CONFIG_GENERIC_LOCKBREAK is not set
12CONFIG_GENERIC_TIME=y
13CONFIG_GENERIC_CMOS_UPDATE=y
14CONFIG_CLOCKSOURCE_WATCHDOG=y
15CONFIG_GENERIC_CLOCKEVENTS=y
16CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
17CONFIG_LOCKDEP_SUPPORT=y
18CONFIG_STACKTRACE_SUPPORT=y
19CONFIG_HAVE_LATENCYTOP_SUPPORT=y
20CONFIG_FAST_CMPXCHG_LOCAL=y
21CONFIG_MMU=y
22CONFIG_ZONE_DMA=y
23CONFIG_GENERIC_ISA_DMA=y
24CONFIG_GENERIC_IOMAP=y
25CONFIG_GENERIC_BUG=y
26CONFIG_GENERIC_HWEIGHT=y
27# CONFIG_GENERIC_GPIO is not set
28CONFIG_ARCH_MAY_HAVE_PC_FDC=y
29# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
30CONFIG_RWSEM_XCHGADD_ALGORITHM=y
31# CONFIG_ARCH_HAS_ILOG2_U32 is not set
32# CONFIG_ARCH_HAS_ILOG2_U64 is not set
33CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
34CONFIG_GENERIC_CALIBRATE_DELAY=y
35# CONFIG_GENERIC_TIME_VSYSCALL is not set
36CONFIG_ARCH_HAS_CPU_RELAX=y
37CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
38CONFIG_HAVE_SETUP_PER_CPU_AREA=y
39# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
40CONFIG_ARCH_HIBERNATION_POSSIBLE=y
41CONFIG_ARCH_SUSPEND_POSSIBLE=y
42# CONFIG_ZONE_DMA32 is not set
43CONFIG_ARCH_POPULATES_NODE_MAP=y
44# CONFIG_AUDIT_ARCH is not set
45CONFIG_ARCH_SUPPORTS_AOUT=y
46CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
47CONFIG_GENERIC_HARDIRQS=y
48CONFIG_GENERIC_IRQ_PROBE=y
49CONFIG_GENERIC_PENDING_IRQ=y
50CONFIG_X86_SMP=y
51CONFIG_X86_32_SMP=y
52CONFIG_X86_HT=y
53CONFIG_X86_BIOS_REBOOT=y
54CONFIG_X86_TRAMPOLINE=y
55CONFIG_KTIME_SCALAR=y
56CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
57
58#
59# General setup
60#
61CONFIG_EXPERIMENTAL=y
62CONFIG_LOCK_KERNEL=y
63CONFIG_INIT_ENV_ARG_LIMIT=32
64CONFIG_LOCALVERSION="-eee901"
65# CONFIG_LOCALVERSION_AUTO is not set
66CONFIG_SWAP=y
67CONFIG_SYSVIPC=y
68CONFIG_SYSVIPC_SYSCTL=y
69CONFIG_POSIX_MQUEUE=y
70CONFIG_BSD_PROCESS_ACCT=y
71CONFIG_BSD_PROCESS_ACCT_V3=y
72CONFIG_TASKSTATS=y
73CONFIG_TASK_DELAY_ACCT=y
74CONFIG_TASK_XACCT=y
75CONFIG_TASK_IO_ACCOUNTING=y
76CONFIG_AUDIT=y
77CONFIG_AUDITSYSCALL=y
78CONFIG_AUDIT_TREE=y
79CONFIG_IKCONFIG=y
80CONFIG_IKCONFIG_PROC=y
81CONFIG_LOG_BUF_SHIFT=17
82# CONFIG_CGROUPS is not set
83CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
84# CONFIG_GROUP_SCHED is not set
85# CONFIG_SYSFS_DEPRECATED_V2 is not set
86CONFIG_RELAY=y
87CONFIG_NAMESPACES=y
88# CONFIG_UTS_NS is not set
89# CONFIG_IPC_NS is not set
90CONFIG_USER_NS=y
91# CONFIG_PID_NS is not set
92CONFIG_BLK_DEV_INITRD=y
93CONFIG_INITRAMFS_SOURCE=""
94CONFIG_CC_OPTIMIZE_FOR_SIZE=y
95CONFIG_FASTBOOT=y
96CONFIG_SYSCTL=y
97# CONFIG_EMBEDDED is not set
98CONFIG_UID16=y
99CONFIG_SYSCTL_SYSCALL=y
100CONFIG_KALLSYMS=y
101CONFIG_KALLSYMS_ALL=y
102CONFIG_KALLSYMS_EXTRA_PASS=y
103CONFIG_HOTPLUG=y
104CONFIG_PRINTK=y
105CONFIG_BUG=y
106CONFIG_ELF_CORE=y
107CONFIG_PCSPKR_PLATFORM=y
108# CONFIG_COMPAT_BRK is not set
109CONFIG_BASE_FULL=y
110CONFIG_FUTEX=y
111CONFIG_ANON_INODES=y
112CONFIG_EPOLL=y
113CONFIG_SIGNALFD=y
114CONFIG_TIMERFD=y
115CONFIG_EVENTFD=y
116CONFIG_SHMEM=y
117CONFIG_VM_EVENT_COUNTERS=y
118CONFIG_SLAB=y
119# CONFIG_SLUB is not set
120# CONFIG_SLOB is not set
121CONFIG_PROFILING=y
122# CONFIG_MARKERS is not set
123# CONFIG_OPROFILE is not set
124CONFIG_HAVE_OPROFILE=y
125# CONFIG_KPROBES is not set
126CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
127CONFIG_HAVE_IOREMAP_PROT=y
128CONFIG_HAVE_KPROBES=y
129CONFIG_HAVE_KRETPROBES=y
130# CONFIG_HAVE_ARCH_TRACEHOOK is not set
131# CONFIG_HAVE_DMA_ATTRS is not set
132CONFIG_USE_GENERIC_SMP_HELPERS=y
133# CONFIG_HAVE_CLK is not set
134CONFIG_PROC_PAGE_MONITOR=y
135CONFIG_HAVE_GENERIC_DMA_COHERENT=y
136CONFIG_SLABINFO=y
137CONFIG_RT_MUTEXES=y
138# CONFIG_TINY_SHMEM is not set
139CONFIG_BASE_SMALL=0
140CONFIG_MODULES=y
141# CONFIG_MODULE_FORCE_LOAD is not set
142CONFIG_MODULE_UNLOAD=y
143# CONFIG_MODULE_FORCE_UNLOAD is not set
144# CONFIG_MODVERSIONS is not set
145# CONFIG_MODULE_SRCVERSION_ALL is not set
146CONFIG_KMOD=y
147CONFIG_STOP_MACHINE=y
148CONFIG_BLOCK=y
149# CONFIG_LBD is not set
150CONFIG_BLK_DEV_IO_TRACE=y
151# CONFIG_LSF is not set
152CONFIG_BLK_DEV_BSG=y
153# CONFIG_BLK_DEV_INTEGRITY is not set
154
155#
156# IO Schedulers
157#
158CONFIG_IOSCHED_NOOP=y
159# CONFIG_IOSCHED_AS is not set
160# CONFIG_IOSCHED_DEADLINE is not set
161CONFIG_IOSCHED_CFQ=y
162# CONFIG_DEFAULT_AS is not set
163# CONFIG_DEFAULT_DEADLINE is not set
164CONFIG_DEFAULT_CFQ=y
165# CONFIG_DEFAULT_NOOP is not set
166CONFIG_DEFAULT_IOSCHED="cfq"
167CONFIG_CLASSIC_RCU=y
168
169#
170# Processor type and features
171#
172CONFIG_TICK_ONESHOT=y
173CONFIG_NO_HZ=y
174CONFIG_HIGH_RES_TIMERS=y
175CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
176CONFIG_SMP=y
177CONFIG_X86_FIND_SMP_CONFIG=y
178CONFIG_X86_MPPARSE=y
179CONFIG_X86_PC=y
180# CONFIG_X86_ELAN is not set
181# CONFIG_X86_VOYAGER is not set
182# CONFIG_X86_GENERICARCH is not set
183# CONFIG_X86_VSMP is not set
184# CONFIG_X86_RDC321X is not set
185CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
186# CONFIG_PARAVIRT_GUEST is not set
187# CONFIG_MEMTEST is not set
188# CONFIG_M386 is not set
189# CONFIG_M486 is not set
190# CONFIG_M586 is not set
191# CONFIG_M586TSC is not set
192# CONFIG_M586MMX is not set
193CONFIG_M686=y
194# CONFIG_MPENTIUMII is not set
195# CONFIG_MPENTIUMIII is not set
196# CONFIG_MPENTIUMM is not set
197# CONFIG_MPENTIUM4 is not set
198# CONFIG_MK6 is not set
199# CONFIG_MK7 is not set
200# CONFIG_MK8 is not set
201# CONFIG_MCRUSOE is not set
202# CONFIG_MEFFICEON is not set
203# CONFIG_MWINCHIPC6 is not set
204# CONFIG_MWINCHIP2 is not set
205# CONFIG_MWINCHIP3D is not set
206# CONFIG_MGEODEGX1 is not set
207# CONFIG_MGEODE_LX is not set
208# CONFIG_MCYRIXIII is not set
209# CONFIG_MVIAC3_2 is not set
210# CONFIG_MVIAC7 is not set
211# CONFIG_MPSC is not set
212# CONFIG_MCORE2 is not set
213# CONFIG_GENERIC_CPU is not set
214# CONFIG_X86_GENERIC is not set
215CONFIG_X86_CPU=y
216CONFIG_X86_CMPXCHG=y
217CONFIG_X86_L1_CACHE_SHIFT=5
218CONFIG_X86_XADD=y
219# CONFIG_X86_PPRO_FENCE is not set
220CONFIG_X86_WP_WORKS_OK=y
221CONFIG_X86_INVLPG=y
222CONFIG_X86_BSWAP=y
223CONFIG_X86_POPAD_OK=y
224CONFIG_X86_USE_PPRO_CHECKSUM=y
225CONFIG_X86_TSC=y
226CONFIG_X86_CMOV=y
227CONFIG_X86_MINIMUM_CPU_FAMILY=4
228CONFIG_X86_DEBUGCTLMSR=y
229CONFIG_HPET_TIMER=y
230CONFIG_HPET_EMULATE_RTC=y
231CONFIG_DMI=y
232# CONFIG_IOMMU_HELPER is not set
233CONFIG_NR_CPUS=2
234CONFIG_SCHED_SMT=y
235CONFIG_SCHED_MC=y
236# CONFIG_PREEMPT_NONE is not set
237CONFIG_PREEMPT_VOLUNTARY=y
238# CONFIG_PREEMPT is not set
239CONFIG_X86_LOCAL_APIC=y
240CONFIG_X86_IO_APIC=y
241CONFIG_X86_MCE=y
242# CONFIG_X86_MCE_NONFATAL is not set
243# CONFIG_X86_MCE_P4THERMAL is not set
244CONFIG_VM86=y
245# CONFIG_TOSHIBA is not set
246# CONFIG_I8K is not set
247# CONFIG_X86_REBOOTFIXUPS is not set
248CONFIG_MICROCODE=y
249CONFIG_MICROCODE_OLD_INTERFACE=y
250CONFIG_X86_MSR=y
251CONFIG_X86_CPUID=y
252# CONFIG_NOHIGHMEM is not set
253CONFIG_HIGHMEM4G=y
254# CONFIG_HIGHMEM64G is not set
255CONFIG_PAGE_OFFSET=0xC0000000
256CONFIG_HIGHMEM=y
257CONFIG_NEED_NODE_MEMMAP_SIZE=y
258CONFIG_ARCH_FLATMEM_ENABLE=y
259CONFIG_ARCH_SPARSEMEM_ENABLE=y
260CONFIG_ARCH_SELECT_MEMORY_MODEL=y
261CONFIG_SELECT_MEMORY_MODEL=y
262# CONFIG_FLATMEM_MANUAL is not set
263# CONFIG_DISCONTIGMEM_MANUAL is not set
264CONFIG_SPARSEMEM_MANUAL=y
265CONFIG_SPARSEMEM=y
266CONFIG_HAVE_MEMORY_PRESENT=y
267CONFIG_SPARSEMEM_STATIC=y
268# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
269
270#
271# Memory hotplug is currently incompatible with Software Suspend
272#
273CONFIG_PAGEFLAGS_EXTENDED=y
274CONFIG_SPLIT_PTLOCK_CPUS=4
275CONFIG_RESOURCES_64BIT=y
276CONFIG_ZONE_DMA_FLAG=1
277CONFIG_BOUNCE=y
278CONFIG_VIRT_TO_BUS=y
279# CONFIG_HIGHPTE is not set
280# CONFIG_MATH_EMULATION is not set
281CONFIG_MTRR=y
282# CONFIG_MTRR_SANITIZER is not set
283# CONFIG_X86_PAT is not set
284# CONFIG_EFI is not set
285# CONFIG_IRQBALANCE is not set
286# CONFIG_SECCOMP is not set
287# CONFIG_HZ_100 is not set
288# CONFIG_HZ_250 is not set
289# CONFIG_HZ_300 is not set
290CONFIG_HZ_1000=y
291CONFIG_HZ=1000
292CONFIG_SCHED_HRTICK=y
293CONFIG_KEXEC=y
294CONFIG_CRASH_DUMP=y
295# CONFIG_KEXEC_JUMP is not set
296CONFIG_PHYSICAL_START=0x400000
297CONFIG_RELOCATABLE=y
298CONFIG_PHYSICAL_ALIGN=0x200000
299CONFIG_HOTPLUG_CPU=y
300CONFIG_COMPAT_VDSO=y
301CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
302
303#
304# Power management options
305#
306CONFIG_PM=y
307CONFIG_PM_DEBUG=y
308# CONFIG_PM_VERBOSE is not set
309CONFIG_CAN_PM_TRACE=y
310CONFIG_PM_TRACE=y
311CONFIG_PM_TRACE_RTC=y
312CONFIG_PM_SLEEP_SMP=y
313CONFIG_PM_SLEEP=y
314CONFIG_SUSPEND=y
315# CONFIG_PM_TEST_SUSPEND is not set
316CONFIG_SUSPEND_FREEZER=y
317CONFIG_HIBERNATION=y
318CONFIG_PM_STD_PARTITION=""
319CONFIG_ACPI=y
320CONFIG_ACPI_SLEEP=y
321CONFIG_ACPI_PROCFS=y
322CONFIG_ACPI_PROCFS_POWER=y
323CONFIG_ACPI_SYSFS_POWER=y
324CONFIG_ACPI_PROC_EVENT=y
325CONFIG_ACPI_AC=y
326CONFIG_ACPI_BATTERY=m
327CONFIG_ACPI_BUTTON=y
328CONFIG_ACPI_VIDEO=y
329CONFIG_ACPI_FAN=y
330CONFIG_ACPI_DOCK=y
331# CONFIG_ACPI_BAY is not set
332CONFIG_ACPI_PROCESSOR=y
333CONFIG_ACPI_HOTPLUG_CPU=y
334CONFIG_ACPI_THERMAL=y
335CONFIG_ACPI_WMI=m
336CONFIG_ACPI_ASUS=y
337# CONFIG_ACPI_TOSHIBA is not set
338# CONFIG_ACPI_CUSTOM_DSDT is not set
339CONFIG_ACPI_BLACKLIST_YEAR=0
340# CONFIG_ACPI_DEBUG is not set
341CONFIG_ACPI_EC=y
342# CONFIG_ACPI_PCI_SLOT is not set
343CONFIG_ACPI_POWER=y
344CONFIG_ACPI_SYSTEM=y
345CONFIG_X86_PM_TIMER=y
346CONFIG_ACPI_CONTAINER=y
347CONFIG_ACPI_SBS=m
348# CONFIG_APM is not set
349
350#
351# CPU Frequency scaling
352#
353CONFIG_CPU_FREQ=y
354CONFIG_CPU_FREQ_TABLE=y
355CONFIG_CPU_FREQ_DEBUG=y
356CONFIG_CPU_FREQ_STAT=m
357CONFIG_CPU_FREQ_STAT_DETAILS=y
358CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
359# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
360# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
361# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
362# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
363CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
364# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
365CONFIG_CPU_FREQ_GOV_USERSPACE=y
366CONFIG_CPU_FREQ_GOV_ONDEMAND=y
367# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
368
369#
370# CPUFreq processor drivers
371#
372CONFIG_X86_ACPI_CPUFREQ=y
373# CONFIG_X86_POWERNOW_K6 is not set
374# CONFIG_X86_POWERNOW_K7 is not set
375# CONFIG_X86_POWERNOW_K8 is not set
376# CONFIG_X86_GX_SUSPMOD is not set
377# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
378# CONFIG_X86_SPEEDSTEP_ICH is not set
379# CONFIG_X86_SPEEDSTEP_SMI is not set
380# CONFIG_X86_P4_CLOCKMOD is not set
381# CONFIG_X86_CPUFREQ_NFORCE2 is not set
382# CONFIG_X86_LONGRUN is not set
383# CONFIG_X86_LONGHAUL is not set
384# CONFIG_X86_E_POWERSAVER is not set
385
386#
387# shared options
388#
389# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
390# CONFIG_X86_SPEEDSTEP_LIB is not set
391CONFIG_CPU_IDLE=y
392CONFIG_CPU_IDLE_GOV_LADDER=y
393CONFIG_CPU_IDLE_GOV_MENU=y
394
395#
396# Bus options (PCI etc.)
397#
398CONFIG_PCI=y
399# CONFIG_PCI_GOBIOS is not set
400# CONFIG_PCI_GOMMCONFIG is not set
401# CONFIG_PCI_GODIRECT is not set
402# CONFIG_PCI_GOOLPC is not set
403CONFIG_PCI_GOANY=y
404CONFIG_PCI_BIOS=y
405CONFIG_PCI_DIRECT=y
406CONFIG_PCI_MMCONFIG=y
407CONFIG_PCI_DOMAINS=y
408CONFIG_PCIEPORTBUS=y
409CONFIG_PCIEAER=y
410CONFIG_PCIEASPM=y
411# CONFIG_PCIEASPM_DEBUG is not set
412CONFIG_ARCH_SUPPORTS_MSI=y
413CONFIG_PCI_MSI=y
414CONFIG_PCI_LEGACY=y
415# CONFIG_PCI_DEBUG is not set
416CONFIG_HT_IRQ=y
417CONFIG_ISA_DMA_API=y
418# CONFIG_ISA is not set
419# CONFIG_MCA is not set
420# CONFIG_SCx200 is not set
421# CONFIG_OLPC is not set
422CONFIG_K8_NB=y
423# CONFIG_PCCARD is not set
424# CONFIG_HOTPLUG_PCI is not set
425
426#
427# Executable file formats / Emulations
428#
429CONFIG_BINFMT_ELF=y
430# CONFIG_BINFMT_AOUT is not set
431CONFIG_BINFMT_MISC=y
432CONFIG_NET=y
433
434#
435# Networking options
436#
437CONFIG_PACKET=y
438CONFIG_PACKET_MMAP=y
439CONFIG_UNIX=y
440CONFIG_XFRM=y
441CONFIG_XFRM_USER=y
442CONFIG_XFRM_SUB_POLICY=y
443CONFIG_XFRM_MIGRATE=y
444CONFIG_XFRM_STATISTICS=y
445CONFIG_XFRM_IPCOMP=m
446CONFIG_NET_KEY=m
447CONFIG_NET_KEY_MIGRATE=y
448CONFIG_INET=y
449CONFIG_IP_MULTICAST=y
450# CONFIG_IP_ADVANCED_ROUTER is not set
451CONFIG_IP_FIB_HASH=y
452# CONFIG_IP_PNP is not set
453# CONFIG_NET_IPIP is not set
454# CONFIG_NET_IPGRE is not set
455CONFIG_IP_MROUTE=y
456CONFIG_IP_PIMSM_V1=y
457CONFIG_IP_PIMSM_V2=y
458# CONFIG_ARPD is not set
459CONFIG_SYN_COOKIES=y
460CONFIG_INET_AH=m
461CONFIG_INET_ESP=m
462CONFIG_INET_IPCOMP=m
463CONFIG_INET_XFRM_TUNNEL=m
464CONFIG_INET_TUNNEL=m
465CONFIG_INET_XFRM_MODE_TRANSPORT=m
466CONFIG_INET_XFRM_MODE_TUNNEL=m
467CONFIG_INET_XFRM_MODE_BEET=m
468CONFIG_INET_LRO=y
469CONFIG_INET_DIAG=m
470CONFIG_INET_TCP_DIAG=m
471CONFIG_TCP_CONG_ADVANCED=y
472CONFIG_TCP_CONG_BIC=m
473CONFIG_TCP_CONG_CUBIC=y
474# CONFIG_TCP_CONG_WESTWOOD is not set
475# CONFIG_TCP_CONG_HTCP is not set
476# CONFIG_TCP_CONG_HSTCP is not set
477# CONFIG_TCP_CONG_HYBLA is not set
478# CONFIG_TCP_CONG_VEGAS is not set
479# CONFIG_TCP_CONG_SCALABLE is not set
480# CONFIG_TCP_CONG_LP is not set
481# CONFIG_TCP_CONG_VENO is not set
482# CONFIG_TCP_CONG_YEAH is not set
483# CONFIG_TCP_CONG_ILLINOIS is not set
484# CONFIG_DEFAULT_BIC is not set
485CONFIG_DEFAULT_CUBIC=y
486# CONFIG_DEFAULT_HTCP is not set
487# CONFIG_DEFAULT_VEGAS is not set
488# CONFIG_DEFAULT_WESTWOOD is not set
489# CONFIG_DEFAULT_RENO is not set
490CONFIG_DEFAULT_TCP_CONG="cubic"
491CONFIG_TCP_MD5SIG=y
492# CONFIG_IP_VS is not set
493CONFIG_IPV6=y
494CONFIG_IPV6_PRIVACY=y
495CONFIG_IPV6_ROUTER_PREF=y
496CONFIG_IPV6_ROUTE_INFO=y
497CONFIG_IPV6_OPTIMISTIC_DAD=y
498CONFIG_INET6_AH=m
499CONFIG_INET6_ESP=m
500CONFIG_INET6_IPCOMP=m
501CONFIG_IPV6_MIP6=m
502CONFIG_INET6_XFRM_TUNNEL=m
503CONFIG_INET6_TUNNEL=m
504CONFIG_INET6_XFRM_MODE_TRANSPORT=m
505CONFIG_INET6_XFRM_MODE_TUNNEL=m
506CONFIG_INET6_XFRM_MODE_BEET=m
507CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
508CONFIG_IPV6_SIT=m
509CONFIG_IPV6_NDISC_NODETYPE=y
510CONFIG_IPV6_TUNNEL=m
511CONFIG_IPV6_MULTIPLE_TABLES=y
512CONFIG_IPV6_SUBTREES=y
513# CONFIG_IPV6_MROUTE is not set
514CONFIG_NETLABEL=y
515CONFIG_NETWORK_SECMARK=y
516CONFIG_NETFILTER=y
517# CONFIG_NETFILTER_DEBUG is not set
518CONFIG_NETFILTER_ADVANCED=y
519
520#
521# Core Netfilter Configuration
522#
523CONFIG_NETFILTER_NETLINK=m
524CONFIG_NETFILTER_NETLINK_QUEUE=m
525CONFIG_NETFILTER_NETLINK_LOG=m
526CONFIG_NF_CONNTRACK=y
527CONFIG_NF_CT_ACCT=y
528CONFIG_NF_CONNTRACK_MARK=y
529CONFIG_NF_CONNTRACK_SECMARK=y
530CONFIG_NF_CONNTRACK_EVENTS=y
531# CONFIG_NF_CT_PROTO_DCCP is not set
532CONFIG_NF_CT_PROTO_GRE=m
533CONFIG_NF_CT_PROTO_SCTP=m
534CONFIG_NF_CT_PROTO_UDPLITE=m
535CONFIG_NF_CONNTRACK_AMANDA=m
536CONFIG_NF_CONNTRACK_FTP=m
537CONFIG_NF_CONNTRACK_H323=m
538CONFIG_NF_CONNTRACK_IRC=m
539CONFIG_NF_CONNTRACK_NETBIOS_NS=m
540CONFIG_NF_CONNTRACK_PPTP=m
541CONFIG_NF_CONNTRACK_SANE=m
542CONFIG_NF_CONNTRACK_SIP=m
543CONFIG_NF_CONNTRACK_TFTP=m
544CONFIG_NF_CT_NETLINK=m
545CONFIG_NETFILTER_XTABLES=y
546CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
547CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
548CONFIG_NETFILTER_XT_TARGET_DSCP=m
549CONFIG_NETFILTER_XT_TARGET_MARK=m
550CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
551CONFIG_NETFILTER_XT_TARGET_NFLOG=m
552CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
553CONFIG_NETFILTER_XT_TARGET_RATEEST=m
554CONFIG_NETFILTER_XT_TARGET_TRACE=m
555CONFIG_NETFILTER_XT_TARGET_SECMARK=m
556CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
557CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
558CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
559CONFIG_NETFILTER_XT_MATCH_COMMENT=m
560CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
561CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
562CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
563CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
564# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
565CONFIG_NETFILTER_XT_MATCH_DSCP=m
566CONFIG_NETFILTER_XT_MATCH_ESP=m
567CONFIG_NETFILTER_XT_MATCH_HELPER=m
568CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
569CONFIG_NETFILTER_XT_MATCH_LENGTH=m
570CONFIG_NETFILTER_XT_MATCH_LIMIT=m
571CONFIG_NETFILTER_XT_MATCH_MAC=m
572CONFIG_NETFILTER_XT_MATCH_MARK=m
573CONFIG_NETFILTER_XT_MATCH_OWNER=m
574CONFIG_NETFILTER_XT_MATCH_POLICY=m
575CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
576CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
577CONFIG_NETFILTER_XT_MATCH_QUOTA=m
578CONFIG_NETFILTER_XT_MATCH_RATEEST=m
579CONFIG_NETFILTER_XT_MATCH_REALM=m
580CONFIG_NETFILTER_XT_MATCH_SCTP=m
581CONFIG_NETFILTER_XT_MATCH_STATE=y
582CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
583CONFIG_NETFILTER_XT_MATCH_STRING=m
584CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
585CONFIG_NETFILTER_XT_MATCH_TIME=m
586CONFIG_NETFILTER_XT_MATCH_U32=m
587CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
588
589#
590# IP: Netfilter Configuration
591#
592CONFIG_NF_CONNTRACK_IPV4=y
593# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
594CONFIG_IP_NF_QUEUE=m
595CONFIG_IP_NF_IPTABLES=y
596CONFIG_IP_NF_MATCH_RECENT=m
597CONFIG_IP_NF_MATCH_ECN=m
598CONFIG_IP_NF_MATCH_AH=m
599CONFIG_IP_NF_MATCH_TTL=m
600CONFIG_IP_NF_MATCH_ADDRTYPE=m
601CONFIG_IP_NF_FILTER=y
602CONFIG_IP_NF_TARGET_REJECT=y
603CONFIG_IP_NF_TARGET_LOG=m
604CONFIG_IP_NF_TARGET_ULOG=m
605CONFIG_NF_NAT=m
606CONFIG_NF_NAT_NEEDED=y
607CONFIG_IP_NF_TARGET_MASQUERADE=m
608CONFIG_IP_NF_TARGET_REDIRECT=m
609CONFIG_IP_NF_TARGET_NETMAP=m
610CONFIG_NF_NAT_SNMP_BASIC=m
611CONFIG_NF_NAT_PROTO_GRE=m
612CONFIG_NF_NAT_PROTO_UDPLITE=m
613CONFIG_NF_NAT_PROTO_SCTP=m
614CONFIG_NF_NAT_FTP=m
615CONFIG_NF_NAT_IRC=m
616CONFIG_NF_NAT_TFTP=m
617CONFIG_NF_NAT_AMANDA=m
618CONFIG_NF_NAT_PPTP=m
619CONFIG_NF_NAT_H323=m
620CONFIG_NF_NAT_SIP=m
621CONFIG_IP_NF_MANGLE=m
622CONFIG_IP_NF_TARGET_ECN=m
623CONFIG_IP_NF_TARGET_TTL=m
624CONFIG_IP_NF_TARGET_CLUSTERIP=m
625CONFIG_IP_NF_RAW=m
626# CONFIG_IP_NF_SECURITY is not set
627CONFIG_IP_NF_ARPTABLES=m
628CONFIG_IP_NF_ARPFILTER=m
629CONFIG_IP_NF_ARP_MANGLE=m
630
631#
632# IPv6: Netfilter Configuration
633#
634CONFIG_NF_CONNTRACK_IPV6=y
635CONFIG_IP6_NF_QUEUE=m
636CONFIG_IP6_NF_IPTABLES=y
637CONFIG_IP6_NF_MATCH_RT=m
638CONFIG_IP6_NF_MATCH_OPTS=m
639CONFIG_IP6_NF_MATCH_FRAG=m
640CONFIG_IP6_NF_MATCH_HL=m
641CONFIG_IP6_NF_MATCH_IPV6HEADER=m
642CONFIG_IP6_NF_MATCH_AH=m
643CONFIG_IP6_NF_MATCH_MH=m
644CONFIG_IP6_NF_MATCH_EUI64=m
645CONFIG_IP6_NF_FILTER=y
646CONFIG_IP6_NF_TARGET_LOG=m
647CONFIG_IP6_NF_TARGET_REJECT=y
648CONFIG_IP6_NF_MANGLE=m
649CONFIG_IP6_NF_TARGET_HL=m
650CONFIG_IP6_NF_RAW=m
651# CONFIG_IP6_NF_SECURITY is not set
652# CONFIG_IP_DCCP is not set
653# CONFIG_IP_SCTP is not set
654# CONFIG_TIPC is not set
655# CONFIG_ATM is not set
656# CONFIG_BRIDGE is not set
657# CONFIG_VLAN_8021Q is not set
658# CONFIG_DECNET is not set
659# CONFIG_LLC2 is not set
660# CONFIG_IPX is not set
661# CONFIG_ATALK is not set
662# CONFIG_X25 is not set
663# CONFIG_LAPB is not set
664# CONFIG_ECONET is not set
665# CONFIG_WAN_ROUTER is not set
666# CONFIG_NET_SCHED is not set
667CONFIG_NET_CLS_ROUTE=y
668
669#
670# Network testing
671#
672# CONFIG_NET_PKTGEN is not set
673# CONFIG_HAMRADIO is not set
674# CONFIG_CAN is not set
675# CONFIG_IRDA is not set
676CONFIG_BT=m
677CONFIG_BT_L2CAP=m
678CONFIG_BT_SCO=m
679CONFIG_BT_RFCOMM=m
680CONFIG_BT_RFCOMM_TTY=y
681CONFIG_BT_BNEP=m
682# CONFIG_BT_BNEP_MC_FILTER is not set
683# CONFIG_BT_BNEP_PROTO_FILTER is not set
684# CONFIG_BT_HIDP is not set
685
686#
687# Bluetooth device drivers
688#
689CONFIG_BT_HCIUSB=m
690CONFIG_BT_HCIUSB_SCO=y
691# CONFIG_BT_HCIBTUSB is not set
692CONFIG_BT_HCIBTSDIO=m
693CONFIG_BT_HCIUART=m
694CONFIG_BT_HCIUART_H4=y
695CONFIG_BT_HCIUART_BCSP=y
696CONFIG_BT_HCIUART_LL=y
697CONFIG_BT_HCIBCM203X=m
698CONFIG_BT_HCIBPA10X=m
699CONFIG_BT_HCIBFUSB=m
700CONFIG_BT_HCIVHCI=m
701# CONFIG_AF_RXRPC is not set
702CONFIG_FIB_RULES=y
703
704#
705# Wireless
706#
707CONFIG_CFG80211=m
708CONFIG_NL80211=y
709CONFIG_WIRELESS_EXT=y
710# CONFIG_WIRELESS_EXT_SYSFS is not set
711CONFIG_MAC80211=m
712
713#
714# Rate control algorithm selection
715#
716CONFIG_MAC80211_RC_PID=y
717CONFIG_MAC80211_RC_DEFAULT_PID=y
718CONFIG_MAC80211_RC_DEFAULT="pid"
719CONFIG_MAC80211_MESH=y
720CONFIG_MAC80211_LEDS=y
721CONFIG_MAC80211_DEBUGFS=y
722# CONFIG_MAC80211_DEBUG_MENU is not set
723CONFIG_IEEE80211=m
724# CONFIG_IEEE80211_DEBUG is not set
725CONFIG_IEEE80211_CRYPT_WEP=m
726CONFIG_IEEE80211_CRYPT_CCMP=m
727CONFIG_IEEE80211_CRYPT_TKIP=m
728CONFIG_RFKILL=m
729CONFIG_RFKILL_INPUT=m
730CONFIG_RFKILL_LEDS=y
731# CONFIG_NET_9P is not set
732
733#
734# Device Drivers
735#
736
737#
738# Generic Driver Options
739#
740CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
741CONFIG_STANDALONE=y
742CONFIG_PREVENT_FIRMWARE_BUILD=y
743CONFIG_FW_LOADER=y
744CONFIG_FIRMWARE_IN_KERNEL=y
745CONFIG_EXTRA_FIRMWARE=""
746# CONFIG_DEBUG_DRIVER is not set
747CONFIG_DEBUG_DEVRES=y
748# CONFIG_SYS_HYPERVISOR is not set
749CONFIG_CONNECTOR=y
750CONFIG_PROC_EVENTS=y
751# CONFIG_MTD is not set
752# CONFIG_PARPORT is not set
753CONFIG_PNP=y
754# CONFIG_PNP_DEBUG is not set
755
756#
757# Protocols
758#
759CONFIG_PNPACPI=y
760CONFIG_BLK_DEV=y
761# CONFIG_BLK_DEV_FD is not set
762# CONFIG_BLK_CPQ_DA is not set
763# CONFIG_BLK_CPQ_CISS_DA is not set
764# CONFIG_BLK_DEV_DAC960 is not set
765# CONFIG_BLK_DEV_UMEM is not set
766# CONFIG_BLK_DEV_COW_COMMON is not set
767CONFIG_BLK_DEV_LOOP=y
768CONFIG_BLK_DEV_CRYPTOLOOP=m
769# CONFIG_BLK_DEV_NBD is not set
770# CONFIG_BLK_DEV_SX8 is not set
771# CONFIG_BLK_DEV_UB is not set
772CONFIG_BLK_DEV_RAM=y
773CONFIG_BLK_DEV_RAM_COUNT=16
774CONFIG_BLK_DEV_RAM_SIZE=262144
775# CONFIG_BLK_DEV_XIP is not set
776CONFIG_CDROM_PKTCDVD=m
777CONFIG_CDROM_PKTCDVD_BUFFERS=8
778# CONFIG_CDROM_PKTCDVD_WCACHE is not set
779# CONFIG_ATA_OVER_ETH is not set
780# CONFIG_BLK_DEV_HD is not set
781CONFIG_MISC_DEVICES=y
782# CONFIG_IBM_ASM is not set
783# CONFIG_PHANTOM is not set
784CONFIG_EEPROM_93CX6=m
785# CONFIG_SGI_IOC4 is not set
786CONFIG_TIFM_CORE=m
787CONFIG_TIFM_7XX1=m
788# CONFIG_ACER_WMI is not set
789# CONFIG_FUJITSU_LAPTOP is not set
790# CONFIG_TC1100_WMI is not set
791# CONFIG_HP_WMI is not set
792# CONFIG_MSI_LAPTOP is not set
793# CONFIG_COMPAL_LAPTOP is not set
794# CONFIG_SONY_LAPTOP is not set
795# CONFIG_THINKPAD_ACPI is not set
796# CONFIG_INTEL_MENLOW is not set
797CONFIG_EEEPC_LAPTOP=y
798# CONFIG_ENCLOSURE_SERVICES is not set
799# CONFIG_HP_ILO is not set
800CONFIG_HAVE_IDE=y
801# CONFIG_IDE is not set
802
803#
804# SCSI device support
805#
806CONFIG_RAID_ATTRS=m
807CONFIG_SCSI=y
808CONFIG_SCSI_DMA=y
809# CONFIG_SCSI_TGT is not set
810# CONFIG_SCSI_NETLINK is not set
811CONFIG_SCSI_PROC_FS=y
812
813#
814# SCSI support type (disk, tape, CD-ROM)
815#
816CONFIG_BLK_DEV_SD=y
817CONFIG_CHR_DEV_ST=m
818# CONFIG_CHR_DEV_OSST is not set
819CONFIG_BLK_DEV_SR=y
820CONFIG_BLK_DEV_SR_VENDOR=y
821# CONFIG_CHR_DEV_SG is not set
822CONFIG_CHR_DEV_SCH=m
823
824#
825# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
826#
827CONFIG_SCSI_MULTI_LUN=y
828CONFIG_SCSI_CONSTANTS=y
829CONFIG_SCSI_LOGGING=y
830CONFIG_SCSI_SCAN_ASYNC=y
831CONFIG_SCSI_WAIT_SCAN=m
832
833#
834# SCSI Transports
835#
836# CONFIG_SCSI_SPI_ATTRS is not set
837# CONFIG_SCSI_FC_ATTRS is not set
838# CONFIG_SCSI_ISCSI_ATTRS is not set
839# CONFIG_SCSI_SAS_ATTRS is not set
840# CONFIG_SCSI_SAS_LIBSAS is not set
841# CONFIG_SCSI_SRP_ATTRS is not set
842CONFIG_SCSI_LOWLEVEL=y
843# CONFIG_ISCSI_TCP is not set
844# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
845# CONFIG_SCSI_3W_9XXX is not set
846# CONFIG_SCSI_ACARD is not set
847# CONFIG_SCSI_AACRAID is not set
848# CONFIG_SCSI_AIC7XXX is not set
849# CONFIG_SCSI_AIC7XXX_OLD is not set
850# CONFIG_SCSI_AIC79XX is not set
851# CONFIG_SCSI_AIC94XX is not set
852# CONFIG_SCSI_DPT_I2O is not set
853# CONFIG_SCSI_ADVANSYS is not set
854# CONFIG_SCSI_ARCMSR is not set
855# CONFIG_MEGARAID_NEWGEN is not set
856# CONFIG_MEGARAID_LEGACY is not set
857# CONFIG_MEGARAID_SAS is not set
858# CONFIG_SCSI_HPTIOP is not set
859# CONFIG_SCSI_BUSLOGIC is not set
860# CONFIG_SCSI_DMX3191D is not set
861# CONFIG_SCSI_EATA is not set
862# CONFIG_SCSI_FUTURE_DOMAIN is not set
863# CONFIG_SCSI_GDTH is not set
864# CONFIG_SCSI_IPS is not set
865# CONFIG_SCSI_INITIO is not set
866# CONFIG_SCSI_INIA100 is not set
867# CONFIG_SCSI_MVSAS is not set
868# CONFIG_SCSI_STEX is not set
869# CONFIG_SCSI_SYM53C8XX_2 is not set
870# CONFIG_SCSI_IPR is not set
871# CONFIG_SCSI_QLOGIC_1280 is not set
872# CONFIG_SCSI_QLA_FC is not set
873# CONFIG_SCSI_QLA_ISCSI is not set
874# CONFIG_SCSI_LPFC is not set
875# CONFIG_SCSI_DC395x is not set
876# CONFIG_SCSI_DC390T is not set
877# CONFIG_SCSI_NSP32 is not set
878# CONFIG_SCSI_DEBUG is not set
879# CONFIG_SCSI_SRP is not set
880# CONFIG_SCSI_DH is not set
881CONFIG_ATA=y
882# CONFIG_ATA_NONSTANDARD is not set
883CONFIG_ATA_ACPI=y
884# CONFIG_SATA_PMP is not set
885CONFIG_SATA_AHCI=y
886# CONFIG_SATA_SIL24 is not set
887CONFIG_ATA_SFF=y
888# CONFIG_SATA_SVW is not set
889CONFIG_ATA_PIIX=y
890# CONFIG_SATA_MV is not set
891# CONFIG_SATA_NV is not set
892# CONFIG_PDC_ADMA is not set
893# CONFIG_SATA_QSTOR is not set
894# CONFIG_SATA_PROMISE is not set
895# CONFIG_SATA_SX4 is not set
896# CONFIG_SATA_SIL is not set
897# CONFIG_SATA_SIS is not set
898# CONFIG_SATA_ULI is not set
899# CONFIG_SATA_VIA is not set
900# CONFIG_SATA_VITESSE is not set
901# CONFIG_SATA_INIC162X is not set
902# CONFIG_PATA_ACPI is not set
903# CONFIG_PATA_ALI is not set
904# CONFIG_PATA_AMD is not set
905# CONFIG_PATA_ARTOP is not set
906# CONFIG_PATA_ATIIXP is not set
907# CONFIG_PATA_CMD640_PCI is not set
908# CONFIG_PATA_CMD64X is not set
909# CONFIG_PATA_CS5520 is not set
910# CONFIG_PATA_CS5530 is not set
911# CONFIG_PATA_CS5535 is not set
912# CONFIG_PATA_CS5536 is not set
913# CONFIG_PATA_CYPRESS is not set
914# CONFIG_PATA_EFAR is not set
915# CONFIG_ATA_GENERIC is not set
916# CONFIG_PATA_HPT366 is not set
917# CONFIG_PATA_HPT37X is not set
918# CONFIG_PATA_HPT3X2N is not set
919# CONFIG_PATA_HPT3X3 is not set
920# CONFIG_PATA_IT821X is not set
921# CONFIG_PATA_IT8213 is not set
922# CONFIG_PATA_JMICRON is not set
923# CONFIG_PATA_TRIFLEX is not set
924# CONFIG_PATA_MARVELL is not set
925# CONFIG_PATA_MPIIX is not set
926# CONFIG_PATA_OLDPIIX is not set
927# CONFIG_PATA_NETCELL is not set
928# CONFIG_PATA_NINJA32 is not set
929# CONFIG_PATA_NS87410 is not set
930# CONFIG_PATA_NS87415 is not set
931# CONFIG_PATA_OPTI is not set
932# CONFIG_PATA_OPTIDMA is not set
933# CONFIG_PATA_PDC_OLD is not set
934# CONFIG_PATA_RADISYS is not set
935# CONFIG_PATA_RZ1000 is not set
936# CONFIG_PATA_SC1200 is not set
937# CONFIG_PATA_SERVERWORKS is not set
938# CONFIG_PATA_PDC2027X is not set
939# CONFIG_PATA_SIL680 is not set
940# CONFIG_PATA_SIS is not set
941# CONFIG_PATA_VIA is not set
942# CONFIG_PATA_WINBOND is not set
943CONFIG_PATA_SCH=y
944# CONFIG_MD is not set
945# CONFIG_FUSION is not set
946
947#
948# IEEE 1394 (FireWire) support
949#
950
951#
952# Enable only one of the two stacks, unless you know what you are doing
953#
954# CONFIG_FIREWIRE is not set
955# CONFIG_IEEE1394 is not set
956# CONFIG_I2O is not set
957# CONFIG_MACINTOSH_DRIVERS is not set
958CONFIG_NETDEVICES=y
959# CONFIG_DUMMY is not set
960# CONFIG_BONDING is not set
961CONFIG_MACVLAN=m
962# CONFIG_EQUALIZER is not set
963# CONFIG_TUN is not set
964# CONFIG_VETH is not set
965# CONFIG_NET_SB1000 is not set
966# CONFIG_ARCNET is not set
967CONFIG_PHYLIB=m
968
969#
970# MII PHY device drivers
971#
972CONFIG_MARVELL_PHY=m
973CONFIG_DAVICOM_PHY=m
974CONFIG_QSEMI_PHY=m
975CONFIG_LXT_PHY=m
976CONFIG_CICADA_PHY=m
977CONFIG_VITESSE_PHY=m
978CONFIG_SMSC_PHY=m
979CONFIG_BROADCOM_PHY=m
980CONFIG_ICPLUS_PHY=m
981CONFIG_REALTEK_PHY=m
982CONFIG_MDIO_BITBANG=m
983CONFIG_NET_ETHERNET=y
984CONFIG_MII=m
985CONFIG_HAPPYMEAL=m
986CONFIG_SUNGEM=m
987CONFIG_CASSINI=m
988CONFIG_NET_VENDOR_3COM=y
989# CONFIG_VORTEX is not set
990# CONFIG_TYPHOON is not set
991# CONFIG_NET_TULIP is not set
992# CONFIG_HP100 is not set
993# CONFIG_IBM_NEW_EMAC_ZMII is not set
994# CONFIG_IBM_NEW_EMAC_RGMII is not set
995# CONFIG_IBM_NEW_EMAC_TAH is not set
996# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
997# CONFIG_NET_PCI is not set
998# CONFIG_B44 is not set
999CONFIG_NETDEV_1000=y
1000# CONFIG_ACENIC is not set
1001# CONFIG_DL2K is not set
1002# CONFIG_E1000 is not set
1003# CONFIG_E1000E is not set
1004# CONFIG_IP1000 is not set
1005# CONFIG_IGB is not set
1006# CONFIG_NS83820 is not set
1007# CONFIG_HAMACHI is not set
1008# CONFIG_YELLOWFIN is not set
1009# CONFIG_R8169 is not set
1010# CONFIG_SIS190 is not set
1011# CONFIG_SKGE is not set
1012# CONFIG_SKY2 is not set
1013# CONFIG_VIA_VELOCITY is not set
1014# CONFIG_TIGON3 is not set
1015# CONFIG_BNX2 is not set
1016# CONFIG_QLA3XXX is not set
1017CONFIG_ATL1=m
1018CONFIG_ATL1E=m
1019# CONFIG_NETDEV_10000 is not set
1020# CONFIG_TR is not set
1021
1022#
1023# Wireless LAN
1024#
1025CONFIG_WLAN_PRE80211=y
1026# CONFIG_STRIP is not set
1027CONFIG_WLAN_80211=y
1028# CONFIG_IPW2100 is not set
1029# CONFIG_IPW2200 is not set
1030# CONFIG_LIBERTAS is not set
1031# CONFIG_AIRO is not set
1032# CONFIG_HERMES is not set
1033# CONFIG_ATMEL is not set
1034# CONFIG_PRISM54 is not set
1035CONFIG_USB_ZD1201=m
1036CONFIG_USB_NET_RNDIS_WLAN=m
1037CONFIG_RTL8180=m
1038CONFIG_RTL8187=m
1039# CONFIG_ADM8211 is not set
1040# CONFIG_MAC80211_HWSIM is not set
1041# CONFIG_P54_COMMON is not set
1042CONFIG_ATH5K=m
1043# CONFIG_ATH5K_DEBUG is not set
1044# CONFIG_ATH9K is not set
1045CONFIG_IWLWIFI=m
1046CONFIG_IWLCORE=m
1047# CONFIG_IWLWIFI_LEDS is not set
1048CONFIG_IWLWIFI_RFKILL=y
1049# CONFIG_IWLWIFI_DEBUG is not set
1050# CONFIG_IWLAGN is not set
1051CONFIG_IWL3945=m
1052CONFIG_IWL3945_RFKILL=y
1053# CONFIG_IWL3945_SPECTRUM_MEASUREMENT is not set
1054# CONFIG_IWL3945_LEDS is not set
1055# CONFIG_IWL3945_DEBUG is not set
1056# CONFIG_HOSTAP is not set
1057# CONFIG_B43 is not set
1058# CONFIG_B43LEGACY is not set
1059# CONFIG_ZD1211RW is not set
1060CONFIG_RT2X00=m
1061CONFIG_RT2X00_LIB=m
1062CONFIG_RT2X00_LIB_PCI=m
1063CONFIG_RT2X00_LIB_USB=m
1064CONFIG_RT2X00_LIB_FIRMWARE=y
1065CONFIG_RT2X00_LIB_RFKILL=y
1066CONFIG_RT2X00_LIB_LEDS=y
1067CONFIG_RT2400PCI=m
1068CONFIG_RT2400PCI_RFKILL=y
1069CONFIG_RT2400PCI_LEDS=y
1070CONFIG_RT2500PCI=m
1071CONFIG_RT2500PCI_RFKILL=y
1072CONFIG_RT2500PCI_LEDS=y
1073CONFIG_RT61PCI=m
1074CONFIG_RT61PCI_RFKILL=y
1075CONFIG_RT61PCI_LEDS=y
1076CONFIG_RT2500USB=m
1077CONFIG_RT2500USB_LEDS=y
1078CONFIG_RT73USB=m
1079CONFIG_RT73USB_LEDS=y
1080CONFIG_RT2X00_LIB_DEBUGFS=y
1081# CONFIG_RT2X00_DEBUG is not set
1082
1083#
1084# USB Network Adapters
1085#
1086CONFIG_USB_CATC=m
1087CONFIG_USB_KAWETH=m
1088CONFIG_USB_PEGASUS=m
1089CONFIG_USB_RTL8150=m
1090CONFIG_USB_USBNET=m
1091CONFIG_USB_NET_AX8817X=m
1092CONFIG_USB_NET_CDCETHER=m
1093CONFIG_USB_NET_DM9601=m
1094CONFIG_USB_NET_GL620A=m
1095CONFIG_USB_NET_NET1080=m
1096CONFIG_USB_NET_PLUSB=m
1097CONFIG_USB_NET_MCS7830=m
1098CONFIG_USB_NET_RNDIS_HOST=m
1099CONFIG_USB_NET_CDC_SUBSET=m
1100CONFIG_USB_ALI_M5632=y
1101CONFIG_USB_AN2720=y
1102CONFIG_USB_BELKIN=y
1103CONFIG_USB_ARMLINUX=y
1104CONFIG_USB_EPSON2888=y
1105CONFIG_USB_KC2190=y
1106CONFIG_USB_NET_ZAURUS=m
1107# CONFIG_USB_HSO is not set
1108# CONFIG_WAN is not set
1109# CONFIG_FDDI is not set
1110# CONFIG_HIPPI is not set
1111CONFIG_PPP=m
1112CONFIG_PPP_MULTILINK=y
1113CONFIG_PPP_FILTER=y
1114CONFIG_PPP_ASYNC=m
1115CONFIG_PPP_SYNC_TTY=m
1116CONFIG_PPP_DEFLATE=m
1117# CONFIG_PPP_BSDCOMP is not set
1118CONFIG_PPP_MPPE=m
1119CONFIG_PPPOE=m
1120CONFIG_PPPOL2TP=m
1121# CONFIG_SLIP is not set
1122CONFIG_SLHC=m
1123CONFIG_NET_FC=y
1124CONFIG_NETCONSOLE=m
1125CONFIG_NETCONSOLE_DYNAMIC=y
1126CONFIG_NETPOLL=y
1127CONFIG_NETPOLL_TRAP=y
1128CONFIG_NET_POLL_CONTROLLER=y
1129# CONFIG_ISDN is not set
1130# CONFIG_PHONE is not set
1131
1132#
1133# Input device support
1134#
1135CONFIG_INPUT=y
1136CONFIG_INPUT_FF_MEMLESS=y
1137CONFIG_INPUT_POLLDEV=m
1138
1139#
1140# Userland interfaces
1141#
1142CONFIG_INPUT_MOUSEDEV=y
1143# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
1144CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
1145CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
1146CONFIG_INPUT_JOYDEV=m
1147CONFIG_INPUT_EVDEV=y
1148# CONFIG_INPUT_EVBUG is not set
1149
1150#
1151# Input Device Drivers
1152#
1153CONFIG_INPUT_KEYBOARD=y
1154CONFIG_KEYBOARD_ATKBD=y
1155# CONFIG_KEYBOARD_SUNKBD is not set
1156# CONFIG_KEYBOARD_LKKBD is not set
1157# CONFIG_KEYBOARD_XTKBD is not set
1158# CONFIG_KEYBOARD_NEWTON is not set
1159# CONFIG_KEYBOARD_STOWAWAY is not set
1160CONFIG_INPUT_MOUSE=y
1161CONFIG_MOUSE_PS2=y
1162CONFIG_MOUSE_PS2_ALPS=y
1163CONFIG_MOUSE_PS2_LOGIPS2PP=y
1164CONFIG_MOUSE_PS2_SYNAPTICS=y
1165CONFIG_MOUSE_PS2_LIFEBOOK=y
1166CONFIG_MOUSE_PS2_TRACKPOINT=y
1167# CONFIG_MOUSE_PS2_TOUCHKIT is not set
1168CONFIG_MOUSE_SERIAL=m
1169# CONFIG_MOUSE_APPLETOUCH is not set
1170# CONFIG_MOUSE_BCM5974 is not set
1171CONFIG_MOUSE_VSXXXAA=m
1172CONFIG_INPUT_JOYSTICK=y
1173# CONFIG_JOYSTICK_ANALOG is not set
1174# CONFIG_JOYSTICK_A3D is not set
1175# CONFIG_JOYSTICK_ADI is not set
1176# CONFIG_JOYSTICK_COBRA is not set
1177# CONFIG_JOYSTICK_GF2K is not set
1178# CONFIG_JOYSTICK_GRIP is not set
1179# CONFIG_JOYSTICK_GRIP_MP is not set
1180# CONFIG_JOYSTICK_GUILLEMOT is not set
1181# CONFIG_JOYSTICK_INTERACT is not set
1182# CONFIG_JOYSTICK_SIDEWINDER is not set
1183# CONFIG_JOYSTICK_TMDC is not set
1184# CONFIG_JOYSTICK_IFORCE is not set
1185# CONFIG_JOYSTICK_WARRIOR is not set
1186# CONFIG_JOYSTICK_MAGELLAN is not set
1187# CONFIG_JOYSTICK_SPACEORB is not set
1188# CONFIG_JOYSTICK_SPACEBALL is not set
1189# CONFIG_JOYSTICK_STINGER is not set
1190# CONFIG_JOYSTICK_TWIDJOY is not set
1191# CONFIG_JOYSTICK_ZHENHUA is not set
1192# CONFIG_JOYSTICK_JOYDUMP is not set
1193# CONFIG_JOYSTICK_XPAD is not set
1194# CONFIG_INPUT_TABLET is not set
1195CONFIG_INPUT_TOUCHSCREEN=y
1196CONFIG_TOUCHSCREEN_FUJITSU=m
1197CONFIG_TOUCHSCREEN_GUNZE=m
1198CONFIG_TOUCHSCREEN_ELO=m
1199CONFIG_TOUCHSCREEN_MTOUCH=m
1200CONFIG_TOUCHSCREEN_INEXIO=m
1201CONFIG_TOUCHSCREEN_MK712=m
1202CONFIG_TOUCHSCREEN_PENMOUNT=m
1203CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
1204CONFIG_TOUCHSCREEN_TOUCHWIN=m
1205CONFIG_TOUCHSCREEN_UCB1400=m
1206# CONFIG_TOUCHSCREEN_WM97XX is not set
1207CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
1208CONFIG_TOUCHSCREEN_USB_EGALAX=y
1209CONFIG_TOUCHSCREEN_USB_PANJIT=y
1210CONFIG_TOUCHSCREEN_USB_3M=y
1211CONFIG_TOUCHSCREEN_USB_ITM=y
1212CONFIG_TOUCHSCREEN_USB_ETURBO=y
1213CONFIG_TOUCHSCREEN_USB_GUNZE=y
1214CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
1215CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
1216CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
1217CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
1218CONFIG_TOUCHSCREEN_USB_GOTOP=y
1219CONFIG_TOUCHSCREEN_TOUCHIT213=m
1220CONFIG_INPUT_MISC=y
1221# CONFIG_INPUT_PCSPKR is not set
1222# CONFIG_INPUT_APANEL is not set
1223# CONFIG_INPUT_WISTRON_BTNS is not set
1224CONFIG_INPUT_ATLAS_BTNS=m
1225CONFIG_INPUT_ATI_REMOTE=m
1226CONFIG_INPUT_ATI_REMOTE2=m
1227CONFIG_INPUT_KEYSPAN_REMOTE=m
1228CONFIG_INPUT_POWERMATE=m
1229CONFIG_INPUT_YEALINK=m
1230CONFIG_INPUT_UINPUT=m
1231
1232#
1233# Hardware I/O ports
1234#
1235CONFIG_SERIO=y
1236CONFIG_SERIO_I8042=y
1237CONFIG_SERIO_SERPORT=y
1238# CONFIG_SERIO_CT82C710 is not set
1239# CONFIG_SERIO_PCIPS2 is not set
1240CONFIG_SERIO_LIBPS2=y
1241CONFIG_SERIO_RAW=m
1242# CONFIG_GAMEPORT is not set
1243
1244#
1245# Character devices
1246#
1247CONFIG_VT=y
1248CONFIG_CONSOLE_TRANSLATIONS=y
1249CONFIG_VT_CONSOLE=y
1250CONFIG_HW_CONSOLE=y
1251CONFIG_VT_HW_CONSOLE_BINDING=y
1252# CONFIG_DEVKMEM is not set
1253# CONFIG_SERIAL_NONSTANDARD is not set
1254# CONFIG_NOZOMI is not set
1255
1256#
1257# Serial drivers
1258#
1259# CONFIG_SERIAL_8250 is not set
1260CONFIG_FIX_EARLYCON_MEM=y
1261
1262#
1263# Non-8250 serial port support
1264#
1265# CONFIG_SERIAL_JSM is not set
1266CONFIG_UNIX98_PTYS=y
1267# CONFIG_LEGACY_PTYS is not set
1268# CONFIG_IPMI_HANDLER is not set
1269# CONFIG_HW_RANDOM is not set
1270# CONFIG_NVRAM is not set
1271# CONFIG_R3964 is not set
1272# CONFIG_APPLICOM is not set
1273# CONFIG_SONYPI is not set
1274# CONFIG_MWAVE is not set
1275# CONFIG_PC8736x_GPIO is not set
1276# CONFIG_NSC_GPIO is not set
1277# CONFIG_CS5535_GPIO is not set
1278# CONFIG_RAW_DRIVER is not set
1279CONFIG_HPET=y
1280# CONFIG_HPET_MMAP is not set
1281# CONFIG_HANGCHECK_TIMER is not set
1282# CONFIG_TCG_TPM is not set
1283# CONFIG_TELCLOCK is not set
1284CONFIG_DEVPORT=y
1285CONFIG_I2C=y
1286CONFIG_I2C_BOARDINFO=y
1287# CONFIG_I2C_CHARDEV is not set
1288CONFIG_I2C_HELPER_AUTO=y
1289CONFIG_I2C_ALGOBIT=y
1290
1291#
1292# I2C Hardware Bus support
1293#
1294
1295#
1296# PC SMBus host controller drivers
1297#
1298# CONFIG_I2C_ALI1535 is not set
1299# CONFIG_I2C_ALI1563 is not set
1300# CONFIG_I2C_ALI15X3 is not set
1301# CONFIG_I2C_AMD756 is not set
1302# CONFIG_I2C_AMD8111 is not set
1303# CONFIG_I2C_I801 is not set
1304# CONFIG_I2C_ISCH is not set
1305# CONFIG_I2C_PIIX4 is not set
1306# CONFIG_I2C_NFORCE2 is not set
1307# CONFIG_I2C_SIS5595 is not set
1308# CONFIG_I2C_SIS630 is not set
1309# CONFIG_I2C_SIS96X is not set
1310# CONFIG_I2C_VIA is not set
1311# CONFIG_I2C_VIAPRO is not set
1312
1313#
1314# I2C system bus drivers (mostly embedded / system-on-chip)
1315#
1316# CONFIG_I2C_OCORES is not set
1317# CONFIG_I2C_SIMTEC is not set
1318
1319#
1320# External I2C/SMBus adapter drivers
1321#
1322# CONFIG_I2C_PARPORT_LIGHT is not set
1323# CONFIG_I2C_TAOS_EVM is not set
1324# CONFIG_I2C_TINY_USB is not set
1325
1326#
1327# Graphics adapter I2C/DDC channel drivers
1328#
1329# CONFIG_I2C_VOODOO3 is not set
1330
1331#
1332# Other I2C/SMBus bus drivers
1333#
1334# CONFIG_I2C_PCA_PLATFORM is not set
1335# CONFIG_I2C_STUB is not set
1336# CONFIG_SCx200_ACB is not set
1337
1338#
1339# Miscellaneous I2C Chip support
1340#
1341# CONFIG_DS1682 is not set
1342# CONFIG_AT24 is not set
1343# CONFIG_SENSORS_EEPROM is not set
1344# CONFIG_SENSORS_PCF8574 is not set
1345# CONFIG_PCF8575 is not set
1346# CONFIG_SENSORS_PCA9539 is not set
1347# CONFIG_SENSORS_PCF8591 is not set
1348# CONFIG_SENSORS_MAX6875 is not set
1349# CONFIG_SENSORS_TSL2550 is not set
1350# CONFIG_I2C_DEBUG_CORE is not set
1351# CONFIG_I2C_DEBUG_ALGO is not set
1352# CONFIG_I2C_DEBUG_BUS is not set
1353# CONFIG_I2C_DEBUG_CHIP is not set
1354# CONFIG_SPI is not set
1355CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
1356# CONFIG_GPIOLIB is not set
1357# CONFIG_W1 is not set
1358CONFIG_POWER_SUPPLY=y
1359# CONFIG_POWER_SUPPLY_DEBUG is not set
1360# CONFIG_PDA_POWER is not set
1361# CONFIG_BATTERY_DS2760 is not set
1362CONFIG_HWMON=y
1363# CONFIG_HWMON_VID is not set
1364# CONFIG_SENSORS_ABITUGURU is not set
1365# CONFIG_SENSORS_ABITUGURU3 is not set
1366# CONFIG_SENSORS_AD7414 is not set
1367# CONFIG_SENSORS_AD7418 is not set
1368# CONFIG_SENSORS_ADM1021 is not set
1369# CONFIG_SENSORS_ADM1025 is not set
1370# CONFIG_SENSORS_ADM1026 is not set
1371# CONFIG_SENSORS_ADM1029 is not set
1372# CONFIG_SENSORS_ADM1031 is not set
1373# CONFIG_SENSORS_ADM9240 is not set
1374# CONFIG_SENSORS_ADT7470 is not set
1375# CONFIG_SENSORS_ADT7473 is not set
1376# CONFIG_SENSORS_K8TEMP is not set
1377# CONFIG_SENSORS_ASB100 is not set
1378# CONFIG_SENSORS_ATXP1 is not set
1379# CONFIG_SENSORS_DS1621 is not set
1380# CONFIG_SENSORS_I5K_AMB is not set
1381# CONFIG_SENSORS_F71805F is not set
1382# CONFIG_SENSORS_F71882FG is not set
1383# CONFIG_SENSORS_F75375S is not set
1384# CONFIG_SENSORS_FSCHER is not set
1385# CONFIG_SENSORS_FSCPOS is not set
1386# CONFIG_SENSORS_FSCHMD is not set
1387# CONFIG_SENSORS_GL518SM is not set
1388# CONFIG_SENSORS_GL520SM is not set
1389# CONFIG_SENSORS_CORETEMP is not set
1390# CONFIG_SENSORS_IT87 is not set
1391# CONFIG_SENSORS_LM63 is not set
1392# CONFIG_SENSORS_LM75 is not set
1393# CONFIG_SENSORS_LM77 is not set
1394# CONFIG_SENSORS_LM78 is not set
1395# CONFIG_SENSORS_LM80 is not set
1396# CONFIG_SENSORS_LM83 is not set
1397# CONFIG_SENSORS_LM85 is not set
1398# CONFIG_SENSORS_LM87 is not set
1399# CONFIG_SENSORS_LM90 is not set
1400# CONFIG_SENSORS_LM92 is not set
1401# CONFIG_SENSORS_LM93 is not set
1402# CONFIG_SENSORS_MAX1619 is not set
1403# CONFIG_SENSORS_MAX6650 is not set
1404# CONFIG_SENSORS_PC87360 is not set
1405# CONFIG_SENSORS_PC87427 is not set
1406# CONFIG_SENSORS_SIS5595 is not set
1407# CONFIG_SENSORS_DME1737 is not set
1408# CONFIG_SENSORS_SMSC47M1 is not set
1409# CONFIG_SENSORS_SMSC47M192 is not set
1410# CONFIG_SENSORS_SMSC47B397 is not set
1411# CONFIG_SENSORS_ADS7828 is not set
1412# CONFIG_SENSORS_THMC50 is not set
1413# CONFIG_SENSORS_VIA686A is not set
1414# CONFIG_SENSORS_VT1211 is not set
1415# CONFIG_SENSORS_VT8231 is not set
1416# CONFIG_SENSORS_W83781D is not set
1417# CONFIG_SENSORS_W83791D is not set
1418# CONFIG_SENSORS_W83792D is not set
1419# CONFIG_SENSORS_W83793 is not set
1420# CONFIG_SENSORS_W83L785TS is not set
1421# CONFIG_SENSORS_W83L786NG is not set
1422# CONFIG_SENSORS_W83627HF is not set
1423# CONFIG_SENSORS_W83627EHF is not set
1424# CONFIG_SENSORS_HDAPS is not set
1425# CONFIG_SENSORS_APPLESMC is not set
1426# CONFIG_HWMON_DEBUG_CHIP is not set
1427CONFIG_THERMAL=y
1428# CONFIG_THERMAL_HWMON is not set
1429# CONFIG_WATCHDOG is not set
1430
1431#
1432# Sonics Silicon Backplane
1433#
1434CONFIG_SSB_POSSIBLE=y
1435# CONFIG_SSB is not set
1436
1437#
1438# Multifunction device drivers
1439#
1440# CONFIG_MFD_CORE is not set
1441# CONFIG_MFD_SM501 is not set
1442# CONFIG_HTC_PASIC3 is not set
1443# CONFIG_MFD_TMIO is not set
1444
1445#
1446# Multimedia devices
1447#
1448
1449#
1450# Multimedia core support
1451#
1452CONFIG_VIDEO_DEV=y
1453CONFIG_VIDEO_V4L2_COMMON=y
1454# CONFIG_VIDEO_ALLOW_V4L1 is not set
1455CONFIG_VIDEO_V4L1_COMPAT=y
1456CONFIG_DVB_CORE=y
1457CONFIG_VIDEO_MEDIA=y
1458
1459#
1460# Multimedia drivers
1461#
1462# CONFIG_MEDIA_ATTACH is not set
1463CONFIG_MEDIA_TUNER=y
1464# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
1465CONFIG_MEDIA_TUNER_SIMPLE=y
1466CONFIG_MEDIA_TUNER_TDA8290=y
1467CONFIG_MEDIA_TUNER_TDA9887=y
1468CONFIG_MEDIA_TUNER_TEA5761=y
1469CONFIG_MEDIA_TUNER_TEA5767=y
1470CONFIG_MEDIA_TUNER_MT20XX=y
1471CONFIG_MEDIA_TUNER_XC2028=y
1472CONFIG_MEDIA_TUNER_XC5000=y
1473CONFIG_VIDEO_V4L2=y
1474CONFIG_VIDEO_CAPTURE_DRIVERS=y
1475# CONFIG_VIDEO_ADV_DEBUG is not set
1476CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
1477# CONFIG_VIDEO_VIVI is not set
1478# CONFIG_VIDEO_BT848 is not set
1479# CONFIG_VIDEO_SAA5246A is not set
1480# CONFIG_VIDEO_SAA5249 is not set
1481# CONFIG_VIDEO_SAA7134 is not set
1482# CONFIG_VIDEO_HEXIUM_ORION is not set
1483# CONFIG_VIDEO_HEXIUM_GEMINI is not set
1484# CONFIG_VIDEO_CX88 is not set
1485# CONFIG_VIDEO_CX23885 is not set
1486# CONFIG_VIDEO_AU0828 is not set
1487# CONFIG_VIDEO_CX18 is not set
1488# CONFIG_VIDEO_CAFE_CCIC is not set
1489CONFIG_V4L_USB_DRIVERS=y
1490CONFIG_USB_VIDEO_CLASS=y
1491CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
1492# CONFIG_USB_GSPCA is not set
1493# CONFIG_VIDEO_PVRUSB2 is not set
1494# CONFIG_VIDEO_EM28XX is not set
1495# CONFIG_VIDEO_USBVISION is not set
1496# CONFIG_USB_ET61X251 is not set
1497# CONFIG_USB_SN9C102 is not set
1498# CONFIG_USB_ZC0301 is not set
1499# CONFIG_USB_ZR364XX is not set
1500# CONFIG_USB_STKWEBCAM is not set
1501# CONFIG_USB_S2255 is not set
1502# CONFIG_SOC_CAMERA is not set
1503# CONFIG_VIDEO_SH_MOBILE_CEU is not set
1504# CONFIG_RADIO_ADAPTERS is not set
1505# CONFIG_DVB_CAPTURE_DRIVERS is not set
1506# CONFIG_DAB is not set
1507
1508#
1509# Graphics support
1510#
1511CONFIG_AGP=y
1512# CONFIG_AGP_ALI is not set
1513# CONFIG_AGP_ATI is not set
1514# CONFIG_AGP_AMD is not set
1515CONFIG_AGP_AMD64=y
1516CONFIG_AGP_INTEL=y
1517# CONFIG_AGP_NVIDIA is not set
1518# CONFIG_AGP_SIS is not set
1519# CONFIG_AGP_SWORKS is not set
1520# CONFIG_AGP_VIA is not set
1521# CONFIG_AGP_EFFICEON is not set
1522CONFIG_DRM=y
1523# CONFIG_DRM_TDFX is not set
1524# CONFIG_DRM_R128 is not set
1525# CONFIG_DRM_RADEON is not set
1526CONFIG_DRM_I810=y
1527# CONFIG_DRM_I830 is not set
1528CONFIG_DRM_I915=y
1529# CONFIG_DRM_MGA is not set
1530# CONFIG_DRM_SIS is not set
1531# CONFIG_DRM_VIA is not set
1532# CONFIG_DRM_SAVAGE is not set
1533# CONFIG_VGASTATE is not set
1534CONFIG_VIDEO_OUTPUT_CONTROL=y
1535CONFIG_FB=y
1536CONFIG_FIRMWARE_EDID=y
1537CONFIG_FB_DDC=y
1538CONFIG_FB_CFB_FILLRECT=y
1539CONFIG_FB_CFB_COPYAREA=y
1540CONFIG_FB_CFB_IMAGEBLIT=y
1541# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
1542# CONFIG_FB_SYS_FILLRECT is not set
1543# CONFIG_FB_SYS_COPYAREA is not set
1544# CONFIG_FB_SYS_IMAGEBLIT is not set
1545# CONFIG_FB_FOREIGN_ENDIAN is not set
1546# CONFIG_FB_SYS_FOPS is not set
1547# CONFIG_FB_SVGALIB is not set
1548# CONFIG_FB_MACMODES is not set
1549# CONFIG_FB_BACKLIGHT is not set
1550CONFIG_FB_MODE_HELPERS=y
1551# CONFIG_FB_TILEBLITTING is not set
1552
1553#
1554# Frame buffer hardware drivers
1555#
1556# CONFIG_FB_CIRRUS is not set
1557# CONFIG_FB_PM2 is not set
1558# CONFIG_FB_CYBER2000 is not set
1559# CONFIG_FB_ARC is not set
1560# CONFIG_FB_ASILIANT is not set
1561# CONFIG_FB_IMSTT is not set
1562# CONFIG_FB_VGA16 is not set
1563# CONFIG_FB_UVESA is not set
1564# CONFIG_FB_VESA is not set
1565# CONFIG_FB_EFI is not set
1566# CONFIG_FB_N411 is not set
1567# CONFIG_FB_HGA is not set
1568# CONFIG_FB_S1D13XXX is not set
1569# CONFIG_FB_NVIDIA is not set
1570# CONFIG_FB_RIVA is not set
1571# CONFIG_FB_I810 is not set
1572# CONFIG_FB_LE80578 is not set
1573CONFIG_FB_INTEL=y
1574CONFIG_FB_INTEL_DEBUG=y
1575CONFIG_FB_INTEL_I2C=y
1576# CONFIG_FB_MATROX is not set
1577# CONFIG_FB_RADEON is not set
1578# CONFIG_FB_ATY128 is not set
1579# CONFIG_FB_ATY is not set
1580# CONFIG_FB_S3 is not set
1581# CONFIG_FB_SAVAGE is not set
1582# CONFIG_FB_SIS is not set
1583# CONFIG_FB_NEOMAGIC is not set
1584# CONFIG_FB_KYRO is not set
1585# CONFIG_FB_3DFX is not set
1586# CONFIG_FB_VOODOO1 is not set
1587# CONFIG_FB_VT8623 is not set
1588# CONFIG_FB_CYBLA is not set
1589# CONFIG_FB_TRIDENT is not set
1590# CONFIG_FB_ARK is not set
1591# CONFIG_FB_PM3 is not set
1592# CONFIG_FB_CARMINE is not set
1593# CONFIG_FB_GEODE is not set
1594# CONFIG_FB_VIRTUAL is not set
1595CONFIG_BACKLIGHT_LCD_SUPPORT=y
1596CONFIG_LCD_CLASS_DEVICE=y
1597# CONFIG_LCD_ILI9320 is not set
1598CONFIG_LCD_PLATFORM=y
1599CONFIG_BACKLIGHT_CLASS_DEVICE=y
1600# CONFIG_BACKLIGHT_CORGI is not set
1601# CONFIG_BACKLIGHT_PROGEAR is not set
1602CONFIG_BACKLIGHT_MBP_NVIDIA=y
1603
1604#
1605# Display device support
1606#
1607CONFIG_DISPLAY_SUPPORT=y
1608
1609#
1610# Display hardware drivers
1611#
1612
1613#
1614# Console display driver support
1615#
1616CONFIG_VGA_CONSOLE=y
1617CONFIG_VGACON_SOFT_SCROLLBACK=y
1618CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
1619CONFIG_VIDEO_SELECT=y
1620CONFIG_DUMMY_CONSOLE=y
1621CONFIG_FRAMEBUFFER_CONSOLE=y
1622# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1623# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1624# CONFIG_FONTS is not set
1625CONFIG_FONT_8x8=y
1626CONFIG_FONT_8x16=y
1627# CONFIG_LOGO is not set
1628CONFIG_SOUND=y
1629CONFIG_SND=y
1630CONFIG_SND_TIMER=y
1631CONFIG_SND_PCM=y
1632CONFIG_SND_HWDEP=y
1633CONFIG_SND_RAWMIDI=m
1634CONFIG_SND_SEQUENCER=y
1635CONFIG_SND_SEQ_DUMMY=y
1636# CONFIG_SND_MIXER_OSS is not set
1637# CONFIG_SND_PCM_OSS is not set
1638# CONFIG_SND_SEQUENCER_OSS is not set
1639CONFIG_SND_DYNAMIC_MINORS=y
1640# CONFIG_SND_SUPPORT_OLD_API is not set
1641CONFIG_SND_VERBOSE_PROCFS=y
1642CONFIG_SND_VERBOSE_PRINTK=y
1643CONFIG_SND_DEBUG=y
1644# CONFIG_SND_DEBUG_VERBOSE is not set
1645CONFIG_SND_PCM_XRUN_DEBUG=y
1646CONFIG_SND_VMASTER=y
1647CONFIG_SND_AC97_CODEC=y
1648CONFIG_SND_DRIVERS=y
1649# CONFIG_SND_PCSP is not set
1650# CONFIG_SND_DUMMY is not set
1651# CONFIG_SND_VIRMIDI is not set
1652# CONFIG_SND_MTPAV is not set
1653# CONFIG_SND_SERIAL_U16550 is not set
1654# CONFIG_SND_MPU401 is not set
1655CONFIG_SND_AC97_POWER_SAVE=y
1656CONFIG_SND_AC97_POWER_SAVE_DEFAULT=5
1657CONFIG_SND_PCI=y
1658# CONFIG_SND_AD1889 is not set
1659# CONFIG_SND_ALS300 is not set
1660# CONFIG_SND_ALS4000 is not set
1661# CONFIG_SND_ALI5451 is not set
1662# CONFIG_SND_ATIIXP is not set
1663# CONFIG_SND_ATIIXP_MODEM is not set
1664# CONFIG_SND_AU8810 is not set
1665# CONFIG_SND_AU8820 is not set
1666# CONFIG_SND_AU8830 is not set
1667# CONFIG_SND_AW2 is not set
1668# CONFIG_SND_AZT3328 is not set
1669# CONFIG_SND_BT87X is not set
1670# CONFIG_SND_CA0106 is not set
1671# CONFIG_SND_CMIPCI is not set
1672# CONFIG_SND_OXYGEN is not set
1673# CONFIG_SND_CS4281 is not set
1674# CONFIG_SND_CS46XX is not set
1675# CONFIG_SND_CS5530 is not set
1676# CONFIG_SND_CS5535AUDIO is not set
1677# CONFIG_SND_DARLA20 is not set
1678# CONFIG_SND_GINA20 is not set
1679# CONFIG_SND_LAYLA20 is not set
1680# CONFIG_SND_DARLA24 is not set
1681# CONFIG_SND_GINA24 is not set
1682# CONFIG_SND_LAYLA24 is not set
1683# CONFIG_SND_MONA is not set
1684# CONFIG_SND_MIA is not set
1685# CONFIG_SND_ECHO3G is not set
1686# CONFIG_SND_INDIGO is not set
1687# CONFIG_SND_INDIGOIO is not set
1688# CONFIG_SND_INDIGODJ is not set
1689# CONFIG_SND_EMU10K1 is not set
1690# CONFIG_SND_EMU10K1X is not set
1691# CONFIG_SND_ENS1370 is not set
1692# CONFIG_SND_ENS1371 is not set
1693# CONFIG_SND_ES1938 is not set
1694# CONFIG_SND_ES1968 is not set
1695# CONFIG_SND_FM801 is not set
1696CONFIG_SND_HDA_INTEL=y
1697CONFIG_SND_HDA_HWDEP=y
1698CONFIG_SND_HDA_CODEC_REALTEK=y
1699CONFIG_SND_HDA_CODEC_ANALOG=y
1700CONFIG_SND_HDA_CODEC_SIGMATEL=y
1701CONFIG_SND_HDA_CODEC_VIA=y
1702CONFIG_SND_HDA_CODEC_ATIHDMI=y
1703CONFIG_SND_HDA_CODEC_CONEXANT=y
1704CONFIG_SND_HDA_CODEC_CMEDIA=y
1705CONFIG_SND_HDA_CODEC_SI3054=y
1706CONFIG_SND_HDA_GENERIC=y
1707CONFIG_SND_HDA_POWER_SAVE=y
1708CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
1709# CONFIG_SND_HDSP is not set
1710# CONFIG_SND_HDSPM is not set
1711# CONFIG_SND_HIFIER is not set
1712# CONFIG_SND_ICE1712 is not set
1713# CONFIG_SND_ICE1724 is not set
1714CONFIG_SND_INTEL8X0=y
1715# CONFIG_SND_INTEL8X0M is not set
1716# CONFIG_SND_KORG1212 is not set
1717# CONFIG_SND_MAESTRO3 is not set
1718# CONFIG_SND_MIXART is not set
1719# CONFIG_SND_NM256 is not set
1720# CONFIG_SND_PCXHR is not set
1721# CONFIG_SND_RIPTIDE is not set
1722# CONFIG_SND_RME32 is not set
1723# CONFIG_SND_RME96 is not set
1724# CONFIG_SND_RME9652 is not set
1725# CONFIG_SND_SIS7019 is not set
1726# CONFIG_SND_SONICVIBES is not set
1727# CONFIG_SND_TRIDENT is not set
1728# CONFIG_SND_VIA82XX is not set
1729# CONFIG_SND_VIA82XX_MODEM is not set
1730# CONFIG_SND_VIRTUOSO is not set
1731# CONFIG_SND_VX222 is not set
1732# CONFIG_SND_YMFPCI is not set
1733CONFIG_SND_USB=y
1734CONFIG_SND_USB_AUDIO=m
1735CONFIG_SND_USB_USX2Y=m
1736CONFIG_SND_USB_CAIAQ=m
1737CONFIG_SND_USB_CAIAQ_INPUT=y
1738# CONFIG_SND_SOC is not set
1739# CONFIG_SOUND_PRIME is not set
1740CONFIG_AC97_BUS=y
1741CONFIG_HID_SUPPORT=y
1742CONFIG_HID=y
1743CONFIG_HID_DEBUG=y
1744CONFIG_HIDRAW=y
1745
1746#
1747# USB Input Devices
1748#
1749CONFIG_USB_HID=y
1750CONFIG_USB_HIDINPUT_POWERBOOK=y
1751CONFIG_HID_FF=y
1752CONFIG_HID_PID=y
1753CONFIG_LOGITECH_FF=y
1754# CONFIG_LOGIRUMBLEPAD2_FF is not set
1755CONFIG_PANTHERLORD_FF=y
1756CONFIG_THRUSTMASTER_FF=y
1757CONFIG_ZEROPLUS_FF=y
1758CONFIG_USB_HIDDEV=y
1759CONFIG_USB_SUPPORT=y
1760CONFIG_USB_ARCH_HAS_HCD=y
1761CONFIG_USB_ARCH_HAS_OHCI=y
1762CONFIG_USB_ARCH_HAS_EHCI=y
1763CONFIG_USB=y
1764# CONFIG_USB_DEBUG is not set
1765CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
1766
1767#
1768# Miscellaneous USB options
1769#
1770CONFIG_USB_DEVICEFS=y
1771# CONFIG_USB_DEVICE_CLASS is not set
1772# CONFIG_USB_DYNAMIC_MINORS is not set
1773CONFIG_USB_SUSPEND=y
1774# CONFIG_USB_OTG is not set
1775CONFIG_USB_MON=y
1776
1777#
1778# USB Host Controller Drivers
1779#
1780# CONFIG_USB_C67X00_HCD is not set
1781CONFIG_USB_EHCI_HCD=y
1782CONFIG_USB_EHCI_ROOT_HUB_TT=y
1783CONFIG_USB_EHCI_TT_NEWSCHED=y
1784CONFIG_USB_ISP116X_HCD=m
1785# CONFIG_USB_ISP1760_HCD is not set
1786CONFIG_USB_OHCI_HCD=y
1787# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
1788# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
1789CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1790CONFIG_USB_UHCI_HCD=y
1791CONFIG_USB_U132_HCD=m
1792CONFIG_USB_SL811_HCD=m
1793# CONFIG_USB_R8A66597_HCD is not set
1794
1795#
1796# USB Device Class drivers
1797#
1798CONFIG_USB_ACM=m
1799CONFIG_USB_PRINTER=m
1800# CONFIG_USB_WDM is not set
1801
1802#
1803# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1804#
1805
1806#
1807# may also be needed; see USB_STORAGE Help for more information
1808#
1809CONFIG_USB_STORAGE=y
1810# CONFIG_USB_STORAGE_DEBUG is not set
1811CONFIG_USB_STORAGE_DATAFAB=y
1812CONFIG_USB_STORAGE_FREECOM=y
1813CONFIG_USB_STORAGE_ISD200=y
1814CONFIG_USB_STORAGE_DPCM=y
1815CONFIG_USB_STORAGE_USBAT=y
1816CONFIG_USB_STORAGE_SDDR09=y
1817CONFIG_USB_STORAGE_SDDR55=y
1818CONFIG_USB_STORAGE_JUMPSHOT=y
1819CONFIG_USB_STORAGE_ALAUDA=y
1820# CONFIG_USB_STORAGE_ONETOUCH is not set
1821CONFIG_USB_STORAGE_KARMA=y
1822# CONFIG_USB_STORAGE_SIERRA is not set
1823# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
1824# CONFIG_USB_LIBUSUAL is not set
1825
1826#
1827# USB Imaging devices
1828#
1829CONFIG_USB_MDC800=m
1830CONFIG_USB_MICROTEK=m
1831
1832#
1833# USB port drivers
1834#
1835CONFIG_USB_SERIAL=m
1836CONFIG_USB_EZUSB=y
1837CONFIG_USB_SERIAL_GENERIC=y
1838CONFIG_USB_SERIAL_AIRCABLE=m
1839CONFIG_USB_SERIAL_ARK3116=m
1840CONFIG_USB_SERIAL_BELKIN=m
1841CONFIG_USB_SERIAL_CH341=m
1842CONFIG_USB_SERIAL_WHITEHEAT=m
1843CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1844CONFIG_USB_SERIAL_CP2101=m
1845CONFIG_USB_SERIAL_CYPRESS_M8=m
1846CONFIG_USB_SERIAL_EMPEG=m
1847CONFIG_USB_SERIAL_FTDI_SIO=m
1848CONFIG_USB_SERIAL_FUNSOFT=m
1849CONFIG_USB_SERIAL_VISOR=m
1850CONFIG_USB_SERIAL_IPAQ=m
1851CONFIG_USB_SERIAL_IR=m
1852CONFIG_USB_SERIAL_EDGEPORT=m
1853CONFIG_USB_SERIAL_EDGEPORT_TI=m
1854CONFIG_USB_SERIAL_GARMIN=m
1855CONFIG_USB_SERIAL_IPW=m
1856CONFIG_USB_SERIAL_IUU=m
1857CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1858CONFIG_USB_SERIAL_KEYSPAN=m
1859CONFIG_USB_SERIAL_KEYSPAN_MPR=y
1860CONFIG_USB_SERIAL_KEYSPAN_USA28=y
1861CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
1862CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
1863CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
1864CONFIG_USB_SERIAL_KEYSPAN_USA19=y
1865CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
1866CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
1867CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
1868CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
1869CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
1870CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
1871CONFIG_USB_SERIAL_KLSI=m
1872CONFIG_USB_SERIAL_KOBIL_SCT=m
1873CONFIG_USB_SERIAL_MCT_U232=m
1874CONFIG_USB_SERIAL_MOS7720=m
1875CONFIG_USB_SERIAL_MOS7840=m
1876# CONFIG_USB_SERIAL_MOTOROLA is not set
1877CONFIG_USB_SERIAL_NAVMAN=m
1878CONFIG_USB_SERIAL_PL2303=m
1879CONFIG_USB_SERIAL_OTI6858=m
1880# CONFIG_USB_SERIAL_SPCP8X5 is not set
1881CONFIG_USB_SERIAL_HP4X=m
1882CONFIG_USB_SERIAL_SAFE=m
1883CONFIG_USB_SERIAL_SAFE_PADDED=y
1884CONFIG_USB_SERIAL_SIERRAWIRELESS=m
1885CONFIG_USB_SERIAL_TI=m
1886CONFIG_USB_SERIAL_CYBERJACK=m
1887CONFIG_USB_SERIAL_XIRCOM=m
1888CONFIG_USB_SERIAL_OPTION=m
1889CONFIG_USB_SERIAL_OMNINET=m
1890CONFIG_USB_SERIAL_DEBUG=m
1891
1892#
1893# USB Miscellaneous drivers
1894#
1895CONFIG_USB_EMI62=m
1896CONFIG_USB_EMI26=m
1897CONFIG_USB_ADUTUX=m
1898# CONFIG_USB_RIO500 is not set
1899CONFIG_USB_LEGOTOWER=m
1900CONFIG_USB_LCD=m
1901CONFIG_USB_BERRY_CHARGE=m
1902CONFIG_USB_LED=m
1903# CONFIG_USB_CYPRESS_CY7C63 is not set
1904# CONFIG_USB_CYTHERM is not set
1905CONFIG_USB_PHIDGET=m
1906CONFIG_USB_PHIDGETKIT=m
1907CONFIG_USB_PHIDGETMOTORCONTROL=m
1908CONFIG_USB_PHIDGETSERVO=m
1909CONFIG_USB_IDMOUSE=m
1910CONFIG_USB_FTDI_ELAN=m
1911CONFIG_USB_APPLEDISPLAY=m
1912CONFIG_USB_SISUSBVGA=m
1913CONFIG_USB_SISUSBVGA_CON=y
1914CONFIG_USB_LD=m
1915CONFIG_USB_TRANCEVIBRATOR=m
1916CONFIG_USB_IOWARRIOR=m
1917# CONFIG_USB_TEST is not set
1918# CONFIG_USB_ISIGHTFW is not set
1919# CONFIG_USB_GADGET is not set
1920CONFIG_MMC=m
1921# CONFIG_MMC_DEBUG is not set
1922# CONFIG_MMC_UNSAFE_RESUME is not set
1923
1924#
1925# MMC/SD Card Drivers
1926#
1927CONFIG_MMC_BLOCK=m
1928CONFIG_MMC_BLOCK_BOUNCE=y
1929CONFIG_SDIO_UART=m
1930# CONFIG_MMC_TEST is not set
1931
1932#
1933# MMC/SD Host Controller Drivers
1934#
1935CONFIG_MMC_SDHCI=m
1936# CONFIG_MMC_SDHCI_PCI is not set
1937CONFIG_MMC_WBSD=m
1938CONFIG_MMC_TIFM_SD=m
1939CONFIG_MEMSTICK=m
1940CONFIG_MEMSTICK_DEBUG=y
1941
1942#
1943# MemoryStick drivers
1944#
1945# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
1946CONFIG_MSPRO_BLOCK=m
1947
1948#
1949# MemoryStick Host Controller Drivers
1950#
1951# CONFIG_MEMSTICK_TIFM_MS is not set
1952# CONFIG_MEMSTICK_JMICRON_38X is not set
1953CONFIG_NEW_LEDS=y
1954CONFIG_LEDS_CLASS=m
1955
1956#
1957# LED drivers
1958#
1959# CONFIG_LEDS_PCA9532 is not set
1960# CONFIG_LEDS_CLEVO_MAIL is not set
1961# CONFIG_LEDS_PCA955X is not set
1962
1963#
1964# LED Triggers
1965#
1966CONFIG_LEDS_TRIGGERS=y
1967# CONFIG_LEDS_TRIGGER_TIMER is not set
1968# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
1969# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
1970# CONFIG_ACCESSIBILITY is not set
1971# CONFIG_INFINIBAND is not set
1972# CONFIG_EDAC is not set
1973CONFIG_RTC_LIB=y
1974CONFIG_RTC_CLASS=y
1975# CONFIG_RTC_HCTOSYS is not set
1976# CONFIG_RTC_DEBUG is not set
1977
1978#
1979# RTC interfaces
1980#
1981CONFIG_RTC_INTF_SYSFS=y
1982CONFIG_RTC_INTF_PROC=y
1983CONFIG_RTC_INTF_DEV=y
1984# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1985# CONFIG_RTC_DRV_TEST is not set
1986
1987#
1988# I2C RTC drivers
1989#
1990# CONFIG_RTC_DRV_DS1307 is not set
1991# CONFIG_RTC_DRV_DS1374 is not set
1992# CONFIG_RTC_DRV_DS1672 is not set
1993# CONFIG_RTC_DRV_MAX6900 is not set
1994# CONFIG_RTC_DRV_RS5C372 is not set
1995# CONFIG_RTC_DRV_ISL1208 is not set
1996# CONFIG_RTC_DRV_X1205 is not set
1997# CONFIG_RTC_DRV_PCF8563 is not set
1998# CONFIG_RTC_DRV_PCF8583 is not set
1999# CONFIG_RTC_DRV_M41T80 is not set
2000# CONFIG_RTC_DRV_S35390A is not set
2001# CONFIG_RTC_DRV_FM3130 is not set
2002
2003#
2004# SPI RTC drivers
2005#
2006
2007#
2008# Platform RTC drivers
2009#
2010CONFIG_RTC_DRV_CMOS=y
2011# CONFIG_RTC_DRV_DS1511 is not set
2012# CONFIG_RTC_DRV_DS1553 is not set
2013# CONFIG_RTC_DRV_DS1742 is not set
2014# CONFIG_RTC_DRV_STK17TA8 is not set
2015# CONFIG_RTC_DRV_M48T86 is not set
2016# CONFIG_RTC_DRV_M48T59 is not set
2017# CONFIG_RTC_DRV_V3020 is not set
2018
2019#
2020# on-CPU RTC drivers
2021#
2022# CONFIG_DMADEVICES is not set
2023# CONFIG_UIO is not set
2024
2025#
2026# Firmware Drivers
2027#
2028# CONFIG_EDD is not set
2029CONFIG_FIRMWARE_MEMMAP=y
2030# CONFIG_DELL_RBU is not set
2031# CONFIG_DCDBAS is not set
2032# CONFIG_DMIID is not set
2033# CONFIG_ISCSI_IBFT_FIND is not set
2034
2035#
2036# File systems
2037#
2038# CONFIG_EXT2_FS is not set
2039CONFIG_EXT3_FS=y
2040CONFIG_EXT3_FS_XATTR=y
2041CONFIG_EXT3_FS_POSIX_ACL=y
2042CONFIG_EXT3_FS_SECURITY=y
2043# CONFIG_EXT4DEV_FS is not set
2044CONFIG_JBD=y
2045# CONFIG_JBD_DEBUG is not set
2046CONFIG_FS_MBCACHE=y
2047# CONFIG_REISERFS_FS is not set
2048# CONFIG_JFS_FS is not set
2049CONFIG_FS_POSIX_ACL=y
2050# CONFIG_XFS_FS is not set
2051# CONFIG_OCFS2_FS is not set
2052CONFIG_DNOTIFY=y
2053CONFIG_INOTIFY=y
2054CONFIG_INOTIFY_USER=y
2055CONFIG_QUOTA=y
2056CONFIG_QUOTA_NETLINK_INTERFACE=y
2057# CONFIG_PRINT_QUOTA_WARNING is not set
2058# CONFIG_QFMT_V1 is not set
2059CONFIG_QFMT_V2=y
2060CONFIG_QUOTACTL=y
2061# CONFIG_AUTOFS_FS is not set
2062# CONFIG_AUTOFS4_FS is not set
2063CONFIG_FUSE_FS=m
2064CONFIG_GENERIC_ACL=y
2065
2066#
2067# CD-ROM/DVD Filesystems
2068#
2069CONFIG_ISO9660_FS=y
2070CONFIG_JOLIET=y
2071CONFIG_ZISOFS=y
2072CONFIG_UDF_FS=m
2073CONFIG_UDF_NLS=y
2074
2075#
2076# DOS/FAT/NT Filesystems
2077#
2078CONFIG_FAT_FS=y
2079CONFIG_MSDOS_FS=y
2080CONFIG_VFAT_FS=y
2081CONFIG_FAT_DEFAULT_CODEPAGE=437
2082CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
2083# CONFIG_NTFS_FS is not set
2084
2085#
2086# Pseudo filesystems
2087#
2088CONFIG_PROC_FS=y
2089CONFIG_PROC_KCORE=y
2090CONFIG_PROC_VMCORE=y
2091CONFIG_PROC_SYSCTL=y
2092CONFIG_SYSFS=y
2093CONFIG_TMPFS=y
2094CONFIG_TMPFS_POSIX_ACL=y
2095CONFIG_HUGETLBFS=y
2096CONFIG_HUGETLB_PAGE=y
2097CONFIG_CONFIGFS_FS=m
2098
2099#
2100# Miscellaneous filesystems
2101#
2102# CONFIG_ADFS_FS is not set
2103# CONFIG_AFFS_FS is not set
2104# CONFIG_ECRYPT_FS is not set
2105# CONFIG_HFS_FS is not set
2106# CONFIG_HFSPLUS_FS is not set
2107# CONFIG_BEFS_FS is not set
2108# CONFIG_BFS_FS is not set
2109# CONFIG_EFS_FS is not set
2110# CONFIG_CRAMFS is not set
2111# CONFIG_VXFS_FS is not set
2112# CONFIG_MINIX_FS is not set
2113# CONFIG_OMFS_FS is not set
2114# CONFIG_HPFS_FS is not set
2115# CONFIG_QNX4FS_FS is not set
2116# CONFIG_ROMFS_FS is not set
2117# CONFIG_SYSV_FS is not set
2118# CONFIG_UFS_FS is not set
2119CONFIG_NETWORK_FILESYSTEMS=y
2120# CONFIG_NFS_FS is not set
2121# CONFIG_NFSD is not set
2122# CONFIG_SMB_FS is not set
2123# CONFIG_CIFS is not set
2124# CONFIG_NCP_FS is not set
2125# CONFIG_CODA_FS is not set
2126# CONFIG_AFS_FS is not set
2127
2128#
2129# Partition Types
2130#
2131CONFIG_PARTITION_ADVANCED=y
2132# CONFIG_ACORN_PARTITION is not set
2133CONFIG_OSF_PARTITION=y
2134CONFIG_AMIGA_PARTITION=y
2135# CONFIG_ATARI_PARTITION is not set
2136CONFIG_MAC_PARTITION=y
2137CONFIG_MSDOS_PARTITION=y
2138CONFIG_BSD_DISKLABEL=y
2139CONFIG_MINIX_SUBPARTITION=y
2140CONFIG_SOLARIS_X86_PARTITION=y
2141CONFIG_UNIXWARE_DISKLABEL=y
2142# CONFIG_LDM_PARTITION is not set
2143CONFIG_SGI_PARTITION=y
2144# CONFIG_ULTRIX_PARTITION is not set
2145CONFIG_SUN_PARTITION=y
2146CONFIG_KARMA_PARTITION=y
2147CONFIG_EFI_PARTITION=y
2148# CONFIG_SYSV68_PARTITION is not set
2149CONFIG_NLS=y
2150CONFIG_NLS_DEFAULT="utf8"
2151CONFIG_NLS_CODEPAGE_437=y
2152CONFIG_NLS_CODEPAGE_737=m
2153CONFIG_NLS_CODEPAGE_775=m
2154CONFIG_NLS_CODEPAGE_850=m
2155CONFIG_NLS_CODEPAGE_852=m
2156CONFIG_NLS_CODEPAGE_855=m
2157CONFIG_NLS_CODEPAGE_857=m
2158CONFIG_NLS_CODEPAGE_860=m
2159CONFIG_NLS_CODEPAGE_861=m
2160CONFIG_NLS_CODEPAGE_862=m
2161CONFIG_NLS_CODEPAGE_863=m
2162CONFIG_NLS_CODEPAGE_864=m
2163CONFIG_NLS_CODEPAGE_865=m
2164CONFIG_NLS_CODEPAGE_866=m
2165CONFIG_NLS_CODEPAGE_869=m
2166CONFIG_NLS_CODEPAGE_936=m
2167CONFIG_NLS_CODEPAGE_950=m
2168CONFIG_NLS_CODEPAGE_932=m
2169CONFIG_NLS_CODEPAGE_949=m
2170CONFIG_NLS_CODEPAGE_874=m
2171CONFIG_NLS_ISO8859_8=m
2172CONFIG_NLS_CODEPAGE_1250=m
2173CONFIG_NLS_CODEPAGE_1251=m
2174CONFIG_NLS_ASCII=y
2175CONFIG_NLS_ISO8859_1=m
2176CONFIG_NLS_ISO8859_2=m
2177CONFIG_NLS_ISO8859_3=m
2178CONFIG_NLS_ISO8859_4=m
2179CONFIG_NLS_ISO8859_5=m
2180CONFIG_NLS_ISO8859_6=m
2181CONFIG_NLS_ISO8859_7=m
2182CONFIG_NLS_ISO8859_9=m
2183CONFIG_NLS_ISO8859_13=m
2184CONFIG_NLS_ISO8859_14=m
2185CONFIG_NLS_ISO8859_15=m
2186CONFIG_NLS_KOI8_R=m
2187CONFIG_NLS_KOI8_U=m
2188CONFIG_NLS_UTF8=m
2189# CONFIG_DLM is not set
2190
2191#
2192# Kernel hacking
2193#
2194CONFIG_TRACE_IRQFLAGS_SUPPORT=y
2195CONFIG_PRINTK_TIME=y
2196# CONFIG_ENABLE_WARN_DEPRECATED is not set
2197CONFIG_ENABLE_MUST_CHECK=y
2198CONFIG_FRAME_WARN=1024
2199CONFIG_MAGIC_SYSRQ=y
2200CONFIG_UNUSED_SYMBOLS=y
2201CONFIG_DEBUG_FS=y
2202# CONFIG_HEADERS_CHECK is not set
2203CONFIG_DEBUG_KERNEL=y
2204CONFIG_DEBUG_SHIRQ=y
2205CONFIG_DETECT_SOFTLOCKUP=y
2206# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
2207CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
2208CONFIG_SCHED_DEBUG=y
2209CONFIG_SCHEDSTATS=y
2210CONFIG_TIMER_STATS=y
2211# CONFIG_DEBUG_OBJECTS is not set
2212# CONFIG_DEBUG_SLAB is not set
2213# CONFIG_DEBUG_RT_MUTEXES is not set
2214# CONFIG_RT_MUTEX_TESTER is not set
2215# CONFIG_DEBUG_SPINLOCK is not set
2216# CONFIG_DEBUG_MUTEXES is not set
2217# CONFIG_DEBUG_LOCK_ALLOC is not set
2218# CONFIG_PROVE_LOCKING is not set
2219# CONFIG_LOCK_STAT is not set
2220CONFIG_DEBUG_SPINLOCK_SLEEP=y
2221# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
2222CONFIG_STACKTRACE=y
2223# CONFIG_DEBUG_KOBJECT is not set
2224# CONFIG_DEBUG_HIGHMEM is not set
2225CONFIG_DEBUG_BUGVERBOSE=y
2226# CONFIG_DEBUG_INFO is not set
2227# CONFIG_DEBUG_VM is not set
2228# CONFIG_DEBUG_WRITECOUNT is not set
2229CONFIG_DEBUG_MEMORY_INIT=y
2230CONFIG_DEBUG_LIST=y
2231# CONFIG_DEBUG_SG is not set
2232CONFIG_FRAME_POINTER=y
2233CONFIG_BOOT_PRINTK_DELAY=y
2234# CONFIG_RCU_TORTURE_TEST is not set
2235# CONFIG_BACKTRACE_SELF_TEST is not set
2236# CONFIG_FAULT_INJECTION is not set
2237CONFIG_LATENCYTOP=y
2238CONFIG_SYSCTL_SYSCALL_CHECK=y
2239CONFIG_HAVE_FTRACE=y
2240CONFIG_HAVE_DYNAMIC_FTRACE=y
2241CONFIG_TRACING=y
2242# CONFIG_FTRACE is not set
2243# CONFIG_IRQSOFF_TRACER is not set
2244CONFIG_SYSPROF_TRACER=y
2245# CONFIG_SCHED_TRACER is not set
2246# CONFIG_CONTEXT_SWITCH_TRACER is not set
2247# CONFIG_FTRACE_STARTUP_TEST is not set
2248# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
2249# CONFIG_SAMPLES is not set
2250CONFIG_HAVE_ARCH_KGDB=y
2251# CONFIG_KGDB is not set
2252# CONFIG_STRICT_DEVMEM is not set
2253CONFIG_X86_VERBOSE_BOOTUP=y
2254CONFIG_EARLY_PRINTK=y
2255# CONFIG_DEBUG_STACKOVERFLOW is not set
2256# CONFIG_DEBUG_STACK_USAGE is not set
2257# CONFIG_DEBUG_PAGEALLOC is not set
2258# CONFIG_DEBUG_PER_CPU_MAPS is not set
2259CONFIG_X86_PTDUMP=y
2260CONFIG_DEBUG_RODATA=y
2261# CONFIG_DEBUG_RODATA_TEST is not set
2262# CONFIG_DEBUG_NX_TEST is not set
2263# CONFIG_4KSTACKS is not set
2264CONFIG_DOUBLEFAULT=y
2265# CONFIG_MMIOTRACE is not set
2266CONFIG_IO_DELAY_TYPE_0X80=0
2267CONFIG_IO_DELAY_TYPE_0XED=1
2268CONFIG_IO_DELAY_TYPE_UDELAY=2
2269CONFIG_IO_DELAY_TYPE_NONE=3
2270CONFIG_IO_DELAY_0X80=y
2271# CONFIG_IO_DELAY_0XED is not set
2272# CONFIG_IO_DELAY_UDELAY is not set
2273# CONFIG_IO_DELAY_NONE is not set
2274CONFIG_DEFAULT_IO_DELAY_TYPE=0
2275CONFIG_DEBUG_BOOT_PARAMS=y
2276# CONFIG_CPA_DEBUG is not set
2277# CONFIG_OPTIMIZE_INLINING is not set
2278
2279#
2280# Security options
2281#
2282CONFIG_KEYS=y
2283CONFIG_KEYS_DEBUG_PROC_KEYS=y
2284CONFIG_SECURITY=y
2285CONFIG_SECURITY_NETWORK=y
2286CONFIG_SECURITY_NETWORK_XFRM=y
2287CONFIG_SECURITY_FILE_CAPABILITIES=y
2288# CONFIG_SECURITY_ROOTPLUG is not set
2289CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536
2290# CONFIG_SECURITY_SELINUX is not set
2291# CONFIG_SECURITY_SMACK is not set
2292CONFIG_CRYPTO=y
2293
2294#
2295# Crypto core or helper
2296#
2297CONFIG_CRYPTO_ALGAPI=y
2298CONFIG_CRYPTO_AEAD=m
2299CONFIG_CRYPTO_BLKCIPHER=m
2300CONFIG_CRYPTO_HASH=y
2301CONFIG_CRYPTO_MANAGER=y
2302CONFIG_CRYPTO_GF128MUL=m
2303CONFIG_CRYPTO_NULL=m
2304# CONFIG_CRYPTO_CRYPTD is not set
2305CONFIG_CRYPTO_AUTHENC=m
2306CONFIG_CRYPTO_TEST=m
2307
2308#
2309# Authenticated Encryption with Associated Data
2310#
2311CONFIG_CRYPTO_CCM=m
2312CONFIG_CRYPTO_GCM=m
2313CONFIG_CRYPTO_SEQIV=m
2314
2315#
2316# Block modes
2317#
2318CONFIG_CRYPTO_CBC=m
2319CONFIG_CRYPTO_CTR=m
2320# CONFIG_CRYPTO_CTS is not set
2321CONFIG_CRYPTO_ECB=m
2322CONFIG_CRYPTO_LRW=m
2323CONFIG_CRYPTO_PCBC=m
2324CONFIG_CRYPTO_XTS=m
2325
2326#
2327# Hash modes
2328#
2329CONFIG_CRYPTO_HMAC=y
2330CONFIG_CRYPTO_XCBC=m
2331
2332#
2333# Digest
2334#
2335CONFIG_CRYPTO_CRC32C=m
2336CONFIG_CRYPTO_MD4=m
2337CONFIG_CRYPTO_MD5=y
2338CONFIG_CRYPTO_MICHAEL_MIC=m
2339# CONFIG_CRYPTO_RMD128 is not set
2340# CONFIG_CRYPTO_RMD160 is not set
2341# CONFIG_CRYPTO_RMD256 is not set
2342# CONFIG_CRYPTO_RMD320 is not set
2343CONFIG_CRYPTO_SHA1=y
2344CONFIG_CRYPTO_SHA256=m
2345CONFIG_CRYPTO_SHA512=m
2346CONFIG_CRYPTO_TGR192=m
2347CONFIG_CRYPTO_WP512=m
2348
2349#
2350# Ciphers
2351#
2352CONFIG_CRYPTO_AES=m
2353# CONFIG_CRYPTO_AES_586 is not set
2354CONFIG_CRYPTO_ANUBIS=m
2355CONFIG_CRYPTO_ARC4=m
2356CONFIG_CRYPTO_BLOWFISH=m
2357CONFIG_CRYPTO_CAMELLIA=m
2358CONFIG_CRYPTO_CAST5=m
2359CONFIG_CRYPTO_CAST6=m
2360CONFIG_CRYPTO_DES=m
2361CONFIG_CRYPTO_FCRYPT=m
2362CONFIG_CRYPTO_KHAZAD=m
2363CONFIG_CRYPTO_SALSA20=m
2364# CONFIG_CRYPTO_SALSA20_586 is not set
2365CONFIG_CRYPTO_SEED=m
2366CONFIG_CRYPTO_SERPENT=m
2367CONFIG_CRYPTO_TEA=m
2368CONFIG_CRYPTO_TWOFISH=m
2369CONFIG_CRYPTO_TWOFISH_COMMON=m
2370# CONFIG_CRYPTO_TWOFISH_586 is not set
2371
2372#
2373# Compression
2374#
2375CONFIG_CRYPTO_DEFLATE=m
2376# CONFIG_CRYPTO_LZO is not set
2377CONFIG_CRYPTO_HW=y
2378# CONFIG_CRYPTO_DEV_PADLOCK is not set
2379# CONFIG_CRYPTO_DEV_GEODE is not set
2380# CONFIG_CRYPTO_DEV_HIFN_795X is not set
2381CONFIG_HAVE_KVM=y
2382# CONFIG_VIRTUALIZATION is not set
2383
2384#
2385# Library routines
2386#
2387CONFIG_BITREVERSE=y
2388CONFIG_GENERIC_FIND_FIRST_BIT=y
2389CONFIG_GENERIC_FIND_NEXT_BIT=y
2390CONFIG_CRC_CCITT=m
2391CONFIG_CRC16=m
2392CONFIG_CRC_T10DIF=y
2393CONFIG_CRC_ITU_T=m
2394CONFIG_CRC32=y
2395# CONFIG_CRC7 is not set
2396CONFIG_LIBCRC32C=m
2397CONFIG_AUDIT_GENERIC=y
2398CONFIG_ZLIB_INFLATE=y
2399CONFIG_ZLIB_DEFLATE=m
2400CONFIG_TEXTSEARCH=y
2401CONFIG_TEXTSEARCH_KMP=m
2402CONFIG_TEXTSEARCH_BM=m
2403CONFIG_TEXTSEARCH_FSM=m
2404CONFIG_PLIST=y
2405CONFIG_HAS_IOMEM=y
2406CONFIG_HAS_IOPORT=y
2407CONFIG_HAS_DMA=y
diff --git a/meta/packages/linux/linux-moblin.inc b/meta/packages/linux/linux-moblin.inc
index 802bde26ee..2892a5f7a3 100644
--- a/meta/packages/linux/linux-moblin.inc
+++ b/meta/packages/linux/linux-moblin.inc
@@ -1,4 +1,4 @@
1DESCRIPTION = "2.6 Linux Development Kernel for moblin2 platforms" 1DESCRIPTION = "2.6 Linux Development Kernel for moblin Atom based platforms"
2SECTION = "kernel" 2SECTION = "kernel"
3LICENSE = "GPL" 3LICENSE = "GPL"
4 4
diff --git a/meta/packages/linux/linux-moblin_2.6.27-rc1.bb b/meta/packages/linux/linux-moblin_2.6.27-rc1.bb
index fc507dea1d..7dbea30559 100644
--- a/meta/packages/linux/linux-moblin_2.6.27-rc1.bb
+++ b/meta/packages/linux/linux-moblin_2.6.27-rc1.bb
@@ -2,8 +2,6 @@ require linux-moblin.inc
2 2
3PR = "r4" 3PR = "r4"
4 4
5DEFAULT_PREFERENCE_eee901 = "1"
6
7SRC_URI = "${KERNELORG_MIRROR}pub/linux/kernel/v2.6/linux-2.6.26.tar.bz2 \ 5SRC_URI = "${KERNELORG_MIRROR}pub/linux/kernel/v2.6/linux-2.6.26.tar.bz2 \
8 ${KERNELORG_MIRROR}pub/linux/kernel/v2.6/testing/patch-2.6.27-rc1.bz2;patch=1 \ 6 ${KERNELORG_MIRROR}pub/linux/kernel/v2.6/testing/patch-2.6.27-rc1.bz2;patch=1 \
9 file://0001_Export_shmem_file_setup_for_DRM-GEM.patch;patch=1 \ 7 file://0001_Export_shmem_file_setup_for_DRM-GEM.patch;patch=1 \
diff --git a/meta/packages/linux/linux-moblin_2.6.27-rc6.bb b/meta/packages/linux/linux-moblin_2.6.27-rc6.bb
new file mode 100644
index 0000000000..aae5b1502e
--- /dev/null
+++ b/meta/packages/linux/linux-moblin_2.6.27-rc6.bb
@@ -0,0 +1,54 @@
1require linux-moblin.inc
2
3PR = "r2"
4
5DEFAULT_PREFERENCE = "-1"
6DEFAULT_PREFERENCE_eee901 = "1"
7
8SRC_URI = "${KERNELORG_MIRROR}pub/linux/kernel/v2.6/linux-2.6.26.tar.bz2 \
9 ${KERNELORG_MIRROR}pub/linux/kernel/v2.6/testing/patch-2.6.27-rc6.bz2;patch=1 \
10 file://0001-drm-remove-define-for-non-linux-systems.patch;patch=1 \
11 file://0002-i915-remove-settable-use_mi_batchbuffer_start.patch;patch=1 \
12 file://0003-i915-Ignore-X-server-provided-mmio-address.patch;patch=1 \
13 file://0004-i915-Use-more-consistent-names-for-regs-and-store.patch;patch=1 \
14 file://0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch;patch=1 \
15 file://0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch;patch=1 \
16 file://0007-i915-Initialize-hardware-status-page-at-device-load.patch;patch=1 \
17 file://0008-Add-Intel-ACPI-IGD-OpRegion-support.patch;patch=1 \
18 file://0009-drm-fix-sysfs-error-path.patch;patch=1 \
19 file://0010-i915-separate-suspend-resume-functions.patch;patch=1 \
20 file://0011-drm-vblank-rework.patch;patch=1 \
21 file://0012-Export-shmem_file_setup-for-DRM-GEM.patch;patch=1 \
22 file://0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch;patch=1 \
23 file://0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch;patch=1 \
24 file://0015-i915-Add-chip-set-ID-param.patch;patch=1 \
25 file://0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch;patch=1 \
26 file://0017-i915-Make-use-of-sarea_priv-conditional.patch;patch=1 \
27 file://0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch;patch=1 \
28 file://0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch;patch=1 \
29 file://0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch;patch=1 \
30 file://0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch;patch=1 \
31 file://0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch;patch=1 \
32 file://0023-drm-clean-up-many-sparse-warnings-in-i915.patch;patch=1 \
33 file://0024-fastboot-create-a-asynchronous-initlevel.patch;patch=1 \
34 file://0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch;patch=1 \
35 file://0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch;patch=1 \
36 file://0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch;patch=1 \
37 file://0028-fastboot-sync-the-async-execution-before-late_initc.patch;patch=1 \
38 file://0029-fastboot-make-fastboot-a-config-option.patch;patch=1 \
39 file://0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch;patch=1 \
40 file://0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch;patch=1 \
41 file://0032-fastboot-remove-wait-for-all-devices-before-mounti.patch;patch=1 \
42 file://0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch;patch=1 \
43 file://0034-fastboot-fix-typo-in-init-Kconfig-text.patch;patch=1 \
44 file://0035-fastboot-remove-duplicate-unpack_to_rootfs.patch;patch=1 \
45 file://0036-warning-fix-init-do_mounts_md-c.patch;patch=1 \
46 file://0037-init-initramfs.c-unused-function-when-compiling-wit.patch;patch=1 \
47 file://0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch;patch=1 \
48 file://0039-Add-a-script-to-visualize-the-kernel-boot-process.patch;patch=1 \
49 file://0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch;patch=1 \
50 file://0041-r8169-8101e.patch;patch=1 \
51 file://0042-intelfb-945gme.patch;patch=1 \
52 file://defconfig-eee901"
53
54S = "${WORKDIR}/linux-2.6.26"