summaryrefslogtreecommitdiffstats
path: root/meta-moblin/packages/linux
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2009-02-12 10:21:54 +0000
committerRichard Purdie <rpurdie@linux.intel.com>2009-02-12 10:21:54 +0000
commit1e4f72fcbf6b82a3ccfea4df1d42b71ce28d7fe3 (patch)
treefafb40a8af47377198d44ebf6d04e9e2c1c2eef4 /meta-moblin/packages/linux
parent10f46e011775bec893f22ec88e7f4ee4acccb7db (diff)
downloadpoky-1e4f72fcbf6b82a3ccfea4df1d42b71ce28d7fe3.tar.gz
linux-moblin: Add 2.6.28+2.6.29-rc2 version
Diffstat (limited to 'meta-moblin/packages/linux')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0001-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch61
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0002-fastboot-remove-wait-for-all-devices-before-mounti.patch38
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0003-fastboot-remove-duplicate-unpack_to_rootfs.patch161
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0004-superreadahead-patch.patch66
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0005-fastboot-async-enable-default.patch12
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0006-Revert-drm-i915-GEM-on-PAE-has-problems-disable.patch55
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0007-acer-error-msg.patch17
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/defconfig-menlow3137
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/defconfig-netbook2403
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/psb-driver.patch24644
-rw-r--r--meta-moblin/packages/linux/linux-moblin_2.6.28+2.6.29-rc2.bb24
11 files changed, 30618 insertions, 0 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0001-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0001-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch
new file mode 100644
index 0000000000..8f34a0f3f4
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0001-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch
@@ -0,0 +1,61 @@
1From 0384d086e31092628596af98b1e33fad586cef0a 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--- a/init/main.c 2009-01-07 18:29:11.000000000 -0800
19+++ b/init/main.c 2009-01-07 18:32:08.000000000 -0800
20@@ -837,6 +837,7 @@ static void run_init_process(char *init_
21 */
22 static noinline int init_post(void)
23 {
24+ int retry_count = 1;
25 /* need to finish all async __init code before freeing the memory */
26 async_synchronize_full();
27 free_initmem();
28@@ -859,6 +860,8 @@ static noinline int init_post(void)
29 ramdisk_execute_command);
30 }
31
32+retry:
33+
34 /*
35 * We try each of these until one succeeds.
36 *
37@@ -871,6 +874,23 @@ static noinline int init_post(void)
38 "defaults...\n", execute_command);
39 }
40 run_init_process("/sbin/init");
41+
42+ if (retry_count > 0) {
43+ retry_count--;
44+ /*
45+ * We haven't found init yet... potentially because the device
46+ * is still being probed. We need to
47+ * - flush keventd and friends
48+ * - wait for the known devices to complete their probing
49+ * - try to mount the root fs again
50+ */
51+ flush_scheduled_work();
52+ while (driver_probe_done() != 0)
53+ msleep(100);
54+ prepare_namespace();
55+ goto retry;
56+ }
57+
58 run_init_process("/etc/init");
59 run_init_process("/bin/init");
60 run_init_process("/bin/sh");
61
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0002-fastboot-remove-wait-for-all-devices-before-mounti.patch b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0002-fastboot-remove-wait-for-all-devices-before-mounti.patch
new file mode 100644
index 0000000000..9ea6d62a63
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0002-fastboot-remove-wait-for-all-devices-before-mounti.patch
@@ -0,0 +1,38 @@
1From dce8113d033975f56630cf6d2a6a908cfb66059d 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--- a/init/do_mounts.c 2009-01-07 18:42:10.000000000 -0800
24+++ b/init/do_mounts.c 2009-01-07 18:43:02.000000000 -0800
25@@ -370,10 +370,12 @@ void __init prepare_namespace(void)
26 ssleep(root_delay);
27 }
28
29+#if 0
30 /* wait for the known devices to complete their probing */
31 while (driver_probe_done() != 0)
32 msleep(100);
33+#endif
34 async_synchronize_full();
35
36 md_run_setup();
37
38
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0003-fastboot-remove-duplicate-unpack_to_rootfs.patch b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0003-fastboot-remove-duplicate-unpack_to_rootfs.patch
new file mode 100644
index 0000000000..ea4c617ed9
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0003-fastboot-remove-duplicate-unpack_to_rootfs.patch
@@ -0,0 +1,161 @@
1From 24559ecf972ff482222f6fc152f15468d2380e2d 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 4f5ba75..6b5c1dc 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 #include <linux/utime.h>
30
31@@ -166,8 +167,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@@ -229,10 +228,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@@ -303,8 +298,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@@ -475,10 +468,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@@ -573,10 +565,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@@ -584,13 +623,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@@ -603,7 +644,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.5.1
161
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0004-superreadahead-patch.patch b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0004-superreadahead-patch.patch
new file mode 100644
index 0000000000..e4e2001104
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0004-superreadahead-patch.patch
@@ -0,0 +1,66 @@
1From be9df3282d24a7326bba2eea986c79d822f0e998 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 21 Sep 2008 11:58:27 -0700
4Subject: [PATCH] superreadahead patch
5
6---
7 fs/ext3/ioctl.c | 3 +++
8 fs/ext3/super.c | 1 +
9 include/linux/ext3_fs.h | 1 +
10 include/linux/fs.h | 2 ++
11 4 files changed, 7 insertions(+), 0 deletions(-)
12
13diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
14index b7394d0..c2e7f23 100644
15--- a/fs/ext3/ioctl.c
16+++ b/fs/ext3/ioctl.c
17@@ -290,6 +290,9 @@ group_add_out:
18 mnt_drop_write(filp->f_path.mnt);
19 return err;
20 }
21+ case EXT3_IOC_INODE_JIFFIES: {
22+ return inode->created_when;
23+ }
24
25
26 default:
27diff --git a/fs/ext3/super.c b/fs/ext3/super.c
28index f6c94f2..268dd1d 100644
29--- a/fs/ext3/super.c
30+++ b/fs/ext3/super.c
31@@ -461,6 +461,7 @@ static struct inode *ext3_alloc_inode(struct super_block *sb)
32 #endif
33 ei->i_block_alloc_info = NULL;
34 ei->vfs_inode.i_version = 1;
35+ ei->vfs_inode.created_when = jiffies;
36 return &ei->vfs_inode;
37 }
38
39diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
40index d14f029..fff5510 100644
41--- a/include/linux/ext3_fs.h
42+++ b/include/linux/ext3_fs.h
43@@ -225,6 +225,7 @@ struct ext3_new_group_data {
44 #endif
45 #define EXT3_IOC_GETRSVSZ _IOR('f', 5, long)
46 #define EXT3_IOC_SETRSVSZ _IOW('f', 6, long)
47+#define EXT3_IOC_INODE_JIFFIES _IOR('f', 19, long)
48
49 /*
50 * ioctl commands in 32 bit emulation
51diff --git a/include/linux/fs.h b/include/linux/fs.h
52index 4a853ef..c346136 100644
53--- a/include/linux/fs.h
54+++ b/include/linux/fs.h
55@@ -685,6 +685,8 @@ struct inode {
56 void *i_security;
57 #endif
58 void *i_private; /* fs or device private pointer */
59+
60+ unsigned long created_when; /* jiffies of creation time */
61 };
62
63 /*
64--
651.5.5.1
66
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0005-fastboot-async-enable-default.patch b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0005-fastboot-async-enable-default.patch
new file mode 100644
index 0000000000..6eea4f6e17
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0005-fastboot-async-enable-default.patch
@@ -0,0 +1,12 @@
1--- a/kernel/async.c 2009-01-19 18:30:29.000000000 -0800
2+++ b/kernel/async.c 2009-01-19 18:31:12.000000000 -0800
3@@ -65,7 +65,7 @@ static LIST_HEAD(async_pending);
4 static LIST_HEAD(async_running);
5 static DEFINE_SPINLOCK(async_lock);
6
7-static int async_enabled = 0;
8+static int async_enabled = 1;
9
10 struct async_entry {
11 struct list_head list;
12
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0006-Revert-drm-i915-GEM-on-PAE-has-problems-disable.patch b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0006-Revert-drm-i915-GEM-on-PAE-has-problems-disable.patch
new file mode 100644
index 0000000000..77c9fa6ef3
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0006-Revert-drm-i915-GEM-on-PAE-has-problems-disable.patch
@@ -0,0 +1,55 @@
1From ee977685870767221dc763338bb6ed5fd83f65be Mon Sep 17 00:00:00 2001
2From: Yong Wang <yong.y.wang@intel.com>
3Date: Tue, 6 Jan 2009 15:13:41 +0800
4Subject: [PATCH] Revert "drm/i915: GEM on PAE has problems - disable it for now."
5
6This reverts commit ac5c4e76180a74c7f922f6fa71ace0cef45fa433.
7---
8 drivers/gpu/drm/i915/i915_dma.c | 10 +---------
9 drivers/gpu/drm/i915/i915_drv.h | 2 --
10 2 files changed, 1 insertions(+), 11 deletions(-)
11
12diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
13index afa8a12..553dd4b 100644
14--- a/drivers/gpu/drm/i915/i915_dma.c
15+++ b/drivers/gpu/drm/i915/i915_dma.c
16@@ -717,7 +717,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
17 value = dev->pci_device;
18 break;
19 case I915_PARAM_HAS_GEM:
20- value = dev_priv->has_gem;
21+ value = 1;
22 break;
23 default:
24 DRM_ERROR("Unknown parameter %d\n", param->param);
25@@ -830,14 +830,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
26
27 dev_priv->regs = ioremap(base, size);
28
29-#ifdef CONFIG_HIGHMEM64G
30- /* don't enable GEM on PAE - needs agp + set_memory_* interface fixes */
31- dev_priv->has_gem = 0;
32-#else
33- /* enable GEM by default */
34- dev_priv->has_gem = 1;
35-#endif
36-
37 i915_gem_load(dev);
38
39 /* Init HWS */
40diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
41index b3cc473..adc972c 100644
42--- a/drivers/gpu/drm/i915/i915_drv.h
43+++ b/drivers/gpu/drm/i915/i915_drv.h
44@@ -106,8 +106,6 @@ struct intel_opregion {
45 typedef struct drm_i915_private {
46 struct drm_device *dev;
47
48- int has_gem;
49-
50 void __iomem *regs;
51 drm_local_map_t *sarea;
52
53--
541.5.5.1
55
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0007-acer-error-msg.patch b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0007-acer-error-msg.patch
new file mode 100644
index 0000000000..7bf897ab57
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/0007-acer-error-msg.patch
@@ -0,0 +1,17 @@
1From: Arjan van de Ven <arjan@linux.intel.com>
2Date: Fri, 23 Jan 2009
3
4Small fix changing error msg to info msg in acer wmi driver
5---
6diff -durp a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
7--- a/drivers/platform/x86/acer-wmi.c 2009-01-23 13:58:36.000000000 -0800
8+++ b/drivers/platform/x86/acer-wmi.c 2009-01-23 14:00:12.000000000 -0800
9@@ -1290,7 +1290,7 @@ static int __init acer_wmi_init(void)
10 AMW0_find_mailled();
11
12 if (!interface) {
13- printk(ACER_ERR "No or unsupported WMI interface, unable to "
14+ printk(ACER_INFO "No or unsupported WMI interface, unable to "
15 "load\n");
16 return -ENODEV;
17 }
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/defconfig-menlow b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/defconfig-menlow
new file mode 100644
index 0000000000..30c1656220
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/defconfig-menlow
@@ -0,0 +1,3137 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.27
4# Wed Jan 14 11:45:36 2009
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="-default"
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
74# CONFIG_TASK_XACCT is not set
75CONFIG_AUDIT=y
76CONFIG_AUDITSYSCALL=y
77CONFIG_AUDIT_TREE=y
78CONFIG_IKCONFIG=y
79CONFIG_IKCONFIG_PROC=y
80CONFIG_LOG_BUF_SHIFT=15
81# CONFIG_CGROUPS is not set
82CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
83# CONFIG_GROUP_SCHED is not set
84CONFIG_SYSFS_DEPRECATED=y
85CONFIG_SYSFS_DEPRECATED_V2=y
86CONFIG_RELAY=y
87CONFIG_NAMESPACES=y
88# CONFIG_UTS_NS is not set
89# CONFIG_IPC_NS is not set
90# CONFIG_USER_NS is not set
91# CONFIG_PID_NS is not set
92CONFIG_BLK_DEV_INITRD=y
93CONFIG_INITRAMFS_SOURCE=""
94CONFIG_CC_OPTIMIZE_FOR_SIZE=y
95# CONFIG_FASTBOOT is not set
96CONFIG_SYSCTL=y
97# CONFIG_EMBEDDED is not set
98CONFIG_UID16=y
99CONFIG_SYSCTL_SYSCALL=y
100CONFIG_KALLSYMS=y
101CONFIG_KALLSYMS_ALL=y
102# CONFIG_KALLSYMS_EXTRA_PASS is not set
103CONFIG_HOTPLUG=y
104CONFIG_PRINTK=y
105CONFIG_BUG=y
106CONFIG_ELF_CORE=y
107CONFIG_PCSPKR_PLATFORM=y
108CONFIG_COMPAT_BRK=y
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
143CONFIG_MODULE_FORCE_UNLOAD=y
144CONFIG_MODVERSIONS=y
145CONFIG_MODULE_SRCVERSION_ALL=y
146CONFIG_KMOD=y
147CONFIG_STOP_MACHINE=y
148CONFIG_BLOCK=y
149CONFIG_LBD=y
150CONFIG_BLK_DEV_IO_TRACE=y
151CONFIG_LSF=y
152# CONFIG_BLK_DEV_BSG is not set
153# CONFIG_BLK_DEV_INTEGRITY is not set
154
155#
156# IO Schedulers
157#
158CONFIG_IOSCHED_NOOP=y
159CONFIG_IOSCHED_AS=y
160CONFIG_IOSCHED_DEADLINE=y
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
179# CONFIG_X86_PC is not set
180# CONFIG_X86_ELAN is not set
181# CONFIG_X86_VOYAGER is not set
182CONFIG_X86_GENERICARCH=y
183# CONFIG_X86_NUMAQ is not set
184# CONFIG_X86_SUMMIT is not set
185# CONFIG_X86_ES7000 is not set
186# CONFIG_X86_BIGSMP is not set
187# CONFIG_X86_VSMP is not set
188# CONFIG_X86_RDC321X is not set
189CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
190# CONFIG_PARAVIRT_GUEST is not set
191# CONFIG_MEMTEST is not set
192CONFIG_X86_CYCLONE_TIMER=y
193# CONFIG_M386 is not set
194# CONFIG_M486 is not set
195CONFIG_M586=y
196# CONFIG_M586TSC is not set
197# CONFIG_M586MMX is not set
198# CONFIG_M686 is not set
199# CONFIG_MPENTIUMII is not set
200# CONFIG_MPENTIUMIII is not set
201# CONFIG_MPENTIUMM is not set
202# CONFIG_MPENTIUM4 is not set
203# CONFIG_MK6 is not set
204# CONFIG_MK7 is not set
205# CONFIG_MK8 is not set
206# CONFIG_MCRUSOE is not set
207# CONFIG_MEFFICEON is not set
208# CONFIG_MWINCHIPC6 is not set
209# CONFIG_MWINCHIP2 is not set
210# CONFIG_MWINCHIP3D is not set
211# CONFIG_MGEODEGX1 is not set
212# CONFIG_MGEODE_LX is not set
213# CONFIG_MCYRIXIII is not set
214# CONFIG_MVIAC3_2 is not set
215# CONFIG_MVIAC7 is not set
216# CONFIG_MPSC is not set
217# CONFIG_MCORE2 is not set
218# CONFIG_GENERIC_CPU is not set
219CONFIG_X86_GENERIC=y
220CONFIG_X86_CPU=y
221CONFIG_X86_CMPXCHG=y
222CONFIG_X86_L1_CACHE_SHIFT=7
223CONFIG_X86_XADD=y
224CONFIG_X86_PPRO_FENCE=y
225CONFIG_X86_F00F_BUG=y
226CONFIG_X86_WP_WORKS_OK=y
227CONFIG_X86_INVLPG=y
228CONFIG_X86_BSWAP=y
229CONFIG_X86_POPAD_OK=y
230CONFIG_X86_ALIGNMENT_16=y
231CONFIG_X86_INTEL_USERCOPY=y
232CONFIG_X86_MINIMUM_CPU_FAMILY=4
233CONFIG_HPET_TIMER=y
234CONFIG_DMI=y
235# CONFIG_IOMMU_HELPER is not set
236CONFIG_NR_CPUS=8
237# CONFIG_SCHED_SMT is not set
238CONFIG_SCHED_MC=y
239# CONFIG_PREEMPT_NONE is not set
240CONFIG_PREEMPT_VOLUNTARY=y
241# CONFIG_PREEMPT is not set
242CONFIG_X86_LOCAL_APIC=y
243CONFIG_X86_IO_APIC=y
244CONFIG_X86_MCE=y
245CONFIG_X86_MCE_NONFATAL=y
246# CONFIG_X86_MCE_P4THERMAL is not set
247CONFIG_VM86=y
248# CONFIG_TOSHIBA is not set
249# CONFIG_I8K is not set
250CONFIG_X86_REBOOTFIXUPS=y
251CONFIG_MICROCODE=m
252CONFIG_MICROCODE_OLD_INTERFACE=y
253CONFIG_X86_MSR=m
254CONFIG_X86_CPUID=m
255# CONFIG_NOHIGHMEM is not set
256CONFIG_HIGHMEM4G=y
257# CONFIG_HIGHMEM64G is not set
258CONFIG_PAGE_OFFSET=0xC0000000
259CONFIG_HIGHMEM=y
260CONFIG_SELECT_MEMORY_MODEL=y
261CONFIG_FLATMEM_MANUAL=y
262# CONFIG_DISCONTIGMEM_MANUAL is not set
263# CONFIG_SPARSEMEM_MANUAL is not set
264CONFIG_FLATMEM=y
265CONFIG_FLAT_NODE_MEM_MAP=y
266# CONFIG_SPARSEMEM_STATIC is not set
267# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
268CONFIG_PAGEFLAGS_EXTENDED=y
269CONFIG_SPLIT_PTLOCK_CPUS=4
270# CONFIG_RESOURCES_64BIT is not set
271CONFIG_ZONE_DMA_FLAG=1
272CONFIG_BOUNCE=y
273CONFIG_VIRT_TO_BUS=y
274CONFIG_HIGHPTE=y
275# CONFIG_MATH_EMULATION is not set
276CONFIG_MTRR=y
277# CONFIG_MTRR_SANITIZER is not set
278# CONFIG_X86_PAT is not set
279CONFIG_EFI=y
280# CONFIG_IRQBALANCE is not set
281CONFIG_SECCOMP=y
282# CONFIG_HZ_100 is not set
283CONFIG_HZ_250=y
284# CONFIG_HZ_300 is not set
285# CONFIG_HZ_1000 is not set
286CONFIG_HZ=250
287CONFIG_SCHED_HRTICK=y
288CONFIG_KEXEC=y
289# CONFIG_CRASH_DUMP is not set
290# CONFIG_KEXEC_JUMP is not set
291CONFIG_PHYSICAL_START=0x100000
292# CONFIG_RELOCATABLE is not set
293CONFIG_PHYSICAL_ALIGN=0x100000
294CONFIG_HOTPLUG_CPU=y
295CONFIG_COMPAT_VDSO=y
296CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
297
298#
299# Power management options
300#
301CONFIG_PM=y
302# CONFIG_PM_DEBUG is not set
303CONFIG_PM_SLEEP_SMP=y
304CONFIG_PM_SLEEP=y
305CONFIG_SUSPEND=y
306CONFIG_SUSPEND_FREEZER=y
307CONFIG_HIBERNATION=y
308CONFIG_PM_STD_PARTITION=""
309CONFIG_ACPI=y
310CONFIG_ACPI_SLEEP=y
311CONFIG_ACPI_PROCFS=y
312CONFIG_ACPI_PROCFS_POWER=y
313CONFIG_ACPI_SYSFS_POWER=y
314CONFIG_ACPI_PROC_EVENT=y
315CONFIG_ACPI_AC=y
316CONFIG_ACPI_BATTERY=y
317CONFIG_ACPI_BUTTON=y
318CONFIG_ACPI_VIDEO=y
319CONFIG_ACPI_FAN=y
320CONFIG_ACPI_DOCK=y
321# CONFIG_ACPI_BAY is not set
322CONFIG_ACPI_PROCESSOR=y
323CONFIG_ACPI_HOTPLUG_CPU=y
324CONFIG_ACPI_THERMAL=y
325# CONFIG_ACPI_WMI is not set
326# CONFIG_ACPI_ASUS is not set
327# CONFIG_ACPI_TOSHIBA is not set
328CONFIG_ACPI_CUSTOM_DSDT_FILE=""
329# CONFIG_ACPI_CUSTOM_DSDT is not set
330CONFIG_ACPI_BLACKLIST_YEAR=2001
331# CONFIG_ACPI_DEBUG is not set
332CONFIG_ACPI_EC=y
333# CONFIG_ACPI_PCI_SLOT is not set
334CONFIG_ACPI_POWER=y
335CONFIG_ACPI_SYSTEM=y
336CONFIG_X86_PM_TIMER=y
337CONFIG_ACPI_CONTAINER=y
338CONFIG_ACPI_SBS=y
339CONFIG_X86_APM_BOOT=y
340CONFIG_APM=y
341# CONFIG_APM_IGNORE_USER_SUSPEND is not set
342CONFIG_APM_DO_ENABLE=y
343# CONFIG_APM_CPU_IDLE is not set
344CONFIG_APM_DISPLAY_BLANK=y
345CONFIG_APM_ALLOW_INTS=y
346# CONFIG_APM_REAL_MODE_POWER_OFF is not set
347
348#
349# CPU Frequency scaling
350#
351CONFIG_CPU_FREQ=y
352CONFIG_CPU_FREQ_TABLE=y
353# CONFIG_CPU_FREQ_DEBUG is not set
354CONFIG_CPU_FREQ_STAT=m
355CONFIG_CPU_FREQ_STAT_DETAILS=y
356# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
357# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
358CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
359# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
360# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
361CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
362CONFIG_CPU_FREQ_GOV_POWERSAVE=m
363CONFIG_CPU_FREQ_GOV_USERSPACE=y
364CONFIG_CPU_FREQ_GOV_ONDEMAND=m
365CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
366
367#
368# CPUFreq processor drivers
369#
370CONFIG_X86_ACPI_CPUFREQ=y
371# CONFIG_X86_POWERNOW_K6 is not set
372# CONFIG_X86_POWERNOW_K7 is not set
373# CONFIG_X86_POWERNOW_K8 is not set
374# CONFIG_X86_GX_SUSPMOD is not set
375CONFIG_X86_SPEEDSTEP_CENTRINO=m
376CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
377CONFIG_X86_SPEEDSTEP_ICH=m
378CONFIG_X86_SPEEDSTEP_SMI=m
379CONFIG_X86_P4_CLOCKMOD=m
380# CONFIG_X86_CPUFREQ_NFORCE2 is not set
381# CONFIG_X86_LONGRUN is not set
382# CONFIG_X86_LONGHAUL is not set
383# CONFIG_X86_E_POWERSAVER is not set
384
385#
386# shared options
387#
388# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
389CONFIG_X86_SPEEDSTEP_LIB=m
390CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y
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_HOTPLUG_PCI_PCIE=m
410CONFIG_PCIEAER=y
411# CONFIG_PCIEASPM 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
418CONFIG_ISA=y
419# CONFIG_EISA is not set
420# CONFIG_MCA is not set
421# CONFIG_SCx200 is not set
422# CONFIG_OLPC is not set
423# CONFIG_PCCARD is not set
424CONFIG_HOTPLUG_PCI=m
425CONFIG_HOTPLUG_PCI_FAKE=m
426# CONFIG_HOTPLUG_PCI_COMPAQ is not set
427# CONFIG_HOTPLUG_PCI_IBM is not set
428CONFIG_HOTPLUG_PCI_ACPI=m
429CONFIG_HOTPLUG_PCI_ACPI_IBM=m
430CONFIG_HOTPLUG_PCI_CPCI=y
431CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m
432CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m
433CONFIG_HOTPLUG_PCI_SHPC=m
434
435#
436# Executable file formats / Emulations
437#
438CONFIG_BINFMT_ELF=y
439CONFIG_BINFMT_AOUT=m
440CONFIG_BINFMT_MISC=m
441CONFIG_NET=y
442
443#
444# Networking options
445#
446CONFIG_PACKET=m
447CONFIG_PACKET_MMAP=y
448CONFIG_UNIX=y
449CONFIG_XFRM=y
450CONFIG_XFRM_USER=m
451# CONFIG_XFRM_SUB_POLICY is not set
452# CONFIG_XFRM_MIGRATE is not set
453# CONFIG_XFRM_STATISTICS is not set
454CONFIG_XFRM_IPCOMP=m
455CONFIG_NET_KEY=m
456# CONFIG_NET_KEY_MIGRATE is not set
457CONFIG_INET=y
458CONFIG_IP_MULTICAST=y
459CONFIG_IP_ADVANCED_ROUTER=y
460CONFIG_ASK_IP_FIB_HASH=y
461# CONFIG_IP_FIB_TRIE is not set
462CONFIG_IP_FIB_HASH=y
463CONFIG_IP_MULTIPLE_TABLES=y
464CONFIG_IP_ROUTE_MULTIPATH=y
465CONFIG_IP_ROUTE_VERBOSE=y
466CONFIG_IP_PNP=y
467CONFIG_IP_PNP_DHCP=y
468CONFIG_IP_PNP_BOOTP=y
469CONFIG_IP_PNP_RARP=y
470CONFIG_NET_IPIP=m
471CONFIG_NET_IPGRE=m
472CONFIG_NET_IPGRE_BROADCAST=y
473CONFIG_IP_MROUTE=y
474CONFIG_IP_PIMSM_V1=y
475CONFIG_IP_PIMSM_V2=y
476# CONFIG_ARPD is not set
477CONFIG_SYN_COOKIES=y
478CONFIG_INET_AH=m
479CONFIG_INET_ESP=m
480CONFIG_INET_IPCOMP=m
481CONFIG_INET_XFRM_TUNNEL=m
482CONFIG_INET_TUNNEL=m
483CONFIG_INET_XFRM_MODE_TRANSPORT=m
484CONFIG_INET_XFRM_MODE_TUNNEL=m
485CONFIG_INET_XFRM_MODE_BEET=y
486# CONFIG_INET_LRO is not set
487CONFIG_INET_DIAG=m
488CONFIG_INET_TCP_DIAG=m
489CONFIG_TCP_CONG_ADVANCED=y
490CONFIG_TCP_CONG_BIC=m
491CONFIG_TCP_CONG_CUBIC=m
492CONFIG_TCP_CONG_WESTWOOD=m
493CONFIG_TCP_CONG_HTCP=m
494CONFIG_TCP_CONG_HSTCP=m
495CONFIG_TCP_CONG_HYBLA=m
496CONFIG_TCP_CONG_VEGAS=m
497CONFIG_TCP_CONG_SCALABLE=m
498CONFIG_TCP_CONG_LP=m
499CONFIG_TCP_CONG_VENO=m
500# CONFIG_TCP_CONG_YEAH is not set
501# CONFIG_TCP_CONG_ILLINOIS is not set
502# CONFIG_DEFAULT_BIC is not set
503# CONFIG_DEFAULT_CUBIC is not set
504# CONFIG_DEFAULT_HTCP is not set
505# CONFIG_DEFAULT_VEGAS is not set
506# CONFIG_DEFAULT_WESTWOOD is not set
507CONFIG_DEFAULT_RENO=y
508CONFIG_DEFAULT_TCP_CONG="reno"
509# CONFIG_TCP_MD5SIG is not set
510CONFIG_IP_VS=m
511# CONFIG_IP_VS_DEBUG is not set
512CONFIG_IP_VS_TAB_BITS=12
513
514#
515# IPVS transport protocol load balancing support
516#
517CONFIG_IP_VS_PROTO_TCP=y
518CONFIG_IP_VS_PROTO_UDP=y
519CONFIG_IP_VS_PROTO_ESP=y
520CONFIG_IP_VS_PROTO_AH=y
521
522#
523# IPVS scheduler
524#
525CONFIG_IP_VS_RR=m
526CONFIG_IP_VS_WRR=m
527CONFIG_IP_VS_LC=m
528CONFIG_IP_VS_WLC=m
529CONFIG_IP_VS_LBLC=m
530CONFIG_IP_VS_LBLCR=m
531CONFIG_IP_VS_DH=m
532CONFIG_IP_VS_SH=m
533CONFIG_IP_VS_SED=m
534CONFIG_IP_VS_NQ=m
535
536#
537# IPVS application helper
538#
539CONFIG_IP_VS_FTP=m
540CONFIG_IPV6=m
541CONFIG_IPV6_PRIVACY=y
542CONFIG_IPV6_ROUTER_PREF=y
543CONFIG_IPV6_ROUTE_INFO=y
544# CONFIG_IPV6_OPTIMISTIC_DAD is not set
545CONFIG_INET6_AH=m
546CONFIG_INET6_ESP=m
547CONFIG_INET6_IPCOMP=m
548# CONFIG_IPV6_MIP6 is not set
549CONFIG_INET6_XFRM_TUNNEL=m
550CONFIG_INET6_TUNNEL=m
551CONFIG_INET6_XFRM_MODE_TRANSPORT=m
552CONFIG_INET6_XFRM_MODE_TUNNEL=m
553CONFIG_INET6_XFRM_MODE_BEET=m
554# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
555CONFIG_IPV6_SIT=m
556CONFIG_IPV6_NDISC_NODETYPE=y
557CONFIG_IPV6_TUNNEL=m
558# CONFIG_IPV6_MULTIPLE_TABLES is not set
559# CONFIG_IPV6_MROUTE is not set
560# CONFIG_NETLABEL is not set
561CONFIG_NETWORK_SECMARK=y
562CONFIG_NETFILTER=y
563# CONFIG_NETFILTER_DEBUG is not set
564CONFIG_NETFILTER_ADVANCED=y
565CONFIG_BRIDGE_NETFILTER=y
566
567#
568# Core Netfilter Configuration
569#
570CONFIG_NETFILTER_NETLINK=m
571CONFIG_NETFILTER_NETLINK_QUEUE=m
572CONFIG_NETFILTER_NETLINK_LOG=m
573# CONFIG_NF_CONNTRACK is not set
574CONFIG_NETFILTER_XTABLES=m
575CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
576# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
577CONFIG_NETFILTER_XT_TARGET_MARK=m
578CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
579# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
580# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
581# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
582CONFIG_NETFILTER_XT_TARGET_SECMARK=m
583# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
584# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
585CONFIG_NETFILTER_XT_MATCH_COMMENT=m
586CONFIG_NETFILTER_XT_MATCH_DCCP=m
587# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
588CONFIG_NETFILTER_XT_MATCH_ESP=m
589# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
590CONFIG_NETFILTER_XT_MATCH_LENGTH=m
591CONFIG_NETFILTER_XT_MATCH_LIMIT=m
592CONFIG_NETFILTER_XT_MATCH_MAC=m
593CONFIG_NETFILTER_XT_MATCH_MARK=m
594# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
595CONFIG_NETFILTER_XT_MATCH_POLICY=m
596CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
597CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
598CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
599CONFIG_NETFILTER_XT_MATCH_QUOTA=m
600# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
601CONFIG_NETFILTER_XT_MATCH_REALM=m
602CONFIG_NETFILTER_XT_MATCH_SCTP=m
603CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
604CONFIG_NETFILTER_XT_MATCH_STRING=m
605CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
606# CONFIG_NETFILTER_XT_MATCH_TIME is not set
607# CONFIG_NETFILTER_XT_MATCH_U32 is not set
608# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
609
610#
611# IP: Netfilter Configuration
612#
613CONFIG_IP_NF_QUEUE=m
614CONFIG_IP_NF_IPTABLES=m
615CONFIG_IP_NF_MATCH_RECENT=m
616CONFIG_IP_NF_MATCH_ECN=m
617CONFIG_IP_NF_MATCH_AH=m
618CONFIG_IP_NF_MATCH_TTL=m
619CONFIG_IP_NF_MATCH_ADDRTYPE=m
620CONFIG_IP_NF_FILTER=m
621CONFIG_IP_NF_TARGET_REJECT=m
622CONFIG_IP_NF_TARGET_LOG=m
623CONFIG_IP_NF_TARGET_ULOG=m
624CONFIG_IP_NF_MANGLE=m
625CONFIG_IP_NF_TARGET_ECN=m
626CONFIG_IP_NF_TARGET_TTL=m
627CONFIG_IP_NF_RAW=m
628# CONFIG_IP_NF_SECURITY is not set
629CONFIG_IP_NF_ARPTABLES=m
630CONFIG_IP_NF_ARPFILTER=m
631CONFIG_IP_NF_ARP_MANGLE=m
632
633#
634# IPv6: Netfilter Configuration
635#
636CONFIG_IP6_NF_QUEUE=m
637CONFIG_IP6_NF_IPTABLES=m
638CONFIG_IP6_NF_MATCH_RT=m
639CONFIG_IP6_NF_MATCH_OPTS=m
640CONFIG_IP6_NF_MATCH_FRAG=m
641CONFIG_IP6_NF_MATCH_HL=m
642CONFIG_IP6_NF_MATCH_IPV6HEADER=m
643CONFIG_IP6_NF_MATCH_AH=m
644# CONFIG_IP6_NF_MATCH_MH is not set
645CONFIG_IP6_NF_MATCH_EUI64=m
646CONFIG_IP6_NF_FILTER=m
647CONFIG_IP6_NF_TARGET_LOG=m
648CONFIG_IP6_NF_TARGET_REJECT=m
649CONFIG_IP6_NF_MANGLE=m
650CONFIG_IP6_NF_TARGET_HL=m
651CONFIG_IP6_NF_RAW=m
652# CONFIG_IP6_NF_SECURITY is not set
653
654#
655# DECnet: Netfilter Configuration
656#
657CONFIG_DECNET_NF_GRABULATOR=m
658
659#
660# Bridge: Netfilter Configuration
661#
662CONFIG_BRIDGE_NF_EBTABLES=m
663CONFIG_BRIDGE_EBT_BROUTE=m
664CONFIG_BRIDGE_EBT_T_FILTER=m
665CONFIG_BRIDGE_EBT_T_NAT=m
666CONFIG_BRIDGE_EBT_802_3=m
667CONFIG_BRIDGE_EBT_AMONG=m
668CONFIG_BRIDGE_EBT_ARP=m
669CONFIG_BRIDGE_EBT_IP=m
670# CONFIG_BRIDGE_EBT_IP6 is not set
671CONFIG_BRIDGE_EBT_LIMIT=m
672CONFIG_BRIDGE_EBT_MARK=m
673CONFIG_BRIDGE_EBT_PKTTYPE=m
674CONFIG_BRIDGE_EBT_STP=m
675CONFIG_BRIDGE_EBT_VLAN=m
676CONFIG_BRIDGE_EBT_ARPREPLY=m
677CONFIG_BRIDGE_EBT_DNAT=m
678CONFIG_BRIDGE_EBT_MARK_T=m
679CONFIG_BRIDGE_EBT_REDIRECT=m
680CONFIG_BRIDGE_EBT_SNAT=m
681CONFIG_BRIDGE_EBT_LOG=m
682CONFIG_BRIDGE_EBT_ULOG=m
683# CONFIG_BRIDGE_EBT_NFLOG is not set
684CONFIG_IP_DCCP=m
685CONFIG_INET_DCCP_DIAG=m
686CONFIG_IP_DCCP_ACKVEC=y
687
688#
689# DCCP CCIDs Configuration (EXPERIMENTAL)
690#
691CONFIG_IP_DCCP_CCID2=m
692# CONFIG_IP_DCCP_CCID2_DEBUG is not set
693CONFIG_IP_DCCP_CCID3=m
694# CONFIG_IP_DCCP_CCID3_DEBUG is not set
695CONFIG_IP_DCCP_CCID3_RTO=100
696CONFIG_IP_DCCP_TFRC_LIB=m
697
698#
699# DCCP Kernel Hacking
700#
701# CONFIG_IP_DCCP_DEBUG is not set
702CONFIG_IP_SCTP=m
703# CONFIG_SCTP_DBG_MSG is not set
704# CONFIG_SCTP_DBG_OBJCNT is not set
705# CONFIG_SCTP_HMAC_NONE is not set
706# CONFIG_SCTP_HMAC_SHA1 is not set
707CONFIG_SCTP_HMAC_MD5=y
708# CONFIG_TIPC is not set
709CONFIG_ATM=m
710CONFIG_ATM_CLIP=m
711CONFIG_ATM_CLIP_NO_ICMP=y
712CONFIG_ATM_LANE=m
713CONFIG_ATM_MPOA=m
714CONFIG_ATM_BR2684=m
715# CONFIG_ATM_BR2684_IPFILTER is not set
716CONFIG_STP=m
717CONFIG_BRIDGE=m
718CONFIG_VLAN_8021Q=m
719# CONFIG_VLAN_8021Q_GVRP is not set
720CONFIG_DECNET=m
721CONFIG_DECNET_ROUTER=y
722CONFIG_LLC=m
723CONFIG_LLC2=m
724CONFIG_IPX=m
725# CONFIG_IPX_INTERN is not set
726CONFIG_ATALK=m
727CONFIG_DEV_APPLETALK=m
728CONFIG_LTPC=m
729CONFIG_COPS=m
730CONFIG_COPS_DAYNA=y
731CONFIG_COPS_TANGENT=y
732CONFIG_IPDDP=m
733CONFIG_IPDDP_ENCAP=y
734CONFIG_IPDDP_DECAP=y
735CONFIG_X25=m
736CONFIG_LAPB=m
737CONFIG_ECONET=m
738# CONFIG_ECONET_AUNUDP is not set
739# CONFIG_ECONET_NATIVE is not set
740CONFIG_WAN_ROUTER=m
741CONFIG_NET_SCHED=y
742
743#
744# Queueing/Scheduling
745#
746CONFIG_NET_SCH_CBQ=m
747CONFIG_NET_SCH_HTB=m
748CONFIG_NET_SCH_HFSC=m
749CONFIG_NET_SCH_ATM=m
750CONFIG_NET_SCH_PRIO=m
751CONFIG_NET_SCH_RED=m
752CONFIG_NET_SCH_SFQ=m
753CONFIG_NET_SCH_TEQL=m
754CONFIG_NET_SCH_TBF=m
755CONFIG_NET_SCH_GRED=m
756CONFIG_NET_SCH_DSMARK=m
757CONFIG_NET_SCH_NETEM=m
758CONFIG_NET_SCH_INGRESS=m
759
760#
761# Classification
762#
763CONFIG_NET_CLS=y
764CONFIG_NET_CLS_BASIC=m
765CONFIG_NET_CLS_TCINDEX=m
766CONFIG_NET_CLS_ROUTE4=m
767CONFIG_NET_CLS_ROUTE=y
768CONFIG_NET_CLS_FW=m
769CONFIG_NET_CLS_U32=m
770CONFIG_CLS_U32_PERF=y
771CONFIG_CLS_U32_MARK=y
772CONFIG_NET_CLS_RSVP=m
773CONFIG_NET_CLS_RSVP6=m
774# CONFIG_NET_CLS_FLOW is not set
775# CONFIG_NET_EMATCH is not set
776CONFIG_NET_CLS_ACT=y
777CONFIG_NET_ACT_POLICE=m
778CONFIG_NET_ACT_GACT=m
779CONFIG_GACT_PROB=y
780CONFIG_NET_ACT_MIRRED=m
781CONFIG_NET_ACT_IPT=m
782# CONFIG_NET_ACT_NAT is not set
783CONFIG_NET_ACT_PEDIT=m
784CONFIG_NET_ACT_SIMP=m
785# CONFIG_NET_CLS_IND is not set
786CONFIG_NET_SCH_FIFO=y
787
788#
789# Network testing
790#
791CONFIG_NET_PKTGEN=m
792# CONFIG_HAMRADIO is not set
793# CONFIG_CAN is not set
794# CONFIG_IRDA is not set
795CONFIG_BT=m
796CONFIG_BT_L2CAP=m
797CONFIG_BT_SCO=m
798CONFIG_BT_RFCOMM=m
799CONFIG_BT_RFCOMM_TTY=y
800CONFIG_BT_BNEP=m
801CONFIG_BT_BNEP_MC_FILTER=y
802CONFIG_BT_BNEP_PROTO_FILTER=y
803CONFIG_BT_HIDP=m
804
805#
806# Bluetooth device drivers
807#
808CONFIG_BT_HCIUSB=m
809CONFIG_BT_HCIUSB_SCO=y
810# CONFIG_BT_HCIBTUSB is not set
811# CONFIG_BT_HCIBTSDIO is not set
812CONFIG_BT_HCIUART=m
813CONFIG_BT_HCIUART_H4=y
814CONFIG_BT_HCIUART_BCSP=y
815# CONFIG_BT_HCIUART_LL is not set
816CONFIG_BT_HCIBCM203X=m
817CONFIG_BT_HCIBPA10X=m
818CONFIG_BT_HCIBFUSB=m
819CONFIG_BT_HCIVHCI=m
820# CONFIG_AF_RXRPC is not set
821CONFIG_FIB_RULES=y
822
823#
824# Wireless
825#
826# CONFIG_CFG80211 is not set
827CONFIG_WIRELESS_EXT=y
828CONFIG_WIRELESS_EXT_SYSFS=y
829# CONFIG_MAC80211 is not set
830CONFIG_IEEE80211=m
831# CONFIG_IEEE80211_DEBUG is not set
832CONFIG_IEEE80211_CRYPT_WEP=m
833CONFIG_IEEE80211_CRYPT_CCMP=m
834CONFIG_IEEE80211_CRYPT_TKIP=m
835# CONFIG_RFKILL is not set
836# CONFIG_NET_9P is not set
837
838#
839# Device Drivers
840#
841
842#
843# Generic Driver Options
844#
845CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
846# CONFIG_STANDALONE is not set
847CONFIG_PREVENT_FIRMWARE_BUILD=y
848CONFIG_FW_LOADER=y
849CONFIG_FIRMWARE_IN_KERNEL=y
850CONFIG_EXTRA_FIRMWARE=""
851# CONFIG_DEBUG_DRIVER is not set
852# CONFIG_DEBUG_DEVRES is not set
853# CONFIG_SYS_HYPERVISOR is not set
854CONFIG_CONNECTOR=y
855CONFIG_PROC_EVENTS=y
856CONFIG_MTD=m
857# CONFIG_MTD_DEBUG is not set
858CONFIG_MTD_CONCAT=m
859CONFIG_MTD_PARTITIONS=y
860CONFIG_MTD_REDBOOT_PARTS=m
861CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
862# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
863# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
864# CONFIG_MTD_AR7_PARTS is not set
865
866#
867# User Modules And Translation Layers
868#
869CONFIG_MTD_CHAR=m
870CONFIG_MTD_BLKDEVS=m
871CONFIG_MTD_BLOCK=m
872# CONFIG_MTD_BLOCK_RO is not set
873# CONFIG_FTL is not set
874# CONFIG_NFTL is not set
875# CONFIG_INFTL is not set
876CONFIG_RFD_FTL=m
877# CONFIG_SSFDC is not set
878# CONFIG_MTD_OOPS is not set
879
880#
881# RAM/ROM/Flash chip drivers
882#
883CONFIG_MTD_CFI=m
884CONFIG_MTD_JEDECPROBE=m
885CONFIG_MTD_GEN_PROBE=m
886CONFIG_MTD_CFI_ADV_OPTIONS=y
887CONFIG_MTD_CFI_NOSWAP=y
888# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
889# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
890# CONFIG_MTD_CFI_GEOMETRY is not set
891CONFIG_MTD_MAP_BANK_WIDTH_1=y
892CONFIG_MTD_MAP_BANK_WIDTH_2=y
893CONFIG_MTD_MAP_BANK_WIDTH_4=y
894# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
895# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
896# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
897CONFIG_MTD_CFI_I1=y
898CONFIG_MTD_CFI_I2=y
899# CONFIG_MTD_CFI_I4 is not set
900# CONFIG_MTD_CFI_I8 is not set
901# CONFIG_MTD_OTP is not set
902CONFIG_MTD_CFI_INTELEXT=m
903CONFIG_MTD_CFI_AMDSTD=m
904CONFIG_MTD_CFI_STAA=m
905CONFIG_MTD_CFI_UTIL=m
906# CONFIG_MTD_RAM is not set
907# CONFIG_MTD_ROM is not set
908CONFIG_MTD_ABSENT=m
909
910#
911# Mapping drivers for chip access
912#
913CONFIG_MTD_COMPLEX_MAPPINGS=y
914CONFIG_MTD_PHYSMAP=m
915CONFIG_MTD_PHYSMAP_START=0x8000000
916CONFIG_MTD_PHYSMAP_LEN=0x4000000
917CONFIG_MTD_PHYSMAP_BANKWIDTH=2
918CONFIG_MTD_SC520CDP=m
919CONFIG_MTD_NETSC520=m
920CONFIG_MTD_TS5500=m
921CONFIG_MTD_SBC_GXX=m
922CONFIG_MTD_AMD76XROM=m
923CONFIG_MTD_ICHXROM=m
924# CONFIG_MTD_ESB2ROM is not set
925# CONFIG_MTD_CK804XROM is not set
926CONFIG_MTD_SCB2_FLASH=m
927CONFIG_MTD_NETtel=m
928CONFIG_MTD_DILNETPC=m
929CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000
930CONFIG_MTD_L440GX=m
931CONFIG_MTD_PCI=m
932# CONFIG_MTD_INTEL_VR_NOR is not set
933# CONFIG_MTD_PLATRAM is not set
934
935#
936# Self-contained MTD device drivers
937#
938CONFIG_MTD_PMC551=m
939CONFIG_MTD_PMC551_BUGFIX=y
940# CONFIG_MTD_PMC551_DEBUG is not set
941# CONFIG_MTD_DATAFLASH is not set
942# CONFIG_MTD_M25P80 is not set
943CONFIG_MTD_SLRAM=m
944CONFIG_MTD_PHRAM=m
945CONFIG_MTD_MTDRAM=m
946CONFIG_MTDRAM_TOTAL_SIZE=4096
947CONFIG_MTDRAM_ERASE_SIZE=128
948CONFIG_MTD_BLOCK2MTD=m
949
950#
951# Disk-On-Chip Device Drivers
952#
953CONFIG_MTD_DOC2000=m
954CONFIG_MTD_DOC2001=m
955CONFIG_MTD_DOC2001PLUS=m
956CONFIG_MTD_DOCPROBE=m
957CONFIG_MTD_DOCECC=m
958CONFIG_MTD_DOCPROBE_ADVANCED=y
959CONFIG_MTD_DOCPROBE_ADDRESS=0x0000
960CONFIG_MTD_DOCPROBE_HIGH=y
961CONFIG_MTD_DOCPROBE_55AA=y
962CONFIG_MTD_NAND=m
963# CONFIG_MTD_NAND_VERIFY_WRITE is not set
964CONFIG_MTD_NAND_ECC_SMC=y
965# CONFIG_MTD_NAND_MUSEUM_IDS is not set
966CONFIG_MTD_NAND_IDS=m
967CONFIG_MTD_NAND_DISKONCHIP=m
968# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
969CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
970CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
971# CONFIG_MTD_NAND_CAFE is not set
972CONFIG_MTD_NAND_CS553X=m
973CONFIG_MTD_NAND_NANDSIM=m
974# CONFIG_MTD_NAND_PLATFORM is not set
975# CONFIG_MTD_ALAUDA is not set
976CONFIG_MTD_ONENAND=m
977# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
978CONFIG_MTD_ONENAND_OTP=y
979# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
980# CONFIG_MTD_ONENAND_SIM is not set
981
982#
983# UBI - Unsorted block images
984#
985# CONFIG_MTD_UBI is not set
986# CONFIG_PARPORT is not set
987CONFIG_PNP=y
988# CONFIG_PNP_DEBUG is not set
989
990#
991# Protocols
992#
993# CONFIG_ISAPNP is not set
994CONFIG_PNPBIOS=y
995CONFIG_PNPBIOS_PROC_FS=y
996CONFIG_PNPACPI=y
997CONFIG_BLK_DEV=y
998# CONFIG_BLK_DEV_FD is not set
999CONFIG_BLK_DEV_XD=m
1000CONFIG_BLK_CPQ_DA=m
1001CONFIG_BLK_CPQ_CISS_DA=m
1002CONFIG_CISS_SCSI_TAPE=y
1003CONFIG_BLK_DEV_DAC960=m
1004CONFIG_BLK_DEV_UMEM=m
1005# CONFIG_BLK_DEV_COW_COMMON is not set
1006CONFIG_BLK_DEV_LOOP=y
1007CONFIG_BLK_DEV_CRYPTOLOOP=m
1008CONFIG_BLK_DEV_NBD=m
1009CONFIG_BLK_DEV_SX8=m
1010# CONFIG_BLK_DEV_UB is not set
1011CONFIG_BLK_DEV_RAM=y
1012CONFIG_BLK_DEV_RAM_COUNT=16
1013CONFIG_BLK_DEV_RAM_SIZE=64000
1014# CONFIG_BLK_DEV_XIP is not set
1015CONFIG_CDROM_PKTCDVD=m
1016CONFIG_CDROM_PKTCDVD_BUFFERS=8
1017CONFIG_CDROM_PKTCDVD_WCACHE=y
1018CONFIG_ATA_OVER_ETH=m
1019# CONFIG_BLK_DEV_HD is not set
1020CONFIG_MISC_DEVICES=y
1021# CONFIG_IBM_ASM is not set
1022# CONFIG_PHANTOM is not set
1023# CONFIG_EEPROM_93CX6 is not set
1024# CONFIG_SGI_IOC4 is not set
1025# CONFIG_TIFM_CORE is not set
1026# CONFIG_ACER_WMI is not set
1027# CONFIG_ASUS_LAPTOP is not set
1028# CONFIG_FUJITSU_LAPTOP is not set
1029# CONFIG_TC1100_WMI is not set
1030# CONFIG_MSI_LAPTOP is not set
1031# CONFIG_COMPAL_LAPTOP is not set
1032# CONFIG_SONY_LAPTOP is not set
1033# CONFIG_THINKPAD_ACPI is not set
1034# CONFIG_INTEL_MENLOW is not set
1035# CONFIG_EEEPC_LAPTOP is not set
1036# CONFIG_ENCLOSURE_SERVICES is not set
1037# CONFIG_HP_ILO is not set
1038CONFIG_HAVE_IDE=y
1039# CONFIG_IDE is not set
1040
1041#
1042# SCSI device support
1043#
1044CONFIG_RAID_ATTRS=m
1045CONFIG_SCSI=y
1046CONFIG_SCSI_DMA=y
1047# CONFIG_SCSI_TGT is not set
1048CONFIG_SCSI_NETLINK=y
1049CONFIG_SCSI_PROC_FS=y
1050
1051#
1052# SCSI support type (disk, tape, CD-ROM)
1053#
1054CONFIG_BLK_DEV_SD=y
1055CONFIG_CHR_DEV_ST=m
1056CONFIG_CHR_DEV_OSST=m
1057CONFIG_BLK_DEV_SR=y
1058# CONFIG_BLK_DEV_SR_VENDOR is not set
1059CONFIG_CHR_DEV_SG=y
1060CONFIG_CHR_DEV_SCH=m
1061
1062#
1063# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
1064#
1065CONFIG_SCSI_MULTI_LUN=y
1066CONFIG_SCSI_CONSTANTS=y
1067CONFIG_SCSI_LOGGING=y
1068# CONFIG_SCSI_SCAN_ASYNC is not set
1069CONFIG_SCSI_WAIT_SCAN=m
1070
1071#
1072# SCSI Transports
1073#
1074CONFIG_SCSI_SPI_ATTRS=m
1075CONFIG_SCSI_FC_ATTRS=m
1076CONFIG_SCSI_ISCSI_ATTRS=m
1077# CONFIG_SCSI_SAS_LIBSAS is not set
1078# CONFIG_SCSI_SRP_ATTRS is not set
1079CONFIG_SCSI_LOWLEVEL=y
1080# CONFIG_ISCSI_TCP is not set
1081# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
1082# CONFIG_SCSI_3W_9XXX is not set
1083# CONFIG_SCSI_7000FASST is not set
1084# CONFIG_SCSI_ACARD is not set
1085# CONFIG_SCSI_AHA152X is not set
1086# CONFIG_SCSI_AHA1542 is not set
1087# CONFIG_SCSI_AACRAID is not set
1088# CONFIG_SCSI_AIC7XXX is not set
1089# CONFIG_SCSI_AIC7XXX_OLD is not set
1090# CONFIG_SCSI_AIC79XX is not set
1091# CONFIG_SCSI_AIC94XX is not set
1092# CONFIG_SCSI_DPT_I2O is not set
1093# CONFIG_SCSI_ADVANSYS is not set
1094# CONFIG_SCSI_IN2000 is not set
1095# CONFIG_SCSI_ARCMSR is not set
1096# CONFIG_MEGARAID_NEWGEN is not set
1097# CONFIG_MEGARAID_LEGACY is not set
1098# CONFIG_MEGARAID_SAS is not set
1099# CONFIG_SCSI_HPTIOP is not set
1100# CONFIG_SCSI_BUSLOGIC is not set
1101# CONFIG_SCSI_DMX3191D is not set
1102# CONFIG_SCSI_DTC3280 is not set
1103# CONFIG_SCSI_EATA is not set
1104# CONFIG_SCSI_FUTURE_DOMAIN is not set
1105CONFIG_SCSI_GDTH=m
1106# CONFIG_SCSI_GENERIC_NCR5380 is not set
1107# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
1108# CONFIG_SCSI_IPS is not set
1109# CONFIG_SCSI_INITIO is not set
1110# CONFIG_SCSI_INIA100 is not set
1111# CONFIG_SCSI_MVSAS is not set
1112# CONFIG_SCSI_NCR53C406A is not set
1113# CONFIG_SCSI_STEX is not set
1114# CONFIG_SCSI_SYM53C8XX_2 is not set
1115# CONFIG_SCSI_IPR is not set
1116# CONFIG_SCSI_PAS16 is not set
1117# CONFIG_SCSI_QLOGIC_FAS is not set
1118# CONFIG_SCSI_QLOGIC_1280 is not set
1119# CONFIG_SCSI_QLA_FC is not set
1120# CONFIG_SCSI_QLA_ISCSI is not set
1121# CONFIG_SCSI_LPFC is not set
1122# CONFIG_SCSI_SYM53C416 is not set
1123# CONFIG_SCSI_DC395x is not set
1124# CONFIG_SCSI_DC390T is not set
1125# CONFIG_SCSI_T128 is not set
1126# CONFIG_SCSI_U14_34F is not set
1127# CONFIG_SCSI_ULTRASTOR is not set
1128# CONFIG_SCSI_NSP32 is not set
1129# CONFIG_SCSI_DEBUG is not set
1130# CONFIG_SCSI_SRP is not set
1131# CONFIG_SCSI_DH is not set
1132CONFIG_ATA=y
1133# CONFIG_ATA_NONSTANDARD is not set
1134CONFIG_ATA_ACPI=y
1135CONFIG_SATA_PMP=y
1136# CONFIG_SATA_AHCI is not set
1137# CONFIG_SATA_SIL24 is not set
1138CONFIG_ATA_SFF=y
1139# CONFIG_SATA_SVW is not set
1140CONFIG_ATA_PIIX=y
1141# CONFIG_SATA_MV is not set
1142# CONFIG_SATA_NV is not set
1143# CONFIG_PDC_ADMA is not set
1144# CONFIG_SATA_QSTOR is not set
1145# CONFIG_SATA_PROMISE is not set
1146# CONFIG_SATA_SX4 is not set
1147# CONFIG_SATA_SIL is not set
1148# CONFIG_SATA_SIS is not set
1149# CONFIG_SATA_ULI is not set
1150# CONFIG_SATA_VIA is not set
1151# CONFIG_SATA_VITESSE is not set
1152# CONFIG_SATA_INIC162X is not set
1153# CONFIG_PATA_ACPI is not set
1154# CONFIG_PATA_ALI is not set
1155# CONFIG_PATA_AMD is not set
1156# CONFIG_PATA_ARTOP is not set
1157# CONFIG_PATA_ATIIXP is not set
1158# CONFIG_PATA_CMD640_PCI is not set
1159# CONFIG_PATA_CMD64X is not set
1160# CONFIG_PATA_CS5520 is not set
1161# CONFIG_PATA_CS5530 is not set
1162# CONFIG_PATA_CS5535 is not set
1163# CONFIG_PATA_CS5536 is not set
1164# CONFIG_PATA_CYPRESS is not set
1165# CONFIG_PATA_EFAR is not set
1166CONFIG_ATA_GENERIC=y
1167# CONFIG_PATA_HPT366 is not set
1168# CONFIG_PATA_HPT37X is not set
1169# CONFIG_PATA_HPT3X2N is not set
1170# CONFIG_PATA_HPT3X3 is not set
1171# CONFIG_PATA_IT821X is not set
1172# CONFIG_PATA_IT8213 is not set
1173# CONFIG_PATA_JMICRON is not set
1174# CONFIG_PATA_LEGACY is not set
1175# CONFIG_PATA_TRIFLEX is not set
1176# CONFIG_PATA_MARVELL is not set
1177CONFIG_PATA_MPIIX=y
1178# CONFIG_PATA_OLDPIIX is not set
1179# CONFIG_PATA_NETCELL is not set
1180# CONFIG_PATA_NINJA32 is not set
1181# CONFIG_PATA_NS87410 is not set
1182# CONFIG_PATA_NS87415 is not set
1183# CONFIG_PATA_OPTI is not set
1184# CONFIG_PATA_OPTIDMA is not set
1185# CONFIG_PATA_PDC_OLD is not set
1186# CONFIG_PATA_QDI is not set
1187# CONFIG_PATA_RADISYS is not set
1188# CONFIG_PATA_RZ1000 is not set
1189# CONFIG_PATA_SC1200 is not set
1190# CONFIG_PATA_SERVERWORKS is not set
1191# CONFIG_PATA_PDC2027X is not set
1192# CONFIG_PATA_SIL680 is not set
1193# CONFIG_PATA_SIS is not set
1194# CONFIG_PATA_VIA is not set
1195# CONFIG_PATA_WINBOND is not set
1196# CONFIG_PATA_WINBOND_VLB is not set
1197# CONFIG_PATA_SCH is not set
1198# CONFIG_MD is not set
1199# CONFIG_FUSION is not set
1200
1201#
1202# IEEE 1394 (FireWire) support
1203#
1204
1205#
1206# Enable only one of the two stacks, unless you know what you are doing
1207#
1208# CONFIG_FIREWIRE is not set
1209CONFIG_IEEE1394=m
1210CONFIG_IEEE1394_OHCI1394=m
1211# CONFIG_IEEE1394_PCILYNX is not set
1212CONFIG_IEEE1394_SBP2=m
1213# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
1214CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y
1215CONFIG_IEEE1394_ETH1394=m
1216CONFIG_IEEE1394_RAWIO=m
1217CONFIG_IEEE1394_VIDEO1394=m
1218CONFIG_IEEE1394_DV1394=m
1219# CONFIG_IEEE1394_VERBOSEDEBUG is not set
1220CONFIG_I2O=m
1221CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y
1222CONFIG_I2O_EXT_ADAPTEC=y
1223CONFIG_I2O_CONFIG=m
1224CONFIG_I2O_CONFIG_OLD_IOCTL=y
1225CONFIG_I2O_BUS=m
1226CONFIG_I2O_BLOCK=m
1227CONFIG_I2O_SCSI=m
1228CONFIG_I2O_PROC=m
1229# CONFIG_MACINTOSH_DRIVERS is not set
1230CONFIG_NETDEVICES=y
1231CONFIG_IFB=m
1232CONFIG_DUMMY=m
1233CONFIG_BONDING=m
1234# CONFIG_MACVLAN is not set
1235CONFIG_EQUALIZER=m
1236CONFIG_TUN=m
1237# CONFIG_VETH is not set
1238# CONFIG_NET_SB1000 is not set
1239# CONFIG_ARCNET is not set
1240CONFIG_PHYLIB=m
1241
1242#
1243# MII PHY device drivers
1244#
1245CONFIG_MARVELL_PHY=m
1246CONFIG_DAVICOM_PHY=m
1247CONFIG_QSEMI_PHY=m
1248CONFIG_LXT_PHY=m
1249CONFIG_CICADA_PHY=m
1250CONFIG_VITESSE_PHY=m
1251CONFIG_SMSC_PHY=m
1252# CONFIG_BROADCOM_PHY is not set
1253# CONFIG_ICPLUS_PHY is not set
1254# CONFIG_REALTEK_PHY is not set
1255# CONFIG_MDIO_BITBANG is not set
1256CONFIG_NET_ETHERNET=y
1257CONFIG_MII=y
1258# CONFIG_HAPPYMEAL is not set
1259# CONFIG_SUNGEM is not set
1260# CONFIG_CASSINI is not set
1261CONFIG_NET_VENDOR_3COM=y
1262CONFIG_EL1=m
1263CONFIG_EL2=m
1264CONFIG_ELPLUS=m
1265CONFIG_EL16=m
1266CONFIG_EL3=m
1267CONFIG_3C515=m
1268CONFIG_VORTEX=m
1269CONFIG_TYPHOON=m
1270# CONFIG_LANCE is not set
1271CONFIG_NET_VENDOR_SMC=y
1272CONFIG_WD80x3=m
1273CONFIG_ULTRA=m
1274CONFIG_SMC9194=m
1275# CONFIG_ENC28J60 is not set
1276# CONFIG_NET_VENDOR_RACAL is not set
1277CONFIG_NET_TULIP=y
1278CONFIG_DE2104X=m
1279CONFIG_TULIP=m
1280# CONFIG_TULIP_MWI is not set
1281# CONFIG_TULIP_MMIO is not set
1282CONFIG_TULIP_NAPI=y
1283CONFIG_TULIP_NAPI_HW_MITIGATION=y
1284CONFIG_DE4X5=m
1285CONFIG_WINBOND_840=m
1286CONFIG_DM9102=m
1287CONFIG_ULI526X=m
1288# CONFIG_AT1700 is not set
1289# CONFIG_DEPCA is not set
1290# CONFIG_HP100 is not set
1291# CONFIG_NET_ISA is not set
1292# CONFIG_IBM_NEW_EMAC_ZMII is not set
1293# CONFIG_IBM_NEW_EMAC_RGMII is not set
1294# CONFIG_IBM_NEW_EMAC_TAH is not set
1295# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
1296CONFIG_NET_PCI=y
1297# CONFIG_PCNET32 is not set
1298# CONFIG_AMD8111_ETH is not set
1299# CONFIG_ADAPTEC_STARFIRE is not set
1300# CONFIG_AC3200 is not set
1301# CONFIG_APRICOT is not set
1302# CONFIG_B44 is not set
1303# CONFIG_FORCEDETH is not set
1304# CONFIG_CS89x0 is not set
1305# CONFIG_EEPRO100 is not set
1306CONFIG_E100=m
1307# CONFIG_FEALNX is not set
1308# CONFIG_NATSEMI is not set
1309CONFIG_NE2K_PCI=m
1310CONFIG_8139CP=m
1311CONFIG_8139TOO=m
1312# CONFIG_8139TOO_PIO is not set
1313# CONFIG_8139TOO_TUNE_TWISTER is not set
1314CONFIG_8139TOO_8129=y
1315# CONFIG_8139_OLD_RX_RESET is not set
1316# CONFIG_R6040 is not set
1317# CONFIG_SIS900 is not set
1318CONFIG_EPIC100=m
1319# CONFIG_SUNDANCE is not set
1320# CONFIG_TLAN is not set
1321# CONFIG_VIA_RHINE is not set
1322# CONFIG_SC92031 is not set
1323CONFIG_NETDEV_1000=y
1324# CONFIG_ACENIC is not set
1325# CONFIG_DL2K is not set
1326CONFIG_E1000=m
1327CONFIG_E1000_DISABLE_PACKET_SPLIT=y
1328# CONFIG_E1000E is not set
1329# CONFIG_IP1000 is not set
1330# CONFIG_IGB is not set
1331# CONFIG_NS83820 is not set
1332# CONFIG_HAMACHI is not set
1333# CONFIG_YELLOWFIN is not set
1334# CONFIG_R8169 is not set
1335# CONFIG_SIS190 is not set
1336CONFIG_SKGE=y
1337# CONFIG_SKGE_DEBUG is not set
1338CONFIG_SKY2=y
1339# CONFIG_SKY2_DEBUG is not set
1340# CONFIG_VIA_VELOCITY is not set
1341# CONFIG_TIGON3 is not set
1342# CONFIG_BNX2 is not set
1343# CONFIG_QLA3XXX is not set
1344# CONFIG_ATL1 is not set
1345# CONFIG_ATL1E is not set
1346CONFIG_NETDEV_10000=y
1347# CONFIG_CHELSIO_T1 is not set
1348# CONFIG_CHELSIO_T3 is not set
1349# CONFIG_IXGBE is not set
1350CONFIG_IXGB=m
1351# CONFIG_S2IO is not set
1352# CONFIG_MYRI10GE is not set
1353# CONFIG_NETXEN_NIC is not set
1354# CONFIG_NIU is not set
1355# CONFIG_MLX4_CORE is not set
1356# CONFIG_TEHUTI is not set
1357# CONFIG_BNX2X is not set
1358# CONFIG_SFC is not set
1359# CONFIG_TR is not set
1360
1361#
1362# Wireless LAN
1363#
1364# CONFIG_WLAN_PRE80211 is not set
1365CONFIG_WLAN_80211=y
1366CONFIG_IPW2100=m
1367# CONFIG_IPW2100_MONITOR is not set
1368# CONFIG_IPW2100_DEBUG is not set
1369CONFIG_IPW2200=m
1370# CONFIG_IPW2200_MONITOR is not set
1371# CONFIG_IPW2200_QOS is not set
1372# CONFIG_IPW2200_DEBUG is not set
1373# CONFIG_LIBERTAS is not set
1374# CONFIG_AIRO is not set
1375# CONFIG_HERMES is not set
1376# CONFIG_ATMEL is not set
1377# CONFIG_PRISM54 is not set
1378# CONFIG_USB_ZD1201 is not set
1379# CONFIG_USB_NET_RNDIS_WLAN is not set
1380# CONFIG_IWLWIFI_LEDS is not set
1381# CONFIG_HOSTAP is not set
1382
1383#
1384# USB Network Adapters
1385#
1386CONFIG_USB_CATC=m
1387CONFIG_USB_KAWETH=m
1388CONFIG_USB_PEGASUS=m
1389CONFIG_USB_RTL8150=m
1390CONFIG_USB_USBNET=y
1391CONFIG_USB_NET_AX8817X=y
1392CONFIG_USB_NET_CDCETHER=m
1393# CONFIG_USB_NET_DM9601 is not set
1394CONFIG_USB_NET_GL620A=m
1395CONFIG_USB_NET_NET1080=m
1396CONFIG_USB_NET_PLUSB=m
1397# CONFIG_USB_NET_MCS7830 is not set
1398CONFIG_USB_NET_RNDIS_HOST=m
1399CONFIG_USB_NET_CDC_SUBSET=m
1400CONFIG_USB_ALI_M5632=y
1401CONFIG_USB_AN2720=y
1402CONFIG_USB_BELKIN=y
1403CONFIG_USB_ARMLINUX=y
1404CONFIG_USB_EPSON2888=y
1405# CONFIG_USB_KC2190 is not set
1406CONFIG_USB_NET_ZAURUS=m
1407# CONFIG_WAN is not set
1408CONFIG_ATM_DRIVERS=y
1409# CONFIG_ATM_DUMMY is not set
1410# CONFIG_ATM_TCP is not set
1411# CONFIG_ATM_LANAI is not set
1412# CONFIG_ATM_ENI is not set
1413# CONFIG_ATM_FIRESTREAM is not set
1414# CONFIG_ATM_ZATM is not set
1415# CONFIG_ATM_NICSTAR is not set
1416# CONFIG_ATM_IDT77252 is not set
1417# CONFIG_ATM_AMBASSADOR is not set
1418# CONFIG_ATM_HORIZON is not set
1419# CONFIG_ATM_IA is not set
1420# CONFIG_ATM_FORE200E is not set
1421# CONFIG_ATM_HE is not set
1422# CONFIG_FDDI is not set
1423# CONFIG_HIPPI is not set
1424CONFIG_PPP=m
1425CONFIG_PPP_MULTILINK=y
1426CONFIG_PPP_FILTER=y
1427CONFIG_PPP_ASYNC=m
1428CONFIG_PPP_SYNC_TTY=m
1429CONFIG_PPP_DEFLATE=m
1430CONFIG_PPP_BSDCOMP=m
1431CONFIG_PPP_MPPE=m
1432CONFIG_PPPOE=m
1433CONFIG_PPPOATM=m
1434# CONFIG_PPPOL2TP is not set
1435CONFIG_SLIP=m
1436CONFIG_SLIP_COMPRESSED=y
1437CONFIG_SLHC=m
1438CONFIG_SLIP_SMART=y
1439CONFIG_SLIP_MODE_SLIP6=y
1440CONFIG_NET_FC=y
1441CONFIG_NETCONSOLE=m
1442# CONFIG_NETCONSOLE_DYNAMIC is not set
1443CONFIG_NETPOLL=y
1444CONFIG_NETPOLL_TRAP=y
1445CONFIG_NET_POLL_CONTROLLER=y
1446# CONFIG_ISDN is not set
1447CONFIG_PHONE=m
1448# CONFIG_PHONE_IXJ is not set
1449
1450#
1451# Input device support
1452#
1453CONFIG_INPUT=y
1454CONFIG_INPUT_FF_MEMLESS=y
1455CONFIG_INPUT_POLLDEV=m
1456
1457#
1458# Userland interfaces
1459#
1460CONFIG_INPUT_MOUSEDEV=y
1461CONFIG_INPUT_MOUSEDEV_PSAUX=y
1462CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
1463CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
1464CONFIG_INPUT_JOYDEV=m
1465CONFIG_INPUT_EVDEV=y
1466# CONFIG_INPUT_EVBUG is not set
1467
1468#
1469# Input Device Drivers
1470#
1471CONFIG_INPUT_KEYBOARD=y
1472CONFIG_KEYBOARD_ATKBD=y
1473CONFIG_KEYBOARD_SUNKBD=m
1474# CONFIG_KEYBOARD_LKKBD is not set
1475CONFIG_KEYBOARD_XTKBD=m
1476CONFIG_KEYBOARD_NEWTON=m
1477# CONFIG_KEYBOARD_STOWAWAY is not set
1478CONFIG_INPUT_MOUSE=y
1479CONFIG_MOUSE_PS2=y
1480CONFIG_MOUSE_PS2_ALPS=y
1481CONFIG_MOUSE_PS2_LOGIPS2PP=y
1482CONFIG_MOUSE_PS2_SYNAPTICS=y
1483CONFIG_MOUSE_PS2_LIFEBOOK=y
1484CONFIG_MOUSE_PS2_TRACKPOINT=y
1485# CONFIG_MOUSE_PS2_TOUCHKIT is not set
1486CONFIG_MOUSE_SERIAL=m
1487# CONFIG_MOUSE_APPLETOUCH is not set
1488# CONFIG_MOUSE_BCM5974 is not set
1489CONFIG_MOUSE_INPORT=m
1490CONFIG_MOUSE_ATIXL=y
1491CONFIG_MOUSE_LOGIBM=m
1492CONFIG_MOUSE_PC110PAD=m
1493# CONFIG_MOUSE_VSXXXAA is not set
1494CONFIG_INPUT_JOYSTICK=y
1495CONFIG_JOYSTICK_ANALOG=m
1496CONFIG_JOYSTICK_A3D=m
1497CONFIG_JOYSTICK_ADI=m
1498CONFIG_JOYSTICK_COBRA=m
1499CONFIG_JOYSTICK_GF2K=m
1500CONFIG_JOYSTICK_GRIP=m
1501CONFIG_JOYSTICK_GRIP_MP=m
1502CONFIG_JOYSTICK_GUILLEMOT=m
1503CONFIG_JOYSTICK_INTERACT=m
1504CONFIG_JOYSTICK_SIDEWINDER=m
1505CONFIG_JOYSTICK_TMDC=m
1506CONFIG_JOYSTICK_IFORCE=m
1507CONFIG_JOYSTICK_IFORCE_USB=y
1508CONFIG_JOYSTICK_IFORCE_232=y
1509CONFIG_JOYSTICK_WARRIOR=m
1510CONFIG_JOYSTICK_MAGELLAN=m
1511CONFIG_JOYSTICK_SPACEORB=m
1512CONFIG_JOYSTICK_SPACEBALL=m
1513CONFIG_JOYSTICK_STINGER=m
1514CONFIG_JOYSTICK_TWIDJOY=m
1515# CONFIG_JOYSTICK_ZHENHUA is not set
1516CONFIG_JOYSTICK_JOYDUMP=m
1517# CONFIG_JOYSTICK_XPAD is not set
1518# CONFIG_INPUT_TABLET is not set
1519CONFIG_INPUT_TOUCHSCREEN=y
1520CONFIG_TOUCHSCREEN_ADS7846=m
1521# CONFIG_TOUCHSCREEN_FUJITSU is not set
1522CONFIG_TOUCHSCREEN_GUNZE=m
1523CONFIG_TOUCHSCREEN_ELO=m
1524CONFIG_TOUCHSCREEN_MTOUCH=m
1525# CONFIG_TOUCHSCREEN_INEXIO is not set
1526CONFIG_TOUCHSCREEN_MK712=m
1527# CONFIG_TOUCHSCREEN_HTCPEN is not set
1528# CONFIG_TOUCHSCREEN_PENMOUNT is not set
1529# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
1530# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
1531# CONFIG_TOUCHSCREEN_UCB1400 is not set
1532# CONFIG_TOUCHSCREEN_WM97XX is not set
1533# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
1534# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
1535CONFIG_INPUT_MISC=y
1536CONFIG_INPUT_PCSPKR=y
1537# CONFIG_INPUT_APANEL is not set
1538CONFIG_INPUT_WISTRON_BTNS=m
1539# CONFIG_INPUT_ATLAS_BTNS is not set
1540# CONFIG_INPUT_ATI_REMOTE is not set
1541# CONFIG_INPUT_ATI_REMOTE2 is not set
1542# CONFIG_INPUT_KEYSPAN_REMOTE is not set
1543# CONFIG_INPUT_POWERMATE is not set
1544# CONFIG_INPUT_YEALINK is not set
1545CONFIG_INPUT_UINPUT=m
1546
1547#
1548# Hardware I/O ports
1549#
1550CONFIG_SERIO=y
1551CONFIG_SERIO_I8042=y
1552CONFIG_SERIO_SERPORT=m
1553CONFIG_SERIO_CT82C710=m
1554CONFIG_SERIO_PCIPS2=m
1555CONFIG_SERIO_LIBPS2=y
1556CONFIG_SERIO_RAW=m
1557CONFIG_GAMEPORT=m
1558CONFIG_GAMEPORT_NS558=m
1559CONFIG_GAMEPORT_L4=m
1560CONFIG_GAMEPORT_EMU10K1=m
1561CONFIG_GAMEPORT_FM801=m
1562
1563#
1564# Character devices
1565#
1566CONFIG_VT=y
1567CONFIG_CONSOLE_TRANSLATIONS=y
1568CONFIG_VT_CONSOLE=y
1569CONFIG_HW_CONSOLE=y
1570CONFIG_VT_HW_CONSOLE_BINDING=y
1571CONFIG_DEVKMEM=y
1572CONFIG_SERIAL_NONSTANDARD=y
1573# CONFIG_COMPUTONE is not set
1574# CONFIG_ROCKETPORT is not set
1575# CONFIG_CYCLADES is not set
1576# CONFIG_DIGIEPCA is not set
1577# CONFIG_ESPSERIAL is not set
1578# CONFIG_MOXA_INTELLIO is not set
1579# CONFIG_MOXA_SMARTIO is not set
1580# CONFIG_ISI is not set
1581# CONFIG_SYNCLINK is not set
1582# CONFIG_SYNCLINKMP is not set
1583# CONFIG_SYNCLINK_GT is not set
1584# CONFIG_N_HDLC is not set
1585# CONFIG_RISCOM8 is not set
1586# CONFIG_SPECIALIX is not set
1587# CONFIG_SX is not set
1588# CONFIG_RIO is not set
1589# CONFIG_STALDRV is not set
1590# CONFIG_NOZOMI is not set
1591
1592#
1593# Serial drivers
1594#
1595CONFIG_SERIAL_8250=y
1596CONFIG_SERIAL_8250_CONSOLE=y
1597CONFIG_FIX_EARLYCON_MEM=y
1598CONFIG_SERIAL_8250_PCI=y
1599CONFIG_SERIAL_8250_PNP=y
1600CONFIG_SERIAL_8250_NR_UARTS=8
1601CONFIG_SERIAL_8250_RUNTIME_UARTS=4
1602CONFIG_SERIAL_8250_EXTENDED=y
1603# CONFIG_SERIAL_8250_MANY_PORTS is not set
1604CONFIG_SERIAL_8250_SHARE_IRQ=y
1605# CONFIG_SERIAL_8250_DETECT_IRQ is not set
1606# CONFIG_SERIAL_8250_RSA is not set
1607
1608#
1609# Non-8250 serial port support
1610#
1611CONFIG_SERIAL_CORE=y
1612CONFIG_SERIAL_CORE_CONSOLE=y
1613CONFIG_SERIAL_JSM=y
1614CONFIG_UNIX98_PTYS=y
1615CONFIG_LEGACY_PTYS=y
1616CONFIG_LEGACY_PTY_COUNT=64
1617CONFIG_IPMI_HANDLER=m
1618CONFIG_IPMI_PANIC_EVENT=y
1619CONFIG_IPMI_PANIC_STRING=y
1620CONFIG_IPMI_DEVICE_INTERFACE=m
1621CONFIG_IPMI_SI=m
1622CONFIG_IPMI_WATCHDOG=m
1623CONFIG_IPMI_POWEROFF=m
1624CONFIG_HW_RANDOM=y
1625CONFIG_HW_RANDOM_INTEL=m
1626# CONFIG_HW_RANDOM_AMD is not set
1627# CONFIG_HW_RANDOM_GEODE is not set
1628# CONFIG_HW_RANDOM_VIA is not set
1629CONFIG_NVRAM=m
1630# CONFIG_DTLK is not set
1631# CONFIG_R3964 is not set
1632# CONFIG_APPLICOM is not set
1633# CONFIG_SONYPI is not set
1634# CONFIG_MWAVE is not set
1635# CONFIG_PC8736x_GPIO is not set
1636# CONFIG_NSC_GPIO is not set
1637# CONFIG_CS5535_GPIO is not set
1638CONFIG_RAW_DRIVER=m
1639CONFIG_MAX_RAW_DEVS=4096
1640CONFIG_HPET=y
1641CONFIG_HPET_MMAP=y
1642CONFIG_HANGCHECK_TIMER=m
1643# CONFIG_TCG_TPM is not set
1644# CONFIG_TELCLOCK is not set
1645CONFIG_DEVPORT=y
1646CONFIG_I2C=m
1647CONFIG_I2C_BOARDINFO=y
1648CONFIG_I2C_CHARDEV=m
1649CONFIG_I2C_HELPER_AUTO=y
1650CONFIG_I2C_ALGOBIT=m
1651CONFIG_I2C_ALGOPCA=m
1652
1653#
1654# I2C Hardware Bus support
1655#
1656
1657#
1658# PC SMBus host controller drivers
1659#
1660CONFIG_I2C_ALI1535=m
1661CONFIG_I2C_ALI1563=m
1662CONFIG_I2C_ALI15X3=m
1663CONFIG_I2C_AMD756=m
1664CONFIG_I2C_AMD756_S4882=m
1665CONFIG_I2C_AMD8111=m
1666CONFIG_I2C_I801=m
1667# CONFIG_I2C_ISCH is not set
1668CONFIG_I2C_PIIX4=m
1669CONFIG_I2C_NFORCE2=m
1670# CONFIG_I2C_NFORCE2_S4985 is not set
1671CONFIG_I2C_SIS5595=m
1672CONFIG_I2C_SIS630=m
1673CONFIG_I2C_SIS96X=m
1674CONFIG_I2C_VIA=m
1675CONFIG_I2C_VIAPRO=m
1676
1677#
1678# I2C system bus drivers (mostly embedded / system-on-chip)
1679#
1680CONFIG_I2C_OCORES=m
1681# CONFIG_I2C_SIMTEC is not set
1682
1683#
1684# External I2C/SMBus adapter drivers
1685#
1686CONFIG_I2C_PARPORT_LIGHT=m
1687# CONFIG_I2C_TAOS_EVM is not set
1688# CONFIG_I2C_TINY_USB is not set
1689
1690#
1691# Graphics adapter I2C/DDC channel drivers
1692#
1693CONFIG_I2C_VOODOO3=m
1694
1695#
1696# Other I2C/SMBus bus drivers
1697#
1698CONFIG_I2C_PCA_ISA=m
1699# CONFIG_I2C_PCA_PLATFORM is not set
1700CONFIG_I2C_STUB=m
1701CONFIG_SCx200_ACB=m
1702
1703#
1704# Miscellaneous I2C Chip support
1705#
1706# CONFIG_DS1682 is not set
1707# CONFIG_AT24 is not set
1708CONFIG_SENSORS_EEPROM=m
1709CONFIG_SENSORS_PCF8574=m
1710# CONFIG_PCF8575 is not set
1711CONFIG_SENSORS_PCA9539=m
1712CONFIG_SENSORS_PCF8591=m
1713CONFIG_SENSORS_MAX6875=m
1714# CONFIG_SENSORS_TSL2550 is not set
1715# CONFIG_I2C_DEBUG_CORE is not set
1716# CONFIG_I2C_DEBUG_ALGO is not set
1717# CONFIG_I2C_DEBUG_BUS is not set
1718# CONFIG_I2C_DEBUG_CHIP is not set
1719CONFIG_SPI=y
1720# CONFIG_SPI_DEBUG is not set
1721CONFIG_SPI_MASTER=y
1722
1723#
1724# SPI Master Controller Drivers
1725#
1726CONFIG_SPI_BITBANG=m
1727
1728#
1729# SPI Protocol Masters
1730#
1731# CONFIG_SPI_AT25 is not set
1732# CONFIG_SPI_SPIDEV is not set
1733# CONFIG_SPI_TLE62X0 is not set
1734CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
1735# CONFIG_GPIOLIB is not set
1736CONFIG_W1=m
1737CONFIG_W1_CON=y
1738
1739#
1740# 1-wire Bus Masters
1741#
1742CONFIG_W1_MASTER_MATROX=m
1743CONFIG_W1_MASTER_DS2490=m
1744CONFIG_W1_MASTER_DS2482=m
1745
1746#
1747# 1-wire Slaves
1748#
1749CONFIG_W1_SLAVE_THERM=m
1750CONFIG_W1_SLAVE_SMEM=m
1751CONFIG_W1_SLAVE_DS2433=m
1752CONFIG_W1_SLAVE_DS2433_CRC=y
1753# CONFIG_W1_SLAVE_DS2760 is not set
1754CONFIG_POWER_SUPPLY=y
1755# CONFIG_POWER_SUPPLY_DEBUG is not set
1756# CONFIG_PDA_POWER is not set
1757# CONFIG_BATTERY_DS2760 is not set
1758CONFIG_HWMON=y
1759CONFIG_HWMON_VID=m
1760# CONFIG_SENSORS_ABITUGURU is not set
1761# CONFIG_SENSORS_ABITUGURU3 is not set
1762# CONFIG_SENSORS_AD7414 is not set
1763# CONFIG_SENSORS_AD7418 is not set
1764# CONFIG_SENSORS_ADCXX is not set
1765# CONFIG_SENSORS_ADM1021 is not set
1766# CONFIG_SENSORS_ADM1025 is not set
1767# CONFIG_SENSORS_ADM1026 is not set
1768# CONFIG_SENSORS_ADM1029 is not set
1769# CONFIG_SENSORS_ADM1031 is not set
1770# CONFIG_SENSORS_ADM9240 is not set
1771# CONFIG_SENSORS_ADT7470 is not set
1772# CONFIG_SENSORS_ADT7473 is not set
1773# CONFIG_SENSORS_K8TEMP is not set
1774# CONFIG_SENSORS_ASB100 is not set
1775# CONFIG_SENSORS_ATXP1 is not set
1776# CONFIG_SENSORS_DS1621 is not set
1777# CONFIG_SENSORS_I5K_AMB is not set
1778# CONFIG_SENSORS_F71805F is not set
1779# CONFIG_SENSORS_F71882FG is not set
1780# CONFIG_SENSORS_F75375S is not set
1781# CONFIG_SENSORS_FSCHER is not set
1782# CONFIG_SENSORS_FSCPOS is not set
1783# CONFIG_SENSORS_FSCHMD is not set
1784# CONFIG_SENSORS_GL518SM is not set
1785# CONFIG_SENSORS_GL520SM is not set
1786# CONFIG_SENSORS_CORETEMP is not set
1787# CONFIG_SENSORS_IBMAEM is not set
1788# CONFIG_SENSORS_IBMPEX is not set
1789# CONFIG_SENSORS_IT87 is not set
1790# CONFIG_SENSORS_LM63 is not set
1791# CONFIG_SENSORS_LM70 is not set
1792# CONFIG_SENSORS_LM75 is not set
1793# CONFIG_SENSORS_LM77 is not set
1794# CONFIG_SENSORS_LM78 is not set
1795# CONFIG_SENSORS_LM80 is not set
1796# CONFIG_SENSORS_LM83 is not set
1797CONFIG_SENSORS_LM85=m
1798# CONFIG_SENSORS_LM87 is not set
1799# CONFIG_SENSORS_LM90 is not set
1800# CONFIG_SENSORS_LM92 is not set
1801# CONFIG_SENSORS_LM93 is not set
1802# CONFIG_SENSORS_MAX1619 is not set
1803# CONFIG_SENSORS_MAX6650 is not set
1804# CONFIG_SENSORS_PC87360 is not set
1805# CONFIG_SENSORS_PC87427 is not set
1806# CONFIG_SENSORS_SIS5595 is not set
1807# CONFIG_SENSORS_DME1737 is not set
1808# CONFIG_SENSORS_SMSC47M1 is not set
1809# CONFIG_SENSORS_SMSC47M192 is not set
1810# CONFIG_SENSORS_SMSC47B397 is not set
1811# CONFIG_SENSORS_ADS7828 is not set
1812# CONFIG_SENSORS_THMC50 is not set
1813# CONFIG_SENSORS_VIA686A is not set
1814# CONFIG_SENSORS_VT1211 is not set
1815# CONFIG_SENSORS_VT8231 is not set
1816# CONFIG_SENSORS_W83781D is not set
1817# CONFIG_SENSORS_W83791D is not set
1818# CONFIG_SENSORS_W83792D is not set
1819# CONFIG_SENSORS_W83793 is not set
1820# CONFIG_SENSORS_W83L785TS is not set
1821# CONFIG_SENSORS_W83L786NG is not set
1822# CONFIG_SENSORS_W83627HF is not set
1823# CONFIG_SENSORS_W83627EHF is not set
1824# CONFIG_SENSORS_HDAPS is not set
1825# CONFIG_SENSORS_APPLESMC is not set
1826# CONFIG_HWMON_DEBUG_CHIP is not set
1827CONFIG_THERMAL=y
1828# CONFIG_THERMAL_HWMON is not set
1829# CONFIG_WATCHDOG is not set
1830
1831#
1832# Sonics Silicon Backplane
1833#
1834CONFIG_SSB_POSSIBLE=y
1835# CONFIG_SSB is not set
1836
1837#
1838# Multifunction device drivers
1839#
1840# CONFIG_MFD_CORE is not set
1841# CONFIG_MFD_SM501 is not set
1842# CONFIG_HTC_PASIC3 is not set
1843# CONFIG_MFD_TMIO is not set
1844
1845#
1846# Multimedia devices
1847#
1848
1849#
1850# Multimedia core support
1851#
1852CONFIG_VIDEO_DEV=m
1853CONFIG_VIDEO_V4L2_COMMON=m
1854CONFIG_VIDEO_ALLOW_V4L1=y
1855CONFIG_VIDEO_V4L1_COMPAT=y
1856CONFIG_DVB_CORE=m
1857CONFIG_VIDEO_MEDIA=m
1858
1859#
1860# Multimedia drivers
1861#
1862# CONFIG_MEDIA_ATTACH is not set
1863CONFIG_MEDIA_TUNER=m
1864# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
1865CONFIG_MEDIA_TUNER_SIMPLE=m
1866CONFIG_MEDIA_TUNER_TDA8290=m
1867CONFIG_MEDIA_TUNER_TDA18271=m
1868CONFIG_MEDIA_TUNER_TDA9887=m
1869CONFIG_MEDIA_TUNER_TEA5761=m
1870CONFIG_MEDIA_TUNER_TEA5767=m
1871CONFIG_MEDIA_TUNER_MT20XX=m
1872CONFIG_MEDIA_TUNER_MT2060=m
1873CONFIG_MEDIA_TUNER_XC2028=m
1874CONFIG_MEDIA_TUNER_XC5000=m
1875CONFIG_VIDEO_V4L2=m
1876CONFIG_VIDEO_V4L1=m
1877CONFIG_VIDEOBUF_GEN=m
1878CONFIG_VIDEOBUF_VMALLOC=m
1879CONFIG_VIDEO_IR=m
1880CONFIG_VIDEO_TVEEPROM=m
1881CONFIG_VIDEO_TUNER=m
1882CONFIG_VIDEO_CAPTURE_DRIVERS=y
1883# CONFIG_VIDEO_ADV_DEBUG is not set
1884CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
1885CONFIG_VIDEO_IR_I2C=m
1886CONFIG_VIDEO_MSP3400=m
1887CONFIG_VIDEO_CS53L32A=m
1888CONFIG_VIDEO_WM8775=m
1889CONFIG_VIDEO_SAA711X=m
1890CONFIG_VIDEO_TVP5150=m
1891CONFIG_VIDEO_CX25840=m
1892CONFIG_VIDEO_CX2341X=m
1893# CONFIG_VIDEO_VIVI is not set
1894# CONFIG_VIDEO_BT848 is not set
1895# CONFIG_VIDEO_PMS is not set
1896# CONFIG_VIDEO_CPIA is not set
1897# CONFIG_VIDEO_CPIA2 is not set
1898# CONFIG_VIDEO_SAA5246A is not set
1899# CONFIG_VIDEO_SAA5249 is not set
1900# CONFIG_TUNER_3036 is not set
1901# CONFIG_VIDEO_STRADIS is not set
1902# CONFIG_VIDEO_ZORAN is not set
1903# CONFIG_VIDEO_SAA7134 is not set
1904# CONFIG_VIDEO_MXB is not set
1905# CONFIG_VIDEO_DPC is not set
1906# CONFIG_VIDEO_HEXIUM_ORION is not set
1907# CONFIG_VIDEO_HEXIUM_GEMINI is not set
1908# CONFIG_VIDEO_CX88 is not set
1909# CONFIG_VIDEO_CX23885 is not set
1910# CONFIG_VIDEO_AU0828 is not set
1911# CONFIG_VIDEO_IVTV is not set
1912# CONFIG_VIDEO_CX18 is not set
1913# CONFIG_VIDEO_CAFE_CCIC is not set
1914CONFIG_V4L_USB_DRIVERS=y
1915# CONFIG_USB_VIDEO_CLASS is not set
1916# CONFIG_USB_GSPCA is not set
1917CONFIG_VIDEO_PVRUSB2=m
1918CONFIG_VIDEO_PVRUSB2_SYSFS=y
1919CONFIG_VIDEO_PVRUSB2_DVB=y
1920# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
1921CONFIG_VIDEO_EM28XX=m
1922# CONFIG_VIDEO_EM28XX_ALSA is not set
1923# CONFIG_VIDEO_EM28XX_DVB is not set
1924# CONFIG_VIDEO_USBVISION is not set
1925CONFIG_VIDEO_USBVIDEO=m
1926CONFIG_USB_VICAM=m
1927CONFIG_USB_IBMCAM=m
1928CONFIG_USB_KONICAWC=m
1929CONFIG_USB_QUICKCAM_MESSENGER=m
1930CONFIG_USB_ET61X251=m
1931CONFIG_VIDEO_OVCAMCHIP=m
1932CONFIG_USB_W9968CF=m
1933CONFIG_USB_OV511=m
1934CONFIG_USB_SE401=m
1935CONFIG_USB_SN9C102=m
1936CONFIG_USB_STV680=m
1937# CONFIG_USB_ZC0301 is not set
1938CONFIG_USB_PWC=m
1939# CONFIG_USB_PWC_DEBUG is not set
1940# CONFIG_USB_ZR364XX is not set
1941# CONFIG_USB_STKWEBCAM is not set
1942# CONFIG_USB_S2255 is not set
1943# CONFIG_SOC_CAMERA is not set
1944# CONFIG_VIDEO_SH_MOBILE_CEU is not set
1945CONFIG_RADIO_ADAPTERS=y
1946# CONFIG_RADIO_CADET is not set
1947# CONFIG_RADIO_RTRACK is not set
1948# CONFIG_RADIO_RTRACK2 is not set
1949# CONFIG_RADIO_AZTECH is not set
1950# CONFIG_RADIO_GEMTEK is not set
1951# CONFIG_RADIO_GEMTEK_PCI is not set
1952# CONFIG_RADIO_MAXIRADIO is not set
1953# CONFIG_RADIO_MAESTRO is not set
1954# CONFIG_RADIO_SF16FMI is not set
1955# CONFIG_RADIO_SF16FMR2 is not set
1956# CONFIG_RADIO_TERRATEC is not set
1957# CONFIG_RADIO_TRUST is not set
1958# CONFIG_RADIO_TYPHOON is not set
1959# CONFIG_RADIO_ZOLTRIX is not set
1960# CONFIG_USB_DSBR is not set
1961# CONFIG_USB_SI470X is not set
1962CONFIG_DVB_CAPTURE_DRIVERS=y
1963
1964#
1965# Supported SAA7146 based PCI Adapters
1966#
1967# CONFIG_TTPCI_EEPROM is not set
1968# CONFIG_DVB_AV7110 is not set
1969# CONFIG_DVB_BUDGET_CORE is not set
1970
1971#
1972# Supported USB Adapters
1973#
1974CONFIG_DVB_USB=m
1975# CONFIG_DVB_USB_DEBUG is not set
1976CONFIG_DVB_USB_A800=m
1977CONFIG_DVB_USB_DIBUSB_MB=m
1978# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
1979CONFIG_DVB_USB_DIBUSB_MC=m
1980# CONFIG_DVB_USB_DIB0700 is not set
1981CONFIG_DVB_USB_UMT_010=m
1982# CONFIG_DVB_USB_CXUSB is not set
1983# CONFIG_DVB_USB_M920X is not set
1984# CONFIG_DVB_USB_GL861 is not set
1985# CONFIG_DVB_USB_AU6610 is not set
1986CONFIG_DVB_USB_DIGITV=m
1987CONFIG_DVB_USB_VP7045=m
1988CONFIG_DVB_USB_VP702X=m
1989CONFIG_DVB_USB_GP8PSK=m
1990CONFIG_DVB_USB_NOVA_T_USB2=m
1991# CONFIG_DVB_USB_TTUSB2 is not set
1992CONFIG_DVB_USB_DTT200U=m
1993# CONFIG_DVB_USB_OPERA1 is not set
1994# CONFIG_DVB_USB_AF9005 is not set
1995# CONFIG_DVB_USB_DW2102 is not set
1996# CONFIG_DVB_USB_ANYSEE is not set
1997# CONFIG_DVB_TTUSB_BUDGET is not set
1998# CONFIG_DVB_TTUSB_DEC is not set
1999# CONFIG_DVB_CINERGYT2 is not set
2000# CONFIG_DVB_SIANO_SMS1XXX is not set
2001
2002#
2003# Supported FlexCopII (B2C2) Adapters
2004#
2005# CONFIG_DVB_B2C2_FLEXCOP is not set
2006
2007#
2008# Supported BT878 Adapters
2009#
2010
2011#
2012# Supported Pluto2 Adapters
2013#
2014# CONFIG_DVB_PLUTO2 is not set
2015
2016#
2017# Supported DVB Frontends
2018#
2019
2020#
2021# Customise DVB Frontends
2022#
2023# CONFIG_DVB_FE_CUSTOMISE is not set
2024
2025#
2026# DVB-S (satellite) frontends
2027#
2028CONFIG_DVB_CX24110=m
2029CONFIG_DVB_CX24123=m
2030CONFIG_DVB_MT312=m
2031CONFIG_DVB_S5H1420=m
2032CONFIG_DVB_STV0299=m
2033CONFIG_DVB_TDA8083=m
2034CONFIG_DVB_TDA10086=m
2035CONFIG_DVB_VES1X93=m
2036# CONFIG_DVB_TUNER_ITD1000 is not set
2037CONFIG_DVB_TDA826X=m
2038CONFIG_DVB_TUA6100=m
2039
2040#
2041# DVB-T (terrestrial) frontends
2042#
2043CONFIG_DVB_SP8870=m
2044CONFIG_DVB_SP887X=m
2045CONFIG_DVB_CX22700=m
2046CONFIG_DVB_CX22702=m
2047# CONFIG_DVB_DRX397XD is not set
2048CONFIG_DVB_L64781=m
2049CONFIG_DVB_TDA1004X=m
2050CONFIG_DVB_NXT6000=m
2051CONFIG_DVB_MT352=m
2052CONFIG_DVB_ZL10353=m
2053CONFIG_DVB_DIB3000MB=m
2054CONFIG_DVB_DIB3000MC=m
2055# CONFIG_DVB_DIB7000M is not set
2056# CONFIG_DVB_DIB7000P is not set
2057CONFIG_DVB_TDA10048=m
2058
2059#
2060# DVB-C (cable) frontends
2061#
2062CONFIG_DVB_VES1820=m
2063CONFIG_DVB_TDA10021=m
2064# CONFIG_DVB_TDA10023 is not set
2065CONFIG_DVB_STV0297=m
2066
2067#
2068# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
2069#
2070CONFIG_DVB_NXT200X=m
2071CONFIG_DVB_OR51211=m
2072CONFIG_DVB_OR51132=m
2073CONFIG_DVB_BCM3510=m
2074CONFIG_DVB_LGDT330X=m
2075CONFIG_DVB_S5H1409=m
2076# CONFIG_DVB_AU8522 is not set
2077CONFIG_DVB_S5H1411=m
2078
2079#
2080# Digital terrestrial only tuners/PLL
2081#
2082CONFIG_DVB_PLL=m
2083# CONFIG_DVB_TUNER_DIB0070 is not set
2084
2085#
2086# SEC control devices for DVB-S
2087#
2088CONFIG_DVB_LNBP21=m
2089# CONFIG_DVB_ISL6405 is not set
2090CONFIG_DVB_ISL6421=m
2091CONFIG_DAB=y
2092CONFIG_USB_DABUSB=m
2093
2094#
2095# Graphics support
2096#
2097CONFIG_AGP=m
2098# CONFIG_AGP_ALI is not set
2099# CONFIG_AGP_ATI is not set
2100# CONFIG_AGP_AMD is not set
2101# CONFIG_AGP_AMD64 is not set
2102CONFIG_AGP_INTEL=m
2103CONFIG_AGP_NVIDIA=m
2104# CONFIG_AGP_SIS is not set
2105# CONFIG_AGP_SWORKS is not set
2106# CONFIG_AGP_VIA is not set
2107# CONFIG_AGP_EFFICEON is not set
2108CONFIG_DRM=m
2109# CONFIG_DRM_TDFX is not set
2110# CONFIG_DRM_R128 is not set
2111# CONFIG_DRM_RADEON is not set
2112# CONFIG_DRM_I810 is not set
2113# CONFIG_DRM_I830 is not set
2114# CONFIG_DRM_I915 is not set
2115# CONFIG_DRM_MGA is not set
2116# CONFIG_DRM_SIS is not set
2117# CONFIG_DRM_VIA is not set
2118# CONFIG_DRM_SAVAGE is not set
2119CONFIG_DRM_PSB=m
2120CONFIG_VGASTATE=m
2121CONFIG_VIDEO_OUTPUT_CONTROL=y
2122CONFIG_FB=y
2123CONFIG_FIRMWARE_EDID=y
2124CONFIG_FB_DDC=m
2125CONFIG_FB_CFB_FILLRECT=y
2126CONFIG_FB_CFB_COPYAREA=y
2127CONFIG_FB_CFB_IMAGEBLIT=y
2128# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
2129# CONFIG_FB_SYS_FILLRECT is not set
2130# CONFIG_FB_SYS_COPYAREA is not set
2131# CONFIG_FB_SYS_IMAGEBLIT is not set
2132# CONFIG_FB_FOREIGN_ENDIAN is not set
2133# CONFIG_FB_SYS_FOPS is not set
2134# CONFIG_FB_SVGALIB is not set
2135# CONFIG_FB_MACMODES is not set
2136CONFIG_FB_BACKLIGHT=y
2137CONFIG_FB_MODE_HELPERS=y
2138CONFIG_FB_TILEBLITTING=y
2139
2140#
2141# Frame buffer hardware drivers
2142#
2143# CONFIG_FB_CIRRUS is not set
2144# CONFIG_FB_PM2 is not set
2145# CONFIG_FB_CYBER2000 is not set
2146# CONFIG_FB_ARC is not set
2147# CONFIG_FB_ASILIANT is not set
2148# CONFIG_FB_IMSTT is not set
2149CONFIG_FB_VGA16=m
2150# CONFIG_FB_UVESA is not set
2151CONFIG_FB_VESA=y
2152# CONFIG_FB_EFI is not set
2153# CONFIG_FB_IMAC is not set
2154# CONFIG_FB_N411 is not set
2155# CONFIG_FB_HGA is not set
2156# CONFIG_FB_S1D13XXX is not set
2157CONFIG_FB_NVIDIA=m
2158CONFIG_FB_NVIDIA_I2C=y
2159# CONFIG_FB_NVIDIA_DEBUG is not set
2160CONFIG_FB_NVIDIA_BACKLIGHT=y
2161CONFIG_FB_RIVA=m
2162CONFIG_FB_RIVA_I2C=y
2163# CONFIG_FB_RIVA_DEBUG is not set
2164CONFIG_FB_RIVA_BACKLIGHT=y
2165CONFIG_FB_I810=m
2166CONFIG_FB_I810_GTF=y
2167CONFIG_FB_I810_I2C=y
2168# CONFIG_FB_LE80578 is not set
2169CONFIG_FB_INTEL=m
2170# CONFIG_FB_INTEL_DEBUG is not set
2171CONFIG_FB_INTEL_I2C=y
2172# CONFIG_FB_MATROX is not set
2173CONFIG_FB_RADEON=m
2174CONFIG_FB_RADEON_I2C=y
2175CONFIG_FB_RADEON_BACKLIGHT=y
2176# CONFIG_FB_RADEON_DEBUG is not set
2177# CONFIG_FB_ATY128 is not set
2178CONFIG_FB_ATY=m
2179CONFIG_FB_ATY_CT=y
2180CONFIG_FB_ATY_GENERIC_LCD=y
2181CONFIG_FB_ATY_GX=y
2182CONFIG_FB_ATY_BACKLIGHT=y
2183# CONFIG_FB_S3 is not set
2184# CONFIG_FB_SAVAGE is not set
2185# CONFIG_FB_SIS is not set
2186# CONFIG_FB_NEOMAGIC is not set
2187# CONFIG_FB_KYRO is not set
2188# CONFIG_FB_3DFX is not set
2189# CONFIG_FB_VOODOO1 is not set
2190# CONFIG_FB_VT8623 is not set
2191# CONFIG_FB_CYBLA is not set
2192# CONFIG_FB_TRIDENT is not set
2193# CONFIG_FB_ARK is not set
2194# CONFIG_FB_PM3 is not set
2195# CONFIG_FB_CARMINE is not set
2196# CONFIG_FB_GEODE is not set
2197# CONFIG_FB_VIRTUAL is not set
2198CONFIG_BACKLIGHT_LCD_SUPPORT=y
2199CONFIG_LCD_CLASS_DEVICE=m
2200# CONFIG_LCD_LTV350QV is not set
2201# CONFIG_LCD_ILI9320 is not set
2202# CONFIG_LCD_VGG2432A4 is not set
2203# CONFIG_LCD_PLATFORM is not set
2204CONFIG_BACKLIGHT_CLASS_DEVICE=y
2205# CONFIG_BACKLIGHT_CORGI is not set
2206# CONFIG_BACKLIGHT_PROGEAR is not set
2207# CONFIG_BACKLIGHT_MBP_NVIDIA is not set
2208
2209#
2210# Display device support
2211#
2212# CONFIG_DISPLAY_SUPPORT is not set
2213
2214#
2215# Console display driver support
2216#
2217CONFIG_VGA_CONSOLE=y
2218CONFIG_VGACON_SOFT_SCROLLBACK=y
2219CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
2220CONFIG_VIDEO_SELECT=y
2221CONFIG_MDA_CONSOLE=m
2222CONFIG_DUMMY_CONSOLE=y
2223CONFIG_FRAMEBUFFER_CONSOLE=y
2224# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
2225CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
2226# CONFIG_FONTS is not set
2227CONFIG_FONT_8x8=y
2228CONFIG_FONT_8x16=y
2229# CONFIG_LOGO is not set
2230CONFIG_SOUND=m
2231CONFIG_SND=m
2232CONFIG_SND_TIMER=m
2233CONFIG_SND_PCM=m
2234CONFIG_SND_HWDEP=m
2235CONFIG_SND_RAWMIDI=m
2236CONFIG_SND_SEQUENCER=m
2237CONFIG_SND_SEQ_DUMMY=m
2238CONFIG_SND_OSSEMUL=y
2239CONFIG_SND_MIXER_OSS=m
2240CONFIG_SND_PCM_OSS=m
2241CONFIG_SND_PCM_OSS_PLUGINS=y
2242CONFIG_SND_SEQUENCER_OSS=y
2243CONFIG_SND_DYNAMIC_MINORS=y
2244CONFIG_SND_SUPPORT_OLD_API=y
2245CONFIG_SND_VERBOSE_PROCFS=y
2246CONFIG_SND_VERBOSE_PRINTK=y
2247CONFIG_SND_DEBUG=y
2248# CONFIG_SND_DEBUG_VERBOSE is not set
2249# CONFIG_SND_PCM_XRUN_DEBUG is not set
2250CONFIG_SND_VMASTER=y
2251CONFIG_SND_MPU401_UART=m
2252CONFIG_SND_AC97_CODEC=m
2253CONFIG_SND_DRIVERS=y
2254CONFIG_SND_DUMMY=m
2255CONFIG_SND_VIRMIDI=m
2256CONFIG_SND_MTPAV=m
2257CONFIG_SND_SERIAL_U16550=m
2258CONFIG_SND_MPU401=m
2259CONFIG_SND_AC97_POWER_SAVE=y
2260CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0
2261CONFIG_SND_ISA=y
2262# CONFIG_SND_ADLIB is not set
2263# CONFIG_SND_AD1816A is not set
2264# CONFIG_SND_AD1848 is not set
2265# CONFIG_SND_ALS100 is not set
2266# CONFIG_SND_AZT2320 is not set
2267# CONFIG_SND_CMI8330 is not set
2268# CONFIG_SND_CS4231 is not set
2269# CONFIG_SND_CS4232 is not set
2270# CONFIG_SND_CS4236 is not set
2271# CONFIG_SND_DT019X is not set
2272# CONFIG_SND_ES968 is not set
2273# CONFIG_SND_ES1688 is not set
2274# CONFIG_SND_ES18XX is not set
2275# CONFIG_SND_SC6000 is not set
2276# CONFIG_SND_GUSCLASSIC is not set
2277# CONFIG_SND_GUSEXTREME is not set
2278# CONFIG_SND_GUSMAX is not set
2279# CONFIG_SND_INTERWAVE is not set
2280# CONFIG_SND_INTERWAVE_STB is not set
2281# CONFIG_SND_OPL3SA2 is not set
2282# CONFIG_SND_OPTI92X_AD1848 is not set
2283# CONFIG_SND_OPTI92X_CS4231 is not set
2284# CONFIG_SND_OPTI93X is not set
2285# CONFIG_SND_MIRO is not set
2286# CONFIG_SND_SB8 is not set
2287# CONFIG_SND_SB16 is not set
2288# CONFIG_SND_SBAWE is not set
2289# CONFIG_SND_SGALAXY is not set
2290# CONFIG_SND_SSCAPE is not set
2291# CONFIG_SND_WAVEFRONT is not set
2292CONFIG_SND_PCI=y
2293# CONFIG_SND_AD1889 is not set
2294# CONFIG_SND_ALS300 is not set
2295# CONFIG_SND_ALS4000 is not set
2296# CONFIG_SND_ALI5451 is not set
2297# CONFIG_SND_ATIIXP is not set
2298# CONFIG_SND_ATIIXP_MODEM is not set
2299# CONFIG_SND_AU8810 is not set
2300# CONFIG_SND_AU8820 is not set
2301# CONFIG_SND_AU8830 is not set
2302# CONFIG_SND_AW2 is not set
2303# CONFIG_SND_AZT3328 is not set
2304# CONFIG_SND_BT87X is not set
2305# CONFIG_SND_CA0106 is not set
2306# CONFIG_SND_CMIPCI is not set
2307# CONFIG_SND_OXYGEN is not set
2308# CONFIG_SND_CS4281 is not set
2309# CONFIG_SND_CS46XX is not set
2310# CONFIG_SND_CS5530 is not set
2311# CONFIG_SND_CS5535AUDIO is not set
2312# CONFIG_SND_DARLA20 is not set
2313# CONFIG_SND_GINA20 is not set
2314# CONFIG_SND_LAYLA20 is not set
2315# CONFIG_SND_DARLA24 is not set
2316# CONFIG_SND_GINA24 is not set
2317# CONFIG_SND_LAYLA24 is not set
2318# CONFIG_SND_MONA is not set
2319# CONFIG_SND_MIA is not set
2320# CONFIG_SND_ECHO3G is not set
2321# CONFIG_SND_INDIGO is not set
2322# CONFIG_SND_INDIGOIO is not set
2323# CONFIG_SND_INDIGODJ is not set
2324# CONFIG_SND_EMU10K1 is not set
2325# CONFIG_SND_EMU10K1X is not set
2326# CONFIG_SND_ENS1370 is not set
2327# CONFIG_SND_ENS1371 is not set
2328# CONFIG_SND_ES1938 is not set
2329# CONFIG_SND_ES1968 is not set
2330# CONFIG_SND_FM801 is not set
2331CONFIG_SND_HDA_INTEL=m
2332# CONFIG_SND_HDA_HWDEP is not set
2333CONFIG_SND_HDA_CODEC_REALTEK=y
2334CONFIG_SND_HDA_CODEC_ANALOG=y
2335CONFIG_SND_HDA_CODEC_SIGMATEL=y
2336CONFIG_SND_HDA_CODEC_VIA=y
2337CONFIG_SND_HDA_CODEC_ATIHDMI=y
2338CONFIG_SND_HDA_CODEC_CONEXANT=y
2339CONFIG_SND_HDA_CODEC_CMEDIA=y
2340CONFIG_SND_HDA_CODEC_SI3054=y
2341CONFIG_SND_HDA_GENERIC=y
2342# CONFIG_SND_HDA_POWER_SAVE is not set
2343# CONFIG_SND_HDSP is not set
2344# CONFIG_SND_HDSPM is not set
2345# CONFIG_SND_HIFIER is not set
2346# CONFIG_SND_ICE1712 is not set
2347# CONFIG_SND_ICE1724 is not set
2348CONFIG_SND_INTEL8X0=m
2349CONFIG_SND_INTEL8X0M=m
2350# CONFIG_SND_KORG1212 is not set
2351# CONFIG_SND_MAESTRO3 is not set
2352# CONFIG_SND_MIXART is not set
2353# CONFIG_SND_NM256 is not set
2354# CONFIG_SND_PCXHR is not set
2355# CONFIG_SND_RIPTIDE is not set
2356# CONFIG_SND_RME32 is not set
2357# CONFIG_SND_RME96 is not set
2358# CONFIG_SND_RME9652 is not set
2359# CONFIG_SND_SIS7019 is not set
2360# CONFIG_SND_SONICVIBES is not set
2361# CONFIG_SND_TRIDENT is not set
2362# CONFIG_SND_VIA82XX is not set
2363# CONFIG_SND_VIA82XX_MODEM is not set
2364# CONFIG_SND_VIRTUOSO is not set
2365# CONFIG_SND_VX222 is not set
2366# CONFIG_SND_YMFPCI is not set
2367CONFIG_SND_SPI=y
2368CONFIG_SND_USB=y
2369CONFIG_SND_USB_AUDIO=m
2370# CONFIG_SND_USB_USX2Y is not set
2371# CONFIG_SND_USB_CAIAQ is not set
2372# CONFIG_SND_SOC is not set
2373# CONFIG_SOUND_PRIME is not set
2374CONFIG_AC97_BUS=m
2375CONFIG_HID_SUPPORT=y
2376CONFIG_HID=y
2377# CONFIG_HID_DEBUG is not set
2378# CONFIG_HIDRAW is not set
2379
2380#
2381# USB Input Devices
2382#
2383CONFIG_USB_HID=y
2384CONFIG_USB_HIDINPUT_POWERBOOK=y
2385CONFIG_HID_FF=y
2386CONFIG_HID_PID=y
2387CONFIG_LOGITECH_FF=y
2388# CONFIG_LOGIRUMBLEPAD2_FF is not set
2389# CONFIG_PANTHERLORD_FF is not set
2390CONFIG_THRUSTMASTER_FF=y
2391# CONFIG_ZEROPLUS_FF is not set
2392CONFIG_USB_HIDDEV=y
2393CONFIG_USB_SUPPORT=y
2394CONFIG_USB_ARCH_HAS_HCD=y
2395CONFIG_USB_ARCH_HAS_OHCI=y
2396CONFIG_USB_ARCH_HAS_EHCI=y
2397CONFIG_USB=y
2398# CONFIG_USB_DEBUG is not set
2399# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
2400
2401#
2402# Miscellaneous USB options
2403#
2404CONFIG_USB_DEVICEFS=y
2405CONFIG_USB_DEVICE_CLASS=y
2406# CONFIG_USB_DYNAMIC_MINORS is not set
2407CONFIG_USB_SUSPEND=y
2408# CONFIG_USB_OTG is not set
2409CONFIG_USB_MON=y
2410
2411#
2412# USB Host Controller Drivers
2413#
2414# CONFIG_USB_C67X00_HCD is not set
2415CONFIG_USB_EHCI_HCD=y
2416CONFIG_USB_EHCI_ROOT_HUB_TT=y
2417CONFIG_USB_EHCI_TT_NEWSCHED=y
2418# CONFIG_USB_ISP116X_HCD is not set
2419# CONFIG_USB_ISP1760_HCD is not set
2420CONFIG_USB_OHCI_HCD=y
2421# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
2422# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
2423CONFIG_USB_OHCI_LITTLE_ENDIAN=y
2424CONFIG_USB_UHCI_HCD=y
2425# CONFIG_USB_SL811_HCD is not set
2426# CONFIG_USB_R8A66597_HCD is not set
2427# CONFIG_USB_GADGET_MUSB_HDRC is not set
2428
2429#
2430# USB Device Class drivers
2431#
2432CONFIG_USB_ACM=m
2433CONFIG_USB_PRINTER=m
2434# CONFIG_USB_WDM is not set
2435
2436#
2437# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
2438#
2439
2440#
2441# may also be needed; see USB_STORAGE Help for more information
2442#
2443CONFIG_USB_STORAGE=y
2444# CONFIG_USB_STORAGE_DEBUG is not set
2445CONFIG_USB_STORAGE_DATAFAB=y
2446CONFIG_USB_STORAGE_FREECOM=y
2447# CONFIG_USB_STORAGE_ISD200 is not set
2448CONFIG_USB_STORAGE_DPCM=y
2449CONFIG_USB_STORAGE_USBAT=y
2450CONFIG_USB_STORAGE_SDDR09=y
2451CONFIG_USB_STORAGE_SDDR55=y
2452CONFIG_USB_STORAGE_JUMPSHOT=y
2453CONFIG_USB_STORAGE_ALAUDA=y
2454# CONFIG_USB_STORAGE_ONETOUCH is not set
2455# CONFIG_USB_STORAGE_KARMA is not set
2456# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
2457# CONFIG_USB_LIBUSUAL is not set
2458
2459#
2460# USB Imaging devices
2461#
2462CONFIG_USB_MDC800=m
2463CONFIG_USB_MICROTEK=m
2464
2465#
2466# USB port drivers
2467#
2468CONFIG_USB_SERIAL=m
2469CONFIG_USB_EZUSB=y
2470CONFIG_USB_SERIAL_GENERIC=y
2471# CONFIG_USB_SERIAL_AIRCABLE is not set
2472CONFIG_USB_SERIAL_ARK3116=m
2473CONFIG_USB_SERIAL_BELKIN=m
2474# CONFIG_USB_SERIAL_CH341 is not set
2475CONFIG_USB_SERIAL_WHITEHEAT=m
2476CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
2477CONFIG_USB_SERIAL_CP2101=m
2478CONFIG_USB_SERIAL_CYPRESS_M8=m
2479CONFIG_USB_SERIAL_EMPEG=m
2480CONFIG_USB_SERIAL_FTDI_SIO=m
2481CONFIG_USB_SERIAL_FUNSOFT=m
2482CONFIG_USB_SERIAL_VISOR=m
2483CONFIG_USB_SERIAL_IPAQ=m
2484CONFIG_USB_SERIAL_IR=m
2485CONFIG_USB_SERIAL_EDGEPORT=m
2486CONFIG_USB_SERIAL_EDGEPORT_TI=m
2487CONFIG_USB_SERIAL_GARMIN=m
2488CONFIG_USB_SERIAL_IPW=m
2489# CONFIG_USB_SERIAL_IUU is not set
2490CONFIG_USB_SERIAL_KEYSPAN_PDA=m
2491CONFIG_USB_SERIAL_KEYSPAN=m
2492CONFIG_USB_SERIAL_KEYSPAN_MPR=y
2493CONFIG_USB_SERIAL_KEYSPAN_USA28=y
2494CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
2495CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
2496CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
2497CONFIG_USB_SERIAL_KEYSPAN_USA19=y
2498CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
2499CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
2500CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
2501CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
2502CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
2503CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
2504CONFIG_USB_SERIAL_KLSI=m
2505CONFIG_USB_SERIAL_KOBIL_SCT=m
2506CONFIG_USB_SERIAL_MCT_U232=m
2507# CONFIG_USB_SERIAL_MOS7720 is not set
2508# CONFIG_USB_SERIAL_MOS7840 is not set
2509# CONFIG_USB_SERIAL_MOTOROLA is not set
2510CONFIG_USB_SERIAL_NAVMAN=m
2511CONFIG_USB_SERIAL_PL2303=m
2512# CONFIG_USB_SERIAL_OTI6858 is not set
2513# CONFIG_USB_SERIAL_SPCP8X5 is not set
2514CONFIG_USB_SERIAL_HP4X=m
2515CONFIG_USB_SERIAL_SAFE=m
2516CONFIG_USB_SERIAL_SAFE_PADDED=y
2517CONFIG_USB_SERIAL_SIERRAWIRELESS=m
2518CONFIG_USB_SERIAL_TI=m
2519CONFIG_USB_SERIAL_CYBERJACK=m
2520CONFIG_USB_SERIAL_XIRCOM=m
2521CONFIG_USB_SERIAL_OPTION=m
2522CONFIG_USB_SERIAL_OMNINET=m
2523# CONFIG_USB_SERIAL_DEBUG is not set
2524
2525#
2526# USB Miscellaneous drivers
2527#
2528CONFIG_USB_EMI62=m
2529CONFIG_USB_EMI26=m
2530# CONFIG_USB_ADUTUX is not set
2531CONFIG_USB_RIO500=m
2532CONFIG_USB_LEGOTOWER=m
2533CONFIG_USB_LCD=m
2534# CONFIG_USB_BERRY_CHARGE is not set
2535CONFIG_USB_LED=m
2536CONFIG_USB_CYPRESS_CY7C63=m
2537CONFIG_USB_CYTHERM=m
2538# CONFIG_USB_PHIDGET is not set
2539CONFIG_USB_IDMOUSE=m
2540# CONFIG_USB_FTDI_ELAN is not set
2541CONFIG_USB_APPLEDISPLAY=m
2542CONFIG_USB_SISUSBVGA=m
2543CONFIG_USB_SISUSBVGA_CON=y
2544CONFIG_USB_LD=m
2545# CONFIG_USB_TRANCEVIBRATOR is not set
2546# CONFIG_USB_IOWARRIOR is not set
2547# CONFIG_USB_TEST is not set
2548# CONFIG_USB_ISIGHTFW is not set
2549CONFIG_USB_ATM=m
2550CONFIG_USB_SPEEDTOUCH=m
2551CONFIG_USB_CXACRU=m
2552CONFIG_USB_UEAGLEATM=m
2553CONFIG_USB_XUSBATM=m
2554CONFIG_USB_GADGET=y
2555# CONFIG_USB_GADGET_DEBUG is not set
2556CONFIG_USB_GADGET_DEBUG_FILES=y
2557# CONFIG_USB_GADGET_DEBUG_FS is not set
2558CONFIG_USB_GADGET_SELECTED=y
2559CONFIG_USB_GADGET_AMD5536UDC=y
2560CONFIG_USB_AMD5536UDC=y
2561# CONFIG_USB_GADGET_ATMEL_USBA is not set
2562# CONFIG_USB_GADGET_FSL_USB2 is not set
2563# CONFIG_USB_GADGET_NET2280 is not set
2564# CONFIG_USB_GADGET_PXA25X is not set
2565# CONFIG_USB_GADGET_M66592 is not set
2566# CONFIG_USB_GADGET_PXA27X is not set
2567# CONFIG_USB_GADGET_GOKU is not set
2568# CONFIG_USB_GADGET_LH7A40X is not set
2569# CONFIG_USB_GADGET_OMAP is not set
2570# CONFIG_USB_GADGET_S3C2410 is not set
2571# CONFIG_USB_GADGET_AT91 is not set
2572# CONFIG_USB_GADGET_DUMMY_HCD is not set
2573CONFIG_USB_GADGET_DUALSPEED=y
2574# CONFIG_USB_ZERO is not set
2575CONFIG_USB_ETH=m
2576CONFIG_USB_ETH_RNDIS=y
2577# CONFIG_USB_GADGETFS is not set
2578CONFIG_USB_FILE_STORAGE=m
2579CONFIG_USB_FILE_STORAGE_TEST=y
2580# CONFIG_USB_G_SERIAL is not set
2581# CONFIG_USB_MIDI_GADGET is not set
2582# CONFIG_USB_G_PRINTER is not set
2583# CONFIG_USB_CDC_COMPOSITE is not set
2584CONFIG_MMC=y
2585# CONFIG_MMC_DEBUG is not set
2586CONFIG_MMC_UNSAFE_RESUME=y
2587
2588#
2589# MMC/SD Card Drivers
2590#
2591CONFIG_MMC_BLOCK=y
2592CONFIG_MMC_BLOCK_BOUNCE=y
2593# CONFIG_SDIO_UART is not set
2594# CONFIG_MMC_TEST is not set
2595
2596#
2597# MMC/SD Host Controller Drivers
2598#
2599CONFIG_MMC_SDHCI=y
2600# CONFIG_MMC_SDHCI_PCI is not set
2601# CONFIG_MMC_WBSD is not set
2602# CONFIG_MMC_TIFM_SD is not set
2603# CONFIG_MEMSTICK is not set
2604CONFIG_NEW_LEDS=y
2605CONFIG_LEDS_CLASS=m
2606
2607#
2608# LED drivers
2609#
2610# CONFIG_LEDS_PCA9532 is not set
2611# CONFIG_LEDS_CLEVO_MAIL is not set
2612# CONFIG_LEDS_PCA955X is not set
2613
2614#
2615# LED Triggers
2616#
2617CONFIG_LEDS_TRIGGERS=y
2618CONFIG_LEDS_TRIGGER_TIMER=m
2619CONFIG_LEDS_TRIGGER_HEARTBEAT=m
2620# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
2621# CONFIG_ACCESSIBILITY is not set
2622# CONFIG_INFINIBAND is not set
2623# CONFIG_EDAC is not set
2624CONFIG_RTC_LIB=m
2625CONFIG_RTC_CLASS=m
2626
2627#
2628# RTC interfaces
2629#
2630CONFIG_RTC_INTF_SYSFS=y
2631CONFIG_RTC_INTF_PROC=y
2632CONFIG_RTC_INTF_DEV=y
2633CONFIG_RTC_INTF_DEV_UIE_EMUL=y
2634CONFIG_RTC_DRV_TEST=m
2635
2636#
2637# I2C RTC drivers
2638#
2639CONFIG_RTC_DRV_DS1307=m
2640# CONFIG_RTC_DRV_DS1374 is not set
2641CONFIG_RTC_DRV_DS1672=m
2642# CONFIG_RTC_DRV_MAX6900 is not set
2643CONFIG_RTC_DRV_RS5C372=m
2644CONFIG_RTC_DRV_ISL1208=m
2645CONFIG_RTC_DRV_X1205=m
2646CONFIG_RTC_DRV_PCF8563=m
2647CONFIG_RTC_DRV_PCF8583=m
2648# CONFIG_RTC_DRV_M41T80 is not set
2649# CONFIG_RTC_DRV_S35390A is not set
2650# CONFIG_RTC_DRV_FM3130 is not set
2651
2652#
2653# SPI RTC drivers
2654#
2655# CONFIG_RTC_DRV_M41T94 is not set
2656# CONFIG_RTC_DRV_DS1305 is not set
2657CONFIG_RTC_DRV_MAX6902=m
2658# CONFIG_RTC_DRV_R9701 is not set
2659CONFIG_RTC_DRV_RS5C348=m
2660
2661#
2662# Platform RTC drivers
2663#
2664# CONFIG_RTC_DRV_CMOS is not set
2665# CONFIG_RTC_DRV_DS1511 is not set
2666CONFIG_RTC_DRV_DS1553=m
2667CONFIG_RTC_DRV_DS1742=m
2668# CONFIG_RTC_DRV_STK17TA8 is not set
2669CONFIG_RTC_DRV_M48T86=m
2670# CONFIG_RTC_DRV_M48T59 is not set
2671CONFIG_RTC_DRV_V3020=m
2672
2673#
2674# on-CPU RTC drivers
2675#
2676# CONFIG_DMADEVICES is not set
2677# CONFIG_UIO is not set
2678
2679#
2680# Firmware Drivers
2681#
2682CONFIG_EDD=m
2683# CONFIG_EDD_OFF is not set
2684CONFIG_FIRMWARE_MEMMAP=y
2685# CONFIG_EFI_VARS is not set
2686# CONFIG_DELL_RBU is not set
2687# CONFIG_DCDBAS is not set
2688CONFIG_DMIID=y
2689# CONFIG_ISCSI_IBFT_FIND is not set
2690
2691#
2692# File systems
2693#
2694CONFIG_EXT2_FS=y
2695CONFIG_EXT2_FS_XATTR=y
2696CONFIG_EXT2_FS_POSIX_ACL=y
2697CONFIG_EXT2_FS_SECURITY=y
2698# CONFIG_EXT2_FS_XIP is not set
2699CONFIG_EXT3_FS=y
2700CONFIG_EXT3_FS_XATTR=y
2701CONFIG_EXT3_FS_POSIX_ACL=y
2702CONFIG_EXT3_FS_SECURITY=y
2703# CONFIG_EXT4DEV_FS is not set
2704CONFIG_JBD=y
2705# CONFIG_JBD_DEBUG is not set
2706CONFIG_FS_MBCACHE=y
2707CONFIG_REISERFS_FS=m
2708# CONFIG_REISERFS_CHECK is not set
2709# CONFIG_REISERFS_PROC_INFO is not set
2710CONFIG_REISERFS_FS_XATTR=y
2711CONFIG_REISERFS_FS_POSIX_ACL=y
2712CONFIG_REISERFS_FS_SECURITY=y
2713CONFIG_JFS_FS=m
2714CONFIG_JFS_POSIX_ACL=y
2715CONFIG_JFS_SECURITY=y
2716# CONFIG_JFS_DEBUG is not set
2717CONFIG_JFS_STATISTICS=y
2718CONFIG_FS_POSIX_ACL=y
2719# CONFIG_XFS_FS is not set
2720# CONFIG_GFS2_FS is not set
2721# CONFIG_OCFS2_FS is not set
2722CONFIG_DNOTIFY=y
2723CONFIG_INOTIFY=y
2724CONFIG_INOTIFY_USER=y
2725CONFIG_QUOTA=y
2726# CONFIG_QUOTA_NETLINK_INTERFACE is not set
2727CONFIG_PRINT_QUOTA_WARNING=y
2728CONFIG_QFMT_V1=m
2729CONFIG_QFMT_V2=m
2730CONFIG_QUOTACTL=y
2731CONFIG_AUTOFS_FS=m
2732CONFIG_AUTOFS4_FS=m
2733CONFIG_FUSE_FS=m
2734CONFIG_GENERIC_ACL=y
2735
2736#
2737# CD-ROM/DVD Filesystems
2738#
2739CONFIG_ISO9660_FS=y
2740CONFIG_JOLIET=y
2741CONFIG_ZISOFS=y
2742CONFIG_UDF_FS=m
2743CONFIG_UDF_NLS=y
2744
2745#
2746# DOS/FAT/NT Filesystems
2747#
2748CONFIG_FAT_FS=y
2749CONFIG_MSDOS_FS=y
2750CONFIG_VFAT_FS=y
2751CONFIG_FAT_DEFAULT_CODEPAGE=437
2752CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
2753CONFIG_NTFS_FS=m
2754# CONFIG_NTFS_DEBUG is not set
2755CONFIG_NTFS_RW=y
2756
2757#
2758# Pseudo filesystems
2759#
2760CONFIG_PROC_FS=y
2761CONFIG_PROC_KCORE=y
2762CONFIG_PROC_SYSCTL=y
2763CONFIG_SYSFS=y
2764CONFIG_TMPFS=y
2765CONFIG_TMPFS_POSIX_ACL=y
2766CONFIG_HUGETLBFS=y
2767CONFIG_HUGETLB_PAGE=y
2768CONFIG_CONFIGFS_FS=m
2769
2770#
2771# Miscellaneous filesystems
2772#
2773CONFIG_ADFS_FS=m
2774# CONFIG_ADFS_FS_RW is not set
2775CONFIG_AFFS_FS=m
2776# CONFIG_ECRYPT_FS is not set
2777CONFIG_HFS_FS=m
2778CONFIG_HFSPLUS_FS=m
2779CONFIG_BEFS_FS=m
2780# CONFIG_BEFS_DEBUG is not set
2781CONFIG_BFS_FS=m
2782CONFIG_EFS_FS=m
2783CONFIG_JFFS2_FS=m
2784CONFIG_JFFS2_FS_DEBUG=0
2785CONFIG_JFFS2_FS_WRITEBUFFER=y
2786# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
2787CONFIG_JFFS2_SUMMARY=y
2788CONFIG_JFFS2_FS_XATTR=y
2789CONFIG_JFFS2_FS_POSIX_ACL=y
2790CONFIG_JFFS2_FS_SECURITY=y
2791CONFIG_JFFS2_COMPRESSION_OPTIONS=y
2792CONFIG_JFFS2_ZLIB=y
2793# CONFIG_JFFS2_LZO is not set
2794CONFIG_JFFS2_RTIME=y
2795# CONFIG_JFFS2_RUBIN is not set
2796# CONFIG_JFFS2_CMODE_NONE is not set
2797CONFIG_JFFS2_CMODE_PRIORITY=y
2798# CONFIG_JFFS2_CMODE_SIZE is not set
2799# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
2800CONFIG_CRAMFS=y
2801CONFIG_VXFS_FS=m
2802# CONFIG_MINIX_FS is not set
2803# CONFIG_OMFS_FS is not set
2804CONFIG_HPFS_FS=m
2805CONFIG_QNX4FS_FS=m
2806CONFIG_ROMFS_FS=m
2807CONFIG_SYSV_FS=m
2808CONFIG_UFS_FS=m
2809CONFIG_UFS_FS_WRITE=y
2810# CONFIG_UFS_DEBUG is not set
2811CONFIG_NETWORK_FILESYSTEMS=y
2812CONFIG_NFS_FS=m
2813CONFIG_NFS_V3=y
2814CONFIG_NFS_V3_ACL=y
2815CONFIG_NFS_V4=y
2816CONFIG_NFSD=m
2817CONFIG_NFSD_V2_ACL=y
2818CONFIG_NFSD_V3=y
2819CONFIG_NFSD_V3_ACL=y
2820CONFIG_NFSD_V4=y
2821CONFIG_LOCKD=m
2822CONFIG_LOCKD_V4=y
2823CONFIG_EXPORTFS=m
2824CONFIG_NFS_ACL_SUPPORT=m
2825CONFIG_NFS_COMMON=y
2826CONFIG_SUNRPC=m
2827CONFIG_SUNRPC_GSS=m
2828CONFIG_RPCSEC_GSS_KRB5=m
2829CONFIG_RPCSEC_GSS_SPKM3=m
2830CONFIG_SMB_FS=y
2831# CONFIG_SMB_NLS_DEFAULT is not set
2832CONFIG_CIFS=m
2833CONFIG_CIFS_STATS=y
2834CONFIG_CIFS_STATS2=y
2835CONFIG_CIFS_WEAK_PW_HASH=y
2836# CONFIG_CIFS_UPCALL is not set
2837CONFIG_CIFS_XATTR=y
2838CONFIG_CIFS_POSIX=y
2839# CONFIG_CIFS_DEBUG2 is not set
2840# CONFIG_CIFS_EXPERIMENTAL is not set
2841# CONFIG_NCP_FS is not set
2842# CONFIG_CODA_FS is not set
2843# CONFIG_AFS_FS is not set
2844
2845#
2846# Partition Types
2847#
2848CONFIG_PARTITION_ADVANCED=y
2849# CONFIG_ACORN_PARTITION is not set
2850CONFIG_OSF_PARTITION=y
2851# CONFIG_AMIGA_PARTITION is not set
2852CONFIG_ATARI_PARTITION=y
2853CONFIG_MAC_PARTITION=y
2854CONFIG_MSDOS_PARTITION=y
2855CONFIG_BSD_DISKLABEL=y
2856# CONFIG_MINIX_SUBPARTITION is not set
2857CONFIG_SOLARIS_X86_PARTITION=y
2858CONFIG_UNIXWARE_DISKLABEL=y
2859CONFIG_LDM_PARTITION=y
2860# CONFIG_LDM_DEBUG is not set
2861CONFIG_SGI_PARTITION=y
2862CONFIG_ULTRIX_PARTITION=y
2863CONFIG_SUN_PARTITION=y
2864CONFIG_KARMA_PARTITION=y
2865CONFIG_EFI_PARTITION=y
2866# CONFIG_SYSV68_PARTITION is not set
2867CONFIG_NLS=y
2868CONFIG_NLS_DEFAULT="utf8"
2869CONFIG_NLS_CODEPAGE_437=y
2870CONFIG_NLS_CODEPAGE_737=m
2871CONFIG_NLS_CODEPAGE_775=m
2872CONFIG_NLS_CODEPAGE_850=m
2873CONFIG_NLS_CODEPAGE_852=m
2874CONFIG_NLS_CODEPAGE_855=m
2875CONFIG_NLS_CODEPAGE_857=m
2876CONFIG_NLS_CODEPAGE_860=m
2877CONFIG_NLS_CODEPAGE_861=m
2878CONFIG_NLS_CODEPAGE_862=m
2879CONFIG_NLS_CODEPAGE_863=m
2880CONFIG_NLS_CODEPAGE_864=m
2881CONFIG_NLS_CODEPAGE_865=m
2882CONFIG_NLS_CODEPAGE_866=m
2883CONFIG_NLS_CODEPAGE_869=m
2884CONFIG_NLS_CODEPAGE_936=m
2885CONFIG_NLS_CODEPAGE_950=m
2886CONFIG_NLS_CODEPAGE_932=m
2887CONFIG_NLS_CODEPAGE_949=m
2888CONFIG_NLS_CODEPAGE_874=m
2889CONFIG_NLS_ISO8859_8=m
2890CONFIG_NLS_CODEPAGE_1250=m
2891CONFIG_NLS_CODEPAGE_1251=m
2892CONFIG_NLS_ASCII=y
2893CONFIG_NLS_ISO8859_1=y
2894CONFIG_NLS_ISO8859_2=m
2895CONFIG_NLS_ISO8859_3=m
2896CONFIG_NLS_ISO8859_4=m
2897CONFIG_NLS_ISO8859_5=m
2898CONFIG_NLS_ISO8859_6=m
2899CONFIG_NLS_ISO8859_7=m
2900CONFIG_NLS_ISO8859_9=m
2901CONFIG_NLS_ISO8859_13=m
2902CONFIG_NLS_ISO8859_14=m
2903CONFIG_NLS_ISO8859_15=m
2904CONFIG_NLS_KOI8_R=m
2905CONFIG_NLS_KOI8_U=m
2906CONFIG_NLS_UTF8=m
2907# CONFIG_DLM is not set
2908
2909#
2910# Kernel hacking
2911#
2912CONFIG_TRACE_IRQFLAGS_SUPPORT=y
2913# CONFIG_PRINTK_TIME is not set
2914CONFIG_ENABLE_WARN_DEPRECATED=y
2915CONFIG_ENABLE_MUST_CHECK=y
2916CONFIG_FRAME_WARN=1024
2917CONFIG_MAGIC_SYSRQ=y
2918# CONFIG_UNUSED_SYMBOLS is not set
2919CONFIG_DEBUG_FS=y
2920# CONFIG_HEADERS_CHECK is not set
2921CONFIG_DEBUG_KERNEL=y
2922# CONFIG_DEBUG_SHIRQ is not set
2923CONFIG_DETECT_SOFTLOCKUP=y
2924# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
2925CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
2926CONFIG_SCHED_DEBUG=y
2927# CONFIG_SCHEDSTATS is not set
2928CONFIG_TIMER_STATS=y
2929# CONFIG_DEBUG_OBJECTS is not set
2930# CONFIG_DEBUG_SLAB is not set
2931# CONFIG_DEBUG_RT_MUTEXES is not set
2932# CONFIG_RT_MUTEX_TESTER is not set
2933# CONFIG_DEBUG_SPINLOCK is not set
2934# CONFIG_DEBUG_MUTEXES is not set
2935# CONFIG_DEBUG_LOCK_ALLOC is not set
2936# CONFIG_PROVE_LOCKING is not set
2937# CONFIG_LOCK_STAT is not set
2938# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
2939# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
2940# CONFIG_DEBUG_KOBJECT is not set
2941# CONFIG_DEBUG_HIGHMEM is not set
2942CONFIG_DEBUG_BUGVERBOSE=y
2943# CONFIG_DEBUG_INFO is not set
2944# CONFIG_DEBUG_VM is not set
2945# CONFIG_DEBUG_WRITECOUNT is not set
2946CONFIG_DEBUG_MEMORY_INIT=y
2947# CONFIG_DEBUG_LIST is not set
2948# CONFIG_DEBUG_SG is not set
2949# CONFIG_FRAME_POINTER is not set
2950# CONFIG_BOOT_PRINTK_DELAY is not set
2951# CONFIG_RCU_TORTURE_TEST is not set
2952# CONFIG_BACKTRACE_SELF_TEST is not set
2953# CONFIG_FAULT_INJECTION is not set
2954# CONFIG_LATENCYTOP is not set
2955# CONFIG_SYSCTL_SYSCALL_CHECK is not set
2956CONFIG_HAVE_FTRACE=y
2957CONFIG_HAVE_DYNAMIC_FTRACE=y
2958# CONFIG_FTRACE is not set
2959# CONFIG_IRQSOFF_TRACER is not set
2960# CONFIG_SYSPROF_TRACER is not set
2961# CONFIG_SCHED_TRACER is not set
2962# CONFIG_CONTEXT_SWITCH_TRACER is not set
2963# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
2964# CONFIG_SAMPLES is not set
2965CONFIG_HAVE_ARCH_KGDB=y
2966# CONFIG_KGDB is not set
2967# CONFIG_STRICT_DEVMEM is not set
2968CONFIG_X86_VERBOSE_BOOTUP=y
2969CONFIG_EARLY_PRINTK=y
2970# CONFIG_DEBUG_STACKOVERFLOW is not set
2971# CONFIG_DEBUG_STACK_USAGE is not set
2972# CONFIG_DEBUG_PAGEALLOC is not set
2973# CONFIG_DEBUG_PER_CPU_MAPS is not set
2974# CONFIG_X86_PTDUMP is not set
2975# CONFIG_DEBUG_RODATA is not set
2976# CONFIG_DEBUG_NX_TEST is not set
2977# CONFIG_4KSTACKS is not set
2978CONFIG_DOUBLEFAULT=y
2979# CONFIG_MMIOTRACE is not set
2980CONFIG_IO_DELAY_TYPE_0X80=0
2981CONFIG_IO_DELAY_TYPE_0XED=1
2982CONFIG_IO_DELAY_TYPE_UDELAY=2
2983CONFIG_IO_DELAY_TYPE_NONE=3
2984CONFIG_IO_DELAY_0X80=y
2985# CONFIG_IO_DELAY_0XED is not set
2986# CONFIG_IO_DELAY_UDELAY is not set
2987# CONFIG_IO_DELAY_NONE is not set
2988CONFIG_DEFAULT_IO_DELAY_TYPE=0
2989# CONFIG_DEBUG_BOOT_PARAMS is not set
2990# CONFIG_CPA_DEBUG is not set
2991# CONFIG_OPTIMIZE_INLINING is not set
2992
2993#
2994# Security options
2995#
2996CONFIG_KEYS=y
2997CONFIG_KEYS_DEBUG_PROC_KEYS=y
2998CONFIG_SECURITY=y
2999CONFIG_SECURITY_NETWORK=y
3000# CONFIG_SECURITY_NETWORK_XFRM is not set
3001# CONFIG_SECURITY_FILE_CAPABILITIES is not set
3002# CONFIG_SECURITY_ROOTPLUG is not set
3003CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
3004CONFIG_SECURITY_SELINUX=y
3005CONFIG_SECURITY_SELINUX_BOOTPARAM=y
3006CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
3007CONFIG_SECURITY_SELINUX_DISABLE=y
3008CONFIG_SECURITY_SELINUX_DEVELOP=y
3009CONFIG_SECURITY_SELINUX_AVC_STATS=y
3010CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
3011# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
3012# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
3013CONFIG_CRYPTO=y
3014
3015#
3016# Crypto core or helper
3017#
3018CONFIG_CRYPTO_ALGAPI=y
3019CONFIG_CRYPTO_AEAD=m
3020CONFIG_CRYPTO_BLKCIPHER=y
3021CONFIG_CRYPTO_HASH=y
3022CONFIG_CRYPTO_MANAGER=y
3023# CONFIG_CRYPTO_GF128MUL is not set
3024CONFIG_CRYPTO_NULL=m
3025# CONFIG_CRYPTO_CRYPTD is not set
3026CONFIG_CRYPTO_AUTHENC=m
3027CONFIG_CRYPTO_TEST=m
3028
3029#
3030# Authenticated Encryption with Associated Data
3031#
3032# CONFIG_CRYPTO_CCM is not set
3033# CONFIG_CRYPTO_GCM is not set
3034# CONFIG_CRYPTO_SEQIV is not set
3035
3036#
3037# Block modes
3038#
3039CONFIG_CRYPTO_CBC=y
3040# CONFIG_CRYPTO_CTR is not set
3041# CONFIG_CRYPTO_CTS is not set
3042CONFIG_CRYPTO_ECB=m
3043# CONFIG_CRYPTO_LRW is not set
3044CONFIG_CRYPTO_PCBC=m
3045# CONFIG_CRYPTO_XTS is not set
3046
3047#
3048# Hash modes
3049#
3050CONFIG_CRYPTO_HMAC=y
3051# CONFIG_CRYPTO_XCBC is not set
3052
3053#
3054# Digest
3055#
3056CONFIG_CRYPTO_CRC32C=m
3057CONFIG_CRYPTO_MD4=m
3058CONFIG_CRYPTO_MD5=y
3059CONFIG_CRYPTO_MICHAEL_MIC=m
3060# CONFIG_CRYPTO_RMD128 is not set
3061# CONFIG_CRYPTO_RMD160 is not set
3062# CONFIG_CRYPTO_RMD256 is not set
3063# CONFIG_CRYPTO_RMD320 is not set
3064CONFIG_CRYPTO_SHA1=m
3065CONFIG_CRYPTO_SHA256=m
3066CONFIG_CRYPTO_SHA512=m
3067CONFIG_CRYPTO_TGR192=m
3068CONFIG_CRYPTO_WP512=m
3069
3070#
3071# Ciphers
3072#
3073CONFIG_CRYPTO_AES=m
3074CONFIG_CRYPTO_AES_586=m
3075CONFIG_CRYPTO_ANUBIS=m
3076CONFIG_CRYPTO_ARC4=m
3077CONFIG_CRYPTO_BLOWFISH=m
3078# CONFIG_CRYPTO_CAMELLIA is not set
3079CONFIG_CRYPTO_CAST5=y
3080CONFIG_CRYPTO_CAST6=m
3081CONFIG_CRYPTO_DES=y
3082# CONFIG_CRYPTO_FCRYPT is not set
3083CONFIG_CRYPTO_KHAZAD=m
3084# CONFIG_CRYPTO_SALSA20 is not set
3085# CONFIG_CRYPTO_SALSA20_586 is not set
3086# CONFIG_CRYPTO_SEED is not set
3087CONFIG_CRYPTO_SERPENT=m
3088CONFIG_CRYPTO_TEA=m
3089CONFIG_CRYPTO_TWOFISH=m
3090CONFIG_CRYPTO_TWOFISH_COMMON=m
3091# CONFIG_CRYPTO_TWOFISH_586 is not set
3092
3093#
3094# Compression
3095#
3096CONFIG_CRYPTO_DEFLATE=m
3097# CONFIG_CRYPTO_LZO is not set
3098CONFIG_CRYPTO_HW=y
3099CONFIG_CRYPTO_DEV_PADLOCK=m
3100CONFIG_CRYPTO_DEV_PADLOCK_AES=m
3101CONFIG_CRYPTO_DEV_PADLOCK_SHA=m
3102CONFIG_CRYPTO_DEV_GEODE=m
3103# CONFIG_CRYPTO_DEV_HIFN_795X is not set
3104CONFIG_HAVE_KVM=y
3105CONFIG_VIRTUALIZATION=y
3106# CONFIG_KVM is not set
3107# CONFIG_LGUEST is not set
3108# CONFIG_VIRTIO_PCI is not set
3109# CONFIG_VIRTIO_BALLOON is not set
3110
3111#
3112# Library routines
3113#
3114CONFIG_BITREVERSE=y
3115CONFIG_GENERIC_FIND_FIRST_BIT=y
3116CONFIG_GENERIC_FIND_NEXT_BIT=y
3117CONFIG_CRC_CCITT=m
3118CONFIG_CRC16=m
3119# CONFIG_CRC_T10DIF is not set
3120CONFIG_CRC_ITU_T=m
3121CONFIG_CRC32=y
3122# CONFIG_CRC7 is not set
3123CONFIG_LIBCRC32C=m
3124CONFIG_AUDIT_GENERIC=y
3125CONFIG_ZLIB_INFLATE=y
3126CONFIG_ZLIB_DEFLATE=m
3127CONFIG_REED_SOLOMON=m
3128CONFIG_REED_SOLOMON_DEC16=y
3129CONFIG_TEXTSEARCH=y
3130CONFIG_TEXTSEARCH_KMP=m
3131CONFIG_TEXTSEARCH_BM=m
3132CONFIG_TEXTSEARCH_FSM=m
3133CONFIG_PLIST=y
3134CONFIG_HAS_IOMEM=y
3135CONFIG_HAS_IOPORT=y
3136CONFIG_HAS_DMA=y
3137CONFIG_CHECK_SIGNATURE=y
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/defconfig-netbook b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/defconfig-netbook
new file mode 100644
index 0000000000..b520435082
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/defconfig-netbook
@@ -0,0 +1,2403 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.27
4# Wed Nov 5 17:17:12 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="-netbook"
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
772# CONFIG_BLK_DEV_RAM is not set
773CONFIG_CDROM_PKTCDVD=m
774CONFIG_CDROM_PKTCDVD_BUFFERS=8
775# CONFIG_CDROM_PKTCDVD_WCACHE is not set
776# CONFIG_ATA_OVER_ETH is not set
777# CONFIG_BLK_DEV_HD is not set
778CONFIG_MISC_DEVICES=y
779# CONFIG_IBM_ASM is not set
780# CONFIG_PHANTOM is not set
781CONFIG_EEPROM_93CX6=m
782# CONFIG_SGI_IOC4 is not set
783CONFIG_TIFM_CORE=m
784CONFIG_TIFM_7XX1=m
785# CONFIG_ACER_WMI is not set
786# CONFIG_FUJITSU_LAPTOP is not set
787# CONFIG_TC1100_WMI is not set
788# CONFIG_HP_WMI is not set
789# CONFIG_MSI_LAPTOP is not set
790# CONFIG_COMPAL_LAPTOP is not set
791# CONFIG_SONY_LAPTOP is not set
792# CONFIG_THINKPAD_ACPI is not set
793# CONFIG_INTEL_MENLOW is not set
794CONFIG_EEEPC_LAPTOP=y
795# CONFIG_ENCLOSURE_SERVICES is not set
796# CONFIG_HP_ILO is not set
797CONFIG_HAVE_IDE=y
798# CONFIG_IDE is not set
799
800#
801# SCSI device support
802#
803CONFIG_RAID_ATTRS=m
804CONFIG_SCSI=y
805CONFIG_SCSI_DMA=y
806# CONFIG_SCSI_TGT is not set
807# CONFIG_SCSI_NETLINK is not set
808CONFIG_SCSI_PROC_FS=y
809
810#
811# SCSI support type (disk, tape, CD-ROM)
812#
813CONFIG_BLK_DEV_SD=y
814CONFIG_CHR_DEV_ST=m
815# CONFIG_CHR_DEV_OSST is not set
816CONFIG_BLK_DEV_SR=y
817CONFIG_BLK_DEV_SR_VENDOR=y
818# CONFIG_CHR_DEV_SG is not set
819CONFIG_CHR_DEV_SCH=m
820
821#
822# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
823#
824CONFIG_SCSI_MULTI_LUN=y
825CONFIG_SCSI_CONSTANTS=y
826CONFIG_SCSI_LOGGING=y
827CONFIG_SCSI_SCAN_ASYNC=y
828CONFIG_SCSI_WAIT_SCAN=m
829
830#
831# SCSI Transports
832#
833# CONFIG_SCSI_SPI_ATTRS is not set
834# CONFIG_SCSI_FC_ATTRS is not set
835# CONFIG_SCSI_ISCSI_ATTRS is not set
836# CONFIG_SCSI_SAS_ATTRS is not set
837# CONFIG_SCSI_SAS_LIBSAS is not set
838# CONFIG_SCSI_SRP_ATTRS is not set
839CONFIG_SCSI_LOWLEVEL=y
840# CONFIG_ISCSI_TCP is not set
841# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
842# CONFIG_SCSI_3W_9XXX is not set
843# CONFIG_SCSI_ACARD is not set
844# CONFIG_SCSI_AACRAID is not set
845# CONFIG_SCSI_AIC7XXX is not set
846# CONFIG_SCSI_AIC7XXX_OLD is not set
847# CONFIG_SCSI_AIC79XX is not set
848# CONFIG_SCSI_AIC94XX is not set
849# CONFIG_SCSI_DPT_I2O is not set
850# CONFIG_SCSI_ADVANSYS is not set
851# CONFIG_SCSI_ARCMSR is not set
852# CONFIG_MEGARAID_NEWGEN is not set
853# CONFIG_MEGARAID_LEGACY is not set
854# CONFIG_MEGARAID_SAS is not set
855# CONFIG_SCSI_HPTIOP is not set
856# CONFIG_SCSI_BUSLOGIC is not set
857# CONFIG_SCSI_DMX3191D is not set
858# CONFIG_SCSI_EATA is not set
859# CONFIG_SCSI_FUTURE_DOMAIN is not set
860# CONFIG_SCSI_GDTH is not set
861# CONFIG_SCSI_IPS is not set
862# CONFIG_SCSI_INITIO is not set
863# CONFIG_SCSI_INIA100 is not set
864# CONFIG_SCSI_MVSAS is not set
865# CONFIG_SCSI_STEX is not set
866# CONFIG_SCSI_SYM53C8XX_2 is not set
867# CONFIG_SCSI_IPR is not set
868# CONFIG_SCSI_QLOGIC_1280 is not set
869# CONFIG_SCSI_QLA_FC is not set
870# CONFIG_SCSI_QLA_ISCSI is not set
871# CONFIG_SCSI_LPFC is not set
872# CONFIG_SCSI_DC395x is not set
873# CONFIG_SCSI_DC390T is not set
874# CONFIG_SCSI_NSP32 is not set
875# CONFIG_SCSI_DEBUG is not set
876# CONFIG_SCSI_SRP is not set
877# CONFIG_SCSI_DH is not set
878CONFIG_ATA=y
879# CONFIG_ATA_NONSTANDARD is not set
880CONFIG_ATA_ACPI=y
881# CONFIG_SATA_PMP is not set
882CONFIG_SATA_AHCI=y
883# CONFIG_SATA_SIL24 is not set
884CONFIG_ATA_SFF=y
885# CONFIG_SATA_SVW is not set
886CONFIG_ATA_PIIX=y
887# CONFIG_SATA_MV is not set
888# CONFIG_SATA_NV is not set
889# CONFIG_PDC_ADMA is not set
890# CONFIG_SATA_QSTOR is not set
891# CONFIG_SATA_PROMISE is not set
892# CONFIG_SATA_SX4 is not set
893# CONFIG_SATA_SIL is not set
894# CONFIG_SATA_SIS is not set
895# CONFIG_SATA_ULI is not set
896# CONFIG_SATA_VIA is not set
897# CONFIG_SATA_VITESSE is not set
898# CONFIG_SATA_INIC162X is not set
899# CONFIG_PATA_ACPI is not set
900# CONFIG_PATA_ALI is not set
901# CONFIG_PATA_AMD is not set
902# CONFIG_PATA_ARTOP is not set
903# CONFIG_PATA_ATIIXP is not set
904# CONFIG_PATA_CMD640_PCI is not set
905# CONFIG_PATA_CMD64X is not set
906# CONFIG_PATA_CS5520 is not set
907# CONFIG_PATA_CS5530 is not set
908# CONFIG_PATA_CS5535 is not set
909# CONFIG_PATA_CS5536 is not set
910# CONFIG_PATA_CYPRESS is not set
911# CONFIG_PATA_EFAR is not set
912# CONFIG_ATA_GENERIC is not set
913# CONFIG_PATA_HPT366 is not set
914# CONFIG_PATA_HPT37X is not set
915# CONFIG_PATA_HPT3X2N is not set
916# CONFIG_PATA_HPT3X3 is not set
917# CONFIG_PATA_IT821X is not set
918# CONFIG_PATA_IT8213 is not set
919# CONFIG_PATA_JMICRON is not set
920# CONFIG_PATA_TRIFLEX is not set
921# CONFIG_PATA_MARVELL is not set
922# CONFIG_PATA_MPIIX is not set
923# CONFIG_PATA_OLDPIIX is not set
924# CONFIG_PATA_NETCELL is not set
925# CONFIG_PATA_NINJA32 is not set
926# CONFIG_PATA_NS87410 is not set
927# CONFIG_PATA_NS87415 is not set
928# CONFIG_PATA_OPTI is not set
929# CONFIG_PATA_OPTIDMA is not set
930# CONFIG_PATA_PDC_OLD is not set
931# CONFIG_PATA_RADISYS is not set
932# CONFIG_PATA_RZ1000 is not set
933# CONFIG_PATA_SC1200 is not set
934# CONFIG_PATA_SERVERWORKS is not set
935# CONFIG_PATA_PDC2027X is not set
936# CONFIG_PATA_SIL680 is not set
937# CONFIG_PATA_SIS is not set
938# CONFIG_PATA_VIA is not set
939# CONFIG_PATA_WINBOND is not set
940CONFIG_PATA_SCH=y
941# CONFIG_MD is not set
942# CONFIG_FUSION is not set
943
944#
945# IEEE 1394 (FireWire) support
946#
947
948#
949# Enable only one of the two stacks, unless you know what you are doing
950#
951# CONFIG_FIREWIRE is not set
952# CONFIG_IEEE1394 is not set
953# CONFIG_I2O is not set
954# CONFIG_MACINTOSH_DRIVERS is not set
955CONFIG_NETDEVICES=y
956# CONFIG_DUMMY is not set
957# CONFIG_BONDING is not set
958CONFIG_MACVLAN=m
959# CONFIG_EQUALIZER is not set
960# CONFIG_TUN is not set
961# CONFIG_VETH is not set
962# CONFIG_NET_SB1000 is not set
963# CONFIG_ARCNET is not set
964CONFIG_PHYLIB=m
965
966#
967# MII PHY device drivers
968#
969CONFIG_MARVELL_PHY=m
970CONFIG_DAVICOM_PHY=m
971CONFIG_QSEMI_PHY=m
972CONFIG_LXT_PHY=m
973CONFIG_CICADA_PHY=m
974CONFIG_VITESSE_PHY=m
975CONFIG_SMSC_PHY=m
976CONFIG_BROADCOM_PHY=m
977CONFIG_ICPLUS_PHY=m
978CONFIG_REALTEK_PHY=m
979CONFIG_MDIO_BITBANG=m
980CONFIG_NET_ETHERNET=y
981CONFIG_MII=m
982CONFIG_HAPPYMEAL=m
983CONFIG_SUNGEM=m
984CONFIG_CASSINI=m
985CONFIG_NET_VENDOR_3COM=y
986# CONFIG_VORTEX is not set
987# CONFIG_TYPHOON is not set
988# CONFIG_NET_TULIP is not set
989# CONFIG_HP100 is not set
990# CONFIG_IBM_NEW_EMAC_ZMII is not set
991# CONFIG_IBM_NEW_EMAC_RGMII is not set
992# CONFIG_IBM_NEW_EMAC_TAH is not set
993# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
994# CONFIG_NET_PCI is not set
995# CONFIG_B44 is not set
996CONFIG_NETDEV_1000=y
997# CONFIG_ACENIC is not set
998# CONFIG_DL2K is not set
999# CONFIG_E1000 is not set
1000# CONFIG_E1000E is not set
1001# CONFIG_IP1000 is not set
1002# CONFIG_IGB is not set
1003# CONFIG_NS83820 is not set
1004# CONFIG_HAMACHI is not set
1005# CONFIG_YELLOWFIN is not set
1006# CONFIG_R8169 is not set
1007# CONFIG_SIS190 is not set
1008# CONFIG_SKGE is not set
1009# CONFIG_SKY2 is not set
1010# CONFIG_VIA_VELOCITY is not set
1011# CONFIG_TIGON3 is not set
1012# CONFIG_BNX2 is not set
1013# CONFIG_QLA3XXX is not set
1014CONFIG_ATL1=m
1015CONFIG_ATL1E=m
1016# CONFIG_NETDEV_10000 is not set
1017# CONFIG_TR is not set
1018
1019#
1020# Wireless LAN
1021#
1022CONFIG_WLAN_PRE80211=y
1023# CONFIG_STRIP is not set
1024CONFIG_WLAN_80211=y
1025# CONFIG_IPW2100 is not set
1026# CONFIG_IPW2200 is not set
1027# CONFIG_LIBERTAS is not set
1028# CONFIG_AIRO is not set
1029# CONFIG_HERMES is not set
1030# CONFIG_ATMEL is not set
1031# CONFIG_PRISM54 is not set
1032CONFIG_USB_ZD1201=m
1033CONFIG_USB_NET_RNDIS_WLAN=m
1034CONFIG_RTL8180=m
1035CONFIG_RTL8187=m
1036# CONFIG_ADM8211 is not set
1037# CONFIG_MAC80211_HWSIM is not set
1038# CONFIG_P54_COMMON is not set
1039CONFIG_ATH5K=m
1040# CONFIG_ATH5K_DEBUG is not set
1041# CONFIG_ATH9K is not set
1042CONFIG_IWLWIFI=m
1043CONFIG_IWLCORE=m
1044# CONFIG_IWLWIFI_LEDS is not set
1045CONFIG_IWLWIFI_RFKILL=y
1046# CONFIG_IWLWIFI_DEBUG is not set
1047# CONFIG_IWLAGN is not set
1048CONFIG_IWL3945=m
1049CONFIG_IWL3945_RFKILL=y
1050# CONFIG_IWL3945_SPECTRUM_MEASUREMENT is not set
1051# CONFIG_IWL3945_LEDS is not set
1052# CONFIG_IWL3945_DEBUG is not set
1053# CONFIG_HOSTAP is not set
1054# CONFIG_B43 is not set
1055# CONFIG_B43LEGACY is not set
1056# CONFIG_ZD1211RW is not set
1057CONFIG_RT2X00=m
1058CONFIG_RT2X00_LIB=m
1059CONFIG_RT2X00_LIB_PCI=m
1060CONFIG_RT2X00_LIB_USB=m
1061CONFIG_RT2X00_LIB_FIRMWARE=y
1062CONFIG_RT2X00_LIB_RFKILL=y
1063CONFIG_RT2X00_LIB_LEDS=y
1064CONFIG_RT2400PCI=m
1065CONFIG_RT2400PCI_RFKILL=y
1066CONFIG_RT2400PCI_LEDS=y
1067CONFIG_RT2500PCI=m
1068CONFIG_RT2500PCI_RFKILL=y
1069CONFIG_RT2500PCI_LEDS=y
1070CONFIG_RT61PCI=m
1071CONFIG_RT61PCI_RFKILL=y
1072CONFIG_RT61PCI_LEDS=y
1073CONFIG_RT2500USB=m
1074CONFIG_RT2500USB_LEDS=y
1075CONFIG_RT73USB=m
1076CONFIG_RT73USB_LEDS=y
1077CONFIG_RT2X00_LIB_DEBUGFS=y
1078# CONFIG_RT2X00_DEBUG is not set
1079
1080#
1081# USB Network Adapters
1082#
1083CONFIG_USB_CATC=m
1084CONFIG_USB_KAWETH=m
1085CONFIG_USB_PEGASUS=m
1086CONFIG_USB_RTL8150=m
1087CONFIG_USB_USBNET=m
1088CONFIG_USB_NET_AX8817X=m
1089CONFIG_USB_NET_CDCETHER=m
1090CONFIG_USB_NET_DM9601=m
1091CONFIG_USB_NET_GL620A=m
1092CONFIG_USB_NET_NET1080=m
1093CONFIG_USB_NET_PLUSB=m
1094CONFIG_USB_NET_MCS7830=m
1095CONFIG_USB_NET_RNDIS_HOST=m
1096CONFIG_USB_NET_CDC_SUBSET=m
1097CONFIG_USB_ALI_M5632=y
1098CONFIG_USB_AN2720=y
1099CONFIG_USB_BELKIN=y
1100CONFIG_USB_ARMLINUX=y
1101CONFIG_USB_EPSON2888=y
1102CONFIG_USB_KC2190=y
1103CONFIG_USB_NET_ZAURUS=m
1104# CONFIG_USB_HSO is not set
1105# CONFIG_WAN is not set
1106# CONFIG_FDDI is not set
1107# CONFIG_HIPPI is not set
1108CONFIG_PPP=m
1109CONFIG_PPP_MULTILINK=y
1110CONFIG_PPP_FILTER=y
1111CONFIG_PPP_ASYNC=m
1112CONFIG_PPP_SYNC_TTY=m
1113CONFIG_PPP_DEFLATE=m
1114# CONFIG_PPP_BSDCOMP is not set
1115CONFIG_PPP_MPPE=m
1116CONFIG_PPPOE=m
1117CONFIG_PPPOL2TP=m
1118# CONFIG_SLIP is not set
1119CONFIG_SLHC=m
1120CONFIG_NET_FC=y
1121CONFIG_NETCONSOLE=m
1122CONFIG_NETCONSOLE_DYNAMIC=y
1123CONFIG_NETPOLL=y
1124CONFIG_NETPOLL_TRAP=y
1125CONFIG_NET_POLL_CONTROLLER=y
1126# CONFIG_ISDN is not set
1127# CONFIG_PHONE is not set
1128
1129#
1130# Input device support
1131#
1132CONFIG_INPUT=y
1133CONFIG_INPUT_FF_MEMLESS=y
1134CONFIG_INPUT_POLLDEV=m
1135
1136#
1137# Userland interfaces
1138#
1139CONFIG_INPUT_MOUSEDEV=y
1140# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
1141CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
1142CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
1143CONFIG_INPUT_JOYDEV=m
1144CONFIG_INPUT_EVDEV=y
1145# CONFIG_INPUT_EVBUG is not set
1146
1147#
1148# Input Device Drivers
1149#
1150CONFIG_INPUT_KEYBOARD=y
1151CONFIG_KEYBOARD_ATKBD=y
1152# CONFIG_KEYBOARD_SUNKBD is not set
1153# CONFIG_KEYBOARD_LKKBD is not set
1154# CONFIG_KEYBOARD_XTKBD is not set
1155# CONFIG_KEYBOARD_NEWTON is not set
1156# CONFIG_KEYBOARD_STOWAWAY is not set
1157CONFIG_INPUT_MOUSE=y
1158CONFIG_MOUSE_PS2=y
1159CONFIG_MOUSE_PS2_ALPS=y
1160CONFIG_MOUSE_PS2_LOGIPS2PP=y
1161CONFIG_MOUSE_PS2_SYNAPTICS=y
1162CONFIG_MOUSE_PS2_LIFEBOOK=y
1163CONFIG_MOUSE_PS2_TRACKPOINT=y
1164# CONFIG_MOUSE_PS2_TOUCHKIT is not set
1165CONFIG_MOUSE_SERIAL=m
1166# CONFIG_MOUSE_APPLETOUCH is not set
1167# CONFIG_MOUSE_BCM5974 is not set
1168CONFIG_MOUSE_VSXXXAA=m
1169CONFIG_INPUT_JOYSTICK=y
1170# CONFIG_JOYSTICK_ANALOG is not set
1171# CONFIG_JOYSTICK_A3D is not set
1172# CONFIG_JOYSTICK_ADI is not set
1173# CONFIG_JOYSTICK_COBRA is not set
1174# CONFIG_JOYSTICK_GF2K is not set
1175# CONFIG_JOYSTICK_GRIP is not set
1176# CONFIG_JOYSTICK_GRIP_MP is not set
1177# CONFIG_JOYSTICK_GUILLEMOT is not set
1178# CONFIG_JOYSTICK_INTERACT is not set
1179# CONFIG_JOYSTICK_SIDEWINDER is not set
1180# CONFIG_JOYSTICK_TMDC is not set
1181# CONFIG_JOYSTICK_IFORCE is not set
1182# CONFIG_JOYSTICK_WARRIOR is not set
1183# CONFIG_JOYSTICK_MAGELLAN is not set
1184# CONFIG_JOYSTICK_SPACEORB is not set
1185# CONFIG_JOYSTICK_SPACEBALL is not set
1186# CONFIG_JOYSTICK_STINGER is not set
1187# CONFIG_JOYSTICK_TWIDJOY is not set
1188# CONFIG_JOYSTICK_ZHENHUA is not set
1189# CONFIG_JOYSTICK_JOYDUMP is not set
1190# CONFIG_JOYSTICK_XPAD is not set
1191# CONFIG_INPUT_TABLET is not set
1192CONFIG_INPUT_TOUCHSCREEN=y
1193CONFIG_TOUCHSCREEN_FUJITSU=m
1194CONFIG_TOUCHSCREEN_GUNZE=m
1195CONFIG_TOUCHSCREEN_ELO=m
1196CONFIG_TOUCHSCREEN_MTOUCH=m
1197CONFIG_TOUCHSCREEN_INEXIO=m
1198CONFIG_TOUCHSCREEN_MK712=m
1199CONFIG_TOUCHSCREEN_PENMOUNT=m
1200CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
1201CONFIG_TOUCHSCREEN_TOUCHWIN=m
1202CONFIG_TOUCHSCREEN_UCB1400=m
1203# CONFIG_TOUCHSCREEN_WM97XX is not set
1204CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
1205CONFIG_TOUCHSCREEN_USB_EGALAX=y
1206CONFIG_TOUCHSCREEN_USB_PANJIT=y
1207CONFIG_TOUCHSCREEN_USB_3M=y
1208CONFIG_TOUCHSCREEN_USB_ITM=y
1209CONFIG_TOUCHSCREEN_USB_ETURBO=y
1210CONFIG_TOUCHSCREEN_USB_GUNZE=y
1211CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
1212CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
1213CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
1214CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
1215CONFIG_TOUCHSCREEN_USB_GOTOP=y
1216CONFIG_TOUCHSCREEN_TOUCHIT213=m
1217CONFIG_INPUT_MISC=y
1218# CONFIG_INPUT_PCSPKR is not set
1219# CONFIG_INPUT_APANEL is not set
1220# CONFIG_INPUT_WISTRON_BTNS is not set
1221CONFIG_INPUT_ATLAS_BTNS=m
1222CONFIG_INPUT_ATI_REMOTE=m
1223CONFIG_INPUT_ATI_REMOTE2=m
1224CONFIG_INPUT_KEYSPAN_REMOTE=m
1225CONFIG_INPUT_POWERMATE=m
1226CONFIG_INPUT_YEALINK=m
1227CONFIG_INPUT_UINPUT=m
1228
1229#
1230# Hardware I/O ports
1231#
1232CONFIG_SERIO=y
1233CONFIG_SERIO_I8042=y
1234CONFIG_SERIO_SERPORT=y
1235# CONFIG_SERIO_CT82C710 is not set
1236# CONFIG_SERIO_PCIPS2 is not set
1237CONFIG_SERIO_LIBPS2=y
1238CONFIG_SERIO_RAW=m
1239# CONFIG_GAMEPORT is not set
1240
1241#
1242# Character devices
1243#
1244CONFIG_VT=y
1245CONFIG_CONSOLE_TRANSLATIONS=y
1246CONFIG_VT_CONSOLE=y
1247CONFIG_HW_CONSOLE=y
1248CONFIG_VT_HW_CONSOLE_BINDING=y
1249# CONFIG_DEVKMEM is not set
1250# CONFIG_SERIAL_NONSTANDARD is not set
1251# CONFIG_NOZOMI is not set
1252
1253#
1254# Serial drivers
1255#
1256# CONFIG_SERIAL_8250 is not set
1257CONFIG_FIX_EARLYCON_MEM=y
1258
1259#
1260# Non-8250 serial port support
1261#
1262# CONFIG_SERIAL_JSM is not set
1263CONFIG_UNIX98_PTYS=y
1264# CONFIG_LEGACY_PTYS is not set
1265# CONFIG_IPMI_HANDLER is not set
1266# CONFIG_HW_RANDOM is not set
1267# CONFIG_NVRAM is not set
1268# CONFIG_R3964 is not set
1269# CONFIG_APPLICOM is not set
1270# CONFIG_SONYPI is not set
1271# CONFIG_MWAVE is not set
1272# CONFIG_PC8736x_GPIO is not set
1273# CONFIG_NSC_GPIO is not set
1274# CONFIG_CS5535_GPIO is not set
1275# CONFIG_RAW_DRIVER is not set
1276CONFIG_HPET=y
1277# CONFIG_HPET_MMAP is not set
1278# CONFIG_HANGCHECK_TIMER is not set
1279# CONFIG_TCG_TPM is not set
1280# CONFIG_TELCLOCK is not set
1281CONFIG_DEVPORT=y
1282CONFIG_I2C=y
1283CONFIG_I2C_BOARDINFO=y
1284# CONFIG_I2C_CHARDEV is not set
1285CONFIG_I2C_HELPER_AUTO=y
1286CONFIG_I2C_ALGOBIT=y
1287
1288#
1289# I2C Hardware Bus support
1290#
1291
1292#
1293# PC SMBus host controller drivers
1294#
1295# CONFIG_I2C_ALI1535 is not set
1296# CONFIG_I2C_ALI1563 is not set
1297# CONFIG_I2C_ALI15X3 is not set
1298# CONFIG_I2C_AMD756 is not set
1299# CONFIG_I2C_AMD8111 is not set
1300# CONFIG_I2C_I801 is not set
1301# CONFIG_I2C_ISCH is not set
1302# CONFIG_I2C_PIIX4 is not set
1303# CONFIG_I2C_NFORCE2 is not set
1304# CONFIG_I2C_SIS5595 is not set
1305# CONFIG_I2C_SIS630 is not set
1306# CONFIG_I2C_SIS96X is not set
1307# CONFIG_I2C_VIA is not set
1308# CONFIG_I2C_VIAPRO is not set
1309
1310#
1311# I2C system bus drivers (mostly embedded / system-on-chip)
1312#
1313# CONFIG_I2C_OCORES is not set
1314# CONFIG_I2C_SIMTEC is not set
1315
1316#
1317# External I2C/SMBus adapter drivers
1318#
1319# CONFIG_I2C_PARPORT_LIGHT is not set
1320# CONFIG_I2C_TAOS_EVM is not set
1321# CONFIG_I2C_TINY_USB is not set
1322
1323#
1324# Graphics adapter I2C/DDC channel drivers
1325#
1326# CONFIG_I2C_VOODOO3 is not set
1327
1328#
1329# Other I2C/SMBus bus drivers
1330#
1331# CONFIG_I2C_PCA_PLATFORM is not set
1332# CONFIG_I2C_STUB is not set
1333# CONFIG_SCx200_ACB is not set
1334
1335#
1336# Miscellaneous I2C Chip support
1337#
1338# CONFIG_DS1682 is not set
1339# CONFIG_AT24 is not set
1340# CONFIG_SENSORS_EEPROM is not set
1341# CONFIG_SENSORS_PCF8574 is not set
1342# CONFIG_PCF8575 is not set
1343# CONFIG_SENSORS_PCA9539 is not set
1344# CONFIG_SENSORS_PCF8591 is not set
1345# CONFIG_SENSORS_MAX6875 is not set
1346# CONFIG_SENSORS_TSL2550 is not set
1347# CONFIG_I2C_DEBUG_CORE is not set
1348# CONFIG_I2C_DEBUG_ALGO is not set
1349# CONFIG_I2C_DEBUG_BUS is not set
1350# CONFIG_I2C_DEBUG_CHIP is not set
1351# CONFIG_SPI is not set
1352CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
1353# CONFIG_GPIOLIB is not set
1354# CONFIG_W1 is not set
1355CONFIG_POWER_SUPPLY=y
1356# CONFIG_POWER_SUPPLY_DEBUG is not set
1357# CONFIG_PDA_POWER is not set
1358# CONFIG_BATTERY_DS2760 is not set
1359CONFIG_HWMON=y
1360# CONFIG_HWMON_VID is not set
1361# CONFIG_SENSORS_ABITUGURU is not set
1362# CONFIG_SENSORS_ABITUGURU3 is not set
1363# CONFIG_SENSORS_AD7414 is not set
1364# CONFIG_SENSORS_AD7418 is not set
1365# CONFIG_SENSORS_ADM1021 is not set
1366# CONFIG_SENSORS_ADM1025 is not set
1367# CONFIG_SENSORS_ADM1026 is not set
1368# CONFIG_SENSORS_ADM1029 is not set
1369# CONFIG_SENSORS_ADM1031 is not set
1370# CONFIG_SENSORS_ADM9240 is not set
1371# CONFIG_SENSORS_ADT7470 is not set
1372# CONFIG_SENSORS_ADT7473 is not set
1373# CONFIG_SENSORS_K8TEMP is not set
1374# CONFIG_SENSORS_ASB100 is not set
1375# CONFIG_SENSORS_ATXP1 is not set
1376# CONFIG_SENSORS_DS1621 is not set
1377# CONFIG_SENSORS_I5K_AMB is not set
1378# CONFIG_SENSORS_F71805F is not set
1379# CONFIG_SENSORS_F71882FG is not set
1380# CONFIG_SENSORS_F75375S is not set
1381# CONFIG_SENSORS_FSCHER is not set
1382# CONFIG_SENSORS_FSCPOS is not set
1383# CONFIG_SENSORS_FSCHMD is not set
1384# CONFIG_SENSORS_GL518SM is not set
1385# CONFIG_SENSORS_GL520SM is not set
1386# CONFIG_SENSORS_CORETEMP is not set
1387# CONFIG_SENSORS_IT87 is not set
1388# CONFIG_SENSORS_LM63 is not set
1389# CONFIG_SENSORS_LM75 is not set
1390# CONFIG_SENSORS_LM77 is not set
1391# CONFIG_SENSORS_LM78 is not set
1392# CONFIG_SENSORS_LM80 is not set
1393# CONFIG_SENSORS_LM83 is not set
1394# CONFIG_SENSORS_LM85 is not set
1395# CONFIG_SENSORS_LM87 is not set
1396# CONFIG_SENSORS_LM90 is not set
1397# CONFIG_SENSORS_LM92 is not set
1398# CONFIG_SENSORS_LM93 is not set
1399# CONFIG_SENSORS_MAX1619 is not set
1400# CONFIG_SENSORS_MAX6650 is not set
1401# CONFIG_SENSORS_PC87360 is not set
1402# CONFIG_SENSORS_PC87427 is not set
1403# CONFIG_SENSORS_SIS5595 is not set
1404# CONFIG_SENSORS_DME1737 is not set
1405# CONFIG_SENSORS_SMSC47M1 is not set
1406# CONFIG_SENSORS_SMSC47M192 is not set
1407# CONFIG_SENSORS_SMSC47B397 is not set
1408# CONFIG_SENSORS_ADS7828 is not set
1409# CONFIG_SENSORS_THMC50 is not set
1410# CONFIG_SENSORS_VIA686A is not set
1411# CONFIG_SENSORS_VT1211 is not set
1412# CONFIG_SENSORS_VT8231 is not set
1413# CONFIG_SENSORS_W83781D is not set
1414# CONFIG_SENSORS_W83791D is not set
1415# CONFIG_SENSORS_W83792D is not set
1416# CONFIG_SENSORS_W83793 is not set
1417# CONFIG_SENSORS_W83L785TS is not set
1418# CONFIG_SENSORS_W83L786NG is not set
1419# CONFIG_SENSORS_W83627HF is not set
1420# CONFIG_SENSORS_W83627EHF is not set
1421# CONFIG_SENSORS_HDAPS is not set
1422# CONFIG_SENSORS_APPLESMC is not set
1423# CONFIG_HWMON_DEBUG_CHIP is not set
1424CONFIG_THERMAL=y
1425# CONFIG_THERMAL_HWMON is not set
1426# CONFIG_WATCHDOG is not set
1427
1428#
1429# Sonics Silicon Backplane
1430#
1431CONFIG_SSB_POSSIBLE=y
1432# CONFIG_SSB is not set
1433
1434#
1435# Multifunction device drivers
1436#
1437# CONFIG_MFD_CORE is not set
1438# CONFIG_MFD_SM501 is not set
1439# CONFIG_HTC_PASIC3 is not set
1440# CONFIG_MFD_TMIO is not set
1441
1442#
1443# Multimedia devices
1444#
1445
1446#
1447# Multimedia core support
1448#
1449CONFIG_VIDEO_DEV=y
1450CONFIG_VIDEO_V4L2_COMMON=y
1451# CONFIG_VIDEO_ALLOW_V4L1 is not set
1452CONFIG_VIDEO_V4L1_COMPAT=y
1453CONFIG_DVB_CORE=y
1454CONFIG_VIDEO_MEDIA=y
1455
1456#
1457# Multimedia drivers
1458#
1459# CONFIG_MEDIA_ATTACH is not set
1460CONFIG_MEDIA_TUNER=y
1461# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
1462CONFIG_MEDIA_TUNER_SIMPLE=y
1463CONFIG_MEDIA_TUNER_TDA8290=y
1464CONFIG_MEDIA_TUNER_TDA9887=y
1465CONFIG_MEDIA_TUNER_TEA5761=y
1466CONFIG_MEDIA_TUNER_TEA5767=y
1467CONFIG_MEDIA_TUNER_MT20XX=y
1468CONFIG_MEDIA_TUNER_XC2028=y
1469CONFIG_MEDIA_TUNER_XC5000=y
1470CONFIG_VIDEO_V4L2=y
1471CONFIG_VIDEO_CAPTURE_DRIVERS=y
1472# CONFIG_VIDEO_ADV_DEBUG is not set
1473CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
1474# CONFIG_VIDEO_VIVI is not set
1475# CONFIG_VIDEO_BT848 is not set
1476# CONFIG_VIDEO_SAA5246A is not set
1477# CONFIG_VIDEO_SAA5249 is not set
1478# CONFIG_VIDEO_SAA7134 is not set
1479# CONFIG_VIDEO_HEXIUM_ORION is not set
1480# CONFIG_VIDEO_HEXIUM_GEMINI is not set
1481# CONFIG_VIDEO_CX88 is not set
1482# CONFIG_VIDEO_CX23885 is not set
1483# CONFIG_VIDEO_AU0828 is not set
1484# CONFIG_VIDEO_CX18 is not set
1485# CONFIG_VIDEO_CAFE_CCIC is not set
1486CONFIG_V4L_USB_DRIVERS=y
1487CONFIG_USB_VIDEO_CLASS=m
1488CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
1489# CONFIG_USB_GSPCA is not set
1490# CONFIG_VIDEO_PVRUSB2 is not set
1491# CONFIG_VIDEO_EM28XX is not set
1492# CONFIG_VIDEO_USBVISION is not set
1493# CONFIG_USB_ET61X251 is not set
1494# CONFIG_USB_SN9C102 is not set
1495# CONFIG_USB_ZC0301 is not set
1496# CONFIG_USB_ZR364XX is not set
1497# CONFIG_USB_STKWEBCAM is not set
1498# CONFIG_USB_S2255 is not set
1499# CONFIG_SOC_CAMERA is not set
1500# CONFIG_VIDEO_SH_MOBILE_CEU is not set
1501# CONFIG_RADIO_ADAPTERS is not set
1502# CONFIG_DVB_CAPTURE_DRIVERS is not set
1503# CONFIG_DAB is not set
1504
1505#
1506# Graphics support
1507#
1508CONFIG_AGP=y
1509# CONFIG_AGP_ALI is not set
1510# CONFIG_AGP_ATI is not set
1511# CONFIG_AGP_AMD is not set
1512CONFIG_AGP_AMD64=y
1513CONFIG_AGP_INTEL=y
1514# CONFIG_AGP_NVIDIA is not set
1515# CONFIG_AGP_SIS is not set
1516# CONFIG_AGP_SWORKS is not set
1517# CONFIG_AGP_VIA is not set
1518# CONFIG_AGP_EFFICEON is not set
1519CONFIG_DRM=y
1520# CONFIG_DRM_TDFX is not set
1521# CONFIG_DRM_R128 is not set
1522# CONFIG_DRM_RADEON is not set
1523CONFIG_DRM_I810=y
1524# CONFIG_DRM_I830 is not set
1525CONFIG_DRM_I915=y
1526# CONFIG_DRM_MGA is not set
1527# CONFIG_DRM_SIS is not set
1528# CONFIG_DRM_VIA is not set
1529# CONFIG_DRM_SAVAGE is not set
1530# CONFIG_VGASTATE is not set
1531CONFIG_VIDEO_OUTPUT_CONTROL=y
1532CONFIG_FB=y
1533CONFIG_FIRMWARE_EDID=y
1534CONFIG_FB_DDC=y
1535CONFIG_FB_CFB_FILLRECT=y
1536CONFIG_FB_CFB_COPYAREA=y
1537CONFIG_FB_CFB_IMAGEBLIT=y
1538# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
1539# CONFIG_FB_SYS_FILLRECT is not set
1540# CONFIG_FB_SYS_COPYAREA is not set
1541# CONFIG_FB_SYS_IMAGEBLIT is not set
1542# CONFIG_FB_FOREIGN_ENDIAN is not set
1543# CONFIG_FB_SYS_FOPS is not set
1544# CONFIG_FB_SVGALIB is not set
1545# CONFIG_FB_MACMODES is not set
1546# CONFIG_FB_BACKLIGHT is not set
1547CONFIG_FB_MODE_HELPERS=y
1548# CONFIG_FB_TILEBLITTING is not set
1549
1550#
1551# Frame buffer hardware drivers
1552#
1553# CONFIG_FB_CIRRUS is not set
1554# CONFIG_FB_PM2 is not set
1555# CONFIG_FB_CYBER2000 is not set
1556# CONFIG_FB_ARC is not set
1557# CONFIG_FB_ASILIANT is not set
1558# CONFIG_FB_IMSTT is not set
1559# CONFIG_FB_VGA16 is not set
1560# CONFIG_FB_UVESA is not set
1561# CONFIG_FB_VESA is not set
1562# CONFIG_FB_EFI is not set
1563# CONFIG_FB_N411 is not set
1564# CONFIG_FB_HGA is not set
1565# CONFIG_FB_S1D13XXX is not set
1566# CONFIG_FB_NVIDIA is not set
1567# CONFIG_FB_RIVA is not set
1568# CONFIG_FB_I810 is not set
1569# CONFIG_FB_LE80578 is not set
1570CONFIG_FB_INTEL=y
1571CONFIG_FB_INTEL_DEBUG=y
1572CONFIG_FB_INTEL_I2C=y
1573# CONFIG_FB_MATROX is not set
1574# CONFIG_FB_RADEON is not set
1575# CONFIG_FB_ATY128 is not set
1576# CONFIG_FB_ATY is not set
1577# CONFIG_FB_S3 is not set
1578# CONFIG_FB_SAVAGE is not set
1579# CONFIG_FB_SIS is not set
1580# CONFIG_FB_NEOMAGIC is not set
1581# CONFIG_FB_KYRO is not set
1582# CONFIG_FB_3DFX is not set
1583# CONFIG_FB_VOODOO1 is not set
1584# CONFIG_FB_VT8623 is not set
1585# CONFIG_FB_CYBLA is not set
1586# CONFIG_FB_TRIDENT is not set
1587# CONFIG_FB_ARK is not set
1588# CONFIG_FB_PM3 is not set
1589# CONFIG_FB_CARMINE is not set
1590# CONFIG_FB_GEODE is not set
1591# CONFIG_FB_VIRTUAL is not set
1592CONFIG_BACKLIGHT_LCD_SUPPORT=y
1593CONFIG_LCD_CLASS_DEVICE=y
1594# CONFIG_LCD_ILI9320 is not set
1595CONFIG_LCD_PLATFORM=y
1596CONFIG_BACKLIGHT_CLASS_DEVICE=y
1597# CONFIG_BACKLIGHT_CORGI is not set
1598# CONFIG_BACKLIGHT_PROGEAR is not set
1599CONFIG_BACKLIGHT_MBP_NVIDIA=y
1600
1601#
1602# Display device support
1603#
1604CONFIG_DISPLAY_SUPPORT=y
1605
1606#
1607# Display hardware drivers
1608#
1609
1610#
1611# Console display driver support
1612#
1613CONFIG_VGA_CONSOLE=y
1614CONFIG_VGACON_SOFT_SCROLLBACK=y
1615CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
1616CONFIG_VIDEO_SELECT=y
1617CONFIG_DUMMY_CONSOLE=y
1618CONFIG_FRAMEBUFFER_CONSOLE=y
1619# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1620# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1621# CONFIG_FONTS is not set
1622CONFIG_FONT_8x8=y
1623CONFIG_FONT_8x16=y
1624# CONFIG_LOGO is not set
1625CONFIG_SOUND=y
1626CONFIG_SND=y
1627CONFIG_SND_TIMER=y
1628CONFIG_SND_PCM=y
1629CONFIG_SND_HWDEP=y
1630CONFIG_SND_RAWMIDI=m
1631CONFIG_SND_SEQUENCER=y
1632CONFIG_SND_SEQ_DUMMY=y
1633# CONFIG_SND_MIXER_OSS is not set
1634# CONFIG_SND_PCM_OSS is not set
1635# CONFIG_SND_SEQUENCER_OSS is not set
1636CONFIG_SND_DYNAMIC_MINORS=y
1637# CONFIG_SND_SUPPORT_OLD_API is not set
1638CONFIG_SND_VERBOSE_PROCFS=y
1639CONFIG_SND_VERBOSE_PRINTK=y
1640CONFIG_SND_DEBUG=y
1641# CONFIG_SND_DEBUG_VERBOSE is not set
1642CONFIG_SND_PCM_XRUN_DEBUG=y
1643CONFIG_SND_VMASTER=y
1644CONFIG_SND_AC97_CODEC=y
1645CONFIG_SND_DRIVERS=y
1646# CONFIG_SND_PCSP is not set
1647# CONFIG_SND_DUMMY is not set
1648# CONFIG_SND_VIRMIDI is not set
1649# CONFIG_SND_MTPAV is not set
1650# CONFIG_SND_SERIAL_U16550 is not set
1651# CONFIG_SND_MPU401 is not set
1652CONFIG_SND_AC97_POWER_SAVE=y
1653CONFIG_SND_AC97_POWER_SAVE_DEFAULT=5
1654CONFIG_SND_PCI=y
1655# CONFIG_SND_AD1889 is not set
1656# CONFIG_SND_ALS300 is not set
1657# CONFIG_SND_ALS4000 is not set
1658# CONFIG_SND_ALI5451 is not set
1659# CONFIG_SND_ATIIXP is not set
1660# CONFIG_SND_ATIIXP_MODEM is not set
1661# CONFIG_SND_AU8810 is not set
1662# CONFIG_SND_AU8820 is not set
1663# CONFIG_SND_AU8830 is not set
1664# CONFIG_SND_AW2 is not set
1665# CONFIG_SND_AZT3328 is not set
1666# CONFIG_SND_BT87X is not set
1667# CONFIG_SND_CA0106 is not set
1668# CONFIG_SND_CMIPCI is not set
1669# CONFIG_SND_OXYGEN is not set
1670# CONFIG_SND_CS4281 is not set
1671# CONFIG_SND_CS46XX is not set
1672# CONFIG_SND_CS5530 is not set
1673# CONFIG_SND_CS5535AUDIO is not set
1674# CONFIG_SND_DARLA20 is not set
1675# CONFIG_SND_GINA20 is not set
1676# CONFIG_SND_LAYLA20 is not set
1677# CONFIG_SND_DARLA24 is not set
1678# CONFIG_SND_GINA24 is not set
1679# CONFIG_SND_LAYLA24 is not set
1680# CONFIG_SND_MONA is not set
1681# CONFIG_SND_MIA is not set
1682# CONFIG_SND_ECHO3G is not set
1683# CONFIG_SND_INDIGO is not set
1684# CONFIG_SND_INDIGOIO is not set
1685# CONFIG_SND_INDIGODJ is not set
1686# CONFIG_SND_EMU10K1 is not set
1687# CONFIG_SND_EMU10K1X is not set
1688# CONFIG_SND_ENS1370 is not set
1689# CONFIG_SND_ENS1371 is not set
1690# CONFIG_SND_ES1938 is not set
1691# CONFIG_SND_ES1968 is not set
1692# CONFIG_SND_FM801 is not set
1693CONFIG_SND_HDA_INTEL=y
1694CONFIG_SND_HDA_HWDEP=y
1695CONFIG_SND_HDA_CODEC_REALTEK=y
1696CONFIG_SND_HDA_CODEC_ANALOG=y
1697CONFIG_SND_HDA_CODEC_SIGMATEL=y
1698CONFIG_SND_HDA_CODEC_VIA=y
1699CONFIG_SND_HDA_CODEC_ATIHDMI=y
1700CONFIG_SND_HDA_CODEC_CONEXANT=y
1701CONFIG_SND_HDA_CODEC_CMEDIA=y
1702CONFIG_SND_HDA_CODEC_SI3054=y
1703CONFIG_SND_HDA_GENERIC=y
1704CONFIG_SND_HDA_POWER_SAVE=y
1705CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
1706# CONFIG_SND_HDSP is not set
1707# CONFIG_SND_HDSPM is not set
1708# CONFIG_SND_HIFIER is not set
1709# CONFIG_SND_ICE1712 is not set
1710# CONFIG_SND_ICE1724 is not set
1711CONFIG_SND_INTEL8X0=y
1712# CONFIG_SND_INTEL8X0M is not set
1713# CONFIG_SND_KORG1212 is not set
1714# CONFIG_SND_MAESTRO3 is not set
1715# CONFIG_SND_MIXART is not set
1716# CONFIG_SND_NM256 is not set
1717# CONFIG_SND_PCXHR is not set
1718# CONFIG_SND_RIPTIDE is not set
1719# CONFIG_SND_RME32 is not set
1720# CONFIG_SND_RME96 is not set
1721# CONFIG_SND_RME9652 is not set
1722# CONFIG_SND_SIS7019 is not set
1723# CONFIG_SND_SONICVIBES is not set
1724# CONFIG_SND_TRIDENT is not set
1725# CONFIG_SND_VIA82XX is not set
1726# CONFIG_SND_VIA82XX_MODEM is not set
1727# CONFIG_SND_VIRTUOSO is not set
1728# CONFIG_SND_VX222 is not set
1729# CONFIG_SND_YMFPCI is not set
1730CONFIG_SND_USB=y
1731CONFIG_SND_USB_AUDIO=m
1732CONFIG_SND_USB_USX2Y=m
1733CONFIG_SND_USB_CAIAQ=m
1734CONFIG_SND_USB_CAIAQ_INPUT=y
1735# CONFIG_SND_SOC is not set
1736# CONFIG_SOUND_PRIME is not set
1737CONFIG_AC97_BUS=y
1738CONFIG_HID_SUPPORT=y
1739CONFIG_HID=y
1740CONFIG_HID_DEBUG=y
1741CONFIG_HIDRAW=y
1742
1743#
1744# USB Input Devices
1745#
1746CONFIG_USB_HID=y
1747CONFIG_USB_HIDINPUT_POWERBOOK=y
1748CONFIG_HID_FF=y
1749CONFIG_HID_PID=y
1750CONFIG_LOGITECH_FF=y
1751# CONFIG_LOGIRUMBLEPAD2_FF is not set
1752CONFIG_PANTHERLORD_FF=y
1753CONFIG_THRUSTMASTER_FF=y
1754CONFIG_ZEROPLUS_FF=y
1755CONFIG_USB_HIDDEV=y
1756CONFIG_USB_SUPPORT=y
1757CONFIG_USB_ARCH_HAS_HCD=y
1758CONFIG_USB_ARCH_HAS_OHCI=y
1759CONFIG_USB_ARCH_HAS_EHCI=y
1760CONFIG_USB=y
1761# CONFIG_USB_DEBUG is not set
1762CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
1763
1764#
1765# Miscellaneous USB options
1766#
1767CONFIG_USB_DEVICEFS=y
1768# CONFIG_USB_DEVICE_CLASS is not set
1769# CONFIG_USB_DYNAMIC_MINORS is not set
1770CONFIG_USB_SUSPEND=y
1771# CONFIG_USB_OTG is not set
1772CONFIG_USB_MON=y
1773
1774#
1775# USB Host Controller Drivers
1776#
1777# CONFIG_USB_C67X00_HCD is not set
1778CONFIG_USB_EHCI_HCD=y
1779CONFIG_USB_EHCI_ROOT_HUB_TT=y
1780CONFIG_USB_EHCI_TT_NEWSCHED=y
1781# CONFIG_USB_ISP116X_HCD is not set
1782# CONFIG_USB_ISP1760_HCD is not set
1783CONFIG_USB_OHCI_HCD=m
1784# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
1785# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
1786CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1787CONFIG_USB_UHCI_HCD=m
1788CONFIG_USB_U132_HCD=m
1789CONFIG_USB_SL811_HCD=m
1790# CONFIG_USB_R8A66597_HCD is not set
1791
1792#
1793# USB Device Class drivers
1794#
1795CONFIG_USB_ACM=m
1796CONFIG_USB_PRINTER=m
1797# CONFIG_USB_WDM is not set
1798
1799#
1800# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1801#
1802
1803#
1804# may also be needed; see USB_STORAGE Help for more information
1805#
1806CONFIG_USB_STORAGE=y
1807# CONFIG_USB_STORAGE_DEBUG is not set
1808CONFIG_USB_STORAGE_DATAFAB=y
1809CONFIG_USB_STORAGE_FREECOM=y
1810CONFIG_USB_STORAGE_ISD200=y
1811CONFIG_USB_STORAGE_DPCM=y
1812CONFIG_USB_STORAGE_USBAT=y
1813CONFIG_USB_STORAGE_SDDR09=y
1814CONFIG_USB_STORAGE_SDDR55=y
1815CONFIG_USB_STORAGE_JUMPSHOT=y
1816CONFIG_USB_STORAGE_ALAUDA=y
1817# CONFIG_USB_STORAGE_ONETOUCH is not set
1818CONFIG_USB_STORAGE_KARMA=y
1819# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
1820# CONFIG_USB_LIBUSUAL is not set
1821
1822#
1823# USB Imaging devices
1824#
1825CONFIG_USB_MDC800=m
1826CONFIG_USB_MICROTEK=m
1827
1828#
1829# USB port drivers
1830#
1831CONFIG_USB_SERIAL=m
1832CONFIG_USB_EZUSB=y
1833CONFIG_USB_SERIAL_GENERIC=y
1834CONFIG_USB_SERIAL_AIRCABLE=m
1835CONFIG_USB_SERIAL_ARK3116=m
1836CONFIG_USB_SERIAL_BELKIN=m
1837CONFIG_USB_SERIAL_CH341=m
1838CONFIG_USB_SERIAL_WHITEHEAT=m
1839CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1840CONFIG_USB_SERIAL_CP2101=m
1841CONFIG_USB_SERIAL_CYPRESS_M8=m
1842CONFIG_USB_SERIAL_EMPEG=m
1843CONFIG_USB_SERIAL_FTDI_SIO=m
1844CONFIG_USB_SERIAL_FUNSOFT=m
1845CONFIG_USB_SERIAL_VISOR=m
1846CONFIG_USB_SERIAL_IPAQ=m
1847CONFIG_USB_SERIAL_IR=m
1848CONFIG_USB_SERIAL_EDGEPORT=m
1849CONFIG_USB_SERIAL_EDGEPORT_TI=m
1850CONFIG_USB_SERIAL_GARMIN=m
1851CONFIG_USB_SERIAL_IPW=m
1852CONFIG_USB_SERIAL_IUU=m
1853CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1854CONFIG_USB_SERIAL_KEYSPAN=m
1855CONFIG_USB_SERIAL_KEYSPAN_MPR=y
1856CONFIG_USB_SERIAL_KEYSPAN_USA28=y
1857CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
1858CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
1859CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
1860CONFIG_USB_SERIAL_KEYSPAN_USA19=y
1861CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
1862CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
1863CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
1864CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
1865CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
1866CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
1867CONFIG_USB_SERIAL_KLSI=m
1868CONFIG_USB_SERIAL_KOBIL_SCT=m
1869CONFIG_USB_SERIAL_MCT_U232=m
1870CONFIG_USB_SERIAL_MOS7720=m
1871CONFIG_USB_SERIAL_MOS7840=m
1872# CONFIG_USB_SERIAL_MOTOROLA is not set
1873CONFIG_USB_SERIAL_NAVMAN=m
1874CONFIG_USB_SERIAL_PL2303=m
1875CONFIG_USB_SERIAL_OTI6858=m
1876# CONFIG_USB_SERIAL_SPCP8X5 is not set
1877CONFIG_USB_SERIAL_HP4X=m
1878CONFIG_USB_SERIAL_SAFE=m
1879CONFIG_USB_SERIAL_SAFE_PADDED=y
1880CONFIG_USB_SERIAL_SIERRAWIRELESS=m
1881CONFIG_USB_SERIAL_TI=m
1882CONFIG_USB_SERIAL_CYBERJACK=m
1883CONFIG_USB_SERIAL_XIRCOM=m
1884CONFIG_USB_SERIAL_OPTION=m
1885CONFIG_USB_SERIAL_OMNINET=m
1886CONFIG_USB_SERIAL_DEBUG=m
1887
1888#
1889# USB Miscellaneous drivers
1890#
1891CONFIG_USB_EMI62=m
1892CONFIG_USB_EMI26=m
1893CONFIG_USB_ADUTUX=m
1894# CONFIG_USB_RIO500 is not set
1895CONFIG_USB_LEGOTOWER=m
1896CONFIG_USB_LCD=m
1897CONFIG_USB_BERRY_CHARGE=m
1898CONFIG_USB_LED=m
1899# CONFIG_USB_CYPRESS_CY7C63 is not set
1900# CONFIG_USB_CYTHERM is not set
1901CONFIG_USB_PHIDGET=m
1902CONFIG_USB_PHIDGETKIT=m
1903CONFIG_USB_PHIDGETMOTORCONTROL=m
1904CONFIG_USB_PHIDGETSERVO=m
1905CONFIG_USB_IDMOUSE=m
1906CONFIG_USB_FTDI_ELAN=m
1907CONFIG_USB_APPLEDISPLAY=m
1908CONFIG_USB_SISUSBVGA=m
1909CONFIG_USB_SISUSBVGA_CON=y
1910CONFIG_USB_LD=m
1911CONFIG_USB_TRANCEVIBRATOR=m
1912CONFIG_USB_IOWARRIOR=m
1913# CONFIG_USB_TEST is not set
1914# CONFIG_USB_ISIGHTFW is not set
1915# CONFIG_USB_GADGET is not set
1916CONFIG_MMC=m
1917# CONFIG_MMC_DEBUG is not set
1918# CONFIG_MMC_UNSAFE_RESUME is not set
1919
1920#
1921# MMC/SD Card Drivers
1922#
1923CONFIG_MMC_BLOCK=m
1924CONFIG_MMC_BLOCK_BOUNCE=y
1925CONFIG_SDIO_UART=m
1926# CONFIG_MMC_TEST is not set
1927
1928#
1929# MMC/SD Host Controller Drivers
1930#
1931CONFIG_MMC_SDHCI=m
1932# CONFIG_MMC_SDHCI_PCI is not set
1933CONFIG_MMC_WBSD=m
1934CONFIG_MMC_TIFM_SD=m
1935CONFIG_MEMSTICK=m
1936CONFIG_MEMSTICK_DEBUG=y
1937
1938#
1939# MemoryStick drivers
1940#
1941# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
1942CONFIG_MSPRO_BLOCK=m
1943
1944#
1945# MemoryStick Host Controller Drivers
1946#
1947# CONFIG_MEMSTICK_TIFM_MS is not set
1948# CONFIG_MEMSTICK_JMICRON_38X is not set
1949CONFIG_NEW_LEDS=y
1950CONFIG_LEDS_CLASS=m
1951
1952#
1953# LED drivers
1954#
1955# CONFIG_LEDS_PCA9532 is not set
1956# CONFIG_LEDS_CLEVO_MAIL is not set
1957# CONFIG_LEDS_PCA955X is not set
1958
1959#
1960# LED Triggers
1961#
1962CONFIG_LEDS_TRIGGERS=y
1963# CONFIG_LEDS_TRIGGER_TIMER is not set
1964# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
1965# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
1966# CONFIG_ACCESSIBILITY is not set
1967# CONFIG_INFINIBAND is not set
1968# CONFIG_EDAC is not set
1969CONFIG_RTC_LIB=y
1970CONFIG_RTC_CLASS=y
1971# CONFIG_RTC_HCTOSYS is not set
1972# CONFIG_RTC_DEBUG is not set
1973
1974#
1975# RTC interfaces
1976#
1977CONFIG_RTC_INTF_SYSFS=y
1978CONFIG_RTC_INTF_PROC=y
1979CONFIG_RTC_INTF_DEV=y
1980# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1981# CONFIG_RTC_DRV_TEST is not set
1982
1983#
1984# I2C RTC drivers
1985#
1986# CONFIG_RTC_DRV_DS1307 is not set
1987# CONFIG_RTC_DRV_DS1374 is not set
1988# CONFIG_RTC_DRV_DS1672 is not set
1989# CONFIG_RTC_DRV_MAX6900 is not set
1990# CONFIG_RTC_DRV_RS5C372 is not set
1991# CONFIG_RTC_DRV_ISL1208 is not set
1992# CONFIG_RTC_DRV_X1205 is not set
1993# CONFIG_RTC_DRV_PCF8563 is not set
1994# CONFIG_RTC_DRV_PCF8583 is not set
1995# CONFIG_RTC_DRV_M41T80 is not set
1996# CONFIG_RTC_DRV_S35390A is not set
1997# CONFIG_RTC_DRV_FM3130 is not set
1998
1999#
2000# SPI RTC drivers
2001#
2002
2003#
2004# Platform RTC drivers
2005#
2006CONFIG_RTC_DRV_CMOS=y
2007# CONFIG_RTC_DRV_DS1511 is not set
2008# CONFIG_RTC_DRV_DS1553 is not set
2009# CONFIG_RTC_DRV_DS1742 is not set
2010# CONFIG_RTC_DRV_STK17TA8 is not set
2011# CONFIG_RTC_DRV_M48T86 is not set
2012# CONFIG_RTC_DRV_M48T59 is not set
2013# CONFIG_RTC_DRV_V3020 is not set
2014
2015#
2016# on-CPU RTC drivers
2017#
2018# CONFIG_DMADEVICES is not set
2019# CONFIG_UIO is not set
2020
2021#
2022# Firmware Drivers
2023#
2024# CONFIG_EDD is not set
2025CONFIG_FIRMWARE_MEMMAP=y
2026# CONFIG_DELL_RBU is not set
2027# CONFIG_DCDBAS is not set
2028# CONFIG_DMIID is not set
2029# CONFIG_ISCSI_IBFT_FIND is not set
2030
2031#
2032# File systems
2033#
2034# CONFIG_EXT2_FS is not set
2035CONFIG_EXT3_FS=y
2036CONFIG_EXT3_FS_XATTR=y
2037CONFIG_EXT3_FS_POSIX_ACL=y
2038CONFIG_EXT3_FS_SECURITY=y
2039# CONFIG_EXT4DEV_FS is not set
2040CONFIG_JBD=y
2041# CONFIG_JBD_DEBUG is not set
2042CONFIG_FS_MBCACHE=y
2043# CONFIG_REISERFS_FS is not set
2044# CONFIG_JFS_FS is not set
2045CONFIG_FS_POSIX_ACL=y
2046# CONFIG_XFS_FS is not set
2047# CONFIG_OCFS2_FS is not set
2048CONFIG_DNOTIFY=y
2049CONFIG_INOTIFY=y
2050CONFIG_INOTIFY_USER=y
2051CONFIG_QUOTA=y
2052CONFIG_QUOTA_NETLINK_INTERFACE=y
2053# CONFIG_PRINT_QUOTA_WARNING is not set
2054# CONFIG_QFMT_V1 is not set
2055CONFIG_QFMT_V2=y
2056CONFIG_QUOTACTL=y
2057# CONFIG_AUTOFS_FS is not set
2058# CONFIG_AUTOFS4_FS is not set
2059CONFIG_FUSE_FS=m
2060CONFIG_GENERIC_ACL=y
2061
2062#
2063# CD-ROM/DVD Filesystems
2064#
2065CONFIG_ISO9660_FS=y
2066CONFIG_JOLIET=y
2067CONFIG_ZISOFS=y
2068CONFIG_UDF_FS=m
2069CONFIG_UDF_NLS=y
2070
2071#
2072# DOS/FAT/NT Filesystems
2073#
2074CONFIG_FAT_FS=y
2075CONFIG_MSDOS_FS=y
2076CONFIG_VFAT_FS=y
2077CONFIG_FAT_DEFAULT_CODEPAGE=437
2078CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
2079# CONFIG_NTFS_FS is not set
2080
2081#
2082# Pseudo filesystems
2083#
2084CONFIG_PROC_FS=y
2085CONFIG_PROC_KCORE=y
2086CONFIG_PROC_VMCORE=y
2087CONFIG_PROC_SYSCTL=y
2088CONFIG_SYSFS=y
2089CONFIG_TMPFS=y
2090CONFIG_TMPFS_POSIX_ACL=y
2091CONFIG_HUGETLBFS=y
2092CONFIG_HUGETLB_PAGE=y
2093CONFIG_CONFIGFS_FS=m
2094
2095#
2096# Miscellaneous filesystems
2097#
2098# CONFIG_ADFS_FS is not set
2099# CONFIG_AFFS_FS is not set
2100# CONFIG_ECRYPT_FS is not set
2101# CONFIG_HFS_FS is not set
2102# CONFIG_HFSPLUS_FS is not set
2103# CONFIG_BEFS_FS is not set
2104# CONFIG_BFS_FS is not set
2105# CONFIG_EFS_FS is not set
2106# CONFIG_CRAMFS is not set
2107# CONFIG_VXFS_FS is not set
2108# CONFIG_MINIX_FS is not set
2109# CONFIG_OMFS_FS is not set
2110# CONFIG_HPFS_FS is not set
2111# CONFIG_QNX4FS_FS is not set
2112# CONFIG_ROMFS_FS is not set
2113# CONFIG_SYSV_FS is not set
2114# CONFIG_UFS_FS is not set
2115CONFIG_NETWORK_FILESYSTEMS=y
2116# CONFIG_NFS_FS is not set
2117# CONFIG_NFSD is not set
2118# CONFIG_SMB_FS is not set
2119# CONFIG_CIFS is not set
2120# CONFIG_NCP_FS is not set
2121# CONFIG_CODA_FS is not set
2122# CONFIG_AFS_FS is not set
2123
2124#
2125# Partition Types
2126#
2127CONFIG_PARTITION_ADVANCED=y
2128# CONFIG_ACORN_PARTITION is not set
2129CONFIG_OSF_PARTITION=y
2130CONFIG_AMIGA_PARTITION=y
2131# CONFIG_ATARI_PARTITION is not set
2132CONFIG_MAC_PARTITION=y
2133CONFIG_MSDOS_PARTITION=y
2134CONFIG_BSD_DISKLABEL=y
2135CONFIG_MINIX_SUBPARTITION=y
2136CONFIG_SOLARIS_X86_PARTITION=y
2137CONFIG_UNIXWARE_DISKLABEL=y
2138# CONFIG_LDM_PARTITION is not set
2139CONFIG_SGI_PARTITION=y
2140# CONFIG_ULTRIX_PARTITION is not set
2141CONFIG_SUN_PARTITION=y
2142CONFIG_KARMA_PARTITION=y
2143CONFIG_EFI_PARTITION=y
2144# CONFIG_SYSV68_PARTITION is not set
2145CONFIG_NLS=y
2146CONFIG_NLS_DEFAULT="utf8"
2147CONFIG_NLS_CODEPAGE_437=y
2148CONFIG_NLS_CODEPAGE_737=m
2149CONFIG_NLS_CODEPAGE_775=m
2150CONFIG_NLS_CODEPAGE_850=m
2151CONFIG_NLS_CODEPAGE_852=m
2152CONFIG_NLS_CODEPAGE_855=m
2153CONFIG_NLS_CODEPAGE_857=m
2154CONFIG_NLS_CODEPAGE_860=m
2155CONFIG_NLS_CODEPAGE_861=m
2156CONFIG_NLS_CODEPAGE_862=m
2157CONFIG_NLS_CODEPAGE_863=m
2158CONFIG_NLS_CODEPAGE_864=m
2159CONFIG_NLS_CODEPAGE_865=m
2160CONFIG_NLS_CODEPAGE_866=m
2161CONFIG_NLS_CODEPAGE_869=m
2162CONFIG_NLS_CODEPAGE_936=m
2163CONFIG_NLS_CODEPAGE_950=m
2164CONFIG_NLS_CODEPAGE_932=m
2165CONFIG_NLS_CODEPAGE_949=m
2166CONFIG_NLS_CODEPAGE_874=m
2167CONFIG_NLS_ISO8859_8=m
2168CONFIG_NLS_CODEPAGE_1250=m
2169CONFIG_NLS_CODEPAGE_1251=m
2170CONFIG_NLS_ASCII=y
2171CONFIG_NLS_ISO8859_1=m
2172CONFIG_NLS_ISO8859_2=m
2173CONFIG_NLS_ISO8859_3=m
2174CONFIG_NLS_ISO8859_4=m
2175CONFIG_NLS_ISO8859_5=m
2176CONFIG_NLS_ISO8859_6=m
2177CONFIG_NLS_ISO8859_7=m
2178CONFIG_NLS_ISO8859_9=m
2179CONFIG_NLS_ISO8859_13=m
2180CONFIG_NLS_ISO8859_14=m
2181CONFIG_NLS_ISO8859_15=m
2182CONFIG_NLS_KOI8_R=m
2183CONFIG_NLS_KOI8_U=m
2184CONFIG_NLS_UTF8=m
2185# CONFIG_DLM is not set
2186
2187#
2188# Kernel hacking
2189#
2190CONFIG_TRACE_IRQFLAGS_SUPPORT=y
2191CONFIG_PRINTK_TIME=y
2192# CONFIG_ENABLE_WARN_DEPRECATED is not set
2193CONFIG_ENABLE_MUST_CHECK=y
2194CONFIG_FRAME_WARN=1024
2195CONFIG_MAGIC_SYSRQ=y
2196CONFIG_UNUSED_SYMBOLS=y
2197CONFIG_DEBUG_FS=y
2198# CONFIG_HEADERS_CHECK is not set
2199CONFIG_DEBUG_KERNEL=y
2200CONFIG_DEBUG_SHIRQ=y
2201CONFIG_DETECT_SOFTLOCKUP=y
2202# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
2203CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
2204CONFIG_SCHED_DEBUG=y
2205CONFIG_SCHEDSTATS=y
2206CONFIG_TIMER_STATS=y
2207# CONFIG_DEBUG_OBJECTS is not set
2208# CONFIG_DEBUG_SLAB is not set
2209# CONFIG_DEBUG_RT_MUTEXES is not set
2210# CONFIG_RT_MUTEX_TESTER is not set
2211# CONFIG_DEBUG_SPINLOCK is not set
2212# CONFIG_DEBUG_MUTEXES is not set
2213# CONFIG_DEBUG_LOCK_ALLOC is not set
2214# CONFIG_PROVE_LOCKING is not set
2215# CONFIG_LOCK_STAT is not set
2216CONFIG_DEBUG_SPINLOCK_SLEEP=y
2217# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
2218CONFIG_STACKTRACE=y
2219# CONFIG_DEBUG_KOBJECT is not set
2220# CONFIG_DEBUG_HIGHMEM is not set
2221CONFIG_DEBUG_BUGVERBOSE=y
2222# CONFIG_DEBUG_INFO is not set
2223# CONFIG_DEBUG_VM is not set
2224# CONFIG_DEBUG_WRITECOUNT is not set
2225CONFIG_DEBUG_MEMORY_INIT=y
2226CONFIG_DEBUG_LIST=y
2227# CONFIG_DEBUG_SG is not set
2228CONFIG_FRAME_POINTER=y
2229CONFIG_BOOT_PRINTK_DELAY=y
2230# CONFIG_RCU_TORTURE_TEST is not set
2231# CONFIG_BACKTRACE_SELF_TEST is not set
2232# CONFIG_FAULT_INJECTION is not set
2233CONFIG_LATENCYTOP=y
2234CONFIG_SYSCTL_SYSCALL_CHECK=y
2235CONFIG_HAVE_FTRACE=y
2236CONFIG_HAVE_DYNAMIC_FTRACE=y
2237CONFIG_TRACING=y
2238# CONFIG_FTRACE is not set
2239# CONFIG_IRQSOFF_TRACER is not set
2240CONFIG_SYSPROF_TRACER=y
2241# CONFIG_SCHED_TRACER is not set
2242# CONFIG_CONTEXT_SWITCH_TRACER is not set
2243# CONFIG_FTRACE_STARTUP_TEST is not set
2244# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
2245# CONFIG_SAMPLES is not set
2246CONFIG_HAVE_ARCH_KGDB=y
2247# CONFIG_KGDB is not set
2248# CONFIG_STRICT_DEVMEM is not set
2249CONFIG_X86_VERBOSE_BOOTUP=y
2250CONFIG_EARLY_PRINTK=y
2251# CONFIG_DEBUG_STACKOVERFLOW is not set
2252# CONFIG_DEBUG_STACK_USAGE is not set
2253# CONFIG_DEBUG_PAGEALLOC is not set
2254# CONFIG_DEBUG_PER_CPU_MAPS is not set
2255CONFIG_X86_PTDUMP=y
2256CONFIG_DEBUG_RODATA=y
2257# CONFIG_DEBUG_RODATA_TEST is not set
2258# CONFIG_DEBUG_NX_TEST is not set
2259# CONFIG_4KSTACKS is not set
2260CONFIG_DOUBLEFAULT=y
2261# CONFIG_MMIOTRACE is not set
2262CONFIG_IO_DELAY_TYPE_0X80=0
2263CONFIG_IO_DELAY_TYPE_0XED=1
2264CONFIG_IO_DELAY_TYPE_UDELAY=2
2265CONFIG_IO_DELAY_TYPE_NONE=3
2266CONFIG_IO_DELAY_0X80=y
2267# CONFIG_IO_DELAY_0XED is not set
2268# CONFIG_IO_DELAY_UDELAY is not set
2269# CONFIG_IO_DELAY_NONE is not set
2270CONFIG_DEFAULT_IO_DELAY_TYPE=0
2271CONFIG_DEBUG_BOOT_PARAMS=y
2272# CONFIG_CPA_DEBUG is not set
2273# CONFIG_OPTIMIZE_INLINING is not set
2274
2275#
2276# Security options
2277#
2278CONFIG_KEYS=y
2279CONFIG_KEYS_DEBUG_PROC_KEYS=y
2280CONFIG_SECURITY=y
2281CONFIG_SECURITY_NETWORK=y
2282CONFIG_SECURITY_NETWORK_XFRM=y
2283CONFIG_SECURITY_FILE_CAPABILITIES=y
2284# CONFIG_SECURITY_ROOTPLUG is not set
2285CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536
2286# CONFIG_SECURITY_SELINUX is not set
2287# CONFIG_SECURITY_SMACK is not set
2288CONFIG_CRYPTO=y
2289
2290#
2291# Crypto core or helper
2292#
2293CONFIG_CRYPTO_ALGAPI=y
2294CONFIG_CRYPTO_AEAD=m
2295CONFIG_CRYPTO_BLKCIPHER=m
2296CONFIG_CRYPTO_HASH=y
2297CONFIG_CRYPTO_MANAGER=y
2298CONFIG_CRYPTO_GF128MUL=m
2299CONFIG_CRYPTO_NULL=m
2300# CONFIG_CRYPTO_CRYPTD is not set
2301CONFIG_CRYPTO_AUTHENC=m
2302CONFIG_CRYPTO_TEST=m
2303
2304#
2305# Authenticated Encryption with Associated Data
2306#
2307CONFIG_CRYPTO_CCM=m
2308CONFIG_CRYPTO_GCM=m
2309CONFIG_CRYPTO_SEQIV=m
2310
2311#
2312# Block modes
2313#
2314CONFIG_CRYPTO_CBC=m
2315CONFIG_CRYPTO_CTR=m
2316# CONFIG_CRYPTO_CTS is not set
2317CONFIG_CRYPTO_ECB=m
2318CONFIG_CRYPTO_LRW=m
2319CONFIG_CRYPTO_PCBC=m
2320CONFIG_CRYPTO_XTS=m
2321
2322#
2323# Hash modes
2324#
2325CONFIG_CRYPTO_HMAC=y
2326CONFIG_CRYPTO_XCBC=m
2327
2328#
2329# Digest
2330#
2331CONFIG_CRYPTO_CRC32C=m
2332CONFIG_CRYPTO_MD4=m
2333CONFIG_CRYPTO_MD5=y
2334CONFIG_CRYPTO_MICHAEL_MIC=m
2335# CONFIG_CRYPTO_RMD128 is not set
2336# CONFIG_CRYPTO_RMD160 is not set
2337# CONFIG_CRYPTO_RMD256 is not set
2338# CONFIG_CRYPTO_RMD320 is not set
2339CONFIG_CRYPTO_SHA1=y
2340CONFIG_CRYPTO_SHA256=m
2341CONFIG_CRYPTO_SHA512=m
2342CONFIG_CRYPTO_TGR192=m
2343CONFIG_CRYPTO_WP512=m
2344
2345#
2346# Ciphers
2347#
2348CONFIG_CRYPTO_AES=m
2349# CONFIG_CRYPTO_AES_586 is not set
2350CONFIG_CRYPTO_ANUBIS=m
2351CONFIG_CRYPTO_ARC4=m
2352CONFIG_CRYPTO_BLOWFISH=m
2353CONFIG_CRYPTO_CAMELLIA=m
2354CONFIG_CRYPTO_CAST5=m
2355CONFIG_CRYPTO_CAST6=m
2356CONFIG_CRYPTO_DES=m
2357CONFIG_CRYPTO_FCRYPT=m
2358CONFIG_CRYPTO_KHAZAD=m
2359CONFIG_CRYPTO_SALSA20=m
2360# CONFIG_CRYPTO_SALSA20_586 is not set
2361CONFIG_CRYPTO_SEED=m
2362CONFIG_CRYPTO_SERPENT=m
2363CONFIG_CRYPTO_TEA=m
2364CONFIG_CRYPTO_TWOFISH=m
2365CONFIG_CRYPTO_TWOFISH_COMMON=m
2366# CONFIG_CRYPTO_TWOFISH_586 is not set
2367
2368#
2369# Compression
2370#
2371CONFIG_CRYPTO_DEFLATE=m
2372# CONFIG_CRYPTO_LZO is not set
2373CONFIG_CRYPTO_HW=y
2374# CONFIG_CRYPTO_DEV_PADLOCK is not set
2375# CONFIG_CRYPTO_DEV_GEODE is not set
2376# CONFIG_CRYPTO_DEV_HIFN_795X is not set
2377CONFIG_HAVE_KVM=y
2378# CONFIG_VIRTUALIZATION is not set
2379
2380#
2381# Library routines
2382#
2383CONFIG_BITREVERSE=y
2384CONFIG_GENERIC_FIND_FIRST_BIT=y
2385CONFIG_GENERIC_FIND_NEXT_BIT=y
2386CONFIG_CRC_CCITT=m
2387CONFIG_CRC16=m
2388CONFIG_CRC_T10DIF=y
2389CONFIG_CRC_ITU_T=m
2390CONFIG_CRC32=y
2391# CONFIG_CRC7 is not set
2392CONFIG_LIBCRC32C=m
2393CONFIG_AUDIT_GENERIC=y
2394CONFIG_ZLIB_INFLATE=y
2395CONFIG_ZLIB_DEFLATE=m
2396CONFIG_TEXTSEARCH=y
2397CONFIG_TEXTSEARCH_KMP=m
2398CONFIG_TEXTSEARCH_BM=m
2399CONFIG_TEXTSEARCH_FSM=m
2400CONFIG_PLIST=y
2401CONFIG_HAS_IOMEM=y
2402CONFIG_HAS_IOPORT=y
2403CONFIG_HAS_DMA=y
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/psb-driver.patch b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/psb-driver.patch
new file mode 100644
index 0000000000..c515bc60ce
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.28+2.6.29-rc2/psb-driver.patch
@@ -0,0 +1,24644 @@
1Index: linux-2.6.28/include/drm/drm.h
2===================================================================
3--- linux-2.6.28.orig/include/drm/drm.h 2009-02-12 09:14:40.000000000 +0000
4+++ linux-2.6.28/include/drm/drm.h 2009-02-12 09:14:41.000000000 +0000
5@@ -174,6 +174,7 @@
6 _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */
7 _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */
8 _DRM_GEM = 6, /**< GEM object */
9+ _DRM_TTM = 7,
10 };
11
12 /**
13@@ -601,6 +602,271 @@
14
15 #include "drm_mode.h"
16
17+#define DRM_FENCE_FLAG_EMIT 0x00000001
18+#define DRM_FENCE_FLAG_SHAREABLE 0x00000002
19+#define DRM_FENCE_FLAG_WAIT_LAZY 0x00000004
20+#define DRM_FENCE_FLAG_WAIT_IGNORE_SIGNALS 0x00000008
21+#define DRM_FENCE_FLAG_NO_USER 0x00000010
22+
23+/* Reserved for driver use */
24+#define DRM_FENCE_MASK_DRIVER 0xFF000000
25+
26+#define DRM_FENCE_TYPE_EXE 0x00000001
27+
28+struct drm_fence_arg {
29+ unsigned int handle;
30+ unsigned int fence_class;
31+ unsigned int type;
32+ unsigned int flags;
33+ unsigned int signaled;
34+ unsigned int error;
35+ unsigned int sequence;
36+ unsigned int pad64;
37+ uint64_t expand_pad[2]; /*Future expansion */
38+};
39+
40+/* Buffer permissions, referring to how the GPU uses the buffers.
41+ * these translate to fence types used for the buffers.
42+ * Typically a texture buffer is read, A destination buffer is write and
43+ * a command (batch-) buffer is exe. Can be or-ed together.
44+ */
45+
46+#define DRM_BO_FLAG_READ (1ULL << 0)
47+#define DRM_BO_FLAG_WRITE (1ULL << 1)
48+#define DRM_BO_FLAG_EXE (1ULL << 2)
49+
50+/*
51+ * Status flags. Can be read to determine the actual state of a buffer.
52+ * Can also be set in the buffer mask before validation.
53+ */
54+
55+/*
56+ * Mask: Never evict this buffer. Not even with force. This type of buffer is only
57+ * available to root and must be manually removed before buffer manager shutdown
58+ * or lock.
59+ * Flags: Acknowledge
60+ */
61+#define DRM_BO_FLAG_NO_EVICT (1ULL << 4)
62+
63+/*
64+ * Mask: Require that the buffer is placed in mappable memory when validated.
65+ * If not set the buffer may or may not be in mappable memory when validated.
66+ * Flags: If set, the buffer is in mappable memory.
67+ */
68+#define DRM_BO_FLAG_MAPPABLE (1ULL << 5)
69+
70+/* Mask: The buffer should be shareable with other processes.
71+ * Flags: The buffer is shareable with other processes.
72+ */
73+#define DRM_BO_FLAG_SHAREABLE (1ULL << 6)
74+
75+/* Mask: If set, place the buffer in cache-coherent memory if available.
76+ * If clear, never place the buffer in cache coherent memory if validated.
77+ * Flags: The buffer is currently in cache-coherent memory.
78+ */
79+#define DRM_BO_FLAG_CACHED (1ULL << 7)
80+
81+/* Mask: Make sure that every time this buffer is validated,
82+ * it ends up on the same location provided that the memory mask is the same.
83+ * The buffer will also not be evicted when claiming space for
84+ * other buffers. Basically a pinned buffer but it may be thrown out as
85+ * part of buffer manager shutdown or locking.
86+ * Flags: Acknowledge.
87+ */
88+#define DRM_BO_FLAG_NO_MOVE (1ULL << 8)
89+
90+/* Mask: Make sure the buffer is in cached memory when mapped
91+ * Flags: Acknowledge.
92+ * Buffers allocated with this flag should not be used for suballocators
93+ * This type may have issues on CPUs with over-aggressive caching
94+ * http://marc.info/?l=linux-kernel&m=102376926732464&w=2
95+ */
96+#define DRM_BO_FLAG_CACHED_MAPPED (1ULL << 19)
97+
98+
99+/* Mask: Force DRM_BO_FLAG_CACHED flag strictly also if it is set.
100+ * Flags: Acknowledge.
101+ */
102+#define DRM_BO_FLAG_FORCE_CACHING (1ULL << 13)
103+
104+/*
105+ * Mask: Force DRM_BO_FLAG_MAPPABLE flag strictly also if it is clear.
106+ * Flags: Acknowledge.
107+ */
108+#define DRM_BO_FLAG_FORCE_MAPPABLE (1ULL << 14)
109+#define DRM_BO_FLAG_TILE (1ULL << 15)
110+
111+/*
112+ * Memory type flags that can be or'ed together in the mask, but only
113+ * one appears in flags.
114+ */
115+
116+/* System memory */
117+#define DRM_BO_FLAG_MEM_LOCAL (1ULL << 24)
118+/* Translation table memory */
119+#define DRM_BO_FLAG_MEM_TT (1ULL << 25)
120+/* Vram memory */
121+#define DRM_BO_FLAG_MEM_VRAM (1ULL << 26)
122+/* Up to the driver to define. */
123+#define DRM_BO_FLAG_MEM_PRIV0 (1ULL << 27)
124+#define DRM_BO_FLAG_MEM_PRIV1 (1ULL << 28)
125+#define DRM_BO_FLAG_MEM_PRIV2 (1ULL << 29)
126+#define DRM_BO_FLAG_MEM_PRIV3 (1ULL << 30)
127+#define DRM_BO_FLAG_MEM_PRIV4 (1ULL << 31)
128+/* We can add more of these now with a 64-bit flag type */
129+
130+/* Memory flag mask */
131+#define DRM_BO_MASK_MEM 0x00000000FF000000ULL
132+#define DRM_BO_MASK_MEMTYPE 0x00000000FF0800A0ULL
133+
134+/* Driver-private flags */
135+#define DRM_BO_MASK_DRIVER 0xFFFF000000000000ULL
136+
137+/* Don't block on validate and map */
138+#define DRM_BO_HINT_DONT_BLOCK 0x00000002
139+/* Don't place this buffer on the unfenced list.*/
140+#define DRM_BO_HINT_DONT_FENCE 0x00000004
141+#define DRM_BO_HINT_WAIT_LAZY 0x00000008
142+#define DRM_BO_HINT_PRESUMED_OFFSET 0x00000010
143+
144+#define DRM_BO_INIT_MAGIC 0xfe769812
145+#define DRM_BO_INIT_MAJOR 1
146+#define DRM_BO_INIT_MINOR 0
147+#define DRM_BO_INIT_PATCH 0
148+
149+
150+struct drm_bo_info_req {
151+ uint64_t mask;
152+ uint64_t flags;
153+ unsigned int handle;
154+ unsigned int hint;
155+ unsigned int fence_class;
156+ unsigned int desired_tile_stride;
157+ unsigned int tile_info;
158+ unsigned int pad64;
159+ uint64_t presumed_offset;
160+};
161+
162+struct drm_bo_create_req {
163+ uint64_t mask;
164+ uint64_t size;
165+ uint64_t buffer_start;
166+ unsigned int hint;
167+ unsigned int page_alignment;
168+};
169+
170+
171+/*
172+ * Reply flags
173+ */
174+
175+#define DRM_BO_REP_BUSY 0x00000001
176+
177+struct drm_bo_info_rep {
178+ uint64_t flags;
179+ uint64_t mask;
180+ uint64_t size;
181+ uint64_t offset;
182+ uint64_t arg_handle;
183+ uint64_t buffer_start;
184+ unsigned int handle;
185+ unsigned int fence_flags;
186+ unsigned int rep_flags;
187+ unsigned int page_alignment;
188+ unsigned int desired_tile_stride;
189+ unsigned int hw_tile_stride;
190+ unsigned int tile_info;
191+ unsigned int pad64;
192+ uint64_t expand_pad[4]; /*Future expansion */
193+};
194+
195+struct drm_bo_arg_rep {
196+ struct drm_bo_info_rep bo_info;
197+ int ret;
198+ unsigned int pad64;
199+};
200+
201+struct drm_bo_create_arg {
202+ union {
203+ struct drm_bo_create_req req;
204+ struct drm_bo_info_rep rep;
205+ } d;
206+};
207+
208+struct drm_bo_handle_arg {
209+ unsigned int handle;
210+};
211+
212+struct drm_bo_reference_info_arg {
213+ union {
214+ struct drm_bo_handle_arg req;
215+ struct drm_bo_info_rep rep;
216+ } d;
217+};
218+
219+struct drm_bo_map_wait_idle_arg {
220+ union {
221+ struct drm_bo_info_req req;
222+ struct drm_bo_info_rep rep;
223+ } d;
224+};
225+
226+struct drm_bo_op_req {
227+ enum {
228+ drm_bo_validate,
229+ drm_bo_fence,
230+ drm_bo_ref_fence,
231+ } op;
232+ unsigned int arg_handle;
233+ struct drm_bo_info_req bo_req;
234+};
235+
236+
237+struct drm_bo_op_arg {
238+ uint64_t next;
239+ union {
240+ struct drm_bo_op_req req;
241+ struct drm_bo_arg_rep rep;
242+ } d;
243+ int handled;
244+ unsigned int pad64;
245+};
246+
247+
248+#define DRM_BO_MEM_LOCAL 0
249+#define DRM_BO_MEM_TT 1
250+#define DRM_BO_MEM_VRAM 2
251+#define DRM_BO_MEM_PRIV0 3
252+#define DRM_BO_MEM_PRIV1 4
253+#define DRM_BO_MEM_PRIV2 5
254+#define DRM_BO_MEM_PRIV3 6
255+#define DRM_BO_MEM_PRIV4 7
256+
257+#define DRM_BO_MEM_TYPES 8 /* For now. */
258+
259+#define DRM_BO_LOCK_UNLOCK_BM (1 << 0)
260+#define DRM_BO_LOCK_IGNORE_NO_EVICT (1 << 1)
261+
262+struct drm_bo_version_arg {
263+ uint32_t major;
264+ uint32_t minor;
265+ uint32_t patchlevel;
266+};
267+
268+struct drm_mm_type_arg {
269+ unsigned int mem_type;
270+ unsigned int lock_flags;
271+};
272+
273+struct drm_mm_init_arg {
274+ unsigned int magic;
275+ unsigned int major;
276+ unsigned int minor;
277+ unsigned int mem_type;
278+ uint64_t p_offset;
279+ uint64_t p_size;
280+};
281+
282 #define DRM_IOCTL_BASE 'd'
283 #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
284 #define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
285@@ -688,6 +954,39 @@
286 #define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
287 #define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int)
288
289+#define DRM_IOCTL_MM_INIT DRM_IOWR(0xc0, struct drm_mm_init_arg)
290+#define DRM_IOCTL_MM_TAKEDOWN DRM_IOWR(0xc1, struct drm_mm_type_arg)
291+#define DRM_IOCTL_MM_LOCK DRM_IOWR(0xc2, struct drm_mm_type_arg)
292+#define DRM_IOCTL_MM_UNLOCK DRM_IOWR(0xc3, struct drm_mm_type_arg)
293+
294+#define DRM_IOCTL_FENCE_CREATE DRM_IOWR(0xc4, struct drm_fence_arg)
295+#define DRM_IOCTL_FENCE_REFERENCE DRM_IOWR(0xc6, struct drm_fence_arg)
296+#define DRM_IOCTL_FENCE_UNREFERENCE DRM_IOWR(0xc7, struct drm_fence_arg)
297+#define DRM_IOCTL_FENCE_SIGNALED DRM_IOWR(0xc8, struct drm_fence_arg)
298+#define DRM_IOCTL_FENCE_FLUSH DRM_IOWR(0xc9, struct drm_fence_arg)
299+#define DRM_IOCTL_FENCE_WAIT DRM_IOWR(0xca, struct drm_fence_arg)
300+#define DRM_IOCTL_FENCE_EMIT DRM_IOWR(0xcb, struct drm_fence_arg)
301+#define DRM_IOCTL_FENCE_BUFFERS DRM_IOWR(0xcc, struct drm_fence_arg)
302+
303+#define DRM_IOCTL_BO_CREATE DRM_IOWR(0xcd, struct drm_bo_create_arg)
304+#define DRM_IOCTL_BO_MAP DRM_IOWR(0xcf, struct drm_bo_map_wait_idle_arg)
305+#define DRM_IOCTL_BO_UNMAP DRM_IOWR(0xd0, struct drm_bo_handle_arg)
306+#define DRM_IOCTL_BO_REFERENCE DRM_IOWR(0xd1, struct drm_bo_reference_info_arg)
307+#define DRM_IOCTL_BO_UNREFERENCE DRM_IOWR(0xd2, struct drm_bo_handle_arg)
308+#define DRM_IOCTL_BO_SETSTATUS DRM_IOWR(0xd3, struct drm_bo_map_wait_idle_arg)
309+#define DRM_IOCTL_BO_INFO DRM_IOWR(0xd4, struct drm_bo_reference_info_arg)
310+#define DRM_IOCTL_BO_WAIT_IDLE DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg)
311+#define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg)
312+
313+
314+#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
315+#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc)
316+#define DRM_IOCTL_MODE_GETOUTPUT DRM_IOWR(0xA2, struct drm_mode_get_output)
317+
318+#define DRM_IOCTL_MODE_ADDMODE DRM_IOWR(0xA7, struct drm_mode_modeinfo)
319+#define DRM_IOCTL_MODE_RMMODE DRM_IOWR(0xA8, unsigned int)
320+/*@}*/
321+
322 /**
323 * Device specific ioctls should only be in their respective headers
324 * The device specific ioctl range is from 0x40 to 0x99.
325@@ -742,6 +1041,11 @@
326 typedef struct drm_agp_info drm_agp_info_t;
327 typedef struct drm_scatter_gather drm_scatter_gather_t;
328 typedef struct drm_set_version drm_set_version_t;
329+
330+typedef struct drm_fence_arg drm_fence_arg_t;
331+typedef struct drm_mm_type_arg drm_mm_type_arg_t;
332+typedef struct drm_mm_init_arg drm_mm_init_arg_t;
333+typedef enum drm_bo_type drm_bo_type_t;
334 #endif
335
336 #endif
337Index: linux-2.6.28/include/drm/drmP.h
338===================================================================
339--- linux-2.6.28.orig/include/drm/drmP.h 2009-02-12 09:14:40.000000000 +0000
340+++ linux-2.6.28/include/drm/drmP.h 2009-02-12 09:14:41.000000000 +0000
341@@ -57,6 +57,7 @@
342 #include <linux/dma-mapping.h>
343 #include <linux/mm.h>
344 #include <linux/cdev.h>
345+#include <linux/i2c.h>
346 #include <linux/mutex.h>
347 #if defined(__alpha__) || defined(__powerpc__)
348 #include <asm/pgtable.h> /* For pte_wrprotect */
349@@ -147,9 +148,24 @@
350 #define DRM_MEM_CTXLIST 21
351 #define DRM_MEM_MM 22
352 #define DRM_MEM_HASHTAB 23
353+#define DRM_MEM_OBJECTS 24
354+#define DRM_MEM_FENCE 25
355+#define DRM_MEM_TTM 26
356+#define DRM_MEM_BUFOBJ 27
357
358 #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
359 #define DRM_MAP_HASH_OFFSET 0x10000000
360+#define DRM_MAP_HASH_ORDER 12
361+#define DRM_OBJECT_HASH_ORDER 12
362+#define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFFUL >> PAGE_SHIFT) + 1)
363+#define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFFUL >> PAGE_SHIFT) * 16)
364+/*
365+ * This should be small enough to allow the use of kmalloc for hash tables
366+ * instead of vmalloc.
367+ */
368+
369+#define DRM_FILE_HASH_ORDER 8
370+#define DRM_MM_INIT_MAX_PAGES 256
371
372 /*@}*/
373
374@@ -378,6 +394,14 @@
375 struct drm_freelist freelist;
376 };
377
378+
379+enum drm_ref_type {
380+ _DRM_REF_USE = 0,
381+ _DRM_REF_TYPE1,
382+ _DRM_NO_REF_TYPES
383+};
384+
385+
386 /** File private data */
387 struct drm_file {
388 int authenticated;
389@@ -387,6 +411,7 @@
390 unsigned long ioctl_count;
391 struct list_head lhead;
392 struct drm_minor *minor;
393+ int remove_auth_on_close;
394 unsigned long lock_count;
395
396 /** Mapping of mm object handles to object pointers. */
397@@ -394,6 +419,16 @@
398 /** Lock for synchronization of access to object_idr. */
399 spinlock_t table_lock;
400
401+ /*
402+ * The user object hash table is global and resides in the
403+ * drm_device structure. We protect the lists and hash tables with the
404+ * device struct_mutex. A bit coarse-grained but probably the best
405+ * option.
406+ */
407+
408+ struct list_head refd_objects;
409+
410+ struct drm_open_hash refd_object_hash[_DRM_NO_REF_TYPES];
411 struct file *filp;
412 void *driver_priv;
413
414@@ -659,6 +694,10 @@
415 void *driver_priv; /**< Private structure for driver to use */
416 };
417
418+#include "drm_objects.h"
419+#include "drm_edid.h"
420+#include "drm_crtc.h"
421+
422 /**
423 * DRM driver structure. This structure represent the common code for
424 * a family of cards. There will one drm_device for each card present
425@@ -684,50 +723,8 @@
426 void (*kernel_context_switch_unlock) (struct drm_device *dev);
427 int (*dri_library_name) (struct drm_device *dev, char *buf);
428
429- /**
430- * get_vblank_counter - get raw hardware vblank counter
431- * @dev: DRM device
432- * @crtc: counter to fetch
433- *
434- * Driver callback for fetching a raw hardware vblank counter
435- * for @crtc. If a device doesn't have a hardware counter, the
436- * driver can simply return the value of drm_vblank_count and
437- * make the enable_vblank() and disable_vblank() hooks into no-ops,
438- * leaving interrupts enabled at all times.
439- *
440- * Wraparound handling and loss of events due to modesetting is dealt
441- * with in the DRM core code.
442- *
443- * RETURNS
444- * Raw vblank counter value.
445- */
446- u32 (*get_vblank_counter) (struct drm_device *dev, int crtc);
447-
448- /**
449- * enable_vblank - enable vblank interrupt events
450- * @dev: DRM device
451- * @crtc: which irq to enable
452- *
453- * Enable vblank interrupts for @crtc. If the device doesn't have
454- * a hardware vblank counter, this routine should be a no-op, since
455- * interrupts will have to stay on to keep the count accurate.
456- *
457- * RETURNS
458- * Zero on success, appropriate errno if the given @crtc's vblank
459- * interrupt cannot be enabled.
460- */
461- int (*enable_vblank) (struct drm_device *dev, int crtc);
462-
463- /**
464- * disable_vblank - disable vblank interrupt events
465- * @dev: DRM device
466- * @crtc: which irq to enable
467- *
468- * Disable vblank interrupts for @crtc. If the device doesn't have
469- * a hardware vblank counter, this routine should be a no-op, since
470- * interrupts will have to stay on to keep the count accurate.
471- */
472- void (*disable_vblank) (struct drm_device *dev, int crtc);
473+ int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence);
474+ int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence);
475
476 /**
477 * Called by \c drm_device_is_agp. Typically used to determine if a
478@@ -766,6 +763,13 @@
479 int (*proc_init)(struct drm_minor *minor);
480 void (*proc_cleanup)(struct drm_minor *minor);
481
482+ /* FB routines, if present */
483+ int (*fb_probe)(struct drm_device *dev, struct drm_crtc *crtc);
484+ int (*fb_remove)(struct drm_device *dev, struct drm_crtc *crtc);
485+
486+ struct drm_fence_driver *fence_driver;
487+ struct drm_bo_driver *bo_driver;
488+
489 /**
490 * Driver-specific constructor for drm_gem_objects, to set up
491 * obj->driver_private.
492@@ -821,8 +825,11 @@
493 */
494 struct drm_device {
495 struct list_head driver_item; /**< list of devices per driver */
496+ char *unique; /**< Unique identifier: e.g., busid */
497+ int unique_len; /**< Length of unique field */
498 char *devname; /**< For /proc/interrupts */
499 int if_version; /**< Highest interface version set */
500+ int blocked; /**< Blocked due to VC switch? */
501
502 /** \name Locks */
503 /*@{ */
504@@ -847,12 +854,18 @@
505 /*@} */
506
507 struct list_head filelist;
508+ struct drm_open_hash magiclist; /**< magic hash table */
509+ struct list_head magicfree;
510
511 /** \name Memory management */
512 /*@{ */
513 struct list_head maplist; /**< Linked list of regions */
514 int map_count; /**< Number of mappable regions */
515 struct drm_open_hash map_hash; /**< User token hash table for maps */
516+ struct drm_mm offset_manager; /**< User token manager */
517+ struct drm_open_hash object_hash; /**< User token hash table for objects */
518+ struct address_space *dev_mapping; /**< For unmap_mapping_range() */
519+ struct page *ttm_dummy_page;
520
521 /** \name Context handle management */
522 /*@{ */
523@@ -864,6 +877,7 @@
524
525 struct list_head vmalist; /**< List of vmas (for debugging) */
526
527+ struct drm_lock_data lock; /**< Information on hardware lock */
528 /*@} */
529
530 /** \name DMA queues (contexts) */
531@@ -877,6 +891,7 @@
532
533 /** \name Context support */
534 /*@{ */
535+ int irq; /**< Interrupt used by board */
536 int irq_enabled; /**< True if irq handler is enabled */
537 __volatile__ long context_flag; /**< Context swapping flag */
538 __volatile__ long interrupt_flag; /**< Interruption handler flag */
539@@ -900,21 +915,15 @@
540 */
541 int vblank_disable_allowed;
542
543- wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */
544- atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */
545+ wait_queue_head_t vbl_queue; /**< VBLANK wait queue */
546+ atomic_t vbl_received;
547+ atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */
548 spinlock_t vbl_lock;
549- struct list_head *vbl_sigs; /**< signal list to send on VBLANK */
550- atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/
551- atomic_t *vblank_refcount; /* number of users of vblank interruptsper crtc */
552- u32 *last_vblank; /* protected by dev->vbl_lock, used */
553- /* for wraparound handling */
554- int *vblank_enabled; /* so we don't call enable more than
555- once per disable */
556- int *vblank_inmodeset; /* Display driver is setting mode */
557- u32 *last_vblank_wait; /* Last vblank seqno waited per CRTC */
558- struct timer_list vblank_disable_timer;
559-
560- u32 max_vblank_count; /**< size of vblank counter register */
561+ struct list_head vbl_sigs; /**< signal list to send on VBLANK */
562+ struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */
563+ unsigned int vbl_pending;
564+ spinlock_t tasklet_lock; /**< For drm_locked_tasklet */
565+ void (*locked_tasklet_func)(struct drm_device *dev);
566
567 /*@} */
568 cycles_t ctx_start;
569@@ -936,7 +945,6 @@
570 int num_crtcs; /**< Number of CRTCs on this device */
571 void *dev_private; /**< device private data */
572 void *mm_private;
573- struct address_space *dev_mapping;
574 struct drm_sigdata sigdata; /**< For block_all_signals */
575 sigset_t sigmask;
576
577@@ -945,6 +953,8 @@
578 unsigned int agp_buffer_token;
579 struct drm_minor *control; /**< Control node for card */
580 struct drm_minor *primary; /**< render type primary screen head */
581+ struct drm_fence_manager fm;
582+ struct drm_buffer_manager bm;
583
584 /** \name Drawable information */
585 /*@{ */
586@@ -976,6 +986,27 @@
587 return dev->pdev->irq;
588 }
589
590+#if __OS_HAS_AGP
591+struct drm_agp_ttm_backend {
592+ struct drm_ttm_backend backend;
593+ DRM_AGP_MEM *mem;
594+ struct agp_bridge_data *bridge;
595+ int populated;
596+};
597+#endif
598+
599+typedef struct ati_pcigart_ttm_backend {
600+ struct drm_ttm_backend backend;
601+ int populated;
602+ void (*gart_flush_fn)(struct drm_device *dev);
603+ struct drm_ati_pcigart_info *gart_info;
604+ unsigned long offset;
605+ struct page **pages;
606+ int num_pages;
607+ int bound;
608+ struct drm_device *dev;
609+} ati_pcigart_ttm_backend_t;
610+
611 static __inline__ int drm_core_check_feature(struct drm_device *dev,
612 int feature)
613 {
614@@ -1042,6 +1073,9 @@
615 /* Driver support (drm_drv.h) */
616 extern int drm_init(struct drm_driver *driver);
617 extern void drm_exit(struct drm_driver *driver);
618+extern void drm_cleanup_pci(struct pci_dev *pdev);
619+extern void drm_vbl_send_signals(struct drm_device *dev);
620+extern struct drm_ttm_backend *drm_agp_init_ttm(struct drm_device *dev);
621 extern int drm_ioctl(struct inode *inode, struct file *filp,
622 unsigned int cmd, unsigned long arg);
623 extern long drm_compat_ioctl(struct file *filp,
624@@ -1208,6 +1242,8 @@
625 extern int drm_wait_vblank(struct drm_device *dev, void *data,
626 struct drm_file *filp);
627 extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq);
628+extern void drm_locked_tasklet(struct drm_device *dev,
629+ void(*func)(struct drm_device *));
630 extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
631 extern void drm_handle_vblank(struct drm_device *dev, int crtc);
632 extern int drm_vblank_get(struct drm_device *dev, int crtc);
633@@ -1218,6 +1254,7 @@
634 extern void drm_vblank_post_modeset(struct drm_device *dev, int crtc);
635 extern int drm_modeset_ctl(struct drm_device *dev, void *data,
636 struct drm_file *file_priv);
637+extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*));
638
639 /* AGP/GART support (drm_agpsupport.h) */
640 extern struct drm_agp_head *drm_agp_init(struct drm_device *dev);
641@@ -1303,9 +1340,6 @@
642 extern int drm_sysfs_device_add(struct drm_minor *minor);
643 extern void drm_sysfs_hotplug_event(struct drm_device *dev);
644 extern void drm_sysfs_device_remove(struct drm_minor *minor);
645-extern char *drm_get_connector_status_name(enum drm_connector_status status);
646-extern int drm_sysfs_connector_add(struct drm_connector *connector);
647-extern void drm_sysfs_connector_remove(struct drm_connector *connector);
648
649 /*
650 * Basic memory manager support (drm_mm.c)
651Index: linux-2.6.28/include/drm/drm_pciids.h
652===================================================================
653--- linux-2.6.28.orig/include/drm/drm_pciids.h 2009-02-12 09:14:31.000000000 +0000
654+++ linux-2.6.28/include/drm/drm_pciids.h 2009-02-12 09:14:41.000000000 +0000
655@@ -419,3 +419,9 @@
656 {0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
657 {0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
658 {0, 0, 0}
659+
660+#define psb_PCI_IDS \
661+ {0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8108}, \
662+ {0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8109}, \
663+ {0, 0, 0}
664+
665Index: linux-2.6.28/drivers/gpu/drm/Makefile
666===================================================================
667--- linux-2.6.28.orig/drivers/gpu/drm/Makefile 2009-02-12 09:14:37.000000000 +0000
668+++ linux-2.6.28/drivers/gpu/drm/Makefile 2009-02-12 09:14:41.000000000 +0000
669@@ -10,8 +10,11 @@
670 drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
671 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
672 drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
673+ drm_fence.o drm_object.o drm_ttm.o drm_bo.o \
674+ drm_bo_lock.o drm_bo_move.o drm_regman.o \
675 drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o
676
677+
678 drm-$(CONFIG_COMPAT) += drm_ioc32.o
679
680 obj-$(CONFIG_DRM) += drm.o
681@@ -22,6 +25,7 @@
682 obj-$(CONFIG_DRM_I810) += i810/
683 obj-$(CONFIG_DRM_I830) += i830/
684 obj-$(CONFIG_DRM_I915) += i915/
685+obj-$(CONFIG_DRM_PSB) += psb/
686 obj-$(CONFIG_DRM_SIS) += sis/
687 obj-$(CONFIG_DRM_SAVAGE)+= savage/
688 obj-$(CONFIG_DRM_VIA) +=via/
689Index: linux-2.6.28/drivers/gpu/drm/drm_agpsupport.c
690===================================================================
691--- linux-2.6.28.orig/drivers/gpu/drm/drm_agpsupport.c 2009-02-12 09:14:31.000000000 +0000
692+++ linux-2.6.28/drivers/gpu/drm/drm_agpsupport.c 2009-02-12 09:14:41.000000000 +0000
693@@ -502,4 +502,156 @@
694 }
695 EXPORT_SYMBOL(drm_agp_chipset_flush);
696
697+/*
698+ * AGP ttm backend interface.
699+ */
700+
701+#ifndef AGP_USER_TYPES
702+#define AGP_USER_TYPES (1 << 16)
703+#define AGP_USER_MEMORY (AGP_USER_TYPES)
704+#define AGP_USER_CACHED_MEMORY (AGP_USER_TYPES + 1)
705+#endif
706+#define AGP_REQUIRED_MAJOR 0
707+#define AGP_REQUIRED_MINOR 102
708+
709+static int drm_agp_needs_unbind_cache_adjust(struct drm_ttm_backend *backend)
710+{
711+ return ((backend->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1);
712+}
713+
714+
715+static int drm_agp_populate(struct drm_ttm_backend *backend,
716+ unsigned long num_pages, struct page **pages)
717+{
718+ struct drm_agp_ttm_backend *agp_be =
719+ container_of(backend, struct drm_agp_ttm_backend, backend);
720+ struct page **cur_page, **last_page = pages + num_pages;
721+ DRM_AGP_MEM *mem;
722+
723+ DRM_DEBUG("drm_agp_populate_ttm\n");
724+ mem = drm_agp_allocate_memory(agp_be->bridge, num_pages, AGP_USER_MEMORY);
725+ if (!mem)
726+ return -ENOMEM;
727+
728+ DRM_DEBUG("Current page count is %ld\n", (long) mem->page_count);
729+ mem->page_count = 0;
730+ for (cur_page = pages; cur_page < last_page; ++cur_page)
731+ mem->memory[mem->page_count++] = phys_to_gart(page_to_phys(*cur_page));
732+ agp_be->mem = mem;
733+ return 0;
734+}
735+
736+static int drm_agp_bind_ttm(struct drm_ttm_backend *backend,
737+ struct drm_bo_mem_reg *bo_mem)
738+{
739+ struct drm_agp_ttm_backend *agp_be =
740+ container_of(backend, struct drm_agp_ttm_backend, backend);
741+ DRM_AGP_MEM *mem = agp_be->mem;
742+ int ret;
743+ int snooped = (bo_mem->flags & DRM_BO_FLAG_CACHED) && !(bo_mem->flags & DRM_BO_FLAG_CACHED_MAPPED);
744+
745+ DRM_DEBUG("drm_agp_bind_ttm\n");
746+ mem->is_flushed = 1;
747+ mem->type = AGP_USER_MEMORY;
748+ /* CACHED MAPPED implies not snooped memory */
749+ if (snooped)
750+ mem->type = AGP_USER_CACHED_MEMORY;
751+
752+ ret = drm_agp_bind_memory(mem, bo_mem->mm_node->start);
753+ if (ret)
754+ DRM_ERROR("AGP Bind memory failed\n");
755+
756+ DRM_FLAG_MASKED(backend->flags, (bo_mem->flags & DRM_BO_FLAG_CACHED) ?
757+ DRM_BE_FLAG_BOUND_CACHED : 0,
758+ DRM_BE_FLAG_BOUND_CACHED);
759+ return ret;
760+}
761+
762+static int drm_agp_unbind_ttm(struct drm_ttm_backend *backend)
763+{
764+ struct drm_agp_ttm_backend *agp_be =
765+ container_of(backend, struct drm_agp_ttm_backend, backend);
766+
767+ DRM_DEBUG("drm_agp_unbind_ttm\n");
768+ if (agp_be->mem->is_bound)
769+ return drm_agp_unbind_memory(agp_be->mem);
770+ else
771+ return 0;
772+}
773+
774+static void drm_agp_clear_ttm(struct drm_ttm_backend *backend)
775+{
776+ struct drm_agp_ttm_backend *agp_be =
777+ container_of(backend, struct drm_agp_ttm_backend, backend);
778+ DRM_AGP_MEM *mem = agp_be->mem;
779+
780+ DRM_DEBUG("drm_agp_clear_ttm\n");
781+ if (mem) {
782+ backend->func->unbind(backend);
783+ agp_free_memory(mem);
784+ }
785+ agp_be->mem = NULL;
786+}
787+
788+static void drm_agp_destroy_ttm(struct drm_ttm_backend *backend)
789+{
790+ struct drm_agp_ttm_backend *agp_be;
791+
792+ if (backend) {
793+ DRM_DEBUG("drm_agp_destroy_ttm\n");
794+ agp_be = container_of(backend, struct drm_agp_ttm_backend, backend);
795+ if (agp_be && agp_be->mem)
796+ backend->func->clear(backend);
797+ }
798+}
799+
800+static struct drm_ttm_backend_func agp_ttm_backend = {
801+ .needs_ub_cache_adjust = drm_agp_needs_unbind_cache_adjust,
802+ .populate = drm_agp_populate,
803+ .clear = drm_agp_clear_ttm,
804+ .bind = drm_agp_bind_ttm,
805+ .unbind = drm_agp_unbind_ttm,
806+ .destroy = drm_agp_destroy_ttm,
807+};
808+
809+struct drm_ttm_backend *drm_agp_init_ttm(struct drm_device *dev)
810+{
811+
812+ struct drm_agp_ttm_backend *agp_be;
813+ struct agp_kern_info *info;
814+
815+ if (!dev->agp) {
816+ DRM_ERROR("AGP is not initialized.\n");
817+ return NULL;
818+ }
819+ info = &dev->agp->agp_info;
820+
821+ if (info->version.major != AGP_REQUIRED_MAJOR ||
822+ info->version.minor < AGP_REQUIRED_MINOR) {
823+ DRM_ERROR("Wrong agpgart version %d.%d\n"
824+ "\tYou need at least version %d.%d.\n",
825+ info->version.major,
826+ info->version.minor,
827+ AGP_REQUIRED_MAJOR,
828+ AGP_REQUIRED_MINOR);
829+ return NULL;
830+ }
831+
832+
833+ agp_be = drm_calloc(1, sizeof(*agp_be), DRM_MEM_TTM);
834+ if (!agp_be)
835+ return NULL;
836+
837+ agp_be->mem = NULL;
838+
839+ agp_be->bridge = dev->agp->bridge;
840+ agp_be->populated = 0;
841+ agp_be->backend.func = &agp_ttm_backend;
842+ agp_be->backend.dev = dev;
843+
844+ return &agp_be->backend;
845+}
846+EXPORT_SYMBOL(drm_agp_init_ttm);
847+
848+
849 #endif /* __OS_HAS_AGP */
850Index: linux-2.6.28/drivers/gpu/drm/drm_bo.c
851===================================================================
852--- /dev/null 1970-01-01 00:00:00.000000000 +0000
853+++ linux-2.6.28/drivers/gpu/drm/drm_bo.c 2009-02-12 09:14:41.000000000 +0000
854@@ -0,0 +1,2660 @@
855+/**************************************************************************
856+ *
857+ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
858+ * All Rights Reserved.
859+ *
860+ * Permission is hereby granted, free of charge, to any person obtaining a
861+ * copy of this software and associated documentation files (the
862+ * "Software"), to deal in the Software without restriction, including
863+ * without limitation the rights to use, copy, modify, merge, publish,
864+ * distribute, sub license, and/or sell copies of the Software, and to
865+ * permit persons to whom the Software is furnished to do so, subject to
866+ * the following conditions:
867+ *
868+ * The above copyright notice and this permission notice (including the
869+ * next paragraph) shall be included in all copies or substantial portions
870+ * of the Software.
871+ *
872+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
873+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
874+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
875+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
876+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
877+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
878+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
879+ *
880+ **************************************************************************/
881+/*
882+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
883+ */
884+
885+#include "drmP.h"
886+
887+/*
888+ * Locking may look a bit complicated but isn't really:
889+ *
890+ * The buffer usage atomic_t needs to be protected by dev->struct_mutex
891+ * when there is a chance that it can be zero before or after the operation.
892+ *
893+ * dev->struct_mutex also protects all lists and list heads,
894+ * Hash tables and hash heads.
895+ *
896+ * bo->mutex protects the buffer object itself excluding the usage field.
897+ * bo->mutex does also protect the buffer list heads, so to manipulate those,
898+ * we need both the bo->mutex and the dev->struct_mutex.
899+ *
900+ * Locking order is bo->mutex, dev->struct_mutex. Therefore list traversal
901+ * is a bit complicated. When dev->struct_mutex is released to grab bo->mutex,
902+ * the list traversal will, in general, need to be restarted.
903+ *
904+ */
905+
906+static void drm_bo_destroy_locked(struct drm_buffer_object *bo);
907+static int drm_bo_setup_vm_locked(struct drm_buffer_object *bo);
908+static void drm_bo_takedown_vm_locked(struct drm_buffer_object *bo);
909+static void drm_bo_unmap_virtual(struct drm_buffer_object *bo);
910+
911+static inline uint64_t drm_bo_type_flags(unsigned type)
912+{
913+ return (1ULL << (24 + type));
914+}
915+
916+/*
917+ * bo locked. dev->struct_mutex locked.
918+ */
919+
920+void drm_bo_add_to_pinned_lru(struct drm_buffer_object *bo)
921+{
922+ struct drm_mem_type_manager *man;
923+
924+ DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
925+ DRM_ASSERT_LOCKED(&bo->mutex);
926+
927+ man = &bo->dev->bm.man[bo->pinned_mem_type];
928+ list_add_tail(&bo->pinned_lru, &man->pinned);
929+}
930+
931+void drm_bo_add_to_lru(struct drm_buffer_object *bo)
932+{
933+ struct drm_mem_type_manager *man;
934+
935+ DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
936+
937+ if (!(bo->mem.mask & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT))
938+ || bo->mem.mem_type != bo->pinned_mem_type) {
939+ man = &bo->dev->bm.man[bo->mem.mem_type];
940+ list_add_tail(&bo->lru, &man->lru);
941+ } else {
942+ INIT_LIST_HEAD(&bo->lru);
943+ }
944+}
945+
946+static int drm_bo_vm_pre_move(struct drm_buffer_object *bo, int old_is_pci)
947+{
948+#ifdef DRM_ODD_MM_COMPAT
949+ int ret;
950+
951+ if (!bo->map_list.map)
952+ return 0;
953+
954+ ret = drm_bo_lock_kmm(bo);
955+ if (ret)
956+ return ret;
957+ drm_bo_unmap_virtual(bo);
958+ if (old_is_pci)
959+ drm_bo_finish_unmap(bo);
960+#else
961+ if (!bo->map_list.map)
962+ return 0;
963+
964+ drm_bo_unmap_virtual(bo);
965+#endif
966+ return 0;
967+}
968+
969+static void drm_bo_vm_post_move(struct drm_buffer_object *bo)
970+{
971+#ifdef DRM_ODD_MM_COMPAT
972+ int ret;
973+
974+ if (!bo->map_list.map)
975+ return;
976+
977+ ret = drm_bo_remap_bound(bo);
978+ if (ret) {
979+ DRM_ERROR("Failed to remap a bound buffer object.\n"
980+ "\tThis might cause a sigbus later.\n");
981+ }
982+ drm_bo_unlock_kmm(bo);
983+#endif
984+}
985+
986+/*
987+ * Call bo->mutex locked.
988+ */
989+
990+static int drm_bo_add_ttm(struct drm_buffer_object *bo)
991+{
992+ struct drm_device *dev = bo->dev;
993+ int ret = 0;
994+
995+ DRM_ASSERT_LOCKED(&bo->mutex);
996+ bo->ttm = NULL;
997+
998+ switch (bo->type) {
999+ case drm_bo_type_dc:
1000+ case drm_bo_type_kernel:
1001+ bo->ttm = drm_ttm_init(dev, bo->num_pages << PAGE_SHIFT);
1002+ if (!bo->ttm)
1003+ ret = -ENOMEM;
1004+ break;
1005+ case drm_bo_type_user:
1006+ bo->ttm = drm_ttm_init(dev, bo->num_pages << PAGE_SHIFT);
1007+ if (!bo->ttm)
1008+ ret = -ENOMEM;
1009+
1010+ ret = drm_ttm_set_user(bo->ttm, current,
1011+ bo->mem.mask & DRM_BO_FLAG_WRITE,
1012+ bo->buffer_start,
1013+ bo->num_pages,
1014+ dev->bm.dummy_read_page);
1015+ if (ret)
1016+ return ret;
1017+
1018+ break;
1019+ default:
1020+ DRM_ERROR("Illegal buffer object type\n");
1021+ ret = -EINVAL;
1022+ break;
1023+ }
1024+
1025+ return ret;
1026+}
1027+
1028+static int drm_bo_handle_move_mem(struct drm_buffer_object *bo,
1029+ struct drm_bo_mem_reg *mem,
1030+ int evict, int no_wait)
1031+{
1032+ struct drm_device *dev = bo->dev;
1033+ struct drm_buffer_manager *bm = &dev->bm;
1034+ int old_is_pci = drm_mem_reg_is_pci(dev, &bo->mem);
1035+ int new_is_pci = drm_mem_reg_is_pci(dev, mem);
1036+ struct drm_mem_type_manager *old_man = &bm->man[bo->mem.mem_type];
1037+ struct drm_mem_type_manager *new_man = &bm->man[mem->mem_type];
1038+ int ret = 0;
1039+
1040+ if (old_is_pci || new_is_pci ||
1041+ ((mem->flags ^ bo->mem.flags) & DRM_BO_FLAG_CACHED))
1042+ ret = drm_bo_vm_pre_move(bo, old_is_pci);
1043+ if (ret)
1044+ return ret;
1045+
1046+ /*
1047+ * Create and bind a ttm if required.
1048+ */
1049+
1050+ if (!(new_man->flags & _DRM_FLAG_MEMTYPE_FIXED) && (bo->ttm == NULL)) {
1051+ ret = drm_bo_add_ttm(bo);
1052+ if (ret)
1053+ goto out_err;
1054+
1055+ if (mem->mem_type != DRM_BO_MEM_LOCAL) {
1056+ ret = drm_bind_ttm(bo->ttm, mem);
1057+ if (ret)
1058+ goto out_err;
1059+ }
1060+
1061+ if (bo->mem.mem_type == DRM_BO_MEM_LOCAL) {
1062+
1063+ struct drm_bo_mem_reg *old_mem = &bo->mem;
1064+ uint64_t save_flags = old_mem->flags;
1065+ uint64_t save_mask = old_mem->mask;
1066+
1067+ *old_mem = *mem;
1068+ mem->mm_node = NULL;
1069+ old_mem->mask = save_mask;
1070+ DRM_FLAG_MASKED(save_flags, mem->flags,
1071+ DRM_BO_MASK_MEMTYPE);
1072+ goto moved;
1073+ }
1074+
1075+ }
1076+
1077+ if (!(old_man->flags & _DRM_FLAG_MEMTYPE_FIXED) &&
1078+ !(new_man->flags & _DRM_FLAG_MEMTYPE_FIXED)) {
1079+
1080+ ret = drm_bo_move_ttm(bo, evict, no_wait, mem);
1081+
1082+ } else if (dev->driver->bo_driver->move) {
1083+ ret = dev->driver->bo_driver->move(bo, evict, no_wait, mem);
1084+
1085+ } else {
1086+
1087+ ret = drm_bo_move_memcpy(bo, evict, no_wait, mem);
1088+
1089+ }
1090+
1091+ if (ret)
1092+ goto out_err;
1093+
1094+moved:
1095+ if (old_is_pci || new_is_pci)
1096+ drm_bo_vm_post_move(bo);
1097+
1098+ if (bo->priv_flags & _DRM_BO_FLAG_EVICTED) {
1099+ ret =
1100+ dev->driver->bo_driver->invalidate_caches(dev,
1101+ bo->mem.flags);
1102+ if (ret)
1103+ DRM_ERROR("Can not flush read caches\n");
1104+ }
1105+
1106+ DRM_FLAG_MASKED(bo->priv_flags,
1107+ (evict) ? _DRM_BO_FLAG_EVICTED : 0,
1108+ _DRM_BO_FLAG_EVICTED);
1109+
1110+ if (bo->mem.mm_node)
1111+ bo->offset = (bo->mem.mm_node->start << PAGE_SHIFT) +
1112+ bm->man[bo->mem.mem_type].gpu_offset;
1113+
1114+
1115+ return 0;
1116+
1117+out_err:
1118+ if (old_is_pci || new_is_pci)
1119+ drm_bo_vm_post_move(bo);
1120+
1121+ new_man = &bm->man[bo->mem.mem_type];
1122+ if ((new_man->flags & _DRM_FLAG_MEMTYPE_FIXED) && bo->ttm) {
1123+ drm_ttm_unbind(bo->ttm);
1124+ drm_destroy_ttm(bo->ttm);
1125+ bo->ttm = NULL;
1126+ }
1127+
1128+ return ret;
1129+}
1130+
1131+/*
1132+ * Call bo->mutex locked.
1133+ * Wait until the buffer is idle.
1134+ */
1135+
1136+int drm_bo_wait(struct drm_buffer_object *bo, int lazy, int ignore_signals,
1137+ int no_wait)
1138+{
1139+ int ret;
1140+
1141+ DRM_ASSERT_LOCKED(&bo->mutex);
1142+
1143+ if (bo->fence) {
1144+ if (drm_fence_object_signaled(bo->fence, bo->fence_type)) {
1145+ drm_fence_usage_deref_unlocked(&bo->fence);
1146+ return 0;
1147+ }
1148+ if (no_wait)
1149+ return -EBUSY;
1150+
1151+ ret = drm_fence_object_wait(bo->fence, lazy, ignore_signals,
1152+ bo->fence_type);
1153+ if (ret)
1154+ return ret;
1155+
1156+ drm_fence_usage_deref_unlocked(&bo->fence);
1157+ }
1158+ return 0;
1159+}
1160+EXPORT_SYMBOL(drm_bo_wait);
1161+
1162+static int drm_bo_expire_fence(struct drm_buffer_object *bo, int allow_errors)
1163+{
1164+ struct drm_device *dev = bo->dev;
1165+ struct drm_buffer_manager *bm = &dev->bm;
1166+
1167+ if (bo->fence) {
1168+ if (bm->nice_mode) {
1169+ unsigned long _end = jiffies + 3 * DRM_HZ;
1170+ int ret;
1171+ do {
1172+ ret = drm_bo_wait(bo, 0, 1, 0);
1173+ if (ret && allow_errors)
1174+ return ret;
1175+
1176+ } while (ret && !time_after_eq(jiffies, _end));
1177+
1178+ if (bo->fence) {
1179+ bm->nice_mode = 0;
1180+ DRM_ERROR("Detected GPU lockup or "
1181+ "fence driver was taken down. "
1182+ "Evicting buffer.\n");
1183+ }
1184+ }
1185+ if (bo->fence)
1186+ drm_fence_usage_deref_unlocked(&bo->fence);
1187+ }
1188+ return 0;
1189+}
1190+
1191+/*
1192+ * Call dev->struct_mutex locked.
1193+ * Attempts to remove all private references to a buffer by expiring its
1194+ * fence object and removing from lru lists and memory managers.
1195+ */
1196+
1197+static void drm_bo_cleanup_refs(struct drm_buffer_object *bo, int remove_all)
1198+{
1199+ struct drm_device *dev = bo->dev;
1200+ struct drm_buffer_manager *bm = &dev->bm;
1201+
1202+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
1203+
1204+ atomic_inc(&bo->usage);
1205+ mutex_unlock(&dev->struct_mutex);
1206+ mutex_lock(&bo->mutex);
1207+
1208+ DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
1209+
1210+ if (bo->fence && drm_fence_object_signaled(bo->fence,
1211+ bo->fence_type))
1212+ drm_fence_usage_deref_unlocked(&bo->fence);
1213+
1214+ if (bo->fence && remove_all)
1215+ (void)drm_bo_expire_fence(bo, 0);
1216+
1217+ mutex_lock(&dev->struct_mutex);
1218+
1219+ if (!atomic_dec_and_test(&bo->usage))
1220+ goto out;
1221+
1222+ if (!bo->fence) {
1223+ list_del_init(&bo->lru);
1224+ if (bo->mem.mm_node) {
1225+ drm_mm_put_block(bo->mem.mm_node);
1226+ if (bo->pinned_node == bo->mem.mm_node)
1227+ bo->pinned_node = NULL;
1228+ bo->mem.mm_node = NULL;
1229+ }
1230+ list_del_init(&bo->pinned_lru);
1231+ if (bo->pinned_node) {
1232+ drm_mm_put_block(bo->pinned_node);
1233+ bo->pinned_node = NULL;
1234+ }
1235+ list_del_init(&bo->ddestroy);
1236+ mutex_unlock(&bo->mutex);
1237+ drm_bo_destroy_locked(bo);
1238+ return;
1239+ }
1240+
1241+ if (list_empty(&bo->ddestroy)) {
1242+ drm_fence_object_flush(bo->fence, bo->fence_type);
1243+ list_add_tail(&bo->ddestroy, &bm->ddestroy);
1244+ schedule_delayed_work(&bm->wq,
1245+ ((DRM_HZ / 100) < 1) ? 1 : DRM_HZ / 100);
1246+ }
1247+
1248+out:
1249+ mutex_unlock(&bo->mutex);
1250+ return;
1251+}
1252+
1253+static void drm_bo_unreserve_size(unsigned long size)
1254+{
1255+ //drm_free_memctl(size);
1256+}
1257+
1258+/*
1259+ * Verify that refcount is 0 and that there are no internal references
1260+ * to the buffer object. Then destroy it.
1261+ */
1262+
1263+static void drm_bo_destroy_locked(struct drm_buffer_object *bo)
1264+{
1265+ struct drm_device *dev = bo->dev;
1266+ struct drm_buffer_manager *bm = &dev->bm;
1267+ unsigned long reserved_size;
1268+
1269+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
1270+
1271+ if (list_empty(&bo->lru) && bo->mem.mm_node == NULL &&
1272+ list_empty(&bo->pinned_lru) && bo->pinned_node == NULL &&
1273+ list_empty(&bo->ddestroy) && atomic_read(&bo->usage) == 0) {
1274+ if (bo->fence != NULL) {
1275+ DRM_ERROR("Fence was non-zero.\n");
1276+ drm_bo_cleanup_refs(bo, 0);
1277+ return;
1278+ }
1279+
1280+#ifdef DRM_ODD_MM_COMPAT
1281+ BUG_ON(!list_empty(&bo->vma_list));
1282+ BUG_ON(!list_empty(&bo->p_mm_list));
1283+#endif
1284+
1285+ if (bo->ttm) {
1286+ drm_ttm_unbind(bo->ttm);
1287+ drm_destroy_ttm(bo->ttm);
1288+ bo->ttm = NULL;
1289+ }
1290+
1291+ atomic_dec(&bm->count);
1292+
1293+ reserved_size = bo->reserved_size;
1294+
1295+ drm_free(bo, sizeof(*bo), DRM_MEM_BUFOBJ);
1296+ drm_bo_unreserve_size(reserved_size);
1297+
1298+ return;
1299+ }
1300+
1301+ /*
1302+ * Some stuff is still trying to reference the buffer object.
1303+ * Get rid of those references.
1304+ */
1305+
1306+ drm_bo_cleanup_refs(bo, 0);
1307+
1308+ return;
1309+}
1310+
1311+/*
1312+ * Call dev->struct_mutex locked.
1313+ */
1314+
1315+static void drm_bo_delayed_delete(struct drm_device *dev, int remove_all)
1316+{
1317+ struct drm_buffer_manager *bm = &dev->bm;
1318+
1319+ struct drm_buffer_object *entry, *nentry;
1320+ struct list_head *list, *next;
1321+
1322+ list_for_each_safe(list, next, &bm->ddestroy) {
1323+ entry = list_entry(list, struct drm_buffer_object, ddestroy);
1324+
1325+ nentry = NULL;
1326+ if (next != &bm->ddestroy) {
1327+ nentry = list_entry(next, struct drm_buffer_object,
1328+ ddestroy);
1329+ atomic_inc(&nentry->usage);
1330+ }
1331+
1332+ drm_bo_cleanup_refs(entry, remove_all);
1333+
1334+ if (nentry)
1335+ atomic_dec(&nentry->usage);
1336+ }
1337+}
1338+
1339+static void drm_bo_delayed_workqueue(struct work_struct *work)
1340+{
1341+ struct drm_buffer_manager *bm =
1342+ container_of(work, struct drm_buffer_manager, wq.work);
1343+ struct drm_device *dev = container_of(bm, struct drm_device, bm);
1344+
1345+ DRM_DEBUG("Delayed delete Worker\n");
1346+
1347+ mutex_lock(&dev->struct_mutex);
1348+ if (!bm->initialized) {
1349+ mutex_unlock(&dev->struct_mutex);
1350+ return;
1351+ }
1352+ drm_bo_delayed_delete(dev, 0);
1353+ if (bm->initialized && !list_empty(&bm->ddestroy)) {
1354+ schedule_delayed_work(&bm->wq,
1355+ ((DRM_HZ / 100) < 1) ? 1 : DRM_HZ / 100);
1356+ }
1357+ mutex_unlock(&dev->struct_mutex);
1358+}
1359+
1360+void drm_bo_usage_deref_locked(struct drm_buffer_object **bo)
1361+{
1362+ struct drm_buffer_object *tmp_bo = *bo;
1363+ bo = NULL;
1364+
1365+ DRM_ASSERT_LOCKED(&tmp_bo->dev->struct_mutex);
1366+
1367+ if (atomic_dec_and_test(&tmp_bo->usage))
1368+ drm_bo_destroy_locked(tmp_bo);
1369+}
1370+EXPORT_SYMBOL(drm_bo_usage_deref_locked);
1371+
1372+static void drm_bo_base_deref_locked(struct drm_file *file_priv,
1373+ struct drm_user_object *uo)
1374+{
1375+ struct drm_buffer_object *bo =
1376+ drm_user_object_entry(uo, struct drm_buffer_object, base);
1377+
1378+ DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
1379+
1380+ drm_bo_takedown_vm_locked(bo);
1381+ drm_bo_usage_deref_locked(&bo);
1382+}
1383+
1384+void drm_bo_usage_deref_unlocked(struct drm_buffer_object **bo)
1385+{
1386+ struct drm_buffer_object *tmp_bo = *bo;
1387+ struct drm_device *dev = tmp_bo->dev;
1388+
1389+ *bo = NULL;
1390+ if (atomic_dec_and_test(&tmp_bo->usage)) {
1391+ mutex_lock(&dev->struct_mutex);
1392+ if (atomic_read(&tmp_bo->usage) == 0)
1393+ drm_bo_destroy_locked(tmp_bo);
1394+ mutex_unlock(&dev->struct_mutex);
1395+ }
1396+}
1397+EXPORT_SYMBOL(drm_bo_usage_deref_unlocked);
1398+
1399+void drm_putback_buffer_objects(struct drm_device *dev)
1400+{
1401+ struct drm_buffer_manager *bm = &dev->bm;
1402+ struct list_head *list = &bm->unfenced;
1403+ struct drm_buffer_object *entry, *next;
1404+
1405+ mutex_lock(&dev->struct_mutex);
1406+ list_for_each_entry_safe(entry, next, list, lru) {
1407+ atomic_inc(&entry->usage);
1408+ mutex_unlock(&dev->struct_mutex);
1409+
1410+ mutex_lock(&entry->mutex);
1411+ BUG_ON(!(entry->priv_flags & _DRM_BO_FLAG_UNFENCED));
1412+ mutex_lock(&dev->struct_mutex);
1413+
1414+ list_del_init(&entry->lru);
1415+ DRM_FLAG_MASKED(entry->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
1416+ wake_up_all(&entry->event_queue);
1417+
1418+ /*
1419+ * FIXME: Might want to put back on head of list
1420+ * instead of tail here.
1421+ */
1422+
1423+ drm_bo_add_to_lru(entry);
1424+ mutex_unlock(&entry->mutex);
1425+ drm_bo_usage_deref_locked(&entry);
1426+ }
1427+ mutex_unlock(&dev->struct_mutex);
1428+}
1429+EXPORT_SYMBOL(drm_putback_buffer_objects);
1430+
1431+
1432+/*
1433+ * Note. The caller has to register (if applicable)
1434+ * and deregister fence object usage.
1435+ */
1436+
1437+int drm_fence_buffer_objects(struct drm_device *dev,
1438+ struct list_head *list,
1439+ uint32_t fence_flags,
1440+ struct drm_fence_object *fence,
1441+ struct drm_fence_object **used_fence)
1442+{
1443+ struct drm_buffer_manager *bm = &dev->bm;
1444+ struct drm_buffer_object *entry;
1445+ uint32_t fence_type = 0;
1446+ uint32_t fence_class = ~0;
1447+ int count = 0;
1448+ int ret = 0;
1449+ struct list_head *l;
1450+
1451+ mutex_lock(&dev->struct_mutex);
1452+
1453+ if (!list)
1454+ list = &bm->unfenced;
1455+
1456+ if (fence)
1457+ fence_class = fence->fence_class;
1458+
1459+ list_for_each_entry(entry, list, lru) {
1460+ BUG_ON(!(entry->priv_flags & _DRM_BO_FLAG_UNFENCED));
1461+ fence_type |= entry->new_fence_type;
1462+ if (fence_class == ~0)
1463+ fence_class = entry->new_fence_class;
1464+ else if (entry->new_fence_class != fence_class) {
1465+ DRM_ERROR("Unmatching fence classes on unfenced list: "
1466+ "%d and %d.\n",
1467+ fence_class,
1468+ entry->new_fence_class);
1469+ ret = -EINVAL;
1470+ goto out;
1471+ }
1472+ count++;
1473+ }
1474+
1475+ if (!count) {
1476+ ret = -EINVAL;
1477+ goto out;
1478+ }
1479+
1480+ if (fence) {
1481+ if ((fence_type & fence->type) != fence_type ||
1482+ (fence->fence_class != fence_class)) {
1483+ DRM_ERROR("Given fence doesn't match buffers "
1484+ "on unfenced list.\n");
1485+ ret = -EINVAL;
1486+ goto out;
1487+ }
1488+ } else {
1489+ mutex_unlock(&dev->struct_mutex);
1490+ ret = drm_fence_object_create(dev, fence_class, fence_type,
1491+ fence_flags | DRM_FENCE_FLAG_EMIT,
1492+ &fence);
1493+ mutex_lock(&dev->struct_mutex);
1494+ if (ret)
1495+ goto out;
1496+ }
1497+
1498+ count = 0;
1499+ l = list->next;
1500+ while (l != list) {
1501+ prefetch(l->next);
1502+ entry = list_entry(l, struct drm_buffer_object, lru);
1503+ atomic_inc(&entry->usage);
1504+ mutex_unlock(&dev->struct_mutex);
1505+ mutex_lock(&entry->mutex);
1506+ mutex_lock(&dev->struct_mutex);
1507+ list_del_init(l);
1508+ if (entry->priv_flags & _DRM_BO_FLAG_UNFENCED) {
1509+ count++;
1510+ if (entry->fence)
1511+ drm_fence_usage_deref_locked(&entry->fence);
1512+ entry->fence = drm_fence_reference_locked(fence);
1513+ entry->fence_class = entry->new_fence_class;
1514+ entry->fence_type = entry->new_fence_type;
1515+ DRM_FLAG_MASKED(entry->priv_flags, 0,
1516+ _DRM_BO_FLAG_UNFENCED);
1517+ wake_up_all(&entry->event_queue);
1518+ drm_bo_add_to_lru(entry);
1519+ }
1520+ mutex_unlock(&entry->mutex);
1521+ drm_bo_usage_deref_locked(&entry);
1522+ l = list->next;
1523+ }
1524+ DRM_DEBUG("Fenced %d buffers\n", count);
1525+out:
1526+ mutex_unlock(&dev->struct_mutex);
1527+ *used_fence = fence;
1528+ return ret;
1529+}
1530+EXPORT_SYMBOL(drm_fence_buffer_objects);
1531+
1532+/*
1533+ * bo->mutex locked
1534+ */
1535+
1536+static int drm_bo_evict(struct drm_buffer_object *bo, unsigned mem_type,
1537+ int no_wait)
1538+{
1539+ int ret = 0;
1540+ struct drm_device *dev = bo->dev;
1541+ struct drm_bo_mem_reg evict_mem;
1542+
1543+ /*
1544+ * Someone might have modified the buffer before we took the
1545+ * buffer mutex.
1546+ */
1547+
1548+ if (bo->priv_flags & _DRM_BO_FLAG_UNFENCED)
1549+ goto out;
1550+ if (bo->mem.mem_type != mem_type)
1551+ goto out;
1552+
1553+ ret = drm_bo_wait(bo, 0, 0, no_wait);
1554+
1555+ if (ret && ret != -EAGAIN) {
1556+ DRM_ERROR("Failed to expire fence before "
1557+ "buffer eviction.\n");
1558+ goto out;
1559+ }
1560+
1561+ evict_mem = bo->mem;
1562+ evict_mem.mm_node = NULL;
1563+
1564+ evict_mem = bo->mem;
1565+ evict_mem.mask = dev->driver->bo_driver->evict_mask(bo);
1566+ ret = drm_bo_mem_space(bo, &evict_mem, no_wait);
1567+
1568+ if (ret) {
1569+ if (ret != -EAGAIN)
1570+ DRM_ERROR("Failed to find memory space for "
1571+ "buffer 0x%p eviction.\n", bo);
1572+ goto out;
1573+ }
1574+
1575+ ret = drm_bo_handle_move_mem(bo, &evict_mem, 1, no_wait);
1576+
1577+ if (ret) {
1578+ if (ret != -EAGAIN)
1579+ DRM_ERROR("Buffer eviction failed\n");
1580+ goto out;
1581+ }
1582+
1583+ mutex_lock(&dev->struct_mutex);
1584+ if (evict_mem.mm_node) {
1585+ if (evict_mem.mm_node != bo->pinned_node)
1586+ drm_mm_put_block(evict_mem.mm_node);
1587+ evict_mem.mm_node = NULL;
1588+ }
1589+ list_del(&bo->lru);
1590+ drm_bo_add_to_lru(bo);
1591+ mutex_unlock(&dev->struct_mutex);
1592+
1593+ DRM_FLAG_MASKED(bo->priv_flags, _DRM_BO_FLAG_EVICTED,
1594+ _DRM_BO_FLAG_EVICTED);
1595+
1596+out:
1597+ return ret;
1598+}
1599+
1600+/**
1601+ * Repeatedly evict memory from the LRU for @mem_type until we create enough
1602+ * space, or we've evicted everything and there isn't enough space.
1603+ */
1604+static int drm_bo_mem_force_space(struct drm_device *dev,
1605+ struct drm_bo_mem_reg *mem,
1606+ uint32_t mem_type, int no_wait)
1607+{
1608+ struct drm_mm_node *node;
1609+ struct drm_buffer_manager *bm = &dev->bm;
1610+ struct drm_buffer_object *entry;
1611+ struct drm_mem_type_manager *man = &bm->man[mem_type];
1612+ struct list_head *lru;
1613+ unsigned long num_pages = mem->num_pages;
1614+ int ret;
1615+
1616+ mutex_lock(&dev->struct_mutex);
1617+ do {
1618+ node = drm_mm_search_free(&man->manager, num_pages,
1619+ mem->page_alignment, 1);
1620+ if (node)
1621+ break;
1622+
1623+ lru = &man->lru;
1624+ if (lru->next == lru)
1625+ break;
1626+
1627+ entry = list_entry(lru->next, struct drm_buffer_object, lru);
1628+ atomic_inc(&entry->usage);
1629+ mutex_unlock(&dev->struct_mutex);
1630+ mutex_lock(&entry->mutex);
1631+ BUG_ON(entry->mem.flags & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT));
1632+
1633+ ret = drm_bo_evict(entry, mem_type, no_wait);
1634+ mutex_unlock(&entry->mutex);
1635+ drm_bo_usage_deref_unlocked(&entry);
1636+ if (ret)
1637+ return ret;
1638+ mutex_lock(&dev->struct_mutex);
1639+ } while (1);
1640+
1641+ if (!node) {
1642+ mutex_unlock(&dev->struct_mutex);
1643+ return -ENOMEM;
1644+ }
1645+
1646+ node = drm_mm_get_block(node, num_pages, mem->page_alignment);
1647+ if (!node) {
1648+ mutex_unlock(&dev->struct_mutex);
1649+ return -ENOMEM;
1650+ }
1651+
1652+ mutex_unlock(&dev->struct_mutex);
1653+ mem->mm_node = node;
1654+ mem->mem_type = mem_type;
1655+ return 0;
1656+}
1657+
1658+static int drm_bo_mt_compatible(struct drm_mem_type_manager *man,
1659+ int disallow_fixed,
1660+ uint32_t mem_type,
1661+ uint64_t mask, uint32_t *res_mask)
1662+{
1663+ uint64_t cur_flags = drm_bo_type_flags(mem_type);
1664+ uint64_t flag_diff;
1665+
1666+ if ((man->flags & _DRM_FLAG_MEMTYPE_FIXED) && disallow_fixed)
1667+ return 0;
1668+ if (man->flags & _DRM_FLAG_MEMTYPE_CACHED)
1669+ cur_flags |= DRM_BO_FLAG_CACHED;
1670+ if (man->flags & _DRM_FLAG_MEMTYPE_MAPPABLE)
1671+ cur_flags |= DRM_BO_FLAG_MAPPABLE;
1672+ if (man->flags & _DRM_FLAG_MEMTYPE_CSELECT)
1673+ DRM_FLAG_MASKED(cur_flags, mask, DRM_BO_FLAG_CACHED);
1674+
1675+ if ((cur_flags & mask & DRM_BO_MASK_MEM) == 0)
1676+ return 0;
1677+
1678+ if (mem_type == DRM_BO_MEM_LOCAL) {
1679+ *res_mask = cur_flags;
1680+ return 1;
1681+ }
1682+
1683+ flag_diff = (mask ^ cur_flags);
1684+ if (flag_diff & DRM_BO_FLAG_CACHED_MAPPED)
1685+ cur_flags |= DRM_BO_FLAG_CACHED_MAPPED;
1686+
1687+ if ((flag_diff & DRM_BO_FLAG_CACHED) &&
1688+ (!(mask & DRM_BO_FLAG_CACHED) ||
1689+ (mask & DRM_BO_FLAG_FORCE_CACHING)))
1690+ return 0;
1691+
1692+ if ((flag_diff & DRM_BO_FLAG_MAPPABLE) &&
1693+ ((mask & DRM_BO_FLAG_MAPPABLE) ||
1694+ (mask & DRM_BO_FLAG_FORCE_MAPPABLE)))
1695+ return 0;
1696+
1697+ *res_mask = cur_flags;
1698+ return 1;
1699+}
1700+
1701+/**
1702+ * Creates space for memory region @mem according to its type.
1703+ *
1704+ * This function first searches for free space in compatible memory types in
1705+ * the priority order defined by the driver. If free space isn't found, then
1706+ * drm_bo_mem_force_space is attempted in priority order to evict and find
1707+ * space.
1708+ */
1709+int drm_bo_mem_space(struct drm_buffer_object *bo,
1710+ struct drm_bo_mem_reg *mem, int no_wait)
1711+{
1712+ struct drm_device *dev = bo->dev;
1713+ struct drm_buffer_manager *bm = &dev->bm;
1714+ struct drm_mem_type_manager *man;
1715+
1716+ uint32_t num_prios = dev->driver->bo_driver->num_mem_type_prio;
1717+ const uint32_t *prios = dev->driver->bo_driver->mem_type_prio;
1718+ uint32_t i;
1719+ uint32_t mem_type = DRM_BO_MEM_LOCAL;
1720+ uint32_t cur_flags;
1721+ int type_found = 0;
1722+ int type_ok = 0;
1723+ int has_eagain = 0;
1724+ struct drm_mm_node *node = NULL;
1725+ int ret;
1726+
1727+ mem->mm_node = NULL;
1728+ for (i = 0; i < num_prios; ++i) {
1729+ mem_type = prios[i];
1730+ man = &bm->man[mem_type];
1731+
1732+ type_ok = drm_bo_mt_compatible(man,
1733+ bo->type == drm_bo_type_user,
1734+ mem_type, mem->mask,
1735+ &cur_flags);
1736+
1737+ if (!type_ok)
1738+ continue;
1739+
1740+ if (mem_type == DRM_BO_MEM_LOCAL)
1741+ break;
1742+
1743+ if ((mem_type == bo->pinned_mem_type) &&
1744+ (bo->pinned_node != NULL)) {
1745+ node = bo->pinned_node;
1746+ break;
1747+ }
1748+
1749+ mutex_lock(&dev->struct_mutex);
1750+ if (man->has_type && man->use_type) {
1751+ type_found = 1;
1752+ node = drm_mm_search_free(&man->manager, mem->num_pages,
1753+ mem->page_alignment, 1);
1754+ if (node)
1755+ node = drm_mm_get_block(node, mem->num_pages,
1756+ mem->page_alignment);
1757+ }
1758+ mutex_unlock(&dev->struct_mutex);
1759+ if (node)
1760+ break;
1761+ }
1762+
1763+ if ((type_ok && (mem_type == DRM_BO_MEM_LOCAL)) || node) {
1764+ mem->mm_node = node;
1765+ mem->mem_type = mem_type;
1766+ mem->flags = cur_flags;
1767+ return 0;
1768+ }
1769+
1770+ if (!type_found)
1771+ return -EINVAL;
1772+
1773+ num_prios = dev->driver->bo_driver->num_mem_busy_prio;
1774+ prios = dev->driver->bo_driver->mem_busy_prio;
1775+
1776+ for (i = 0; i < num_prios; ++i) {
1777+ mem_type = prios[i];
1778+ man = &bm->man[mem_type];
1779+
1780+ if (!man->has_type)
1781+ continue;
1782+
1783+ if (!drm_bo_mt_compatible(man,
1784+ bo->type == drm_bo_type_user,
1785+ mem_type,
1786+ mem->mask,
1787+ &cur_flags))
1788+ continue;
1789+
1790+ ret = drm_bo_mem_force_space(dev, mem, mem_type, no_wait);
1791+
1792+ if (ret == 0 && mem->mm_node) {
1793+ mem->flags = cur_flags;
1794+ return 0;
1795+ }
1796+
1797+ if (ret == -EAGAIN)
1798+ has_eagain = 1;
1799+ }
1800+
1801+ ret = (has_eagain) ? -EAGAIN : -ENOMEM;
1802+ return ret;
1803+}
1804+EXPORT_SYMBOL(drm_bo_mem_space);
1805+
1806+static int drm_bo_new_mask(struct drm_buffer_object *bo,
1807+ uint64_t new_flags, uint64_t used_mask)
1808+{
1809+ uint32_t new_props;
1810+
1811+ if (bo->type == drm_bo_type_user &&
1812+ ((new_flags & (DRM_BO_FLAG_CACHED | DRM_BO_FLAG_FORCE_CACHING)) !=
1813+ (DRM_BO_FLAG_CACHED | DRM_BO_FLAG_FORCE_CACHING))) {
1814+ DRM_ERROR("User buffers require cache-coherent memory.\n");
1815+ return -EINVAL;
1816+ }
1817+
1818+ if ((used_mask & DRM_BO_FLAG_NO_EVICT) && !DRM_SUSER(DRM_CURPROC)) {
1819+ DRM_ERROR("DRM_BO_FLAG_NO_EVICT is only available to priviliged processes.\n");
1820+ return -EPERM;
1821+ }
1822+
1823+ if (likely(used_mask & DRM_BO_MASK_MEM) &&
1824+ (bo->mem.flags & DRM_BO_FLAG_NO_EVICT) &&
1825+ !DRM_SUSER(DRM_CURPROC)) {
1826+ if (likely(bo->mem.flags & new_flags & used_mask &
1827+ DRM_BO_MASK_MEM))
1828+ new_flags = (new_flags & ~DRM_BO_MASK_MEM) |
1829+ (bo->mem.flags & DRM_BO_MASK_MEM);
1830+ else {
1831+ DRM_ERROR("Incompatible memory type specification "
1832+ "for NO_EVICT buffer.\n");
1833+ return -EPERM;
1834+ }
1835+ }
1836+
1837+ if ((new_flags & DRM_BO_FLAG_NO_MOVE)) {
1838+ DRM_ERROR("DRM_BO_FLAG_NO_MOVE is not properly implemented yet.\n");
1839+ return -EPERM;
1840+ }
1841+
1842+ new_props = new_flags & (DRM_BO_FLAG_EXE | DRM_BO_FLAG_WRITE |
1843+ DRM_BO_FLAG_READ);
1844+
1845+ if (!new_props) {
1846+ DRM_ERROR("Invalid buffer object rwx properties\n");
1847+ return -EINVAL;
1848+ }
1849+
1850+ bo->mem.mask = new_flags;
1851+ return 0;
1852+}
1853+
1854+/*
1855+ * Call dev->struct_mutex locked.
1856+ */
1857+
1858+struct drm_buffer_object *drm_lookup_buffer_object(struct drm_file *file_priv,
1859+ uint32_t handle, int check_owner)
1860+{
1861+ struct drm_user_object *uo;
1862+ struct drm_buffer_object *bo;
1863+
1864+ uo = drm_lookup_user_object(file_priv, handle);
1865+
1866+ if (!uo || (uo->type != drm_buffer_type)) {
1867+ DRM_ERROR("Could not find buffer object 0x%08x\n", handle);
1868+ return NULL;
1869+ }
1870+
1871+ if (check_owner && file_priv != uo->owner) {
1872+ if (!drm_lookup_ref_object(file_priv, uo, _DRM_REF_USE))
1873+ return NULL;
1874+ }
1875+
1876+ bo = drm_user_object_entry(uo, struct drm_buffer_object, base);
1877+ atomic_inc(&bo->usage);
1878+ return bo;
1879+}
1880+EXPORT_SYMBOL(drm_lookup_buffer_object);
1881+
1882+/*
1883+ * Call bo->mutex locked.
1884+ * Returns 1 if the buffer is currently rendered to or from. 0 otherwise.
1885+ * Doesn't do any fence flushing as opposed to the drm_bo_busy function.
1886+ */
1887+
1888+static int drm_bo_quick_busy(struct drm_buffer_object *bo)
1889+{
1890+ struct drm_fence_object *fence = bo->fence;
1891+
1892+ BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
1893+ if (fence) {
1894+ if (drm_fence_object_signaled(fence, bo->fence_type)) {
1895+ drm_fence_usage_deref_unlocked(&bo->fence);
1896+ return 0;
1897+ }
1898+ return 1;
1899+ }
1900+ return 0;
1901+}
1902+
1903+/*
1904+ * Call bo->mutex locked.
1905+ * Returns 1 if the buffer is currently rendered to or from. 0 otherwise.
1906+ */
1907+
1908+static int drm_bo_busy(struct drm_buffer_object *bo)
1909+{
1910+ struct drm_fence_object *fence = bo->fence;
1911+
1912+ BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
1913+ if (fence) {
1914+ if (drm_fence_object_signaled(fence, bo->fence_type)) {
1915+ drm_fence_usage_deref_unlocked(&bo->fence);
1916+ return 0;
1917+ }
1918+ drm_fence_object_flush(fence, DRM_FENCE_TYPE_EXE);
1919+ if (drm_fence_object_signaled(fence, bo->fence_type)) {
1920+ drm_fence_usage_deref_unlocked(&bo->fence);
1921+ return 0;
1922+ }
1923+ return 1;
1924+ }
1925+ return 0;
1926+}
1927+
1928+static int drm_bo_evict_cached(struct drm_buffer_object *bo)
1929+{
1930+ int ret = 0;
1931+
1932+ BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
1933+ if (bo->mem.mm_node)
1934+ ret = drm_bo_evict(bo, DRM_BO_MEM_TT, 1);
1935+ return ret;
1936+}
1937+
1938+/*
1939+ * Wait until a buffer is unmapped.
1940+ */
1941+
1942+static int drm_bo_wait_unmapped(struct drm_buffer_object *bo, int no_wait)
1943+{
1944+ int ret = 0;
1945+
1946+ if ((atomic_read(&bo->mapped) >= 0) && no_wait)
1947+ return -EBUSY;
1948+
1949+ DRM_WAIT_ON(ret, bo->event_queue, 3 * DRM_HZ,
1950+ atomic_read(&bo->mapped) == -1);
1951+
1952+ if (ret == -EINTR)
1953+ ret = -EAGAIN;
1954+
1955+ return ret;
1956+}
1957+
1958+static int drm_bo_check_unfenced(struct drm_buffer_object *bo)
1959+{
1960+ int ret;
1961+
1962+ mutex_lock(&bo->mutex);
1963+ ret = (bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
1964+ mutex_unlock(&bo->mutex);
1965+ return ret;
1966+}
1967+
1968+/*
1969+ * Wait until a buffer, scheduled to be fenced moves off the unfenced list.
1970+ * Until then, we cannot really do anything with it except delete it.
1971+ */
1972+
1973+static int drm_bo_wait_unfenced(struct drm_buffer_object *bo, int no_wait,
1974+ int eagain_if_wait)
1975+{
1976+ int ret = (bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
1977+
1978+ if (ret && no_wait)
1979+ return -EBUSY;
1980+ else if (!ret)
1981+ return 0;
1982+
1983+ ret = 0;
1984+ mutex_unlock(&bo->mutex);
1985+ DRM_WAIT_ON(ret, bo->event_queue, 3 * DRM_HZ,
1986+ !drm_bo_check_unfenced(bo));
1987+ mutex_lock(&bo->mutex);
1988+ if (ret == -EINTR)
1989+ return -EAGAIN;
1990+ ret = (bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
1991+ if (ret) {
1992+ DRM_ERROR("Timeout waiting for buffer to become fenced\n");
1993+ return -EBUSY;
1994+ }
1995+ if (eagain_if_wait)
1996+ return -EAGAIN;
1997+
1998+ return 0;
1999+}
2000+
2001+/*
2002+ * Fill in the ioctl reply argument with buffer info.
2003+ * Bo locked.
2004+ */
2005+
2006+void drm_bo_fill_rep_arg(struct drm_buffer_object *bo,
2007+ struct drm_bo_info_rep *rep)
2008+{
2009+ if (!rep)
2010+ return;
2011+
2012+ rep->handle = bo->base.hash.key;
2013+ rep->flags = bo->mem.flags;
2014+ rep->size = bo->num_pages * PAGE_SIZE;
2015+ rep->offset = bo->offset;
2016+
2017+ if (bo->type == drm_bo_type_dc)
2018+ rep->arg_handle = bo->map_list.user_token;
2019+ else
2020+ rep->arg_handle = 0;
2021+
2022+ rep->mask = bo->mem.mask;
2023+ rep->buffer_start = bo->buffer_start;
2024+ rep->fence_flags = bo->fence_type;
2025+ rep->rep_flags = 0;
2026+ rep->page_alignment = bo->mem.page_alignment;
2027+
2028+ if ((bo->priv_flags & _DRM_BO_FLAG_UNFENCED) || drm_bo_quick_busy(bo)) {
2029+ DRM_FLAG_MASKED(rep->rep_flags, DRM_BO_REP_BUSY,
2030+ DRM_BO_REP_BUSY);
2031+ }
2032+}
2033+EXPORT_SYMBOL(drm_bo_fill_rep_arg);
2034+
2035+/*
2036+ * Wait for buffer idle and register that we've mapped the buffer.
2037+ * Mapping is registered as a drm_ref_object with type _DRM_REF_TYPE1,
2038+ * so that if the client dies, the mapping is automatically
2039+ * unregistered.
2040+ */
2041+
2042+static int drm_buffer_object_map(struct drm_file *file_priv, uint32_t handle,
2043+ uint32_t map_flags, unsigned hint,
2044+ struct drm_bo_info_rep *rep)
2045+{
2046+ struct drm_buffer_object *bo;
2047+ struct drm_device *dev = file_priv->minor->dev;
2048+ int ret = 0;
2049+ int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
2050+
2051+ mutex_lock(&dev->struct_mutex);
2052+ bo = drm_lookup_buffer_object(file_priv, handle, 1);
2053+ mutex_unlock(&dev->struct_mutex);
2054+
2055+ if (!bo)
2056+ return -EINVAL;
2057+
2058+ mutex_lock(&bo->mutex);
2059+ ret = drm_bo_wait_unfenced(bo, no_wait, 0);
2060+ if (ret)
2061+ goto out;
2062+
2063+ /*
2064+ * If this returns true, we are currently unmapped.
2065+ * We need to do this test, because unmapping can
2066+ * be done without the bo->mutex held.
2067+ */
2068+
2069+ while (1) {
2070+ if (atomic_inc_and_test(&bo->mapped)) {
2071+ if (no_wait && drm_bo_busy(bo)) {
2072+ atomic_dec(&bo->mapped);
2073+ ret = -EBUSY;
2074+ goto out;
2075+ }
2076+ ret = drm_bo_wait(bo, 0, 0, no_wait);
2077+ if (ret) {
2078+ atomic_dec(&bo->mapped);
2079+ goto out;
2080+ }
2081+
2082+ if (bo->mem.flags & DRM_BO_FLAG_CACHED_MAPPED)
2083+ drm_bo_evict_cached(bo);
2084+
2085+ break;
2086+ } else if (bo->mem.flags & DRM_BO_FLAG_CACHED_MAPPED) {
2087+
2088+ /*
2089+ * We are already mapped with different flags.
2090+ * need to wait for unmap.
2091+ */
2092+
2093+ ret = drm_bo_wait_unmapped(bo, no_wait);
2094+ if (ret)
2095+ goto out;
2096+
2097+ continue;
2098+ }
2099+ break;
2100+ }
2101+
2102+ mutex_lock(&dev->struct_mutex);
2103+ ret = drm_add_ref_object(file_priv, &bo->base, _DRM_REF_TYPE1);
2104+ mutex_unlock(&dev->struct_mutex);
2105+ if (ret) {
2106+ if (atomic_add_negative(-1, &bo->mapped))
2107+ wake_up_all(&bo->event_queue);
2108+
2109+ } else
2110+ drm_bo_fill_rep_arg(bo, rep);
2111+out:
2112+ mutex_unlock(&bo->mutex);
2113+ drm_bo_usage_deref_unlocked(&bo);
2114+ return ret;
2115+}
2116+
2117+static int drm_buffer_object_unmap(struct drm_file *file_priv, uint32_t handle)
2118+{
2119+ struct drm_device *dev = file_priv->minor->dev;
2120+ struct drm_buffer_object *bo;
2121+ struct drm_ref_object *ro;
2122+ int ret = 0;
2123+
2124+ mutex_lock(&dev->struct_mutex);
2125+
2126+ bo = drm_lookup_buffer_object(file_priv, handle, 1);
2127+ if (!bo) {
2128+ ret = -EINVAL;
2129+ goto out;
2130+ }
2131+
2132+ ro = drm_lookup_ref_object(file_priv, &bo->base, _DRM_REF_TYPE1);
2133+ if (!ro) {
2134+ ret = -EINVAL;
2135+ goto out;
2136+ }
2137+
2138+ drm_remove_ref_object(file_priv, ro);
2139+ drm_bo_usage_deref_locked(&bo);
2140+out:
2141+ mutex_unlock(&dev->struct_mutex);
2142+ return ret;
2143+}
2144+
2145+/*
2146+ * Call struct-sem locked.
2147+ */
2148+
2149+static void drm_buffer_user_object_unmap(struct drm_file *file_priv,
2150+ struct drm_user_object *uo,
2151+ enum drm_ref_type action)
2152+{
2153+ struct drm_buffer_object *bo =
2154+ drm_user_object_entry(uo, struct drm_buffer_object, base);
2155+
2156+ /*
2157+ * We DON'T want to take the bo->lock here, because we want to
2158+ * hold it when we wait for unmapped buffer.
2159+ */
2160+
2161+ BUG_ON(action != _DRM_REF_TYPE1);
2162+
2163+ if (atomic_add_negative(-1, &bo->mapped))
2164+ wake_up_all(&bo->event_queue);
2165+}
2166+
2167+/*
2168+ * bo->mutex locked.
2169+ * Note that new_mem_flags are NOT transferred to the bo->mem.mask.
2170+ */
2171+
2172+int drm_bo_move_buffer(struct drm_buffer_object *bo, uint64_t new_mem_flags,
2173+ int no_wait, int move_unfenced)
2174+{
2175+ struct drm_device *dev = bo->dev;
2176+ struct drm_buffer_manager *bm = &dev->bm;
2177+ int ret = 0;
2178+ struct drm_bo_mem_reg mem;
2179+ /*
2180+ * Flush outstanding fences.
2181+ */
2182+
2183+ drm_bo_busy(bo);
2184+
2185+ /*
2186+ * Wait for outstanding fences.
2187+ */
2188+
2189+ ret = drm_bo_wait(bo, 0, 0, no_wait);
2190+ if (ret)
2191+ return ret;
2192+
2193+ mem.num_pages = bo->num_pages;
2194+ mem.size = mem.num_pages << PAGE_SHIFT;
2195+ mem.mask = new_mem_flags;
2196+ mem.page_alignment = bo->mem.page_alignment;
2197+
2198+ mutex_lock(&bm->evict_mutex);
2199+ mutex_lock(&dev->struct_mutex);
2200+ list_del_init(&bo->lru);
2201+ mutex_unlock(&dev->struct_mutex);
2202+
2203+ /*
2204+ * Determine where to move the buffer.
2205+ */
2206+ ret = drm_bo_mem_space(bo, &mem, no_wait);
2207+ if (ret)
2208+ goto out_unlock;
2209+
2210+ ret = drm_bo_handle_move_mem(bo, &mem, 0, no_wait);
2211+
2212+out_unlock:
2213+ mutex_lock(&dev->struct_mutex);
2214+ if (ret || !move_unfenced) {
2215+ if (mem.mm_node) {
2216+ if (mem.mm_node != bo->pinned_node)
2217+ drm_mm_put_block(mem.mm_node);
2218+ mem.mm_node = NULL;
2219+ }
2220+ drm_bo_add_to_lru(bo);
2221+ if (bo->priv_flags & _DRM_BO_FLAG_UNFENCED) {
2222+ wake_up_all(&bo->event_queue);
2223+ DRM_FLAG_MASKED(bo->priv_flags, 0,
2224+ _DRM_BO_FLAG_UNFENCED);
2225+ }
2226+ } else {
2227+ list_add_tail(&bo->lru, &bm->unfenced);
2228+ DRM_FLAG_MASKED(bo->priv_flags, _DRM_BO_FLAG_UNFENCED,
2229+ _DRM_BO_FLAG_UNFENCED);
2230+ }
2231+ mutex_unlock(&dev->struct_mutex);
2232+ mutex_unlock(&bm->evict_mutex);
2233+ return ret;
2234+}
2235+
2236+static int drm_bo_mem_compat(struct drm_bo_mem_reg *mem)
2237+{
2238+ uint32_t flag_diff = (mem->mask ^ mem->flags);
2239+
2240+ if ((mem->mask & mem->flags & DRM_BO_MASK_MEM) == 0)
2241+ return 0;
2242+ if ((flag_diff & DRM_BO_FLAG_CACHED) &&
2243+ (/* !(mem->mask & DRM_BO_FLAG_CACHED) ||*/
2244+ (mem->mask & DRM_BO_FLAG_FORCE_CACHING)))
2245+ return 0;
2246+
2247+ if ((flag_diff & DRM_BO_FLAG_MAPPABLE) &&
2248+ ((mem->mask & DRM_BO_FLAG_MAPPABLE) ||
2249+ (mem->mask & DRM_BO_FLAG_FORCE_MAPPABLE)))
2250+ return 0;
2251+ return 1;
2252+}
2253+
2254+/*
2255+ * bo locked.
2256+ */
2257+
2258+static int drm_buffer_object_validate(struct drm_buffer_object *bo,
2259+ uint32_t fence_class,
2260+ int move_unfenced, int no_wait)
2261+{
2262+ struct drm_device *dev = bo->dev;
2263+ struct drm_buffer_manager *bm = &dev->bm;
2264+ struct drm_bo_driver *driver = dev->driver->bo_driver;
2265+ uint32_t ftype;
2266+ int ret;
2267+
2268+ DRM_DEBUG("New flags 0x%016llx, Old flags 0x%016llx\n",
2269+ (unsigned long long) bo->mem.mask,
2270+ (unsigned long long) bo->mem.flags);
2271+
2272+ ret = driver->fence_type(bo, &fence_class, &ftype);
2273+
2274+ if (ret) {
2275+ DRM_ERROR("Driver did not support given buffer permissions\n");
2276+ return ret;
2277+ }
2278+
2279+ /*
2280+ * We're switching command submission mechanism,
2281+ * or cannot simply rely on the hardware serializing for us.
2282+ *
2283+ * Insert a driver-dependant barrier or wait for buffer idle.
2284+ */
2285+
2286+ if ((fence_class != bo->fence_class) ||
2287+ ((ftype ^ bo->fence_type) & bo->fence_type)) {
2288+
2289+ ret = -EINVAL;
2290+ if (driver->command_stream_barrier) {
2291+ ret = driver->command_stream_barrier(bo,
2292+ fence_class,
2293+ ftype,
2294+ no_wait);
2295+ }
2296+ if (ret)
2297+ ret = drm_bo_wait(bo, 0, 0, no_wait);
2298+
2299+ if (ret)
2300+ return ret;
2301+
2302+ }
2303+
2304+ bo->new_fence_class = fence_class;
2305+ bo->new_fence_type = ftype;
2306+
2307+ ret = drm_bo_wait_unmapped(bo, no_wait);
2308+ if (ret) {
2309+ DRM_ERROR("Timed out waiting for buffer unmap.\n");
2310+ return ret;
2311+ }
2312+
2313+ /*
2314+ * Check whether we need to move buffer.
2315+ */
2316+
2317+ if (!drm_bo_mem_compat(&bo->mem)) {
2318+ ret = drm_bo_move_buffer(bo, bo->mem.mask, no_wait,
2319+ move_unfenced);
2320+ if (ret) {
2321+ if (ret != -EAGAIN)
2322+ DRM_ERROR("Failed moving buffer.\n");
2323+ if (ret == -ENOMEM)
2324+ DRM_ERROR("Out of aperture space.\n");
2325+ return ret;
2326+ }
2327+ }
2328+
2329+ /*
2330+ * Pinned buffers.
2331+ */
2332+
2333+ if (bo->mem.mask & (DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE)) {
2334+ bo->pinned_mem_type = bo->mem.mem_type;
2335+ mutex_lock(&dev->struct_mutex);
2336+ list_del_init(&bo->pinned_lru);
2337+ drm_bo_add_to_pinned_lru(bo);
2338+
2339+ if (bo->pinned_node != bo->mem.mm_node) {
2340+ if (bo->pinned_node != NULL)
2341+ drm_mm_put_block(bo->pinned_node);
2342+ bo->pinned_node = bo->mem.mm_node;
2343+ }
2344+
2345+ mutex_unlock(&dev->struct_mutex);
2346+
2347+ } else if (bo->pinned_node != NULL) {
2348+
2349+ mutex_lock(&dev->struct_mutex);
2350+
2351+ if (bo->pinned_node != bo->mem.mm_node)
2352+ drm_mm_put_block(bo->pinned_node);
2353+
2354+ list_del_init(&bo->pinned_lru);
2355+ bo->pinned_node = NULL;
2356+ mutex_unlock(&dev->struct_mutex);
2357+
2358+ }
2359+
2360+ /*
2361+ * We might need to add a TTM.
2362+ */
2363+
2364+ if (bo->mem.mem_type == DRM_BO_MEM_LOCAL && bo->ttm == NULL) {
2365+ ret = drm_bo_add_ttm(bo);
2366+ if (ret)
2367+ return ret;
2368+ }
2369+ DRM_FLAG_MASKED(bo->mem.flags, bo->mem.mask, ~DRM_BO_MASK_MEMTYPE);
2370+
2371+ /*
2372+ * Finally, adjust lru to be sure.
2373+ */
2374+
2375+ mutex_lock(&dev->struct_mutex);
2376+ list_del(&bo->lru);
2377+ if (move_unfenced) {
2378+ list_add_tail(&bo->lru, &bm->unfenced);
2379+ DRM_FLAG_MASKED(bo->priv_flags, _DRM_BO_FLAG_UNFENCED,
2380+ _DRM_BO_FLAG_UNFENCED);
2381+ } else {
2382+ drm_bo_add_to_lru(bo);
2383+ if (bo->priv_flags & _DRM_BO_FLAG_UNFENCED) {
2384+ wake_up_all(&bo->event_queue);
2385+ DRM_FLAG_MASKED(bo->priv_flags, 0,
2386+ _DRM_BO_FLAG_UNFENCED);
2387+ }
2388+ }
2389+ mutex_unlock(&dev->struct_mutex);
2390+
2391+ return 0;
2392+}
2393+
2394+int drm_bo_do_validate(struct drm_buffer_object *bo,
2395+ uint64_t flags, uint64_t mask, uint32_t hint,
2396+ uint32_t fence_class,
2397+ int no_wait,
2398+ struct drm_bo_info_rep *rep)
2399+{
2400+ int ret;
2401+
2402+ mutex_lock(&bo->mutex);
2403+ ret = drm_bo_wait_unfenced(bo, no_wait, 0);
2404+
2405+ if (ret)
2406+ goto out;
2407+
2408+ DRM_FLAG_MASKED(flags, bo->mem.mask, ~mask);
2409+ ret = drm_bo_new_mask(bo, flags, mask);
2410+ if (ret)
2411+ goto out;
2412+
2413+ ret = drm_buffer_object_validate(bo,
2414+ fence_class,
2415+ !(hint & DRM_BO_HINT_DONT_FENCE),
2416+ no_wait);
2417+out:
2418+ if (rep)
2419+ drm_bo_fill_rep_arg(bo, rep);
2420+
2421+ mutex_unlock(&bo->mutex);
2422+ return ret;
2423+}
2424+EXPORT_SYMBOL(drm_bo_do_validate);
2425+
2426+
2427+int drm_bo_handle_validate(struct drm_file *file_priv, uint32_t handle,
2428+ uint32_t fence_class,
2429+ uint64_t flags, uint64_t mask,
2430+ uint32_t hint,
2431+ int use_old_fence_class,
2432+ struct drm_bo_info_rep *rep,
2433+ struct drm_buffer_object **bo_rep)
2434+{
2435+ struct drm_device *dev = file_priv->minor->dev;
2436+ struct drm_buffer_object *bo;
2437+ int ret;
2438+ int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
2439+
2440+ mutex_lock(&dev->struct_mutex);
2441+ bo = drm_lookup_buffer_object(file_priv, handle, 1);
2442+ mutex_unlock(&dev->struct_mutex);
2443+
2444+ if (!bo)
2445+ return -EINVAL;
2446+
2447+ if (use_old_fence_class)
2448+ fence_class = bo->fence_class;
2449+
2450+ /*
2451+ * Only allow creator to change shared buffer mask.
2452+ */
2453+
2454+ if (bo->base.owner != file_priv)
2455+ mask &= ~(DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE);
2456+
2457+
2458+ ret = drm_bo_do_validate(bo, flags, mask, hint, fence_class,
2459+ no_wait, rep);
2460+
2461+ if (!ret && bo_rep)
2462+ *bo_rep = bo;
2463+ else
2464+ drm_bo_usage_deref_unlocked(&bo);
2465+
2466+ return ret;
2467+}
2468+EXPORT_SYMBOL(drm_bo_handle_validate);
2469+
2470+static int drm_bo_handle_info(struct drm_file *file_priv, uint32_t handle,
2471+ struct drm_bo_info_rep *rep)
2472+{
2473+ struct drm_device *dev = file_priv->minor->dev;
2474+ struct drm_buffer_object *bo;
2475+
2476+ mutex_lock(&dev->struct_mutex);
2477+ bo = drm_lookup_buffer_object(file_priv, handle, 1);
2478+ mutex_unlock(&dev->struct_mutex);
2479+
2480+ if (!bo)
2481+ return -EINVAL;
2482+
2483+ mutex_lock(&bo->mutex);
2484+ if (!(bo->priv_flags & _DRM_BO_FLAG_UNFENCED))
2485+ (void)drm_bo_busy(bo);
2486+ drm_bo_fill_rep_arg(bo, rep);
2487+ mutex_unlock(&bo->mutex);
2488+ drm_bo_usage_deref_unlocked(&bo);
2489+ return 0;
2490+}
2491+
2492+static int drm_bo_handle_wait(struct drm_file *file_priv, uint32_t handle,
2493+ uint32_t hint,
2494+ struct drm_bo_info_rep *rep)
2495+{
2496+ struct drm_device *dev = file_priv->minor->dev;
2497+ struct drm_buffer_object *bo;
2498+ int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
2499+ int ret;
2500+
2501+ mutex_lock(&dev->struct_mutex);
2502+ bo = drm_lookup_buffer_object(file_priv, handle, 1);
2503+ mutex_unlock(&dev->struct_mutex);
2504+
2505+ if (!bo)
2506+ return -EINVAL;
2507+
2508+ mutex_lock(&bo->mutex);
2509+ ret = drm_bo_wait_unfenced(bo, no_wait, 0);
2510+ if (ret)
2511+ goto out;
2512+ ret = drm_bo_wait(bo, hint & DRM_BO_HINT_WAIT_LAZY, 0, no_wait);
2513+ if (ret)
2514+ goto out;
2515+
2516+ drm_bo_fill_rep_arg(bo, rep);
2517+
2518+out:
2519+ mutex_unlock(&bo->mutex);
2520+ drm_bo_usage_deref_unlocked(&bo);
2521+ return ret;
2522+}
2523+
2524+static inline size_t drm_size_align(size_t size)
2525+{
2526+ size_t tmpSize = 4;
2527+ if (size > PAGE_SIZE)
2528+ return PAGE_ALIGN(size);
2529+ while (tmpSize < size)
2530+ tmpSize <<= 1;
2531+
2532+ return (size_t) tmpSize;
2533+}
2534+
2535+static int drm_bo_reserve_size(struct drm_device *dev,
2536+ int user_bo,
2537+ unsigned long num_pages,
2538+ unsigned long *size)
2539+{
2540+ struct drm_bo_driver *driver = dev->driver->bo_driver;
2541+
2542+ *size = drm_size_align(sizeof(struct drm_buffer_object)) +
2543+ /* Always account for a TTM, even for fixed memory types */
2544+ drm_ttm_size(dev, num_pages, user_bo) +
2545+ /* user space mapping structure */
2546+ drm_size_align(sizeof(drm_local_map_t)) +
2547+ /* file offset space, aperture space, pinned space */
2548+ 3*drm_size_align(sizeof(struct drm_mm_node *)) +
2549+ /* ttm backend */
2550+ driver->backend_size(dev, num_pages);
2551+
2552+ // FIXME - ENOMEM?
2553+ return 0;
2554+}
2555+
2556+int drm_buffer_object_create(struct drm_device *dev,
2557+ unsigned long size,
2558+ enum drm_bo_type type,
2559+ uint64_t mask,
2560+ uint32_t hint,
2561+ uint32_t page_alignment,
2562+ unsigned long buffer_start,
2563+ struct drm_buffer_object **buf_obj)
2564+{
2565+ struct drm_buffer_manager *bm = &dev->bm;
2566+ struct drm_buffer_object *bo;
2567+ int ret = 0;
2568+ unsigned long num_pages;
2569+ unsigned long reserved_size;
2570+
2571+ size += buffer_start & ~PAGE_MASK;
2572+ num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
2573+ if (num_pages == 0) {
2574+ DRM_ERROR("Illegal buffer object size.\n");
2575+ return -EINVAL;
2576+ }
2577+
2578+ ret = drm_bo_reserve_size(dev, type == drm_bo_type_user,
2579+ num_pages, &reserved_size);
2580+
2581+ if (ret) {
2582+ DRM_DEBUG("Failed reserving space for buffer object.\n");
2583+ return ret;
2584+ }
2585+
2586+ bo = drm_calloc(1, sizeof(*bo), DRM_MEM_BUFOBJ);
2587+
2588+ if (!bo) {
2589+ drm_bo_unreserve_size(num_pages);
2590+ return -ENOMEM;
2591+ }
2592+
2593+ mutex_init(&bo->mutex);
2594+ mutex_lock(&bo->mutex);
2595+
2596+ bo->reserved_size = reserved_size;
2597+ atomic_set(&bo->usage, 1);
2598+ atomic_set(&bo->mapped, -1);
2599+ DRM_INIT_WAITQUEUE(&bo->event_queue);
2600+ INIT_LIST_HEAD(&bo->lru);
2601+ INIT_LIST_HEAD(&bo->pinned_lru);
2602+ INIT_LIST_HEAD(&bo->ddestroy);
2603+#ifdef DRM_ODD_MM_COMPAT
2604+ INIT_LIST_HEAD(&bo->p_mm_list);
2605+ INIT_LIST_HEAD(&bo->vma_list);
2606+#endif
2607+ bo->dev = dev;
2608+ bo->type = type;
2609+ bo->num_pages = num_pages;
2610+ bo->mem.mem_type = DRM_BO_MEM_LOCAL;
2611+ bo->mem.num_pages = bo->num_pages;
2612+ bo->mem.mm_node = NULL;
2613+ bo->mem.page_alignment = page_alignment;
2614+ bo->buffer_start = buffer_start & PAGE_MASK;
2615+ bo->priv_flags = 0;
2616+ bo->mem.flags = DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED |
2617+ DRM_BO_FLAG_MAPPABLE;
2618+ bo->mem.mask = DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED |
2619+ DRM_BO_FLAG_MAPPABLE;
2620+ atomic_inc(&bm->count);
2621+ ret = drm_bo_new_mask(bo, mask, mask);
2622+ if (ret)
2623+ goto out_err;
2624+
2625+ if (bo->type == drm_bo_type_dc) {
2626+ mutex_lock(&dev->struct_mutex);
2627+ ret = drm_bo_setup_vm_locked(bo);
2628+ mutex_unlock(&dev->struct_mutex);
2629+ if (ret)
2630+ goto out_err;
2631+ }
2632+
2633+ ret = drm_buffer_object_validate(bo, 0, 0, hint & DRM_BO_HINT_DONT_BLOCK);
2634+ if (ret)
2635+ goto out_err;
2636+
2637+ mutex_unlock(&bo->mutex);
2638+ *buf_obj = bo;
2639+ return 0;
2640+
2641+out_err:
2642+ mutex_unlock(&bo->mutex);
2643+
2644+ drm_bo_usage_deref_unlocked(&bo);
2645+ return ret;
2646+}
2647+EXPORT_SYMBOL(drm_buffer_object_create);
2648+
2649+
2650+static int drm_bo_add_user_object(struct drm_file *file_priv,
2651+ struct drm_buffer_object *bo, int shareable)
2652+{
2653+ struct drm_device *dev = file_priv->minor->dev;
2654+ int ret;
2655+
2656+ mutex_lock(&dev->struct_mutex);
2657+ ret = drm_add_user_object(file_priv, &bo->base, shareable);
2658+ if (ret)
2659+ goto out;
2660+
2661+ bo->base.remove = drm_bo_base_deref_locked;
2662+ bo->base.type = drm_buffer_type;
2663+ bo->base.ref_struct_locked = NULL;
2664+ bo->base.unref = drm_buffer_user_object_unmap;
2665+
2666+out:
2667+ mutex_unlock(&dev->struct_mutex);
2668+ return ret;
2669+}
2670+
2671+int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
2672+{
2673+ struct drm_bo_create_arg *arg = data;
2674+ struct drm_bo_create_req *req = &arg->d.req;
2675+ struct drm_bo_info_rep *rep = &arg->d.rep;
2676+ struct drm_buffer_object *entry;
2677+ enum drm_bo_type bo_type;
2678+ int ret = 0;
2679+
2680+ DRM_DEBUG("drm_bo_create_ioctl: %dkb, %dkb align\n",
2681+ (int)(req->size / 1024), req->page_alignment * 4);
2682+
2683+ if (!dev->bm.initialized) {
2684+ DRM_ERROR("Buffer object manager is not initialized.\n");
2685+ return -EINVAL;
2686+ }
2687+
2688+ bo_type = (req->buffer_start) ? drm_bo_type_user : drm_bo_type_dc;
2689+
2690+ if (bo_type == drm_bo_type_user)
2691+ req->mask &= ~DRM_BO_FLAG_SHAREABLE;
2692+
2693+ ret = drm_buffer_object_create(file_priv->minor->dev,
2694+ req->size, bo_type, req->mask,
2695+ req->hint, req->page_alignment,
2696+ req->buffer_start, &entry);
2697+ if (ret)
2698+ goto out;
2699+
2700+ ret = drm_bo_add_user_object(file_priv, entry,
2701+ req->mask & DRM_BO_FLAG_SHAREABLE);
2702+ if (ret) {
2703+ drm_bo_usage_deref_unlocked(&entry);
2704+ goto out;
2705+ }
2706+
2707+ mutex_lock(&entry->mutex);
2708+ drm_bo_fill_rep_arg(entry, rep);
2709+ mutex_unlock(&entry->mutex);
2710+
2711+out:
2712+ return ret;
2713+}
2714+
2715+int drm_bo_setstatus_ioctl(struct drm_device *dev,
2716+ void *data, struct drm_file *file_priv)
2717+{
2718+ struct drm_bo_map_wait_idle_arg *arg = data;
2719+ struct drm_bo_info_req *req = &arg->d.req;
2720+ struct drm_bo_info_rep *rep = &arg->d.rep;
2721+ int ret;
2722+
2723+ if (!dev->bm.initialized) {
2724+ DRM_ERROR("Buffer object manager is not initialized.\n");
2725+ return -EINVAL;
2726+ }
2727+
2728+ ret = drm_bo_read_lock(&dev->bm.bm_lock);
2729+ if (ret)
2730+ return ret;
2731+
2732+ ret = drm_bo_handle_validate(file_priv, req->handle, req->fence_class,
2733+ req->flags,
2734+ req->mask,
2735+ req->hint | DRM_BO_HINT_DONT_FENCE,
2736+ 1,
2737+ rep, NULL);
2738+
2739+ (void) drm_bo_read_unlock(&dev->bm.bm_lock);
2740+ if (ret)
2741+ return ret;
2742+
2743+ return 0;
2744+}
2745+
2746+int drm_bo_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
2747+{
2748+ struct drm_bo_map_wait_idle_arg *arg = data;
2749+ struct drm_bo_info_req *req = &arg->d.req;
2750+ struct drm_bo_info_rep *rep = &arg->d.rep;
2751+ int ret;
2752+ if (!dev->bm.initialized) {
2753+ DRM_ERROR("Buffer object manager is not initialized.\n");
2754+ return -EINVAL;
2755+ }
2756+
2757+ ret = drm_buffer_object_map(file_priv, req->handle, req->mask,
2758+ req->hint, rep);
2759+ if (ret)
2760+ return ret;
2761+
2762+ return 0;
2763+}
2764+
2765+int drm_bo_unmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
2766+{
2767+ struct drm_bo_handle_arg *arg = data;
2768+ int ret;
2769+ if (!dev->bm.initialized) {
2770+ DRM_ERROR("Buffer object manager is not initialized.\n");
2771+ return -EINVAL;
2772+ }
2773+
2774+ ret = drm_buffer_object_unmap(file_priv, arg->handle);
2775+ return ret;
2776+}
2777+
2778+
2779+int drm_bo_reference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
2780+{
2781+ struct drm_bo_reference_info_arg *arg = data;
2782+ struct drm_bo_handle_arg *req = &arg->d.req;
2783+ struct drm_bo_info_rep *rep = &arg->d.rep;
2784+ struct drm_user_object *uo;
2785+ int ret;
2786+
2787+ if (!dev->bm.initialized) {
2788+ DRM_ERROR("Buffer object manager is not initialized.\n");
2789+ return -EINVAL;
2790+ }
2791+
2792+ ret = drm_user_object_ref(file_priv, req->handle,
2793+ drm_buffer_type, &uo);
2794+ if (ret)
2795+ return ret;
2796+
2797+ ret = drm_bo_handle_info(file_priv, req->handle, rep);
2798+ if (ret)
2799+ return ret;
2800+
2801+ return 0;
2802+}
2803+
2804+int drm_bo_unreference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
2805+{
2806+ struct drm_bo_handle_arg *arg = data;
2807+ int ret = 0;
2808+
2809+ if (!dev->bm.initialized) {
2810+ DRM_ERROR("Buffer object manager is not initialized.\n");
2811+ return -EINVAL;
2812+ }
2813+
2814+ ret = drm_user_object_unref(file_priv, arg->handle, drm_buffer_type);
2815+ return ret;
2816+}
2817+
2818+int drm_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
2819+{
2820+ struct drm_bo_reference_info_arg *arg = data;
2821+ struct drm_bo_handle_arg *req = &arg->d.req;
2822+ struct drm_bo_info_rep *rep = &arg->d.rep;
2823+ int ret;
2824+
2825+ if (!dev->bm.initialized) {
2826+ DRM_ERROR("Buffer object manager is not initialized.\n");
2827+ return -EINVAL;
2828+ }
2829+
2830+ ret = drm_bo_handle_info(file_priv, req->handle, rep);
2831+ if (ret)
2832+ return ret;
2833+
2834+ return 0;
2835+}
2836+
2837+int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
2838+{
2839+ struct drm_bo_map_wait_idle_arg *arg = data;
2840+ struct drm_bo_info_req *req = &arg->d.req;
2841+ struct drm_bo_info_rep *rep = &arg->d.rep;
2842+ int ret;
2843+ if (!dev->bm.initialized) {
2844+ DRM_ERROR("Buffer object manager is not initialized.\n");
2845+ return -EINVAL;
2846+ }
2847+
2848+ ret = drm_bo_handle_wait(file_priv, req->handle,
2849+ req->hint, rep);
2850+ if (ret)
2851+ return ret;
2852+
2853+ return 0;
2854+}
2855+
2856+static int drm_bo_leave_list(struct drm_buffer_object *bo,
2857+ uint32_t mem_type,
2858+ int free_pinned,
2859+ int allow_errors)
2860+{
2861+ struct drm_device *dev = bo->dev;
2862+ int ret = 0;
2863+
2864+ mutex_lock(&bo->mutex);
2865+
2866+ ret = drm_bo_expire_fence(bo, allow_errors);
2867+ if (ret)
2868+ goto out;
2869+
2870+ if (free_pinned) {
2871+ DRM_FLAG_MASKED(bo->mem.flags, 0, DRM_BO_FLAG_NO_MOVE);
2872+ mutex_lock(&dev->struct_mutex);
2873+ list_del_init(&bo->pinned_lru);
2874+ if (bo->pinned_node == bo->mem.mm_node)
2875+ bo->pinned_node = NULL;
2876+ if (bo->pinned_node != NULL) {
2877+ drm_mm_put_block(bo->pinned_node);
2878+ bo->pinned_node = NULL;
2879+ }
2880+ mutex_unlock(&dev->struct_mutex);
2881+ }
2882+
2883+ if (bo->mem.flags & DRM_BO_FLAG_NO_EVICT) {
2884+ DRM_ERROR("A DRM_BO_NO_EVICT buffer present at "
2885+ "cleanup. Removing flag and evicting.\n");
2886+ bo->mem.flags &= ~DRM_BO_FLAG_NO_EVICT;
2887+ bo->mem.mask &= ~DRM_BO_FLAG_NO_EVICT;
2888+ }
2889+
2890+ if (bo->mem.mem_type == mem_type)
2891+ ret = drm_bo_evict(bo, mem_type, 0);
2892+
2893+ if (ret) {
2894+ if (allow_errors) {
2895+ goto out;
2896+ } else {
2897+ ret = 0;
2898+ DRM_ERROR("Cleanup eviction failed\n");
2899+ }
2900+ }
2901+
2902+out:
2903+ mutex_unlock(&bo->mutex);
2904+ return ret;
2905+}
2906+
2907+
2908+static struct drm_buffer_object *drm_bo_entry(struct list_head *list,
2909+ int pinned_list)
2910+{
2911+ if (pinned_list)
2912+ return list_entry(list, struct drm_buffer_object, pinned_lru);
2913+ else
2914+ return list_entry(list, struct drm_buffer_object, lru);
2915+}
2916+
2917+/*
2918+ * dev->struct_mutex locked.
2919+ */
2920+
2921+static int drm_bo_force_list_clean(struct drm_device *dev,
2922+ struct list_head *head,
2923+ unsigned mem_type,
2924+ int free_pinned,
2925+ int allow_errors,
2926+ int pinned_list)
2927+{
2928+ struct list_head *list, *next, *prev;
2929+ struct drm_buffer_object *entry, *nentry;
2930+ int ret;
2931+ int do_restart;
2932+
2933+ /*
2934+ * The list traversal is a bit odd here, because an item may
2935+ * disappear from the list when we release the struct_mutex or
2936+ * when we decrease the usage count. Also we're not guaranteed
2937+ * to drain pinned lists, so we can't always restart.
2938+ */
2939+
2940+restart:
2941+ nentry = NULL;
2942+ list_for_each_safe(list, next, head) {
2943+ prev = list->prev;
2944+
2945+ entry = (nentry != NULL) ? nentry: drm_bo_entry(list, pinned_list);
2946+ atomic_inc(&entry->usage);
2947+ if (nentry) {
2948+ atomic_dec(&nentry->usage);
2949+ nentry = NULL;
2950+ }
2951+
2952+ /*
2953+ * Protect the next item from destruction, so we can check
2954+ * its list pointers later on.
2955+ */
2956+
2957+ if (next != head) {
2958+ nentry = drm_bo_entry(next, pinned_list);
2959+ atomic_inc(&nentry->usage);
2960+ }
2961+ mutex_unlock(&dev->struct_mutex);
2962+
2963+ ret = drm_bo_leave_list(entry, mem_type, free_pinned,
2964+ allow_errors);
2965+ mutex_lock(&dev->struct_mutex);
2966+
2967+ drm_bo_usage_deref_locked(&entry);
2968+ if (ret)
2969+ return ret;
2970+
2971+ /*
2972+ * Has the next item disappeared from the list?
2973+ */
2974+
2975+ do_restart = ((next->prev != list) && (next->prev != prev));
2976+
2977+ if (nentry != NULL && do_restart)
2978+ drm_bo_usage_deref_locked(&nentry);
2979+
2980+ if (do_restart)
2981+ goto restart;
2982+ }
2983+ return 0;
2984+}
2985+
2986+int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type)
2987+{
2988+ struct drm_buffer_manager *bm = &dev->bm;
2989+ struct drm_mem_type_manager *man = &bm->man[mem_type];
2990+ int ret = -EINVAL;
2991+
2992+ if (mem_type >= DRM_BO_MEM_TYPES) {
2993+ DRM_ERROR("Illegal memory type %d\n", mem_type);
2994+ return ret;
2995+ }
2996+
2997+ if (!man->has_type) {
2998+ DRM_ERROR("Trying to take down uninitialized "
2999+ "memory manager type %u\n", mem_type);
3000+ return ret;
3001+ }
3002+ man->use_type = 0;
3003+ man->has_type = 0;
3004+
3005+ ret = 0;
3006+ if (mem_type > 0) {
3007+ BUG_ON(!list_empty(&bm->unfenced));
3008+ drm_bo_force_list_clean(dev, &man->lru, mem_type, 1, 0, 0);
3009+ drm_bo_force_list_clean(dev, &man->pinned, mem_type, 1, 0, 1);
3010+
3011+ if (drm_mm_clean(&man->manager)) {
3012+ drm_mm_takedown(&man->manager);
3013+ } else {
3014+ ret = -EBUSY;
3015+ }
3016+ }
3017+
3018+ return ret;
3019+}
3020+EXPORT_SYMBOL(drm_bo_clean_mm);
3021+
3022+/**
3023+ *Evict all buffers of a particular mem_type, but leave memory manager
3024+ *regions for NO_MOVE buffers intact. New buffers cannot be added at this
3025+ *point since we have the hardware lock.
3026+ */
3027+
3028+static int drm_bo_lock_mm(struct drm_device *dev, unsigned mem_type)
3029+{
3030+ int ret;
3031+ struct drm_buffer_manager *bm = &dev->bm;
3032+ struct drm_mem_type_manager *man = &bm->man[mem_type];
3033+
3034+ if (mem_type == 0 || mem_type >= DRM_BO_MEM_TYPES) {
3035+ DRM_ERROR("Illegal memory manager memory type %u.\n", mem_type);
3036+ return -EINVAL;
3037+ }
3038+
3039+ if (!man->has_type) {
3040+ DRM_ERROR("Memory type %u has not been initialized.\n",
3041+ mem_type);
3042+ return 0;
3043+ }
3044+
3045+ ret = drm_bo_force_list_clean(dev, &man->lru, mem_type, 0, 1, 0);
3046+ if (ret)
3047+ return ret;
3048+ ret = drm_bo_force_list_clean(dev, &man->pinned, mem_type, 0, 1, 1);
3049+
3050+ return ret;
3051+}
3052+
3053+int drm_bo_init_mm(struct drm_device *dev,
3054+ unsigned type,
3055+ unsigned long p_offset, unsigned long p_size)
3056+{
3057+ struct drm_buffer_manager *bm = &dev->bm;
3058+ int ret = -EINVAL;
3059+ struct drm_mem_type_manager *man;
3060+
3061+ if (type >= DRM_BO_MEM_TYPES) {
3062+ DRM_ERROR("Illegal memory type %d\n", type);
3063+ return ret;
3064+ }
3065+
3066+ man = &bm->man[type];
3067+ if (man->has_type) {
3068+ DRM_ERROR("Memory manager already initialized for type %d\n",
3069+ type);
3070+ return ret;
3071+ }
3072+
3073+ ret = dev->driver->bo_driver->init_mem_type(dev, type, man);
3074+ if (ret)
3075+ return ret;
3076+
3077+ ret = 0;
3078+ if (type != DRM_BO_MEM_LOCAL) {
3079+ if (!p_size) {
3080+ DRM_ERROR("Zero size memory manager type %d\n", type);
3081+ return ret;
3082+ }
3083+ ret = drm_mm_init(&man->manager, p_offset, p_size);
3084+ if (ret)
3085+ return ret;
3086+ }
3087+ man->has_type = 1;
3088+ man->use_type = 1;
3089+
3090+ INIT_LIST_HEAD(&man->lru);
3091+ INIT_LIST_HEAD(&man->pinned);
3092+
3093+ return 0;
3094+}
3095+EXPORT_SYMBOL(drm_bo_init_mm);
3096+
3097+/*
3098+ * This function is intended to be called on drm driver unload.
3099+ * If you decide to call it from lastclose, you must protect the call
3100+ * from a potentially racing drm_bo_driver_init in firstopen.
3101+ * (This may happen on X server restart).
3102+ */
3103+
3104+int drm_bo_driver_finish(struct drm_device *dev)
3105+{
3106+ struct drm_buffer_manager *bm = &dev->bm;
3107+ int ret = 0;
3108+ unsigned i = DRM_BO_MEM_TYPES;
3109+ struct drm_mem_type_manager *man;
3110+
3111+ mutex_lock(&dev->struct_mutex);
3112+
3113+ if (!bm->initialized)
3114+ goto out;
3115+ bm->initialized = 0;
3116+
3117+ while (i--) {
3118+ man = &bm->man[i];
3119+ if (man->has_type) {
3120+ man->use_type = 0;
3121+ if ((i != DRM_BO_MEM_LOCAL) && drm_bo_clean_mm(dev, i)) {
3122+ ret = -EBUSY;
3123+ DRM_ERROR("DRM memory manager type %d "
3124+ "is not clean.\n", i);
3125+ }
3126+ man->has_type = 0;
3127+ }
3128+ }
3129+ mutex_unlock(&dev->struct_mutex);
3130+
3131+ if (!cancel_delayed_work(&bm->wq))
3132+ flush_scheduled_work();
3133+
3134+ mutex_lock(&dev->struct_mutex);
3135+ drm_bo_delayed_delete(dev, 1);
3136+ if (list_empty(&bm->ddestroy))
3137+ DRM_DEBUG("Delayed destroy list was clean\n");
3138+
3139+ if (list_empty(&bm->man[0].lru))
3140+ DRM_DEBUG("Swap list was clean\n");
3141+
3142+ if (list_empty(&bm->man[0].pinned))
3143+ DRM_DEBUG("NO_MOVE list was clean\n");
3144+
3145+ if (list_empty(&bm->unfenced))
3146+ DRM_DEBUG("Unfenced list was clean\n");
3147+
3148+ __free_page(bm->dummy_read_page);
3149+
3150+out:
3151+ mutex_unlock(&dev->struct_mutex);
3152+ return ret;
3153+}
3154+EXPORT_SYMBOL(drm_bo_driver_finish);
3155+
3156+/*
3157+ * This function is intended to be called on drm driver load.
3158+ * If you decide to call it from firstopen, you must protect the call
3159+ * from a potentially racing drm_bo_driver_finish in lastclose.
3160+ * (This may happen on X server restart).
3161+ */
3162+
3163+int drm_bo_driver_init(struct drm_device *dev)
3164+{
3165+ struct drm_bo_driver *driver = dev->driver->bo_driver;
3166+ struct drm_buffer_manager *bm = &dev->bm;
3167+ int ret = -EINVAL;
3168+
3169+ bm->dummy_read_page = NULL;
3170+ drm_bo_init_lock(&bm->bm_lock);
3171+ mutex_lock(&dev->struct_mutex);
3172+ if (!driver)
3173+ goto out_unlock;
3174+
3175+ bm->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32);
3176+ if (!bm->dummy_read_page) {
3177+ ret = -ENOMEM;
3178+ goto out_unlock;
3179+ }
3180+
3181+
3182+ /*
3183+ * Initialize the system memory buffer type.
3184+ * Other types need to be driver / IOCTL initialized.
3185+ */
3186+ ret = drm_bo_init_mm(dev, DRM_BO_MEM_LOCAL, 0, 0);
3187+ if (ret)
3188+ goto out_unlock;
3189+
3190+ INIT_DELAYED_WORK(&bm->wq, drm_bo_delayed_workqueue);
3191+
3192+ bm->initialized = 1;
3193+ bm->nice_mode = 1;
3194+ atomic_set(&bm->count, 0);
3195+ bm->cur_pages = 0;
3196+ INIT_LIST_HEAD(&bm->unfenced);
3197+ INIT_LIST_HEAD(&bm->ddestroy);
3198+out_unlock:
3199+ mutex_unlock(&dev->struct_mutex);
3200+ return ret;
3201+}
3202+EXPORT_SYMBOL(drm_bo_driver_init);
3203+
3204+int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
3205+{
3206+ struct drm_mm_init_arg *arg = data;
3207+ struct drm_buffer_manager *bm = &dev->bm;
3208+ struct drm_bo_driver *driver = dev->driver->bo_driver;
3209+ int ret;
3210+
3211+ if (!driver) {
3212+ DRM_ERROR("Buffer objects are not supported by this driver\n");
3213+ return -EINVAL;
3214+ }
3215+
3216+ ret = drm_bo_write_lock(&bm->bm_lock, file_priv);
3217+ if (ret)
3218+ return ret;
3219+
3220+ ret = -EINVAL;
3221+ if (arg->magic != DRM_BO_INIT_MAGIC) {
3222+ DRM_ERROR("You are using an old libdrm that is not compatible with\n"
3223+ "\tthe kernel DRM module. Please upgrade your libdrm.\n");
3224+ return -EINVAL;
3225+ }
3226+ if (arg->major != DRM_BO_INIT_MAJOR) {
3227+ DRM_ERROR("libdrm and kernel DRM buffer object interface major\n"
3228+ "\tversion don't match. Got %d, expected %d.\n",
3229+ arg->major, DRM_BO_INIT_MAJOR);
3230+ return -EINVAL;
3231+ }
3232+
3233+ mutex_lock(&dev->struct_mutex);
3234+ if (!bm->initialized) {
3235+ DRM_ERROR("DRM memory manager was not initialized.\n");
3236+ goto out;
3237+ }
3238+ if (arg->mem_type == 0) {
3239+ DRM_ERROR("System memory buffers already initialized.\n");
3240+ goto out;
3241+ }
3242+ ret = drm_bo_init_mm(dev, arg->mem_type,
3243+ arg->p_offset, arg->p_size);
3244+
3245+out:
3246+ mutex_unlock(&dev->struct_mutex);
3247+ (void) drm_bo_write_unlock(&bm->bm_lock, file_priv);
3248+
3249+ if (ret)
3250+ return ret;
3251+
3252+ return 0;
3253+}
3254+
3255+int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
3256+{
3257+ struct drm_mm_type_arg *arg = data;
3258+ struct drm_buffer_manager *bm = &dev->bm;
3259+ struct drm_bo_driver *driver = dev->driver->bo_driver;
3260+ int ret;
3261+
3262+ if (!driver) {
3263+ DRM_ERROR("Buffer objects are not supported by this driver\n");
3264+ return -EINVAL;
3265+ }
3266+
3267+ ret = drm_bo_write_lock(&bm->bm_lock, file_priv);
3268+ if (ret)
3269+ return ret;
3270+
3271+ mutex_lock(&dev->struct_mutex);
3272+ ret = -EINVAL;
3273+ if (!bm->initialized) {
3274+ DRM_ERROR("DRM memory manager was not initialized\n");
3275+ goto out;
3276+ }
3277+ if (arg->mem_type == 0) {
3278+ DRM_ERROR("No takedown for System memory buffers.\n");
3279+ goto out;
3280+ }
3281+ ret = 0;
3282+ if (drm_bo_clean_mm(dev, arg->mem_type)) {
3283+ DRM_ERROR("Memory manager type %d not clean. "
3284+ "Delaying takedown\n", arg->mem_type);
3285+ }
3286+out:
3287+ mutex_unlock(&dev->struct_mutex);
3288+ (void) drm_bo_write_unlock(&bm->bm_lock, file_priv);
3289+
3290+ if (ret)
3291+ return ret;
3292+
3293+ return 0;
3294+}
3295+
3296+int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
3297+{
3298+ struct drm_mm_type_arg *arg = data;
3299+ struct drm_bo_driver *driver = dev->driver->bo_driver;
3300+ int ret;
3301+
3302+ if (!driver) {
3303+ DRM_ERROR("Buffer objects are not supported by this driver\n");
3304+ return -EINVAL;
3305+ }
3306+
3307+ if (arg->lock_flags & DRM_BO_LOCK_IGNORE_NO_EVICT) {
3308+ DRM_ERROR("Lock flag DRM_BO_LOCK_IGNORE_NO_EVICT not supported yet.\n");
3309+ return -EINVAL;
3310+ }
3311+
3312+ if (arg->lock_flags & DRM_BO_LOCK_UNLOCK_BM) {
3313+ ret = drm_bo_write_lock(&dev->bm.bm_lock, file_priv);
3314+ if (ret)
3315+ return ret;
3316+ }
3317+
3318+ mutex_lock(&dev->struct_mutex);
3319+ ret = drm_bo_lock_mm(dev, arg->mem_type);
3320+ mutex_unlock(&dev->struct_mutex);
3321+ if (ret) {
3322+ (void) drm_bo_write_unlock(&dev->bm.bm_lock, file_priv);
3323+ return ret;
3324+ }
3325+
3326+ return 0;
3327+}
3328+
3329+int drm_mm_unlock_ioctl(struct drm_device *dev,
3330+ void *data,
3331+ struct drm_file *file_priv)
3332+{
3333+ struct drm_mm_type_arg *arg = data;
3334+ struct drm_bo_driver *driver = dev->driver->bo_driver;
3335+ int ret;
3336+
3337+ if (!driver) {
3338+ DRM_ERROR("Buffer objects are not supported by this driver\n");
3339+ return -EINVAL;
3340+ }
3341+
3342+ if (arg->lock_flags & DRM_BO_LOCK_UNLOCK_BM) {
3343+ ret = drm_bo_write_unlock(&dev->bm.bm_lock, file_priv);
3344+ if (ret)
3345+ return ret;
3346+ }
3347+
3348+ return 0;
3349+}
3350+
3351+/*
3352+ * buffer object vm functions.
3353+ */
3354+
3355+int drm_mem_reg_is_pci(struct drm_device *dev, struct drm_bo_mem_reg *mem)
3356+{
3357+ struct drm_buffer_manager *bm = &dev->bm;
3358+ struct drm_mem_type_manager *man = &bm->man[mem->mem_type];
3359+
3360+ if (!(man->flags & _DRM_FLAG_MEMTYPE_FIXED)) {
3361+ if (mem->mem_type == DRM_BO_MEM_LOCAL)
3362+ return 0;
3363+
3364+ if (man->flags & _DRM_FLAG_MEMTYPE_CMA)
3365+ return 0;
3366+
3367+ if (mem->flags & DRM_BO_FLAG_CACHED)
3368+ return 0;
3369+ }
3370+ return 1;
3371+}
3372+EXPORT_SYMBOL(drm_mem_reg_is_pci);
3373+
3374+/**
3375+ * \c Get the PCI offset for the buffer object memory.
3376+ *
3377+ * \param bo The buffer object.
3378+ * \param bus_base On return the base of the PCI region
3379+ * \param bus_offset On return the byte offset into the PCI region
3380+ * \param bus_size On return the byte size of the buffer object or zero if
3381+ * the buffer object memory is not accessible through a PCI region.
3382+ * \return Failure indication.
3383+ *
3384+ * Returns -EINVAL if the buffer object is currently not mappable.
3385+ * Otherwise returns zero.
3386+ */
3387+
3388+int drm_bo_pci_offset(struct drm_device *dev,
3389+ struct drm_bo_mem_reg *mem,
3390+ unsigned long *bus_base,
3391+ unsigned long *bus_offset, unsigned long *bus_size)
3392+{
3393+ struct drm_buffer_manager *bm = &dev->bm;
3394+ struct drm_mem_type_manager *man = &bm->man[mem->mem_type];
3395+
3396+ *bus_size = 0;
3397+ if (!(man->flags & _DRM_FLAG_MEMTYPE_MAPPABLE))
3398+ return -EINVAL;
3399+
3400+ if (drm_mem_reg_is_pci(dev, mem)) {
3401+ *bus_offset = mem->mm_node->start << PAGE_SHIFT;
3402+ *bus_size = mem->num_pages << PAGE_SHIFT;
3403+ *bus_base = man->io_offset;
3404+ }
3405+
3406+ return 0;
3407+}
3408+
3409+/**
3410+ * \c Kill all user-space virtual mappings of this buffer object.
3411+ *
3412+ * \param bo The buffer object.
3413+ *
3414+ * Call bo->mutex locked.
3415+ */
3416+
3417+void drm_bo_unmap_virtual(struct drm_buffer_object *bo)
3418+{
3419+ struct drm_device *dev = bo->dev;
3420+ loff_t offset = ((loff_t) bo->map_list.hash.key) << PAGE_SHIFT;
3421+ loff_t holelen = ((loff_t) bo->mem.num_pages) << PAGE_SHIFT;
3422+
3423+ if (!dev->dev_mapping)
3424+ return;
3425+
3426+ unmap_mapping_range(dev->dev_mapping, offset, holelen, 1);
3427+}
3428+
3429+static void drm_bo_takedown_vm_locked(struct drm_buffer_object *bo)
3430+{
3431+ struct drm_map_list *list;
3432+ drm_local_map_t *map;
3433+ struct drm_device *dev = bo->dev;
3434+
3435+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
3436+ if (bo->type != drm_bo_type_dc)
3437+ return;
3438+
3439+ list = &bo->map_list;
3440+ if (list->user_token) {
3441+ drm_ht_remove_item(&dev->map_hash, &list->hash);
3442+ list->user_token = 0;
3443+ }
3444+ if (list->file_offset_node) {
3445+ drm_mm_put_block(list->file_offset_node);
3446+ list->file_offset_node = NULL;
3447+ }
3448+
3449+ map = list->map;
3450+ if (!map)
3451+ return;
3452+
3453+ drm_free(map, sizeof(*map), DRM_MEM_BUFOBJ);
3454+ list->map = NULL;
3455+ list->user_token = 0ULL;
3456+ drm_bo_usage_deref_locked(&bo);
3457+}
3458+
3459+static int drm_bo_setup_vm_locked(struct drm_buffer_object *bo)
3460+{
3461+ struct drm_map_list *list = &bo->map_list;
3462+ drm_local_map_t *map;
3463+ struct drm_device *dev = bo->dev;
3464+
3465+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
3466+ list->map = drm_calloc(1, sizeof(*map), DRM_MEM_BUFOBJ);
3467+ if (!list->map)
3468+ return -ENOMEM;
3469+
3470+ map = list->map;
3471+ map->offset = 0;
3472+ map->type = _DRM_TTM;
3473+ map->flags = _DRM_REMOVABLE;
3474+ map->size = bo->mem.num_pages * PAGE_SIZE;
3475+ atomic_inc(&bo->usage);
3476+ map->handle = (void *)bo;
3477+
3478+ list->file_offset_node = drm_mm_search_free(&dev->offset_manager,
3479+ bo->mem.num_pages, 0, 0);
3480+
3481+ if (!list->file_offset_node) {
3482+ drm_bo_takedown_vm_locked(bo);
3483+ return -ENOMEM;
3484+ }
3485+
3486+ list->file_offset_node = drm_mm_get_block(list->file_offset_node,
3487+ bo->mem.num_pages, 0);
3488+ if (!list->file_offset_node) {
3489+ drm_bo_takedown_vm_locked(bo);
3490+ return -ENOMEM;
3491+ }
3492+
3493+ list->hash.key = list->file_offset_node->start;
3494+ if (drm_ht_insert_item(&dev->map_hash, &list->hash)) {
3495+ drm_bo_takedown_vm_locked(bo);
3496+ return -ENOMEM;
3497+ }
3498+
3499+ list->user_token = ((uint64_t) list->hash.key) << PAGE_SHIFT;
3500+
3501+ return 0;
3502+}
3503+
3504+int drm_bo_version_ioctl(struct drm_device *dev, void *data,
3505+ struct drm_file *file_priv)
3506+{
3507+ struct drm_bo_version_arg *arg = (struct drm_bo_version_arg *)data;
3508+
3509+ arg->major = DRM_BO_INIT_MAJOR;
3510+ arg->minor = DRM_BO_INIT_MINOR;
3511+ arg->patchlevel = DRM_BO_INIT_PATCH;
3512+
3513+ return 0;
3514+}
3515Index: linux-2.6.28/drivers/gpu/drm/drm_bo_lock.c
3516===================================================================
3517--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3518+++ linux-2.6.28/drivers/gpu/drm/drm_bo_lock.c 2009-02-12 09:14:41.000000000 +0000
3519@@ -0,0 +1,175 @@
3520+/**************************************************************************
3521+ *
3522+ * Copyright (c) 2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
3523+ * All Rights Reserved.
3524+ *
3525+ * Permission is hereby granted, free of charge, to any person obtaining a
3526+ * copy of this software and associated documentation files (the
3527+ * "Software"), to deal in the Software without restriction, including
3528+ * without limitation the rights to use, copy, modify, merge, publish,
3529+ * distribute, sub license, and/or sell copies of the Software, and to
3530+ * permit persons to whom the Software is furnished to do so, subject to
3531+ * the following conditions:
3532+ *
3533+ * The above copyright notice and this permission notice (including the
3534+ * next paragraph) shall be included in all copies or substantial portions
3535+ * of the Software.
3536+ *
3537+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3538+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3539+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
3540+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
3541+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
3542+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
3543+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
3544+ *
3545+ **************************************************************************/
3546+/*
3547+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
3548+ */
3549+
3550+/*
3551+ * This file implements a simple replacement for the buffer manager use
3552+ * of the heavyweight hardware lock.
3553+ * The lock is a read-write lock. Taking it in read mode is fast, and
3554+ * intended for in-kernel use only.
3555+ * Taking it in write mode is slow.
3556+ *
3557+ * The write mode is used only when there is a need to block all
3558+ * user-space processes from allocating a
3559+ * new memory area.
3560+ * Typical use in write mode is X server VT switching, and it's allowed
3561+ * to leave kernel space with the write lock held. If a user-space process
3562+ * dies while having the write-lock, it will be released during the file
3563+ * descriptor release.
3564+ *
3565+ * The read lock is typically placed at the start of an IOCTL- or
3566+ * user-space callable function that may end up allocating a memory area.
3567+ * This includes setstatus, super-ioctls and no_pfn; the latter may move
3568+ * unmappable regions to mappable. It's a bug to leave kernel space with the
3569+ * read lock held.
3570+ *
3571+ * Both read- and write lock taking is interruptible for low signal-delivery
3572+ * latency. The locking functions will return -EAGAIN if interrupted by a
3573+ * signal.
3574+ *
3575+ * Locking order: The lock should be taken BEFORE any kernel mutexes
3576+ * or spinlocks.
3577+ */
3578+
3579+#include "drmP.h"
3580+
3581+void drm_bo_init_lock(struct drm_bo_lock *lock)
3582+{
3583+ DRM_INIT_WAITQUEUE(&lock->queue);
3584+ atomic_set(&lock->write_lock_pending, 0);
3585+ atomic_set(&lock->readers, 0);
3586+}
3587+
3588+void drm_bo_read_unlock(struct drm_bo_lock *lock)
3589+{
3590+ if (unlikely(atomic_add_negative(-1, &lock->readers)))
3591+ BUG();
3592+ if (atomic_read(&lock->readers) == 0)
3593+ wake_up_interruptible(&lock->queue);
3594+}
3595+EXPORT_SYMBOL(drm_bo_read_unlock);
3596+
3597+int drm_bo_read_lock(struct drm_bo_lock *lock)
3598+{
3599+ while (unlikely(atomic_read(&lock->write_lock_pending) != 0)) {
3600+ int ret;
3601+ ret = wait_event_interruptible
3602+ (lock->queue, atomic_read(&lock->write_lock_pending) == 0);
3603+ if (ret)
3604+ return -EAGAIN;
3605+ }
3606+
3607+ while (unlikely(!atomic_add_unless(&lock->readers, 1, -1))) {
3608+ int ret;
3609+ ret = wait_event_interruptible
3610+ (lock->queue, atomic_add_unless(&lock->readers, 1, -1));
3611+ if (ret)
3612+ return -EAGAIN;
3613+ }
3614+ return 0;
3615+}
3616+EXPORT_SYMBOL(drm_bo_read_lock);
3617+
3618+static int __drm_bo_write_unlock(struct drm_bo_lock *lock)
3619+{
3620+ if (unlikely(atomic_cmpxchg(&lock->readers, -1, 0) != -1))
3621+ return -EINVAL;
3622+ if (unlikely(atomic_cmpxchg(&lock->write_lock_pending, 1, 0) != 1))
3623+ return -EINVAL;
3624+ wake_up_interruptible(&lock->queue);
3625+ return 0;
3626+}
3627+
3628+static void drm_bo_write_lock_remove(struct drm_file *file_priv,
3629+ struct drm_user_object *item)
3630+{
3631+ struct drm_bo_lock *lock = container_of(item, struct drm_bo_lock, base);
3632+ int ret;
3633+
3634+ ret = __drm_bo_write_unlock(lock);
3635+ BUG_ON(ret);
3636+}
3637+
3638+int drm_bo_write_lock(struct drm_bo_lock *lock, struct drm_file *file_priv)
3639+{
3640+ int ret = 0;
3641+ struct drm_device *dev;
3642+
3643+ if (unlikely(atomic_cmpxchg(&lock->write_lock_pending, 0, 1) != 0))
3644+ return -EINVAL;
3645+
3646+ while (unlikely(atomic_cmpxchg(&lock->readers, 0, -1) != 0)) {
3647+ ret = wait_event_interruptible
3648+ (lock->queue, atomic_cmpxchg(&lock->readers, 0, -1) == 0);
3649+
3650+ if (ret) {
3651+ atomic_set(&lock->write_lock_pending, 0);
3652+ wake_up_interruptible(&lock->queue);
3653+ return -EAGAIN;
3654+ }
3655+ }
3656+
3657+ /*
3658+ * Add a dummy user-object, the destructor of which will
3659+ * make sure the lock is released if the client dies
3660+ * while holding it.
3661+ */
3662+
3663+ dev = file_priv->minor->dev;
3664+ mutex_lock(&dev->struct_mutex);
3665+ ret = drm_add_user_object(file_priv, &lock->base, 0);
3666+ lock->base.remove = &drm_bo_write_lock_remove;
3667+ lock->base.type = drm_lock_type;
3668+ if (ret)
3669+ (void)__drm_bo_write_unlock(lock);
3670+
3671+ mutex_unlock(&dev->struct_mutex);
3672+
3673+ return ret;
3674+}
3675+
3676+int drm_bo_write_unlock(struct drm_bo_lock *lock, struct drm_file *file_priv)
3677+{
3678+ struct drm_device *dev = file_priv->minor->dev;
3679+ struct drm_ref_object *ro;
3680+
3681+ mutex_lock(&dev->struct_mutex);
3682+
3683+ if (lock->base.owner != file_priv) {
3684+ mutex_unlock(&dev->struct_mutex);
3685+ return -EINVAL;
3686+ }
3687+ ro = drm_lookup_ref_object(file_priv, &lock->base, _DRM_REF_USE);
3688+ BUG_ON(!ro);
3689+ drm_remove_ref_object(file_priv, ro);
3690+ lock->base.owner = NULL;
3691+
3692+ mutex_unlock(&dev->struct_mutex);
3693+ return 0;
3694+}
3695Index: linux-2.6.28/drivers/gpu/drm/drm_bo_move.c
3696===================================================================
3697--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3698+++ linux-2.6.28/drivers/gpu/drm/drm_bo_move.c 2009-02-12 09:14:41.000000000 +0000
3699@@ -0,0 +1,597 @@
3700+/**************************************************************************
3701+ *
3702+ * Copyright (c) 2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
3703+ * All Rights Reserved.
3704+ *
3705+ * Permission is hereby granted, free of charge, to any person obtaining a
3706+ * copy of this software and associated documentation files (the
3707+ * "Software"), to deal in the Software without restriction, including
3708+ * without limitation the rights to use, copy, modify, merge, publish,
3709+ * distribute, sub license, and/or sell copies of the Software, and to
3710+ * permit persons to whom the Software is furnished to do so, subject to
3711+ * the following conditions:
3712+ *
3713+ * The above copyright notice and this permission notice (including the
3714+ * next paragraph) shall be included in all copies or substantial portions
3715+ * of the Software.
3716+ *
3717+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3718+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3719+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
3720+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
3721+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
3722+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
3723+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
3724+ *
3725+ **************************************************************************/
3726+/*
3727+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
3728+ */
3729+
3730+#include "drmP.h"
3731+
3732+/**
3733+ * Free the old memory node unless it's a pinned region and we
3734+ * have not been requested to free also pinned regions.
3735+ */
3736+
3737+static void drm_bo_free_old_node(struct drm_buffer_object *bo)
3738+{
3739+ struct drm_bo_mem_reg *old_mem = &bo->mem;
3740+
3741+ if (old_mem->mm_node && (old_mem->mm_node != bo->pinned_node)) {
3742+ mutex_lock(&bo->dev->struct_mutex);
3743+ drm_mm_put_block(old_mem->mm_node);
3744+ mutex_unlock(&bo->dev->struct_mutex);
3745+ }
3746+ old_mem->mm_node = NULL;
3747+}
3748+
3749+int drm_bo_move_ttm(struct drm_buffer_object *bo,
3750+ int evict, int no_wait, struct drm_bo_mem_reg *new_mem)
3751+{
3752+ struct drm_ttm *ttm = bo->ttm;
3753+ struct drm_bo_mem_reg *old_mem = &bo->mem;
3754+ uint64_t save_flags = old_mem->flags;
3755+ uint64_t save_mask = old_mem->mask;
3756+ int ret;
3757+
3758+ if (old_mem->mem_type != DRM_BO_MEM_LOCAL) {
3759+ if (evict)
3760+ drm_ttm_evict(ttm);
3761+ else
3762+ drm_ttm_unbind(ttm);
3763+
3764+ drm_bo_free_old_node(bo);
3765+ DRM_FLAG_MASKED(old_mem->flags,
3766+ DRM_BO_FLAG_CACHED | DRM_BO_FLAG_MAPPABLE |
3767+ DRM_BO_FLAG_MEM_LOCAL, DRM_BO_MASK_MEMTYPE);
3768+ old_mem->mem_type = DRM_BO_MEM_LOCAL;
3769+ save_flags = old_mem->flags;
3770+ }
3771+ if (new_mem->mem_type != DRM_BO_MEM_LOCAL) {
3772+ ret = drm_bind_ttm(ttm, new_mem);
3773+ if (ret)
3774+ return ret;
3775+ }
3776+
3777+ *old_mem = *new_mem;
3778+ new_mem->mm_node = NULL;
3779+ old_mem->mask = save_mask;
3780+ DRM_FLAG_MASKED(save_flags, new_mem->flags, DRM_BO_MASK_MEMTYPE);
3781+ return 0;
3782+}
3783+EXPORT_SYMBOL(drm_bo_move_ttm);
3784+
3785+/**
3786+ * \c Return a kernel virtual address to the buffer object PCI memory.
3787+ *
3788+ * \param bo The buffer object.
3789+ * \return Failure indication.
3790+ *
3791+ * Returns -EINVAL if the buffer object is currently not mappable.
3792+ * Returns -ENOMEM if the ioremap operation failed.
3793+ * Otherwise returns zero.
3794+ *
3795+ * After a successfull call, bo->iomap contains the virtual address, or NULL
3796+ * if the buffer object content is not accessible through PCI space.
3797+ * Call bo->mutex locked.
3798+ */
3799+
3800+int drm_mem_reg_ioremap(struct drm_device *dev, struct drm_bo_mem_reg *mem,
3801+ void **virtual)
3802+{
3803+ struct drm_buffer_manager *bm = &dev->bm;
3804+ struct drm_mem_type_manager *man = &bm->man[mem->mem_type];
3805+ unsigned long bus_offset;
3806+ unsigned long bus_size;
3807+ unsigned long bus_base;
3808+ int ret;
3809+ void *addr;
3810+
3811+ *virtual = NULL;
3812+ ret = drm_bo_pci_offset(dev, mem, &bus_base, &bus_offset, &bus_size);
3813+ if (ret || bus_size == 0)
3814+ return ret;
3815+
3816+ if (!(man->flags & _DRM_FLAG_NEEDS_IOREMAP))
3817+ addr = (void *)(((u8 *) man->io_addr) + bus_offset);
3818+ else {
3819+ addr = ioremap_nocache(bus_base + bus_offset, bus_size);
3820+ if (!addr)
3821+ return -ENOMEM;
3822+ }
3823+ *virtual = addr;
3824+ return 0;
3825+}
3826+EXPORT_SYMBOL(drm_mem_reg_ioremap);
3827+
3828+/**
3829+ * \c Unmap mapping obtained using drm_bo_ioremap
3830+ *
3831+ * \param bo The buffer object.
3832+ *
3833+ * Call bo->mutex locked.
3834+ */
3835+
3836+void drm_mem_reg_iounmap(struct drm_device *dev, struct drm_bo_mem_reg *mem,
3837+ void *virtual)
3838+{
3839+ struct drm_buffer_manager *bm;
3840+ struct drm_mem_type_manager *man;
3841+
3842+ bm = &dev->bm;
3843+ man = &bm->man[mem->mem_type];
3844+
3845+ if (virtual && (man->flags & _DRM_FLAG_NEEDS_IOREMAP))
3846+ iounmap(virtual);
3847+}
3848+EXPORT_SYMBOL(drm_mem_reg_iounmap);
3849+
3850+static int drm_copy_io_page(void *dst, void *src, unsigned long page)
3851+{
3852+ uint32_t *dstP =
3853+ (uint32_t *) ((unsigned long)dst + (page << PAGE_SHIFT));
3854+ uint32_t *srcP =
3855+ (uint32_t *) ((unsigned long)src + (page << PAGE_SHIFT));
3856+
3857+ int i;
3858+ for (i = 0; i < PAGE_SIZE / sizeof(uint32_t); ++i)
3859+ iowrite32(ioread32(srcP++), dstP++);
3860+ return 0;
3861+}
3862+
3863+static int drm_copy_io_ttm_page(struct drm_ttm *ttm, void *src,
3864+ unsigned long page)
3865+{
3866+ struct page *d = drm_ttm_get_page(ttm, page);
3867+ void *dst;
3868+
3869+ if (!d)
3870+ return -ENOMEM;
3871+
3872+ src = (void *)((unsigned long)src + (page << PAGE_SHIFT));
3873+ dst = kmap(d);
3874+ if (!dst)
3875+ return -ENOMEM;
3876+
3877+ memcpy_fromio(dst, src, PAGE_SIZE);
3878+ kunmap(d);
3879+ return 0;
3880+}
3881+
3882+static int drm_copy_ttm_io_page(struct drm_ttm *ttm, void *dst, unsigned long page)
3883+{
3884+ struct page *s = drm_ttm_get_page(ttm, page);
3885+ void *src;
3886+
3887+ if (!s)
3888+ return -ENOMEM;
3889+
3890+ dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT));
3891+ src = kmap(s);
3892+ if (!src)
3893+ return -ENOMEM;
3894+
3895+ memcpy_toio(dst, src, PAGE_SIZE);
3896+ kunmap(s);
3897+ return 0;
3898+}
3899+
3900+int drm_bo_move_memcpy(struct drm_buffer_object *bo,
3901+ int evict, int no_wait, struct drm_bo_mem_reg *new_mem)
3902+{
3903+ struct drm_device *dev = bo->dev;
3904+ struct drm_mem_type_manager *man = &dev->bm.man[new_mem->mem_type];
3905+ struct drm_ttm *ttm = bo->ttm;
3906+ struct drm_bo_mem_reg *old_mem = &bo->mem;
3907+ struct drm_bo_mem_reg old_copy = *old_mem;
3908+ void *old_iomap;
3909+ void *new_iomap;
3910+ int ret;
3911+ uint64_t save_flags = old_mem->flags;
3912+ uint64_t save_mask = old_mem->mask;
3913+ unsigned long i;
3914+ unsigned long page;
3915+ unsigned long add = 0;
3916+ int dir;
3917+
3918+ ret = drm_mem_reg_ioremap(dev, old_mem, &old_iomap);
3919+ if (ret)
3920+ return ret;
3921+ ret = drm_mem_reg_ioremap(dev, new_mem, &new_iomap);
3922+ if (ret)
3923+ goto out;
3924+
3925+ if (old_iomap == NULL && new_iomap == NULL)
3926+ goto out2;
3927+ if (old_iomap == NULL && ttm == NULL)
3928+ goto out2;
3929+
3930+ add = 0;
3931+ dir = 1;
3932+
3933+ if ((old_mem->mem_type == new_mem->mem_type) &&
3934+ (new_mem->mm_node->start <
3935+ old_mem->mm_node->start + old_mem->mm_node->size)) {
3936+ dir = -1;
3937+ add = new_mem->num_pages - 1;
3938+ }
3939+
3940+ for (i = 0; i < new_mem->num_pages; ++i) {
3941+ page = i * dir + add;
3942+ if (old_iomap == NULL)
3943+ ret = drm_copy_ttm_io_page(ttm, new_iomap, page);
3944+ else if (new_iomap == NULL)
3945+ ret = drm_copy_io_ttm_page(ttm, old_iomap, page);
3946+ else
3947+ ret = drm_copy_io_page(new_iomap, old_iomap, page);
3948+ if (ret)
3949+ goto out1;
3950+ }
3951+ mb();
3952+out2:
3953+ drm_bo_free_old_node(bo);
3954+
3955+ *old_mem = *new_mem;
3956+ new_mem->mm_node = NULL;
3957+ old_mem->mask = save_mask;
3958+ DRM_FLAG_MASKED(save_flags, new_mem->flags, DRM_BO_MASK_MEMTYPE);
3959+
3960+ if ((man->flags & _DRM_FLAG_MEMTYPE_FIXED) && (ttm != NULL)) {
3961+ drm_ttm_unbind(ttm);
3962+ drm_destroy_ttm(ttm);
3963+ bo->ttm = NULL;
3964+ }
3965+
3966+out1:
3967+ drm_mem_reg_iounmap(dev, new_mem, new_iomap);
3968+out:
3969+ drm_mem_reg_iounmap(dev, &old_copy, old_iomap);
3970+ return ret;
3971+}
3972+EXPORT_SYMBOL(drm_bo_move_memcpy);
3973+
3974+/*
3975+ * Transfer a buffer object's memory and LRU status to a newly
3976+ * created object. User-space references remains with the old
3977+ * object. Call bo->mutex locked.
3978+ */
3979+
3980+int drm_buffer_object_transfer(struct drm_buffer_object *bo,
3981+ struct drm_buffer_object **new_obj)
3982+{
3983+ struct drm_buffer_object *fbo;
3984+ struct drm_device *dev = bo->dev;
3985+ struct drm_buffer_manager *bm = &dev->bm;
3986+
3987+ fbo = drm_calloc(1, sizeof(*fbo), DRM_MEM_BUFOBJ);
3988+ if (!fbo)
3989+ return -ENOMEM;
3990+
3991+ *fbo = *bo;
3992+ mutex_init(&fbo->mutex);
3993+ mutex_lock(&fbo->mutex);
3994+ mutex_lock(&dev->struct_mutex);
3995+
3996+ DRM_INIT_WAITQUEUE(&bo->event_queue);
3997+ INIT_LIST_HEAD(&fbo->ddestroy);
3998+ INIT_LIST_HEAD(&fbo->lru);
3999+ INIT_LIST_HEAD(&fbo->pinned_lru);
4000+#ifdef DRM_ODD_MM_COMPAT
4001+ INIT_LIST_HEAD(&fbo->vma_list);
4002+ INIT_LIST_HEAD(&fbo->p_mm_list);
4003+#endif
4004+
4005+ fbo->fence = drm_fence_reference_locked(bo->fence);
4006+ fbo->pinned_node = NULL;
4007+ fbo->mem.mm_node->private = (void *)fbo;
4008+ atomic_set(&fbo->usage, 1);
4009+ atomic_inc(&bm->count);
4010+ mutex_unlock(&dev->struct_mutex);
4011+ mutex_unlock(&fbo->mutex);
4012+ bo->reserved_size = 0;
4013+ *new_obj = fbo;
4014+ return 0;
4015+}
4016+
4017+/*
4018+ * Since move is underway, we need to block signals in this function.
4019+ * We cannot restart until it has finished.
4020+ */
4021+
4022+int drm_bo_move_accel_cleanup(struct drm_buffer_object *bo,
4023+ int evict, int no_wait, uint32_t fence_class,
4024+ uint32_t fence_type, uint32_t fence_flags,
4025+ struct drm_bo_mem_reg *new_mem)
4026+{
4027+ struct drm_device *dev = bo->dev;
4028+ struct drm_mem_type_manager *man = &dev->bm.man[new_mem->mem_type];
4029+ struct drm_bo_mem_reg *old_mem = &bo->mem;
4030+ int ret;
4031+ uint64_t save_flags = old_mem->flags;
4032+ uint64_t save_mask = old_mem->mask;
4033+ struct drm_buffer_object *old_obj;
4034+
4035+ if (bo->fence)
4036+ drm_fence_usage_deref_unlocked(&bo->fence);
4037+ ret = drm_fence_object_create(dev, fence_class, fence_type,
4038+ fence_flags | DRM_FENCE_FLAG_EMIT,
4039+ &bo->fence);
4040+ bo->fence_type = fence_type;
4041+ if (ret)
4042+ return ret;
4043+
4044+#ifdef DRM_ODD_MM_COMPAT
4045+ /*
4046+ * In this mode, we don't allow pipelining a copy blit,
4047+ * since the buffer will be accessible from user space
4048+ * the moment we return and rebuild the page tables.
4049+ *
4050+ * With normal vm operation, page tables are rebuilt
4051+ * on demand using fault(), which waits for buffer idle.
4052+ */
4053+ if (1)
4054+#else
4055+ if (evict || ((bo->mem.mm_node == bo->pinned_node) &&
4056+ bo->mem.mm_node != NULL))
4057+#endif
4058+ {
4059+ ret = drm_bo_wait(bo, 0, 1, 0);
4060+ if (ret)
4061+ return ret;
4062+
4063+ drm_bo_free_old_node(bo);
4064+
4065+ if ((man->flags & _DRM_FLAG_MEMTYPE_FIXED) && (bo->ttm != NULL)) {
4066+ drm_ttm_unbind(bo->ttm);
4067+ drm_destroy_ttm(bo->ttm);
4068+ bo->ttm = NULL;
4069+ }
4070+ } else {
4071+
4072+ /* This should help pipeline ordinary buffer moves.
4073+ *
4074+ * Hang old buffer memory on a new buffer object,
4075+ * and leave it to be released when the GPU
4076+ * operation has completed.
4077+ */
4078+
4079+ ret = drm_buffer_object_transfer(bo, &old_obj);
4080+
4081+ if (ret)
4082+ return ret;
4083+
4084+ if (!(man->flags & _DRM_FLAG_MEMTYPE_FIXED))
4085+ old_obj->ttm = NULL;
4086+ else
4087+ bo->ttm = NULL;
4088+
4089+ mutex_lock(&dev->struct_mutex);
4090+ list_del_init(&old_obj->lru);
4091+ DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
4092+ drm_bo_add_to_lru(old_obj);
4093+
4094+ drm_bo_usage_deref_locked(&old_obj);
4095+ mutex_unlock(&dev->struct_mutex);
4096+
4097+ }
4098+
4099+ *old_mem = *new_mem;
4100+ new_mem->mm_node = NULL;
4101+ old_mem->mask = save_mask;
4102+ DRM_FLAG_MASKED(save_flags, new_mem->flags, DRM_BO_MASK_MEMTYPE);
4103+ return 0;
4104+}
4105+EXPORT_SYMBOL(drm_bo_move_accel_cleanup);
4106+
4107+int drm_bo_same_page(unsigned long offset,
4108+ unsigned long offset2)
4109+{
4110+ return (offset & PAGE_MASK) == (offset2 & PAGE_MASK);
4111+}
4112+EXPORT_SYMBOL(drm_bo_same_page);
4113+
4114+unsigned long drm_bo_offset_end(unsigned long offset,
4115+ unsigned long end)
4116+{
4117+ offset = (offset + PAGE_SIZE) & PAGE_MASK;
4118+ return (end < offset) ? end : offset;
4119+}
4120+EXPORT_SYMBOL(drm_bo_offset_end);
4121+
4122+static pgprot_t drm_kernel_io_prot(uint32_t map_type)
4123+{
4124+ pgprot_t tmp = PAGE_KERNEL;
4125+
4126+#if defined(__i386__) || defined(__x86_64__)
4127+#ifdef USE_PAT_WC
4128+#warning using pat
4129+ if (drm_use_pat() && map_type == _DRM_TTM) {
4130+ pgprot_val(tmp) |= _PAGE_PAT;
4131+ return tmp;
4132+ }
4133+#endif
4134+ if (boot_cpu_data.x86 > 3 && map_type != _DRM_AGP) {
4135+ pgprot_val(tmp) |= _PAGE_PCD;
4136+ pgprot_val(tmp) &= ~_PAGE_PWT;
4137+ }
4138+#elif defined(__powerpc__)
4139+ pgprot_val(tmp) |= _PAGE_NO_CACHE;
4140+ if (map_type == _DRM_REGISTERS)
4141+ pgprot_val(tmp) |= _PAGE_GUARDED;
4142+#endif
4143+#if defined(__ia64__)
4144+ if (map_type == _DRM_TTM)
4145+ tmp = pgprot_writecombine(tmp);
4146+ else
4147+ tmp = pgprot_noncached(tmp);
4148+#endif
4149+ return tmp;
4150+}
4151+
4152+static int drm_bo_ioremap(struct drm_buffer_object *bo, unsigned long bus_base,
4153+ unsigned long bus_offset, unsigned long bus_size,
4154+ struct drm_bo_kmap_obj *map)
4155+{
4156+ struct drm_device *dev = bo->dev;
4157+ struct drm_bo_mem_reg *mem = &bo->mem;
4158+ struct drm_mem_type_manager *man = &dev->bm.man[mem->mem_type];
4159+
4160+ if (!(man->flags & _DRM_FLAG_NEEDS_IOREMAP)) {
4161+ map->bo_kmap_type = bo_map_premapped;
4162+ map->virtual = (void *)(((u8 *) man->io_addr) + bus_offset);
4163+ } else {
4164+ map->bo_kmap_type = bo_map_iomap;
4165+ map->virtual = ioremap_nocache(bus_base + bus_offset, bus_size);
4166+ }
4167+ return (!map->virtual) ? -ENOMEM : 0;
4168+}
4169+
4170+static int drm_bo_kmap_ttm(struct drm_buffer_object *bo,
4171+ unsigned long start_page, unsigned long num_pages,
4172+ struct drm_bo_kmap_obj *map)
4173+{
4174+ struct drm_device *dev = bo->dev;
4175+ struct drm_bo_mem_reg *mem = &bo->mem;
4176+ struct drm_mem_type_manager *man = &dev->bm.man[mem->mem_type];
4177+ pgprot_t prot;
4178+ struct drm_ttm *ttm = bo->ttm;
4179+ struct page *d;
4180+ int i;
4181+
4182+ BUG_ON(!ttm);
4183+
4184+ if (num_pages == 1 && (mem->flags & DRM_BO_FLAG_CACHED)) {
4185+
4186+ /*
4187+ * We're mapping a single page, and the desired
4188+ * page protection is consistent with the bo.
4189+ */
4190+
4191+ map->bo_kmap_type = bo_map_kmap;
4192+ map->page = drm_ttm_get_page(ttm, start_page);
4193+ map->virtual = kmap(map->page);
4194+ } else {
4195+ /*
4196+ * Populate the part we're mapping;
4197+ */
4198+
4199+ for (i = start_page; i < start_page + num_pages; ++i) {
4200+ d = drm_ttm_get_page(ttm, i);
4201+ if (!d)
4202+ return -ENOMEM;
4203+ }
4204+
4205+ /*
4206+ * We need to use vmap to get the desired page protection
4207+ * or to make the buffer object look contigous.
4208+ */
4209+
4210+ prot = (mem->flags & DRM_BO_FLAG_CACHED) ?
4211+ PAGE_KERNEL :
4212+ drm_kernel_io_prot(man->drm_bus_maptype);
4213+ map->bo_kmap_type = bo_map_vmap;
4214+ map->virtual = vmap(ttm->pages + start_page,
4215+ num_pages, 0, prot);
4216+ }
4217+ return (!map->virtual) ? -ENOMEM : 0;
4218+}
4219+
4220+/*
4221+ * This function is to be used for kernel mapping of buffer objects.
4222+ * It chooses the appropriate mapping method depending on the memory type
4223+ * and caching policy the buffer currently has.
4224+ * Mapping multiple pages or buffers that live in io memory is a bit slow and
4225+ * consumes vmalloc space. Be restrictive with such mappings.
4226+ * Mapping single pages usually returns the logical kernel address,
4227+ * (which is fast)
4228+ * BUG may use slower temporary mappings for high memory pages or
4229+ * uncached / write-combined pages.
4230+ *
4231+ * The function fills in a drm_bo_kmap_obj which can be used to return the
4232+ * kernel virtual address of the buffer.
4233+ *
4234+ * Code servicing a non-priviliged user request is only allowed to map one
4235+ * page at a time. We might need to implement a better scheme to stop such
4236+ * processes from consuming all vmalloc space.
4237+ */
4238+
4239+int drm_bo_kmap(struct drm_buffer_object *bo, unsigned long start_page,
4240+ unsigned long num_pages, struct drm_bo_kmap_obj *map)
4241+{
4242+ int ret;
4243+ unsigned long bus_base;
4244+ unsigned long bus_offset;
4245+ unsigned long bus_size;
4246+
4247+ map->virtual = NULL;
4248+
4249+ if (num_pages > bo->num_pages)
4250+ return -EINVAL;
4251+ if (start_page > bo->num_pages)
4252+ return -EINVAL;
4253+#if 0
4254+ if (num_pages > 1 && !DRM_SUSER(DRM_CURPROC))
4255+ return -EPERM;
4256+#endif
4257+ ret = drm_bo_pci_offset(bo->dev, &bo->mem, &bus_base,
4258+ &bus_offset, &bus_size);
4259+
4260+ if (ret)
4261+ return ret;
4262+
4263+ if (bus_size == 0) {
4264+ return drm_bo_kmap_ttm(bo, start_page, num_pages, map);
4265+ } else {
4266+ bus_offset += start_page << PAGE_SHIFT;
4267+ bus_size = num_pages << PAGE_SHIFT;
4268+ return drm_bo_ioremap(bo, bus_base, bus_offset, bus_size, map);
4269+ }
4270+}
4271+EXPORT_SYMBOL(drm_bo_kmap);
4272+
4273+void drm_bo_kunmap(struct drm_bo_kmap_obj *map)
4274+{
4275+ if (!map->virtual)
4276+ return;
4277+
4278+ switch (map->bo_kmap_type) {
4279+ case bo_map_iomap:
4280+ iounmap(map->virtual);
4281+ break;
4282+ case bo_map_vmap:
4283+ vunmap(map->virtual);
4284+ break;
4285+ case bo_map_kmap:
4286+ kunmap(map->page);
4287+ break;
4288+ case bo_map_premapped:
4289+ break;
4290+ default:
4291+ BUG();
4292+ }
4293+ map->virtual = NULL;
4294+ map->page = NULL;
4295+}
4296+EXPORT_SYMBOL(drm_bo_kunmap);
4297Index: linux-2.6.28/drivers/gpu/drm/drm_bufs.c
4298===================================================================
4299--- linux-2.6.28.orig/drivers/gpu/drm/drm_bufs.c 2009-02-12 09:14:37.000000000 +0000
4300+++ linux-2.6.28/drivers/gpu/drm/drm_bufs.c 2009-02-12 09:14:41.000000000 +0000
4301@@ -435,6 +435,8 @@
4302 case _DRM_GEM:
4303 DRM_ERROR("tried to rmmap GEM object\n");
4304 break;
4305+ case _DRM_TTM:
4306+ BUG_ON(1);
4307 }
4308 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
4309
4310Index: linux-2.6.28/drivers/gpu/drm/drm_drv.c
4311===================================================================
4312--- linux-2.6.28.orig/drivers/gpu/drm/drm_drv.c 2009-02-12 09:14:37.000000000 +0000
4313+++ linux-2.6.28/drivers/gpu/drm/drm_drv.c 2009-02-12 09:14:41.000000000 +0000
4314@@ -1,3 +1,4 @@
4315+
4316 /**
4317 * \file drm_drv.c
4318 * Generic driver template
4319@@ -49,6 +50,9 @@
4320 #include "drmP.h"
4321 #include "drm_core.h"
4322
4323+static void drm_cleanup(struct drm_device * dev);
4324+int drm_fb_loaded = 0;
4325+
4326 static int drm_version(struct drm_device *dev, void *data,
4327 struct drm_file *file_priv);
4328
4329@@ -119,7 +123,7 @@
4330
4331 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
4332
4333- DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
4334+
4335
4336 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
4337
4338@@ -130,19 +134,48 @@
4339 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW),
4340 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW),
4341 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW),
4342- DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
4343+/* DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
4344 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER),
4345 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER),
4346 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW),
4347- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW),
4348+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW),*/
4349 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
4350 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
4351 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW),
4352- DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
4353- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
4354+/* DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
4355+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),*/
4356 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW),
4357 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW),
4358 DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW),
4359+
4360+ DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl,
4361+ DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
4362+ DRM_IOCTL_DEF(DRM_IOCTL_MM_TAKEDOWN, drm_mm_takedown_ioctl,
4363+ DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
4364+ DRM_IOCTL_DEF(DRM_IOCTL_MM_LOCK, drm_mm_lock_ioctl,
4365+ DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
4366+ DRM_IOCTL_DEF(DRM_IOCTL_MM_UNLOCK, drm_mm_unlock_ioctl,
4367+ DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
4368+
4369+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_CREATE, drm_fence_create_ioctl, DRM_AUTH),
4370+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_REFERENCE, drm_fence_reference_ioctl, DRM_AUTH),
4371+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_UNREFERENCE, drm_fence_unreference_ioctl, DRM_AUTH),
4372+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_SIGNALED, drm_fence_signaled_ioctl, DRM_AUTH),
4373+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_FLUSH, drm_fence_flush_ioctl, DRM_AUTH),
4374+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_WAIT, drm_fence_wait_ioctl, DRM_AUTH),
4375+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_EMIT, drm_fence_emit_ioctl, DRM_AUTH),
4376+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_BUFFERS, drm_fence_buffers_ioctl, DRM_AUTH),
4377+
4378+ DRM_IOCTL_DEF(DRM_IOCTL_BO_CREATE, drm_bo_create_ioctl, DRM_AUTH),
4379+ DRM_IOCTL_DEF(DRM_IOCTL_BO_MAP, drm_bo_map_ioctl, DRM_AUTH),
4380+ DRM_IOCTL_DEF(DRM_IOCTL_BO_UNMAP, drm_bo_unmap_ioctl, DRM_AUTH),
4381+ DRM_IOCTL_DEF(DRM_IOCTL_BO_REFERENCE, drm_bo_reference_ioctl, DRM_AUTH),
4382+ DRM_IOCTL_DEF(DRM_IOCTL_BO_UNREFERENCE, drm_bo_unreference_ioctl, DRM_AUTH),
4383+ DRM_IOCTL_DEF(DRM_IOCTL_BO_SETSTATUS, drm_bo_setstatus_ioctl, DRM_AUTH),
4384+ DRM_IOCTL_DEF(DRM_IOCTL_BO_INFO, drm_bo_info_ioctl, DRM_AUTH),
4385+ DRM_IOCTL_DEF(DRM_IOCTL_BO_WAIT_IDLE, drm_bo_wait_idle_ioctl, DRM_AUTH),
4386+ DRM_IOCTL_DEF(DRM_IOCTL_BO_VERSION, drm_bo_version_ioctl, 0),
4387+
4388 };
4389
4390 #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
4391@@ -236,6 +269,17 @@
4392 return 0;
4393 }
4394
4395+void drm_cleanup_pci(struct pci_dev *pdev)
4396+{
4397+ struct drm_device *dev = pci_get_drvdata(pdev);
4398+
4399+ pci_set_drvdata(pdev, NULL);
4400+ pci_release_regions(pdev);
4401+ if (dev)
4402+ drm_cleanup(dev);
4403+}
4404+EXPORT_SYMBOL(drm_cleanup_pci);
4405+
4406 /**
4407 * Module initialization. Called via init_module at module load time, or via
4408 * linux/init/main.c (this is not currently supported).
4409@@ -301,9 +345,10 @@
4410 return;
4411 }
4412
4413- drm_vblank_cleanup(dev);
4414+ //drm_vblank_cleanup(dev);
4415
4416 drm_lastclose(dev);
4417+ drm_ctxbitmap_cleanup(dev);
4418
4419 if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
4420 dev->agp && dev->agp->agp_mtrr >= 0) {
4421@@ -317,13 +362,21 @@
4422 if (dev->driver->unload)
4423 dev->driver->unload(dev);
4424
4425+ drm_bo_driver_finish(dev);
4426+ drm_fence_manager_takedown(dev);
4427+
4428 if (drm_core_has_AGP(dev) && dev->agp) {
4429 drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
4430 dev->agp = NULL;
4431 }
4432
4433 drm_ht_remove(&dev->map_hash);
4434- drm_ctxbitmap_cleanup(dev);
4435+ drm_mm_takedown(&dev->offset_manager);
4436+ drm_ht_remove(&dev->object_hash);
4437+
4438+
4439+ if (!drm_fb_loaded)
4440+ pci_disable_device(dev->pdev);
4441
4442 if (drm_core_check_feature(dev, DRIVER_MODESET))
4443 drm_put_minor(&dev->control);
4444Index: linux-2.6.28/drivers/gpu/drm/drm_fence.c
4445===================================================================
4446--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4447+++ linux-2.6.28/drivers/gpu/drm/drm_fence.c 2009-02-12 09:14:41.000000000 +0000
4448@@ -0,0 +1,829 @@
4449+/**************************************************************************
4450+ *
4451+ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
4452+ * All Rights Reserved.
4453+ *
4454+ * Permission is hereby granted, free of charge, to any person obtaining a
4455+ * copy of this software and associated documentation files (the
4456+ * "Software"), to deal in the Software without restriction, including
4457+ * without limitation the rights to use, copy, modify, merge, publish,
4458+ * distribute, sub license, and/or sell copies of the Software, and to
4459+ * permit persons to whom the Software is furnished to do so, subject to
4460+ * the following conditions:
4461+ *
4462+ * The above copyright notice and this permission notice (including the
4463+ * next paragraph) shall be included in all copies or substantial portions
4464+ * of the Software.
4465+ *
4466+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4467+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4468+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
4469+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
4470+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
4471+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
4472+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
4473+ *
4474+ **************************************************************************/
4475+/*
4476+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
4477+ */
4478+
4479+#include "drmP.h"
4480+
4481+
4482+/*
4483+ * Convenience function to be called by fence::wait methods that
4484+ * need polling.
4485+ */
4486+
4487+int drm_fence_wait_polling(struct drm_fence_object *fence, int lazy,
4488+ int interruptible, uint32_t mask,
4489+ unsigned long end_jiffies)
4490+{
4491+ struct drm_device *dev = fence->dev;
4492+ struct drm_fence_manager *fm = &dev->fm;
4493+ struct drm_fence_class_manager *fc = &fm->fence_class[fence->fence_class];
4494+ uint32_t count = 0;
4495+ int ret;
4496+
4497+ DECLARE_WAITQUEUE(entry, current);
4498+ add_wait_queue(&fc->fence_queue, &entry);
4499+
4500+ ret = 0;
4501+
4502+ for (;;) {
4503+ __set_current_state((interruptible) ?
4504+ TASK_INTERRUPTIBLE :
4505+ TASK_UNINTERRUPTIBLE);
4506+ if (drm_fence_object_signaled(fence, mask))
4507+ break;
4508+ if (time_after_eq(jiffies, end_jiffies)) {
4509+ ret = -EBUSY;
4510+ break;
4511+ }
4512+ if (lazy)
4513+ schedule_timeout(1);
4514+ else if ((++count & 0x0F) == 0){
4515+ __set_current_state(TASK_RUNNING);
4516+ schedule();
4517+ __set_current_state((interruptible) ?
4518+ TASK_INTERRUPTIBLE :
4519+ TASK_UNINTERRUPTIBLE);
4520+ }
4521+ if (interruptible && signal_pending(current)) {
4522+ ret = -EAGAIN;
4523+ break;
4524+ }
4525+ }
4526+ __set_current_state(TASK_RUNNING);
4527+ remove_wait_queue(&fc->fence_queue, &entry);
4528+ return ret;
4529+}
4530+EXPORT_SYMBOL(drm_fence_wait_polling);
4531+
4532+/*
4533+ * Typically called by the IRQ handler.
4534+ */
4535+
4536+void drm_fence_handler(struct drm_device *dev, uint32_t fence_class,
4537+ uint32_t sequence, uint32_t type, uint32_t error)
4538+{
4539+ int wake = 0;
4540+ uint32_t diff;
4541+ uint32_t relevant_type;
4542+ uint32_t new_type;
4543+ struct drm_fence_manager *fm = &dev->fm;
4544+ struct drm_fence_class_manager *fc = &fm->fence_class[fence_class];
4545+ struct drm_fence_driver *driver = dev->driver->fence_driver;
4546+ struct list_head *head;
4547+ struct drm_fence_object *fence, *next;
4548+ int found = 0;
4549+
4550+ if (list_empty(&fc->ring))
4551+ return;
4552+
4553+ list_for_each_entry(fence, &fc->ring, ring) {
4554+ diff = (sequence - fence->sequence) & driver->sequence_mask;
4555+ if (diff > driver->wrap_diff) {
4556+ found = 1;
4557+ break;
4558+ }
4559+ }
4560+
4561+ fc->waiting_types &= ~type;
4562+ head = (found) ? &fence->ring : &fc->ring;
4563+
4564+ list_for_each_entry_safe_reverse(fence, next, head, ring) {
4565+ if (&fence->ring == &fc->ring)
4566+ break;
4567+
4568+ if (error) {
4569+ fence->error = error;
4570+ fence->signaled_types = fence->type;
4571+ list_del_init(&fence->ring);
4572+ wake = 1;
4573+ break;
4574+ }
4575+
4576+ if (type & DRM_FENCE_TYPE_EXE)
4577+ type |= fence->native_types;
4578+
4579+ relevant_type = type & fence->type;
4580+ new_type = (fence->signaled_types | relevant_type) ^
4581+ fence->signaled_types;
4582+
4583+ if (new_type) {
4584+ fence->signaled_types |= new_type;
4585+ DRM_DEBUG("Fence 0x%08lx signaled 0x%08x\n",
4586+ fence->base.hash.key, fence->signaled_types);
4587+
4588+ if (driver->needed_flush)
4589+ fc->pending_flush |= driver->needed_flush(fence);
4590+
4591+ if (new_type & fence->waiting_types)
4592+ wake = 1;
4593+ }
4594+
4595+ fc->waiting_types |= fence->waiting_types & ~fence->signaled_types;
4596+
4597+ if (!(fence->type & ~fence->signaled_types)) {
4598+ DRM_DEBUG("Fence completely signaled 0x%08lx\n",
4599+ fence->base.hash.key);
4600+ list_del_init(&fence->ring);
4601+ }
4602+ }
4603+
4604+ /*
4605+ * Reinstate lost waiting types.
4606+ */
4607+
4608+ if ((fc->waiting_types & type) != type) {
4609+ head = head->prev;
4610+ list_for_each_entry(fence, head, ring) {
4611+ if (&fence->ring == &fc->ring)
4612+ break;
4613+ diff = (fc->highest_waiting_sequence - fence->sequence) &
4614+ driver->sequence_mask;
4615+ if (diff > driver->wrap_diff)
4616+ break;
4617+
4618+ fc->waiting_types |= fence->waiting_types & ~fence->signaled_types;
4619+ }
4620+ }
4621+
4622+ if (wake)
4623+ wake_up_all(&fc->fence_queue);
4624+}
4625+EXPORT_SYMBOL(drm_fence_handler);
4626+
4627+static void drm_fence_unring(struct drm_device *dev, struct list_head *ring)
4628+{
4629+ struct drm_fence_manager *fm = &dev->fm;
4630+ unsigned long flags;
4631+
4632+ write_lock_irqsave(&fm->lock, flags);
4633+ list_del_init(ring);
4634+ write_unlock_irqrestore(&fm->lock, flags);
4635+}
4636+
4637+void drm_fence_usage_deref_locked(struct drm_fence_object **fence)
4638+{
4639+ struct drm_fence_object *tmp_fence = *fence;
4640+ struct drm_device *dev = tmp_fence->dev;
4641+ struct drm_fence_manager *fm = &dev->fm;
4642+
4643+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
4644+ *fence = NULL;
4645+ if (atomic_dec_and_test(&tmp_fence->usage)) {
4646+ drm_fence_unring(dev, &tmp_fence->ring);
4647+ DRM_DEBUG("Destroyed a fence object 0x%08lx\n",
4648+ tmp_fence->base.hash.key);
4649+ atomic_dec(&fm->count);
4650+ BUG_ON(!list_empty(&tmp_fence->base.list));
4651+ drm_free(tmp_fence, sizeof(*tmp_fence), DRM_MEM_FENCE);
4652+ }
4653+}
4654+EXPORT_SYMBOL(drm_fence_usage_deref_locked);
4655+
4656+void drm_fence_usage_deref_unlocked(struct drm_fence_object **fence)
4657+{
4658+ struct drm_fence_object *tmp_fence = *fence;
4659+ struct drm_device *dev = tmp_fence->dev;
4660+ struct drm_fence_manager *fm = &dev->fm;
4661+
4662+ *fence = NULL;
4663+ if (atomic_dec_and_test(&tmp_fence->usage)) {
4664+ mutex_lock(&dev->struct_mutex);
4665+ if (atomic_read(&tmp_fence->usage) == 0) {
4666+ drm_fence_unring(dev, &tmp_fence->ring);
4667+ atomic_dec(&fm->count);
4668+ BUG_ON(!list_empty(&tmp_fence->base.list));
4669+ drm_free(tmp_fence, sizeof(*tmp_fence), DRM_MEM_FENCE);
4670+ }
4671+ mutex_unlock(&dev->struct_mutex);
4672+ }
4673+}
4674+EXPORT_SYMBOL(drm_fence_usage_deref_unlocked);
4675+
4676+struct drm_fence_object
4677+*drm_fence_reference_locked(struct drm_fence_object *src)
4678+{
4679+ DRM_ASSERT_LOCKED(&src->dev->struct_mutex);
4680+
4681+ atomic_inc(&src->usage);
4682+ return src;
4683+}
4684+
4685+void drm_fence_reference_unlocked(struct drm_fence_object **dst,
4686+ struct drm_fence_object *src)
4687+{
4688+ mutex_lock(&src->dev->struct_mutex);
4689+ *dst = src;
4690+ atomic_inc(&src->usage);
4691+ mutex_unlock(&src->dev->struct_mutex);
4692+}
4693+EXPORT_SYMBOL(drm_fence_reference_unlocked);
4694+
4695+static void drm_fence_object_destroy(struct drm_file *priv,
4696+ struct drm_user_object *base)
4697+{
4698+ struct drm_fence_object *fence =
4699+ drm_user_object_entry(base, struct drm_fence_object, base);
4700+
4701+ drm_fence_usage_deref_locked(&fence);
4702+}
4703+
4704+int drm_fence_object_signaled(struct drm_fence_object *fence, uint32_t mask)
4705+{
4706+ unsigned long flags;
4707+ int signaled;
4708+ struct drm_device *dev = fence->dev;
4709+ struct drm_fence_manager *fm = &dev->fm;
4710+ struct drm_fence_driver *driver = dev->driver->fence_driver;
4711+
4712+ mask &= fence->type;
4713+ read_lock_irqsave(&fm->lock, flags);
4714+ signaled = (mask & fence->signaled_types) == mask;
4715+ read_unlock_irqrestore(&fm->lock, flags);
4716+ if (!signaled && driver->poll) {
4717+ write_lock_irqsave(&fm->lock, flags);
4718+ driver->poll(dev, fence->fence_class, mask);
4719+ signaled = (mask & fence->signaled_types) == mask;
4720+ write_unlock_irqrestore(&fm->lock, flags);
4721+ }
4722+ return signaled;
4723+}
4724+EXPORT_SYMBOL(drm_fence_object_signaled);
4725+
4726+
4727+int drm_fence_object_flush(struct drm_fence_object *fence,
4728+ uint32_t type)
4729+{
4730+ struct drm_device *dev = fence->dev;
4731+ struct drm_fence_manager *fm = &dev->fm;
4732+ struct drm_fence_class_manager *fc = &fm->fence_class[fence->fence_class];
4733+ struct drm_fence_driver *driver = dev->driver->fence_driver;
4734+ unsigned long irq_flags;
4735+ uint32_t saved_pending_flush;
4736+ uint32_t diff;
4737+ int call_flush;
4738+
4739+ if (type & ~fence->type) {
4740+ DRM_ERROR("Flush trying to extend fence type, "
4741+ "0x%x, 0x%x\n", type, fence->type);
4742+ return -EINVAL;
4743+ }
4744+
4745+ write_lock_irqsave(&fm->lock, irq_flags);
4746+ fence->waiting_types |= type;
4747+ fc->waiting_types |= fence->waiting_types;
4748+ diff = (fence->sequence - fc->highest_waiting_sequence) &
4749+ driver->sequence_mask;
4750+
4751+ if (diff < driver->wrap_diff)
4752+ fc->highest_waiting_sequence = fence->sequence;
4753+
4754+ /*
4755+ * fence->waiting_types has changed. Determine whether
4756+ * we need to initiate some kind of flush as a result of this.
4757+ */
4758+
4759+ saved_pending_flush = fc->pending_flush;
4760+ if (driver->needed_flush)
4761+ fc->pending_flush |= driver->needed_flush(fence);
4762+
4763+ if (driver->poll)
4764+ driver->poll(dev, fence->fence_class, fence->waiting_types);
4765+
4766+ call_flush = fc->pending_flush;
4767+ write_unlock_irqrestore(&fm->lock, irq_flags);
4768+
4769+ if (call_flush && driver->flush)
4770+ driver->flush(dev, fence->fence_class);
4771+
4772+ return 0;
4773+}
4774+EXPORT_SYMBOL(drm_fence_object_flush);
4775+
4776+/*
4777+ * Make sure old fence objects are signaled before their fence sequences are
4778+ * wrapped around and reused.
4779+ */
4780+
4781+void drm_fence_flush_old(struct drm_device *dev, uint32_t fence_class,
4782+ uint32_t sequence)
4783+{
4784+ struct drm_fence_manager *fm = &dev->fm;
4785+ struct drm_fence_class_manager *fc = &fm->fence_class[fence_class];
4786+ struct drm_fence_object *fence;
4787+ unsigned long irq_flags;
4788+ struct drm_fence_driver *driver = dev->driver->fence_driver;
4789+ int call_flush;
4790+
4791+ uint32_t diff;
4792+
4793+ write_lock_irqsave(&fm->lock, irq_flags);
4794+
4795+ list_for_each_entry_reverse(fence, &fc->ring, ring) {
4796+ diff = (sequence - fence->sequence) & driver->sequence_mask;
4797+ if (diff <= driver->flush_diff)
4798+ break;
4799+
4800+ fence->waiting_types = fence->type;
4801+ fc->waiting_types |= fence->type;
4802+
4803+ if (driver->needed_flush)
4804+ fc->pending_flush |= driver->needed_flush(fence);
4805+ }
4806+
4807+ if (driver->poll)
4808+ driver->poll(dev, fence_class, fc->waiting_types);
4809+
4810+ call_flush = fc->pending_flush;
4811+ write_unlock_irqrestore(&fm->lock, irq_flags);
4812+
4813+ if (call_flush && driver->flush)
4814+ driver->flush(dev, fence->fence_class);
4815+
4816+ /*
4817+ * FIXME: Shold we implement a wait here for really old fences?
4818+ */
4819+
4820+}
4821+EXPORT_SYMBOL(drm_fence_flush_old);
4822+
4823+int drm_fence_object_wait(struct drm_fence_object *fence,
4824+ int lazy, int ignore_signals, uint32_t mask)
4825+{
4826+ struct drm_device *dev = fence->dev;
4827+ struct drm_fence_driver *driver = dev->driver->fence_driver;
4828+ struct drm_fence_manager *fm = &dev->fm;
4829+ struct drm_fence_class_manager *fc = &fm->fence_class[fence->fence_class];
4830+ int ret = 0;
4831+ unsigned long _end = 3 * DRM_HZ;
4832+
4833+ if (mask & ~fence->type) {
4834+ DRM_ERROR("Wait trying to extend fence type"
4835+ " 0x%08x 0x%08x\n", mask, fence->type);
4836+ BUG();
4837+ return -EINVAL;
4838+ }
4839+
4840+ if (driver->wait)
4841+ return driver->wait(fence, lazy, !ignore_signals, mask);
4842+
4843+
4844+ drm_fence_object_flush(fence, mask);
4845+ if (driver->has_irq(dev, fence->fence_class, mask)) {
4846+ if (!ignore_signals)
4847+ ret = wait_event_interruptible_timeout
4848+ (fc->fence_queue,
4849+ drm_fence_object_signaled(fence, mask),
4850+ 3 * DRM_HZ);
4851+ else
4852+ ret = wait_event_timeout
4853+ (fc->fence_queue,
4854+ drm_fence_object_signaled(fence, mask),
4855+ 3 * DRM_HZ);
4856+
4857+ if (unlikely(ret == -ERESTARTSYS))
4858+ return -EAGAIN;
4859+
4860+ if (unlikely(ret == 0))
4861+ return -EBUSY;
4862+
4863+ return 0;
4864+ }
4865+
4866+ return drm_fence_wait_polling(fence, lazy, !ignore_signals, mask,
4867+ _end);
4868+}
4869+EXPORT_SYMBOL(drm_fence_object_wait);
4870+
4871+
4872+
4873+int drm_fence_object_emit(struct drm_fence_object *fence, uint32_t fence_flags,
4874+ uint32_t fence_class, uint32_t type)
4875+{
4876+ struct drm_device *dev = fence->dev;
4877+ struct drm_fence_manager *fm = &dev->fm;
4878+ struct drm_fence_driver *driver = dev->driver->fence_driver;
4879+ struct drm_fence_class_manager *fc = &fm->fence_class[fence->fence_class];
4880+ unsigned long flags;
4881+ uint32_t sequence;
4882+ uint32_t native_types;
4883+ int ret;
4884+
4885+ drm_fence_unring(dev, &fence->ring);
4886+ ret = driver->emit(dev, fence_class, fence_flags, &sequence,
4887+ &native_types);
4888+ if (ret)
4889+ return ret;
4890+
4891+ write_lock_irqsave(&fm->lock, flags);
4892+ fence->fence_class = fence_class;
4893+ fence->type = type;
4894+ fence->waiting_types = 0;
4895+ fence->signaled_types = 0;
4896+ fence->error = 0;
4897+ fence->sequence = sequence;
4898+ fence->native_types = native_types;
4899+ if (list_empty(&fc->ring))
4900+ fc->highest_waiting_sequence = sequence - 1;
4901+ list_add_tail(&fence->ring, &fc->ring);
4902+ fc->latest_queued_sequence = sequence;
4903+ write_unlock_irqrestore(&fm->lock, flags);
4904+ return 0;
4905+}
4906+EXPORT_SYMBOL(drm_fence_object_emit);
4907+
4908+static int drm_fence_object_init(struct drm_device *dev, uint32_t fence_class,
4909+ uint32_t type,
4910+ uint32_t fence_flags,
4911+ struct drm_fence_object *fence)
4912+{
4913+ int ret = 0;
4914+ unsigned long flags;
4915+ struct drm_fence_manager *fm = &dev->fm;
4916+
4917+ mutex_lock(&dev->struct_mutex);
4918+ atomic_set(&fence->usage, 1);
4919+ mutex_unlock(&dev->struct_mutex);
4920+
4921+ write_lock_irqsave(&fm->lock, flags);
4922+ INIT_LIST_HEAD(&fence->ring);
4923+
4924+ /*
4925+ * Avoid hitting BUG() for kernel-only fence objects.
4926+ */
4927+
4928+ INIT_LIST_HEAD(&fence->base.list);
4929+ fence->fence_class = fence_class;
4930+ fence->type = type;
4931+ fence->signaled_types = 0;
4932+ fence->waiting_types = 0;
4933+ fence->sequence = 0;
4934+ fence->error = 0;
4935+ fence->dev = dev;
4936+ write_unlock_irqrestore(&fm->lock, flags);
4937+ if (fence_flags & DRM_FENCE_FLAG_EMIT) {
4938+ ret = drm_fence_object_emit(fence, fence_flags,
4939+ fence->fence_class, type);
4940+ }
4941+ return ret;
4942+}
4943+
4944+int drm_fence_add_user_object(struct drm_file *priv,
4945+ struct drm_fence_object *fence, int shareable)
4946+{
4947+ struct drm_device *dev = priv->minor->dev;
4948+ int ret;
4949+
4950+ mutex_lock(&dev->struct_mutex);
4951+ ret = drm_add_user_object(priv, &fence->base, shareable);
4952+ if (ret)
4953+ goto out;
4954+ atomic_inc(&fence->usage);
4955+ fence->base.type = drm_fence_type;
4956+ fence->base.remove = &drm_fence_object_destroy;
4957+ DRM_DEBUG("Fence 0x%08lx created\n", fence->base.hash.key);
4958+out:
4959+ mutex_unlock(&dev->struct_mutex);
4960+ return ret;
4961+}
4962+EXPORT_SYMBOL(drm_fence_add_user_object);
4963+
4964+int drm_fence_object_create(struct drm_device *dev, uint32_t fence_class,
4965+ uint32_t type, unsigned flags,
4966+ struct drm_fence_object **c_fence)
4967+{
4968+ struct drm_fence_object *fence;
4969+ int ret;
4970+ struct drm_fence_manager *fm = &dev->fm;
4971+
4972+ fence = drm_calloc(1, sizeof(*fence), DRM_MEM_FENCE);
4973+ if (!fence) {
4974+ DRM_INFO("Out of memory creating fence object.\n");
4975+ return -ENOMEM;
4976+ }
4977+ ret = drm_fence_object_init(dev, fence_class, type, flags, fence);
4978+ if (ret) {
4979+ drm_fence_usage_deref_unlocked(&fence);
4980+ return ret;
4981+ }
4982+ *c_fence = fence;
4983+ atomic_inc(&fm->count);
4984+
4985+ return 0;
4986+}
4987+EXPORT_SYMBOL(drm_fence_object_create);
4988+
4989+void drm_fence_manager_init(struct drm_device *dev)
4990+{
4991+ struct drm_fence_manager *fm = &dev->fm;
4992+ struct drm_fence_class_manager *fence_class;
4993+ struct drm_fence_driver *fed = dev->driver->fence_driver;
4994+ int i;
4995+ unsigned long flags;
4996+
4997+ rwlock_init(&fm->lock);
4998+ write_lock_irqsave(&fm->lock, flags);
4999+ fm->initialized = 0;
5000+ if (!fed)
5001+ goto out_unlock;
5002+
5003+ fm->initialized = 1;
5004+ fm->num_classes = fed->num_classes;
5005+ BUG_ON(fm->num_classes > _DRM_FENCE_CLASSES);
5006+
5007+ for (i = 0; i < fm->num_classes; ++i) {
5008+ fence_class = &fm->fence_class[i];
5009+
5010+ memset(fence_class, 0, sizeof(*fence_class));
5011+ INIT_LIST_HEAD(&fence_class->ring);
5012+ DRM_INIT_WAITQUEUE(&fence_class->fence_queue);
5013+ }
5014+
5015+ atomic_set(&fm->count, 0);
5016+ out_unlock:
5017+ write_unlock_irqrestore(&fm->lock, flags);
5018+}
5019+
5020+void drm_fence_fill_arg(struct drm_fence_object *fence,
5021+ struct drm_fence_arg *arg)
5022+{
5023+ struct drm_device *dev = fence->dev;
5024+ struct drm_fence_manager *fm = &dev->fm;
5025+ unsigned long irq_flags;
5026+
5027+ read_lock_irqsave(&fm->lock, irq_flags);
5028+ arg->handle = fence->base.hash.key;
5029+ arg->fence_class = fence->fence_class;
5030+ arg->type = fence->type;
5031+ arg->signaled = fence->signaled_types;
5032+ arg->error = fence->error;
5033+ arg->sequence = fence->sequence;
5034+ read_unlock_irqrestore(&fm->lock, irq_flags);
5035+}
5036+EXPORT_SYMBOL(drm_fence_fill_arg);
5037+
5038+void drm_fence_manager_takedown(struct drm_device *dev)
5039+{
5040+}
5041+
5042+struct drm_fence_object *drm_lookup_fence_object(struct drm_file *priv,
5043+ uint32_t handle)
5044+{
5045+ struct drm_device *dev = priv->minor->dev;
5046+ struct drm_user_object *uo;
5047+ struct drm_fence_object *fence;
5048+
5049+ mutex_lock(&dev->struct_mutex);
5050+ uo = drm_lookup_user_object(priv, handle);
5051+ if (!uo || (uo->type != drm_fence_type)) {
5052+ mutex_unlock(&dev->struct_mutex);
5053+ return NULL;
5054+ }
5055+ fence = drm_fence_reference_locked(drm_user_object_entry(uo, struct drm_fence_object, base));
5056+ mutex_unlock(&dev->struct_mutex);
5057+ return fence;
5058+}
5059+
5060+int drm_fence_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
5061+{
5062+ int ret;
5063+ struct drm_fence_manager *fm = &dev->fm;
5064+ struct drm_fence_arg *arg = data;
5065+ struct drm_fence_object *fence;
5066+ ret = 0;
5067+
5068+ if (!fm->initialized) {
5069+ DRM_ERROR("The DRM driver does not support fencing.\n");
5070+ return -EINVAL;
5071+ }
5072+
5073+ if (arg->flags & DRM_FENCE_FLAG_EMIT)
5074+ LOCK_TEST_WITH_RETURN(dev, file_priv);
5075+ ret = drm_fence_object_create(dev, arg->fence_class,
5076+ arg->type, arg->flags, &fence);
5077+ if (ret)
5078+ return ret;
5079+ ret = drm_fence_add_user_object(file_priv, fence,
5080+ arg->flags &
5081+ DRM_FENCE_FLAG_SHAREABLE);
5082+ if (ret) {
5083+ drm_fence_usage_deref_unlocked(&fence);
5084+ return ret;
5085+ }
5086+
5087+ /*
5088+ * usage > 0. No need to lock dev->struct_mutex;
5089+ */
5090+
5091+ arg->handle = fence->base.hash.key;
5092+
5093+ drm_fence_fill_arg(fence, arg);
5094+ drm_fence_usage_deref_unlocked(&fence);
5095+
5096+ return ret;
5097+}
5098+
5099+int drm_fence_reference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
5100+{
5101+ int ret;
5102+ struct drm_fence_manager *fm = &dev->fm;
5103+ struct drm_fence_arg *arg = data;
5104+ struct drm_fence_object *fence;
5105+ struct drm_user_object *uo;
5106+ ret = 0;
5107+
5108+ if (!fm->initialized) {
5109+ DRM_ERROR("The DRM driver does not support fencing.\n");
5110+ return -EINVAL;
5111+ }
5112+
5113+ ret = drm_user_object_ref(file_priv, arg->handle, drm_fence_type, &uo);
5114+ if (ret)
5115+ return ret;
5116+ fence = drm_lookup_fence_object(file_priv, arg->handle);
5117+ drm_fence_fill_arg(fence, arg);
5118+ drm_fence_usage_deref_unlocked(&fence);
5119+
5120+ return ret;
5121+}
5122+
5123+
5124+int drm_fence_unreference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
5125+{
5126+ int ret;
5127+ struct drm_fence_manager *fm = &dev->fm;
5128+ struct drm_fence_arg *arg = data;
5129+ ret = 0;
5130+
5131+ if (!fm->initialized) {
5132+ DRM_ERROR("The DRM driver does not support fencing.\n");
5133+ return -EINVAL;
5134+ }
5135+
5136+ return drm_user_object_unref(file_priv, arg->handle, drm_fence_type);
5137+}
5138+
5139+int drm_fence_signaled_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
5140+{
5141+ int ret;
5142+ struct drm_fence_manager *fm = &dev->fm;
5143+ struct drm_fence_arg *arg = data;
5144+ struct drm_fence_object *fence;
5145+ ret = 0;
5146+
5147+ if (!fm->initialized) {
5148+ DRM_ERROR("The DRM driver does not support fencing.\n");
5149+ return -EINVAL;
5150+ }
5151+
5152+ fence = drm_lookup_fence_object(file_priv, arg->handle);
5153+ if (!fence)
5154+ return -EINVAL;
5155+
5156+ drm_fence_fill_arg(fence, arg);
5157+ drm_fence_usage_deref_unlocked(&fence);
5158+
5159+ return ret;
5160+}
5161+
5162+int drm_fence_flush_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
5163+{
5164+ int ret;
5165+ struct drm_fence_manager *fm = &dev->fm;
5166+ struct drm_fence_arg *arg = data;
5167+ struct drm_fence_object *fence;
5168+ ret = 0;
5169+
5170+ if (!fm->initialized) {
5171+ DRM_ERROR("The DRM driver does not support fencing.\n");
5172+ return -EINVAL;
5173+ }
5174+
5175+ fence = drm_lookup_fence_object(file_priv, arg->handle);
5176+ if (!fence)
5177+ return -EINVAL;
5178+ ret = drm_fence_object_flush(fence, arg->type);
5179+
5180+ drm_fence_fill_arg(fence, arg);
5181+ drm_fence_usage_deref_unlocked(&fence);
5182+
5183+ return ret;
5184+}
5185+
5186+
5187+int drm_fence_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
5188+{
5189+ int ret;
5190+ struct drm_fence_manager *fm = &dev->fm;
5191+ struct drm_fence_arg *arg = data;
5192+ struct drm_fence_object *fence;
5193+ ret = 0;
5194+
5195+ if (!fm->initialized) {
5196+ DRM_ERROR("The DRM driver does not support fencing.\n");
5197+ return -EINVAL;
5198+ }
5199+
5200+ fence = drm_lookup_fence_object(file_priv, arg->handle);
5201+ if (!fence)
5202+ return -EINVAL;
5203+ ret = drm_fence_object_wait(fence,
5204+ arg->flags & DRM_FENCE_FLAG_WAIT_LAZY,
5205+ 0, arg->type);
5206+
5207+ drm_fence_fill_arg(fence, arg);
5208+ drm_fence_usage_deref_unlocked(&fence);
5209+
5210+ return ret;
5211+}
5212+
5213+
5214+int drm_fence_emit_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
5215+{
5216+ int ret;
5217+ struct drm_fence_manager *fm = &dev->fm;
5218+ struct drm_fence_arg *arg = data;
5219+ struct drm_fence_object *fence;
5220+ ret = 0;
5221+
5222+ if (!fm->initialized) {
5223+ DRM_ERROR("The DRM driver does not support fencing.\n");
5224+ return -EINVAL;
5225+ }
5226+
5227+ LOCK_TEST_WITH_RETURN(dev, file_priv);
5228+ fence = drm_lookup_fence_object(file_priv, arg->handle);
5229+ if (!fence)
5230+ return -EINVAL;
5231+ ret = drm_fence_object_emit(fence, arg->flags, arg->fence_class,
5232+ arg->type);
5233+
5234+ drm_fence_fill_arg(fence, arg);
5235+ drm_fence_usage_deref_unlocked(&fence);
5236+
5237+ return ret;
5238+}
5239+
5240+int drm_fence_buffers_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
5241+{
5242+ int ret;
5243+ struct drm_fence_manager *fm = &dev->fm;
5244+ struct drm_fence_arg *arg = data;
5245+ struct drm_fence_object *fence;
5246+ ret = 0;
5247+
5248+ if (!fm->initialized) {
5249+ DRM_ERROR("The DRM driver does not support fencing.\n");
5250+ return -EINVAL;
5251+ }
5252+
5253+ if (!dev->bm.initialized) {
5254+ DRM_ERROR("Buffer object manager is not initialized\n");
5255+ return -EINVAL;
5256+ }
5257+ LOCK_TEST_WITH_RETURN(dev, file_priv);
5258+ ret = drm_fence_buffer_objects(dev, NULL, arg->flags,
5259+ NULL, &fence);
5260+ if (ret)
5261+ return ret;
5262+
5263+ if (!(arg->flags & DRM_FENCE_FLAG_NO_USER)) {
5264+ ret = drm_fence_add_user_object(file_priv, fence,
5265+ arg->flags &
5266+ DRM_FENCE_FLAG_SHAREABLE);
5267+ if (ret)
5268+ return ret;
5269+ }
5270+
5271+ arg->handle = fence->base.hash.key;
5272+
5273+ drm_fence_fill_arg(fence, arg);
5274+ drm_fence_usage_deref_unlocked(&fence);
5275+
5276+ return ret;
5277+}
5278Index: linux-2.6.28/drivers/gpu/drm/drm_fops.c
5279===================================================================
5280--- linux-2.6.28.orig/drivers/gpu/drm/drm_fops.c 2009-02-12 09:14:37.000000000 +0000
5281+++ linux-2.6.28/drivers/gpu/drm/drm_fops.c 2009-02-12 09:14:41.000000000 +0000
5282@@ -1,3 +1,4 @@
5283+
5284 /**
5285 * \file drm_fops.c
5286 * File operations for DRM
5287@@ -232,6 +233,7 @@
5288 int minor_id = iminor(inode);
5289 struct drm_file *priv;
5290 int ret;
5291+ int i, j;
5292
5293 if (filp->f_flags & O_EXCL)
5294 return -EBUSY; /* No exclusive opens */
5295@@ -257,10 +259,24 @@
5296
5297 INIT_LIST_HEAD(&priv->lhead);
5298 INIT_LIST_HEAD(&priv->fbs);
5299+ INIT_LIST_HEAD(&priv->refd_objects);
5300
5301 if (dev->driver->driver_features & DRIVER_GEM)
5302 drm_gem_open(dev, priv);
5303
5304+ for (i = 0; i < _DRM_NO_REF_TYPES; ++i) {
5305+ ret = drm_ht_create(&priv->refd_object_hash[i],
5306+ DRM_FILE_HASH_ORDER);
5307+ if (ret)
5308+ break;
5309+ }
5310+
5311+ if (ret) {
5312+ for (j = 0; j < i; ++j)
5313+ drm_ht_remove(&priv->refd_object_hash[j]);
5314+ goto out_free;
5315+ }
5316+
5317 if (dev->driver->open) {
5318 ret = dev->driver->open(dev, priv);
5319 if (ret < 0)
5320@@ -416,6 +432,33 @@
5321 }
5322 }
5323
5324+static void drm_object_release(struct file *filp)
5325+{
5326+ struct drm_file *priv = filp->private_data;
5327+ struct list_head *head;
5328+ struct drm_ref_object *ref_object;
5329+ int i;
5330+
5331+ /*
5332+ * Free leftover ref objects created by me. Note that we cannot use
5333+ * list_for_each() here, as the struct_mutex may be temporarily
5334+ * released by the remove_() functions, and thus the lists may be
5335+ * altered.
5336+ * Also, a drm_remove_ref_object() will not remove it
5337+ * from the list unless its refcount is 1.
5338+ */
5339+
5340+ head = &priv->refd_objects;
5341+ while (head->next != head) {
5342+ ref_object = list_entry(head->next, struct drm_ref_object, list);
5343+ drm_remove_ref_object(priv, ref_object);
5344+ head = &priv->refd_objects;
5345+ }
5346+
5347+ for (i = 0; i < _DRM_NO_REF_TYPES; ++i)
5348+ drm_ht_remove(&priv->refd_object_hash[i]);
5349+}
5350+
5351 /**
5352 * Release file.
5353 *
5354Index: linux-2.6.28/drivers/gpu/drm/drm_irq.c
5355===================================================================
5356--- linux-2.6.28.orig/drivers/gpu/drm/drm_irq.c 2009-02-12 09:14:37.000000000 +0000
5357+++ linux-2.6.28/drivers/gpu/drm/drm_irq.c 2009-02-12 09:14:41.000000000 +0000
5358@@ -1,3 +1,4 @@
5359+
5360 /**
5361 * \file drm_irq.c
5362 * IRQ support
5363@@ -70,6 +71,7 @@
5364
5365 return 0;
5366 }
5367+#if 0
5368
5369 static void vblank_disable_fn(unsigned long arg)
5370 {
5371@@ -116,14 +118,12 @@
5372 dev->num_crtcs, DRM_MEM_DRIVER);
5373 drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs,
5374 DRM_MEM_DRIVER);
5375- drm_free(dev->last_vblank_wait,
5376- sizeof(*dev->last_vblank_wait) * dev->num_crtcs,
5377- DRM_MEM_DRIVER);
5378 drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) *
5379 dev->num_crtcs, DRM_MEM_DRIVER);
5380
5381 dev->num_crtcs = 0;
5382 }
5383+EXPORT_SYMBOL(drm_vblank_cleanup);
5384
5385 int drm_vblank_init(struct drm_device *dev, int num_crtcs)
5386 {
5387@@ -164,11 +164,6 @@
5388 if (!dev->last_vblank)
5389 goto err;
5390
5391- dev->last_vblank_wait = drm_calloc(num_crtcs, sizeof(u32),
5392- DRM_MEM_DRIVER);
5393- if (!dev->last_vblank_wait)
5394- goto err;
5395-
5396 dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int),
5397 DRM_MEM_DRIVER);
5398 if (!dev->vblank_inmodeset)
5399@@ -192,6 +187,8 @@
5400 }
5401 EXPORT_SYMBOL(drm_vblank_init);
5402
5403+#endif
5404+
5405 /**
5406 * Install IRQ handler.
5407 *
5408@@ -229,6 +226,17 @@
5409
5410 DRM_DEBUG("irq=%d\n", dev->pdev->irq);
5411
5412+ if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
5413+ init_waitqueue_head(&dev->vbl_queue);
5414+
5415+ spin_lock_init(&dev->vbl_lock);
5416+
5417+ INIT_LIST_HEAD(&dev->vbl_sigs);
5418+ INIT_LIST_HEAD(&dev->vbl_sigs2);
5419+
5420+ dev->vbl_pending = 0;
5421+ }
5422+
5423 /* Before installing handler */
5424 dev->driver->irq_preinstall(dev);
5425
5426@@ -238,7 +246,10 @@
5427
5428 ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler,
5429 sh_flags, dev->devname, dev);
5430-
5431+ /* Expose the device irq number to drivers that want to export it for
5432+ * whatever reason.
5433+ */
5434+ dev->irq = drm_dev_to_irq(dev);
5435 if (ret < 0) {
5436 mutex_lock(&dev->struct_mutex);
5437 dev->irq_enabled = 0;
5438@@ -267,8 +278,7 @@
5439 */
5440 int drm_irq_uninstall(struct drm_device * dev)
5441 {
5442- unsigned long irqflags;
5443- int irq_enabled, i;
5444+ int irq_enabled;
5445
5446 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
5447 return -EINVAL;
5448@@ -278,16 +288,6 @@
5449 dev->irq_enabled = 0;
5450 mutex_unlock(&dev->struct_mutex);
5451
5452- /*
5453- * Wake up any waiters so they don't hang.
5454- */
5455- spin_lock_irqsave(&dev->vbl_lock, irqflags);
5456- for (i = 0; i < dev->num_crtcs; i++) {
5457- DRM_WAKEUP(&dev->vbl_queue[i]);
5458- dev->vblank_enabled[i] = 0;
5459- }
5460- spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
5461-
5462 if (!irq_enabled)
5463 return -EINVAL;
5464
5465@@ -297,6 +297,8 @@
5466
5467 free_irq(dev->pdev->irq, dev);
5468
5469+ dev->locked_tasklet_func = NULL;
5470+
5471 return 0;
5472 }
5473 EXPORT_SYMBOL(drm_irq_uninstall);
5474@@ -342,196 +344,6 @@
5475 }
5476
5477 /**
5478- * drm_vblank_count - retrieve "cooked" vblank counter value
5479- * @dev: DRM device
5480- * @crtc: which counter to retrieve
5481- *
5482- * Fetches the "cooked" vblank count value that represents the number of
5483- * vblank events since the system was booted, including lost events due to
5484- * modesetting activity.
5485- */
5486-u32 drm_vblank_count(struct drm_device *dev, int crtc)
5487-{
5488- return atomic_read(&dev->_vblank_count[crtc]);
5489-}
5490-EXPORT_SYMBOL(drm_vblank_count);
5491-
5492-/**
5493- * drm_update_vblank_count - update the master vblank counter
5494- * @dev: DRM device
5495- * @crtc: counter to update
5496- *
5497- * Call back into the driver to update the appropriate vblank counter
5498- * (specified by @crtc). Deal with wraparound, if it occurred, and
5499- * update the last read value so we can deal with wraparound on the next
5500- * call if necessary.
5501- *
5502- * Only necessary when going from off->on, to account for frames we
5503- * didn't get an interrupt for.
5504- *
5505- * Note: caller must hold dev->vbl_lock since this reads & writes
5506- * device vblank fields.
5507- */
5508-static void drm_update_vblank_count(struct drm_device *dev, int crtc)
5509-{
5510- u32 cur_vblank, diff;
5511-
5512- /*
5513- * Interrupts were disabled prior to this call, so deal with counter
5514- * wrap if needed.
5515- * NOTE! It's possible we lost a full dev->max_vblank_count events
5516- * here if the register is small or we had vblank interrupts off for
5517- * a long time.
5518- */
5519- cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
5520- diff = cur_vblank - dev->last_vblank[crtc];
5521- if (cur_vblank < dev->last_vblank[crtc]) {
5522- diff += dev->max_vblank_count;
5523-
5524- DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
5525- crtc, dev->last_vblank[crtc], cur_vblank, diff);
5526- }
5527-
5528- DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
5529- crtc, diff);
5530-
5531- atomic_add(diff, &dev->_vblank_count[crtc]);
5532-}
5533-
5534-/**
5535- * drm_vblank_get - get a reference count on vblank events
5536- * @dev: DRM device
5537- * @crtc: which CRTC to own
5538- *
5539- * Acquire a reference count on vblank events to avoid having them disabled
5540- * while in use.
5541- *
5542- * RETURNS
5543- * Zero on success, nonzero on failure.
5544- */
5545-int drm_vblank_get(struct drm_device *dev, int crtc)
5546-{
5547- unsigned long irqflags;
5548- int ret = 0;
5549-
5550- spin_lock_irqsave(&dev->vbl_lock, irqflags);
5551- /* Going from 0->1 means we have to enable interrupts again */
5552- if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 &&
5553- !dev->vblank_enabled[crtc]) {
5554- ret = dev->driver->enable_vblank(dev, crtc);
5555- DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
5556- if (ret)
5557- atomic_dec(&dev->vblank_refcount[crtc]);
5558- else {
5559- dev->vblank_enabled[crtc] = 1;
5560- drm_update_vblank_count(dev, crtc);
5561- }
5562- }
5563- spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
5564-
5565- return ret;
5566-}
5567-EXPORT_SYMBOL(drm_vblank_get);
5568-
5569-/**
5570- * drm_vblank_put - give up ownership of vblank events
5571- * @dev: DRM device
5572- * @crtc: which counter to give up
5573- *
5574- * Release ownership of a given vblank counter, turning off interrupts
5575- * if possible.
5576- */
5577-void drm_vblank_put(struct drm_device *dev, int crtc)
5578-{
5579- /* Last user schedules interrupt disable */
5580- if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
5581- mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
5582-}
5583-EXPORT_SYMBOL(drm_vblank_put);
5584-
5585-/**
5586- * drm_vblank_pre_modeset - account for vblanks across mode sets
5587- * @dev: DRM device
5588- * @crtc: CRTC in question
5589- * @post: post or pre mode set?
5590- *
5591- * Account for vblank events across mode setting events, which will likely
5592- * reset the hardware frame counter.
5593- */
5594-void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
5595-{
5596- /*
5597- * To avoid all the problems that might happen if interrupts
5598- * were enabled/disabled around or between these calls, we just
5599- * have the kernel take a reference on the CRTC (just once though
5600- * to avoid corrupting the count if multiple, mismatch calls occur),
5601- * so that interrupts remain enabled in the interim.
5602- */
5603- if (!dev->vblank_inmodeset[crtc]) {
5604- dev->vblank_inmodeset[crtc] = 1;
5605- drm_vblank_get(dev, crtc);
5606- }
5607-}
5608-EXPORT_SYMBOL(drm_vblank_pre_modeset);
5609-
5610-void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
5611-{
5612- unsigned long irqflags;
5613-
5614- if (dev->vblank_inmodeset[crtc]) {
5615- spin_lock_irqsave(&dev->vbl_lock, irqflags);
5616- dev->vblank_disable_allowed = 1;
5617- dev->vblank_inmodeset[crtc] = 0;
5618- spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
5619- drm_vblank_put(dev, crtc);
5620- }
5621-}
5622-EXPORT_SYMBOL(drm_vblank_post_modeset);
5623-
5624-/**
5625- * drm_modeset_ctl - handle vblank event counter changes across mode switch
5626- * @DRM_IOCTL_ARGS: standard ioctl arguments
5627- *
5628- * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
5629- * ioctls around modesetting so that any lost vblank events are accounted for.
5630- *
5631- * Generally the counter will reset across mode sets. If interrupts are
5632- * enabled around this call, we don't have to do anything since the counter
5633- * will have already been incremented.
5634- */
5635-int drm_modeset_ctl(struct drm_device *dev, void *data,
5636- struct drm_file *file_priv)
5637-{
5638- struct drm_modeset_ctl *modeset = data;
5639- int crtc, ret = 0;
5640-
5641- /* If drm_vblank_init() hasn't been called yet, just no-op */
5642- if (!dev->num_crtcs)
5643- goto out;
5644-
5645- crtc = modeset->crtc;
5646- if (crtc >= dev->num_crtcs) {
5647- ret = -EINVAL;
5648- goto out;
5649- }
5650-
5651- switch (modeset->cmd) {
5652- case _DRM_PRE_MODESET:
5653- drm_vblank_pre_modeset(dev, crtc);
5654- break;
5655- case _DRM_POST_MODESET:
5656- drm_vblank_post_modeset(dev, crtc);
5657- break;
5658- default:
5659- ret = -EINVAL;
5660- break;
5661- }
5662-
5663-out:
5664- return ret;
5665-}
5666-
5667-/**
5668 * Wait for VBLANK.
5669 *
5670 * \param inode device inode.
5671@@ -550,14 +362,14 @@
5672 *
5673 * If a signal is not requested, then calls vblank_wait().
5674 */
5675-int drm_wait_vblank(struct drm_device *dev, void *data,
5676- struct drm_file *file_priv)
5677+int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv)
5678 {
5679 union drm_wait_vblank *vblwait = data;
5680+ struct timeval now;
5681 int ret = 0;
5682- unsigned int flags, seq, crtc;
5683+ unsigned int flags, seq;
5684
5685- if ((!dev->pdev->irq) || (!dev->irq_enabled))
5686+ if ((!dev->irq) || (!dev->irq_enabled))
5687 return -EINVAL;
5688
5689 if (vblwait->request.type &
5690@@ -569,17 +381,13 @@
5691 }
5692
5693 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
5694- crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
5695
5696- if (crtc >= dev->num_crtcs)
5697+ if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ?
5698+ DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
5699 return -EINVAL;
5700
5701- ret = drm_vblank_get(dev, crtc);
5702- if (ret) {
5703- DRM_ERROR("failed to acquire vblank counter, %d\n", ret);
5704- return ret;
5705- }
5706- seq = drm_vblank_count(dev, crtc);
5707+ seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2
5708+ : &dev->vbl_received);
5709
5710 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
5711 case _DRM_VBLANK_RELATIVE:
5712@@ -588,8 +396,7 @@
5713 case _DRM_VBLANK_ABSOLUTE:
5714 break;
5715 default:
5716- ret = -EINVAL;
5717- goto done;
5718+ return -EINVAL;
5719 }
5720
5721 if ((flags & _DRM_VBLANK_NEXTONMISS) &&
5722@@ -599,7 +406,8 @@
5723
5724 if (flags & _DRM_VBLANK_SIGNAL) {
5725 unsigned long irqflags;
5726- struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
5727+ struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY)
5728+ ? &dev->vbl_sigs2 : &dev->vbl_sigs;
5729 struct drm_vbl_sig *vbl_sig;
5730
5731 spin_lock_irqsave(&dev->vbl_lock, irqflags);
5732@@ -620,32 +428,22 @@
5733 }
5734 }
5735
5736- if (atomic_read(&dev->vbl_signal_pending) >= 100) {
5737+ if (dev->vbl_pending >= 100) {
5738 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
5739- ret = -EBUSY;
5740- goto done;
5741+ return -EBUSY;
5742 }
5743
5744- spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
5745+ dev->vbl_pending++;
5746
5747- vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
5748- DRM_MEM_DRIVER);
5749- if (!vbl_sig) {
5750- ret = -ENOMEM;
5751- goto done;
5752- }
5753+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
5754
5755- /* Get a refcount on the vblank, which will be released by
5756- * drm_vbl_send_signals().
5757- */
5758- ret = drm_vblank_get(dev, crtc);
5759- if (ret) {
5760- drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
5761- DRM_MEM_DRIVER);
5762- goto done;
5763+ if (!
5764+ (vbl_sig =
5765+ drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) {
5766+ return -ENOMEM;
5767 }
5768
5769- atomic_inc(&dev->vbl_signal_pending);
5770+ memset((void *)vbl_sig, 0, sizeof(*vbl_sig));
5771
5772 vbl_sig->sequence = vblwait->request.sequence;
5773 vbl_sig->info.si_signo = vblwait->request.signal;
5774@@ -659,31 +457,20 @@
5775
5776 vblwait->reply.sequence = seq;
5777 } else {
5778- DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
5779- vblwait->request.sequence, crtc);
5780- dev->last_vblank_wait[crtc] = vblwait->request.sequence;
5781- DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
5782- (((drm_vblank_count(dev, crtc) -
5783- vblwait->request.sequence) <= (1 << 23)) ||
5784- !dev->irq_enabled));
5785-
5786- if (ret != -EINTR) {
5787- struct timeval now;
5788-
5789- do_gettimeofday(&now);
5790-
5791- vblwait->reply.tval_sec = now.tv_sec;
5792- vblwait->reply.tval_usec = now.tv_usec;
5793- vblwait->reply.sequence = drm_vblank_count(dev, crtc);
5794- DRM_DEBUG("returning %d to client\n",
5795- vblwait->reply.sequence);
5796- } else {
5797- DRM_DEBUG("vblank wait interrupted by signal\n");
5798- }
5799+ if (flags & _DRM_VBLANK_SECONDARY) {
5800+ if (dev->driver->vblank_wait2)
5801+ ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence);
5802+ } else if (dev->driver->vblank_wait)
5803+ ret =
5804+ dev->driver->vblank_wait(dev,
5805+ &vblwait->request.sequence);
5806+
5807+ do_gettimeofday(&now);
5808+ vblwait->reply.tval_sec = now.tv_sec;
5809+ vblwait->reply.tval_usec = now.tv_usec;
5810 }
5811
5812-done:
5813- drm_vblank_put(dev, crtc);
5814+ done:
5815 return ret;
5816 }
5817
5818@@ -691,54 +478,118 @@
5819 * Send the VBLANK signals.
5820 *
5821 * \param dev DRM device.
5822- * \param crtc CRTC where the vblank event occurred
5823 *
5824 * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
5825 *
5826 * If a signal is not requested, then calls vblank_wait().
5827 */
5828-static void drm_vbl_send_signals(struct drm_device *dev, int crtc)
5829+void drm_vbl_send_signals(struct drm_device * dev)
5830 {
5831- struct drm_vbl_sig *vbl_sig, *tmp;
5832- struct list_head *vbl_sigs;
5833- unsigned int vbl_seq;
5834 unsigned long flags;
5835+ int i;
5836
5837 spin_lock_irqsave(&dev->vbl_lock, flags);
5838
5839- vbl_sigs = &dev->vbl_sigs[crtc];
5840- vbl_seq = drm_vblank_count(dev, crtc);
5841+ for (i = 0; i < 2; i++) {
5842+ struct drm_vbl_sig *vbl_sig, *tmp;
5843+ struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs;
5844+ unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 :
5845+ &dev->vbl_received);
5846+
5847+ list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
5848+ if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
5849+ vbl_sig->info.si_code = vbl_seq;
5850+ send_sig_info(vbl_sig->info.si_signo,
5851+ &vbl_sig->info, vbl_sig->task);
5852
5853- list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
5854- if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
5855- vbl_sig->info.si_code = vbl_seq;
5856- send_sig_info(vbl_sig->info.si_signo,
5857- &vbl_sig->info, vbl_sig->task);
5858-
5859- list_del(&vbl_sig->head);
5860-
5861- drm_free(vbl_sig, sizeof(*vbl_sig),
5862- DRM_MEM_DRIVER);
5863- atomic_dec(&dev->vbl_signal_pending);
5864- drm_vblank_put(dev, crtc);
5865- }
5866+ list_del(&vbl_sig->head);
5867+
5868+ drm_free(vbl_sig, sizeof(*vbl_sig),
5869+ DRM_MEM_DRIVER);
5870+
5871+ dev->vbl_pending--;
5872+ }
5873+ }
5874 }
5875
5876 spin_unlock_irqrestore(&dev->vbl_lock, flags);
5877 }
5878+EXPORT_SYMBOL(drm_vbl_send_signals);
5879
5880 /**
5881- * drm_handle_vblank - handle a vblank event
5882- * @dev: DRM device
5883- * @crtc: where this event occurred
5884+ * Tasklet wrapper function.
5885 *
5886- * Drivers should call this routine in their vblank interrupt handlers to
5887- * update the vblank counter and send any signals that may be pending.
5888+ * \param data DRM device in disguise.
5889+ *
5890+ * Attempts to grab the HW lock and calls the driver callback on success. On
5891+ * failure, leave the lock marked as contended so the callback can be called
5892+ * from drm_unlock().
5893 */
5894-void drm_handle_vblank(struct drm_device *dev, int crtc)
5895+static void drm_locked_tasklet_func(unsigned long data)
5896 {
5897- atomic_inc(&dev->_vblank_count[crtc]);
5898- DRM_WAKEUP(&dev->vbl_queue[crtc]);
5899- drm_vbl_send_signals(dev, crtc);
5900+ struct drm_device *dev = (struct drm_device *)data;
5901+ unsigned long irqflags;
5902+ void (*tasklet_func)(struct drm_device *);
5903+
5904+ spin_lock_irqsave(&dev->tasklet_lock, irqflags);
5905+ tasklet_func = dev->locked_tasklet_func;
5906+ spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
5907+
5908+ if (!tasklet_func ||
5909+ !drm_lock_take(&dev->lock,
5910+ DRM_KERNEL_CONTEXT)) {
5911+ return;
5912+ }
5913+
5914+ dev->lock.lock_time = jiffies;
5915+ atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
5916+
5917+ spin_lock_irqsave(&dev->tasklet_lock, irqflags);
5918+ tasklet_func = dev->locked_tasklet_func;
5919+ dev->locked_tasklet_func = NULL;
5920+ spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
5921+
5922+ if (tasklet_func != NULL)
5923+ tasklet_func(dev);
5924+
5925+ drm_lock_free(&dev->lock,
5926+ DRM_KERNEL_CONTEXT);
5927+}
5928+
5929+/**
5930+ * Schedule a tasklet to call back a driver hook with the HW lock held.
5931+ *
5932+ * \param dev DRM device.
5933+ * \param func Driver callback.
5934+ *
5935+ * This is intended for triggering actions that require the HW lock from an
5936+ * interrupt handler. The lock will be grabbed ASAP after the interrupt handler
5937+ * completes. Note that the callback may be called from interrupt or process
5938+ * context, it must not make any assumptions about this. Also, the HW lock will
5939+ * be held with the kernel context or any client context.
5940+ */
5941+void drm_locked_tasklet(struct drm_device *dev, void (*func)(struct drm_device *))
5942+{
5943+ unsigned long irqflags;
5944+ static DECLARE_TASKLET(drm_tasklet, drm_locked_tasklet_func, 0);
5945+
5946+ if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ) ||
5947+ test_bit(TASKLET_STATE_SCHED, &drm_tasklet.state))
5948+ return;
5949+
5950+ spin_lock_irqsave(&dev->tasklet_lock, irqflags);
5951+
5952+ if (dev->locked_tasklet_func) {
5953+ spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
5954+ return;
5955+ }
5956+
5957+ dev->locked_tasklet_func = func;
5958+
5959+ spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
5960+
5961+ drm_tasklet.data = (unsigned long)dev;
5962+
5963+ tasklet_hi_schedule(&drm_tasklet);
5964 }
5965-EXPORT_SYMBOL(drm_handle_vblank);
5966+EXPORT_SYMBOL(drm_locked_tasklet);
5967Index: linux-2.6.28/drivers/gpu/drm/drm_object.c
5968===================================================================
5969--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5970+++ linux-2.6.28/drivers/gpu/drm/drm_object.c 2009-02-12 09:14:41.000000000 +0000
5971@@ -0,0 +1,294 @@
5972+/**************************************************************************
5973+ *
5974+ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
5975+ * All Rights Reserved.
5976+ *
5977+ * Permission is hereby granted, free of charge, to any person obtaining a
5978+ * copy of this software and associated documentation files (the
5979+ * "Software"), to deal in the Software without restriction, including
5980+ * without limitation the rights to use, copy, modify, merge, publish,
5981+ * distribute, sub license, and/or sell copies of the Software, and to
5982+ * permit persons to whom the Software is furnished to do so, subject to
5983+ * the following conditions:
5984+ *
5985+ * The above copyright notice and this permission notice (including the
5986+ * next paragraph) shall be included in all copies or substantial portions
5987+ * of the Software.
5988+ *
5989+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5990+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5991+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
5992+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
5993+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
5994+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
5995+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
5996+ *
5997+ **************************************************************************/
5998+/*
5999+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
6000+ */
6001+
6002+#include "drmP.h"
6003+
6004+int drm_add_user_object(struct drm_file *priv, struct drm_user_object *item,
6005+ int shareable)
6006+{
6007+ struct drm_device *dev = priv->minor->dev;
6008+ int ret;
6009+
6010+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
6011+
6012+ /* The refcount will be bumped to 1 when we add the ref object below. */
6013+ atomic_set(&item->refcount, 0);
6014+ item->shareable = shareable;
6015+ item->owner = priv;
6016+
6017+ ret = drm_ht_just_insert_please(&dev->object_hash, &item->hash,
6018+ (unsigned long)item, 32, 0, 0);
6019+ if (ret)
6020+ return ret;
6021+
6022+ ret = drm_add_ref_object(priv, item, _DRM_REF_USE);
6023+ if (ret)
6024+ ret = drm_ht_remove_item(&dev->object_hash, &item->hash);
6025+
6026+ return ret;
6027+}
6028+EXPORT_SYMBOL(drm_add_user_object);
6029+
6030+struct drm_user_object *drm_lookup_user_object(struct drm_file *priv, uint32_t key)
6031+{
6032+ struct drm_device *dev = priv->minor->dev;
6033+ struct drm_hash_item *hash;
6034+ int ret;
6035+ struct drm_user_object *item;
6036+
6037+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
6038+
6039+ ret = drm_ht_find_item(&dev->object_hash, key, &hash);
6040+ if (ret)
6041+ return NULL;
6042+
6043+ item = drm_hash_entry(hash, struct drm_user_object, hash);
6044+
6045+ if (priv != item->owner) {
6046+ struct drm_open_hash *ht = &priv->refd_object_hash[_DRM_REF_USE];
6047+ ret = drm_ht_find_item(ht, (unsigned long)item, &hash);
6048+ if (ret) {
6049+ DRM_ERROR("Object not registered for usage\n");
6050+ return NULL;
6051+ }
6052+ }
6053+ return item;
6054+}
6055+EXPORT_SYMBOL(drm_lookup_user_object);
6056+
6057+static void drm_deref_user_object(struct drm_file *priv, struct drm_user_object *item)
6058+{
6059+ struct drm_device *dev = priv->minor->dev;
6060+ int ret;
6061+
6062+ if (atomic_dec_and_test(&item->refcount)) {
6063+ ret = drm_ht_remove_item(&dev->object_hash, &item->hash);
6064+ BUG_ON(ret);
6065+ item->remove(priv, item);
6066+ }
6067+}
6068+
6069+static int drm_object_ref_action(struct drm_file *priv, struct drm_user_object *ro,
6070+ enum drm_ref_type action)
6071+{
6072+ int ret = 0;
6073+
6074+ switch (action) {
6075+ case _DRM_REF_USE:
6076+ atomic_inc(&ro->refcount);
6077+ break;
6078+ default:
6079+ if (!ro->ref_struct_locked) {
6080+ break;
6081+ } else {
6082+ ro->ref_struct_locked(priv, ro, action);
6083+ }
6084+ }
6085+ return ret;
6086+}
6087+
6088+int drm_add_ref_object(struct drm_file *priv, struct drm_user_object *referenced_object,
6089+ enum drm_ref_type ref_action)
6090+{
6091+ int ret = 0;
6092+ struct drm_ref_object *item;
6093+ struct drm_open_hash *ht = &priv->refd_object_hash[ref_action];
6094+
6095+ DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex);
6096+ if (!referenced_object->shareable && priv != referenced_object->owner) {
6097+ DRM_ERROR("Not allowed to reference this object\n");
6098+ return -EINVAL;
6099+ }
6100+
6101+ /*
6102+ * If this is not a usage reference, Check that usage has been registered
6103+ * first. Otherwise strange things may happen on destruction.
6104+ */
6105+
6106+ if ((ref_action != _DRM_REF_USE) && priv != referenced_object->owner) {
6107+ item =
6108+ drm_lookup_ref_object(priv, referenced_object,
6109+ _DRM_REF_USE);
6110+ if (!item) {
6111+ DRM_ERROR
6112+ ("Object not registered for usage by this client\n");
6113+ return -EINVAL;
6114+ }
6115+ }
6116+
6117+ if (NULL !=
6118+ (item =
6119+ drm_lookup_ref_object(priv, referenced_object, ref_action))) {
6120+ atomic_inc(&item->refcount);
6121+ return drm_object_ref_action(priv, referenced_object,
6122+ ref_action);
6123+ }
6124+
6125+ item = drm_calloc(1, sizeof(*item), DRM_MEM_OBJECTS);
6126+ if (item == NULL) {
6127+ DRM_ERROR("Could not allocate reference object\n");
6128+ return -ENOMEM;
6129+ }
6130+
6131+ atomic_set(&item->refcount, 1);
6132+ item->hash.key = (unsigned long)referenced_object;
6133+ ret = drm_ht_insert_item(ht, &item->hash);
6134+ item->unref_action = ref_action;
6135+
6136+ if (ret)
6137+ goto out;
6138+
6139+ list_add(&item->list, &priv->refd_objects);
6140+ ret = drm_object_ref_action(priv, referenced_object, ref_action);
6141+out:
6142+ return ret;
6143+}
6144+
6145+struct drm_ref_object *drm_lookup_ref_object(struct drm_file *priv,
6146+ struct drm_user_object *referenced_object,
6147+ enum drm_ref_type ref_action)
6148+{
6149+ struct drm_hash_item *hash;
6150+ int ret;
6151+
6152+ DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex);
6153+ ret = drm_ht_find_item(&priv->refd_object_hash[ref_action],
6154+ (unsigned long)referenced_object, &hash);
6155+ if (ret)
6156+ return NULL;
6157+
6158+ return drm_hash_entry(hash, struct drm_ref_object, hash);
6159+}
6160+EXPORT_SYMBOL(drm_lookup_ref_object);
6161+
6162+static void drm_remove_other_references(struct drm_file *priv,
6163+ struct drm_user_object *ro)
6164+{
6165+ int i;
6166+ struct drm_open_hash *ht;
6167+ struct drm_hash_item *hash;
6168+ struct drm_ref_object *item;
6169+
6170+ for (i = _DRM_REF_USE + 1; i < _DRM_NO_REF_TYPES; ++i) {
6171+ ht = &priv->refd_object_hash[i];
6172+ while (!drm_ht_find_item(ht, (unsigned long)ro, &hash)) {
6173+ item = drm_hash_entry(hash, struct drm_ref_object, hash);
6174+ drm_remove_ref_object(priv, item);
6175+ }
6176+ }
6177+}
6178+
6179+void drm_remove_ref_object(struct drm_file *priv, struct drm_ref_object *item)
6180+{
6181+ int ret;
6182+ struct drm_user_object *user_object = (struct drm_user_object *) item->hash.key;
6183+ struct drm_open_hash *ht = &priv->refd_object_hash[item->unref_action];
6184+ enum drm_ref_type unref_action;
6185+
6186+ DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex);
6187+ unref_action = item->unref_action;
6188+ if (atomic_dec_and_test(&item->refcount)) {
6189+ ret = drm_ht_remove_item(ht, &item->hash);
6190+ BUG_ON(ret);
6191+ list_del_init(&item->list);
6192+ if (unref_action == _DRM_REF_USE)
6193+ drm_remove_other_references(priv, user_object);
6194+ drm_free(item, sizeof(*item), DRM_MEM_OBJECTS);
6195+ }
6196+
6197+ switch (unref_action) {
6198+ case _DRM_REF_USE:
6199+ drm_deref_user_object(priv, user_object);
6200+ break;
6201+ default:
6202+ BUG_ON(!user_object->unref);
6203+ user_object->unref(priv, user_object, unref_action);
6204+ break;
6205+ }
6206+
6207+}
6208+EXPORT_SYMBOL(drm_remove_ref_object);
6209+
6210+int drm_user_object_ref(struct drm_file *priv, uint32_t user_token,
6211+ enum drm_object_type type, struct drm_user_object **object)
6212+{
6213+ struct drm_device *dev = priv->minor->dev;
6214+ struct drm_user_object *uo;
6215+ struct drm_hash_item *hash;
6216+ int ret;
6217+
6218+ mutex_lock(&dev->struct_mutex);
6219+ ret = drm_ht_find_item(&dev->object_hash, user_token, &hash);
6220+ if (ret) {
6221+ DRM_ERROR("Could not find user object to reference.\n");
6222+ goto out_err;
6223+ }
6224+ uo = drm_hash_entry(hash, struct drm_user_object, hash);
6225+ if (uo->type != type) {
6226+ ret = -EINVAL;
6227+ goto out_err;
6228+ }
6229+ ret = drm_add_ref_object(priv, uo, _DRM_REF_USE);
6230+ if (ret)
6231+ goto out_err;
6232+ mutex_unlock(&dev->struct_mutex);
6233+ *object = uo;
6234+ return 0;
6235+out_err:
6236+ mutex_unlock(&dev->struct_mutex);
6237+ return ret;
6238+}
6239+
6240+int drm_user_object_unref(struct drm_file *priv, uint32_t user_token,
6241+ enum drm_object_type type)
6242+{
6243+ struct drm_device *dev = priv->minor->dev;
6244+ struct drm_user_object *uo;
6245+ struct drm_ref_object *ro;
6246+ int ret;
6247+
6248+ mutex_lock(&dev->struct_mutex);
6249+ uo = drm_lookup_user_object(priv, user_token);
6250+ if (!uo || (uo->type != type)) {
6251+ ret = -EINVAL;
6252+ goto out_err;
6253+ }
6254+ ro = drm_lookup_ref_object(priv, uo, _DRM_REF_USE);
6255+ if (!ro) {
6256+ ret = -EINVAL;
6257+ goto out_err;
6258+ }
6259+ drm_remove_ref_object(priv, ro);
6260+ mutex_unlock(&dev->struct_mutex);
6261+ return 0;
6262+out_err:
6263+ mutex_unlock(&dev->struct_mutex);
6264+ return ret;
6265+}
6266Index: linux-2.6.28/drivers/gpu/drm/drm_regman.c
6267===================================================================
6268--- /dev/null 1970-01-01 00:00:00.000000000 +0000
6269+++ linux-2.6.28/drivers/gpu/drm/drm_regman.c 2009-02-12 09:14:41.000000000 +0000
6270@@ -0,0 +1,200 @@
6271+/**************************************************************************
6272+ * Copyright (c) 2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
6273+ * All Rights Reserved.
6274+ *
6275+ * Permission is hereby granted, free of charge, to any person obtaining a
6276+ * copy of this software and associated documentation files (the
6277+ * "Software"), to deal in the Software without restriction, including
6278+ * without limitation the rights to use, copy, modify, merge, publish,
6279+ * distribute, sub license, and/or sell copies of the Software, and to
6280+ * permit persons to whom the Software is furnished to do so, subject to
6281+ * the following conditions:
6282+ *
6283+ * The above copyright notice and this permission notice (including the
6284+ * next paragraph) shall be included in all copies or substantial portions
6285+ * of the Software.
6286+ *
6287+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6288+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6289+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
6290+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
6291+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
6292+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
6293+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
6294+ *
6295+ **************************************************************************/
6296+/*
6297+ * An allocate-fence manager implementation intended for sets of base-registers
6298+ * or tiling-registers.
6299+ */
6300+
6301+#include "drmP.h"
6302+
6303+/*
6304+ * Allocate a compatible register and put it on the unfenced list.
6305+ */
6306+
6307+int drm_regs_alloc(struct drm_reg_manager *manager,
6308+ const void *data,
6309+ uint32_t fence_class,
6310+ uint32_t fence_type,
6311+ int interruptible, int no_wait, struct drm_reg **reg)
6312+{
6313+ struct drm_reg *entry, *next_entry;
6314+ int ret;
6315+
6316+ *reg = NULL;
6317+
6318+ /*
6319+ * Search the unfenced list.
6320+ */
6321+
6322+ list_for_each_entry(entry, &manager->unfenced, head) {
6323+ if (manager->reg_reusable(entry, data)) {
6324+ entry->new_fence_type |= fence_type;
6325+ goto out;
6326+ }
6327+ }
6328+
6329+ /*
6330+ * Search the lru list.
6331+ */
6332+
6333+ list_for_each_entry_safe(entry, next_entry, &manager->lru, head) {
6334+ struct drm_fence_object *fence = entry->fence;
6335+ if (fence->fence_class == fence_class &&
6336+ (entry->fence_type & fence_type) == entry->fence_type &&
6337+ manager->reg_reusable(entry, data)) {
6338+ list_del(&entry->head);
6339+ entry->new_fence_type = fence_type;
6340+ list_add_tail(&entry->head, &manager->unfenced);
6341+ goto out;
6342+ }
6343+ }
6344+
6345+ /*
6346+ * Search the free list.
6347+ */
6348+
6349+ list_for_each_entry(entry, &manager->free, head) {
6350+ list_del(&entry->head);
6351+ entry->new_fence_type = fence_type;
6352+ list_add_tail(&entry->head, &manager->unfenced);
6353+ goto out;
6354+ }
6355+
6356+ if (no_wait)
6357+ return -EBUSY;
6358+
6359+ /*
6360+ * Go back to the lru list and try to expire fences.
6361+ */
6362+
6363+ list_for_each_entry_safe(entry, next_entry, &manager->lru, head) {
6364+ BUG_ON(!entry->fence);
6365+ ret = drm_fence_object_wait(entry->fence, 0, !interruptible,
6366+ entry->fence_type);
6367+ if (ret)
6368+ return ret;
6369+
6370+ drm_fence_usage_deref_unlocked(&entry->fence);
6371+ list_del(&entry->head);
6372+ entry->new_fence_type = fence_type;
6373+ list_add_tail(&entry->head, &manager->unfenced);
6374+ goto out;
6375+ }
6376+
6377+ /*
6378+ * Oops. All registers are used up :(.
6379+ */
6380+
6381+ return -EBUSY;
6382+out:
6383+ *reg = entry;
6384+ return 0;
6385+}
6386+EXPORT_SYMBOL(drm_regs_alloc);
6387+
6388+void drm_regs_fence(struct drm_reg_manager *manager,
6389+ struct drm_fence_object *fence)
6390+{
6391+ struct drm_reg *entry;
6392+ struct drm_reg *next_entry;
6393+
6394+ if (!fence) {
6395+
6396+ /*
6397+ * Old fence (if any) is still valid.
6398+ * Put back on free and lru lists.
6399+ */
6400+
6401+ list_for_each_entry_safe_reverse(entry, next_entry,
6402+ &manager->unfenced, head) {
6403+ list_del(&entry->head);
6404+ list_add(&entry->head, (entry->fence) ?
6405+ &manager->lru : &manager->free);
6406+ }
6407+ } else {
6408+
6409+ /*
6410+ * Fence with a new fence and put on lru list.
6411+ */
6412+
6413+ list_for_each_entry_safe(entry, next_entry, &manager->unfenced,
6414+ head) {
6415+ list_del(&entry->head);
6416+ if (entry->fence)
6417+ drm_fence_usage_deref_unlocked(&entry->fence);
6418+ drm_fence_reference_unlocked(&entry->fence, fence);
6419+
6420+ entry->fence_type = entry->new_fence_type;
6421+ BUG_ON((entry->fence_type & fence->type) !=
6422+ entry->fence_type);
6423+
6424+ list_add_tail(&entry->head, &manager->lru);
6425+ }
6426+ }
6427+}
6428+EXPORT_SYMBOL(drm_regs_fence);
6429+
6430+void drm_regs_free(struct drm_reg_manager *manager)
6431+{
6432+ struct drm_reg *entry;
6433+ struct drm_reg *next_entry;
6434+
6435+ drm_regs_fence(manager, NULL);
6436+
6437+ list_for_each_entry_safe(entry, next_entry, &manager->free, head) {
6438+ list_del(&entry->head);
6439+ manager->reg_destroy(entry);
6440+ }
6441+
6442+ list_for_each_entry_safe(entry, next_entry, &manager->lru, head) {
6443+
6444+ (void)drm_fence_object_wait(entry->fence, 1, 1,
6445+ entry->fence_type);
6446+ list_del(&entry->head);
6447+ drm_fence_usage_deref_unlocked(&entry->fence);
6448+ manager->reg_destroy(entry);
6449+ }
6450+}
6451+EXPORT_SYMBOL(drm_regs_free);
6452+
6453+void drm_regs_add(struct drm_reg_manager *manager, struct drm_reg *reg)
6454+{
6455+ reg->fence = NULL;
6456+ list_add_tail(&reg->head, &manager->free);
6457+}
6458+EXPORT_SYMBOL(drm_regs_add);
6459+
6460+void drm_regs_init(struct drm_reg_manager *manager,
6461+ int (*reg_reusable) (const struct drm_reg *, const void *),
6462+ void (*reg_destroy) (struct drm_reg *))
6463+{
6464+ INIT_LIST_HEAD(&manager->free);
6465+ INIT_LIST_HEAD(&manager->lru);
6466+ INIT_LIST_HEAD(&manager->unfenced);
6467+ manager->reg_reusable = reg_reusable;
6468+ manager->reg_destroy = reg_destroy;
6469+}
6470+EXPORT_SYMBOL(drm_regs_init);
6471Index: linux-2.6.28/drivers/gpu/drm/drm_stub.c
6472===================================================================
6473--- linux-2.6.28.orig/drivers/gpu/drm/drm_stub.c 2009-02-12 09:14:37.000000000 +0000
6474+++ linux-2.6.28/drivers/gpu/drm/drm_stub.c 2009-02-12 09:14:41.000000000 +0000
6475@@ -201,6 +201,7 @@
6476 init_timer(&dev->timer);
6477 mutex_init(&dev->struct_mutex);
6478 mutex_init(&dev->ctxlist_mutex);
6479+ mutex_init(&dev->bm.evict_mutex);
6480
6481 idr_init(&dev->drw_idr);
6482
6483@@ -216,6 +217,18 @@
6484 return -ENOMEM;
6485 }
6486
6487+ if (drm_mm_init(&dev->offset_manager, DRM_FILE_PAGE_OFFSET_START,
6488+ DRM_FILE_PAGE_OFFSET_SIZE)) {
6489+ drm_ht_remove(&dev->map_hash);
6490+ return -ENOMEM;
6491+ }
6492+
6493+ if (drm_ht_create(&dev->object_hash, DRM_OBJECT_HASH_ORDER)) {
6494+ drm_ht_remove(&dev->map_hash);
6495+ drm_mm_takedown(&dev->offset_manager);
6496+ return -ENOMEM;
6497+ }
6498+
6499 /* the DRM has 6 basic counters */
6500 dev->counters = 6;
6501 dev->types[0] = _DRM_STAT_LOCK;
6502@@ -252,15 +265,7 @@
6503 goto error_out_unreg;
6504 }
6505
6506- if (driver->driver_features & DRIVER_GEM) {
6507- retcode = drm_gem_init(dev);
6508- if (retcode) {
6509- DRM_ERROR("Cannot initialize graphics execution "
6510- "manager (GEM)\n");
6511- goto error_out_unreg;
6512- }
6513- }
6514-
6515+ drm_fence_manager_init(dev);
6516 return 0;
6517
6518 error_out_unreg:
6519@@ -386,13 +391,6 @@
6520 goto err_g3;
6521 }
6522
6523- /* setup the grouping for the legacy output */
6524- if (drm_core_check_feature(dev, DRIVER_MODESET)) {
6525- ret = drm_mode_group_init_legacy_group(dev, &dev->primary->mode_group);
6526- if (ret)
6527- goto err_g3;
6528- }
6529-
6530 list_add_tail(&dev->driver_item, &driver->device_list);
6531
6532 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
6533@@ -409,6 +407,8 @@
6534 drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
6535 return ret;
6536 }
6537+EXPORT_SYMBOL(drm_get_dev);
6538+
6539
6540 /**
6541 * Put a device minor number.
6542Index: linux-2.6.28/drivers/gpu/drm/drm_ttm.c
6543===================================================================
6544--- /dev/null 1970-01-01 00:00:00.000000000 +0000
6545+++ linux-2.6.28/drivers/gpu/drm/drm_ttm.c 2009-02-12 09:14:41.000000000 +0000
6546@@ -0,0 +1,430 @@
6547+/**************************************************************************
6548+ *
6549+ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
6550+ * All Rights Reserved.
6551+ *
6552+ * Permission is hereby granted, free of charge, to any person obtaining a
6553+ * copy of this software and associated documentation files (the
6554+ * "Software"), to deal in the Software without restriction, including
6555+ * without limitation the rights to use, copy, modify, merge, publish,
6556+ * distribute, sub license, and/or sell copies of the Software, and to
6557+ * permit persons to whom the Software is furnished to do so, subject to
6558+ * the following conditions:
6559+ *
6560+ * The above copyright notice and this permission notice (including the
6561+ * next paragraph) shall be included in all copies or substantial portions
6562+ * of the Software.
6563+ *
6564+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6565+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6566+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
6567+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
6568+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
6569+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
6570+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
6571+ *
6572+ **************************************************************************/
6573+/*
6574+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
6575+ */
6576+
6577+#include "drmP.h"
6578+#include <asm/agp.h>
6579+
6580+static void drm_ttm_ipi_handler(void *null)
6581+{
6582+ flush_agp_cache();
6583+}
6584+
6585+void drm_ttm_cache_flush(void)
6586+{
6587+ if (on_each_cpu(drm_ttm_ipi_handler, NULL, 1) != 0)
6588+ DRM_ERROR("Timed out waiting for drm cache flush.\n");
6589+}
6590+EXPORT_SYMBOL(drm_ttm_cache_flush);
6591+
6592+/*
6593+ * Use kmalloc if possible. Otherwise fall back to vmalloc.
6594+ */
6595+
6596+static void ttm_alloc_pages(struct drm_ttm *ttm)
6597+{
6598+ unsigned long size = ttm->num_pages * sizeof(*ttm->pages);
6599+ ttm->pages = NULL;
6600+
6601+ if (size <= PAGE_SIZE)
6602+ ttm->pages = drm_calloc(1, size, DRM_MEM_TTM);
6603+
6604+ if (!ttm->pages) {
6605+ ttm->pages = vmalloc_user(size);
6606+ if (ttm->pages)
6607+ ttm->page_flags |= DRM_TTM_PAGE_VMALLOC;
6608+ }
6609+}
6610+
6611+static void ttm_free_pages(struct drm_ttm *ttm)
6612+{
6613+ unsigned long size = ttm->num_pages * sizeof(*ttm->pages);
6614+
6615+ if (ttm->page_flags & DRM_TTM_PAGE_VMALLOC) {
6616+ vfree(ttm->pages);
6617+ ttm->page_flags &= ~DRM_TTM_PAGE_VMALLOC;
6618+ } else {
6619+ drm_free(ttm->pages, size, DRM_MEM_TTM);
6620+ }
6621+ ttm->pages = NULL;
6622+}
6623+
6624+static struct page *drm_ttm_alloc_page(void)
6625+{
6626+ struct page *page;
6627+
6628+ page = alloc_page(GFP_KERNEL | __GFP_ZERO | GFP_DMA32);
6629+ if (!page)
6630+ return NULL;
6631+ return page;
6632+}
6633+
6634+/*
6635+ * Change caching policy for the linear kernel map
6636+ * for range of pages in a ttm.
6637+ */
6638+
6639+static int drm_set_caching(struct drm_ttm *ttm, int noncached)
6640+{
6641+ int i;
6642+ struct page **cur_page;
6643+ int do_tlbflush = 0;
6644+
6645+ if ((ttm->page_flags & DRM_TTM_PAGE_UNCACHED) == noncached)
6646+ return 0;
6647+
6648+ if (noncached)
6649+ drm_ttm_cache_flush();
6650+
6651+ for (i = 0; i < ttm->num_pages; ++i) {
6652+ cur_page = ttm->pages + i;
6653+ if (*cur_page) {
6654+ if (!PageHighMem(*cur_page)) {
6655+ if (noncached) {
6656+ map_page_into_agp(*cur_page);
6657+ } else {
6658+ unmap_page_from_agp(*cur_page);
6659+ }
6660+ do_tlbflush = 1;
6661+ }
6662+ }
6663+ }
6664+ //if (do_tlbflush)
6665+ // flush_agp_mappings();
6666+
6667+ DRM_FLAG_MASKED(ttm->page_flags, noncached, DRM_TTM_PAGE_UNCACHED);
6668+
6669+ return 0;
6670+}
6671+
6672+
6673+static void drm_ttm_free_user_pages(struct drm_ttm *ttm)
6674+{
6675+ int write;
6676+ int dirty;
6677+ struct page *page;
6678+ int i;
6679+
6680+ BUG_ON(!(ttm->page_flags & DRM_TTM_PAGE_USER));
6681+ write = ((ttm->page_flags & DRM_TTM_PAGE_USER_WRITE) != 0);
6682+ dirty = ((ttm->page_flags & DRM_TTM_PAGE_USER_DIRTY) != 0);
6683+
6684+ for (i = 0; i < ttm->num_pages; ++i) {
6685+ page = ttm->pages[i];
6686+ if (page == NULL)
6687+ continue;
6688+
6689+ if (page == ttm->dummy_read_page) {
6690+ BUG_ON(write);
6691+ continue;
6692+ }
6693+
6694+ if (write && dirty && !PageReserved(page))
6695+ set_page_dirty_lock(page);
6696+
6697+ ttm->pages[i] = NULL;
6698+ put_page(page);
6699+ }
6700+}
6701+
6702+static void drm_ttm_free_alloced_pages(struct drm_ttm *ttm)
6703+{
6704+ int i;
6705+ struct drm_buffer_manager *bm = &ttm->dev->bm;
6706+ struct page **cur_page;
6707+
6708+ for (i = 0; i < ttm->num_pages; ++i) {
6709+ cur_page = ttm->pages + i;
6710+ if (*cur_page) {
6711+ if (page_count(*cur_page) != 1)
6712+ DRM_ERROR("Erroneous page count. Leaking pages.\n");
6713+ if (page_mapped(*cur_page))
6714+ DRM_ERROR("Erroneous map count. Leaking page mappings.\n");
6715+ __free_page(*cur_page);
6716+ --bm->cur_pages;
6717+ }
6718+ }
6719+}
6720+
6721+/*
6722+ * Free all resources associated with a ttm.
6723+ */
6724+
6725+int drm_destroy_ttm(struct drm_ttm *ttm)
6726+{
6727+ struct drm_ttm_backend *be;
6728+
6729+ if (!ttm)
6730+ return 0;
6731+
6732+ be = ttm->be;
6733+ if (be) {
6734+ be->func->destroy(be);
6735+ ttm->be = NULL;
6736+ }
6737+
6738+ if (ttm->pages) {
6739+ if (ttm->page_flags & DRM_TTM_PAGE_UNCACHED)
6740+ drm_set_caching(ttm, 0);
6741+
6742+ if (ttm->page_flags & DRM_TTM_PAGE_USER)
6743+ drm_ttm_free_user_pages(ttm);
6744+ else
6745+ drm_ttm_free_alloced_pages(ttm);
6746+
6747+ ttm_free_pages(ttm);
6748+ }
6749+
6750+ return 0;
6751+}
6752+
6753+struct page *drm_ttm_get_page(struct drm_ttm *ttm, int index)
6754+{
6755+ struct page *p;
6756+ struct drm_buffer_manager *bm = &ttm->dev->bm;
6757+
6758+ p = ttm->pages[index];
6759+ if (!p) {
6760+ p = drm_ttm_alloc_page();
6761+ if (!p)
6762+ return NULL;
6763+ ttm->pages[index] = p;
6764+ ++bm->cur_pages;
6765+ }
6766+ return p;
6767+}
6768+EXPORT_SYMBOL(drm_ttm_get_page);
6769+
6770+int drm_ttm_set_user(struct drm_ttm *ttm,
6771+ struct task_struct *tsk,
6772+ int write,
6773+ unsigned long start,
6774+ unsigned long num_pages,
6775+ struct page *dummy_read_page)
6776+{
6777+ struct mm_struct *mm = tsk->mm;
6778+ int ret;
6779+ int i;
6780+
6781+ BUG_ON(num_pages != ttm->num_pages);
6782+
6783+ ttm->dummy_read_page = dummy_read_page;
6784+ ttm->page_flags |= DRM_TTM_PAGE_USER |
6785+ ((write) ? DRM_TTM_PAGE_USER_WRITE : 0);
6786+
6787+
6788+ down_read(&mm->mmap_sem);
6789+ ret = get_user_pages(tsk, mm, start, num_pages,
6790+ write, 0, ttm->pages, NULL);
6791+ up_read(&mm->mmap_sem);
6792+
6793+ if (ret != num_pages && write) {
6794+ drm_ttm_free_user_pages(ttm);
6795+ return -ENOMEM;
6796+ }
6797+
6798+ for (i = 0; i < num_pages; ++i) {
6799+ if (ttm->pages[i] == NULL)
6800+ ttm->pages[i] = ttm->dummy_read_page;
6801+ }
6802+
6803+ return 0;
6804+}
6805+
6806+int drm_ttm_populate(struct drm_ttm *ttm)
6807+{
6808+ struct page *page;
6809+ unsigned long i;
6810+ struct drm_ttm_backend *be;
6811+
6812+ if (ttm->state != ttm_unpopulated)
6813+ return 0;
6814+
6815+ be = ttm->be;
6816+ for (i = 0; i < ttm->num_pages; ++i) {
6817+ page = drm_ttm_get_page(ttm, i);
6818+ if (!page)
6819+ return -ENOMEM;
6820+ }
6821+ be->func->populate(be, ttm->num_pages, ttm->pages);
6822+ ttm->state = ttm_unbound;
6823+ return 0;
6824+}
6825+
6826+static inline size_t drm_size_align(size_t size)
6827+{
6828+ size_t tmpSize = 4;
6829+ if (size > PAGE_SIZE)
6830+ return PAGE_ALIGN(size);
6831+ while (tmpSize < size)
6832+ tmpSize <<= 1;
6833+
6834+ return (size_t) tmpSize;
6835+}
6836+
6837+/*
6838+ * Calculate the estimated pinned memory usage of a ttm.
6839+ */
6840+
6841+unsigned long drm_ttm_size(struct drm_device *dev,
6842+ unsigned long num_pages,
6843+ int user_bo)
6844+{
6845+ struct drm_bo_driver *bo_driver = dev->driver->bo_driver;
6846+ unsigned long tmp;
6847+
6848+ tmp = drm_size_align(sizeof(struct drm_ttm)) +
6849+ drm_size_align(num_pages * sizeof(struct page *)) +
6850+ ((user_bo) ? 0 : drm_size_align(num_pages * PAGE_SIZE));
6851+
6852+ if (bo_driver->backend_size)
6853+ tmp += bo_driver->backend_size(dev, num_pages);
6854+ else
6855+ tmp += drm_size_align(num_pages * sizeof(struct page *)) +
6856+ 3*drm_size_align(sizeof(struct drm_ttm_backend));
6857+ return tmp;
6858+}
6859+
6860+
6861+/*
6862+ * Initialize a ttm.
6863+ */
6864+
6865+struct drm_ttm *drm_ttm_init(struct drm_device *dev, unsigned long size)
6866+{
6867+ struct drm_bo_driver *bo_driver = dev->driver->bo_driver;
6868+ struct drm_ttm *ttm;
6869+
6870+ if (!bo_driver)
6871+ return NULL;
6872+
6873+ ttm = drm_calloc(1, sizeof(*ttm), DRM_MEM_TTM);
6874+ if (!ttm)
6875+ return NULL;
6876+
6877+ ttm->dev = dev;
6878+ atomic_set(&ttm->vma_count, 0);
6879+
6880+ ttm->destroy = 0;
6881+ ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
6882+
6883+ ttm->page_flags = 0;
6884+
6885+ /*
6886+ * Account also for AGP module memory usage.
6887+ */
6888+
6889+ ttm_alloc_pages(ttm);
6890+ if (!ttm->pages) {
6891+ drm_destroy_ttm(ttm);
6892+ DRM_ERROR("Failed allocating page table\n");
6893+ return NULL;
6894+ }
6895+ ttm->be = bo_driver->create_ttm_backend_entry(dev);
6896+ if (!ttm->be) {
6897+ drm_destroy_ttm(ttm);
6898+ DRM_ERROR("Failed creating ttm backend entry\n");
6899+ return NULL;
6900+ }
6901+ ttm->state = ttm_unpopulated;
6902+ return ttm;
6903+}
6904+
6905+/*
6906+ * Unbind a ttm region from the aperture.
6907+ */
6908+
6909+void drm_ttm_evict(struct drm_ttm *ttm)
6910+{
6911+ struct drm_ttm_backend *be = ttm->be;
6912+ int ret;
6913+
6914+ if (ttm->state == ttm_bound) {
6915+ ret = be->func->unbind(be);
6916+ BUG_ON(ret);
6917+ }
6918+
6919+ ttm->state = ttm_evicted;
6920+}
6921+
6922+void drm_ttm_fixup_caching(struct drm_ttm *ttm)
6923+{
6924+
6925+ if (ttm->state == ttm_evicted) {
6926+ struct drm_ttm_backend *be = ttm->be;
6927+ if (be->func->needs_ub_cache_adjust(be))
6928+ drm_set_caching(ttm, 0);
6929+ ttm->state = ttm_unbound;
6930+ }
6931+}
6932+
6933+void drm_ttm_unbind(struct drm_ttm *ttm)
6934+{
6935+ if (ttm->state == ttm_bound)
6936+ drm_ttm_evict(ttm);
6937+
6938+ drm_ttm_fixup_caching(ttm);
6939+}
6940+
6941+int drm_bind_ttm(struct drm_ttm *ttm, struct drm_bo_mem_reg *bo_mem)
6942+{
6943+ struct drm_bo_driver *bo_driver = ttm->dev->driver->bo_driver;
6944+ int ret = 0;
6945+ struct drm_ttm_backend *be;
6946+
6947+ if (!ttm)
6948+ return -EINVAL;
6949+ if (ttm->state == ttm_bound)
6950+ return 0;
6951+
6952+ be = ttm->be;
6953+
6954+ ret = drm_ttm_populate(ttm);
6955+ if (ret)
6956+ return ret;
6957+
6958+ if (ttm->state == ttm_unbound && !(bo_mem->flags & DRM_BO_FLAG_CACHED))
6959+ drm_set_caching(ttm, DRM_TTM_PAGE_UNCACHED);
6960+ else if ((bo_mem->flags & DRM_BO_FLAG_CACHED_MAPPED) &&
6961+ bo_driver->ttm_cache_flush)
6962+ bo_driver->ttm_cache_flush(ttm);
6963+
6964+ ret = be->func->bind(be, bo_mem);
6965+ if (ret) {
6966+ ttm->state = ttm_evicted;
6967+ DRM_ERROR("Couldn't bind backend.\n");
6968+ return ret;
6969+ }
6970+
6971+ ttm->state = ttm_bound;
6972+ if (ttm->page_flags & DRM_TTM_PAGE_USER)
6973+ ttm->page_flags |= DRM_TTM_PAGE_USER_DIRTY;
6974+ return 0;
6975+}
6976+EXPORT_SYMBOL(drm_bind_ttm);
6977Index: linux-2.6.28/drivers/gpu/drm/drm_vm.c
6978===================================================================
6979--- linux-2.6.28.orig/drivers/gpu/drm/drm_vm.c 2009-02-12 09:14:37.000000000 +0000
6980+++ linux-2.6.28/drivers/gpu/drm/drm_vm.c 2009-02-12 09:14:41.000000000 +0000
6981@@ -40,6 +40,10 @@
6982
6983 static void drm_vm_open(struct vm_area_struct *vma);
6984 static void drm_vm_close(struct vm_area_struct *vma);
6985+static int drm_bo_mmap_locked(struct vm_area_struct *vma,
6986+ struct file *filp,
6987+ drm_local_map_t *map);
6988+
6989
6990 static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
6991 {
6992@@ -270,6 +274,9 @@
6993 case _DRM_GEM:
6994 DRM_ERROR("tried to rmmap GEM object\n");
6995 break;
6996+ case _DRM_TTM:
6997+ BUG_ON(1);
6998+ break;
6999 }
7000 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
7001 }
7002@@ -650,6 +657,8 @@
7003 vma->vm_flags |= VM_RESERVED;
7004 vma->vm_page_prot = drm_dma_prot(map->type, vma);
7005 break;
7006+ case _DRM_TTM:
7007+ return drm_bo_mmap_locked(vma, filp, map);
7008 default:
7009 return -EINVAL; /* This should never happen. */
7010 }
7011@@ -674,3 +683,213 @@
7012 return ret;
7013 }
7014 EXPORT_SYMBOL(drm_mmap);
7015+
7016+/**
7017+ * buffer object vm functions.
7018+ */
7019+
7020+/**
7021+ * \c Pagefault method for buffer objects.
7022+ *
7023+ * \param vma Virtual memory area.
7024+ * \param address File offset.
7025+ * \return Error or refault. The pfn is manually inserted.
7026+ *
7027+ * It's important that pfns are inserted while holding the bo->mutex lock.
7028+ * otherwise we might race with unmap_mapping_range() which is always
7029+ * called with the bo->mutex lock held.
7030+ *
7031+ * We're modifying the page attribute bits of the vma->vm_page_prot field,
7032+ * without holding the mmap_sem in write mode. Only in read mode.
7033+ * These bits are not used by the mm subsystem code, and we consider them
7034+ * protected by the bo->mutex lock.
7035+ */
7036+
7037+#define DRM_NOPFN_EXTRA 15 /* Fault 16 pages at a time in */
7038+
7039+int drm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
7040+{
7041+ struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data;
7042+ unsigned long page_offset;
7043+ struct page *page = NULL;
7044+ struct drm_ttm *ttm = NULL;
7045+ struct drm_device *dev;
7046+ unsigned long pfn;
7047+ int err;
7048+ unsigned long bus_base;
7049+ unsigned long bus_offset;
7050+ unsigned long bus_size;
7051+ int i;
7052+ unsigned long ret = VM_FAULT_NOPAGE;
7053+ unsigned long address = (unsigned long)vmf->virtual_address;
7054+
7055+ if (address > vma->vm_end)
7056+ return VM_FAULT_SIGBUS;
7057+
7058+ dev = bo->dev;
7059+ err = drm_bo_read_lock(&dev->bm.bm_lock);
7060+ if (err)
7061+ return VM_FAULT_NOPAGE;
7062+
7063+ err = mutex_lock_interruptible(&bo->mutex);
7064+ if (err) {
7065+ drm_bo_read_unlock(&dev->bm.bm_lock);
7066+ return VM_FAULT_NOPAGE;
7067+ }
7068+
7069+ err = drm_bo_wait(bo, 0, 0, 0);
7070+ if (err) {
7071+ ret = (err != -EAGAIN) ? VM_FAULT_SIGBUS : VM_FAULT_NOPAGE;
7072+ goto out_unlock;
7073+ }
7074+
7075+ /*
7076+ * If buffer happens to be in a non-mappable location,
7077+ * move it to a mappable.
7078+ */
7079+
7080+ if (!(bo->mem.flags & DRM_BO_FLAG_MAPPABLE)) {
7081+ uint32_t new_mask = bo->mem.mask |
7082+ DRM_BO_FLAG_MAPPABLE |
7083+ DRM_BO_FLAG_FORCE_MAPPABLE;
7084+ err = drm_bo_move_buffer(bo, new_mask, 0, 0);
7085+ if (err) {
7086+ ret = (err != -EAGAIN) ? VM_FAULT_SIGBUS : VM_FAULT_NOPAGE;
7087+ goto out_unlock;
7088+ }
7089+ }
7090+
7091+ err = drm_bo_pci_offset(dev, &bo->mem, &bus_base, &bus_offset,
7092+ &bus_size);
7093+
7094+ if (err) {
7095+ ret = VM_FAULT_SIGBUS;
7096+ goto out_unlock;
7097+ }
7098+
7099+ page_offset = (address - vma->vm_start) >> PAGE_SHIFT;
7100+
7101+ if (bus_size) {
7102+ struct drm_mem_type_manager *man = &dev->bm.man[bo->mem.mem_type];
7103+
7104+ pfn = ((bus_base + bus_offset) >> PAGE_SHIFT) + page_offset;
7105+ vma->vm_page_prot = drm_io_prot(man->drm_bus_maptype, vma);
7106+ } else {
7107+ ttm = bo->ttm;
7108+
7109+ drm_ttm_fixup_caching(ttm);
7110+ page = drm_ttm_get_page(ttm, page_offset);
7111+ if (!page) {
7112+ ret = VM_FAULT_OOM;
7113+ goto out_unlock;
7114+ }
7115+ pfn = page_to_pfn(page);
7116+ vma->vm_page_prot = (bo->mem.flags & DRM_BO_FLAG_CACHED) ?
7117+ vm_get_page_prot(vma->vm_flags) :
7118+ drm_io_prot(_DRM_TTM, vma);
7119+ }
7120+
7121+ err = vm_insert_pfn(vma, address, pfn);
7122+ if (err) {
7123+ ret = (err != -EAGAIN) ? VM_FAULT_OOM : VM_FAULT_NOPAGE;
7124+ goto out_unlock;
7125+ }
7126+
7127+ for (i=0; i<DRM_NOPFN_EXTRA; ++i) {
7128+
7129+ if (++page_offset == bo->mem.num_pages)
7130+ break;
7131+ address = vma->vm_start + (page_offset << PAGE_SHIFT);
7132+ if (address >= vma->vm_end)
7133+ break;
7134+ if (bus_size) {
7135+ pfn = ((bus_base + bus_offset) >> PAGE_SHIFT)
7136+ + page_offset;
7137+ } else {
7138+ page = drm_ttm_get_page(ttm, page_offset);
7139+ if (!page)
7140+ break;
7141+ pfn = page_to_pfn(page);
7142+ }
7143+ if (vm_insert_pfn(vma, address, pfn))
7144+ break;
7145+ }
7146+out_unlock:
7147+ mutex_unlock(&bo->mutex);
7148+ drm_bo_read_unlock(&dev->bm.bm_lock);
7149+ return ret;
7150+}
7151+EXPORT_SYMBOL(drm_bo_vm_fault);
7152+
7153+static void drm_bo_vm_open_locked(struct vm_area_struct *vma)
7154+{
7155+ struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data;
7156+
7157+ drm_vm_open_locked(vma);
7158+ atomic_inc(&bo->usage);
7159+}
7160+
7161+/**
7162+ * \c vma open method for buffer objects.
7163+ *
7164+ * \param vma virtual memory area.
7165+ */
7166+
7167+static void drm_bo_vm_open(struct vm_area_struct *vma)
7168+{
7169+ struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data;
7170+ struct drm_device *dev = bo->dev;
7171+
7172+ mutex_lock(&dev->struct_mutex);
7173+ drm_bo_vm_open_locked(vma);
7174+ mutex_unlock(&dev->struct_mutex);
7175+}
7176+
7177+/**
7178+ * \c vma close method for buffer objects.
7179+ *
7180+ * \param vma virtual memory area.
7181+ */
7182+
7183+static void drm_bo_vm_close(struct vm_area_struct *vma)
7184+{
7185+ struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data;
7186+ struct drm_device *dev = bo->dev;
7187+
7188+ drm_vm_close(vma);
7189+ if (bo) {
7190+ mutex_lock(&dev->struct_mutex);
7191+ drm_bo_usage_deref_locked((struct drm_buffer_object **)
7192+ &vma->vm_private_data);
7193+ mutex_unlock(&dev->struct_mutex);
7194+ }
7195+ return;
7196+}
7197+
7198+static struct vm_operations_struct drm_bo_vm_ops = {
7199+ .fault = drm_bo_vm_fault,
7200+ .open = drm_bo_vm_open,
7201+ .close = drm_bo_vm_close,
7202+};
7203+
7204+/**
7205+ * mmap buffer object memory.
7206+ *
7207+ * \param vma virtual memory area.
7208+ * \param file_priv DRM file private.
7209+ * \param map The buffer object drm map.
7210+ * \return zero on success or a negative number on failure.
7211+ */
7212+
7213+int drm_bo_mmap_locked(struct vm_area_struct *vma,
7214+ struct file *filp,
7215+ drm_local_map_t *map)
7216+{
7217+ vma->vm_ops = &drm_bo_vm_ops;
7218+ vma->vm_private_data = map->handle;
7219+ vma->vm_file = filp;
7220+ vma->vm_flags |= VM_RESERVED | VM_IO;
7221+ vma->vm_flags |= VM_PFNMAP;
7222+ drm_bo_vm_open_locked(vma);
7223+ return 0;
7224+}
7225Index: linux-2.6.28/drivers/gpu/drm/psb/Makefile
7226===================================================================
7227--- /dev/null 1970-01-01 00:00:00.000000000 +0000
7228+++ linux-2.6.28/drivers/gpu/drm/psb/Makefile 2009-02-12 09:14:41.000000000 +0000
7229@@ -0,0 +1,12 @@
7230+#
7231+# Makefile for the drm device driver. This driver provides support for the
7232+# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
7233+
7234+ccflags-y := -Iinclude/drm
7235+
7236+psb-y := psb_drv.o psb_mmu.o psb_sgx.o psb_irq.o psb_fence.o psb_buffer.o \
7237+ psb_gtt.o psb_setup.o psb_i2c.o psb_fb.o psb_msvdx.o \
7238+ psb_msvdxinit.o psb_regman.o psb_reset.o psb_scene.o \
7239+ psb_schedule.o psb_xhw.o
7240+
7241+obj-$(CONFIG_DRM_PSB) += psb.o
7242Index: linux-2.6.28/drivers/gpu/drm/psb/i915_reg.h
7243===================================================================
7244--- /dev/null 1970-01-01 00:00:00.000000000 +0000
7245+++ linux-2.6.28/drivers/gpu/drm/psb/i915_reg.h 2009-02-12 09:14:41.000000000 +0000
7246@@ -0,0 +1,67 @@
7247+#include "../i915/i915_reg.h"
7248+
7249+
7250+/*#define IS_I830(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82830_CGC)
7251+#define IS_845G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82845G_IG)
7252+#define IS_I85X(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG)
7253+#define IS_I855(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG)
7254+#define IS_I865G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82865_IG)
7255+
7256+#define IS_I915G(dev) (dev->pci_device == PCI_DEVICE_ID_INTEL_82915G_IG)
7257+#define IS_I915GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82915GM_IG)
7258+#define IS_I945G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945G_IG)
7259+#define IS_I945GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945GM_IG)
7260+
7261+#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \
7262+ (dev)->pci_device == 0x2982 || \
7263+ (dev)->pci_device == 0x2992 || \
7264+ (dev)->pci_device == 0x29A2 || \
7265+ (dev)->pci_device == 0x2A02 || \
7266+ (dev)->pci_device == 0x2A12)
7267+
7268+#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02)
7269+
7270+#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \
7271+ (dev)->pci_device == 0x29B2 || \
7272+ (dev)->pci_device == 0x29D2)
7273+
7274+#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \
7275+ IS_I945GM(dev) || IS_I965G(dev) || IS_POULSBO(dev))
7276+
7277+#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
7278+ IS_I945GM(dev) || IS_I965GM(dev) || IS_POULSBO(dev))
7279+
7280+#define IS_POULSBO(dev) (((dev)->pci_device == 0x8108) || \
7281+ ((dev)->pci_device == 0x8109))*/
7282+
7283+#define FPA0 0x06040
7284+#define FPA1 0x06044
7285+#define FPB0 0x06048
7286+#define FPB1 0x0604c
7287+#define FP_N_DIV_MASK 0x003f0000
7288+#define FP_N_DIV_SHIFT 16
7289+#define FP_M1_DIV_MASK 0x00003f00
7290+#define FP_M1_DIV_SHIFT 8
7291+#define FP_M2_DIV_MASK 0x0000003f
7292+#define FP_M2_DIV_SHIFT 0
7293+
7294+#define DPLL_B_MD 0x06020
7295+
7296+#define ADPA 0x61100
7297+#define ADPA_DAC_ENABLE (1<<31)
7298+#define ADPA_DAC_DISABLE 0
7299+#define ADPA_PIPE_SELECT_MASK (1<<30)
7300+#define ADPA_PIPE_A_SELECT 0
7301+#define ADPA_PIPE_B_SELECT (1<<30)
7302+#define ADPA_USE_VGA_HVPOLARITY (1<<15)
7303+#define ADPA_SETS_HVPOLARITY 0
7304+#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
7305+#define ADPA_VSYNC_CNTL_ENABLE 0
7306+#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
7307+#define ADPA_HSYNC_CNTL_ENABLE 0
7308+#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
7309+#define ADPA_VSYNC_ACTIVE_LOW 0
7310+#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
7311+#define ADPA_HSYNC_ACTIVE_LOW 0
7312+
7313+
7314Index: linux-2.6.28/drivers/gpu/drm/psb/intel_display.c
7315===================================================================
7316--- /dev/null 1970-01-01 00:00:00.000000000 +0000
7317+++ linux-2.6.28/drivers/gpu/drm/psb/intel_display.c 2009-02-12 09:14:41.000000000 +0000
7318@@ -0,0 +1,1813 @@
7319+/*
7320+ * Copyright © 2006-2007 Intel Corporation
7321+ *
7322+ * Permission is hereby granted, free of charge, to any person obtaining a
7323+ * copy of this software and associated documentation files (the "Software"),
7324+ * to deal in the Software without restriction, including without limitation
7325+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7326+ * and/or sell copies of the Software, and to permit persons to whom the
7327+ * Software is furnished to do so, subject to the following conditions:
7328+ *
7329+ * The above copyright notice and this permission notice (including the next
7330+ * paragraph) shall be included in all copies or substantial portions of the
7331+ * Software.
7332+ *
7333+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7334+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7335+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
7336+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
7337+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
7338+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
7339+ * DEALINGS IN THE SOFTWARE.
7340+ *
7341+ * Authors:
7342+ * Eric Anholt <eric@anholt.net>
7343+ */
7344+
7345+#include <linux/i2c.h>
7346+#include "drmP.h"
7347+#include "../i915/intel_drv.h"
7348+#include "i915_drm.h"
7349+#include "../i915/i915_drv.h"
7350+
7351+#include "drm_crtc_helper.h"
7352+
7353+bool intel_pipe_has_type (struct drm_crtc *crtc, int type);
7354+
7355+typedef struct {
7356+ /* given values */
7357+ int n;
7358+ int m1, m2;
7359+ int p1, p2;
7360+ /* derived values */
7361+ int dot;
7362+ int vco;
7363+ int m;
7364+ int p;
7365+} intel_clock_t;
7366+
7367+typedef struct {
7368+ int min, max;
7369+} intel_range_t;
7370+
7371+typedef struct {
7372+ int dot_limit;
7373+ int p2_slow, p2_fast;
7374+} intel_p2_t;
7375+
7376+#define INTEL_P2_NUM 2
7377+
7378+typedef struct {
7379+ intel_range_t dot, vco, n, m, m1, m2, p, p1;
7380+ intel_p2_t p2;
7381+} intel_limit_t;
7382+
7383+#define I8XX_DOT_MIN 25000
7384+#define I8XX_DOT_MAX 350000
7385+#define I8XX_VCO_MIN 930000
7386+#define I8XX_VCO_MAX 1400000
7387+#define I8XX_N_MIN 3
7388+#define I8XX_N_MAX 16
7389+#define I8XX_M_MIN 96
7390+#define I8XX_M_MAX 140
7391+#define I8XX_M1_MIN 18
7392+#define I8XX_M1_MAX 26
7393+#define I8XX_M2_MIN 6
7394+#define I8XX_M2_MAX 16
7395+#define I8XX_P_MIN 4
7396+#define I8XX_P_MAX 128
7397+#define I8XX_P1_MIN 2
7398+#define I8XX_P1_MAX 33
7399+#define I8XX_P1_LVDS_MIN 1
7400+#define I8XX_P1_LVDS_MAX 6
7401+#define I8XX_P2_SLOW 4
7402+#define I8XX_P2_FAST 2
7403+#define I8XX_P2_LVDS_SLOW 14
7404+#define I8XX_P2_LVDS_FAST 14 /* No fast option */
7405+#define I8XX_P2_SLOW_LIMIT 165000
7406+
7407+#define I9XX_DOT_MIN 20000
7408+#define I9XX_DOT_MAX 400000
7409+#define I9XX_VCO_MIN 1400000
7410+#define I9XX_VCO_MAX 2800000
7411+#define I9XX_N_MIN 3
7412+#define I9XX_N_MAX 8
7413+#define I9XX_M_MIN 70
7414+#define I9XX_M_MAX 120
7415+#define I9XX_M1_MIN 10
7416+#define I9XX_M1_MAX 20
7417+#define I9XX_M2_MIN 5
7418+#define I9XX_M2_MAX 9
7419+#define I9XX_P_SDVO_DAC_MIN 5
7420+#define I9XX_P_SDVO_DAC_MAX 80
7421+#define I9XX_P_LVDS_MIN 7
7422+#define I9XX_P_LVDS_MAX 98
7423+#define I9XX_P1_MIN 1
7424+#define I9XX_P1_MAX 8
7425+#define I9XX_P2_SDVO_DAC_SLOW 10
7426+#define I9XX_P2_SDVO_DAC_FAST 5
7427+#define I9XX_P2_SDVO_DAC_SLOW_LIMIT 200000
7428+#define I9XX_P2_LVDS_SLOW 14
7429+#define I9XX_P2_LVDS_FAST 7
7430+#define I9XX_P2_LVDS_SLOW_LIMIT 112000
7431+
7432+#define INTEL_LIMIT_I8XX_DVO_DAC 0
7433+#define INTEL_LIMIT_I8XX_LVDS 1
7434+#define INTEL_LIMIT_I9XX_SDVO_DAC 2
7435+#define INTEL_LIMIT_I9XX_LVDS 3
7436+
7437+static const intel_limit_t intel_limits[] = {
7438+ { /* INTEL_LIMIT_I8XX_DVO_DAC */
7439+ .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
7440+ .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX },
7441+ .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX },
7442+ .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX },
7443+ .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX },
7444+ .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX },
7445+ .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX },
7446+ .p1 = { .min = I8XX_P1_MIN, .max = I8XX_P1_MAX },
7447+ .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
7448+ .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST },
7449+ },
7450+ { /* INTEL_LIMIT_I8XX_LVDS */
7451+ .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
7452+ .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX },
7453+ .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX },
7454+ .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX },
7455+ .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX },
7456+ .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX },
7457+ .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX },
7458+ .p1 = { .min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX },
7459+ .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
7460+ .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST },
7461+ },
7462+ { /* INTEL_LIMIT_I9XX_SDVO_DAC */
7463+ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
7464+ .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX },
7465+ .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX },
7466+ .m = { .min = I9XX_M_MIN, .max = I9XX_M_MAX },
7467+ .m1 = { .min = I9XX_M1_MIN, .max = I9XX_M1_MAX },
7468+ .m2 = { .min = I9XX_M2_MIN, .max = I9XX_M2_MAX },
7469+ .p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX },
7470+ .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
7471+ .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
7472+ .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
7473+ },
7474+ { /* INTEL_LIMIT_I9XX_LVDS */
7475+ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
7476+ .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX },
7477+ .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX },
7478+ .m = { .min = I9XX_M_MIN, .max = I9XX_M_MAX },
7479+ .m1 = { .min = I9XX_M1_MIN, .max = I9XX_M1_MAX },
7480+ .m2 = { .min = I9XX_M2_MIN, .max = I9XX_M2_MAX },
7481+ .p = { .min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX },
7482+ .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
7483+ /* The single-channel range is 25-112Mhz, and dual-channel
7484+ * is 80-224Mhz. Prefer single channel as much as possible.
7485+ */
7486+ .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
7487+ .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST },
7488+ },
7489+};
7490+
7491+static const intel_limit_t *intel_limit(struct drm_crtc *crtc)
7492+{
7493+ struct drm_device *dev = crtc->dev;
7494+ const intel_limit_t *limit;
7495+
7496+ if (IS_I9XX(dev)) {
7497+ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
7498+ limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS];
7499+ else
7500+ limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
7501+ } else {
7502+ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
7503+ limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS];
7504+ else
7505+ limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC];
7506+ }
7507+ return limit;
7508+}
7509+
7510+/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
7511+
7512+static void i8xx_clock(int refclk, intel_clock_t *clock)
7513+{
7514+ clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
7515+ clock->p = clock->p1 * clock->p2;
7516+ clock->vco = refclk * clock->m / (clock->n + 2);
7517+ clock->dot = clock->vco / clock->p;
7518+}
7519+
7520+/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */
7521+
7522+static void i9xx_clock(int refclk, intel_clock_t *clock)
7523+{
7524+ clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
7525+ clock->p = clock->p1 * clock->p2;
7526+ clock->vco = refclk * clock->m / (clock->n + 2);
7527+ clock->dot = clock->vco / clock->p;
7528+}
7529+
7530+static void intel_clock(struct drm_device *dev, int refclk,
7531+ intel_clock_t *clock)
7532+{
7533+ if (IS_I9XX(dev))
7534+ i9xx_clock (refclk, clock);
7535+ else
7536+ i8xx_clock (refclk, clock);
7537+}
7538+
7539+/**
7540+ * Returns whether any output on the specified pipe is of the specified type
7541+ */
7542+bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
7543+{
7544+ struct drm_device *dev = crtc->dev;
7545+ struct drm_mode_config *mode_config = &dev->mode_config;
7546+ struct drm_connector *l_entry;
7547+
7548+ list_for_each_entry(l_entry, &mode_config->connector_list, head) {
7549+ if (l_entry->encoder &&
7550+ l_entry->encoder->crtc == crtc) {
7551+ struct intel_output *intel_output = to_intel_output(l_entry);
7552+ if (intel_output->type == type)
7553+ return true;
7554+ }
7555+ }
7556+ return false;
7557+}
7558+
7559+#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; }
7560+/**
7561+ * Returns whether the given set of divisors are valid for a given refclk with
7562+ * the given connectors.
7563+ */
7564+
7565+static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock)
7566+{
7567+ const intel_limit_t *limit = intel_limit (crtc);
7568+
7569+ if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
7570+ INTELPllInvalid ("p1 out of range\n");
7571+ if (clock->p < limit->p.min || limit->p.max < clock->p)
7572+ INTELPllInvalid ("p out of range\n");
7573+ if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
7574+ INTELPllInvalid ("m2 out of range\n");
7575+ if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
7576+ INTELPllInvalid ("m1 out of range\n");
7577+ if (clock->m1 <= clock->m2)
7578+ INTELPllInvalid ("m1 <= m2\n");
7579+ if (clock->m < limit->m.min || limit->m.max < clock->m)
7580+ INTELPllInvalid ("m out of range\n");
7581+ if (clock->n < limit->n.min || limit->n.max < clock->n)
7582+ INTELPllInvalid ("n out of range\n");
7583+ if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
7584+ INTELPllInvalid ("vco out of range\n");
7585+ /* XXX: We may need to be checking "Dot clock" depending on the multiplier,
7586+ * connector, etc., rather than just a single range.
7587+ */
7588+ if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
7589+ INTELPllInvalid ("dot out of range\n");
7590+
7591+ return true;
7592+}
7593+
7594+/**
7595+ * Returns a set of divisors for the desired target clock with the given
7596+ * refclk, or FALSE. The returned values represent the clock equation:
7597+ * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
7598+ */
7599+static bool intel_find_best_PLL(struct drm_crtc *crtc, int target,
7600+ int refclk, intel_clock_t *best_clock)
7601+{
7602+ struct drm_device *dev = crtc->dev;
7603+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
7604+ intel_clock_t clock;
7605+ const intel_limit_t *limit = intel_limit(crtc);
7606+ int err = target;
7607+
7608+ if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
7609+ (I915_READ(LVDS) & LVDS_PORT_EN) != 0) {
7610+ /*
7611+ * For LVDS, if the panel is on, just rely on its current
7612+ * settings for dual-channel. We haven't figured out how to
7613+ * reliably set up different single/dual channel state, if we
7614+ * even can.
7615+ */
7616+ if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
7617+ LVDS_CLKB_POWER_UP)
7618+ clock.p2 = limit->p2.p2_fast;
7619+ else
7620+ clock.p2 = limit->p2.p2_slow;
7621+ } else {
7622+ if (target < limit->p2.dot_limit)
7623+ clock.p2 = limit->p2.p2_slow;
7624+ else
7625+ clock.p2 = limit->p2.p2_fast;
7626+ }
7627+
7628+ memset (best_clock, 0, sizeof (*best_clock));
7629+
7630+ for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
7631+ for (clock.m2 = limit->m2.min; clock.m2 < clock.m1 &&
7632+ clock.m2 <= limit->m2.max; clock.m2++) {
7633+ for (clock.n = limit->n.min; clock.n <= limit->n.max;
7634+ clock.n++) {
7635+ for (clock.p1 = limit->p1.min;
7636+ clock.p1 <= limit->p1.max; clock.p1++) {
7637+ int this_err;
7638+
7639+ intel_clock(dev, refclk, &clock);
7640+
7641+ if (!intel_PLL_is_valid(crtc, &clock))
7642+ continue;
7643+
7644+ this_err = abs(clock.dot - target);
7645+ if (this_err < err) {
7646+ *best_clock = clock;
7647+ err = this_err;
7648+ }
7649+ }
7650+ }
7651+ }
7652+ }
7653+
7654+ return (err != target);
7655+}
7656+
7657+void
7658+intel_wait_for_vblank(struct drm_device *dev)
7659+{
7660+ /* Wait for 20ms, i.e. one cycle at 50hz. */
7661+ udelay(20000);
7662+}
7663+
7664+static void
7665+intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
7666+ struct drm_framebuffer *old_fb)
7667+{
7668+ struct drm_device *dev = crtc->dev;
7669+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
7670+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
7671+ int pipe = intel_crtc->pipe;
7672+ unsigned long Start, Offset;
7673+ int dspbase = (pipe == 0 ? DSPAADDR : DSPBADDR);
7674+ int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
7675+ int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
7676+ int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
7677+ u32 dspcntr, alignment;
7678+
7679+ Start = crtc->fb->offset;
7680+ Offset = y * crtc->fb->pitch + x;
7681+
7682+ DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
7683+ if (IS_I965G(dev)) {
7684+ I915_WRITE(dspbase, Offset);
7685+ I915_READ(dspbase);
7686+ I915_WRITE(dspsurf, Start);
7687+ I915_READ(dspsurf);
7688+ } else {
7689+ I915_WRITE(dspbase, Start + Offset);
7690+ I915_READ(dspbase);
7691+ }
7692+
7693+
7694+ if (!dev_priv->sarea_priv)
7695+ return;
7696+
7697+ switch (pipe) {
7698+ case 0:
7699+ dev_priv->sarea_priv->pipeA_x = x;
7700+ dev_priv->sarea_priv->pipeA_y = y;
7701+ break;
7702+ case 1:
7703+ dev_priv->sarea_priv->pipeB_x = x;
7704+ dev_priv->sarea_priv->pipeB_y = y;
7705+ break;
7706+ default:
7707+ DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
7708+ break;
7709+ }
7710+}
7711+
7712+
7713+
7714+/**
7715+ * Sets the power management mode of the pipe and plane.
7716+ *
7717+ * This code should probably grow support for turning the cursor off and back
7718+ * on appropriately at the same time as we're turning the pipe off/on.
7719+ */
7720+static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
7721+{
7722+ struct drm_device *dev = crtc->dev;
7723+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
7724+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
7725+ int pipe = intel_crtc->pipe;
7726+ int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
7727+ int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
7728+ int dspbase_reg = (pipe == 0) ? DSPAADDR : DSPBADDR;
7729+ int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
7730+ u32 temp;
7731+ bool enabled;
7732+
7733+ /* XXX: When our outputs are all unaware of DPMS modes other than off
7734+ * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
7735+ */
7736+ switch (mode) {
7737+ case DRM_MODE_DPMS_ON:
7738+ case DRM_MODE_DPMS_STANDBY:
7739+ case DRM_MODE_DPMS_SUSPEND:
7740+ /* Enable the DPLL */
7741+ temp = I915_READ(dpll_reg);
7742+ if ((temp & DPLL_VCO_ENABLE) == 0) {
7743+ I915_WRITE(dpll_reg, temp);
7744+ I915_READ(dpll_reg);
7745+ /* Wait for the clocks to stabilize. */
7746+ udelay(150);
7747+ I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
7748+ I915_READ(dpll_reg);
7749+ /* Wait for the clocks to stabilize. */
7750+ udelay(150);
7751+ I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
7752+ I915_READ(dpll_reg);
7753+ /* Wait for the clocks to stabilize. */
7754+ udelay(150);
7755+ }
7756+
7757+ /* Enable the pipe */
7758+ temp = I915_READ(pipeconf_reg);
7759+ if ((temp & PIPEACONF_ENABLE) == 0)
7760+ I915_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
7761+
7762+ /* Enable the plane */
7763+ temp = I915_READ(dspcntr_reg);
7764+ if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
7765+ I915_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
7766+ /* Flush the plane changes */
7767+ I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
7768+ }
7769+
7770+ intel_crtc_load_lut(crtc);
7771+
7772+ /* Give the overlay scaler a chance to enable if it's on this pipe */
7773+ //intel_crtc_dpms_video(crtc, true); TODO
7774+ break;
7775+ case DRM_MODE_DPMS_OFF:
7776+ /* Give the overlay scaler a chance to disable if it's on this pipe */
7777+ //intel_crtc_dpms_video(crtc, FALSE); TODO
7778+
7779+ /* Disable the VGA plane that we never use */
7780+ I915_WRITE(VGACNTRL, VGA_DISP_DISABLE);
7781+
7782+ /* Disable display plane */
7783+ temp = I915_READ(dspcntr_reg);
7784+ if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
7785+ I915_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
7786+ /* Flush the plane changes */
7787+ I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
7788+ I915_READ(dspbase_reg);
7789+ }
7790+
7791+ if (!IS_I9XX(dev)) {
7792+ /* Wait for vblank for the disable to take effect */
7793+ intel_wait_for_vblank(dev);
7794+ }
7795+
7796+ /* Next, disable display pipes */
7797+ temp = I915_READ(pipeconf_reg);
7798+ if ((temp & PIPEACONF_ENABLE) != 0) {
7799+ I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
7800+ I915_READ(pipeconf_reg);
7801+ }
7802+
7803+ /* Wait for vblank for the disable to take effect. */
7804+ intel_wait_for_vblank(dev);
7805+
7806+ temp = I915_READ(dpll_reg);
7807+ if ((temp & DPLL_VCO_ENABLE) != 0) {
7808+ I915_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
7809+ I915_READ(dpll_reg);
7810+ }
7811+
7812+ /* Wait for the clocks to turn off. */
7813+ udelay(150);
7814+ break;
7815+ }
7816+
7817+
7818+ if (!dev_priv->sarea_priv)
7819+ return;
7820+
7821+ enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
7822+
7823+ switch (pipe) {
7824+ case 0:
7825+ dev_priv->sarea_priv->pipeA_w = enabled ? crtc->mode.hdisplay : 0;
7826+ dev_priv->sarea_priv->pipeA_h = enabled ? crtc->mode.vdisplay : 0;
7827+ break;
7828+ case 1:
7829+ dev_priv->sarea_priv->pipeB_w = enabled ? crtc->mode.hdisplay : 0;
7830+ dev_priv->sarea_priv->pipeB_h = enabled ? crtc->mode.vdisplay : 0;
7831+ break;
7832+ default:
7833+ DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
7834+ break;
7835+ }
7836+
7837+ intel_crtc->dpms_mode = mode;
7838+}
7839+
7840+static void intel_crtc_prepare (struct drm_crtc *crtc)
7841+{
7842+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
7843+ crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
7844+}
7845+
7846+static void intel_crtc_commit (struct drm_crtc *crtc)
7847+{
7848+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
7849+ crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
7850+}
7851+
7852+void intel_encoder_prepare (struct drm_encoder *encoder)
7853+{
7854+ struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
7855+ /* lvds has its own version of prepare see intel_lvds_prepare */
7856+ encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
7857+}
7858+
7859+void intel_encoder_commit (struct drm_encoder *encoder)
7860+{
7861+ struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
7862+ /* lvds has its own version of commit see intel_lvds_commit */
7863+ encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
7864+}
7865+
7866+static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
7867+ struct drm_display_mode *mode,
7868+ struct drm_display_mode *adjusted_mode)
7869+{
7870+ return true;
7871+}
7872+
7873+
7874+/** Returns the core display clock speed for i830 - i945 */
7875+static int intel_get_core_clock_speed(struct drm_device *dev)
7876+{
7877+
7878+ /* Core clock values taken from the published datasheets.
7879+ * The 830 may go up to 166 Mhz, which we should check.
7880+ */
7881+ if (IS_I945G(dev))
7882+ return 400000;
7883+ else if (IS_I915G(dev))
7884+ return 333000;
7885+ else if (IS_I945GM(dev) || IS_POULSBO(dev) || IS_845G(dev))
7886+ return 200000;
7887+ else if (IS_I915GM(dev)) {
7888+ u16 gcfgc = 0;
7889+
7890+ pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
7891+
7892+ if (gcfgc & GC_LOW_FREQUENCY_ENABLE)
7893+ return 133000;
7894+ else {
7895+ switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
7896+ case GC_DISPLAY_CLOCK_333_MHZ:
7897+ return 333000;
7898+ default:
7899+ case GC_DISPLAY_CLOCK_190_200_MHZ:
7900+ return 190000;
7901+ }
7902+ }
7903+ } else if (IS_I865G(dev))
7904+ return 266000;
7905+ else if (IS_I855(dev)) {
7906+ u16 hpllcc = 0;
7907+ /* Assume that the hardware is in the high speed state. This
7908+ * should be the default.
7909+ */
7910+ switch (hpllcc & GC_CLOCK_CONTROL_MASK) {
7911+ case GC_CLOCK_133_200:
7912+ case GC_CLOCK_100_200:
7913+ return 200000;
7914+ case GC_CLOCK_166_250:
7915+ return 250000;
7916+ case GC_CLOCK_100_133:
7917+ return 133000;
7918+ }
7919+ } else /* 852, 830 */
7920+ return 133000;
7921+
7922+ return 0; /* Silence gcc warning */
7923+}
7924+
7925+
7926+/**
7927+ * Return the pipe currently connected to the panel fitter,
7928+ * or -1 if the panel fitter is not present or not in use
7929+ */
7930+static int intel_panel_fitter_pipe (struct drm_device *dev)
7931+{
7932+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
7933+ u32 pfit_control;
7934+
7935+ /* i830 doesn't have a panel fitter */
7936+ if (IS_I830(dev))
7937+ return -1;
7938+
7939+ pfit_control = I915_READ(PFIT_CONTROL);
7940+
7941+ /* See if the panel fitter is in use */
7942+ if ((pfit_control & PFIT_ENABLE) == 0)
7943+ return -1;
7944+
7945+ /* 965 can place panel fitter on either pipe */
7946+ if (IS_I965G(dev))
7947+ return (pfit_control >> 29) & 0x3;
7948+
7949+ /* older chips can only use pipe 1 */
7950+ return 1;
7951+}
7952+
7953+#define WA_NO_FB_GARBAGE_DISPLAY
7954+#ifdef WA_NO_FB_GARBAGE_DISPLAY
7955+static u32 fp_reg_value[2];
7956+static u32 dpll_reg_value[2];
7957+static u32 dpll_md_reg_value[2];
7958+static u32 dspcntr_reg_value[2];
7959+static u32 pipeconf_reg_value[2];
7960+static u32 htot_reg_value[2];
7961+static u32 hblank_reg_value[2];
7962+static u32 hsync_reg_value[2];
7963+static u32 vtot_reg_value[2];
7964+static u32 vblank_reg_value[2];
7965+static u32 vsync_reg_value[2];
7966+static u32 dspsize_reg_value[2];
7967+static u32 dspstride_reg_value[2];
7968+static u32 dsppos_reg_value[2];
7969+static u32 pipesrc_reg_value[2];
7970+
7971+static u32 dspbase_value[2];
7972+
7973+static u32 lvds_reg_value[2];
7974+static u32 vgacntrl_reg_value[2];
7975+static u32 pfit_control_reg_value[2];
7976+
7977+#if 0
7978+void intel_crtc_mode_restore(struct drm_crtc *crtc)
7979+{
7980+ struct drm_device *dev = crtc->dev;
7981+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
7982+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
7983+ int pipe = intel_crtc->pipe;
7984+ int fp_reg = (pipe == 0) ? FPA0 : FPB0;
7985+ int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
7986+ int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
7987+ int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
7988+ int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
7989+ int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
7990+ int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
7991+ int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
7992+ int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
7993+ int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
7994+ int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
7995+ int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
7996+ int dspstride_reg = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
7997+ int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
7998+ int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
7999+ int dspbase = (pipe == 0 ? DSPAADDR : DSPBADDR);
8000+
8001+ bool ok, is_sdvo = false, is_dvo = false;
8002+ bool is_crt = false, is_lvds = false, is_tv = false;
8003+ struct drm_mode_config *mode_config = &dev->mode_config;
8004+ struct drm_connector *output;
8005+
8006+ list_for_each_entry(output, &mode_config->connector_list, head) {
8007+ struct intel_output *intel_output = to_intel_output(crtc);
8008+
8009+ if (output->crtc != crtc)
8010+ continue;
8011+
8012+ switch (intel_output->type) {
8013+ case INTEL_OUTPUT_LVDS:
8014+ is_lvds = TRUE;
8015+ break;
8016+ case INTEL_OUTPUT_SDVO:
8017+ is_sdvo = TRUE;
8018+ break;
8019+ case INTEL_OUTPUT_DVO:
8020+ is_dvo = TRUE;
8021+ break;
8022+ case INTEL_OUTPUT_TVOUT:
8023+ is_tv = TRUE;
8024+ break;
8025+ case INTEL_OUTPUT_ANALOG:
8026+ is_crt = TRUE;
8027+ break;
8028+ }
8029+ if(is_lvds && ((lvds_reg_value[pipe] & LVDS_PORT_EN) == 0))
8030+ {
8031+ printk("%s: is_lvds but not the boot display, so return\n",
8032+ __FUNCTION__);
8033+ return;
8034+ }
8035+ output->funcs->prepare(output);
8036+ }
8037+
8038+ intel_crtc_prepare(crtc);
8039+ /* Disable the panel fitter if it was on our pipe */
8040+ if (intel_panel_fitter_pipe(dev) == pipe)
8041+ I915_WRITE(PFIT_CONTROL, 0);
8042+
8043+ if (dpll_reg_value[pipe] & DPLL_VCO_ENABLE) {
8044+ I915_WRITE(fp_reg, fp_reg_value[pipe]);
8045+ I915_WRITE(dpll_reg, dpll_reg_value[pipe]& ~DPLL_VCO_ENABLE);
8046+ I915_READ(dpll_reg);
8047+ udelay(150);
8048+ }
8049+
8050+ /*
8051+ if(is_lvds)
8052+ I915_WRITE(LVDS, lvds_reg_value[pipe]);
8053+ */
8054+ if (is_lvds) {
8055+ I915_WRITE(LVDS, lvds_reg_value[pipe]);
8056+ I915_READ(LVDS);
8057+ }
8058+
8059+ I915_WRITE(fp_reg, fp_reg_value[pipe]);
8060+ I915_WRITE(dpll_reg, dpll_reg_value[pipe]);
8061+ I915_READ(dpll_reg);
8062+ udelay(150);
8063+ //I915_WRITE(dpll_md_reg, dpll_md_reg_value[pipe]);
8064+ I915_WRITE(dpll_reg, dpll_reg_value[pipe]);
8065+ I915_READ(dpll_reg);
8066+ udelay(150);
8067+ I915_WRITE(htot_reg, htot_reg_value[pipe]);
8068+ I915_WRITE(hblank_reg, hblank_reg_value[pipe]);
8069+ I915_WRITE(hsync_reg, hsync_reg_value[pipe]);
8070+ I915_WRITE(vtot_reg, vtot_reg_value[pipe]);
8071+ I915_WRITE(vblank_reg, vblank_reg_value[pipe]);
8072+ I915_WRITE(vsync_reg, vsync_reg_value[pipe]);
8073+ I915_WRITE(dspstride_reg, dspstride_reg_value[pipe]);
8074+ I915_WRITE(dspsize_reg, dspsize_reg_value[pipe]);
8075+ I915_WRITE(dsppos_reg, dsppos_reg_value[pipe]);
8076+ I915_WRITE(pipesrc_reg, pipesrc_reg_value[pipe]);
8077+ I915_WRITE(pipeconf_reg, pipeconf_reg_value[pipe]);
8078+ I915_READ(pipeconf_reg);
8079+ intel_wait_for_vblank(dev);
8080+ I915_WRITE(dspcntr_reg, dspcntr_reg_value[pipe]);
8081+ I915_WRITE(dspbase, dspbase_value[pipe]);
8082+ I915_READ(dspbase);
8083+ I915_WRITE(VGACNTRL, vgacntrl_reg_value[pipe]);
8084+ intel_wait_for_vblank(dev);
8085+ I915_WRITE(PFIT_CONTROL, pfit_control_reg_value[pipe]);
8086+
8087+ intel_crtc_commit(crtc);
8088+ list_for_each_entry(output, &mode_config->connector_list, head) {
8089+ if (output->crtc != crtc)
8090+ continue;
8091+
8092+ output->funcs->commit(output);
8093+ //output->funcs->dpms(output, DRM_MODE_DPMS_OFF);
8094+ //printk("turn off the display first\n");
8095+ }
8096+ return;
8097+}
8098+
8099+void intel_crtc_mode_save(struct drm_crtc *crtc)
8100+{
8101+ struct drm_device *dev = crtc->dev;
8102+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
8103+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
8104+ int pipe = intel_crtc->pipe;
8105+ int fp_reg = (pipe == 0) ? FPA0 : FPB0;
8106+ int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
8107+ int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
8108+ int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
8109+ int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
8110+ int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
8111+ int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
8112+ int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
8113+ int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
8114+ int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
8115+ int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
8116+ int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
8117+ int dspstride_reg = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
8118+ int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
8119+ int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
8120+ int dspbase = (pipe == 0 ? DSPAADDR : DSPBADDR);
8121+ bool ok, is_sdvo = false, is_dvo = false;
8122+ bool is_crt = false, is_lvds = false, is_tv = false;
8123+ struct drm_mode_config *mode_config = &dev->mode_config;
8124+ struct drm_connector *output;
8125+
8126+ list_for_each_entry(output, &mode_config->connector_list, head) {
8127+ struct intel_output *intel_output = to_intel_output(crtc);
8128+
8129+ if (output->crtc != crtc)
8130+ continue;
8131+
8132+ switch (intel_output->type) {
8133+ case INTEL_OUTPUT_LVDS:
8134+ is_lvds = TRUE;
8135+ break;
8136+ case INTEL_OUTPUT_SDVO:
8137+ is_sdvo = TRUE;
8138+ break;
8139+ case INTEL_OUTPUT_DVO:
8140+ is_dvo = TRUE;
8141+ break;
8142+ case INTEL_OUTPUT_TVOUT:
8143+ is_tv = TRUE;
8144+ break;
8145+ case INTEL_OUTPUT_ANALOG:
8146+ is_crt = TRUE;
8147+ break;
8148+ }
8149+ }
8150+
8151+ fp_reg_value[pipe] = I915_READ(fp_reg);
8152+ dpll_reg_value[pipe] = I915_READ(dpll_reg);
8153+ dpll_md_reg_value[pipe] = I915_READ(dpll_md_reg);
8154+ dspcntr_reg_value[pipe] = I915_READ(dspcntr_reg);
8155+ pipeconf_reg_value[pipe] = I915_READ(pipeconf_reg);
8156+ htot_reg_value[pipe] = I915_READ(htot_reg);
8157+ hblank_reg_value[pipe] = I915_READ(hblank_reg);
8158+ hsync_reg_value[pipe] = I915_READ(hsync_reg);
8159+ vtot_reg_value[pipe] = I915_READ(vtot_reg);
8160+ vblank_reg_value[pipe] = I915_READ(vblank_reg);
8161+ vsync_reg_value[pipe] = I915_READ(vsync_reg);
8162+ dspsize_reg_value[pipe] = I915_READ(dspsize_reg);
8163+ dspstride_reg_value[pipe] = I915_READ(dspstride_reg);
8164+ dsppos_reg_value[pipe] = I915_READ(dsppos_reg);
8165+ pipesrc_reg_value[pipe] = I915_READ(pipesrc_reg);
8166+ dspbase_value[pipe] = I915_READ(dspbase);
8167+ if(is_lvds)
8168+ lvds_reg_value[pipe] = I915_READ(LVDS);
8169+ vgacntrl_reg_value[pipe] = I915_READ(VGACNTRL);
8170+ pfit_control_reg_value[pipe] = I915_READ(PFIT_CONTROL);
8171+}
8172+#endif
8173+#endif
8174+static void intel_crtc_mode_set(struct drm_crtc *crtc,
8175+ struct drm_display_mode *mode,
8176+ struct drm_display_mode *adjusted_mode,
8177+ int x, int y,
8178+ struct drm_framebuffer *old_fb)
8179+{
8180+ struct drm_device *dev = crtc->dev;
8181+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
8182+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
8183+ int pipe = intel_crtc->pipe;
8184+ int fp_reg = (pipe == 0) ? FPA0 : FPB0;
8185+ int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
8186+ int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
8187+ int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
8188+ int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
8189+ int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
8190+ int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
8191+ int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
8192+ int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
8193+ int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
8194+ int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
8195+ int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
8196+ int dspstride_reg = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
8197+ int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
8198+ int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
8199+ int refclk;
8200+ intel_clock_t clock;
8201+ u32 dpll = 0, fp = 0, dspcntr, pipeconf;
8202+ bool ok, is_sdvo = false, is_dvo = false;
8203+ bool is_crt = false, is_lvds = false, is_tv = false;
8204+ struct drm_mode_config *mode_config = &dev->mode_config;
8205+ struct drm_connector *connector;
8206+
8207+ if (!crtc->fb) {
8208+ DRM_ERROR("Can't set mode without attached fb\n");
8209+ return;
8210+ }
8211+
8212+ list_for_each_entry(connector, &mode_config->connector_list, head) {
8213+ struct intel_output *intel_output = to_intel_output(connector);
8214+
8215+ if (!connector->encoder || connector->encoder->crtc != crtc)
8216+ continue;
8217+
8218+ switch (intel_output->type) {
8219+ case INTEL_OUTPUT_LVDS:
8220+ is_lvds = true;
8221+ break;
8222+ case INTEL_OUTPUT_SDVO:
8223+ case INTEL_OUTPUT_HDMI:
8224+ is_sdvo = true;
8225+ break;
8226+ case INTEL_OUTPUT_DVO:
8227+ is_dvo = true;
8228+ break;
8229+ case INTEL_OUTPUT_TVOUT:
8230+ is_tv = true;
8231+ break;
8232+ case INTEL_OUTPUT_ANALOG:
8233+ is_crt = true;
8234+ break;
8235+ }
8236+ }
8237+
8238+ if (IS_I9XX(dev)) {
8239+ refclk = 96000;
8240+ } else {
8241+ refclk = 48000;
8242+ }
8243+
8244+ ok = intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, &clock);
8245+ if (!ok) {
8246+ DRM_ERROR("Couldn't find PLL settings for mode!\n");
8247+ return;
8248+ }
8249+
8250+ fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
8251+
8252+ dpll = DPLL_VGA_MODE_DIS;
8253+ if (IS_I9XX(dev)) {
8254+ if (is_lvds) {
8255+ dpll |= DPLLB_MODE_LVDS;
8256+ if (IS_POULSBO(dev))
8257+ dpll |= DPLL_DVO_HIGH_SPEED;
8258+ } else
8259+ dpll |= DPLLB_MODE_DAC_SERIAL;
8260+ if (is_sdvo) {
8261+ dpll |= DPLL_DVO_HIGH_SPEED;
8262+ if (IS_I945G(dev) || IS_I945GM(dev) || IS_POULSBO(dev)) {
8263+ int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
8264+ dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
8265+ }
8266+ }
8267+
8268+ /* compute bitmask from p1 value */
8269+ dpll |= (1 << (clock.p1 - 1)) << 16;
8270+ switch (clock.p2) {
8271+ case 5:
8272+ dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
8273+ break;
8274+ case 7:
8275+ dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
8276+ break;
8277+ case 10:
8278+ dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
8279+ break;
8280+ case 14:
8281+ dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
8282+ break;
8283+ }
8284+ if (IS_I965G(dev))
8285+ dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
8286+ } else {
8287+ if (is_lvds) {
8288+ dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
8289+ } else {
8290+ if (clock.p1 == 2)
8291+ dpll |= PLL_P1_DIVIDE_BY_TWO;
8292+ else
8293+ dpll |= (clock.p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT;
8294+ if (clock.p2 == 4)
8295+ dpll |= PLL_P2_DIVIDE_BY_4;
8296+ }
8297+ }
8298+
8299+ if (is_tv) {
8300+ /* XXX: just matching BIOS for now */
8301+/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
8302+ dpll |= 3;
8303+ }
8304+ else
8305+ dpll |= PLL_REF_INPUT_DREFCLK;
8306+
8307+ /* setup pipeconf */
8308+ pipeconf = I915_READ(pipeconf_reg);
8309+
8310+ /* Set up the display plane register */
8311+ dspcntr = DISPPLANE_GAMMA_ENABLE;
8312+
8313+ switch (crtc->fb->bits_per_pixel) {
8314+ case 8:
8315+ dspcntr |= DISPPLANE_8BPP;
8316+ break;
8317+ case 16:
8318+ if (crtc->fb->depth == 15)
8319+ dspcntr |= DISPPLANE_15_16BPP;
8320+ else
8321+ dspcntr |= DISPPLANE_16BPP;
8322+ break;
8323+ case 32:
8324+ dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
8325+ break;
8326+ default:
8327+ DRM_ERROR("Unknown color depth\n");
8328+ return;
8329+ }
8330+
8331+
8332+ if (pipe == 0)
8333+ dspcntr |= DISPPLANE_SEL_PIPE_A;
8334+ else
8335+ dspcntr |= DISPPLANE_SEL_PIPE_B;
8336+
8337+ if (pipe == 0 && !IS_I965G(dev)) {
8338+ /* Enable pixel doubling when the dot clock is > 90% of the (display)
8339+ * core speed.
8340+ *
8341+ * XXX: No double-wide on 915GM pipe B. Is that the only reason for the
8342+ * pipe == 0 check?
8343+ */
8344+ if (mode->clock > intel_get_core_clock_speed(dev) * 9 / 10)
8345+ pipeconf |= PIPEACONF_DOUBLE_WIDE;
8346+ else
8347+ pipeconf &= ~PIPEACONF_DOUBLE_WIDE;
8348+ }
8349+
8350+ dspcntr |= DISPLAY_PLANE_ENABLE;
8351+ pipeconf |= PIPEACONF_ENABLE;
8352+ dpll |= DPLL_VCO_ENABLE;
8353+
8354+
8355+ /* Disable the panel fitter if it was on our pipe */
8356+ if (intel_panel_fitter_pipe(dev) == pipe)
8357+ I915_WRITE(PFIT_CONTROL, 0);
8358+
8359+ DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
8360+ drm_mode_debug_printmodeline(mode);
8361+
8362+
8363+ if (dpll & DPLL_VCO_ENABLE) {
8364+ I915_WRITE(fp_reg, fp);
8365+ I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
8366+ I915_READ(dpll_reg);
8367+ udelay(150);
8368+ }
8369+
8370+ /* The LVDS pin pair needs to be on before the DPLLs are enabled.
8371+ * This is an exception to the general rule that mode_set doesn't turn
8372+ * things on.
8373+ */
8374+ if (is_lvds) {
8375+ u32 lvds = I915_READ(LVDS);
8376+
8377+ lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
8378+ /* Set the B0-B3 data pairs corresponding to whether we're going to
8379+ * set the DPLLs for dual-channel mode or not.
8380+ */
8381+ if (clock.p2 == 7)
8382+ lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
8383+ else
8384+ lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
8385+
8386+ /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
8387+ * appropriately here, but we need to look more thoroughly into how
8388+ * panels behave in the two modes.
8389+ */
8390+
8391+ I915_WRITE(LVDS, lvds);
8392+ I915_READ(LVDS);
8393+ }
8394+
8395+ I915_WRITE(fp_reg, fp);
8396+ I915_WRITE(dpll_reg, dpll);
8397+ I915_READ(dpll_reg);
8398+ /* Wait for the clocks to stabilize. */
8399+ udelay(150);
8400+
8401+ if (IS_I965G(dev)) {
8402+ int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
8403+ I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
8404+ ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
8405+ } else {
8406+ /* write it again -- the BIOS does, after all */
8407+ I915_WRITE(dpll_reg, dpll);
8408+ }
8409+ I915_READ(dpll_reg);
8410+ /* Wait for the clocks to stabilize. */
8411+ udelay(150);
8412+
8413+ I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
8414+ ((adjusted_mode->crtc_htotal - 1) << 16));
8415+ I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
8416+ ((adjusted_mode->crtc_hblank_end - 1) << 16));
8417+ I915_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
8418+ ((adjusted_mode->crtc_hsync_end - 1) << 16));
8419+ I915_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
8420+ ((adjusted_mode->crtc_vtotal - 1) << 16));
8421+ I915_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
8422+ ((adjusted_mode->crtc_vblank_end - 1) << 16));
8423+ I915_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
8424+ ((adjusted_mode->crtc_vsync_end - 1) << 16));
8425+ I915_WRITE(dspstride_reg, crtc->fb->pitch);
8426+ /* pipesrc and dspsize control the size that is scaled from, which should
8427+ * always be the user's requested size.
8428+ */
8429+ I915_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
8430+ I915_WRITE(dsppos_reg, 0);
8431+ I915_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
8432+ I915_WRITE(pipeconf_reg, pipeconf);
8433+ I915_READ(pipeconf_reg);
8434+
8435+ intel_wait_for_vblank(dev);
8436+
8437+ I915_WRITE(dspcntr_reg, dspcntr);
8438+
8439+ /* Flush the plane changes */
8440+ intel_pipe_set_base(crtc, x, y, old_fb);
8441+
8442+ intel_wait_for_vblank(dev);
8443+}
8444+
8445+/** Loads the palette/gamma unit for the CRTC with the prepared values */
8446+void intel_crtc_load_lut(struct drm_crtc *crtc)
8447+{
8448+ struct drm_device *dev = crtc->dev;
8449+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
8450+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
8451+ int palreg = (intel_crtc->pipe == 0) ? PALETTE_A : PALETTE_B;
8452+ int i;
8453+
8454+ /* The clocks have to be on to load the palette. */
8455+ if (!crtc->enabled)
8456+ return;
8457+
8458+ for (i = 0; i < 256; i++) {
8459+ I915_WRITE(palreg + 4 * i,
8460+ (intel_crtc->lut_r[i] << 16) |
8461+ (intel_crtc->lut_g[i] << 8) |
8462+ intel_crtc->lut_b[i]);
8463+ }
8464+}
8465+
8466+static int intel_crtc_cursor_set(struct drm_crtc *crtc,
8467+ struct drm_file *file_priv,
8468+ uint32_t handle,
8469+ uint32_t width, uint32_t height)
8470+{
8471+ struct drm_device *dev = crtc->dev;
8472+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
8473+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
8474+ struct drm_gem_object *bo;
8475+ struct drm_i915_gem_object *obj_priv;
8476+ int pipe = intel_crtc->pipe;
8477+ uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
8478+ uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
8479+ uint32_t temp;
8480+ size_t addr;
8481+ int ret;
8482+
8483+ DRM_DEBUG("\n");
8484+
8485+ /* if we want to turn off the cursor ignore width and height */
8486+ if (!handle) {
8487+ DRM_DEBUG("cursor off\n");
8488+ temp = CURSOR_MODE_DISABLE;
8489+ addr = 0;
8490+ bo = NULL;
8491+ goto finish;
8492+ }
8493+
8494+ /* Currently we only support 64x64 cursors */
8495+ if (width != 64 || height != 64) {
8496+ DRM_ERROR("we currently only support 64x64 cursors\n");
8497+ return -EINVAL;
8498+ }
8499+
8500+ bo = drm_gem_object_lookup(dev, file_priv, handle);
8501+ if (!bo)
8502+ return -ENOENT;
8503+
8504+ obj_priv = bo->driver_private;
8505+
8506+ if (bo->size < width * height * 4) {
8507+ DRM_ERROR("buffer is to small\n");
8508+ ret = -ENOMEM;
8509+ goto fail;
8510+ }
8511+#if 0
8512+ /* we only need to pin inside GTT if cursor is non-phy */
8513+ if (!dev_priv->cursor_needs_physical) {
8514+ ret = i915_gem_object_pin(bo, PAGE_SIZE);
8515+ if (ret) {
8516+ DRM_ERROR("failed to pin cursor bo\n");
8517+ goto fail;
8518+ }
8519+ addr = obj_priv->gtt_offset;
8520+ } else {
8521+ ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
8522+ if (ret) {
8523+ DRM_ERROR("failed to attach phys object\n");
8524+ goto fail;
8525+ }
8526+ addr = obj_priv->phys_obj->handle->busaddr;
8527+ }
8528+#endif
8529+ temp = 0;
8530+ /* set the pipe for the cursor */
8531+ temp |= (pipe << 28);
8532+ temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
8533+
8534+ finish:
8535+ I915_WRITE(control, temp);
8536+ I915_WRITE(base, addr);
8537+
8538+ if (intel_crtc->cursor_bo) {
8539+#if 0
8540+ if (dev_priv->cursor_needs_physical) {
8541+ if (intel_crtc->cursor_bo != bo)
8542+ i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo);
8543+ } else
8544+ i915_gem_object_unpin(intel_crtc->cursor_bo);
8545+ mutex_lock(&dev->struct_mutex);
8546+ drm_gem_object_unreference(intel_crtc->cursor_bo);
8547+ mutex_unlock(&dev->struct_mutex);
8548+#endif
8549+ }
8550+
8551+ intel_crtc->cursor_addr = addr;
8552+ intel_crtc->cursor_bo = bo;
8553+
8554+ return 0;
8555+fail:
8556+ mutex_lock(&dev->struct_mutex);
8557+ drm_gem_object_unreference(bo);
8558+ mutex_unlock(&dev->struct_mutex);
8559+ return ret;
8560+}
8561+
8562+static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
8563+{
8564+ struct drm_device *dev = crtc->dev;
8565+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
8566+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
8567+ int pipe = intel_crtc->pipe;
8568+ uint32_t temp = 0;
8569+ uint32_t adder;
8570+
8571+ if (x < 0) {
8572+ temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
8573+ x = -x;
8574+ }
8575+ if (y < 0) {
8576+ temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
8577+ y = -y;
8578+ }
8579+
8580+ temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
8581+ temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
8582+
8583+ adder = intel_crtc->cursor_addr;
8584+ I915_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
8585+ I915_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
8586+
8587+ return 0;
8588+}
8589+
8590+/** Sets the color ramps on behalf of RandR */
8591+void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
8592+ u16 blue, int regno)
8593+{
8594+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
8595+
8596+ intel_crtc->lut_r[regno] = red >> 8;
8597+ intel_crtc->lut_g[regno] = green >> 8;
8598+ intel_crtc->lut_b[regno] = blue >> 8;
8599+}
8600+
8601+static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
8602+ u16 *blue, uint32_t size)
8603+{
8604+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
8605+ int i;
8606+
8607+ if (size != 256)
8608+ return;
8609+
8610+ for (i = 0; i < 256; i++) {
8611+ intel_crtc->lut_r[i] = red[i] >> 8;
8612+ intel_crtc->lut_g[i] = green[i] >> 8;
8613+ intel_crtc->lut_b[i] = blue[i] >> 8;
8614+ }
8615+
8616+ intel_crtc_load_lut(crtc);
8617+}
8618+
8619+/**
8620+ * Get a pipe with a simple mode set on it for doing load-based monitor
8621+ * detection.
8622+ *
8623+ * It will be up to the load-detect code to adjust the pipe as appropriate for
8624+ * its requirements. The pipe will be connected to no other outputs.
8625+ *
8626+ * Currently this code will only succeed if there is a pipe with no outputs
8627+ * configured for it. In the future, it could choose to temporarily disable
8628+ * some outputs to free up a pipe for its use.
8629+ *
8630+ * \return crtc, or NULL if no pipes are available.
8631+ */
8632+
8633+/* VESA 640x480x72Hz mode to set on the pipe */
8634+static struct drm_display_mode load_detect_mode = {
8635+ DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664,
8636+ 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
8637+};
8638+
8639+struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
8640+ struct drm_display_mode *mode,
8641+ int *dpms_mode)
8642+{
8643+ struct intel_crtc *intel_crtc;
8644+ struct drm_crtc *possible_crtc;
8645+ struct drm_crtc *supported_crtc =NULL;
8646+ struct drm_encoder *encoder = &intel_output->enc;
8647+ struct drm_crtc *crtc = NULL;
8648+ struct drm_device *dev = encoder->dev;
8649+ struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
8650+ struct drm_crtc_helper_funcs *crtc_funcs;
8651+ int i = -1;
8652+
8653+ /*
8654+ * Algorithm gets a little messy:
8655+ * - if the connector already has an assigned crtc, use it (but make
8656+ * sure it's on first)
8657+ * - try to find the first unused crtc that can drive this connector,
8658+ * and use that if we find one
8659+ * - if there are no unused crtcs available, try to use the first
8660+ * one we found that supports the connector
8661+ */
8662+
8663+ /* See if we already have a CRTC for this connector */
8664+ if (encoder->crtc) {
8665+ crtc = encoder->crtc;
8666+ /* Make sure the crtc and connector are running */
8667+ intel_crtc = to_intel_crtc(crtc);
8668+ *dpms_mode = intel_crtc->dpms_mode;
8669+ if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) {
8670+ crtc_funcs = crtc->helper_private;
8671+ crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
8672+ encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
8673+ }
8674+ return crtc;
8675+ }
8676+
8677+ /* Find an unused one (if possible) */
8678+ list_for_each_entry(possible_crtc, &dev->mode_config.crtc_list, head) {
8679+ i++;
8680+ if (!(encoder->possible_crtcs & (1 << i)))
8681+ continue;
8682+ if (!possible_crtc->enabled) {
8683+ crtc = possible_crtc;
8684+ break;
8685+ }
8686+ if (!supported_crtc)
8687+ supported_crtc = possible_crtc;
8688+ }
8689+
8690+ /*
8691+ * If we didn't find an unused CRTC, don't use any.
8692+ */
8693+ if (!crtc) {
8694+ return NULL;
8695+ }
8696+
8697+ encoder->crtc = crtc;
8698+ intel_output->load_detect_temp = true;
8699+
8700+ intel_crtc = to_intel_crtc(crtc);
8701+ *dpms_mode = intel_crtc->dpms_mode;
8702+
8703+ if (!crtc->enabled) {
8704+ if (!mode)
8705+ mode = &load_detect_mode;
8706+ drm_crtc_helper_set_mode(crtc, mode, 0, 0, crtc->fb);
8707+ } else {
8708+ if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) {
8709+ crtc_funcs = crtc->helper_private;
8710+ crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
8711+ }
8712+
8713+ /* Add this connector to the crtc */
8714+ encoder_funcs->mode_set(encoder, &crtc->mode, &crtc->mode);
8715+ encoder_funcs->commit(encoder);
8716+ }
8717+ /* let the connector get through one full cycle before testing */
8718+ intel_wait_for_vblank(dev);
8719+
8720+ return crtc;
8721+}
8722+
8723+void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode)
8724+{
8725+ struct drm_encoder *encoder = &intel_output->enc;
8726+ struct drm_device *dev = encoder->dev;
8727+ struct drm_crtc *crtc = encoder->crtc;
8728+ struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
8729+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
8730+
8731+ if (intel_output->load_detect_temp) {
8732+ encoder->crtc = NULL;
8733+ intel_output->load_detect_temp = false;
8734+ crtc->enabled = drm_helper_crtc_in_use(crtc);
8735+ drm_helper_disable_unused_functions(dev);
8736+ }
8737+
8738+ /* Switch crtc and output back off if necessary */
8739+ if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) {
8740+ if (encoder->crtc == crtc)
8741+ encoder_funcs->dpms(encoder, dpms_mode);
8742+ crtc_funcs->dpms(crtc, dpms_mode);
8743+ }
8744+}
8745+
8746+/* Returns the clock of the currently programmed mode of the given pipe. */
8747+static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
8748+{
8749+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
8750+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
8751+ int pipe = intel_crtc->pipe;
8752+ u32 dpll = I915_READ((pipe == 0) ? DPLL_A : DPLL_B);
8753+ u32 fp;
8754+ intel_clock_t clock;
8755+
8756+ if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
8757+ fp = I915_READ((pipe == 0) ? FPA0 : FPB0);
8758+ else
8759+ fp = I915_READ((pipe == 0) ? FPA1 : FPB1);
8760+
8761+ clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
8762+ clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
8763+ clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
8764+ if (IS_I9XX(dev)) {
8765+ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
8766+ DPLL_FPA01_P1_POST_DIV_SHIFT);
8767+
8768+ switch (dpll & DPLL_MODE_MASK) {
8769+ case DPLLB_MODE_DAC_SERIAL:
8770+ clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ?
8771+ 5 : 10;
8772+ break;
8773+ case DPLLB_MODE_LVDS:
8774+ clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ?
8775+ 7 : 14;
8776+ break;
8777+ default:
8778+ DRM_DEBUG("Unknown DPLL mode %08x in programmed "
8779+ "mode\n", (int)(dpll & DPLL_MODE_MASK));
8780+ return 0;
8781+ }
8782+
8783+ /* XXX: Handle the 100Mhz refclk */
8784+ i9xx_clock(96000, &clock);
8785+ } else {
8786+ bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN);
8787+
8788+ if (is_lvds) {
8789+ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
8790+ DPLL_FPA01_P1_POST_DIV_SHIFT);
8791+ clock.p2 = 14;
8792+
8793+ if ((dpll & PLL_REF_INPUT_MASK) ==
8794+ PLLB_REF_INPUT_SPREADSPECTRUMIN) {
8795+ /* XXX: might not be 66MHz */
8796+ i8xx_clock(66000, &clock);
8797+ } else
8798+ i8xx_clock(48000, &clock);
8799+ } else {
8800+ if (dpll & PLL_P1_DIVIDE_BY_TWO)
8801+ clock.p1 = 2;
8802+ else {
8803+ clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
8804+ DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
8805+ }
8806+ if (dpll & PLL_P2_DIVIDE_BY_4)
8807+ clock.p2 = 4;
8808+ else
8809+ clock.p2 = 2;
8810+
8811+ i8xx_clock(48000, &clock);
8812+ }
8813+ }
8814+
8815+ /* XXX: It would be nice to validate the clocks, but we can't reuse
8816+ * i830PllIsValid() because it relies on the xf86_config connector
8817+ * configuration being accurate, which it isn't necessarily.
8818+ */
8819+
8820+ return clock.dot;
8821+}
8822+
8823+/** Returns the currently programmed mode of the given pipe. */
8824+struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
8825+ struct drm_crtc *crtc)
8826+{
8827+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
8828+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
8829+ int pipe = intel_crtc->pipe;
8830+ struct drm_display_mode *mode;
8831+ int htot = I915_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
8832+ int hsync = I915_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
8833+ int vtot = I915_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
8834+ int vsync = I915_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
8835+
8836+ mode = kzalloc(sizeof(*mode), GFP_KERNEL);
8837+ if (!mode)
8838+ return NULL;
8839+
8840+ mode->clock = intel_crtc_clock_get(dev, crtc);
8841+ mode->hdisplay = (htot & 0xffff) + 1;
8842+ mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
8843+ mode->hsync_start = (hsync & 0xffff) + 1;
8844+ mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
8845+ mode->vdisplay = (vtot & 0xffff) + 1;
8846+ mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
8847+ mode->vsync_start = (vsync & 0xffff) + 1;
8848+ mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
8849+
8850+ drm_mode_set_name(mode);
8851+ drm_mode_set_crtcinfo(mode, 0);
8852+
8853+ return mode;
8854+}
8855+
8856+static void intel_crtc_destroy(struct drm_crtc *crtc)
8857+{
8858+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
8859+
8860+ drm_crtc_cleanup(crtc);
8861+ kfree(intel_crtc);
8862+}
8863+
8864+static const struct drm_crtc_helper_funcs intel_helper_funcs = {
8865+ .dpms = intel_crtc_dpms,
8866+ .mode_fixup = intel_crtc_mode_fixup,
8867+ .mode_set = intel_crtc_mode_set,
8868+ .mode_set_base = intel_pipe_set_base,
8869+ .prepare = intel_crtc_prepare,
8870+ .commit = intel_crtc_commit,
8871+};
8872+
8873+static const struct drm_crtc_funcs intel_crtc_funcs = {
8874+ .cursor_set = intel_crtc_cursor_set,
8875+ .cursor_move = intel_crtc_cursor_move,
8876+ .gamma_set = intel_crtc_gamma_set,
8877+ .set_config = drm_crtc_helper_set_config,
8878+ .destroy = intel_crtc_destroy,
8879+};
8880+
8881+
8882+static void intel_crtc_init(struct drm_device *dev, int pipe)
8883+{
8884+ struct intel_crtc *intel_crtc;
8885+ int i;
8886+
8887+ intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
8888+ if (intel_crtc == NULL)
8889+ return;
8890+
8891+ drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs);
8892+
8893+ intel_crtc->pipe = pipe;
8894+ for (i = 0; i < 256; i++) {
8895+ intel_crtc->lut_r[i] = i;
8896+ intel_crtc->lut_g[i] = i;
8897+ intel_crtc->lut_b[i] = i;
8898+ }
8899+
8900+ intel_crtc->cursor_addr = 0;
8901+ intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF;
8902+ drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
8903+
8904+ intel_crtc->mode_set.crtc = &intel_crtc->base;
8905+ intel_crtc->mode_set.connectors = (struct drm_connector **)(intel_crtc + 1);
8906+ intel_crtc->mode_set.num_connectors = 0;
8907+
8908+}
8909+
8910+struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
8911+{
8912+ struct drm_crtc *crtc = NULL;
8913+
8914+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
8915+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
8916+ if (intel_crtc->pipe == pipe)
8917+ break;
8918+ }
8919+ return crtc;
8920+}
8921+
8922+static int intel_connector_clones(struct drm_device *dev, int type_mask)
8923+{
8924+ int index_mask = 0;
8925+ struct drm_connector *connector;
8926+ int entry = 0;
8927+
8928+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
8929+ struct intel_output *intel_output = to_intel_output(connector);
8930+ if (type_mask & (1 << intel_output->type))
8931+ index_mask |= (1 << entry);
8932+ entry++;
8933+ }
8934+ return index_mask;
8935+}
8936+
8937+
8938+static void intel_setup_outputs(struct drm_device *dev)
8939+{
8940+ struct drm_connector *connector;
8941+
8942+ if (!IS_POULSBO(dev))
8943+ intel_crt_init(dev);
8944+
8945+ /* Set up integrated LVDS */
8946+ if (IS_MOBILE(dev) && !IS_I830(dev))
8947+ intel_lvds_init(dev);
8948+
8949+ if (IS_I9XX(dev)) {
8950+ intel_sdvo_init(dev, SDVOB);
8951+ intel_sdvo_init(dev, SDVOC);
8952+ }
8953+
8954+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
8955+ struct intel_output *intel_output = to_intel_output(connector);
8956+ struct drm_encoder *encoder = &intel_output->enc;
8957+ int crtc_mask = 0, clone_mask = 0;
8958+
8959+ /* valid crtcs */
8960+ switch(intel_output->type) {
8961+ case INTEL_OUTPUT_HDMI:
8962+ crtc_mask = ((1 << 0)|
8963+ (1 << 1));
8964+ clone_mask = ((1 << INTEL_OUTPUT_HDMI));
8965+ break;
8966+ case INTEL_OUTPUT_DVO:
8967+ case INTEL_OUTPUT_SDVO:
8968+ crtc_mask = ((1 << 0)|
8969+ (1 << 1));
8970+ clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
8971+ (1 << INTEL_OUTPUT_DVO) |
8972+ (1 << INTEL_OUTPUT_SDVO));
8973+ break;
8974+ case INTEL_OUTPUT_ANALOG:
8975+ crtc_mask = ((1 << 0)|
8976+ (1 << 1));
8977+ clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
8978+ (1 << INTEL_OUTPUT_DVO) |
8979+ (1 << INTEL_OUTPUT_SDVO));
8980+ break;
8981+ case INTEL_OUTPUT_LVDS:
8982+ crtc_mask = (1 << 1);
8983+ clone_mask = (1 << INTEL_OUTPUT_LVDS);
8984+ break;
8985+ case INTEL_OUTPUT_TVOUT:
8986+ crtc_mask = ((1 << 0) |
8987+ (1 << 1));
8988+ clone_mask = (1 << INTEL_OUTPUT_TVOUT);
8989+ break;
8990+ }
8991+ encoder->possible_crtcs = crtc_mask;
8992+ encoder->possible_clones = intel_connector_clones(dev, clone_mask);
8993+ }
8994+}
8995+
8996+static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
8997+{
8998+ struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
8999+ struct drm_device *dev = fb->dev;
9000+
9001+ //if (fb->fbdev)
9002+ // intelfb_remove(dev, fb);
9003+
9004+ drm_framebuffer_cleanup(fb);
9005+ mutex_lock(&dev->struct_mutex);
9006+ drm_gem_object_unreference(intel_fb->obj);
9007+ mutex_unlock(&dev->struct_mutex);
9008+
9009+ kfree(intel_fb);
9010+}
9011+
9012+static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
9013+ struct drm_file *file_priv,
9014+ unsigned int *handle)
9015+{
9016+ struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
9017+ struct drm_gem_object *object = intel_fb->obj;
9018+
9019+ return drm_gem_handle_create(file_priv, object, handle);
9020+}
9021+
9022+static const struct drm_framebuffer_funcs intel_fb_funcs = {
9023+ .destroy = intel_user_framebuffer_destroy,
9024+ .create_handle = intel_user_framebuffer_create_handle,
9025+};
9026+
9027+int intel_framebuffer_create(struct drm_device *dev,
9028+ struct drm_mode_fb_cmd *mode_cmd,
9029+ struct drm_framebuffer **fb,
9030+ struct drm_gem_object *obj)
9031+{
9032+ struct intel_framebuffer *intel_fb;
9033+ int ret;
9034+
9035+ intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
9036+ if (!intel_fb)
9037+ return -ENOMEM;
9038+
9039+ ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
9040+ if (ret) {
9041+ DRM_ERROR("framebuffer init failed %d\n", ret);
9042+ return ret;
9043+ }
9044+
9045+ drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
9046+
9047+ intel_fb->obj = obj;
9048+
9049+ *fb = &intel_fb->base;
9050+
9051+ return 0;
9052+}
9053+
9054+
9055+static struct drm_framebuffer *
9056+intel_user_framebuffer_create(struct drm_device *dev,
9057+ struct drm_file *filp,
9058+ struct drm_mode_fb_cmd *mode_cmd)
9059+{
9060+ struct drm_gem_object *obj;
9061+ struct drm_framebuffer *fb;
9062+ int ret;
9063+
9064+ obj = drm_gem_object_lookup(dev, filp, mode_cmd->handle);
9065+ if (!obj)
9066+ return NULL;
9067+
9068+ ret = intel_framebuffer_create(dev, mode_cmd, &fb, obj);
9069+ if (ret) {
9070+ drm_gem_object_unreference(obj);
9071+ return NULL;
9072+ }
9073+
9074+ return fb;
9075+}
9076+
9077+static const struct drm_mode_config_funcs intel_mode_funcs = {
9078+ .fb_create = intel_user_framebuffer_create,
9079+// .fb_changed = intelfb_probe,
9080+};
9081+
9082+void intel_modeset_init(struct drm_device *dev)
9083+{
9084+ int num_pipe;
9085+ int i;
9086+
9087+ drm_mode_config_init(dev);
9088+
9089+ dev->mode_config.min_width = 0;
9090+ dev->mode_config.min_height = 0;
9091+
9092+ dev->mode_config.funcs = (void *)&intel_mode_funcs;
9093+
9094+ dev->mode_config.max_width = 2048;
9095+ dev->mode_config.max_height = 2048;
9096+
9097+ /* set memory base */
9098+ if (IS_I9XX(dev))
9099+ dev->mode_config.fb_base = pci_resource_start(dev->pdev, 2);
9100+ else
9101+ dev->mode_config.fb_base = pci_resource_start(dev->pdev, 0);
9102+
9103+ if (IS_MOBILE(dev) || IS_I9XX(dev))
9104+ num_pipe = 2;
9105+ else
9106+ num_pipe = 1;
9107+ DRM_DEBUG("%d display pipe%s available.\n",
9108+ num_pipe, num_pipe > 1 ? "s" : "");
9109+
9110+ for (i = 0; i < num_pipe; i++) {
9111+ intel_crtc_init(dev, i);
9112+ }
9113+
9114+ intel_setup_outputs(dev);
9115+}
9116+
9117+void intel_modeset_cleanup(struct drm_device *dev)
9118+{
9119+ drm_mode_config_cleanup(dev);
9120+}
9121+
9122+
9123+/* current intel driver doesn't take advantage of encoders
9124+ always give back the encoder for the connector
9125+*/
9126+struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
9127+{
9128+ struct intel_output *intel_output = to_intel_output(connector);
9129+
9130+ return &intel_output->enc;
9131+}
9132Index: linux-2.6.28/drivers/gpu/drm/psb/intel_drv.h
9133===================================================================
9134--- /dev/null 1970-01-01 00:00:00.000000000 +0000
9135+++ linux-2.6.28/drivers/gpu/drm/psb/intel_drv.h 2009-02-12 09:14:41.000000000 +0000
9136@@ -0,0 +1,7 @@
9137+#include "../i915/intel_drv.h"
9138+extern void intel_modeset_init(struct drm_device *dev);
9139+extern void intel_modeset_cleanup(struct drm_device *dev);
9140+
9141+extern void intel_crtc_mode_restore(struct drm_crtc *crtc);
9142+extern void intel_crtc_mode_save(struct drm_crtc *crtc);
9143+
9144Index: linux-2.6.28/drivers/gpu/drm/psb/psb_buffer.c
9145===================================================================
9146--- /dev/null 1970-01-01 00:00:00.000000000 +0000
9147+++ linux-2.6.28/drivers/gpu/drm/psb/psb_buffer.c 2009-02-12 09:14:41.000000000 +0000
9148@@ -0,0 +1,437 @@
9149+/**************************************************************************
9150+ * Copyright (c) 2007, Intel Corporation.
9151+ * All Rights Reserved.
9152+ *
9153+ * This program is free software; you can redistribute it and/or modify it
9154+ * under the terms and conditions of the GNU General Public License,
9155+ * version 2, as published by the Free Software Foundation.
9156+ *
9157+ * This program is distributed in the hope it will be useful, but WITHOUT
9158+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9159+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
9160+ * more details.
9161+ *
9162+ * You should have received a copy of the GNU General Public License along with
9163+ * this program; if not, write to the Free Software Foundation, Inc.,
9164+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
9165+ *
9166+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
9167+ * develop this driver.
9168+ *
9169+ **************************************************************************/
9170+/*
9171+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
9172+ */
9173+#include "drmP.h"
9174+#include "psb_drv.h"
9175+#include "psb_schedule.h"
9176+
9177+struct drm_psb_ttm_backend {
9178+ struct drm_ttm_backend base;
9179+ struct page **pages;
9180+ unsigned int desired_tile_stride;
9181+ unsigned int hw_tile_stride;
9182+ int mem_type;
9183+ unsigned long offset;
9184+ unsigned long num_pages;
9185+};
9186+
9187+int psb_fence_types(struct drm_buffer_object *bo, uint32_t * class,
9188+ uint32_t * type)
9189+{
9190+ switch (*class) {
9191+ case PSB_ENGINE_TA:
9192+ *type = DRM_FENCE_TYPE_EXE |
9193+ _PSB_FENCE_TYPE_TA_DONE | _PSB_FENCE_TYPE_RASTER_DONE;
9194+ if (bo->mem.mask & PSB_BO_FLAG_TA)
9195+ *type &= ~_PSB_FENCE_TYPE_RASTER_DONE;
9196+ if (bo->mem.mask & PSB_BO_FLAG_SCENE)
9197+ *type |= _PSB_FENCE_TYPE_SCENE_DONE;
9198+ if (bo->mem.mask & PSB_BO_FLAG_FEEDBACK)
9199+ *type |= _PSB_FENCE_TYPE_FEEDBACK;
9200+ break;
9201+ default:
9202+ *type = DRM_FENCE_TYPE_EXE;
9203+ }
9204+ return 0;
9205+}
9206+
9207+static inline size_t drm_size_align(size_t size)
9208+{
9209+ size_t tmpSize = 4;
9210+ if (size > PAGE_SIZE)
9211+ return PAGE_ALIGN(size);
9212+ while (tmpSize < size)
9213+ tmpSize <<= 1;
9214+
9215+ return (size_t) tmpSize;
9216+}
9217+
9218+/*
9219+ * Poulsbo GPU virtual space looks like this
9220+ * (We currently use only one MMU context).
9221+ *
9222+ * gatt_start = Start of GATT aperture in bus space.
9223+ * stolen_end = End of GATT populated by stolen memory in bus space.
9224+ * gatt_end = End of GATT
9225+ * twod_end = MIN(gatt_start + 256_MEM, gatt_end)
9226+ *
9227+ * 0x00000000 -> 0x10000000 Temporary mapping space for tiling- and copy operations.
9228+ * This space is not managed and is protected by the
9229+ * temp_mem mutex.
9230+ *
9231+ * 0x10000000 -> 0x20000000 DRM_PSB_MEM_KERNEL For kernel buffers.
9232+ *
9233+ * 0x20000000 -> gatt_start DRM_PSB_MEM_MMU For generic MMU-only use.
9234+ *
9235+ * gatt_start -> stolen_end DRM_BO_MEM_VRAM Pre-populated GATT pages.
9236+ *
9237+ * stolen_end -> twod_end DRM_BO_MEM_TT GATT memory usable by 2D engine.
9238+ *
9239+ * twod_end -> gatt_end DRM_BO_MEM_APER GATT memory not usable by 2D engine.
9240+ *
9241+ * gatt_end -> 0xffffffff Currently unused.
9242+ */
9243+
9244+int psb_init_mem_type(struct drm_device *dev, uint32_t type,
9245+ struct drm_mem_type_manager *man)
9246+{
9247+ struct drm_psb_private *dev_priv =
9248+ (struct drm_psb_private *)dev->dev_private;
9249+ struct psb_gtt *pg = dev_priv->pg;
9250+
9251+ switch (type) {
9252+ case DRM_BO_MEM_LOCAL:
9253+ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
9254+ _DRM_FLAG_MEMTYPE_CACHED;
9255+ man->drm_bus_maptype = 0;
9256+ break;
9257+ case DRM_PSB_MEM_KERNEL:
9258+ man->io_offset = 0x00000000;
9259+ man->io_size = 0x00000000;
9260+ man->io_addr = NULL;
9261+ man->drm_bus_maptype = _DRM_TTM;
9262+ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
9263+ _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_MEMTYPE_CMA;
9264+ man->gpu_offset = PSB_MEM_KERNEL_START;
9265+ break;
9266+ case DRM_PSB_MEM_MMU:
9267+ man->io_offset = 0x00000000;
9268+ man->io_size = 0x00000000;
9269+ man->io_addr = NULL;
9270+ man->drm_bus_maptype = _DRM_TTM;
9271+ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
9272+ _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_MEMTYPE_CMA;
9273+ man->gpu_offset = PSB_MEM_MMU_START;
9274+ break;
9275+ case DRM_PSB_MEM_PDS:
9276+ man->io_offset = 0x00000000;
9277+ man->io_size = 0x00000000;
9278+ man->io_addr = NULL;
9279+ man->drm_bus_maptype = _DRM_TTM;
9280+ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
9281+ _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_MEMTYPE_CMA;
9282+ man->gpu_offset = PSB_MEM_PDS_START;
9283+ break;
9284+ case DRM_PSB_MEM_RASTGEOM:
9285+ man->io_offset = 0x00000000;
9286+ man->io_size = 0x00000000;
9287+ man->io_addr = NULL;
9288+ man->drm_bus_maptype = _DRM_TTM;
9289+ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
9290+ _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_MEMTYPE_CMA;
9291+ man->gpu_offset = PSB_MEM_RASTGEOM_START;
9292+ break;
9293+ case DRM_BO_MEM_VRAM:
9294+ man->io_addr = NULL;
9295+ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
9296+ _DRM_FLAG_MEMTYPE_FIXED | _DRM_FLAG_NEEDS_IOREMAP;
9297+#ifdef PSB_WORKING_HOST_MMU_ACCESS
9298+ man->drm_bus_maptype = _DRM_AGP;
9299+ man->io_offset = pg->gatt_start;
9300+ man->io_size = pg->gatt_pages << PAGE_SHIFT;
9301+#else
9302+ man->drm_bus_maptype = _DRM_TTM; /* Forces uncached */
9303+ man->io_offset = pg->stolen_base;
9304+ man->io_size = pg->stolen_size;
9305+#endif
9306+ man->gpu_offset = pg->gatt_start;
9307+ break;
9308+ case DRM_BO_MEM_TT: /* Mappable GATT memory */
9309+ man->io_offset = pg->gatt_start;
9310+ man->io_size = pg->gatt_pages << PAGE_SHIFT;
9311+ man->io_addr = NULL;
9312+#ifdef PSB_WORKING_HOST_MMU_ACCESS
9313+ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
9314+ _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_NEEDS_IOREMAP;
9315+ man->drm_bus_maptype = _DRM_AGP;
9316+#else
9317+ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
9318+ _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_MEMTYPE_CMA;
9319+ man->drm_bus_maptype = _DRM_TTM;
9320+#endif
9321+ man->gpu_offset = pg->gatt_start;
9322+ break;
9323+ case DRM_PSB_MEM_APER: /*MMU memory. Mappable. Not usable for 2D. */
9324+ man->io_offset = pg->gatt_start;
9325+ man->io_size = pg->gatt_pages << PAGE_SHIFT;
9326+ man->io_addr = NULL;
9327+#ifdef PSB_WORKING_HOST_MMU_ACCESS
9328+ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
9329+ _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_NEEDS_IOREMAP;
9330+ man->drm_bus_maptype = _DRM_AGP;
9331+#else
9332+ man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
9333+ _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_MEMTYPE_CMA;
9334+ man->drm_bus_maptype = _DRM_TTM;
9335+#endif
9336+ man->gpu_offset = pg->gatt_start;
9337+ break;
9338+ default:
9339+ DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
9340+ return -EINVAL;
9341+ }
9342+ return 0;
9343+}
9344+
9345+uint32_t psb_evict_mask(struct drm_buffer_object * bo)
9346+{
9347+ switch (bo->mem.mem_type) {
9348+ case DRM_BO_MEM_VRAM:
9349+ return DRM_BO_FLAG_MEM_TT;
9350+ default:
9351+ return DRM_BO_FLAG_MEM_LOCAL;
9352+ }
9353+}
9354+
9355+int psb_invalidate_caches(struct drm_device *dev, uint64_t flags)
9356+{
9357+ return 0;
9358+}
9359+
9360+static int psb_move_blit(struct drm_buffer_object *bo,
9361+ int evict, int no_wait, struct drm_bo_mem_reg *new_mem)
9362+{
9363+ struct drm_bo_mem_reg *old_mem = &bo->mem;
9364+ int dir = 0;
9365+
9366+ if ((old_mem->mem_type == new_mem->mem_type) &&
9367+ (new_mem->mm_node->start <
9368+ old_mem->mm_node->start + old_mem->mm_node->size)) {
9369+ dir = 1;
9370+ }
9371+
9372+ psb_emit_2d_copy_blit(bo->dev,
9373+ old_mem->mm_node->start << PAGE_SHIFT,
9374+ new_mem->mm_node->start << PAGE_SHIFT,
9375+ new_mem->num_pages, dir);
9376+
9377+ return drm_bo_move_accel_cleanup(bo, evict, no_wait, 0,
9378+ DRM_FENCE_TYPE_EXE, 0, new_mem);
9379+}
9380+
9381+/*
9382+ * Flip destination ttm into cached-coherent GATT,
9383+ * then blit and subsequently move out again.
9384+ */
9385+
9386+static int psb_move_flip(struct drm_buffer_object *bo,
9387+ int evict, int no_wait, struct drm_bo_mem_reg *new_mem)
9388+{
9389+ struct drm_device *dev = bo->dev;
9390+ struct drm_bo_mem_reg tmp_mem;
9391+ int ret;
9392+
9393+ tmp_mem = *new_mem;
9394+ tmp_mem.mm_node = NULL;
9395+ tmp_mem.mask = DRM_BO_FLAG_MEM_TT |
9396+ DRM_BO_FLAG_CACHED | DRM_BO_FLAG_FORCE_CACHING;
9397+
9398+ ret = drm_bo_mem_space(bo, &tmp_mem, no_wait);
9399+ if (ret)
9400+ return ret;
9401+ ret = drm_bind_ttm(bo->ttm, &tmp_mem);
9402+ if (ret)
9403+ goto out_cleanup;
9404+ ret = psb_move_blit(bo, 1, no_wait, &tmp_mem);
9405+ if (ret)
9406+ goto out_cleanup;
9407+
9408+ ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem);
9409+ out_cleanup:
9410+ if (tmp_mem.mm_node) {
9411+ mutex_lock(&dev->struct_mutex);
9412+ if (tmp_mem.mm_node != bo->pinned_node)
9413+ drm_mm_put_block(tmp_mem.mm_node);
9414+ tmp_mem.mm_node = NULL;
9415+ mutex_unlock(&dev->struct_mutex);
9416+ }
9417+ return ret;
9418+}
9419+
9420+int psb_move(struct drm_buffer_object *bo,
9421+ int evict, int no_wait, struct drm_bo_mem_reg *new_mem)
9422+{
9423+ struct drm_bo_mem_reg *old_mem = &bo->mem;
9424+
9425+ if (old_mem->mem_type == DRM_BO_MEM_LOCAL) {
9426+ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
9427+ } else if (new_mem->mem_type == DRM_BO_MEM_LOCAL) {
9428+ if (psb_move_flip(bo, evict, no_wait, new_mem))
9429+ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
9430+ } else {
9431+ if (psb_move_blit(bo, evict, no_wait, new_mem))
9432+ return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
9433+ }
9434+ return 0;
9435+}
9436+
9437+static int drm_psb_tbe_nca(struct drm_ttm_backend *backend)
9438+{
9439+ return ((backend->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1);
9440+}
9441+
9442+static int drm_psb_tbe_populate(struct drm_ttm_backend *backend,
9443+ unsigned long num_pages, struct page **pages)
9444+{
9445+ struct drm_psb_ttm_backend *psb_be =
9446+ container_of(backend, struct drm_psb_ttm_backend, base);
9447+
9448+ psb_be->pages = pages;
9449+ return 0;
9450+}
9451+
9452+static int drm_psb_tbe_unbind(struct drm_ttm_backend *backend)
9453+{
9454+ struct drm_device *dev = backend->dev;
9455+ struct drm_psb_private *dev_priv =
9456+ (struct drm_psb_private *)dev->dev_private;
9457+ struct drm_psb_ttm_backend *psb_be =
9458+ container_of(backend, struct drm_psb_ttm_backend, base);
9459+ struct psb_mmu_pd *pd = psb_mmu_get_default_pd(dev_priv->mmu);
9460+ struct drm_mem_type_manager *man = &dev->bm.man[psb_be->mem_type];
9461+
9462+ PSB_DEBUG_RENDER("MMU unbind.\n");
9463+
9464+ if (psb_be->mem_type == DRM_BO_MEM_TT) {
9465+ uint32_t gatt_p_offset = (psb_be->offset - man->gpu_offset) >>
9466+ PAGE_SHIFT;
9467+
9468+ (void)psb_gtt_remove_pages(dev_priv->pg, gatt_p_offset,
9469+ psb_be->num_pages,
9470+ psb_be->desired_tile_stride,
9471+ psb_be->hw_tile_stride);
9472+ }
9473+
9474+ psb_mmu_remove_pages(pd, psb_be->offset,
9475+ psb_be->num_pages,
9476+ psb_be->desired_tile_stride,
9477+ psb_be->hw_tile_stride);
9478+
9479+ return 0;
9480+}
9481+
9482+static int drm_psb_tbe_bind(struct drm_ttm_backend *backend,
9483+ struct drm_bo_mem_reg *bo_mem)
9484+{
9485+ struct drm_device *dev = backend->dev;
9486+ struct drm_psb_private *dev_priv =
9487+ (struct drm_psb_private *)dev->dev_private;
9488+ struct drm_psb_ttm_backend *psb_be =
9489+ container_of(backend, struct drm_psb_ttm_backend, base);
9490+ struct psb_mmu_pd *pd = psb_mmu_get_default_pd(dev_priv->mmu);
9491+ struct drm_mem_type_manager *man = &dev->bm.man[bo_mem->mem_type];
9492+ int type;
9493+ int ret = 0;
9494+
9495+ psb_be->mem_type = bo_mem->mem_type;
9496+ psb_be->num_pages = bo_mem->num_pages;
9497+ psb_be->desired_tile_stride = bo_mem->desired_tile_stride;
9498+ psb_be->hw_tile_stride = bo_mem->hw_tile_stride;
9499+ psb_be->desired_tile_stride = 0;
9500+ psb_be->hw_tile_stride = 0;
9501+ psb_be->offset = (bo_mem->mm_node->start << PAGE_SHIFT) +
9502+ man->gpu_offset;
9503+
9504+ type = (bo_mem->flags & DRM_BO_FLAG_CACHED) ? PSB_MMU_CACHED_MEMORY : 0;
9505+
9506+ PSB_DEBUG_RENDER("MMU bind.\n");
9507+ if (psb_be->mem_type == DRM_BO_MEM_TT) {
9508+ uint32_t gatt_p_offset = (psb_be->offset - man->gpu_offset) >>
9509+ PAGE_SHIFT;
9510+
9511+ ret = psb_gtt_insert_pages(dev_priv->pg, psb_be->pages,
9512+ gatt_p_offset,
9513+ psb_be->num_pages,
9514+ psb_be->desired_tile_stride,
9515+ psb_be->hw_tile_stride, type);
9516+ }
9517+
9518+ ret = psb_mmu_insert_pages(pd, psb_be->pages,
9519+ psb_be->offset, psb_be->num_pages,
9520+ psb_be->desired_tile_stride,
9521+ psb_be->hw_tile_stride, type);
9522+ if (ret)
9523+ goto out_err;
9524+
9525+ DRM_FLAG_MASKED(backend->flags, (bo_mem->flags & DRM_BO_FLAG_CACHED) ?
9526+ DRM_BE_FLAG_BOUND_CACHED : 0, DRM_BE_FLAG_BOUND_CACHED);
9527+
9528+ return 0;
9529+ out_err:
9530+ drm_psb_tbe_unbind(backend);
9531+ return ret;
9532+
9533+}
9534+
9535+static void drm_psb_tbe_clear(struct drm_ttm_backend *backend)
9536+{
9537+ struct drm_psb_ttm_backend *psb_be =
9538+ container_of(backend, struct drm_psb_ttm_backend, base);
9539+
9540+ psb_be->pages = NULL;
9541+ return;
9542+}
9543+
9544+static void drm_psb_tbe_destroy(struct drm_ttm_backend *backend)
9545+{
9546+ struct drm_psb_ttm_backend *psb_be =
9547+ container_of(backend, struct drm_psb_ttm_backend, base);
9548+
9549+ if (backend)
9550+ drm_free(psb_be, sizeof(*psb_be), DRM_MEM_TTM);
9551+}
9552+
9553+static struct drm_ttm_backend_func psb_ttm_backend = {
9554+ .needs_ub_cache_adjust = drm_psb_tbe_nca,
9555+ .populate = drm_psb_tbe_populate,
9556+ .clear = drm_psb_tbe_clear,
9557+ .bind = drm_psb_tbe_bind,
9558+ .unbind = drm_psb_tbe_unbind,
9559+ .destroy = drm_psb_tbe_destroy,
9560+};
9561+
9562+struct drm_ttm_backend *drm_psb_tbe_init(struct drm_device *dev)
9563+{
9564+ struct drm_psb_ttm_backend *psb_be;
9565+
9566+ psb_be = drm_calloc(1, sizeof(*psb_be), DRM_MEM_TTM);
9567+ if (!psb_be)
9568+ return NULL;
9569+ psb_be->pages = NULL;
9570+ psb_be->base.func = &psb_ttm_backend;
9571+ psb_be->base.dev = dev;
9572+
9573+ return &psb_be->base;
9574+}
9575+
9576+int psb_tbe_size(struct drm_device *dev, unsigned long num_pages)
9577+{
9578+ /*
9579+ * Return the size of the structures themselves and the
9580+ * estimated size of the pagedir and pagetable entries.
9581+ */
9582+
9583+ return drm_size_align(sizeof(struct drm_psb_ttm_backend)) +
9584+ 8*num_pages;
9585+}
9586Index: linux-2.6.28/drivers/gpu/drm/psb/psb_drm.h
9587===================================================================
9588--- /dev/null 1970-01-01 00:00:00.000000000 +0000
9589+++ linux-2.6.28/drivers/gpu/drm/psb/psb_drm.h 2009-02-12 09:14:41.000000000 +0000
9590@@ -0,0 +1,370 @@
9591+/**************************************************************************
9592+ * Copyright (c) 2007, Intel Corporation.
9593+ * All Rights Reserved.
9594+ *
9595+ * This program is free software; you can redistribute it and/or modify it
9596+ * under the terms and conditions of the GNU General Public License,
9597+ * version 2, as published by the Free Software Foundation.
9598+ *
9599+ * This program is distributed in the hope it will be useful, but WITHOUT
9600+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9601+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
9602+ * more details.
9603+ *
9604+ * You should have received a copy of the GNU General Public License along with
9605+ * this program; if not, write to the Free Software Foundation, Inc.,
9606+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
9607+ *
9608+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
9609+ * develop this driver.
9610+ *
9611+ **************************************************************************/
9612+/*
9613+ */
9614+
9615+#ifndef _PSB_DRM_H_
9616+#define _PSB_DRM_H_
9617+
9618+#if defined(__linux__) && !defined(__KERNEL__)
9619+#include<stdint.h>
9620+#endif
9621+
9622+/*
9623+ * Intel Poulsbo driver package version.
9624+ *
9625+ */
9626+/* #define PSB_PACKAGE_VERSION "ED"__DATE__*/
9627+#define PSB_PACKAGE_VERSION "2.1.0.32L.0019"
9628+
9629+#define DRM_PSB_SAREA_MAJOR 0
9630+#define DRM_PSB_SAREA_MINOR 1
9631+#define PSB_FIXED_SHIFT 16
9632+
9633+/*
9634+ * Public memory types.
9635+ */
9636+
9637+#define DRM_PSB_MEM_MMU DRM_BO_MEM_PRIV1
9638+#define DRM_PSB_FLAG_MEM_MMU DRM_BO_FLAG_MEM_PRIV1
9639+#define DRM_PSB_MEM_PDS DRM_BO_MEM_PRIV2
9640+#define DRM_PSB_FLAG_MEM_PDS DRM_BO_FLAG_MEM_PRIV2
9641+#define DRM_PSB_MEM_APER DRM_BO_MEM_PRIV3
9642+#define DRM_PSB_FLAG_MEM_APER DRM_BO_FLAG_MEM_PRIV3
9643+#define DRM_PSB_MEM_RASTGEOM DRM_BO_MEM_PRIV4
9644+#define DRM_PSB_FLAG_MEM_RASTGEOM DRM_BO_FLAG_MEM_PRIV4
9645+#define PSB_MEM_RASTGEOM_START 0x30000000
9646+
9647+typedef int32_t psb_fixed;
9648+typedef uint32_t psb_ufixed;
9649+
9650+static inline psb_fixed psb_int_to_fixed(int a)
9651+{
9652+ return a * (1 << PSB_FIXED_SHIFT);
9653+}
9654+
9655+static inline psb_ufixed psb_unsigned_to_ufixed(unsigned int a)
9656+{
9657+ return a << PSB_FIXED_SHIFT;
9658+}
9659+
9660+/*Status of the command sent to the gfx device.*/
9661+typedef enum {
9662+ DRM_CMD_SUCCESS,
9663+ DRM_CMD_FAILED,
9664+ DRM_CMD_HANG
9665+} drm_cmd_status_t;
9666+
9667+struct drm_psb_scanout {
9668+ uint32_t buffer_id; /* DRM buffer object ID */
9669+ uint32_t rotation; /* Rotation as in RR_rotation definitions */
9670+ uint32_t stride; /* Buffer stride in bytes */
9671+ uint32_t depth; /* Buffer depth in bits (NOT) bpp */
9672+ uint32_t width; /* Buffer width in pixels */
9673+ uint32_t height; /* Buffer height in lines */
9674+ psb_fixed transform[3][3]; /* Buffer composite transform */
9675+ /* (scaling, rot, reflect) */
9676+};
9677+
9678+#define DRM_PSB_SAREA_OWNERS 16
9679+#define DRM_PSB_SAREA_OWNER_2D 0
9680+#define DRM_PSB_SAREA_OWNER_3D 1
9681+
9682+#define DRM_PSB_SAREA_SCANOUTS 3
9683+
9684+struct drm_psb_sarea {
9685+ /* Track changes of this data structure */
9686+
9687+ uint32_t major;
9688+ uint32_t minor;
9689+
9690+ /* Last context to touch part of hw */
9691+ uint32_t ctx_owners[DRM_PSB_SAREA_OWNERS];
9692+
9693+ /* Definition of front- and rotated buffers */
9694+ uint32_t num_scanouts;
9695+ struct drm_psb_scanout scanouts[DRM_PSB_SAREA_SCANOUTS];
9696+
9697+ int pipeA_x;
9698+ int pipeA_y;
9699+ int pipeA_w;
9700+ int pipeA_h;
9701+ int pipeB_x;
9702+ int pipeB_y;
9703+ int pipeB_w;
9704+ int pipeB_h;
9705+ uint32_t msvdx_state;
9706+ uint32_t msvdx_context;
9707+};
9708+
9709+#define PSB_RELOC_MAGIC 0x67676767
9710+#define PSB_RELOC_SHIFT_MASK 0x0000FFFF
9711+#define PSB_RELOC_SHIFT_SHIFT 0
9712+#define PSB_RELOC_ALSHIFT_MASK 0xFFFF0000
9713+#define PSB_RELOC_ALSHIFT_SHIFT 16
9714+
9715+#define PSB_RELOC_OP_OFFSET 0 /* Offset of the indicated
9716+ * buffer
9717+ */
9718+#define PSB_RELOC_OP_2D_OFFSET 1 /* Offset of the indicated
9719+ * buffer, relative to 2D
9720+ * base address
9721+ */
9722+#define PSB_RELOC_OP_PDS_OFFSET 2 /* Offset of the indicated buffer,
9723+ * relative to PDS base address
9724+ */
9725+#define PSB_RELOC_OP_STRIDE 3 /* Stride of the indicated
9726+ * buffer (for tiling)
9727+ */
9728+#define PSB_RELOC_OP_USE_OFFSET 4 /* Offset of USE buffer
9729+ * relative to base reg
9730+ */
9731+#define PSB_RELOC_OP_USE_REG 5 /* Base reg of USE buffer */
9732+
9733+struct drm_psb_reloc {
9734+ uint32_t reloc_op;
9735+ uint32_t where; /* offset in destination buffer */
9736+ uint32_t buffer; /* Buffer reloc applies to */
9737+ uint32_t mask; /* Destination format: */
9738+ uint32_t shift; /* Destination format: */
9739+ uint32_t pre_add; /* Destination format: */
9740+ uint32_t background; /* Destination add */
9741+ uint32_t dst_buffer; /* Destination buffer. Index into buffer_list */
9742+ uint32_t arg0; /* Reloc-op dependant */
9743+ uint32_t arg1;
9744+};
9745+
9746+#define PSB_BO_FLAG_TA (1ULL << 48)
9747+#define PSB_BO_FLAG_SCENE (1ULL << 49)
9748+#define PSB_BO_FLAG_FEEDBACK (1ULL << 50)
9749+#define PSB_BO_FLAG_USSE (1ULL << 51)
9750+
9751+#define PSB_ENGINE_2D 0
9752+#define PSB_ENGINE_VIDEO 1
9753+#define PSB_ENGINE_RASTERIZER 2
9754+#define PSB_ENGINE_TA 3
9755+#define PSB_ENGINE_HPRAST 4
9756+
9757+/*
9758+ * For this fence class we have a couple of
9759+ * fence types.
9760+ */
9761+
9762+#define _PSB_FENCE_EXE_SHIFT 0
9763+#define _PSB_FENCE_TA_DONE_SHIFT 1
9764+#define _PSB_FENCE_RASTER_DONE_SHIFT 2
9765+#define _PSB_FENCE_SCENE_DONE_SHIFT 3
9766+#define _PSB_FENCE_FEEDBACK_SHIFT 4
9767+
9768+#define _PSB_ENGINE_TA_FENCE_TYPES 5
9769+#define _PSB_FENCE_TYPE_TA_DONE (1 << _PSB_FENCE_TA_DONE_SHIFT)
9770+#define _PSB_FENCE_TYPE_RASTER_DONE (1 << _PSB_FENCE_RASTER_DONE_SHIFT)
9771+#define _PSB_FENCE_TYPE_SCENE_DONE (1 << _PSB_FENCE_SCENE_DONE_SHIFT)
9772+#define _PSB_FENCE_TYPE_FEEDBACK (1 << _PSB_FENCE_FEEDBACK_SHIFT)
9773+
9774+#define PSB_ENGINE_HPRAST 4
9775+#define PSB_NUM_ENGINES 5
9776+
9777+#define PSB_TA_FLAG_FIRSTPASS (1 << 0)
9778+#define PSB_TA_FLAG_LASTPASS (1 << 1)
9779+
9780+#define PSB_FEEDBACK_OP_VISTEST (1 << 0)
9781+
9782+struct drm_psb_scene {
9783+ int handle_valid;
9784+ uint32_t handle;
9785+ uint32_t w;
9786+ uint32_t h;
9787+ uint32_t num_buffers;
9788+};
9789+
9790+struct drm_psb_hw_info
9791+{
9792+ uint32_t rev_id;
9793+ uint32_t caps;
9794+};
9795+
9796+typedef struct drm_psb_cmdbuf_arg {
9797+ uint64_t buffer_list; /* List of buffers to validate */
9798+ uint64_t clip_rects; /* See i915 counterpart */
9799+ uint64_t scene_arg;
9800+ uint64_t fence_arg;
9801+
9802+ uint32_t ta_flags;
9803+
9804+ uint32_t ta_handle; /* TA reg-value pairs */
9805+ uint32_t ta_offset;
9806+ uint32_t ta_size;
9807+
9808+ uint32_t oom_handle;
9809+ uint32_t oom_offset;
9810+ uint32_t oom_size;
9811+
9812+ uint32_t cmdbuf_handle; /* 2D Command buffer object or, */
9813+ uint32_t cmdbuf_offset; /* rasterizer reg-value pairs */
9814+ uint32_t cmdbuf_size;
9815+
9816+ uint32_t reloc_handle; /* Reloc buffer object */
9817+ uint32_t reloc_offset;
9818+ uint32_t num_relocs;
9819+
9820+ int32_t damage; /* Damage front buffer with cliprects */
9821+ /* Not implemented yet */
9822+ uint32_t fence_flags;
9823+ uint32_t engine;
9824+
9825+ /*
9826+ * Feedback;
9827+ */
9828+
9829+ uint32_t feedback_ops;
9830+ uint32_t feedback_handle;
9831+ uint32_t feedback_offset;
9832+ uint32_t feedback_breakpoints;
9833+ uint32_t feedback_size;
9834+} drm_psb_cmdbuf_arg_t;
9835+
9836+struct drm_psb_xhw_init_arg {
9837+ uint32_t operation;
9838+ uint32_t buffer_handle;
9839+};
9840+
9841+/*
9842+ * Feedback components:
9843+ */
9844+
9845+/*
9846+ * Vistest component. The number of these in the feedback buffer
9847+ * equals the number of vistest breakpoints + 1.
9848+ * This is currently the only feedback component.
9849+ */
9850+
9851+struct drm_psb_vistest {
9852+ uint32_t vt[8];
9853+};
9854+
9855+#define PSB_HW_COOKIE_SIZE 16
9856+#define PSB_HW_FEEDBACK_SIZE 8
9857+#define PSB_HW_OOM_CMD_SIZE 6
9858+
9859+struct drm_psb_xhw_arg {
9860+ uint32_t op;
9861+ int ret;
9862+ uint32_t irq_op;
9863+ uint32_t issue_irq;
9864+ uint32_t cookie[PSB_HW_COOKIE_SIZE];
9865+ union {
9866+ struct {
9867+ uint32_t w;
9868+ uint32_t h;
9869+ uint32_t size;
9870+ uint32_t clear_p_start;
9871+ uint32_t clear_num_pages;
9872+ } si;
9873+ struct {
9874+ uint32_t fire_flags;
9875+ uint32_t hw_context;
9876+ uint32_t offset;
9877+ uint32_t engine;
9878+ uint32_t flags;
9879+ uint32_t rca;
9880+ uint32_t num_oom_cmds;
9881+ uint32_t oom_cmds[PSB_HW_OOM_CMD_SIZE];
9882+ } sb;
9883+ struct {
9884+ uint32_t pages;
9885+ uint32_t size;
9886+ } bi;
9887+ struct {
9888+ uint32_t bca;
9889+ uint32_t rca;
9890+ uint32_t flags;
9891+ } oom;
9892+ struct {
9893+ uint32_t pt_offset;
9894+ uint32_t param_offset;
9895+ uint32_t flags;
9896+ } bl;
9897+ struct {
9898+ uint32_t value;
9899+ } cl;
9900+ uint32_t feedback[PSB_HW_FEEDBACK_SIZE];
9901+ } arg;
9902+};
9903+
9904+#define DRM_PSB_CMDBUF 0x00
9905+#define DRM_PSB_XHW_INIT 0x01
9906+#define DRM_PSB_XHW 0x02
9907+#define DRM_PSB_SCENE_UNREF 0x03
9908+/* Controlling the kernel modesetting buffers */
9909+#define DRM_PSB_KMS_OFF 0x04
9910+#define DRM_PSB_KMS_ON 0x05
9911+#define DRM_PSB_HW_INFO 0x06
9912+
9913+#define PSB_XHW_INIT 0x00
9914+#define PSB_XHW_TAKEDOWN 0x01
9915+
9916+#define PSB_XHW_FIRE_RASTER 0x00
9917+#define PSB_XHW_SCENE_INFO 0x01
9918+#define PSB_XHW_SCENE_BIND_FIRE 0x02
9919+#define PSB_XHW_TA_MEM_INFO 0x03
9920+#define PSB_XHW_RESET_DPM 0x04
9921+#define PSB_XHW_OOM 0x05
9922+#define PSB_XHW_TERMINATE 0x06
9923+#define PSB_XHW_VISTEST 0x07
9924+#define PSB_XHW_RESUME 0x08
9925+#define PSB_XHW_TA_MEM_LOAD 0x09
9926+#define PSB_XHW_CHECK_LOCKUP 0x0a
9927+
9928+#define PSB_SCENE_FLAG_DIRTY (1 << 0)
9929+#define PSB_SCENE_FLAG_COMPLETE (1 << 1)
9930+#define PSB_SCENE_FLAG_SETUP (1 << 2)
9931+#define PSB_SCENE_FLAG_SETUP_ONLY (1 << 3)
9932+#define PSB_SCENE_FLAG_CLEARED (1 << 4)
9933+
9934+#define PSB_TA_MEM_FLAG_TA (1 << 0)
9935+#define PSB_TA_MEM_FLAG_RASTER (1 << 1)
9936+#define PSB_TA_MEM_FLAG_HOSTA (1 << 2)
9937+#define PSB_TA_MEM_FLAG_HOSTD (1 << 3)
9938+#define PSB_TA_MEM_FLAG_INIT (1 << 4)
9939+#define PSB_TA_MEM_FLAG_NEW_PT_OFFSET (1 << 5)
9940+
9941+/*Raster fire will deallocate memory */
9942+#define PSB_FIRE_FLAG_RASTER_DEALLOC (1 << 0)
9943+/*Isp reset needed due to change in ZLS format */
9944+#define PSB_FIRE_FLAG_NEEDS_ISP_RESET (1 << 1)
9945+/*These are set by Xpsb. */
9946+#define PSB_FIRE_FLAG_XHW_MASK 0xff000000
9947+/*The task has had at least one OOM and Xpsb will
9948+ send back messages on each fire. */
9949+#define PSB_FIRE_FLAG_XHW_OOM (1 << 24)
9950+
9951+#define PSB_SCENE_ENGINE_TA 0
9952+#define PSB_SCENE_ENGINE_RASTER 1
9953+#define PSB_SCENE_NUM_ENGINES 2
9954+
9955+struct drm_psb_dev_info_arg {
9956+ uint32_t num_use_attribute_registers;
9957+};
9958+#define DRM_PSB_DEVINFO 0x01
9959+
9960+#endif
9961Index: linux-2.6.28/drivers/gpu/drm/psb/psb_drv.c
9962===================================================================
9963--- /dev/null 1970-01-01 00:00:00.000000000 +0000
9964+++ linux-2.6.28/drivers/gpu/drm/psb/psb_drv.c 2009-02-12 09:14:41.000000000 +0000
9965@@ -0,0 +1,1096 @@
9966+/**************************************************************************
9967+ * Copyright (c) 2007, Intel Corporation.
9968+ * All Rights Reserved.
9969+ *
9970+ * This program is free software; you can redistribute it and/or modify it
9971+ * under the terms and conditions of the GNU General Public License,
9972+ * version 2, as published by the Free Software Foundation.
9973+ *
9974+ * This program is distributed in the hope it will be useful, but WITHOUT
9975+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9976+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
9977+ * more details.
9978+ *
9979+ * You should have received a copy of the GNU General Public License along with
9980+ * this program; if not, write to the Free Software Foundation, Inc.,
9981+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
9982+ *
9983+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
9984+ * develop this driver.
9985+ *
9986+ **************************************************************************/
9987+/*
9988+ */
9989+
9990+#include "drmP.h"
9991+#include "drm.h"
9992+#include "psb_drm.h"
9993+#include "psb_drv.h"
9994+#include "psb_reg.h"
9995+#include "i915_reg.h"
9996+#include "psb_msvdx.h"
9997+#include "drm_pciids.h"
9998+#include "psb_scene.h"
9999+#include "drm_crtc.h"
10000+#include "drm_crtc_helper.h"
10001+#include <linux/cpu.h>
10002+#include <linux/notifier.h>
10003+#include <linux/fb.h>
10004+
10005+extern int drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX, uint32_t maxY);
10006+
10007+int drm_psb_debug = 0;
10008+EXPORT_SYMBOL(drm_psb_debug);
10009+static int drm_psb_trap_pagefaults = 0;
10010+static int drm_psb_clock_gating = 0;
10011+static int drm_psb_ta_mem_size = 32 * 1024;
10012+int drm_psb_disable_vsync = 1;
10013+int drm_psb_no_fb = 0;
10014+int drm_psb_force_pipeb = 0;
10015+char* psb_init_mode;
10016+/*
10017+ *
10018+ */
10019+#define SII_1392_WA
10020+#ifdef SII_1392_WA
10021+extern int SII_1392;
10022+#endif
10023+
10024+MODULE_PARM_DESC(debug, "Enable debug output");
10025+MODULE_PARM_DESC(clock_gating, "clock gating");
10026+MODULE_PARM_DESC(no_fb, "Disable FBdev");
10027+MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults");
10028+MODULE_PARM_DESC(disable_vsync, "Disable vsync interrupts");
10029+MODULE_PARM_DESC(force_pipeb, "Forces PIPEB to become primary fb");
10030+MODULE_PARM_DESC(ta_mem_size, "TA memory size in kiB");
10031+MODULE_PARM_DESC(mode, "initial mode name");
10032+MODULE_PARM_DESC(xres, "initial mode width");
10033+MODULE_PARM_DESC(yres, "initial mode height");
10034+
10035+module_param_named(debug, drm_psb_debug, int, 0600);
10036+module_param_named(clock_gating, drm_psb_clock_gating, int, 0600);
10037+module_param_named(no_fb, drm_psb_no_fb, int, 0600);
10038+module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600);
10039+module_param_named(disable_vsync, drm_psb_disable_vsync, int, 0600);
10040+module_param_named(force_pipeb, drm_psb_force_pipeb, int, 0600);
10041+module_param_named(ta_mem_size, drm_psb_ta_mem_size, int, 0600);
10042+module_param_named(mode, psb_init_mode, charp, 0600);
10043+
10044+static struct pci_device_id pciidlist[] = {
10045+ psb_PCI_IDS
10046+};
10047+
10048+#define DRM_PSB_CMDBUF_IOCTL DRM_IOW(DRM_PSB_CMDBUF, \
10049+ struct drm_psb_cmdbuf_arg)
10050+#define DRM_PSB_XHW_INIT_IOCTL DRM_IOR(DRM_PSB_XHW_INIT, \
10051+ struct drm_psb_xhw_init_arg)
10052+#define DRM_PSB_XHW_IOCTL DRM_IO(DRM_PSB_XHW)
10053+
10054+#define DRM_PSB_SCENE_UNREF_IOCTL DRM_IOWR(DRM_PSB_SCENE_UNREF, \
10055+ struct drm_psb_scene)
10056+#define DRM_PSB_HW_INFO_IOCTL DRM_IOR(DRM_PSB_HW_INFO, \
10057+ struct drm_psb_hw_info)
10058+
10059+#define DRM_PSB_KMS_OFF_IOCTL DRM_IO(DRM_PSB_KMS_OFF)
10060+#define DRM_PSB_KMS_ON_IOCTL DRM_IO(DRM_PSB_KMS_ON)
10061+
10062+static struct drm_ioctl_desc psb_ioctls[] = {
10063+ DRM_IOCTL_DEF(DRM_PSB_CMDBUF_IOCTL, psb_cmdbuf_ioctl, DRM_AUTH),
10064+ DRM_IOCTL_DEF(DRM_PSB_XHW_INIT_IOCTL, psb_xhw_init_ioctl,
10065+ DRM_ROOT_ONLY),
10066+ DRM_IOCTL_DEF(DRM_PSB_XHW_IOCTL, psb_xhw_ioctl, DRM_ROOT_ONLY),
10067+ DRM_IOCTL_DEF(DRM_PSB_SCENE_UNREF_IOCTL, drm_psb_scene_unref_ioctl,
10068+ DRM_AUTH),
10069+ DRM_IOCTL_DEF(DRM_PSB_KMS_OFF_IOCTL, psbfb_kms_off_ioctl,
10070+ DRM_ROOT_ONLY),
10071+ DRM_IOCTL_DEF(DRM_PSB_KMS_ON_IOCTL, psbfb_kms_on_ioctl, DRM_ROOT_ONLY),
10072+ DRM_IOCTL_DEF(DRM_PSB_HW_INFO_IOCTL, psb_hw_info_ioctl, DRM_AUTH),
10073+};
10074+static int psb_max_ioctl = DRM_ARRAY_SIZE(psb_ioctls);
10075+
10076+static int probe(struct pci_dev *pdev, const struct pci_device_id *ent);
10077+
10078+#ifdef USE_PAT_WC
10079+#warning Init pat
10080+static int __cpuinit psb_cpu_callback(struct notifier_block *nfb,
10081+ unsigned long action,
10082+ void *hcpu)
10083+{
10084+ if (action == CPU_ONLINE)
10085+ drm_init_pat();
10086+
10087+ return 0;
10088+}
10089+
10090+static struct notifier_block __cpuinitdata psb_nb = {
10091+ .notifier_call = psb_cpu_callback,
10092+ .priority = 1
10093+};
10094+#endif
10095+
10096+static int dri_library_name(struct drm_device *dev, char *buf)
10097+{
10098+ return snprintf(buf, PAGE_SIZE, "psb\n");
10099+}
10100+
10101+static void psb_set_uopt(struct drm_psb_uopt *uopt)
10102+{
10103+ uopt->clock_gating = drm_psb_clock_gating;
10104+}
10105+
10106+static void psb_lastclose(struct drm_device *dev)
10107+{
10108+ struct drm_psb_private *dev_priv =
10109+ (struct drm_psb_private *)dev->dev_private;
10110+
10111+ if (!dev->dev_private)
10112+ return;
10113+
10114+ mutex_lock(&dev->struct_mutex);
10115+ if (dev_priv->ta_mem)
10116+ psb_ta_mem_unref_devlocked(&dev_priv->ta_mem);
10117+ mutex_unlock(&dev->struct_mutex);
10118+ mutex_lock(&dev_priv->cmdbuf_mutex);
10119+ if (dev_priv->buffers) {
10120+ vfree(dev_priv->buffers);
10121+ dev_priv->buffers = NULL;
10122+ }
10123+ mutex_unlock(&dev_priv->cmdbuf_mutex);
10124+}
10125+
10126+static void psb_do_takedown(struct drm_device *dev)
10127+{
10128+ struct drm_psb_private *dev_priv =
10129+ (struct drm_psb_private *)dev->dev_private;
10130+
10131+ mutex_lock(&dev->struct_mutex);
10132+ if (dev->bm.initialized) {
10133+ if (dev_priv->have_mem_rastgeom) {
10134+ drm_bo_clean_mm(dev, DRM_PSB_MEM_RASTGEOM);
10135+ dev_priv->have_mem_rastgeom = 0;
10136+ }
10137+ if (dev_priv->have_mem_mmu) {
10138+ drm_bo_clean_mm(dev, DRM_PSB_MEM_MMU);
10139+ dev_priv->have_mem_mmu = 0;
10140+ }
10141+ if (dev_priv->have_mem_aper) {
10142+ drm_bo_clean_mm(dev, DRM_PSB_MEM_APER);
10143+ dev_priv->have_mem_aper = 0;
10144+ }
10145+ if (dev_priv->have_tt) {
10146+ drm_bo_clean_mm(dev, DRM_BO_MEM_TT);
10147+ dev_priv->have_tt = 0;
10148+ }
10149+ if (dev_priv->have_vram) {
10150+ drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM);
10151+ dev_priv->have_vram = 0;
10152+ }
10153+ }
10154+ mutex_unlock(&dev->struct_mutex);
10155+
10156+ if (dev_priv->has_msvdx)
10157+ psb_msvdx_uninit(dev);
10158+
10159+ if (dev_priv->comm) {
10160+ kunmap(dev_priv->comm_page);
10161+ dev_priv->comm = NULL;
10162+ }
10163+ if (dev_priv->comm_page) {
10164+ __free_page(dev_priv->comm_page);
10165+ dev_priv->comm_page = NULL;
10166+ }
10167+}
10168+
10169+void psb_clockgating(struct drm_psb_private *dev_priv)
10170+{
10171+ uint32_t clock_gating;
10172+
10173+ if (dev_priv->uopt.clock_gating == 1) {
10174+ PSB_DEBUG_INIT("Disabling clock gating.\n");
10175+
10176+ clock_gating = (_PSB_C_CLKGATECTL_CLKG_DISABLED <<
10177+ _PSB_C_CLKGATECTL_2D_CLKG_SHIFT) |
10178+ (_PSB_C_CLKGATECTL_CLKG_DISABLED <<
10179+ _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT) |
10180+ (_PSB_C_CLKGATECTL_CLKG_DISABLED <<
10181+ _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT) |
10182+ (_PSB_C_CLKGATECTL_CLKG_DISABLED <<
10183+ _PSB_C_CLKGATECTL_TA_CLKG_SHIFT) |
10184+ (_PSB_C_CLKGATECTL_CLKG_DISABLED <<
10185+ _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT) |
10186+ (_PSB_C_CLKGATECTL_CLKG_DISABLED <<
10187+ _PSB_C_CLKGATECTL_USE_CLKG_SHIFT);
10188+
10189+ } else if (dev_priv->uopt.clock_gating == 2) {
10190+ PSB_DEBUG_INIT("Enabling clock gating.\n");
10191+
10192+ clock_gating = (_PSB_C_CLKGATECTL_CLKG_AUTO <<
10193+ _PSB_C_CLKGATECTL_2D_CLKG_SHIFT) |
10194+ (_PSB_C_CLKGATECTL_CLKG_AUTO <<
10195+ _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT) |
10196+ (_PSB_C_CLKGATECTL_CLKG_AUTO <<
10197+ _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT) |
10198+ (_PSB_C_CLKGATECTL_CLKG_AUTO <<
10199+ _PSB_C_CLKGATECTL_TA_CLKG_SHIFT) |
10200+ (_PSB_C_CLKGATECTL_CLKG_AUTO <<
10201+ _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT) |
10202+ (_PSB_C_CLKGATECTL_CLKG_AUTO <<
10203+ _PSB_C_CLKGATECTL_USE_CLKG_SHIFT);
10204+ } else
10205+ clock_gating = PSB_RSGX32(PSB_CR_CLKGATECTL);
10206+
10207+#ifdef FIX_TG_2D_CLOCKGATE
10208+ clock_gating &= ~_PSB_C_CLKGATECTL_2D_CLKG_MASK;
10209+ clock_gating |= (_PSB_C_CLKGATECTL_CLKG_DISABLED <<
10210+ _PSB_C_CLKGATECTL_2D_CLKG_SHIFT);
10211+#endif
10212+ PSB_WSGX32(clock_gating, PSB_CR_CLKGATECTL);
10213+ (void)PSB_RSGX32(PSB_CR_CLKGATECTL);
10214+}
10215+
10216+static int psb_do_init(struct drm_device *dev)
10217+{
10218+ struct drm_psb_private *dev_priv =
10219+ (struct drm_psb_private *)dev->dev_private;
10220+ struct psb_gtt *pg = dev_priv->pg;
10221+
10222+ uint32_t stolen_gtt;
10223+ uint32_t tt_start;
10224+ uint32_t tt_pages;
10225+
10226+ int ret = -ENOMEM;
10227+
10228+ DRM_ERROR("Debug is 0x%08x\n", drm_psb_debug);
10229+
10230+ dev_priv->ta_mem_pages =
10231+ PSB_ALIGN_TO(drm_psb_ta_mem_size * 1024, PAGE_SIZE) >> PAGE_SHIFT;
10232+ dev_priv->comm_page = alloc_page(GFP_KERNEL);
10233+ if (!dev_priv->comm_page)
10234+ goto out_err;
10235+
10236+ dev_priv->comm = kmap(dev_priv->comm_page);
10237+ memset((void *)dev_priv->comm, 0, PAGE_SIZE);
10238+
10239+ dev_priv->has_msvdx = 1;
10240+ if (psb_msvdx_init(dev))
10241+ dev_priv->has_msvdx = 0;
10242+
10243+ /*
10244+ * Initialize sequence numbers for the different command
10245+ * submission mechanisms.
10246+ */
10247+
10248+ dev_priv->sequence[PSB_ENGINE_2D] = 0;
10249+ dev_priv->sequence[PSB_ENGINE_RASTERIZER] = 0;
10250+ dev_priv->sequence[PSB_ENGINE_TA] = 0;
10251+ dev_priv->sequence[PSB_ENGINE_HPRAST] = 0;
10252+
10253+ if (pg->gatt_start & 0x0FFFFFFF) {
10254+ DRM_ERROR("Gatt must be 256M aligned. This is a bug.\n");
10255+ ret = -EINVAL;
10256+ goto out_err;
10257+ }
10258+
10259+ stolen_gtt = (pg->stolen_size >> PAGE_SHIFT) * 4;
10260+ stolen_gtt = (stolen_gtt + PAGE_SIZE - 1) >> PAGE_SHIFT;
10261+ stolen_gtt = (stolen_gtt < pg->gtt_pages) ? stolen_gtt : pg->gtt_pages;
10262+
10263+ dev_priv->gatt_free_offset = pg->gatt_start +
10264+ (stolen_gtt << PAGE_SHIFT) * 1024;
10265+
10266+ /*
10267+ * Insert a cache-coherent communications page in mmu space
10268+ * just after the stolen area. Will be used for fencing etc.
10269+ */
10270+
10271+ dev_priv->comm_mmu_offset = dev_priv->gatt_free_offset;
10272+ dev_priv->gatt_free_offset += PAGE_SIZE;
10273+
10274+ ret = psb_mmu_insert_pages(psb_mmu_get_default_pd(dev_priv->mmu),
10275+ &dev_priv->comm_page,
10276+ dev_priv->comm_mmu_offset, 1, 0, 0,
10277+ PSB_MMU_CACHED_MEMORY);
10278+
10279+ if (ret)
10280+ goto out_err;
10281+
10282+ if (1 || drm_debug) {
10283+ uint32_t core_id = PSB_RSGX32(PSB_CR_CORE_ID);
10284+ uint32_t core_rev = PSB_RSGX32(PSB_CR_CORE_REVISION);
10285+ DRM_INFO("SGX core id = 0x%08x\n", core_id);
10286+ DRM_INFO("SGX core rev major = 0x%02x, minor = 0x%02x\n",
10287+ (core_rev & _PSB_CC_REVISION_MAJOR_MASK) >>
10288+ _PSB_CC_REVISION_MAJOR_SHIFT,
10289+ (core_rev & _PSB_CC_REVISION_MINOR_MASK) >>
10290+ _PSB_CC_REVISION_MINOR_SHIFT);
10291+ DRM_INFO
10292+ ("SGX core rev maintenance = 0x%02x, designer = 0x%02x\n",
10293+ (core_rev & _PSB_CC_REVISION_MAINTENANCE_MASK) >>
10294+ _PSB_CC_REVISION_MAINTENANCE_SHIFT,
10295+ (core_rev & _PSB_CC_REVISION_DESIGNER_MASK) >>
10296+ _PSB_CC_REVISION_DESIGNER_SHIFT);
10297+ }
10298+
10299+ dev_priv->irqmask_lock = SPIN_LOCK_UNLOCKED;
10300+ dev_priv->fence0_irq_on = 0;
10301+
10302+ tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
10303+ pg->gatt_pages : PSB_TT_PRIV0_PLIMIT;
10304+ tt_start = dev_priv->gatt_free_offset - pg->gatt_start;
10305+ tt_pages -= tt_start >> PAGE_SHIFT;
10306+
10307+ mutex_lock(&dev->struct_mutex);
10308+
10309+ if (!drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0,
10310+ pg->stolen_size >> PAGE_SHIFT)) {
10311+ dev_priv->have_vram = 1;
10312+ }
10313+
10314+ if (!drm_bo_init_mm(dev, DRM_BO_MEM_TT, tt_start >> PAGE_SHIFT,
10315+ tt_pages)) {
10316+ dev_priv->have_tt = 1;
10317+ }
10318+
10319+ if (!drm_bo_init_mm(dev, DRM_PSB_MEM_MMU, 0x00000000,
10320+ (pg->gatt_start -
10321+ PSB_MEM_MMU_START) >> PAGE_SHIFT)) {
10322+ dev_priv->have_mem_mmu = 1;
10323+ }
10324+
10325+ if (!drm_bo_init_mm(dev, DRM_PSB_MEM_RASTGEOM, 0x00000000,
10326+ (PSB_MEM_MMU_START -
10327+ PSB_MEM_RASTGEOM_START) >> PAGE_SHIFT)) {
10328+ dev_priv->have_mem_rastgeom = 1;
10329+ }
10330+#if 0
10331+ if (pg->gatt_pages > PSB_TT_PRIV0_PLIMIT) {
10332+ if (!drm_bo_init_mm(dev, DRM_PSB_MEM_APER, PSB_TT_PRIV0_PLIMIT,
10333+ pg->gatt_pages - PSB_TT_PRIV0_PLIMIT)) {
10334+ dev_priv->have_mem_aper = 1;
10335+ }
10336+ }
10337+#endif
10338+
10339+ mutex_unlock(&dev->struct_mutex);
10340+
10341+ return 0;
10342+ out_err:
10343+ psb_do_takedown(dev);
10344+ return ret;
10345+}
10346+
10347+static int psb_driver_unload(struct drm_device *dev)
10348+{
10349+ struct drm_psb_private *dev_priv =
10350+ (struct drm_psb_private *)dev->dev_private;
10351+
10352+ intel_modeset_cleanup(dev);
10353+
10354+ if (dev_priv) {
10355+ psb_watchdog_takedown(dev_priv);
10356+ psb_do_takedown(dev);
10357+ psb_xhw_takedown(dev_priv);
10358+ psb_scheduler_takedown(&dev_priv->scheduler);
10359+
10360+ mutex_lock(&dev->struct_mutex);
10361+ if (dev_priv->have_mem_pds) {
10362+ drm_bo_clean_mm(dev, DRM_PSB_MEM_PDS);
10363+ dev_priv->have_mem_pds = 0;
10364+ }
10365+ if (dev_priv->have_mem_kernel) {
10366+ drm_bo_clean_mm(dev, DRM_PSB_MEM_KERNEL);
10367+ dev_priv->have_mem_kernel = 0;
10368+ }
10369+ mutex_unlock(&dev->struct_mutex);
10370+
10371+ (void)drm_bo_driver_finish(dev);
10372+
10373+ if (dev_priv->pf_pd) {
10374+ psb_mmu_free_pagedir(dev_priv->pf_pd);
10375+ dev_priv->pf_pd = NULL;
10376+ }
10377+ if (dev_priv->mmu) {
10378+ struct psb_gtt *pg = dev_priv->pg;
10379+
10380+ down_read(&pg->sem);
10381+ psb_mmu_remove_pfn_sequence(psb_mmu_get_default_pd
10382+ (dev_priv->mmu),
10383+ pg->gatt_start,
10384+ pg->
10385+ stolen_size >> PAGE_SHIFT);
10386+ up_read(&pg->sem);
10387+ psb_mmu_driver_takedown(dev_priv->mmu);
10388+ dev_priv->mmu = NULL;
10389+ }
10390+ psb_gtt_takedown(dev_priv->pg, 1);
10391+ if (dev_priv->scratch_page) {
10392+ __free_page(dev_priv->scratch_page);
10393+ dev_priv->scratch_page = NULL;
10394+ }
10395+ psb_takedown_use_base(dev_priv);
10396+ if (dev_priv->vdc_reg) {
10397+ iounmap(dev_priv->vdc_reg);
10398+ dev_priv->vdc_reg = NULL;
10399+ }
10400+ if (dev_priv->sgx_reg) {
10401+ iounmap(dev_priv->sgx_reg);
10402+ dev_priv->sgx_reg = NULL;
10403+ }
10404+ if (dev_priv->msvdx_reg) {
10405+ iounmap(dev_priv->msvdx_reg);
10406+ dev_priv->msvdx_reg = NULL;
10407+ }
10408+
10409+ drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
10410+ dev->dev_private = NULL;
10411+ }
10412+ return 0;
10413+}
10414+
10415+
10416+extern int drm_pick_crtcs(struct drm_device *dev);
10417+extern char drm_init_mode[32];
10418+
10419+static int psb_initial_config(struct drm_device *dev, bool can_grow)
10420+{
10421+ struct drm_psb_private *dev_priv = dev->dev_private;
10422+ struct drm_connector *output;
10423+ struct drm_crtc *crtc;
10424+ int ret = false;
10425+
10426+ mutex_lock(&dev->mode_config.mutex);
10427+
10428+ drm_helper_probe_connector_modes(dev, 2048, 2048);
10429+
10430+ /* strncpy(drm_init_mode, psb_init_mode, strlen(psb_init_mode)); */
10431+
10432+ drm_pick_crtcs(dev);
10433+
10434+ if ((I915_READ(PIPEACONF) & PIPEACONF_ENABLE) && !drm_psb_force_pipeb)
10435+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
10436+ if (!crtc->desired_mode)
10437+ continue;
10438+
10439+ dev->driver->fb_probe(dev, crtc);
10440+ } else
10441+ list_for_each_entry_reverse(crtc, &dev->mode_config.crtc_list,
10442+ head) {
10443+ if (!crtc->desired_mode)
10444+ continue;
10445+
10446+ dev->driver->fb_probe(dev, crtc);
10447+ }
10448+
10449+ list_for_each_entry(output, &dev->mode_config.connector_list, head) {
10450+
10451+ if (!output->encoder->crtc || !output->encoder->crtc->desired_mode)
10452+ continue;
10453+
10454+ if (output->encoder->crtc->fb)
10455+ drm_crtc_helper_set_mode(output->encoder->crtc,
10456+ output->encoder->crtc->desired_mode, 0, 0, NULL);
10457+ }
10458+
10459+#ifdef SII_1392_WA
10460+ if((SII_1392 != 1) || (drm_psb_no_fb==0))
10461+ drm_helper_disable_unused_functions(dev);
10462+#else
10463+ drm_helper_disable_unused_functions(dev);
10464+#endif
10465+
10466+
10467+ mutex_unlock(&dev->mode_config.mutex);
10468+
10469+ return ret;
10470+
10471+}
10472+
10473+static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
10474+{
10475+ struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
10476+ struct drm_device *dev = fb->dev;
10477+
10478+ //if (fb->fbdev)
10479+ // intelfb_remove(dev, fb);
10480+
10481+ drm_framebuffer_cleanup(fb);
10482+ mutex_lock(&dev->struct_mutex);
10483+ drm_gem_object_unreference(intel_fb->obj);
10484+ mutex_unlock(&dev->struct_mutex);
10485+
10486+ kfree(intel_fb);
10487+}
10488+
10489+static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
10490+ struct drm_file *file_priv,
10491+ unsigned int *handle)
10492+{
10493+ struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
10494+ struct drm_gem_object *object = intel_fb->obj;
10495+
10496+ return drm_gem_handle_create(file_priv, object, handle);
10497+}
10498+
10499+static const struct drm_framebuffer_funcs psb_fb_funcs = {
10500+ .destroy = psb_user_framebuffer_destroy,
10501+ .create_handle = psb_user_framebuffer_create_handle,
10502+};
10503+
10504+int psb_framebuffer_create(struct drm_device *dev,
10505+ struct drm_mode_fb_cmd *mode_cmd,
10506+ struct drm_framebuffer **fb,
10507+ struct drm_gem_object *obj)
10508+{
10509+ struct intel_framebuffer *intel_fb;
10510+ int ret;
10511+
10512+ intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
10513+ if (!intel_fb)
10514+ return -ENOMEM;
10515+
10516+ ret = drm_framebuffer_init(dev, &intel_fb->base, &psb_fb_funcs);
10517+ if (ret) {
10518+ DRM_ERROR("framebuffer init failed %d\n", ret);
10519+ return ret;
10520+ }
10521+
10522+ drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
10523+
10524+ intel_fb->obj = obj;
10525+
10526+ *fb = &intel_fb->base;
10527+
10528+ return 0;
10529+}
10530+
10531+
10532+static struct drm_framebuffer *
10533+psb_user_framebuffer_create(struct drm_device *dev,
10534+ struct drm_file *filp,
10535+ struct drm_mode_fb_cmd *mode_cmd)
10536+{
10537+ struct drm_gem_object *obj;
10538+ struct drm_framebuffer *fb;
10539+ int ret;
10540+
10541+ obj = drm_gem_object_lookup(dev, filp, mode_cmd->handle);
10542+ if (!obj)
10543+ return NULL;
10544+
10545+ ret = psb_framebuffer_create(dev, mode_cmd, &fb, obj);
10546+ if (ret) {
10547+ drm_gem_object_unreference(obj);
10548+ return NULL;
10549+ }
10550+
10551+ return fb;
10552+}
10553+
10554+
10555+int psbfb_probe2(struct drm_device *dev)
10556+{
10557+ return 0;
10558+}
10559+
10560+static const struct drm_mode_config_funcs psb_mode_funcs = {
10561+ .fb_create = psb_user_framebuffer_create,
10562+ .fb_changed = psbfb_probe2,
10563+};
10564+
10565+static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
10566+{
10567+ struct drm_psb_private *dev_priv;
10568+ unsigned long resource_start;
10569+ struct psb_gtt *pg;
10570+ int ret = -ENOMEM;
10571+
10572+ DRM_INFO("psb - %s\n", PSB_PACKAGE_VERSION);
10573+ dev_priv = drm_calloc(1, sizeof(*dev_priv), DRM_MEM_DRIVER);
10574+ if (dev_priv == NULL)
10575+ return -ENOMEM;
10576+
10577+ mutex_init(&dev_priv->temp_mem);
10578+ mutex_init(&dev_priv->cmdbuf_mutex);
10579+ mutex_init(&dev_priv->reset_mutex);
10580+ psb_init_disallowed();
10581+
10582+ atomic_set(&dev_priv->msvdx_mmu_invaldc, 0);
10583+
10584+#ifdef FIX_TG_16
10585+ atomic_set(&dev_priv->lock_2d, 0);
10586+ atomic_set(&dev_priv->ta_wait_2d, 0);
10587+ atomic_set(&dev_priv->ta_wait_2d_irq, 0);
10588+ atomic_set(&dev_priv->waiters_2d, 0);;
10589+ DRM_INIT_WAITQUEUE(&dev_priv->queue_2d);
10590+#else
10591+ mutex_init(&dev_priv->mutex_2d);
10592+#endif
10593+
10594+ spin_lock_init(&dev_priv->reloc_lock);
10595+
10596+ DRM_INIT_WAITQUEUE(&dev_priv->rel_mapped_queue);
10597+ DRM_INIT_WAITQUEUE(&dev_priv->event_2d_queue);
10598+
10599+ dev->dev_private = (void *)dev_priv;
10600+ dev_priv->chipset = chipset;
10601+ psb_set_uopt(&dev_priv->uopt);
10602+
10603+ psb_watchdog_init(dev_priv);
10604+ psb_scheduler_init(dev, &dev_priv->scheduler);
10605+
10606+ resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE);
10607+
10608+ dev_priv->msvdx_reg =
10609+ ioremap(resource_start + PSB_MSVDX_OFFSET, PSB_MSVDX_SIZE);
10610+ if (!dev_priv->msvdx_reg)
10611+ goto out_err;
10612+
10613+ dev_priv->vdc_reg =
10614+ ioremap(resource_start + PSB_VDC_OFFSET, PSB_VDC_SIZE);
10615+ if (!dev_priv->vdc_reg)
10616+ goto out_err;
10617+
10618+ dev_priv->sgx_reg =
10619+ ioremap(resource_start + PSB_SGX_OFFSET, PSB_SGX_SIZE);
10620+ if (!dev_priv->sgx_reg)
10621+ goto out_err;
10622+
10623+ psb_clockgating(dev_priv);
10624+ if (psb_init_use_base(dev_priv, 3, 13))
10625+ goto out_err;
10626+
10627+ dev_priv->scratch_page = alloc_page(GFP_DMA32 | __GFP_ZERO);
10628+ if (!dev_priv->scratch_page)
10629+ goto out_err;
10630+
10631+ dev_priv->pg = psb_gtt_alloc(dev);
10632+ if (!dev_priv->pg)
10633+ goto out_err;
10634+
10635+ ret = psb_gtt_init(dev_priv->pg, 0);
10636+ if (ret)
10637+ goto out_err;
10638+
10639+ dev_priv->mmu = psb_mmu_driver_init(dev_priv->sgx_reg,
10640+ drm_psb_trap_pagefaults, 0,
10641+ &dev_priv->msvdx_mmu_invaldc);
10642+ if (!dev_priv->mmu)
10643+ goto out_err;
10644+
10645+ pg = dev_priv->pg;
10646+
10647+ /*
10648+ * Make sgx MMU aware of the stolen memory area we call VRAM.
10649+ */
10650+
10651+ down_read(&pg->sem);
10652+ ret =
10653+ psb_mmu_insert_pfn_sequence(psb_mmu_get_default_pd(dev_priv->mmu),
10654+ pg->stolen_base >> PAGE_SHIFT,
10655+ pg->gatt_start,
10656+ pg->stolen_size >> PAGE_SHIFT, 0);
10657+ up_read(&pg->sem);
10658+ if (ret)
10659+ goto out_err;
10660+
10661+ dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0);
10662+ if (!dev_priv->pf_pd)
10663+ goto out_err;
10664+
10665+ /*
10666+ * Make all presumably unused requestors page-fault by making them
10667+ * use context 1 which does not have any valid mappings.
10668+ */
10669+
10670+ PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0);
10671+ PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1);
10672+ PSB_RSGX32(PSB_CR_BIF_BANK1);
10673+
10674+ psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0);
10675+ psb_mmu_set_pd_context(dev_priv->pf_pd, 1);
10676+ psb_mmu_enable_requestor(dev_priv->mmu, _PSB_MMU_ER_MASK);
10677+
10678+ psb_init_2d(dev_priv);
10679+
10680+ ret = drm_bo_driver_init(dev);
10681+ if (ret)
10682+ goto out_err;
10683+
10684+ ret = drm_bo_init_mm(dev, DRM_PSB_MEM_KERNEL, 0x00000000,
10685+ (PSB_MEM_PDS_START - PSB_MEM_KERNEL_START)
10686+ >> PAGE_SHIFT);
10687+ if (ret)
10688+ goto out_err;
10689+ dev_priv->have_mem_kernel = 1;
10690+
10691+ ret = drm_bo_init_mm(dev, DRM_PSB_MEM_PDS, 0x00000000,
10692+ (PSB_MEM_RASTGEOM_START - PSB_MEM_PDS_START)
10693+ >> PAGE_SHIFT);
10694+ if (ret)
10695+ goto out_err;
10696+ dev_priv->have_mem_pds = 1;
10697+
10698+ ret = psb_do_init(dev);
10699+ if (ret)
10700+ return ret;
10701+
10702+ ret = psb_xhw_init(dev);
10703+ if (ret)
10704+ return ret;
10705+
10706+ PSB_WSGX32(PSB_MEM_PDS_START, PSB_CR_PDS_EXEC_BASE);
10707+ PSB_WSGX32(PSB_MEM_RASTGEOM_START, PSB_CR_BIF_3D_REQ_BASE);
10708+
10709+ intel_modeset_init(dev);
10710+
10711+ dev->mode_config.funcs = (void *)&psb_mode_funcs;
10712+
10713+ drm_helper_initial_config(dev, false);
10714+
10715+
10716+#ifdef USE_PAT_WC
10717+#warning Init pat
10718+ register_cpu_notifier(&psb_nb);
10719+#endif
10720+
10721+ return 0;
10722+ out_err:
10723+ psb_driver_unload(dev);
10724+ return ret;
10725+}
10726+
10727+int psb_driver_device_is_agp(struct drm_device *dev)
10728+{
10729+ return 0;
10730+}
10731+
10732+static int psb_prepare_msvdx_suspend(struct drm_device *dev)
10733+{
10734+ struct drm_psb_private *dev_priv =
10735+ (struct drm_psb_private *)dev->dev_private;
10736+ struct drm_fence_manager *fm = &dev->fm;
10737+ struct drm_fence_class_manager *fc = &fm->fence_class[PSB_ENGINE_VIDEO];
10738+ struct drm_fence_object *fence;
10739+ int ret = 0;
10740+ int signaled = 0;
10741+ int count = 0;
10742+ unsigned long _end = jiffies + 3 * DRM_HZ;
10743+
10744+ PSB_DEBUG_GENERAL("MSVDXACPI Entering psb_prepare_msvdx_suspend....\n");
10745+
10746+ /*set the msvdx-reset flag here.. */
10747+ dev_priv->msvdx_needs_reset = 1;
10748+
10749+ /*Ensure that all pending IRQs are serviced, */
10750+ list_for_each_entry(fence, &fc->ring, ring) {
10751+ count++;
10752+ do {
10753+ DRM_WAIT_ON(ret, fc->fence_queue, 3 * DRM_HZ,
10754+ (signaled =
10755+ drm_fence_object_signaled(fence,
10756+ DRM_FENCE_TYPE_EXE)));
10757+ if (signaled)
10758+ break;
10759+ if (time_after_eq(jiffies, _end))
10760+ PSB_DEBUG_GENERAL
10761+ ("MSVDXACPI: fence 0x%x didn't get signaled for 3 secs; we will suspend anyways\n",
10762+ (unsigned int)fence);
10763+ } while (ret == -EINTR);
10764+
10765+ }
10766+
10767+ /* Issue software reset */
10768+ PSB_WMSVDX32 (msvdx_sw_reset_all, MSVDX_CONTROL);
10769+
10770+ ret = psb_wait_for_register (dev_priv, MSVDX_CONTROL, 0,
10771+ MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK);
10772+
10773+ PSB_DEBUG_GENERAL("MSVDXACPI: All MSVDX IRQs (%d) serviced...\n",
10774+ count);
10775+ return 0;
10776+}
10777+
10778+static int psb_suspend(struct pci_dev *pdev, pm_message_t state)
10779+{
10780+ struct drm_device *dev = pci_get_drvdata(pdev);
10781+ struct drm_psb_private *dev_priv =
10782+ (struct drm_psb_private *)dev->dev_private;
10783+ struct drm_connector *output;
10784+
10785+ if (drm_psb_no_fb == 0)
10786+ psbfb_suspend(dev);
10787+ else {
10788+ if(num_registered_fb)
10789+ {
10790+ list_for_each_entry(output, &dev->mode_config.connector_list, head) {
10791+ //if(output->encoder->crtc != NULL)
10792+ // intel_crtc_mode_save(output->encoder->crtc);
10793+ //if(output->funcs->save)
10794+ // output->funcs->save(output);
10795+ }
10796+ }
10797+ }
10798+
10799+ dev_priv->saveCLOCKGATING = PSB_RSGX32(PSB_CR_CLKGATECTL);
10800+ (void)psb_idle_3d(dev);
10801+ (void)psb_idle_2d(dev);
10802+ flush_scheduled_work();
10803+
10804+ psb_takedown_use_base(dev_priv);
10805+
10806+ if (dev_priv->has_msvdx)
10807+ psb_prepare_msvdx_suspend(dev);
10808+
10809+ pci_save_state(pdev);
10810+ pci_disable_device(pdev);
10811+ pci_set_power_state(pdev, PCI_D3hot);
10812+
10813+ return 0;
10814+}
10815+
10816+static int psb_resume(struct pci_dev *pdev)
10817+{
10818+ struct drm_device *dev = pci_get_drvdata(pdev);
10819+ struct drm_psb_private *dev_priv =
10820+ (struct drm_psb_private *)dev->dev_private;
10821+ struct psb_gtt *pg = dev_priv->pg;
10822+ struct drm_connector *output;
10823+ int ret;
10824+
10825+ pci_set_power_state(pdev, PCI_D0);
10826+ pci_restore_state(pdev);
10827+ ret = pci_enable_device(pdev);
10828+ if (ret)
10829+ return ret;
10830+
10831+#ifdef USE_PAT_WC
10832+#warning Init pat
10833+ /* for single CPU's we do it here, then for more than one CPU we
10834+ * use the CPU notifier to reinit PAT on those CPU's.
10835+ */
10836+ drm_init_pat();
10837+#endif
10838+
10839+ INIT_LIST_HEAD(&dev_priv->resume_buf.head);
10840+ dev_priv->msvdx_needs_reset = 1;
10841+
10842+ PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
10843+ pci_write_config_word(pdev, PSB_GMCH_CTRL,
10844+ pg->gmch_ctrl | _PSB_GMCH_ENABLED);
10845+
10846+ /*
10847+ * The GTT page tables are probably not saved.
10848+ * However, TT and VRAM is empty at this point.
10849+ */
10850+
10851+ psb_gtt_init(dev_priv->pg, 1);
10852+
10853+ /*
10854+ * The SGX loses it's register contents.
10855+ * Restore BIF registers. The MMU page tables are
10856+ * "normal" pages, so their contents should be kept.
10857+ */
10858+
10859+ PSB_WSGX32(dev_priv->saveCLOCKGATING, PSB_CR_CLKGATECTL);
10860+ PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0);
10861+ PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1);
10862+ PSB_RSGX32(PSB_CR_BIF_BANK1);
10863+
10864+ psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0);
10865+ psb_mmu_set_pd_context(dev_priv->pf_pd, 1);
10866+ psb_mmu_enable_requestor(dev_priv->mmu, _PSB_MMU_ER_MASK);
10867+
10868+ /*
10869+ * 2D Base registers..
10870+ */
10871+ psb_init_2d(dev_priv);
10872+
10873+ if (drm_psb_no_fb == 0) {
10874+ list_for_each_entry(output, &dev->mode_config.connector_list, head) {
10875+ if(output->encoder->crtc != NULL)
10876+ drm_crtc_helper_set_mode(output->encoder->crtc, &output->encoder->crtc->mode,
10877+ output->encoder->crtc->x, output->encoder->crtc->y, NULL);
10878+ }
10879+ }
10880+
10881+ /*
10882+ * Persistant 3D base registers and USSE base registers..
10883+ */
10884+
10885+ PSB_WSGX32(PSB_MEM_PDS_START, PSB_CR_PDS_EXEC_BASE);
10886+ PSB_WSGX32(PSB_MEM_RASTGEOM_START, PSB_CR_BIF_3D_REQ_BASE);
10887+ psb_init_use_base(dev_priv, 3, 13);
10888+
10889+ /*
10890+ * Now, re-initialize the 3D engine.
10891+ */
10892+
10893+ psb_xhw_resume(dev_priv, &dev_priv->resume_buf);
10894+
10895+ psb_scheduler_ta_mem_check(dev_priv);
10896+ if (dev_priv->ta_mem && !dev_priv->force_ta_mem_load) {
10897+ psb_xhw_ta_mem_load(dev_priv, &dev_priv->resume_buf,
10898+ PSB_TA_MEM_FLAG_TA |
10899+ PSB_TA_MEM_FLAG_RASTER |
10900+ PSB_TA_MEM_FLAG_HOSTA |
10901+ PSB_TA_MEM_FLAG_HOSTD |
10902+ PSB_TA_MEM_FLAG_INIT,
10903+ dev_priv->ta_mem->ta_memory->offset,
10904+ dev_priv->ta_mem->hw_data->offset,
10905+ dev_priv->ta_mem->hw_cookie);
10906+ }
10907+
10908+ if (drm_psb_no_fb == 0)
10909+ psbfb_resume(dev);
10910+
10911+ else {
10912+ if(num_registered_fb)
10913+ {
10914+ struct fb_info *fb_info=registered_fb[0];
10915+ list_for_each_entry(output, &dev->mode_config.connector_list, head) {
10916+ //if(output->encoder->crtc != NULL)
10917+ // intel_crtc_mode_restore(output->encoder->crtc);
10918+ }
10919+ if(fb_info)
10920+ {
10921+ fb_set_suspend(fb_info, 0);
10922+ printk("set the fb_set_suspend resume end\n");
10923+ }
10924+ }
10925+ }
10926+
10927+
10928+ return 0;
10929+}
10930+
10931+/* always available as we are SIGIO'd */
10932+static unsigned int psb_poll(struct file *filp, struct poll_table_struct *wait)
10933+{
10934+ return (POLLIN | POLLRDNORM);
10935+}
10936+
10937+static int psb_release(struct inode *inode, struct file *filp)
10938+{
10939+ struct drm_file *file_priv = (struct drm_file *)filp->private_data;
10940+ struct drm_device *dev = file_priv->minor->dev;
10941+ struct drm_psb_private *dev_priv =
10942+ (struct drm_psb_private *)dev->dev_private;
10943+
10944+ if (dev_priv && dev_priv->xhw_file) {
10945+ psb_xhw_init_takedown(dev_priv, file_priv, 1);
10946+ }
10947+ return drm_release(inode, filp);
10948+}
10949+
10950+extern struct drm_fence_driver psb_fence_driver;
10951+
10952+/*
10953+ * Use this memory type priority if no eviction is needed.
10954+ */
10955+static uint32_t psb_mem_prios[] = { DRM_BO_MEM_VRAM,
10956+ DRM_BO_MEM_TT,
10957+ DRM_PSB_MEM_KERNEL,
10958+ DRM_PSB_MEM_MMU,
10959+ DRM_PSB_MEM_RASTGEOM,
10960+ DRM_PSB_MEM_PDS,
10961+ DRM_PSB_MEM_APER,
10962+ DRM_BO_MEM_LOCAL
10963+};
10964+
10965+/*
10966+ * Use this memory type priority if need to evict.
10967+ */
10968+static uint32_t psb_busy_prios[] = { DRM_BO_MEM_TT,
10969+ DRM_BO_MEM_VRAM,
10970+ DRM_PSB_MEM_KERNEL,
10971+ DRM_PSB_MEM_MMU,
10972+ DRM_PSB_MEM_RASTGEOM,
10973+ DRM_PSB_MEM_PDS,
10974+ DRM_PSB_MEM_APER,
10975+ DRM_BO_MEM_LOCAL
10976+};
10977+
10978+static struct drm_bo_driver psb_bo_driver = {
10979+ .mem_type_prio = psb_mem_prios,
10980+ .mem_busy_prio = psb_busy_prios,
10981+ .num_mem_type_prio = ARRAY_SIZE(psb_mem_prios),
10982+ .num_mem_busy_prio = ARRAY_SIZE(psb_busy_prios),
10983+ .create_ttm_backend_entry = drm_psb_tbe_init,
10984+ .fence_type = psb_fence_types,
10985+ .invalidate_caches = psb_invalidate_caches,
10986+ .init_mem_type = psb_init_mem_type,
10987+ .evict_mask = psb_evict_mask,
10988+ .move = psb_move,
10989+ .backend_size = psb_tbe_size,
10990+ .command_stream_barrier = NULL,
10991+};
10992+
10993+static struct drm_driver driver = {
10994+ .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
10995+ DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2,
10996+ .load = psb_driver_load,
10997+ .unload = psb_driver_unload,
10998+ .dri_library_name = dri_library_name,
10999+ .get_reg_ofs = drm_core_get_reg_ofs,
11000+ .ioctls = psb_ioctls,
11001+ .device_is_agp = psb_driver_device_is_agp,
11002+ .vblank_wait = psb_vblank_wait,
11003+ .vblank_wait2 = psb_vblank_wait2,
11004+ .irq_preinstall = psb_irq_preinstall,
11005+ .irq_postinstall = psb_irq_postinstall,
11006+ .irq_uninstall = psb_irq_uninstall,
11007+ .irq_handler = psb_irq_handler,
11008+ .fb_probe = psbfb_probe,
11009+ .fb_remove = psbfb_remove,
11010+ .firstopen = NULL,
11011+ .lastclose = psb_lastclose,
11012+ .fops = {
11013+ .owner = THIS_MODULE,
11014+ .open = drm_open,
11015+ .release = psb_release,
11016+ .ioctl = drm_ioctl,
11017+ .mmap = drm_mmap,
11018+ .poll = psb_poll,
11019+ .fasync = drm_fasync,
11020+ },
11021+ .pci_driver = {
11022+ .name = DRIVER_NAME,
11023+ .id_table = pciidlist,
11024+ .probe = probe,
11025+ .remove = __devexit_p(drm_cleanup_pci),
11026+ .resume = psb_resume,
11027+ .suspend = psb_suspend,
11028+ },
11029+ .fence_driver = &psb_fence_driver,
11030+ .bo_driver = &psb_bo_driver,
11031+ .name = DRIVER_NAME,
11032+ .desc = DRIVER_DESC,
11033+ .date = PSB_DRM_DRIVER_DATE,
11034+ .major = PSB_DRM_DRIVER_MAJOR,
11035+ .minor = PSB_DRM_DRIVER_MINOR,
11036+ .patchlevel = PSB_DRM_DRIVER_PATCHLEVEL
11037+};
11038+
11039+static int probe(struct pci_dev *pdev, const struct pci_device_id *ent)
11040+{
11041+ return drm_get_dev(pdev, ent, &driver);
11042+}
11043+
11044+static int __init psb_init(void)
11045+{
11046+ driver.num_ioctls = psb_max_ioctl;
11047+
11048+ return drm_init(&driver);
11049+}
11050+
11051+static void __exit psb_exit(void)
11052+{
11053+ drm_exit(&driver);
11054+}
11055+
11056+module_init(psb_init);
11057+module_exit(psb_exit);
11058+
11059+MODULE_AUTHOR(DRIVER_AUTHOR);
11060+MODULE_DESCRIPTION(DRIVER_DESC);
11061+MODULE_LICENSE("GPL");
11062Index: linux-2.6.28/drivers/gpu/drm/psb/psb_drv.h
11063===================================================================
11064--- /dev/null 1970-01-01 00:00:00.000000000 +0000
11065+++ linux-2.6.28/drivers/gpu/drm/psb/psb_drv.h 2009-02-12 09:14:41.000000000 +0000
11066@@ -0,0 +1,548 @@
11067+/**************************************************************************
11068+ * Copyright (c) 2007, Intel Corporation.
11069+ * All Rights Reserved.
11070+ *
11071+ * This program is free software; you can redistribute it and/or modify it
11072+ * under the terms and conditions of the GNU General Public License,
11073+ * version 2, as published by the Free Software Foundation.
11074+ *
11075+ * This program is distributed in the hope it will be useful, but WITHOUT
11076+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11077+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11078+ * more details.
11079+ *
11080+ * You should have received a copy of the GNU General Public License along with
11081+ * this program; if not, write to the Free Software Foundation, Inc.,
11082+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
11083+ *
11084+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
11085+ * develop this driver.
11086+ *
11087+ **************************************************************************/
11088+/*
11089+ */
11090+#ifndef _PSB_DRV_H_
11091+#define _PSB_DRV_H_
11092+
11093+#include "drmP.h"
11094+#include "psb_drm.h"
11095+#include "psb_reg.h"
11096+#include "psb_schedule.h"
11097+#include "intel_drv.h"
11098+#include "psb_priv.h"
11099+
11100+enum {
11101+ CHIP_PSB_8108 = 0,
11102+ CHIP_PSB_8109 = 1
11103+};
11104+
11105+/*
11106+ * Hardware bugfixes
11107+ */
11108+
11109+#define FIX_TG_16
11110+#define FIX_TG_2D_CLOCKGATE
11111+
11112+#define DRIVER_NAME "psb"
11113+#define DRIVER_DESC "drm driver for the Intel GMA500"
11114+#define DRIVER_AUTHOR "Tungsten Graphics Inc."
11115+
11116+#define PSB_DRM_DRIVER_DATE "20080613"
11117+#define PSB_DRM_DRIVER_MAJOR 4
11118+#define PSB_DRM_DRIVER_MINOR 12
11119+#define PSB_DRM_DRIVER_PATCHLEVEL 0
11120+
11121+#define PSB_VDC_OFFSET 0x00000000
11122+#define PSB_VDC_SIZE 0x000080000
11123+#define PSB_SGX_SIZE 0x8000
11124+#define PSB_SGX_OFFSET 0x00040000
11125+#define PSB_MMIO_RESOURCE 0
11126+#define PSB_GATT_RESOURCE 2
11127+#define PSB_GTT_RESOURCE 3
11128+#define PSB_GMCH_CTRL 0x52
11129+#define PSB_BSM 0x5C
11130+#define _PSB_GMCH_ENABLED 0x4
11131+#define PSB_PGETBL_CTL 0x2020
11132+#define _PSB_PGETBL_ENABLED 0x00000001
11133+#define PSB_SGX_2D_SLAVE_PORT 0x4000
11134+#define PSB_TT_PRIV0_LIMIT (256*1024*1024)
11135+#define PSB_TT_PRIV0_PLIMIT (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT)
11136+#define PSB_NUM_VALIDATE_BUFFERS 1024
11137+#define PSB_MEM_KERNEL_START 0x10000000
11138+#define PSB_MEM_PDS_START 0x20000000
11139+#define PSB_MEM_MMU_START 0x40000000
11140+
11141+#define DRM_PSB_MEM_KERNEL DRM_BO_MEM_PRIV0
11142+#define DRM_PSB_FLAG_MEM_KERNEL DRM_BO_FLAG_MEM_PRIV0
11143+
11144+/*
11145+ * Flags for external memory type field.
11146+ */
11147+
11148+#define PSB_MSVDX_OFFSET 0x50000 /*MSVDX Base offset */
11149+#define PSB_MSVDX_SIZE 0x8000 /*MSVDX MMIO region is 0x50000 - 0x57fff ==> 32KB */
11150+
11151+#define PSB_MMU_CACHED_MEMORY 0x0001 /* Bind to MMU only */
11152+#define PSB_MMU_RO_MEMORY 0x0002 /* MMU RO memory */
11153+#define PSB_MMU_WO_MEMORY 0x0004 /* MMU WO memory */
11154+
11155+/*
11156+ * PTE's and PDE's
11157+ */
11158+
11159+#define PSB_PDE_MASK 0x003FFFFF
11160+#define PSB_PDE_SHIFT 22
11161+#define PSB_PTE_SHIFT 12
11162+
11163+#define PSB_PTE_VALID 0x0001 /* PTE / PDE valid */
11164+#define PSB_PTE_WO 0x0002 /* Write only */
11165+#define PSB_PTE_RO 0x0004 /* Read only */
11166+#define PSB_PTE_CACHED 0x0008 /* CPU cache coherent */
11167+
11168+/*
11169+ * VDC registers and bits
11170+ */
11171+#define PSB_HWSTAM 0x2098
11172+#define PSB_INSTPM 0x20C0
11173+#define PSB_INT_IDENTITY_R 0x20A4
11174+#define _PSB_VSYNC_PIPEB_FLAG (1<<5)
11175+#define _PSB_VSYNC_PIPEA_FLAG (1<<7)
11176+#define _PSB_IRQ_SGX_FLAG (1<<18)
11177+#define _PSB_IRQ_MSVDX_FLAG (1<<19)
11178+#define PSB_INT_MASK_R 0x20A8
11179+#define PSB_INT_ENABLE_R 0x20A0
11180+#define PSB_PIPEASTAT 0x70024
11181+#define _PSB_VBLANK_INTERRUPT_ENABLE (1 << 17)
11182+#define _PSB_VBLANK_CLEAR (1 << 1)
11183+#define PSB_PIPEBSTAT 0x71024
11184+
11185+#define _PSB_MMU_ER_MASK 0x0001FF00
11186+#define _PSB_MMU_ER_HOST (1 << 16)
11187+#define GPIOA 0x5010
11188+#define GPIOB 0x5014
11189+#define GPIOC 0x5018
11190+#define GPIOD 0x501c
11191+#define GPIOE 0x5020
11192+#define GPIOF 0x5024
11193+#define GPIOG 0x5028
11194+#define GPIOH 0x502c
11195+#define GPIO_CLOCK_DIR_MASK (1 << 0)
11196+#define GPIO_CLOCK_DIR_IN (0 << 1)
11197+#define GPIO_CLOCK_DIR_OUT (1 << 1)
11198+#define GPIO_CLOCK_VAL_MASK (1 << 2)
11199+#define GPIO_CLOCK_VAL_OUT (1 << 3)
11200+#define GPIO_CLOCK_VAL_IN (1 << 4)
11201+#define GPIO_CLOCK_PULLUP_DISABLE (1 << 5)
11202+#define GPIO_DATA_DIR_MASK (1 << 8)
11203+#define GPIO_DATA_DIR_IN (0 << 9)
11204+#define GPIO_DATA_DIR_OUT (1 << 9)
11205+#define GPIO_DATA_VAL_MASK (1 << 10)
11206+#define GPIO_DATA_VAL_OUT (1 << 11)
11207+#define GPIO_DATA_VAL_IN (1 << 12)
11208+#define GPIO_DATA_PULLUP_DISABLE (1 << 13)
11209+
11210+#define VCLK_DIVISOR_VGA0 0x6000
11211+#define VCLK_DIVISOR_VGA1 0x6004
11212+#define VCLK_POST_DIV 0x6010
11213+
11214+#define I915_WRITE(_offs, _val) \
11215+ iowrite32(_val, dev_priv->vdc_reg + (_offs))
11216+#define I915_READ(_offs) \
11217+ ioread32(dev_priv->vdc_reg + (_offs))
11218+
11219+#define PSB_COMM_2D (PSB_ENGINE_2D << 4)
11220+#define PSB_COMM_3D (PSB_ENGINE_3D << 4)
11221+#define PSB_COMM_TA (PSB_ENGINE_TA << 4)
11222+#define PSB_COMM_HP (PSB_ENGINE_HP << 4)
11223+#define PSB_COMM_USER_IRQ (1024 >> 2)
11224+#define PSB_COMM_USER_IRQ_LOST (PSB_COMM_USER_IRQ + 1)
11225+#define PSB_COMM_FW (2048 >> 2)
11226+
11227+#define PSB_UIRQ_VISTEST 1
11228+#define PSB_UIRQ_OOM_REPLY 2
11229+#define PSB_UIRQ_FIRE_TA_REPLY 3
11230+#define PSB_UIRQ_FIRE_RASTER_REPLY 4
11231+
11232+#define PSB_2D_SIZE (256*1024*1024)
11233+#define PSB_MAX_RELOC_PAGES 1024
11234+
11235+#define PSB_LOW_REG_OFFS 0x0204
11236+#define PSB_HIGH_REG_OFFS 0x0600
11237+
11238+#define PSB_NUM_VBLANKS 2
11239+
11240+#define PSB_COMM_2D (PSB_ENGINE_2D << 4)
11241+#define PSB_COMM_3D (PSB_ENGINE_3D << 4)
11242+#define PSB_COMM_TA (PSB_ENGINE_TA << 4)
11243+#define PSB_COMM_HP (PSB_ENGINE_HP << 4)
11244+#define PSB_COMM_FW (2048 >> 2)
11245+
11246+#define PSB_2D_SIZE (256*1024*1024)
11247+#define PSB_MAX_RELOC_PAGES 1024
11248+
11249+#define PSB_LOW_REG_OFFS 0x0204
11250+#define PSB_HIGH_REG_OFFS 0x0600
11251+
11252+#define PSB_NUM_VBLANKS 2
11253+#define PSB_WATCHDOG_DELAY (DRM_HZ / 10)
11254+
11255+/*
11256+ * User options.
11257+ */
11258+
11259+
11260+struct psb_gtt {
11261+ struct drm_device *dev;
11262+ int initialized;
11263+ uint32_t gatt_start;
11264+ uint32_t gtt_start;
11265+ uint32_t gtt_phys_start;
11266+ unsigned gtt_pages;
11267+ unsigned gatt_pages;
11268+ uint32_t stolen_base;
11269+ uint32_t pge_ctl;
11270+ u16 gmch_ctrl;
11271+ unsigned long stolen_size;
11272+ uint32_t *gtt_map;
11273+ struct rw_semaphore sem;
11274+};
11275+
11276+struct psb_use_base {
11277+ struct list_head head;
11278+ struct drm_fence_object *fence;
11279+ unsigned int reg;
11280+ unsigned long offset;
11281+ unsigned int dm;
11282+};
11283+
11284+struct psb_buflist_item;
11285+
11286+struct psb_msvdx_cmd_queue {
11287+ struct list_head head;
11288+ void *cmd;
11289+ unsigned long cmd_size;
11290+ uint32_t sequence;
11291+};
11292+
11293+
11294+struct psb_mmu_driver;
11295+
11296+extern struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
11297+ int trap_pagefaults,
11298+ int invalid_type,
11299+ atomic_t *msvdx_mmu_invaldc);
11300+extern void psb_mmu_driver_takedown(struct psb_mmu_driver *driver);
11301+extern struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver *driver);
11302+extern void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd, uint32_t mmu_offset,
11303+ uint32_t gtt_start, uint32_t gtt_pages);
11304+extern void psb_mmu_test(struct psb_mmu_driver *driver, uint32_t offset);
11305+extern struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver,
11306+ int trap_pagefaults,
11307+ int invalid_type);
11308+extern void psb_mmu_free_pagedir(struct psb_mmu_pd *pd);
11309+extern void psb_mmu_flush(struct psb_mmu_driver *driver);
11310+extern void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd,
11311+ unsigned long address,
11312+ uint32_t num_pages);
11313+extern int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd,
11314+ uint32_t start_pfn,
11315+ unsigned long address,
11316+ uint32_t num_pages, int type);
11317+extern int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
11318+ unsigned long *pfn);
11319+
11320+/*
11321+ * Enable / disable MMU for different requestors.
11322+ */
11323+
11324+extern void psb_mmu_enable_requestor(struct psb_mmu_driver *driver,
11325+ uint32_t mask);
11326+extern void psb_mmu_disable_requestor(struct psb_mmu_driver *driver,
11327+ uint32_t mask);
11328+extern void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context);
11329+extern int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages,
11330+ unsigned long address, uint32_t num_pages,
11331+ uint32_t desired_tile_stride,
11332+ uint32_t hw_tile_stride, int type);
11333+extern void psb_mmu_remove_pages(struct psb_mmu_pd *pd, unsigned long address,
11334+ uint32_t num_pages,
11335+ uint32_t desired_tile_stride,
11336+ uint32_t hw_tile_stride);
11337+/*
11338+ * psb_sgx.c
11339+ */
11340+
11341+extern int psb_blit_sequence(struct drm_psb_private *dev_priv,
11342+ uint32_t sequence);
11343+extern void psb_init_2d(struct drm_psb_private *dev_priv);
11344+extern int psb_idle_2d(struct drm_device *dev);
11345+extern int psb_idle_3d(struct drm_device *dev);
11346+extern int psb_emit_2d_copy_blit(struct drm_device *dev,
11347+ uint32_t src_offset,
11348+ uint32_t dst_offset, uint32_t pages,
11349+ int direction);
11350+extern int psb_cmdbuf_ioctl(struct drm_device *dev, void *data,
11351+ struct drm_file *file_priv);
11352+extern int psb_reg_submit(struct drm_psb_private *dev_priv, uint32_t * regs,
11353+ unsigned int cmds);
11354+extern int psb_submit_copy_cmdbuf(struct drm_device *dev,
11355+ struct drm_buffer_object *cmd_buffer,
11356+ unsigned long cmd_offset,
11357+ unsigned long cmd_size, int engine,
11358+ uint32_t * copy_buffer);
11359+extern void psb_fence_or_sync(struct drm_file *priv,
11360+ int engine,
11361+ struct drm_psb_cmdbuf_arg *arg,
11362+ struct drm_fence_arg *fence_arg,
11363+ struct drm_fence_object **fence_p);
11364+extern void psb_init_disallowed(void);
11365+
11366+/*
11367+ * psb_irq.c
11368+ */
11369+
11370+extern irqreturn_t psb_irq_handler(DRM_IRQ_ARGS);
11371+extern void psb_irq_preinstall(struct drm_device *dev);
11372+extern int psb_irq_postinstall(struct drm_device *dev);
11373+extern void psb_irq_uninstall(struct drm_device *dev);
11374+extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
11375+extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence);
11376+
11377+/*
11378+ * psb_fence.c
11379+ */
11380+
11381+extern void psb_fence_handler(struct drm_device *dev, uint32_t class);
11382+extern void psb_2D_irq_off(struct drm_psb_private *dev_priv);
11383+extern void psb_2D_irq_on(struct drm_psb_private *dev_priv);
11384+extern uint32_t psb_fence_advance_sequence(struct drm_device *dev,
11385+ uint32_t class);
11386+extern int psb_fence_emit_sequence(struct drm_device *dev, uint32_t fence_class,
11387+ uint32_t flags, uint32_t * sequence,
11388+ uint32_t * native_type);
11389+extern void psb_fence_error(struct drm_device *dev,
11390+ uint32_t class,
11391+ uint32_t sequence, uint32_t type, int error);
11392+
11393+/*MSVDX stuff*/
11394+extern void psb_msvdx_irq_off(struct drm_psb_private *dev_priv);
11395+extern void psb_msvdx_irq_on(struct drm_psb_private *dev_priv);
11396+extern int psb_hw_info_ioctl(struct drm_device *dev, void *data,
11397+ struct drm_file *file_priv);
11398+
11399+/*
11400+ * psb_buffer.c
11401+ */
11402+extern struct drm_ttm_backend *drm_psb_tbe_init(struct drm_device *dev);
11403+extern int psb_fence_types(struct drm_buffer_object *bo, uint32_t * class,
11404+ uint32_t * type);
11405+extern uint32_t psb_evict_mask(struct drm_buffer_object *bo);
11406+extern int psb_invalidate_caches(struct drm_device *dev, uint64_t flags);
11407+extern int psb_init_mem_type(struct drm_device *dev, uint32_t type,
11408+ struct drm_mem_type_manager *man);
11409+extern int psb_move(struct drm_buffer_object *bo,
11410+ int evict, int no_wait, struct drm_bo_mem_reg *new_mem);
11411+extern int psb_tbe_size(struct drm_device *dev, unsigned long num_pages);
11412+
11413+/*
11414+ * psb_gtt.c
11415+ */
11416+extern int psb_gtt_init(struct psb_gtt *pg, int resume);
11417+extern int psb_gtt_insert_pages(struct psb_gtt *pg, struct page **pages,
11418+ unsigned offset_pages, unsigned num_pages,
11419+ unsigned desired_tile_stride,
11420+ unsigned hw_tile_stride, int type);
11421+extern int psb_gtt_remove_pages(struct psb_gtt *pg, unsigned offset_pages,
11422+ unsigned num_pages,
11423+ unsigned desired_tile_stride,
11424+ unsigned hw_tile_stride);
11425+
11426+extern struct psb_gtt *psb_gtt_alloc(struct drm_device *dev);
11427+extern void psb_gtt_takedown(struct psb_gtt *pg, int free);
11428+
11429+/*
11430+ * psb_fb.c
11431+ */
11432+extern int psbfb_probe(struct drm_device *dev, struct drm_crtc *crtc);
11433+extern int psbfb_remove(struct drm_device *dev, struct drm_crtc *crtc);
11434+extern int psbfb_kms_off_ioctl(struct drm_device *dev, void *data,
11435+ struct drm_file *file_priv);
11436+extern int psbfb_kms_on_ioctl(struct drm_device *dev, void *data,
11437+ struct drm_file *file_priv);
11438+extern void psbfb_suspend(struct drm_device *dev);
11439+extern void psbfb_resume(struct drm_device *dev);
11440+
11441+/*
11442+ * psb_reset.c
11443+ */
11444+
11445+extern void psb_reset(struct drm_psb_private *dev_priv, int reset_2d);
11446+extern void psb_schedule_watchdog(struct drm_psb_private *dev_priv);
11447+extern void psb_watchdog_init(struct drm_psb_private *dev_priv);
11448+extern void psb_watchdog_takedown(struct drm_psb_private *dev_priv);
11449+extern void psb_print_pagefault(struct drm_psb_private *dev_priv);
11450+
11451+/*
11452+ * psb_regman.c
11453+ */
11454+
11455+extern void psb_takedown_use_base(struct drm_psb_private *dev_priv);
11456+extern int psb_grab_use_base(struct drm_psb_private *dev_priv,
11457+ unsigned long dev_virtual,
11458+ unsigned long size,
11459+ unsigned int data_master,
11460+ uint32_t fence_class,
11461+ uint32_t fence_type,
11462+ int no_wait,
11463+ int ignore_signals,
11464+ int *r_reg, uint32_t * r_offset);
11465+extern int psb_init_use_base(struct drm_psb_private *dev_priv,
11466+ unsigned int reg_start, unsigned int reg_num);
11467+
11468+/*
11469+ * psb_xhw.c
11470+ */
11471+
11472+extern int psb_xhw_ioctl(struct drm_device *dev, void *data,
11473+ struct drm_file *file_priv);
11474+extern int psb_xhw_init_ioctl(struct drm_device *dev, void *data,
11475+ struct drm_file *file_priv);
11476+extern int psb_xhw_init(struct drm_device *dev);
11477+extern void psb_xhw_takedown(struct drm_psb_private *dev_priv);
11478+extern void psb_xhw_init_takedown(struct drm_psb_private *dev_priv,
11479+ struct drm_file *file_priv, int closing);
11480+extern int psb_xhw_scene_bind_fire(struct drm_psb_private *dev_priv,
11481+ struct psb_xhw_buf *buf,
11482+ uint32_t fire_flags,
11483+ uint32_t hw_context,
11484+ uint32_t * cookie,
11485+ uint32_t * oom_cmds,
11486+ uint32_t num_oom_cmds,
11487+ uint32_t offset,
11488+ uint32_t engine, uint32_t flags);
11489+extern int psb_xhw_fire_raster(struct drm_psb_private *dev_priv,
11490+ struct psb_xhw_buf *buf, uint32_t fire_flags);
11491+extern int psb_xhw_scene_info(struct drm_psb_private *dev_priv,
11492+ struct psb_xhw_buf *buf,
11493+ uint32_t w,
11494+ uint32_t h,
11495+ uint32_t * hw_cookie,
11496+ uint32_t * bo_size,
11497+ uint32_t * clear_p_start,
11498+ uint32_t * clear_num_pages);
11499+
11500+extern int psb_xhw_reset_dpm(struct drm_psb_private *dev_priv,
11501+ struct psb_xhw_buf *buf);
11502+extern int psb_xhw_check_lockup(struct drm_psb_private *dev_priv,
11503+ struct psb_xhw_buf *buf, uint32_t * value);
11504+extern int psb_xhw_ta_mem_info(struct drm_psb_private *dev_priv,
11505+ struct psb_xhw_buf *buf,
11506+ uint32_t pages,
11507+ uint32_t * hw_cookie, uint32_t * size);
11508+extern int psb_xhw_ta_oom(struct drm_psb_private *dev_priv,
11509+ struct psb_xhw_buf *buf, uint32_t * cookie);
11510+extern void psb_xhw_ta_oom_reply(struct drm_psb_private *dev_priv,
11511+ struct psb_xhw_buf *buf,
11512+ uint32_t * cookie,
11513+ uint32_t * bca,
11514+ uint32_t * rca, uint32_t * flags);
11515+extern int psb_xhw_vistest(struct drm_psb_private *dev_priv,
11516+ struct psb_xhw_buf *buf);
11517+extern int psb_xhw_handler(struct drm_psb_private *dev_priv);
11518+extern int psb_xhw_resume(struct drm_psb_private *dev_priv,
11519+ struct psb_xhw_buf *buf);
11520+extern void psb_xhw_fire_reply(struct drm_psb_private *dev_priv,
11521+ struct psb_xhw_buf *buf, uint32_t * cookie);
11522+extern int psb_xhw_ta_mem_load(struct drm_psb_private *dev_priv,
11523+ struct psb_xhw_buf *buf,
11524+ uint32_t flags,
11525+ uint32_t param_offset,
11526+ uint32_t pt_offset, uint32_t * hw_cookie);
11527+extern void psb_xhw_clean_buf(struct drm_psb_private *dev_priv,
11528+ struct psb_xhw_buf *buf);
11529+
11530+/*
11531+ * psb_schedule.c: HW bug fixing.
11532+ */
11533+
11534+#ifdef FIX_TG_16
11535+
11536+extern void psb_2d_unlock(struct drm_psb_private *dev_priv);
11537+extern void psb_2d_lock(struct drm_psb_private *dev_priv);
11538+extern void psb_resume_ta_2d_idle(struct drm_psb_private *dev_priv);
11539+
11540+#else
11541+
11542+#define psb_2d_lock(_dev_priv) mutex_lock(&(_dev_priv)->mutex_2d)
11543+#define psb_2d_unlock(_dev_priv) mutex_unlock(&(_dev_priv)->mutex_2d)
11544+
11545+#endif
11546+
11547+/*
11548+ * Utilities
11549+ */
11550+
11551+#define PSB_ALIGN_TO(_val, _align) \
11552+ (((_val) + ((_align) - 1)) & ~((_align) - 1))
11553+#define PSB_WVDC32(_val, _offs) \
11554+ iowrite32(_val, dev_priv->vdc_reg + (_offs))
11555+#define PSB_RVDC32(_offs) \
11556+ ioread32(dev_priv->vdc_reg + (_offs))
11557+#define PSB_WSGX32(_val, _offs) \
11558+ iowrite32(_val, dev_priv->sgx_reg + (_offs))
11559+#define PSB_RSGX32(_offs) \
11560+ ioread32(dev_priv->sgx_reg + (_offs))
11561+#define PSB_WMSVDX32(_val, _offs) \
11562+ iowrite32(_val, dev_priv->msvdx_reg + (_offs))
11563+#define PSB_RMSVDX32(_offs) \
11564+ ioread32(dev_priv->msvdx_reg + (_offs))
11565+
11566+#define PSB_ALPL(_val, _base) \
11567+ (((_val) >> (_base ## _ALIGNSHIFT)) << (_base ## _SHIFT))
11568+#define PSB_ALPLM(_val, _base) \
11569+ ((((_val) >> (_base ## _ALIGNSHIFT)) << (_base ## _SHIFT)) & (_base ## _MASK))
11570+
11571+#define PSB_D_RENDER (1 << 16)
11572+
11573+#define PSB_D_GENERAL (1 << 0)
11574+#define PSB_D_INIT (1 << 1)
11575+#define PSB_D_IRQ (1 << 2)
11576+#define PSB_D_FW (1 << 3)
11577+#define PSB_D_PERF (1 << 4)
11578+#define PSB_D_TMP (1 << 5)
11579+#define PSB_D_RELOC (1 << 6)
11580+
11581+extern int drm_psb_debug;
11582+extern int drm_psb_no_fb;
11583+extern int drm_psb_disable_vsync;
11584+
11585+#define PSB_DEBUG_FW(_fmt, _arg...) \
11586+ PSB_DEBUG(PSB_D_FW, _fmt, ##_arg)
11587+#define PSB_DEBUG_GENERAL(_fmt, _arg...) \
11588+ PSB_DEBUG(PSB_D_GENERAL, _fmt, ##_arg)
11589+#define PSB_DEBUG_INIT(_fmt, _arg...) \
11590+ PSB_DEBUG(PSB_D_INIT, _fmt, ##_arg)
11591+#define PSB_DEBUG_IRQ(_fmt, _arg...) \
11592+ PSB_DEBUG(PSB_D_IRQ, _fmt, ##_arg)
11593+#define PSB_DEBUG_RENDER(_fmt, _arg...) \
11594+ PSB_DEBUG(PSB_D_RENDER, _fmt, ##_arg)
11595+#define PSB_DEBUG_PERF(_fmt, _arg...) \
11596+ PSB_DEBUG(PSB_D_PERF, _fmt, ##_arg)
11597+#define PSB_DEBUG_TMP(_fmt, _arg...) \
11598+ PSB_DEBUG(PSB_D_TMP, _fmt, ##_arg)
11599+#define PSB_DEBUG_RELOC(_fmt, _arg...) \
11600+ PSB_DEBUG(PSB_D_RELOC, _fmt, ##_arg)
11601+
11602+#if DRM_DEBUG_CODE
11603+#define PSB_DEBUG(_flag, _fmt, _arg...) \
11604+ do { \
11605+ if (unlikely((_flag) & drm_psb_debug)) \
11606+ printk(KERN_DEBUG \
11607+ "[psb:0x%02x:%s] " _fmt , _flag, \
11608+ __FUNCTION__ , ##_arg); \
11609+ } while (0)
11610+#else
11611+#define PSB_DEBUG(_fmt, _arg...) do { } while (0)
11612+#endif
11613+
11614+#endif
11615Index: linux-2.6.28/drivers/gpu/drm/psb/psb_fb.c
11616===================================================================
11617--- /dev/null 1970-01-01 00:00:00.000000000 +0000
11618+++ linux-2.6.28/drivers/gpu/drm/psb/psb_fb.c 2009-02-12 09:14:41.000000000 +0000
11619@@ -0,0 +1,1349 @@
11620+/**************************************************************************
11621+ * Copyright (c) 2007, Intel Corporation.
11622+ * All Rights Reserved.
11623+ *
11624+ * This program is free software; you can redistribute it and/or modify it
11625+ * under the terms and conditions of the GNU General Public License,
11626+ * version 2, as published by the Free Software Foundation.
11627+ *
11628+ * This program is distributed in the hope it will be useful, but WITHOUT
11629+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11630+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11631+ * more details.
11632+ *
11633+ * You should have received a copy of the GNU General Public License along with
11634+ * this program; if not, write to the Free Software Foundation, Inc.,
11635+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
11636+ *
11637+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
11638+ * develop this driver.
11639+ *
11640+ **************************************************************************/
11641+
11642+#include <linux/module.h>
11643+#include <linux/kernel.h>
11644+#include <linux/errno.h>
11645+#include <linux/string.h>
11646+#include <linux/mm.h>
11647+#include <linux/tty.h>
11648+#include <linux/slab.h>
11649+#include <linux/delay.h>
11650+#include <linux/fb.h>
11651+#include <linux/init.h>
11652+#include <linux/console.h>
11653+
11654+#include "drmP.h"
11655+#include "drm.h"
11656+#include "drm_crtc.h"
11657+#include "psb_drv.h"
11658+
11659+#define SII_1392_WA
11660+#ifdef SII_1392_WA
11661+extern int SII_1392;
11662+#endif
11663+
11664+struct psbfb_vm_info {
11665+ struct drm_buffer_object *bo;
11666+ struct address_space *f_mapping;
11667+ struct mutex vm_mutex;
11668+ atomic_t refcount;
11669+};
11670+
11671+struct psbfb_par {
11672+ struct drm_device *dev;
11673+ struct drm_crtc *crtc;
11674+ struct drm_connector *output;
11675+ struct psbfb_vm_info *vi;
11676+ int dpms_state;
11677+};
11678+
11679+static void psbfb_vm_info_deref(struct psbfb_vm_info **vi)
11680+{
11681+ struct psbfb_vm_info *tmp = *vi;
11682+ *vi = NULL;
11683+ if (atomic_dec_and_test(&tmp->refcount)) {
11684+ drm_bo_usage_deref_unlocked(&tmp->bo);
11685+ drm_free(tmp, sizeof(*tmp), DRM_MEM_MAPS);
11686+ }
11687+}
11688+
11689+static struct psbfb_vm_info *psbfb_vm_info_ref(struct psbfb_vm_info *vi)
11690+{
11691+ atomic_inc(&vi->refcount);
11692+ return vi;
11693+}
11694+
11695+static struct psbfb_vm_info *psbfb_vm_info_create(void)
11696+{
11697+ struct psbfb_vm_info *vi;
11698+
11699+ vi = drm_calloc(1, sizeof(*vi), DRM_MEM_MAPS);
11700+ if (!vi)
11701+ return NULL;
11702+
11703+ mutex_init(&vi->vm_mutex);
11704+ atomic_set(&vi->refcount, 1);
11705+ return vi;
11706+}
11707+
11708+#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)
11709+
11710+static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
11711+ unsigned blue, unsigned transp, struct fb_info *info)
11712+{
11713+ struct psbfb_par *par = info->par;
11714+ struct drm_crtc *crtc = par->crtc;
11715+ uint32_t v;
11716+
11717+ if (!crtc->fb)
11718+ return -ENOMEM;
11719+
11720+ if (regno > 255)
11721+ return 1;
11722+
11723+ if (crtc->funcs->gamma_set)
11724+ crtc->funcs->gamma_set(crtc, red, green, blue, regno);
11725+
11726+ red = CMAP_TOHW(red, info->var.red.length);
11727+ blue = CMAP_TOHW(blue, info->var.blue.length);
11728+ green = CMAP_TOHW(green, info->var.green.length);
11729+ transp = CMAP_TOHW(transp, info->var.transp.length);
11730+
11731+ v = (red << info->var.red.offset) |
11732+ (green << info->var.green.offset) |
11733+ (blue << info->var.blue.offset) |
11734+ (transp << info->var.transp.offset);
11735+
11736+ switch (crtc->fb->bits_per_pixel) {
11737+ case 16:
11738+ ((uint32_t *) info->pseudo_palette)[regno] = v;
11739+ break;
11740+ case 24:
11741+ case 32:
11742+ ((uint32_t *) info->pseudo_palette)[regno] = v;
11743+ break;
11744+ }
11745+
11746+ return 0;
11747+}
11748+
11749+static int psbfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
11750+{
11751+ struct psbfb_par *par = info->par;
11752+ struct drm_device *dev = par->dev;
11753+ struct drm_framebuffer *fb = par->crtc->fb;
11754+ struct drm_display_mode *drm_mode;
11755+ struct drm_connector *output;
11756+ int depth;
11757+ int pitch;
11758+ int bpp = var->bits_per_pixel;
11759+
11760+ if (!fb)
11761+ return -ENOMEM;
11762+
11763+ if (!var->pixclock)
11764+ return -EINVAL;
11765+
11766+ /* don't support virtuals for now */
11767+ if (var->xres_virtual > var->xres)
11768+ return -EINVAL;
11769+
11770+ if (var->yres_virtual > var->yres)
11771+ return -EINVAL;
11772+
11773+ switch (bpp) {
11774+ case 8:
11775+ depth = 8;
11776+ break;
11777+ case 16:
11778+ depth = (var->green.length == 6) ? 16 : 15;
11779+ break;
11780+ case 24: /* assume this is 32bpp / depth 24 */
11781+ bpp = 32;
11782+ /* fallthrough */
11783+ case 32:
11784+ depth = (var->transp.length > 0) ? 32 : 24;
11785+ break;
11786+ default:
11787+ return -EINVAL;
11788+ }
11789+
11790+ pitch = ((var->xres * ((bpp + 1) / 8)) + 0x3f) & ~0x3f;
11791+
11792+ /* Check that we can resize */
11793+ if ((pitch * var->yres) > (fb->bo->num_pages << PAGE_SHIFT)) {
11794+#if 1
11795+ /* Need to resize the fb object.
11796+ * But the generic fbdev code doesn't really understand
11797+ * that we can do this. So disable for now.
11798+ */
11799+ DRM_INFO("Can't support requested size, too big!\n");
11800+ return -EINVAL;
11801+#else
11802+ int ret;
11803+ struct drm_buffer_object *fbo = NULL;
11804+ struct drm_bo_kmap_obj tmp_kmap;
11805+
11806+ /* a temporary BO to check if we could resize in setpar.
11807+ * Therefore no need to set NO_EVICT.
11808+ */
11809+ ret = drm_buffer_object_create(dev,
11810+ pitch * var->yres,
11811+ drm_bo_type_kernel,
11812+ DRM_BO_FLAG_READ |
11813+ DRM_BO_FLAG_WRITE |
11814+ DRM_BO_FLAG_MEM_TT |
11815+ DRM_BO_FLAG_MEM_VRAM,
11816+ DRM_BO_HINT_DONT_FENCE,
11817+ 0, 0, &fbo);
11818+ if (ret || !fbo)
11819+ return -ENOMEM;
11820+
11821+ ret = drm_bo_kmap(fbo, 0, fbo->num_pages, &tmp_kmap);
11822+ if (ret) {
11823+ drm_bo_usage_deref_unlocked(&fbo);
11824+ return -EINVAL;
11825+ }
11826+
11827+ drm_bo_kunmap(&tmp_kmap);
11828+ /* destroy our current fbo! */
11829+ drm_bo_usage_deref_unlocked(&fbo);
11830+#endif
11831+ }
11832+
11833+ switch (depth) {
11834+ case 8:
11835+ var->red.offset = 0;
11836+ var->green.offset = 0;
11837+ var->blue.offset = 0;
11838+ var->red.length = 8;
11839+ var->green.length = 8;
11840+ var->blue.length = 8;
11841+ var->transp.length = 0;
11842+ var->transp.offset = 0;
11843+ break;
11844+ case 15:
11845+ var->red.offset = 10;
11846+ var->green.offset = 5;
11847+ var->blue.offset = 0;
11848+ var->red.length = 5;
11849+ var->green.length = 5;
11850+ var->blue.length = 5;
11851+ var->transp.length = 1;
11852+ var->transp.offset = 15;
11853+ break;
11854+ case 16:
11855+ var->red.offset = 11;
11856+ var->green.offset = 5;
11857+ var->blue.offset = 0;
11858+ var->red.length = 5;
11859+ var->green.length = 6;
11860+ var->blue.length = 5;
11861+ var->transp.length = 0;
11862+ var->transp.offset = 0;
11863+ break;
11864+ case 24:
11865+ var->red.offset = 16;
11866+ var->green.offset = 8;
11867+ var->blue.offset = 0;
11868+ var->red.length = 8;
11869+ var->green.length = 8;
11870+ var->blue.length = 8;
11871+ var->transp.length = 0;
11872+ var->transp.offset = 0;
11873+ break;
11874+ case 32:
11875+ var->red.offset = 16;
11876+ var->green.offset = 8;
11877+ var->blue.offset = 0;
11878+ var->red.length = 8;
11879+ var->green.length = 8;
11880+ var->blue.length = 8;
11881+ var->transp.length = 8;
11882+ var->transp.offset = 24;
11883+ break;
11884+ default:
11885+ return -EINVAL;
11886+ }
11887+
11888+#if 0
11889+ /* Here we walk the output mode list and look for modes. If we haven't
11890+ * got it, then bail. Not very nice, so this is disabled.
11891+ * In the set_par code, we create our mode based on the incoming
11892+ * parameters. Nicer, but may not be desired by some.
11893+ */
11894+ list_for_each_entry(output, &dev->mode_config.connector_list, head) {
11895+ if (output->crtc == par->crtc)
11896+ break;
11897+ }
11898+
11899+ list_for_each_entry(drm_mode, &output->modes, head) {
11900+ if (drm_mode->hdisplay == var->xres &&
11901+ drm_mode->vdisplay == var->yres && drm_mode->clock != 0)
11902+ break;
11903+ }
11904+
11905+ if (!drm_mode)
11906+ return -EINVAL;
11907+#else
11908+ (void)dev; /* silence warnings */
11909+ (void)output;
11910+ (void)drm_mode;
11911+#endif
11912+
11913+ return 0;
11914+}
11915+
11916+static int psbfb_move_fb_bo(struct fb_info *info, struct drm_buffer_object *bo,
11917+ uint64_t mem_type_flags)
11918+{
11919+ struct psbfb_par *par;
11920+ loff_t holelen;
11921+ int ret;
11922+
11923+ /*
11924+ * Kill all user-space mappings of this device. They will be
11925+ * faulted back using nopfn when accessed.
11926+ */
11927+
11928+ par = info->par;
11929+ holelen = ((loff_t) bo->mem.num_pages) << PAGE_SHIFT;
11930+ mutex_lock(&par->vi->vm_mutex);
11931+ if (par->vi->f_mapping) {
11932+ unmap_mapping_range(par->vi->f_mapping, 0, holelen, 1);
11933+ }
11934+
11935+ ret = drm_bo_do_validate(bo,
11936+ mem_type_flags,
11937+ DRM_BO_MASK_MEM |
11938+ DRM_BO_FLAG_NO_EVICT,
11939+ DRM_BO_HINT_DONT_FENCE, 0, 1, NULL);
11940+
11941+ mutex_unlock(&par->vi->vm_mutex);
11942+ return ret;
11943+}
11944+
11945+/* this will let fbcon do the mode init */
11946+static int psbfb_set_par(struct fb_info *info)
11947+{
11948+ struct psbfb_par *par = info->par;
11949+ struct drm_framebuffer *fb = par->crtc->fb;
11950+ struct drm_device *dev = par->dev;
11951+ struct drm_display_mode *drm_mode;
11952+ struct fb_var_screeninfo *var = &info->var;
11953+ struct drm_psb_private *dev_priv = dev->dev_private;
11954+ struct drm_connector *output;
11955+ int pitch;
11956+ int depth;
11957+ int bpp = var->bits_per_pixel;
11958+
11959+ if (!fb)
11960+ return -ENOMEM;
11961+
11962+ switch (bpp) {
11963+ case 8:
11964+ depth = 8;
11965+ break;
11966+ case 16:
11967+ depth = (var->green.length == 6) ? 16 : 15;
11968+ break;
11969+ case 24: /* assume this is 32bpp / depth 24 */
11970+ bpp = 32;
11971+ /* fallthrough */
11972+ case 32:
11973+ depth = (var->transp.length > 0) ? 32 : 24;
11974+ break;
11975+ default:
11976+ return -EINVAL;
11977+ }
11978+
11979+ pitch = ((var->xres * ((bpp + 1) / 8)) + 0x3f) & ~0x3f;
11980+
11981+ if ((pitch * var->yres) > (fb->bo->num_pages << PAGE_SHIFT)) {
11982+#if 1
11983+ /* Need to resize the fb object.
11984+ * But the generic fbdev code doesn't really understand
11985+ * that we can do this. So disable for now.
11986+ */
11987+ DRM_INFO("Can't support requested size, too big!\n");
11988+ return -EINVAL;
11989+#else
11990+ int ret;
11991+ struct drm_buffer_object *fbo = NULL, *tfbo;
11992+ struct drm_bo_kmap_obj tmp_kmap, tkmap;
11993+
11994+ ret = drm_buffer_object_create(dev,
11995+ pitch * var->yres,
11996+ drm_bo_type_kernel,
11997+ DRM_BO_FLAG_READ |
11998+ DRM_BO_FLAG_WRITE |
11999+ DRM_BO_FLAG_MEM_TT |
12000+ DRM_BO_FLAG_MEM_VRAM |
12001+ DRM_BO_FLAG_NO_EVICT,
12002+ DRM_BO_HINT_DONT_FENCE,
12003+ 0, 0, &fbo);
12004+ if (ret || !fbo) {
12005+ DRM_ERROR
12006+ ("failed to allocate new resized framebuffer\n");
12007+ return -ENOMEM;
12008+ }
12009+
12010+ ret = drm_bo_kmap(fbo, 0, fbo->num_pages, &tmp_kmap);
12011+ if (ret) {
12012+ DRM_ERROR("failed to kmap framebuffer.\n");
12013+ drm_bo_usage_deref_unlocked(&fbo);
12014+ return -EINVAL;
12015+ }
12016+
12017+ DRM_DEBUG("allocated %dx%d fb: 0x%08lx, bo %p\n", fb->width,
12018+ fb->height, fb->offset, fbo);
12019+
12020+ /* set new screen base */
12021+ info->screen_base = tmp_kmap.virtual;
12022+
12023+ tkmap = fb->kmap;
12024+ fb->kmap = tmp_kmap;
12025+ drm_bo_kunmap(&tkmap);
12026+
12027+ tfbo = fb->bo;
12028+ fb->bo = fbo;
12029+ drm_bo_usage_deref_unlocked(&tfbo);
12030+#endif
12031+ }
12032+
12033+ fb->offset = fb->bo->offset - dev_priv->pg->gatt_start;
12034+ fb->width = var->xres;
12035+ fb->height = var->yres;
12036+ fb->bits_per_pixel = bpp;
12037+ fb->pitch = pitch;
12038+ fb->depth = depth;
12039+
12040+ info->fix.line_length = fb->pitch;
12041+ info->fix.visual =
12042+ (fb->depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
12043+
12044+ /* some fbdev's apps don't want these to change */
12045+ info->fix.smem_start = dev->mode_config.fb_base + fb->offset;
12046+
12047+ /* we have to align the output base address because the fb->bo
12048+ may be moved in the previous drm_bo_do_validate().
12049+ Otherwise the output screens may go black when exit the X
12050+ window and re-enter the console */
12051+ info->screen_base = fb->kmap.virtual;
12052+
12053+#if 0
12054+ /* relates to resize - disable */
12055+ info->fix.smem_len = info->fix.line_length * var->yres;
12056+ info->screen_size = info->fix.smem_len; /* ??? */
12057+#endif
12058+
12059+ /* Should we walk the output's modelist or just create our own ???
12060+ * For now, we create and destroy a mode based on the incoming
12061+ * parameters. But there's commented out code below which scans
12062+ * the output list too.
12063+ */
12064+#if 0
12065+ list_for_each_entry(output, &dev->mode_config.connector_list, head) {
12066+ if (output->crtc == par->crtc)
12067+ break;
12068+ }
12069+
12070+ list_for_each_entry(drm_mode, &output->modes, head) {
12071+ if (drm_mode->hdisplay == var->xres &&
12072+ drm_mode->vdisplay == var->yres && drm_mode->clock != 0)
12073+ break;
12074+ }
12075+#else
12076+ (void)output; /* silence warning */
12077+
12078+ drm_mode = drm_mode_create(dev);
12079+ drm_mode->hdisplay = var->xres;
12080+ drm_mode->hsync_start = drm_mode->hdisplay + var->right_margin;
12081+ drm_mode->hsync_end = drm_mode->hsync_start + var->hsync_len;
12082+ drm_mode->htotal = drm_mode->hsync_end + var->left_margin;
12083+ drm_mode->vdisplay = var->yres;
12084+ drm_mode->vsync_start = drm_mode->vdisplay + var->lower_margin;
12085+ drm_mode->vsync_end = drm_mode->vsync_start + var->vsync_len;
12086+ drm_mode->vtotal = drm_mode->vsync_end + var->upper_margin;
12087+ drm_mode->clock = PICOS2KHZ(var->pixclock);
12088+ drm_mode->vrefresh = drm_mode_vrefresh(drm_mode);
12089+ drm_mode_set_name(drm_mode);
12090+ drm_mode_set_crtcinfo(drm_mode, CRTC_INTERLACE_HALVE_V);
12091+#endif
12092+
12093+ if (!drm_crtc_helper_set_mode(par->crtc, drm_mode, 0, 0, NULL))
12094+ return -EINVAL;
12095+
12096+ /* Have to destroy our created mode if we're not searching the mode
12097+ * list for it.
12098+ */
12099+#if 1
12100+ drm_mode_destroy(dev, drm_mode);
12101+#endif
12102+
12103+ return 0;
12104+}
12105+
12106+extern int psb_2d_submit(struct drm_psb_private *, uint32_t *, uint32_t);;
12107+
12108+static int psb_accel_2d_fillrect(struct drm_psb_private *dev_priv,
12109+ uint32_t dst_offset, uint32_t dst_stride,
12110+ uint32_t dst_format, uint16_t dst_x,
12111+ uint16_t dst_y, uint16_t size_x,
12112+ uint16_t size_y, uint32_t fill)
12113+{
12114+ uint32_t buffer[10];
12115+ uint32_t *buf;
12116+ int ret;
12117+
12118+ buf = buffer;
12119+
12120+ *buf++ = PSB_2D_FENCE_BH;
12121+
12122+ *buf++ =
12123+ PSB_2D_DST_SURF_BH | dst_format | (dst_stride <<
12124+ PSB_2D_DST_STRIDE_SHIFT);
12125+ *buf++ = dst_offset;
12126+
12127+ *buf++ =
12128+ PSB_2D_BLIT_BH |
12129+ PSB_2D_ROT_NONE |
12130+ PSB_2D_COPYORDER_TL2BR |
12131+ PSB_2D_DSTCK_DISABLE |
12132+ PSB_2D_SRCCK_DISABLE | PSB_2D_USE_FILL | PSB_2D_ROP3_PATCOPY;
12133+
12134+ *buf++ = fill << PSB_2D_FILLCOLOUR_SHIFT;
12135+ *buf++ =
12136+ (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y <<
12137+ PSB_2D_DST_YSTART_SHIFT);
12138+ *buf++ =
12139+ (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y <<
12140+ PSB_2D_DST_YSIZE_SHIFT);
12141+ *buf++ = PSB_2D_FLUSH_BH;
12142+
12143+ psb_2d_lock(dev_priv);
12144+ ret = psb_2d_submit(dev_priv, buffer, buf - buffer);
12145+ psb_2d_unlock(dev_priv);
12146+
12147+ return ret;
12148+}
12149+
12150+static void psbfb_fillrect_accel(struct fb_info *info,
12151+ const struct fb_fillrect *r)
12152+{
12153+ struct psbfb_par *par = info->par;
12154+ struct drm_framebuffer *fb = par->crtc->fb;
12155+ struct drm_psb_private *dev_priv = par->dev->dev_private;
12156+ uint32_t offset;
12157+ uint32_t stride;
12158+ uint32_t format;
12159+
12160+ if (!fb)
12161+ return;
12162+
12163+ offset = fb->offset;
12164+ stride = fb->pitch;
12165+
12166+ switch (fb->depth) {
12167+ case 8:
12168+ format = PSB_2D_DST_332RGB;
12169+ break;
12170+ case 15:
12171+ format = PSB_2D_DST_555RGB;
12172+ break;
12173+ case 16:
12174+ format = PSB_2D_DST_565RGB;
12175+ break;
12176+ case 24:
12177+ case 32:
12178+ /* this is wrong but since we don't do blending its okay */
12179+ format = PSB_2D_DST_8888ARGB;
12180+ break;
12181+ default:
12182+ /* software fallback */
12183+ cfb_fillrect(info, r);
12184+ return;
12185+ }
12186+
12187+ psb_accel_2d_fillrect(dev_priv,
12188+ offset, stride, format,
12189+ r->dx, r->dy, r->width, r->height, r->color);
12190+}
12191+
12192+static void psbfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
12193+{
12194+ if (info->state != FBINFO_STATE_RUNNING)
12195+ return;
12196+ if (info->flags & FBINFO_HWACCEL_DISABLED) {
12197+ cfb_fillrect(info, rect);
12198+ return;
12199+ }
12200+ if (in_interrupt() || in_atomic()) {
12201+ /*
12202+ * Catch case when we're shutting down.
12203+ */
12204+ cfb_fillrect(info, rect);
12205+ return;
12206+ }
12207+ psbfb_fillrect_accel(info, rect);
12208+}
12209+
12210+uint32_t psb_accel_2d_copy_direction(int xdir, int ydir)
12211+{
12212+ if (xdir < 0)
12213+ return ((ydir <
12214+ 0) ? PSB_2D_COPYORDER_BR2TL : PSB_2D_COPYORDER_TR2BL);
12215+ else
12216+ return ((ydir <
12217+ 0) ? PSB_2D_COPYORDER_BL2TR : PSB_2D_COPYORDER_TL2BR);
12218+}
12219+
12220+/*
12221+ * @srcOffset in bytes
12222+ * @srcStride in bytes
12223+ * @srcFormat psb 2D format defines
12224+ * @dstOffset in bytes
12225+ * @dstStride in bytes
12226+ * @dstFormat psb 2D format defines
12227+ * @srcX offset in pixels
12228+ * @srcY offset in pixels
12229+ * @dstX offset in pixels
12230+ * @dstY offset in pixels
12231+ * @sizeX of the copied area
12232+ * @sizeY of the copied area
12233+ */
12234+static int psb_accel_2d_copy(struct drm_psb_private *dev_priv,
12235+ uint32_t src_offset, uint32_t src_stride,
12236+ uint32_t src_format, uint32_t dst_offset,
12237+ uint32_t dst_stride, uint32_t dst_format,
12238+ uint16_t src_x, uint16_t src_y, uint16_t dst_x,
12239+ uint16_t dst_y, uint16_t size_x, uint16_t size_y)
12240+{
12241+ uint32_t blit_cmd;
12242+ uint32_t buffer[10];
12243+ uint32_t *buf;
12244+ uint32_t direction;
12245+ int ret;
12246+
12247+ buf = buffer;
12248+
12249+ direction = psb_accel_2d_copy_direction(src_x - dst_x, src_y - dst_y);
12250+
12251+ if (direction == PSB_2D_COPYORDER_BR2TL ||
12252+ direction == PSB_2D_COPYORDER_TR2BL) {
12253+ src_x += size_x - 1;
12254+ dst_x += size_x - 1;
12255+ }
12256+ if (direction == PSB_2D_COPYORDER_BR2TL ||
12257+ direction == PSB_2D_COPYORDER_BL2TR) {
12258+ src_y += size_y - 1;
12259+ dst_y += size_y - 1;
12260+ }
12261+
12262+ blit_cmd =
12263+ PSB_2D_BLIT_BH |
12264+ PSB_2D_ROT_NONE |
12265+ PSB_2D_DSTCK_DISABLE |
12266+ PSB_2D_SRCCK_DISABLE |
12267+ PSB_2D_USE_PAT | PSB_2D_ROP3_SRCCOPY | direction;
12268+
12269+ *buf++ = PSB_2D_FENCE_BH;
12270+ *buf++ =
12271+ PSB_2D_DST_SURF_BH | dst_format | (dst_stride <<
12272+ PSB_2D_DST_STRIDE_SHIFT);
12273+ *buf++ = dst_offset;
12274+ *buf++ =
12275+ PSB_2D_SRC_SURF_BH | src_format | (src_stride <<
12276+ PSB_2D_SRC_STRIDE_SHIFT);
12277+ *buf++ = src_offset;
12278+ *buf++ =
12279+ PSB_2D_SRC_OFF_BH | (src_x << PSB_2D_SRCOFF_XSTART_SHIFT) | (src_y
12280+ <<
12281+ PSB_2D_SRCOFF_YSTART_SHIFT);
12282+ *buf++ = blit_cmd;
12283+ *buf++ =
12284+ (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y <<
12285+ PSB_2D_DST_YSTART_SHIFT);
12286+ *buf++ =
12287+ (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y <<
12288+ PSB_2D_DST_YSIZE_SHIFT);
12289+ *buf++ = PSB_2D_FLUSH_BH;
12290+
12291+ psb_2d_lock(dev_priv);
12292+ ret = psb_2d_submit(dev_priv, buffer, buf - buffer);
12293+ psb_2d_unlock(dev_priv);
12294+ return ret;
12295+}
12296+
12297+static void psbfb_copyarea_accel(struct fb_info *info,
12298+ const struct fb_copyarea *a)
12299+{
12300+ struct psbfb_par *par = info->par;
12301+ struct drm_framebuffer *fb = par->crtc->fb;
12302+ struct drm_psb_private *dev_priv = par->dev->dev_private;
12303+ uint32_t offset;
12304+ uint32_t stride;
12305+ uint32_t src_format;
12306+ uint32_t dst_format;
12307+
12308+ if (!fb)
12309+ return;
12310+
12311+ offset = fb->offset;
12312+ stride = fb->pitch;
12313+
12314+ if (a->width == 8 || a->height == 8) {
12315+ psb_2d_lock(dev_priv);
12316+ psb_idle_2d(par->dev);
12317+ psb_2d_unlock(dev_priv);
12318+ cfb_copyarea(info, a);
12319+ return;
12320+ }
12321+
12322+ switch (fb->depth) {
12323+ case 8:
12324+ src_format = PSB_2D_SRC_332RGB;
12325+ dst_format = PSB_2D_DST_332RGB;
12326+ break;
12327+ case 15:
12328+ src_format = PSB_2D_SRC_555RGB;
12329+ dst_format = PSB_2D_DST_555RGB;
12330+ break;
12331+ case 16:
12332+ src_format = PSB_2D_SRC_565RGB;
12333+ dst_format = PSB_2D_DST_565RGB;
12334+ break;
12335+ case 24:
12336+ case 32:
12337+ /* this is wrong but since we don't do blending its okay */
12338+ src_format = PSB_2D_SRC_8888ARGB;
12339+ dst_format = PSB_2D_DST_8888ARGB;
12340+ break;
12341+ default:
12342+ /* software fallback */
12343+ cfb_copyarea(info, a);
12344+ return;
12345+ }
12346+
12347+ psb_accel_2d_copy(dev_priv,
12348+ offset, stride, src_format,
12349+ offset, stride, dst_format,
12350+ a->sx, a->sy, a->dx, a->dy, a->width, a->height);
12351+}
12352+
12353+static void psbfb_copyarea(struct fb_info *info,
12354+ const struct fb_copyarea *region)
12355+{
12356+ if (info->state != FBINFO_STATE_RUNNING)
12357+ return;
12358+ if (info->flags & FBINFO_HWACCEL_DISABLED) {
12359+ cfb_copyarea(info, region);
12360+ return;
12361+ }
12362+ if (in_interrupt() || in_atomic()) {
12363+ /*
12364+ * Catch case when we're shutting down.
12365+ */
12366+ cfb_copyarea(info, region);
12367+ return;
12368+ }
12369+
12370+ psbfb_copyarea_accel(info, region);
12371+}
12372+
12373+void psbfb_imageblit(struct fb_info *info, const struct fb_image *image)
12374+{
12375+ if (info->state != FBINFO_STATE_RUNNING)
12376+ return;
12377+ if (info->flags & FBINFO_HWACCEL_DISABLED) {
12378+ cfb_imageblit(info, image);
12379+ return;
12380+ }
12381+ if (in_interrupt() || in_atomic()) {
12382+ cfb_imageblit(info, image);
12383+ return;
12384+ }
12385+
12386+ cfb_imageblit(info, image);
12387+}
12388+
12389+static int psbfb_blank(int blank_mode, struct fb_info *info)
12390+{
12391+ int dpms_mode;
12392+ struct psbfb_par *par = info->par;
12393+ struct drm_connector *output;
12394+ struct drm_crtc_helper_funcs *crtc_funcs;
12395+
12396+ par->dpms_state = blank_mode;
12397+
12398+ switch(blank_mode) {
12399+ case FB_BLANK_UNBLANK:
12400+ dpms_mode = DRM_MODE_DPMS_ON;
12401+ break;
12402+ case FB_BLANK_NORMAL:
12403+ if (!par->crtc)
12404+ return 0;
12405+ crtc_funcs = par->crtc->helper_private;
12406+
12407+ (*crtc_funcs->dpms)(par->crtc, DRM_MODE_DPMS_STANDBY);
12408+ return 0;
12409+ case FB_BLANK_HSYNC_SUSPEND:
12410+ default:
12411+ dpms_mode = DRM_MODE_DPMS_STANDBY;
12412+ break;
12413+ case FB_BLANK_VSYNC_SUSPEND:
12414+ dpms_mode = DRM_MODE_DPMS_SUSPEND;
12415+ break;
12416+ case FB_BLANK_POWERDOWN:
12417+ dpms_mode = DRM_MODE_DPMS_OFF;
12418+ break;
12419+ }
12420+
12421+ if (!par->crtc)
12422+ return 0;
12423+
12424+ crtc_funcs = par->crtc->helper_private;
12425+
12426+ list_for_each_entry(output, &par->dev->mode_config.connector_list, head) {
12427+ if (output->encoder->crtc == par->crtc)
12428+ (*output->funcs->dpms)(output, dpms_mode);
12429+ }
12430+
12431+ return 0;
12432+}
12433+
12434+
12435+static int psbfb_kms_off(struct drm_device *dev, int suspend)
12436+{
12437+ struct drm_framebuffer *fb = 0;
12438+ struct drm_buffer_object *bo = 0;
12439+ struct drm_psb_private *dev_priv = dev->dev_private;
12440+ int ret = 0;
12441+
12442+ DRM_DEBUG("psbfb_kms_off_ioctl\n");
12443+
12444+ mutex_lock(&dev->mode_config.mutex);
12445+ list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
12446+ struct fb_info *info = fb->fbdev;
12447+ struct psbfb_par *par = info->par;
12448+ int save_dpms_state;
12449+
12450+ if (suspend)
12451+ fb_set_suspend(info, 1);
12452+ else
12453+ info->state &= ~FBINFO_STATE_RUNNING;
12454+
12455+ info->screen_base = NULL;
12456+
12457+ bo = fb->bo;
12458+
12459+ if (!bo)
12460+ continue;
12461+
12462+ drm_bo_kunmap(&fb->kmap);
12463+
12464+ /*
12465+ * We don't take the 2D lock here as we assume that the
12466+ * 2D engine will eventually idle anyway.
12467+ */
12468+
12469+ if (!suspend) {
12470+ uint32_t dummy2 = 0;
12471+ (void) psb_fence_emit_sequence(dev, PSB_ENGINE_2D, 0,
12472+ &dummy2, &dummy2);
12473+ psb_2d_lock(dev_priv);
12474+ (void)psb_idle_2d(dev);
12475+ psb_2d_unlock(dev_priv);
12476+ } else
12477+ psb_idle_2d(dev);
12478+
12479+ save_dpms_state = par->dpms_state;
12480+ psbfb_blank(FB_BLANK_NORMAL, info);
12481+ par->dpms_state = save_dpms_state;
12482+
12483+ ret = psbfb_move_fb_bo(info, bo, DRM_BO_FLAG_MEM_LOCAL);
12484+
12485+ if (ret)
12486+ goto out_err;
12487+ }
12488+ out_err:
12489+ mutex_unlock(&dev->mode_config.mutex);
12490+
12491+ return ret;
12492+}
12493+
12494+int psbfb_kms_off_ioctl(struct drm_device *dev, void *data,
12495+ struct drm_file *file_priv)
12496+{
12497+ int ret;
12498+
12499+ acquire_console_sem();
12500+ ret = psbfb_kms_off(dev, 0);
12501+ release_console_sem();
12502+
12503+ return ret;
12504+}
12505+
12506+static int psbfb_kms_on(struct drm_device *dev, int resume)
12507+{
12508+ struct drm_framebuffer *fb = 0;
12509+ struct drm_buffer_object *bo = 0;
12510+ struct drm_psb_private *dev_priv = dev->dev_private;
12511+ int ret = 0;
12512+ int dummy;
12513+
12514+ DRM_DEBUG("psbfb_kms_on_ioctl\n");
12515+
12516+ if (!resume) {
12517+ uint32_t dummy2 = 0;
12518+ (void) psb_fence_emit_sequence(dev, PSB_ENGINE_2D, 0,
12519+ &dummy2, &dummy2);
12520+ psb_2d_lock(dev_priv);
12521+ (void)psb_idle_2d(dev);
12522+ psb_2d_unlock(dev_priv);
12523+ } else
12524+ psb_idle_2d(dev);
12525+
12526+ mutex_lock(&dev->mode_config.mutex);
12527+ list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
12528+ struct fb_info *info = fb->fbdev;
12529+ struct psbfb_par *par = info->par;
12530+
12531+ bo = fb->bo;
12532+ if (!bo)
12533+ continue;
12534+
12535+ ret = psbfb_move_fb_bo(info, bo,
12536+ DRM_BO_FLAG_MEM_TT |
12537+ DRM_BO_FLAG_MEM_VRAM |
12538+ DRM_BO_FLAG_NO_EVICT);
12539+ if (ret)
12540+ goto out_err;
12541+
12542+ ret = drm_bo_kmap(bo, 0, bo->num_pages, &fb->kmap);
12543+ if (ret)
12544+ goto out_err;
12545+
12546+ info->screen_base = drm_bmo_virtual(&fb->kmap, &dummy);
12547+ fb->offset = bo->offset - dev_priv->pg->gatt_start;
12548+
12549+ if (ret)
12550+ goto out_err;
12551+
12552+ if (resume)
12553+ fb_set_suspend(info, 0);
12554+ else
12555+ info->state |= FBINFO_STATE_RUNNING;
12556+
12557+ /*
12558+ * Re-run modesetting here, since the VDS scanout offset may
12559+ * have changed.
12560+ */
12561+
12562+ if (par->crtc->enabled) {
12563+ psbfb_set_par(info);
12564+ psbfb_blank(par->dpms_state, info);
12565+ }
12566+ }
12567+ out_err:
12568+ mutex_unlock(&dev->mode_config.mutex);
12569+
12570+ return ret;
12571+}
12572+
12573+int psbfb_kms_on_ioctl(struct drm_device *dev, void *data,
12574+ struct drm_file *file_priv)
12575+{
12576+ int ret;
12577+
12578+ acquire_console_sem();
12579+ ret = psbfb_kms_on(dev, 0);
12580+ release_console_sem();
12581+#ifdef SII_1392_WA
12582+ if((SII_1392 != 1) || (drm_psb_no_fb==0))
12583+ drm_helper_disable_unused_functions(dev);
12584+#else
12585+ drm_helper_disable_unused_functions(dev);
12586+#endif
12587+ return ret;
12588+}
12589+
12590+void psbfb_suspend(struct drm_device *dev)
12591+{
12592+ acquire_console_sem();
12593+ psbfb_kms_off(dev, 1);
12594+ release_console_sem();
12595+}
12596+
12597+void psbfb_resume(struct drm_device *dev)
12598+{
12599+ acquire_console_sem();
12600+ psbfb_kms_on(dev, 1);
12601+ release_console_sem();
12602+#ifdef SII_1392_WA
12603+ if((SII_1392 != 1) || (drm_psb_no_fb==0))
12604+ drm_helper_disable_unused_functions(dev);
12605+#else
12606+ drm_helper_disable_unused_functions(dev);
12607+#endif
12608+}
12609+
12610+/*
12611+ * FIXME: Before kernel inclusion, migrate nopfn to fault.
12612+ * Also, these should be the default vm ops for buffer object type fbs.
12613+ */
12614+
12615+extern unsigned long drm_bo_vm_fault(struct vm_area_struct *vma,
12616+ struct vm_fault *vmf);
12617+
12618+/*
12619+ * This wrapper is a bit ugly and is here because we need access to a mutex
12620+ * that we can lock both around nopfn and around unmap_mapping_range + move.
12621+ * Normally, this would've been done using the bo mutex, but unfortunately
12622+ * we cannot lock it around drm_bo_do_validate(), since that would imply
12623+ * recursive locking.
12624+ */
12625+
12626+static int psbfb_fault(struct vm_area_struct *vma,
12627+ struct vm_fault *vmf)
12628+{
12629+ struct psbfb_vm_info *vi = (struct psbfb_vm_info *)vma->vm_private_data;
12630+ struct vm_area_struct tmp_vma;
12631+ int ret;
12632+
12633+ mutex_lock(&vi->vm_mutex);
12634+ tmp_vma = *vma;
12635+ tmp_vma.vm_private_data = vi->bo;
12636+ ret = drm_bo_vm_fault(&tmp_vma, vmf);
12637+ mutex_unlock(&vi->vm_mutex);
12638+ return ret;
12639+}
12640+
12641+static void psbfb_vm_open(struct vm_area_struct *vma)
12642+{
12643+ struct psbfb_vm_info *vi = (struct psbfb_vm_info *)vma->vm_private_data;
12644+
12645+ atomic_inc(&vi->refcount);
12646+}
12647+
12648+static void psbfb_vm_close(struct vm_area_struct *vma)
12649+{
12650+ psbfb_vm_info_deref((struct psbfb_vm_info **)&vma->vm_private_data);
12651+}
12652+
12653+static struct vm_operations_struct psbfb_vm_ops = {
12654+ .fault = psbfb_fault,
12655+ .open = psbfb_vm_open,
12656+ .close = psbfb_vm_close,
12657+};
12658+
12659+static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
12660+{
12661+ struct psbfb_par *par = info->par;
12662+ struct drm_framebuffer *fb = par->crtc->fb;
12663+ struct drm_buffer_object *bo = fb->bo;
12664+ unsigned long size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
12665+ unsigned long offset = vma->vm_pgoff;
12666+
12667+ if (vma->vm_pgoff != 0)
12668+ return -EINVAL;
12669+ if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
12670+ return -EINVAL;
12671+ if (offset + size > bo->num_pages)
12672+ return -EINVAL;
12673+
12674+ mutex_lock(&par->vi->vm_mutex);
12675+ if (!par->vi->f_mapping)
12676+ par->vi->f_mapping = vma->vm_file->f_mapping;
12677+ mutex_unlock(&par->vi->vm_mutex);
12678+
12679+ vma->vm_private_data = psbfb_vm_info_ref(par->vi);
12680+
12681+ vma->vm_ops = &psbfb_vm_ops;
12682+ vma->vm_flags |= VM_PFNMAP;
12683+
12684+ return 0;
12685+}
12686+
12687+int psbfb_sync(struct fb_info *info)
12688+{
12689+ struct psbfb_par *par = info->par;
12690+ struct drm_psb_private *dev_priv = par->dev->dev_private;
12691+
12692+ psb_2d_lock(dev_priv);
12693+ psb_idle_2d(par->dev);
12694+ psb_2d_unlock(dev_priv);
12695+
12696+ return 0;
12697+}
12698+
12699+static struct fb_ops psbfb_ops = {
12700+ .owner = THIS_MODULE,
12701+ .fb_check_var = psbfb_check_var,
12702+ .fb_set_par = psbfb_set_par,
12703+ .fb_setcolreg = psbfb_setcolreg,
12704+ .fb_fillrect = psbfb_fillrect,
12705+ .fb_copyarea = psbfb_copyarea,
12706+ .fb_imageblit = psbfb_imageblit,
12707+ .fb_mmap = psbfb_mmap,
12708+ .fb_sync = psbfb_sync,
12709+ .fb_blank = psbfb_blank,
12710+};
12711+
12712+static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
12713+{
12714+ drm_framebuffer_cleanup(fb);
12715+ kfree(fb);
12716+}
12717+
12718+static const struct drm_framebuffer_funcs psb_fb_funcs = {
12719+ .destroy = psb_user_framebuffer_destroy,
12720+};
12721+
12722+int psbfb_probe(struct drm_device *dev, struct drm_crtc *crtc)
12723+{
12724+ struct fb_info *info;
12725+ struct psbfb_par *par;
12726+ struct device *device = &dev->pdev->dev;
12727+ struct drm_framebuffer *fb;
12728+ struct drm_display_mode *mode = crtc->desired_mode;
12729+ struct drm_psb_private *dev_priv =
12730+ (struct drm_psb_private *)dev->dev_private;
12731+ struct drm_buffer_object *fbo = NULL;
12732+ int ret;
12733+ int is_iomem;
12734+
12735+ if (drm_psb_no_fb) {
12736+ /* need to do this as the DRM will disable the output */
12737+ crtc->enabled = 1;
12738+ return 0;
12739+ }
12740+
12741+ fb = kzalloc(sizeof(struct drm_framebuffer), GFP_KERNEL);
12742+ if (!fb)
12743+ return -ENOMEM;
12744+
12745+
12746+ ret = drm_framebuffer_init(dev, fb, &psb_fb_funcs);
12747+ if (!fb) {
12748+ DRM_ERROR("failed to allocate fb.\n");
12749+ return -ENOMEM;
12750+ }
12751+ crtc->fb = fb;
12752+
12753+ fb->width = mode->hdisplay;
12754+ fb->height = mode->vdisplay;
12755+
12756+ fb->bits_per_pixel = 32;
12757+ fb->depth = 24;
12758+ fb->pitch =
12759+ ((fb->width * ((fb->bits_per_pixel + 1) / 8)) + 0x3f) & ~0x3f;
12760+
12761+ info = framebuffer_alloc(sizeof(struct psbfb_par), device);
12762+ if (!info) {
12763+ kfree(fb);
12764+ return -ENOMEM;
12765+ }
12766+
12767+ ret = drm_buffer_object_create(dev,
12768+ fb->pitch * fb->height,
12769+ drm_bo_type_kernel,
12770+ DRM_BO_FLAG_READ |
12771+ DRM_BO_FLAG_WRITE |
12772+ DRM_BO_FLAG_MEM_TT |
12773+ DRM_BO_FLAG_MEM_VRAM |
12774+ DRM_BO_FLAG_NO_EVICT,
12775+ DRM_BO_HINT_DONT_FENCE, 0, 0, &fbo);
12776+ if (ret || !fbo) {
12777+ DRM_ERROR("failed to allocate framebuffer\n");
12778+ goto out_err0;
12779+ }
12780+
12781+ fb->offset = fbo->offset - dev_priv->pg->gatt_start;
12782+ fb->bo = fbo;
12783+ DRM_DEBUG("allocated %dx%d fb: 0x%08lx, bo %p\n", fb->width,
12784+ fb->height, fb->offset, fbo);
12785+
12786+ fb->fbdev = info;
12787+
12788+ par = info->par;
12789+
12790+ par->dev = dev;
12791+ par->crtc = crtc;
12792+ par->vi = psbfb_vm_info_create();
12793+ if (!par->vi)
12794+ goto out_err1;
12795+
12796+ mutex_lock(&dev->struct_mutex);
12797+ par->vi->bo = fbo;
12798+ atomic_inc(&fbo->usage);
12799+ mutex_unlock(&dev->struct_mutex);
12800+
12801+ par->vi->f_mapping = NULL;
12802+ info->fbops = &psbfb_ops;
12803+
12804+ strcpy(info->fix.id, "psbfb");
12805+ info->fix.type = FB_TYPE_PACKED_PIXELS;
12806+ info->fix.visual = FB_VISUAL_DIRECTCOLOR;
12807+ info->fix.type_aux = 0;
12808+ info->fix.xpanstep = 1;
12809+ info->fix.ypanstep = 1;
12810+ info->fix.ywrapstep = 0;
12811+ info->fix.accel = FB_ACCEL_NONE; /* ??? */
12812+ info->fix.type_aux = 0;
12813+ info->fix.mmio_start = 0;
12814+ info->fix.mmio_len = 0;
12815+ info->fix.line_length = fb->pitch;
12816+ info->fix.smem_start = dev->mode_config.fb_base + fb->offset;
12817+ info->fix.smem_len = info->fix.line_length * fb->height;
12818+
12819+ info->flags = FBINFO_DEFAULT |
12820+ FBINFO_PARTIAL_PAN_OK /*| FBINFO_MISC_ALWAYS_SETPAR */ ;
12821+
12822+ ret = drm_bo_kmap(fb->bo, 0, fb->bo->num_pages, &fb->kmap);
12823+ if (ret) {
12824+ DRM_ERROR("error mapping fb: %d\n", ret);
12825+ goto out_err2;
12826+ }
12827+
12828+ info->screen_base = drm_bmo_virtual(&fb->kmap, &is_iomem);
12829+ memset(info->screen_base, 0x00, fb->pitch*fb->height);
12830+ info->screen_size = info->fix.smem_len; /* FIXME */
12831+ info->pseudo_palette = fb->pseudo_palette;
12832+ info->var.xres_virtual = fb->width;
12833+ info->var.yres_virtual = fb->height;
12834+ info->var.bits_per_pixel = fb->bits_per_pixel;
12835+ info->var.xoffset = 0;
12836+ info->var.yoffset = 0;
12837+ info->var.activate = FB_ACTIVATE_NOW;
12838+ info->var.height = -1;
12839+ info->var.width = -1;
12840+ info->var.vmode = FB_VMODE_NONINTERLACED;
12841+
12842+ info->var.xres = mode->hdisplay;
12843+ info->var.right_margin = mode->hsync_start - mode->hdisplay;
12844+ info->var.hsync_len = mode->hsync_end - mode->hsync_start;
12845+ info->var.left_margin = mode->htotal - mode->hsync_end;
12846+ info->var.yres = mode->vdisplay;
12847+ info->var.lower_margin = mode->vsync_start - mode->vdisplay;
12848+ info->var.vsync_len = mode->vsync_end - mode->vsync_start;
12849+ info->var.upper_margin = mode->vtotal - mode->vsync_end;
12850+ info->var.pixclock = 10000000 / mode->htotal * 1000 /
12851+ mode->vtotal * 100;
12852+ /* avoid overflow */
12853+ info->var.pixclock = info->var.pixclock * 1000 / mode->vrefresh;
12854+
12855+ info->pixmap.size = 64 * 1024;
12856+ info->pixmap.buf_align = 8;
12857+ info->pixmap.access_align = 32;
12858+ info->pixmap.flags = FB_PIXMAP_SYSTEM;
12859+ info->pixmap.scan_align = 1;
12860+
12861+ DRM_DEBUG("fb depth is %d\n", fb->depth);
12862+ DRM_DEBUG(" pitch is %d\n", fb->pitch);
12863+ switch (fb->depth) {
12864+ case 8:
12865+ info->var.red.offset = 0;
12866+ info->var.green.offset = 0;
12867+ info->var.blue.offset = 0;
12868+ info->var.red.length = 8; /* 8bit DAC */
12869+ info->var.green.length = 8;
12870+ info->var.blue.length = 8;
12871+ info->var.transp.offset = 0;
12872+ info->var.transp.length = 0;
12873+ break;
12874+ case 15:
12875+ info->var.red.offset = 10;
12876+ info->var.green.offset = 5;
12877+ info->var.blue.offset = 0;
12878+ info->var.red.length = info->var.green.length =
12879+ info->var.blue.length = 5;
12880+ info->var.transp.offset = 15;
12881+ info->var.transp.length = 1;
12882+ break;
12883+ case 16:
12884+ info->var.red.offset = 11;
12885+ info->var.green.offset = 5;
12886+ info->var.blue.offset = 0;
12887+ info->var.red.length = 5;
12888+ info->var.green.length = 6;
12889+ info->var.blue.length = 5;
12890+ info->var.transp.offset = 0;
12891+ break;
12892+ case 24:
12893+ info->var.red.offset = 16;
12894+ info->var.green.offset = 8;
12895+ info->var.blue.offset = 0;
12896+ info->var.red.length = info->var.green.length =
12897+ info->var.blue.length = 8;
12898+ info->var.transp.offset = 0;
12899+ info->var.transp.length = 0;
12900+ break;
12901+ case 32:
12902+ info->var.red.offset = 16;
12903+ info->var.green.offset = 8;
12904+ info->var.blue.offset = 0;
12905+ info->var.red.length = info->var.green.length =
12906+ info->var.blue.length = 8;
12907+ info->var.transp.offset = 24;
12908+ info->var.transp.length = 8;
12909+ break;
12910+ default:
12911+ break;
12912+ }
12913+
12914+ if (register_framebuffer(info) < 0)
12915+ goto out_err3;
12916+
12917+ if (psbfb_check_var(&info->var, info) < 0)
12918+ goto out_err4;
12919+
12920+ psbfb_set_par(info);
12921+
12922+ DRM_INFO("fb%d: %s frame buffer device\n", info->node, info->fix.id);
12923+
12924+ return 0;
12925+ out_err4:
12926+ unregister_framebuffer(info);
12927+ out_err3:
12928+ drm_bo_kunmap(&fb->kmap);
12929+ out_err2:
12930+ psbfb_vm_info_deref(&par->vi);
12931+ out_err1:
12932+ drm_bo_usage_deref_unlocked(&fb->bo);
12933+ out_err0:
12934+ drm_framebuffer_cleanup(fb);
12935+ framebuffer_release(info);
12936+ crtc->fb = NULL;
12937+ return -EINVAL;
12938+}
12939+
12940+EXPORT_SYMBOL(psbfb_probe);
12941+
12942+int psbfb_remove(struct drm_device *dev, struct drm_crtc *crtc)
12943+{
12944+ struct drm_framebuffer *fb;
12945+ struct fb_info *info;
12946+ struct psbfb_par *par;
12947+
12948+ if (drm_psb_no_fb)
12949+ return 0;
12950+
12951+ fb = crtc->fb;
12952+ info = fb->fbdev;
12953+
12954+ if (info) {
12955+ unregister_framebuffer(info);
12956+ drm_bo_kunmap(&fb->kmap);
12957+ par = info->par;
12958+ if (par)
12959+ psbfb_vm_info_deref(&par->vi);
12960+ drm_bo_usage_deref_unlocked(&fb->bo);
12961+ drm_framebuffer_cleanup(fb);
12962+ framebuffer_release(info);
12963+ }
12964+ return 0;
12965+}
12966+
12967+EXPORT_SYMBOL(psbfb_remove);
12968+
12969Index: linux-2.6.28/drivers/gpu/drm/psb/psb_fence.c
12970===================================================================
12971--- /dev/null 1970-01-01 00:00:00.000000000 +0000
12972+++ linux-2.6.28/drivers/gpu/drm/psb/psb_fence.c 2009-02-12 09:14:41.000000000 +0000
12973@@ -0,0 +1,285 @@
12974+/**************************************************************************
12975+ * Copyright (c) 2007, Intel Corporation.
12976+ * All Rights Reserved.
12977+ *
12978+ * This program is free software; you can redistribute it and/or modify it
12979+ * under the terms and conditions of the GNU General Public License,
12980+ * version 2, as published by the Free Software Foundation.
12981+ *
12982+ * This program is distributed in the hope it will be useful, but WITHOUT
12983+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12984+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12985+ * more details.
12986+ *
12987+ * You should have received a copy of the GNU General Public License along with
12988+ * this program; if not, write to the Free Software Foundation, Inc.,
12989+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
12990+ *
12991+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
12992+ * develop this driver.
12993+ *
12994+ **************************************************************************/
12995+/*
12996+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
12997+ */
12998+
12999+#include "drmP.h"
13000+#include "psb_drv.h"
13001+
13002+static void psb_poll_ta(struct drm_device *dev, uint32_t waiting_types)
13003+{
13004+ struct drm_psb_private *dev_priv =
13005+ (struct drm_psb_private *)dev->dev_private;
13006+ struct drm_fence_driver *driver = dev->driver->fence_driver;
13007+ uint32_t cur_flag = 1;
13008+ uint32_t flags = 0;
13009+ uint32_t sequence = 0;
13010+ uint32_t remaining = 0xFFFFFFFF;
13011+ uint32_t diff;
13012+
13013+ struct psb_scheduler *scheduler;
13014+ struct psb_scheduler_seq *seq;
13015+ struct drm_fence_class_manager *fc =
13016+ &dev->fm.fence_class[PSB_ENGINE_TA];
13017+
13018+ if (unlikely(!dev_priv))
13019+ return;
13020+
13021+ scheduler = &dev_priv->scheduler;
13022+ seq = scheduler->seq;
13023+
13024+ while (likely(waiting_types & remaining)) {
13025+ if (!(waiting_types & cur_flag))
13026+ goto skip;
13027+ if (seq->reported)
13028+ goto skip;
13029+ if (flags == 0)
13030+ sequence = seq->sequence;
13031+ else if (sequence != seq->sequence) {
13032+ drm_fence_handler(dev, PSB_ENGINE_TA,
13033+ sequence, flags, 0);
13034+ sequence = seq->sequence;
13035+ flags = 0;
13036+ }
13037+ flags |= cur_flag;
13038+
13039+ /*
13040+ * Sequence may not have ended up on the ring yet.
13041+ * In that case, report it but don't mark it as
13042+ * reported. A subsequent poll will report it again.
13043+ */
13044+
13045+ diff = (fc->latest_queued_sequence - sequence) &
13046+ driver->sequence_mask;
13047+ if (diff < driver->wrap_diff)
13048+ seq->reported = 1;
13049+
13050+ skip:
13051+ cur_flag <<= 1;
13052+ remaining <<= 1;
13053+ seq++;
13054+ }
13055+
13056+ if (flags) {
13057+ drm_fence_handler(dev, PSB_ENGINE_TA, sequence, flags, 0);
13058+ }
13059+}
13060+
13061+static void psb_poll_other(struct drm_device *dev, uint32_t fence_class,
13062+ uint32_t waiting_types)
13063+{
13064+ struct drm_psb_private *dev_priv =
13065+ (struct drm_psb_private *)dev->dev_private;
13066+ struct drm_fence_manager *fm = &dev->fm;
13067+ struct drm_fence_class_manager *fc = &fm->fence_class[fence_class];
13068+ uint32_t sequence;
13069+
13070+ if (unlikely(!dev_priv))
13071+ return;
13072+
13073+ if (waiting_types) {
13074+ if (fence_class == PSB_ENGINE_VIDEO)
13075+ sequence = dev_priv->msvdx_current_sequence;
13076+ else
13077+ sequence = dev_priv->comm[fence_class << 4];
13078+
13079+ drm_fence_handler(dev, fence_class, sequence,
13080+ DRM_FENCE_TYPE_EXE, 0);
13081+
13082+ switch (fence_class) {
13083+ case PSB_ENGINE_2D:
13084+ if (dev_priv->fence0_irq_on && !fc->waiting_types) {
13085+ psb_2D_irq_off(dev_priv);
13086+ dev_priv->fence0_irq_on = 0;
13087+ } else if (!dev_priv->fence0_irq_on
13088+ && fc->waiting_types) {
13089+ psb_2D_irq_on(dev_priv);
13090+ dev_priv->fence0_irq_on = 1;
13091+ }
13092+ break;
13093+#if 0
13094+ /*
13095+ * FIXME: MSVDX irq switching
13096+ */
13097+
13098+ case PSB_ENGINE_VIDEO:
13099+ if (dev_priv->fence2_irq_on && !fc->waiting_types) {
13100+ psb_msvdx_irq_off(dev_priv);
13101+ dev_priv->fence2_irq_on = 0;
13102+ } else if (!dev_priv->fence2_irq_on
13103+ && fc->pending_exe_flush) {
13104+ psb_msvdx_irq_on(dev_priv);
13105+ dev_priv->fence2_irq_on = 1;
13106+ }
13107+ break;
13108+#endif
13109+ default:
13110+ return;
13111+ }
13112+ }
13113+}
13114+
13115+static void psb_fence_poll(struct drm_device *dev,
13116+ uint32_t fence_class, uint32_t waiting_types)
13117+{
13118+ switch (fence_class) {
13119+ case PSB_ENGINE_TA:
13120+ psb_poll_ta(dev, waiting_types);
13121+ break;
13122+ default:
13123+ psb_poll_other(dev, fence_class, waiting_types);
13124+ break;
13125+ }
13126+}
13127+
13128+void psb_fence_error(struct drm_device *dev,
13129+ uint32_t fence_class,
13130+ uint32_t sequence, uint32_t type, int error)
13131+{
13132+ struct drm_fence_manager *fm = &dev->fm;
13133+ unsigned long irq_flags;
13134+
13135+ BUG_ON(fence_class >= PSB_NUM_ENGINES);
13136+ write_lock_irqsave(&fm->lock, irq_flags);
13137+ drm_fence_handler(dev, fence_class, sequence, type, error);
13138+ write_unlock_irqrestore(&fm->lock, irq_flags);
13139+}
13140+
13141+int psb_fence_emit_sequence(struct drm_device *dev, uint32_t fence_class,
13142+ uint32_t flags, uint32_t * sequence,
13143+ uint32_t * native_type)
13144+{
13145+ struct drm_psb_private *dev_priv =
13146+ (struct drm_psb_private *)dev->dev_private;
13147+ uint32_t seq = 0;
13148+ int ret;
13149+
13150+ if (!dev_priv)
13151+ return -EINVAL;
13152+
13153+ if (fence_class >= PSB_NUM_ENGINES)
13154+ return -EINVAL;
13155+
13156+ switch (fence_class) {
13157+ case PSB_ENGINE_2D:
13158+ spin_lock(&dev_priv->sequence_lock);
13159+ seq = ++dev_priv->sequence[fence_class];
13160+ spin_unlock(&dev_priv->sequence_lock);
13161+ ret = psb_blit_sequence(dev_priv, seq);
13162+ if (ret)
13163+ return ret;
13164+ break;
13165+ case PSB_ENGINE_VIDEO:
13166+ spin_lock(&dev_priv->sequence_lock);
13167+ seq = ++dev_priv->sequence[fence_class];
13168+ spin_unlock(&dev_priv->sequence_lock);
13169+ break;
13170+ default:
13171+ spin_lock(&dev_priv->sequence_lock);
13172+ seq = dev_priv->sequence[fence_class];
13173+ spin_unlock(&dev_priv->sequence_lock);
13174+ }
13175+
13176+ *sequence = seq;
13177+ *native_type = DRM_FENCE_TYPE_EXE;
13178+
13179+ return 0;
13180+}
13181+
13182+uint32_t psb_fence_advance_sequence(struct drm_device * dev,
13183+ uint32_t fence_class)
13184+{
13185+ struct drm_psb_private *dev_priv =
13186+ (struct drm_psb_private *)dev->dev_private;
13187+ uint32_t sequence;
13188+
13189+ spin_lock(&dev_priv->sequence_lock);
13190+ sequence = ++dev_priv->sequence[fence_class];
13191+ spin_unlock(&dev_priv->sequence_lock);
13192+
13193+ return sequence;
13194+}
13195+
13196+void psb_fence_handler(struct drm_device *dev, uint32_t fence_class)
13197+{
13198+ struct drm_fence_manager *fm = &dev->fm;
13199+ struct drm_fence_class_manager *fc = &fm->fence_class[fence_class];
13200+
13201+#ifdef FIX_TG_16
13202+ if (fence_class == 0) {
13203+ struct drm_psb_private *dev_priv =
13204+ (struct drm_psb_private *)dev->dev_private;
13205+
13206+ if ((atomic_read(&dev_priv->ta_wait_2d_irq) == 1) &&
13207+ (PSB_RSGX32(PSB_CR_2D_SOCIF) == _PSB_C2_SOCIF_EMPTY) &&
13208+ ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) &
13209+ _PSB_C2B_STATUS_BUSY) == 0))
13210+ psb_resume_ta_2d_idle(dev_priv);
13211+ }
13212+#endif
13213+ write_lock(&fm->lock);
13214+ psb_fence_poll(dev, fence_class, fc->waiting_types);
13215+ write_unlock(&fm->lock);
13216+}
13217+
13218+static int psb_fence_wait(struct drm_fence_object *fence,
13219+ int lazy, int interruptible, uint32_t mask)
13220+{
13221+ struct drm_device *dev = fence->dev;
13222+ struct drm_fence_class_manager *fc =
13223+ &dev->fm.fence_class[fence->fence_class];
13224+ int ret = 0;
13225+ unsigned long timeout = DRM_HZ *
13226+ ((fence->fence_class == PSB_ENGINE_TA) ? 30 : 3);
13227+
13228+ drm_fence_object_flush(fence, mask);
13229+ if (interruptible)
13230+ ret = wait_event_interruptible_timeout
13231+ (fc->fence_queue, drm_fence_object_signaled(fence, mask),
13232+ timeout);
13233+ else
13234+ ret = wait_event_timeout
13235+ (fc->fence_queue, drm_fence_object_signaled(fence, mask),
13236+ timeout);
13237+
13238+ if (unlikely(ret == -ERESTARTSYS))
13239+ return -EAGAIN;
13240+
13241+ if (unlikely(ret == 0))
13242+ return -EBUSY;
13243+
13244+ return 0;
13245+}
13246+
13247+struct drm_fence_driver psb_fence_driver = {
13248+ .num_classes = PSB_NUM_ENGINES,
13249+ .wrap_diff = (1 << 30),
13250+ .flush_diff = (1 << 29),
13251+ .sequence_mask = 0xFFFFFFFFU,
13252+ .has_irq = NULL,
13253+ .emit = psb_fence_emit_sequence,
13254+ .flush = NULL,
13255+ .poll = psb_fence_poll,
13256+ .needed_flush = NULL,
13257+ .wait = psb_fence_wait
13258+};
13259Index: linux-2.6.28/drivers/gpu/drm/psb/psb_gtt.c
13260===================================================================
13261--- /dev/null 1970-01-01 00:00:00.000000000 +0000
13262+++ linux-2.6.28/drivers/gpu/drm/psb/psb_gtt.c 2009-02-12 09:14:41.000000000 +0000
13263@@ -0,0 +1,233 @@
13264+/**************************************************************************
13265+ * Copyright (c) 2007, Intel Corporation.
13266+ * All Rights Reserved.
13267+ *
13268+ * This program is free software; you can redistribute it and/or modify it
13269+ * under the terms and conditions of the GNU General Public License,
13270+ * version 2, as published by the Free Software Foundation.
13271+ *
13272+ * This program is distributed in the hope it will be useful, but WITHOUT
13273+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13274+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13275+ * more details.
13276+ *
13277+ * You should have received a copy of the GNU General Public License along with
13278+ * this program; if not, write to the Free Software Foundation, Inc.,
13279+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
13280+ *
13281+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
13282+ * develop this driver.
13283+ *
13284+ **************************************************************************/
13285+/*
13286+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
13287+ */
13288+#include "drmP.h"
13289+#include "psb_drv.h"
13290+
13291+static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
13292+{
13293+ uint32_t mask = PSB_PTE_VALID;
13294+
13295+ if (type & PSB_MMU_CACHED_MEMORY)
13296+ mask |= PSB_PTE_CACHED;
13297+ if (type & PSB_MMU_RO_MEMORY)
13298+ mask |= PSB_PTE_RO;
13299+ if (type & PSB_MMU_WO_MEMORY)
13300+ mask |= PSB_PTE_WO;
13301+
13302+ return (pfn << PAGE_SHIFT) | mask;
13303+}
13304+
13305+struct psb_gtt *psb_gtt_alloc(struct drm_device *dev)
13306+{
13307+ struct psb_gtt *tmp = drm_calloc(1, sizeof(*tmp), DRM_MEM_DRIVER);
13308+
13309+ if (!tmp)
13310+ return NULL;
13311+
13312+ init_rwsem(&tmp->sem);
13313+ tmp->dev = dev;
13314+
13315+ return tmp;
13316+}
13317+
13318+void psb_gtt_takedown(struct psb_gtt *pg, int free)
13319+{
13320+ struct drm_psb_private *dev_priv = pg->dev->dev_private;
13321+
13322+ if (!pg)
13323+ return;
13324+
13325+ if (pg->gtt_map) {
13326+ iounmap(pg->gtt_map);
13327+ pg->gtt_map = NULL;
13328+ }
13329+ if (pg->initialized) {
13330+ pci_write_config_word(pg->dev->pdev, PSB_GMCH_CTRL,
13331+ pg->gmch_ctrl);
13332+ PSB_WVDC32(pg->pge_ctl, PSB_PGETBL_CTL);
13333+ (void)PSB_RVDC32(PSB_PGETBL_CTL);
13334+ }
13335+ if (free)
13336+ drm_free(pg, sizeof(*pg), DRM_MEM_DRIVER);
13337+}
13338+
13339+int psb_gtt_init(struct psb_gtt *pg, int resume)
13340+{
13341+ struct drm_device *dev = pg->dev;
13342+ struct drm_psb_private *dev_priv = dev->dev_private;
13343+ unsigned gtt_pages;
13344+ unsigned long stolen_size;
13345+ unsigned i, num_pages;
13346+ unsigned pfn_base;
13347+
13348+ int ret = 0;
13349+ uint32_t pte;
13350+
13351+ pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &pg->gmch_ctrl);
13352+ pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
13353+ pg->gmch_ctrl | _PSB_GMCH_ENABLED);
13354+
13355+ pg->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
13356+ PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
13357+ (void)PSB_RVDC32(PSB_PGETBL_CTL);
13358+
13359+ pg->initialized = 1;
13360+
13361+ pg->gtt_phys_start = pg->pge_ctl & PAGE_MASK;
13362+ pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
13363+ pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
13364+ gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT;
13365+ pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
13366+ >> PAGE_SHIFT;
13367+ pci_read_config_dword(dev->pdev, PSB_BSM, &pg->stolen_base);
13368+ stolen_size = pg->gtt_phys_start - pg->stolen_base - PAGE_SIZE;
13369+
13370+ PSB_DEBUG_INIT("GTT phys start: 0x%08x.\n", pg->gtt_phys_start);
13371+ PSB_DEBUG_INIT("GTT start: 0x%08x.\n", pg->gtt_start);
13372+ PSB_DEBUG_INIT("GATT start: 0x%08x.\n", pg->gatt_start);
13373+ PSB_DEBUG_INIT("GTT pages: %u\n", gtt_pages);
13374+ PSB_DEBUG_INIT("Stolen size: %lu kiB\n", stolen_size / 1024);
13375+
13376+ if (resume && (gtt_pages != pg->gtt_pages) &&
13377+ (stolen_size != pg->stolen_size)) {
13378+ DRM_ERROR("GTT resume error.\n");
13379+ ret = -EINVAL;
13380+ goto out_err;
13381+ }
13382+
13383+ pg->gtt_pages = gtt_pages;
13384+ pg->stolen_size = stolen_size;
13385+ pg->gtt_map =
13386+ ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
13387+ if (!pg->gtt_map) {
13388+ DRM_ERROR("Failure to map gtt.\n");
13389+ ret = -ENOMEM;
13390+ goto out_err;
13391+ }
13392+
13393+ /*
13394+ * insert stolen pages.
13395+ */
13396+
13397+ pfn_base = pg->stolen_base >> PAGE_SHIFT;
13398+ num_pages = stolen_size >> PAGE_SHIFT;
13399+ PSB_DEBUG_INIT("Set up %d stolen pages starting at 0x%08x\n",
13400+ num_pages, pfn_base);
13401+ for (i = 0; i < num_pages; ++i) {
13402+ pte = psb_gtt_mask_pte(pfn_base + i, 0);
13403+ iowrite32(pte, pg->gtt_map + i);
13404+ }
13405+
13406+ /*
13407+ * Init rest of gtt.
13408+ */
13409+
13410+ pfn_base = page_to_pfn(dev_priv->scratch_page);
13411+ pte = psb_gtt_mask_pte(pfn_base, 0);
13412+ PSB_DEBUG_INIT("Initializing the rest of a total "
13413+ "of %d gtt pages.\n", pg->gatt_pages);
13414+
13415+ for (; i < pg->gatt_pages; ++i)
13416+ iowrite32(pte, pg->gtt_map + i);
13417+ (void)ioread32(pg->gtt_map + i - 1);
13418+
13419+ return 0;
13420+
13421+ out_err:
13422+ psb_gtt_takedown(pg, 0);
13423+ return ret;
13424+}
13425+
13426+int psb_gtt_insert_pages(struct psb_gtt *pg, struct page **pages,
13427+ unsigned offset_pages, unsigned num_pages,
13428+ unsigned desired_tile_stride, unsigned hw_tile_stride,
13429+ int type)
13430+{
13431+ unsigned rows = 1;
13432+ unsigned add;
13433+ unsigned row_add;
13434+ unsigned i;
13435+ unsigned j;
13436+ uint32_t *cur_page = NULL;
13437+ uint32_t pte;
13438+
13439+ if (hw_tile_stride)
13440+ rows = num_pages / desired_tile_stride;
13441+ else
13442+ desired_tile_stride = num_pages;
13443+
13444+ add = desired_tile_stride;
13445+ row_add = hw_tile_stride;
13446+
13447+ down_read(&pg->sem);
13448+ for (i = 0; i < rows; ++i) {
13449+ cur_page = pg->gtt_map + offset_pages;
13450+ for (j = 0; j < desired_tile_stride; ++j) {
13451+ pte = psb_gtt_mask_pte(page_to_pfn(*pages++), type);
13452+ iowrite32(pte, cur_page++);
13453+ }
13454+ offset_pages += add;
13455+ }
13456+ (void)ioread32(cur_page - 1);
13457+ up_read(&pg->sem);
13458+
13459+ return 0;
13460+}
13461+
13462+int psb_gtt_remove_pages(struct psb_gtt *pg, unsigned offset_pages,
13463+ unsigned num_pages, unsigned desired_tile_stride,
13464+ unsigned hw_tile_stride)
13465+{
13466+ struct drm_psb_private *dev_priv = pg->dev->dev_private;
13467+ unsigned rows = 1;
13468+ unsigned add;
13469+ unsigned row_add;
13470+ unsigned i;
13471+ unsigned j;
13472+ uint32_t *cur_page = NULL;
13473+ unsigned pfn_base = page_to_pfn(dev_priv->scratch_page);
13474+ uint32_t pte = psb_gtt_mask_pte(pfn_base, 0);
13475+
13476+ if (hw_tile_stride)
13477+ rows = num_pages / desired_tile_stride;
13478+ else
13479+ desired_tile_stride = num_pages;
13480+
13481+ add = desired_tile_stride;
13482+ row_add = hw_tile_stride;
13483+
13484+ down_read(&pg->sem);
13485+ for (i = 0; i < rows; ++i) {
13486+ cur_page = pg->gtt_map + offset_pages;
13487+ for (j = 0; j < desired_tile_stride; ++j) {
13488+ iowrite32(pte, cur_page++);
13489+ }
13490+ offset_pages += add;
13491+ }
13492+ (void)ioread32(cur_page - 1);
13493+ up_read(&pg->sem);
13494+
13495+ return 0;
13496+}
13497Index: linux-2.6.28/drivers/gpu/drm/psb/psb_i2c.c
13498===================================================================
13499--- /dev/null 1970-01-01 00:00:00.000000000 +0000
13500+++ linux-2.6.28/drivers/gpu/drm/psb/psb_i2c.c 2009-02-12 09:14:41.000000000 +0000
13501@@ -0,0 +1,179 @@
13502+/*
13503+ * Copyright © 2006-2007 Intel Corporation
13504+ *
13505+ * Permission is hereby granted, free of charge, to any person obtaining a
13506+ * copy of this software and associated documentation files (the "Software"),
13507+ * to deal in the Software without restriction, including without limitation
13508+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13509+ * and/or sell copies of the Software, and to permit persons to whom the
13510+ * Software is furnished to do so, subject to the following conditions:
13511+ *
13512+ * The above copyright notice and this permission notice (including the next
13513+ * paragraph) shall be included in all copies or substantial portions of the
13514+ * Software.
13515+ *
13516+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13517+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13518+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
13519+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
13520+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
13521+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
13522+ * DEALINGS IN THE SOFTWARE.
13523+ *
13524+ * Authors:
13525+ * Eric Anholt <eric@anholt.net>
13526+ */
13527+/*
13528+ * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
13529+ * Jesse Barnes <jesse.barnes@intel.com>
13530+ */
13531+
13532+#include <linux/i2c.h>
13533+#include <linux/i2c-id.h>
13534+#include <linux/i2c-algo-bit.h>
13535+#include "drmP.h"
13536+#include "drm.h"
13537+#include "intel_drv.h"
13538+#include "psb_drv.h"
13539+
13540+/*
13541+ * Intel GPIO access functions
13542+ */
13543+
13544+#define I2C_RISEFALL_TIME 20
13545+
13546+static int get_clock(void *data)
13547+{
13548+ struct intel_i2c_chan *chan = data;
13549+ struct drm_psb_private *dev_priv = chan->drm_dev->dev_private;
13550+ uint32_t val;
13551+
13552+ val = PSB_RVDC32(chan->reg);
13553+ return ((val & GPIO_CLOCK_VAL_IN) != 0);
13554+}
13555+
13556+static int get_data(void *data)
13557+{
13558+ struct intel_i2c_chan *chan = data;
13559+ struct drm_psb_private *dev_priv = chan->drm_dev->dev_private;
13560+ uint32_t val;
13561+
13562+ val = PSB_RVDC32(chan->reg);
13563+ return ((val & GPIO_DATA_VAL_IN) != 0);
13564+}
13565+
13566+static void set_clock(void *data, int state_high)
13567+{
13568+ struct intel_i2c_chan *chan = data;
13569+ struct drm_psb_private *dev_priv = chan->drm_dev->dev_private;
13570+ uint32_t reserved = 0, clock_bits;
13571+
13572+ /* On most chips, these bits must be preserved in software. */
13573+ reserved = PSB_RVDC32(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
13574+ GPIO_CLOCK_PULLUP_DISABLE);
13575+
13576+ if (state_high)
13577+ clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
13578+ else
13579+ clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
13580+ GPIO_CLOCK_VAL_MASK;
13581+ PSB_WVDC32(reserved | clock_bits, chan->reg);
13582+ udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
13583+}
13584+
13585+static void set_data(void *data, int state_high)
13586+{
13587+ struct intel_i2c_chan *chan = data;
13588+ struct drm_psb_private *dev_priv = chan->drm_dev->dev_private;
13589+ uint32_t reserved = 0, data_bits;
13590+
13591+ /* On most chips, these bits must be preserved in software. */
13592+ reserved = PSB_RVDC32(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
13593+ GPIO_CLOCK_PULLUP_DISABLE);
13594+
13595+ if (state_high)
13596+ data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
13597+ else
13598+ data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
13599+ GPIO_DATA_VAL_MASK;
13600+
13601+ PSB_WVDC32(data_bits, chan->reg);
13602+ udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
13603+}
13604+
13605+/**
13606+ * intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
13607+ * @dev: DRM device
13608+ * @output: driver specific output device
13609+ * @reg: GPIO reg to use
13610+ * @name: name for this bus
13611+ *
13612+ * Creates and registers a new i2c bus with the Linux i2c layer, for use
13613+ * in output probing and control (e.g. DDC or SDVO control functions).
13614+ *
13615+ * Possible values for @reg include:
13616+ * %GPIOA
13617+ * %GPIOB
13618+ * %GPIOC
13619+ * %GPIOD
13620+ * %GPIOE
13621+ * %GPIOF
13622+ * %GPIOG
13623+ * %GPIOH
13624+ * see PRM for details on how these different busses are used.
13625+ */
13626+struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev,
13627+ const uint32_t reg, const char *name)
13628+{
13629+ struct intel_i2c_chan *chan;
13630+
13631+ chan = kzalloc(sizeof(struct intel_i2c_chan), GFP_KERNEL);
13632+ if (!chan)
13633+ goto out_free;
13634+
13635+ chan->drm_dev = dev;
13636+ chan->reg = reg;
13637+ snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name);
13638+ chan->adapter.owner = THIS_MODULE;
13639+ chan->adapter.id = I2C_HW_B_INTELFB;
13640+ chan->adapter.algo_data = &chan->algo;
13641+ chan->adapter.dev.parent = &dev->pdev->dev;
13642+ chan->algo.setsda = set_data;
13643+ chan->algo.setscl = set_clock;
13644+ chan->algo.getsda = get_data;
13645+ chan->algo.getscl = get_clock;
13646+ chan->algo.udelay = 20;
13647+ chan->algo.timeout = usecs_to_jiffies(2200);
13648+ chan->algo.data = chan;
13649+
13650+ i2c_set_adapdata(&chan->adapter, chan);
13651+
13652+ if (i2c_bit_add_bus(&chan->adapter))
13653+ goto out_free;
13654+
13655+ /* JJJ: raise SCL and SDA? */
13656+ set_data(chan, 1);
13657+ set_clock(chan, 1);
13658+ udelay(20);
13659+
13660+ return chan;
13661+
13662+ out_free:
13663+ kfree(chan);
13664+ return NULL;
13665+}
13666+
13667+/**
13668+ * intel_i2c_destroy - unregister and free i2c bus resources
13669+ * @output: channel to free
13670+ *
13671+ * Unregister the adapter from the i2c layer, then free the structure.
13672+ */
13673+void intel_i2c_destroy(struct intel_i2c_chan *chan)
13674+{
13675+ if (!chan)
13676+ return;
13677+
13678+ i2c_del_adapter(&chan->adapter);
13679+ kfree(chan);
13680+}
13681Index: linux-2.6.28/drivers/gpu/drm/psb/psb_irq.c
13682===================================================================
13683--- /dev/null 1970-01-01 00:00:00.000000000 +0000
13684+++ linux-2.6.28/drivers/gpu/drm/psb/psb_irq.c 2009-02-12 09:14:41.000000000 +0000
13685@@ -0,0 +1,382 @@
13686+/**************************************************************************
13687+ * Copyright (c) 2007, Intel Corporation.
13688+ * All Rights Reserved.
13689+ *
13690+ * This program is free software; you can redistribute it and/or modify it
13691+ * under the terms and conditions of the GNU General Public License,
13692+ * version 2, as published by the Free Software Foundation.
13693+ *
13694+ * This program is distributed in the hope it will be useful, but WITHOUT
13695+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13696+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13697+ * more details.
13698+ *
13699+ * You should have received a copy of the GNU General Public License along with
13700+ * this program; if not, write to the Free Software Foundation, Inc.,
13701+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
13702+ *
13703+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
13704+ * develop this driver.
13705+ *
13706+ **************************************************************************/
13707+/*
13708+ */
13709+
13710+#include "drmP.h"
13711+#include "psb_drv.h"
13712+#include "psb_reg.h"
13713+#include "psb_msvdx.h"
13714+
13715+/*
13716+ * Video display controller interrupt.
13717+ */
13718+
13719+static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)
13720+{
13721+ struct drm_psb_private *dev_priv =
13722+ (struct drm_psb_private *)dev->dev_private;
13723+ uint32_t pipe_stats;
13724+ int wake = 0;
13725+
13726+ if (!drm_psb_disable_vsync && (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)) {
13727+ pipe_stats = PSB_RVDC32(PSB_PIPEASTAT);
13728+ atomic_inc(&dev->vbl_received);
13729+ wake = 1;
13730+ PSB_WVDC32(pipe_stats | _PSB_VBLANK_INTERRUPT_ENABLE |
13731+ _PSB_VBLANK_CLEAR, PSB_PIPEASTAT);
13732+ }
13733+
13734+ if (!drm_psb_disable_vsync && (vdc_stat & _PSB_VSYNC_PIPEB_FLAG)) {
13735+ pipe_stats = PSB_RVDC32(PSB_PIPEBSTAT);
13736+ atomic_inc(&dev->vbl_received2);
13737+ wake = 1;
13738+ PSB_WVDC32(pipe_stats | _PSB_VBLANK_INTERRUPT_ENABLE |
13739+ _PSB_VBLANK_CLEAR, PSB_PIPEBSTAT);
13740+ }
13741+
13742+ PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R);
13743+ (void)PSB_RVDC32(PSB_INT_IDENTITY_R);
13744+ DRM_READMEMORYBARRIER();
13745+
13746+ if (wake) {
13747+ DRM_WAKEUP(&dev->vbl_queue);
13748+ drm_vbl_send_signals(dev);
13749+ }
13750+}
13751+
13752+/*
13753+ * SGX interrupt source 1.
13754+ */
13755+
13756+static void psb_sgx_interrupt(struct drm_device *dev, uint32_t sgx_stat,
13757+ uint32_t sgx_stat2)
13758+{
13759+ struct drm_psb_private *dev_priv =
13760+ (struct drm_psb_private *)dev->dev_private;
13761+
13762+ if (sgx_stat & _PSB_CE_TWOD_COMPLETE) {
13763+ DRM_WAKEUP(&dev_priv->event_2d_queue);
13764+ psb_fence_handler(dev, 0);
13765+ }
13766+
13767+ if (unlikely(sgx_stat2 & _PSB_CE2_BIF_REQUESTER_FAULT))
13768+ psb_print_pagefault(dev_priv);
13769+
13770+ psb_scheduler_handler(dev_priv, sgx_stat);
13771+}
13772+
13773+/*
13774+ * MSVDX interrupt.
13775+ */
13776+static void psb_msvdx_interrupt(struct drm_device *dev, uint32_t msvdx_stat)
13777+{
13778+ struct drm_psb_private *dev_priv =
13779+ (struct drm_psb_private *)dev->dev_private;
13780+
13781+ if (msvdx_stat & MSVDX_INTERRUPT_STATUS_CR_MMU_FAULT_IRQ_MASK) {
13782+ /*Ideally we should we should never get to this */
13783+ PSB_DEBUG_GENERAL
13784+ ("******MSVDX: msvdx_stat: 0x%x fence2_irq_on=%d ***** (MMU FAULT)\n",
13785+ msvdx_stat, dev_priv->fence2_irq_on);
13786+
13787+ /* Pause MMU */
13788+ PSB_WMSVDX32(MSVDX_MMU_CONTROL0_CR_MMU_PAUSE_MASK,
13789+ MSVDX_MMU_CONTROL0);
13790+ DRM_WRITEMEMORYBARRIER();
13791+
13792+ /* Clear this interupt bit only */
13793+ PSB_WMSVDX32(MSVDX_INTERRUPT_STATUS_CR_MMU_FAULT_IRQ_MASK,
13794+ MSVDX_INTERRUPT_CLEAR);
13795+ PSB_RMSVDX32(MSVDX_INTERRUPT_CLEAR);
13796+ DRM_READMEMORYBARRIER();
13797+
13798+ dev_priv->msvdx_needs_reset = 1;
13799+ } else if (msvdx_stat & MSVDX_INTERRUPT_STATUS_CR_MTX_IRQ_MASK) {
13800+ PSB_DEBUG_GENERAL
13801+ ("******MSVDX: msvdx_stat: 0x%x fence2_irq_on=%d ***** (MTX)\n",
13802+ msvdx_stat, dev_priv->fence2_irq_on);
13803+
13804+ /* Clear all interupt bits */
13805+ PSB_WMSVDX32(0xffff, MSVDX_INTERRUPT_CLEAR);
13806+ PSB_RMSVDX32(MSVDX_INTERRUPT_CLEAR);
13807+ DRM_READMEMORYBARRIER();
13808+
13809+ psb_msvdx_mtx_interrupt(dev);
13810+ }
13811+}
13812+
13813+irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
13814+{
13815+ struct drm_device *dev = (struct drm_device *)arg;
13816+ struct drm_psb_private *dev_priv =
13817+ (struct drm_psb_private *)dev->dev_private;
13818+
13819+ uint32_t vdc_stat;
13820+ uint32_t sgx_stat;
13821+ uint32_t sgx_stat2;
13822+ uint32_t msvdx_stat;
13823+ int handled = 0;
13824+
13825+ spin_lock(&dev_priv->irqmask_lock);
13826+
13827+ vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R);
13828+ sgx_stat = PSB_RSGX32(PSB_CR_EVENT_STATUS);
13829+ sgx_stat2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2);
13830+ msvdx_stat = PSB_RMSVDX32(MSVDX_INTERRUPT_STATUS);
13831+
13832+ sgx_stat2 &= dev_priv->sgx2_irq_mask;
13833+ sgx_stat &= dev_priv->sgx_irq_mask;
13834+ PSB_WSGX32(sgx_stat2, PSB_CR_EVENT_HOST_CLEAR2);
13835+ PSB_WSGX32(sgx_stat, PSB_CR_EVENT_HOST_CLEAR);
13836+ (void)PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR);
13837+
13838+ vdc_stat &= dev_priv->vdc_irq_mask;
13839+ spin_unlock(&dev_priv->irqmask_lock);
13840+
13841+ if (msvdx_stat) {
13842+ psb_msvdx_interrupt(dev, msvdx_stat);
13843+ handled = 1;
13844+ }
13845+
13846+ if (vdc_stat) {
13847+ /* MSVDX IRQ status is part of vdc_irq_mask */
13848+ psb_vdc_interrupt(dev, vdc_stat);
13849+ handled = 1;
13850+ }
13851+
13852+ if (sgx_stat || sgx_stat2) {
13853+ psb_sgx_interrupt(dev, sgx_stat, sgx_stat2);
13854+ handled = 1;
13855+ }
13856+
13857+ if (!handled) {
13858+ return IRQ_NONE;
13859+ }
13860+
13861+ return IRQ_HANDLED;
13862+}
13863+
13864+void psb_msvdx_irq_preinstall(struct drm_psb_private *dev_priv)
13865+{
13866+ unsigned long mtx_int = 0;
13867+ dev_priv->vdc_irq_mask |= _PSB_IRQ_MSVDX_FLAG;
13868+
13869+ /*Clear MTX interrupt */
13870+ REGIO_WRITE_FIELD_LITE(mtx_int, MSVDX_INTERRUPT_STATUS, CR_MTX_IRQ, 1);
13871+ PSB_WMSVDX32(mtx_int, MSVDX_INTERRUPT_CLEAR);
13872+}
13873+
13874+void psb_irq_preinstall(struct drm_device *dev)
13875+{
13876+ struct drm_psb_private *dev_priv =
13877+ (struct drm_psb_private *)dev->dev_private;
13878+ spin_lock(&dev_priv->irqmask_lock);
13879+ PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
13880+ PSB_WVDC32(0x00000000, PSB_INT_MASK_R);
13881+ PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R);
13882+ PSB_WSGX32(0x00000000, PSB_CR_EVENT_HOST_ENABLE);
13883+ (void)PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE);
13884+
13885+ dev_priv->sgx_irq_mask = _PSB_CE_PIXELBE_END_RENDER |
13886+ _PSB_CE_DPM_3D_MEM_FREE |
13887+ _PSB_CE_TA_FINISHED |
13888+ _PSB_CE_DPM_REACHED_MEM_THRESH |
13889+ _PSB_CE_DPM_OUT_OF_MEMORY_GBL |
13890+ _PSB_CE_DPM_OUT_OF_MEMORY_MT |
13891+ _PSB_CE_TA_TERMINATE | _PSB_CE_SW_EVENT;
13892+
13893+ dev_priv->sgx2_irq_mask = _PSB_CE2_BIF_REQUESTER_FAULT;
13894+
13895+ dev_priv->vdc_irq_mask = _PSB_IRQ_SGX_FLAG | _PSB_IRQ_MSVDX_FLAG;
13896+
13897+ if (!drm_psb_disable_vsync)
13898+ dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG |
13899+ _PSB_VSYNC_PIPEB_FLAG;
13900+
13901+ /*Clear MTX interrupt */
13902+ {
13903+ unsigned long mtx_int = 0;
13904+ REGIO_WRITE_FIELD_LITE(mtx_int, MSVDX_INTERRUPT_STATUS,
13905+ CR_MTX_IRQ, 1);
13906+ PSB_WMSVDX32(mtx_int, MSVDX_INTERRUPT_CLEAR);
13907+ }
13908+ spin_unlock(&dev_priv->irqmask_lock);
13909+}
13910+
13911+void psb_msvdx_irq_postinstall(struct drm_psb_private *dev_priv)
13912+{
13913+ /* Enable Mtx Interupt to host */
13914+ unsigned long enables = 0;
13915+ PSB_DEBUG_GENERAL("Setting up MSVDX IRQs.....\n");
13916+ REGIO_WRITE_FIELD_LITE(enables, MSVDX_INTERRUPT_STATUS, CR_MTX_IRQ, 1);
13917+ PSB_WMSVDX32(enables, MSVDX_HOST_INTERRUPT_ENABLE);
13918+}
13919+
13920+int psb_irq_postinstall(struct drm_device *dev)
13921+{
13922+ struct drm_psb_private *dev_priv =
13923+ (struct drm_psb_private *)dev->dev_private;
13924+ unsigned long irqflags;
13925+
13926+ spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
13927+ PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
13928+ PSB_WSGX32(dev_priv->sgx2_irq_mask, PSB_CR_EVENT_HOST_ENABLE2);
13929+ PSB_WSGX32(dev_priv->sgx_irq_mask, PSB_CR_EVENT_HOST_ENABLE);
13930+ (void)PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE);
13931+ /****MSVDX IRQ Setup...*****/
13932+ /* Enable Mtx Interupt to host */
13933+ {
13934+ unsigned long enables = 0;
13935+ PSB_DEBUG_GENERAL("Setting up MSVDX IRQs.....\n");
13936+ REGIO_WRITE_FIELD_LITE(enables, MSVDX_INTERRUPT_STATUS,
13937+ CR_MTX_IRQ, 1);
13938+ PSB_WMSVDX32(enables, MSVDX_HOST_INTERRUPT_ENABLE);
13939+ }
13940+ dev_priv->irq_enabled = 1;
13941+ spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
13942+ return 0;
13943+}
13944+
13945+void psb_irq_uninstall(struct drm_device *dev)
13946+{
13947+ struct drm_psb_private *dev_priv =
13948+ (struct drm_psb_private *)dev->dev_private;
13949+ unsigned long irqflags;
13950+
13951+ spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
13952+
13953+ dev_priv->sgx_irq_mask = 0x00000000;
13954+ dev_priv->sgx2_irq_mask = 0x00000000;
13955+ dev_priv->vdc_irq_mask = 0x00000000;
13956+
13957+ PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
13958+ PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
13959+ PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
13960+ PSB_WSGX32(dev_priv->sgx_irq_mask, PSB_CR_EVENT_HOST_ENABLE);
13961+ PSB_WSGX32(dev_priv->sgx2_irq_mask, PSB_CR_EVENT_HOST_ENABLE2);
13962+ wmb();
13963+ PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);
13964+ PSB_WSGX32(PSB_RSGX32(PSB_CR_EVENT_STATUS), PSB_CR_EVENT_HOST_CLEAR);
13965+ PSB_WSGX32(PSB_RSGX32(PSB_CR_EVENT_STATUS2), PSB_CR_EVENT_HOST_CLEAR2);
13966+
13967+ /****MSVDX IRQ Setup...*****/
13968+ /* Clear interrupt enabled flag */
13969+ PSB_WMSVDX32(0, MSVDX_HOST_INTERRUPT_ENABLE);
13970+
13971+ dev_priv->irq_enabled = 0;
13972+ spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
13973+
13974+}
13975+
13976+void psb_2D_irq_off(struct drm_psb_private *dev_priv)
13977+{
13978+ unsigned long irqflags;
13979+ uint32_t old_mask;
13980+ uint32_t cleared_mask;
13981+
13982+ spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
13983+ --dev_priv->irqen_count_2d;
13984+ if (dev_priv->irq_enabled && dev_priv->irqen_count_2d == 0) {
13985+
13986+ old_mask = dev_priv->sgx_irq_mask;
13987+ dev_priv->sgx_irq_mask &= ~_PSB_CE_TWOD_COMPLETE;
13988+ PSB_WSGX32(dev_priv->sgx_irq_mask, PSB_CR_EVENT_HOST_ENABLE);
13989+ (void)PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE);
13990+
13991+ cleared_mask = (old_mask ^ dev_priv->sgx_irq_mask) & old_mask;
13992+ PSB_WSGX32(cleared_mask, PSB_CR_EVENT_HOST_CLEAR);
13993+ (void)PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR);
13994+ }
13995+ spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
13996+}
13997+
13998+void psb_2D_irq_on(struct drm_psb_private *dev_priv)
13999+{
14000+ unsigned long irqflags;
14001+
14002+ spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
14003+ if (dev_priv->irq_enabled && dev_priv->irqen_count_2d == 0) {
14004+ dev_priv->sgx_irq_mask |= _PSB_CE_TWOD_COMPLETE;
14005+ PSB_WSGX32(dev_priv->sgx_irq_mask, PSB_CR_EVENT_HOST_ENABLE);
14006+ (void)PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE);
14007+ }
14008+ ++dev_priv->irqen_count_2d;
14009+ spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
14010+}
14011+
14012+static int psb_vblank_do_wait(struct drm_device *dev, unsigned int *sequence,
14013+ atomic_t * counter)
14014+{
14015+ unsigned int cur_vblank;
14016+ int ret = 0;
14017+
14018+ DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
14019+ (((cur_vblank = atomic_read(counter))
14020+ - *sequence) <= (1 << 23)));
14021+
14022+ *sequence = cur_vblank;
14023+
14024+ return ret;
14025+}
14026+
14027+int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence)
14028+{
14029+ int ret;
14030+
14031+ ret = psb_vblank_do_wait(dev, sequence, &dev->vbl_received);
14032+ return ret;
14033+}
14034+
14035+int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
14036+{
14037+ int ret;
14038+
14039+ ret = psb_vblank_do_wait(dev, sequence, &dev->vbl_received2);
14040+ return ret;
14041+}
14042+
14043+void psb_msvdx_irq_off(struct drm_psb_private *dev_priv)
14044+{
14045+ unsigned long irqflags;
14046+
14047+ spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
14048+ if (dev_priv->irq_enabled) {
14049+ dev_priv->vdc_irq_mask &= ~_PSB_IRQ_MSVDX_FLAG;
14050+ PSB_WSGX32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
14051+ (void)PSB_RSGX32(PSB_INT_ENABLE_R);
14052+ }
14053+ spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
14054+}
14055+
14056+void psb_msvdx_irq_on(struct drm_psb_private *dev_priv)
14057+{
14058+ unsigned long irqflags;
14059+
14060+ spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
14061+ if (dev_priv->irq_enabled) {
14062+ dev_priv->vdc_irq_mask |= _PSB_IRQ_MSVDX_FLAG;
14063+ PSB_WSGX32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
14064+ (void)PSB_RSGX32(PSB_INT_ENABLE_R);
14065+ }
14066+ spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
14067+}
14068Index: linux-2.6.28/drivers/gpu/drm/psb/psb_mmu.c
14069===================================================================
14070--- /dev/null 1970-01-01 00:00:00.000000000 +0000
14071+++ linux-2.6.28/drivers/gpu/drm/psb/psb_mmu.c 2009-02-12 09:14:42.000000000 +0000
14072@@ -0,0 +1,1037 @@
14073+/**************************************************************************
14074+ * Copyright (c) 2007, Intel Corporation.
14075+ * All Rights Reserved.
14076+ *
14077+ * This program is free software; you can redistribute it and/or modify it
14078+ * under the terms and conditions of the GNU General Public License,
14079+ * version 2, as published by the Free Software Foundation.
14080+ *
14081+ * This program is distributed in the hope it will be useful, but WITHOUT
14082+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14083+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14084+ * more details.
14085+ *
14086+ * You should have received a copy of the GNU General Public License along with
14087+ * this program; if not, write to the Free Software Foundation, Inc.,
14088+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
14089+ *
14090+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
14091+ * develop this driver.
14092+ *
14093+ **************************************************************************/
14094+#include "drmP.h"
14095+#include "psb_drv.h"
14096+#include "psb_reg.h"
14097+
14098+/*
14099+ * Code for the SGX MMU:
14100+ */
14101+
14102+/*
14103+ * clflush on one processor only:
14104+ * clflush should apparently flush the cache line on all processors in an
14105+ * SMP system.
14106+ */
14107+
14108+/*
14109+ * kmap atomic:
14110+ * The usage of the slots must be completely encapsulated within a spinlock, and
14111+ * no other functions that may be using the locks for other purposed may be
14112+ * called from within the locked region.
14113+ * Since the slots are per processor, this will guarantee that we are the only
14114+ * user.
14115+ */
14116+
14117+/*
14118+ * TODO: Inserting ptes from an interrupt handler:
14119+ * This may be desirable for some SGX functionality where the GPU can fault in
14120+ * needed pages. For that, we need to make an atomic insert_pages function, that
14121+ * may fail.
14122+ * If it fails, the caller need to insert the page using a workqueue function,
14123+ * but on average it should be fast.
14124+ */
14125+
14126+struct psb_mmu_driver {
14127+ /* protects driver- and pd structures. Always take in read mode
14128+ * before taking the page table spinlock.
14129+ */
14130+ struct rw_semaphore sem;
14131+
14132+ /* protects page tables, directory tables and pt tables.
14133+ * and pt structures.
14134+ */
14135+ spinlock_t lock;
14136+
14137+ atomic_t needs_tlbflush;
14138+ atomic_t *msvdx_mmu_invaldc;
14139+ uint8_t __iomem *register_map;
14140+ struct psb_mmu_pd *default_pd;
14141+ uint32_t bif_ctrl;
14142+ int has_clflush;
14143+ int clflush_add;
14144+ unsigned long clflush_mask;
14145+};
14146+
14147+struct psb_mmu_pd;
14148+
14149+struct psb_mmu_pt {
14150+ struct psb_mmu_pd *pd;
14151+ uint32_t index;
14152+ uint32_t count;
14153+ struct page *p;
14154+ uint32_t *v;
14155+};
14156+
14157+struct psb_mmu_pd {
14158+ struct psb_mmu_driver *driver;
14159+ int hw_context;
14160+ struct psb_mmu_pt **tables;
14161+ struct page *p;
14162+ struct page *dummy_pt;
14163+ struct page *dummy_page;
14164+ uint32_t pd_mask;
14165+ uint32_t invalid_pde;
14166+ uint32_t invalid_pte;
14167+};
14168+
14169+static inline uint32_t psb_mmu_pt_index(uint32_t offset)
14170+{
14171+ return (offset >> PSB_PTE_SHIFT) & 0x3FF;
14172+}
14173+static inline uint32_t psb_mmu_pd_index(uint32_t offset)
14174+{
14175+ return (offset >> PSB_PDE_SHIFT);
14176+}
14177+
14178+#if defined(CONFIG_X86)
14179+static inline void psb_clflush(void *addr)
14180+{
14181+ __asm__ __volatile__("clflush (%0)\n"::"r"(addr):"memory");
14182+}
14183+
14184+static inline void psb_mmu_clflush(struct psb_mmu_driver *driver, void *addr)
14185+{
14186+ if (!driver->has_clflush)
14187+ return;
14188+
14189+ mb();
14190+ psb_clflush(addr);
14191+ mb();
14192+}
14193+#else
14194+
14195+static inline void psb_mmu_clflush(struct psb_mmu_driver *driver, void *addr)
14196+{;
14197+}
14198+
14199+#endif
14200+
14201+static inline void psb_iowrite32(const struct psb_mmu_driver *d,
14202+ uint32_t val, uint32_t offset)
14203+{
14204+ iowrite32(val, d->register_map + offset);
14205+}
14206+
14207+static inline uint32_t psb_ioread32(const struct psb_mmu_driver *d,
14208+ uint32_t offset)
14209+{
14210+ return ioread32(d->register_map + offset);
14211+}
14212+
14213+static void psb_mmu_flush_pd_locked(struct psb_mmu_driver *driver, int force)
14214+{
14215+ if (atomic_read(&driver->needs_tlbflush) || force) {
14216+ uint32_t val = psb_ioread32(driver, PSB_CR_BIF_CTRL);
14217+ psb_iowrite32(driver, val | _PSB_CB_CTRL_INVALDC,
14218+ PSB_CR_BIF_CTRL);
14219+ wmb();
14220+ psb_iowrite32(driver, val & ~_PSB_CB_CTRL_INVALDC,
14221+ PSB_CR_BIF_CTRL);
14222+ (void)psb_ioread32(driver, PSB_CR_BIF_CTRL);
14223+ if (driver->msvdx_mmu_invaldc)
14224+ atomic_set(driver->msvdx_mmu_invaldc, 1);
14225+ }
14226+ atomic_set(&driver->needs_tlbflush, 0);
14227+}
14228+
14229+static void psb_mmu_flush_pd(struct psb_mmu_driver *driver, int force)
14230+{
14231+ down_write(&driver->sem);
14232+ psb_mmu_flush_pd_locked(driver, force);
14233+ up_write(&driver->sem);
14234+}
14235+
14236+void psb_mmu_flush(struct psb_mmu_driver *driver)
14237+{
14238+ uint32_t val;
14239+
14240+ down_write(&driver->sem);
14241+ val = psb_ioread32(driver, PSB_CR_BIF_CTRL);
14242+ if (atomic_read(&driver->needs_tlbflush))
14243+ psb_iowrite32(driver, val | _PSB_CB_CTRL_INVALDC,
14244+ PSB_CR_BIF_CTRL);
14245+ else
14246+ psb_iowrite32(driver, val | _PSB_CB_CTRL_FLUSH,
14247+ PSB_CR_BIF_CTRL);
14248+ wmb();
14249+ psb_iowrite32(driver,
14250+ val & ~(_PSB_CB_CTRL_FLUSH | _PSB_CB_CTRL_INVALDC),
14251+ PSB_CR_BIF_CTRL);
14252+ (void)psb_ioread32(driver, PSB_CR_BIF_CTRL);
14253+ atomic_set(&driver->needs_tlbflush, 0);
14254+ if (driver->msvdx_mmu_invaldc)
14255+ atomic_set(driver->msvdx_mmu_invaldc, 1);
14256+ up_write(&driver->sem);
14257+}
14258+
14259+void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context)
14260+{
14261+ uint32_t offset = (hw_context == 0) ? PSB_CR_BIF_DIR_LIST_BASE0 :
14262+ PSB_CR_BIF_DIR_LIST_BASE1 + hw_context * 4;
14263+
14264+ drm_ttm_cache_flush();
14265+ down_write(&pd->driver->sem);
14266+ psb_iowrite32(pd->driver, (page_to_pfn(pd->p) << PAGE_SHIFT), offset);
14267+ wmb();
14268+ psb_mmu_flush_pd_locked(pd->driver, 1);
14269+ pd->hw_context = hw_context;
14270+ up_write(&pd->driver->sem);
14271+
14272+}
14273+
14274+static inline unsigned long psb_pd_addr_end(unsigned long addr,
14275+ unsigned long end)
14276+{
14277+
14278+ addr = (addr + PSB_PDE_MASK + 1) & ~PSB_PDE_MASK;
14279+ return (addr < end) ? addr : end;
14280+}
14281+
14282+static inline uint32_t psb_mmu_mask_pte(uint32_t pfn, int type)
14283+{
14284+ uint32_t mask = PSB_PTE_VALID;
14285+
14286+ if (type & PSB_MMU_CACHED_MEMORY)
14287+ mask |= PSB_PTE_CACHED;
14288+ if (type & PSB_MMU_RO_MEMORY)
14289+ mask |= PSB_PTE_RO;
14290+ if (type & PSB_MMU_WO_MEMORY)
14291+ mask |= PSB_PTE_WO;
14292+
14293+ return (pfn << PAGE_SHIFT) | mask;
14294+}
14295+
14296+struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver,
14297+ int trap_pagefaults, int invalid_type)
14298+{
14299+ struct psb_mmu_pd *pd = kmalloc(sizeof(*pd), GFP_KERNEL);
14300+ uint32_t *v;
14301+ int i;
14302+
14303+ if (!pd)
14304+ return NULL;
14305+
14306+ pd->p = alloc_page(GFP_DMA32);
14307+ if (!pd->p)
14308+ goto out_err1;
14309+ pd->dummy_pt = alloc_page(GFP_DMA32);
14310+ if (!pd->dummy_pt)
14311+ goto out_err2;
14312+ pd->dummy_page = alloc_page(GFP_DMA32);
14313+ if (!pd->dummy_page)
14314+ goto out_err3;
14315+
14316+ if (!trap_pagefaults) {
14317+ pd->invalid_pde = psb_mmu_mask_pte(page_to_pfn(pd->dummy_pt),
14318+ invalid_type |
14319+ PSB_MMU_CACHED_MEMORY);
14320+ pd->invalid_pte = psb_mmu_mask_pte(page_to_pfn(pd->dummy_page),
14321+ invalid_type |
14322+ PSB_MMU_CACHED_MEMORY);
14323+ } else {
14324+ pd->invalid_pde = 0;
14325+ pd->invalid_pte = 0;
14326+ }
14327+
14328+ v = kmap(pd->dummy_pt);
14329+ for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) {
14330+ v[i] = pd->invalid_pte;
14331+ }
14332+ kunmap(pd->dummy_pt);
14333+
14334+ v = kmap(pd->p);
14335+ for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) {
14336+ v[i] = pd->invalid_pde;
14337+ }
14338+ kunmap(pd->p);
14339+
14340+ clear_page(kmap(pd->dummy_page));
14341+ kunmap(pd->dummy_page);
14342+
14343+ pd->tables = vmalloc_user(sizeof(struct psb_mmu_pt *) * 1024);
14344+ if (!pd->tables)
14345+ goto out_err4;
14346+
14347+ pd->hw_context = -1;
14348+ pd->pd_mask = PSB_PTE_VALID;
14349+ pd->driver = driver;
14350+
14351+ return pd;
14352+
14353+ out_err4:
14354+ __free_page(pd->dummy_page);
14355+ out_err3:
14356+ __free_page(pd->dummy_pt);
14357+ out_err2:
14358+ __free_page(pd->p);
14359+ out_err1:
14360+ kfree(pd);
14361+ return NULL;
14362+}
14363+
14364+void psb_mmu_free_pt(struct psb_mmu_pt *pt)
14365+{
14366+ __free_page(pt->p);
14367+ kfree(pt);
14368+}
14369+
14370+void psb_mmu_free_pagedir(struct psb_mmu_pd *pd)
14371+{
14372+ struct psb_mmu_driver *driver = pd->driver;
14373+ struct psb_mmu_pt *pt;
14374+ int i;
14375+
14376+ down_write(&driver->sem);
14377+ if (pd->hw_context != -1) {
14378+ psb_iowrite32(driver, 0,
14379+ PSB_CR_BIF_DIR_LIST_BASE0 + pd->hw_context * 4);
14380+ psb_mmu_flush_pd_locked(driver, 1);
14381+ }
14382+
14383+ /* Should take the spinlock here, but we don't need to do that
14384+ since we have the semaphore in write mode. */
14385+
14386+ for (i = 0; i < 1024; ++i) {
14387+ pt = pd->tables[i];
14388+ if (pt)
14389+ psb_mmu_free_pt(pt);
14390+ }
14391+
14392+ vfree(pd->tables);
14393+ __free_page(pd->dummy_page);
14394+ __free_page(pd->dummy_pt);
14395+ __free_page(pd->p);
14396+ kfree(pd);
14397+ up_write(&driver->sem);
14398+}
14399+
14400+static struct psb_mmu_pt *psb_mmu_alloc_pt(struct psb_mmu_pd *pd)
14401+{
14402+ struct psb_mmu_pt *pt = kmalloc(sizeof(*pt), GFP_KERNEL);
14403+ void *v;
14404+ uint32_t clflush_add = pd->driver->clflush_add >> PAGE_SHIFT;
14405+ uint32_t clflush_count = PAGE_SIZE / clflush_add;
14406+ spinlock_t *lock = &pd->driver->lock;
14407+ uint8_t *clf;
14408+ uint32_t *ptes;
14409+ int i;
14410+
14411+ if (!pt)
14412+ return NULL;
14413+
14414+ pt->p = alloc_page(GFP_DMA32);
14415+ if (!pt->p) {
14416+ kfree(pt);
14417+ return NULL;
14418+ }
14419+
14420+ spin_lock(lock);
14421+
14422+ v = kmap_atomic(pt->p, KM_USER0);
14423+ clf = (uint8_t *) v;
14424+ ptes = (uint32_t *) v;
14425+ for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) {
14426+ *ptes++ = pd->invalid_pte;
14427+ }
14428+
14429+#if defined(CONFIG_X86)
14430+ if (pd->driver->has_clflush && pd->hw_context != -1) {
14431+ mb();
14432+ for (i = 0; i < clflush_count; ++i) {
14433+ psb_clflush(clf);
14434+ clf += clflush_add;
14435+ }
14436+ mb();
14437+ }
14438+#endif
14439+ kunmap_atomic(v, KM_USER0);
14440+ spin_unlock(lock);
14441+
14442+ pt->count = 0;
14443+ pt->pd = pd;
14444+ pt->index = 0;
14445+
14446+ return pt;
14447+}
14448+
14449+struct psb_mmu_pt *psb_mmu_pt_alloc_map_lock(struct psb_mmu_pd *pd,
14450+ unsigned long addr)
14451+{
14452+ uint32_t index = psb_mmu_pd_index(addr);
14453+ struct psb_mmu_pt *pt;
14454+ volatile uint32_t *v;
14455+ spinlock_t *lock = &pd->driver->lock;
14456+
14457+ spin_lock(lock);
14458+ pt = pd->tables[index];
14459+ while (!pt) {
14460+ spin_unlock(lock);
14461+ pt = psb_mmu_alloc_pt(pd);
14462+ if (!pt)
14463+ return NULL;
14464+ spin_lock(lock);
14465+
14466+ if (pd->tables[index]) {
14467+ spin_unlock(lock);
14468+ psb_mmu_free_pt(pt);
14469+ spin_lock(lock);
14470+ pt = pd->tables[index];
14471+ continue;
14472+ }
14473+
14474+ v = kmap_atomic(pd->p, KM_USER0);
14475+ pd->tables[index] = pt;
14476+ v[index] = (page_to_pfn(pt->p) << 12) | pd->pd_mask;
14477+ pt->index = index;
14478+ kunmap_atomic((void *)v, KM_USER0);
14479+
14480+ if (pd->hw_context != -1) {
14481+ psb_mmu_clflush(pd->driver, (void *)&v[index]);
14482+ atomic_set(&pd->driver->needs_tlbflush, 1);
14483+ }
14484+ }
14485+ pt->v = kmap_atomic(pt->p, KM_USER0);
14486+ return pt;
14487+}
14488+
14489+static struct psb_mmu_pt *psb_mmu_pt_map_lock(struct psb_mmu_pd *pd,
14490+ unsigned long addr)
14491+{
14492+ uint32_t index = psb_mmu_pd_index(addr);
14493+ struct psb_mmu_pt *pt;
14494+ spinlock_t *lock = &pd->driver->lock;
14495+
14496+ spin_lock(lock);
14497+ pt = pd->tables[index];
14498+ if (!pt) {
14499+ spin_unlock(lock);
14500+ return NULL;
14501+ }
14502+ pt->v = kmap_atomic(pt->p, KM_USER0);
14503+ return pt;
14504+}
14505+
14506+static void psb_mmu_pt_unmap_unlock(struct psb_mmu_pt *pt)
14507+{
14508+ struct psb_mmu_pd *pd = pt->pd;
14509+ volatile uint32_t *v;
14510+
14511+ kunmap_atomic(pt->v, KM_USER0);
14512+ if (pt->count == 0) {
14513+ v = kmap_atomic(pd->p, KM_USER0);
14514+ v[pt->index] = pd->invalid_pde;
14515+ pd->tables[pt->index] = NULL;
14516+
14517+ if (pd->hw_context != -1) {
14518+ psb_mmu_clflush(pd->driver, (void *)&v[pt->index]);
14519+ atomic_set(&pd->driver->needs_tlbflush, 1);
14520+ }
14521+ kunmap_atomic(pt->v, KM_USER0);
14522+ spin_unlock(&pd->driver->lock);
14523+ psb_mmu_free_pt(pt);
14524+ return;
14525+ }
14526+ spin_unlock(&pd->driver->lock);
14527+}
14528+
14529+static inline void psb_mmu_set_pte(struct psb_mmu_pt *pt, unsigned long addr,
14530+ uint32_t pte)
14531+{
14532+ pt->v[psb_mmu_pt_index(addr)] = pte;
14533+}
14534+
14535+static inline void psb_mmu_invalidate_pte(struct psb_mmu_pt *pt,
14536+ unsigned long addr)
14537+{
14538+ pt->v[psb_mmu_pt_index(addr)] = pt->pd->invalid_pte;
14539+}
14540+
14541+#if 0
14542+static uint32_t psb_mmu_check_pte_locked(struct psb_mmu_pd *pd,
14543+ uint32_t mmu_offset)
14544+{
14545+ uint32_t *v;
14546+ uint32_t pfn;
14547+
14548+ v = kmap_atomic(pd->p, KM_USER0);
14549+ if (!v) {
14550+ printk(KERN_INFO "Could not kmap pde page.\n");
14551+ return 0;
14552+ }
14553+ pfn = v[psb_mmu_pd_index(mmu_offset)];
14554+ // printk(KERN_INFO "pde is 0x%08x\n",pfn);
14555+ kunmap_atomic(v, KM_USER0);
14556+ if (((pfn & 0x0F) != PSB_PTE_VALID)) {
14557+ printk(KERN_INFO "Strange pde at 0x%08x: 0x%08x.\n",
14558+ mmu_offset, pfn);
14559+ }
14560+ v = ioremap(pfn & 0xFFFFF000, 4096);
14561+ if (!v) {
14562+ printk(KERN_INFO "Could not kmap pte page.\n");
14563+ return 0;
14564+ }
14565+ pfn = v[psb_mmu_pt_index(mmu_offset)];
14566+ // printk(KERN_INFO "pte is 0x%08x\n",pfn);
14567+ iounmap(v);
14568+ if (((pfn & 0x0F) != PSB_PTE_VALID)) {
14569+ printk(KERN_INFO "Strange pte at 0x%08x: 0x%08x.\n",
14570+ mmu_offset, pfn);
14571+ }
14572+ return pfn >> PAGE_SHIFT;
14573+}
14574+
14575+static void psb_mmu_check_mirrored_gtt(struct psb_mmu_pd *pd,
14576+ uint32_t mmu_offset, uint32_t gtt_pages)
14577+{
14578+ uint32_t start;
14579+ uint32_t next;
14580+
14581+ printk(KERN_INFO "Checking mirrored gtt 0x%08x %d\n",
14582+ mmu_offset, gtt_pages);
14583+ down_read(&pd->driver->sem);
14584+ start = psb_mmu_check_pte_locked(pd, mmu_offset);
14585+ mmu_offset += PAGE_SIZE;
14586+ gtt_pages -= 1;
14587+ while (gtt_pages--) {
14588+ next = psb_mmu_check_pte_locked(pd, mmu_offset);
14589+ if (next != start + 1) {
14590+ printk(KERN_INFO "Ptes out of order: 0x%08x, 0x%08x.\n",
14591+ start, next);
14592+ }
14593+ start = next;
14594+ mmu_offset += PAGE_SIZE;
14595+ }
14596+ up_read(&pd->driver->sem);
14597+}
14598+
14599+#endif
14600+
14601+void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd,
14602+ uint32_t mmu_offset, uint32_t gtt_start,
14603+ uint32_t gtt_pages)
14604+{
14605+ uint32_t *v;
14606+ uint32_t start = psb_mmu_pd_index(mmu_offset);
14607+ struct psb_mmu_driver *driver = pd->driver;
14608+
14609+ down_read(&driver->sem);
14610+ spin_lock(&driver->lock);
14611+
14612+ v = kmap_atomic(pd->p, KM_USER0);
14613+ v += start;
14614+
14615+ while (gtt_pages--) {
14616+ *v++ = gtt_start | pd->pd_mask;
14617+ gtt_start += PAGE_SIZE;
14618+ }
14619+
14620+ drm_ttm_cache_flush();
14621+ kunmap_atomic(v, KM_USER0);
14622+ spin_unlock(&driver->lock);
14623+
14624+ if (pd->hw_context != -1)
14625+ atomic_set(&pd->driver->needs_tlbflush, 1);
14626+
14627+ up_read(&pd->driver->sem);
14628+ psb_mmu_flush_pd(pd->driver, 0);
14629+}
14630+
14631+struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver *driver)
14632+{
14633+ struct psb_mmu_pd *pd;
14634+
14635+ down_read(&driver->sem);
14636+ pd = driver->default_pd;
14637+ up_read(&driver->sem);
14638+
14639+ return pd;
14640+}
14641+
14642+/* Returns the physical address of the PD shared by sgx/msvdx */
14643+uint32_t psb_get_default_pd_addr(struct psb_mmu_driver * driver)
14644+{
14645+ struct psb_mmu_pd *pd;
14646+
14647+ pd = psb_mmu_get_default_pd(driver);
14648+ return ((page_to_pfn(pd->p) << PAGE_SHIFT));
14649+}
14650+
14651+void psb_mmu_driver_takedown(struct psb_mmu_driver *driver)
14652+{
14653+ psb_iowrite32(driver, driver->bif_ctrl, PSB_CR_BIF_CTRL);
14654+ psb_mmu_free_pagedir(driver->default_pd);
14655+ kfree(driver);
14656+}
14657+
14658+struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
14659+ int trap_pagefaults,
14660+ int invalid_type,
14661+ atomic_t *msvdx_mmu_invaldc)
14662+{
14663+ struct psb_mmu_driver *driver;
14664+
14665+ driver = (struct psb_mmu_driver *)kmalloc(sizeof(*driver), GFP_KERNEL);
14666+
14667+ if (!driver)
14668+ return NULL;
14669+
14670+ driver->default_pd = psb_mmu_alloc_pd(driver, trap_pagefaults,
14671+ invalid_type);
14672+ if (!driver->default_pd)
14673+ goto out_err1;
14674+
14675+ spin_lock_init(&driver->lock);
14676+ init_rwsem(&driver->sem);
14677+ down_write(&driver->sem);
14678+ driver->register_map = registers;
14679+ atomic_set(&driver->needs_tlbflush, 1);
14680+ driver->msvdx_mmu_invaldc = msvdx_mmu_invaldc;
14681+
14682+ driver->bif_ctrl = psb_ioread32(driver, PSB_CR_BIF_CTRL);
14683+ psb_iowrite32(driver, driver->bif_ctrl | _PSB_CB_CTRL_CLEAR_FAULT,
14684+ PSB_CR_BIF_CTRL);
14685+ psb_iowrite32(driver, driver->bif_ctrl & ~_PSB_CB_CTRL_CLEAR_FAULT,
14686+ PSB_CR_BIF_CTRL);
14687+
14688+ driver->has_clflush = 0;
14689+
14690+#if defined(CONFIG_X86)
14691+ if (boot_cpu_has(X86_FEATURE_CLFLSH)) {
14692+ uint32_t tfms, misc, cap0, cap4, clflush_size;
14693+
14694+ /*
14695+ * clflush size is determined at kernel setup for x86_64 but not for
14696+ * i386. We have to do it here.
14697+ */
14698+
14699+ cpuid(0x00000001, &tfms, &misc, &cap0, &cap4);
14700+ clflush_size = ((misc >> 8) & 0xff) * 8;
14701+ driver->has_clflush = 1;
14702+ driver->clflush_add =
14703+ PAGE_SIZE * clflush_size / sizeof(uint32_t);
14704+ driver->clflush_mask = driver->clflush_add - 1;
14705+ driver->clflush_mask = ~driver->clflush_mask;
14706+ }
14707+#endif
14708+
14709+ up_write(&driver->sem);
14710+ return driver;
14711+
14712+ out_err1:
14713+ kfree(driver);
14714+ return NULL;
14715+}
14716+
14717+#if defined(CONFIG_X86)
14718+static void psb_mmu_flush_ptes(struct psb_mmu_pd *pd, unsigned long address,
14719+ uint32_t num_pages, uint32_t desired_tile_stride,
14720+ uint32_t hw_tile_stride)
14721+{
14722+ struct psb_mmu_pt *pt;
14723+ uint32_t rows = 1;
14724+ uint32_t i;
14725+ unsigned long addr;
14726+ unsigned long end;
14727+ unsigned long next;
14728+ unsigned long add;
14729+ unsigned long row_add;
14730+ unsigned long clflush_add = pd->driver->clflush_add;
14731+ unsigned long clflush_mask = pd->driver->clflush_mask;
14732+
14733+ if (!pd->driver->has_clflush) {
14734+ drm_ttm_cache_flush();
14735+ return;
14736+ }
14737+
14738+ if (hw_tile_stride)
14739+ rows = num_pages / desired_tile_stride;
14740+ else
14741+ desired_tile_stride = num_pages;
14742+
14743+ add = desired_tile_stride << PAGE_SHIFT;
14744+ row_add = hw_tile_stride << PAGE_SHIFT;
14745+ mb();
14746+ for (i = 0; i < rows; ++i) {
14747+
14748+ addr = address;
14749+ end = addr + add;
14750+
14751+ do {
14752+ next = psb_pd_addr_end(addr, end);
14753+ pt = psb_mmu_pt_map_lock(pd, addr);
14754+ if (!pt)
14755+ continue;
14756+ do {
14757+ psb_clflush(&pt->v[psb_mmu_pt_index(addr)]);
14758+ } while (addr += clflush_add,
14759+ (addr & clflush_mask) < next);
14760+
14761+ psb_mmu_pt_unmap_unlock(pt);
14762+ } while (addr = next, next != end);
14763+ address += row_add;
14764+ }
14765+ mb();
14766+}
14767+#else
14768+static void psb_mmu_flush_ptes(struct psb_mmu_pd *pd, unsigned long address,
14769+ uint32_t num_pages, uint32_t desired_tile_stride,
14770+ uint32_t hw_tile_stride)
14771+{
14772+ drm_ttm_cache_flush();
14773+}
14774+#endif
14775+
14776+void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd,
14777+ unsigned long address, uint32_t num_pages)
14778+{
14779+ struct psb_mmu_pt *pt;
14780+ unsigned long addr;
14781+ unsigned long end;
14782+ unsigned long next;
14783+ unsigned long f_address = address;
14784+
14785+ down_read(&pd->driver->sem);
14786+
14787+ addr = address;
14788+ end = addr + (num_pages << PAGE_SHIFT);
14789+
14790+ do {
14791+ next = psb_pd_addr_end(addr, end);
14792+ pt = psb_mmu_pt_alloc_map_lock(pd, addr);
14793+ if (!pt)
14794+ goto out;
14795+ do {
14796+ psb_mmu_invalidate_pte(pt, addr);
14797+ --pt->count;
14798+ } while (addr += PAGE_SIZE, addr < next);
14799+ psb_mmu_pt_unmap_unlock(pt);
14800+
14801+ } while (addr = next, next != end);
14802+
14803+ out:
14804+ if (pd->hw_context != -1)
14805+ psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1);
14806+
14807+ up_read(&pd->driver->sem);
14808+
14809+ if (pd->hw_context != -1)
14810+ psb_mmu_flush(pd->driver);
14811+
14812+ return;
14813+}
14814+
14815+void psb_mmu_remove_pages(struct psb_mmu_pd *pd, unsigned long address,
14816+ uint32_t num_pages, uint32_t desired_tile_stride,
14817+ uint32_t hw_tile_stride)
14818+{
14819+ struct psb_mmu_pt *pt;
14820+ uint32_t rows = 1;
14821+ uint32_t i;
14822+ unsigned long addr;
14823+ unsigned long end;
14824+ unsigned long next;
14825+ unsigned long add;
14826+ unsigned long row_add;
14827+ unsigned long f_address = address;
14828+
14829+ if (hw_tile_stride)
14830+ rows = num_pages / desired_tile_stride;
14831+ else
14832+ desired_tile_stride = num_pages;
14833+
14834+ add = desired_tile_stride << PAGE_SHIFT;
14835+ row_add = hw_tile_stride << PAGE_SHIFT;
14836+
14837+ down_read(&pd->driver->sem);
14838+
14839+ /* Make sure we only need to flush this processor's cache */
14840+
14841+ for (i = 0; i < rows; ++i) {
14842+
14843+ addr = address;
14844+ end = addr + add;
14845+
14846+ do {
14847+ next = psb_pd_addr_end(addr, end);
14848+ pt = psb_mmu_pt_map_lock(pd, addr);
14849+ if (!pt)
14850+ continue;
14851+ do {
14852+ psb_mmu_invalidate_pte(pt, addr);
14853+ --pt->count;
14854+
14855+ } while (addr += PAGE_SIZE, addr < next);
14856+ psb_mmu_pt_unmap_unlock(pt);
14857+
14858+ } while (addr = next, next != end);
14859+ address += row_add;
14860+ }
14861+ if (pd->hw_context != -1)
14862+ psb_mmu_flush_ptes(pd, f_address, num_pages,
14863+ desired_tile_stride, hw_tile_stride);
14864+
14865+ up_read(&pd->driver->sem);
14866+
14867+ if (pd->hw_context != -1)
14868+ psb_mmu_flush(pd->driver);
14869+}
14870+
14871+int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd, uint32_t start_pfn,
14872+ unsigned long address, uint32_t num_pages,
14873+ int type)
14874+{
14875+ struct psb_mmu_pt *pt;
14876+ uint32_t pte;
14877+ unsigned long addr;
14878+ unsigned long end;
14879+ unsigned long next;
14880+ unsigned long f_address = address;
14881+ int ret = -ENOMEM;
14882+
14883+ down_read(&pd->driver->sem);
14884+
14885+ addr = address;
14886+ end = addr + (num_pages << PAGE_SHIFT);
14887+
14888+ do {
14889+ next = psb_pd_addr_end(addr, end);
14890+ pt = psb_mmu_pt_alloc_map_lock(pd, addr);
14891+ if (!pt) {
14892+ ret = -ENOMEM;
14893+ goto out;
14894+ }
14895+ do {
14896+ pte = psb_mmu_mask_pte(start_pfn++, type);
14897+ psb_mmu_set_pte(pt, addr, pte);
14898+ pt->count++;
14899+ } while (addr += PAGE_SIZE, addr < next);
14900+ psb_mmu_pt_unmap_unlock(pt);
14901+
14902+ } while (addr = next, next != end);
14903+ ret = 0;
14904+
14905+ out:
14906+ if (pd->hw_context != -1)
14907+ psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1);
14908+
14909+ up_read(&pd->driver->sem);
14910+
14911+ if (pd->hw_context != -1)
14912+ psb_mmu_flush(pd->driver);
14913+
14914+ return 0;
14915+}
14916+
14917+int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages,
14918+ unsigned long address, uint32_t num_pages,
14919+ uint32_t desired_tile_stride, uint32_t hw_tile_stride,
14920+ int type)
14921+{
14922+ struct psb_mmu_pt *pt;
14923+ uint32_t rows = 1;
14924+ uint32_t i;
14925+ uint32_t pte;
14926+ unsigned long addr;
14927+ unsigned long end;
14928+ unsigned long next;
14929+ unsigned long add;
14930+ unsigned long row_add;
14931+ unsigned long f_address = address;
14932+ int ret = -ENOMEM;
14933+
14934+ if (hw_tile_stride) {
14935+ if (num_pages % desired_tile_stride != 0)
14936+ return -EINVAL;
14937+ rows = num_pages / desired_tile_stride;
14938+ } else {
14939+ desired_tile_stride = num_pages;
14940+ }
14941+
14942+ add = desired_tile_stride << PAGE_SHIFT;
14943+ row_add = hw_tile_stride << PAGE_SHIFT;
14944+
14945+ down_read(&pd->driver->sem);
14946+
14947+ for (i = 0; i < rows; ++i) {
14948+
14949+ addr = address;
14950+ end = addr + add;
14951+
14952+ do {
14953+ next = psb_pd_addr_end(addr, end);
14954+ pt = psb_mmu_pt_alloc_map_lock(pd, addr);
14955+ if (!pt)
14956+ goto out;
14957+ do {
14958+ pte = psb_mmu_mask_pte(page_to_pfn(*pages++),
14959+ type);
14960+ psb_mmu_set_pte(pt, addr, pte);
14961+ pt->count++;
14962+ } while (addr += PAGE_SIZE, addr < next);
14963+ psb_mmu_pt_unmap_unlock(pt);
14964+
14965+ } while (addr = next, next != end);
14966+
14967+ address += row_add;
14968+ }
14969+ ret = 0;
14970+ out:
14971+ if (pd->hw_context != -1)
14972+ psb_mmu_flush_ptes(pd, f_address, num_pages,
14973+ desired_tile_stride, hw_tile_stride);
14974+
14975+ up_read(&pd->driver->sem);
14976+
14977+ if (pd->hw_context != -1)
14978+ psb_mmu_flush(pd->driver);
14979+
14980+ return 0;
14981+}
14982+
14983+void psb_mmu_enable_requestor(struct psb_mmu_driver *driver, uint32_t mask)
14984+{
14985+ mask &= _PSB_MMU_ER_MASK;
14986+ psb_iowrite32(driver, psb_ioread32(driver, PSB_CR_BIF_CTRL) & ~mask,
14987+ PSB_CR_BIF_CTRL);
14988+ (void)psb_ioread32(driver, PSB_CR_BIF_CTRL);
14989+}
14990+
14991+void psb_mmu_disable_requestor(struct psb_mmu_driver *driver, uint32_t mask)
14992+{
14993+ mask &= _PSB_MMU_ER_MASK;
14994+ psb_iowrite32(driver, psb_ioread32(driver, PSB_CR_BIF_CTRL) | mask,
14995+ PSB_CR_BIF_CTRL);
14996+ (void)psb_ioread32(driver, PSB_CR_BIF_CTRL);
14997+}
14998+
14999+int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
15000+ unsigned long *pfn)
15001+{
15002+ int ret;
15003+ struct psb_mmu_pt *pt;
15004+ uint32_t tmp;
15005+ spinlock_t *lock = &pd->driver->lock;
15006+
15007+ down_read(&pd->driver->sem);
15008+ pt = psb_mmu_pt_map_lock(pd, virtual);
15009+ if (!pt) {
15010+ uint32_t *v;
15011+
15012+ spin_lock(lock);
15013+ v = kmap_atomic(pd->p, KM_USER0);
15014+ tmp = v[psb_mmu_pd_index(virtual)];
15015+ kunmap_atomic(v, KM_USER0);
15016+ spin_unlock(lock);
15017+
15018+ if (tmp != pd->invalid_pde || !(tmp & PSB_PTE_VALID) ||
15019+ !(pd->invalid_pte & PSB_PTE_VALID)) {
15020+ ret = -EINVAL;
15021+ goto out;
15022+ }
15023+ ret = 0;
15024+ *pfn = pd->invalid_pte >> PAGE_SHIFT;
15025+ goto out;
15026+ }
15027+ tmp = pt->v[psb_mmu_pt_index(virtual)];
15028+ if (!(tmp & PSB_PTE_VALID)) {
15029+ ret = -EINVAL;
15030+ } else {
15031+ ret = 0;
15032+ *pfn = tmp >> PAGE_SHIFT;
15033+ }
15034+ psb_mmu_pt_unmap_unlock(pt);
15035+ out:
15036+ up_read(&pd->driver->sem);
15037+ return ret;
15038+}
15039+
15040+void psb_mmu_test(struct psb_mmu_driver *driver, uint32_t offset)
15041+{
15042+ struct page *p;
15043+ unsigned long pfn;
15044+ int ret = 0;
15045+ struct psb_mmu_pd *pd;
15046+ uint32_t *v;
15047+ uint32_t *vmmu;
15048+
15049+ pd = driver->default_pd;
15050+ if (!pd) {
15051+ printk(KERN_WARNING "Could not get default pd\n");
15052+ }
15053+
15054+ p = alloc_page(GFP_DMA32);
15055+
15056+ if (!p) {
15057+ printk(KERN_WARNING "Failed allocating page\n");
15058+ return;
15059+ }
15060+
15061+ v = kmap(p);
15062+ memset(v, 0x67, PAGE_SIZE);
15063+
15064+ pfn = (offset >> PAGE_SHIFT);
15065+
15066+ ret = psb_mmu_insert_pages(pd, &p, pfn << PAGE_SHIFT, 1, 0, 0,
15067+ PSB_MMU_CACHED_MEMORY);
15068+ if (ret) {
15069+ printk(KERN_WARNING "Failed inserting mmu page\n");
15070+ goto out_err1;
15071+ }
15072+
15073+ /* Ioremap the page through the GART aperture */
15074+
15075+ vmmu = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
15076+ if (!vmmu) {
15077+ printk(KERN_WARNING "Failed ioremapping page\n");
15078+ goto out_err2;
15079+ }
15080+
15081+ /* Read from the page with mmu disabled. */
15082+ printk(KERN_INFO "Page first dword is 0x%08x\n", ioread32(vmmu));
15083+
15084+ /* Enable the mmu for host accesses and read again. */
15085+ psb_mmu_enable_requestor(driver, _PSB_MMU_ER_HOST);
15086+
15087+ printk(KERN_INFO "MMU Page first dword is (0x67676767) 0x%08x\n",
15088+ ioread32(vmmu));
15089+ *v = 0x15243705;
15090+ printk(KERN_INFO "MMU Page new dword is (0x15243705) 0x%08x\n",
15091+ ioread32(vmmu));
15092+ iowrite32(0x16243355, vmmu);
15093+ (void)ioread32(vmmu);
15094+ printk(KERN_INFO "Page new dword is (0x16243355) 0x%08x\n", *v);
15095+
15096+ printk(KERN_INFO "Int stat is 0x%08x\n",
15097+ psb_ioread32(driver, PSB_CR_BIF_INT_STAT));
15098+ printk(KERN_INFO "Fault is 0x%08x\n",
15099+ psb_ioread32(driver, PSB_CR_BIF_FAULT));
15100+
15101+ /* Disable MMU for host accesses and clear page fault register */
15102+ psb_mmu_disable_requestor(driver, _PSB_MMU_ER_HOST);
15103+ iounmap(vmmu);
15104+ out_err2:
15105+ psb_mmu_remove_pages(pd, pfn << PAGE_SHIFT, 1, 0, 0);
15106+ out_err1:
15107+ kunmap(p);
15108+ __free_page(p);
15109+}
15110Index: linux-2.6.28/drivers/gpu/drm/psb/psb_msvdx.c
15111===================================================================
15112--- /dev/null 1970-01-01 00:00:00.000000000 +0000
15113+++ linux-2.6.28/drivers/gpu/drm/psb/psb_msvdx.c 2009-02-12 09:14:42.000000000 +0000
15114@@ -0,0 +1,678 @@
15115+/**
15116+ * file psb_msvdx.c
15117+ * MSVDX I/O operations and IRQ handling
15118+ *
15119+ */
15120+
15121+/**************************************************************************
15122+ *
15123+ * Copyright (c) 2007 Intel Corporation, Hillsboro, OR, USA
15124+ * Copyright (c) Imagination Technologies Limited, UK
15125+ * All Rights Reserved.
15126+ *
15127+ * Permission is hereby granted, free of charge, to any person obtaining a
15128+ * copy of this software and associated documentation files (the
15129+ * "Software"), to deal in the Software without restriction, including
15130+ * without limitation the rights to use, copy, modify, merge, publish,
15131+ * distribute, sub license, and/or sell copies of the Software, and to
15132+ * permit persons to whom the Software is furnished to do so, subject to
15133+ * the following conditions:
15134+ *
15135+ * The above copyright notice and this permission notice (including the
15136+ * next paragraph) shall be included in all copies or substantial portions
15137+ * of the Software.
15138+ *
15139+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15140+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15141+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
15142+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
15143+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
15144+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
15145+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
15146+ *
15147+ **************************************************************************/
15148+
15149+#include "drmP.h"
15150+#include "drm_os_linux.h"
15151+#include "psb_drv.h"
15152+#include "psb_drm.h"
15153+#include "psb_msvdx.h"
15154+
15155+#include <asm/io.h>
15156+#include <linux/delay.h>
15157+
15158+#ifndef list_first_entry
15159+#define list_first_entry(ptr, type, member) \
15160+ list_entry((ptr)->next, type, member)
15161+#endif
15162+
15163+static int psb_msvdx_send (struct drm_device *dev, void *cmd,
15164+ unsigned long cmd_size);
15165+
15166+int
15167+psb_msvdx_dequeue_send (struct drm_device *dev)
15168+{
15169+ struct drm_psb_private *dev_priv = dev->dev_private;
15170+ struct psb_msvdx_cmd_queue *msvdx_cmd = NULL;
15171+ int ret = 0;
15172+
15173+ if (list_empty (&dev_priv->msvdx_queue))
15174+ {
15175+ PSB_DEBUG_GENERAL ("MSVDXQUE: msvdx list empty.\n");
15176+ dev_priv->msvdx_busy = 0;
15177+ return -EINVAL;
15178+ }
15179+ msvdx_cmd =
15180+ list_first_entry (&dev_priv->msvdx_queue, struct psb_msvdx_cmd_queue,
15181+ head);
15182+ PSB_DEBUG_GENERAL ("MSVDXQUE: Queue has id %08x\n", msvdx_cmd->sequence);
15183+ ret = psb_msvdx_send (dev, msvdx_cmd->cmd, msvdx_cmd->cmd_size);
15184+ if (ret)
15185+ {
15186+ PSB_DEBUG_GENERAL ("MSVDXQUE: psb_msvdx_send failed\n");
15187+ ret = -EINVAL;
15188+ }
15189+ list_del (&msvdx_cmd->head);
15190+ kfree (msvdx_cmd->cmd);
15191+ drm_free (msvdx_cmd, sizeof (struct psb_msvdx_cmd_queue), DRM_MEM_DRIVER);
15192+ return ret;
15193+}
15194+
15195+int
15196+psb_msvdx_map_command (struct drm_device *dev,
15197+ struct drm_buffer_object *cmd_buffer,
15198+ unsigned long cmd_offset, unsigned long cmd_size,
15199+ void **msvdx_cmd, uint32_t sequence, int copy_cmd)
15200+{
15201+ struct drm_psb_private *dev_priv = dev->dev_private;
15202+ int ret = 0;
15203+ unsigned long cmd_page_offset = cmd_offset & ~PAGE_MASK;
15204+ unsigned long cmd_size_remaining;
15205+ struct drm_bo_kmap_obj cmd_kmap;
15206+ void *cmd, *tmp, *cmd_start;
15207+ int is_iomem;
15208+
15209+ /* command buffers may not exceed page boundary */
15210+ if (cmd_size + cmd_page_offset > PAGE_SIZE)
15211+ return -EINVAL;
15212+
15213+ ret = drm_bo_kmap (cmd_buffer, cmd_offset >> PAGE_SHIFT, 2, &cmd_kmap);
15214+
15215+ if (ret)
15216+ {
15217+ PSB_DEBUG_GENERAL ("MSVDXQUE:ret:%d\n", ret);
15218+ return ret;
15219+ }
15220+
15221+ cmd_start =
15222+ (void *) drm_bmo_virtual (&cmd_kmap, &is_iomem) + cmd_page_offset;
15223+ cmd = cmd_start;
15224+ cmd_size_remaining = cmd_size;
15225+
15226+ while (cmd_size_remaining > 0)
15227+ {
15228+ uint32_t mmu_ptd;
15229+ uint32_t cur_cmd_size = MEMIO_READ_FIELD (cmd, FWRK_GENMSG_SIZE);
15230+ uint32_t cur_cmd_id = MEMIO_READ_FIELD (cmd, FWRK_GENMSG_ID);
15231+ PSB_DEBUG_GENERAL
15232+ ("cmd start at %08x cur_cmd_size = %d cur_cmd_id = %02x fence = %08x\n",
15233+ (uint32_t) cmd, cur_cmd_size, cur_cmd_id, sequence);
15234+ if ((cur_cmd_size % sizeof (uint32_t))
15235+ || (cur_cmd_size > cmd_size_remaining))
15236+ {
15237+ ret = -EINVAL;
15238+ PSB_DEBUG_GENERAL ("MSVDX: ret:%d\n", ret);
15239+ goto out;
15240+ }
15241+
15242+ switch (cur_cmd_id)
15243+ {
15244+ case VA_MSGID_RENDER:
15245+ /* Fence ID */
15246+ MEMIO_WRITE_FIELD (cmd, FW_VA_RENDER_FENCE_VALUE, sequence);
15247+
15248+ mmu_ptd = psb_get_default_pd_addr (dev_priv->mmu);
15249+ if (atomic_cmpxchg(&dev_priv->msvdx_mmu_invaldc, 1, 0) == 1)
15250+ {
15251+ mmu_ptd |= 1;
15252+ PSB_DEBUG_GENERAL ("MSVDX: Setting MMU invalidate flag\n");
15253+ }
15254+ /* PTD */
15255+ MEMIO_WRITE_FIELD (cmd, FW_VA_RENDER_MMUPTD, mmu_ptd);
15256+ break;
15257+
15258+ default:
15259+ /* Msg not supported */
15260+ ret = -EINVAL;
15261+ PSB_DEBUG_GENERAL ("MSVDX: ret:%d\n", ret);
15262+ goto out;
15263+ }
15264+
15265+ cmd += cur_cmd_size;
15266+ cmd_size_remaining -= cur_cmd_size;
15267+ }
15268+
15269+ if (copy_cmd)
15270+ {
15271+ PSB_DEBUG_GENERAL
15272+ ("MSVDXQUE: psb_msvdx_map_command copying command...\n");
15273+ tmp = drm_calloc (1, cmd_size, DRM_MEM_DRIVER);
15274+ if (tmp == NULL)
15275+ {
15276+ ret = -ENOMEM;
15277+ PSB_DEBUG_GENERAL ("MSVDX: ret:%d\n", ret);
15278+ goto out;
15279+ }
15280+ memcpy (tmp, cmd_start, cmd_size);
15281+ *msvdx_cmd = tmp;
15282+ }
15283+ else
15284+ {
15285+ PSB_DEBUG_GENERAL
15286+ ("MSVDXQUE: psb_msvdx_map_command did NOT copy command...\n");
15287+ ret = psb_msvdx_send (dev, cmd_start, cmd_size);
15288+ if (ret)
15289+ {
15290+ PSB_DEBUG_GENERAL ("MSVDXQUE: psb_msvdx_send failed\n");
15291+ ret = -EINVAL;
15292+ }
15293+ }
15294+
15295+out:
15296+ drm_bo_kunmap (&cmd_kmap);
15297+
15298+ return ret;
15299+}
15300+
15301+int
15302+psb_submit_video_cmdbuf (struct drm_device *dev,
15303+ struct drm_buffer_object *cmd_buffer,
15304+ unsigned long cmd_offset, unsigned long cmd_size,
15305+ struct drm_fence_object *fence)
15306+{
15307+ struct drm_psb_private *dev_priv = dev->dev_private;
15308+ uint32_t sequence = fence->sequence;
15309+ unsigned long irq_flags;
15310+ int ret = 0;
15311+
15312+ mutex_lock (&dev_priv->msvdx_mutex);
15313+ psb_schedule_watchdog (dev_priv);
15314+
15315+ spin_lock_irqsave (&dev_priv->msvdx_lock, irq_flags);
15316+ if (dev_priv->msvdx_needs_reset)
15317+ {
15318+ spin_unlock_irqrestore (&dev_priv->msvdx_lock, irq_flags);
15319+ PSB_DEBUG_GENERAL ("MSVDX: Needs reset\n");
15320+ if (psb_msvdx_reset (dev_priv))
15321+ {
15322+ mutex_unlock (&dev_priv->msvdx_mutex);
15323+ ret = -EBUSY;
15324+ PSB_DEBUG_GENERAL ("MSVDX: Reset failed\n");
15325+ return ret;
15326+ }
15327+ PSB_DEBUG_GENERAL ("MSVDX: Reset ok\n");
15328+ dev_priv->msvdx_needs_reset = 0;
15329+ dev_priv->msvdx_busy = 0;
15330+ dev_priv->msvdx_start_idle = 0;
15331+
15332+ psb_msvdx_init (dev);
15333+ psb_msvdx_irq_preinstall (dev_priv);
15334+ psb_msvdx_irq_postinstall (dev_priv);
15335+ PSB_DEBUG_GENERAL ("MSVDX: Init ok\n");
15336+ spin_lock_irqsave (&dev_priv->msvdx_lock, irq_flags);
15337+ }
15338+
15339+ if (!dev_priv->msvdx_busy)
15340+ {
15341+ dev_priv->msvdx_busy = 1;
15342+ spin_unlock_irqrestore (&dev_priv->msvdx_lock, irq_flags);
15343+ PSB_DEBUG_GENERAL
15344+ ("MSVDXQUE: nothing in the queue sending sequence:%08x..\n",
15345+ sequence);
15346+ ret =
15347+ psb_msvdx_map_command (dev, cmd_buffer, cmd_offset, cmd_size,
15348+ NULL, sequence, 0);
15349+ if (ret)
15350+ {
15351+ mutex_unlock (&dev_priv->msvdx_mutex);
15352+ PSB_DEBUG_GENERAL ("MSVDXQUE: Failed to extract cmd...\n");
15353+ return ret;
15354+ }
15355+ }
15356+ else
15357+ {
15358+ struct psb_msvdx_cmd_queue *msvdx_cmd;
15359+ void *cmd = NULL;
15360+
15361+ spin_unlock_irqrestore (&dev_priv->msvdx_lock, irq_flags);
15362+ /*queue the command to be sent when the h/w is ready */
15363+ PSB_DEBUG_GENERAL ("MSVDXQUE: queueing sequence:%08x..\n", sequence);
15364+ msvdx_cmd =
15365+ drm_calloc (1, sizeof (struct psb_msvdx_cmd_queue), DRM_MEM_DRIVER);
15366+ if (msvdx_cmd == NULL)
15367+ {
15368+ mutex_unlock (&dev_priv->msvdx_mutex);
15369+ PSB_DEBUG_GENERAL ("MSVDXQUE: Out of memory...\n");
15370+ return -ENOMEM;
15371+ }
15372+
15373+ ret =
15374+ psb_msvdx_map_command (dev, cmd_buffer, cmd_offset, cmd_size,
15375+ &cmd, sequence, 1);
15376+ if (ret)
15377+ {
15378+ mutex_unlock (&dev_priv->msvdx_mutex);
15379+ PSB_DEBUG_GENERAL ("MSVDXQUE: Failed to extract cmd...\n");
15380+ drm_free (msvdx_cmd, sizeof (struct psb_msvdx_cmd_queue),
15381+ DRM_MEM_DRIVER);
15382+ return ret;
15383+ }
15384+ msvdx_cmd->cmd = cmd;
15385+ msvdx_cmd->cmd_size = cmd_size;
15386+ msvdx_cmd->sequence = sequence;
15387+ spin_lock_irqsave (&dev_priv->msvdx_lock, irq_flags);
15388+ list_add_tail (&msvdx_cmd->head, &dev_priv->msvdx_queue);
15389+ if (!dev_priv->msvdx_busy)
15390+ {
15391+ dev_priv->msvdx_busy = 1;
15392+ PSB_DEBUG_GENERAL ("MSVDXQUE: Need immediate dequeue\n");
15393+ psb_msvdx_dequeue_send (dev);
15394+ }
15395+ spin_unlock_irqrestore (&dev_priv->msvdx_lock, irq_flags);
15396+ }
15397+ mutex_unlock (&dev_priv->msvdx_mutex);
15398+ return ret;
15399+}
15400+
15401+int
15402+psb_msvdx_send (struct drm_device *dev, void *cmd, unsigned long cmd_size)
15403+{
15404+ int ret = 0;
15405+ struct drm_psb_private *dev_priv = dev->dev_private;
15406+
15407+ while (cmd_size > 0)
15408+ {
15409+ uint32_t cur_cmd_size = MEMIO_READ_FIELD (cmd, FWRK_GENMSG_SIZE);
15410+ if (cur_cmd_size > cmd_size)
15411+ {
15412+ ret = -EINVAL;
15413+ PSB_DEBUG_GENERAL
15414+ ("MSVDX: cmd_size = %d cur_cmd_size = %d\n",
15415+ (int) cmd_size, cur_cmd_size);
15416+ goto out;
15417+ }
15418+ /* Send the message to h/w */
15419+ ret = psb_mtx_send (dev_priv, cmd);
15420+ if (ret)
15421+ {
15422+ PSB_DEBUG_GENERAL ("MSVDX: ret:%d\n", ret);
15423+ goto out;
15424+ }
15425+ cmd += cur_cmd_size;
15426+ cmd_size -= cur_cmd_size;
15427+ }
15428+
15429+out:
15430+ PSB_DEBUG_GENERAL ("MSVDX: ret:%d\n", ret);
15431+ return ret;
15432+}
15433+
15434+/***********************************************************************************
15435+ * Function Name : psb_mtx_send
15436+ * Inputs :
15437+ * Outputs :
15438+ * Returns :
15439+ * Description :
15440+ ************************************************************************************/
15441+int
15442+psb_mtx_send (struct drm_psb_private *dev_priv, const void *pvMsg)
15443+{
15444+
15445+ static uint32_t padMessage[FWRK_PADMSG_SIZE];
15446+
15447+ const uint32_t *pui32Msg = (uint32_t *) pvMsg;
15448+ uint32_t msgNumWords, wordsFree, readIndex, writeIndex;
15449+ int ret = 0;
15450+
15451+ PSB_DEBUG_GENERAL ("MSVDX: psb_mtx_send\n");
15452+
15453+ /* we need clocks enabled before we touch VEC local ram */
15454+ PSB_WMSVDX32 (clk_enable_all, MSVDX_MAN_CLK_ENABLE);
15455+
15456+ msgNumWords = (MEMIO_READ_FIELD (pvMsg, FWRK_GENMSG_SIZE) + 3) / 4;
15457+
15458+ if (msgNumWords > NUM_WORDS_MTX_BUF)
15459+ {
15460+ ret = -EINVAL;
15461+ PSB_DEBUG_GENERAL ("MSVDX: ret:%d\n", ret);
15462+ goto out;
15463+ }
15464+
15465+ readIndex = PSB_RMSVDX32 (MSVDX_COMMS_TO_MTX_RD_INDEX);
15466+ writeIndex = PSB_RMSVDX32 (MSVDX_COMMS_TO_MTX_WRT_INDEX);
15467+
15468+ if (writeIndex + msgNumWords > NUM_WORDS_MTX_BUF)
15469+ { /* message would wrap, need to send a pad message */
15470+ BUG_ON (MEMIO_READ_FIELD (pvMsg, FWRK_GENMSG_ID) == FWRK_MSGID_PADDING); /* Shouldn't happen for a PAD message itself */
15471+ /* if the read pointer is at zero then we must wait for it to change otherwise the write
15472+ * pointer will equal the read pointer,which should only happen when the buffer is empty
15473+ *
15474+ * This will only happens if we try to overfill the queue, queue management should make
15475+ * sure this never happens in the first place.
15476+ */
15477+ BUG_ON (0 == readIndex);
15478+ if (0 == readIndex)
15479+ {
15480+ ret = -EINVAL;
15481+ PSB_DEBUG_GENERAL ("MSVDX: ret:%d\n", ret);
15482+ goto out;
15483+ }
15484+ /* Send a pad message */
15485+ MEMIO_WRITE_FIELD (padMessage, FWRK_GENMSG_SIZE,
15486+ (NUM_WORDS_MTX_BUF - writeIndex) << 2);
15487+ MEMIO_WRITE_FIELD (padMessage, FWRK_GENMSG_ID, FWRK_MSGID_PADDING);
15488+ psb_mtx_send (dev_priv, padMessage);
15489+ writeIndex = PSB_RMSVDX32 (MSVDX_COMMS_TO_MTX_WRT_INDEX);
15490+ }
15491+
15492+ wordsFree =
15493+ (writeIndex >=
15494+ readIndex) ? NUM_WORDS_MTX_BUF - (writeIndex -
15495+ readIndex) : readIndex - writeIndex;
15496+
15497+ BUG_ON (msgNumWords > wordsFree);
15498+ if (msgNumWords > wordsFree)
15499+ {
15500+ ret = -EINVAL;
15501+ PSB_DEBUG_GENERAL ("MSVDX: ret:%d\n", ret);
15502+ goto out;
15503+ }
15504+
15505+ while (msgNumWords > 0)
15506+ {
15507+ PSB_WMSVDX32 (*pui32Msg++, MSVDX_COMMS_TO_MTX_BUF + (writeIndex << 2));
15508+ msgNumWords--;
15509+ writeIndex++;
15510+ if (NUM_WORDS_MTX_BUF == writeIndex)
15511+ {
15512+ writeIndex = 0;
15513+ }
15514+ }
15515+ PSB_WMSVDX32 (writeIndex, MSVDX_COMMS_TO_MTX_WRT_INDEX);
15516+
15517+ /* Make sure clocks are enabled before we kick */
15518+ PSB_WMSVDX32 (clk_enable_all, MSVDX_MAN_CLK_ENABLE);
15519+
15520+ /* signal an interrupt to let the mtx know there is a new message */
15521+ PSB_WMSVDX32 (1, MSVDX_MTX_KICKI);
15522+
15523+out:
15524+ return ret;
15525+}
15526+
15527+/*
15528+ * MSVDX MTX interrupt
15529+ */
15530+void
15531+psb_msvdx_mtx_interrupt (struct drm_device *dev)
15532+{
15533+ static uint32_t msgBuffer[128];
15534+ uint32_t readIndex, writeIndex;
15535+ uint32_t msgNumWords, msgWordOffset;
15536+ struct drm_psb_private *dev_priv =
15537+ (struct drm_psb_private *) dev->dev_private;
15538+
15539+ /* Are clocks enabled - If not enable before attempting to read from VLR */
15540+ if (PSB_RMSVDX32 (MSVDX_MAN_CLK_ENABLE) != (clk_enable_all))
15541+ {
15542+ PSB_DEBUG_GENERAL
15543+ ("MSVDX: Warning - Clocks disabled when Interupt set\n");
15544+ PSB_WMSVDX32 (clk_enable_all, MSVDX_MAN_CLK_ENABLE);
15545+ }
15546+
15547+ for (;;)
15548+ {
15549+ readIndex = PSB_RMSVDX32 (MSVDX_COMMS_TO_HOST_RD_INDEX);
15550+ writeIndex = PSB_RMSVDX32 (MSVDX_COMMS_TO_HOST_WRT_INDEX);
15551+
15552+ if (readIndex != writeIndex)
15553+ {
15554+ msgWordOffset = 0;
15555+
15556+ msgBuffer[msgWordOffset] =
15557+ PSB_RMSVDX32 (MSVDX_COMMS_TO_HOST_BUF + (readIndex << 2));
15558+
15559+ msgNumWords = (MEMIO_READ_FIELD (msgBuffer, FWRK_GENMSG_SIZE) + 3) / 4; /* round to nearest word */
15560+
15561+ /*ASSERT(msgNumWords <= sizeof(msgBuffer) / sizeof(uint32_t)); */
15562+
15563+ if (++readIndex >= NUM_WORDS_HOST_BUF)
15564+ readIndex = 0;
15565+
15566+ for (msgWordOffset++; msgWordOffset < msgNumWords; msgWordOffset++)
15567+ {
15568+ msgBuffer[msgWordOffset] =
15569+ PSB_RMSVDX32 (MSVDX_COMMS_TO_HOST_BUF + (readIndex << 2));
15570+
15571+ if (++readIndex >= NUM_WORDS_HOST_BUF)
15572+ {
15573+ readIndex = 0;
15574+ }
15575+ }
15576+
15577+ /* Update the Read index */
15578+ PSB_WMSVDX32 (readIndex, MSVDX_COMMS_TO_HOST_RD_INDEX);
15579+
15580+ if (!dev_priv->msvdx_needs_reset)
15581+ switch (MEMIO_READ_FIELD (msgBuffer, FWRK_GENMSG_ID))
15582+ {
15583+ case VA_MSGID_CMD_HW_PANIC:
15584+ case VA_MSGID_CMD_FAILED:
15585+ {
15586+ uint32_t ui32Fence = MEMIO_READ_FIELD (msgBuffer,
15587+ FW_VA_CMD_FAILED_FENCE_VALUE);
15588+ uint32_t ui32FaultStatus = MEMIO_READ_FIELD (msgBuffer,
15589+ FW_VA_CMD_FAILED_IRQSTATUS);
15590+
15591+ if(MEMIO_READ_FIELD (msgBuffer, FWRK_GENMSG_ID) == VA_MSGID_CMD_HW_PANIC )
15592+ PSB_DEBUG_GENERAL
15593+ ("MSVDX: VA_MSGID_CMD_HW_PANIC: Msvdx fault detected - Fence: %08x, Status: %08x - resetting and ignoring error\n",
15594+ ui32Fence, ui32FaultStatus);
15595+ else
15596+ PSB_DEBUG_GENERAL
15597+ ("MSVDX: VA_MSGID_CMD_FAILED: Msvdx fault detected - Fence: %08x, Status: %08x - resetting and ignoring error\n",
15598+ ui32Fence, ui32FaultStatus);
15599+
15600+ dev_priv->msvdx_needs_reset = 1;
15601+
15602+ if(MEMIO_READ_FIELD (msgBuffer, FWRK_GENMSG_ID) == VA_MSGID_CMD_HW_PANIC)
15603+ {
15604+ if (dev_priv->
15605+ msvdx_current_sequence
15606+ - dev_priv->sequence[PSB_ENGINE_VIDEO] > 0x0FFFFFFF)
15607+ dev_priv->msvdx_current_sequence++;
15608+ PSB_DEBUG_GENERAL
15609+ ("MSVDX: Fence ID missing, assuming %08x\n",
15610+ dev_priv->msvdx_current_sequence);
15611+ }
15612+ else
15613+ dev_priv->msvdx_current_sequence = ui32Fence;
15614+
15615+ psb_fence_error (dev,
15616+ PSB_ENGINE_VIDEO,
15617+ dev_priv->
15618+ msvdx_current_sequence,
15619+ DRM_FENCE_TYPE_EXE, DRM_CMD_FAILED);
15620+
15621+ /* Flush the command queue */
15622+ psb_msvdx_flush_cmd_queue (dev);
15623+
15624+ goto isrExit;
15625+ break;
15626+ }
15627+ case VA_MSGID_CMD_COMPLETED:
15628+ {
15629+ uint32_t ui32Fence = MEMIO_READ_FIELD (msgBuffer,
15630+ FW_VA_CMD_COMPLETED_FENCE_VALUE);
15631+ uint32_t ui32Flags =
15632+ MEMIO_READ_FIELD (msgBuffer, FW_VA_CMD_COMPLETED_FLAGS);
15633+
15634+ PSB_DEBUG_GENERAL
15635+ ("msvdx VA_MSGID_CMD_COMPLETED: FenceID: %08x, flags: 0x%x\n",
15636+ ui32Fence, ui32Flags);
15637+ dev_priv->msvdx_current_sequence = ui32Fence;
15638+
15639+ psb_fence_handler (dev, PSB_ENGINE_VIDEO);
15640+
15641+
15642+ if (ui32Flags & FW_VA_RENDER_HOST_INT)
15643+ {
15644+ /*Now send the next command from the msvdx cmd queue */
15645+ psb_msvdx_dequeue_send (dev);
15646+ goto isrExit;
15647+ }
15648+ break;
15649+ }
15650+ case VA_MSGID_ACK:
15651+ PSB_DEBUG_GENERAL ("msvdx VA_MSGID_ACK\n");
15652+ break;
15653+
15654+ case VA_MSGID_TEST1:
15655+ PSB_DEBUG_GENERAL ("msvdx VA_MSGID_TEST1\n");
15656+ break;
15657+
15658+ case VA_MSGID_TEST2:
15659+ PSB_DEBUG_GENERAL ("msvdx VA_MSGID_TEST2\n");
15660+ break;
15661+ /* Don't need to do anything with these messages */
15662+
15663+ case VA_MSGID_DEBLOCK_REQUIRED:
15664+ {
15665+ uint32_t ui32ContextId = MEMIO_READ_FIELD (msgBuffer,
15666+ FW_VA_DEBLOCK_REQUIRED_CONTEXT);
15667+
15668+ /* The BE we now be locked. */
15669+
15670+ /* Unblock rendec by reading the mtx2mtx end of slice */
15671+ (void) PSB_RMSVDX32 (MSVDX_RENDEC_READ_DATA);
15672+
15673+ PSB_DEBUG_GENERAL
15674+ ("msvdx VA_MSGID_DEBLOCK_REQUIRED Context=%08x\n",
15675+ ui32ContextId);
15676+ goto isrExit;
15677+ break;
15678+ }
15679+
15680+ default:
15681+ {
15682+ PSB_DEBUG_GENERAL
15683+ ("ERROR: msvdx Unknown message from MTX \n");
15684+ }
15685+ break;
15686+
15687+ }
15688+ }
15689+ else
15690+ {
15691+ /* Get out of here if nothing */
15692+ break;
15693+ }
15694+ }
15695+isrExit:
15696+
15697+#if 1
15698+ if (!dev_priv->msvdx_busy)
15699+ {
15700+ /* check that clocks are enabled before reading VLR */
15701+ if( PSB_RMSVDX32( MSVDX_MAN_CLK_ENABLE ) != (clk_enable_all) )
15702+ PSB_WMSVDX32 (clk_enable_all, MSVDX_MAN_CLK_ENABLE);
15703+
15704+ /* If the firmware says the hardware is idle and the CCB is empty then we can power down */
15705+ {
15706+ uint32_t ui32FWStatus = PSB_RMSVDX32( MSVDX_COMMS_FW_STATUS );
15707+ uint32_t ui32CCBRoff = PSB_RMSVDX32 ( MSVDX_COMMS_TO_MTX_RD_INDEX );
15708+ uint32_t ui32CCBWoff = PSB_RMSVDX32 ( MSVDX_COMMS_TO_MTX_WRT_INDEX );
15709+
15710+ if( (ui32FWStatus & MSVDX_FW_STATUS_HW_IDLE) && (ui32CCBRoff == ui32CCBWoff))
15711+ {
15712+ PSB_DEBUG_GENERAL("MSVDX_CLOCK: Setting clock to minimal...\n");
15713+ PSB_WMSVDX32 (clk_enable_minimal, MSVDX_MAN_CLK_ENABLE);
15714+ }
15715+ }
15716+ }
15717+#endif
15718+ DRM_MEMORYBARRIER ();
15719+}
15720+
15721+void
15722+psb_msvdx_lockup (struct drm_psb_private *dev_priv,
15723+ int *msvdx_lockup, int *msvdx_idle)
15724+{
15725+ unsigned long irq_flags;
15726+// struct psb_scheduler *scheduler = &dev_priv->scheduler;
15727+
15728+ spin_lock_irqsave (&dev_priv->msvdx_lock, irq_flags);
15729+ *msvdx_lockup = 0;
15730+ *msvdx_idle = 1;
15731+
15732+ if (!dev_priv->has_msvdx)
15733+ {
15734+ spin_unlock_irqrestore (&dev_priv->msvdx_lock, irq_flags);
15735+ return;
15736+ }
15737+#if 0
15738+ PSB_DEBUG_GENERAL ("MSVDXTimer: current_sequence:%d "
15739+ "last_sequence:%d and last_submitted_sequence :%d\n",
15740+ dev_priv->msvdx_current_sequence,
15741+ dev_priv->msvdx_last_sequence,
15742+ dev_priv->sequence[PSB_ENGINE_VIDEO]);
15743+#endif
15744+ if (dev_priv->msvdx_current_sequence -
15745+ dev_priv->sequence[PSB_ENGINE_VIDEO] > 0x0FFFFFFF)
15746+ {
15747+
15748+ if (dev_priv->msvdx_current_sequence == dev_priv->msvdx_last_sequence)
15749+ {
15750+ PSB_DEBUG_GENERAL
15751+ ("MSVDXTimer: msvdx locked-up for sequence:%d\n",
15752+ dev_priv->msvdx_current_sequence);
15753+ *msvdx_lockup = 1;
15754+ }
15755+ else
15756+ {
15757+ PSB_DEBUG_GENERAL ("MSVDXTimer: msvdx responded fine so far...\n");
15758+ dev_priv->msvdx_last_sequence = dev_priv->msvdx_current_sequence;
15759+ *msvdx_idle = 0;
15760+ }
15761+ if (dev_priv->msvdx_start_idle)
15762+ dev_priv->msvdx_start_idle = 0;
15763+ }
15764+ else
15765+ {
15766+ if (dev_priv->msvdx_needs_reset == 0)
15767+ {
15768+ if (dev_priv->msvdx_start_idle && (dev_priv->msvdx_finished_sequence == dev_priv->msvdx_current_sequence))
15769+ {
15770+ //if (dev_priv->msvdx_idle_start_jiffies + MSVDX_MAX_IDELTIME >= jiffies)
15771+ if (time_after_eq(jiffies, dev_priv->msvdx_idle_start_jiffies + MSVDX_MAX_IDELTIME))
15772+ {
15773+ printk("set the msvdx clock to 0 in the %s\n", __FUNCTION__);
15774+ PSB_WMSVDX32 (0, MSVDX_MAN_CLK_ENABLE);
15775+ dev_priv->msvdx_needs_reset = 1;
15776+ }
15777+ else
15778+ {
15779+ *msvdx_idle = 0;
15780+ }
15781+ }
15782+ else
15783+ {
15784+ dev_priv->msvdx_start_idle = 1;
15785+ dev_priv->msvdx_idle_start_jiffies = jiffies;
15786+ dev_priv->msvdx_finished_sequence = dev_priv->msvdx_current_sequence;
15787+ *msvdx_idle = 0;
15788+ }
15789+ }
15790+ }
15791+ spin_unlock_irqrestore (&dev_priv->msvdx_lock, irq_flags);
15792+}
15793Index: linux-2.6.28/drivers/gpu/drm/psb/psb_msvdx.h
15794===================================================================
15795--- /dev/null 1970-01-01 00:00:00.000000000 +0000
15796+++ linux-2.6.28/drivers/gpu/drm/psb/psb_msvdx.h 2009-02-12 09:14:42.000000000 +0000
15797@@ -0,0 +1,564 @@
15798+/**************************************************************************
15799+ *
15800+ * Copyright (c) 2007 Intel Corporation, Hillsboro, OR, USA
15801+ * Copyright (c) Imagination Technologies Limited, UK
15802+ * All Rights Reserved.
15803+ *
15804+ * Permission is hereby granted, free of charge, to any person obtaining a
15805+ * copy of this software and associated documentation files (the
15806+ * "Software"), to deal in the Software without restriction, including
15807+ * without limitation the rights to use, copy, modify, merge, publish,
15808+ * distribute, sub license, and/or sell copies of the Software, and to
15809+ * permit persons to whom the Software is furnished to do so, subject to
15810+ * the following conditions:
15811+ *
15812+ * The above copyright notice and this permission notice (including the
15813+ * next paragraph) shall be included in all copies or substantial portions
15814+ * of the Software.
15815+ *
15816+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15817+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15818+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
15819+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
15820+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
15821+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
15822+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
15823+ *
15824+ **************************************************************************/
15825+
15826+#ifndef _PSB_MSVDX_H_
15827+#define _PSB_MSVDX_H_
15828+
15829+#define assert(expr) \
15830+ if(unlikely(!(expr))) { \
15831+ printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \
15832+ #expr,__FILE__,__FUNCTION__,__LINE__); \
15833+ }
15834+
15835+#define PSB_ASSERT(x) assert (x)
15836+#define IMG_ASSERT(x) assert (x)
15837+
15838+#include "psb_drv.h"
15839+int
15840+psb_wait_for_register (struct drm_psb_private *dev_priv,
15841+ uint32_t ui32Offset,
15842+ uint32_t ui32Value, uint32_t ui32Enable);
15843+
15844+void psb_msvdx_mtx_interrupt (struct drm_device *dev);
15845+int psb_msvdx_init (struct drm_device *dev);
15846+int psb_msvdx_uninit (struct drm_device *dev);
15847+int psb_msvdx_reset (struct drm_psb_private *dev_priv);
15848+uint32_t psb_get_default_pd_addr (struct psb_mmu_driver *driver);
15849+int psb_mtx_send (struct drm_psb_private *dev_priv, const void *pvMsg);
15850+void psb_msvdx_irq_preinstall (struct drm_psb_private *dev_priv);
15851+void psb_msvdx_irq_postinstall (struct drm_psb_private *dev_priv);
15852+void psb_msvdx_flush_cmd_queue (struct drm_device *dev);
15853+extern void psb_msvdx_lockup (struct drm_psb_private *dev_priv,
15854+ int *msvdx_lockup, int *msvdx_idle);
15855+#define MSVDX_DEVICE_NODE_FLAGS_MMU_NONOPT_INV 2 /* Non-Optimal Invalidation is not default */
15856+#define FW_VA_RENDER_HOST_INT 0x00004000
15857+#define MSVDX_DEVICE_NODE_FLAGS_MMU_HW_INVALIDATION 0x00000020
15858+
15859+#define MSVDX_DEVICE_NODE_FLAG_BRN23154_BLOCK_ON_FE 0x00000200
15860+
15861+#define MSVDX_DEVICE_NODE_FLAGS_DEFAULT_D0 (MSVDX_DEVICE_NODE_FLAGS_MMU_NONOPT_INV | MSVDX_DEVICE_NODE_FLAGS_MMU_HW_INVALIDATION \
15862+ | MSVDX_DEVICE_NODE_FLAG_BRN23154_BLOCK_ON_FE)
15863+#define MSVDX_DEVICE_NODE_FLAGS_DEFAULT_D1 (MSVDX_DEVICE_NODE_FLAGS_MMU_HW_INVALIDATION \
15864+ | MSVDX_DEVICE_NODE_FLAG_BRN23154_BLOCK_ON_FE)
15865+
15866+
15867+#define POULSBO_D0 0x5
15868+#define POULSBO_D1 0x6
15869+#define PSB_REVID_OFFSET 0x8
15870+
15871+#define MSVDX_FW_STATUS_HW_IDLE 0x00000001 /* There is no work currently underway on the hardware*/
15872+
15873+#define clk_enable_all MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK | \
15874+ MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_PROCESS_MAN_CLK_ENABLE_MASK | \
15875+ MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_ACCESS_MAN_CLK_ENABLE_MASK | \
15876+ MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDMC_MAN_CLK_ENABLE_MASK | \
15877+ MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ENTDEC_MAN_CLK_ENABLE_MASK | \
15878+ MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ITRANS_MAN_CLK_ENABLE_MASK | \
15879+ MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK
15880+
15881+#define clk_enable_minimal MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK | \
15882+ MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK
15883+
15884+#define clk_enable_auto MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_PROCESS_AUTO_CLK_ENABLE_MASK | \
15885+ MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_ACCESS_AUTO_CLK_ENABLE_MASK | \
15886+ MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDMC_AUTO_CLK_ENABLE_MASK | \
15887+ MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ENTDEC_AUTO_CLK_ENABLE_MASK | \
15888+ MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ITRANS_AUTO_CLK_ENABLE_MASK | \
15889+ MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK | \
15890+ MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK
15891+
15892+#define msvdx_sw_reset_all MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK | \
15893+ MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_FE_SOFT_RESET_MASK | \
15894+ MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_BE_SOFT_RESET_MASK | \
15895+ MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_VEC_MEMIF_SOFT_RESET_MASK | \
15896+ MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_VEC_RENDEC_DEC_SOFT_RESET_MASK
15897+
15898+
15899+#define PCI_PORT5_REG80_FFUSE 0xD0058000
15900+#define MTX_CODE_BASE (0x80900000)
15901+#define MTX_DATA_BASE (0x82880000)
15902+#define PC_START_ADDRESS (0x80900000)
15903+
15904+#define MTX_CORE_CODE_MEM (0x10 )
15905+#define MTX_CORE_DATA_MEM (0x18 )
15906+
15907+#define MTX_INTERNAL_REG( R_SPECIFIER , U_SPECIFIER ) ( ((R_SPECIFIER)<<4) | (U_SPECIFIER) )
15908+#define MTX_PC MTX_INTERNAL_REG( 0 , 5 )
15909+
15910+#define RENDEC_A_SIZE ( 2 * 1024* 1024 )
15911+#define RENDEC_B_SIZE ( RENDEC_A_SIZE / 4 )
15912+
15913+#define MEMIO_READ_FIELD(vpMem, field) \
15914+ ((uint32_t)(((*((field##_TYPE *)(((uint32_t)vpMem) + field##_OFFSET))) & field##_MASK) >> field##_SHIFT))
15915+
15916+#define MEMIO_WRITE_FIELD(vpMem, field, ui32Value) \
15917+ (*((field##_TYPE *)(((uint32_t)vpMem) + field##_OFFSET))) = \
15918+ ((*((field##_TYPE *)(((uint32_t)vpMem) + field##_OFFSET))) & (field##_TYPE)~field##_MASK) | \
15919+ (field##_TYPE)(( (uint32_t) (ui32Value) << field##_SHIFT) & field##_MASK);
15920+
15921+#define MEMIO_WRITE_FIELD_LITE(vpMem, field, ui32Value) \
15922+ (*((field##_TYPE *)(((uint32_t)vpMem) + field##_OFFSET))) = \
15923+ ((*((field##_TYPE *)(((uint32_t)vpMem) + field##_OFFSET))) | \
15924+ (field##_TYPE) (( (uint32_t) (ui32Value) << field##_SHIFT)) );
15925+
15926+#define REGIO_READ_FIELD(ui32RegValue, reg, field) \
15927+ ((ui32RegValue & reg##_##field##_MASK) >> reg##_##field##_SHIFT)
15928+
15929+#define REGIO_WRITE_FIELD(ui32RegValue, reg, field, ui32Value) \
15930+ (ui32RegValue) = \
15931+ ((ui32RegValue) & ~(reg##_##field##_MASK)) | \
15932+ (((ui32Value) << (reg##_##field##_SHIFT)) & (reg##_##field##_MASK));
15933+
15934+#define REGIO_WRITE_FIELD_LITE(ui32RegValue, reg, field, ui32Value) \
15935+ (ui32RegValue) = \
15936+ ( (ui32RegValue) | ( (ui32Value) << (reg##_##field##_SHIFT) ) );
15937+
15938+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK (0x00000001)
15939+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_PROCESS_MAN_CLK_ENABLE_MASK (0x00000002)
15940+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_ACCESS_MAN_CLK_ENABLE_MASK (0x00000004)
15941+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDMC_MAN_CLK_ENABLE_MASK (0x00000008)
15942+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ENTDEC_MAN_CLK_ENABLE_MASK (0x00000010)
15943+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ITRANS_MAN_CLK_ENABLE_MASK (0x00000020)
15944+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK (0x00000040)
15945+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_ACCESS_AUTO_CLK_ENABLE_MASK (0x00040000)
15946+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDMC_AUTO_CLK_ENABLE_MASK (0x00080000)
15947+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ENTDEC_AUTO_CLK_ENABLE_MASK (0x00100000)
15948+#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ITRANS_AUTO_CLK_ENABLE_MASK (0x00200000)
15949+#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK (0x00000100)
15950+#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_FE_SOFT_RESET_MASK (0x00010000)
15951+#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_BE_SOFT_RESET_MASK (0x00100000)
15952+#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_VEC_MEMIF_SOFT_RESET_MASK (0x01000000)
15953+#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_VEC_RENDEC_DEC_SOFT_RESET_MASK (0x10000000)
15954+
15955+/* MTX registers */
15956+#define MSVDX_MTX_ENABLE (0x0000)
15957+#define MSVDX_MTX_KICKI (0x0088)
15958+#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST (0x00FC)
15959+#define MSVDX_MTX_REGISTER_READ_WRITE_DATA (0x00F8)
15960+#define MSVDX_MTX_RAM_ACCESS_DATA_TRANSFER (0x0104)
15961+#define MSVDX_MTX_RAM_ACCESS_CONTROL (0x0108)
15962+#define MSVDX_MTX_RAM_ACCESS_STATUS (0x010C)
15963+#define MSVDX_MTX_SOFT_RESET (0x0200)
15964+
15965+/* MSVDX registers */
15966+#define MSVDX_CONTROL (0x0600)
15967+#define MSVDX_INTERRUPT_CLEAR (0x060C)
15968+#define MSVDX_INTERRUPT_STATUS (0x0608)
15969+#define MSVDX_HOST_INTERRUPT_ENABLE (0x0610)
15970+#define MSVDX_MMU_CONTROL0 (0x0680)
15971+#define MSVDX_MTX_RAM_BANK (0x06F0)
15972+#define MSVDX_MAN_CLK_ENABLE (0x0620)
15973+
15974+/* RENDEC registers */
15975+#define MSVDX_RENDEC_CONTROL0 (0x0868)
15976+#define MSVDX_RENDEC_CONTROL1 (0x086C)
15977+#define MSVDX_RENDEC_BUFFER_SIZE (0x0870)
15978+#define MSVDX_RENDEC_BASE_ADDR0 (0x0874)
15979+#define MSVDX_RENDEC_BASE_ADDR1 (0x0878)
15980+#define MSVDX_RENDEC_READ_DATA (0x0898)
15981+#define MSVDX_RENDEC_CONTEXT0 (0x0950)
15982+#define MSVDX_RENDEC_CONTEXT1 (0x0954)
15983+#define MSVDX_RENDEC_CONTEXT2 (0x0958)
15984+#define MSVDX_RENDEC_CONTEXT3 (0x095C)
15985+#define MSVDX_RENDEC_CONTEXT4 (0x0960)
15986+#define MSVDX_RENDEC_CONTEXT5 (0x0964)
15987+
15988+/*
15989+ * This defines the MSVDX communication buffer
15990+ */
15991+#define MSVDX_COMMS_SIGNATURE_VALUE (0xA5A5A5A5) /*!< Signature value */
15992+#define NUM_WORDS_HOST_BUF (100) /*!< Host buffer size (in 32-bit words) */
15993+#define NUM_WORDS_MTX_BUF (100) /*!< MTX buffer size (in 32-bit words) */
15994+
15995+#define MSVDX_COMMS_AREA_ADDR (0x02cc0)
15996+
15997+#define MSVDX_COMMS_FW_STATUS (MSVDX_COMMS_AREA_ADDR - 0x10)
15998+#define MSVDX_COMMS_SCRATCH (MSVDX_COMMS_AREA_ADDR - 0x08)
15999+#define MSVDX_COMMS_MSG_COUNTER (MSVDX_COMMS_AREA_ADDR - 0x04)
16000+#define MSVDX_COMMS_SIGNATURE (MSVDX_COMMS_AREA_ADDR + 0x00)
16001+#define MSVDX_COMMS_TO_HOST_BUF_SIZE (MSVDX_COMMS_AREA_ADDR + 0x04)
16002+#define MSVDX_COMMS_TO_HOST_RD_INDEX (MSVDX_COMMS_AREA_ADDR + 0x08)
16003+#define MSVDX_COMMS_TO_HOST_WRT_INDEX (MSVDX_COMMS_AREA_ADDR + 0x0C)
16004+#define MSVDX_COMMS_TO_MTX_BUF_SIZE (MSVDX_COMMS_AREA_ADDR + 0x10)
16005+#define MSVDX_COMMS_TO_MTX_RD_INDEX (MSVDX_COMMS_AREA_ADDR + 0x14)
16006+#define MSVDX_COMMS_OFFSET_FLAGS (MSVDX_COMMS_AREA_ADDR + 0x18)
16007+#define MSVDX_COMMS_TO_MTX_WRT_INDEX (MSVDX_COMMS_AREA_ADDR + 0x1C)
16008+#define MSVDX_COMMS_TO_HOST_BUF (MSVDX_COMMS_AREA_ADDR + 0x20)
16009+#define MSVDX_COMMS_TO_MTX_BUF (MSVDX_COMMS_TO_HOST_BUF + (NUM_WORDS_HOST_BUF << 2))
16010+
16011+#define MSVDX_COMMS_AREA_END (MSVDX_COMMS_TO_MTX_BUF + (NUM_WORDS_HOST_BUF << 2))
16012+
16013+#if (MSVDX_COMMS_AREA_END != 0x03000)
16014+#error
16015+#endif
16016+
16017+#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK (0x80000000)
16018+#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_SHIFT (31)
16019+
16020+#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_RNW_MASK (0x00010000)
16021+#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_RNW_SHIFT (16)
16022+
16023+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMID_MASK (0x0FF00000)
16024+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMID_SHIFT (20)
16025+
16026+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCM_ADDR_MASK (0x000FFFFC)
16027+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCM_ADDR_SHIFT (2)
16028+
16029+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMAI_MASK (0x00000002)
16030+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMAI_SHIFT (1)
16031+
16032+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMR_MASK (0x00000001)
16033+#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMR_SHIFT (0)
16034+
16035+#define MSVDX_MTX_SOFT_RESET_MTX_RESET_MASK (0x00000001)
16036+#define MSVDX_MTX_SOFT_RESET_MTX_RESET_SHIFT (0)
16037+
16038+#define MSVDX_MTX_ENABLE_MTX_ENABLE_MASK (0x00000001)
16039+#define MSVDX_MTX_ENABLE_MTX_ENABLE_SHIFT (0)
16040+
16041+#define MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK (0x00000100)
16042+#define MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_SHIFT (8)
16043+
16044+#define MSVDX_INTERRUPT_STATUS_CR_MMU_FAULT_IRQ_MASK (0x00000F00)
16045+#define MSVDX_INTERRUPT_STATUS_CR_MMU_FAULT_IRQ_SHIFT (8)
16046+
16047+#define MSVDX_INTERRUPT_STATUS_CR_MTX_IRQ_MASK (0x00004000)
16048+#define MSVDX_INTERRUPT_STATUS_CR_MTX_IRQ_SHIFT (14)
16049+
16050+#define MSVDX_MMU_CONTROL0_CR_MMU_PAUSE_MASK (0x00000002)
16051+#define MSVDX_MMU_CONTROL0_CR_MMU_PAUSE_SHIFT (1)
16052+
16053+#define MSVDX_MTX_RAM_BANK_CR_MTX_RAM_BANK_SIZE_MASK (0x000F0000)
16054+#define MSVDX_MTX_RAM_BANK_CR_MTX_RAM_BANK_SIZE_SHIFT (16)
16055+
16056+#define MSVDX_RENDEC_BUFFER_SIZE_RENDEC_BUFFER_SIZE0_MASK (0x0000FFFF)
16057+#define MSVDX_RENDEC_BUFFER_SIZE_RENDEC_BUFFER_SIZE0_SHIFT (0)
16058+
16059+#define MSVDX_RENDEC_BUFFER_SIZE_RENDEC_BUFFER_SIZE1_MASK (0xFFFF0000)
16060+#define MSVDX_RENDEC_BUFFER_SIZE_RENDEC_BUFFER_SIZE1_SHIFT (16)
16061+
16062+#define MSVDX_RENDEC_CONTROL1_RENDEC_DECODE_START_SIZE_MASK (0x000000FF)
16063+#define MSVDX_RENDEC_CONTROL1_RENDEC_DECODE_START_SIZE_SHIFT (0)
16064+
16065+#define MSVDX_RENDEC_CONTROL1_RENDEC_BURST_SIZE_W_MASK (0x000C0000)
16066+#define MSVDX_RENDEC_CONTROL1_RENDEC_BURST_SIZE_W_SHIFT (18)
16067+
16068+#define MSVDX_RENDEC_CONTROL1_RENDEC_BURST_SIZE_R_MASK (0x00030000)
16069+#define MSVDX_RENDEC_CONTROL1_RENDEC_BURST_SIZE_R_SHIFT (16)
16070+
16071+#define MSVDX_RENDEC_CONTROL1_RENDEC_EXTERNAL_MEMORY_MASK (0x01000000)
16072+#define MSVDX_RENDEC_CONTROL1_RENDEC_EXTERNAL_MEMORY_SHIFT (24)
16073+
16074+#define MSVDX_RENDEC_CONTROL0_RENDEC_INITIALISE_MASK (0x00000001)
16075+#define MSVDX_RENDEC_CONTROL0_RENDEC_INITIALISE_SHIFT (0)
16076+
16077+#define FWRK_MSGID_START_PSR_HOSTMTX_MSG (0x80) /*!< Start of parser specific Host->MTX messages. */
16078+#define FWRK_MSGID_START_PSR_MTXHOST_MSG (0xC0) /*!< Start of parser specific MTX->Host messages. */
16079+#define FWRK_MSGID_PADDING ( 0 )
16080+
16081+#define FWRK_GENMSG_SIZE_TYPE uint8_t
16082+#define FWRK_GENMSG_SIZE_MASK (0xFF)
16083+#define FWRK_GENMSG_SIZE_SHIFT (0)
16084+#define FWRK_GENMSG_SIZE_OFFSET (0x0000)
16085+#define FWRK_GENMSG_ID_TYPE uint8_t
16086+#define FWRK_GENMSG_ID_MASK (0xFF)
16087+#define FWRK_GENMSG_ID_SHIFT (0)
16088+#define FWRK_GENMSG_ID_OFFSET (0x0001)
16089+#define FWRK_PADMSG_SIZE (2)
16090+
16091+/*!
16092+******************************************************************************
16093+ This type defines the framework specified message ids
16094+******************************************************************************/
16095+enum
16096+{
16097+ /*! Sent by the DXVA driver on the host to the mtx firmware.
16098+ */
16099+ VA_MSGID_INIT = FWRK_MSGID_START_PSR_HOSTMTX_MSG,
16100+ VA_MSGID_RENDER,
16101+ VA_MSGID_DEBLOCK,
16102+ VA_MSGID_OOLD,
16103+
16104+ /* Test Messages */
16105+ VA_MSGID_TEST1,
16106+ VA_MSGID_TEST2,
16107+
16108+ /*! Sent by the mtx firmware to itself.
16109+ */
16110+ VA_MSGID_RENDER_MC_INTERRUPT,
16111+
16112+ /*! Sent by the DXVA firmware on the MTX to the host.
16113+ */
16114+ VA_MSGID_CMD_COMPLETED = FWRK_MSGID_START_PSR_MTXHOST_MSG,
16115+ VA_MSGID_CMD_COMPLETED_BATCH,
16116+ VA_MSGID_DEBLOCK_REQUIRED,
16117+ VA_MSGID_TEST_RESPONCE,
16118+ VA_MSGID_ACK,
16119+
16120+ VA_MSGID_CMD_FAILED,
16121+ VA_MSGID_CMD_UNSUPPORTED,
16122+ VA_MSGID_CMD_HW_PANIC,
16123+};
16124+
16125+/* MSVDX Firmware interface */
16126+
16127+#define FW_VA_RENDER_SIZE (32)
16128+
16129+// FW_VA_RENDER MSG_SIZE
16130+#define FW_VA_RENDER_MSG_SIZE_ALIGNMENT (1)
16131+#define FW_VA_RENDER_MSG_SIZE_TYPE uint8_t
16132+#define FW_VA_RENDER_MSG_SIZE_MASK (0xFF)
16133+#define FW_VA_RENDER_MSG_SIZE_LSBMASK (0xFF)
16134+#define FW_VA_RENDER_MSG_SIZE_OFFSET (0x0000)
16135+#define FW_VA_RENDER_MSG_SIZE_SHIFT (0)
16136+
16137+// FW_VA_RENDER ID
16138+#define FW_VA_RENDER_ID_ALIGNMENT (1)
16139+#define FW_VA_RENDER_ID_TYPE uint8_t
16140+#define FW_VA_RENDER_ID_MASK (0xFF)
16141+#define FW_VA_RENDER_ID_LSBMASK (0xFF)
16142+#define FW_VA_RENDER_ID_OFFSET (0x0001)
16143+#define FW_VA_RENDER_ID_SHIFT (0)
16144+
16145+// FW_VA_RENDER BUFFER_SIZE
16146+#define FW_VA_RENDER_BUFFER_SIZE_ALIGNMENT (2)
16147+#define FW_VA_RENDER_BUFFER_SIZE_TYPE uint16_t
16148+#define FW_VA_RENDER_BUFFER_SIZE_MASK (0x0FFF)
16149+#define FW_VA_RENDER_BUFFER_SIZE_LSBMASK (0x0FFF)
16150+#define FW_VA_RENDER_BUFFER_SIZE_OFFSET (0x0002)
16151+#define FW_VA_RENDER_BUFFER_SIZE_SHIFT (0)
16152+
16153+// FW_VA_RENDER MMUPTD
16154+#define FW_VA_RENDER_MMUPTD_ALIGNMENT (4)
16155+#define FW_VA_RENDER_MMUPTD_TYPE uint32_t
16156+#define FW_VA_RENDER_MMUPTD_MASK (0xFFFFFFFF)
16157+#define FW_VA_RENDER_MMUPTD_LSBMASK (0xFFFFFFFF)
16158+#define FW_VA_RENDER_MMUPTD_OFFSET (0x0004)
16159+#define FW_VA_RENDER_MMUPTD_SHIFT (0)
16160+
16161+// FW_VA_RENDER LLDMA_ADDRESS
16162+#define FW_VA_RENDER_LLDMA_ADDRESS_ALIGNMENT (4)
16163+#define FW_VA_RENDER_LLDMA_ADDRESS_TYPE uint32_t
16164+#define FW_VA_RENDER_LLDMA_ADDRESS_MASK (0xFFFFFFFF)
16165+#define FW_VA_RENDER_LLDMA_ADDRESS_LSBMASK (0xFFFFFFFF)
16166+#define FW_VA_RENDER_LLDMA_ADDRESS_OFFSET (0x0008)
16167+#define FW_VA_RENDER_LLDMA_ADDRESS_SHIFT (0)
16168+
16169+// FW_VA_RENDER CONTEXT
16170+#define FW_VA_RENDER_CONTEXT_ALIGNMENT (4)
16171+#define FW_VA_RENDER_CONTEXT_TYPE uint32_t
16172+#define FW_VA_RENDER_CONTEXT_MASK (0xFFFFFFFF)
16173+#define FW_VA_RENDER_CONTEXT_LSBMASK (0xFFFFFFFF)
16174+#define FW_VA_RENDER_CONTEXT_OFFSET (0x000C)
16175+#define FW_VA_RENDER_CONTEXT_SHIFT (0)
16176+
16177+// FW_VA_RENDER FENCE_VALUE
16178+#define FW_VA_RENDER_FENCE_VALUE_ALIGNMENT (4)
16179+#define FW_VA_RENDER_FENCE_VALUE_TYPE uint32_t
16180+#define FW_VA_RENDER_FENCE_VALUE_MASK (0xFFFFFFFF)
16181+#define FW_VA_RENDER_FENCE_VALUE_LSBMASK (0xFFFFFFFF)
16182+#define FW_VA_RENDER_FENCE_VALUE_OFFSET (0x0010)
16183+#define FW_VA_RENDER_FENCE_VALUE_SHIFT (0)
16184+
16185+// FW_VA_RENDER OPERATING_MODE
16186+#define FW_VA_RENDER_OPERATING_MODE_ALIGNMENT (4)
16187+#define FW_VA_RENDER_OPERATING_MODE_TYPE uint32_t
16188+#define FW_VA_RENDER_OPERATING_MODE_MASK (0xFFFFFFFF)
16189+#define FW_VA_RENDER_OPERATING_MODE_LSBMASK (0xFFFFFFFF)
16190+#define FW_VA_RENDER_OPERATING_MODE_OFFSET (0x0014)
16191+#define FW_VA_RENDER_OPERATING_MODE_SHIFT (0)
16192+
16193+// FW_VA_RENDER FIRST_MB_IN_SLICE
16194+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_ALIGNMENT (2)
16195+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_TYPE uint16_t
16196+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_MASK (0xFFFF)
16197+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_LSBMASK (0xFFFF)
16198+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_OFFSET (0x0018)
16199+#define FW_VA_RENDER_FIRST_MB_IN_SLICE_SHIFT (0)
16200+
16201+// FW_VA_RENDER LAST_MB_IN_FRAME
16202+#define FW_VA_RENDER_LAST_MB_IN_FRAME_ALIGNMENT (2)
16203+#define FW_VA_RENDER_LAST_MB_IN_FRAME_TYPE uint16_t
16204+#define FW_VA_RENDER_LAST_MB_IN_FRAME_MASK (0xFFFF)
16205+#define FW_VA_RENDER_LAST_MB_IN_FRAME_LSBMASK (0xFFFF)
16206+#define FW_VA_RENDER_LAST_MB_IN_FRAME_OFFSET (0x001A)
16207+#define FW_VA_RENDER_LAST_MB_IN_FRAME_SHIFT (0)
16208+
16209+// FW_VA_RENDER FLAGS
16210+#define FW_VA_RENDER_FLAGS_ALIGNMENT (4)
16211+#define FW_VA_RENDER_FLAGS_TYPE uint32_t
16212+#define FW_VA_RENDER_FLAGS_MASK (0xFFFFFFFF)
16213+#define FW_VA_RENDER_FLAGS_LSBMASK (0xFFFFFFFF)
16214+#define FW_VA_RENDER_FLAGS_OFFSET (0x001C)
16215+#define FW_VA_RENDER_FLAGS_SHIFT (0)
16216+
16217+#define FW_VA_CMD_COMPLETED_SIZE (12)
16218+
16219+// FW_VA_CMD_COMPLETED MSG_SIZE
16220+#define FW_VA_CMD_COMPLETED_MSG_SIZE_ALIGNMENT (1)
16221+#define FW_VA_CMD_COMPLETED_MSG_SIZE_TYPE uint8_t
16222+#define FW_VA_CMD_COMPLETED_MSG_SIZE_MASK (0xFF)
16223+#define FW_VA_CMD_COMPLETED_MSG_SIZE_LSBMASK (0xFF)
16224+#define FW_VA_CMD_COMPLETED_MSG_SIZE_OFFSET (0x0000)
16225+#define FW_VA_CMD_COMPLETED_MSG_SIZE_SHIFT (0)
16226+
16227+// FW_VA_CMD_COMPLETED ID
16228+#define FW_VA_CMD_COMPLETED_ID_ALIGNMENT (1)
16229+#define FW_VA_CMD_COMPLETED_ID_TYPE uint8_t
16230+#define FW_VA_CMD_COMPLETED_ID_MASK (0xFF)
16231+#define FW_VA_CMD_COMPLETED_ID_LSBMASK (0xFF)
16232+#define FW_VA_CMD_COMPLETED_ID_OFFSET (0x0001)
16233+#define FW_VA_CMD_COMPLETED_ID_SHIFT (0)
16234+
16235+// FW_VA_CMD_COMPLETED FENCE_VALUE
16236+#define FW_VA_CMD_COMPLETED_FENCE_VALUE_ALIGNMENT (4)
16237+#define FW_VA_CMD_COMPLETED_FENCE_VALUE_TYPE uint32_t
16238+#define FW_VA_CMD_COMPLETED_FENCE_VALUE_MASK (0xFFFFFFFF)
16239+#define FW_VA_CMD_COMPLETED_FENCE_VALUE_LSBMASK (0xFFFFFFFF)
16240+#define FW_VA_CMD_COMPLETED_FENCE_VALUE_OFFSET (0x0004)
16241+#define FW_VA_CMD_COMPLETED_FENCE_VALUE_SHIFT (0)
16242+
16243+// FW_VA_CMD_COMPLETED FLAGS
16244+#define FW_VA_CMD_COMPLETED_FLAGS_ALIGNMENT (4)
16245+#define FW_VA_CMD_COMPLETED_FLAGS_TYPE uint32_t
16246+#define FW_VA_CMD_COMPLETED_FLAGS_MASK (0xFFFFFFFF)
16247+#define FW_VA_CMD_COMPLETED_FLAGS_LSBMASK (0xFFFFFFFF)
16248+#define FW_VA_CMD_COMPLETED_FLAGS_OFFSET (0x0008)
16249+#define FW_VA_CMD_COMPLETED_FLAGS_SHIFT (0)
16250+
16251+#define FW_VA_CMD_FAILED_SIZE (12)
16252+
16253+// FW_VA_CMD_FAILED MSG_SIZE
16254+#define FW_VA_CMD_FAILED_MSG_SIZE_ALIGNMENT (1)
16255+#define FW_VA_CMD_FAILED_MSG_SIZE_TYPE uint8_t
16256+#define FW_VA_CMD_FAILED_MSG_SIZE_MASK (0xFF)
16257+#define FW_VA_CMD_FAILED_MSG_SIZE_LSBMASK (0xFF)
16258+#define FW_VA_CMD_FAILED_MSG_SIZE_OFFSET (0x0000)
16259+#define FW_VA_CMD_FAILED_MSG_SIZE_SHIFT (0)
16260+
16261+// FW_VA_CMD_FAILED ID
16262+#define FW_VA_CMD_FAILED_ID_ALIGNMENT (1)
16263+#define FW_VA_CMD_FAILED_ID_TYPE uint8_t
16264+#define FW_VA_CMD_FAILED_ID_MASK (0xFF)
16265+#define FW_VA_CMD_FAILED_ID_LSBMASK (0xFF)
16266+#define FW_VA_CMD_FAILED_ID_OFFSET (0x0001)
16267+#define FW_VA_CMD_FAILED_ID_SHIFT (0)
16268+
16269+// FW_VA_CMD_FAILED FLAGS
16270+#define FW_VA_CMD_FAILED_FLAGS_ALIGNMENT (2)
16271+#define FW_VA_CMD_FAILED_FLAGS_TYPE uint16_t
16272+#define FW_VA_CMD_FAILED_FLAGS_MASK (0xFFFF)
16273+#define FW_VA_CMD_FAILED_FLAGS_LSBMASK (0xFFFF)
16274+#define FW_VA_CMD_FAILED_FLAGS_OFFSET (0x0002)
16275+#define FW_VA_CMD_FAILED_FLAGS_SHIFT (0)
16276+
16277+// FW_VA_CMD_FAILED FENCE_VALUE
16278+#define FW_VA_CMD_FAILED_FENCE_VALUE_ALIGNMENT (4)
16279+#define FW_VA_CMD_FAILED_FENCE_VALUE_TYPE uint32_t
16280+#define FW_VA_CMD_FAILED_FENCE_VALUE_MASK (0xFFFFFFFF)
16281+#define FW_VA_CMD_FAILED_FENCE_VALUE_LSBMASK (0xFFFFFFFF)
16282+#define FW_VA_CMD_FAILED_FENCE_VALUE_OFFSET (0x0004)
16283+#define FW_VA_CMD_FAILED_FENCE_VALUE_SHIFT (0)
16284+
16285+// FW_VA_CMD_FAILED IRQSTATUS
16286+#define FW_VA_CMD_FAILED_IRQSTATUS_ALIGNMENT (4)
16287+#define FW_VA_CMD_FAILED_IRQSTATUS_TYPE uint32_t
16288+#define FW_VA_CMD_FAILED_IRQSTATUS_MASK (0xFFFFFFFF)
16289+#define FW_VA_CMD_FAILED_IRQSTATUS_LSBMASK (0xFFFFFFFF)
16290+#define FW_VA_CMD_FAILED_IRQSTATUS_OFFSET (0x0008)
16291+#define FW_VA_CMD_FAILED_IRQSTATUS_SHIFT (0)
16292+
16293+#define FW_VA_DEBLOCK_REQUIRED_SIZE (8)
16294+
16295+// FW_VA_DEBLOCK_REQUIRED MSG_SIZE
16296+#define FW_VA_DEBLOCK_REQUIRED_MSG_SIZE_ALIGNMENT (1)
16297+#define FW_VA_DEBLOCK_REQUIRED_MSG_SIZE_TYPE uint8_t
16298+#define FW_VA_DEBLOCK_REQUIRED_MSG_SIZE_MASK (0xFF)
16299+#define FW_VA_DEBLOCK_REQUIRED_MSG_SIZE_LSBMASK (0xFF)
16300+#define FW_VA_DEBLOCK_REQUIRED_MSG_SIZE_OFFSET (0x0000)
16301+#define FW_VA_DEBLOCK_REQUIRED_MSG_SIZE_SHIFT (0)
16302+
16303+// FW_VA_DEBLOCK_REQUIRED ID
16304+#define FW_VA_DEBLOCK_REQUIRED_ID_ALIGNMENT (1)
16305+#define FW_VA_DEBLOCK_REQUIRED_ID_TYPE uint8_t
16306+#define FW_VA_DEBLOCK_REQUIRED_ID_MASK (0xFF)
16307+#define FW_VA_DEBLOCK_REQUIRED_ID_LSBMASK (0xFF)
16308+#define FW_VA_DEBLOCK_REQUIRED_ID_OFFSET (0x0001)
16309+#define FW_VA_DEBLOCK_REQUIRED_ID_SHIFT (0)
16310+
16311+// FW_VA_DEBLOCK_REQUIRED CONTEXT
16312+#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_ALIGNMENT (4)
16313+#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_TYPE uint32_t
16314+#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_MASK (0xFFFFFFFF)
16315+#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_LSBMASK (0xFFFFFFFF)
16316+#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_OFFSET (0x0004)
16317+#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_SHIFT (0)
16318+
16319+#define FW_VA_HW_PANIC_SIZE (12)
16320+
16321+// FW_VA_HW_PANIC FLAGS
16322+#define FW_VA_HW_PANIC_FLAGS_ALIGNMENT (2)
16323+#define FW_VA_HW_PANIC_FLAGS_TYPE uint16_t
16324+#define FW_VA_HW_PANIC_FLAGS_MASK (0xFFFF)
16325+#define FW_VA_HW_PANIC_FLAGS_LSBMASK (0xFFFF)
16326+#define FW_VA_HW_PANIC_FLAGS_OFFSET (0x0002)
16327+#define FW_VA_HW_PANIC_FLAGS_SHIFT (0)
16328+
16329+// FW_VA_HW_PANIC MSG_SIZE
16330+#define FW_VA_HW_PANIC_MSG_SIZE_ALIGNMENT (1)
16331+#define FW_VA_HW_PANIC_MSG_SIZE_TYPE uint8_t
16332+#define FW_VA_HW_PANIC_MSG_SIZE_MASK (0xFF)
16333+#define FW_VA_HW_PANIC_MSG_SIZE_LSBMASK (0xFF)
16334+#define FW_VA_HW_PANIC_MSG_SIZE_OFFSET (0x0000)
16335+#define FW_VA_HW_PANIC_MSG_SIZE_SHIFT (0)
16336+
16337+// FW_VA_HW_PANIC ID
16338+#define FW_VA_HW_PANIC_ID_ALIGNMENT (1)
16339+#define FW_VA_HW_PANIC_ID_TYPE uint8_t
16340+#define FW_VA_HW_PANIC_ID_MASK (0xFF)
16341+#define FW_VA_HW_PANIC_ID_LSBMASK (0xFF)
16342+#define FW_VA_HW_PANIC_ID_OFFSET (0x0001)
16343+#define FW_VA_HW_PANIC_ID_SHIFT (0)
16344+
16345+// FW_VA_HW_PANIC FENCE_VALUE
16346+#define FW_VA_HW_PANIC_FENCE_VALUE_ALIGNMENT (4)
16347+#define FW_VA_HW_PANIC_FENCE_VALUE_TYPE uint32_t
16348+#define FW_VA_HW_PANIC_FENCE_VALUE_MASK (0xFFFFFFFF)
16349+#define FW_VA_HW_PANIC_FENCE_VALUE_LSBMASK (0xFFFFFFFF)
16350+#define FW_VA_HW_PANIC_FENCE_VALUE_OFFSET (0x0004)
16351+#define FW_VA_HW_PANIC_FENCE_VALUE_SHIFT (0)
16352+
16353+// FW_VA_HW_PANIC IRQSTATUS
16354+#define FW_VA_HW_PANIC_IRQSTATUS_ALIGNMENT (4)
16355+#define FW_VA_HW_PANIC_IRQSTATUS_TYPE uint32_t
16356+#define FW_VA_HW_PANIC_IRQSTATUS_MASK (0xFFFFFFFF)
16357+#define FW_VA_HW_PANIC_IRQSTATUS_LSBMASK (0xFFFFFFFF)
16358+#define FW_VA_HW_PANIC_IRQSTATUS_OFFSET (0x0008)
16359+#define FW_VA_HW_PANIC_IRQSTATUS_SHIFT (0)
16360+
16361+#endif
16362Index: linux-2.6.28/drivers/gpu/drm/psb/psb_msvdxinit.c
16363===================================================================
16364--- /dev/null 1970-01-01 00:00:00.000000000 +0000
16365+++ linux-2.6.28/drivers/gpu/drm/psb/psb_msvdxinit.c 2009-02-12 09:14:42.000000000 +0000
16366@@ -0,0 +1,625 @@
16367+/**
16368+ * file psb_msvdxinit.c
16369+ * MSVDX initialization and mtx-firmware upload
16370+ *
16371+ */
16372+
16373+/**************************************************************************
16374+ *
16375+ * Copyright (c) 2007 Intel Corporation, Hillsboro, OR, USA
16376+ * Copyright (c) Imagination Technologies Limited, UK
16377+ * All Rights Reserved.
16378+ *
16379+ * Permission is hereby granted, free of charge, to any person obtaining a
16380+ * copy of this software and associated documentation files (the
16381+ * "Software"), to deal in the Software without restriction, including
16382+ * without limitation the rights to use, copy, modify, merge, publish,
16383+ * distribute, sub license, and/or sell copies of the Software, and to
16384+ * permit persons to whom the Software is furnished to do so, subject to
16385+ * the following conditions:
16386+ *
16387+ * The above copyright notice and this permission notice (including the
16388+ * next paragraph) shall be included in all copies or substantial portions
16389+ * of the Software.
16390+ *
16391+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16392+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16393+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16394+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
16395+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16396+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
16397+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
16398+ *
16399+ **************************************************************************/
16400+
16401+#include "drmP.h"
16402+#include "drm.h"
16403+#include "psb_drv.h"
16404+#include "psb_msvdx.h"
16405+#include <linux/firmware.h>
16406+
16407+/*MSVDX FW header*/
16408+struct msvdx_fw
16409+{
16410+ uint32_t ver;
16411+ uint32_t text_size;
16412+ uint32_t data_size;
16413+ uint32_t data_location;
16414+};
16415+
16416+int
16417+psb_wait_for_register (struct drm_psb_private *dev_priv,
16418+ uint32_t ui32Offset,
16419+ uint32_t ui32Value, uint32_t ui32Enable)
16420+{
16421+ uint32_t ui32Temp;
16422+ uint32_t ui32PollCount = 1000;
16423+ while (ui32PollCount)
16424+ {
16425+ ui32Temp = PSB_RMSVDX32 (ui32Offset);
16426+ if (ui32Value == (ui32Temp & ui32Enable)) /* All the bits are reset */
16427+ return 0; /* So exit */
16428+
16429+ /* Wait a bit */
16430+ DRM_UDELAY (100);
16431+ ui32PollCount--;
16432+ }
16433+ PSB_DEBUG_GENERAL
16434+ ("MSVDX: Timeout while waiting for register %08x: expecting %08x (mask %08x), got %08x\n",
16435+ ui32Offset, ui32Value, ui32Enable, ui32Temp);
16436+ return 1;
16437+}
16438+
16439+int
16440+psb_poll_mtx_irq (struct drm_psb_private *dev_priv)
16441+{
16442+ int ret = 0;
16443+ uint32_t MtxInt = 0;
16444+ REGIO_WRITE_FIELD_LITE (MtxInt, MSVDX_INTERRUPT_STATUS, CR_MTX_IRQ, 1);
16445+
16446+ ret = psb_wait_for_register (dev_priv, MSVDX_INTERRUPT_STATUS, MtxInt, /* Required value */
16447+ MtxInt /* Enabled bits */ );
16448+ if (ret)
16449+ {
16450+ PSB_DEBUG_GENERAL
16451+ ("MSVDX: Error Mtx did not return int within a resonable time\n");
16452+
16453+ return ret;
16454+ }
16455+
16456+ PSB_DEBUG_GENERAL ("MSVDX: Got MTX Int\n");
16457+
16458+ /* Got it so clear the bit */
16459+ PSB_WMSVDX32 (MtxInt, MSVDX_INTERRUPT_CLEAR);
16460+
16461+ return ret;
16462+}
16463+
16464+void
16465+psb_write_mtx_core_reg (struct drm_psb_private *dev_priv,
16466+ const uint32_t ui32CoreRegister,
16467+ const uint32_t ui32Val)
16468+{
16469+ uint32_t ui32Reg = 0;
16470+
16471+ /* Put data in MTX_RW_DATA */
16472+ PSB_WMSVDX32 (ui32Val, MSVDX_MTX_REGISTER_READ_WRITE_DATA);
16473+
16474+ /* DREADY is set to 0 and request a write */
16475+ ui32Reg = ui32CoreRegister;
16476+ REGIO_WRITE_FIELD_LITE (ui32Reg, MSVDX_MTX_REGISTER_READ_WRITE_REQUEST,
16477+ MTX_RNW, 0);
16478+ REGIO_WRITE_FIELD_LITE (ui32Reg, MSVDX_MTX_REGISTER_READ_WRITE_REQUEST,
16479+ MTX_DREADY, 0);
16480+ PSB_WMSVDX32 (ui32Reg, MSVDX_MTX_REGISTER_READ_WRITE_REQUEST);
16481+
16482+ psb_wait_for_register (dev_priv, MSVDX_MTX_REGISTER_READ_WRITE_REQUEST, MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK, /* Required Value */
16483+ MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK);
16484+}
16485+
16486+void
16487+psb_upload_fw (struct drm_psb_private *dev_priv, const uint32_t ui32DataMem,
16488+ uint32_t ui32RamBankSize, uint32_t ui32Address,
16489+ const unsigned int uiWords, const uint32_t * const pui32Data)
16490+{
16491+ uint32_t ui32Loop, ui32Ctrl, ui32RamId, ui32Addr, ui32CurrBank =
16492+ (uint32_t) ~ 0;
16493+ uint32_t ui32AccessControl;
16494+
16495+ /* Save the access control register... */
16496+ ui32AccessControl = PSB_RMSVDX32 (MSVDX_MTX_RAM_ACCESS_CONTROL);
16497+
16498+ /* Wait for MCMSTAT to become be idle 1 */
16499+ psb_wait_for_register (dev_priv, MSVDX_MTX_RAM_ACCESS_STATUS, 1, /* Required Value */
16500+ 0xffffffff /* Enables */ );
16501+
16502+ for (ui32Loop = 0; ui32Loop < uiWords; ui32Loop++)
16503+ {
16504+ ui32RamId = ui32DataMem + (ui32Address / ui32RamBankSize);
16505+
16506+ if (ui32RamId != ui32CurrBank)
16507+ {
16508+ ui32Addr = ui32Address >> 2;
16509+
16510+ ui32Ctrl = 0;
16511+
16512+ REGIO_WRITE_FIELD_LITE (ui32Ctrl,
16513+ MSVDX_MTX_RAM_ACCESS_CONTROL,
16514+ MTX_MCMID, ui32RamId);
16515+ REGIO_WRITE_FIELD_LITE (ui32Ctrl,
16516+ MSVDX_MTX_RAM_ACCESS_CONTROL,
16517+ MTX_MCM_ADDR, ui32Addr);
16518+ REGIO_WRITE_FIELD_LITE (ui32Ctrl,
16519+ MSVDX_MTX_RAM_ACCESS_CONTROL, MTX_MCMAI, 1);
16520+
16521+ PSB_WMSVDX32 (ui32Ctrl, MSVDX_MTX_RAM_ACCESS_CONTROL);
16522+
16523+ ui32CurrBank = ui32RamId;
16524+ }
16525+ ui32Address += 4;
16526+
16527+ PSB_WMSVDX32 (pui32Data[ui32Loop], MSVDX_MTX_RAM_ACCESS_DATA_TRANSFER);
16528+
16529+ /* Wait for MCMSTAT to become be idle 1 */
16530+ psb_wait_for_register (dev_priv, MSVDX_MTX_RAM_ACCESS_STATUS, 1, /* Required Value */
16531+ 0xffffffff /* Enables */ );
16532+ }
16533+ PSB_DEBUG_GENERAL ("MSVDX: Upload done\n");
16534+
16535+ /* Restore the access control register... */
16536+ PSB_WMSVDX32 (ui32AccessControl, MSVDX_MTX_RAM_ACCESS_CONTROL);
16537+}
16538+
16539+static int
16540+psb_verify_fw (struct drm_psb_private *dev_priv,
16541+ const uint32_t ui32RamBankSize,
16542+ const uint32_t ui32DataMem, uint32_t ui32Address,
16543+ const uint32_t uiWords, const uint32_t * const pui32Data)
16544+{
16545+ uint32_t ui32Loop, ui32Ctrl, ui32RamId, ui32Addr, ui32CurrBank =
16546+ (uint32_t) ~ 0;
16547+ uint32_t ui32AccessControl;
16548+ int ret = 0;
16549+
16550+ /* Save the access control register... */
16551+ ui32AccessControl = PSB_RMSVDX32 (MSVDX_MTX_RAM_ACCESS_CONTROL);
16552+
16553+ /* Wait for MCMSTAT to become be idle 1 */
16554+ psb_wait_for_register (dev_priv, MSVDX_MTX_RAM_ACCESS_STATUS, 1, /* Required Value */
16555+ 0xffffffff /* Enables */ );
16556+
16557+ for (ui32Loop = 0; ui32Loop < uiWords; ui32Loop++)
16558+ {
16559+ uint32_t ui32ReadBackVal;
16560+ ui32RamId = ui32DataMem + (ui32Address / ui32RamBankSize);
16561+
16562+ if (ui32RamId != ui32CurrBank)
16563+ {
16564+ ui32Addr = ui32Address >> 2;
16565+ ui32Ctrl = 0;
16566+ REGIO_WRITE_FIELD_LITE (ui32Ctrl,
16567+ MSVDX_MTX_RAM_ACCESS_CONTROL,
16568+ MTX_MCMID, ui32RamId);
16569+ REGIO_WRITE_FIELD_LITE (ui32Ctrl,
16570+ MSVDX_MTX_RAM_ACCESS_CONTROL,
16571+ MTX_MCM_ADDR, ui32Addr);
16572+ REGIO_WRITE_FIELD_LITE (ui32Ctrl,
16573+ MSVDX_MTX_RAM_ACCESS_CONTROL, MTX_MCMAI, 1);
16574+ REGIO_WRITE_FIELD_LITE (ui32Ctrl,
16575+ MSVDX_MTX_RAM_ACCESS_CONTROL, MTX_MCMR, 1);
16576+
16577+ PSB_WMSVDX32 (ui32Ctrl, MSVDX_MTX_RAM_ACCESS_CONTROL);
16578+
16579+ ui32CurrBank = ui32RamId;
16580+ }
16581+ ui32Address += 4;
16582+
16583+ /* Wait for MCMSTAT to become be idle 1 */
16584+ psb_wait_for_register (dev_priv, MSVDX_MTX_RAM_ACCESS_STATUS, 1, /* Required Value */
16585+ 0xffffffff /* Enables */ );
16586+
16587+ ui32ReadBackVal = PSB_RMSVDX32 (MSVDX_MTX_RAM_ACCESS_DATA_TRANSFER);
16588+ if (pui32Data[ui32Loop] != ui32ReadBackVal)
16589+ {
16590+ DRM_ERROR
16591+ ("psb: Firmware validation fails at index=%08x\n", ui32Loop);
16592+ ret = 1;
16593+ break;
16594+ }
16595+ }
16596+
16597+ /* Restore the access control register... */
16598+ PSB_WMSVDX32 (ui32AccessControl, MSVDX_MTX_RAM_ACCESS_CONTROL);
16599+
16600+ return ret;
16601+}
16602+
16603+static uint32_t *
16604+msvdx_get_fw (struct drm_device *dev,
16605+ const struct firmware **raw, uint8_t * name)
16606+{
16607+ int rc;
16608+ int *ptr = NULL;
16609+
16610+ rc = request_firmware (raw, name, &dev->pdev->dev);
16611+ if (rc < 0)
16612+ {
16613+ DRM_ERROR ("MSVDX: %s request_firmware failed: Reason %d\n", name, rc);
16614+ return NULL;
16615+ }
16616+
16617+ if ((*raw)->size < sizeof (struct msvdx_fw))
16618+ {
16619+ PSB_DEBUG_GENERAL ("MSVDX: %s is is not correct size(%zd)\n",
16620+ name, (*raw)->size);
16621+ return NULL;
16622+ }
16623+
16624+ ptr = (int *) ((*raw))->data;
16625+
16626+ if (!ptr)
16627+ {
16628+ PSB_DEBUG_GENERAL ("MSVDX: Failed to load %s\n", name);
16629+ return NULL;
16630+ }
16631+ /*another sanity check... */
16632+ if ((*raw)->size !=
16633+ (sizeof (struct msvdx_fw) +
16634+ sizeof (uint32_t) * ((struct msvdx_fw *) ptr)->text_size +
16635+ sizeof (uint32_t) * ((struct msvdx_fw *) ptr)->data_size))
16636+ {
16637+ PSB_DEBUG_GENERAL ("MSVDX: %s is is not correct size(%zd)\n",
16638+ name, (*raw)->size);
16639+ return NULL;
16640+ }
16641+ return ptr;
16642+}
16643+
16644+static int
16645+psb_setup_fw (struct drm_device *dev)
16646+{
16647+ struct drm_psb_private *dev_priv = dev->dev_private;
16648+ int ret = 0;
16649+
16650+ uint32_t ram_bank_size;
16651+ struct msvdx_fw *fw;
16652+ uint32_t *fw_ptr = NULL;
16653+ uint32_t *text_ptr = NULL;
16654+ uint32_t *data_ptr = NULL;
16655+ const struct firmware *raw = NULL;
16656+ /* todo : Assert the clock is on - if not turn it on to upload code */
16657+
16658+ PSB_DEBUG_GENERAL ("MSVDX: psb_setup_fw\n");
16659+
16660+ /* Reset MTX */
16661+ PSB_WMSVDX32 (MSVDX_MTX_SOFT_RESET_MTX_RESET_MASK, MSVDX_MTX_SOFT_RESET);
16662+
16663+ /* Initialses Communication controll area to 0 */
16664+ if(dev_priv->psb_rev_id >= POULSBO_D1)
16665+ {
16666+ PSB_DEBUG_GENERAL("MSVDX: Detected Poulsbo D1 or later revision.\n");
16667+ PSB_WMSVDX32 (MSVDX_DEVICE_NODE_FLAGS_DEFAULT_D1, MSVDX_COMMS_OFFSET_FLAGS);
16668+ }
16669+ else
16670+ {
16671+ PSB_DEBUG_GENERAL("MSVDX: Detected Poulsbo D0 or earlier revision.\n");
16672+ PSB_WMSVDX32 (MSVDX_DEVICE_NODE_FLAGS_DEFAULT_D0, MSVDX_COMMS_OFFSET_FLAGS);
16673+ }
16674+
16675+ PSB_WMSVDX32 (0, MSVDX_COMMS_MSG_COUNTER);
16676+ PSB_WMSVDX32 (0, MSVDX_COMMS_SIGNATURE);
16677+ PSB_WMSVDX32 (0, MSVDX_COMMS_TO_HOST_RD_INDEX);
16678+ PSB_WMSVDX32 (0, MSVDX_COMMS_TO_HOST_WRT_INDEX);
16679+ PSB_WMSVDX32 (0, MSVDX_COMMS_TO_MTX_RD_INDEX);
16680+ PSB_WMSVDX32 (0, MSVDX_COMMS_TO_MTX_WRT_INDEX);
16681+ PSB_WMSVDX32 (0, MSVDX_COMMS_FW_STATUS);
16682+
16683+ /* read register bank size */
16684+ {
16685+ uint32_t ui32BankSize, ui32Reg;
16686+ ui32Reg = PSB_RMSVDX32 (MSVDX_MTX_RAM_BANK);
16687+ ui32BankSize =
16688+ REGIO_READ_FIELD (ui32Reg, MSVDX_MTX_RAM_BANK, CR_MTX_RAM_BANK_SIZE);
16689+ ram_bank_size = (uint32_t) (1 << (ui32BankSize + 2));
16690+ }
16691+
16692+ PSB_DEBUG_GENERAL ("MSVDX: RAM bank size = %d bytes\n", ram_bank_size);
16693+
16694+ fw_ptr = msvdx_get_fw (dev, &raw, "msvdx_fw.bin");
16695+
16696+ if (!fw_ptr)
16697+ {
16698+ DRM_ERROR ("psb: No valid msvdx_fw.bin firmware found.\n");
16699+ ret = 1;
16700+ goto out;
16701+ }
16702+
16703+ fw = (struct msvdx_fw *) fw_ptr;
16704+ if (fw->ver != 0x02)
16705+ {
16706+ DRM_ERROR
16707+ ("psb: msvdx_fw.bin firmware version mismatch, got version=%02x expected version=%02x\n",
16708+ fw->ver, 0x02);
16709+ ret = 1;
16710+ goto out;
16711+ }
16712+
16713+ text_ptr = (uint32_t *) ((uint8_t *) fw_ptr + sizeof (struct msvdx_fw));
16714+ data_ptr = text_ptr + fw->text_size;
16715+
16716+ PSB_DEBUG_GENERAL ("MSVDX: Retrieved pointers for firmware\n");
16717+ PSB_DEBUG_GENERAL ("MSVDX: text_size: %d\n", fw->text_size);
16718+ PSB_DEBUG_GENERAL ("MSVDX: data_size: %d\n", fw->data_size);
16719+ PSB_DEBUG_GENERAL ("MSVDX: data_location: 0x%x\n", fw->data_location);
16720+ PSB_DEBUG_GENERAL ("MSVDX: First 4 bytes of text: 0x%x\n", *text_ptr);
16721+ PSB_DEBUG_GENERAL ("MSVDX: First 4 bytes of data: 0x%x\n", *data_ptr);
16722+
16723+ PSB_DEBUG_GENERAL ("MSVDX: Uploading firmware\n");
16724+ psb_upload_fw (dev_priv, MTX_CORE_CODE_MEM, ram_bank_size,
16725+ PC_START_ADDRESS - MTX_CODE_BASE, fw->text_size, text_ptr);
16726+ psb_upload_fw (dev_priv, MTX_CORE_DATA_MEM, ram_bank_size,
16727+ fw->data_location - MTX_DATA_BASE, fw->data_size, data_ptr);
16728+
16729+ /*todo : Verify code upload possibly only in debug */
16730+ if (psb_verify_fw
16731+ (dev_priv, ram_bank_size, MTX_CORE_CODE_MEM,
16732+ PC_START_ADDRESS - MTX_CODE_BASE, fw->text_size, text_ptr))
16733+ {
16734+ /* Firmware code upload failed */
16735+ ret = 1;
16736+ goto out;
16737+ }
16738+ if (psb_verify_fw
16739+ (dev_priv, ram_bank_size, MTX_CORE_DATA_MEM,
16740+ fw->data_location - MTX_DATA_BASE, fw->data_size, data_ptr))
16741+ {
16742+ /* Firmware data upload failed */
16743+ ret = 1;
16744+ goto out;
16745+ }
16746+
16747+ /* -- Set starting PC address */
16748+ psb_write_mtx_core_reg (dev_priv, MTX_PC, PC_START_ADDRESS);
16749+
16750+ /* -- Turn on the thread */
16751+ PSB_WMSVDX32 (MSVDX_MTX_ENABLE_MTX_ENABLE_MASK, MSVDX_MTX_ENABLE);
16752+
16753+ /* Wait for the signature value to be written back */
16754+ ret = psb_wait_for_register (dev_priv, MSVDX_COMMS_SIGNATURE, MSVDX_COMMS_SIGNATURE_VALUE, /* Required value */
16755+ 0xffffffff /* Enabled bits */ );
16756+ if (ret)
16757+ {
16758+ DRM_ERROR ("psb: MSVDX firmware fails to initialize.\n");
16759+ goto out;
16760+ }
16761+
16762+ PSB_DEBUG_GENERAL ("MSVDX: MTX Initial indications OK\n");
16763+ PSB_DEBUG_GENERAL ("MSVDX: MSVDX_COMMS_AREA_ADDR = %08x\n",
16764+ MSVDX_COMMS_AREA_ADDR);
16765+out:
16766+ if (raw)
16767+ {
16768+ PSB_DEBUG_GENERAL ("MSVDX releasing firmware resouces....\n");
16769+ release_firmware (raw);
16770+ }
16771+ return ret;
16772+}
16773+
16774+static void
16775+psb_free_ccb (struct drm_buffer_object **ccb)
16776+{
16777+ drm_bo_usage_deref_unlocked (ccb);
16778+ *ccb = NULL;
16779+}
16780+
16781+/*******************************************************************************
16782+
16783+ @Function psb_msvdx_reset
16784+
16785+ @Description
16786+
16787+ Reset chip and disable interrupts.
16788+
16789+ @Input psDeviceNode - device info. structure
16790+
16791+ @Return 0 - Success
16792+ 1 - Failure
16793+
16794+******************************************************************************/
16795+int
16796+psb_msvdx_reset (struct drm_psb_private *dev_priv)
16797+{
16798+ int ret = 0;
16799+
16800+ /* Issue software reset */
16801+ PSB_WMSVDX32 (msvdx_sw_reset_all, MSVDX_CONTROL);
16802+
16803+ ret = psb_wait_for_register (dev_priv, MSVDX_CONTROL, 0, /* Required value */
16804+ MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK
16805+ /* Enabled bits */ );
16806+
16807+ if (!ret)
16808+ {
16809+ /* Clear interrupt enabled flag */
16810+ PSB_WMSVDX32 (0, MSVDX_HOST_INTERRUPT_ENABLE);
16811+
16812+ /* Clear any pending interrupt flags */
16813+ PSB_WMSVDX32 (0xFFFFFFFF, MSVDX_INTERRUPT_CLEAR);
16814+ }
16815+
16816+ mutex_destroy (&dev_priv->msvdx_mutex);
16817+
16818+ return ret;
16819+}
16820+
16821+static int
16822+psb_allocate_ccb (struct drm_device *dev,
16823+ struct drm_buffer_object **ccb,
16824+ uint32_t * base_addr, int size)
16825+{
16826+ int ret;
16827+ struct drm_bo_kmap_obj tmp_kmap;
16828+ int is_iomem;
16829+
16830+ ret = drm_buffer_object_create (dev, size,
16831+ drm_bo_type_kernel,
16832+ DRM_BO_FLAG_READ |
16833+ DRM_PSB_FLAG_MEM_KERNEL |
16834+ DRM_BO_FLAG_NO_EVICT,
16835+ DRM_BO_HINT_DONT_FENCE, 0, 0, ccb);
16836+ if (ret)
16837+ {
16838+ PSB_DEBUG_GENERAL ("Failed to allocate CCB.\n");
16839+ *ccb = NULL;
16840+ return 1;
16841+ }
16842+
16843+ ret = drm_bo_kmap (*ccb, 0, (*ccb)->num_pages, &tmp_kmap);
16844+ if (ret)
16845+ {
16846+ PSB_DEBUG_GENERAL ("drm_bo_kmap failed ret: %d\n", ret);
16847+ drm_bo_usage_deref_unlocked (ccb);
16848+ *ccb = NULL;
16849+ return 1;
16850+ }
16851+
16852+ memset (drm_bmo_virtual (&tmp_kmap, &is_iomem), 0, size);
16853+ drm_bo_kunmap (&tmp_kmap);
16854+
16855+ *base_addr = (*ccb)->offset;
16856+ return 0;
16857+}
16858+
16859+int
16860+psb_msvdx_init (struct drm_device *dev)
16861+{
16862+ struct drm_psb_private *dev_priv = dev->dev_private;
16863+ uint32_t ui32Cmd;
16864+ int ret;
16865+
16866+ PSB_DEBUG_GENERAL ("MSVDX: psb_msvdx_init\n");
16867+
16868+ /*Initialize command msvdx queueing */
16869+ INIT_LIST_HEAD (&dev_priv->msvdx_queue);
16870+ mutex_init (&dev_priv->msvdx_mutex);
16871+ spin_lock_init (&dev_priv->msvdx_lock);
16872+ dev_priv->msvdx_busy = 0;
16873+
16874+ /*figure out the stepping*/
16875+ pci_read_config_byte(dev->pdev, PSB_REVID_OFFSET, &dev_priv->psb_rev_id );
16876+
16877+ /* Enable Clocks */
16878+ PSB_DEBUG_GENERAL ("Enabling clocks\n");
16879+ PSB_WMSVDX32 (clk_enable_all, MSVDX_MAN_CLK_ENABLE);
16880+
16881+ /* Enable MMU by removing all bypass bits */
16882+ PSB_WMSVDX32 (0, MSVDX_MMU_CONTROL0);
16883+
16884+ PSB_DEBUG_GENERAL ("MSVDX: Setting up RENDEC\n");
16885+ /* Allocate device virtual memory as required by rendec.... */
16886+ if (!dev_priv->ccb0)
16887+ {
16888+ ret =
16889+ psb_allocate_ccb (dev, &dev_priv->ccb0,
16890+ &dev_priv->base_addr0, RENDEC_A_SIZE);
16891+ if (ret)
16892+ goto err_exit;
16893+ }
16894+
16895+ if (!dev_priv->ccb1)
16896+ {
16897+ ret =
16898+ psb_allocate_ccb (dev, &dev_priv->ccb1,
16899+ &dev_priv->base_addr1, RENDEC_B_SIZE);
16900+ if (ret)
16901+ goto err_exit;
16902+ }
16903+
16904+ PSB_DEBUG_GENERAL ("MSVDX: RENDEC A: %08x RENDEC B: %08x\n",
16905+ dev_priv->base_addr0, dev_priv->base_addr1);
16906+
16907+ PSB_WMSVDX32 (dev_priv->base_addr0, MSVDX_RENDEC_BASE_ADDR0);
16908+ PSB_WMSVDX32 (dev_priv->base_addr1, MSVDX_RENDEC_BASE_ADDR1);
16909+
16910+ ui32Cmd = 0;
16911+ REGIO_WRITE_FIELD (ui32Cmd, MSVDX_RENDEC_BUFFER_SIZE,
16912+ RENDEC_BUFFER_SIZE0, RENDEC_A_SIZE / 4096);
16913+ REGIO_WRITE_FIELD (ui32Cmd, MSVDX_RENDEC_BUFFER_SIZE,
16914+ RENDEC_BUFFER_SIZE1, RENDEC_B_SIZE / 4096);
16915+ PSB_WMSVDX32 (ui32Cmd, MSVDX_RENDEC_BUFFER_SIZE);
16916+
16917+ ui32Cmd = 0;
16918+ REGIO_WRITE_FIELD (ui32Cmd, MSVDX_RENDEC_CONTROL1,
16919+ RENDEC_DECODE_START_SIZE, 0);
16920+ REGIO_WRITE_FIELD (ui32Cmd, MSVDX_RENDEC_CONTROL1, RENDEC_BURST_SIZE_W, 1);
16921+ REGIO_WRITE_FIELD (ui32Cmd, MSVDX_RENDEC_CONTROL1, RENDEC_BURST_SIZE_R, 1);
16922+ REGIO_WRITE_FIELD (ui32Cmd, MSVDX_RENDEC_CONTROL1,
16923+ RENDEC_EXTERNAL_MEMORY, 1);
16924+ PSB_WMSVDX32 (ui32Cmd, MSVDX_RENDEC_CONTROL1);
16925+
16926+ ui32Cmd = 0x00101010;
16927+ PSB_WMSVDX32 (ui32Cmd, MSVDX_RENDEC_CONTEXT0);
16928+ PSB_WMSVDX32 (ui32Cmd, MSVDX_RENDEC_CONTEXT1);
16929+ PSB_WMSVDX32 (ui32Cmd, MSVDX_RENDEC_CONTEXT2);
16930+ PSB_WMSVDX32 (ui32Cmd, MSVDX_RENDEC_CONTEXT3);
16931+ PSB_WMSVDX32 (ui32Cmd, MSVDX_RENDEC_CONTEXT4);
16932+ PSB_WMSVDX32 (ui32Cmd, MSVDX_RENDEC_CONTEXT5);
16933+
16934+ ui32Cmd = 0;
16935+ REGIO_WRITE_FIELD (ui32Cmd, MSVDX_RENDEC_CONTROL0, RENDEC_INITIALISE, 1);
16936+ PSB_WMSVDX32 (ui32Cmd, MSVDX_RENDEC_CONTROL0);
16937+
16938+ ret = psb_setup_fw (dev);
16939+ if (ret)
16940+ goto err_exit;
16941+
16942+ PSB_WMSVDX32 (clk_enable_minimal, MSVDX_MAN_CLK_ENABLE);
16943+
16944+ return 0;
16945+
16946+err_exit:
16947+ if (dev_priv->ccb0)
16948+ psb_free_ccb (&dev_priv->ccb0);
16949+ if (dev_priv->ccb1)
16950+ psb_free_ccb (&dev_priv->ccb1);
16951+
16952+ return 1;
16953+}
16954+
16955+int
16956+psb_msvdx_uninit (struct drm_device *dev)
16957+{
16958+ struct drm_psb_private *dev_priv = dev->dev_private;
16959+
16960+ /*Reset MSVDX chip */
16961+ psb_msvdx_reset (dev_priv);
16962+
16963+// PSB_WMSVDX32 (clk_enable_minimal, MSVDX_MAN_CLK_ENABLE);
16964+ printk("set the msvdx clock to 0 in the %s\n", __FUNCTION__);
16965+ PSB_WMSVDX32 (0, MSVDX_MAN_CLK_ENABLE);
16966+
16967+ /*Clean up resources...*/
16968+ if (dev_priv->ccb0)
16969+ psb_free_ccb (&dev_priv->ccb0);
16970+ if (dev_priv->ccb1)
16971+ psb_free_ccb (&dev_priv->ccb1);
16972+
16973+ return 0;
16974+}
16975+
16976+int psb_hw_info_ioctl(struct drm_device *dev, void *data,
16977+ struct drm_file *file_priv)
16978+{
16979+ struct drm_psb_private *dev_priv = dev->dev_private;
16980+ struct drm_psb_hw_info *hw_info = data;
16981+ struct pci_dev * pci_root = pci_get_bus_and_slot(0, 0);
16982+
16983+ hw_info->rev_id = dev_priv->psb_rev_id;
16984+
16985+ /*read the fuse info to determine the caps*/
16986+ pci_write_config_dword(pci_root, 0xD0, PCI_PORT5_REG80_FFUSE);
16987+ pci_read_config_dword(pci_root, 0xD4, &hw_info->caps);
16988+
16989+ PSB_DEBUG_GENERAL("MSVDX: PSB caps: 0x%x\n", hw_info->caps);
16990+ return 0;
16991+}
16992Index: linux-2.6.28/drivers/gpu/drm/psb/psb_reg.h
16993===================================================================
16994--- /dev/null 1970-01-01 00:00:00.000000000 +0000
16995+++ linux-2.6.28/drivers/gpu/drm/psb/psb_reg.h 2009-02-12 09:14:42.000000000 +0000
16996@@ -0,0 +1,562 @@
16997+/**************************************************************************
16998+ *
16999+ * Copyright (c) (2005-2007) Imagination Technologies Limited.
17000+ * Copyright (c) 2007, Intel Corporation.
17001+ * All Rights Reserved.
17002+ *
17003+ * This program is free software; you can redistribute it and/or modify it
17004+ * under the terms and conditions of the GNU General Public License,
17005+ * version 2, as published by the Free Software Foundation.
17006+ *
17007+ * This program is distributed in the hope it will be useful, but WITHOUT
17008+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17009+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17010+ * more details.
17011+ *
17012+ * You should have received a copy of the GNU General Public License along with
17013+ * this program; if not, write to the Free Software Foundation, Inc.,
17014+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17015+ *
17016+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
17017+ * develop this driver.
17018+ *
17019+ **************************************************************************/
17020+/*
17021+ */
17022+#ifndef _PSB_REG_H_
17023+#define _PSB_REG_H_
17024+
17025+#define PSB_CR_CLKGATECTL 0x0000
17026+#define _PSB_C_CLKGATECTL_AUTO_MAN_REG (1 << 24)
17027+#define _PSB_C_CLKGATECTL_USE_CLKG_SHIFT (20)
17028+#define _PSB_C_CLKGATECTL_USE_CLKG_MASK (0x3 << 20)
17029+#define _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT (16)
17030+#define _PSB_C_CLKGATECTL_DPM_CLKG_MASK (0x3 << 16)
17031+#define _PSB_C_CLKGATECTL_TA_CLKG_SHIFT (12)
17032+#define _PSB_C_CLKGATECTL_TA_CLKG_MASK (0x3 << 12)
17033+#define _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT (8)
17034+#define _PSB_C_CLKGATECTL_TSP_CLKG_MASK (0x3 << 8)
17035+#define _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT (4)
17036+#define _PSB_C_CLKGATECTL_ISP_CLKG_MASK (0x3 << 4)
17037+#define _PSB_C_CLKGATECTL_2D_CLKG_SHIFT (0)
17038+#define _PSB_C_CLKGATECTL_2D_CLKG_MASK (0x3 << 0)
17039+#define _PSB_C_CLKGATECTL_CLKG_ENABLED (0)
17040+#define _PSB_C_CLKGATECTL_CLKG_DISABLED (1)
17041+#define _PSB_C_CLKGATECTL_CLKG_AUTO (2)
17042+
17043+#define PSB_CR_CORE_ID 0x0010
17044+#define _PSB_CC_ID_ID_SHIFT (16)
17045+#define _PSB_CC_ID_ID_MASK (0xFFFF << 16)
17046+#define _PSB_CC_ID_CONFIG_SHIFT (0)
17047+#define _PSB_CC_ID_CONFIG_MASK (0xFFFF << 0)
17048+
17049+#define PSB_CR_CORE_REVISION 0x0014
17050+#define _PSB_CC_REVISION_DESIGNER_SHIFT (24)
17051+#define _PSB_CC_REVISION_DESIGNER_MASK (0xFF << 24)
17052+#define _PSB_CC_REVISION_MAJOR_SHIFT (16)
17053+#define _PSB_CC_REVISION_MAJOR_MASK (0xFF << 16)
17054+#define _PSB_CC_REVISION_MINOR_SHIFT (8)
17055+#define _PSB_CC_REVISION_MINOR_MASK (0xFF << 8)
17056+#define _PSB_CC_REVISION_MAINTENANCE_SHIFT (0)
17057+#define _PSB_CC_REVISION_MAINTENANCE_MASK (0xFF << 0)
17058+
17059+#define PSB_CR_DESIGNER_REV_FIELD1 0x0018
17060+
17061+#define PSB_CR_SOFT_RESET 0x0080
17062+#define _PSB_CS_RESET_TSP_RESET (1 << 6)
17063+#define _PSB_CS_RESET_ISP_RESET (1 << 5)
17064+#define _PSB_CS_RESET_USE_RESET (1 << 4)
17065+#define _PSB_CS_RESET_TA_RESET (1 << 3)
17066+#define _PSB_CS_RESET_DPM_RESET (1 << 2)
17067+#define _PSB_CS_RESET_TWOD_RESET (1 << 1)
17068+#define _PSB_CS_RESET_BIF_RESET (1 << 0)
17069+
17070+#define PSB_CR_DESIGNER_REV_FIELD2 0x001C
17071+
17072+#define PSB_CR_EVENT_HOST_ENABLE2 0x0110
17073+
17074+#define PSB_CR_EVENT_STATUS2 0x0118
17075+
17076+#define PSB_CR_EVENT_HOST_CLEAR2 0x0114
17077+#define _PSB_CE2_BIF_REQUESTER_FAULT (1 << 4)
17078+
17079+#define PSB_CR_EVENT_STATUS 0x012C
17080+
17081+#define PSB_CR_EVENT_HOST_ENABLE 0x0130
17082+
17083+#define PSB_CR_EVENT_HOST_CLEAR 0x0134
17084+#define _PSB_CE_MASTER_INTERRUPT (1 << 31)
17085+#define _PSB_CE_TA_DPM_FAULT (1 << 28)
17086+#define _PSB_CE_TWOD_COMPLETE (1 << 27)
17087+#define _PSB_CE_DPM_OUT_OF_MEMORY_ZLS (1 << 25)
17088+#define _PSB_CE_DPM_TA_MEM_FREE (1 << 24)
17089+#define _PSB_CE_PIXELBE_END_RENDER (1 << 18)
17090+#define _PSB_CE_SW_EVENT (1 << 14)
17091+#define _PSB_CE_TA_FINISHED (1 << 13)
17092+#define _PSB_CE_TA_TERMINATE (1 << 12)
17093+#define _PSB_CE_DPM_REACHED_MEM_THRESH (1 << 3)
17094+#define _PSB_CE_DPM_OUT_OF_MEMORY_GBL (1 << 2)
17095+#define _PSB_CE_DPM_OUT_OF_MEMORY_MT (1 << 1)
17096+#define _PSB_CE_DPM_3D_MEM_FREE (1 << 0)
17097+
17098+
17099+#define PSB_USE_OFFSET_MASK 0x0007FFFF
17100+#define PSB_USE_OFFSET_SIZE (PSB_USE_OFFSET_MASK + 1)
17101+#define PSB_CR_USE_CODE_BASE0 0x0A0C
17102+#define PSB_CR_USE_CODE_BASE1 0x0A10
17103+#define PSB_CR_USE_CODE_BASE2 0x0A14
17104+#define PSB_CR_USE_CODE_BASE3 0x0A18
17105+#define PSB_CR_USE_CODE_BASE4 0x0A1C
17106+#define PSB_CR_USE_CODE_BASE5 0x0A20
17107+#define PSB_CR_USE_CODE_BASE6 0x0A24
17108+#define PSB_CR_USE_CODE_BASE7 0x0A28
17109+#define PSB_CR_USE_CODE_BASE8 0x0A2C
17110+#define PSB_CR_USE_CODE_BASE9 0x0A30
17111+#define PSB_CR_USE_CODE_BASE10 0x0A34
17112+#define PSB_CR_USE_CODE_BASE11 0x0A38
17113+#define PSB_CR_USE_CODE_BASE12 0x0A3C
17114+#define PSB_CR_USE_CODE_BASE13 0x0A40
17115+#define PSB_CR_USE_CODE_BASE14 0x0A44
17116+#define PSB_CR_USE_CODE_BASE15 0x0A48
17117+#define PSB_CR_USE_CODE_BASE(_i) (0x0A0C + ((_i) << 2))
17118+#define _PSB_CUC_BASE_DM_SHIFT (25)
17119+#define _PSB_CUC_BASE_DM_MASK (0x3 << 25)
17120+#define _PSB_CUC_BASE_ADDR_SHIFT (0) // 1024-bit aligned address?
17121+#define _PSB_CUC_BASE_ADDR_ALIGNSHIFT (7)
17122+#define _PSB_CUC_BASE_ADDR_MASK (0x1FFFFFF << 0)
17123+#define _PSB_CUC_DM_VERTEX (0)
17124+#define _PSB_CUC_DM_PIXEL (1)
17125+#define _PSB_CUC_DM_RESERVED (2)
17126+#define _PSB_CUC_DM_EDM (3)
17127+
17128+#define PSB_CR_PDS_EXEC_BASE 0x0AB8
17129+#define _PSB_CR_PDS_EXEC_BASE_ADDR_SHIFT (20) // 1MB aligned address
17130+#define _PSB_CR_PDS_EXEC_BASE_ADDR_ALIGNSHIFT (20)
17131+
17132+#define PSB_CR_EVENT_KICKER 0x0AC4
17133+#define _PSB_CE_KICKER_ADDRESS_SHIFT (4) // 128-bit aligned address
17134+
17135+#define PSB_CR_EVENT_KICK 0x0AC8
17136+#define _PSB_CE_KICK_NOW (1 << 0)
17137+
17138+
17139+#define PSB_CR_BIF_DIR_LIST_BASE1 0x0C38
17140+
17141+#define PSB_CR_BIF_CTRL 0x0C00
17142+#define _PSB_CB_CTRL_CLEAR_FAULT (1 << 4)
17143+#define _PSB_CB_CTRL_INVALDC (1 << 3)
17144+#define _PSB_CB_CTRL_FLUSH (1 << 2)
17145+
17146+#define PSB_CR_BIF_INT_STAT 0x0C04
17147+
17148+#define PSB_CR_BIF_FAULT 0x0C08
17149+#define _PSB_CBI_STAT_PF_N_RW (1 << 14)
17150+#define _PSB_CBI_STAT_FAULT_SHIFT (0)
17151+#define _PSB_CBI_STAT_FAULT_MASK (0x3FFF << 0)
17152+#define _PSB_CBI_STAT_FAULT_CACHE (1 << 1)
17153+#define _PSB_CBI_STAT_FAULT_TA (1 << 2)
17154+#define _PSB_CBI_STAT_FAULT_VDM (1 << 3)
17155+#define _PSB_CBI_STAT_FAULT_2D (1 << 4)
17156+#define _PSB_CBI_STAT_FAULT_PBE (1 << 5)
17157+#define _PSB_CBI_STAT_FAULT_TSP (1 << 6)
17158+#define _PSB_CBI_STAT_FAULT_ISP (1 << 7)
17159+#define _PSB_CBI_STAT_FAULT_USSEPDS (1 << 8)
17160+#define _PSB_CBI_STAT_FAULT_HOST (1 << 9)
17161+
17162+#define PSB_CR_BIF_BANK0 0x0C78
17163+
17164+#define PSB_CR_BIF_BANK1 0x0C7C
17165+
17166+#define PSB_CR_BIF_DIR_LIST_BASE0 0x0C84
17167+
17168+#define PSB_CR_BIF_TWOD_REQ_BASE 0x0C88
17169+#define PSB_CR_BIF_3D_REQ_BASE 0x0CAC
17170+
17171+#define PSB_CR_2D_SOCIF 0x0E18
17172+#define _PSB_C2_SOCIF_FREESPACE_SHIFT (0)
17173+#define _PSB_C2_SOCIF_FREESPACE_MASK (0xFF << 0)
17174+#define _PSB_C2_SOCIF_EMPTY (0x80 << 0)
17175+
17176+#define PSB_CR_2D_BLIT_STATUS 0x0E04
17177+#define _PSB_C2B_STATUS_BUSY (1 << 24)
17178+#define _PSB_C2B_STATUS_COMPLETE_SHIFT (0)
17179+#define _PSB_C2B_STATUS_COMPLETE_MASK (0xFFFFFF << 0)
17180+
17181+/*
17182+ * 2D defs.
17183+ */
17184+
17185+/*
17186+ * 2D Slave Port Data : Block Header's Object Type
17187+ */
17188+
17189+#define PSB_2D_CLIP_BH (0x00000000)
17190+#define PSB_2D_PAT_BH (0x10000000)
17191+#define PSB_2D_CTRL_BH (0x20000000)
17192+#define PSB_2D_SRC_OFF_BH (0x30000000)
17193+#define PSB_2D_MASK_OFF_BH (0x40000000)
17194+#define PSB_2D_RESERVED1_BH (0x50000000)
17195+#define PSB_2D_RESERVED2_BH (0x60000000)
17196+#define PSB_2D_FENCE_BH (0x70000000)
17197+#define PSB_2D_BLIT_BH (0x80000000)
17198+#define PSB_2D_SRC_SURF_BH (0x90000000)
17199+#define PSB_2D_DST_SURF_BH (0xA0000000)
17200+#define PSB_2D_PAT_SURF_BH (0xB0000000)
17201+#define PSB_2D_SRC_PAL_BH (0xC0000000)
17202+#define PSB_2D_PAT_PAL_BH (0xD0000000)
17203+#define PSB_2D_MASK_SURF_BH (0xE0000000)
17204+#define PSB_2D_FLUSH_BH (0xF0000000)
17205+
17206+/*
17207+ * Clip Definition block (PSB_2D_CLIP_BH)
17208+ */
17209+#define PSB_2D_CLIPCOUNT_MAX (1)
17210+#define PSB_2D_CLIPCOUNT_MASK (0x00000000)
17211+#define PSB_2D_CLIPCOUNT_CLRMASK (0xFFFFFFFF)
17212+#define PSB_2D_CLIPCOUNT_SHIFT (0)
17213+// clip rectangle min & max
17214+#define PSB_2D_CLIP_XMAX_MASK (0x00FFF000)
17215+#define PSB_2D_CLIP_XMAX_CLRMASK (0xFF000FFF)
17216+#define PSB_2D_CLIP_XMAX_SHIFT (12)
17217+#define PSB_2D_CLIP_XMIN_MASK (0x00000FFF)
17218+#define PSB_2D_CLIP_XMIN_CLRMASK (0x00FFF000)
17219+#define PSB_2D_CLIP_XMIN_SHIFT (0)
17220+// clip rectangle offset
17221+#define PSB_2D_CLIP_YMAX_MASK (0x00FFF000)
17222+#define PSB_2D_CLIP_YMAX_CLRMASK (0xFF000FFF)
17223+#define PSB_2D_CLIP_YMAX_SHIFT (12)
17224+#define PSB_2D_CLIP_YMIN_MASK (0x00000FFF)
17225+#define PSB_2D_CLIP_YMIN_CLRMASK (0x00FFF000)
17226+#define PSB_2D_CLIP_YMIN_SHIFT (0)
17227+
17228+/*
17229+ * Pattern Control (PSB_2D_PAT_BH)
17230+ */
17231+#define PSB_2D_PAT_HEIGHT_MASK (0x0000001F)
17232+#define PSB_2D_PAT_HEIGHT_SHIFT (0)
17233+#define PSB_2D_PAT_WIDTH_MASK (0x000003E0)
17234+#define PSB_2D_PAT_WIDTH_SHIFT (5)
17235+#define PSB_2D_PAT_YSTART_MASK (0x00007C00)
17236+#define PSB_2D_PAT_YSTART_SHIFT (10)
17237+#define PSB_2D_PAT_XSTART_MASK (0x000F8000)
17238+#define PSB_2D_PAT_XSTART_SHIFT (15)
17239+
17240+/*
17241+ * 2D Control block (PSB_2D_CTRL_BH)
17242+ */
17243+// Present Flags
17244+#define PSB_2D_SRCCK_CTRL (0x00000001)
17245+#define PSB_2D_DSTCK_CTRL (0x00000002)
17246+#define PSB_2D_ALPHA_CTRL (0x00000004)
17247+// Colour Key Colour (SRC/DST)
17248+#define PSB_2D_CK_COL_MASK (0xFFFFFFFF)
17249+#define PSB_2D_CK_COL_CLRMASK (0x00000000)
17250+#define PSB_2D_CK_COL_SHIFT (0)
17251+// Colour Key Mask (SRC/DST)
17252+#define PSB_2D_CK_MASK_MASK (0xFFFFFFFF)
17253+#define PSB_2D_CK_MASK_CLRMASK (0x00000000)
17254+#define PSB_2D_CK_MASK_SHIFT (0)
17255+// Alpha Control (Alpha/RGB)
17256+#define PSB_2D_GBLALPHA_MASK (0x000FF000)
17257+#define PSB_2D_GBLALPHA_CLRMASK (0xFFF00FFF)
17258+#define PSB_2D_GBLALPHA_SHIFT (12)
17259+#define PSB_2D_SRCALPHA_OP_MASK (0x00700000)
17260+#define PSB_2D_SRCALPHA_OP_CLRMASK (0xFF8FFFFF)
17261+#define PSB_2D_SRCALPHA_OP_SHIFT (20)
17262+#define PSB_2D_SRCALPHA_OP_ONE (0x00000000)
17263+#define PSB_2D_SRCALPHA_OP_SRC (0x00100000)
17264+#define PSB_2D_SRCALPHA_OP_DST (0x00200000)
17265+#define PSB_2D_SRCALPHA_OP_SG (0x00300000)
17266+#define PSB_2D_SRCALPHA_OP_DG (0x00400000)
17267+#define PSB_2D_SRCALPHA_OP_GBL (0x00500000)
17268+#define PSB_2D_SRCALPHA_OP_ZERO (0x00600000)
17269+#define PSB_2D_SRCALPHA_INVERT (0x00800000)
17270+#define PSB_2D_SRCALPHA_INVERT_CLR (0xFF7FFFFF)
17271+#define PSB_2D_DSTALPHA_OP_MASK (0x07000000)
17272+#define PSB_2D_DSTALPHA_OP_CLRMASK (0xF8FFFFFF)
17273+#define PSB_2D_DSTALPHA_OP_SHIFT (24)
17274+#define PSB_2D_DSTALPHA_OP_ONE (0x00000000)
17275+#define PSB_2D_DSTALPHA_OP_SRC (0x01000000)
17276+#define PSB_2D_DSTALPHA_OP_DST (0x02000000)
17277+#define PSB_2D_DSTALPHA_OP_SG (0x03000000)
17278+#define PSB_2D_DSTALPHA_OP_DG (0x04000000)
17279+#define PSB_2D_DSTALPHA_OP_GBL (0x05000000)
17280+#define PSB_2D_DSTALPHA_OP_ZERO (0x06000000)
17281+#define PSB_2D_DSTALPHA_INVERT (0x08000000)
17282+#define PSB_2D_DSTALPHA_INVERT_CLR (0xF7FFFFFF)
17283+
17284+#define PSB_2D_PRE_MULTIPLICATION_ENABLE (0x10000000)
17285+#define PSB_2D_PRE_MULTIPLICATION_CLRMASK (0xEFFFFFFF)
17286+#define PSB_2D_ZERO_SOURCE_ALPHA_ENABLE (0x20000000)
17287+#define PSB_2D_ZERO_SOURCE_ALPHA_CLRMASK (0xDFFFFFFF)
17288+
17289+/*
17290+ *Source Offset (PSB_2D_SRC_OFF_BH)
17291+ */
17292+#define PSB_2D_SRCOFF_XSTART_MASK ((0x00000FFF) << 12)
17293+#define PSB_2D_SRCOFF_XSTART_SHIFT (12)
17294+#define PSB_2D_SRCOFF_YSTART_MASK (0x00000FFF)
17295+#define PSB_2D_SRCOFF_YSTART_SHIFT (0)
17296+
17297+/*
17298+ * Mask Offset (PSB_2D_MASK_OFF_BH)
17299+ */
17300+#define PSB_2D_MASKOFF_XSTART_MASK ((0x00000FFF) << 12)
17301+#define PSB_2D_MASKOFF_XSTART_SHIFT (12)
17302+#define PSB_2D_MASKOFF_YSTART_MASK (0x00000FFF)
17303+#define PSB_2D_MASKOFF_YSTART_SHIFT (0)
17304+
17305+/*
17306+ * 2D Fence (see PSB_2D_FENCE_BH): bits 0:27 are ignored
17307+ */
17308+
17309+/*
17310+ *Blit Rectangle (PSB_2D_BLIT_BH)
17311+ */
17312+
17313+#define PSB_2D_ROT_MASK (3<<25)
17314+#define PSB_2D_ROT_CLRMASK (~PSB_2D_ROT_MASK)
17315+#define PSB_2D_ROT_NONE (0<<25)
17316+#define PSB_2D_ROT_90DEGS (1<<25)
17317+#define PSB_2D_ROT_180DEGS (2<<25)
17318+#define PSB_2D_ROT_270DEGS (3<<25)
17319+
17320+#define PSB_2D_COPYORDER_MASK (3<<23)
17321+#define PSB_2D_COPYORDER_CLRMASK (~PSB_2D_COPYORDER_MASK)
17322+#define PSB_2D_COPYORDER_TL2BR (0<<23)
17323+#define PSB_2D_COPYORDER_BR2TL (1<<23)
17324+#define PSB_2D_COPYORDER_TR2BL (2<<23)
17325+#define PSB_2D_COPYORDER_BL2TR (3<<23)
17326+
17327+#define PSB_2D_DSTCK_CLRMASK (0xFF9FFFFF)
17328+#define PSB_2D_DSTCK_DISABLE (0x00000000)
17329+#define PSB_2D_DSTCK_PASS (0x00200000)
17330+#define PSB_2D_DSTCK_REJECT (0x00400000)
17331+
17332+#define PSB_2D_SRCCK_CLRMASK (0xFFE7FFFF)
17333+#define PSB_2D_SRCCK_DISABLE (0x00000000)
17334+#define PSB_2D_SRCCK_PASS (0x00080000)
17335+#define PSB_2D_SRCCK_REJECT (0x00100000)
17336+
17337+#define PSB_2D_CLIP_ENABLE (0x00040000)
17338+
17339+#define PSB_2D_ALPHA_ENABLE (0x00020000)
17340+
17341+#define PSB_2D_PAT_CLRMASK (0xFFFEFFFF)
17342+#define PSB_2D_PAT_MASK (0x00010000)
17343+#define PSB_2D_USE_PAT (0x00010000)
17344+#define PSB_2D_USE_FILL (0x00000000)
17345+/*
17346+ * Tungsten Graphics note on rop codes: If rop A and rop B are
17347+ * identical, the mask surface will not be read and need not be
17348+ * set up.
17349+ */
17350+
17351+#define PSB_2D_ROP3B_MASK (0x0000FF00)
17352+#define PSB_2D_ROP3B_CLRMASK (0xFFFF00FF)
17353+#define PSB_2D_ROP3B_SHIFT (8)
17354+// rop code A
17355+#define PSB_2D_ROP3A_MASK (0x000000FF)
17356+#define PSB_2D_ROP3A_CLRMASK (0xFFFFFF00)
17357+#define PSB_2D_ROP3A_SHIFT (0)
17358+
17359+#define PSB_2D_ROP4_MASK (0x0000FFFF)
17360+/*
17361+ * DWORD0: (Only pass if Pattern control == Use Fill Colour)
17362+ * Fill Colour RGBA8888
17363+ */
17364+#define PSB_2D_FILLCOLOUR_MASK (0xFFFFFFFF)
17365+#define PSB_2D_FILLCOLOUR_SHIFT (0)
17366+/*
17367+ * DWORD1: (Always Present)
17368+ * X Start (Dest)
17369+ * Y Start (Dest)
17370+ */
17371+#define PSB_2D_DST_XSTART_MASK (0x00FFF000)
17372+#define PSB_2D_DST_XSTART_CLRMASK (0xFF000FFF)
17373+#define PSB_2D_DST_XSTART_SHIFT (12)
17374+#define PSB_2D_DST_YSTART_MASK (0x00000FFF)
17375+#define PSB_2D_DST_YSTART_CLRMASK (0xFFFFF000)
17376+#define PSB_2D_DST_YSTART_SHIFT (0)
17377+/*
17378+ * DWORD2: (Always Present)
17379+ * X Size (Dest)
17380+ * Y Size (Dest)
17381+ */
17382+#define PSB_2D_DST_XSIZE_MASK (0x00FFF000)
17383+#define PSB_2D_DST_XSIZE_CLRMASK (0xFF000FFF)
17384+#define PSB_2D_DST_XSIZE_SHIFT (12)
17385+#define PSB_2D_DST_YSIZE_MASK (0x00000FFF)
17386+#define PSB_2D_DST_YSIZE_CLRMASK (0xFFFFF000)
17387+#define PSB_2D_DST_YSIZE_SHIFT (0)
17388+
17389+/*
17390+ * Source Surface (PSB_2D_SRC_SURF_BH)
17391+ */
17392+/*
17393+ * WORD 0
17394+ */
17395+
17396+#define PSB_2D_SRC_FORMAT_MASK (0x00078000)
17397+#define PSB_2D_SRC_1_PAL (0x00000000)
17398+#define PSB_2D_SRC_2_PAL (0x00008000)
17399+#define PSB_2D_SRC_4_PAL (0x00010000)
17400+#define PSB_2D_SRC_8_PAL (0x00018000)
17401+#define PSB_2D_SRC_8_ALPHA (0x00020000)
17402+#define PSB_2D_SRC_4_ALPHA (0x00028000)
17403+#define PSB_2D_SRC_332RGB (0x00030000)
17404+#define PSB_2D_SRC_4444ARGB (0x00038000)
17405+#define PSB_2D_SRC_555RGB (0x00040000)
17406+#define PSB_2D_SRC_1555ARGB (0x00048000)
17407+#define PSB_2D_SRC_565RGB (0x00050000)
17408+#define PSB_2D_SRC_0888ARGB (0x00058000)
17409+#define PSB_2D_SRC_8888ARGB (0x00060000)
17410+#define PSB_2D_SRC_8888UYVY (0x00068000)
17411+#define PSB_2D_SRC_RESERVED (0x00070000)
17412+#define PSB_2D_SRC_1555ARGB_LOOKUP (0x00078000)
17413+
17414+
17415+#define PSB_2D_SRC_STRIDE_MASK (0x00007FFF)
17416+#define PSB_2D_SRC_STRIDE_CLRMASK (0xFFFF8000)
17417+#define PSB_2D_SRC_STRIDE_SHIFT (0)
17418+/*
17419+ * WORD 1 - Base Address
17420+ */
17421+#define PSB_2D_SRC_ADDR_MASK (0x0FFFFFFC)
17422+#define PSB_2D_SRC_ADDR_CLRMASK (0x00000003)
17423+#define PSB_2D_SRC_ADDR_SHIFT (2)
17424+#define PSB_2D_SRC_ADDR_ALIGNSHIFT (2)
17425+
17426+/*
17427+ * Pattern Surface (PSB_2D_PAT_SURF_BH)
17428+ */
17429+/*
17430+ * WORD 0
17431+ */
17432+
17433+#define PSB_2D_PAT_FORMAT_MASK (0x00078000)
17434+#define PSB_2D_PAT_1_PAL (0x00000000)
17435+#define PSB_2D_PAT_2_PAL (0x00008000)
17436+#define PSB_2D_PAT_4_PAL (0x00010000)
17437+#define PSB_2D_PAT_8_PAL (0x00018000)
17438+#define PSB_2D_PAT_8_ALPHA (0x00020000)
17439+#define PSB_2D_PAT_4_ALPHA (0x00028000)
17440+#define PSB_2D_PAT_332RGB (0x00030000)
17441+#define PSB_2D_PAT_4444ARGB (0x00038000)
17442+#define PSB_2D_PAT_555RGB (0x00040000)
17443+#define PSB_2D_PAT_1555ARGB (0x00048000)
17444+#define PSB_2D_PAT_565RGB (0x00050000)
17445+#define PSB_2D_PAT_0888ARGB (0x00058000)
17446+#define PSB_2D_PAT_8888ARGB (0x00060000)
17447+
17448+#define PSB_2D_PAT_STRIDE_MASK (0x00007FFF)
17449+#define PSB_2D_PAT_STRIDE_CLRMASK (0xFFFF8000)
17450+#define PSB_2D_PAT_STRIDE_SHIFT (0)
17451+/*
17452+ * WORD 1 - Base Address
17453+ */
17454+#define PSB_2D_PAT_ADDR_MASK (0x0FFFFFFC)
17455+#define PSB_2D_PAT_ADDR_CLRMASK (0x00000003)
17456+#define PSB_2D_PAT_ADDR_SHIFT (2)
17457+#define PSB_2D_PAT_ADDR_ALIGNSHIFT (2)
17458+
17459+/*
17460+ * Destination Surface (PSB_2D_DST_SURF_BH)
17461+ */
17462+/*
17463+ * WORD 0
17464+ */
17465+
17466+#define PSB_2D_DST_FORMAT_MASK (0x00078000)
17467+#define PSB_2D_DST_332RGB (0x00030000)
17468+#define PSB_2D_DST_4444ARGB (0x00038000)
17469+#define PSB_2D_DST_555RGB (0x00040000)
17470+#define PSB_2D_DST_1555ARGB (0x00048000)
17471+#define PSB_2D_DST_565RGB (0x00050000)
17472+#define PSB_2D_DST_0888ARGB (0x00058000)
17473+#define PSB_2D_DST_8888ARGB (0x00060000)
17474+#define PSB_2D_DST_8888AYUV (0x00070000)
17475+
17476+#define PSB_2D_DST_STRIDE_MASK (0x00007FFF)
17477+#define PSB_2D_DST_STRIDE_CLRMASK (0xFFFF8000)
17478+#define PSB_2D_DST_STRIDE_SHIFT (0)
17479+/*
17480+ * WORD 1 - Base Address
17481+ */
17482+#define PSB_2D_DST_ADDR_MASK (0x0FFFFFFC)
17483+#define PSB_2D_DST_ADDR_CLRMASK (0x00000003)
17484+#define PSB_2D_DST_ADDR_SHIFT (2)
17485+#define PSB_2D_DST_ADDR_ALIGNSHIFT (2)
17486+
17487+/*
17488+ * Mask Surface (PSB_2D_MASK_SURF_BH)
17489+ */
17490+/*
17491+ * WORD 0
17492+ */
17493+#define PSB_2D_MASK_STRIDE_MASK (0x00007FFF)
17494+#define PSB_2D_MASK_STRIDE_CLRMASK (0xFFFF8000)
17495+#define PSB_2D_MASK_STRIDE_SHIFT (0)
17496+/*
17497+ * WORD 1 - Base Address
17498+ */
17499+#define PSB_2D_MASK_ADDR_MASK (0x0FFFFFFC)
17500+#define PSB_2D_MASK_ADDR_CLRMASK (0x00000003)
17501+#define PSB_2D_MASK_ADDR_SHIFT (2)
17502+#define PSB_2D_MASK_ADDR_ALIGNSHIFT (2)
17503+
17504+/*
17505+ * Source Palette (PSB_2D_SRC_PAL_BH)
17506+ */
17507+
17508+#define PSB_2D_SRCPAL_ADDR_SHIFT (0)
17509+#define PSB_2D_SRCPAL_ADDR_CLRMASK (0xF0000007)
17510+#define PSB_2D_SRCPAL_ADDR_MASK (0x0FFFFFF8)
17511+#define PSB_2D_SRCPAL_BYTEALIGN (1024)
17512+
17513+/*
17514+ * Pattern Palette (PSB_2D_PAT_PAL_BH)
17515+ */
17516+
17517+#define PSB_2D_PATPAL_ADDR_SHIFT (0)
17518+#define PSB_2D_PATPAL_ADDR_CLRMASK (0xF0000007)
17519+#define PSB_2D_PATPAL_ADDR_MASK (0x0FFFFFF8)
17520+#define PSB_2D_PATPAL_BYTEALIGN (1024)
17521+
17522+/*
17523+ * Rop3 Codes (2 LS bytes)
17524+ */
17525+
17526+#define PSB_2D_ROP3_SRCCOPY (0xCCCC)
17527+#define PSB_2D_ROP3_PATCOPY (0xF0F0)
17528+#define PSB_2D_ROP3_WHITENESS (0xFFFF)
17529+#define PSB_2D_ROP3_BLACKNESS (0x0000)
17530+#define PSB_2D_ROP3_SRC (0xCC)
17531+#define PSB_2D_ROP3_PAT (0xF0)
17532+#define PSB_2D_ROP3_DST (0xAA)
17533+
17534+
17535+/*
17536+ * Sizes.
17537+ */
17538+
17539+#define PSB_SCENE_HW_COOKIE_SIZE 16
17540+#define PSB_TA_MEM_HW_COOKIE_SIZE 16
17541+
17542+/*
17543+ * Scene stuff.
17544+ */
17545+
17546+#define PSB_NUM_HW_SCENES 2
17547+
17548+/*
17549+ * Scheduler completion actions.
17550+ */
17551+
17552+#define PSB_RASTER_BLOCK 0
17553+#define PSB_RASTER 1
17554+#define PSB_RETURN 2
17555+#define PSB_TA 3
17556+
17557+
17558+#endif
17559Index: linux-2.6.28/drivers/gpu/drm/psb/psb_regman.c
17560===================================================================
17561--- /dev/null 1970-01-01 00:00:00.000000000 +0000
17562+++ linux-2.6.28/drivers/gpu/drm/psb/psb_regman.c 2009-02-12 09:14:42.000000000 +0000
17563@@ -0,0 +1,175 @@
17564+/**************************************************************************
17565+ * Copyright (c) 2007, Intel Corporation.
17566+ * All Rights Reserved.
17567+ *
17568+ * This program is free software; you can redistribute it and/or modify it
17569+ * under the terms and conditions of the GNU General Public License,
17570+ * version 2, as published by the Free Software Foundation.
17571+ *
17572+ * This program is distributed in the hope it will be useful, but WITHOUT
17573+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17574+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17575+ * more details.
17576+ *
17577+ * You should have received a copy of the GNU General Public License along with
17578+ * this program; if not, write to the Free Software Foundation, Inc.,
17579+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17580+ *
17581+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
17582+ * develop this driver.
17583+ *
17584+ **************************************************************************/
17585+/*
17586+ */
17587+
17588+#include "drmP.h"
17589+#include "psb_drv.h"
17590+
17591+struct psb_use_reg {
17592+ struct drm_reg reg;
17593+ struct drm_psb_private *dev_priv;
17594+ uint32_t reg_seq;
17595+ uint32_t base;
17596+ uint32_t data_master;
17597+};
17598+
17599+struct psb_use_reg_data {
17600+ uint32_t base;
17601+ uint32_t size;
17602+ uint32_t data_master;
17603+};
17604+
17605+static int psb_use_reg_reusable(const struct drm_reg *reg, const void *data)
17606+{
17607+ struct psb_use_reg *use_reg =
17608+ container_of(reg, struct psb_use_reg, reg);
17609+ struct psb_use_reg_data *use_data = (struct psb_use_reg_data *)data;
17610+
17611+ return ((use_reg->base <= use_data->base) &&
17612+ (use_reg->base + PSB_USE_OFFSET_SIZE >
17613+ use_data->base + use_data->size) &&
17614+ use_reg->data_master == use_data->data_master);
17615+}
17616+
17617+static int psb_use_reg_set(struct psb_use_reg *use_reg,
17618+ const struct psb_use_reg_data *use_data)
17619+{
17620+ struct drm_psb_private *dev_priv = use_reg->dev_priv;
17621+
17622+ if (use_reg->reg.fence == NULL)
17623+ use_reg->data_master = use_data->data_master;
17624+
17625+ if (use_reg->reg.fence == NULL &&
17626+ !psb_use_reg_reusable(&use_reg->reg, (const void *)use_data)) {
17627+
17628+ use_reg->base = use_data->base & ~PSB_USE_OFFSET_MASK;
17629+ use_reg->data_master = use_data->data_master;
17630+
17631+ if (!psb_use_reg_reusable(&use_reg->reg,
17632+ (const void *)use_data)) {
17633+ DRM_ERROR("USE base mechanism didn't support "
17634+ "buffer size or alignment\n");
17635+ return -EINVAL;
17636+ }
17637+
17638+ PSB_WSGX32(PSB_ALPL(use_reg->base, _PSB_CUC_BASE_ADDR) |
17639+ (use_reg->data_master << _PSB_CUC_BASE_DM_SHIFT),
17640+ PSB_CR_USE_CODE_BASE(use_reg->reg_seq));
17641+ }
17642+ return 0;
17643+
17644+}
17645+
17646+int psb_grab_use_base(struct drm_psb_private *dev_priv,
17647+ unsigned long base,
17648+ unsigned long size,
17649+ unsigned int data_master,
17650+ uint32_t fence_class,
17651+ uint32_t fence_type,
17652+ int no_wait,
17653+ int interruptible, int *r_reg, uint32_t * r_offset)
17654+{
17655+ struct psb_use_reg_data use_data = {
17656+ .base = base,
17657+ .size = size,
17658+ .data_master = data_master
17659+ };
17660+ int ret;
17661+
17662+ struct drm_reg *reg;
17663+ struct psb_use_reg *use_reg;
17664+
17665+ ret = drm_regs_alloc(&dev_priv->use_manager,
17666+ (const void *)&use_data,
17667+ fence_class,
17668+ fence_type, interruptible, no_wait, &reg);
17669+ if (ret)
17670+ return ret;
17671+
17672+ use_reg = container_of(reg, struct psb_use_reg, reg);
17673+ ret = psb_use_reg_set(use_reg, &use_data);
17674+
17675+ if (ret)
17676+ return ret;
17677+
17678+ *r_reg = use_reg->reg_seq;
17679+ *r_offset = base - use_reg->base;
17680+
17681+ return 0;
17682+};
17683+
17684+static void psb_use_reg_destroy(struct drm_reg *reg)
17685+{
17686+ struct psb_use_reg *use_reg =
17687+ container_of(reg, struct psb_use_reg, reg);
17688+ struct drm_psb_private *dev_priv = use_reg->dev_priv;
17689+
17690+ PSB_WSGX32(PSB_ALPL(0, _PSB_CUC_BASE_ADDR),
17691+ PSB_CR_USE_CODE_BASE(use_reg->reg_seq));
17692+
17693+ drm_free(use_reg, sizeof(*use_reg), DRM_MEM_DRIVER);
17694+}
17695+
17696+int psb_init_use_base(struct drm_psb_private *dev_priv,
17697+ unsigned int reg_start, unsigned int reg_num)
17698+{
17699+ struct psb_use_reg *use_reg;
17700+ int i;
17701+ int ret = 0;
17702+
17703+ mutex_lock(&dev_priv->cmdbuf_mutex);
17704+
17705+ drm_regs_init(&dev_priv->use_manager,
17706+ &psb_use_reg_reusable, &psb_use_reg_destroy);
17707+
17708+ for (i = reg_start; i < reg_start + reg_num; ++i) {
17709+ use_reg = drm_calloc(1, sizeof(*use_reg), DRM_MEM_DRIVER);
17710+ if (!use_reg) {
17711+ ret = -ENOMEM;
17712+ goto out;
17713+ }
17714+
17715+ use_reg->dev_priv = dev_priv;
17716+ use_reg->reg_seq = i;
17717+ use_reg->base = 0;
17718+ use_reg->data_master = _PSB_CUC_DM_PIXEL;
17719+
17720+ PSB_WSGX32(PSB_ALPL(use_reg->base, _PSB_CUC_BASE_ADDR) |
17721+ (use_reg->data_master << _PSB_CUC_BASE_DM_SHIFT),
17722+ PSB_CR_USE_CODE_BASE(use_reg->reg_seq));
17723+
17724+ drm_regs_add(&dev_priv->use_manager, &use_reg->reg);
17725+ }
17726+ out:
17727+ mutex_unlock(&dev_priv->cmdbuf_mutex);
17728+
17729+ return ret;
17730+
17731+}
17732+
17733+void psb_takedown_use_base(struct drm_psb_private *dev_priv)
17734+{
17735+ mutex_lock(&dev_priv->cmdbuf_mutex);
17736+ drm_regs_free(&dev_priv->use_manager);
17737+ mutex_unlock(&dev_priv->cmdbuf_mutex);
17738+}
17739Index: linux-2.6.28/drivers/gpu/drm/psb/psb_reset.c
17740===================================================================
17741--- /dev/null 1970-01-01 00:00:00.000000000 +0000
17742+++ linux-2.6.28/drivers/gpu/drm/psb/psb_reset.c 2009-02-12 09:14:42.000000000 +0000
17743@@ -0,0 +1,374 @@
17744+/**************************************************************************
17745+ * Copyright (c) 2007, Intel Corporation.
17746+ * All Rights Reserved.
17747+ *
17748+ * This program is free software; you can redistribute it and/or modify it
17749+ * under the terms and conditions of the GNU General Public License,
17750+ * version 2, as published by the Free Software Foundation.
17751+ *
17752+ * This program is distributed in the hope it will be useful, but WITHOUT
17753+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17754+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17755+ * more details.
17756+ *
17757+ * You should have received a copy of the GNU General Public License along with
17758+ * this program; if not, write to the Free Software Foundation, Inc.,
17759+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17760+ *
17761+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
17762+ * develop this driver.
17763+ *
17764+ **************************************************************************/
17765+/*
17766+ * Authors:
17767+ * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
17768+ */
17769+
17770+#include "drmP.h"
17771+#include "psb_drv.h"
17772+#include "psb_reg.h"
17773+#include "psb_scene.h"
17774+#include "psb_msvdx.h"
17775+
17776+#define PSB_2D_TIMEOUT_MSEC 100
17777+
17778+void psb_reset(struct drm_psb_private *dev_priv, int reset_2d)
17779+{
17780+ uint32_t val;
17781+
17782+ val = _PSB_CS_RESET_BIF_RESET |
17783+ _PSB_CS_RESET_DPM_RESET |
17784+ _PSB_CS_RESET_TA_RESET |
17785+ _PSB_CS_RESET_USE_RESET |
17786+ _PSB_CS_RESET_ISP_RESET | _PSB_CS_RESET_TSP_RESET;
17787+
17788+ if (reset_2d)
17789+ val |= _PSB_CS_RESET_TWOD_RESET;
17790+
17791+ PSB_WSGX32(val, PSB_CR_SOFT_RESET);
17792+ (void)PSB_RSGX32(PSB_CR_SOFT_RESET);
17793+
17794+ msleep(1);
17795+
17796+ PSB_WSGX32(0, PSB_CR_SOFT_RESET);
17797+ wmb();
17798+ PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_CB_CTRL_CLEAR_FAULT,
17799+ PSB_CR_BIF_CTRL);
17800+ wmb();
17801+ (void)PSB_RSGX32(PSB_CR_BIF_CTRL);
17802+
17803+ msleep(1);
17804+ PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) & ~_PSB_CB_CTRL_CLEAR_FAULT,
17805+ PSB_CR_BIF_CTRL);
17806+ (void)PSB_RSGX32(PSB_CR_BIF_CTRL);
17807+}
17808+
17809+void psb_print_pagefault(struct drm_psb_private *dev_priv)
17810+{
17811+ uint32_t val;
17812+ uint32_t addr;
17813+
17814+ val = PSB_RSGX32(PSB_CR_BIF_INT_STAT);
17815+ addr = PSB_RSGX32(PSB_CR_BIF_FAULT);
17816+
17817+ if (val) {
17818+ if (val & _PSB_CBI_STAT_PF_N_RW)
17819+ DRM_ERROR("Poulsbo MMU page fault:\n");
17820+ else
17821+ DRM_ERROR("Poulsbo MMU read / write "
17822+ "protection fault:\n");
17823+
17824+ if (val & _PSB_CBI_STAT_FAULT_CACHE)
17825+ DRM_ERROR("\tCache requestor.\n");
17826+ if (val & _PSB_CBI_STAT_FAULT_TA)
17827+ DRM_ERROR("\tTA requestor.\n");
17828+ if (val & _PSB_CBI_STAT_FAULT_VDM)
17829+ DRM_ERROR("\tVDM requestor.\n");
17830+ if (val & _PSB_CBI_STAT_FAULT_2D)
17831+ DRM_ERROR("\t2D requestor.\n");
17832+ if (val & _PSB_CBI_STAT_FAULT_PBE)
17833+ DRM_ERROR("\tPBE requestor.\n");
17834+ if (val & _PSB_CBI_STAT_FAULT_TSP)
17835+ DRM_ERROR("\tTSP requestor.\n");
17836+ if (val & _PSB_CBI_STAT_FAULT_ISP)
17837+ DRM_ERROR("\tISP requestor.\n");
17838+ if (val & _PSB_CBI_STAT_FAULT_USSEPDS)
17839+ DRM_ERROR("\tUSSEPDS requestor.\n");
17840+ if (val & _PSB_CBI_STAT_FAULT_HOST)
17841+ DRM_ERROR("\tHost requestor.\n");
17842+
17843+ DRM_ERROR("\tMMU failing address is 0x%08x.\n", (unsigned)addr);
17844+ }
17845+}
17846+
17847+void psb_schedule_watchdog(struct drm_psb_private *dev_priv)
17848+{
17849+ struct timer_list *wt = &dev_priv->watchdog_timer;
17850+ unsigned long irq_flags;
17851+
17852+ spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
17853+ if (dev_priv->timer_available && !timer_pending(wt)) {
17854+ wt->expires = jiffies + PSB_WATCHDOG_DELAY;
17855+ add_timer(wt);
17856+ }
17857+ spin_unlock_irqrestore(&dev_priv->watchdog_lock, irq_flags);
17858+}
17859+
17860+#if 0
17861+static void psb_seq_lockup_idle(struct drm_psb_private *dev_priv,
17862+ unsigned int engine, int *lockup, int *idle)
17863+{
17864+ uint32_t received_seq;
17865+
17866+ received_seq = dev_priv->comm[engine << 4];
17867+ spin_lock(&dev_priv->sequence_lock);
17868+ *idle = (received_seq == dev_priv->sequence[engine]);
17869+ spin_unlock(&dev_priv->sequence_lock);
17870+
17871+ if (*idle) {
17872+ dev_priv->idle[engine] = 1;
17873+ *lockup = 0;
17874+ return;
17875+ }
17876+
17877+ if (dev_priv->idle[engine]) {
17878+ dev_priv->idle[engine] = 0;
17879+ dev_priv->last_sequence[engine] = received_seq;
17880+ *lockup = 0;
17881+ return;
17882+ }
17883+
17884+ *lockup = (dev_priv->last_sequence[engine] == received_seq);
17885+}
17886+
17887+#endif
17888+static void psb_watchdog_func(unsigned long data)
17889+{
17890+ struct drm_psb_private *dev_priv = (struct drm_psb_private *)data;
17891+ int lockup;
17892+ int msvdx_lockup;
17893+ int msvdx_idle;
17894+ int lockup_2d;
17895+ int idle_2d;
17896+ int idle;
17897+ unsigned long irq_flags;
17898+
17899+ psb_scheduler_lockup(dev_priv, &lockup, &idle);
17900+ psb_msvdx_lockup(dev_priv, &msvdx_lockup, &msvdx_idle);
17901+#if 0
17902+ psb_seq_lockup_idle(dev_priv, PSB_ENGINE_2D, &lockup_2d, &idle_2d);
17903+#else
17904+ lockup_2d = 0;
17905+ idle_2d = 1;
17906+#endif
17907+ if (lockup || msvdx_lockup || lockup_2d) {
17908+ spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
17909+ dev_priv->timer_available = 0;
17910+ spin_unlock_irqrestore(&dev_priv->watchdog_lock, irq_flags);
17911+ if (lockup) {
17912+ psb_print_pagefault(dev_priv);
17913+ schedule_work(&dev_priv->watchdog_wq);
17914+ }
17915+ if (msvdx_lockup)
17916+ schedule_work(&dev_priv->msvdx_watchdog_wq);
17917+ }
17918+ if (!idle || !msvdx_idle || !idle_2d)
17919+ psb_schedule_watchdog(dev_priv);
17920+}
17921+
17922+void psb_msvdx_flush_cmd_queue(struct drm_device *dev)
17923+{
17924+ struct drm_psb_private *dev_priv = dev->dev_private;
17925+ struct psb_msvdx_cmd_queue *msvdx_cmd;
17926+ struct list_head *list, *next;
17927+ /*Flush the msvdx cmd queue and signal all fences in the queue */
17928+ list_for_each_safe(list, next, &dev_priv->msvdx_queue) {
17929+ msvdx_cmd = list_entry(list, struct psb_msvdx_cmd_queue, head);
17930+ PSB_DEBUG_GENERAL("MSVDXQUE: flushing sequence:%d\n",
17931+ msvdx_cmd->sequence);
17932+ dev_priv->msvdx_current_sequence = msvdx_cmd->sequence;
17933+ psb_fence_error(dev, PSB_ENGINE_VIDEO,
17934+ dev_priv->msvdx_current_sequence,
17935+ DRM_FENCE_TYPE_EXE, DRM_CMD_HANG);
17936+ list_del(list);
17937+ kfree(msvdx_cmd->cmd);
17938+ drm_free(msvdx_cmd, sizeof(struct psb_msvdx_cmd_queue),
17939+ DRM_MEM_DRIVER);
17940+ }
17941+}
17942+
17943+static void psb_msvdx_reset_wq(struct work_struct *work)
17944+{
17945+ struct drm_psb_private *dev_priv =
17946+ container_of(work, struct drm_psb_private, msvdx_watchdog_wq);
17947+
17948+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
17949+ unsigned long irq_flags;
17950+
17951+ mutex_lock(&dev_priv->msvdx_mutex);
17952+ dev_priv->msvdx_needs_reset = 1;
17953+ dev_priv->msvdx_current_sequence++;
17954+ PSB_DEBUG_GENERAL
17955+ ("MSVDXFENCE: incremented msvdx_current_sequence to :%d\n",
17956+ dev_priv->msvdx_current_sequence);
17957+
17958+ psb_fence_error(scheduler->dev, PSB_ENGINE_VIDEO,
17959+ dev_priv->msvdx_current_sequence, DRM_FENCE_TYPE_EXE,
17960+ DRM_CMD_HANG);
17961+
17962+ spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
17963+ dev_priv->timer_available = 1;
17964+ spin_unlock_irqrestore(&dev_priv->watchdog_lock, irq_flags);
17965+
17966+ spin_lock_irqsave(&dev_priv->msvdx_lock, irq_flags);
17967+ psb_msvdx_flush_cmd_queue(scheduler->dev);
17968+ spin_unlock_irqrestore(&dev_priv->msvdx_lock, irq_flags);
17969+
17970+ psb_schedule_watchdog(dev_priv);
17971+ mutex_unlock(&dev_priv->msvdx_mutex);
17972+}
17973+
17974+static int psb_xhw_mmu_reset(struct drm_psb_private *dev_priv)
17975+{
17976+ struct psb_xhw_buf buf;
17977+ uint32_t bif_ctrl;
17978+
17979+ INIT_LIST_HEAD(&buf.head);
17980+ psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0);
17981+ bif_ctrl = PSB_RSGX32(PSB_CR_BIF_CTRL);
17982+ PSB_WSGX32(bif_ctrl |
17983+ _PSB_CB_CTRL_CLEAR_FAULT |
17984+ _PSB_CB_CTRL_INVALDC, PSB_CR_BIF_CTRL);
17985+ (void)PSB_RSGX32(PSB_CR_BIF_CTRL);
17986+ msleep(1);
17987+ PSB_WSGX32(bif_ctrl, PSB_CR_BIF_CTRL);
17988+ (void)PSB_RSGX32(PSB_CR_BIF_CTRL);
17989+ return psb_xhw_reset_dpm(dev_priv, &buf);
17990+}
17991+
17992+/*
17993+ * Block command submission and reset hardware and schedulers.
17994+ */
17995+
17996+static void psb_reset_wq(struct work_struct *work)
17997+{
17998+ struct drm_psb_private *dev_priv =
17999+ container_of(work, struct drm_psb_private, watchdog_wq);
18000+ int lockup_2d;
18001+ int idle_2d;
18002+ unsigned long irq_flags;
18003+ int ret;
18004+ int reset_count = 0;
18005+ struct psb_xhw_buf buf;
18006+ uint32_t xhw_lockup;
18007+
18008+ /*
18009+ * Block command submission.
18010+ */
18011+
18012+ mutex_lock(&dev_priv->reset_mutex);
18013+
18014+ INIT_LIST_HEAD(&buf.head);
18015+ if (psb_xhw_check_lockup(dev_priv, &buf, &xhw_lockup) == 0) {
18016+ if (xhw_lockup == 0 && psb_extend_raster_timeout(dev_priv) == 0) {
18017+ /*
18018+ * no lockup, just re-schedule
18019+ */
18020+ spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
18021+ dev_priv->timer_available = 1;
18022+ spin_unlock_irqrestore(&dev_priv->watchdog_lock,
18023+ irq_flags);
18024+ psb_schedule_watchdog(dev_priv);
18025+ mutex_unlock(&dev_priv->reset_mutex);
18026+ return;
18027+ }
18028+ }
18029+#if 0
18030+ msleep(PSB_2D_TIMEOUT_MSEC);
18031+
18032+ psb_seq_lockup_idle(dev_priv, PSB_ENGINE_2D, &lockup_2d, &idle_2d);
18033+
18034+ if (lockup_2d) {
18035+ uint32_t seq_2d;
18036+ spin_lock(&dev_priv->sequence_lock);
18037+ seq_2d = dev_priv->sequence[PSB_ENGINE_2D];
18038+ spin_unlock(&dev_priv->sequence_lock);
18039+ psb_fence_error(dev_priv->scheduler.dev,
18040+ PSB_ENGINE_2D,
18041+ seq_2d, DRM_FENCE_TYPE_EXE, -EBUSY);
18042+ DRM_INFO("Resetting 2D engine.\n");
18043+ }
18044+
18045+ psb_reset(dev_priv, lockup_2d);
18046+#else
18047+ (void)lockup_2d;
18048+ (void)idle_2d;
18049+ psb_reset(dev_priv, 0);
18050+#endif
18051+ (void)psb_xhw_mmu_reset(dev_priv);
18052+ DRM_INFO("Resetting scheduler.\n");
18053+ psb_scheduler_pause(dev_priv);
18054+ psb_scheduler_reset(dev_priv, -EBUSY);
18055+ psb_scheduler_ta_mem_check(dev_priv);
18056+
18057+ while (dev_priv->ta_mem &&
18058+ !dev_priv->force_ta_mem_load && ++reset_count < 10) {
18059+
18060+ /*
18061+ * TA memory is currently fenced so offsets
18062+ * are valid. Reload offsets into the dpm now.
18063+ */
18064+
18065+ struct psb_xhw_buf buf;
18066+ INIT_LIST_HEAD(&buf.head);
18067+
18068+ msleep(100);
18069+ DRM_INFO("Trying to reload TA memory.\n");
18070+ ret = psb_xhw_ta_mem_load(dev_priv, &buf,
18071+ PSB_TA_MEM_FLAG_TA |
18072+ PSB_TA_MEM_FLAG_RASTER |
18073+ PSB_TA_MEM_FLAG_HOSTA |
18074+ PSB_TA_MEM_FLAG_HOSTD |
18075+ PSB_TA_MEM_FLAG_INIT,
18076+ dev_priv->ta_mem->ta_memory->offset,
18077+ dev_priv->ta_mem->hw_data->offset,
18078+ dev_priv->ta_mem->hw_cookie);
18079+ if (!ret)
18080+ break;
18081+
18082+ psb_reset(dev_priv, 0);
18083+ (void)psb_xhw_mmu_reset(dev_priv);
18084+ }
18085+
18086+ psb_scheduler_restart(dev_priv);
18087+ spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
18088+ dev_priv->timer_available = 1;
18089+ spin_unlock_irqrestore(&dev_priv->watchdog_lock, irq_flags);
18090+ mutex_unlock(&dev_priv->reset_mutex);
18091+}
18092+
18093+void psb_watchdog_init(struct drm_psb_private *dev_priv)
18094+{
18095+ struct timer_list *wt = &dev_priv->watchdog_timer;
18096+ unsigned long irq_flags;
18097+
18098+ dev_priv->watchdog_lock = SPIN_LOCK_UNLOCKED;
18099+ spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
18100+ init_timer(wt);
18101+ INIT_WORK(&dev_priv->watchdog_wq, &psb_reset_wq);
18102+ INIT_WORK(&dev_priv->msvdx_watchdog_wq, &psb_msvdx_reset_wq);
18103+ wt->data = (unsigned long)dev_priv;
18104+ wt->function = &psb_watchdog_func;
18105+ dev_priv->timer_available = 1;
18106+ spin_unlock_irqrestore(&dev_priv->watchdog_lock, irq_flags);
18107+}
18108+
18109+void psb_watchdog_takedown(struct drm_psb_private *dev_priv)
18110+{
18111+ unsigned long irq_flags;
18112+
18113+ spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
18114+ dev_priv->timer_available = 0;
18115+ spin_unlock_irqrestore(&dev_priv->watchdog_lock, irq_flags);
18116+ (void)del_timer_sync(&dev_priv->watchdog_timer);
18117+}
18118Index: linux-2.6.28/drivers/gpu/drm/psb/psb_scene.c
18119===================================================================
18120--- /dev/null 1970-01-01 00:00:00.000000000 +0000
18121+++ linux-2.6.28/drivers/gpu/drm/psb/psb_scene.c 2009-02-12 09:14:42.000000000 +0000
18122@@ -0,0 +1,531 @@
18123+/**************************************************************************
18124+ * Copyright (c) 2007, Intel Corporation.
18125+ * All Rights Reserved.
18126+ *
18127+ * This program is free software; you can redistribute it and/or modify it
18128+ * under the terms and conditions of the GNU General Public License,
18129+ * version 2, as published by the Free Software Foundation.
18130+ *
18131+ * This program is distributed in the hope it will be useful, but WITHOUT
18132+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18133+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18134+ * more details.
18135+ *
18136+ * You should have received a copy of the GNU General Public License along with
18137+ * this program; if not, write to the Free Software Foundation, Inc.,
18138+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18139+ *
18140+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
18141+ * develop this driver.
18142+ *
18143+ **************************************************************************/
18144+/*
18145+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
18146+ */
18147+
18148+#include "drmP.h"
18149+#include "psb_drv.h"
18150+#include "psb_scene.h"
18151+
18152+void psb_clear_scene_atomic(struct psb_scene *scene)
18153+{
18154+ int i;
18155+ struct page *page;
18156+ void *v;
18157+
18158+ for (i = 0; i < scene->clear_num_pages; ++i) {
18159+ page = drm_ttm_get_page(scene->hw_data->ttm,
18160+ scene->clear_p_start + i);
18161+ if (in_irq())
18162+ v = kmap_atomic(page, KM_IRQ0);
18163+ else
18164+ v = kmap_atomic(page, KM_USER0);
18165+
18166+ memset(v, 0, PAGE_SIZE);
18167+
18168+ if (in_irq())
18169+ kunmap_atomic(v, KM_IRQ0);
18170+ else
18171+ kunmap_atomic(v, KM_USER0);
18172+ }
18173+}
18174+
18175+int psb_clear_scene(struct psb_scene *scene)
18176+{
18177+ struct drm_bo_kmap_obj bmo;
18178+ int is_iomem;
18179+ void *addr;
18180+
18181+ int ret = drm_bo_kmap(scene->hw_data, scene->clear_p_start,
18182+ scene->clear_num_pages, &bmo);
18183+
18184+ PSB_DEBUG_RENDER("Scene clear\n");
18185+ if (ret)
18186+ return ret;
18187+
18188+ addr = drm_bmo_virtual(&bmo, &is_iomem);
18189+ BUG_ON(is_iomem);
18190+ memset(addr, 0, scene->clear_num_pages << PAGE_SHIFT);
18191+ drm_bo_kunmap(&bmo);
18192+
18193+ return 0;
18194+}
18195+
18196+static void psb_destroy_scene_devlocked(struct psb_scene *scene)
18197+{
18198+ if (!scene)
18199+ return;
18200+
18201+ PSB_DEBUG_RENDER("Scene destroy\n");
18202+ drm_bo_usage_deref_locked(&scene->hw_data);
18203+ drm_free(scene, sizeof(*scene), DRM_MEM_DRIVER);
18204+}
18205+
18206+void psb_scene_unref_devlocked(struct psb_scene **scene)
18207+{
18208+ struct psb_scene *tmp_scene = *scene;
18209+
18210+ PSB_DEBUG_RENDER("Scene unref\n");
18211+ *scene = NULL;
18212+ if (atomic_dec_and_test(&tmp_scene->ref_count)) {
18213+ psb_scheduler_remove_scene_refs(tmp_scene);
18214+ psb_destroy_scene_devlocked(tmp_scene);
18215+ }
18216+}
18217+
18218+struct psb_scene *psb_scene_ref(struct psb_scene *src)
18219+{
18220+ PSB_DEBUG_RENDER("Scene ref\n");
18221+ atomic_inc(&src->ref_count);
18222+ return src;
18223+}
18224+
18225+static struct psb_scene *psb_alloc_scene(struct drm_device *dev,
18226+ uint32_t w, uint32_t h)
18227+{
18228+ struct drm_psb_private *dev_priv =
18229+ (struct drm_psb_private *)dev->dev_private;
18230+ int ret = -EINVAL;
18231+ struct psb_scene *scene;
18232+ uint32_t bo_size;
18233+ struct psb_xhw_buf buf;
18234+
18235+ PSB_DEBUG_RENDER("Alloc scene w %u h %u\n", w, h);
18236+
18237+ scene = drm_calloc(1, sizeof(*scene), DRM_MEM_DRIVER);
18238+
18239+ if (!scene) {
18240+ DRM_ERROR("Out of memory allocating scene object.\n");
18241+ return NULL;
18242+ }
18243+
18244+ scene->dev = dev;
18245+ scene->w = w;
18246+ scene->h = h;
18247+ scene->hw_scene = NULL;
18248+ atomic_set(&scene->ref_count, 1);
18249+
18250+ INIT_LIST_HEAD(&buf.head);
18251+ ret = psb_xhw_scene_info(dev_priv, &buf, scene->w, scene->h,
18252+ scene->hw_cookie, &bo_size,
18253+ &scene->clear_p_start,
18254+ &scene->clear_num_pages);
18255+ if (ret)
18256+ goto out_err;
18257+
18258+ ret = drm_buffer_object_create(dev, bo_size, drm_bo_type_kernel,
18259+ DRM_PSB_FLAG_MEM_MMU |
18260+ DRM_BO_FLAG_READ |
18261+ DRM_BO_FLAG_CACHED |
18262+ PSB_BO_FLAG_SCENE |
18263+ DRM_BO_FLAG_WRITE,
18264+ DRM_BO_HINT_DONT_FENCE,
18265+ 0, 0, &scene->hw_data);
18266+ if (ret)
18267+ goto out_err;
18268+
18269+ return scene;
18270+ out_err:
18271+ drm_free(scene, sizeof(*scene), DRM_MEM_DRIVER);
18272+ return NULL;
18273+}
18274+
18275+int psb_validate_scene_pool(struct psb_scene_pool *pool, uint64_t flags,
18276+ uint64_t mask,
18277+ uint32_t hint,
18278+ uint32_t w,
18279+ uint32_t h,
18280+ int final_pass, struct psb_scene **scene_p)
18281+{
18282+ struct drm_device *dev = pool->dev;
18283+ struct drm_psb_private *dev_priv =
18284+ (struct drm_psb_private *)dev->dev_private;
18285+ struct psb_scene *scene = pool->scenes[pool->cur_scene];
18286+ int ret;
18287+ unsigned long irq_flags;
18288+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
18289+ uint32_t bin_pt_offset;
18290+ uint32_t bin_param_offset;
18291+
18292+ PSB_DEBUG_RENDER("Validate scene pool. Scene %u\n", pool->cur_scene);
18293+
18294+ if (unlikely(!dev_priv->ta_mem)) {
18295+ dev_priv->ta_mem =
18296+ psb_alloc_ta_mem(dev, dev_priv->ta_mem_pages);
18297+ if (!dev_priv->ta_mem)
18298+ return -ENOMEM;
18299+
18300+ bin_pt_offset = ~0;
18301+ bin_param_offset = ~0;
18302+ } else {
18303+ bin_pt_offset = dev_priv->ta_mem->hw_data->offset;
18304+ bin_param_offset = dev_priv->ta_mem->ta_memory->offset;
18305+ }
18306+
18307+ pool->w = w;
18308+ pool->h = h;
18309+ if (scene && (scene->w != pool->w || scene->h != pool->h)) {
18310+ spin_lock_irqsave(&scheduler->lock, irq_flags);
18311+ if (scene->flags & PSB_SCENE_FLAG_DIRTY) {
18312+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
18313+ DRM_ERROR("Trying to resize a dirty scene.\n");
18314+ return -EINVAL;
18315+ }
18316+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
18317+ mutex_lock(&dev->struct_mutex);
18318+ psb_scene_unref_devlocked(&pool->scenes[pool->cur_scene]);
18319+ mutex_unlock(&dev->struct_mutex);
18320+ scene = NULL;
18321+ }
18322+
18323+ if (!scene) {
18324+ pool->scenes[pool->cur_scene] = scene =
18325+ psb_alloc_scene(pool->dev, pool->w, pool->h);
18326+
18327+ if (!scene)
18328+ return -ENOMEM;
18329+
18330+ scene->flags = PSB_SCENE_FLAG_CLEARED;
18331+ }
18332+
18333+ /*
18334+ * FIXME: We need atomic bit manipulation here for the
18335+ * scheduler. For now use the spinlock.
18336+ */
18337+
18338+ spin_lock_irqsave(&scheduler->lock, irq_flags);
18339+ if (!(scene->flags & PSB_SCENE_FLAG_CLEARED)) {
18340+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
18341+ PSB_DEBUG_RENDER("Waiting to clear scene memory.\n");
18342+ mutex_lock(&scene->hw_data->mutex);
18343+ ret = drm_bo_wait(scene->hw_data, 0, 0, 0);
18344+ mutex_unlock(&scene->hw_data->mutex);
18345+ if (ret)
18346+ return ret;
18347+
18348+ ret = psb_clear_scene(scene);
18349+
18350+ if (ret)
18351+ return ret;
18352+ spin_lock_irqsave(&scheduler->lock, irq_flags);
18353+ scene->flags |= PSB_SCENE_FLAG_CLEARED;
18354+ }
18355+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
18356+
18357+ ret = drm_bo_do_validate(scene->hw_data, flags, mask, hint,
18358+ PSB_ENGINE_TA, 0, NULL);
18359+ if (ret)
18360+ return ret;
18361+ ret = drm_bo_do_validate(dev_priv->ta_mem->hw_data, 0, 0, 0,
18362+ PSB_ENGINE_TA, 0, NULL);
18363+ if (ret)
18364+ return ret;
18365+ ret = drm_bo_do_validate(dev_priv->ta_mem->ta_memory, 0, 0, 0,
18366+ PSB_ENGINE_TA, 0, NULL);
18367+ if (ret)
18368+ return ret;
18369+
18370+ if (unlikely(bin_param_offset !=
18371+ dev_priv->ta_mem->ta_memory->offset ||
18372+ bin_pt_offset !=
18373+ dev_priv->ta_mem->hw_data->offset ||
18374+ dev_priv->force_ta_mem_load)) {
18375+
18376+ struct psb_xhw_buf buf;
18377+
18378+ INIT_LIST_HEAD(&buf.head);
18379+ ret = psb_xhw_ta_mem_load(dev_priv, &buf,
18380+ PSB_TA_MEM_FLAG_TA |
18381+ PSB_TA_MEM_FLAG_RASTER |
18382+ PSB_TA_MEM_FLAG_HOSTA |
18383+ PSB_TA_MEM_FLAG_HOSTD |
18384+ PSB_TA_MEM_FLAG_INIT,
18385+ dev_priv->ta_mem->ta_memory->offset,
18386+ dev_priv->ta_mem->hw_data->offset,
18387+ dev_priv->ta_mem->hw_cookie);
18388+ if (ret)
18389+ return ret;
18390+
18391+ dev_priv->force_ta_mem_load = 0;
18392+ }
18393+
18394+ if (final_pass) {
18395+
18396+ /*
18397+ * Clear the scene on next use. Advance the scene counter.
18398+ */
18399+
18400+ spin_lock_irqsave(&scheduler->lock, irq_flags);
18401+ scene->flags &= ~PSB_SCENE_FLAG_CLEARED;
18402+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
18403+ pool->cur_scene = (pool->cur_scene + 1) % pool->num_scenes;
18404+ }
18405+
18406+ *scene_p = psb_scene_ref(scene);
18407+ return 0;
18408+}
18409+
18410+static void psb_scene_pool_destroy_devlocked(struct psb_scene_pool *pool)
18411+{
18412+ int i;
18413+
18414+ if (!pool)
18415+ return;
18416+
18417+ PSB_DEBUG_RENDER("Scene pool destroy.\n");
18418+ for (i = 0; i < pool->num_scenes; ++i) {
18419+ PSB_DEBUG_RENDER("scenes %d is 0x%08lx\n", i,
18420+ (unsigned long)pool->scenes[i]);
18421+ if (pool->scenes[i])
18422+ psb_scene_unref_devlocked(&pool->scenes[i]);
18423+ }
18424+ drm_free(pool, sizeof(*pool), DRM_MEM_DRIVER);
18425+}
18426+
18427+void psb_scene_pool_unref_devlocked(struct psb_scene_pool **pool)
18428+{
18429+ struct psb_scene_pool *tmp_pool = *pool;
18430+ struct drm_device *dev = tmp_pool->dev;
18431+
18432+ PSB_DEBUG_RENDER("Scene pool unref\n");
18433+ (void)dev;
18434+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
18435+ *pool = NULL;
18436+ if (--tmp_pool->ref_count == 0)
18437+ psb_scene_pool_destroy_devlocked(tmp_pool);
18438+}
18439+
18440+struct psb_scene_pool *psb_scene_pool_ref_devlocked(struct psb_scene_pool *src)
18441+{
18442+ ++src->ref_count;
18443+ return src;
18444+}
18445+
18446+/*
18447+ * Callback for user object manager.
18448+ */
18449+
18450+static void psb_scene_pool_destroy(struct drm_file *priv,
18451+ struct drm_user_object *base)
18452+{
18453+ struct psb_scene_pool *pool =
18454+ drm_user_object_entry(base, struct psb_scene_pool, user);
18455+
18456+ psb_scene_pool_unref_devlocked(&pool);
18457+}
18458+
18459+struct psb_scene_pool *psb_scene_pool_lookup_devlocked(struct drm_file *priv,
18460+ uint32_t handle,
18461+ int check_owner)
18462+{
18463+ struct drm_user_object *uo;
18464+ struct psb_scene_pool *pool;
18465+
18466+ uo = drm_lookup_user_object(priv, handle);
18467+ if (!uo || (uo->type != PSB_USER_OBJECT_SCENE_POOL)) {
18468+ DRM_ERROR("Could not find scene pool object 0x%08x\n", handle);
18469+ return NULL;
18470+ }
18471+
18472+ if (check_owner && priv != uo->owner) {
18473+ if (!drm_lookup_ref_object(priv, uo, _DRM_REF_USE))
18474+ return NULL;
18475+ }
18476+
18477+ pool = drm_user_object_entry(uo, struct psb_scene_pool, user);
18478+ return psb_scene_pool_ref_devlocked(pool);
18479+}
18480+
18481+struct psb_scene_pool *psb_scene_pool_alloc(struct drm_file *priv,
18482+ int shareable,
18483+ uint32_t num_scenes,
18484+ uint32_t w, uint32_t h)
18485+{
18486+ struct drm_device *dev = priv->minor->dev;
18487+ struct psb_scene_pool *pool;
18488+ int ret;
18489+
18490+ PSB_DEBUG_RENDER("Scene pool alloc\n");
18491+ pool = drm_calloc(1, sizeof(*pool), DRM_MEM_DRIVER);
18492+ if (!pool) {
18493+ DRM_ERROR("Out of memory allocating scene pool object.\n");
18494+ return NULL;
18495+ }
18496+ pool->w = w;
18497+ pool->h = h;
18498+ pool->dev = dev;
18499+ pool->num_scenes = num_scenes;
18500+
18501+ mutex_lock(&dev->struct_mutex);
18502+ ret = drm_add_user_object(priv, &pool->user, shareable);
18503+ if (ret)
18504+ goto out_err;
18505+
18506+ pool->user.type = PSB_USER_OBJECT_SCENE_POOL;
18507+ pool->user.remove = &psb_scene_pool_destroy;
18508+ pool->ref_count = 2;
18509+ mutex_unlock(&dev->struct_mutex);
18510+ return pool;
18511+ out_err:
18512+ drm_free(pool, sizeof(*pool), DRM_MEM_DRIVER);
18513+ return NULL;
18514+}
18515+
18516+/*
18517+ * Code to support multiple ta memory buffers.
18518+ */
18519+
18520+static void psb_destroy_ta_mem_devlocked(struct psb_ta_mem *ta_mem)
18521+{
18522+ if (!ta_mem)
18523+ return;
18524+
18525+ drm_bo_usage_deref_locked(&ta_mem->hw_data);
18526+ drm_bo_usage_deref_locked(&ta_mem->ta_memory);
18527+ drm_free(ta_mem, sizeof(*ta_mem), DRM_MEM_DRIVER);
18528+}
18529+
18530+void psb_ta_mem_unref_devlocked(struct psb_ta_mem **ta_mem)
18531+{
18532+ struct psb_ta_mem *tmp_ta_mem = *ta_mem;
18533+ struct drm_device *dev = tmp_ta_mem->dev;
18534+
18535+ (void)dev;
18536+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
18537+ *ta_mem = NULL;
18538+ if (--tmp_ta_mem->ref_count == 0)
18539+ psb_destroy_ta_mem_devlocked(tmp_ta_mem);
18540+}
18541+
18542+void psb_ta_mem_ref_devlocked(struct psb_ta_mem **dst, struct psb_ta_mem *src)
18543+{
18544+ struct drm_device *dev = src->dev;
18545+
18546+ (void)dev;
18547+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
18548+ *dst = src;
18549+ ++src->ref_count;
18550+}
18551+
18552+struct psb_ta_mem *psb_alloc_ta_mem(struct drm_device *dev, uint32_t pages)
18553+{
18554+ struct drm_psb_private *dev_priv =
18555+ (struct drm_psb_private *)dev->dev_private;
18556+ int ret = -EINVAL;
18557+ struct psb_ta_mem *ta_mem;
18558+ uint32_t bo_size;
18559+ struct psb_xhw_buf buf;
18560+
18561+ INIT_LIST_HEAD(&buf.head);
18562+
18563+ ta_mem = drm_calloc(1, sizeof(*ta_mem), DRM_MEM_DRIVER);
18564+
18565+ if (!ta_mem) {
18566+ DRM_ERROR("Out of memory allocating parameter memory.\n");
18567+ return NULL;
18568+ }
18569+
18570+ ret = psb_xhw_ta_mem_info(dev_priv, &buf, pages,
18571+ ta_mem->hw_cookie, &bo_size);
18572+ if (ret == -ENOMEM) {
18573+ DRM_ERROR("Parameter memory size is too small.\n");
18574+ DRM_INFO("Attempted to use %u kiB of parameter memory.\n",
18575+ (unsigned int)(pages * (PAGE_SIZE / 1024)));
18576+ DRM_INFO("The Xpsb driver thinks this is too small and\n");
18577+ DRM_INFO("suggests %u kiB. Check the psb DRM\n",
18578+ (unsigned int)(bo_size / 1024));
18579+ DRM_INFO("\"ta_mem_size\" parameter!\n");
18580+ }
18581+ if (ret)
18582+ goto out_err0;
18583+
18584+ bo_size = pages * PAGE_SIZE;
18585+ ta_mem->dev = dev;
18586+ ret = drm_buffer_object_create(dev, bo_size, drm_bo_type_kernel,
18587+ DRM_PSB_FLAG_MEM_MMU | DRM_BO_FLAG_READ |
18588+ DRM_BO_FLAG_WRITE |
18589+ PSB_BO_FLAG_SCENE,
18590+ DRM_BO_HINT_DONT_FENCE, 0, 0,
18591+ &ta_mem->hw_data);
18592+ if (ret)
18593+ goto out_err0;
18594+
18595+ ret =
18596+ drm_buffer_object_create(dev, pages << PAGE_SHIFT,
18597+ drm_bo_type_kernel,
18598+ DRM_PSB_FLAG_MEM_RASTGEOM |
18599+ DRM_BO_FLAG_READ |
18600+ DRM_BO_FLAG_WRITE |
18601+ PSB_BO_FLAG_SCENE,
18602+ DRM_BO_HINT_DONT_FENCE, 0,
18603+ 1024 * 1024 >> PAGE_SHIFT,
18604+ &ta_mem->ta_memory);
18605+ if (ret)
18606+ goto out_err1;
18607+
18608+ ta_mem->ref_count = 1;
18609+ return ta_mem;
18610+ out_err1:
18611+ drm_bo_usage_deref_unlocked(&ta_mem->hw_data);
18612+ out_err0:
18613+ drm_free(ta_mem, sizeof(*ta_mem), DRM_MEM_DRIVER);
18614+ return NULL;
18615+}
18616+
18617+int drm_psb_scene_unref_ioctl(struct drm_device *dev,
18618+ void *data, struct drm_file *file_priv)
18619+{
18620+ struct drm_psb_scene *scene = (struct drm_psb_scene *)data;
18621+ struct drm_user_object *uo;
18622+ struct drm_ref_object *ro;
18623+ int ret = 0;
18624+
18625+ mutex_lock(&dev->struct_mutex);
18626+ if (!scene->handle_valid)
18627+ goto out_unlock;
18628+
18629+ uo = drm_lookup_user_object(file_priv, scene->handle);
18630+ if (!uo) {
18631+ ret = -EINVAL;
18632+ goto out_unlock;
18633+ }
18634+ if (uo->type != PSB_USER_OBJECT_SCENE_POOL) {
18635+ DRM_ERROR("Not a scene pool object.\n");
18636+ ret = -EINVAL;
18637+ goto out_unlock;
18638+ }
18639+ if (uo->owner != file_priv) {
18640+ DRM_ERROR("Not owner of scene pool object.\n");
18641+ ret = -EPERM;
18642+ goto out_unlock;
18643+ }
18644+
18645+ scene->handle_valid = 0;
18646+ ro = drm_lookup_ref_object(file_priv, uo, _DRM_REF_USE);
18647+ BUG_ON(!ro);
18648+ drm_remove_ref_object(file_priv, ro);
18649+
18650+ out_unlock:
18651+ mutex_unlock(&dev->struct_mutex);
18652+ return ret;
18653+}
18654Index: linux-2.6.28/drivers/gpu/drm/psb/psb_scene.h
18655===================================================================
18656--- /dev/null 1970-01-01 00:00:00.000000000 +0000
18657+++ linux-2.6.28/drivers/gpu/drm/psb/psb_scene.h 2009-02-12 09:14:42.000000000 +0000
18658@@ -0,0 +1,112 @@
18659+/**************************************************************************
18660+ * Copyright (c) 2007, Intel Corporation.
18661+ * All Rights Reserved.
18662+ *
18663+ * This program is free software; you can redistribute it and/or modify it
18664+ * under the terms and conditions of the GNU General Public License,
18665+ * version 2, as published by the Free Software Foundation.
18666+ *
18667+ * This program is distributed in the hope it will be useful, but WITHOUT
18668+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18669+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18670+ * more details.
18671+ *
18672+ * You should have received a copy of the GNU General Public License along with
18673+ * this program; if not, write to the Free Software Foundation, Inc.,
18674+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18675+ *
18676+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
18677+ * develop this driver.
18678+ *
18679+ **************************************************************************/
18680+/*
18681+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
18682+ */
18683+
18684+#ifndef _PSB_SCENE_H_
18685+#define _PSB_SCENE_H_
18686+
18687+#define PSB_USER_OBJECT_SCENE_POOL drm_driver_type0
18688+#define PSB_USER_OBJECT_TA_MEM drm_driver_type1
18689+#define PSB_MAX_NUM_SCENES 8
18690+
18691+struct psb_hw_scene;
18692+struct psb_hw_ta_mem;
18693+
18694+struct psb_scene_pool {
18695+ struct drm_device *dev;
18696+ struct drm_user_object user;
18697+ uint32_t ref_count;
18698+ uint32_t w;
18699+ uint32_t h;
18700+ uint32_t cur_scene;
18701+ struct psb_scene *scenes[PSB_MAX_NUM_SCENES];
18702+ uint32_t num_scenes;
18703+};
18704+
18705+struct psb_scene {
18706+ struct drm_device *dev;
18707+ atomic_t ref_count;
18708+ uint32_t hw_cookie[PSB_SCENE_HW_COOKIE_SIZE];
18709+ uint32_t bo_size;
18710+ uint32_t w;
18711+ uint32_t h;
18712+ struct psb_ta_mem *ta_mem;
18713+ struct psb_hw_scene *hw_scene;
18714+ struct drm_buffer_object *hw_data;
18715+ uint32_t flags;
18716+ uint32_t clear_p_start;
18717+ uint32_t clear_num_pages;
18718+};
18719+
18720+struct psb_scene_entry {
18721+ struct list_head head;
18722+ struct psb_scene *scene;
18723+};
18724+
18725+struct psb_user_scene {
18726+ struct drm_device *dev;
18727+ struct drm_user_object user;
18728+};
18729+
18730+struct psb_ta_mem {
18731+ struct drm_device *dev;
18732+ struct drm_user_object user;
18733+ uint32_t ref_count;
18734+ uint32_t hw_cookie[PSB_TA_MEM_HW_COOKIE_SIZE];
18735+ uint32_t bo_size;
18736+ struct drm_buffer_object *ta_memory;
18737+ struct drm_buffer_object *hw_data;
18738+ int is_deallocating;
18739+ int deallocating_scheduled;
18740+};
18741+
18742+extern struct psb_scene_pool *psb_scene_pool_alloc(struct drm_file *priv,
18743+ int shareable,
18744+ uint32_t num_scenes,
18745+ uint32_t w, uint32_t h);
18746+extern void psb_scene_pool_unref_devlocked(struct psb_scene_pool **pool);
18747+extern struct psb_scene_pool *psb_scene_pool_lookup_devlocked(struct drm_file
18748+ *priv,
18749+ uint32_t handle,
18750+ int check_owner);
18751+extern int psb_validate_scene_pool(struct psb_scene_pool *pool, uint64_t flags,
18752+ uint64_t mask, uint32_t hint, uint32_t w,
18753+ uint32_t h, int final_pass,
18754+ struct psb_scene **scene_p);
18755+extern void psb_scene_unref_devlocked(struct psb_scene **scene);
18756+extern struct psb_scene *psb_scene_ref(struct psb_scene *src);
18757+extern int drm_psb_scene_unref_ioctl(struct drm_device *dev,
18758+ void *data, struct drm_file *file_priv);
18759+
18760+static inline uint32_t psb_scene_pool_handle(struct psb_scene_pool *pool)
18761+{
18762+ return pool->user.hash.key;
18763+}
18764+extern struct psb_ta_mem *psb_alloc_ta_mem(struct drm_device *dev,
18765+ uint32_t pages);
18766+extern void psb_ta_mem_ref_devlocked(struct psb_ta_mem **dst,
18767+ struct psb_ta_mem *src);
18768+extern void psb_ta_mem_unref_devlocked(struct psb_ta_mem **ta_mem);
18769+
18770+#endif
18771Index: linux-2.6.28/drivers/gpu/drm/psb/psb_schedule.c
18772===================================================================
18773--- /dev/null 1970-01-01 00:00:00.000000000 +0000
18774+++ linux-2.6.28/drivers/gpu/drm/psb/psb_schedule.c 2009-02-12 09:14:42.000000000 +0000
18775@@ -0,0 +1,1445 @@
18776+/**************************************************************************
18777+ * Copyright (c) 2007, Intel Corporation.
18778+ * All Rights Reserved.
18779+ *
18780+ * This program is free software; you can redistribute it and/or modify it
18781+ * under the terms and conditions of the GNU General Public License,
18782+ * version 2, as published by the Free Software Foundation.
18783+ *
18784+ * This program is distributed in the hope it will be useful, but WITHOUT
18785+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18786+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18787+ * more details.
18788+ *
18789+ * You should have received a copy of the GNU General Public License along with
18790+ * this program; if not, write to the Free Software Foundation, Inc.,
18791+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18792+ *
18793+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
18794+ * develop this driver.
18795+ *
18796+ **************************************************************************/
18797+/*
18798+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
18799+ */
18800+
18801+#include "drmP.h"
18802+#include "psb_drm.h"
18803+#include "psb_drv.h"
18804+#include "psb_reg.h"
18805+#include "psb_scene.h"
18806+
18807+#define PSB_ALLOWED_RASTER_RUNTIME (DRM_HZ * 20)
18808+#define PSB_RASTER_TIMEOUT (DRM_HZ / 2)
18809+#define PSB_TA_TIMEOUT (DRM_HZ / 5)
18810+
18811+#undef PSB_SOFTWARE_WORKAHEAD
18812+
18813+#ifdef PSB_STABLE_SETTING
18814+
18815+/*
18816+ * Software blocks completely while the engines are working so there can be no
18817+ * overlap.
18818+ */
18819+
18820+#define PSB_WAIT_FOR_RASTER_COMPLETION
18821+#define PSB_WAIT_FOR_TA_COMPLETION
18822+
18823+#elif defined(PSB_PARANOID_SETTING)
18824+/*
18825+ * Software blocks "almost" while the engines are working so there can be no
18826+ * overlap.
18827+ */
18828+
18829+#define PSB_WAIT_FOR_RASTER_COMPLETION
18830+#define PSB_WAIT_FOR_TA_COMPLETION
18831+#define PSB_BE_PARANOID
18832+
18833+#elif defined(PSB_SOME_OVERLAP_BUT_LOCKUP)
18834+/*
18835+ * Software leaps ahead while the rasterizer is running and prepares
18836+ * a new ta job that can be scheduled before the rasterizer has
18837+ * finished.
18838+ */
18839+
18840+#define PSB_WAIT_FOR_TA_COMPLETION
18841+
18842+#elif defined(PSB_SOFTWARE_WORKAHEAD)
18843+/*
18844+ * Don't sync, but allow software to work ahead. and queue a number of jobs.
18845+ * But block overlapping in the scheduler.
18846+ */
18847+
18848+#define PSB_BLOCK_OVERLAP
18849+#define ONLY_ONE_JOB_IN_RASTER_QUEUE
18850+
18851+#endif
18852+
18853+/*
18854+ * Avoid pixelbe pagefaults on C0.
18855+ */
18856+#if 0
18857+#define PSB_BLOCK_OVERLAP
18858+#endif
18859+
18860+static void psb_dispatch_ta(struct drm_psb_private *dev_priv,
18861+ struct psb_scheduler *scheduler,
18862+ uint32_t reply_flag);
18863+static void psb_dispatch_raster(struct drm_psb_private *dev_priv,
18864+ struct psb_scheduler *scheduler,
18865+ uint32_t reply_flag);
18866+
18867+#ifdef FIX_TG_16
18868+
18869+static void psb_2d_atomic_unlock(struct drm_psb_private *dev_priv);
18870+static int psb_2d_trylock(struct drm_psb_private *dev_priv);
18871+static int psb_check_2d_idle(struct drm_psb_private *dev_priv);
18872+
18873+#endif
18874+
18875+void psb_scheduler_lockup(struct drm_psb_private *dev_priv,
18876+ int *lockup, int *idle)
18877+{
18878+ unsigned long irq_flags;
18879+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
18880+
18881+ *lockup = 0;
18882+ *idle = 1;
18883+
18884+ spin_lock_irqsave(&scheduler->lock, irq_flags);
18885+
18886+ if (scheduler->current_task[PSB_SCENE_ENGINE_TA] != NULL &&
18887+ time_after_eq(jiffies, scheduler->ta_end_jiffies)) {
18888+ *lockup = 1;
18889+ }
18890+ if (!*lockup
18891+ && (scheduler->current_task[PSB_SCENE_ENGINE_RASTER] != NULL)
18892+ && time_after_eq(jiffies, scheduler->raster_end_jiffies)) {
18893+ *lockup = 1;
18894+ }
18895+ if (!*lockup)
18896+ *idle = scheduler->idle;
18897+
18898+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
18899+}
18900+
18901+static inline void psb_set_idle(struct psb_scheduler *scheduler)
18902+{
18903+ scheduler->idle =
18904+ (scheduler->current_task[PSB_SCENE_ENGINE_RASTER] == NULL) &&
18905+ (scheduler->current_task[PSB_SCENE_ENGINE_TA] == NULL);
18906+ if (scheduler->idle)
18907+ wake_up(&scheduler->idle_queue);
18908+}
18909+
18910+/*
18911+ * Call with the scheduler spinlock held.
18912+ * Assigns a scene context to either the ta or the rasterizer,
18913+ * flushing out other scenes to memory if necessary.
18914+ */
18915+
18916+static int psb_set_scene_fire(struct psb_scheduler *scheduler,
18917+ struct psb_scene *scene,
18918+ int engine, struct psb_task *task)
18919+{
18920+ uint32_t flags = 0;
18921+ struct psb_hw_scene *hw_scene;
18922+ struct drm_device *dev = scene->dev;
18923+ struct drm_psb_private *dev_priv =
18924+ (struct drm_psb_private *)dev->dev_private;
18925+
18926+ hw_scene = scene->hw_scene;
18927+ if (hw_scene && hw_scene->last_scene == scene) {
18928+
18929+ /*
18930+ * Reuse the last hw scene context and delete it from the
18931+ * free list.
18932+ */
18933+
18934+ PSB_DEBUG_RENDER("Reusing hw scene %d.\n",
18935+ hw_scene->context_number);
18936+ if (scene->flags & PSB_SCENE_FLAG_DIRTY) {
18937+
18938+ /*
18939+ * No hw context initialization to be done.
18940+ */
18941+
18942+ flags |= PSB_SCENE_FLAG_SETUP_ONLY;
18943+ }
18944+
18945+ list_del_init(&hw_scene->head);
18946+
18947+ } else {
18948+ struct list_head *list;
18949+ hw_scene = NULL;
18950+
18951+ /*
18952+ * Grab a new hw scene context.
18953+ */
18954+
18955+ list_for_each(list, &scheduler->hw_scenes) {
18956+ hw_scene = list_entry(list, struct psb_hw_scene, head);
18957+ break;
18958+ }
18959+ BUG_ON(!hw_scene);
18960+ PSB_DEBUG_RENDER("New hw scene %d.\n",
18961+ hw_scene->context_number);
18962+
18963+ list_del_init(list);
18964+ }
18965+ scene->hw_scene = hw_scene;
18966+ hw_scene->last_scene = scene;
18967+
18968+ flags |= PSB_SCENE_FLAG_SETUP;
18969+
18970+ /*
18971+ * Switch context and setup the engine.
18972+ */
18973+
18974+ return psb_xhw_scene_bind_fire(dev_priv,
18975+ &task->buf,
18976+ task->flags,
18977+ hw_scene->context_number,
18978+ scene->hw_cookie,
18979+ task->oom_cmds,
18980+ task->oom_cmd_size,
18981+ scene->hw_data->offset,
18982+ engine, flags | scene->flags);
18983+}
18984+
18985+static inline void psb_report_fence(struct psb_scheduler *scheduler,
18986+ uint32_t class,
18987+ uint32_t sequence,
18988+ uint32_t type, int call_handler)
18989+{
18990+ struct psb_scheduler_seq *seq = &scheduler->seq[type];
18991+
18992+ seq->sequence = sequence;
18993+ seq->reported = 0;
18994+ if (call_handler)
18995+ psb_fence_handler(scheduler->dev, class);
18996+}
18997+
18998+static void psb_schedule_raster(struct drm_psb_private *dev_priv,
18999+ struct psb_scheduler *scheduler);
19000+
19001+static void psb_schedule_ta(struct drm_psb_private *dev_priv,
19002+ struct psb_scheduler *scheduler)
19003+{
19004+ struct psb_task *task = NULL;
19005+ struct list_head *list, *next;
19006+ int pushed_raster_task = 0;
19007+
19008+ PSB_DEBUG_RENDER("schedule ta\n");
19009+
19010+ if (scheduler->idle_count != 0)
19011+ return;
19012+
19013+ if (scheduler->current_task[PSB_SCENE_ENGINE_TA] != NULL)
19014+ return;
19015+
19016+ if (scheduler->ta_state)
19017+ return;
19018+
19019+ /*
19020+ * Skip the ta stage for rasterization-only
19021+ * tasks. They arrive here to make sure we're rasterizing
19022+ * tasks in the correct order.
19023+ */
19024+
19025+ list_for_each_safe(list, next, &scheduler->ta_queue) {
19026+ task = list_entry(list, struct psb_task, head);
19027+ if (task->task_type != psb_raster_task)
19028+ break;
19029+
19030+ list_del_init(list);
19031+ list_add_tail(list, &scheduler->raster_queue);
19032+ psb_report_fence(scheduler, task->engine, task->sequence,
19033+ _PSB_FENCE_TA_DONE_SHIFT, 1);
19034+ task = NULL;
19035+ pushed_raster_task = 1;
19036+ }
19037+
19038+ if (pushed_raster_task)
19039+ psb_schedule_raster(dev_priv, scheduler);
19040+
19041+ if (!task)
19042+ return;
19043+
19044+ /*
19045+ * Still waiting for a vistest?
19046+ */
19047+
19048+ if (scheduler->feedback_task == task)
19049+ return;
19050+
19051+#ifdef ONLY_ONE_JOB_IN_RASTER_QUEUE
19052+
19053+ /*
19054+ * Block ta from trying to use both hardware contexts
19055+ * without the rasterizer starting to render from one of them.
19056+ */
19057+
19058+ if (!list_empty(&scheduler->raster_queue)) {
19059+ return;
19060+ }
19061+#endif
19062+
19063+#ifdef PSB_BLOCK_OVERLAP
19064+ /*
19065+ * Make sure rasterizer isn't doing anything.
19066+ */
19067+ if (scheduler->current_task[PSB_SCENE_ENGINE_RASTER] != NULL)
19068+ return;
19069+#endif
19070+ if (list_empty(&scheduler->hw_scenes))
19071+ return;
19072+
19073+#ifdef FIX_TG_16
19074+ if (psb_check_2d_idle(dev_priv))
19075+ return;
19076+#endif
19077+
19078+ list_del_init(&task->head);
19079+ if (task->flags & PSB_FIRE_FLAG_XHW_OOM)
19080+ scheduler->ta_state = 1;
19081+
19082+ scheduler->current_task[PSB_SCENE_ENGINE_TA] = task;
19083+ scheduler->idle = 0;
19084+ scheduler->ta_end_jiffies = jiffies + PSB_TA_TIMEOUT;
19085+
19086+ task->reply_flags = (task->flags & PSB_FIRE_FLAG_XHW_OOM) ?
19087+ 0x00000000 : PSB_RF_FIRE_TA;
19088+
19089+ (void)psb_reg_submit(dev_priv, task->ta_cmds, task->ta_cmd_size);
19090+ psb_set_scene_fire(scheduler, task->scene, PSB_SCENE_ENGINE_TA, task);
19091+ psb_schedule_watchdog(dev_priv);
19092+}
19093+
19094+static int psb_fire_raster(struct psb_scheduler *scheduler,
19095+ struct psb_task *task)
19096+{
19097+ struct drm_device *dev = scheduler->dev;
19098+ struct drm_psb_private *dev_priv = (struct drm_psb_private *)
19099+ dev->dev_private;
19100+
19101+ PSB_DEBUG_RENDER("Fire raster %d\n", task->sequence);
19102+
19103+ return psb_xhw_fire_raster(dev_priv, &task->buf, task->flags);
19104+}
19105+
19106+/*
19107+ * Take the first rasterization task from the hp raster queue or from the
19108+ * raster queue and fire the rasterizer.
19109+ */
19110+
19111+static void psb_schedule_raster(struct drm_psb_private *dev_priv,
19112+ struct psb_scheduler *scheduler)
19113+{
19114+ struct psb_task *task;
19115+ struct list_head *list;
19116+
19117+ if (scheduler->idle_count != 0)
19118+ return;
19119+
19120+ if (scheduler->current_task[PSB_SCENE_ENGINE_RASTER] != NULL) {
19121+ PSB_DEBUG_RENDER("Raster busy.\n");
19122+ return;
19123+ }
19124+#ifdef PSB_BLOCK_OVERLAP
19125+ if (scheduler->current_task[PSB_SCENE_ENGINE_TA] != NULL) {
19126+ PSB_DEBUG_RENDER("TA busy.\n");
19127+ return;
19128+ }
19129+#endif
19130+
19131+ if (!list_empty(&scheduler->hp_raster_queue))
19132+ list = scheduler->hp_raster_queue.next;
19133+ else if (!list_empty(&scheduler->raster_queue))
19134+ list = scheduler->raster_queue.next;
19135+ else {
19136+ PSB_DEBUG_RENDER("Nothing in list\n");
19137+ return;
19138+ }
19139+
19140+ task = list_entry(list, struct psb_task, head);
19141+
19142+ /*
19143+ * Sometimes changing ZLS format requires an ISP reset.
19144+ * Doesn't seem to consume too much time.
19145+ */
19146+
19147+ if (task->scene)
19148+ PSB_WSGX32(_PSB_CS_RESET_ISP_RESET, PSB_CR_SOFT_RESET);
19149+
19150+ scheduler->current_task[PSB_SCENE_ENGINE_RASTER] = task;
19151+
19152+ list_del_init(list);
19153+ scheduler->idle = 0;
19154+ scheduler->raster_end_jiffies = jiffies + PSB_RASTER_TIMEOUT;
19155+ scheduler->total_raster_jiffies = 0;
19156+
19157+ if (task->scene)
19158+ PSB_WSGX32(0, PSB_CR_SOFT_RESET);
19159+
19160+ (void)psb_reg_submit(dev_priv, task->raster_cmds,
19161+ task->raster_cmd_size);
19162+
19163+ if (task->scene) {
19164+ task->reply_flags = (task->flags & PSB_FIRE_FLAG_XHW_OOM) ?
19165+ 0x00000000 : PSB_RF_FIRE_RASTER;
19166+ psb_set_scene_fire(scheduler,
19167+ task->scene, PSB_SCENE_ENGINE_RASTER, task);
19168+ } else {
19169+ task->reply_flags = PSB_RF_DEALLOC | PSB_RF_FIRE_RASTER;
19170+ psb_fire_raster(scheduler, task);
19171+ }
19172+ psb_schedule_watchdog(dev_priv);
19173+}
19174+
19175+int psb_extend_raster_timeout(struct drm_psb_private *dev_priv)
19176+{
19177+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
19178+ unsigned long irq_flags;
19179+ int ret;
19180+
19181+ spin_lock_irqsave(&scheduler->lock, irq_flags);
19182+ scheduler->total_raster_jiffies +=
19183+ jiffies - scheduler->raster_end_jiffies + PSB_RASTER_TIMEOUT;
19184+ scheduler->raster_end_jiffies = jiffies + PSB_RASTER_TIMEOUT;
19185+ ret = (scheduler->total_raster_jiffies > PSB_ALLOWED_RASTER_RUNTIME) ?
19186+ -EBUSY : 0;
19187+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
19188+ return ret;
19189+}
19190+
19191+/*
19192+ * TA done handler.
19193+ */
19194+
19195+static void psb_ta_done(struct drm_psb_private *dev_priv,
19196+ struct psb_scheduler *scheduler)
19197+{
19198+ struct psb_task *task = scheduler->current_task[PSB_SCENE_ENGINE_TA];
19199+ struct psb_scene *scene = task->scene;
19200+
19201+ PSB_DEBUG_RENDER("TA done %u\n", task->sequence);
19202+
19203+ switch (task->ta_complete_action) {
19204+ case PSB_RASTER_BLOCK:
19205+ scheduler->ta_state = 1;
19206+ scene->flags |=
19207+ (PSB_SCENE_FLAG_DIRTY | PSB_SCENE_FLAG_COMPLETE);
19208+ list_add_tail(&task->head, &scheduler->raster_queue);
19209+ break;
19210+ case PSB_RASTER:
19211+ scene->flags |=
19212+ (PSB_SCENE_FLAG_DIRTY | PSB_SCENE_FLAG_COMPLETE);
19213+ list_add_tail(&task->head, &scheduler->raster_queue);
19214+ break;
19215+ case PSB_RETURN:
19216+ scheduler->ta_state = 0;
19217+ scene->flags |= PSB_SCENE_FLAG_DIRTY;
19218+ list_add_tail(&scene->hw_scene->head, &scheduler->hw_scenes);
19219+
19220+ break;
19221+ }
19222+
19223+ scheduler->current_task[PSB_SCENE_ENGINE_TA] = NULL;
19224+
19225+#ifdef FIX_TG_16
19226+ psb_2d_atomic_unlock(dev_priv);
19227+#endif
19228+
19229+ if (task->ta_complete_action != PSB_RASTER_BLOCK)
19230+ psb_report_fence(scheduler, task->engine, task->sequence,
19231+ _PSB_FENCE_TA_DONE_SHIFT, 1);
19232+
19233+ psb_schedule_raster(dev_priv, scheduler);
19234+ psb_schedule_ta(dev_priv, scheduler);
19235+ psb_set_idle(scheduler);
19236+
19237+ if (task->ta_complete_action != PSB_RETURN)
19238+ return;
19239+
19240+ list_add_tail(&task->head, &scheduler->task_done_queue);
19241+ schedule_delayed_work(&scheduler->wq, 1);
19242+}
19243+
19244+/*
19245+ * Rasterizer done handler.
19246+ */
19247+
19248+static void psb_raster_done(struct drm_psb_private *dev_priv,
19249+ struct psb_scheduler *scheduler)
19250+{
19251+ struct psb_task *task =
19252+ scheduler->current_task[PSB_SCENE_ENGINE_RASTER];
19253+ struct psb_scene *scene = task->scene;
19254+ uint32_t complete_action = task->raster_complete_action;
19255+
19256+ PSB_DEBUG_RENDER("Raster done %u\n", task->sequence);
19257+
19258+ scheduler->current_task[PSB_SCENE_ENGINE_RASTER] = NULL;
19259+
19260+ if (complete_action != PSB_RASTER)
19261+ psb_schedule_raster(dev_priv, scheduler);
19262+
19263+ if (scene) {
19264+ if (task->feedback.page) {
19265+ if (unlikely(scheduler->feedback_task)) {
19266+ /*
19267+ * This should never happen, since the previous
19268+ * feedback query will return before the next
19269+ * raster task is fired.
19270+ */
19271+ DRM_ERROR("Feedback task busy.\n");
19272+ }
19273+ scheduler->feedback_task = task;
19274+ psb_xhw_vistest(dev_priv, &task->buf);
19275+ }
19276+ switch (complete_action) {
19277+ case PSB_RETURN:
19278+ scene->flags &=
19279+ ~(PSB_SCENE_FLAG_DIRTY | PSB_SCENE_FLAG_COMPLETE);
19280+ list_add_tail(&scene->hw_scene->head,
19281+ &scheduler->hw_scenes);
19282+ psb_report_fence(scheduler, task->engine,
19283+ task->sequence,
19284+ _PSB_FENCE_SCENE_DONE_SHIFT, 1);
19285+ if (task->flags & PSB_FIRE_FLAG_XHW_OOM) {
19286+ scheduler->ta_state = 0;
19287+ }
19288+ break;
19289+ case PSB_RASTER:
19290+ list_add(&task->head, &scheduler->raster_queue);
19291+ task->raster_complete_action = PSB_RETURN;
19292+ psb_schedule_raster(dev_priv, scheduler);
19293+ break;
19294+ case PSB_TA:
19295+ list_add(&task->head, &scheduler->ta_queue);
19296+ scheduler->ta_state = 0;
19297+ task->raster_complete_action = PSB_RETURN;
19298+ task->ta_complete_action = PSB_RASTER;
19299+ break;
19300+
19301+ }
19302+ }
19303+ psb_schedule_ta(dev_priv, scheduler);
19304+ psb_set_idle(scheduler);
19305+
19306+ if (complete_action == PSB_RETURN) {
19307+ if (task->scene == NULL) {
19308+ psb_report_fence(scheduler, task->engine,
19309+ task->sequence,
19310+ _PSB_FENCE_RASTER_DONE_SHIFT, 1);
19311+ }
19312+ if (!task->feedback.page) {
19313+ list_add_tail(&task->head, &scheduler->task_done_queue);
19314+ schedule_delayed_work(&scheduler->wq, 1);
19315+ }
19316+ }
19317+}
19318+
19319+void psb_scheduler_pause(struct drm_psb_private *dev_priv)
19320+{
19321+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
19322+ unsigned long irq_flags;
19323+
19324+ spin_lock_irqsave(&scheduler->lock, irq_flags);
19325+ scheduler->idle_count++;
19326+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
19327+}
19328+
19329+void psb_scheduler_restart(struct drm_psb_private *dev_priv)
19330+{
19331+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
19332+ unsigned long irq_flags;
19333+
19334+ spin_lock_irqsave(&scheduler->lock, irq_flags);
19335+ if (--scheduler->idle_count == 0) {
19336+ psb_schedule_ta(dev_priv, scheduler);
19337+ psb_schedule_raster(dev_priv, scheduler);
19338+ }
19339+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
19340+}
19341+
19342+int psb_scheduler_idle(struct drm_psb_private *dev_priv)
19343+{
19344+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
19345+ unsigned long irq_flags;
19346+ int ret;
19347+ spin_lock_irqsave(&scheduler->lock, irq_flags);
19348+ ret = scheduler->idle_count != 0 && scheduler->idle;
19349+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
19350+ return ret;
19351+}
19352+
19353+int psb_scheduler_finished(struct drm_psb_private *dev_priv)
19354+{
19355+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
19356+ unsigned long irq_flags;
19357+ int ret;
19358+ spin_lock_irqsave(&scheduler->lock, irq_flags);
19359+ ret = (scheduler->idle &&
19360+ list_empty(&scheduler->raster_queue) &&
19361+ list_empty(&scheduler->ta_queue) &&
19362+ list_empty(&scheduler->hp_raster_queue));
19363+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
19364+ return ret;
19365+}
19366+
19367+static void psb_ta_oom(struct drm_psb_private *dev_priv,
19368+ struct psb_scheduler *scheduler)
19369+{
19370+
19371+ struct psb_task *task = scheduler->current_task[PSB_SCENE_ENGINE_TA];
19372+ if (!task)
19373+ return;
19374+
19375+ if (task->aborting)
19376+ return;
19377+ task->aborting = 1;
19378+
19379+ DRM_INFO("Info: TA out of parameter memory.\n");
19380+
19381+ (void)psb_xhw_ta_oom(dev_priv, &task->buf, task->scene->hw_cookie);
19382+}
19383+
19384+static void psb_ta_oom_reply(struct drm_psb_private *dev_priv,
19385+ struct psb_scheduler *scheduler)
19386+{
19387+
19388+ struct psb_task *task = scheduler->current_task[PSB_SCENE_ENGINE_TA];
19389+ uint32_t flags;
19390+ if (!task)
19391+ return;
19392+
19393+ psb_xhw_ta_oom_reply(dev_priv, &task->buf,
19394+ task->scene->hw_cookie,
19395+ &task->ta_complete_action,
19396+ &task->raster_complete_action, &flags);
19397+ task->flags |= flags;
19398+ task->aborting = 0;
19399+ psb_dispatch_ta(dev_priv, scheduler, PSB_RF_OOM_REPLY);
19400+}
19401+
19402+static void psb_ta_hw_scene_freed(struct drm_psb_private *dev_priv,
19403+ struct psb_scheduler *scheduler)
19404+{
19405+ DRM_ERROR("TA hw scene freed.\n");
19406+}
19407+
19408+static void psb_vistest_reply(struct drm_psb_private *dev_priv,
19409+ struct psb_scheduler *scheduler)
19410+{
19411+ struct psb_task *task = scheduler->feedback_task;
19412+ uint8_t *feedback_map;
19413+ uint32_t add;
19414+ uint32_t cur;
19415+ struct drm_psb_vistest *vistest;
19416+ int i;
19417+
19418+ scheduler->feedback_task = NULL;
19419+ if (!task) {
19420+ DRM_ERROR("No Poulsbo feedback task.\n");
19421+ return;
19422+ }
19423+ if (!task->feedback.page) {
19424+ DRM_ERROR("No Poulsbo feedback page.\n");
19425+ goto out;
19426+ }
19427+
19428+ if (in_irq())
19429+ feedback_map = kmap_atomic(task->feedback.page, KM_IRQ0);
19430+ else
19431+ feedback_map = kmap_atomic(task->feedback.page, KM_USER0);
19432+
19433+ /*
19434+ * Loop over all requested vistest components here.
19435+ * Only one (vistest) currently.
19436+ */
19437+
19438+ vistest = (struct drm_psb_vistest *)
19439+ (feedback_map + task->feedback.offset);
19440+
19441+ for (i = 0; i < PSB_HW_FEEDBACK_SIZE; ++i) {
19442+ add = task->buf.arg.arg.feedback[i];
19443+ cur = vistest->vt[i];
19444+
19445+ /*
19446+ * Vistest saturates.
19447+ */
19448+
19449+ vistest->vt[i] = (cur + add < cur) ? ~0 : cur + add;
19450+ }
19451+ if (in_irq())
19452+ kunmap_atomic(feedback_map, KM_IRQ0);
19453+ else
19454+ kunmap_atomic(feedback_map, KM_USER0);
19455+ out:
19456+ psb_report_fence(scheduler, task->engine, task->sequence,
19457+ _PSB_FENCE_FEEDBACK_SHIFT, 1);
19458+
19459+ if (list_empty(&task->head)) {
19460+ list_add_tail(&task->head, &scheduler->task_done_queue);
19461+ schedule_delayed_work(&scheduler->wq, 1);
19462+ } else
19463+ psb_schedule_ta(dev_priv, scheduler);
19464+}
19465+
19466+static void psb_ta_fire_reply(struct drm_psb_private *dev_priv,
19467+ struct psb_scheduler *scheduler)
19468+{
19469+ struct psb_task *task = scheduler->current_task[PSB_SCENE_ENGINE_TA];
19470+
19471+ psb_xhw_fire_reply(dev_priv, &task->buf, task->scene->hw_cookie);
19472+
19473+ psb_dispatch_ta(dev_priv, scheduler, PSB_RF_FIRE_TA);
19474+}
19475+
19476+static void psb_raster_fire_reply(struct drm_psb_private *dev_priv,
19477+ struct psb_scheduler *scheduler)
19478+{
19479+ struct psb_task *task =
19480+ scheduler->current_task[PSB_SCENE_ENGINE_RASTER];
19481+ uint32_t reply_flags;
19482+
19483+ if (!task) {
19484+ DRM_ERROR("Null task.\n");
19485+ return;
19486+ }
19487+
19488+ task->raster_complete_action = task->buf.arg.arg.sb.rca;
19489+ psb_xhw_fire_reply(dev_priv, &task->buf, task->scene->hw_cookie);
19490+
19491+ reply_flags = PSB_RF_FIRE_RASTER;
19492+ if (task->raster_complete_action == PSB_RASTER)
19493+ reply_flags |= PSB_RF_DEALLOC;
19494+
19495+ psb_dispatch_raster(dev_priv, scheduler, reply_flags);
19496+}
19497+
19498+static int psb_user_interrupt(struct drm_psb_private *dev_priv,
19499+ struct psb_scheduler *scheduler)
19500+{
19501+ uint32_t type;
19502+ int ret;
19503+ unsigned long irq_flags;
19504+
19505+ /*
19506+ * Xhw cannot write directly to the comm page, so
19507+ * do it here. Firmware would have written directly.
19508+ */
19509+
19510+ ret = psb_xhw_handler(dev_priv);
19511+ if (unlikely(ret))
19512+ return ret;
19513+
19514+ spin_lock_irqsave(&dev_priv->xhw_lock, irq_flags);
19515+ type = dev_priv->comm[PSB_COMM_USER_IRQ];
19516+ dev_priv->comm[PSB_COMM_USER_IRQ] = 0;
19517+ if (dev_priv->comm[PSB_COMM_USER_IRQ_LOST]) {
19518+ dev_priv->comm[PSB_COMM_USER_IRQ_LOST] = 0;
19519+ DRM_ERROR("Lost Poulsbo hardware event.\n");
19520+ }
19521+ spin_unlock_irqrestore(&dev_priv->xhw_lock, irq_flags);
19522+
19523+ if (type == 0)
19524+ return 0;
19525+
19526+ switch (type) {
19527+ case PSB_UIRQ_VISTEST:
19528+ psb_vistest_reply(dev_priv, scheduler);
19529+ break;
19530+ case PSB_UIRQ_OOM_REPLY:
19531+ psb_ta_oom_reply(dev_priv, scheduler);
19532+ break;
19533+ case PSB_UIRQ_FIRE_TA_REPLY:
19534+ psb_ta_fire_reply(dev_priv, scheduler);
19535+ break;
19536+ case PSB_UIRQ_FIRE_RASTER_REPLY:
19537+ psb_raster_fire_reply(dev_priv, scheduler);
19538+ break;
19539+ default:
19540+ DRM_ERROR("Unknown Poulsbo hardware event. %d\n", type);
19541+ }
19542+ return 0;
19543+}
19544+
19545+int psb_forced_user_interrupt(struct drm_psb_private *dev_priv)
19546+{
19547+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
19548+ unsigned long irq_flags;
19549+ int ret;
19550+
19551+ spin_lock_irqsave(&scheduler->lock, irq_flags);
19552+ ret = psb_user_interrupt(dev_priv, scheduler);
19553+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
19554+ return ret;
19555+}
19556+
19557+static void psb_dispatch_ta(struct drm_psb_private *dev_priv,
19558+ struct psb_scheduler *scheduler,
19559+ uint32_t reply_flag)
19560+{
19561+ struct psb_task *task = scheduler->current_task[PSB_SCENE_ENGINE_TA];
19562+ uint32_t flags;
19563+ uint32_t mask;
19564+
19565+ task->reply_flags |= reply_flag;
19566+ flags = task->reply_flags;
19567+ mask = PSB_RF_FIRE_TA;
19568+
19569+ if (!(flags & mask))
19570+ return;
19571+
19572+ mask = PSB_RF_TA_DONE;
19573+ if ((flags & mask) == mask) {
19574+ task->reply_flags &= ~mask;
19575+ psb_ta_done(dev_priv, scheduler);
19576+ }
19577+
19578+ mask = PSB_RF_OOM;
19579+ if ((flags & mask) == mask) {
19580+ task->reply_flags &= ~mask;
19581+ psb_ta_oom(dev_priv, scheduler);
19582+ }
19583+
19584+ mask = (PSB_RF_OOM_REPLY | PSB_RF_TERMINATE);
19585+ if ((flags & mask) == mask) {
19586+ task->reply_flags &= ~mask;
19587+ psb_ta_done(dev_priv, scheduler);
19588+ }
19589+}
19590+
19591+static void psb_dispatch_raster(struct drm_psb_private *dev_priv,
19592+ struct psb_scheduler *scheduler,
19593+ uint32_t reply_flag)
19594+{
19595+ struct psb_task *task =
19596+ scheduler->current_task[PSB_SCENE_ENGINE_RASTER];
19597+ uint32_t flags;
19598+ uint32_t mask;
19599+
19600+ task->reply_flags |= reply_flag;
19601+ flags = task->reply_flags;
19602+ mask = PSB_RF_FIRE_RASTER;
19603+
19604+ if (!(flags & mask))
19605+ return;
19606+
19607+ /*
19608+ * For rasterizer-only tasks, don't report fence done here,
19609+ * as this is time consuming and the rasterizer wants a new
19610+ * task immediately. For other tasks, the hardware is probably
19611+ * still busy deallocating TA memory, so we can report
19612+ * fence done in parallel.
19613+ */
19614+
19615+ if (task->raster_complete_action == PSB_RETURN &&
19616+ (reply_flag & PSB_RF_RASTER_DONE) && task->scene != NULL) {
19617+ psb_report_fence(scheduler, task->engine, task->sequence,
19618+ _PSB_FENCE_RASTER_DONE_SHIFT, 1);
19619+ }
19620+
19621+ mask = PSB_RF_RASTER_DONE | PSB_RF_DEALLOC;
19622+ if ((flags & mask) == mask) {
19623+ task->reply_flags &= ~mask;
19624+ psb_raster_done(dev_priv, scheduler);
19625+ }
19626+}
19627+
19628+void psb_scheduler_handler(struct drm_psb_private *dev_priv, uint32_t status)
19629+{
19630+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
19631+
19632+ spin_lock(&scheduler->lock);
19633+
19634+ if (status & _PSB_CE_PIXELBE_END_RENDER) {
19635+ psb_dispatch_raster(dev_priv, scheduler, PSB_RF_RASTER_DONE);
19636+ }
19637+ if (status & _PSB_CE_DPM_3D_MEM_FREE) {
19638+ psb_dispatch_raster(dev_priv, scheduler, PSB_RF_DEALLOC);
19639+ }
19640+ if (status & _PSB_CE_TA_FINISHED) {
19641+ psb_dispatch_ta(dev_priv, scheduler, PSB_RF_TA_DONE);
19642+ }
19643+ if (status & _PSB_CE_TA_TERMINATE) {
19644+ psb_dispatch_ta(dev_priv, scheduler, PSB_RF_TERMINATE);
19645+ }
19646+ if (status & (_PSB_CE_DPM_REACHED_MEM_THRESH |
19647+ _PSB_CE_DPM_OUT_OF_MEMORY_GBL |
19648+ _PSB_CE_DPM_OUT_OF_MEMORY_MT)) {
19649+ psb_dispatch_ta(dev_priv, scheduler, PSB_RF_OOM);
19650+ }
19651+ if (status & _PSB_CE_DPM_TA_MEM_FREE) {
19652+ psb_ta_hw_scene_freed(dev_priv, scheduler);
19653+ }
19654+ if (status & _PSB_CE_SW_EVENT) {
19655+ psb_user_interrupt(dev_priv, scheduler);
19656+ }
19657+ spin_unlock(&scheduler->lock);
19658+}
19659+
19660+static void psb_free_task_wq(struct work_struct *work)
19661+{
19662+ struct psb_scheduler *scheduler =
19663+ container_of(work, struct psb_scheduler, wq.work);
19664+
19665+ struct drm_device *dev = scheduler->dev;
19666+ struct list_head *list, *next;
19667+ unsigned long irq_flags;
19668+ struct psb_task *task;
19669+
19670+ if (!mutex_trylock(&scheduler->task_wq_mutex))
19671+ return;
19672+
19673+ spin_lock_irqsave(&scheduler->lock, irq_flags);
19674+ list_for_each_safe(list, next, &scheduler->task_done_queue) {
19675+ task = list_entry(list, struct psb_task, head);
19676+ list_del_init(list);
19677+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
19678+
19679+ PSB_DEBUG_RENDER("Checking Task %d: Scene 0x%08lx, "
19680+ "Feedback bo 0x%08lx, done %d\n",
19681+ task->sequence, (unsigned long)task->scene,
19682+ (unsigned long)task->feedback.bo,
19683+ atomic_read(&task->buf.done));
19684+
19685+ if (task->scene) {
19686+ mutex_lock(&dev->struct_mutex);
19687+ PSB_DEBUG_RENDER("Unref scene %d\n", task->sequence);
19688+ psb_scene_unref_devlocked(&task->scene);
19689+ if (task->feedback.bo) {
19690+ PSB_DEBUG_RENDER("Unref feedback bo %d\n",
19691+ task->sequence);
19692+ drm_bo_usage_deref_locked(&task->feedback.bo);
19693+ }
19694+ mutex_unlock(&dev->struct_mutex);
19695+ }
19696+
19697+ if (atomic_read(&task->buf.done)) {
19698+ PSB_DEBUG_RENDER("Deleting task %d\n", task->sequence);
19699+ drm_free(task, sizeof(*task), DRM_MEM_DRIVER);
19700+ task = NULL;
19701+ }
19702+ spin_lock_irqsave(&scheduler->lock, irq_flags);
19703+ if (task != NULL)
19704+ list_add(list, &scheduler->task_done_queue);
19705+ }
19706+ if (!list_empty(&scheduler->task_done_queue)) {
19707+ PSB_DEBUG_RENDER("Rescheduling wq\n");
19708+ schedule_delayed_work(&scheduler->wq, 1);
19709+ }
19710+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
19711+
19712+ mutex_unlock(&scheduler->task_wq_mutex);
19713+}
19714+
19715+/*
19716+ * Check if any of the tasks in the queues is using a scene.
19717+ * In that case we know the TA memory buffer objects are
19718+ * fenced and will not be evicted until that fence is signaled.
19719+ */
19720+
19721+void psb_scheduler_ta_mem_check(struct drm_psb_private *dev_priv)
19722+{
19723+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
19724+ unsigned long irq_flags;
19725+ struct psb_task *task;
19726+ struct psb_task *next_task;
19727+
19728+ dev_priv->force_ta_mem_load = 1;
19729+ spin_lock_irqsave(&scheduler->lock, irq_flags);
19730+ list_for_each_entry_safe(task, next_task, &scheduler->ta_queue, head) {
19731+ if (task->scene) {
19732+ dev_priv->force_ta_mem_load = 0;
19733+ break;
19734+ }
19735+ }
19736+ list_for_each_entry_safe(task, next_task, &scheduler->raster_queue,
19737+ head) {
19738+ if (task->scene) {
19739+ dev_priv->force_ta_mem_load = 0;
19740+ break;
19741+ }
19742+ }
19743+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
19744+}
19745+
19746+void psb_scheduler_reset(struct drm_psb_private *dev_priv, int error_condition)
19747+{
19748+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
19749+ unsigned long wait_jiffies;
19750+ unsigned long cur_jiffies;
19751+ struct psb_task *task;
19752+ struct psb_task *next_task;
19753+ unsigned long irq_flags;
19754+
19755+ psb_scheduler_pause(dev_priv);
19756+ if (!psb_scheduler_idle(dev_priv)) {
19757+ spin_lock_irqsave(&scheduler->lock, irq_flags);
19758+
19759+ cur_jiffies = jiffies;
19760+ wait_jiffies = cur_jiffies;
19761+ if (scheduler->current_task[PSB_SCENE_ENGINE_TA] &&
19762+ time_after_eq(scheduler->ta_end_jiffies, wait_jiffies))
19763+ wait_jiffies = scheduler->ta_end_jiffies;
19764+ if (scheduler->current_task[PSB_SCENE_ENGINE_RASTER] &&
19765+ time_after_eq(scheduler->raster_end_jiffies, wait_jiffies))
19766+ wait_jiffies = scheduler->raster_end_jiffies;
19767+
19768+ wait_jiffies -= cur_jiffies;
19769+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
19770+
19771+ (void)wait_event_timeout(scheduler->idle_queue,
19772+ psb_scheduler_idle(dev_priv),
19773+ wait_jiffies);
19774+ }
19775+
19776+ if (!psb_scheduler_idle(dev_priv)) {
19777+ spin_lock_irqsave(&scheduler->lock, irq_flags);
19778+ task = scheduler->current_task[PSB_SCENE_ENGINE_RASTER];
19779+ if (task) {
19780+ DRM_ERROR("Detected Poulsbo rasterizer lockup.\n");
19781+ if (task->engine == PSB_ENGINE_HPRAST) {
19782+ psb_fence_error(scheduler->dev,
19783+ PSB_ENGINE_HPRAST,
19784+ task->sequence,
19785+ _PSB_FENCE_TYPE_RASTER_DONE,
19786+ error_condition);
19787+
19788+ list_del(&task->head);
19789+ psb_xhw_clean_buf(dev_priv, &task->buf);
19790+ list_add_tail(&task->head,
19791+ &scheduler->task_done_queue);
19792+ } else {
19793+ list_add(&task->head, &scheduler->raster_queue);
19794+ }
19795+ }
19796+ scheduler->current_task[PSB_SCENE_ENGINE_RASTER] = NULL;
19797+ task = scheduler->current_task[PSB_SCENE_ENGINE_TA];
19798+ if (task) {
19799+ DRM_ERROR("Detected Poulsbo ta lockup.\n");
19800+ list_add_tail(&task->head, &scheduler->raster_queue);
19801+#ifdef FIX_TG_16
19802+ psb_2d_atomic_unlock(dev_priv);
19803+#endif
19804+ }
19805+ scheduler->current_task[PSB_SCENE_ENGINE_TA] = NULL;
19806+ scheduler->ta_state = 0;
19807+
19808+#ifdef FIX_TG_16
19809+ atomic_set(&dev_priv->ta_wait_2d, 0);
19810+ atomic_set(&dev_priv->ta_wait_2d_irq, 0);
19811+ wake_up(&dev_priv->queue_2d);
19812+#endif
19813+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
19814+ }
19815+
19816+ /*
19817+ * Empty raster queue.
19818+ */
19819+
19820+ spin_lock_irqsave(&scheduler->lock, irq_flags);
19821+ list_for_each_entry_safe(task, next_task, &scheduler->raster_queue,
19822+ head) {
19823+ struct psb_scene *scene = task->scene;
19824+
19825+ psb_fence_error(scheduler->dev,
19826+ task->engine,
19827+ task->sequence,
19828+ _PSB_FENCE_TYPE_TA_DONE |
19829+ _PSB_FENCE_TYPE_RASTER_DONE |
19830+ _PSB_FENCE_TYPE_SCENE_DONE |
19831+ _PSB_FENCE_TYPE_FEEDBACK, error_condition);
19832+ if (scene) {
19833+ scene->flags = 0;
19834+ if (scene->hw_scene) {
19835+ list_add_tail(&scene->hw_scene->head,
19836+ &scheduler->hw_scenes);
19837+ scene->hw_scene = NULL;
19838+ }
19839+ }
19840+
19841+ psb_xhw_clean_buf(dev_priv, &task->buf);
19842+ list_del(&task->head);
19843+ list_add_tail(&task->head, &scheduler->task_done_queue);
19844+ }
19845+
19846+ schedule_delayed_work(&scheduler->wq, 1);
19847+ scheduler->idle = 1;
19848+ wake_up(&scheduler->idle_queue);
19849+
19850+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
19851+ psb_scheduler_restart(dev_priv);
19852+
19853+}
19854+
19855+int psb_scheduler_init(struct drm_device *dev, struct psb_scheduler *scheduler)
19856+{
19857+ struct psb_hw_scene *hw_scene;
19858+ int i;
19859+
19860+ memset(scheduler, 0, sizeof(*scheduler));
19861+ scheduler->dev = dev;
19862+ mutex_init(&scheduler->task_wq_mutex);
19863+ scheduler->lock = SPIN_LOCK_UNLOCKED;
19864+ scheduler->idle = 1;
19865+
19866+ INIT_LIST_HEAD(&scheduler->ta_queue);
19867+ INIT_LIST_HEAD(&scheduler->raster_queue);
19868+ INIT_LIST_HEAD(&scheduler->hp_raster_queue);
19869+ INIT_LIST_HEAD(&scheduler->hw_scenes);
19870+ INIT_LIST_HEAD(&scheduler->task_done_queue);
19871+ INIT_DELAYED_WORK(&scheduler->wq, &psb_free_task_wq);
19872+ init_waitqueue_head(&scheduler->idle_queue);
19873+
19874+ for (i = 0; i < PSB_NUM_HW_SCENES; ++i) {
19875+ hw_scene = &scheduler->hs[i];
19876+ hw_scene->context_number = i;
19877+ list_add_tail(&hw_scene->head, &scheduler->hw_scenes);
19878+ }
19879+
19880+ for (i = 0; i < _PSB_ENGINE_TA_FENCE_TYPES; ++i) {
19881+ scheduler->seq[i].reported = 0;
19882+ }
19883+
19884+ return 0;
19885+}
19886+
19887+/*
19888+ * Scene references maintained by the scheduler are not refcounted.
19889+ * Remove all references to a particular scene here.
19890+ */
19891+
19892+void psb_scheduler_remove_scene_refs(struct psb_scene *scene)
19893+{
19894+ struct drm_psb_private *dev_priv =
19895+ (struct drm_psb_private *)scene->dev->dev_private;
19896+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
19897+ struct psb_hw_scene *hw_scene;
19898+ unsigned long irq_flags;
19899+ unsigned int i;
19900+
19901+ spin_lock_irqsave(&scheduler->lock, irq_flags);
19902+ for (i = 0; i < PSB_NUM_HW_SCENES; ++i) {
19903+ hw_scene = &scheduler->hs[i];
19904+ if (hw_scene->last_scene == scene) {
19905+ BUG_ON(list_empty(&hw_scene->head));
19906+ hw_scene->last_scene = NULL;
19907+ }
19908+ }
19909+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
19910+}
19911+
19912+void psb_scheduler_takedown(struct psb_scheduler *scheduler)
19913+{
19914+ flush_scheduled_work();
19915+}
19916+
19917+static int psb_setup_task_devlocked(struct drm_device *dev,
19918+ struct drm_psb_cmdbuf_arg *arg,
19919+ struct drm_buffer_object *raster_cmd_buffer,
19920+ struct drm_buffer_object *ta_cmd_buffer,
19921+ struct drm_buffer_object *oom_cmd_buffer,
19922+ struct psb_scene *scene,
19923+ enum psb_task_type task_type,
19924+ uint32_t engine,
19925+ uint32_t flags, struct psb_task **task_p)
19926+{
19927+ struct psb_task *task;
19928+ int ret;
19929+
19930+ if (ta_cmd_buffer && arg->ta_size > PSB_MAX_TA_CMDS) {
19931+ DRM_ERROR("Too many ta cmds %d.\n", arg->ta_size);
19932+ return -EINVAL;
19933+ }
19934+ if (raster_cmd_buffer && arg->cmdbuf_size > PSB_MAX_RASTER_CMDS) {
19935+ DRM_ERROR("Too many raster cmds %d.\n", arg->cmdbuf_size);
19936+ return -EINVAL;
19937+ }
19938+ if (oom_cmd_buffer && arg->oom_size > PSB_MAX_OOM_CMDS) {
19939+ DRM_ERROR("Too many raster cmds %d.\n", arg->oom_size);
19940+ return -EINVAL;
19941+ }
19942+
19943+ task = drm_calloc(1, sizeof(*task), DRM_MEM_DRIVER);
19944+ if (!task)
19945+ return -ENOMEM;
19946+
19947+ atomic_set(&task->buf.done, 1);
19948+ task->engine = engine;
19949+ INIT_LIST_HEAD(&task->head);
19950+ INIT_LIST_HEAD(&task->buf.head);
19951+ if (ta_cmd_buffer && arg->ta_size != 0) {
19952+ task->ta_cmd_size = arg->ta_size;
19953+ ret = psb_submit_copy_cmdbuf(dev, ta_cmd_buffer,
19954+ arg->ta_offset,
19955+ arg->ta_size,
19956+ PSB_ENGINE_TA, task->ta_cmds);
19957+ if (ret)
19958+ goto out_err;
19959+ }
19960+ if (raster_cmd_buffer) {
19961+ task->raster_cmd_size = arg->cmdbuf_size;
19962+ ret = psb_submit_copy_cmdbuf(dev, raster_cmd_buffer,
19963+ arg->cmdbuf_offset,
19964+ arg->cmdbuf_size,
19965+ PSB_ENGINE_TA, task->raster_cmds);
19966+ if (ret)
19967+ goto out_err;
19968+ }
19969+ if (oom_cmd_buffer && arg->oom_size != 0) {
19970+ task->oom_cmd_size = arg->oom_size;
19971+ ret = psb_submit_copy_cmdbuf(dev, oom_cmd_buffer,
19972+ arg->oom_offset,
19973+ arg->oom_size,
19974+ PSB_ENGINE_TA, task->oom_cmds);
19975+ if (ret)
19976+ goto out_err;
19977+ }
19978+ task->task_type = task_type;
19979+ task->flags = flags;
19980+ if (scene)
19981+ task->scene = psb_scene_ref(scene);
19982+
19983+ *task_p = task;
19984+ return 0;
19985+ out_err:
19986+ drm_free(task, sizeof(*task), DRM_MEM_DRIVER);
19987+ *task_p = NULL;
19988+ return ret;
19989+}
19990+
19991+int psb_cmdbuf_ta(struct drm_file *priv,
19992+ struct drm_psb_cmdbuf_arg *arg,
19993+ struct drm_buffer_object *cmd_buffer,
19994+ struct drm_buffer_object *ta_buffer,
19995+ struct drm_buffer_object *oom_buffer,
19996+ struct psb_scene *scene,
19997+ struct psb_feedback_info *feedback,
19998+ struct drm_fence_arg *fence_arg)
19999+{
20000+ struct drm_device *dev = priv->minor->dev;
20001+ struct drm_psb_private *dev_priv = dev->dev_private;
20002+ struct drm_fence_object *fence = NULL;
20003+ struct psb_task *task = NULL;
20004+ int ret;
20005+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
20006+ unsigned long irq_flags;
20007+
20008+ PSB_DEBUG_RENDER("Cmdbuf ta\n");
20009+
20010+ ret = mutex_lock_interruptible(&dev_priv->reset_mutex);
20011+ if (ret)
20012+ return -EAGAIN;
20013+
20014+ mutex_lock(&dev->struct_mutex);
20015+ ret = psb_setup_task_devlocked(dev, arg, cmd_buffer, ta_buffer,
20016+ oom_buffer, scene,
20017+ psb_ta_task, PSB_ENGINE_TA,
20018+ PSB_FIRE_FLAG_RASTER_DEALLOC, &task);
20019+ mutex_unlock(&dev->struct_mutex);
20020+
20021+ if (ret)
20022+ goto out_err;
20023+
20024+ task->feedback = *feedback;
20025+
20026+ /*
20027+ * Hand the task over to the scheduler.
20028+ */
20029+
20030+ spin_lock_irqsave(&scheduler->lock, irq_flags);
20031+ task->sequence = psb_fence_advance_sequence(dev, PSB_ENGINE_TA);
20032+
20033+ psb_report_fence(scheduler, PSB_ENGINE_TA, task->sequence, 0, 1);
20034+
20035+ task->ta_complete_action = PSB_RASTER;
20036+ task->raster_complete_action = PSB_RETURN;
20037+
20038+ list_add_tail(&task->head, &scheduler->ta_queue);
20039+ PSB_DEBUG_RENDER("queued ta %u\n", task->sequence);
20040+
20041+ psb_schedule_ta(dev_priv, scheduler);
20042+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
20043+
20044+ psb_fence_or_sync(priv, PSB_ENGINE_TA, arg, fence_arg, &fence);
20045+ drm_regs_fence(&dev_priv->use_manager, fence);
20046+ if (fence)
20047+ fence_arg->signaled |= 0x1;
20048+
20049+ out_err:
20050+ if (ret && ret != -EAGAIN)
20051+ DRM_ERROR("TA task queue job failed.\n");
20052+
20053+ if (fence) {
20054+#ifdef PSB_WAIT_FOR_TA_COMPLETION
20055+ drm_fence_object_wait(fence, 1, 1, DRM_FENCE_TYPE_EXE |
20056+ _PSB_FENCE_TYPE_TA_DONE);
20057+#ifdef PSB_BE_PARANOID
20058+ drm_fence_object_wait(fence, 1, 1, DRM_FENCE_TYPE_EXE |
20059+ _PSB_FENCE_TYPE_SCENE_DONE);
20060+#endif
20061+#endif
20062+ drm_fence_usage_deref_unlocked(&fence);
20063+ }
20064+ mutex_unlock(&dev_priv->reset_mutex);
20065+
20066+ return ret;
20067+}
20068+
20069+int psb_cmdbuf_raster(struct drm_file *priv,
20070+ struct drm_psb_cmdbuf_arg *arg,
20071+ struct drm_buffer_object *cmd_buffer,
20072+ struct drm_fence_arg *fence_arg)
20073+{
20074+ struct drm_device *dev = priv->minor->dev;
20075+ struct drm_psb_private *dev_priv = dev->dev_private;
20076+ struct drm_fence_object *fence = NULL;
20077+ struct psb_task *task = NULL;
20078+ int ret;
20079+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
20080+ unsigned long irq_flags;
20081+
20082+ PSB_DEBUG_RENDER("Cmdbuf Raster\n");
20083+
20084+ ret = mutex_lock_interruptible(&dev_priv->reset_mutex);
20085+ if (ret)
20086+ return -EAGAIN;
20087+
20088+ mutex_lock(&dev->struct_mutex);
20089+ ret = psb_setup_task_devlocked(dev, arg, cmd_buffer, NULL, NULL,
20090+ NULL, psb_raster_task,
20091+ PSB_ENGINE_TA, 0, &task);
20092+ mutex_unlock(&dev->struct_mutex);
20093+
20094+ if (ret)
20095+ goto out_err;
20096+
20097+ /*
20098+ * Hand the task over to the scheduler.
20099+ */
20100+
20101+ spin_lock_irqsave(&scheduler->lock, irq_flags);
20102+ task->sequence = psb_fence_advance_sequence(dev, PSB_ENGINE_TA);
20103+ psb_report_fence(scheduler, PSB_ENGINE_TA, task->sequence, 0, 1);
20104+ task->ta_complete_action = PSB_RASTER;
20105+ task->raster_complete_action = PSB_RETURN;
20106+
20107+ list_add_tail(&task->head, &scheduler->ta_queue);
20108+ PSB_DEBUG_RENDER("queued raster %u\n", task->sequence);
20109+ psb_schedule_ta(dev_priv, scheduler);
20110+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
20111+
20112+ psb_fence_or_sync(priv, PSB_ENGINE_TA, arg, fence_arg, &fence);
20113+ drm_regs_fence(&dev_priv->use_manager, fence);
20114+ if (fence)
20115+ fence_arg->signaled |= 0x1;
20116+ out_err:
20117+ if (ret && ret != -EAGAIN)
20118+ DRM_ERROR("Raster task queue job failed.\n");
20119+
20120+ if (fence) {
20121+#ifdef PSB_WAIT_FOR_RASTER_COMPLETION
20122+ drm_fence_object_wait(fence, 1, 1, fence->type);
20123+#endif
20124+ drm_fence_usage_deref_unlocked(&fence);
20125+ }
20126+
20127+ mutex_unlock(&dev_priv->reset_mutex);
20128+
20129+ return ret;
20130+}
20131+
20132+#ifdef FIX_TG_16
20133+
20134+static int psb_check_2d_idle(struct drm_psb_private *dev_priv)
20135+{
20136+ if (psb_2d_trylock(dev_priv)) {
20137+ if ((PSB_RSGX32(PSB_CR_2D_SOCIF) == _PSB_C2_SOCIF_EMPTY) &&
20138+ !((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) &
20139+ _PSB_C2B_STATUS_BUSY))) {
20140+ return 0;
20141+ }
20142+ if (atomic_cmpxchg(&dev_priv->ta_wait_2d_irq, 0, 1) == 0)
20143+ psb_2D_irq_on(dev_priv);
20144+
20145+ PSB_WSGX32(PSB_2D_FENCE_BH, PSB_SGX_2D_SLAVE_PORT);
20146+ PSB_WSGX32(PSB_2D_FLUSH_BH, PSB_SGX_2D_SLAVE_PORT);
20147+ (void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT);
20148+
20149+ psb_2d_atomic_unlock(dev_priv);
20150+ }
20151+
20152+ atomic_set(&dev_priv->ta_wait_2d, 1);
20153+ return -EBUSY;
20154+}
20155+
20156+static void psb_atomic_resume_ta_2d_idle(struct drm_psb_private *dev_priv)
20157+{
20158+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
20159+
20160+ if (atomic_cmpxchg(&dev_priv->ta_wait_2d, 1, 0) == 1) {
20161+ psb_schedule_ta(dev_priv, scheduler);
20162+ if (atomic_read(&dev_priv->waiters_2d) != 0)
20163+ wake_up(&dev_priv->queue_2d);
20164+ }
20165+}
20166+
20167+void psb_resume_ta_2d_idle(struct drm_psb_private *dev_priv)
20168+{
20169+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
20170+ unsigned long irq_flags;
20171+
20172+ spin_lock_irqsave(&scheduler->lock, irq_flags);
20173+ if (atomic_cmpxchg(&dev_priv->ta_wait_2d_irq, 1, 0) == 1) {
20174+ atomic_set(&dev_priv->ta_wait_2d, 0);
20175+ psb_2D_irq_off(dev_priv);
20176+ psb_schedule_ta(dev_priv, scheduler);
20177+ if (atomic_read(&dev_priv->waiters_2d) != 0)
20178+ wake_up(&dev_priv->queue_2d);
20179+ }
20180+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
20181+}
20182+
20183+/*
20184+ * 2D locking functions. Can't use a mutex since the trylock() and
20185+ * unlock() methods need to be accessible from interrupt context.
20186+ */
20187+
20188+static int psb_2d_trylock(struct drm_psb_private *dev_priv)
20189+{
20190+ return (atomic_cmpxchg(&dev_priv->lock_2d, 0, 1) == 0);
20191+}
20192+
20193+static void psb_2d_atomic_unlock(struct drm_psb_private *dev_priv)
20194+{
20195+ atomic_set(&dev_priv->lock_2d, 0);
20196+ if (atomic_read(&dev_priv->waiters_2d) != 0)
20197+ wake_up(&dev_priv->queue_2d);
20198+}
20199+
20200+void psb_2d_unlock(struct drm_psb_private *dev_priv)
20201+{
20202+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
20203+ unsigned long irq_flags;
20204+
20205+ spin_lock_irqsave(&scheduler->lock, irq_flags);
20206+ psb_2d_atomic_unlock(dev_priv);
20207+ if (atomic_read(&dev_priv->ta_wait_2d) != 0)
20208+ psb_atomic_resume_ta_2d_idle(dev_priv);
20209+ spin_unlock_irqrestore(&scheduler->lock, irq_flags);
20210+}
20211+
20212+void psb_2d_lock(struct drm_psb_private *dev_priv)
20213+{
20214+ atomic_inc(&dev_priv->waiters_2d);
20215+ wait_event(dev_priv->queue_2d, atomic_read(&dev_priv->ta_wait_2d) == 0);
20216+ wait_event(dev_priv->queue_2d, psb_2d_trylock(dev_priv));
20217+ atomic_dec(&dev_priv->waiters_2d);
20218+}
20219+
20220+#endif
20221Index: linux-2.6.28/drivers/gpu/drm/psb/psb_schedule.h
20222===================================================================
20223--- /dev/null 1970-01-01 00:00:00.000000000 +0000
20224+++ linux-2.6.28/drivers/gpu/drm/psb/psb_schedule.h 2009-02-12 09:14:42.000000000 +0000
20225@@ -0,0 +1,170 @@
20226+/**************************************************************************
20227+ * Copyright (c) 2007, Intel Corporation.
20228+ * All Rights Reserved.
20229+ *
20230+ * This program is free software; you can redistribute it and/or modify it
20231+ * under the terms and conditions of the GNU General Public License,
20232+ * version 2, as published by the Free Software Foundation.
20233+ *
20234+ * This program is distributed in the hope it will be useful, but WITHOUT
20235+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20236+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20237+ * more details.
20238+ *
20239+ * You should have received a copy of the GNU General Public License along with
20240+ * this program; if not, write to the Free Software Foundation, Inc.,
20241+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20242+ *
20243+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
20244+ * develop this driver.
20245+ *
20246+ **************************************************************************/
20247+/*
20248+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
20249+ */
20250+
20251+#ifndef _PSB_SCHEDULE_H_
20252+#define _PSB_SCHEDULE_H_
20253+
20254+#include "drmP.h"
20255+
20256+enum psb_task_type {
20257+ psb_ta_midscene_task,
20258+ psb_ta_task,
20259+ psb_raster_task,
20260+ psb_freescene_task
20261+};
20262+
20263+#define PSB_MAX_TA_CMDS 60
20264+#define PSB_MAX_RASTER_CMDS 60
20265+#define PSB_MAX_OOM_CMDS 6
20266+
20267+struct psb_xhw_buf {
20268+ struct list_head head;
20269+ int copy_back;
20270+ atomic_t done;
20271+ struct drm_psb_xhw_arg arg;
20272+
20273+};
20274+
20275+struct psb_feedback_info {
20276+ struct drm_buffer_object *bo;
20277+ struct page *page;
20278+ uint32_t offset;
20279+};
20280+
20281+struct psb_task {
20282+ struct list_head head;
20283+ struct psb_scene *scene;
20284+ struct psb_feedback_info feedback;
20285+ enum psb_task_type task_type;
20286+ uint32_t engine;
20287+ uint32_t sequence;
20288+ uint32_t ta_cmds[PSB_MAX_TA_CMDS];
20289+ uint32_t raster_cmds[PSB_MAX_RASTER_CMDS];
20290+ uint32_t oom_cmds[PSB_MAX_OOM_CMDS];
20291+ uint32_t ta_cmd_size;
20292+ uint32_t raster_cmd_size;
20293+ uint32_t oom_cmd_size;
20294+ uint32_t feedback_offset;
20295+ uint32_t ta_complete_action;
20296+ uint32_t raster_complete_action;
20297+ uint32_t hw_cookie;
20298+ uint32_t flags;
20299+ uint32_t reply_flags;
20300+ uint32_t aborting;
20301+ struct psb_xhw_buf buf;
20302+};
20303+
20304+struct psb_hw_scene {
20305+ struct list_head head;
20306+ uint32_t context_number;
20307+
20308+ /*
20309+ * This pointer does not refcount the last_scene_buffer,
20310+ * so we must make sure it is set to NULL before destroying
20311+ * the corresponding task.
20312+ */
20313+
20314+ struct psb_scene *last_scene;
20315+};
20316+
20317+struct psb_scene;
20318+struct drm_psb_private;
20319+
20320+struct psb_scheduler_seq {
20321+ uint32_t sequence;
20322+ int reported;
20323+};
20324+
20325+struct psb_scheduler {
20326+ struct drm_device *dev;
20327+ struct psb_scheduler_seq seq[_PSB_ENGINE_TA_FENCE_TYPES];
20328+ struct psb_hw_scene hs[PSB_NUM_HW_SCENES];
20329+ struct mutex task_wq_mutex;
20330+ spinlock_t lock;
20331+ struct list_head hw_scenes;
20332+ struct list_head ta_queue;
20333+ struct list_head raster_queue;
20334+ struct list_head hp_raster_queue;
20335+ struct list_head task_done_queue;
20336+ struct psb_task *current_task[PSB_SCENE_NUM_ENGINES];
20337+ struct psb_task *feedback_task;
20338+ int ta_state;
20339+ struct psb_hw_scene *pending_hw_scene;
20340+ uint32_t pending_hw_scene_seq;
20341+ struct delayed_work wq;
20342+ struct psb_scene_pool *pool;
20343+ uint32_t idle_count;
20344+ int idle;
20345+ wait_queue_head_t idle_queue;
20346+ unsigned long ta_end_jiffies;
20347+ unsigned long raster_end_jiffies;
20348+ unsigned long total_raster_jiffies;
20349+};
20350+
20351+#define PSB_RF_FIRE_TA (1 << 0)
20352+#define PSB_RF_OOM (1 << 1)
20353+#define PSB_RF_OOM_REPLY (1 << 2)
20354+#define PSB_RF_TERMINATE (1 << 3)
20355+#define PSB_RF_TA_DONE (1 << 4)
20356+#define PSB_RF_FIRE_RASTER (1 << 5)
20357+#define PSB_RF_RASTER_DONE (1 << 6)
20358+#define PSB_RF_DEALLOC (1 << 7)
20359+
20360+extern struct psb_scene_pool *psb_alloc_scene_pool(struct drm_file *priv,
20361+ int shareable, uint32_t w,
20362+ uint32_t h);
20363+extern uint32_t psb_scene_handle(struct psb_scene *scene);
20364+extern int psb_scheduler_init(struct drm_device *dev,
20365+ struct psb_scheduler *scheduler);
20366+extern void psb_scheduler_takedown(struct psb_scheduler *scheduler);
20367+extern int psb_cmdbuf_ta(struct drm_file *priv,
20368+ struct drm_psb_cmdbuf_arg *arg,
20369+ struct drm_buffer_object *cmd_buffer,
20370+ struct drm_buffer_object *ta_buffer,
20371+ struct drm_buffer_object *oom_buffer,
20372+ struct psb_scene *scene,
20373+ struct psb_feedback_info *feedback,
20374+ struct drm_fence_arg *fence_arg);
20375+extern int psb_cmdbuf_raster(struct drm_file *priv,
20376+ struct drm_psb_cmdbuf_arg *arg,
20377+ struct drm_buffer_object *cmd_buffer,
20378+ struct drm_fence_arg *fence_arg);
20379+extern void psb_scheduler_handler(struct drm_psb_private *dev_priv,
20380+ uint32_t status);
20381+extern void psb_scheduler_pause(struct drm_psb_private *dev_priv);
20382+extern void psb_scheduler_restart(struct drm_psb_private *dev_priv);
20383+extern int psb_scheduler_idle(struct drm_psb_private *dev_priv);
20384+extern int psb_scheduler_finished(struct drm_psb_private *dev_priv);
20385+
20386+extern void psb_scheduler_lockup(struct drm_psb_private *dev_priv,
20387+ int *lockup, int *idle);
20388+extern void psb_scheduler_reset(struct drm_psb_private *dev_priv,
20389+ int error_condition);
20390+extern int psb_forced_user_interrupt(struct drm_psb_private *dev_priv);
20391+extern void psb_scheduler_remove_scene_refs(struct psb_scene *scene);
20392+extern void psb_scheduler_ta_mem_check(struct drm_psb_private *dev_priv);
20393+extern int psb_extend_raster_timeout(struct drm_psb_private *dev_priv);
20394+
20395+#endif
20396Index: linux-2.6.28/drivers/gpu/drm/psb/psb_setup.c
20397===================================================================
20398--- /dev/null 1970-01-01 00:00:00.000000000 +0000
20399+++ linux-2.6.28/drivers/gpu/drm/psb/psb_setup.c 2009-02-12 09:14:42.000000000 +0000
20400@@ -0,0 +1,18 @@
20401+#include "drmP.h"
20402+#include "drm.h"
20403+#include "drm_crtc.h"
20404+#include "drm_edid.h"
20405+#include "psb_drm.h"
20406+#include "psb_priv.h"
20407+//#include "i915_reg.h"
20408+//#include "intel_drv.h"
20409+#include "../i915/intel_crt.c"
20410+
20411+/* Fixed name */
20412+#define ACPI_EDID_LCD "\\_SB_.PCI0.GFX0.DD04._DDC"
20413+#define ACPI_DOD "\\_SB_.PCI0.GFX0._DOD"
20414+
20415+#include "../i915/intel_lvds.c"
20416+#include "../i915/intel_sdvo.c"
20417+#include "intel_display.c"
20418+#include "../i915/intel_modes.c"
20419Index: linux-2.6.28/drivers/gpu/drm/psb/psb_sgx.c
20420===================================================================
20421--- /dev/null 1970-01-01 00:00:00.000000000 +0000
20422+++ linux-2.6.28/drivers/gpu/drm/psb/psb_sgx.c 2009-02-12 09:14:42.000000000 +0000
20423@@ -0,0 +1,1422 @@
20424+/**************************************************************************
20425+ * Copyright (c) 2007, Intel Corporation.
20426+ * All Rights Reserved.
20427+ *
20428+ * This program is free software; you can redistribute it and/or modify it
20429+ * under the terms and conditions of the GNU General Public License,
20430+ * version 2, as published by the Free Software Foundation.
20431+ *
20432+ * This program is distributed in the hope it will be useful, but WITHOUT
20433+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20434+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20435+ * more details.
20436+ *
20437+ * You should have received a copy of the GNU General Public License along with
20438+ * this program; if not, write to the Free Software Foundation, Inc.,
20439+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20440+ *
20441+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
20442+ * develop this driver.
20443+ *
20444+ **************************************************************************/
20445+/*
20446+ */
20447+
20448+#include "drmP.h"
20449+#include "psb_drv.h"
20450+#include "psb_drm.h"
20451+#include "psb_reg.h"
20452+#include "psb_scene.h"
20453+
20454+#include "psb_msvdx.h"
20455+
20456+int psb_submit_video_cmdbuf(struct drm_device *dev,
20457+ struct drm_buffer_object *cmd_buffer,
20458+ unsigned long cmd_offset, unsigned long cmd_size,
20459+ struct drm_fence_object *fence);
20460+
20461+struct psb_dstbuf_cache {
20462+ unsigned int dst;
20463+ uint32_t *use_page;
20464+ unsigned int use_index;
20465+ uint32_t use_background;
20466+ struct drm_buffer_object *dst_buf;
20467+ unsigned long dst_offset;
20468+ uint32_t *dst_page;
20469+ unsigned int dst_page_offset;
20470+ struct drm_bo_kmap_obj dst_kmap;
20471+ int dst_is_iomem;
20472+};
20473+
20474+struct psb_buflist_item {
20475+ struct drm_buffer_object *bo;
20476+ void __user *data;
20477+ int ret;
20478+ int presumed_offset_correct;
20479+};
20480+
20481+
20482+#define PSB_REG_GRAN_SHIFT 2
20483+#define PSB_REG_GRANULARITY (1 << PSB_REG_GRAN_SHIFT)
20484+#define PSB_MAX_REG 0x1000
20485+
20486+static const uint32_t disallowed_ranges[][2] = {
20487+ {0x0000, 0x0200},
20488+ {0x0208, 0x0214},
20489+ {0x021C, 0x0224},
20490+ {0x0230, 0x0234},
20491+ {0x0248, 0x024C},
20492+ {0x0254, 0x0358},
20493+ {0x0428, 0x0428},
20494+ {0x0430, 0x043C},
20495+ {0x0498, 0x04B4},
20496+ {0x04CC, 0x04D8},
20497+ {0x04E0, 0x07FC},
20498+ {0x0804, 0x0A58},
20499+ {0x0A68, 0x0A80},
20500+ {0x0AA0, 0x0B1C},
20501+ {0x0B2C, 0x0CAC},
20502+ {0x0CB4, PSB_MAX_REG - PSB_REG_GRANULARITY}
20503+};
20504+
20505+static uint32_t psb_disallowed_regs[PSB_MAX_REG /
20506+ (PSB_REG_GRANULARITY *
20507+ (sizeof(uint32_t) << 3))];
20508+
20509+static inline int psb_disallowed(uint32_t reg)
20510+{
20511+ reg >>= PSB_REG_GRAN_SHIFT;
20512+ return ((psb_disallowed_regs[reg >> 5] & (1 << (reg & 31))) != 0);
20513+}
20514+
20515+void psb_init_disallowed(void)
20516+{
20517+ int i;
20518+ uint32_t reg, tmp;
20519+ static int initialized = 0;
20520+
20521+ if (initialized)
20522+ return;
20523+
20524+ initialized = 1;
20525+ memset(psb_disallowed_regs, 0, sizeof(psb_disallowed_regs));
20526+
20527+ for (i = 0; i < (sizeof(disallowed_ranges) / (2 * sizeof(uint32_t)));
20528+ ++i) {
20529+ for (reg = disallowed_ranges[i][0];
20530+ reg <= disallowed_ranges[i][1]; reg += 4) {
20531+ tmp = reg >> 2;
20532+ psb_disallowed_regs[tmp >> 5] |= (1 << (tmp & 31));
20533+ }
20534+ }
20535+}
20536+
20537+static int psb_memcpy_check(uint32_t * dst, const uint32_t * src, uint32_t size)
20538+{
20539+ size >>= 3;
20540+ while (size--) {
20541+ if (unlikely((*src >= 0x1000) || psb_disallowed(*src))) {
20542+ DRM_ERROR("Forbidden SGX register access: "
20543+ "0x%04x.\n", *src);
20544+ return -EPERM;
20545+ }
20546+ *dst++ = *src++;
20547+ *dst++ = *src++;
20548+ }
20549+ return 0;
20550+}
20551+
20552+static int psb_2d_wait_available(struct drm_psb_private *dev_priv,
20553+ unsigned size)
20554+{
20555+ uint32_t avail = PSB_RSGX32(PSB_CR_2D_SOCIF);
20556+ int ret = 0;
20557+
20558+ retry:
20559+ if (avail < size) {
20560+#if 0
20561+ /* We'd ideally
20562+ * like to have an IRQ-driven event here.
20563+ */
20564+
20565+ psb_2D_irq_on(dev_priv);
20566+ DRM_WAIT_ON(ret, dev_priv->event_2d_queue, DRM_HZ,
20567+ ((avail = PSB_RSGX32(PSB_CR_2D_SOCIF)) >= size));
20568+ psb_2D_irq_off(dev_priv);
20569+ if (ret == 0)
20570+ return 0;
20571+ if (ret == -EINTR) {
20572+ ret = 0;
20573+ goto retry;
20574+ }
20575+#else
20576+ avail = PSB_RSGX32(PSB_CR_2D_SOCIF);
20577+ goto retry;
20578+#endif
20579+ }
20580+ return ret;
20581+}
20582+
20583+int psb_2d_submit(struct drm_psb_private *dev_priv, uint32_t * cmdbuf,
20584+ unsigned size)
20585+{
20586+ int ret = 0;
20587+ int i;
20588+ unsigned submit_size;
20589+
20590+ while (size > 0) {
20591+ submit_size = (size < 0x60) ? size : 0x60;
20592+ size -= submit_size;
20593+ ret = psb_2d_wait_available(dev_priv, submit_size);
20594+ if (ret)
20595+ return ret;
20596+
20597+ submit_size <<= 2;
20598+
20599+ for (i = 0; i < submit_size; i += 4) {
20600+ PSB_WSGX32(*cmdbuf++, PSB_SGX_2D_SLAVE_PORT + i);
20601+ }
20602+ (void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4);
20603+ }
20604+ return 0;
20605+}
20606+
20607+int psb_blit_sequence(struct drm_psb_private *dev_priv, uint32_t sequence)
20608+{
20609+ uint32_t buffer[8];
20610+ uint32_t *bufp = buffer;
20611+ int ret;
20612+
20613+ *bufp++ = PSB_2D_FENCE_BH;
20614+
20615+ *bufp++ = PSB_2D_DST_SURF_BH |
20616+ PSB_2D_DST_8888ARGB | (4 << PSB_2D_DST_STRIDE_SHIFT);
20617+ *bufp++ = dev_priv->comm_mmu_offset - dev_priv->mmu_2d_offset;
20618+
20619+ *bufp++ = PSB_2D_BLIT_BH |
20620+ PSB_2D_ROT_NONE |
20621+ PSB_2D_COPYORDER_TL2BR |
20622+ PSB_2D_DSTCK_DISABLE |
20623+ PSB_2D_SRCCK_DISABLE | PSB_2D_USE_FILL | PSB_2D_ROP3_PATCOPY;
20624+
20625+ *bufp++ = sequence << PSB_2D_FILLCOLOUR_SHIFT;
20626+ *bufp++ = (0 << PSB_2D_DST_XSTART_SHIFT) |
20627+ (0 << PSB_2D_DST_YSTART_SHIFT);
20628+ *bufp++ = (1 << PSB_2D_DST_XSIZE_SHIFT) | (1 << PSB_2D_DST_YSIZE_SHIFT);
20629+
20630+ *bufp++ = PSB_2D_FLUSH_BH;
20631+
20632+ psb_2d_lock(dev_priv);
20633+ ret = psb_2d_submit(dev_priv, buffer, bufp - buffer);
20634+ psb_2d_unlock(dev_priv);
20635+
20636+ if (!ret)
20637+ psb_schedule_watchdog(dev_priv);
20638+ return ret;
20639+}
20640+
20641+int psb_emit_2d_copy_blit(struct drm_device *dev,
20642+ uint32_t src_offset,
20643+ uint32_t dst_offset, uint32_t pages, int direction)
20644+{
20645+ uint32_t cur_pages;
20646+ struct drm_psb_private *dev_priv = dev->dev_private;
20647+ uint32_t buf[10];
20648+ uint32_t *bufp;
20649+ uint32_t xstart;
20650+ uint32_t ystart;
20651+ uint32_t blit_cmd;
20652+ uint32_t pg_add;
20653+ int ret = 0;
20654+
20655+ if (!dev_priv)
20656+ return 0;
20657+
20658+ if (direction) {
20659+ pg_add = (pages - 1) << PAGE_SHIFT;
20660+ src_offset += pg_add;
20661+ dst_offset += pg_add;
20662+ }
20663+
20664+ blit_cmd = PSB_2D_BLIT_BH |
20665+ PSB_2D_ROT_NONE |
20666+ PSB_2D_DSTCK_DISABLE |
20667+ PSB_2D_SRCCK_DISABLE |
20668+ PSB_2D_USE_PAT |
20669+ PSB_2D_ROP3_SRCCOPY |
20670+ (direction ? PSB_2D_COPYORDER_BR2TL : PSB_2D_COPYORDER_TL2BR);
20671+ xstart = (direction) ? ((PAGE_SIZE - 1) >> 2) : 0;
20672+
20673+ psb_2d_lock(dev_priv);
20674+ while (pages > 0) {
20675+ cur_pages = pages;
20676+ if (cur_pages > 2048)
20677+ cur_pages = 2048;
20678+ pages -= cur_pages;
20679+ ystart = (direction) ? cur_pages - 1 : 0;
20680+
20681+ bufp = buf;
20682+ *bufp++ = PSB_2D_FENCE_BH;
20683+
20684+ *bufp++ = PSB_2D_DST_SURF_BH | PSB_2D_DST_8888ARGB |
20685+ (PAGE_SIZE << PSB_2D_DST_STRIDE_SHIFT);
20686+ *bufp++ = dst_offset;
20687+ *bufp++ = PSB_2D_SRC_SURF_BH | PSB_2D_SRC_8888ARGB |
20688+ (PAGE_SIZE << PSB_2D_SRC_STRIDE_SHIFT);
20689+ *bufp++ = src_offset;
20690+ *bufp++ =
20691+ PSB_2D_SRC_OFF_BH | (xstart << PSB_2D_SRCOFF_XSTART_SHIFT) |
20692+ (ystart << PSB_2D_SRCOFF_YSTART_SHIFT);
20693+ *bufp++ = blit_cmd;
20694+ *bufp++ = (xstart << PSB_2D_DST_XSTART_SHIFT) |
20695+ (ystart << PSB_2D_DST_YSTART_SHIFT);
20696+ *bufp++ = ((PAGE_SIZE >> 2) << PSB_2D_DST_XSIZE_SHIFT) |
20697+ (cur_pages << PSB_2D_DST_YSIZE_SHIFT);
20698+
20699+ ret = psb_2d_submit(dev_priv, buf, bufp - buf);
20700+ if (ret)
20701+ goto out;
20702+ pg_add = (cur_pages << PAGE_SHIFT) * ((direction) ? -1 : 1);
20703+ src_offset += pg_add;
20704+ dst_offset += pg_add;
20705+ }
20706+ out:
20707+ psb_2d_unlock(dev_priv);
20708+ return ret;
20709+}
20710+
20711+void psb_init_2d(struct drm_psb_private *dev_priv)
20712+{
20713+ dev_priv->sequence_lock = SPIN_LOCK_UNLOCKED;
20714+ psb_reset(dev_priv, 1);
20715+ dev_priv->mmu_2d_offset = dev_priv->pg->gatt_start;
20716+ PSB_WSGX32(dev_priv->mmu_2d_offset, PSB_CR_BIF_TWOD_REQ_BASE);
20717+ (void)PSB_RSGX32(PSB_CR_BIF_TWOD_REQ_BASE);
20718+}
20719+
20720+int psb_idle_2d(struct drm_device *dev)
20721+{
20722+ struct drm_psb_private *dev_priv = dev->dev_private;
20723+ unsigned long _end = jiffies + DRM_HZ;
20724+ int busy = 0;
20725+
20726+ /*
20727+ * First idle the 2D engine.
20728+ */
20729+
20730+ if (dev_priv->engine_lockup_2d)
20731+ return -EBUSY;
20732+
20733+ if ((PSB_RSGX32(PSB_CR_2D_SOCIF) == _PSB_C2_SOCIF_EMPTY) &&
20734+ ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & _PSB_C2B_STATUS_BUSY) == 0))
20735+ goto out;
20736+
20737+ do {
20738+ busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY);
20739+ } while (busy && !time_after_eq(jiffies, _end));
20740+
20741+ if (busy)
20742+ busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY);
20743+ if (busy)
20744+ goto out;
20745+
20746+ do {
20747+ busy =
20748+ ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & _PSB_C2B_STATUS_BUSY)
20749+ != 0);
20750+ } while (busy && !time_after_eq(jiffies, _end));
20751+ if (busy)
20752+ busy =
20753+ ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & _PSB_C2B_STATUS_BUSY)
20754+ != 0);
20755+
20756+ out:
20757+ if (busy)
20758+ dev_priv->engine_lockup_2d = 1;
20759+
20760+ return (busy) ? -EBUSY : 0;
20761+}
20762+
20763+int psb_idle_3d(struct drm_device *dev)
20764+{
20765+ struct drm_psb_private *dev_priv = dev->dev_private;
20766+ struct psb_scheduler *scheduler = &dev_priv->scheduler;
20767+ int ret;
20768+
20769+ ret = wait_event_timeout(scheduler->idle_queue,
20770+ psb_scheduler_finished(dev_priv), DRM_HZ * 10);
20771+
20772+ return (ret < 1) ? -EBUSY : 0;
20773+}
20774+
20775+static void psb_dereference_buffers_locked(struct psb_buflist_item *buffers,
20776+ unsigned num_buffers)
20777+{
20778+ while (num_buffers--)
20779+ drm_bo_usage_deref_locked(&((buffers++)->bo));
20780+
20781+}
20782+
20783+static int psb_check_presumed(struct drm_bo_op_arg *arg,
20784+ struct drm_buffer_object *bo,
20785+ uint32_t __user * data, int *presumed_ok)
20786+{
20787+ struct drm_bo_op_req *req = &arg->d.req;
20788+ uint32_t hint_offset;
20789+ uint32_t hint = req->bo_req.hint;
20790+
20791+ *presumed_ok = 0;
20792+
20793+ if (!(hint & DRM_BO_HINT_PRESUMED_OFFSET))
20794+ return 0;
20795+ if (bo->mem.mem_type == DRM_BO_MEM_LOCAL) {
20796+ *presumed_ok = 1;
20797+ return 0;
20798+ }
20799+ if (bo->offset == req->bo_req.presumed_offset) {
20800+ *presumed_ok = 1;
20801+ return 0;
20802+ }
20803+
20804+ /*
20805+ * We need to turn off the HINT_PRESUMED_OFFSET for this buffer in
20806+ * the user-space IOCTL argument list, since the buffer has moved,
20807+ * we're about to apply relocations and we might subsequently
20808+ * hit an -EAGAIN. In that case the argument list will be reused by
20809+ * user-space, but the presumed offset is no longer valid.
20810+ *
20811+ * Needless to say, this is a bit ugly.
20812+ */
20813+
20814+ hint_offset = (uint32_t *) & req->bo_req.hint - (uint32_t *) arg;
20815+ hint &= ~DRM_BO_HINT_PRESUMED_OFFSET;
20816+ return __put_user(hint, data + hint_offset);
20817+}
20818+
20819+static int psb_validate_buffer_list(struct drm_file *file_priv,
20820+ unsigned fence_class,
20821+ unsigned long data,
20822+ struct psb_buflist_item *buffers,
20823+ unsigned *num_buffers)
20824+{
20825+ struct drm_bo_op_arg arg;
20826+ struct drm_bo_op_req *req = &arg.d.req;
20827+ int ret = 0;
20828+ unsigned buf_count = 0;
20829+ struct psb_buflist_item *item = buffers;
20830+
20831+ do {
20832+ if (buf_count >= *num_buffers) {
20833+ DRM_ERROR("Buffer count exceeded %d\n.", *num_buffers);
20834+ ret = -EINVAL;
20835+ goto out_err;
20836+ }
20837+ item = buffers + buf_count;
20838+ item->bo = NULL;
20839+
20840+ if (copy_from_user(&arg, (void __user *)data, sizeof(arg))) {
20841+ ret = -EFAULT;
20842+ DRM_ERROR("Error copying validate list.\n"
20843+ "\tbuffer %d, user addr 0x%08lx %d\n",
20844+ buf_count, (unsigned long)data, sizeof(arg));
20845+ goto out_err;
20846+ }
20847+
20848+ ret = 0;
20849+ if (req->op != drm_bo_validate) {
20850+ DRM_ERROR
20851+ ("Buffer object operation wasn't \"validate\".\n");
20852+ ret = -EINVAL;
20853+ goto out_err;
20854+ }
20855+
20856+ item->ret = 0;
20857+ item->data = (void *)__user data;
20858+ ret = drm_bo_handle_validate(file_priv,
20859+ req->bo_req.handle,
20860+ fence_class,
20861+ req->bo_req.flags,
20862+ req->bo_req.mask,
20863+ req->bo_req.hint,
20864+ 0, NULL, &item->bo);
20865+ if (ret)
20866+ goto out_err;
20867+
20868+ PSB_DEBUG_GENERAL("Validated buffer at 0x%08lx\n",
20869+ buffers[buf_count].bo->offset);
20870+
20871+ buf_count++;
20872+
20873+
20874+ ret = psb_check_presumed(&arg, item->bo,
20875+ (uint32_t __user *)
20876+ (unsigned long) data,
20877+ &item->presumed_offset_correct);
20878+
20879+ if (ret)
20880+ goto out_err;
20881+
20882+ data = arg.next;
20883+ } while (data);
20884+
20885+ *num_buffers = buf_count;
20886+
20887+ return 0;
20888+ out_err:
20889+
20890+ *num_buffers = buf_count;
20891+ item->ret = (ret != -EAGAIN) ? ret : 0;
20892+ return ret;
20893+}
20894+
20895+int
20896+psb_reg_submit(struct drm_psb_private *dev_priv, uint32_t * regs,
20897+ unsigned int cmds)
20898+{
20899+ int i;
20900+
20901+ /*
20902+ * cmds is 32-bit words.
20903+ */
20904+
20905+ cmds >>= 1;
20906+ for (i = 0; i < cmds; ++i) {
20907+ PSB_WSGX32(regs[1], regs[0]);
20908+ regs += 2;
20909+ }
20910+ wmb();
20911+ return 0;
20912+}
20913+
20914+/*
20915+ * Security: Block user-space writing to MMU mapping registers.
20916+ * This is important for security and brings Poulsbo DRM
20917+ * up to par with the other DRM drivers. Using this,
20918+ * user-space should not be able to map arbitrary memory
20919+ * pages to graphics memory, but all user-space processes
20920+ * basically have access to all buffer objects mapped to
20921+ * graphics memory.
20922+ */
20923+
20924+int
20925+psb_submit_copy_cmdbuf(struct drm_device *dev,
20926+ struct drm_buffer_object *cmd_buffer,
20927+ unsigned long cmd_offset,
20928+ unsigned long cmd_size,
20929+ int engine, uint32_t * copy_buffer)
20930+{
20931+ unsigned long cmd_end = cmd_offset + (cmd_size << 2);
20932+ struct drm_psb_private *dev_priv = dev->dev_private;
20933+ unsigned long cmd_page_offset = cmd_offset - (cmd_offset & PAGE_MASK);
20934+ unsigned long cmd_next;
20935+ struct drm_bo_kmap_obj cmd_kmap;
20936+ uint32_t *cmd_page;
20937+ unsigned cmds;
20938+ int is_iomem;
20939+ int ret = 0;
20940+
20941+ if (cmd_size == 0)
20942+ return 0;
20943+
20944+ if (engine == PSB_ENGINE_2D)
20945+ psb_2d_lock(dev_priv);
20946+
20947+ do {
20948+ cmd_next = drm_bo_offset_end(cmd_offset, cmd_end);
20949+ ret = drm_bo_kmap(cmd_buffer, cmd_offset >> PAGE_SHIFT,
20950+ 1, &cmd_kmap);
20951+
20952+ if (ret)
20953+ return ret;
20954+ cmd_page = drm_bmo_virtual(&cmd_kmap, &is_iomem);
20955+ cmd_page_offset = (cmd_offset & ~PAGE_MASK) >> 2;
20956+ cmds = (cmd_next - cmd_offset) >> 2;
20957+
20958+ switch (engine) {
20959+ case PSB_ENGINE_2D:
20960+ ret =
20961+ psb_2d_submit(dev_priv, cmd_page + cmd_page_offset,
20962+ cmds);
20963+ break;
20964+ case PSB_ENGINE_RASTERIZER:
20965+ case PSB_ENGINE_TA:
20966+ case PSB_ENGINE_HPRAST:
20967+ PSB_DEBUG_GENERAL("Reg copy.\n");
20968+ ret = psb_memcpy_check(copy_buffer,
20969+ cmd_page + cmd_page_offset,
20970+ cmds * sizeof(uint32_t));
20971+ copy_buffer += cmds;
20972+ break;
20973+ default:
20974+ ret = -EINVAL;
20975+ }
20976+ drm_bo_kunmap(&cmd_kmap);
20977+ if (ret)
20978+ break;
20979+ } while (cmd_offset = cmd_next, cmd_offset != cmd_end);
20980+
20981+ if (engine == PSB_ENGINE_2D)
20982+ psb_2d_unlock(dev_priv);
20983+
20984+ return ret;
20985+}
20986+
20987+static void psb_clear_dstbuf_cache(struct psb_dstbuf_cache *dst_cache)
20988+{
20989+ if (dst_cache->dst_page) {
20990+ drm_bo_kunmap(&dst_cache->dst_kmap);
20991+ dst_cache->dst_page = NULL;
20992+ }
20993+ dst_cache->dst_buf = NULL;
20994+ dst_cache->dst = ~0;
20995+ dst_cache->use_page = NULL;
20996+}
20997+
20998+static int psb_update_dstbuf_cache(struct psb_dstbuf_cache *dst_cache,
20999+ struct psb_buflist_item *buffers,
21000+ unsigned int dst, unsigned long dst_offset)
21001+{
21002+ int ret;
21003+
21004+ PSB_DEBUG_RELOC("Destination buffer is %d.\n", dst);
21005+
21006+ if (unlikely(dst != dst_cache->dst || NULL == dst_cache->dst_buf)) {
21007+ psb_clear_dstbuf_cache(dst_cache);
21008+ dst_cache->dst = dst;
21009+ dst_cache->dst_buf = buffers[dst].bo;
21010+ }
21011+
21012+ if (unlikely(dst_offset > dst_cache->dst_buf->num_pages * PAGE_SIZE)) {
21013+ DRM_ERROR("Relocation destination out of bounds.\n");
21014+ return -EINVAL;
21015+ }
21016+
21017+ if (!drm_bo_same_page(dst_cache->dst_offset, dst_offset) ||
21018+ NULL == dst_cache->dst_page) {
21019+ if (NULL != dst_cache->dst_page) {
21020+ drm_bo_kunmap(&dst_cache->dst_kmap);
21021+ dst_cache->dst_page = NULL;
21022+ }
21023+
21024+ ret = drm_bo_kmap(dst_cache->dst_buf, dst_offset >> PAGE_SHIFT,
21025+ 1, &dst_cache->dst_kmap);
21026+ if (ret) {
21027+ DRM_ERROR("Could not map destination buffer for "
21028+ "relocation.\n");
21029+ return ret;
21030+ }
21031+
21032+ dst_cache->dst_page = drm_bmo_virtual(&dst_cache->dst_kmap,
21033+ &dst_cache->dst_is_iomem);
21034+ dst_cache->dst_offset = dst_offset & PAGE_MASK;
21035+ dst_cache->dst_page_offset = dst_cache->dst_offset >> 2;
21036+ }
21037+ return 0;
21038+}
21039+
21040+static int psb_apply_reloc(struct drm_psb_private *dev_priv,
21041+ uint32_t fence_class,
21042+ const struct drm_psb_reloc *reloc,
21043+ struct psb_buflist_item *buffers,
21044+ int num_buffers,
21045+ struct psb_dstbuf_cache *dst_cache,
21046+ int no_wait, int interruptible)
21047+{
21048+ int reg;
21049+ uint32_t val;
21050+ uint32_t background;
21051+ unsigned int index;
21052+ int ret;
21053+ unsigned int shift;
21054+ unsigned int align_shift;
21055+ uint32_t fence_type;
21056+ struct drm_buffer_object *reloc_bo;
21057+
21058+ PSB_DEBUG_RELOC("Reloc type %d\n"
21059+ "\t where 0x%04x\n"
21060+ "\t buffer 0x%04x\n"
21061+ "\t mask 0x%08x\n"
21062+ "\t shift 0x%08x\n"
21063+ "\t pre_add 0x%08x\n"
21064+ "\t background 0x%08x\n"
21065+ "\t dst_buffer 0x%08x\n"
21066+ "\t arg0 0x%08x\n"
21067+ "\t arg1 0x%08x\n",
21068+ reloc->reloc_op,
21069+ reloc->where,
21070+ reloc->buffer,
21071+ reloc->mask,
21072+ reloc->shift,
21073+ reloc->pre_add,
21074+ reloc->background,
21075+ reloc->dst_buffer, reloc->arg0, reloc->arg1);
21076+
21077+ if (unlikely(reloc->buffer >= num_buffers)) {
21078+ DRM_ERROR("Illegal relocation buffer %d.\n", reloc->buffer);
21079+ return -EINVAL;
21080+ }
21081+
21082+ if (buffers[reloc->buffer].presumed_offset_correct)
21083+ return 0;
21084+
21085+ if (unlikely(reloc->dst_buffer >= num_buffers)) {
21086+ DRM_ERROR("Illegal destination buffer for relocation %d.\n",
21087+ reloc->dst_buffer);
21088+ return -EINVAL;
21089+ }
21090+
21091+ ret = psb_update_dstbuf_cache(dst_cache, buffers, reloc->dst_buffer,
21092+ reloc->where << 2);
21093+ if (ret)
21094+ return ret;
21095+
21096+ reloc_bo = buffers[reloc->buffer].bo;
21097+
21098+ if (unlikely(reloc->pre_add > (reloc_bo->num_pages << PAGE_SHIFT))) {
21099+ DRM_ERROR("Illegal relocation offset add.\n");
21100+ return -EINVAL;
21101+ }
21102+
21103+ switch (reloc->reloc_op) {
21104+ case PSB_RELOC_OP_OFFSET:
21105+ val = reloc_bo->offset + reloc->pre_add;
21106+ break;
21107+ case PSB_RELOC_OP_2D_OFFSET:
21108+ val = reloc_bo->offset + reloc->pre_add -
21109+ dev_priv->mmu_2d_offset;
21110+ if (unlikely(val >= PSB_2D_SIZE)) {
21111+ DRM_ERROR("2D relocation out of bounds\n");
21112+ return -EINVAL;
21113+ }
21114+ break;
21115+ case PSB_RELOC_OP_PDS_OFFSET:
21116+ val = reloc_bo->offset + reloc->pre_add - PSB_MEM_PDS_START;
21117+ if (unlikely(val >= (PSB_MEM_MMU_START - PSB_MEM_PDS_START))) {
21118+ DRM_ERROR("PDS relocation out of bounds\n");
21119+ return -EINVAL;
21120+ }
21121+ break;
21122+ case PSB_RELOC_OP_USE_OFFSET:
21123+ case PSB_RELOC_OP_USE_REG:
21124+
21125+ /*
21126+ * Security:
21127+ * Only allow VERTEX or PIXEL data masters, as
21128+ * shaders run under other data masters may in theory
21129+ * alter MMU mappings.
21130+ */
21131+
21132+ if (unlikely(reloc->arg1 != _PSB_CUC_DM_PIXEL &&
21133+ reloc->arg1 != _PSB_CUC_DM_VERTEX)) {
21134+ DRM_ERROR("Invalid data master in relocation. %d\n",
21135+ reloc->arg1);
21136+ return -EPERM;
21137+ }
21138+
21139+ fence_type = reloc_bo->fence_type;
21140+ ret = psb_grab_use_base(dev_priv,
21141+ reloc_bo->offset +
21142+ reloc->pre_add, reloc->arg0,
21143+ reloc->arg1, fence_class,
21144+ fence_type, no_wait,
21145+ interruptible, &reg, &val);
21146+ if (ret)
21147+ return ret;
21148+
21149+ val = (reloc->reloc_op == PSB_RELOC_OP_USE_REG) ? reg : val;
21150+ break;
21151+ default:
21152+ DRM_ERROR("Unimplemented relocation.\n");
21153+ return -EINVAL;
21154+ }
21155+
21156+ shift = (reloc->shift & PSB_RELOC_SHIFT_MASK) >> PSB_RELOC_SHIFT_SHIFT;
21157+ align_shift = (reloc->shift & PSB_RELOC_ALSHIFT_MASK) >>
21158+ PSB_RELOC_ALSHIFT_SHIFT;
21159+
21160+ val = ((val >> align_shift) << shift);
21161+ index = reloc->where - dst_cache->dst_page_offset;
21162+
21163+ background = reloc->background;
21164+
21165+ if (reloc->reloc_op == PSB_RELOC_OP_USE_OFFSET) {
21166+ if (dst_cache->use_page == dst_cache->dst_page &&
21167+ dst_cache->use_index == index)
21168+ background = dst_cache->use_background;
21169+ else
21170+ background = dst_cache->dst_page[index];
21171+ }
21172+#if 0
21173+ if (dst_cache->dst_page[index] != PSB_RELOC_MAGIC &&
21174+ reloc->reloc_op != PSB_RELOC_OP_USE_OFFSET)
21175+ DRM_ERROR("Inconsistent relocation 0x%08lx.\n",
21176+ (unsigned long)dst_cache->dst_page[index]);
21177+#endif
21178+
21179+ val = (background & ~reloc->mask) | (val & reloc->mask);
21180+ dst_cache->dst_page[index] = val;
21181+
21182+ if (reloc->reloc_op == PSB_RELOC_OP_USE_OFFSET ||
21183+ reloc->reloc_op == PSB_RELOC_OP_USE_REG) {
21184+ dst_cache->use_page = dst_cache->dst_page;
21185+ dst_cache->use_index = index;
21186+ dst_cache->use_background = val;
21187+ }
21188+
21189+ PSB_DEBUG_RELOC("Reloc buffer %d index 0x%08x, value 0x%08x\n",
21190+ reloc->dst_buffer, index, dst_cache->dst_page[index]);
21191+
21192+ return 0;
21193+}
21194+
21195+static int psb_ok_to_map_reloc(struct drm_psb_private *dev_priv,
21196+ unsigned int num_pages)
21197+{
21198+ int ret = 0;
21199+
21200+ spin_lock(&dev_priv->reloc_lock);
21201+ if (dev_priv->rel_mapped_pages + num_pages <= PSB_MAX_RELOC_PAGES) {
21202+ dev_priv->rel_mapped_pages += num_pages;
21203+ ret = 1;
21204+ }
21205+ spin_unlock(&dev_priv->reloc_lock);
21206+ return ret;
21207+}
21208+
21209+static int psb_fixup_relocs(struct drm_file *file_priv,
21210+ uint32_t fence_class,
21211+ unsigned int num_relocs,
21212+ unsigned int reloc_offset,
21213+ uint32_t reloc_handle,
21214+ struct psb_buflist_item *buffers,
21215+ unsigned int num_buffers,
21216+ int no_wait, int interruptible)
21217+{
21218+ struct drm_device *dev = file_priv->minor->dev;
21219+ struct drm_psb_private *dev_priv =
21220+ (struct drm_psb_private *)dev->dev_private;
21221+ struct drm_buffer_object *reloc_buffer = NULL;
21222+ unsigned int reloc_num_pages;
21223+ unsigned int reloc_first_page;
21224+ unsigned int reloc_last_page;
21225+ struct psb_dstbuf_cache dst_cache;
21226+ struct drm_psb_reloc *reloc;
21227+ struct drm_bo_kmap_obj reloc_kmap;
21228+ int reloc_is_iomem;
21229+ int count;
21230+ int ret = 0;
21231+ int registered = 0;
21232+ int short_circuit = 1;
21233+ int i;
21234+
21235+ if (num_relocs == 0)
21236+ return 0;
21237+
21238+ for (i=0; i<num_buffers; ++i) {
21239+ if (!buffers[i].presumed_offset_correct) {
21240+ short_circuit = 0;
21241+ break;
21242+ }
21243+ }
21244+
21245+ if (short_circuit)
21246+ return 0;
21247+
21248+ memset(&dst_cache, 0, sizeof(dst_cache));
21249+ memset(&reloc_kmap, 0, sizeof(reloc_kmap));
21250+
21251+ mutex_lock(&dev->struct_mutex);
21252+ reloc_buffer = drm_lookup_buffer_object(file_priv, reloc_handle, 1);
21253+ mutex_unlock(&dev->struct_mutex);
21254+ if (!reloc_buffer)
21255+ goto out;
21256+
21257+ reloc_first_page = reloc_offset >> PAGE_SHIFT;
21258+ reloc_last_page =
21259+ (reloc_offset +
21260+ num_relocs * sizeof(struct drm_psb_reloc)) >> PAGE_SHIFT;
21261+ reloc_num_pages = reloc_last_page - reloc_first_page + 1;
21262+ reloc_offset &= ~PAGE_MASK;
21263+
21264+ if (reloc_num_pages > PSB_MAX_RELOC_PAGES) {
21265+ DRM_ERROR("Relocation buffer is too large\n");
21266+ ret = -EINVAL;
21267+ goto out;
21268+ }
21269+
21270+ DRM_WAIT_ON(ret, dev_priv->rel_mapped_queue, 3 * DRM_HZ,
21271+ (registered =
21272+ psb_ok_to_map_reloc(dev_priv, reloc_num_pages)));
21273+
21274+ if (ret == -EINTR) {
21275+ ret = -EAGAIN;
21276+ goto out;
21277+ }
21278+ if (ret) {
21279+ DRM_ERROR("Error waiting for space to map "
21280+ "relocation buffer.\n");
21281+ goto out;
21282+ }
21283+
21284+ ret = drm_bo_kmap(reloc_buffer, reloc_first_page,
21285+ reloc_num_pages, &reloc_kmap);
21286+
21287+ if (ret) {
21288+ DRM_ERROR("Could not map relocation buffer.\n"
21289+ "\tReloc buffer id 0x%08x.\n"
21290+ "\tReloc first page %d.\n"
21291+ "\tReloc num pages %d.\n",
21292+ reloc_handle, reloc_first_page, reloc_num_pages);
21293+ goto out;
21294+ }
21295+
21296+ reloc = (struct drm_psb_reloc *)
21297+ ((unsigned long)drm_bmo_virtual(&reloc_kmap, &reloc_is_iomem) +
21298+ reloc_offset);
21299+
21300+ for (count = 0; count < num_relocs; ++count) {
21301+ ret = psb_apply_reloc(dev_priv, fence_class,
21302+ reloc, buffers,
21303+ num_buffers, &dst_cache,
21304+ no_wait, interruptible);
21305+ if (ret)
21306+ goto out1;
21307+ reloc++;
21308+ }
21309+
21310+ out1:
21311+ drm_bo_kunmap(&reloc_kmap);
21312+ out:
21313+ if (registered) {
21314+ spin_lock(&dev_priv->reloc_lock);
21315+ dev_priv->rel_mapped_pages -= reloc_num_pages;
21316+ spin_unlock(&dev_priv->reloc_lock);
21317+ DRM_WAKEUP(&dev_priv->rel_mapped_queue);
21318+ }
21319+
21320+ psb_clear_dstbuf_cache(&dst_cache);
21321+ if (reloc_buffer)
21322+ drm_bo_usage_deref_unlocked(&reloc_buffer);
21323+ return ret;
21324+}
21325+
21326+static int psb_cmdbuf_2d(struct drm_file *priv,
21327+ struct drm_psb_cmdbuf_arg *arg,
21328+ struct drm_buffer_object *cmd_buffer,
21329+ struct drm_fence_arg *fence_arg)
21330+{
21331+ struct drm_device *dev = priv->minor->dev;
21332+ struct drm_psb_private *dev_priv =
21333+ (struct drm_psb_private *)dev->dev_private;
21334+ int ret;
21335+
21336+ ret = mutex_lock_interruptible(&dev_priv->reset_mutex);
21337+ if (ret)
21338+ return -EAGAIN;
21339+
21340+ ret = psb_submit_copy_cmdbuf(dev, cmd_buffer, arg->cmdbuf_offset,
21341+ arg->cmdbuf_size, PSB_ENGINE_2D, NULL);
21342+ if (ret)
21343+ goto out_unlock;
21344+
21345+ psb_fence_or_sync(priv, PSB_ENGINE_2D, arg, fence_arg, NULL);
21346+
21347+ mutex_lock(&cmd_buffer->mutex);
21348+ if (cmd_buffer->fence != NULL)
21349+ drm_fence_usage_deref_unlocked(&cmd_buffer->fence);
21350+ mutex_unlock(&cmd_buffer->mutex);
21351+ out_unlock:
21352+ mutex_unlock(&dev_priv->reset_mutex);
21353+ return ret;
21354+}
21355+
21356+#if 0
21357+static int psb_dump_page(struct drm_buffer_object *bo,
21358+ unsigned int page_offset, unsigned int num)
21359+{
21360+ struct drm_bo_kmap_obj kmobj;
21361+ int is_iomem;
21362+ uint32_t *p;
21363+ int ret;
21364+ unsigned int i;
21365+
21366+ ret = drm_bo_kmap(bo, page_offset, 1, &kmobj);
21367+ if (ret)
21368+ return ret;
21369+
21370+ p = drm_bmo_virtual(&kmobj, &is_iomem);
21371+ for (i = 0; i < num; ++i)
21372+ PSB_DEBUG_GENERAL("0x%04x: 0x%08x\n", i, *p++);
21373+
21374+ drm_bo_kunmap(&kmobj);
21375+ return 0;
21376+}
21377+#endif
21378+
21379+static void psb_idle_engine(struct drm_device *dev, int engine)
21380+{
21381+ struct drm_psb_private *dev_priv =
21382+ (struct drm_psb_private *)dev->dev_private;
21383+ uint32_t dummy;
21384+
21385+ switch (engine) {
21386+ case PSB_ENGINE_2D:
21387+
21388+ /*
21389+ * Make sure we flush 2D properly using a dummy
21390+ * fence sequence emit.
21391+ */
21392+
21393+ (void)psb_fence_emit_sequence(dev, PSB_ENGINE_2D, 0,
21394+ &dummy, &dummy);
21395+ psb_2d_lock(dev_priv);
21396+ (void)psb_idle_2d(dev);
21397+ psb_2d_unlock(dev_priv);
21398+ break;
21399+ case PSB_ENGINE_TA:
21400+ case PSB_ENGINE_RASTERIZER:
21401+ case PSB_ENGINE_HPRAST:
21402+ (void)psb_idle_3d(dev);
21403+ break;
21404+ default:
21405+
21406+ /*
21407+ * FIXME: Insert video engine idle command here.
21408+ */
21409+
21410+ break;
21411+ }
21412+}
21413+
21414+void psb_fence_or_sync(struct drm_file *priv,
21415+ int engine,
21416+ struct drm_psb_cmdbuf_arg *arg,
21417+ struct drm_fence_arg *fence_arg,
21418+ struct drm_fence_object **fence_p)
21419+{
21420+ struct drm_device *dev = priv->minor->dev;
21421+ int ret;
21422+ struct drm_fence_object *fence;
21423+
21424+ ret = drm_fence_buffer_objects(dev, NULL, arg->fence_flags,
21425+ NULL, &fence);
21426+
21427+ if (ret) {
21428+
21429+ /*
21430+ * Fence creation failed.
21431+ * Fall back to synchronous operation and idle the engine.
21432+ */
21433+
21434+ psb_idle_engine(dev, engine);
21435+ if (!(arg->fence_flags & DRM_FENCE_FLAG_NO_USER)) {
21436+
21437+ /*
21438+ * Communicate to user-space that
21439+ * fence creation has failed and that
21440+ * the engine is idle.
21441+ */
21442+
21443+ fence_arg->handle = ~0;
21444+ fence_arg->error = ret;
21445+ }
21446+
21447+ drm_putback_buffer_objects(dev);
21448+ if (fence_p)
21449+ *fence_p = NULL;
21450+ return;
21451+ }
21452+
21453+ if (!(arg->fence_flags & DRM_FENCE_FLAG_NO_USER)) {
21454+
21455+ ret = drm_fence_add_user_object(priv, fence,
21456+ arg->fence_flags &
21457+ DRM_FENCE_FLAG_SHAREABLE);
21458+ if (!ret)
21459+ drm_fence_fill_arg(fence, fence_arg);
21460+ else {
21461+ /*
21462+ * Fence user object creation failed.
21463+ * We must idle the engine here as well, as user-
21464+ * space expects a fence object to wait on. Since we
21465+ * have a fence object we wait for it to signal
21466+ * to indicate engine "sufficiently" idle.
21467+ */
21468+
21469+ (void)drm_fence_object_wait(fence, 0, 1, fence->type);
21470+ drm_fence_usage_deref_unlocked(&fence);
21471+ fence_arg->handle = ~0;
21472+ fence_arg->error = ret;
21473+ }
21474+ }
21475+
21476+ if (fence_p)
21477+ *fence_p = fence;
21478+ else if (fence)
21479+ drm_fence_usage_deref_unlocked(&fence);
21480+}
21481+
21482+int psb_handle_copyback(struct drm_device *dev,
21483+ struct psb_buflist_item *buffers,
21484+ unsigned int num_buffers, int ret, void *data)
21485+{
21486+ struct drm_psb_private *dev_priv =
21487+ (struct drm_psb_private *)dev->dev_private;
21488+ struct drm_bo_op_arg arg;
21489+ struct psb_buflist_item *item = buffers;
21490+ struct drm_buffer_object *bo;
21491+ int err = ret;
21492+ int i;
21493+
21494+ /*
21495+ * Clear the unfenced use base register lists and buffer lists.
21496+ */
21497+
21498+ if (ret) {
21499+ drm_regs_fence(&dev_priv->use_manager, NULL);
21500+ drm_putback_buffer_objects(dev);
21501+ }
21502+
21503+ if (ret != -EAGAIN) {
21504+ for (i = 0; i < num_buffers; ++i) {
21505+ arg.handled = 1;
21506+ arg.d.rep.ret = item->ret;
21507+ bo = item->bo;
21508+ mutex_lock(&bo->mutex);
21509+ drm_bo_fill_rep_arg(bo, &arg.d.rep.bo_info);
21510+ mutex_unlock(&bo->mutex);
21511+ if (copy_to_user(item->data, &arg, sizeof(arg)))
21512+ err = -EFAULT;
21513+ ++item;
21514+ }
21515+ }
21516+
21517+ return err;
21518+}
21519+
21520+static int psb_cmdbuf_video(struct drm_file *priv,
21521+ struct drm_psb_cmdbuf_arg *arg,
21522+ unsigned int num_buffers,
21523+ struct drm_buffer_object *cmd_buffer,
21524+ struct drm_fence_arg *fence_arg)
21525+{
21526+ struct drm_device *dev = priv->minor->dev;
21527+ struct drm_fence_object *fence;
21528+ int ret;
21529+
21530+ /*
21531+ * Check this. Doesn't seem right. Have fencing done AFTER command
21532+ * submission and make sure drm_psb_idle idles the MSVDX completely.
21533+ */
21534+
21535+ psb_fence_or_sync(priv, PSB_ENGINE_VIDEO, arg, fence_arg, &fence);
21536+ ret = psb_submit_video_cmdbuf(dev, cmd_buffer, arg->cmdbuf_offset,
21537+ arg->cmdbuf_size, fence);
21538+
21539+ if (ret)
21540+ return ret;
21541+
21542+ drm_fence_usage_deref_unlocked(&fence);
21543+ mutex_lock(&cmd_buffer->mutex);
21544+ if (cmd_buffer->fence != NULL)
21545+ drm_fence_usage_deref_unlocked(&cmd_buffer->fence);
21546+ mutex_unlock(&cmd_buffer->mutex);
21547+ return 0;
21548+}
21549+
21550+int psb_feedback_buf(struct drm_file *file_priv,
21551+ uint32_t feedback_ops,
21552+ uint32_t handle,
21553+ uint32_t offset,
21554+ uint32_t feedback_breakpoints,
21555+ uint32_t feedback_size, struct psb_feedback_info *feedback)
21556+{
21557+ struct drm_buffer_object *bo;
21558+ struct page *page;
21559+ uint32_t page_no;
21560+ uint32_t page_offset;
21561+ int ret;
21562+
21563+ if (feedback_ops & ~PSB_FEEDBACK_OP_VISTEST) {
21564+ DRM_ERROR("Illegal feedback op.\n");
21565+ return -EINVAL;
21566+ }
21567+
21568+ if (feedback_breakpoints != 0) {
21569+ DRM_ERROR("Feedback breakpoints not implemented yet.\n");
21570+ return -EINVAL;
21571+ }
21572+
21573+ if (feedback_size < PSB_HW_FEEDBACK_SIZE * sizeof(uint32_t)) {
21574+ DRM_ERROR("Feedback buffer size too small.\n");
21575+ return -EINVAL;
21576+ }
21577+
21578+ page_offset = offset & ~PAGE_MASK;
21579+ if ((PAGE_SIZE - PSB_HW_FEEDBACK_SIZE * sizeof(uint32_t))
21580+ < page_offset) {
21581+ DRM_ERROR("Illegal feedback buffer alignment.\n");
21582+ return -EINVAL;
21583+ }
21584+
21585+ ret = drm_bo_handle_validate(file_priv,
21586+ handle,
21587+ PSB_ENGINE_TA,
21588+ DRM_BO_FLAG_MEM_LOCAL |
21589+ DRM_BO_FLAG_CACHED |
21590+ DRM_BO_FLAG_WRITE |
21591+ PSB_BO_FLAG_FEEDBACK,
21592+ DRM_BO_MASK_MEM |
21593+ DRM_BO_FLAG_CACHED |
21594+ DRM_BO_FLAG_WRITE |
21595+ PSB_BO_FLAG_FEEDBACK, 0, 0, NULL, &bo);
21596+ if (ret)
21597+ return ret;
21598+
21599+ page_no = offset >> PAGE_SHIFT;
21600+ if (page_no >= bo->num_pages) {
21601+ ret = -EINVAL;
21602+ DRM_ERROR("Illegal feedback buffer offset.\n");
21603+ goto out_unref;
21604+ }
21605+
21606+ if (bo->ttm == NULL) {
21607+ ret = -EINVAL;
21608+ DRM_ERROR("Vistest buffer without TTM.\n");
21609+ goto out_unref;
21610+ }
21611+
21612+ page = drm_ttm_get_page(bo->ttm, page_no);
21613+ if (!page) {
21614+ ret = -ENOMEM;
21615+ goto out_unref;
21616+ }
21617+
21618+ feedback->page = page;
21619+ feedback->bo = bo;
21620+ feedback->offset = page_offset;
21621+ return 0;
21622+
21623+ out_unref:
21624+ drm_bo_usage_deref_unlocked(&bo);
21625+ return ret;
21626+}
21627+
21628+int psb_cmdbuf_ioctl(struct drm_device *dev, void *data,
21629+ struct drm_file *file_priv)
21630+{
21631+ drm_psb_cmdbuf_arg_t *arg = data;
21632+ int ret = 0;
21633+ unsigned num_buffers;
21634+ struct drm_buffer_object *cmd_buffer = NULL;
21635+ struct drm_buffer_object *ta_buffer = NULL;
21636+ struct drm_buffer_object *oom_buffer = NULL;
21637+ struct drm_fence_arg fence_arg;
21638+ struct drm_psb_scene user_scene;
21639+ struct psb_scene_pool *pool = NULL;
21640+ struct psb_scene *scene = NULL;
21641+ struct drm_psb_private *dev_priv =
21642+ (struct drm_psb_private *)file_priv->minor->dev->dev_private;
21643+ int engine;
21644+ struct psb_feedback_info feedback;
21645+
21646+ if (!dev_priv)
21647+ return -EINVAL;
21648+
21649+ ret = drm_bo_read_lock(&dev->bm.bm_lock);
21650+ if (ret)
21651+ return ret;
21652+
21653+ num_buffers = PSB_NUM_VALIDATE_BUFFERS;
21654+
21655+ ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex);
21656+ if (ret) {
21657+ drm_bo_read_unlock(&dev->bm.bm_lock);
21658+ return -EAGAIN;
21659+ }
21660+ if (unlikely(dev_priv->buffers == NULL)) {
21661+ dev_priv->buffers = vmalloc(PSB_NUM_VALIDATE_BUFFERS *
21662+ sizeof(*dev_priv->buffers));
21663+ if (dev_priv->buffers == NULL) {
21664+ drm_bo_read_unlock(&dev->bm.bm_lock);
21665+ return -ENOMEM;
21666+ }
21667+ }
21668+
21669+
21670+ engine = (arg->engine == PSB_ENGINE_RASTERIZER) ?
21671+ PSB_ENGINE_TA : arg->engine;
21672+
21673+ ret =
21674+ psb_validate_buffer_list(file_priv, engine,
21675+ (unsigned long)arg->buffer_list,
21676+ dev_priv->buffers, &num_buffers);
21677+ if (ret)
21678+ goto out_err0;
21679+
21680+ ret = psb_fixup_relocs(file_priv, engine, arg->num_relocs,
21681+ arg->reloc_offset, arg->reloc_handle,
21682+ dev_priv->buffers, num_buffers, 0, 1);
21683+ if (ret)
21684+ goto out_err0;
21685+
21686+ mutex_lock(&dev->struct_mutex);
21687+ cmd_buffer = drm_lookup_buffer_object(file_priv, arg->cmdbuf_handle, 1);
21688+ mutex_unlock(&dev->struct_mutex);
21689+ if (!cmd_buffer) {
21690+ ret = -EINVAL;
21691+ goto out_err0;
21692+ }
21693+
21694+ switch (arg->engine) {
21695+ case PSB_ENGINE_2D:
21696+ ret = psb_cmdbuf_2d(file_priv, arg, cmd_buffer, &fence_arg);
21697+ if (ret)
21698+ goto out_err0;
21699+ break;
21700+ case PSB_ENGINE_VIDEO:
21701+ ret =
21702+ psb_cmdbuf_video(file_priv, arg, num_buffers, cmd_buffer,
21703+ &fence_arg);
21704+ if (ret)
21705+ goto out_err0;
21706+ break;
21707+ case PSB_ENGINE_RASTERIZER:
21708+ ret = psb_cmdbuf_raster(file_priv, arg, cmd_buffer, &fence_arg);
21709+ if (ret)
21710+ goto out_err0;
21711+ break;
21712+ case PSB_ENGINE_TA:
21713+ if (arg->ta_handle == arg->cmdbuf_handle) {
21714+ mutex_lock(&dev->struct_mutex);
21715+ atomic_inc(&cmd_buffer->usage);
21716+ ta_buffer = cmd_buffer;
21717+ mutex_unlock(&dev->struct_mutex);
21718+ } else {
21719+ mutex_lock(&dev->struct_mutex);
21720+ ta_buffer =
21721+ drm_lookup_buffer_object(file_priv,
21722+ arg->ta_handle, 1);
21723+ mutex_unlock(&dev->struct_mutex);
21724+ if (!ta_buffer) {
21725+ ret = -EINVAL;
21726+ goto out_err0;
21727+ }
21728+ }
21729+ if (arg->oom_size != 0) {
21730+ if (arg->oom_handle == arg->cmdbuf_handle) {
21731+ mutex_lock(&dev->struct_mutex);
21732+ atomic_inc(&cmd_buffer->usage);
21733+ oom_buffer = cmd_buffer;
21734+ mutex_unlock(&dev->struct_mutex);
21735+ } else {
21736+ mutex_lock(&dev->struct_mutex);
21737+ oom_buffer =
21738+ drm_lookup_buffer_object(file_priv,
21739+ arg->oom_handle,
21740+ 1);
21741+ mutex_unlock(&dev->struct_mutex);
21742+ if (!oom_buffer) {
21743+ ret = -EINVAL;
21744+ goto out_err0;
21745+ }
21746+ }
21747+ }
21748+
21749+ ret = copy_from_user(&user_scene, (void __user *)
21750+ ((unsigned long)arg->scene_arg),
21751+ sizeof(user_scene));
21752+ if (ret)
21753+ goto out_err0;
21754+
21755+ if (!user_scene.handle_valid) {
21756+ pool = psb_scene_pool_alloc(file_priv, 0,
21757+ user_scene.num_buffers,
21758+ user_scene.w, user_scene.h);
21759+ if (!pool) {
21760+ ret = -ENOMEM;
21761+ goto out_err0;
21762+ }
21763+
21764+ user_scene.handle = psb_scene_pool_handle(pool);
21765+ user_scene.handle_valid = 1;
21766+ ret = copy_to_user((void __user *)
21767+ ((unsigned long)arg->scene_arg),
21768+ &user_scene, sizeof(user_scene));
21769+
21770+ if (ret)
21771+ goto out_err0;
21772+ } else {
21773+ mutex_lock(&dev->struct_mutex);
21774+ pool = psb_scene_pool_lookup_devlocked(file_priv,
21775+ user_scene.
21776+ handle, 1);
21777+ mutex_unlock(&dev->struct_mutex);
21778+ if (!pool) {
21779+ ret = -EINVAL;
21780+ goto out_err0;
21781+ }
21782+ }
21783+
21784+ mutex_lock(&dev_priv->reset_mutex);
21785+ ret = psb_validate_scene_pool(pool, 0, 0, 0,
21786+ user_scene.w,
21787+ user_scene.h,
21788+ arg->ta_flags &
21789+ PSB_TA_FLAG_LASTPASS, &scene);
21790+ mutex_unlock(&dev_priv->reset_mutex);
21791+
21792+ if (ret)
21793+ goto out_err0;
21794+
21795+ memset(&feedback, 0, sizeof(feedback));
21796+ if (arg->feedback_ops) {
21797+ ret = psb_feedback_buf(file_priv,
21798+ arg->feedback_ops,
21799+ arg->feedback_handle,
21800+ arg->feedback_offset,
21801+ arg->feedback_breakpoints,
21802+ arg->feedback_size, &feedback);
21803+ if (ret)
21804+ goto out_err0;
21805+ }
21806+ ret = psb_cmdbuf_ta(file_priv, arg, cmd_buffer, ta_buffer,
21807+ oom_buffer, scene, &feedback, &fence_arg);
21808+ if (ret)
21809+ goto out_err0;
21810+ break;
21811+ default:
21812+ DRM_ERROR("Unimplemented command submission mechanism (%x).\n",
21813+ arg->engine);
21814+ ret = -EINVAL;
21815+ goto out_err0;
21816+ }
21817+
21818+ if (!(arg->fence_flags & DRM_FENCE_FLAG_NO_USER)) {
21819+ ret = copy_to_user((void __user *)
21820+ ((unsigned long)arg->fence_arg),
21821+ &fence_arg, sizeof(fence_arg));
21822+ }
21823+
21824+ out_err0:
21825+ ret =
21826+ psb_handle_copyback(dev, dev_priv->buffers, num_buffers, ret, data);
21827+ mutex_lock(&dev->struct_mutex);
21828+ if (scene)
21829+ psb_scene_unref_devlocked(&scene);
21830+ if (pool)
21831+ psb_scene_pool_unref_devlocked(&pool);
21832+ if (cmd_buffer)
21833+ drm_bo_usage_deref_locked(&cmd_buffer);
21834+ if (ta_buffer)
21835+ drm_bo_usage_deref_locked(&ta_buffer);
21836+ if (oom_buffer)
21837+ drm_bo_usage_deref_locked(&oom_buffer);
21838+
21839+ psb_dereference_buffers_locked(dev_priv->buffers, num_buffers);
21840+ mutex_unlock(&dev->struct_mutex);
21841+ mutex_unlock(&dev_priv->cmdbuf_mutex);
21842+
21843+ drm_bo_read_unlock(&dev->bm.bm_lock);
21844+ return ret;
21845+}
21846Index: linux-2.6.28/drivers/gpu/drm/psb/psb_xhw.c
21847===================================================================
21848--- /dev/null 1970-01-01 00:00:00.000000000 +0000
21849+++ linux-2.6.28/drivers/gpu/drm/psb/psb_xhw.c 2009-02-12 09:14:42.000000000 +0000
21850@@ -0,0 +1,614 @@
21851+/**************************************************************************
21852+ * Copyright (c) 2007, Intel Corporation.
21853+ * All Rights Reserved.
21854+ *
21855+ * This program is free software; you can redistribute it and/or modify it
21856+ * under the terms and conditions of the GNU General Public License,
21857+ * version 2, as published by the Free Software Foundation.
21858+ *
21859+ * This program is distributed in the hope it will be useful, but WITHOUT
21860+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21861+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21862+ * more details.
21863+ *
21864+ * You should have received a copy of the GNU General Public License along with
21865+ * this program; if not, write to the Free Software Foundation, Inc.,
21866+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21867+ *
21868+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
21869+ * develop this driver.
21870+ *
21871+ **************************************************************************/
21872+/*
21873+ * Make calls into closed source X server code.
21874+ */
21875+
21876+#include "drmP.h"
21877+#include "psb_drv.h"
21878+
21879+void
21880+psb_xhw_clean_buf(struct drm_psb_private *dev_priv, struct psb_xhw_buf *buf)
21881+{
21882+ unsigned long irq_flags;
21883+
21884+ spin_lock_irqsave(&dev_priv->xhw_lock, irq_flags);
21885+ list_del_init(&buf->head);
21886+ if (dev_priv->xhw_cur_buf == buf)
21887+ dev_priv->xhw_cur_buf = NULL;
21888+ atomic_set(&buf->done, 1);
21889+ spin_unlock_irqrestore(&dev_priv->xhw_lock, irq_flags);
21890+}
21891+
21892+static inline int psb_xhw_add(struct drm_psb_private *dev_priv,
21893+ struct psb_xhw_buf *buf)
21894+{
21895+ unsigned long irq_flags;
21896+
21897+ spin_lock_irqsave(&dev_priv->xhw_lock, irq_flags);
21898+ atomic_set(&buf->done, 0);
21899+ if (unlikely(!dev_priv->xhw_submit_ok)) {
21900+ spin_unlock_irqrestore(&dev_priv->xhw_lock, irq_flags);
21901+ DRM_ERROR("No Xpsb 3D extension available.\n");
21902+ return -EINVAL;
21903+ }
21904+ if (!list_empty(&buf->head)) {
21905+ DRM_ERROR("Recursive list adding.\n");
21906+ goto out;
21907+ }
21908+ list_add_tail(&buf->head, &dev_priv->xhw_in);
21909+ wake_up_interruptible(&dev_priv->xhw_queue);
21910+ out:
21911+ spin_unlock_irqrestore(&dev_priv->xhw_lock, irq_flags);
21912+ return 0;
21913+}
21914+
21915+int psb_xhw_scene_info(struct drm_psb_private *dev_priv,
21916+ struct psb_xhw_buf *buf,
21917+ uint32_t w,
21918+ uint32_t h,
21919+ uint32_t * hw_cookie,
21920+ uint32_t * bo_size,
21921+ uint32_t * clear_p_start, uint32_t * clear_num_pages)
21922+{
21923+ struct drm_psb_xhw_arg *xa = &buf->arg;
21924+ int ret;
21925+
21926+ buf->copy_back = 1;
21927+ xa->op = PSB_XHW_SCENE_INFO;
21928+ xa->irq_op = 0;
21929+ xa->issue_irq = 0;
21930+ xa->arg.si.w = w;
21931+ xa->arg.si.h = h;
21932+
21933+ ret = psb_xhw_add(dev_priv, buf);
21934+ if (ret)
21935+ return ret;
21936+
21937+ (void)wait_event_timeout(dev_priv->xhw_caller_queue,
21938+ atomic_read(&buf->done), DRM_HZ);
21939+
21940+ if (!atomic_read(&buf->done)) {
21941+ psb_xhw_clean_buf(dev_priv, buf);
21942+ return -EBUSY;
21943+ }
21944+
21945+ if (!xa->ret) {
21946+ memcpy(hw_cookie, xa->cookie, sizeof(xa->cookie));
21947+ *bo_size = xa->arg.si.size;
21948+ *clear_p_start = xa->arg.si.clear_p_start;
21949+ *clear_num_pages = xa->arg.si.clear_num_pages;
21950+ }
21951+ return xa->ret;
21952+}
21953+
21954+int psb_xhw_fire_raster(struct drm_psb_private *dev_priv,
21955+ struct psb_xhw_buf *buf, uint32_t fire_flags)
21956+{
21957+ struct drm_psb_xhw_arg *xa = &buf->arg;
21958+
21959+ buf->copy_back = 0;
21960+ xa->op = PSB_XHW_FIRE_RASTER;
21961+ xa->issue_irq = 0;
21962+ xa->arg.sb.fire_flags = 0;
21963+
21964+ return psb_xhw_add(dev_priv, buf);
21965+}
21966+
21967+int psb_xhw_vistest(struct drm_psb_private *dev_priv, struct psb_xhw_buf *buf)
21968+{
21969+ struct drm_psb_xhw_arg *xa = &buf->arg;
21970+
21971+ buf->copy_back = 1;
21972+ xa->op = PSB_XHW_VISTEST;
21973+ /*
21974+ * Could perhaps decrease latency somewhat by
21975+ * issuing an irq in this case.
21976+ */
21977+ xa->issue_irq = 0;
21978+ xa->irq_op = PSB_UIRQ_VISTEST;
21979+ return psb_xhw_add(dev_priv, buf);
21980+}
21981+
21982+int psb_xhw_scene_bind_fire(struct drm_psb_private *dev_priv,
21983+ struct psb_xhw_buf *buf,
21984+ uint32_t fire_flags,
21985+ uint32_t hw_context,
21986+ uint32_t * cookie,
21987+ uint32_t * oom_cmds,
21988+ uint32_t num_oom_cmds,
21989+ uint32_t offset, uint32_t engine, uint32_t flags)
21990+{
21991+ struct drm_psb_xhw_arg *xa = &buf->arg;
21992+
21993+ buf->copy_back = (fire_flags & PSB_FIRE_FLAG_XHW_OOM);
21994+ xa->op = PSB_XHW_SCENE_BIND_FIRE;
21995+ xa->issue_irq = (buf->copy_back) ? 1 : 0;
21996+ if (unlikely(buf->copy_back))
21997+ xa->irq_op = (engine == PSB_SCENE_ENGINE_TA) ?
21998+ PSB_UIRQ_FIRE_TA_REPLY : PSB_UIRQ_FIRE_RASTER_REPLY;
21999+ else
22000+ xa->irq_op = 0;
22001+ xa->arg.sb.fire_flags = fire_flags;
22002+ xa->arg.sb.hw_context = hw_context;
22003+ xa->arg.sb.offset = offset;
22004+ xa->arg.sb.engine = engine;
22005+ xa->arg.sb.flags = flags;
22006+ xa->arg.sb.num_oom_cmds = num_oom_cmds;
22007+ memcpy(xa->cookie, cookie, sizeof(xa->cookie));
22008+ if (num_oom_cmds)
22009+ memcpy(xa->arg.sb.oom_cmds, oom_cmds,
22010+ sizeof(uint32_t) * num_oom_cmds);
22011+ return psb_xhw_add(dev_priv, buf);
22012+}
22013+
22014+int psb_xhw_reset_dpm(struct drm_psb_private *dev_priv, struct psb_xhw_buf *buf)
22015+{
22016+ struct drm_psb_xhw_arg *xa = &buf->arg;
22017+ int ret;
22018+
22019+ buf->copy_back = 1;
22020+ xa->op = PSB_XHW_RESET_DPM;
22021+ xa->issue_irq = 0;
22022+ xa->irq_op = 0;
22023+
22024+ ret = psb_xhw_add(dev_priv, buf);
22025+ if (ret)
22026+ return ret;
22027+
22028+ (void)wait_event_timeout(dev_priv->xhw_caller_queue,
22029+ atomic_read(&buf->done), 3 * DRM_HZ);
22030+
22031+ if (!atomic_read(&buf->done)) {
22032+ psb_xhw_clean_buf(dev_priv, buf);
22033+ return -EBUSY;
22034+ }
22035+
22036+ return xa->ret;
22037+}
22038+
22039+int psb_xhw_check_lockup(struct drm_psb_private *dev_priv,
22040+ struct psb_xhw_buf *buf, uint32_t * value)
22041+{
22042+ struct drm_psb_xhw_arg *xa = &buf->arg;
22043+ int ret;
22044+
22045+ *value = 0;
22046+
22047+ buf->copy_back = 1;
22048+ xa->op = PSB_XHW_CHECK_LOCKUP;
22049+ xa->issue_irq = 0;
22050+ xa->irq_op = 0;
22051+
22052+ ret = psb_xhw_add(dev_priv, buf);
22053+ if (ret)
22054+ return ret;
22055+
22056+ (void)wait_event_timeout(dev_priv->xhw_caller_queue,
22057+ atomic_read(&buf->done), DRM_HZ * 3);
22058+
22059+ if (!atomic_read(&buf->done)) {
22060+ psb_xhw_clean_buf(dev_priv, buf);
22061+ return -EBUSY;
22062+ }
22063+
22064+ if (!xa->ret)
22065+ *value = xa->arg.cl.value;
22066+
22067+ return xa->ret;
22068+}
22069+
22070+static int psb_xhw_terminate(struct drm_psb_private *dev_priv,
22071+ struct psb_xhw_buf *buf)
22072+{
22073+ struct drm_psb_xhw_arg *xa = &buf->arg;
22074+ unsigned long irq_flags;
22075+
22076+ buf->copy_back = 0;
22077+ xa->op = PSB_XHW_TERMINATE;
22078+ xa->issue_irq = 0;
22079+
22080+ spin_lock_irqsave(&dev_priv->xhw_lock, irq_flags);
22081+ dev_priv->xhw_submit_ok = 0;
22082+ atomic_set(&buf->done, 0);
22083+ if (!list_empty(&buf->head)) {
22084+ DRM_ERROR("Recursive list adding.\n");
22085+ goto out;
22086+ }
22087+ list_add_tail(&buf->head, &dev_priv->xhw_in);
22088+ out:
22089+ spin_unlock_irqrestore(&dev_priv->xhw_lock, irq_flags);
22090+ wake_up_interruptible(&dev_priv->xhw_queue);
22091+
22092+ (void)wait_event_timeout(dev_priv->xhw_caller_queue,
22093+ atomic_read(&buf->done), DRM_HZ / 10);
22094+
22095+ if (!atomic_read(&buf->done)) {
22096+ DRM_ERROR("Xpsb terminate timeout.\n");
22097+ psb_xhw_clean_buf(dev_priv, buf);
22098+ return -EBUSY;
22099+ }
22100+
22101+ return 0;
22102+}
22103+
22104+int psb_xhw_ta_mem_info(struct drm_psb_private *dev_priv,
22105+ struct psb_xhw_buf *buf,
22106+ uint32_t pages, uint32_t * hw_cookie, uint32_t * size)
22107+{
22108+ struct drm_psb_xhw_arg *xa = &buf->arg;
22109+ int ret;
22110+
22111+ buf->copy_back = 1;
22112+ xa->op = PSB_XHW_TA_MEM_INFO;
22113+ xa->issue_irq = 0;
22114+ xa->irq_op = 0;
22115+ xa->arg.bi.pages = pages;
22116+
22117+ ret = psb_xhw_add(dev_priv, buf);
22118+ if (ret)
22119+ return ret;
22120+
22121+ (void)wait_event_timeout(dev_priv->xhw_caller_queue,
22122+ atomic_read(&buf->done), DRM_HZ);
22123+
22124+ if (!atomic_read(&buf->done)) {
22125+ psb_xhw_clean_buf(dev_priv, buf);
22126+ return -EBUSY;
22127+ }
22128+
22129+ if (!xa->ret)
22130+ memcpy(hw_cookie, xa->cookie, sizeof(xa->cookie));
22131+
22132+ *size = xa->arg.bi.size;
22133+ return xa->ret;
22134+}
22135+
22136+int psb_xhw_ta_mem_load(struct drm_psb_private *dev_priv,
22137+ struct psb_xhw_buf *buf,
22138+ uint32_t flags,
22139+ uint32_t param_offset,
22140+ uint32_t pt_offset, uint32_t * hw_cookie)
22141+{
22142+ struct drm_psb_xhw_arg *xa = &buf->arg;
22143+ int ret;
22144+
22145+ buf->copy_back = 1;
22146+ xa->op = PSB_XHW_TA_MEM_LOAD;
22147+ xa->issue_irq = 0;
22148+ xa->irq_op = 0;
22149+ xa->arg.bl.flags = flags;
22150+ xa->arg.bl.param_offset = param_offset;
22151+ xa->arg.bl.pt_offset = pt_offset;
22152+ memcpy(xa->cookie, hw_cookie, sizeof(xa->cookie));
22153+
22154+ ret = psb_xhw_add(dev_priv, buf);
22155+ if (ret)
22156+ return ret;
22157+
22158+ (void)wait_event_timeout(dev_priv->xhw_caller_queue,
22159+ atomic_read(&buf->done), 3 * DRM_HZ);
22160+
22161+ if (!atomic_read(&buf->done)) {
22162+ psb_xhw_clean_buf(dev_priv, buf);
22163+ return -EBUSY;
22164+ }
22165+
22166+ if (!xa->ret)
22167+ memcpy(hw_cookie, xa->cookie, sizeof(xa->cookie));
22168+
22169+ return xa->ret;
22170+}
22171+
22172+int psb_xhw_ta_oom(struct drm_psb_private *dev_priv,
22173+ struct psb_xhw_buf *buf, uint32_t * cookie)
22174+{
22175+ struct drm_psb_xhw_arg *xa = &buf->arg;
22176+
22177+ /*
22178+ * This calls the extensive closed source
22179+ * OOM handler, which resolves the condition and
22180+ * sends a reply telling the scheduler what to do
22181+ * with the task.
22182+ */
22183+
22184+ buf->copy_back = 1;
22185+ xa->op = PSB_XHW_OOM;
22186+ xa->issue_irq = 1;
22187+ xa->irq_op = PSB_UIRQ_OOM_REPLY;
22188+ memcpy(xa->cookie, cookie, sizeof(xa->cookie));
22189+
22190+ return psb_xhw_add(dev_priv, buf);
22191+}
22192+
22193+void psb_xhw_ta_oom_reply(struct drm_psb_private *dev_priv,
22194+ struct psb_xhw_buf *buf,
22195+ uint32_t * cookie,
22196+ uint32_t * bca, uint32_t * rca, uint32_t * flags)
22197+{
22198+ struct drm_psb_xhw_arg *xa = &buf->arg;
22199+
22200+ /*
22201+ * Get info about how to schedule an OOM task.
22202+ */
22203+
22204+ memcpy(cookie, xa->cookie, sizeof(xa->cookie));
22205+ *bca = xa->arg.oom.bca;
22206+ *rca = xa->arg.oom.rca;
22207+ *flags = xa->arg.oom.flags;
22208+}
22209+
22210+void psb_xhw_fire_reply(struct drm_psb_private *dev_priv,
22211+ struct psb_xhw_buf *buf, uint32_t * cookie)
22212+{
22213+ struct drm_psb_xhw_arg *xa = &buf->arg;
22214+
22215+ memcpy(cookie, xa->cookie, sizeof(xa->cookie));
22216+}
22217+
22218+int psb_xhw_resume(struct drm_psb_private *dev_priv, struct psb_xhw_buf *buf)
22219+{
22220+ struct drm_psb_xhw_arg *xa = &buf->arg;
22221+
22222+ buf->copy_back = 0;
22223+ xa->op = PSB_XHW_RESUME;
22224+ xa->issue_irq = 0;
22225+ xa->irq_op = 0;
22226+ return psb_xhw_add(dev_priv, buf);
22227+}
22228+
22229+void psb_xhw_takedown(struct drm_psb_private *dev_priv)
22230+{
22231+}
22232+
22233+int psb_xhw_init(struct drm_device *dev)
22234+{
22235+ struct drm_psb_private *dev_priv =
22236+ (struct drm_psb_private *)dev->dev_private;
22237+ unsigned long irq_flags;
22238+
22239+ INIT_LIST_HEAD(&dev_priv->xhw_in);
22240+ dev_priv->xhw_lock = SPIN_LOCK_UNLOCKED;
22241+ atomic_set(&dev_priv->xhw_client, 0);
22242+ init_waitqueue_head(&dev_priv->xhw_queue);
22243+ init_waitqueue_head(&dev_priv->xhw_caller_queue);
22244+ mutex_init(&dev_priv->xhw_mutex);
22245+ spin_lock_irqsave(&dev_priv->xhw_lock, irq_flags);
22246+ dev_priv->xhw_on = 0;
22247+ spin_unlock_irqrestore(&dev_priv->xhw_lock, irq_flags);
22248+
22249+ return 0;
22250+}
22251+
22252+static int psb_xhw_init_init(struct drm_device *dev,
22253+ struct drm_file *file_priv,
22254+ struct drm_psb_xhw_init_arg *arg)
22255+{
22256+ struct drm_psb_private *dev_priv =
22257+ (struct drm_psb_private *)dev->dev_private;
22258+ int ret;
22259+ int is_iomem;
22260+
22261+ if (atomic_add_unless(&dev_priv->xhw_client, 1, 1)) {
22262+ unsigned long irq_flags;
22263+
22264+ mutex_lock(&dev->struct_mutex);
22265+ dev_priv->xhw_bo =
22266+ drm_lookup_buffer_object(file_priv, arg->buffer_handle, 1);
22267+ mutex_unlock(&dev->struct_mutex);
22268+ if (!dev_priv->xhw_bo) {
22269+ ret = -EINVAL;
22270+ goto out_err;
22271+ }
22272+ ret = drm_bo_kmap(dev_priv->xhw_bo, 0,
22273+ dev_priv->xhw_bo->num_pages,
22274+ &dev_priv->xhw_kmap);
22275+ if (ret) {
22276+ DRM_ERROR("Failed mapping X server "
22277+ "communications buffer.\n");
22278+ goto out_err0;
22279+ }
22280+ dev_priv->xhw = drm_bmo_virtual(&dev_priv->xhw_kmap, &is_iomem);
22281+ if (is_iomem) {
22282+ DRM_ERROR("X server communications buffer"
22283+ "is in device memory.\n");
22284+ ret = -EINVAL;
22285+ goto out_err1;
22286+ }
22287+ dev_priv->xhw_file = file_priv;
22288+
22289+ spin_lock_irqsave(&dev_priv->xhw_lock, irq_flags);
22290+ dev_priv->xhw_on = 1;
22291+ dev_priv->xhw_submit_ok = 1;
22292+ spin_unlock_irqrestore(&dev_priv->xhw_lock, irq_flags);
22293+ return 0;
22294+ } else {
22295+ DRM_ERROR("Xhw is already initialized.\n");
22296+ return -EBUSY;
22297+ }
22298+ out_err1:
22299+ dev_priv->xhw = NULL;
22300+ drm_bo_kunmap(&dev_priv->xhw_kmap);
22301+ out_err0:
22302+ drm_bo_usage_deref_unlocked(&dev_priv->xhw_bo);
22303+ out_err:
22304+ atomic_dec(&dev_priv->xhw_client);
22305+ return ret;
22306+}
22307+
22308+static void psb_xhw_queue_empty(struct drm_psb_private *dev_priv)
22309+{
22310+ struct psb_xhw_buf *cur_buf, *next;
22311+ unsigned long irq_flags;
22312+
22313+ spin_lock_irqsave(&dev_priv->xhw_lock, irq_flags);
22314+ dev_priv->xhw_submit_ok = 0;
22315+
22316+ list_for_each_entry_safe(cur_buf, next, &dev_priv->xhw_in, head) {
22317+ list_del_init(&cur_buf->head);
22318+ if (cur_buf->copy_back) {
22319+ cur_buf->arg.ret = -EINVAL;
22320+ }
22321+ atomic_set(&cur_buf->done, 1);
22322+ }
22323+ spin_unlock_irqrestore(&dev_priv->xhw_lock, irq_flags);
22324+ wake_up(&dev_priv->xhw_caller_queue);
22325+}
22326+
22327+void psb_xhw_init_takedown(struct drm_psb_private *dev_priv,
22328+ struct drm_file *file_priv, int closing)
22329+{
22330+
22331+ if (dev_priv->xhw_file == file_priv &&
22332+ atomic_add_unless(&dev_priv->xhw_client, -1, 0)) {
22333+
22334+ if (closing)
22335+ psb_xhw_queue_empty(dev_priv);
22336+ else {
22337+ struct psb_xhw_buf buf;
22338+ INIT_LIST_HEAD(&buf.head);
22339+
22340+ psb_xhw_terminate(dev_priv, &buf);
22341+ psb_xhw_queue_empty(dev_priv);
22342+ }
22343+
22344+ dev_priv->xhw = NULL;
22345+ drm_bo_kunmap(&dev_priv->xhw_kmap);
22346+ drm_bo_usage_deref_unlocked(&dev_priv->xhw_bo);
22347+ dev_priv->xhw_file = NULL;
22348+ }
22349+}
22350+
22351+int psb_xhw_init_ioctl(struct drm_device *dev, void *data,
22352+ struct drm_file *file_priv)
22353+{
22354+ struct drm_psb_xhw_init_arg *arg = (struct drm_psb_xhw_init_arg *)data;
22355+ struct drm_psb_private *dev_priv =
22356+ (struct drm_psb_private *)dev->dev_private;
22357+
22358+ switch (arg->operation) {
22359+ case PSB_XHW_INIT:
22360+ return psb_xhw_init_init(dev, file_priv, arg);
22361+ case PSB_XHW_TAKEDOWN:
22362+ psb_xhw_init_takedown(dev_priv, file_priv, 0);
22363+ }
22364+ return 0;
22365+}
22366+
22367+static int psb_xhw_in_empty(struct drm_psb_private *dev_priv)
22368+{
22369+ int empty;
22370+ unsigned long irq_flags;
22371+
22372+ spin_lock_irqsave(&dev_priv->xhw_lock, irq_flags);
22373+ empty = list_empty(&dev_priv->xhw_in);
22374+ spin_unlock_irqrestore(&dev_priv->xhw_lock, irq_flags);
22375+ return empty;
22376+}
22377+
22378+int psb_xhw_handler(struct drm_psb_private *dev_priv)
22379+{
22380+ unsigned long irq_flags;
22381+ struct drm_psb_xhw_arg *xa;
22382+ struct psb_xhw_buf *buf;
22383+
22384+ spin_lock_irqsave(&dev_priv->xhw_lock, irq_flags);
22385+
22386+ if (!dev_priv->xhw_on) {
22387+ spin_unlock_irqrestore(&dev_priv->xhw_lock, irq_flags);
22388+ return -EINVAL;
22389+ }
22390+
22391+ buf = dev_priv->xhw_cur_buf;
22392+ if (buf && buf->copy_back) {
22393+ xa = &buf->arg;
22394+ memcpy(xa, dev_priv->xhw, sizeof(*xa));
22395+ dev_priv->comm[PSB_COMM_USER_IRQ] = xa->irq_op;
22396+ atomic_set(&buf->done, 1);
22397+ wake_up(&dev_priv->xhw_caller_queue);
22398+ } else
22399+ dev_priv->comm[PSB_COMM_USER_IRQ] = 0;
22400+
22401+ dev_priv->xhw_cur_buf = 0;
22402+ spin_unlock_irqrestore(&dev_priv->xhw_lock, irq_flags);
22403+ return 0;
22404+}
22405+
22406+int psb_xhw_ioctl(struct drm_device *dev, void *data,
22407+ struct drm_file *file_priv)
22408+{
22409+ struct drm_psb_private *dev_priv =
22410+ (struct drm_psb_private *)dev->dev_private;
22411+ unsigned long irq_flags;
22412+ struct drm_psb_xhw_arg *xa;
22413+ int ret;
22414+ struct list_head *list;
22415+ struct psb_xhw_buf *buf;
22416+
22417+ if (!dev_priv)
22418+ return -EINVAL;
22419+
22420+ if (mutex_lock_interruptible(&dev_priv->xhw_mutex))
22421+ return -EAGAIN;
22422+
22423+ if (psb_forced_user_interrupt(dev_priv)) {
22424+ mutex_unlock(&dev_priv->xhw_mutex);
22425+ return -EINVAL;
22426+ }
22427+
22428+ spin_lock_irqsave(&dev_priv->xhw_lock, irq_flags);
22429+ while (list_empty(&dev_priv->xhw_in)) {
22430+ spin_unlock_irqrestore(&dev_priv->xhw_lock, irq_flags);
22431+ ret = wait_event_interruptible_timeout(dev_priv->xhw_queue,
22432+ !psb_xhw_in_empty
22433+ (dev_priv), DRM_HZ);
22434+ if (ret == -ERESTARTSYS || ret == 0) {
22435+ mutex_unlock(&dev_priv->xhw_mutex);
22436+ return -EAGAIN;
22437+ }
22438+ spin_lock_irqsave(&dev_priv->xhw_lock, irq_flags);
22439+ }
22440+
22441+ list = dev_priv->xhw_in.next;
22442+ list_del_init(list);
22443+
22444+ buf = list_entry(list, struct psb_xhw_buf, head);
22445+ xa = &buf->arg;
22446+ memcpy(dev_priv->xhw, xa, sizeof(*xa));
22447+
22448+ if (unlikely(buf->copy_back))
22449+ dev_priv->xhw_cur_buf = buf;
22450+ else {
22451+ atomic_set(&buf->done, 1);
22452+ dev_priv->xhw_cur_buf = NULL;
22453+ }
22454+
22455+ if (xa->op == PSB_XHW_TERMINATE) {
22456+ dev_priv->xhw_on = 0;
22457+ wake_up(&dev_priv->xhw_caller_queue);
22458+ }
22459+ spin_unlock_irqrestore(&dev_priv->xhw_lock, irq_flags);
22460+
22461+ mutex_unlock(&dev_priv->xhw_mutex);
22462+
22463+ return 0;
22464+}
22465Index: linux-2.6.28/drivers/gpu/drm/Kconfig
22466===================================================================
22467--- linux-2.6.28.orig/drivers/gpu/drm/Kconfig 2009-02-12 09:14:37.000000000 +0000
22468+++ linux-2.6.28/drivers/gpu/drm/Kconfig 2009-02-12 09:14:42.000000000 +0000
22469@@ -123,3 +123,9 @@
22470 help
22471 Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
22472 chipset. If M is selected the module will be called savage.
22473+
22474+config DRM_PSB
22475+ tristate "Intel Poulsbo"
22476+ depends on DRM && PCI && I2C_ALGOBIT
22477+ help
22478+ Choose this option if you have an Intel Poulsbo chipset.
22479Index: linux-2.6.28/include/drm/drm_objects.h
22480===================================================================
22481--- /dev/null 1970-01-01 00:00:00.000000000 +0000
22482+++ linux-2.6.28/include/drm/drm_objects.h 2009-02-12 09:14:42.000000000 +0000
22483@@ -0,0 +1,717 @@
22484+/**************************************************************************
22485+ *
22486+ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
22487+ * All Rights Reserved.
22488+ *
22489+ * Permission is hereby granted, free of charge, to any person obtaining a
22490+ * copy of this software and associated documentation files (the
22491+ * "Software"), to deal in the Software without restriction, including
22492+ * without limitation the rights to use, copy, modify, merge, publish,
22493+ * distribute, sub license, and/or sell copies of the Software, and to
22494+ * permit persons to whom the Software is furnished to do so, subject to
22495+ * the following conditions:
22496+ *
22497+ * The above copyright notice and this permission notice (including the
22498+ * next paragraph) shall be included in all copies or substantial portions
22499+ * of the Software.
22500+ *
22501+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22502+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22503+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22504+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22505+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22506+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22507+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
22508+ *
22509+ **************************************************************************/
22510+/*
22511+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
22512+ */
22513+
22514+#ifndef _DRM_OBJECTS_H
22515+#define _DRM_OBJECTS_H
22516+
22517+struct drm_device;
22518+struct drm_bo_mem_reg;
22519+
22520+/***************************************************
22521+ * User space objects. (drm_object.c)
22522+ */
22523+
22524+#define drm_user_object_entry(_ptr, _type, _member) container_of(_ptr, _type, _member)
22525+
22526+enum drm_object_type {
22527+ drm_fence_type,
22528+ drm_buffer_type,
22529+ drm_lock_type,
22530+ /*
22531+ * Add other user space object types here.
22532+ */
22533+ drm_driver_type0 = 256,
22534+ drm_driver_type1,
22535+ drm_driver_type2,
22536+ drm_driver_type3,
22537+ drm_driver_type4
22538+};
22539+
22540+/*
22541+ * A user object is a structure that helps the drm give out user handles
22542+ * to kernel internal objects and to keep track of these objects so that
22543+ * they can be destroyed, for example when the user space process exits.
22544+ * Designed to be accessible using a user space 32-bit handle.
22545+ */
22546+
22547+struct drm_user_object {
22548+ struct drm_hash_item hash;
22549+ struct list_head list;
22550+ enum drm_object_type type;
22551+ atomic_t refcount;
22552+ int shareable;
22553+ struct drm_file *owner;
22554+ void (*ref_struct_locked) (struct drm_file *priv,
22555+ struct drm_user_object *obj,
22556+ enum drm_ref_type ref_action);
22557+ void (*unref) (struct drm_file *priv, struct drm_user_object *obj,
22558+ enum drm_ref_type unref_action);
22559+ void (*remove) (struct drm_file *priv, struct drm_user_object *obj);
22560+};
22561+
22562+/*
22563+ * A ref object is a structure which is used to
22564+ * keep track of references to user objects and to keep track of these
22565+ * references so that they can be destroyed for example when the user space
22566+ * process exits. Designed to be accessible using a pointer to the _user_ object.
22567+ */
22568+
22569+struct drm_ref_object {
22570+ struct drm_hash_item hash;
22571+ struct list_head list;
22572+ atomic_t refcount;
22573+ enum drm_ref_type unref_action;
22574+};
22575+
22576+/**
22577+ * Must be called with the struct_mutex held.
22578+ */
22579+
22580+extern int drm_add_user_object(struct drm_file *priv, struct drm_user_object *item,
22581+ int shareable);
22582+/**
22583+ * Must be called with the struct_mutex held.
22584+ */
22585+
22586+extern struct drm_user_object *drm_lookup_user_object(struct drm_file *priv,
22587+ uint32_t key);
22588+
22589+/*
22590+ * Must be called with the struct_mutex held. May temporarily release it.
22591+ */
22592+
22593+extern int drm_add_ref_object(struct drm_file *priv,
22594+ struct drm_user_object *referenced_object,
22595+ enum drm_ref_type ref_action);
22596+
22597+/*
22598+ * Must be called with the struct_mutex held.
22599+ */
22600+
22601+struct drm_ref_object *drm_lookup_ref_object(struct drm_file *priv,
22602+ struct drm_user_object *referenced_object,
22603+ enum drm_ref_type ref_action);
22604+/*
22605+ * Must be called with the struct_mutex held.
22606+ * If "item" has been obtained by a call to drm_lookup_ref_object. You may not
22607+ * release the struct_mutex before calling drm_remove_ref_object.
22608+ * This function may temporarily release the struct_mutex.
22609+ */
22610+
22611+extern void drm_remove_ref_object(struct drm_file *priv, struct drm_ref_object *item);
22612+extern int drm_user_object_ref(struct drm_file *priv, uint32_t user_token,
22613+ enum drm_object_type type,
22614+ struct drm_user_object **object);
22615+extern int drm_user_object_unref(struct drm_file *priv, uint32_t user_token,
22616+ enum drm_object_type type);
22617+
22618+/***************************************************
22619+ * Fence objects. (drm_fence.c)
22620+ */
22621+
22622+struct drm_fence_object {
22623+ struct drm_user_object base;
22624+ struct drm_device *dev;
22625+ atomic_t usage;
22626+
22627+ /*
22628+ * The below three fields are protected by the fence manager spinlock.
22629+ */
22630+
22631+ struct list_head ring;
22632+ int fence_class;
22633+ uint32_t native_types;
22634+ uint32_t type;
22635+ uint32_t signaled_types;
22636+ uint32_t sequence;
22637+ uint32_t waiting_types;
22638+ uint32_t error;
22639+};
22640+
22641+#define _DRM_FENCE_CLASSES 8
22642+
22643+struct drm_fence_class_manager {
22644+ struct list_head ring;
22645+ uint32_t pending_flush;
22646+ uint32_t waiting_types;
22647+ wait_queue_head_t fence_queue;
22648+ uint32_t highest_waiting_sequence;
22649+ uint32_t latest_queued_sequence;
22650+};
22651+
22652+struct drm_fence_manager {
22653+ int initialized;
22654+ rwlock_t lock;
22655+ struct drm_fence_class_manager fence_class[_DRM_FENCE_CLASSES];
22656+ uint32_t num_classes;
22657+ atomic_t count;
22658+};
22659+
22660+struct drm_fence_driver {
22661+ unsigned long *waiting_jiffies;
22662+ uint32_t num_classes;
22663+ uint32_t wrap_diff;
22664+ uint32_t flush_diff;
22665+ uint32_t sequence_mask;
22666+
22667+ /*
22668+ * Driver implemented functions:
22669+ * has_irq() : 1 if the hardware can update the indicated type_flags using an
22670+ * irq handler. 0 if polling is required.
22671+ *
22672+ * emit() : Emit a sequence number to the command stream.
22673+ * Return the sequence number.
22674+ *
22675+ * flush() : Make sure the flags indicated in fc->pending_flush will eventually
22676+ * signal for fc->highest_received_sequence and all preceding sequences.
22677+ * Acknowledge by clearing the flags fc->pending_flush.
22678+ *
22679+ * poll() : Call drm_fence_handler with any new information.
22680+ *
22681+ * needed_flush() : Given the current state of the fence->type flags and previusly
22682+ * executed or queued flushes, return the type_flags that need flushing.
22683+ *
22684+ * wait(): Wait for the "mask" flags to signal on a given fence, performing
22685+ * whatever's necessary to make this happen.
22686+ */
22687+
22688+ int (*has_irq) (struct drm_device *dev, uint32_t fence_class,
22689+ uint32_t flags);
22690+ int (*emit) (struct drm_device *dev, uint32_t fence_class,
22691+ uint32_t flags, uint32_t *breadcrumb,
22692+ uint32_t *native_type);
22693+ void (*flush) (struct drm_device *dev, uint32_t fence_class);
22694+ void (*poll) (struct drm_device *dev, uint32_t fence_class,
22695+ uint32_t types);
22696+ uint32_t (*needed_flush) (struct drm_fence_object *fence);
22697+ int (*wait) (struct drm_fence_object *fence, int lazy,
22698+ int interruptible, uint32_t mask);
22699+};
22700+
22701+extern int drm_fence_wait_polling(struct drm_fence_object *fence, int lazy,
22702+ int interruptible, uint32_t mask,
22703+ unsigned long end_jiffies);
22704+extern void drm_fence_handler(struct drm_device *dev, uint32_t fence_class,
22705+ uint32_t sequence, uint32_t type,
22706+ uint32_t error);
22707+extern void drm_fence_manager_init(struct drm_device *dev);
22708+extern void drm_fence_manager_takedown(struct drm_device *dev);
22709+extern void drm_fence_flush_old(struct drm_device *dev, uint32_t fence_class,
22710+ uint32_t sequence);
22711+extern int drm_fence_object_flush(struct drm_fence_object *fence,
22712+ uint32_t type);
22713+extern int drm_fence_object_signaled(struct drm_fence_object *fence,
22714+ uint32_t type);
22715+extern void drm_fence_usage_deref_locked(struct drm_fence_object **fence);
22716+extern void drm_fence_usage_deref_unlocked(struct drm_fence_object **fence);
22717+extern struct drm_fence_object *drm_fence_reference_locked(struct drm_fence_object *src);
22718+extern void drm_fence_reference_unlocked(struct drm_fence_object **dst,
22719+ struct drm_fence_object *src);
22720+extern int drm_fence_object_wait(struct drm_fence_object *fence,
22721+ int lazy, int ignore_signals, uint32_t mask);
22722+extern int drm_fence_object_create(struct drm_device *dev, uint32_t type,
22723+ uint32_t fence_flags, uint32_t fence_class,
22724+ struct drm_fence_object **c_fence);
22725+extern int drm_fence_object_emit(struct drm_fence_object *fence,
22726+ uint32_t fence_flags, uint32_t class,
22727+ uint32_t type);
22728+extern void drm_fence_fill_arg(struct drm_fence_object *fence,
22729+ struct drm_fence_arg *arg);
22730+
22731+extern int drm_fence_add_user_object(struct drm_file *priv,
22732+ struct drm_fence_object *fence,
22733+ int shareable);
22734+
22735+extern int drm_fence_create_ioctl(struct drm_device *dev, void *data,
22736+ struct drm_file *file_priv);
22737+extern int drm_fence_destroy_ioctl(struct drm_device *dev, void *data,
22738+ struct drm_file *file_priv);
22739+extern int drm_fence_reference_ioctl(struct drm_device *dev, void *data,
22740+ struct drm_file *file_priv);
22741+extern int drm_fence_unreference_ioctl(struct drm_device *dev, void *data,
22742+ struct drm_file *file_priv);
22743+extern int drm_fence_signaled_ioctl(struct drm_device *dev, void *data,
22744+ struct drm_file *file_priv);
22745+extern int drm_fence_flush_ioctl(struct drm_device *dev, void *data,
22746+ struct drm_file *file_priv);
22747+extern int drm_fence_wait_ioctl(struct drm_device *dev, void *data,
22748+ struct drm_file *file_priv);
22749+extern int drm_fence_emit_ioctl(struct drm_device *dev, void *data,
22750+ struct drm_file *file_priv);
22751+extern int drm_fence_buffers_ioctl(struct drm_device *dev, void *data,
22752+ struct drm_file *file_priv);
22753+/**************************************************
22754+ *TTMs
22755+ */
22756+
22757+/*
22758+ * The ttm backend GTT interface. (In our case AGP).
22759+ * Any similar type of device (PCIE?)
22760+ * needs only to implement these functions to be usable with the TTM interface.
22761+ * The AGP backend implementation lives in drm_agpsupport.c
22762+ * basically maps these calls to available functions in agpgart.
22763+ * Each drm device driver gets an
22764+ * additional function pointer that creates these types,
22765+ * so that the device can choose the correct aperture.
22766+ * (Multiple AGP apertures, etc.)
22767+ * Most device drivers will let this point to the standard AGP implementation.
22768+ */
22769+
22770+#define DRM_BE_FLAG_NEEDS_FREE 0x00000001
22771+#define DRM_BE_FLAG_BOUND_CACHED 0x00000002
22772+
22773+struct drm_ttm_backend;
22774+struct drm_ttm_backend_func {
22775+ int (*needs_ub_cache_adjust) (struct drm_ttm_backend *backend);
22776+ int (*populate) (struct drm_ttm_backend *backend,
22777+ unsigned long num_pages, struct page **pages);
22778+ void (*clear) (struct drm_ttm_backend *backend);
22779+ int (*bind) (struct drm_ttm_backend *backend,
22780+ struct drm_bo_mem_reg *bo_mem);
22781+ int (*unbind) (struct drm_ttm_backend *backend);
22782+ void (*destroy) (struct drm_ttm_backend *backend);
22783+};
22784+
22785+
22786+struct drm_ttm_backend {
22787+ struct drm_device *dev;
22788+ uint32_t flags;
22789+ struct drm_ttm_backend_func *func;
22790+};
22791+
22792+struct drm_ttm {
22793+ struct page *dummy_read_page;
22794+ struct page **pages;
22795+ uint32_t page_flags;
22796+ unsigned long num_pages;
22797+ atomic_t vma_count;
22798+ struct drm_device *dev;
22799+ int destroy;
22800+ uint32_t mapping_offset;
22801+ struct drm_ttm_backend *be;
22802+ enum {
22803+ ttm_bound,
22804+ ttm_evicted,
22805+ ttm_unbound,
22806+ ttm_unpopulated,
22807+ } state;
22808+
22809+};
22810+
22811+extern struct drm_ttm *drm_ttm_init(struct drm_device *dev, unsigned long size);
22812+extern int drm_bind_ttm(struct drm_ttm *ttm, struct drm_bo_mem_reg *bo_mem);
22813+extern void drm_ttm_unbind(struct drm_ttm *ttm);
22814+extern void drm_ttm_evict(struct drm_ttm *ttm);
22815+extern void drm_ttm_fixup_caching(struct drm_ttm *ttm);
22816+extern struct page *drm_ttm_get_page(struct drm_ttm *ttm, int index);
22817+extern void drm_ttm_cache_flush(void);
22818+extern int drm_ttm_populate(struct drm_ttm *ttm);
22819+extern int drm_ttm_set_user(struct drm_ttm *ttm,
22820+ struct task_struct *tsk,
22821+ int write,
22822+ unsigned long start,
22823+ unsigned long num_pages,
22824+ struct page *dummy_read_page);
22825+unsigned long drm_ttm_size(struct drm_device *dev,
22826+ unsigned long num_pages,
22827+ int user_bo);
22828+
22829+
22830+/*
22831+ * Destroy a ttm. The user normally calls drmRmMap or a similar IOCTL to do
22832+ * this which calls this function iff there are no vmas referencing it anymore.
22833+ * Otherwise it is called when the last vma exits.
22834+ */
22835+
22836+extern int drm_destroy_ttm(struct drm_ttm *ttm);
22837+
22838+#define DRM_FLAG_MASKED(_old, _new, _mask) {\
22839+(_old) ^= (((_old) ^ (_new)) & (_mask)); \
22840+}
22841+
22842+#define DRM_TTM_MASK_FLAGS ((1 << PAGE_SHIFT) - 1)
22843+#define DRM_TTM_MASK_PFN (0xFFFFFFFFU - DRM_TTM_MASK_FLAGS)
22844+
22845+/*
22846+ * Page flags.
22847+ */
22848+
22849+#define DRM_TTM_PAGE_UNCACHED (1 << 0)
22850+#define DRM_TTM_PAGE_USED (1 << 1)
22851+#define DRM_TTM_PAGE_BOUND (1 << 2)
22852+#define DRM_TTM_PAGE_PRESENT (1 << 3)
22853+#define DRM_TTM_PAGE_VMALLOC (1 << 4)
22854+#define DRM_TTM_PAGE_USER (1 << 5)
22855+#define DRM_TTM_PAGE_USER_WRITE (1 << 6)
22856+#define DRM_TTM_PAGE_USER_DIRTY (1 << 7)
22857+#define DRM_TTM_PAGE_USER_DMA (1 << 8)
22858+
22859+/***************************************************
22860+ * Buffer objects. (drm_bo.c, drm_bo_move.c)
22861+ */
22862+
22863+struct drm_bo_mem_reg {
22864+ struct drm_mm_node *mm_node;
22865+ unsigned long size;
22866+ unsigned long num_pages;
22867+ uint32_t page_alignment;
22868+ uint32_t mem_type;
22869+ uint64_t flags;
22870+ uint64_t mask;
22871+ uint32_t desired_tile_stride;
22872+ uint32_t hw_tile_stride;
22873+};
22874+
22875+enum drm_bo_type {
22876+ drm_bo_type_dc,
22877+ drm_bo_type_user,
22878+ drm_bo_type_kernel, /* for initial kernel allocations */
22879+};
22880+
22881+struct drm_buffer_object {
22882+ struct drm_device *dev;
22883+ struct drm_user_object base;
22884+
22885+ /*
22886+ * If there is a possibility that the usage variable is zero,
22887+ * then dev->struct_mutext should be locked before incrementing it.
22888+ */
22889+
22890+ atomic_t usage;
22891+ unsigned long buffer_start;
22892+ enum drm_bo_type type;
22893+ unsigned long offset;
22894+ atomic_t mapped;
22895+ struct drm_bo_mem_reg mem;
22896+
22897+ struct list_head lru;
22898+ struct list_head ddestroy;
22899+
22900+ uint32_t fence_type;
22901+ uint32_t fence_class;
22902+ uint32_t new_fence_type;
22903+ uint32_t new_fence_class;
22904+ struct drm_fence_object *fence;
22905+ uint32_t priv_flags;
22906+ wait_queue_head_t event_queue;
22907+ struct mutex mutex;
22908+ unsigned long num_pages;
22909+ unsigned long reserved_size;
22910+
22911+ /* For pinned buffers */
22912+ struct drm_mm_node *pinned_node;
22913+ uint32_t pinned_mem_type;
22914+ struct list_head pinned_lru;
22915+
22916+ /* For vm */
22917+ struct drm_ttm *ttm;
22918+ struct drm_map_list map_list;
22919+ uint32_t memory_type;
22920+ unsigned long bus_offset;
22921+ uint32_t vm_flags;
22922+ void *iomap;
22923+
22924+#ifdef DRM_ODD_MM_COMPAT
22925+ /* dev->struct_mutex only protected. */
22926+ struct list_head vma_list;
22927+ struct list_head p_mm_list;
22928+#endif
22929+
22930+};
22931+
22932+#define _DRM_BO_FLAG_UNFENCED 0x00000001
22933+#define _DRM_BO_FLAG_EVICTED 0x00000002
22934+
22935+struct drm_mem_type_manager {
22936+ int has_type;
22937+ int use_type;
22938+ struct drm_mm manager;
22939+ struct list_head lru;
22940+ struct list_head pinned;
22941+ uint32_t flags;
22942+ uint32_t drm_bus_maptype;
22943+ unsigned long gpu_offset;
22944+ unsigned long io_offset;
22945+ unsigned long io_size;
22946+ void *io_addr;
22947+};
22948+
22949+struct drm_bo_lock {
22950+ struct drm_user_object base;
22951+ wait_queue_head_t queue;
22952+ atomic_t write_lock_pending;
22953+ atomic_t readers;
22954+};
22955+
22956+#define _DRM_FLAG_MEMTYPE_FIXED 0x00000001 /* Fixed (on-card) PCI memory */
22957+#define _DRM_FLAG_MEMTYPE_MAPPABLE 0x00000002 /* Memory mappable */
22958+#define _DRM_FLAG_MEMTYPE_CACHED 0x00000004 /* Cached binding */
22959+#define _DRM_FLAG_NEEDS_IOREMAP 0x00000008 /* Fixed memory needs ioremap
22960+ before kernel access. */
22961+#define _DRM_FLAG_MEMTYPE_CMA 0x00000010 /* Can't map aperture */
22962+#define _DRM_FLAG_MEMTYPE_CSELECT 0x00000020 /* Select caching */
22963+
22964+struct drm_buffer_manager {
22965+ struct drm_bo_lock bm_lock;
22966+ struct mutex evict_mutex;
22967+ int nice_mode;
22968+ int initialized;
22969+ struct drm_file *last_to_validate;
22970+ struct drm_mem_type_manager man[DRM_BO_MEM_TYPES];
22971+ struct list_head unfenced;
22972+ struct list_head ddestroy;
22973+ struct delayed_work wq;
22974+ uint32_t fence_type;
22975+ unsigned long cur_pages;
22976+ atomic_t count;
22977+ struct page *dummy_read_page;
22978+};
22979+
22980+struct drm_bo_driver {
22981+ const uint32_t *mem_type_prio;
22982+ const uint32_t *mem_busy_prio;
22983+ uint32_t num_mem_type_prio;
22984+ uint32_t num_mem_busy_prio;
22985+ struct drm_ttm_backend *(*create_ttm_backend_entry)
22986+ (struct drm_device *dev);
22987+ int (*backend_size) (struct drm_device *dev,
22988+ unsigned long num_pages);
22989+ int (*fence_type) (struct drm_buffer_object *bo, uint32_t *fclass,
22990+ uint32_t *type);
22991+ int (*invalidate_caches) (struct drm_device *dev, uint64_t flags);
22992+ int (*init_mem_type) (struct drm_device *dev, uint32_t type,
22993+ struct drm_mem_type_manager *man);
22994+ uint32_t(*evict_mask) (struct drm_buffer_object *bo);
22995+ int (*move) (struct drm_buffer_object *bo,
22996+ int evict, int no_wait, struct drm_bo_mem_reg *new_mem);
22997+ void (*ttm_cache_flush)(struct drm_ttm *ttm);
22998+
22999+ /*
23000+ * command_stream_barrier
23001+ *
23002+ * @dev: The drm device.
23003+ *
23004+ * @bo: The buffer object to validate.
23005+ *
23006+ * @new_fence_class: The new fence class for the buffer object.
23007+ *
23008+ * @new_fence_type: The new fence type for the buffer object.
23009+ *
23010+ * @no_wait: whether this should give up and return -EBUSY
23011+ * if this operation would require sleeping
23012+ *
23013+ * Insert a command stream barrier that makes sure that the
23014+ * buffer is idle once the commands associated with the
23015+ * current validation are starting to execute. If an error
23016+ * condition is returned, or the function pointer is NULL,
23017+ * the drm core will force buffer idle
23018+ * during validation.
23019+ */
23020+
23021+ int (*command_stream_barrier) (struct drm_buffer_object *bo,
23022+ uint32_t new_fence_class,
23023+ uint32_t new_fence_type,
23024+ int no_wait);
23025+};
23026+
23027+/*
23028+ * buffer objects (drm_bo.c)
23029+ */
23030+extern int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
23031+extern int drm_bo_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
23032+extern int drm_bo_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
23033+extern int drm_bo_unmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
23034+extern int drm_bo_reference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
23035+extern int drm_bo_set_pin(struct drm_device *dev, struct drm_buffer_object *bo, int pin);
23036+extern int drm_bo_unreference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
23037+extern int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
23038+extern int drm_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
23039+extern int drm_bo_setstatus_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
23040+extern int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
23041+extern int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
23042+extern int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
23043+extern int drm_mm_unlock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
23044+extern int drm_bo_version_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
23045+extern int drm_bo_driver_finish(struct drm_device *dev);
23046+extern int drm_bo_driver_init(struct drm_device *dev);
23047+extern int drm_bo_pci_offset(struct drm_device *dev,
23048+ struct drm_bo_mem_reg *mem,
23049+ unsigned long *bus_base,
23050+ unsigned long *bus_offset,
23051+ unsigned long *bus_size);
23052+extern int drm_mem_reg_is_pci(struct drm_device *dev, struct drm_bo_mem_reg *mem);
23053+
23054+extern void drm_bo_usage_deref_locked(struct drm_buffer_object **bo);
23055+extern void drm_bo_usage_deref_unlocked(struct drm_buffer_object **bo);
23056+extern void drm_putback_buffer_objects(struct drm_device *dev);
23057+extern int drm_fence_buffer_objects(struct drm_device *dev,
23058+ struct list_head *list,
23059+ uint32_t fence_flags,
23060+ struct drm_fence_object *fence,
23061+ struct drm_fence_object **used_fence);
23062+extern void drm_bo_add_to_lru(struct drm_buffer_object *bo);
23063+extern int drm_buffer_object_create(struct drm_device *dev, unsigned long size,
23064+ enum drm_bo_type type, uint64_t mask,
23065+ uint32_t hint, uint32_t page_alignment,
23066+ unsigned long buffer_start,
23067+ struct drm_buffer_object **bo);
23068+extern int drm_bo_wait(struct drm_buffer_object *bo, int lazy, int ignore_signals,
23069+ int no_wait);
23070+extern int drm_bo_mem_space(struct drm_buffer_object *bo,
23071+ struct drm_bo_mem_reg *mem, int no_wait);
23072+extern int drm_bo_move_buffer(struct drm_buffer_object *bo,
23073+ uint64_t new_mem_flags,
23074+ int no_wait, int move_unfenced);
23075+extern int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type);
23076+extern int drm_bo_init_mm(struct drm_device *dev, unsigned type,
23077+ unsigned long p_offset, unsigned long p_size);
23078+extern int drm_bo_handle_validate(struct drm_file *file_priv, uint32_t handle,
23079+ uint32_t fence_class, uint64_t flags,
23080+ uint64_t mask, uint32_t hint,
23081+ int use_old_fence_class,
23082+ struct drm_bo_info_rep *rep,
23083+ struct drm_buffer_object **bo_rep);
23084+extern struct drm_buffer_object *drm_lookup_buffer_object(struct drm_file *file_priv,
23085+ uint32_t handle,
23086+ int check_owner);
23087+extern int drm_bo_do_validate(struct drm_buffer_object *bo,
23088+ uint64_t flags, uint64_t mask, uint32_t hint,
23089+ uint32_t fence_class,
23090+ int no_wait,
23091+ struct drm_bo_info_rep *rep);
23092+extern void drm_bo_fill_rep_arg(struct drm_buffer_object *bo,
23093+ struct drm_bo_info_rep *rep);
23094+/*
23095+ * Buffer object memory move- and map helpers.
23096+ * drm_bo_move.c
23097+ */
23098+
23099+extern int drm_bo_move_ttm(struct drm_buffer_object *bo,
23100+ int evict, int no_wait,
23101+ struct drm_bo_mem_reg *new_mem);
23102+extern int drm_bo_move_memcpy(struct drm_buffer_object *bo,
23103+ int evict,
23104+ int no_wait, struct drm_bo_mem_reg *new_mem);
23105+extern int drm_bo_move_accel_cleanup(struct drm_buffer_object *bo,
23106+ int evict, int no_wait,
23107+ uint32_t fence_class, uint32_t fence_type,
23108+ uint32_t fence_flags,
23109+ struct drm_bo_mem_reg *new_mem);
23110+extern int drm_bo_same_page(unsigned long offset, unsigned long offset2);
23111+extern unsigned long drm_bo_offset_end(unsigned long offset,
23112+ unsigned long end);
23113+
23114+struct drm_bo_kmap_obj {
23115+ void *virtual;
23116+ struct page *page;
23117+ enum {
23118+ bo_map_iomap,
23119+ bo_map_vmap,
23120+ bo_map_kmap,
23121+ bo_map_premapped,
23122+ } bo_kmap_type;
23123+};
23124+
23125+static inline void *drm_bmo_virtual(struct drm_bo_kmap_obj *map, int *is_iomem)
23126+{
23127+ *is_iomem = (map->bo_kmap_type == bo_map_iomap ||
23128+ map->bo_kmap_type == bo_map_premapped);
23129+ return map->virtual;
23130+}
23131+extern void drm_bo_kunmap(struct drm_bo_kmap_obj *map);
23132+extern int drm_bo_kmap(struct drm_buffer_object *bo, unsigned long start_page,
23133+ unsigned long num_pages, struct drm_bo_kmap_obj *map);
23134+
23135+
23136+/*
23137+ * drm_regman.c
23138+ */
23139+
23140+struct drm_reg {
23141+ struct list_head head;
23142+ struct drm_fence_object *fence;
23143+ uint32_t fence_type;
23144+ uint32_t new_fence_type;
23145+};
23146+
23147+struct drm_reg_manager {
23148+ struct list_head free;
23149+ struct list_head lru;
23150+ struct list_head unfenced;
23151+
23152+ int (*reg_reusable)(const struct drm_reg *reg, const void *data);
23153+ void (*reg_destroy)(struct drm_reg *reg);
23154+};
23155+
23156+extern int drm_regs_alloc(struct drm_reg_manager *manager,
23157+ const void *data,
23158+ uint32_t fence_class,
23159+ uint32_t fence_type,
23160+ int interruptible,
23161+ int no_wait,
23162+ struct drm_reg **reg);
23163+
23164+extern void drm_regs_fence(struct drm_reg_manager *regs,
23165+ struct drm_fence_object *fence);
23166+
23167+extern void drm_regs_free(struct drm_reg_manager *manager);
23168+extern void drm_regs_add(struct drm_reg_manager *manager, struct drm_reg *reg);
23169+extern void drm_regs_init(struct drm_reg_manager *manager,
23170+ int (*reg_reusable)(const struct drm_reg *,
23171+ const void *),
23172+ void (*reg_destroy)(struct drm_reg *));
23173+
23174+extern int drm_mem_reg_ioremap(struct drm_device *dev, struct drm_bo_mem_reg * mem,
23175+ void **virtual);
23176+extern void drm_mem_reg_iounmap(struct drm_device *dev, struct drm_bo_mem_reg * mem,
23177+ void *virtual);
23178+/*
23179+ * drm_bo_lock.c
23180+ * Simple replacement for the hardware lock on buffer manager init and clean.
23181+ */
23182+
23183+
23184+extern void drm_bo_init_lock(struct drm_bo_lock *lock);
23185+extern void drm_bo_read_unlock(struct drm_bo_lock *lock);
23186+extern int drm_bo_read_lock(struct drm_bo_lock *lock);
23187+extern int drm_bo_write_lock(struct drm_bo_lock *lock,
23188+ struct drm_file *file_priv);
23189+
23190+extern int drm_bo_write_unlock(struct drm_bo_lock *lock,
23191+ struct drm_file *file_priv);
23192+
23193+#ifdef CONFIG_DEBUG_MUTEXES
23194+#define DRM_ASSERT_LOCKED(_mutex) \
23195+ BUG_ON(!mutex_is_locked(_mutex) || \
23196+ ((_mutex)->owner != current_thread_info()))
23197+#else
23198+#define DRM_ASSERT_LOCKED(_mutex)
23199+#endif
23200+#endif
23201Index: linux-2.6.28/drivers/gpu/drm/drm_proc.c
23202===================================================================
23203--- linux-2.6.28.orig/drivers/gpu/drm/drm_proc.c 2009-02-12 09:14:37.000000000 +0000
23204+++ linux-2.6.28/drivers/gpu/drm/drm_proc.c 2009-02-12 09:14:42.000000000 +0000
23205@@ -489,13 +489,13 @@
23206
23207 for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
23208 DRM_PROC_PRINT("CRTC %d enable: %d\n",
23209- crtc, atomic_read(&dev->vblank_refcount[crtc]));
23210+ crtc, 1);
23211 DRM_PROC_PRINT("CRTC %d counter: %d\n",
23212- crtc, drm_vblank_count(dev, crtc));
23213+ crtc, 1);
23214 DRM_PROC_PRINT("CRTC %d last wait: %d\n",
23215- crtc, dev->last_vblank_wait[crtc]);
23216+ crtc, 1);
23217 DRM_PROC_PRINT("CRTC %d in modeset: %d\n",
23218- crtc, dev->vblank_inmodeset[crtc]);
23219+ crtc, 1);
23220 }
23221
23222 if (len > request + offset)
23223Index: linux-2.6.28/drivers/gpu/drm/drm_crtc.c
23224===================================================================
23225--- linux-2.6.28.orig/drivers/gpu/drm/drm_crtc.c 2009-02-12 09:14:37.000000000 +0000
23226+++ linux-2.6.28/drivers/gpu/drm/drm_crtc.c 2009-02-12 09:14:42.000000000 +0000
23227@@ -807,6 +807,53 @@
23228 }
23229 EXPORT_SYMBOL(drm_mode_config_init);
23230
23231+/**
23232+ * drm_get_buffer_object - find the buffer object for a given handle
23233+ * @dev: DRM device
23234+ * @bo: pointer to caller's buffer_object pointer
23235+ * @handle: handle to lookup
23236+ *
23237+ * LOCKING:
23238+ * Must take @dev's struct_mutex to protect buffer object lookup.
23239+ *
23240+ * Given @handle, lookup the buffer object in @dev and put it in the caller's
23241+ * @bo pointer.
23242+ *
23243+ * RETURNS:
23244+ * Zero on success, -EINVAL if the handle couldn't be found.
23245+ */
23246+static int drm_get_buffer_object(struct drm_device *dev, struct drm_buffer_object **bo, unsigned long handle)
23247+{
23248+ struct drm_user_object *uo;
23249+ struct drm_hash_item *hash;
23250+ int ret;
23251+
23252+ *bo = NULL;
23253+
23254+ mutex_lock(&dev->struct_mutex);
23255+ ret = drm_ht_find_item(&dev->object_hash, handle, &hash);
23256+ if (ret) {
23257+ DRM_ERROR("Couldn't find handle.\n");
23258+ ret = -EINVAL;
23259+ goto out_err;
23260+ }
23261+
23262+ uo = drm_hash_entry(hash, struct drm_user_object, hash);
23263+ if (uo->type != drm_buffer_type) {
23264+ ret = -EINVAL;
23265+ goto out_err;
23266+ }
23267+
23268+ *bo = drm_user_object_entry(uo, struct drm_buffer_object, base);
23269+ ret = 0;
23270+out_err:
23271+ mutex_unlock(&dev->struct_mutex);
23272+ return ret;
23273+}
23274+
23275+char drm_init_mode[32];
23276+EXPORT_SYMBOL(drm_init_mode);
23277+
23278 int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
23279 {
23280 uint32_t total_objects = 0;
23281@@ -1588,6 +1635,8 @@
23282 struct drm_mode_fb_cmd *r = data;
23283 struct drm_mode_config *config = &dev->mode_config;
23284 struct drm_framebuffer *fb;
23285+ struct drm_buffer_object *bo;
23286+ struct drm_crtc *crtc;
23287 int ret = 0;
23288
23289 if ((config->min_width > r->width) || (r->width > config->max_width)) {
23290@@ -1600,20 +1649,46 @@
23291 }
23292
23293 mutex_lock(&dev->mode_config.mutex);
23294+ /* TODO check limits are okay */
23295+ ret = drm_get_buffer_object(dev, &bo, r->handle);
23296+ if (ret || !bo) {
23297+ ret = -EINVAL;
23298+ goto out;
23299+ }
23300
23301 /* TODO check buffer is sufficently large */
23302 /* TODO setup destructor callback */
23303
23304- fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
23305+ fb = kzalloc(sizeof(struct drm_framebuffer), GFP_KERNEL);
23306+ if (!fb) {
23307+ ret = -ENOMEM;
23308+ goto out;
23309+ }
23310+
23311+ drm_framebuffer_init(dev, fb, NULL);
23312 if (!fb) {
23313 DRM_ERROR("could not create framebuffer\n");
23314 ret = -EINVAL;
23315 goto out;
23316 }
23317
23318+ fb->width = r->width;
23319+ fb->height = r->height;
23320+ fb->pitch = r->pitch;
23321+ fb->bits_per_pixel = r->bpp;
23322+ fb->depth = r->depth;
23323+ fb->offset = bo->offset;
23324+ fb->bo = bo;
23325+
23326 r->fb_id = fb->base.id;
23327 list_add(&fb->filp_head, &file_priv->fbs);
23328
23329+ /* FIXME: bind the fb to the right crtc */
23330+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
23331+ crtc->fb = fb;
23332+ dev->driver->fb_probe(dev, crtc);
23333+ }
23334+
23335 out:
23336 mutex_unlock(&dev->mode_config.mutex);
23337 return ret;
23338@@ -1669,8 +1744,10 @@
23339 /* TODO release all crtc connected to the framebuffer */
23340 /* TODO unhock the destructor from the buffer object */
23341
23342- list_del(&fb->filp_head);
23343- fb->funcs->destroy(fb);
23344+ if (fb->bo->type != drm_bo_type_kernel)
23345+ drm_framebuffer_cleanup(fb);
23346+ else
23347+ dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
23348
23349 out:
23350 mutex_unlock(&dev->mode_config.mutex);
23351@@ -1716,7 +1793,7 @@
23352 r->depth = fb->depth;
23353 r->bpp = fb->bits_per_pixel;
23354 r->pitch = fb->pitch;
23355- fb->funcs->create_handle(fb, file_priv, &r->handle);
23356+ r->handle = fb->bo->base.hash.key;
23357
23358 out:
23359 mutex_unlock(&dev->mode_config.mutex);
23360@@ -1746,7 +1823,10 @@
23361 mutex_lock(&dev->mode_config.mutex);
23362 list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
23363 list_del(&fb->filp_head);
23364- fb->funcs->destroy(fb);
23365+ if (fb->bo->type != drm_bo_type_kernel)
23366+ drm_framebuffer_cleanup(fb);
23367+ else
23368+ dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
23369 }
23370 mutex_unlock(&dev->mode_config.mutex);
23371 }
23372Index: linux-2.6.28/drivers/gpu/drm/drm_sysfs.c
23373===================================================================
23374--- linux-2.6.28.orig/drivers/gpu/drm/drm_sysfs.c 2009-02-12 09:14:37.000000000 +0000
23375+++ linux-2.6.28/drivers/gpu/drm/drm_sysfs.c 2009-02-12 09:14:42.000000000 +0000
23376@@ -156,8 +156,9 @@
23377 enum drm_connector_status status;
23378
23379 status = connector->funcs->detect(connector);
23380- return snprintf(buf, PAGE_SIZE, "%s",
23381- drm_get_connector_status_name(status));
23382+ return 0;
23383+ //return snprintf(buf, PAGE_SIZE, "%s",
23384+ // drm_get_connector_status_name(status));
23385 }
23386
23387 static ssize_t dpms_show(struct device *device,
23388Index: linux-2.6.28/include/drm/drm_crtc.h
23389===================================================================
23390--- linux-2.6.28.orig/include/drm/drm_crtc.h 2009-02-12 09:14:40.000000000 +0000
23391+++ linux-2.6.28/include/drm/drm_crtc.h 2009-02-12 09:14:42.000000000 +0000
23392@@ -50,6 +50,8 @@
23393 uint32_t type;
23394 };
23395
23396+#include <drm/drm_objects.h>
23397+
23398 /*
23399 * Note on terminology: here, for brevity and convenience, we refer to connector
23400 * control chips as 'CRTCs'. They can control any type of connector, VGA, LVDS,
23401@@ -258,6 +260,9 @@
23402 int flags;
23403 void *fbdev;
23404 u32 pseudo_palette[17];
23405+ unsigned long offset;
23406+ struct drm_buffer_object *bo;
23407+ struct drm_bo_kmap_obj kmap;
23408 struct list_head filp_head;
23409 };
23410
23411Index: linux-2.6.28/drivers/gpu/drm/i915/intel_crt.c
23412===================================================================
23413--- linux-2.6.28.orig/drivers/gpu/drm/i915/intel_crt.c 2009-02-12 09:14:37.000000000 +0000
23414+++ linux-2.6.28/drivers/gpu/drm/i915/intel_crt.c 2009-02-12 09:14:42.000000000 +0000
23415@@ -36,7 +36,7 @@
23416 static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
23417 {
23418 struct drm_device *dev = encoder->dev;
23419- struct drm_i915_private *dev_priv = dev->dev_private;
23420+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23421 u32 temp;
23422
23423 temp = I915_READ(ADPA);
23424@@ -88,7 +88,7 @@
23425 struct drm_device *dev = encoder->dev;
23426 struct drm_crtc *crtc = encoder->crtc;
23427 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
23428- struct drm_i915_private *dev_priv = dev->dev_private;
23429+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23430 int dpll_md_reg;
23431 u32 adpa, dpll_md;
23432
23433@@ -132,7 +132,7 @@
23434 static bool intel_crt_detect_hotplug(struct drm_connector *connector)
23435 {
23436 struct drm_device *dev = connector->dev;
23437- struct drm_i915_private *dev_priv = dev->dev_private;
23438+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23439 u32 temp;
23440
23441 unsigned long timeout = jiffies + msecs_to_jiffies(1000);
23442@@ -170,7 +170,7 @@
23443 {
23444 struct drm_device *dev = connector->dev;
23445
23446- if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
23447+ if (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) {
23448 if (intel_crt_detect_hotplug(connector))
23449 return connector_status_connected;
23450 else
23451@@ -189,7 +189,7 @@
23452 struct intel_output *intel_output = to_intel_output(connector);
23453
23454 intel_i2c_destroy(intel_output->ddc_bus);
23455- drm_sysfs_connector_remove(connector);
23456+ //drm_sysfs_connector_remove(connector);
23457 drm_connector_cleanup(connector);
23458 kfree(connector);
23459 }
23460@@ -280,5 +280,5 @@
23461 drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
23462 drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
23463
23464- drm_sysfs_connector_add(connector);
23465+ //drm_sysfs_connector_add(connector);
23466 }
23467Index: linux-2.6.28/drivers/gpu/drm/i915/intel_lvds.c
23468===================================================================
23469--- linux-2.6.28.orig/drivers/gpu/drm/i915/intel_lvds.c 2009-02-12 09:14:37.000000000 +0000
23470+++ linux-2.6.28/drivers/gpu/drm/i915/intel_lvds.c 2009-02-12 09:14:42.000000000 +0000
23471@@ -36,6 +36,259 @@
23472 #include "i915_drm.h"
23473 #include "i915_drv.h"
23474
23475+#include <acpi/acpi_drivers.h>
23476+
23477+#define BLC_I2C_TYPE 0x01
23478+#define BLC_PWM_TYPE 0x02
23479+#define BRIGHTNESS_MASK 0xff
23480+#define BRIGHTNESS_MAX_LEVEL 100
23481+#define BLC_POLARITY_NORMAL 0
23482+#define BLC_POLARITY_INVERSE 1
23483+#define BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xfffe)
23484+#define BACKLIGHT_PWM_CTL_SHIFT (16)
23485+#define BLC_MAX_PWM_REG_FREQ 0xfffe
23486+#define BLC_MIN_PWM_REG_FREQ 0x2
23487+#define BLC_PWM_LEGACY_MODE_ENABLE 0x0001
23488+#define BLC_PWM_PRECISION_FACTOR 10//10000000
23489+#define BLC_PWM_FREQ_CALC_CONSTANT 32
23490+#define MHz 1000000
23491+#define OFFSET_OPREGION_VBT 0x400
23492+
23493+typedef struct OpRegion_Header
23494+{
23495+ char sign[16];
23496+ u32 size;
23497+ u32 over;
23498+ char sver[32];
23499+ char vver[16];
23500+ char gver[16];
23501+ u32 mbox;
23502+ char rhd1[164];
23503+} OpRegionRec, *OpRegionPtr;
23504+
23505+struct vbt_header2
23506+{
23507+ char signature[20]; /**< Always starts with 'VBT$' */
23508+ u16 version; /**< decimal */
23509+ u16 header_size; /**< in bytes */
23510+ u16 vbt_size; /**< in bytes */
23511+ u8 vbt_checksum;
23512+ u8 reserved0;
23513+ u32 bdb_offset; /**< from beginning of VBT */
23514+ u32 aim1_offset; /**< from beginning of VBT */
23515+ u32 aim2_offset; /**< from beginning of VBT */
23516+ u32 aim3_offset; /**< from beginning of VBT */
23517+ u32 aim4_offset; /**< from beginning of VBT */
23518+} __attribute__ ((packed));
23519+
23520+struct bdb_header2
23521+{
23522+ char signature[16]; /**< Always 'BIOS_DATA_BLOCK' */
23523+ u16 version; /**< decimal */
23524+ u16 header_size; /**< in bytes */
23525+ u16 bdb_size; /**< in bytes */
23526+} __attribute__ ((packed));
23527+
23528+#define LVDS_CAP_EDID (1 << 6)
23529+#define LVDS_CAP_DITHER (1 << 5)
23530+#define LVDS_CAP_PFIT_AUTO_RATIO (1 << 4)
23531+#define LVDS_CAP_PFIT_GRAPHICS_MODE (1 << 3)
23532+#define LVDS_CAP_PFIT_TEXT_MODE (1 << 2)
23533+#define LVDS_CAP_PFIT_GRAPHICS (1 << 1)
23534+#define LVDS_CAP_PFIT_TEXT (1 << 0)
23535+struct lvds_bdb_1
23536+{
23537+ u8 id; /**< 40 */
23538+ u16 size;
23539+ u8 panel_type;
23540+ u8 reserved0;
23541+ u16 caps;
23542+} __attribute__ ((packed));
23543+
23544+struct lvds_bdb_2_fp_params
23545+{
23546+ u16 x_res;
23547+ u16 y_res;
23548+ u32 lvds_reg;
23549+ u32 lvds_reg_val;
23550+ u32 pp_on_reg;
23551+ u32 pp_on_reg_val;
23552+ u32 pp_off_reg;
23553+ u32 pp_off_reg_val;
23554+ u32 pp_cycle_reg;
23555+ u32 pp_cycle_reg_val;
23556+ u32 pfit_reg;
23557+ u32 pfit_reg_val;
23558+ u16 terminator;
23559+} __attribute__ ((packed));
23560+
23561+struct lvds_bdb_2_fp_edid_dtd
23562+{
23563+ u16 dclk; /**< In 10khz */
23564+ u8 hactive;
23565+ u8 hblank;
23566+ u8 high_h; /**< 7:4 = hactive 11:8, 3:0 = hblank 11:8 */
23567+ u8 vactive;
23568+ u8 vblank;
23569+ u8 high_v; /**< 7:4 = vactive 11:8, 3:0 = vblank 11:8 */
23570+ u8 hsync_off;
23571+ u8 hsync_pulse_width;
23572+ u8 vsync_off;
23573+ u8 high_hsync_off; /**< 7:6 = hsync off 9:8 */
23574+ u8 h_image;
23575+ u8 v_image;
23576+ u8 max_hv;
23577+ u8 h_border;
23578+ u8 v_border;
23579+ u8 flags;
23580+#define FP_EDID_FLAG_VSYNC_POSITIVE (1 << 2)
23581+#define FP_EDID_FLAG_HSYNC_POSITIVE (1 << 1)
23582+} __attribute__ ((packed));
23583+
23584+struct lvds_bdb_2_entry
23585+{
23586+ u16 fp_params_offset; /**< From beginning of BDB */
23587+ u8 fp_params_size;
23588+ u16 fp_edid_dtd_offset;
23589+ u8 fp_edid_dtd_size;
23590+ u16 fp_edid_pid_offset;
23591+ u8 fp_edid_pid_size;
23592+} __attribute__ ((packed));
23593+
23594+struct lvds_bdb_2
23595+{
23596+ u8 id; /**< 41 */
23597+ u16 size;
23598+ u8 table_size; /* not sure on this one */
23599+ struct lvds_bdb_2_entry panels[16];
23600+} __attribute__ ((packed));
23601+
23602+
23603+struct lvds_bdb_blc
23604+{
23605+ u8 id; /**< 43 */
23606+ u16 size;
23607+ u8 table_size;
23608+} __attribute__ ((packed));
23609+
23610+struct lvds_blc
23611+{
23612+ u8 type:2;
23613+ u8 pol:1;
23614+ u8 gpio:3;
23615+ u8 gmbus:2;
23616+ u16 freq;
23617+ u8 minbrightness;
23618+ u8 i2caddr;
23619+ u8 brightnesscmd;
23620+ /* more... */
23621+} __attribute__ ((packed));
23622+
23623+int drm_intel_ignore_acpi = 0;
23624+MODULE_PARM_DESC(ignore_acpi, "Ignore ACPI");
23625+module_param_named(ignore_acpi, drm_intel_ignore_acpi, int, 0600);
23626+
23627+uint8_t blc_type;
23628+uint8_t blc_pol;
23629+uint8_t blc_freq;
23630+uint8_t blc_minbrightness;
23631+uint8_t blc_i2caddr;
23632+uint8_t blc_brightnesscmd;
23633+int lvds_backlight; /* restore backlight to this value */
23634+
23635+struct intel_i2c_chan *lvds_i2c_bus;
23636+u32 CoreClock;
23637+u32 PWMControlRegFreq;
23638+
23639+unsigned char * dev_OpRegion = NULL;
23640+unsigned int dev_OpRegionSize;
23641+
23642+#define PCI_PORT5_REG80_FFUSE 0xD0058000
23643+#define PCI_PORT5_REG80_MAXRES_INT_EN 0x0040
23644+#define MAX_HDISPLAY 800
23645+#define MAX_VDISPLAY 480
23646+bool sku_bMaxResEnableInt = false;
23647+
23648+/** Set BLC through I2C*/
23649+static int
23650+LVDSI2CSetBacklight(struct drm_device *dev, unsigned char ch)
23651+{
23652+ u8 out_buf[2];
23653+ struct i2c_msg msgs[] = {
23654+ {
23655+ .addr = lvds_i2c_bus->slave_addr,
23656+ .flags = 0,
23657+ .len = 2,
23658+ .buf = out_buf,
23659+ }
23660+ };
23661+
23662+ DRM_INFO("LVDSI2CSetBacklight: the slave_addr is 0x%x, the backlight value is %d\n", lvds_i2c_bus->slave_addr, ch);
23663+
23664+ out_buf[0] = blc_brightnesscmd;
23665+ out_buf[1] = ch;
23666+
23667+ if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1)
23668+ {
23669+ DRM_INFO("LVDSI2CSetBacklight: i2c_transfer done\n");
23670+ return true;
23671+ }
23672+
23673+ DRM_ERROR("msg: i2c_transfer error\n");
23674+ return false;
23675+}
23676+
23677+/**
23678+ * Calculate PWM control register value.
23679+ */
23680+static int
23681+LVDSCalculatePWMCtrlRegFreq(struct drm_device *dev)
23682+{
23683+ unsigned long value = 0;
23684+
23685+ DRM_INFO("Enter LVDSCalculatePWMCtrlRegFreq.\n");
23686+ if (blc_freq == 0) {
23687+ DRM_ERROR("LVDSCalculatePWMCtrlRegFreq: Frequency Requested is 0.\n");
23688+ return FALSE;
23689+ }
23690+ value = (CoreClock * MHz);
23691+ value = (value / BLC_PWM_FREQ_CALC_CONSTANT);
23692+ value = (value * BLC_PWM_PRECISION_FACTOR);
23693+ value = (value / blc_freq);
23694+ value = (value / BLC_PWM_PRECISION_FACTOR);
23695+
23696+ if (value > (unsigned long)BLC_MAX_PWM_REG_FREQ ||
23697+ value < (unsigned long)BLC_MIN_PWM_REG_FREQ) {
23698+ return FALSE;
23699+ } else {
23700+ PWMControlRegFreq = ((u32)value & ~BLC_PWM_LEGACY_MODE_ENABLE);
23701+ return TRUE;
23702+ }
23703+}
23704+
23705+/**
23706+ * Returns the maximum level of the backlight duty cycle field.
23707+ */
23708+static u32
23709+LVDSGetPWMMaxBacklight(struct drm_device *dev)
23710+{
23711+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23712+ u32 max_pwm_blc = 0;
23713+
23714+ max_pwm_blc = ((I915_READ(BLC_PWM_CTL) & BACKLIGHT_MODULATION_FREQ_MASK) >> \
23715+ BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
23716+
23717+ if (!(max_pwm_blc & BLC_MAX_PWM_REG_FREQ)) {
23718+ if (LVDSCalculatePWMCtrlRegFreq(dev)) {
23719+ max_pwm_blc = PWMControlRegFreq;
23720+ }
23721+ }
23722+
23723+ DRM_INFO("LVDSGetPWMMaxBacklight: the max_pwm_blc is %d.\n", max_pwm_blc);
23724+ return max_pwm_blc;
23725+}
23726+
23727+
23728 /**
23729 * Sets the backlight level.
23730 *
23731@@ -43,12 +296,48 @@
23732 */
23733 static void intel_lvds_set_backlight(struct drm_device *dev, int level)
23734 {
23735- struct drm_i915_private *dev_priv = dev->dev_private;
23736+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23737+ /*
23738 u32 blc_pwm_ctl;
23739
23740 blc_pwm_ctl = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
23741 I915_WRITE(BLC_PWM_CTL, (blc_pwm_ctl |
23742 (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
23743+ */
23744+ u32 newbacklight = 0;
23745+
23746+ DRM_INFO("intel_lvds_set_backlight: the level is %d\n", level);
23747+
23748+ if(blc_type == BLC_I2C_TYPE){
23749+ newbacklight = BRIGHTNESS_MASK & ((unsigned long)level * \
23750+ BRIGHTNESS_MASK /BRIGHTNESS_MAX_LEVEL);
23751+
23752+ if (blc_pol == BLC_POLARITY_INVERSE) {
23753+ newbacklight = BRIGHTNESS_MASK - newbacklight;
23754+ }
23755+
23756+ LVDSI2CSetBacklight(dev, newbacklight);
23757+
23758+ } else if (blc_type == BLC_PWM_TYPE) {
23759+ u32 max_pwm_blc = LVDSGetPWMMaxBacklight(dev);
23760+
23761+ u32 blc_pwm_duty_cycle;
23762+
23763+ /* Provent LVDS going to total black */
23764+ if ( level < 20) {
23765+ level = 20;
23766+ }
23767+ blc_pwm_duty_cycle = level * max_pwm_blc/BRIGHTNESS_MAX_LEVEL;
23768+
23769+ if (blc_pol == BLC_POLARITY_INVERSE) {
23770+ blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle;
23771+ }
23772+
23773+ blc_pwm_duty_cycle &= BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
23774+
23775+ I915_WRITE(BLC_PWM_CTL,
23776+ (max_pwm_blc << BACKLIGHT_PWM_CTL_SHIFT)| (blc_pwm_duty_cycle));
23777+ }
23778 }
23779
23780 /**
23781@@ -56,10 +345,13 @@
23782 */
23783 static u32 intel_lvds_get_max_backlight(struct drm_device *dev)
23784 {
23785- struct drm_i915_private *dev_priv = dev->dev_private;
23786+ return BRIGHTNESS_MAX_LEVEL;
23787+ /*
23788+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23789
23790 return ((I915_READ(BLC_PWM_CTL) & BACKLIGHT_MODULATION_FREQ_MASK) >>
23791 BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
23792+ */
23793 }
23794
23795 /**
23796@@ -67,9 +359,10 @@
23797 */
23798 static void intel_lvds_set_power(struct drm_device *dev, bool on)
23799 {
23800- struct drm_i915_private *dev_priv = dev->dev_private;
23801+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23802 u32 pp_status;
23803
23804+ DRM_INFO("intel_lvds_set_power: %d\n", on);
23805 if (on) {
23806 I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) |
23807 POWER_TARGET_ON);
23808@@ -77,7 +370,7 @@
23809 pp_status = I915_READ(PP_STATUS);
23810 } while ((pp_status & PP_ON) == 0);
23811
23812- intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle);
23813+ intel_lvds_set_backlight(dev, lvds_backlight);
23814 } else {
23815 intel_lvds_set_backlight(dev, 0);
23816
23817@@ -93,6 +386,7 @@
23818 {
23819 struct drm_device *dev = encoder->dev;
23820
23821+ DRM_INFO("intel_lvds_dpms: the mode is %d\n", mode);
23822 if (mode == DRM_MODE_DPMS_ON)
23823 intel_lvds_set_power(dev, true);
23824 else
23825@@ -104,12 +398,12 @@
23826 static void intel_lvds_save(struct drm_connector *connector)
23827 {
23828 struct drm_device *dev = connector->dev;
23829- struct drm_i915_private *dev_priv = dev->dev_private;
23830+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23831
23832 dev_priv->savePP_ON = I915_READ(PP_ON_DELAYS);
23833 dev_priv->savePP_OFF = I915_READ(PP_OFF_DELAYS);
23834 dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
23835- dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
23836+ dev_priv->savePP_CYCLE = I915_READ(PP_DIVISOR);
23837 dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
23838 dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
23839 BACKLIGHT_DUTY_CYCLE_MASK);
23840@@ -118,19 +412,19 @@
23841 * If the light is off at server startup, just make it full brightness
23842 */
23843 if (dev_priv->backlight_duty_cycle == 0)
23844- dev_priv->backlight_duty_cycle =
23845+ lvds_backlight=
23846 intel_lvds_get_max_backlight(dev);
23847 }
23848
23849 static void intel_lvds_restore(struct drm_connector *connector)
23850 {
23851 struct drm_device *dev = connector->dev;
23852- struct drm_i915_private *dev_priv = dev->dev_private;
23853+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23854
23855 I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
23856 I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON);
23857 I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF);
23858- I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
23859+ I915_WRITE(PP_DIVISOR, dev_priv->savePP_CYCLE);
23860 I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
23861 if (dev_priv->savePP_CONTROL & POWER_TARGET_ON)
23862 intel_lvds_set_power(dev, true);
23863@@ -142,7 +436,7 @@
23864 struct drm_display_mode *mode)
23865 {
23866 struct drm_device *dev = connector->dev;
23867- struct drm_i915_private *dev_priv = dev->dev_private;
23868+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23869 struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode;
23870
23871 if (fixed_mode) {
23872@@ -152,6 +446,13 @@
23873 return MODE_PANEL;
23874 }
23875
23876+ if (IS_POULSBO(dev) && sku_bMaxResEnableInt) {
23877+ if (mode->hdisplay > MAX_HDISPLAY)
23878+ return MODE_PANEL;
23879+ if (mode->vdisplay > MAX_VDISPLAY)
23880+ return MODE_PANEL;
23881+ }
23882+
23883 return MODE_OK;
23884 }
23885
23886@@ -160,7 +461,7 @@
23887 struct drm_display_mode *adjusted_mode)
23888 {
23889 struct drm_device *dev = encoder->dev;
23890- struct drm_i915_private *dev_priv = dev->dev_private;
23891+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23892 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
23893 struct drm_encoder *tmp_encoder;
23894
23895@@ -214,7 +515,7 @@
23896 static void intel_lvds_prepare(struct drm_encoder *encoder)
23897 {
23898 struct drm_device *dev = encoder->dev;
23899- struct drm_i915_private *dev_priv = dev->dev_private;
23900+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23901
23902 dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
23903 dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
23904@@ -226,10 +527,11 @@
23905 static void intel_lvds_commit( struct drm_encoder *encoder)
23906 {
23907 struct drm_device *dev = encoder->dev;
23908- struct drm_i915_private *dev_priv = dev->dev_private;
23909+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23910
23911 if (dev_priv->backlight_duty_cycle == 0)
23912- dev_priv->backlight_duty_cycle =
23913+ //dev_priv->backlight_duty_cycle =
23914+ lvds_backlight =
23915 intel_lvds_get_max_backlight(dev);
23916
23917 intel_lvds_set_power(dev, true);
23918@@ -240,7 +542,7 @@
23919 struct drm_display_mode *adjusted_mode)
23920 {
23921 struct drm_device *dev = encoder->dev;
23922- struct drm_i915_private *dev_priv = dev->dev_private;
23923+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23924 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
23925 u32 pfit_control;
23926
23927@@ -291,10 +593,12 @@
23928 {
23929 struct drm_device *dev = connector->dev;
23930 struct intel_output *intel_output = to_intel_output(connector);
23931- struct drm_i915_private *dev_priv = dev->dev_private;
23932+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
23933 int ret = 0;
23934
23935+ mutex_lock(&dev->mode_config.mutex);
23936 ret = intel_ddc_get_modes(intel_output);
23937+ mutex_unlock(&dev->mode_config.mutex);
23938
23939 if (ret)
23940 return ret;
23941@@ -333,9 +637,12 @@
23942 {
23943 struct intel_output *intel_output = to_intel_output(connector);
23944
23945+ if(dev_OpRegion != NULL)
23946+ iounmap(dev_OpRegion);
23947 if (intel_output->ddc_bus)
23948 intel_i2c_destroy(intel_output->ddc_bus);
23949- drm_sysfs_connector_remove(connector);
23950+ intel_i2c_destroy(lvds_i2c_bus);
23951+ //drm_sysfs_connector_remove(connector);
23952 drm_connector_cleanup(connector);
23953 kfree(connector);
23954 }
23955@@ -373,7 +680,45 @@
23956 };
23957
23958
23959-
23960+int intel_get_acpi_dod(char *method)
23961+{
23962+ int status;
23963+ int found = 0;
23964+ int i;
23965+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
23966+ union acpi_object *dod = NULL;
23967+ union acpi_object *obj;
23968+
23969+ status = acpi_evaluate_object(NULL, method, NULL, &buffer);
23970+ if (ACPI_FAILURE(status))
23971+ return -ENODEV;
23972+
23973+ dod = buffer.pointer;
23974+ if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {
23975+ status = -EFAULT;
23976+ goto out;
23977+ }
23978+
23979+ DRM_DEBUG("Found %d video heads in _DOD\n", dod->package.count);
23980+
23981+ for (i = 0; i < dod->package.count; i++) {
23982+ obj = &dod->package.elements[i];
23983+
23984+ if (obj->type != ACPI_TYPE_INTEGER) {
23985+ DRM_DEBUG("Invalid _DOD data\n");
23986+ } else {
23987+ DRM_DEBUG("dod element[%d] = 0x%x\n", i,
23988+ (int)obj->integer.value);
23989+
23990+ /* look for an LVDS type */
23991+ if (obj->integer.value & 0x00000400)
23992+ found = 1;
23993+ }
23994+ }
23995+ out:
23996+ kfree(buffer.pointer);
23997+ return found;
23998+}
23999 /**
24000 * intel_lvds_init - setup LVDS connectors on this device
24001 * @dev: drm device
24002@@ -383,7 +728,7 @@
24003 */
24004 void intel_lvds_init(struct drm_device *dev)
24005 {
24006- struct drm_i915_private *dev_priv = dev->dev_private;
24007+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
24008 struct intel_output *intel_output;
24009 struct drm_connector *connector;
24010 struct drm_encoder *encoder;
24011@@ -391,12 +736,38 @@
24012 struct drm_crtc *crtc;
24013 u32 lvds;
24014 int pipe;
24015+ u32 OpRegion_Phys;
24016+ unsigned int OpRegion_Size = 0x100;
24017+ OpRegionPtr OpRegion;
24018+ char *OpRegion_String = "IntelGraphicsMem";
24019+ struct pci_dev * pci_root = pci_get_bus_and_slot(0, 0);
24020+ u32 clock;
24021+ u32 sku_value = 0;
24022+ unsigned int CoreClocks[] = {
24023+ 100,
24024+ 133,
24025+ 150,
24026+ 178,
24027+ 200,
24028+ 266,
24029+ 266,
24030+ 266
24031+ };
24032+ struct vbt_header *vbt;
24033+ struct bdb_header *bdb;
24034+ int vbt_off, bdb_off, bdb_block_off, block_size;
24035+ int panel_type = -1;
24036+ unsigned char *bios;
24037+ unsigned char *vbt_buf;
24038
24039 intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
24040 if (!intel_output) {
24041 return;
24042 }
24043
24044+ if (!drm_intel_ignore_acpi && !intel_get_acpi_dod(ACPI_DOD))
24045+ return;
24046+
24047 connector = &intel_output->base;
24048 encoder = &intel_output->enc;
24049 drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs,
24050@@ -414,16 +785,139 @@
24051 connector->interlace_allowed = false;
24052 connector->doublescan_allowed = false;
24053
24054+ //initialize the I2C bus and BLC data
24055+ lvds_i2c_bus = intel_i2c_create(dev, GPIOB, "LVDSBLC_B");
24056+ if (!lvds_i2c_bus) {
24057+ dev_printk(KERN_ERR, &dev->pdev->dev, "i2c bus registration "
24058+ "failed.\n");
24059+ return;
24060+ }
24061+ lvds_i2c_bus->slave_addr = 0x2c;//0x58;
24062+ lvds_backlight = BRIGHTNESS_MAX_LEVEL;
24063+ blc_type = 0;
24064+ blc_pol = 0;
24065+
24066+ //get the BLC init data from VBT
24067
24068- /*
24069- * LVDS discovery:
24070- * 1) check for EDID on DDC
24071- * 2) check for VBT data
24072- * 3) check to see if LVDS is already on
24073- * if none of the above, no panel
24074- * 4) make sure lid is open
24075- * if closed, act like it's not there for now
24076- */
24077+
24078+
24079+
24080+ pci_read_config_dword(dev->pdev, 0xFC, &OpRegion_Phys);
24081+
24082+ dev_OpRegion = ioremap(OpRegion_Phys, OpRegion_Size);
24083+ dev_OpRegionSize = OpRegion_Size;
24084+
24085+ OpRegion = (OpRegionPtr) dev_OpRegion;
24086+
24087+ if (!memcmp(OpRegion->sign, OpRegion_String, 16)) {
24088+ unsigned int OpRegion_NewSize;
24089+
24090+ OpRegion_NewSize = OpRegion->size * 1024;
24091+
24092+ dev_OpRegionSize = OpRegion_NewSize;
24093+
24094+ iounmap(dev_OpRegion);
24095+ dev_OpRegion = ioremap(OpRegion_Phys, OpRegion_NewSize);
24096+ } else {
24097+ iounmap(dev_OpRegion);
24098+ dev_OpRegion = NULL;
24099+ }
24100+
24101+ if((dev_OpRegion != NULL)&&(dev_OpRegionSize >= OFFSET_OPREGION_VBT)) {
24102+ DRM_INFO("intel_lvds_init: OpRegion has the VBT address\n");
24103+ vbt_buf = dev_OpRegion + OFFSET_OPREGION_VBT;
24104+ vbt = (struct vbt_header *)(dev_OpRegion + OFFSET_OPREGION_VBT);
24105+ } else {
24106+ DRM_INFO("intel_lvds_init: No OpRegion, use the bios at fixed address 0xc0000\n");
24107+ bios = phys_to_virt(0xC0000);
24108+ if(*((u16 *)bios) != 0xAA55){
24109+ bios = NULL;
24110+ DRM_ERROR("the bios is incorrect\n");
24111+ goto blc_out;
24112+ }
24113+ vbt_off = bios[0x1a] | (bios[0x1a + 1] << 8);
24114+ DRM_INFO("intel_lvds_init: the vbt off is %x\n", vbt_off);
24115+ vbt_buf = bios + vbt_off;
24116+ vbt = (struct vbt_header *)(bios + vbt_off);
24117+ }
24118+
24119+ bdb_off = vbt->bdb_offset;
24120+ bdb = (struct bdb_header *)(vbt_buf + bdb_off);
24121+
24122+ DRM_INFO("intel_lvds_init: The bdb->signature is %s, the bdb_off is %d\n",bdb->signature, bdb_off);
24123+
24124+ if (memcmp(bdb->signature, "BIOS_DATA_BLOCK ", 16) != 0) {
24125+ DRM_ERROR("the vbt is error\n");
24126+ goto blc_out;
24127+ }
24128+
24129+ for (bdb_block_off = bdb->header_size; bdb_block_off < bdb->bdb_size;
24130+ bdb_block_off += block_size) {
24131+ int start = bdb_off + bdb_block_off;
24132+ int id, num_entries;
24133+ struct lvds_bdb_1 *lvds1;
24134+ struct lvds_blc *lvdsblc;
24135+ struct lvds_bdb_blc *bdbblc;
24136+
24137+ id = vbt_buf[start];
24138+ block_size = (vbt_buf[start + 1] | (vbt_buf[start + 2] << 8)) + 3;
24139+ switch (id) {
24140+ case 40:
24141+ lvds1 = (struct lvds_bdb_1 *)(vbt_buf+ start);
24142+ panel_type = lvds1->panel_type;
24143+ //if (lvds1->caps & LVDS_CAP_DITHER)
24144+ // *panelWantsDither = TRUE;
24145+ break;
24146+
24147+ case 43:
24148+ bdbblc = (struct lvds_bdb_blc *)(vbt_buf + start);
24149+ num_entries = bdbblc->table_size? (bdbblc->size - \
24150+ sizeof(bdbblc->table_size))/bdbblc->table_size : 0;
24151+ if (num_entries << 16 && bdbblc->table_size == sizeof(struct lvds_blc)) {
24152+ lvdsblc = (struct lvds_blc *)(vbt_buf + start + sizeof(struct lvds_bdb_blc));
24153+ lvdsblc += panel_type;
24154+ blc_type = lvdsblc->type;
24155+ blc_pol = lvdsblc->pol;
24156+ blc_freq = lvdsblc->freq;
24157+ blc_minbrightness = lvdsblc->minbrightness;
24158+ blc_i2caddr = lvdsblc->i2caddr;
24159+ blc_brightnesscmd = lvdsblc->brightnesscmd;
24160+ DRM_INFO("intel_lvds_init: BLC Data in BIOS VBT tables: datasize=%d paneltype=%d \
24161+ type=0x%02x pol=0x%02x freq=0x%04x minlevel=0x%02x \
24162+ i2caddr=0x%02x cmd=0x%02x \n",
24163+ 0,
24164+ panel_type,
24165+ lvdsblc->type,
24166+ lvdsblc->pol,
24167+ lvdsblc->freq,
24168+ lvdsblc->minbrightness,
24169+ lvdsblc->i2caddr,
24170+ lvdsblc->brightnesscmd);
24171+ }
24172+ break;
24173+ }
24174+ }
24175+
24176+ //get the Core Clock for calculating MAX PWM value
24177+ //check whether the MaxResEnableInt is
24178+
24179+ if(pci_root)
24180+ {
24181+ pci_write_config_dword(pci_root, 0xD0, 0xD0050300);
24182+ pci_read_config_dword(pci_root, 0xD4, &clock);
24183+ CoreClock = CoreClocks[clock & 0x07];
24184+ DRM_INFO("intel_lvds_init: the CoreClock is %d\n", CoreClock);
24185+
24186+ pci_write_config_dword(pci_root, 0xD0, PCI_PORT5_REG80_FFUSE);
24187+ pci_read_config_dword(pci_root, 0xD4, &sku_value);
24188+ sku_bMaxResEnableInt = (sku_value & PCI_PORT5_REG80_MAXRES_INT_EN)? true : false;
24189+ DRM_INFO("intel_lvds_init: sku_value is 0x%08x\n", sku_value);
24190+ DRM_INFO("intel_lvds_init: sku_bMaxResEnableInt is %d\n", sku_bMaxResEnableInt);
24191+ }
24192+
24193+
24194+
24195+blc_out:
24196
24197 /* Set up the DDC bus. */
24198 intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C");
24199@@ -437,7 +931,9 @@
24200 * Attempt to get the fixed panel mode from DDC. Assume that the
24201 * preferred mode is the right one.
24202 */
24203+ mutex_lock(&dev->mode_config.mutex);
24204 intel_ddc_get_modes(intel_output);
24205+ mutex_unlock(&dev->mode_config.mutex);
24206
24207 list_for_each_entry(scan, &connector->probed_modes, head) {
24208 mutex_lock(&dev->mode_config.mutex);
24209@@ -450,21 +946,6 @@
24210 mutex_unlock(&dev->mode_config.mutex);
24211 }
24212
24213- /* Failed to get EDID, what about VBT? */
24214- if (dev_priv->vbt_mode) {
24215- mutex_lock(&dev->mode_config.mutex);
24216- dev_priv->panel_fixed_mode =
24217- drm_mode_duplicate(dev, dev_priv->vbt_mode);
24218- mutex_unlock(&dev->mode_config.mutex);
24219- if (dev_priv->panel_fixed_mode) {
24220- dev_priv->panel_fixed_mode->type |=
24221- DRM_MODE_TYPE_PREFERRED;
24222- drm_mode_probed_add(connector,
24223- dev_priv->panel_fixed_mode);
24224- goto out;
24225- }
24226- }
24227-
24228 /*
24229 * If we didn't get EDID, try checking if the panel is already turned
24230 * on. If so, assume that whatever is currently programmed is the
24231@@ -520,7 +1001,7 @@
24232
24233
24234 out:
24235- drm_sysfs_connector_add(connector);
24236+ //drm_sysfs_connector_add(connector);
24237 return;
24238
24239 failed:
24240Index: linux-2.6.28/drivers/gpu/drm/i915/intel_sdvo.c
24241===================================================================
24242--- linux-2.6.28.orig/drivers/gpu/drm/i915/intel_sdvo.c 2009-02-12 09:14:37.000000000 +0000
24243+++ linux-2.6.28/drivers/gpu/drm/i915/intel_sdvo.c 2009-02-12 09:14:42.000000000 +0000
24244@@ -37,6 +37,14 @@
24245
24246 #undef SDVO_DEBUG
24247
24248+#define MAX_VAL 1000
24249+#define DPLL_CLOCK_PHASE_9 (1<<9 | 1<<12)
24250+
24251+#define PCI_PORT5_REG80_FFUSE 0xD0058000
24252+#define PCI_PORT5_REG80_SDVO_DISABLE 0x0020
24253+
24254+int SII_1392=0;
24255+
24256 struct intel_sdvo_priv {
24257 struct intel_i2c_chan *i2c_bus;
24258 int slaveaddr;
24259@@ -62,7 +70,7 @@
24260 static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
24261 {
24262 struct drm_device *dev = intel_output->base.dev;
24263- struct drm_i915_private *dev_priv = dev->dev_private;
24264+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
24265 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
24266 u32 bval = val, cval = val;
24267 int i;
24268@@ -552,7 +560,7 @@
24269 struct drm_display_mode *adjusted_mode)
24270 {
24271 struct drm_device *dev = encoder->dev;
24272- struct drm_i915_private *dev_priv = dev->dev_private;
24273+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
24274 struct drm_crtc *crtc = encoder->crtc;
24275 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
24276 struct intel_output *intel_output = enc_to_intel_output(encoder);
24277@@ -659,7 +667,7 @@
24278 if (IS_I965G(dev)) {
24279 /* done in crtc_mode_set as the dpll_md reg must be written
24280 early */
24281- } else if (IS_I945G(dev) || IS_I945GM(dev)) {
24282+ } else if (IS_POULSBO(dev) || IS_I945G(dev) || IS_I945GM(dev)) {
24283 /* done in crtc_mode_set as it lives inside the
24284 dpll register */
24285 } else {
24286@@ -672,7 +680,7 @@
24287 static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
24288 {
24289 struct drm_device *dev = encoder->dev;
24290- struct drm_i915_private *dev_priv = dev->dev_private;
24291+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
24292 struct intel_output *intel_output = enc_to_intel_output(encoder);
24293 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
24294 u32 temp;
24295@@ -722,7 +730,7 @@
24296 static void intel_sdvo_save(struct drm_connector *connector)
24297 {
24298 struct drm_device *dev = connector->dev;
24299- struct drm_i915_private *dev_priv = dev->dev_private;
24300+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
24301 struct intel_output *intel_output = to_intel_output(connector);
24302 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
24303 int o;
24304@@ -759,7 +767,7 @@
24305 static void intel_sdvo_restore(struct drm_connector *connector)
24306 {
24307 struct drm_device *dev = connector->dev;
24308- struct drm_i915_private *dev_priv = dev->dev_private;
24309+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
24310 struct intel_output *intel_output = to_intel_output(connector);
24311 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
24312 int o;
24313@@ -941,7 +949,7 @@
24314
24315 if (intel_output->i2c_bus)
24316 intel_i2c_destroy(intel_output->i2c_bus);
24317- drm_sysfs_connector_remove(connector);
24318+ //drm_sysfs_connector_remove(connector);
24319 drm_connector_cleanup(connector);
24320 kfree(intel_output);
24321 }
24322@@ -988,6 +996,32 @@
24323 u8 ch[0x40];
24324 int i;
24325 int encoder_type, output_id;
24326+ char name[DRM_CONNECTOR_LEN];
24327+ char *name_prefix;
24328+ char *name_suffix;
24329+
24330+ int count = 3;
24331+ u8 response[2];
24332+ u8 status;
24333+ unsigned char bytes[2];
24334+
24335+ DRM_DEBUG("xxintel_sdvo_init\n");
24336+
24337+ if (IS_POULSBO(dev)) {
24338+ struct pci_dev * pci_root = pci_get_bus_and_slot(0, 0);
24339+ u32 sku_value = 0;
24340+ bool sku_bSDVOEnable = true;
24341+ if(pci_root)
24342+ {
24343+ pci_write_config_dword(pci_root, 0xD0, PCI_PORT5_REG80_FFUSE);
24344+ pci_read_config_dword(pci_root, 0xD4, &sku_value);
24345+ sku_bSDVOEnable = (sku_value & PCI_PORT5_REG80_SDVO_DISABLE)?false : true;
24346+ DRM_INFO("intel_sdvo_init: sku_value is 0x%08x\n", sku_value);
24347+ DRM_INFO("intel_sdvo_init: sku_bSDVOEnable is %d\n", sku_bSDVOEnable);
24348+ if (sku_bSDVOEnable == false)
24349+ return false;
24350+ }
24351+ }
24352
24353 intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
24354 if (!intel_output) {
24355@@ -1087,7 +1121,7 @@
24356 connector->connector_type = connector_type;
24357
24358 drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
24359- drm_sysfs_connector_add(connector);
24360+ //drm_sysfs_connector_add(connector);
24361
24362 /* Set the input timing to the screen. Assume always input 0. */
24363 intel_sdvo_set_target_input(intel_output, true, false);
24364Index: linux-2.6.28/drivers/gpu/drm/psb/psb_priv.h
24365===================================================================
24366--- /dev/null 1970-01-01 00:00:00.000000000 +0000
24367+++ linux-2.6.28/drivers/gpu/drm/psb/psb_priv.h 2009-02-12 09:14:42.000000000 +0000
24368@@ -0,0 +1,238 @@
24369+#include "psb_drm.h"
24370+#include "psb_reg.h"
24371+#include "psb_schedule.h"
24372+
24373+#define DRM_DRIVER_PRIVATE_T struct drm_psb_private
24374+#undef I915_WRITE
24375+#undef I915_READ
24376+#define I915_WRITE(_offs, _val) \
24377+ iowrite32(_val, dev_priv->vdc_reg + (_offs))
24378+#define I915_READ(_offs) \
24379+ ioread32(dev_priv->vdc_reg + (_offs))
24380+
24381+struct drm_psb_uopt {
24382+ int clock_gating;
24383+};
24384+
24385+struct drm_psb_private {
24386+ unsigned long chipset;
24387+ uint8_t psb_rev_id;
24388+
24389+ struct psb_xhw_buf resume_buf;
24390+ struct drm_psb_dev_info_arg dev_info;
24391+ struct drm_psb_uopt uopt;
24392+
24393+ struct psb_gtt *pg;
24394+
24395+ struct page *scratch_page;
24396+ struct page *comm_page;
24397+
24398+ volatile uint32_t *comm;
24399+ uint32_t comm_mmu_offset;
24400+ uint32_t mmu_2d_offset;
24401+ uint32_t sequence[PSB_NUM_ENGINES];
24402+ uint32_t last_sequence[PSB_NUM_ENGINES];
24403+ int idle[PSB_NUM_ENGINES];
24404+ uint32_t last_submitted_seq[PSB_NUM_ENGINES];
24405+ int engine_lockup_2d;
24406+
24407+ struct psb_mmu_driver *mmu;
24408+ struct psb_mmu_pd *pf_pd;
24409+
24410+ uint8_t *sgx_reg;
24411+ uint8_t *vdc_reg;
24412+ uint8_t *msvdx_reg;
24413+
24414+ /*
24415+ * MSVDX
24416+ */
24417+ int msvdx_needs_reset;
24418+ int has_msvdx;
24419+ uint32_t gatt_free_offset;
24420+ atomic_t msvdx_mmu_invaldc;
24421+
24422+ /*
24423+ * Fencing / irq.
24424+ */
24425+
24426+ uint32_t sgx_irq_mask;
24427+ uint32_t sgx2_irq_mask;
24428+ uint32_t vdc_irq_mask;
24429+
24430+ spinlock_t irqmask_lock;
24431+ spinlock_t sequence_lock;
24432+ int fence0_irq_on;
24433+ int irq_enabled;
24434+ unsigned int irqen_count_2d;
24435+ wait_queue_head_t event_2d_queue;
24436+
24437+ wait_queue_head_t queue_2d;
24438+ atomic_t lock_2d;
24439+ atomic_t ta_wait_2d;
24440+ atomic_t ta_wait_2d_irq;
24441+ atomic_t waiters_2d;
24442+
24443+ uint32_t msvdx_current_sequence;
24444+ uint32_t msvdx_last_sequence;
24445+#define MSVDX_MAX_IDELTIME HZ*30
24446+ uint32_t msvdx_finished_sequence;
24447+ uint32_t msvdx_start_idle;
24448+ unsigned long msvdx_idle_start_jiffies;
24449+
24450+ int fence2_irq_on;
24451+
24452+ /*
24453+ * MSVDX Rendec Memory
24454+ */
24455+ struct drm_buffer_object *ccb0;
24456+ uint32_t base_addr0;
24457+ struct drm_buffer_object *ccb1;
24458+ uint32_t base_addr1;
24459+
24460+ /*
24461+ * Memory managers
24462+ */
24463+
24464+ int have_vram;
24465+ int have_tt;
24466+ int have_mem_mmu;
24467+ int have_mem_aper;
24468+ int have_mem_kernel;
24469+ int have_mem_pds;
24470+ int have_mem_rastgeom;
24471+ struct mutex temp_mem;
24472+
24473+ /*
24474+ * Relocation buffer mapping.
24475+ */
24476+
24477+ spinlock_t reloc_lock;
24478+ unsigned int rel_mapped_pages;
24479+ wait_queue_head_t rel_mapped_queue;
24480+
24481+ /*
24482+ * SAREA
24483+ */
24484+ struct drm_psb_sarea *sarea_priv;
24485+
24486+ /*
24487+ * LVDS info
24488+ */
24489+ int backlight_duty_cycle; /* restore backlight to this value */
24490+ bool panel_wants_dither;
24491+ struct drm_display_mode *panel_fixed_mode;
24492+
24493+ /*
24494+ * Register state
24495+ */
24496+ uint32_t saveDSPACNTR;
24497+ uint32_t saveDSPBCNTR;
24498+ uint32_t savePIPEACONF;
24499+ uint32_t savePIPEBCONF;
24500+ uint32_t savePIPEASRC;
24501+ uint32_t savePIPEBSRC;
24502+ uint32_t saveFPA0;
24503+ uint32_t saveFPA1;
24504+ uint32_t saveDPLL_A;
24505+ uint32_t saveDPLL_A_MD;
24506+ uint32_t saveHTOTAL_A;
24507+ uint32_t saveHBLANK_A;
24508+ uint32_t saveHSYNC_A;
24509+ uint32_t saveVTOTAL_A;
24510+ uint32_t saveVBLANK_A;
24511+ uint32_t saveVSYNC_A;
24512+ uint32_t saveDSPASTRIDE;
24513+ uint32_t saveDSPASIZE;
24514+ uint32_t saveDSPAPOS;
24515+ uint32_t saveDSPABASE;
24516+ uint32_t saveDSPASURF;
24517+ uint32_t saveFPB0;
24518+ uint32_t saveFPB1;
24519+ uint32_t saveDPLL_B;
24520+ uint32_t saveDPLL_B_MD;
24521+ uint32_t saveHTOTAL_B;
24522+ uint32_t saveHBLANK_B;
24523+ uint32_t saveHSYNC_B;
24524+ uint32_t saveVTOTAL_B;
24525+ uint32_t saveVBLANK_B;
24526+ uint32_t saveVSYNC_B;
24527+ uint32_t saveDSPBSTRIDE;
24528+ uint32_t saveDSPBSIZE;
24529+ uint32_t saveDSPBPOS;
24530+ uint32_t saveDSPBBASE;
24531+ uint32_t saveDSPBSURF;
24532+ uint32_t saveVCLK_DIVISOR_VGA0;
24533+ uint32_t saveVCLK_DIVISOR_VGA1;
24534+ uint32_t saveVCLK_POST_DIV;
24535+ uint32_t saveVGACNTRL;
24536+ uint32_t saveADPA;
24537+ uint32_t saveLVDS;
24538+ uint32_t saveDVOA;
24539+ uint32_t saveDVOB;
24540+ uint32_t saveDVOC;
24541+ uint32_t savePP_ON;
24542+ uint32_t savePP_OFF;
24543+ uint32_t savePP_CONTROL;
24544+ uint32_t savePP_CYCLE;
24545+ uint32_t savePFIT_CONTROL;
24546+ uint32_t savePaletteA[256];
24547+ uint32_t savePaletteB[256];
24548+ uint32_t saveBLC_PWM_CTL;
24549+ uint32_t saveCLOCKGATING;
24550+
24551+ /*
24552+ * USE code base register management.
24553+ */
24554+
24555+ struct drm_reg_manager use_manager;
24556+
24557+ /*
24558+ * Xhw
24559+ */
24560+
24561+ uint32_t *xhw;
24562+ struct drm_buffer_object *xhw_bo;
24563+ struct drm_bo_kmap_obj xhw_kmap;
24564+ struct list_head xhw_in;
24565+ spinlock_t xhw_lock;
24566+ atomic_t xhw_client;
24567+ struct drm_file *xhw_file;
24568+ wait_queue_head_t xhw_queue;
24569+ wait_queue_head_t xhw_caller_queue;
24570+ struct mutex xhw_mutex;
24571+ struct psb_xhw_buf *xhw_cur_buf;
24572+ int xhw_submit_ok;
24573+ int xhw_on;
24574+
24575+ /*
24576+ * Scheduling.
24577+ */
24578+
24579+ struct mutex reset_mutex;
24580+ struct mutex cmdbuf_mutex;
24581+ struct psb_scheduler scheduler;
24582+ struct psb_buflist_item *buffers;
24583+ uint32_t ta_mem_pages;
24584+ struct psb_ta_mem *ta_mem;
24585+ int force_ta_mem_load;
24586+
24587+ /*
24588+ * Watchdog
24589+ */
24590+
24591+ spinlock_t watchdog_lock;
24592+ struct timer_list watchdog_timer;
24593+ struct work_struct watchdog_wq;
24594+ struct work_struct msvdx_watchdog_wq;
24595+ int timer_available;
24596+
24597+ /*
24598+ * msvdx command queue
24599+ */
24600+ spinlock_t msvdx_lock;
24601+ struct mutex msvdx_mutex;
24602+ struct list_head msvdx_queue;
24603+ int msvdx_busy;
24604+
24605+};
24606+
24607Index: linux-2.6.28/drivers/gpu/drm/i915/i915_drv.h
24608===================================================================
24609--- linux-2.6.28.orig/drivers/gpu/drm/i915/i915_drv.h 2009-02-12 09:47:51.000000000 +0000
24610+++ linux-2.6.28/drivers/gpu/drm/i915/i915_drv.h 2009-02-11 21:23:41.000000000 +0000
24611@@ -672,6 +672,7 @@
24612 LOCK_TEST_WITH_RETURN(dev, file_priv); \
24613 } while (0)
24614
24615+#ifndef I915_READ
24616 #define I915_READ(reg) readl(dev_priv->regs + (reg))
24617 #define I915_WRITE(reg, val) writel(val, dev_priv->regs + (reg))
24618 #define I915_READ16(reg) readw(dev_priv->regs + (reg))
24619@@ -685,6 +686,7 @@
24620 writel(upper_32_bits(val), dev_priv->regs + \
24621 (reg) + 4))
24622 #endif
24623+#endif
24624 #define POSTING_READ(reg) (void)I915_READ(reg)
24625
24626 #define I915_VERBOSE 0
24627@@ -776,10 +778,15 @@
24628 (dev)->pci_device == 0x29D2)
24629
24630 #define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \
24631- IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev))
24632+ IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev) || \
24633+ IS_POULSBO(dev))
24634+
24635+#define IS_POULSBO(dev) (((dev)->pci_device == 0x8108) || \
24636+ ((dev)->pci_device == 0x8109))
24637
24638 #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
24639- IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev))
24640+ IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \
24641+ IS_POULSBO(dev))
24642
24643 #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev))
24644 #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev))
diff --git a/meta-moblin/packages/linux/linux-moblin_2.6.28+2.6.29-rc2.bb b/meta-moblin/packages/linux/linux-moblin_2.6.28+2.6.29-rc2.bb
new file mode 100644
index 0000000000..6ab0c8deee
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin_2.6.28+2.6.29-rc2.bb
@@ -0,0 +1,24 @@
1require linux-moblin.inc
2
3PR = "r2"
4PE = "1"
5
6DEFAULT_PREFERENCE = "-1"
7DEFAULT_PREFERENCE_netbook = "1"
8DEFAULT_PREFERENCE_menlow = "1"
9
10SRC_URI = "${KERNELORG_MIRROR}pub/linux/kernel/v2.6/linux-2.6.28.tar.bz2 \
11 ${KERNELORG_MIRROR}pub/linux/kernel/v2.6/testing/patch-2.6.29-rc2.bz2;patch=1 \
12 file://0001-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch;patch=1 \
13 file://0002-fastboot-remove-wait-for-all-devices-before-mounti.patch;patch=1 \
14 file://0003-fastboot-remove-duplicate-unpack_to_rootfs.patch;patch=1 \
15 file://0004-superreadahead-patch.patch;patch=1 \
16 file://0005-fastboot-async-enable-default.patch;patch=1 \
17 file://0006-Revert-drm-i915-GEM-on-PAE-has-problems-disable.patch;patch=1 \
18 file://0007-acer-error-msg.patch;patch=1 \
19 file://defconfig-menlow \
20 file://defconfig-netbook"
21
22SRC_URI_append_menlow = " file://psb-driver.patch;patch=1"
23
24S = "${WORKDIR}/linux-2.6.28"