diff --git a/.gitignore b/.gitignore index 12d63e1fd..03bacc779 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ -*.xz +clog *.bz2 +*.rpm +*.orig +kernel-2.6.*/ +kernel-3.*/ diff --git a/0001-EHCI-don-t-rescan-interrupt-QHs-needlessly.patch b/0001-EHCI-don-t-rescan-interrupt-QHs-needlessly.patch new file mode 100644 index 000000000..499c31a02 --- /dev/null +++ b/0001-EHCI-don-t-rescan-interrupt-QHs-needlessly.patch @@ -0,0 +1,95 @@ +From 1729d20333739e6cc23023e405fe8668f08117a2 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 17 May 2011 10:40:51 -0400 +Subject: [PATCH 1/2] EHCI: don't rescan interrupt QHs needlessly + +This patch (as1466) speeds up processing of ehci-hcd's periodic list. +The existing code will pointlessly rescan an interrupt endpoint queue +each time it encounters the queue's QH in the periodic list, which can +happen quite a few times if the endpoint's period is low. On some +embedded systems, this useless overhead can waste so much time that +the driver falls hopelessly behind and loses events. + +The patch introduces a "periodic_stamp" variable, which gets +incremented each time scan_periodic() runs and each time the scan +advances to a new frame. If the corresponding stamp in an interrupt +QH is equal to the current periodic_stamp, we assume the QH has +already been scanned and skip over it. Otherwise we scan the QH as +usual, and if none of its URBs have completed then we store the +current periodic_stamp in the QH's stamp, preventing it from being +scanned again. + +Signed-off-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/ehci-q.c | 1 + + drivers/usb/host/ehci-sched.c | 14 ++++++++++---- + drivers/usb/host/ehci.h | 1 + + 3 files changed, 12 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c +index ed8db6a..0079610 100644 +--- a/drivers/usb/host/ehci-q.c ++++ b/drivers/usb/host/ehci-q.c +@@ -826,6 +826,7 @@ qh_make ( + is_input, 0, + hb_mult(maxp) * max_packet(maxp))); + qh->start = NO_FRAME; ++ qh->stamp = ehci->periodic_stamp; + + if (urb->dev->speed == USB_SPEED_HIGH) { + qh->c_usecs = 0; +diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c +index a530856..9e54e85 100644 +--- a/drivers/usb/host/ehci-sched.c ++++ b/drivers/usb/host/ehci-sched.c +@@ -2351,6 +2351,7 @@ scan_periodic (struct ehci_hcd *ehci) + } + clock %= mod; + clock_frame = clock >> 3; ++ ++ehci->periodic_stamp; + + for (;;) { + union ehci_shadow q, *q_p; +@@ -2379,10 +2380,14 @@ restart: + temp.qh = qh_get (q.qh); + type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next); + q = q.qh->qh_next; +- modified = qh_completions (ehci, temp.qh); +- if (unlikely(list_empty(&temp.qh->qtd_list) || +- temp.qh->needs_rescan)) +- intr_deschedule (ehci, temp.qh); ++ if (temp.qh->stamp != ehci->periodic_stamp) { ++ modified = qh_completions(ehci, temp.qh); ++ if (!modified) ++ temp.qh->stamp = ehci->periodic_stamp; ++ if (unlikely(list_empty(&temp.qh->qtd_list) || ++ temp.qh->needs_rescan)) ++ intr_deschedule(ehci, temp.qh); ++ } + qh_put (temp.qh); + break; + case Q_TYPE_FSTN: +@@ -2515,6 +2520,7 @@ restart: + if (ehci->clock_frame != clock_frame) { + free_cached_lists(ehci); + ehci->clock_frame = clock_frame; ++ ++ehci->periodic_stamp; + } + } else { + now_uframe++; +diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h +index c702e4b..c2c2f9d 100644 +--- a/drivers/usb/host/ehci.h ++++ b/drivers/usb/host/ehci.h +@@ -117,6 +117,7 @@ struct ehci_hcd { /* one per controller */ + struct timer_list watchdog; + unsigned long actions; + unsigned stamp; ++ unsigned periodic_stamp; + unsigned random_frame; + unsigned long next_statechange; + ktime_t last_periodic_enable; +-- +1.7.6 + diff --git a/0002-USB-EHCI-go-back-to-using-the-system-clock-for-QH-un.patch b/0002-USB-EHCI-go-back-to-using-the-system-clock-for-QH-un.patch new file mode 100644 index 000000000..404ece19d --- /dev/null +++ b/0002-USB-EHCI-go-back-to-using-the-system-clock-for-QH-un.patch @@ -0,0 +1,217 @@ +From e8b80056d07bc849777d032bc699a59cc28f9ddb Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 5 Jul 2011 12:34:05 -0400 +Subject: [PATCH 2/2] USB: EHCI: go back to using the system clock for QH + unlinks + +This patch (as1477) fixes a problem affecting a few types of EHCI +controller. Contrary to what one might expect, these controllers +automatically stop their internal frame counter when no ports are +enabled. Since ehci-hcd currently relies on the frame counter for +determining when it should unlink QHs from the async schedule, those +controllers run into trouble: The frame counter stops and the QHs +never get unlinked. + +Some systems have also experienced other problems traced back to +commit b963801164618e25fbdc0cd452ce49c3628b46c8 (USB: ehci-hcd unlink +speedups), which made the original switch from using the system clock +to using the frame counter. It never became clear what the reason was +for these problems, but evidently it is related to use of the frame +counter. + +To fix all these problems, this patch more or less reverts that commit +and goes back to using the system clock. But this can't be done +cleanly because other changes have since been made to the scan_async() +subroutine. One of these changes involved the tricky logic that tries +to avoid rescanning QHs that have already been seen when the scanning +loop is restarted, which happens whenever an URB is given back. +Switching back to clock-based unlinks would make this logic even more +complicated. + +Therefore the new code doesn't rescan the entire async list whenever a +giveback occurs. Instead it rescans only the current QH and continues +on from there. This requires the use of a separate pointer to keep +track of the next QH to scan, since the current QH may be unlinked +while the scanning is in progress. That new pointer must be global, +so that it can be adjusted forward whenever the _next_ QH gets +unlinked. (uhci-hcd uses this same trick.) + +Simplification of the scanning loop removes a level of indentation, +which accounts for the size of the patch. The amount of code changed +is relatively small, and it isn't exactly a reversion of the +b963801164 commit. + +This fixes Bugzilla #32432. + +Signed-off-by: Alan Stern +CC: +Tested-by: Matej Kenda +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/ehci-hcd.c | 8 ++--- + drivers/usb/host/ehci-q.c | 82 +++++++++++++++++++++---------------------- + drivers/usb/host/ehci.h | 3 +- + 3 files changed, 45 insertions(+), 48 deletions(-) + +diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c +index 761bbb3..8e5b995 100644 +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -83,7 +83,8 @@ static const char hcd_name [] = "ehci_hcd"; + #define EHCI_IAA_MSECS 10 /* arbitrary */ + #define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ + #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ +-#define EHCI_SHRINK_FRAMES 5 /* async qh unlink delay */ ++#define EHCI_SHRINK_JIFFIES (DIV_ROUND_UP(HZ, 200) + 1) ++ /* 200-ms async qh unlink delay */ + + /* Initial IRQ latency: faster than hw default */ + static int log2_irq_thresh = 0; // 0 to 6 +@@ -138,10 +139,7 @@ timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action) + break; + /* case TIMER_ASYNC_SHRINK: */ + default: +- /* add a jiffie since we synch against the +- * 8 KHz uframe counter. +- */ +- t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1; ++ t = EHCI_SHRINK_JIFFIES; + break; + } + mod_timer(&ehci->watchdog, t + jiffies); +diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c +index 0079610..a664203 100644 +--- a/drivers/usb/host/ehci-q.c ++++ b/drivers/usb/host/ehci-q.c +@@ -1226,6 +1226,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) + + prev->hw->hw_next = qh->hw->hw_next; + prev->qh_next = qh->qh_next; ++ if (ehci->qh_scan_next == qh) ++ ehci->qh_scan_next = qh->qh_next.qh; + wmb (); + + /* If the controller isn't running, we don't have to wait for it */ +@@ -1251,53 +1253,49 @@ static void scan_async (struct ehci_hcd *ehci) + struct ehci_qh *qh; + enum ehci_timer_action action = TIMER_IO_WATCHDOG; + +- ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index); + timer_action_done (ehci, TIMER_ASYNC_SHRINK); +-rescan: + stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state); +- qh = ehci->async->qh_next.qh; +- if (likely (qh != NULL)) { +- do { +- /* clean any finished work for this qh */ +- if (!list_empty(&qh->qtd_list) && (stopped || +- qh->stamp != ehci->stamp)) { +- int temp; +- +- /* unlinks could happen here; completion +- * reporting drops the lock. rescan using +- * the latest schedule, but don't rescan +- * qhs we already finished (no looping) +- * unless the controller is stopped. +- */ +- qh = qh_get (qh); +- qh->stamp = ehci->stamp; +- temp = qh_completions (ehci, qh); +- if (qh->needs_rescan) +- unlink_async(ehci, qh); +- qh_put (qh); +- if (temp != 0) { +- goto rescan; +- } +- } + +- /* unlink idle entries, reducing DMA usage as well +- * as HCD schedule-scanning costs. delay for any qh +- * we just scanned, there's a not-unusual case that it +- * doesn't stay idle for long. +- * (plus, avoids some kind of re-activation race.) ++ ehci->qh_scan_next = ehci->async->qh_next.qh; ++ while (ehci->qh_scan_next) { ++ qh = ehci->qh_scan_next; ++ ehci->qh_scan_next = qh->qh_next.qh; ++ rescan: ++ /* clean any finished work for this qh */ ++ if (!list_empty(&qh->qtd_list)) { ++ int temp; ++ ++ /* ++ * Unlinks could happen here; completion reporting ++ * drops the lock. That's why ehci->qh_scan_next ++ * always holds the next qh to scan; if the next qh ++ * gets unlinked then ehci->qh_scan_next is adjusted ++ * in start_unlink_async(). + */ +- if (list_empty(&qh->qtd_list) +- && qh->qh_state == QH_STATE_LINKED) { +- if (!ehci->reclaim && (stopped || +- ((ehci->stamp - qh->stamp) & 0x1fff) +- >= EHCI_SHRINK_FRAMES * 8)) +- start_unlink_async(ehci, qh); +- else +- action = TIMER_ASYNC_SHRINK; +- } ++ qh = qh_get(qh); ++ temp = qh_completions(ehci, qh); ++ if (qh->needs_rescan) ++ unlink_async(ehci, qh); ++ qh->unlink_time = jiffies + EHCI_SHRINK_JIFFIES; ++ qh_put(qh); ++ if (temp != 0) ++ goto rescan; ++ } + +- qh = qh->qh_next.qh; +- } while (qh); ++ /* unlink idle entries, reducing DMA usage as well ++ * as HCD schedule-scanning costs. delay for any qh ++ * we just scanned, there's a not-unusual case that it ++ * doesn't stay idle for long. ++ * (plus, avoids some kind of re-activation race.) ++ */ ++ if (list_empty(&qh->qtd_list) ++ && qh->qh_state == QH_STATE_LINKED) { ++ if (!ehci->reclaim && (stopped || ++ time_after_eq(jiffies, qh->unlink_time))) ++ start_unlink_async(ehci, qh); ++ else ++ action = TIMER_ASYNC_SHRINK; ++ } + } + if (action == TIMER_ASYNC_SHRINK) + timer_action (ehci, TIMER_ASYNC_SHRINK); +diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h +index c2c2f9d..23d9a5e 100644 +--- a/drivers/usb/host/ehci.h ++++ b/drivers/usb/host/ehci.h +@@ -74,6 +74,7 @@ struct ehci_hcd { /* one per controller */ + /* async schedule support */ + struct ehci_qh *async; + struct ehci_qh *reclaim; ++ struct ehci_qh *qh_scan_next; + unsigned scanning : 1; + + /* periodic schedule support */ +@@ -116,7 +117,6 @@ struct ehci_hcd { /* one per controller */ + struct timer_list iaa_watchdog; + struct timer_list watchdog; + unsigned long actions; +- unsigned stamp; + unsigned periodic_stamp; + unsigned random_frame; + unsigned long next_statechange; +@@ -337,6 +337,7 @@ struct ehci_qh { + struct ehci_qh *reclaim; /* next to reclaim */ + + struct ehci_hcd *ehci; ++ unsigned long unlink_time; + + /* + * Do NOT use atomic operations for QH refcounting. On some CPUs +-- +1.7.6 + diff --git a/Ecryptfs-Add-mount-option-to-check-uid-of-device-bei.patch b/Ecryptfs-Add-mount-option-to-check-uid-of-device-bei.patch new file mode 100644 index 000000000..1d67ff8b3 --- /dev/null +++ b/Ecryptfs-Add-mount-option-to-check-uid-of-device-bei.patch @@ -0,0 +1,130 @@ +From ed62f63919f93dcb040109959ee19983eda8ea84 Mon Sep 17 00:00:00 2001 +From: John Johansen +Date: Thu, 15 Sep 2011 12:48:12 -0400 +Subject: [PATCH] Ecryptfs: Add mount option to check uid of device being + mounted = expect uid + +Close a TOCTOU race for mounts done via ecryptfs-mount-private. The mount +source (device) can be raced when the ownership test is done in userspace. +Provide Ecryptfs a means to force the uid check at mount time. + +Signed-off-by: John Johansen +Cc: +Signed-off-by: Tyler Hicks + +Backported to 2.6.35.14 by Josh Boyer +--- + fs/ecryptfs/main.c | 27 ++++++++++++++++++++++----- + 1 files changed, 22 insertions(+), 5 deletions(-) + +diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c +index cbd4e18..c249d14 100644 +--- a/fs/ecryptfs/main.c ++++ b/fs/ecryptfs/main.c +@@ -208,7 +208,7 @@ enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, + ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata, + ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig, + ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes, +- ecryptfs_opt_unlink_sigs, ecryptfs_opt_err }; ++ ecryptfs_opt_unlink_sigs, ecryptfs_opt_check_dev_ruid, ecryptfs_opt_err }; + + static const match_table_t tokens = { + {ecryptfs_opt_sig, "sig=%s"}, +@@ -223,6 +223,7 @@ static const match_table_t tokens = { + {ecryptfs_opt_fn_cipher, "ecryptfs_fn_cipher=%s"}, + {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"}, + {ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"}, ++ {ecryptfs_opt_check_dev_ruid, "ecryptfs_check_dev_ruid"}, + {ecryptfs_opt_err, NULL} + }; + +@@ -266,6 +267,7 @@ static void ecryptfs_init_mount_crypt_stat( + * ecryptfs_parse_options + * @sb: The ecryptfs super block + * @options: The options pased to the kernel ++ * @check_ruid: set to 1 if device uid should be checked against the ruid + * + * Parse mount options: + * debug=N - ecryptfs_verbosity level for debug output +@@ -281,7 +283,7 @@ static void ecryptfs_init_mount_crypt_stat( + * + * Returns zero on success; non-zero on error + */ +-static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) ++static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, uid_t *check_ruid) + { + char *p; + int rc = 0; +@@ -306,6 +308,8 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) + char *cipher_key_bytes_src; + char *fn_cipher_key_bytes_src; + ++ *check_ruid = 0; ++ + if (!options) { + rc = -EINVAL; + goto out; +@@ -406,6 +410,9 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) + case ecryptfs_opt_unlink_sigs: + mount_crypt_stat->flags |= ECRYPTFS_UNLINK_SIGS; + break; ++ case ecryptfs_opt_check_dev_ruid: ++ *check_ruid = 1; ++ break; + case ecryptfs_opt_err: + default: + printk(KERN_WARNING +@@ -494,7 +501,7 @@ static struct file_system_type ecryptfs_fs_type; + * ecryptfs_interpose to create our initial inode and super block + * struct. + */ +-static int ecryptfs_read_super(struct super_block *sb, const char *dev_name) ++static int ecryptfs_read_super(struct super_block *sb, const char *dev_name, uid_t check_ruid) + { + struct path path; + int rc; +@@ -511,6 +518,15 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name) + "known incompatibilities\n"); + goto out_free; + } ++ ++ if (check_ruid && path.dentry->d_inode->i_uid != current_uid()) { ++ rc = -EPERM; ++ printk(KERN_ERR "Mount of device (uid: %d) not owned by " ++ "requested user (uid: %d)\n", ++ path.dentry->d_inode->i_uid, current_uid()); ++ goto out_free; ++ } ++ + ecryptfs_set_superblock_lower(sb, path.dentry->d_sb); + sb->s_maxbytes = path.dentry->d_sb->s_maxbytes; + sb->s_blocksize = path.dentry->d_sb->s_blocksize; +@@ -549,6 +565,7 @@ static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags, + struct ecryptfs_dentry_info *root_info; + const char *err = "Getting sb failed"; + int rc; ++ uid_t check_ruid; + + sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); + if (!sbi) { +@@ -556,7 +573,7 @@ static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags, + goto out; + } + +- rc = ecryptfs_parse_options(sbi, raw_data); ++ rc = ecryptfs_parse_options(sbi, raw_data, &check_ruid); + if (rc) { + err = "Error parsing options"; + goto out; +@@ -601,7 +618,7 @@ static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags, + /* ->kill_sb() will take care of root_info */ + ecryptfs_set_dentry_private(s->s_root, root_info); + s->s_flags |= MS_ACTIVE; +- rc = ecryptfs_read_super(s, dev_name); ++ rc = ecryptfs_read_super(s, dev_name, check_ruid); + if (rc) { + deactivate_locked_super(s); + err = "Reading sb failed"; +-- +1.7.6 + diff --git a/KEYS-Fix-a-NULL-pointer-deref-in-the-user-defined-ke.patch b/KEYS-Fix-a-NULL-pointer-deref-in-the-user-defined-ke.patch new file mode 100644 index 000000000..46755df78 --- /dev/null +++ b/KEYS-Fix-a-NULL-pointer-deref-in-the-user-defined-ke.patch @@ -0,0 +1,71 @@ +From f8789858be5c1b13543040b74d978ea448461155 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Tue, 15 Nov 2011 22:09:45 +0000 +Subject: [PATCH] KEYS: Fix a NULL pointer deref in the user-defined key type + +commit 9f35a33b8d06263a165efe3541d9aa0cdbd70b3b upstream. + +Fix a NULL pointer deref in the user-defined key type whereby updating a +negative key into a fully instantiated key will cause an oops to occur +when the code attempts to free the non-existent old payload. + +This results in an oops that looks something like the following: + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 + IP: [] __call_rcu+0x11/0x13e + PGD 3391d067 PUD 3894a067 PMD 0 + Oops: 0002 [#1] SMP + CPU 1 + Pid: 4354, comm: keyctl Not tainted 3.1.0-fsdevel+ #1140 /DG965RY + RIP: 0010:[] [] __call_rcu+0x11/0x13e + RSP: 0018:ffff88003d591df8 EFLAGS: 00010246 + RAX: 0000000000000000 RBX: 0000000000000000 RCX: 000000000000006e + RDX: ffffffff8161d0c0 RSI: 0000000000000000 RDI: 0000000000000000 + RBP: ffff88003d591e18 R08: 0000000000000000 R09: ffffffff8152fa6c + R10: 0000000000000000 R11: 0000000000000300 R12: ffff88003b8f9538 + R13: ffffffff8161d0c0 R14: ffff88003b8f9d50 R15: ffff88003c69f908 + FS: 00007f97eb18c720(0000) GS:ffff88003bd00000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000008 CR3: 000000003d47a000 CR4: 00000000000006e0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 + Process keyctl (pid: 4354, threadinfo ffff88003d590000, task ffff88003c78a040) + Stack: + ffff88003e0ffde0 ffff88003b8f9538 0000000000000001 ffff88003b8f9d50 + ffff88003d591e28 ffffffff810860f0 ffff88003d591e68 ffffffff8117bfea + ffff88003d591e68 ffffffff00000000 ffff88003e0ffde1 ffff88003e0ffde0 + Call Trace: + [] call_rcu_sched+0x10/0x12 + [] user_update+0x8d/0xa2 + [] key_create_or_update+0x236/0x270 + [] sys_add_key+0x123/0x17e + [] system_call_fastpath+0x16/0x1b + +Signed-off-by: David Howells +Acked-by: Jeff Layton +Acked-by: Neil Horman +Acked-by: Steve Dickson +Acked-by: James Morris +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + security/keys/user_defined.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c +index e9aa079..d6781b9 100644 +--- a/security/keys/user_defined.c ++++ b/security/keys/user_defined.c +@@ -119,7 +119,8 @@ int user_update(struct key *key, const void *data, size_t datalen) + key->expiry = 0; + } + +- call_rcu(&zap->rcu, user_update_rcu_disposal); ++ if (zap) ++ call_rcu(&zap->rcu, user_update_rcu_disposal); + + error: + return ret; +-- +1.7.7.1 + diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..e8d6a55e8 --- /dev/null +++ b/Makefile @@ -0,0 +1,303 @@ +# Makefile for source rpm: kernel +SPECFILE := kernel.spec + +# use noarch for make prep instead of the current CPU +# noarch creates and checks all config files not just the current one, +# in addition "i386" isn't a valid kernel target +PREPARCH = noarch + +# we only check the .sign signatures +UPSTREAM_CHECKS = sign + +.PHONY: help +help: +%: + @echo "Try fedpkg $@ or something like that" + @exit 1 + +include Makefile.config + +ifndef KVERSION +KVERSION := $(shell awk '$$1 == "%define" && $$2 == "base_sublevel" { \ + print "2.6." $$3 \ + }' $(SPECFILE)) +endif + +prep: + fedpkg -v prep --arch=$(PREPARCH) + +extremedebug: + @perl -pi -e 's/# CONFIG_DEBUG_PAGEALLOC is not set/CONFIG_DEBUG_PAGEALLOC=y/' config-nodebug + +debug: + @perl -pi -e 's/# CONFIG_SLUB_DEBUG_ON is not set/CONFIG_SLUB_DEBUG_ON=y/' config-nodebug + @perl -pi -e 's/# CONFIG_LOCK_STAT is not set/CONFIG_LOCK_STAT=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_STACK_USAGE is not set/CONFIG_DEBUG_STACK_USAGE=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_SLAB is not set/CONFIG_DEBUG_SLAB=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_MUTEXES is not set/CONFIG_DEBUG_MUTEXES=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_RT_MUTEXES is not set/CONFIG_DEBUG_RT_MUTEXES=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_RWSEMS is not set/CONFIG_DEBUG_RWSEMS=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_LOCK_ALLOC is not set/CONFIG_DEBUG_LOCK_ALLOC=y/' config-nodebug + @perl -pi -e 's/# CONFIG_PROVE_LOCKING is not set/CONFIG_PROVE_LOCKING=y/' config-nodebug + @perl -pi -e 's/# CONFIG_PROVE_RCU is not set/CONFIG_PROVE_RCU=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_SPINLOCK is not set/CONFIG_DEBUG_SPINLOCK=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_VM is not set/CONFIG_DEBUG_VM=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_SLEEP_IN_IRQ is not set/CONFIG_DEBUG_SLEEP_IN_IRQ=y/' config-nodebug + @perl -pi -e 's/# CONFIG_FAULT_INJECTION is not set/CONFIG_FAULT_INJECTION=y/' config-nodebug + @perl -pi -e 's/# CONFIG_FAILSLAB is not set/CONFIG_FAILSLAB=y/' config-nodebug + @perl -pi -e 's/# CONFIG_FAIL_PAGE_ALLOC is not set/CONFIG_FAIL_PAGE_ALLOC=y/' config-nodebug + @perl -pi -e 's/# CONFIG_FAIL_IO_TIMEOUT is not set/CONFIG_FAIL_IO_TIMEOUT=y/' config-nodebug + @perl -pi -e 's/# CONFIG_FAIL_MAKE_REQUEST is not set/CONFIG_FAIL_MAKE_REQUEST=y/' config-nodebug + @perl -pi -e 's/# CONFIG_FAULT_INJECTION_DEBUG_FS is not set/CONFIG_FAULT_INJECTION_DEBUG_FS=y/' config-nodebug + @perl -pi -e 's/# CONFIG_FAULT_INJECTION_STACKTRACE_FILTER is not set/CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_SG is not set/CONFIG_DEBUG_SG=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_WRITECOUNT is not set/CONFIG_DEBUG_WRITECOUNT=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_OBJECTS is not set/CONFIG_DEBUG_OBJECTS=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_OBJECTS_FREE is not set/CONFIG_DEBUG_OBJECTS_FREE=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_OBJECTS_TIMERS is not set/CONFIG_DEBUG_OBJECTS_TIMERS=y/' config-nodebug + @perl -pi -e 's/# CONFIG_X86_PTDUMP is not set/CONFIG_X86_PTDUMP=y/' config-nodebug + @perl -pi -e 's/# CONFIG_CAN_DEBUG_DEVICES is not set/CONFIG_CAN_DEBUG_DEVICES=y/' config-nodebug + @perl -pi -e 's/# CONFIG_MODULE_FORCE_UNLOAD is not set/CONFIG_MODULE_FORCE_UNLOAD=y/' config-nodebug + @perl -pi -e 's/# CONFIG_SYSCTL_SYSCALL_CHECK is not set/CONFIG_SYSCTL_SYSCALL_CHECK=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_NOTIFIERS is not set/CONFIG_DEBUG_NOTIFIERS=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DMA_API_DEBUG is not set/CONFIG_DMA_API_DEBUG=y/' config-nodebug + @perl -pi -e 's/# CONFIG_PM_TEST_SUSPEND is not set/CONFIG_PM_TEST_SUSPEND=y/' config-generic + @perl -pi -e 's/# CONFIG_PM_ADVANCED_DEBUG is not set/CONFIG_PM_ADVANCED_DEBUG=y/' config-generic + @perl -pi -e 's/# CONFIG_BOOT_TRACER is not set/CONFIG_BOOT_TRACER=y/' config-generic + @perl -pi -e 's/# CONFIG_B43_DEBUG is not set/CONFIG_B43_DEBUG=y/' config-generic + @perl -pi -e 's/# CONFIG_B43LEGACY_DEBUG is not set/CONFIG_B43LEGACY_DEBUG=y/' config-generic + @perl -pi -e 's/# CONFIG_MMIOTRACE is not set/CONFIG_MMIOTRACE=y/' config-nodebug + @perl -pi -e 's/CONFIG_STRIP_ASM_SYMS=y/# CONFIG_STRIP_ASM_SYMS is not set/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_CREDENTIALS is not set/CONFIG_DEBUG_CREDENTIALS=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set/CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y/' config-nodebug + @perl -pi -e 's/# CONFIG_ACPI_DEBUG is not set/CONFIG_ACPI_DEBUG=y/' config-nodebug + @perl -pi -e 's/# CONFIG_EXT4_DEBUG is not set/CONFIG_EXT4_DEBUG=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_PERF_USE_VMALLOC is not set/CONFIG_DEBUG_PERF_USE_VMALLOC=y/' config-nodebug + @perl -pi -e 's/# CONFIG_JBD2_DEBUG is not set/CONFIG_JBD2_DEBUG=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_CFQ_IOSCHED is not set/CONFIG_DEBUG_CFQ_IOSCHED=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DRBD_FAULT_INJECTION is not set/CONFIG_DRBD_FAULT_INJECTION=y/' config-nodebug + @perl -pi -e 's/# CONFIG_ATH_DEBUG is not set/CONFIG_ATH_DEBUG=y/' config-nodebug + @perl -pi -e 's/# CONFIG_IWLWIFI_DEVICE_TRACING is not set/CONFIG_IWLWIFI_DEVICE_TRACING=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_OBJECTS_WORK is not set/CONFIG_DEBUG_OBJECTS_WORK=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set/CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DMADEVICES_DEBUG is not set/CONFIG_DMADEVICES_DEBUG=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DMADEVICES_VDEBUG is not set/CONFIG_DMADEVICES_VDEBUG=y/' config-nodebug + @perl -pi -e 's/# CONFIG_CEPH_FS_PRETTYDEBUG is not set/CONFIG_CEPH_FS_PRETTYDEBUG=y/' config-nodebug + @perl -pi -e 's/# CONFIG_QUOTA_DEBUG is not set/CONFIG_QUOTA_DEBUG=y/' config-nodebug + @perl -pi -e 's/# CONFIG_KGDB_KDB is not set/CONFIG_KGDB_KDB=y/' config-nodebug + @perl -pi -e 's/# CONFIG_KDB_KEYBOARD is not set/CONFIG_KDB_KEYBOARD=y/' config-nodebug + @perl -pi -e 's/# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set/CONFIG_CPU_NOTIFIER_ERROR_INJECT=m/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_PER_CPU_MAPS is not set/CONFIG_DEBUG_PER_CPU_MAPS=y/' config-nodebug + #@perl -pi -e 's/# CONFIG_PCI_DEFAULT_USE_CRS is not set/CONFIG_PCI_DEFAULT_USE_CRS=y/' config-nodebug + + @# just in case we're going from extremedebug -> debug + @perl -pi -e 's/CONFIG_DEBUG_PAGEALLOC=y/# CONFIG_DEBUG_PAGEALLOC is not set/' config-nodebug + + @perl -pi -e 's/CONFIG_NR_CPUS=256/CONFIG_NR_CPUS=512/' config-x86_64-generic + + @perl -pi -e 's/^%define debugbuildsenabled 1/%define debugbuildsenabled 0/' kernel.spec + @perl -pi -e 's/^%define rawhide_skip_docs 0/%define rawhide_skip_docs 1/' kernel.spec + +nodebuginfo: + @perl -pi -e 's/^%define with_debuginfo %\{\?_without_debuginfo: 0\} %\{\?\!_without_debuginfo: 1\}/%define with_debuginfo %\{\?_without_debuginfo: 0\} %\{\?\!_without_debuginfo: 0\}/' kernel.spec +nodebug: release + @perl -pi -e 's/^%define debugbuildsenabled 1/%define debugbuildsenabled 0/' kernel.spec +release: + @perl -pi -e 's/CONFIG_SLUB_DEBUG_ON=y/# CONFIG_SLUB_DEBUG_ON is not set/' config-nodebug + @perl -pi -e 's/CONFIG_LOCK_STAT=y/# CONFIG_LOCK_STAT is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_STACK_USAGE=y/# CONFIG_DEBUG_STACK_USAGE is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_SLAB=y/# CONFIG_DEBUG_SLAB is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_MUTEXES=y/# CONFIG_DEBUG_MUTEXES is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_RT_MUTEXES=y/# CONFIG_DEBUG_RT_MUTEXES is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_RWSEMS=y/# CONFIG_DEBUG_RWSEMS is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_LOCK_ALLOC=y/# CONFIG_DEBUG_LOCK_ALLOC is not set/' config-nodebug + @perl -pi -e 's/CONFIG_PROVE_LOCKING=y/# CONFIG_PROVE_LOCKING is not set/' config-nodebug + @perl -pi -e 's/CONFIG_PROVE_RCU=y/# CONFIG_PROVE_RCU is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_SPINLOCK=y/# CONFIG_DEBUG_SPINLOCK is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_VM=y/# CONFIG_DEBUG_VM is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_SLEEP_IN_IRQ=y/# CONFIG_DEBUG_SLEEP_IN_IRQ is not set/' config-nodebug + @perl -pi -e 's/CONFIG_FAULT_INJECTION=y/# CONFIG_FAULT_INJECTION is not set/' config-nodebug + @perl -pi -e 's/CONFIG_FAILSLAB=y/# CONFIG_FAILSLAB is not set/' config-nodebug + @perl -pi -e 's/CONFIG_FAIL_PAGE_ALLOC=y/# CONFIG_FAIL_PAGE_ALLOC is not set/' config-nodebug + @perl -pi -e 's/CONFIG_FAIL_IO_TIMEOUT=y/# CONFIG_FAIL_IO_TIMEOUT is not set/' config-nodebug + @perl -pi -e 's/CONFIG_FAIL_MAKE_REQUEST=y/# CONFIG_FAIL_MAKE_REQUEST is not set/' config-nodebug + @perl -pi -e 's/CONFIG_FAULT_INJECTION_DEBUG_FS=y/# CONFIG_FAULT_INJECTION_DEBUG_FS is not set/' config-nodebug + @perl -pi -e 's/CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y/# CONFIG_FAULT_INJECTION_STACKTRACE_FILTER is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_SG=y/# CONFIG_DEBUG_SG is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_WRITECOUNT=y/# CONFIG_DEBUG_WRITECOUNT is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_OBJECTS=y/# CONFIG_DEBUG_OBJECTS is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_OBJECTS_FREE=y/# CONFIG_DEBUG_OBJECTS_FREE is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_OBJECTS_TIMERS=y/# CONFIG_DEBUG_OBJECTS_TIMERS is not set/' config-nodebug + @perl -pi -e 's/CONFIG_X86_PTDUMP=y/# CONFIG_X86_PTDUMP is not set/' config-nodebug + @perl -pi -e 's/CONFIG_CAN_DEBUG_DEVICES=y/# CONFIG_CAN_DEBUG_DEVICES is not set/' config-nodebug + @perl -pi -e 's/CONFIG_MODULE_FORCE_UNLOAD=y/# CONFIG_MODULE_FORCE_UNLOAD is not set/' config-nodebug + @perl -pi -e 's/CONFIG_SYSCTL_SYSCALL_CHECK=y/# CONFIG_SYSCTL_SYSCALL_CHECK is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_NOTIFIERS=y/# CONFIG_DEBUG_NOTIFIERS is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DMA_API_DEBUG=y/# CONFIG_DMA_API_DEBUG is not set/' config-nodebug + @perl -pi -e 's/CONFIG_PM_TEST_SUSPEND=y/#\ CONFIG_PM_TEST_SUSPEND\ is\ not\ set/' config-generic + @perl -pi -e 's/CONFIG_PM_ADVANCED_DEBUG=y/#\ CONFIG_PM_ADVANCED_DEBUG\ is\ not\ set/' config-generic + @perl -pi -e 's/CONFIG_BOOT_TRACER=y/#\ CONFIG_BOOT_TRACER\ is\ not\ set/' config-generic + @perl -pi -e 's/CONFIG_B43_DEBUG=y/# CONFIG_B43_DEBUG is not set/' config-generic + @perl -pi -e 's/CONFIG_B43LEGACY_DEBUG=y/# CONFIG_B43LEGACY_DEBUG is not set/' config-generic + @perl -pi -e 's/CONFIG_MMIOTRACE=y/# CONFIG_MMIOTRACE is not set/' config-nodebug + @perl -pi -e 's/# CONFIG_STRIP_ASM_SYMS is not set/CONFIG_STRIP_ASM_SYMS=y/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_CREDENTIALS=y/# CONFIG_DEBUG_CREDENTIALS is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y/# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set/' config-nodebug + @perl -pi -e 's/CONFIG_ACPI_DEBUG=y/# CONFIG_ACPI_DEBUG is not set/' config-nodebug + @perl -pi -e 's/CONFIG_EXT4_DEBUG=y/# CONFIG_EXT4_DEBUG is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_PERF_USE_VMALLOC=y/# CONFIG_DEBUG_PERF_USE_VMALLOC is not set/' config-nodebug + @perl -pi -e 's/CONFIG_JBD2_DEBUG=y/# CONFIG_JBD2_DEBUG is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_CFQ_IOSCHED=y/# CONFIG_DEBUG_CFQ_IOSCHED is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DRBD_FAULT_INJECTION=y/# CONFIG_DRBD_FAULT_INJECTION is not set/' config-nodebug + @perl -pi -e 's/CONFIG_ATH_DEBUG=y/# CONFIG_ATH_DEBUG is not set/' config-nodebug + @perl -pi -e 's/CONFIG_IWLWIFI_DEVICE_TRACING=y/# CONFIG_IWLWIFI_DEVICE_TRACING is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_OBJECTS_WORK=y/# CONFIG_DEBUG_OBJECTS_WORK is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y/# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DMADEVICES_DEBUG=y/# CONFIG_DMADEVICES_DEBUG is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DMADEVICES_VDEBUG=y/# CONFIG_DMADEVICES_VDEBUG is not set/' config-nodebug + @perl -pi -e 's/CONFIG_CEPH_FS_PRETTYDEBUG=y/# CONFIG_CEPH_FS_PRETTYDEBUG is not set/' config-nodebug + @perl -pi -e 's/CONFIG_QUOTA_DEBUG=y/# CONFIG_QUOTA_DEBUG is not set/' config-nodebug + @perl -pi -e 's/CONFIG_CPU_NOTIFIER_ERROR_INJECT=m/# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set/' config-nodebug + #@perl -pi -e 's/CONFIG_KGDB_KDB=y/# CONFIG_KGDB_KDB is not set/' config-nodebug + #@perl -pi -e 's/CONFIG_KDB_KEYBOARD=y/# CONFIG_KDB_KEYBOARD is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_PER_CPU_MAPS=y/# CONFIG_DEBUG_PER_CPU_MAPS is not set/' config-nodebug + #@perl -pi -e 's/CONFIG_PCI_DEFAULT_USE_CRS=y/# CONFIG_PCI_DEFAULT_USE_CRS is not set/' config-nodebug + + @perl -pi -e 's/CONFIG_DEBUG_PAGEALLOC=y/# CONFIG_DEBUG_PAGEALLOC is not set/' config-debug + @perl -pi -e 's/CONFIG_DEBUG_PAGEALLOC=y/# CONFIG_DEBUG_PAGEALLOC is not set/' config-nodebug + + @perl -pi -e 's/CONFIG_NR_CPUS=512/CONFIG_NR_CPUS=256/' config-x86_64-generic + + @perl -pi -e 's/^%define debugbuildsenabled 0/%define debugbuildsenabled 1/' kernel.spec + @perl -pi -e 's/^%define rawhide_skip_docs 1/%define rawhide_skip_docs 0/' kernel.spec + +reconfig: + @rm -f kernel-*-config + @VERSION=$(KVERSION) make -f Makefile.config configs + @scripts/reconfig.sh + +unused-kernel-patches: + @for f in *.patch; do if [ -e $$f ]; then (egrep -q "^Patch[[:digit:]]+:[[:space:]]+$$f" $(SPECFILE) || echo "Unused: $$f") && egrep -q "^ApplyPatch[[:space:]]+$$f|^ApplyOptionalPatch[[:space:]]+$$f" $(SPECFILE) || echo "Unapplied: $$f"; fi; done + +# since i386 isn't a target... +compile compile-short: DIST_DEFINES += --target $(shell uname -m) + +# 'make local' also needs to build the noarch firmware package +local: noarch + +# +# Hacks for building vanilla (unpatched) kernel rpms. +# Use "make vanilla-TARGET" like "make TARGET" (make vanilla-scratch-build). +# +vanilla-%: $(SPECFILE:.spec=-vanilla.spec) + @$(MAKE) $* SPECFILE=$< + +$(SPECFILE:.spec=-vanilla.spec): $(SPECFILE) + @rm -f $@ + (echo %define nopatches 1; cat $<) > $@ + +#scratch-build: NAME = $(shell rpm $(RPM_DEFINES) $(DIST_DEFINES) -q --qf "%{NAME}\n" --specfile $(SPECFILE)| head -1) +#scratch-build: test-srpm +# $(BUILD_CLIENT) build $(BUILD_FLAGS) --scratch $(TARGET) \ +# $(SRCRPMDIR)/$(NAME)-$(VERSION)-$(RELEASE).src.rpm + +# Dismal kludge for building via brew from cvs after "make vanilla-tag". +ifdef BEEHIVE_SRPM_BUILD +export CHECKOUT_TAG ?= $(shell sed s/^.// CVS/Tag) +tag-pattern = $(TAG_NAME)-$(TAG_VERSION)-0_%_$(TAG_RELEASE) +ifeq (,$(filter-out $(tag-pattern),$(CHECKOUT_TAG))) +variant := $(patsubst $(tag-pattern),%,$(CHECKOUT_TAG)) +srpm: SPECFILE := $(wildcard $(SPECFILE:.spec=-$(variant).spec) \ + $(SPECFILE:.spec=.t.$(variant).spec)) +srpm beehive-sprm: RELEASE := 0.$(variant).$(RELEASE) +endif +endif + +# +# Hacks for building kernel rpms from upstream code plus local GIT branches. +# Use "make git/BRANCH/TARGET" like "make TARGET". +# Use "make git/BRANCH-fedora/TARGET" to include Fedora patches on top. +# +ifndef GIT_SPEC +git/%: + @$(MAKE) GIT_SPEC=$(subst /,-,$(*D)) git-$(*F) +else +git-%: $(SPECFILE:.spec=.t.$(GIT_SPEC).spec) + @$(MAKE) GIT_SPEC= $* SPECFILE=$< +endif + +# +# Your git-branches.mk file can define GIT_DIR, e.g.: +# GIT_DIR = ${HOME}/kernel/.git +# Make sure GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL are also set +# or your rpm changelogs will look like crap. +# +# For each branch it can define a variable branch-BRANCH or tag-BRANCH +# giving the parent of BRANCH to diff against in a separate patch. If +# the parent is unknown, it will use $(branch-upstream) defaulting to +# "refs/remotes/upstream/master". +# +# Defining tag-BRANCH means the tag corresponds to an upstream patch in +# the sources file, so that is used instead of generating a patch with +# git. If there is no tag-upstream defined, it will figure out a vNNN +# tag or vNNN-gitN pseudo-tag from the last patch in the sources file. +# For example: +# tag-some-hacks = v2.6.21-rc5 +# branch-more-hacks = some-hacks +# Leads to patches: +# git diff v2.6.21-rc5..more-hacks > linux-2.6.21-rc5-some-hacks.patch +# git diff some-hacks..more-hacks > linux-2.6.21-rc5-more-hacks.patch +# Whereas having no git-branches.mk at all but doing +# "make GIT_DIR=... git/mybranch/test-srpm" does: +# id=`cat patch-2.6.21-rc5-git4.id` # auto-fetched via upstream file +# git diff $id..upstream > linux-2.6.21-rc5-git4-upstream.patch +# git diff upstream..mybranch > linux-2.6.21-rc5-git4-mybranch.patch +# If the upstream patch (or any branch patch) is empty it's left out. +# +git-branches.mk:; +-include git-branches.mk + +branch-upstream ?= refs/remotes/upstream/master + +ifdef GIT_DIR +export GIT_DIR +export GIT_AUTHOR_NAME +export GIT_AUTHOR_EMAIL +gen-patches ?= gen-patches + +ifndef havespec +$(SPECFILE:.spec=.t.%-fedora.spec): $(SPECFILE) $(gen-patches) FORCE + ./$(gen-patches) --fedora < $< > $@ $(gen-patches-args) +$(SPECFILE:.spec=.t.%.spec): $(SPECFILE) $(gen-patches) FORCE + ./$(gen-patches) < $< > $@ $(gen-patches-args) +.PRECIOUS: $(SPECFILE:.spec=.t.%.spec) $(SPECFILE:.spec=.t.%-fedora.spec) +endif + +spec-%: $(SPECFILE:.spec=.t.%.spec) ; +$(SPECFILE):; +FORCE:; + +branch-of-* = $(firstword $(head-$*) $*) +gen-patches-args = --name $* v$(KVERSION) $(call heads,$(branch-of-*)) +define heads +$(if $(tag-$1),$(filter-out v$(KVERSION),$(tag-$1)),\ + $(call heads,$(firstword $(branch-$1) $(branch-upstream)))) $1 +endef + +files-%-fedora: + @echo $(SPECFILE:.spec=.t.$*-fedora.spec) + @$(call list-patches,$(branch-of-*)) +files-%: + @echo $(SPECFILE:.spec=.t.$*.spec) + @$(call list-patches,$(branch-of-*)) +define list-patches +$(if $(tag-$1),version=$(patsubst v%,%,$(tag-$1)),\ + $(call list-patches,$(firstword $(branch-$1) $(branch-upstream)))); \ +echo linux-$${version}-$(patsubst refs/remotes/%/master,%,$1).patch +endef + +ifndef tag-$(branch-upstream) +tag-$(branch-upstream) := $(shell \ + sed -n 's/^.* *//;s/\.bz2$$//;s/patch-/v/;/^v/h;$${g;p}' sources) +endif +endif diff --git a/Makefile.config b/Makefile.config new file mode 100644 index 000000000..53812fa9b --- /dev/null +++ b/Makefile.config @@ -0,0 +1,105 @@ +# Make rules for configuration files. +# +# $Id$ + +CFG = kernel-$(VERSION) + +CONFIGFILES = \ + $(CFG)-i686.config $(CFG)-i686-debug.config \ + $(CFG)-i686-PAE.config $(CFG)-i686-PAEdebug.config \ + $(CFG)-x86_64.config $(CFG)-x86_64-debug.config \ + $(CFG)-s390x.config $(CFG)-arm.config \ + $(CFG)-ppc.config $(CFG)-ppc-smp.config \ + $(CFG)-sparc64.config \ + $(CFG)-ppc64.config $(CFG)-ppc64-debug.config \ + $(CFG)-ia64.config + +PLATFORMS = x86 x86_64 powerpc powerpc32 powerpc64 s390x ia64 sparc64 +TEMPFILES = $(addprefix temp-, $(addsuffix -generic, $(PLATFORMS))) + +configs: $(CONFIGFILES) + @rm -f kernel-*-config + @rm -f $(TEMPFILES) + @rm -f temp-generic temp-*-generic temp-*-generic-tmp + +# Augment the clean target to clean up our own cruft +clean :: + @rm -fv $(CONFIGFILES) $(TEMPFILES) temp-generic kernel-$(VERSION)*config + +temp-generic: config-generic + cat config-generic config-nodebug > temp-generic + +temp-debug-generic: config-generic + cat config-generic config-debug > temp-debug-generic + +temp-x86-generic: config-x86-generic temp-generic + perl merge.pl $^ > $@ + +temp-x86-debug-generic: config-x86-generic temp-debug-generic + perl merge.pl $^ > $@ + +temp-x86_64-generic: config-x86_64-generic temp-generic + perl merge.pl $^ > $@ + +temp-x86_64-debug-generic: config-x86_64-generic temp-debug-generic + perl merge.pl $^ > $@ + +temp-sparc64-generic: config-sparc64-generic temp-generic + perl merge.pl $^ > $@ + +temp-powerpc-generic: config-powerpc-generic temp-generic + perl merge.pl $^ > $@ + +temp-powerpc-debug-generic: config-powerpc-generic temp-debug-generic + perl merge.pl $^ > $@ + +temp-powerpc32-generic: config-powerpc32-generic temp-powerpc-generic + perl merge.pl $^ > $@ + +temp-s390-generic: config-s390x temp-generic + perl merge.pl $^ > $@ + +temp-ia64-generic: config-ia64-generic temp-generic + perl merge.pl $^ > $@ + +kernel-$(VERSION)-i686-PAE.config: config-i686-PAE temp-x86-generic + perl merge.pl $^ i386 > $@ + +kernel-$(VERSION)-i686-PAEdebug.config: config-i686-PAE temp-x86-debug-generic + perl merge.pl $^ i386 > $@ + +kernel-$(VERSION)-i686.config: /dev/null temp-x86-generic + perl merge.pl $^ i386 > $@ + +kernel-$(VERSION)-i686-debug.config: /dev/null temp-x86-debug-generic + perl merge.pl $^ i386 > $@ + +kernel-$(VERSION)-x86_64.config: /dev/null temp-x86_64-generic + perl merge.pl $^ x86_64 > $@ + +kernel-$(VERSION)-x86_64-debug.config: /dev/null temp-x86_64-debug-generic + perl merge.pl $^ x86_64 > $@ + +kernel-$(VERSION)-sparc64.config: /dev/null temp-sparc64-generic + perl merge.pl $^ sparc64 > $@ + +kernel-$(VERSION)-ppc64.config: config-powerpc64 temp-powerpc-generic + perl merge.pl $^ powerpc > $@ + +kernel-$(VERSION)-ppc64-debug.config: config-powerpc64 temp-powerpc-debug-generic + perl merge.pl $^ powerpc > $@ + +kernel-$(VERSION)-s390x.config: config-s390x temp-s390-generic + perl merge.pl $^ s390 > $@ + +kernel-$(VERSION)-arm.config: config-arm temp-generic + perl merge.pl $^ arm > $@ + +kernel-$(VERSION)-ppc.config: /dev/null temp-powerpc32-generic + perl merge.pl $^ powerpc > $@ + +kernel-$(VERSION)-ppc-smp.config: config-powerpc32-smp temp-powerpc32-generic + perl merge.pl $^ powerpc > $@ + +kernel-$(VERSION)-ia64.config: /dev/null temp-ia64-generic + perl merge.pl $^ ia64 > $@ diff --git a/Makefile.rhelver b/Makefile.rhelver deleted file mode 100644 index 727baf119..000000000 --- a/Makefile.rhelver +++ /dev/null @@ -1,60 +0,0 @@ -RHEL_MAJOR = 10 -RHEL_MINOR = 99 - -# -# RHEL_RELEASE -# ------------- -# -# Represents build number in 'release' part of RPM's name-version-release. -# name is , e.g. kernel -# version is upstream kernel version this kernel is based on, e.g. 4.18.0 -# release is .[], e.g. 100.el8 -# -# Use this spot to avoid future merge conflicts. -# Do not trim this comment. -RHEL_RELEASE = 38 - -# -# RHEL_REBASE_NUM -# ---------------- -# -# Used in RPM version string for Gemini kernels, which dont use upstream -# VERSION/PATCHLEVEL/SUBLEVEL. The number represents rebase number for -# current MAJOR release. -# -# Use this spot to avoid future merge conflicts. -# Do not trim this comment. -RHEL_REBASE_NUM = 1 - - -# -# ZSTREAM -# ------- -# -# This variable controls whether we use zstream numbering or not for the -# package release. The zstream release keeps the build number of the last -# build done for ystream for the Beta milestone, and increments a second -# number for each build. The third number is used for branched builds -# (eg.: for builds with security fixes or hot fixes done outside of the -# batch release process). -# -# For example, with ZSTREAM unset or set to "no", all builds will contain -# a release with only the build number, eg.: kernel--X.el*, -# where X is the build number. With ZSTREAM set to "yes", we will have -# builds with kernel--X.Y.Z.el*, where X is the last -# RHEL_RELEASE number before ZSTREAM flag was set to yes, Y will now be the -# build number and Z will always be 1 except if you're doing a branched build -# (when you give RHDISTGIT_BRANCH on the command line, in which case the Z -# number will be incremented instead of the Y). -# -ZSTREAM ?= no - -# -# Automotive -# ---------- -# -# Represents the major and minor release used by automotive. -# Primarily this is used to to identify the build target when -# building the automotive kernel package. -AUTOMOTIVE_MAJOR = 2 -AUTOMOTIVE_MINOR = 99 diff --git a/Module.kabi_dup_aarch64 b/Module.kabi_dup_aarch64 deleted file mode 100644 index e69de29bb..000000000 diff --git a/Module.kabi_dup_ppc64le b/Module.kabi_dup_ppc64le deleted file mode 100644 index e69de29bb..000000000 diff --git a/Module.kabi_dup_riscv64 b/Module.kabi_dup_riscv64 deleted file mode 100644 index e69de29bb..000000000 diff --git a/Module.kabi_dup_s390x b/Module.kabi_dup_s390x deleted file mode 100644 index e69de29bb..000000000 diff --git a/Module.kabi_dup_x86_64 b/Module.kabi_dup_x86_64 deleted file mode 100644 index e69de29bb..000000000 diff --git a/Module.kabi_ppc64le b/Module.kabi_ppc64le deleted file mode 100644 index e69de29bb..000000000 diff --git a/Module.kabi_riscv64 b/Module.kabi_riscv64 deleted file mode 100644 index e69de29bb..000000000 diff --git a/Module.kabi_s390x b/Module.kabi_s390x deleted file mode 100644 index e69de29bb..000000000 diff --git a/Module.kabi_x86_64 b/Module.kabi_x86_64 deleted file mode 100644 index e69de29bb..000000000 diff --git a/Patchlist.changelog b/Patchlist.changelog deleted file mode 100644 index fed3d67b3..000000000 --- a/Patchlist.changelog +++ /dev/null @@ -1,474 +0,0 @@ -https://gitlab.com/cki-project/kernel-ark/-/commit/831ff9bcd8e9eab864062470a3250beb1e1ec924 - 831ff9bcd8e9eab864062470a3250beb1e1ec924 rust: Add -fdiagnostics-show-context to bindgen_skip_c_flags - -https://gitlab.com/cki-project/kernel-ark/-/commit/fe3e9e24af806d756edbda922103b1fa95d9b89b - fe3e9e24af806d756edbda922103b1fa95d9b89b Revert "Removing Obsolete hba pci-ids from rhel8" - -https://gitlab.com/cki-project/kernel-ark/-/commit/c4a0a995da9df8732f688d09db5252173277589d - c4a0a995da9df8732f688d09db5252173277589d rh_messages.h: add missing lpfc devices - -https://gitlab.com/cki-project/kernel-ark/-/commit/0ad9a88c3263fa8fa39437f69472588917255c99 - 0ad9a88c3263fa8fa39437f69472588917255c99 kernel: extend rh_waived to cope better with the CVE mitigations case - -https://gitlab.com/cki-project/kernel-ark/-/commit/cf18c49636f2583c85831f909699034026325242 - cf18c49636f2583c85831f909699034026325242 rh_messages.h: add missing aacraid device - -https://gitlab.com/cki-project/kernel-ark/-/commit/26ca931184edb2c3c7f7c1951f53fa3333d9c90e - 26ca931184edb2c3c7f7c1951f53fa3333d9c90e rh_messages.h: update unmaintained drivers - -https://gitlab.com/cki-project/kernel-ark/-/commit/c1c1a1b7059900f4b9b657f5189285a287160e11 - c1c1a1b7059900f4b9b657f5189285a287160e11 arm64: add early lockdown for secure boot - -https://gitlab.com/cki-project/kernel-ark/-/commit/a613ae52a8d9378e6fa70f697b3ce0acee220491 - a613ae52a8d9378e6fa70f697b3ce0acee220491 efi: pass secure boot mode to kernel proper - -https://gitlab.com/cki-project/kernel-ark/-/commit/f869258b6b654d316e84325e46e431da4dfd04e7 - f869258b6b654d316e84325e46e431da4dfd04e7 selftests/bpf: Remove ksyms_weak_lskel test - -https://gitlab.com/cki-project/kernel-ark/-/commit/8b69219fe6a11766cf1a2e07dc94e56448b47824 - 8b69219fe6a11766cf1a2e07dc94e56448b47824 Simplify include Makefile.rhelver - -https://gitlab.com/cki-project/kernel-ark/-/commit/c2621ac616e25a9a04fbcb8af0c1f8b2bdd8c099 - c2621ac616e25a9a04fbcb8af0c1f8b2bdd8c099 redhat: make ENABLE_WERROR also enable OBJTOOL_WERROR - -https://gitlab.com/cki-project/kernel-ark/-/commit/d28cbdeb89fe565e10fb4be8d8378153e86611f6 - d28cbdeb89fe565e10fb4be8d8378153e86611f6 main.c: fix initcall blacklisted - -https://gitlab.com/cki-project/kernel-ark/-/commit/b71ab57c8db44881edc32a124ddc2ebe536b6a4c - b71ab57c8db44881edc32a124ddc2ebe536b6a4c arch/x86/kernel/setup.c: fix rh_check_supported - -https://gitlab.com/cki-project/kernel-ark/-/commit/c4ea2384863e54e0c5582b3508518e659581ce69 - c4ea2384863e54e0c5582b3508518e659581ce69 efi,lockdown: fix kernel lockdown on Secure Boot - -https://gitlab.com/cki-project/kernel-ark/-/commit/60b2ddeb0986e1c43a98b44a4ab414a7e2744701 - 60b2ddeb0986e1c43a98b44a4ab414a7e2744701 Revert "nvme: Return BLK_STS_TARGET if the DNR bit is set" - -https://gitlab.com/cki-project/kernel-ark/-/commit/860632dd288c7aa7807959a79af9159482510cd1 - 860632dd288c7aa7807959a79af9159482510cd1 Revert "nvme: allow local retry and proper failover for REQ_FAILFAST_TRANSPORT" - -https://gitlab.com/cki-project/kernel-ark/-/commit/aaef2c3ee081c8980bb60fd4b7a6ed9e187d9048 - aaef2c3ee081c8980bb60fd4b7a6ed9e187d9048 Revert "nvme: decouple basic ANA log page re-read support from native multipathing" - -https://gitlab.com/cki-project/kernel-ark/-/commit/5cd4353dae0ee79d13f57b7ccee85cd0bcbe4b4f - 5cd4353dae0ee79d13f57b7ccee85cd0bcbe4b4f Revert "nvme: nvme_mpath_init remove multipath check" - -https://gitlab.com/cki-project/kernel-ark/-/commit/656a0565ffe54f99ac1390a68c5ee7050ab6fb25 - 656a0565ffe54f99ac1390a68c5ee7050ab6fb25 redhat: automotive: define CONFIG_RH_AUTOMOTIVE - -https://gitlab.com/cki-project/kernel-ark/-/commit/f1025d6236c72b4fbd03940b6fa2178f2a84f418 - f1025d6236c72b4fbd03940b6fa2178f2a84f418 redhat: fix modules.order target - -https://gitlab.com/cki-project/kernel-ark/-/commit/6e0fa997052c92d6085a50083e75dedc0160443f - 6e0fa997052c92d6085a50083e75dedc0160443f [redhat] rh_messages.h: driver and device updates - -https://gitlab.com/cki-project/kernel-ark/-/commit/d8822fd0573e9f254f097c1743078e4e74ac70f5 - d8822fd0573e9f254f097c1743078e4e74ac70f5 crypto: rng - Fix extrng EFAULT handling - -https://gitlab.com/cki-project/kernel-ark/-/commit/c224e4b6a61af08574bb0565755ed609bf08cacb - c224e4b6a61af08574bb0565755ed609bf08cacb crypto: sig - Disable signing - -https://gitlab.com/cki-project/kernel-ark/-/commit/39417e970be7f6bc63f34d5ed5511f7e629802c2 - 39417e970be7f6bc63f34d5ed5511f7e629802c2 crypto: rng - Ensure stdrng is tested before user-space starts - -https://gitlab.com/cki-project/kernel-ark/-/commit/52be246b6342ed5b1486729fd5c5893b10549a92 - 52be246b6342ed5b1486729fd5c5893b10549a92 [redhat] rh_messages.h: Mark BlueField-4 as disabled - -https://gitlab.com/cki-project/kernel-ark/-/commit/2c9e64af9fa1f8599ce05877441afcac8ac91b04 - 2c9e64af9fa1f8599ce05877441afcac8ac91b04 Update the RHEL_DIFFERENCES help string - -https://gitlab.com/cki-project/kernel-ark/-/commit/beef34cb1efc34b7fbee35535c66915995d12ed1 - beef34cb1efc34b7fbee35535c66915995d12ed1 redhat: include resolve_btfids in kernel-devel - -https://gitlab.com/cki-project/kernel-ark/-/commit/1a1426b7a8df854c78385dd8ce8b74e9ee641477 - 1a1426b7a8df854c78385dd8ce8b74e9ee641477 redhat: workaround CKI cross compilation for scripts - -https://gitlab.com/cki-project/kernel-ark/-/commit/2c83d6cfffe1f891bf024df81be6cd41c2073ad9 - 2c83d6cfffe1f891bf024df81be6cd41c2073ad9 crypto: akcipher - Disable signing and decryption - -https://gitlab.com/cki-project/kernel-ark/-/commit/af93553b8d335ccf5dd4f90ab9419e497aa36a80 - af93553b8d335ccf5dd4f90ab9419e497aa36a80 crypto: dh - implement FIPS PCT - -https://gitlab.com/cki-project/kernel-ark/-/commit/f0540d9d32978dff227cbb930193e8dc2557b23b - f0540d9d32978dff227cbb930193e8dc2557b23b crypto: ecdh - disallow plain "ecdh" usage in FIPS mode - -https://gitlab.com/cki-project/kernel-ark/-/commit/243ef89ad354eea332d7bfb23fd4cf259240de91 - 243ef89ad354eea332d7bfb23fd4cf259240de91 crypto: seqiv - flag instantiations as FIPS compliant - -https://gitlab.com/cki-project/kernel-ark/-/commit/6a23cbc588e9b9f7b2bc7250c6c6903d4d904eb1 - 6a23cbc588e9b9f7b2bc7250c6c6903d4d904eb1 [kernel] bpf: set default value for bpf_jit_harden - -https://gitlab.com/cki-project/kernel-ark/-/commit/bb84b630a172d0204c8d243c57a6a1d2eae7843c - bb84b630a172d0204c8d243c57a6a1d2eae7843c not upstream: Disable vdso getrandom when FIPS is enabled - -https://gitlab.com/cki-project/kernel-ark/-/commit/b643998c61552fb5615268e7e529999d64d54175 - b643998c61552fb5615268e7e529999d64d54175 Add support to rh_waived cmdline boot parameter - -https://gitlab.com/cki-project/kernel-ark/-/commit/a1e04b6f3580382a902256c7bf8b395b9a1be47f - a1e04b6f3580382a902256c7bf8b395b9a1be47f rh_flags: fix failed when register_sysctl_sz rh_flags_table to kernel - -https://gitlab.com/cki-project/kernel-ark/-/commit/03cf1862c6221ee2a6de9a5ab25adaec6460b62e - 03cf1862c6221ee2a6de9a5ab25adaec6460b62e [redhat] rh_flags: constify the ctl_table argument of proc_handler - -https://gitlab.com/cki-project/kernel-ark/-/commit/e2708e55f9151652da80e388b4bf88c649288c0f - e2708e55f9151652da80e388b4bf88c649288c0f redhat: rh_flags: declare proper static methods when !CONFIG_RHEL_DIFFERENCES - -https://gitlab.com/cki-project/kernel-ark/-/commit/6f593811cc1e5664f45fe2d09916eada1187e992 - 6f593811cc1e5664f45fe2d09916eada1187e992 redhat: make bnx2xx drivers unmaintained in rhel-10 - -https://gitlab.com/cki-project/kernel-ark/-/commit/5db8220bd67c719a20c1269233585b40f48837da - 5db8220bd67c719a20c1269233585b40f48837da rh_flags: Rename rh_features to rh_flags - -https://gitlab.com/cki-project/kernel-ark/-/commit/19ca502a0087eed65a014c6271f9bfc207d8d7eb - 19ca502a0087eed65a014c6271f9bfc207d8d7eb kernel: rh_features: fix reading empty feature list from /proc - -https://gitlab.com/cki-project/kernel-ark/-/commit/ba24639032f00b47748a6f39a4eb33950df015c2 - ba24639032f00b47748a6f39a4eb33950df015c2 rh_features: move rh_features entry to sys/kernel - -https://gitlab.com/cki-project/kernel-ark/-/commit/883e43fe6a0da0d9ad90e7c997a95f11bab9b888 - 883e43fe6a0da0d9ad90e7c997a95f11bab9b888 rh_features: convert to atomic allocation - -https://gitlab.com/cki-project/kernel-ark/-/commit/c8daa2e832df14ee9174435a357b2ae0994a3ef3 - c8daa2e832df14ee9174435a357b2ae0994a3ef3 add rh_features to /proc - -https://gitlab.com/cki-project/kernel-ark/-/commit/4f33dbbe3ec578d49e12c07421b913bf480fccef - 4f33dbbe3ec578d49e12c07421b913bf480fccef add support for rh_features - -https://gitlab.com/cki-project/kernel-ark/-/commit/53a5900b05260b81f13eb3b9d6a9419429f310ab - 53a5900b05260b81f13eb3b9d6a9419429f310ab [redhat] PCI: Fix pci_rh_check_status() call semantics - -https://gitlab.com/cki-project/kernel-ark/-/commit/aeb9a237a0ec39b7bde89d8bb040cd5b267f6802 - aeb9a237a0ec39b7bde89d8bb040cd5b267f6802 scsi: sd: condition probe_type under RHEL_DIFFERENCES - -https://gitlab.com/cki-project/kernel-ark/-/commit/159e72af8b1631b720f4a7e0012fa624764cecde - 159e72af8b1631b720f4a7e0012fa624764cecde scsi: sd: remove unused sd_probe_types - -https://gitlab.com/cki-project/kernel-ark/-/commit/d8c04860eb7bf29617ca1754f1076fd9f5992e77 - d8c04860eb7bf29617ca1754f1076fd9f5992e77 [redhat] rh_messages.h: mark mlx5 on Bluefield-3 as unmaintained - -https://gitlab.com/cki-project/kernel-ark/-/commit/496c64b4afece4ab525467a6be71ffe60d0c564f - 496c64b4afece4ab525467a6be71ffe60d0c564f [redhat] rh_messages.h: initial driver and device lists - -https://gitlab.com/cki-project/kernel-ark/-/commit/5cf456aaba6f5c9406421c04c65d43b2c71f5927 - 5cf456aaba6f5c9406421c04c65d43b2c71f5927 arch/x86: Fix XSAVE check for x86_64-v2 check - -https://gitlab.com/cki-project/kernel-ark/-/commit/252bf9586fca6e57a51966c0294a9a0cb33ff4f5 - 252bf9586fca6e57a51966c0294a9a0cb33ff4f5 arch/x86/kernel/setup.c: fixup rh_check_supported - -https://gitlab.com/cki-project/kernel-ark/-/commit/30faf17591afbd4230d590355351044294ad43d2 - 30faf17591afbd4230d590355351044294ad43d2 lsm: update security_lock_kernel_down - -https://gitlab.com/cki-project/kernel-ark/-/commit/e88ee9e2e869e7259faa5bf3ff6689becabb53cb - e88ee9e2e869e7259faa5bf3ff6689becabb53cb arch/x86: mark x86_64-v1 and x86_64-v2 processors as deprecated - -https://gitlab.com/cki-project/kernel-ark/-/commit/26ebc304df38a49ce7cc69b4bdf220298cff2460 - 26ebc304df38a49ce7cc69b4bdf220298cff2460 redhat: kABI: add missing RH_KABI_SIZE_ALIGN_CHECKS Kconfig option - -https://gitlab.com/cki-project/kernel-ark/-/commit/8c71392703448be8e8217592dd46ea1cc8b157e1 - 8c71392703448be8e8217592dd46ea1cc8b157e1 redhat: rh_kabi: introduce RH_KABI_EXCLUDE_WITH_SIZE - -https://gitlab.com/cki-project/kernel-ark/-/commit/d42afcb843fcc87e59ba39b5574c18d89fd07a91 - d42afcb843fcc87e59ba39b5574c18d89fd07a91 redhat: rh_kabi: move semicolon inside __RH_KABI_CHECK_SIZE - -https://gitlab.com/cki-project/kernel-ark/-/commit/95a56955f9ba6ef1e1dd2d99d8f98254da274267 - 95a56955f9ba6ef1e1dd2d99d8f98254da274267 random: replace import_single_range() with import_ubuf() - -https://gitlab.com/cki-project/kernel-ark/-/commit/92d6612578b79fd3a09e10504ed71209ba43c271 - 92d6612578b79fd3a09e10504ed71209ba43c271 ext4: Mark mounting fs-verity filesystems as tech-preview - -https://gitlab.com/cki-project/kernel-ark/-/commit/5c51745b8aec113ff0605ab833c3e472d99c55c8 - 5c51745b8aec113ff0605ab833c3e472d99c55c8 erofs: Add tech preview markers at mount - -https://gitlab.com/cki-project/kernel-ark/-/commit/6d687c70a7eda10eac0ddc6eedeaccc30eef5349 - 6d687c70a7eda10eac0ddc6eedeaccc30eef5349 kernel/rh_messages.c: Mark functions as possibly unused - -https://gitlab.com/cki-project/kernel-ark/-/commit/dfb09b1d833cad815ea2f5cb69505010de260c40 - dfb09b1d833cad815ea2f5cb69505010de260c40 crypto: rng - Override drivers/char/random in FIPS mode - -https://gitlab.com/cki-project/kernel-ark/-/commit/ddbe3667f2462817f3f936141fff08604dde1564 - ddbe3667f2462817f3f936141fff08604dde1564 random: Add hook to override device reads and getrandom(2) - -https://gitlab.com/cki-project/kernel-ark/-/commit/92525a9129d85fa6400c9e653379862a67cb43b2 - 92525a9129d85fa6400c9e653379862a67cb43b2 [redhat] kernel/rh_messages.c: move hardware tables to rh_messages.h - -https://gitlab.com/cki-project/kernel-ark/-/commit/eacd81fdaf31d456a82c553735faf64c8efad2eb - eacd81fdaf31d456a82c553735faf64c8efad2eb [redhat] kernel/rh_messages.c: Wire up new calls - -https://gitlab.com/cki-project/kernel-ark/-/commit/32af8640a651c642ee5706dda0cf35ff508bcdcb - 32af8640a651c642ee5706dda0cf35ff508bcdcb [redhat] drivers/pci: Update rh_messages.c - -https://gitlab.com/cki-project/kernel-ark/-/commit/db366977f9e13f903cc9b7f22936b581594a7731 - db366977f9e13f903cc9b7f22936b581594a7731 [redhat] drivers/pci: Remove RHEL-only pci_hw_*() functions - -https://gitlab.com/cki-project/kernel-ark/-/commit/402504ff66e5d118b514253df5d55f8413e2e167 - 402504ff66e5d118b514253df5d55f8413e2e167 scsi: sd: Add "probe_type" module parameter to allow synchronous probing - -https://gitlab.com/cki-project/kernel-ark/-/commit/5e96a345c6fb24e282ce1769223c1a339d0dbe94 - 5e96a345c6fb24e282ce1769223c1a339d0dbe94 Revert "Remove EXPERT from ARCH_FORCE_MAX_ORDER for aarch64" - -https://gitlab.com/cki-project/kernel-ark/-/commit/ce943989ae8cb2b8e0b4699c148584d3cd18ec9b - ce943989ae8cb2b8e0b4699c148584d3cd18ec9b kernel/rh_messages.c: Another gcc12 warning on redundant NULL test - -https://gitlab.com/cki-project/kernel-ark/-/commit/c0624b3913d8c3f262e20910a2f2c4d2f99ce61f - c0624b3913d8c3f262e20910a2f2c4d2f99ce61f Enable IO_URING for RHEL - -https://gitlab.com/cki-project/kernel-ark/-/commit/861f2d38d82cfb374799ec517f18cc021701068e - 861f2d38d82cfb374799ec517f18cc021701068e Remove EXPERT from ARCH_FORCE_MAX_ORDER for aarch64 - -https://gitlab.com/cki-project/kernel-ark/-/commit/e02ec93117d6eea21e80baf69e6f9848cf1a9774 - e02ec93117d6eea21e80baf69e6f9848cf1a9774 redhat: version two of Makefile.rhelver tweaks - -https://gitlab.com/cki-project/kernel-ark/-/commit/964e830b4fae678dec5b8b93dcd402c73fdf2912 - 964e830b4fae678dec5b8b93dcd402c73fdf2912 redhat: adapt to upstream Makefile change - -https://gitlab.com/cki-project/kernel-ark/-/commit/60a4025a3b1cdec1c7bbdabf1e30278f615bb493 - 60a4025a3b1cdec1c7bbdabf1e30278f615bb493 kernel/rh_messages.c: gcc12 warning on redundant NULL test - -https://gitlab.com/cki-project/kernel-ark/-/commit/a5c9e3c6e3dcda60b5f753d1bae86a686f3ac087 - a5c9e3c6e3dcda60b5f753d1bae86a686f3ac087 Change acpi_bus_get_acpi_device to acpi_get_acpi_dev - -https://gitlab.com/cki-project/kernel-ark/-/commit/092e751fe418623c5ad04e77fa6c993d48d96533 - 092e751fe418623c5ad04e77fa6c993d48d96533 ARK: Remove code marking devices unmaintained - -https://gitlab.com/cki-project/kernel-ark/-/commit/c27fa327fb3de69773568d211fd2f8f13a72e342 - c27fa327fb3de69773568d211fd2f8f13a72e342 rh_message: Fix function name - -https://gitlab.com/cki-project/kernel-ark/-/commit/c9b07fd3a141ad0283d7eaadf5a06aec9af2b8c9 - c9b07fd3a141ad0283d7eaadf5a06aec9af2b8c9 Add Partner Supported taint flag to kAFS - -https://gitlab.com/cki-project/kernel-ark/-/commit/6b0e3a47ec436527a736c0e7159b41624d176dd9 - 6b0e3a47ec436527a736c0e7159b41624d176dd9 Add Partner Supported taint flag - -https://gitlab.com/cki-project/kernel-ark/-/commit/3a4e2ad92c430d2f584f56ca686bc75a469d06c0 - 3a4e2ad92c430d2f584f56ca686bc75a469d06c0 kabi: Add kABI macros for enum type - -https://gitlab.com/cki-project/kernel-ark/-/commit/04fbd46f834f3a012ca9d5bef91db377a3dbaed0 - 04fbd46f834f3a012ca9d5bef91db377a3dbaed0 kabi: expand and clarify documentation of aux structs - -https://gitlab.com/cki-project/kernel-ark/-/commit/cf8df8ef88e094ebb049a7e1e6fec069aaf54faa - cf8df8ef88e094ebb049a7e1e6fec069aaf54faa kabi: introduce RH_KABI_USE_AUX_PTR - -https://gitlab.com/cki-project/kernel-ark/-/commit/31779ca0c6c9aab28184a42ac3f17ac219b37b2b - 31779ca0c6c9aab28184a42ac3f17ac219b37b2b kabi: rename RH_KABI_SIZE_AND_EXTEND to AUX - -https://gitlab.com/cki-project/kernel-ark/-/commit/2e12a05d339ed936b9cd59f420b161d70b4a130a - 2e12a05d339ed936b9cd59f420b161d70b4a130a kabi: more consistent _RH_KABI_SIZE_AND_EXTEND - -https://gitlab.com/cki-project/kernel-ark/-/commit/b83556eebdc2efdc2d2c22610b7cd7c5cafb2bae - b83556eebdc2efdc2d2c22610b7cd7c5cafb2bae kabi: use fixed field name for extended part - -https://gitlab.com/cki-project/kernel-ark/-/commit/4c9a3b306a34ed7017e35b0de26b2d98e1a04373 - 4c9a3b306a34ed7017e35b0de26b2d98e1a04373 kabi: fix dereference in RH_KABI_CHECK_EXT - -https://gitlab.com/cki-project/kernel-ark/-/commit/a961660df0a73bcf2dcd8cb8855c2f5d5ded0ae9 - a961660df0a73bcf2dcd8cb8855c2f5d5ded0ae9 kabi: fix RH_KABI_SET_SIZE macro - -https://gitlab.com/cki-project/kernel-ark/-/commit/9f9ef5e8b4694fa7fb6a8f941fb741121fe5aab3 - 9f9ef5e8b4694fa7fb6a8f941fb741121fe5aab3 kabi: expand and clarify documentation - -https://gitlab.com/cki-project/kernel-ark/-/commit/308d17beeaa6cb4a514f77319b636c9a2c15f5eb - 308d17beeaa6cb4a514f77319b636c9a2c15f5eb kabi: make RH_KABI_USE replace any number of reserved fields - -https://gitlab.com/cki-project/kernel-ark/-/commit/f3d12dffffeee8d6692be46044b9fc8448901692 - f3d12dffffeee8d6692be46044b9fc8448901692 kabi: rename RH_KABI_USE2 to RH_KABI_USE_SPLIT - -https://gitlab.com/cki-project/kernel-ark/-/commit/520e726b4e78101e73fa3d77cdcbc21d204a75a9 - 520e726b4e78101e73fa3d77cdcbc21d204a75a9 kabi: change RH_KABI_REPLACE2 to RH_KABI_REPLACE_SPLIT - -https://gitlab.com/cki-project/kernel-ark/-/commit/7160868bd40d04e6d1a80f55d1bf9bb62ede0ba3 - 7160868bd40d04e6d1a80f55d1bf9bb62ede0ba3 kabi: change RH_KABI_REPLACE_UNSAFE to RH_KABI_BROKEN_REPLACE - -https://gitlab.com/cki-project/kernel-ark/-/commit/0b83063cf6c57dc20a80c35396fa425ec1963d53 - 0b83063cf6c57dc20a80c35396fa425ec1963d53 kabi: introduce RH_KABI_ADD_MODIFIER - -https://gitlab.com/cki-project/kernel-ark/-/commit/d276c2393792e3eec80a73a4fe964f9ec11145a7 - d276c2393792e3eec80a73a4fe964f9ec11145a7 kabi: Include kconfig.h - -https://gitlab.com/cki-project/kernel-ark/-/commit/28c30de9c771ff91994c9f0a42bdcc260fa97c2d - 28c30de9c771ff91994c9f0a42bdcc260fa97c2d kabi: macros for intentional kABI breakage - -https://gitlab.com/cki-project/kernel-ark/-/commit/9b671c725ac69c47874321e5636e6541bb6d219d - 9b671c725ac69c47874321e5636e6541bb6d219d kabi: fix the note about terminating semicolon - -https://gitlab.com/cki-project/kernel-ark/-/commit/6443eef17fb53f62886ecce519b6e12dd310e7f5 - 6443eef17fb53f62886ecce519b6e12dd310e7f5 kabi: introduce RH_KABI_HIDE_INCLUDE and RH_KABI_FAKE_INCLUDE - -https://gitlab.com/cki-project/kernel-ark/-/commit/47746fc3837b476ec265e2a0c2aaa86de0d3994e - 47746fc3837b476ec265e2a0c2aaa86de0d3994e pci.h: Fix static include - -https://gitlab.com/cki-project/kernel-ark/-/commit/67ce66385c6b619356c4030e6163c4fb18a50427 - 67ce66385c6b619356c4030e6163c4fb18a50427 drivers/pci/pci-driver.c: Fix if/ifdef typo - -https://gitlab.com/cki-project/kernel-ark/-/commit/0dfd7feeadc964ef2a9d118218b54831381c8d7a - 0dfd7feeadc964ef2a9d118218b54831381c8d7a kernel/rh_taint.c: Update to new messaging - -https://gitlab.com/cki-project/kernel-ark/-/commit/35e5ee153637e59c9297c9cc8ba7f3960277ffc2 - 35e5ee153637e59c9297c9cc8ba7f3960277ffc2 redhat: Add mark_driver_deprecated() - -https://gitlab.com/cki-project/kernel-ark/-/commit/ff7aa8cae4c7e3e7bbc1bb5612efc2157c81fa7d - ff7aa8cae4c7e3e7bbc1bb5612efc2157c81fa7d RHEL: disable io_uring support - -https://gitlab.com/cki-project/kernel-ark/-/commit/517351ed810bf2707e7fdb2ab22029aeb594db59 - 517351ed810bf2707e7fdb2ab22029aeb594db59 bpf: Fix unprivileged_bpf_disabled setup - -https://gitlab.com/cki-project/kernel-ark/-/commit/48fe2e5f40c901e92d1f8c62bc97f58af4b0906a - 48fe2e5f40c901e92d1f8c62bc97f58af4b0906a nvme: nvme_mpath_init remove multipath check - -https://gitlab.com/cki-project/kernel-ark/-/commit/1c9bd09f303e2c9d2c67fdc46604d94e00cbf67c - 1c9bd09f303e2c9d2c67fdc46604d94e00cbf67c wireguard: disable in FIPS mode - -https://gitlab.com/cki-project/kernel-ark/-/commit/57872981891fe8f3f7205daa4b78c8c0d676b171 - 57872981891fe8f3f7205daa4b78c8c0d676b171 nvme: decouple basic ANA log page re-read support from native multipathing - -https://gitlab.com/cki-project/kernel-ark/-/commit/0561f5953431ff471193611cd73af65dd394c8cd - 0561f5953431ff471193611cd73af65dd394c8cd nvme: allow local retry and proper failover for REQ_FAILFAST_TRANSPORT - -https://gitlab.com/cki-project/kernel-ark/-/commit/f801483d711fa5f83a0f9d4c479eeba702d1d477 - f801483d711fa5f83a0f9d4c479eeba702d1d477 nvme: Return BLK_STS_TARGET if the DNR bit is set - -https://gitlab.com/cki-project/kernel-ark/-/commit/4f2bc09956ad4829d139e9d69b86ba8b9ebc66e2 - 4f2bc09956ad4829d139e9d69b86ba8b9ebc66e2 REDHAT: coresight: etm4x: Disable coresight on HPE Apollo 70 - -https://gitlab.com/cki-project/kernel-ark/-/commit/65a21d545cc43328ea00fdbd62e7b45f375adce8 - 65a21d545cc43328ea00fdbd62e7b45f375adce8 redhat: remove remaining references of CONFIG_RH_DISABLE_DEPRECATED - -https://gitlab.com/cki-project/kernel-ark/-/commit/1c1b5380b0b56d3be978997b128f84aeb9906656 - 1c1b5380b0b56d3be978997b128f84aeb9906656 arch/x86: Remove vendor specific CPU ID checks - -https://gitlab.com/cki-project/kernel-ark/-/commit/f7c032c856ba6379a77b76179d0352929d6039ec - f7c032c856ba6379a77b76179d0352929d6039ec redhat: Replace hardware.redhat.com link in Unsupported message - -https://gitlab.com/cki-project/kernel-ark/-/commit/9a6eb49603959cf0aab0198e13946eaee07801c3 - 9a6eb49603959cf0aab0198e13946eaee07801c3 x86: Fix compile issues with rh_check_supported() - -https://gitlab.com/cki-project/kernel-ark/-/commit/8a605436efddfa7dbc6e007b2881fa81f17968a5 - 8a605436efddfa7dbc6e007b2881fa81f17968a5 KEYS: Make use of platform keyring for module signature verify - -https://gitlab.com/cki-project/kernel-ark/-/commit/c7c191f662438423a23592db42838ff550c2bdda - c7c191f662438423a23592db42838ff550c2bdda Input: rmi4 - remove the need for artificial IRQ in case of HID - -https://gitlab.com/cki-project/kernel-ark/-/commit/4ae139284600cd6fef133ce7a981485ea73381ab - 4ae139284600cd6fef133ce7a981485ea73381ab ARM: tegra: usb no reset - -https://gitlab.com/cki-project/kernel-ark/-/commit/8156e2102f753bbe0f0dd222a5f232e7f3d99883 - 8156e2102f753bbe0f0dd222a5f232e7f3d99883 arm: make CONFIG_HIGHPTE optional without CONFIG_EXPERT - -https://gitlab.com/cki-project/kernel-ark/-/commit/823e733a88ddd21c735288dd3b08348e79872b91 - 823e733a88ddd21c735288dd3b08348e79872b91 redhat: rh_kabi: deduplication friendly structs - -https://gitlab.com/cki-project/kernel-ark/-/commit/61d2a751fe1b1305684d6c1899f26fa9e38ac0a9 - 61d2a751fe1b1305684d6c1899f26fa9e38ac0a9 redhat: rh_kabi add a comment with warning about RH_KABI_EXCLUDE usage - -https://gitlab.com/cki-project/kernel-ark/-/commit/7d09cb3ea3dd2f3cda5a6a31be429f259106ca61 - 7d09cb3ea3dd2f3cda5a6a31be429f259106ca61 redhat: rh_kabi: introduce RH_KABI_EXTEND_WITH_SIZE - -https://gitlab.com/cki-project/kernel-ark/-/commit/c0c51c6f123df02948e11680d9b90324593ba547 - c0c51c6f123df02948e11680d9b90324593ba547 redhat: rh_kabi: Indirect EXTEND macros so nesting of other macros will resolve. - -https://gitlab.com/cki-project/kernel-ark/-/commit/96b20c70b39cd28efcec2336417cb0db9ff7853c - 96b20c70b39cd28efcec2336417cb0db9ff7853c redhat: rh_kabi: Fix RH_KABI_SET_SIZE to use dereference operator - -https://gitlab.com/cki-project/kernel-ark/-/commit/198030a81d85dbac8f4030e69d3d376327433487 - 198030a81d85dbac8f4030e69d3d376327433487 redhat: rh_kabi: Add macros to size and extend structs - -https://gitlab.com/cki-project/kernel-ark/-/commit/695af00ed9e393abe88d9ee4de3702c15ded186d - 695af00ed9e393abe88d9ee4de3702c15ded186d Removing Obsolete hba pci-ids from rhel8 - -https://gitlab.com/cki-project/kernel-ark/-/commit/736038bd8039d1543468c1dc8925f20929645804 - 736038bd8039d1543468c1dc8925f20929645804 mptsas: pci-id table changes - -https://gitlab.com/cki-project/kernel-ark/-/commit/83cdf2924bdcc90c433a58129b4501e10b1295dc - 83cdf2924bdcc90c433a58129b4501e10b1295dc mptspi: pci-id table changes - -https://gitlab.com/cki-project/kernel-ark/-/commit/0b634d81ed7f0730e13d720508dbaa6ab94e54d2 - 0b634d81ed7f0730e13d720508dbaa6ab94e54d2 qla2xxx: Remove PCI IDs of deprecated adapter - -https://gitlab.com/cki-project/kernel-ark/-/commit/0d11491f9e7fe0c8c301db3256cb47c66ae8450f - 0d11491f9e7fe0c8c301db3256cb47c66ae8450f hpsa: remove old cciss-based smartarray pci ids - -https://gitlab.com/cki-project/kernel-ark/-/commit/75f69a4f7b8f9d38c5efb0231186ed8726e526f2 - 75f69a4f7b8f9d38c5efb0231186ed8726e526f2 kernel: add SUPPORT_REMOVED kernel taint - -https://gitlab.com/cki-project/kernel-ark/-/commit/50081b0865239d853d77bc71e54d13fad8bac9f0 - 50081b0865239d853d77bc71e54d13fad8bac9f0 Rename RH_DISABLE_DEPRECATED to RHEL_DIFFERENCES - -https://gitlab.com/cki-project/kernel-ark/-/commit/dc84f3cc1b19a0524e58a382c382f34081dc6c35 - dc84f3cc1b19a0524e58a382c382f34081dc6c35 s390: Lock down the kernel when the IPL secure flag is set - -https://gitlab.com/cki-project/kernel-ark/-/commit/cb55378c04d6516f303e98061ec7ddd6563429a8 - cb55378c04d6516f303e98061ec7ddd6563429a8 efi: Lock down the kernel if booted in secure boot mode - -https://gitlab.com/cki-project/kernel-ark/-/commit/9b06e1f07c3cc9e1d0533b8615426d4d5d9e4ebb - 9b06e1f07c3cc9e1d0533b8615426d4d5d9e4ebb efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode - -https://gitlab.com/cki-project/kernel-ark/-/commit/db249925c6802b38d910927e4d032af1e00bee56 - db249925c6802b38d910927e4d032af1e00bee56 security: lockdown: expose a hook to lock the kernel down - -https://gitlab.com/cki-project/kernel-ark/-/commit/f9604bcd305aba2a94e713ee758a51143687ae9f - f9604bcd305aba2a94e713ee758a51143687ae9f Make get_cert_list() use efi_status_to_str() to print error messages. - -https://gitlab.com/cki-project/kernel-ark/-/commit/b75eb3e922c93d78d4190a759f5725e856d35439 - b75eb3e922c93d78d4190a759f5725e856d35439 Add efi_status_to_str() and rework efi_status_to_err(). - -https://gitlab.com/cki-project/kernel-ark/-/commit/2f80042d6b8199fceadf3623243402066e0cd4ea - 2f80042d6b8199fceadf3623243402066e0cd4ea Add support for deprecating processors - -https://gitlab.com/cki-project/kernel-ark/-/commit/5a3b4f5754788e42db8ed550b359382b600f2b08 - 5a3b4f5754788e42db8ed550b359382b600f2b08 arm: aarch64: Drop the EXPERT setting from ARM64_FORCE_52BIT - -https://gitlab.com/cki-project/kernel-ark/-/commit/36cd5d0a0aa0a3be8ac385ca8991563c9e58227f - 36cd5d0a0aa0a3be8ac385ca8991563c9e58227f iommu/arm-smmu: workaround DMA mode issues - -https://gitlab.com/cki-project/kernel-ark/-/commit/ca34010e072550c8d5ea57f9436bab254c3521cc - ca34010e072550c8d5ea57f9436bab254c3521cc rh_kabi: introduce RH_KABI_EXCLUDE - -https://gitlab.com/cki-project/kernel-ark/-/commit/26054e2c4e2253fe955a351971dc6b931cb68961 - 26054e2c4e2253fe955a351971dc6b931cb68961 ipmi: do not configure ipmi for HPE m400 - -https://gitlab.com/cki-project/kernel-ark/-/commit/9cb0f734492a21a7e506d7145caf143ccd927b2a - 9cb0f734492a21a7e506d7145caf143ccd927b2a kABI: Add generic kABI macros to use for kABI workarounds - -https://gitlab.com/cki-project/kernel-ark/-/commit/4960e5ee4a0e9bb28e512eb35cfa633ac4552049 - 4960e5ee4a0e9bb28e512eb35cfa633ac4552049 add pci_hw_vendor_status() - -https://gitlab.com/cki-project/kernel-ark/-/commit/291c4e2878431fd6937c5b9248babe8ec8d4233e - 291c4e2878431fd6937c5b9248babe8ec8d4233e ahci: thunderx2: Fix for errata that affects stop engine - -https://gitlab.com/cki-project/kernel-ark/-/commit/996869cc0b3e78cb9182a4ebced2c46ee2774935 - 996869cc0b3e78cb9182a4ebced2c46ee2774935 Vulcan: AHCI PCI bar fix for Broadcom Vulcan early silicon - -https://gitlab.com/cki-project/kernel-ark/-/commit/c1c7a887998ab12c5a1180c4bca3b41c31fe4aa6 - c1c7a887998ab12c5a1180c4bca3b41c31fe4aa6 bpf: set unprivileged_bpf_disabled to 1 by default, add a boot parameter - -https://gitlab.com/cki-project/kernel-ark/-/commit/e40c9d10474d1a5b5f7f01175a72ba4a3c7f5e8e - e40c9d10474d1a5b5f7f01175a72ba4a3c7f5e8e add Red Hat-specific taint flags - -https://gitlab.com/cki-project/kernel-ark/-/commit/f23f446b724fbb79c1e09a278fcb427fc29c0c05 - f23f446b724fbb79c1e09a278fcb427fc29c0c05 tags.sh: Ignore redhat/rpm - -https://gitlab.com/cki-project/kernel-ark/-/commit/a68aa65a20fba1908a7326e5321ce8bc39a9ae14 - a68aa65a20fba1908a7326e5321ce8bc39a9ae14 put RHEL info into generated headers - -https://gitlab.com/cki-project/kernel-ark/-/commit/80937f1973d73fccdc75db4026fbed7cba16f489 - 80937f1973d73fccdc75db4026fbed7cba16f489 aarch64: acpi scan: Fix regression related to X-Gene UARTs - -https://gitlab.com/cki-project/kernel-ark/-/commit/3362fd10fe075b48ff8af023da5643bc9477a4c6 - 3362fd10fe075b48ff8af023da5643bc9477a4c6 ACPI / irq: Workaround firmware issue on X-Gene based m400 - -https://gitlab.com/cki-project/kernel-ark/-/commit/ffc66b174954abecfb360dcc3b98c3139ef12d96 - ffc66b174954abecfb360dcc3b98c3139ef12d96 modules: add rhelversion MODULE_INFO tag - -https://gitlab.com/cki-project/kernel-ark/-/commit/7e469c23b8f648d79e8a0e82ee41cda0e50b2f19 - 7e469c23b8f648d79e8a0e82ee41cda0e50b2f19 ACPI: APEI: arm64: Ignore broken HPE moonshot APEI support - -https://gitlab.com/cki-project/kernel-ark/-/commit/a0f49117d038de2d4db4940f5f039addb2f7231d - a0f49117d038de2d4db4940f5f039addb2f7231d Add Red Hat tainting - -https://gitlab.com/cki-project/kernel-ark/-/commit/fa67c16e780ed355f9847da90e8055ad1175c238 - fa67c16e780ed355f9847da90e8055ad1175c238 Introduce CONFIG_RH_DISABLE_DEPRECATED - -https://gitlab.com/cki-project/kernel-ark/-/commit/e7e1371803470a7840dc61da628cb912834ec149 - e7e1371803470a7840dc61da628cb912834ec149 Pull the RHEL version defines out of the Makefile - -https://gitlab.com/cki-project/kernel-ark/-/commit/84d1d3e3d0c2c7ed1f571c8495bad3b4d97cfa8e - 84d1d3e3d0c2c7ed1f571c8495bad3b4d97cfa8e [initial commit] Add Red Hat variables in the top level makefile - diff --git a/README.rst b/README.rst deleted file mode 100644 index 5de37e5bb..000000000 --- a/README.rst +++ /dev/null @@ -1,25 +0,0 @@ -=================== -The Kernel dist-git -=================== - -The kernel is maintained in a `source tree`_ rather than directly in dist-git. -The specfile is maintained as a `template`_ in the source tree along with a set -of build scripts to generate configurations, (S)RPMs, and to populate the -dist-git repository. - -The `documentation`_ for the source tree covers how to contribute and maintain -the tree. - -If you're looking for the downstream patch set it's available in the source -tree with "git log master..ark-patches" or -`online`_. - -Each release in dist-git is tagged in the source repository so you can easily -check out the source tree for a build. The tags are in the format -name-version-release, but note release doesn't contain the dist tag since the -source can be built in different build roots (Fedora, CentOS, etc.) - -.. _source tree: https://gitlab.com/cki-project/kernel-ark.git -.. _template: https://gitlab.com/cki-project/kernel-ark/-/blob/os-build/redhat/kernel.spec.template -.. _documentation: https://gitlab.com/cki-project/kernel-ark/-/wikis/home -.. _online: https://gitlab.com/cki-project/kernel-ark/-/commits/ark-patches diff --git a/README.txt b/README.txt new file mode 100644 index 000000000..482f8ea5b --- /dev/null +++ b/README.txt @@ -0,0 +1,67 @@ + + Kernel package tips & tricks. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The kernel is one of the more complicated packages in the distro, and +for the newcomer, some of the voodoo in the spec file can be somewhat scary. +This file attempts to document some of the magic. + + +Speeding up make prep +--------------------- +The kernel is nearly 500MB of source code, and as such, 'make prep' +takes a while. The spec file employs some trickery so that repeated +invocations of make prep don't take as long. Ordinarily the %prep +phase of a package will delete the tree it is about to untar/patch. +The kernel %prep keeps around an unpatched version of the tree, +and makes a symlink tree clone of that clean tree and than applies +the patches listed in the spec to the symlink tree. +This makes a huge difference if you're doing multiple make preps a day. +As an added bonus, doing a diff between the clean tree and the symlink +tree is slightly faster than it would be doing two proper copies of the tree. + + +build logs. +----------- +There's a convenience helper script in scripts/grab-logs.sh +that will grab the build logs from koji for the kernel version reported +by make verrel + + +config heirarchy. +----------------- +Instead of having to maintain a config file for every arch variant we build on, +the kernel spec uses a nested system of configs. At the top level, is +config-generic. Add options here that should be present in every possible +config on all architectures. +Beneath this are per-arch overrides. For example config-x86-generic add +additional x86 specific options, and also _override_ any options that were +set in config-generic. +There exist two additional overrides, config-debug, and config-nodebug, +which override -generic, and the per-arch overrides. It is documented +further below. + +debug options. +-------------- +This is a little complicated, as the purpose & meaning of this changes +depending on where we are in the release cycle. +If we are building for a current stable release, 'make release' has +typically been run already, which sets up the following.. +- Two builds occur, a 'kernel' and a 'kernel-debug' flavor. +- kernel-debug will get various heavyweight debugging options like + lockdep etc turned on. + +If we are building for rawhide, 'make debug' has been run, which changes +the status quo to: +- We only build one kernel 'kernel' +- The debug options from 'config-debug' are always turned on. +This is done to increase coverage testing, as not many people actually +run kernel-debug. + +To add new debug options, add an option to _both_ config-debug and config-nodebug, +and also new stanzas to the Makefile 'debug' and 'release' targets. + +Sometimes debug options get added to config-generic, or per-arch overrides +instead of config-[no]debug. In this instance, the options should have no +discernable performance impact, otherwise they belong in the debug files. + diff --git a/TODO b/TODO new file mode 100644 index 000000000..abaefae05 --- /dev/null +++ b/TODO @@ -0,0 +1,61 @@ +# Put stuff likely to go upstream (in decreasing likelyhood) at the top. +# + +* linux-2.6-firewire-git-update.patch + perpetual updates from git trees. + +* linux-2.6-compile-fixes.patch +* linux-2.6-hotfixes.patch + Empty + +* linux-2.6-build-nonintconfig.patch +* linux-2.6-debug-nmi-timeout.patch +* linux-2.6-debug-spinlock-taint.patch +* linux-2.6-debug-taint-vm.patch +* linux-2.6-debug-vm-would-have-oomkilled.patch + TODO: Push upstream + +* linux-2.6-acpi-video-dos.patch +* linux-2.6-defaults-acpi-video.patch + Fedora policy decisions + Turn into CONFIG_ options and upstream ? + +* linux-2.6-crash-driver.patch + Unlikely to go upstream. + https://bugzilla.redhat.com/show_bug.cgi?id=492803 + +* linux-2.6-debug-always-inline-kzalloc.patch + Sent upstream Sep 25 2008 + +* linux-2.6-debug-sizeof-structs.patch + Fedora local debug stuff. + +* linux-2.6-utrace.patch + utrace + +* linux-2.6-defaults-pci_no_msi.patch + Fedora local choices uninteresting to upstream + +* linux-2.6-input-kill-stupid-messages.patch +* linux-2.6-silence-acpi-blacklist.patch +* linux-2.6-silence-fbcon-logo.patch +* linux-2.6-silence-noise.patch + Fedora local 'hush' patches. (Some will go upstream next time) + +* linux-2.6-execshield.patch + Not interesting to upstream. + +* lirc-2.6.33.patch +* hdpvr-ir-enable.patch + jarod working on upstreaming + +* linux-2.6-selinux-mprotect-checks.patch +* linux-2.6-sparc-selinux-mprotect-checks.patch + Newer version might go upstream at some point. + +* linux-2.6-serial-460800.patch + Probably not upstreamable. + http://marc.theaimsgroup.com/?l=linux-kernel&m=112687270832687&w=2 + https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=126403 + http://lkml.org/lkml/2006/8/2/208 + diff --git a/TPM-Call-tpm_transmit-with-correct-size.patch b/TPM-Call-tpm_transmit-with-correct-size.patch new file mode 100644 index 000000000..64f776f13 --- /dev/null +++ b/TPM-Call-tpm_transmit-with-correct-size.patch @@ -0,0 +1,43 @@ +From 6b07d30aca7e52f2881b8c8c20c8a2cd28e8b3d3 Mon Sep 17 00:00:00 2001 +From: Peter Huewe +Date: Thu, 15 Sep 2011 14:37:43 -0300 +Subject: [PATCH] TPM: Call tpm_transmit with correct size + +This patch changes the call of tpm_transmit by supplying the size of the +userspace buffer instead of TPM_BUFSIZE. + +This got assigned CVE-2011-1161. + +[The first hunk didn't make sense given one could expect + way less data than TPM_BUFSIZE, so added tpm_transmit boundary + check over bufsiz instead + The last parameter of tpm_transmit() reflects the amount + of data expected from the device, and not the buffer size + being supplied to it. It isn't ideal to parse it directly, + so we just set it to the maximum the input buffer can handle + and let the userspace API to do such job.] + +Signed-off-by: Rajiv Andrade +Cc: Stable Kernel +Signed-off-by: James Morris +--- + drivers/char/tpm/tpm.c | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c +index caf8012..1fe9793 100644 +--- a/drivers/char/tpm/tpm.c ++++ b/drivers/char/tpm/tpm.c +@@ -383,6 +383,9 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, + u32 count, ordinal; + unsigned long stop; + ++ if (bufsiz > TPM_BUFSIZE) ++ bufsiz = TPM_BUFSIZE; ++ + count = be32_to_cpu(*((__be32 *) (buf + 2))); + ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); + if (count == 0) +-- +1.7.6 + diff --git a/TPM-Zero-buffer-after-copying-to-userspace.patch b/TPM-Zero-buffer-after-copying-to-userspace.patch new file mode 100644 index 000000000..1b3d9ac48 --- /dev/null +++ b/TPM-Zero-buffer-after-copying-to-userspace.patch @@ -0,0 +1,45 @@ +From 3321c07ae5068568cd61ac9f4ba749006a7185c9 Mon Sep 17 00:00:00 2001 +From: Peter Huewe +Date: Thu, 15 Sep 2011 14:47:42 -0300 +Subject: [PATCH] TPM: Zero buffer after copying to userspace + +Since the buffer might contain security related data it might be a good idea to +zero the buffer after we have copied it to userspace. + +This got assigned CVE-2011-1162. + +Signed-off-by: Rajiv Andrade +Cc: Stable Kernel +Signed-off-by: James Morris +--- + drivers/char/tpm/tpm.c | 6 +++++- + 1 files changed, 5 insertions(+), 1 deletions(-) + +diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c +index 1fe9793..9ca5c02 100644 +--- a/drivers/char/tpm/tpm.c ++++ b/drivers/char/tpm/tpm.c +@@ -1105,6 +1105,7 @@ ssize_t tpm_read(struct file *file, char __user *buf, + { + struct tpm_chip *chip = file->private_data; + ssize_t ret_size; ++ int rc; + + del_singleshot_timer_sync(&chip->user_read_timer); + flush_work_sync(&chip->work); +@@ -1115,8 +1116,11 @@ ssize_t tpm_read(struct file *file, char __user *buf, + ret_size = size; + + mutex_lock(&chip->buffer_mutex); +- if (copy_to_user(buf, chip->data_buffer, ret_size)) ++ rc = copy_to_user(buf, chip->data_buffer, ret_size); ++ memset(chip->data_buffer, 0, ret_size); ++ if (rc) + ret_size = -EFAULT; ++ + mutex_unlock(&chip->buffer_mutex); + } + +-- +1.7.6 + diff --git a/acer-wmi-modalias.patch b/acer-wmi-modalias.patch new file mode 100644 index 000000000..ac2f452d0 --- /dev/null +++ b/acer-wmi-modalias.patch @@ -0,0 +1,29 @@ +commit 08a0799d5736f1494ef35d386570d177447acbfb +Author: Lee, Chun-Yi +Date: Wed Apr 6 17:40:06 2011 +0800 + + acer-wmi: Fix capitalisation of GUID in module alias + + wmi:6AF4F258-B401-42Fd-BE91-3D4AC2D7C0D3 needs to be + wmi:6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3 in module alias for acer-wmi is + automatically loaded. + + Cc: Pali Rohár + Cc: Carlos Corbacho + Cc: Matthew Garrett + Signed-off-by: Lee, Chun-Yi + Signed-off-by: Matthew Garrett + +diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c +index 5ea6c34..ac4e7f8 100644 +--- a/drivers/platform/x86/acer-wmi.c ++++ b/drivers/platform/x86/acer-wmi.c +@@ -95,7 +95,7 @@ struct acer_quirks { + #define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A" + + MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB"); +-MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"); ++MODULE_ALIAS("wmi:6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"); + + /* + * Interface capability flags diff --git a/acpi-ec-add-delay-before-write.patch b/acpi-ec-add-delay-before-write.patch new file mode 100644 index 000000000..af49cccbd --- /dev/null +++ b/acpi-ec-add-delay-before-write.patch @@ -0,0 +1,52 @@ +https://bugzilla.kernel.org/show_bug.cgi?id=14733#c41 + +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index 27e0b92..09fbb69 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -226,6 +226,7 @@ static int ec_poll(struct acpi_ec *ec) + if (ec_transaction_done(ec)) + return 0; + } else { ++ msleep(1); + if (wait_event_timeout(ec->wait, + ec_transaction_done(ec), + msecs_to_jiffies(1))) +@@ -233,8 +234,8 @@ static int ec_poll(struct acpi_ec *ec) + } + advance_transaction(ec, acpi_ec_read_status(ec)); + } while (time_before(jiffies, delay)); +- if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) +- break; ++// if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) ++// break; + pr_debug(PREFIX "controller reset, restart transaction\n"); + spin_lock_irqsave(&ec->curr_lock, flags); + start_transaction(ec); +@@ -271,15 +272,25 @@ static int ec_check_ibf0(struct acpi_ec *ec) + return (status & ACPI_EC_FLAG_IBF) == 0; + } + ++/* try to clean input buffer with burst_disable transaction */ ++static int acpi_ec_clean_buffer(struct acpi_ec *ec) ++{ ++ struct transaction t = {.command = ACPI_EC_BURST_DISABLE, ++ .wdata = NULL, .rdata = NULL, ++ .wlen = 0, .rlen = 0}; ++ return acpi_ec_transaction_unlocked(ec, &t); ++} ++ + static int ec_wait_ibf0(struct acpi_ec *ec) + { ++ + unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); + /* interrupt wait manually if GPE mode is not active */ + while (time_before(jiffies, delay)) + if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), + msecs_to_jiffies(1))) + return 0; +- return -ETIME; ++ return acpi_ec_clean_buffer(ec); + } + + static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) diff --git a/acpi-sony-nonvs-blacklist.patch b/acpi-sony-nonvs-blacklist.patch new file mode 100644 index 000000000..db500e8bf --- /dev/null +++ b/acpi-sony-nonvs-blacklist.patch @@ -0,0 +1,38 @@ +diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c +index 3ed80b2..17fc718 100644 +--- a/drivers/acpi/sleep.c ++++ b/drivers/acpi/sleep.c +@@ -390,6 +390,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { + }, + { + .callback = init_nvs_nosave, ++ .ident = "Sony Vaio VGN-FW21E", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21E"), ++ }, ++ }, ++ { ++ .callback = init_nvs_nosave, + .ident = "Sony Vaio VGN-SR11M", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), +diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c +index 0e46fae..6d9a3ab 100644 +--- a/drivers/acpi/sleep.c ++++ b/drivers/acpi/sleep.c +@@ -398,6 +398,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { + }, + { + .callback = init_nvs_nosave, ++ .ident = "Sony Vaio VPCEB17FX", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB17FX"), ++ }, ++ }, ++ { ++ .callback = init_nvs_nosave, + .ident = "Sony Vaio VGN-SR11M", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), diff --git a/acpi-update-battery-information-on-notification-0x81.patch b/acpi-update-battery-information-on-notification-0x81.patch new file mode 100644 index 000000000..e9c027291 --- /dev/null +++ b/acpi-update-battery-information-on-notification-0x81.patch @@ -0,0 +1,68 @@ +--- linux-2.6.35.x86_64/drivers/acpi/battery.c.orig 2010-12-23 10:42:09.291854595 -0500 ++++ linux-2.6.35.x86_64/drivers/acpi/battery.c 2010-12-23 10:44:30.996045838 -0500 +@@ -596,9 +596,10 @@ + } + } + +-static int acpi_battery_update(struct acpi_battery *battery) ++static int acpi_battery_update(struct acpi_battery *battery, bool get_info) + { + int result, old_present = acpi_battery_present(battery); ++ int old_power_unit = battery->power_unit; + result = acpi_battery_get_status(battery); + if (result) + return result; +@@ -621,6 +622,16 @@ + if (!battery->bat.dev) + sysfs_add_battery(battery); + #endif ++ if (get_info) { ++ acpi_battery_get_info(battery); ++#ifdef CONFIG_ACPI_SYSFS_POWER ++ if (old_power_unit != battery->power_unit) { ++ /* The battery has changed its reporting units */ ++ sysfs_remove_battery(battery); ++ sysfs_add_battery(battery); ++ } ++#endif ++ } + result = acpi_battery_get_state(battery); + acpi_battery_quirks2(battery); + return result; +@@ -798,7 +809,7 @@ + static int acpi_battery_read(int fid, struct seq_file *seq) + { + struct acpi_battery *battery = seq->private; +- int result = acpi_battery_update(battery); ++ int result = acpi_battery_update(battery, false); + return acpi_print_funcs[fid](seq, result); + } + +@@ -913,7 +924,8 @@ + #ifdef CONFIG_ACPI_SYSFS_POWER + old = battery->bat.dev; + #endif +- acpi_battery_update(battery); ++ acpi_battery_update(battery, (event == ACPI_BATTERY_NOTIFY_INFO ? true ++ : false)); + acpi_bus_generate_proc_event(device, event, + acpi_battery_present(battery)); + acpi_bus_generate_netlink_event(device->pnp.device_class, +@@ -944,7 +956,7 @@ + if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle, + "_BIX", &handle))) + set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); +- acpi_battery_update(battery); ++ acpi_battery_update(battery, false); + #ifdef CONFIG_ACPI_PROCFS_POWER + result = acpi_battery_add_fs(device); + #endif +@@ -987,7 +999,7 @@ + return -EINVAL; + battery = acpi_driver_data(device); + battery->update_time = 0; +- acpi_battery_update(battery); ++ acpi_battery_update(battery, true); + return 0; + } + diff --git a/add-appleir-usb-driver.patch b/add-appleir-usb-driver.patch new file mode 100644 index 000000000..999ee2e69 --- /dev/null +++ b/add-appleir-usb-driver.patch @@ -0,0 +1,702 @@ +From 46fadae732d825141f45bf2fbd6381451da26ad7 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Fri, 10 Sep 2010 16:40:46 +0100 +Subject: [PATCH] Input: add appleir USB driver + +This driver was originally written by James McKenzie, updated by +Greg Kroah-Hartman, further updated by myself, with suspend support +added. + +More recent versions of the IR receiver are also supported through +a patch by Alex Karpenko. The patch also adds support for the 2nd +and 5th generation of the controller, and the menu key on newer +brushed metal remotes. + +Tested on a MacbookAir1,1 + +Signed-off-by: Bastien Nocera +--- + Documentation/input/appleir.txt | 46 ++++ + drivers/hid/hid-apple.c | 4 - + drivers/hid/hid-core.c | 7 +- + drivers/hid/hid-ids.h | 5 +- + drivers/input/misc/Kconfig | 13 + + drivers/input/misc/Makefile | 1 + + drivers/input/misc/appleir.c | 519 +++++++++++++++++++++++++++++++++++++++ + 7 files changed, 588 insertions(+), 7 deletions(-) + create mode 100644 Documentation/input/appleir.txt + create mode 100644 drivers/input/misc/appleir.c + +diff --git a/Documentation/input/appleir.txt b/Documentation/input/appleir.txt +new file mode 100644 +index 0000000..db637fb +--- /dev/null ++++ b/Documentation/input/appleir.txt +@@ -0,0 +1,46 @@ ++Apple IR receiver Driver (appleir) ++---------------------------------- ++ Copyright (C) 2009 Bastien Nocera ++ ++The appleir driver is a kernel input driver to handle Apple's IR ++receivers (and associated remotes) in the kernel. ++ ++The driver is an input driver which only handles "official" remotes ++as built and sold by Apple. ++ ++Authors ++------- ++ ++James McKenzie (original driver) ++Alex Karpenko (05ac:8242 support) ++Greg Kroah-Hartman (cleanups and original submission) ++Bastien Nocera (further cleanups, brushed metal "enter" ++button support and suspend support) ++ ++Supported hardware ++------------------ ++ ++- All Apple laptops and desktops from 2005 onwards, except: ++ - the unibody Macbook (2009) ++ - Mac Pro (all versions) ++- Apple TV (all revisions prior to September 2010) ++ ++The remote will only support the 6 (old white) or 7 (brushed metal) buttons ++of the remotes as sold by Apple. See the next section if you want to use ++other remotes or want to use lirc with the device instead of the kernel driver. ++ ++Using lirc (native) instead of the kernel driver ++------------------------------------------------ ++ ++First, you will need to disable the kernel driver for the receiver. ++ ++This can be achieved by passing quirks to the usbhid driver. ++The quirk line would be: ++usbhid.quirks=0x05ac:0x8242:0x40000010 ++ ++With 0x05ac being the vendor ID (Apple, you shouldn't need to change this) ++With 0x8242 being the product ID (check the output of lsusb for your hardware) ++And 0x10 being "HID_QUIRK_HIDDEV_FORCE" and 0x40000000 being "HID_QUIRK_NO_IGNORE" ++ ++This should force the creation of a hiddev device for the receiver, and ++make it usable under lirc. +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index bba05d0..0059d5a 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -361,10 +361,6 @@ static void apple_remove(struct hid_device *hdev) + } + + static const struct hid_device_id apple_devices[] = { +- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL), +- .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT }, +- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4), +- .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE), + .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL }, + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 866e54e..1d5e284 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1239,8 +1239,6 @@ static const struct hid_device_id hid_blacklist[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, + { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, + { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, +@@ -1571,6 +1569,11 @@ static const struct hid_device_id hid_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) }, + { HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT)}, + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)}, + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)}, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 31601ee..9afe3bc 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -98,8 +98,11 @@ + #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b + #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a + #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b +-#define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 ++#define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 ++#define USB_DEVICE_ID_APPLE_IRCONTROL2 0x1440 ++#define USB_DEVICE_ID_APPLE_IRCONTROL3 0x8241 + #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 ++#define USB_DEVICE_ID_APPLE_IRCONTROL5 0x8243 + + #define USB_VENDOR_ID_ASUS 0x0486 + #define USB_DEVICE_ID_ASUS_T91MT 0x0185 +diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig +index c44b9ea..76a12b7 100644 +--- a/drivers/input/misc/Kconfig ++++ b/drivers/input/misc/Kconfig +@@ -199,6 +199,19 @@ config INPUT_KEYSPAN_REMOTE + To compile this driver as a module, choose M here: the module will + be called keyspan_remote. + ++config INPUT_APPLEIR ++ tristate "Apple infrared receiver (built in)" ++ depends on USB_ARCH_HAS_HCD ++ select USB ++ help ++ Say Y here if you want to use a Apple infrared remote control. All ++ the Apple computers from 2005 onwards include such a port, except ++ the unibody Macbook (2009), and Mac Pros. This receiver is also ++ used in the Apple TV set-top box prior to the 2010 model. ++ ++ To compile this driver as a module, choose M here: the module will ++ be called appleir. ++ + config INPUT_POWERMATE + tristate "Griffin PowerMate and Contour Jog support" + depends on USB_ARCH_HAS_HCD +diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile +index 71fe57d..62a5c60 100644 +--- a/drivers/input/misc/Makefile ++++ b/drivers/input/misc/Makefile +@@ -9,6 +9,7 @@ obj-$(CONFIG_INPUT_AD714X) += ad714x.o + obj-$(CONFIG_INPUT_AD714X_I2C) += ad714x-i2c.o + obj-$(CONFIG_INPUT_AD714X_SPI) += ad714x-spi.o + obj-$(CONFIG_INPUT_APANEL) += apanel.o ++obj-$(CONFIG_INPUT_APPLEIR) += appleir.o + obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o + obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o + obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o +diff --git a/drivers/input/misc/appleir.c b/drivers/input/misc/appleir.c +new file mode 100644 +index 0000000..3817a3c +--- /dev/null ++++ b/drivers/input/misc/appleir.c +@@ -0,0 +1,519 @@ ++/* ++ * appleir: USB driver for the apple ir device ++ * ++ * Original driver written by James McKenzie ++ * Ported to recent 2.6 kernel versions by Greg Kroah-Hartman ++ * ++ * Copyright (C) 2006 James McKenzie ++ * Copyright (C) 2008 Greg Kroah-Hartman ++ * Copyright (C) 2008 Novell Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the Free ++ * Software Foundation, version 2. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_VERSION "v1.2" ++#define DRIVER_AUTHOR "James McKenzie" ++#define DRIVER_DESC "Apple infrared receiver driver" ++#define DRIVER_LICENSE "GPL" ++ ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_LICENSE(DRIVER_LICENSE); ++ ++#define USB_VENDOR_ID_APPLE 0x05ac ++#define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 ++#define USB_DEVICE_ID_APPLE_IRCONTROL2 0x1440 ++#define USB_DEVICE_ID_APPLE_IRCONTROL3 0x8241 ++#define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 ++#define USB_DEVICE_ID_APPLE_IRCONTROL5 0x8243 ++ ++#define URB_SIZE 32 ++ ++#define MAX_KEYS 9 ++#define MAX_KEYS_MASK (MAX_KEYS - 1) ++ ++#define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0) ++ ++static int debug; ++module_param(debug, int, 0644); ++MODULE_PARM_DESC(debug, "Enable extra debug messages and information"); ++ ++/* I have two devices both of which report the following */ ++/* 25 87 ee 83 0a + */ ++/* 25 87 ee 83 0c - */ ++/* 25 87 ee 83 09 << */ ++/* 25 87 ee 83 06 >> */ ++/* 25 87 ee 83 05 >" */ ++/* 25 87 ee 83 03 menu */ ++/* 26 00 00 00 00 for key repeat*/ ++ ++/* Thomas Glanzmann reports the following responses */ ++/* 25 87 ee ca 0b + */ ++/* 25 87 ee ca 0d - */ ++/* 25 87 ee ca 08 << */ ++/* 25 87 ee ca 07 >> */ ++/* 25 87 ee ca 04 >" */ ++/* 25 87 ee ca 02 menu */ ++/* 26 00 00 00 00 for key repeat*/ ++/* He also observes the following event sometimes */ ++/* sent after a key is release, which I interpret */ ++/* as a flat battery message */ ++/* 25 87 e0 ca 06 flat battery */ ++ ++/* Alexandre Karpenko reports the following responses for Device ID 0x8242 */ ++/* 25 87 ee 47 0b + */ ++/* 25 87 ee 47 0d - */ ++/* 25 87 ee 47 08 << */ ++/* 25 87 ee 47 07 >> */ ++/* 25 87 ee 47 04 >" */ ++/* 25 87 ee 47 02 menu */ ++/* 26 87 ee 47 ** for key repeat (** is the code of the key being held) */ ++ ++/* Bastien Nocera's "new" remote */ ++/* 25 87 ee 91 5f followed by ++ * 25 87 ee 91 05 gives you >" ++ * ++ * 25 87 ee 91 5c followed by ++ * 25 87 ee 91 05 gives you the middle button */ ++ ++static const unsigned short appleir_key_table[] = { ++ KEY_RESERVED, ++ KEY_MENU, ++ KEY_PLAYPAUSE, ++ KEY_FORWARD, ++ KEY_BACK, ++ KEY_VOLUMEUP, ++ KEY_VOLUMEDOWN, ++ KEY_ENTER, ++ KEY_RESERVED, ++}; ++ ++struct appleir { ++ struct input_dev *input_dev; ++ unsigned short keymap[ARRAY_SIZE(appleir_key_table)]; ++ u8 *data; ++ dma_addr_t dma_buf; ++ struct usb_device *usbdev; ++ unsigned int flags; ++ struct urb *urb; ++ struct timer_list key_up_timer; ++ int current_key; ++ int prev_key_idx; ++ char phys[32]; ++}; ++ ++static DEFINE_MUTEX(appleir_mutex); ++ ++enum { ++ APPLEIR_OPENED = 0x1, ++ APPLEIR_SUSPENDED = 0x2, ++}; ++ ++static struct usb_device_id appleir_ids[] = { ++ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) }, ++ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) }, ++ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) }, ++ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, ++ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) }, ++ {} ++}; ++MODULE_DEVICE_TABLE(usb, appleir_ids); ++ ++static void dump_packet(struct appleir *appleir, char *msg, u8 *data, int len) ++{ ++ int i; ++ ++ printk(KERN_ERR "appleir: %s (%d bytes)", msg, len); ++ ++ for (i = 0; i < len; ++i) ++ printk(" %02x", data[i]); ++ printk(" (should be command %d)\n", (data[4] >> 1) & MAX_KEYS_MASK); ++} ++ ++static int get_key(int data) ++{ ++ switch (data) { ++ case 0x02: ++ case 0x03: ++ /* menu */ ++ return 1; ++ case 0x04: ++ case 0x05: ++ /* >" */ ++ return 2; ++ case 0x06: ++ case 0x07: ++ /* >> */ ++ return 3; ++ case 0x08: ++ case 0x09: ++ /* << */ ++ return 4; ++ case 0x0a: ++ case 0x0b: ++ /* + */ ++ return 5; ++ case 0x0c: ++ case 0x0d: ++ /* - */ ++ return 6; ++ case 0x5c: ++ /* Middle button, on newer remotes, ++ * part of a 2 packet-command */ ++ return -7; ++ default: ++ return -1; ++ } ++} ++ ++static void key_up(struct appleir *appleir, int key) ++{ ++ dbginfo(&appleir->input_dev->dev, "key %d up\n", key); ++ input_report_key(appleir->input_dev, key, 0); ++ input_sync(appleir->input_dev); ++} ++ ++static void key_down(struct appleir *appleir, int key) ++{ ++ dbginfo(&appleir->input_dev->dev, "key %d down\n", key); ++ input_report_key(appleir->input_dev, key, 1); ++ input_sync(appleir->input_dev); ++} ++ ++static void battery_flat(struct appleir *appleir) ++{ ++ dev_err(&appleir->input_dev->dev, "possible flat battery?\n"); ++} ++ ++static void key_up_tick(unsigned long data) ++{ ++ struct appleir *appleir = (struct appleir *)data; ++ ++ if (appleir->current_key) { ++ key_up(appleir, appleir->current_key); ++ appleir->current_key = 0; ++ } ++} ++ ++static void new_data(struct appleir *appleir, u8 *data, int len) ++{ ++ static const u8 keydown[] = { 0x25, 0x87, 0xee }; ++ static const u8 keyrepeat[] = { 0x26, }; ++ static const u8 flatbattery[] = { 0x25, 0x87, 0xe0 }; ++ ++ if (debug) ++ dump_packet(appleir, "received", data, len); ++ ++ if (len != 5) ++ return; ++ ++ if (!memcmp(data, keydown, sizeof(keydown))) { ++ int index; ++ ++ /* If we already have a key down, take it up before marking ++ this one down */ ++ if (appleir->current_key) ++ key_up(appleir, appleir->current_key); ++ ++ /* Handle dual packet commands */ ++ if (appleir->prev_key_idx > 0) ++ index = appleir->prev_key_idx; ++ else ++ index = get_key(data[4]); ++ ++ if (index > 0) { ++ appleir->current_key = appleir->keymap[index]; ++ ++ key_down(appleir, appleir->current_key); ++ /* Remote doesn't do key up, either pull them up, in the test ++ above, or here set a timer which pulls them up after 1/8 s */ ++ mod_timer(&appleir->key_up_timer, jiffies + HZ / 8); ++ appleir->prev_key_idx = 0; ++ return; ++ } else if (index == -7) { ++ /* Remember key for next packet */ ++ appleir->prev_key_idx = 0 - index; ++ return; ++ } ++ } ++ ++ appleir->prev_key_idx = 0; ++ ++ if (!memcmp(data, keyrepeat, sizeof(keyrepeat))) { ++ key_down(appleir, appleir->current_key); ++ /* Remote doesn't do key up, either pull them up, in the test ++ above, or here set a timer which pulls them up after 1/8 s */ ++ mod_timer(&appleir->key_up_timer, jiffies + HZ / 8); ++ return; ++ } ++ ++ if (!memcmp(data, flatbattery, sizeof(flatbattery))) { ++ battery_flat(appleir); ++ /* Fall through */ ++ } ++ ++ dump_packet(appleir, "unknown packet", data, len); ++} ++ ++static void appleir_urb(struct urb *urb) ++{ ++ struct appleir *appleir = urb->context; ++ int status = urb->status; ++ int retval; ++ ++ switch (status) { ++ case 0: ++ new_data(appleir, urb->transfer_buffer, urb->actual_length); ++ break; ++ case -ECONNRESET: ++ case -ENOENT: ++ case -ESHUTDOWN: ++ /* This urb is terminated, clean up */ ++ dbginfo(&appleir->input_dev->dev, "%s - urb shutting down with status: %d", __func__, ++ urb->status); ++ return; ++ default: ++ dbginfo(&appleir->input_dev->dev, "%s - nonzero urb status received: %d", __func__, ++ urb->status); ++ } ++ ++ retval = usb_submit_urb(urb, GFP_ATOMIC); ++ if (retval) ++ err("%s - usb_submit_urb failed with result %d", __func__, ++ retval); ++} ++ ++static int appleir_open(struct input_dev *dev) ++{ ++ struct appleir *appleir = input_get_drvdata(dev); ++ struct usb_interface *intf = usb_ifnum_to_if(appleir->usbdev, 0); ++ int r; ++ ++ r = usb_autopm_get_interface(intf); ++ if (r) { ++ dev_err(&intf->dev, ++ "%s(): usb_autopm_get_interface() = %d\n", __func__, r); ++ return r; ++ } ++ ++ mutex_lock(&appleir_mutex); ++ ++ if (usb_submit_urb(appleir->urb, GFP_ATOMIC)) { ++ r = -EIO; ++ goto fail; ++ } ++ ++ appleir->flags |= APPLEIR_OPENED; ++ ++ mutex_unlock(&appleir_mutex); ++ ++ usb_autopm_put_interface(intf); ++ ++ return 0; ++fail: ++ mutex_unlock(&appleir_mutex); ++ usb_autopm_put_interface(intf); ++ return r; ++} ++ ++static void appleir_close(struct input_dev *dev) ++{ ++ struct appleir *appleir = input_get_drvdata(dev); ++ ++ mutex_lock(&appleir_mutex); ++ ++ if (!(appleir->flags & APPLEIR_SUSPENDED)) { ++ usb_kill_urb(appleir->urb); ++ del_timer_sync(&appleir->key_up_timer); ++ } ++ ++ appleir->flags &= ~APPLEIR_OPENED; ++ ++ mutex_unlock(&appleir_mutex); ++} ++ ++static int appleir_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *dev = interface_to_usbdev(intf); ++ struct usb_endpoint_descriptor *endpoint; ++ struct appleir *appleir = NULL; ++ struct input_dev *input_dev; ++ int retval = -ENOMEM; ++ int i; ++ ++ appleir = kzalloc(sizeof(struct appleir), GFP_KERNEL); ++ if (!appleir) ++ goto allocfail; ++ ++ appleir->data = usb_alloc_coherent(dev, URB_SIZE, GFP_KERNEL, ++ &appleir->dma_buf); ++ if (!appleir->data) ++ goto usbfail; ++ ++ appleir->urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!appleir->urb) ++ goto urbfail; ++ ++ appleir->usbdev = dev; ++ ++ input_dev = input_allocate_device(); ++ if (!input_dev) ++ goto inputfail; ++ ++ appleir->input_dev = input_dev; ++ ++ usb_make_path(dev, appleir->phys, sizeof(appleir->phys)); ++ strlcpy(appleir->phys, "/input0", sizeof(appleir->phys)); ++ ++ input_dev->name = "Apple Infrared Remote Controller"; ++ input_dev->phys = appleir->phys; ++ usb_to_input_id(dev, &input_dev->id); ++ input_dev->dev.parent = &intf->dev; ++ input_dev->keycode = appleir->keymap; ++ input_dev->keycodesize = sizeof(unsigned short); ++ input_dev->keycodemax = ARRAY_SIZE(appleir->keymap); ++ ++ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); ++ ++ memcpy(appleir->keymap, appleir_key_table, sizeof(appleir->keymap)); ++ for (i = 0; i < ARRAY_SIZE(appleir_key_table); i++) ++ set_bit(appleir->keymap[i], input_dev->keybit); ++ clear_bit(KEY_RESERVED, input_dev->keybit); ++ ++ input_set_drvdata(input_dev, appleir); ++ input_dev->open = appleir_open; ++ input_dev->close = appleir_close; ++ ++ endpoint = &intf->cur_altsetting->endpoint[0].desc; ++ ++ usb_fill_int_urb(appleir->urb, dev, ++ usb_rcvintpipe(dev, endpoint->bEndpointAddress), ++ appleir->data, 8, ++ appleir_urb, appleir, endpoint->bInterval); ++ ++ appleir->urb->transfer_dma = appleir->dma_buf; ++ appleir->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ ++ setup_timer(&appleir->key_up_timer, ++ key_up_tick, (unsigned long) appleir); ++ ++ retval = input_register_device(appleir->input_dev); ++ if (retval) ++ goto inputfail; ++ ++ usb_set_intfdata(intf, appleir); ++ ++ return 0; ++ ++inputfail: ++ input_free_device(appleir->input_dev); ++ ++urbfail: ++ usb_free_urb(appleir->urb); ++ ++usbfail: ++ usb_free_coherent(dev, URB_SIZE, appleir->data, ++ appleir->dma_buf); ++ ++allocfail: ++ kfree(appleir); ++ ++ return retval; ++} ++ ++static void appleir_disconnect(struct usb_interface *intf) ++{ ++ struct appleir *appleir = usb_get_intfdata(intf); ++ ++ usb_set_intfdata(intf, NULL); ++ input_unregister_device(appleir->input_dev); ++ usb_free_urb(appleir->urb); ++ usb_free_coherent(interface_to_usbdev(intf), URB_SIZE, ++ appleir->data, appleir->dma_buf); ++ kfree(appleir); ++} ++ ++static int appleir_suspend(struct usb_interface *interface, ++ pm_message_t message) ++{ ++ struct appleir *appleir = usb_get_intfdata(interface); ++ ++ mutex_lock(&appleir_mutex); ++ if (appleir->flags & APPLEIR_OPENED) ++ usb_kill_urb(appleir->urb); ++ ++ appleir->flags |= APPLEIR_SUSPENDED; ++ ++ mutex_unlock(&appleir_mutex); ++ ++ return 0; ++} ++ ++static int appleir_resume(struct usb_interface *interface) ++{ ++ struct appleir *appleir; ++ int r = 0; ++ ++ appleir = usb_get_intfdata(interface); ++ ++ mutex_lock(&appleir_mutex); ++ if (appleir->flags & APPLEIR_OPENED) { ++ struct usb_endpoint_descriptor *endpoint; ++ ++ endpoint = &interface->cur_altsetting->endpoint[0].desc; ++ usb_fill_int_urb(appleir->urb, appleir->usbdev, ++ usb_rcvintpipe(appleir->usbdev, endpoint->bEndpointAddress), ++ appleir->data, 8, ++ appleir_urb, appleir, endpoint->bInterval); ++ appleir->urb->transfer_dma = appleir->dma_buf; ++ appleir->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ ++ /* And reset the USB device */ ++ if (usb_submit_urb(appleir->urb, GFP_ATOMIC)) ++ r = -EIO; ++ } ++ ++ appleir->flags &= ~APPLEIR_SUSPENDED; ++ ++ mutex_unlock(&appleir_mutex); ++ ++ return r; ++} ++ ++static struct usb_driver appleir_driver = { ++ .name = "appleir", ++ .probe = appleir_probe, ++ .disconnect = appleir_disconnect, ++ .suspend = appleir_suspend, ++ .resume = appleir_resume, ++ .reset_resume = appleir_resume, ++ .id_table = appleir_ids, ++}; ++ ++static int __init appleir_init(void) ++{ ++ return usb_register(&appleir_driver); ++} ++ ++static void __exit appleir_exit(void) ++{ ++ usb_deregister(&appleir_driver); ++} ++ ++module_init(appleir_init); ++module_exit(appleir_exit); +-- +1.7.2.2 + diff --git a/af_netlink-add-needed-scm_destroy-after-scm_send.patch b/af_netlink-add-needed-scm_destroy-after-scm_send.patch new file mode 100644 index 000000000..df8c69ca0 --- /dev/null +++ b/af_netlink-add-needed-scm_destroy-after-scm_send.patch @@ -0,0 +1,57 @@ +From: Eric W. Biederman +Date: Sun, 13 Jun 2010 03:31:06 +0000 (+0000) +Subject: af_netlink: Add needed scm_destroy after scm_send. +X-Git-Tag: v2.6.36-rc1~571^2~552 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=b47030c71dfd6c8cd5cb6e551b6f7f7cfc96f6a6 + +af_netlink: Add needed scm_destroy after scm_send. + +scm_send occasionally allocates state in the scm_cookie, so I have +modified netlink_sendmsg to guarantee that when scm_send succeeds +scm_destory will be called to free that state. + +Signed-off-by: Eric W. Biederman +Reviewed-by: Daniel Lezcano +Acked-by: Pavel Emelyanov +Signed-off-by: David S. Miller +--- + +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index a2eb965..7aeaa83 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1323,19 +1323,23 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, + if (msg->msg_flags&MSG_OOB) + return -EOPNOTSUPP; + +- if (NULL == siocb->scm) ++ if (NULL == siocb->scm) { + siocb->scm = &scm; ++ memset(&scm, 0, sizeof(scm)); ++ } + err = scm_send(sock, msg, siocb->scm); + if (err < 0) + return err; + + if (msg->msg_namelen) { ++ err = -EINVAL; + if (addr->nl_family != AF_NETLINK) +- return -EINVAL; ++ goto out; + dst_pid = addr->nl_pid; + dst_group = ffs(addr->nl_groups); ++ err = -EPERM; + if (dst_group && !netlink_capable(sock, NL_NONROOT_SEND)) +- return -EPERM; ++ goto out; + } else { + dst_pid = nlk->dst_pid; + dst_group = nlk->dst_group; +@@ -1387,6 +1391,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, + err = netlink_unicast(sk, skb, dst_pid, msg->msg_flags&MSG_DONTWAIT); + + out: ++ scm_destroy(siocb->scm); + return err; + } + diff --git a/asix-add-USB-ID-for-Logitec-LAN-GTJ-U2A.patch b/asix-add-USB-ID-for-Logitec-LAN-GTJ-U2A.patch new file mode 100644 index 000000000..c0d7754a0 --- /dev/null +++ b/asix-add-USB-ID-for-Logitec-LAN-GTJ-U2A.patch @@ -0,0 +1,34 @@ +From f4680d3db71f13d2764340a9880745bf54f2469d Mon Sep 17 00:00:00 2001 +From: Arnaud Ebalard +Date: Wed, 15 Dec 2010 12:16:30 +0000 +Subject: [PATCH] asix: add USB ID for Logitec LAN-GTJ U2A + +Logitec LAN-GTJ U2A (http://www.pro.logitec.co.jp/pro/g/gLAN-GTJU2A/) +USB 2.0 10/10/1000 Ethernet adapter is based on ASIX AX88178 chipset. + +This patch adds missing USB ID for the device. + +Signed-off-by: Arnaud Ebalard +Signed-off-by: David S. Miller +--- + drivers/net/usb/asix.c | 4 ++++ + 1 files changed, 4 insertions(+), 0 deletions(-) + +diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c +index aea4645..6140b56 100644 +--- a/drivers/net/usb/asix.c ++++ b/drivers/net/usb/asix.c +@@ -1508,6 +1508,10 @@ static const struct usb_device_id products [] = { + USB_DEVICE (0x0b95, 0x1780), + .driver_info = (unsigned long) &ax88178_info, + }, { ++ // Logitec LAN-GTJ/U2A ++ USB_DEVICE (0x0789, 0x0160), ++ .driver_info = (unsigned long) &ax88178_info, ++}, { + // Linksys USB200M Rev 2 + USB_DEVICE (0x13b1, 0x0018), + .driver_info = (unsigned long) &ax88772_info, +-- +1.7.6 + diff --git a/befs-Validate-length-of-long-symbolic-links.patch b/befs-Validate-length-of-long-symbolic-links.patch new file mode 100644 index 000000000..f53dfbfad --- /dev/null +++ b/befs-Validate-length-of-long-symbolic-links.patch @@ -0,0 +1,50 @@ +From 338d0f0a6fbc82407864606f5b64b75aeb3c70f2 Mon Sep 17 00:00:00 2001 +From: Timo Warns +Date: Wed, 17 Aug 2011 17:59:56 +0200 +Subject: [PATCH] befs: Validate length of long symbolic links. + +Signed-off-by: Timo Warns +Signed-off-by: Linus Torvalds +--- + fs/befs/linuxvfs.c | 23 ++++++++++++++--------- + 1 files changed, 14 insertions(+), 9 deletions(-) + +diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c +index 54b8c28..720d885 100644 +--- a/fs/befs/linuxvfs.c ++++ b/fs/befs/linuxvfs.c +@@ -474,17 +474,22 @@ befs_follow_link(struct dentry *dentry, struct nameidata *nd) + befs_data_stream *data = &befs_ino->i_data.ds; + befs_off_t len = data->size; + +- befs_debug(sb, "Follow long symlink"); +- +- link = kmalloc(len, GFP_NOFS); +- if (!link) { +- link = ERR_PTR(-ENOMEM); +- } else if (befs_read_lsymlink(sb, data, link, len) != len) { +- kfree(link); +- befs_error(sb, "Failed to read entire long symlink"); ++ if (len == 0) { ++ befs_error(sb, "Long symlink with illegal length"); + link = ERR_PTR(-EIO); + } else { +- link[len - 1] = '\0'; ++ befs_debug(sb, "Follow long symlink"); ++ ++ link = kmalloc(len, GFP_NOFS); ++ if (!link) { ++ link = ERR_PTR(-ENOMEM); ++ } else if (befs_read_lsymlink(sb, data, link, len) != len) { ++ kfree(link); ++ befs_error(sb, "Failed to read entire long symlink"); ++ link = ERR_PTR(-EIO); ++ } else { ++ link[len - 1] = '\0'; ++ } + } + } else { + link = befs_ino->i_data.symlink; +-- +1.7.6 + diff --git a/block-check-for-proper-length-of-iov-entries-earlier-in-blk_rq_map_user_iov.patch b/block-check-for-proper-length-of-iov-entries-earlier-in-blk_rq_map_user_iov.patch new file mode 100644 index 000000000..0ad4928a0 --- /dev/null +++ b/block-check-for-proper-length-of-iov-entries-earlier-in-blk_rq_map_user_iov.patch @@ -0,0 +1,38 @@ +From: Xiaotian Feng +Date: Mon, 29 Nov 2010 09:03:55 +0000 (+0100) +Subject: block: check for proper length of iov entries earlier in blk_rq_map_user_iov() +X-Git-Tag: v2.6.37-rc7~10^2~5 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=54787556 + +block: check for proper length of iov entries earlier in blk_rq_map_user_iov() + +commit 9284bcf checks for proper length of iov entries in +blk_rq_map_user_iov(). But if the map is unaligned, kernel +will break out the loop without checking for the proper length. +So we need to check the proper length before the unalign check. + +Signed-off-by: Xiaotian Feng +Cc: stable@kernel.org +Signed-off-by: Jens Axboe +--- + +diff --git a/block/blk-map.c b/block/blk-map.c +index 5d5dbe4..e663ac2 100644 +--- a/block/blk-map.c ++++ b/block/blk-map.c +@@ -201,12 +201,13 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, + for (i = 0; i < iov_count; i++) { + unsigned long uaddr = (unsigned long)iov[i].iov_base; + ++ if (!iov[i].iov_len) ++ return -EINVAL; ++ + if (uaddr & queue_dma_alignment(q)) { + unaligned = 1; + break; + } +- if (!iov[i].iov_len) +- return -EINVAL; + } + + if (unaligned || (q->dma_pad_mask & len) || map_data) diff --git a/bluetooth-prevent-buffer-overflow-in-l2cap-config-request.patch b/bluetooth-prevent-buffer-overflow-in-l2cap-config-request.patch new file mode 100644 index 000000000..e861b72ed --- /dev/null +++ b/bluetooth-prevent-buffer-overflow-in-l2cap-config-request.patch @@ -0,0 +1,32 @@ +From: Dan Rosenberg +Date: Fri, 24 Jun 2011 12:38:05 +0000 (-0400) +Subject: Bluetooth: Prevent buffer overflow in l2cap config request +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fpadovan%2Fbluetooth-2.6.git;a=commitdiff_plain;h=7ac28817536797fd40e9646452183606f9e17f71 + +Bluetooth: Prevent buffer overflow in l2cap config request +[ backport to 2.6.35 ] + +A remote user can provide a small value for the command size field in +the command header of an l2cap configuration request, resulting in an +integer underflow when subtracting the size of the configuration request +header. This results in copying a very large amount of data via +memcpy() and destroying the kernel heap. Check for underflow. + +Signed-off-by: Dan Rosenberg +Cc: stable +Signed-off-by: Gustavo F. Padovan +--- + +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index 56fdd91..7d8a66b 100644 +--- a/net/bluetooth/l2cap.c ++++ b/net/bluetooth/l2cap.c +@@ -2962,7 +2962,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr + + /* Reject if config buffer is too small. */ + len = cmd_len - sizeof(*req); +- if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) { ++ if (len < 0 || l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) { + l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, + l2cap_build_conf_rsp(sk, rsp, + L2CAP_CONF_REJECT, flags), rsp); diff --git a/bridge-fix-mglist-corruption-that-leads-to-memory-corruption.patch b/bridge-fix-mglist-corruption-that-leads-to-memory-corruption.patch new file mode 100644 index 000000000..198a93b35 --- /dev/null +++ b/bridge-fix-mglist-corruption-that-leads-to-memory-corruption.patch @@ -0,0 +1,42 @@ +bridge: Fix mglist corruption that leads to memory corruption + +The list mp->mglist is used to indicate whether a multicast group +is active on the bridge interface itself as opposed to one of the +constituent interfaces in the bridge. + +Unfortunately the operation that adds the mp->mglist node to the +list neglected to check whether it has already been added. This +leads to list corruption in the form of nodes pointing to itself. + +Normally this would be quite obvious as it would cause an infinite +loop when walking the list. However, as this list is never actually +walked (which means that we don't really need it, I'll get rid of +it in a subsequent patch), this instead is hidden until we perform +a delete operation on the affected nodes. + +As the same node may now be pointed to by more than one node, the +delete operations can then cause modification of freed memory. + +This was observed in practice to cause corruption in 512-byte slabs, +most commonly leading to crashes in jbd2. + +Thanks to Josef Bacik for pointing me in the right direction. + +Reported-by: Ian Page Hands +Signed-off-by: Herbert Xu + +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index f701a21..802d3f8 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -719,7 +719,8 @@ static int br_multicast_add_group(struct net_bridge *br, + goto err; + + if (!port) { +- hlist_add_head(&mp->mglist, &br->mglist); ++ if (hlist_unhashed(&mp->mglist)) ++ hlist_add_head(&mp->mglist, &br->mglist); + mod_timer(&mp->timer, now + br->multicast_membership_interval); + goto out; + } + diff --git a/btrfs-fix-error-handling-in-btrfs_get_sub.patch b/btrfs-fix-error-handling-in-btrfs_get_sub.patch new file mode 100644 index 000000000..a91999510 --- /dev/null +++ b/btrfs-fix-error-handling-in-btrfs_get_sub.patch @@ -0,0 +1,65 @@ +From 8f172904b45a6b530eaa345b23956682629bddee Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Fri, 22 Oct 2010 15:26:53 -0400 +Subject: Btrfs: fix error handling in btrfs_get_sb + +If we failed to find the root subvol id, or the subvol=, we would +deactivate the locked super and close the devices. The problem is at this point +we have gotten the SB all setup, which includes setting super_operations, so +when we'd deactiveate the super, we'd do a close_ctree() which closes the +devices, so we'd end up closing the devices twice. So if you do something like +this + +mount /dev/sda1 /mnt/test1 +mount /dev/sda1 /mnt/test2 -o subvol=xxx +umount /mnt/test1 + +it would blow up (if subvol xxx doesn't exist). This patch fixes that problem. +Thanks, + +Signed-off-by: Josef Bacik +--- + fs/btrfs/super.c | 7 +++---- + 1 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c +index f2393b3..c246f25 100644 +--- a/fs/btrfs/super.c ++++ b/fs/btrfs/super.c +@@ -629,7 +629,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, + if (IS_ERR(root)) { + error = PTR_ERR(root); + deactivate_locked_super(s); +- goto error; ++ goto error_free_subvol_name; + } + /* if they gave us a subvolume name bind mount into that */ + if (strcmp(subvol_name, ".")) { +@@ -643,14 +643,14 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, + deactivate_locked_super(s); + error = PTR_ERR(new_root); + dput(root); +- goto error_close_devices; ++ goto error_free_subvol_name; + } + if (!new_root->d_inode) { + dput(root); + dput(new_root); + deactivate_locked_super(s); + error = -ENXIO; +- goto error_close_devices; ++ goto error_free_subvol_name; + } + dput(root); + root = new_root; +@@ -668,7 +668,6 @@ error_close_devices: + btrfs_close_devices(fs_devices); + error_free_subvol_name: + kfree(subvol_name); +-error: + return error; + } + +-- +1.7.3.3 + diff --git a/btrfs-fix-race-between-btrfs_get_sb-and-unmount.patch b/btrfs-fix-race-between-btrfs_get_sb-and-unmount.patch new file mode 100644 index 000000000..f9ab0d619 --- /dev/null +++ b/btrfs-fix-race-between-btrfs_get_sb-and-unmount.patch @@ -0,0 +1,41 @@ +From 3d07b06c5d62e98b46ef21980e5c2a904990149f Mon Sep 17 00:00:00 2001 +From: Kyle McMartin +Date: Fri, 10 Dec 2010 10:32:29 -0500 +Subject: [PATCH] Btrfs - fix race between btrfs_get_sb() and umount + +When mounting a btrfs file system btrfs_test_super() may attempt to +use sb->s_fs_info, the btrfs root, of a super block that is going away +and that has had the btrfs root set to NULL in its ->put_super(). But +if the super block is going away it cannot be an existing super block +so we can return false in this case. + +Signed-off-by: Ian Kent +Signed-off-by: Chris Mason + +Conflicts: + + fs/btrfs/super.c +--- + fs/btrfs/super.c | 6 ++++++ + 1 files changed, 6 insertions(+), 0 deletions(-) + +diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c +index 89e299f..f4a4dd3 100644 +--- a/fs/btrfs/super.c ++++ b/fs/btrfs/super.c +@@ -551,6 +551,12 @@ static int btrfs_test_super(struct super_block *s, void *data) + struct btrfs_root *test_root = data; + struct btrfs_root *root = btrfs_sb(s); + ++ /* ++ * If this super block is going away, return false as it ++ * can't match as an existing super block. ++ */ ++ if (!atomic_read(&s->s_active)) ++ return 0; + return root->fs_info->fs_devices == test_root->fs_info->fs_devices; + } + +-- +1.7.3.3 + diff --git a/btrfs-fix-typo-in-fallocate-to-make-it-honor-actual-size.patch b/btrfs-fix-typo-in-fallocate-to-make-it-honor-actual-size.patch new file mode 100644 index 000000000..186d40a5b --- /dev/null +++ b/btrfs-fix-typo-in-fallocate-to-make-it-honor-actual-size.patch @@ -0,0 +1,51 @@ +From: Josef Bacik +Date: Mon, 22 Nov 2010 18:50:32 +0000 (+0000) +Subject: Btrfs: fix typo in fallocate to make it honor actual size +X-Git-Tag: v2.6.37-rc4~6^2~7 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=55a61d1d06a3dc443d0db8aaa613365dcb83b98a + +Btrfs: fix typo in fallocate to make it honor actual size + +[ Trivial backport to 2.6.35/2.6.36 ] + +There is a typo in __btrfs_prealloc_file_range() where we set the i_size to +actual_len/cur_offset, and then just set it to cur_offset again, and do the same +with btrfs_ordered_update_i_size(). This fixes it back to keeping i_size in a +local variable and then updating i_size properly. Tested this with + +xfs_io -F -f -c "falloc 0 1" -c "pwrite 0 1" foo + +stat'ing foo gives us a size of 1 instead of 4096 like it was. Thanks, + +Signed-off-by: Josef Bacik +Signed-off-by: Chris Mason +--- + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 37cc177..0058fb3 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -7002,6 +7002,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, + struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_key ins; + u64 cur_offset = start; ++ u64 i_size; + int ret = 0; + + while (num_bytes > 0) { +@@ -7043,11 +7044,11 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, + (actual_len > inode->i_size) && + (cur_offset > inode->i_size)) { + if (cur_offset > actual_len) +- i_size_write(inode, actual_len); ++ i_size = actual_len; + else +- i_size_write(inode, cur_offset); +- i_size_write(inode, cur_offset); +- btrfs_ordered_update_i_size(inode, cur_offset, NULL); ++ i_size = cur_offset; ++ i_size_write(inode, i_size); ++ btrfs_ordered_update_i_size(inode, i_size, NULL); + } + + ret = btrfs_update_inode(trans, root, inode); diff --git a/btrfs-setup-blank-root-and-fs_info-for-mount-time.patch b/btrfs-setup-blank-root-and-fs_info-for-mount-time.patch new file mode 100644 index 000000000..183927438 --- /dev/null +++ b/btrfs-setup-blank-root-and-fs_info-for-mount-time.patch @@ -0,0 +1,117 @@ +From 2049a8887f699650cd66c3da220e84d5c140c546 Mon Sep 17 00:00:00 2001 +From: Kyle McMartin +Date: Fri, 10 Dec 2010 10:09:15 -0500 +Subject: [PATCH] Btrfs: setup blank root and fs_info for mount time + +There is a problem with how we use sget, it searches through the list of supers +attached to the fs_type looking for a super with the same fs_devices as what +we're trying to mount. This depends on sb->s_fs_info being filled, but we don't +fill that in until we get to btrfs_fill_super, so we could hit supers on the +fs_type super list that have a null s_fs_info. In order to fix that we need to +go ahead and setup a blank root with a blank fs_info to hold fs_devices, that +way our test will work out right and then we can set s_fs_info in +btrfs_set_super, and then open_ctree will simply use our pre-allocated root and +fs_info when setting everything up. Thanks, + +Signed-off-by: Josef Bacik +Signed-off-by: Chris Mason + +Conflicts: + + fs/btrfs/super.c +--- + fs/btrfs/disk-io.c | 6 ++---- + fs/btrfs/super.c | 34 +++++++++++++++++++++++++++++++--- + 2 files changed, 33 insertions(+), 7 deletions(-) + +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 34f7c37..b6c3dad 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -1539,10 +1539,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, + GFP_NOFS); + struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root), + GFP_NOFS); +- struct btrfs_root *tree_root = kzalloc(sizeof(struct btrfs_root), +- GFP_NOFS); +- struct btrfs_fs_info *fs_info = kzalloc(sizeof(*fs_info), +- GFP_NOFS); ++ struct btrfs_root *tree_root = btrfs_sb(sb); ++ struct btrfs_fs_info *fs_info = tree_root->fs_info; + struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root), + GFP_NOFS); + struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root), +diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c +index f2393b3..89e299f 100644 +--- a/fs/btrfs/super.c ++++ b/fs/btrfs/super.c +@@ -548,12 +548,20 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) + + static int btrfs_test_super(struct super_block *s, void *data) + { +- struct btrfs_fs_devices *test_fs_devices = data; ++ struct btrfs_root *test_root = data; + struct btrfs_root *root = btrfs_sb(s); + +- return root->fs_info->fs_devices == test_fs_devices; ++ return root->fs_info->fs_devices == test_root->fs_info->fs_devices; + } + ++static int btrfs_set_super(struct super_block *s, void *data) ++{ ++ s->s_fs_info = data; ++ ++ return set_anon_super(s, data); ++} ++ ++ + /* + * Find a superblock for the given device / mount point. + * +@@ -567,6 +575,8 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, + struct super_block *s; + struct dentry *root; + struct btrfs_fs_devices *fs_devices = NULL; ++ struct btrfs_root *tree_root = NULL; ++ struct btrfs_fs_info *fs_info = NULL; + fmode_t mode = FMODE_READ; + char *subvol_name = NULL; + u64 subvol_objectid = 0; +@@ -595,8 +605,24 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, + goto error_close_devices; + } + ++ /* ++ * Setup a dummy root and fs_info for test/set super. This is because ++ * we don't actually fill this stuff out until open_ctree, but we need ++ * it for searching for existing supers, so this lets us do that and ++ * then open_ctree will properly initialize everything later. ++ */ ++ fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); ++ tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); ++ if (!fs_info || !tree_root) { ++ error = -ENOMEM; ++ goto error_close_devices; ++ } ++ fs_info->tree_root = tree_root; ++ fs_info->fs_devices = fs_devices; ++ tree_root->fs_info = fs_info; ++ + bdev = fs_devices->latest_bdev; +- s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices); ++ s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root); + if (IS_ERR(s)) + goto error_s; + +@@ -666,6 +692,8 @@ error_s: + error = PTR_ERR(s); + error_close_devices: + btrfs_close_devices(fs_devices); ++ kfree(fs_info); ++ kfree(tree_root); + error_free_subvol_name: + kfree(subvol_name); + error: +-- +1.7.3.3 + diff --git a/check-kabi b/check-kabi deleted file mode 100755 index 3809209ad..000000000 --- a/check-kabi +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/python3 -# -# check-kabi - Red Hat kABI reference checking tool -# -# We use this script to check against reference Module.kabi files. -# -# Author: Jon Masters -# Copyright (C) 2007-2009 Red Hat, Inc. -# -# This software may be freely redistributed under the terms of the GNU -# General Public License (GPL). - -# Changelog: -# -# 2018/06/01 - Update for python3 by Petr Oros. -# 2009/08/15 - Updated for use in RHEL6. -# 2007/06/13 - Initial rewrite in python by Jon Masters. - -__author__ = "Jon Masters " -__version__ = "2.0" -__date__ = "2009/08/15" -__copyright__ = "Copyright (C) 2007-2009 Red Hat, Inc" -__license__ = "GPL" - -import getopt -import string -import sys - -true = 1 -false = 0 - - -def load_symvers(symvers, filename): - """Load a Module.symvers file.""" - - symvers_file = open(filename, "r") - - while true: - in_line = symvers_file.readline() - if in_line == "": - break - if in_line == "\n": - continue - checksum, symbol, directory, type, *ns = in_line.split() - ns = ns[0] if ns else None - - symvers[symbol] = in_line[0:-1] - - -def load_kabi(kabi, filename): - """Load a Module.kabi file.""" - - kabi_file = open(filename, "r") - - while true: - in_line = kabi_file.readline() - if in_line == "": - break - if in_line == "\n": - continue - checksum, symbol, directory, type, *ns = in_line.split() - ns = ns[0] if ns else None - - kabi[symbol] = in_line[0:-1] - - -def check_kabi(symvers, kabi): - """Check Module.kabi and Module.symvers files.""" - - fail = 0 - warn = 0 - changed_symbols = [] - moved_symbols = [] - ns_symbols = [] - - for symbol in kabi: - abi_hash, abi_sym, abi_dir, abi_type, *abi_ns = kabi[symbol].split() - abi_ns = abi_ns[0] if abi_ns else None - if symbol in symvers: - sym_hash, sym_sym, sym_dir, sym_type, *sym_ns = symvers[symbol].split() - sym_ns = sym_ns[0] if sym_ns else None - if abi_hash != sym_hash: - fail = 1 - changed_symbols.append(symbol) - - if abi_dir != sym_dir: - warn = 1 - moved_symbols.append(symbol) - - if abi_ns != sym_ns: - warn = 1 - ns_symbols.append(symbol) - else: - fail = 1 - changed_symbols.append(symbol) - - if fail: - print("*** ERROR - ABI BREAKAGE WAS DETECTED ***") - print("") - print("The following symbols have been changed (this will cause an ABI breakage):") - print("") - for symbol in changed_symbols: - print(symbol) - print("") - - if warn: - print("*** WARNING - ABI SYMBOLS MOVED ***") - if moved_symbols: - print("") - print("The following symbols moved (typically caused by moving a symbol from being") - print("provided by the kernel vmlinux out to a loadable module):") - print("") - for symbol in moved_symbols: - print(symbol) - print("") - if ns_symbols: - print("") - print("The following symbols changed symbol namespaces:") - print("") - for symbol in ns_symbols: - print(symbol) - print("") - - """Halt the build, if we got errors and/or warnings. In either case, - double-checkig is required to avoid introducing / concealing - KABI inconsistencies.""" - if fail or warn: - sys.exit(1) - sys.exit(0) - - -def usage(): - print(""" -check-kabi: check Module.kabi and Module.symvers files. - - check-kabi [ -k Module.kabi ] [ -s Module.symvers ] - -""") - - -if __name__ == "__main__": - - symvers_file = "" - kabi_file = "" - - opts, args = getopt.getopt(sys.argv[1:], 'hk:s:') - - for o, v in opts: - if o == "-s": - symvers_file = v - if o == "-h": - usage() - sys.exit(0) - if o == "-k": - kabi_file = v - - if (symvers_file == "") or (kabi_file == ""): - usage() - sys.exit(1) - - symvers = {} - kabi = {} - - load_symvers(symvers, symvers_file) - load_kabi(kabi, kabi_file) - check_kabi(symvers, kabi) diff --git a/cifs-fix-possible-memory-corruption-in-CIFSFindNext.patch b/cifs-fix-possible-memory-corruption-in-CIFSFindNext.patch new file mode 100644 index 000000000..06fc5c74a --- /dev/null +++ b/cifs-fix-possible-memory-corruption-in-CIFSFindNext.patch @@ -0,0 +1,82 @@ +Path: news.gmane.org!not-for-mail +From: Jeff Layton +Newsgroups: gmane.linux.kernel.cifs +Subject: [PATCH] cifs: fix possible memory corruption in CIFSFindNext +Date: Tue, 23 Aug 2011 07:21:28 -0400 +Lines: 37 +Approved: news@gmane.org +Message-ID: <1314098488-1547-1-git-send-email-jlayton@redhat.com> +NNTP-Posting-Host: lo.gmane.org +X-Trace: dough.gmane.org 1314098501 27164 80.91.229.12 (23 Aug 2011 11:21:41 GMT) +X-Complaints-To: usenet@dough.gmane.org +NNTP-Posting-Date: Tue, 23 Aug 2011 11:21:41 +0000 (UTC) +Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, dcl-HN4QTLPn1qTvY7RNz7mR4EEOCMrvLtNR@public.gmane.org +To: smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org +Original-X-From: linux-cifs-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Tue Aug 23 13:21:37 2011 +Return-path: +Envelope-to: glkc-linux-cifs-1dZseelyfdZg9hUCZPvPmw@public.gmane.org +Original-Received: from vger.kernel.org ([209.132.180.67]) + by lo.gmane.org with esmtp (Exim 4.69) + (envelope-from ) + id 1Qvp33-0003JC-05 + for glkc-linux-cifs-1dZseelyfdZg9hUCZPvPmw@public.gmane.org; Tue, 23 Aug 2011 13:21:37 +0200 +Original-Received: (majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org) by vger.kernel.org via listexpand + id S1752435Ab1HWLVg (ORCPT ); + Tue, 23 Aug 2011 07:21:36 -0400 +Original-Received: from mail-gy0-f174.google.com ([209.85.160.174]:43114 "EHLO + mail-gy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S1751065Ab1HWLVf (ORCPT + ); Tue, 23 Aug 2011 07:21:35 -0400 +Original-Received: by gya6 with SMTP id 6so4228912gya.19 + for ; Tue, 23 Aug 2011 04:21:35 -0700 (PDT) +Original-Received: by 10.101.144.18 with SMTP id w18mr3505731ann.133.1314098494691; + Tue, 23 Aug 2011 04:21:34 -0700 (PDT) +Original-Received: from salusa.poochiereds.net (cpe-075-177-182-191.nc.res.rr.com [75.177.182.191]) + by mx.google.com with ESMTPS id d33sm48355ano.35.2011.08.23.04.21.32 + (version=SSLv3 cipher=OTHER); + Tue, 23 Aug 2011 04:21:33 -0700 (PDT) +X-Mailer: git-send-email 1.7.6 +Original-Sender: linux-cifs-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org +Precedence: bulk +List-ID: +X-Mailing-List: linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org +Xref: news.gmane.org gmane.linux.kernel.cifs:4006 +Archived-At: + +The name_len variable in CIFSFindNext is a signed int that gets set to +the resume_name_len in the cifs_search_info. The resume_name_len however +is unsigned and for some infolevels is populated directly from a 32 bit +value sent by the server. + +If the server sends a very large value for this, then that value could +look negative when converted to a signed int. That would make that +value pass the PATH_MAX check later in CIFSFindNext. The name_len would +then be used as a length value for a memcpy. It would then be treated +as unsigned again, and the memcpy scribbles over a ton of memory. + +Fix this by making the name_len an unsigned value in CIFSFindNext. + +Cc: +Reported-by: Darren Lavender +Signed-off-by: Jeff Layton +--- + fs/cifs/cifssmb.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c +index f4d0988..950464d 100644 +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -4089,7 +4089,8 @@ int CIFSFindNext(const int xid, struct cifs_tcon *tcon, + T2_FNEXT_RSP_PARMS *parms; + char *response_data; + int rc = 0; +- int bytes_returned, name_len; ++ int bytes_returned; ++ unsigned int name_len; + __u16 params, byte_count; + + cFYI(1, "In FindNext"); +-- +1.7.6 + diff --git a/config-arm b/config-arm new file mode 100644 index 000000000..7b13a8279 --- /dev/null +++ b/config-arm @@ -0,0 +1,115 @@ +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_SMP is not set + +# CONFIG_CMDLINE_FORCE is not set + +CONFIG_CC_OPTIMIZE_FOR_SIZE=y + +CONFIG_ARCH_VERSATILE=y +CONFIG_ARCH_VERSATILE_PB=y +CONFIG_MACH_VERSATILE_AB=y + +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set + +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set + +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 + +# CONFIG_XIP_KERNEL is not set + +CONFIG_ATAGS_PROC=y + +# CONFIG_FPE_NWFPE is not set +CONFIG_FPE_FASTFPE=y +CONFIG_VFP=y + +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_PM_TRACE is not set +CONFIG_SUSPEND=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_APM_EMULATION=y + +CONFIG_ARM_THUMB=y + +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y + +# CONFIG_UACCESS_WITH_MEMCPY is not set + +CONFIG_CMDLINE="console=ttyAM0,115200 root=/dev/sda1 rootdelay=20" + +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y + +# CONFIG_CPU_IDLE is not set + +CONFIG_LEDS=y +CONFIG_LEDS_CPU=y + +CONFIG_MTD_AFS_PARTS=y +CONFIG_MTD_ARM_INTEGRATOR=y +CONFIG_MTD_IMPA7=y + +CONFIG_AX88796=m +CONFIG_AX88796_93CX6=y +CONFIG_SMC91X=m +CONFIG_DM9000=m +CONFIG_DM9000_DEBUGLEVEL=4 +# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set +CONFIG_SMC911X=m +CONFIG_SMSC911X=m + +CONFIG_SERIO_AMBAKMI=m + +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y + +CONFIG_I2C_VERSATILE=y + +CONFIG_THERMAL=y + +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set + +CONFIG_FB_ARMCLCD=m + +CONFIG_SND_ARM=y +CONFIG_SND_ARMAACI=m + +CONFIG_USB_MUSB_HDRC=m +# CONFIG_MUSB_PIO_ONLY is not set +CONFIG_USB_TUSB6010=y +# CONFIG_USB_MUSB_DEBUG is not set + +CONFIG_MMC_ARMMMCI=m + +CONFIG_RTC_DRV_PL030=m +CONFIG_RTC_DRV_PL031=m + +# CONFIG_SGI_IOC4 is not set + +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set + +CONFIG_ARM_UNWIND=y + +CONFIG_RCU_FANOUT=32 + +# CONFIG_USB_ULPI is not set +# CONFIG_OC_ETM is not set + +# CONFIG_MTD_PISMO is not set + +CONFIG_PERF_EVENTS=y +CONFIG_PERF_COUNTERS=y + +# CONFIG_MG_DISK is not set +# CONFIG_GPIO_PL061 is not set diff --git a/config-debug b/config-debug new file mode 100644 index 000000000..6c6209e6b --- /dev/null +++ b/config-debug @@ -0,0 +1,93 @@ +CONFIG_SND_VERBOSE_PRINTK=y +CONFIG_SND_DEBUG=y +CONFIG_SND_PCM_XRUN_DEBUG=y + +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_RT_MUTEXES=y +CONFIG_DEBUG_LOCK_ALLOC=y +CONFIG_PROVE_LOCKING=y +CONFIG_DEBUG_VM=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_PROVE_RCU=y +# CONFIG_PROVE_RCU_REPEATEDLY is not set +CONFIG_DEBUG_PER_CPU_MAPS=y +CONFIG_CPUMASK_OFFSTACK=y + +CONFIG_CPU_NOTIFIER_ERROR_INJECT=m + +CONFIG_FAULT_INJECTION=y +CONFIG_FAILSLAB=y +CONFIG_FAIL_PAGE_ALLOC=y +CONFIG_FAIL_MAKE_REQUEST=y +CONFIG_FAULT_INJECTION_DEBUG_FS=y +CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y +CONFIG_FAIL_IO_TIMEOUT=y + +CONFIG_SLUB_DEBUG_ON=y + +CONFIG_LOCK_STAT=y + +CONFIG_DEBUG_STACK_USAGE=y + +CONFIG_ACPI_DEBUG=y +# CONFIG_ACPI_DEBUG_FUNC_TRACE is not set + +CONFIG_DEBUG_SG=y + +# CONFIG_DEBUG_PAGEALLOC is not set + +CONFIG_DEBUG_WRITECOUNT=y +CONFIG_DEBUG_OBJECTS=y +# CONFIG_DEBUG_OBJECTS_SELFTEST is not set +CONFIG_DEBUG_OBJECTS_FREE=y +CONFIG_DEBUG_OBJECTS_TIMERS=y +CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1 + +CONFIG_X86_PTDUMP=y + +CONFIG_CAN_DEBUG_DEVICES=y + +CONFIG_MODULE_FORCE_UNLOAD=y + +CONFIG_SYSCTL_SYSCALL_CHECK=y + +CONFIG_DEBUG_NOTIFIERS=y + +CONFIG_DMA_API_DEBUG=y + +CONFIG_MMIOTRACE=y + +CONFIG_DEBUG_CREDENTIALS=y + +CONFIG_EXT4_DEBUG=y + +CONFIG_DEBUG_PERF_USE_VMALLOC=y + +# off in both production debug and nodebug builds, +# on in rawhide nodebug builds +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set + +CONFIG_JBD2_DEBUG=y + +CONFIG_DEBUG_CFQ_IOSCHED=y + +CONFIG_DRBD_FAULT_INJECTION=y + +CONFIG_ATH_DEBUG=y +CONFIG_IWLWIFI_DEVICE_TRACING=y + +CONFIG_DEBUG_OBJECTS_WORK=y +# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set + +CONFIG_DMADEVICES_DEBUG=y +CONFIG_DMADEVICES_VDEBUG=y + +CONFIG_PM_ADVANCED_DEBUG=y + +CONFIG_CEPH_FS_PRETTYDEBUG=y +CONFIG_QUOTA_DEBUG=y + +# CONFIG_PCI_DEFAULT_USE_CRS is not set + +CONFIG_KGDB_KDB=y +CONFIG_KDB_KEYBOARD=y diff --git a/config-generic b/config-generic new file mode 100644 index 000000000..b7701bdc7 --- /dev/null +++ b/config-generic @@ -0,0 +1,4321 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MMU=y +CONFIG_SMP=y +CONFIG_HOTPLUG_CPU=y +CONFIG_LOCALVERSION="" +CONFIG_CROSS_COMPILE="" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_HOTPLUG=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y + +CONFIG_BUILD_DOCSRC=y + +# +# General setup +# +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_CFQ_GROUP_IOSCHED=y +CONFIG_DEFAULT_CFQ=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_NET_NS=y + +CONFIG_POSIX_MQUEUE=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set + +CONFIG_SLUB=y +# CONFIG_SLUB_STATS is not set + +CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set +CONFIG_IWMC3200TOP=m +# CONFIG_IWMC3200TOP_DEBUG is not set +CONFIG_IWMC3200TOP_DEBUGFS=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_LOAD is not set +# -- MODULE_FORCE_UNLOAD is controlled by config-debug/nodebug +# CONFIG_MODVERSIONS is not set +CONFIG_MODULE_SRCVERSION_ALL=y + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +CONFIG_PCI=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_STUB=y +CONFIG_PCI_IOV=y +CONFIG_HT_IRQ=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_DEFAULT_ON=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIEAER=y +CONFIG_PCIEASPM=y +# CONFIG_PCIEASPM_DEBUG is not set +CONFIG_PCIE_ECRC=y +CONFIG_PCIEAER_INJECT=m +CONFIG_HOTPLUG_PCI_PCIE=y +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_PCI_LEGACY=y + +CONFIG_ISA=y +# CONFIG_EISA is not set +# CONFIG_MCA is not set +# CONFIG_SCx200 is not set + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=y +CONFIG_PCMCIA_LOAD_CIS=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_YENTA=m +CONFIG_CARDBUS=y +CONFIG_I82092=m +CONFIG_PD6729=m +CONFIG_PCMCIA_IOCTL=y + +CONFIG_PCCARD=y +CONFIG_MMC=m +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=m +# CONFIG_MMC_TEST is not set +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_BLOCK=m +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SDHCI_PCI=m +CONFIG_MMC_SDRICOH_CS=m +CONFIG_MMC_TIFM_SD=m +CONFIG_MMC_WBSD=m +CONFIG_MMC_VIA_SDMMC=m +CONFIG_MMC_SDHCI_PLTFM=m +CONFIG_MMC_CB710=m +CONFIG_MMC_RICOH_MMC=y + +CONFIG_CB710_CORE=m +# CONFIG_CB710_DEBUG is not set + +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_MTHCA=m +# CONFIG_INFINIBAND_MTHCA_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_DEBUG=y +CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_IPATH=m +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_AMSO1100=m +# CONFIG_INFINIBAND_AMSO1100_DEBUG is not set +CONFIG_INFINIBAND_CXGB3=m +CONFIG_INFINIBAND_CXGB4=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_MLX4_INFINIBAND=m +CONFIG_INFINIBAND_NES=m +# CONFIG_INFINIBAND_NES_DEBUG is not set +CONFIG_INFINIBAND_QIB=m + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_FW_LOADER=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_EXTRA_FIRMWARE="" + +# CONFIG_SPI is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_AR7_PARTS=m +CONFIG_MTD_CONCAT=m +CONFIG_MTD_CMDLINE_PARTS=y +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_BLOCK2MTD=m + +CONFIG_MTD_OOPS=m +# CONFIG_MTD_INTEL_VR_NOR is not set +CONFIG_MTD_ALAUDA=m + +CONFIG_FTL=m +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_INFTL=m +CONFIG_RFD_FTL=m +CONFIG_SSFDC=m +# CONFIG_SM_FTL is not set + +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set +# CONFIG_MTD_UBI_DEBUG is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_RAM=m +CONFIG_MTD_ROM=m +CONFIG_MTD_ABSENT=m + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_NETSC520=m +# CONFIG_MTD_SBC_GXX is not set +# CONFIG_MTD_SCx200_DOCFLASH is not set +# CONFIG_MTD_AMD76XROM is not set +CONFIG_MTD_SCB2_FLASH=m +# CONFIG_MTD_NETtel is not set +# CONFIG_MTD_DILNETPC is not set +# CONFIG_MTD_L440GX is not set +CONFIG_MTD_PCI=m +CONFIG_MTD_TS5500=m +# CONFIG_MTD_GPIO_ADDR is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +# CONFIG_MTD_SLRAM is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_DOCPROBE is not set +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +# CONFIG_MTD_DOCPROBE_ADDRESS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_CAFE is not set +CONFIG_MTD_NAND_IDS=m +CONFIG_MTD_NAND_NANDSIM=m +# CONFIG_MTD_ONENAND is not set +CONFIG_MTD_NAND_ECC_SMC=y +CONFIG_MTD_NAND_CS553X=m +# CONFIG_MTD_NAND_DENALI is not set +CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018 +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_RICOH=m + +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_XIP is not set +# CONFIG_MTD_ICHXROM is not set +# CONFIG_MTD_PHRAM is not set +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +# CONFIG_MTD_PLATRAM is not set + +# CONFIG_MTD_TESTS is not set +CONFIG_MTD_LPDDR=m +CONFIG_MTD_QINFO_PROBE=m + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_SERIAL=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +CONFIG_PARPORT_1284=y +# CONFIG_PARPORT_AX88796 is not set + +# +# Plug and Play support +# +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set +# CONFIG_PNP_DEBUG_MESSAGES is not set + +# +# Protocols +# +CONFIG_ISAPNP=y +# CONFIG_PNPBIOS is not set + +CONFIG_ACPI_PCI_SLOT=y +CONFIG_HOTPLUG_PCI_ACPI=y +CONFIG_HOTPLUG_PCI_ACPI_IBM=m + +# +# Block devices +# +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_XD is not set +CONFIG_PARIDE=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PT=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_EPAT=m +CONFIG_PARIDE_EPATC8=y +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_UMEM=m +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_OSD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_ATIIXP=y +CONFIG_LBD=y +CONFIG_BLK_DEV_IO_TRACE=y + +CONFIG_BLK_DEV_DELKIN=m +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_TC86C001 is not set +CONFIG_LBDAF=y +CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_DEV_INTEGRITY=y + + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_IDE_TASK_IOCTL=y +# CONFIG_BLK_DEV_IDE_SATA is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_BLK_DEV_CMD640=y +CONFIG_BLK_DEV_CMD640_ENHANCED=y +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_RZ1000=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_AEC62XX=y +CONFIG_BLK_DEV_ALI15X3=y +# CONFIG_BLK_DEV_AMD74XX is not set +CONFIG_BLK_DEV_CMD64X=y +CONFIG_BLK_DEV_TRIFLEX=y +# CONFIG_BLK_DEV_CY82C693 is not set +CONFIG_BLK_DEV_CS5520=y +CONFIG_BLK_DEV_CS5530=y +CONFIG_BLK_DEV_CS5535=y +CONFIG_BLK_DEV_HPT366=y +CONFIG_BLK_DEV_IT821X=y +CONFIG_BLK_DEV_JMICRON=y +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_NS87415 is not set +CONFIG_BLK_DEV_PDC202XX_OLD=y +CONFIG_BLK_DEV_PDC202XX_NEW=y +CONFIG_BLK_DEV_SVWKS=y +CONFIG_BLK_DEV_SIIMAGE=y +CONFIG_BLK_DEV_SIS5513=y +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_BLK_DEV_HD is not set + +CONFIG_VIRTIO=m +CONFIG_VIRTIO_BLK=m +CONFIG_VIRTIO_RING=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_NET=m +CONFIG_VMXNET3=m +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_VIRTIO_CONSOLE=m +CONFIG_VHOST_NET=m + +# +# SCSI device support +# +CONFIG_SCSI=y + +CONFIG_SCSI_ENCLOSURE=m +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SRP=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_TGT=m + +CONFIG_SCSI_DH=y +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_ALUA=m + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SAS_ATA=y +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_RAID_ATTRS=m + +CONFIG_ISCSI_TCP=m + +# +# SCSI low-level drivers +# +CONFIG_SCSI_LOWLEVEL=y +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m +# CONFIG_SCSI_7000FASST is not set +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_SCSI_AIC94XX=m +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIC7XXX_CMDS_PER_DEVICE=4 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC7XXX_OLD=m +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=4 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +# CONFIG_AIC79XX_BUILD_FIRMWARE is not set +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +# CONFIG_SCSI_ADVANSYS is not set +CONFIG_SCSI_BFA_FC=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_SAS=m +CONFIG_SCSI_MVSAS=m +# CONFIG_SCSI_MVSAS_DEBUG is not set +CONFIG_SCSI_MPT2SAS=m +CONFIG_SCSI_MPT2SAS_MAX_SGE=128 +CONFIG_SCSI_MPT2SAS_LOGGING=y + +CONFIG_SCSI_OSD_INITIATOR=m +CONFIG_SCSI_OSD_ULD=m +CONFIG_SCSI_OSD_DPRINT_SENSE=1 +# CONFIG_SCSI_OSD_DEBUG is not set + +CONFIG_SCSI_BNX2_ISCSI=m +CONFIG_BE2ISCSI=m +CONFIG_SCSI_PMCRAID=m + +CONFIG_SCSI_HPSA=m +CONFIG_SCSI_3W_SAS=m +CONFIG_SCSI_PM8001=m +CONFIG_VMWARE_PVSCSI=m +CONFIG_VMWARE_BALLOON=m + +CONFIG_ATA=y +CONFIG_ATA_BMDMA=y +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_ATA_SFF=y +CONFIG_ATA_PIIX=y +CONFIG_ATA_ACPI=y +CONFIG_BLK_DEV_SX8=m +CONFIG_PDC_ADMA=m +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PMP=y +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m + +CONFIG_PATA_ACPI=m +CONFIG_PATA_ALI=m +CONFIG_PATA_AMD=m +CONFIG_PATA_ARTOP=m +CONFIG_PATA_ATIIXP=m +CONFIG_PATA_CMD640_PCI=m +CONFIG_PATA_CMD64X=m +CONFIG_PATA_CS5520=m +CONFIG_PATA_CS5530=m +CONFIG_PATA_CS5535=m +CONFIG_PATA_CS5536=m +CONFIG_PATA_CYPRESS=m +CONFIG_PATA_EFAR=m +CONFIG_ATA_GENERIC=m +CONFIG_PATA_HPT366=m +CONFIG_PATA_HPT37X=m +CONFIG_PATA_HPT3X2N=m +CONFIG_PATA_HPT3X3=m +# CONFIG_PATA_HPT3X3_DMA is not set +# CONFIG_PATA_ISAPNP is not set +CONFIG_PATA_IT821X=m +CONFIG_PATA_IT8213=m +CONFIG_PATA_JMICRON=m +# CONFIG_PATA_LEGACY is not set +CONFIG_PATA_NINJA32=m +CONFIG_PATA_MARVELL=m +# CONFIG_PATA_WINBOND_VLB is not set +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +CONFIG_PATA_NS87410=m +CONFIG_PATA_NS87415=m +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_OPTI=m +CONFIG_PATA_OPTIDMA=m +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC_OLD=m +CONFIG_PATA_QDI=m +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RDC=m +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_PDC2027X=m +CONFIG_PATA_SCH=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TOSHIBA=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_VIA=m +CONFIG_PATA_WINBOND=m +CONFIG_PATA_ATP867X=m + +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_FLASHPOINT=y +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IPS=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_DC395x=m +# CONFIG_SCSI_NSP32 is not set +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_DPT_I2O is not set +CONFIG_SCSI_LPFC=m + +# +# PCMCIA SCSI adapter support +# +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_PCMCIA_AHA152X=m +# CONFIG_PCMCIA_FDOMAIN is not set +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_SYM53C500=m + + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_AUTODETECT=y +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +# CONFIG_MULTICORE_RAID456 is not set +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=m +CONFIG_DM_DEBUG=y +# CONFIG_DM_DELAY is not set +CONFIG_DM_MIRROR=y +CONFIG_DM_MULTIPATH=m +CONFIG_DM_SNAPSHOT=y +CONFIG_DM_UEVENT=y +CONFIG_DM_ZERO=y +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m + +# +# Fusion MPT device support +# +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_SAS=m +CONFIG_FUSION_LOGGING=y + +# +# IEEE 1394 (FireWire) support (JUJU alternative stack) +# +CONFIG_FIREWIRE=m +CONFIG_FIREWIRE_OHCI=m +CONFIG_FIREWIRE_SBP2=m +CONFIG_FIREWIRE_NET=m +CONFIG_FIREWIRE_OHCI_DEBUG=y +# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set + +# +# Networking support +# +CONFIG_NET=y + +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_YEAH=m + +CONFIG_TCP_MD5SIG=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_NET_KEY=m +CONFIG_NET_KEY_MIGRATE=y +CONFIG_INET=y +CONFIG_INET_LRO=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_DIAG=m +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_NF_SECURITY=m +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_ARPD=y +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y + +# +# IP: Virtual Server Configuration +# +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_FTP=m + +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_SIT=m +CONFIG_IPV6_SIT_6RD=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y + +CONFIG_RDS=m +# CONFIG_RDS_DEBUG is not set +CONFIG_RDS_RDMA=m +CONFIG_RDS_TCP=m + +CONFIG_NET_9P=m +CONFIG_NET_9P_VIRTIO=m +# CONFIG_NET_9P_DEBUG is not set +CONFIG_NET_9P_RDMA=m + +CONFIG_DECNET=m +CONFIG_DECNET_ROUTER=y +# CONFIG_DECNET_NF_GRABULATOR is not set +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_NF_CONNTRACK=y +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_XTABLES=y +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_OSF=m + +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# IP: Netfilter Configuration +# + +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_ZONES=y +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_NF_NAT=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_UDPLITE=m + +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m + +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_FILTER=y + +# +# IPv6: Netfilter Configuration +# +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_HL=m + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_XFRM=y +CONFIG_XFRM_MIGRATE=y +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_STATISTICS=y +CONFIG_XFRM_USER=y +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_BEET=m + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IP_SCTP=m +CONFIG_NET_SCTPPROBE=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +CONFIG_SCTP_HMAC_SHA1=y +# CONFIG_SCTP_HMAC_MD5 is not set +CONFIG_ATM=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_LLC=m +# CONFIG_LLC2 is not set +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=y +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +CONFIG_WAN_ROUTER=m +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=y +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_NET_DCCPPROBE=m + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set + +CONFIG_NETLABEL=y + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_CGROUP=y +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_IND=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_MARK=y +CONFIG_CLS_U32_PERF=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m + +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m + +CONFIG_DCB=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_NET_TCPPROBE is not set +CONFIG_NET_DROP_MONITOR=y +CONFIG_NETDEVICES=y + +# disable later --kyle + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +CONFIG_IFB=m +CONFIG_DUMMY=m +CONFIG_BONDING=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_EQUALIZER=m +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_NET_SB1000=m + +# +# ATM +# +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_CLIP=m +CONFIG_ATM_LANE=m +CONFIG_ATM_BR2684=m +CONFIG_NET_SCH_ATM=m +CONFIG_ATM_TCP=m +# CONFIG_ATM_LANAI is not set +CONFIG_ATM_ENI=m +CONFIG_ATM_FIRESTREAM=m +# CONFIG_ATM_ZATM is not set +# CONFIG_ATM_IDT77252 is not set +# CONFIG_ATM_AMBASSADOR is not set +# CONFIG_ATM_HORIZON is not set +# CONFIG_ATM_FORE200E is not set +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_FORE200E_TX_RETRY=16 +CONFIG_ATM_FORE200E_DEBUG=0 + +CONFIG_ATM_HE=m +CONFIG_PPPOATM=m +CONFIG_PPPOL2TP=m +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_IA is not set +# CONFIG_ATM_CLIP_NO_ICMP is not set +# CONFIG_ATM_MPOA is not set +# CONFIG_ATM_BR2684_IPFILTER is not set +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +# CONFIG_ATM_ZATM_DEBUG is not set +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +# CONFIG_ATM_HORIZON_DEBUG is not set +# CONFIG_ATM_HE_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_SOLOS=m + +CONFIG_L2TP=m +CONFIG_L2TP_DEBUGFS=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m + +# CONFIG_CAIF is not set + +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=y + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NET_ETHERNET=y +CONFIG_PHYLIB=m +CONFIG_BROADCOM_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_FIXED_PHY=y +CONFIG_MDIO_BITBANG=m +CONFIG_NATIONAL_PHY=m +CONFIG_ICPLUS_PHY=m +CONFIG_LSI_ET1011C_PHY=m +CONFIG_LXT_PHY=m +CONFIG_MARVELL_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_REALTEK_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_STE10XP=m +CONFIG_VITESSE_PHY=m +CONFIG_MICREL_PHY=m + +CONFIG_MII=m +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_NET_VENDOR_3COM=y +CONFIG_VORTEX=m +CONFIG_TYPHOON=m +CONFIG_DNET=m + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_DE2104X_DSL=0 +CONFIG_TULIP=m +# CONFIG_TULIP_NAPI is not set +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_MMIO=y +# CONFIG_NI5010 is not set +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_ULI526X=m +# CONFIG_HP100 is not set +CONFIG_LNE390=m +CONFIG_NE3210=m +CONFIG_ES3210=m +CONFIG_NET_PCI=y +CONFIG_PCNET32=m +CONFIG_AMD8111_ETH=m +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_KSZ884X_PCI=m +CONFIG_B44=m +CONFIG_B44_PCI=y +CONFIG_BNX2=m +CONFIG_CNIC=m +CONFIG_QLA3XXX=m +CONFIG_ATL1=m +CONFIG_ATL1C=m +CONFIG_ATL2=m +CONFIG_ATL1E=m +CONFIG_E100=m +CONFIG_FEALNX=m +CONFIG_FORCEDETH=m +CONFIG_FORCEDETH_NAPI=y +CONFIG_NATSEMI=m +CONFIG_NE2K_PCI=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_SIS900=m +CONFIG_SIS190=m +CONFIG_EPIC100=m +CONFIG_SC92031=m +CONFIG_SMSC9420=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_TLAN=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_VELOCITY=m +CONFIG_NET_POCKET=y +CONFIG_ATP=m +CONFIG_DE600=m +CONFIG_DE620=m +CONFIG_CASSINI=m +CONFIG_ETHOC=m +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set + +# +# Ethernet (1000 Mbit) +# +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_DL2K=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_IGB=m +CONFIG_IGB_DCA=y +CONFIG_IGBVF=m +CONFIG_NS83820=m +CONFIG_HAMACHI=m +CONFIG_YELLOWFIN=m +CONFIG_R8169=m +CONFIG_R8169_VLAN=y +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_TIGON3=m +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +CONFIG_JME=m + +# +# Ethernet (10000 Mbit) +# +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T3=m +CONFIG_CHELSIO_T4=m +CONFIG_IP1000=m +CONFIG_IXGB=m +CONFIG_IXGBEVF=m +CONFIG_IXGBE=m +CONFIG_IXGBE_DCA=y +CONFIG_IXGBE_DCB=y +CONFIG_MYRI10GE=m +CONFIG_MYRI10GE_DCA=y +CONFIG_NETXEN_NIC=m +CONFIG_NIU=m +CONFIG_S2IO=m +CONFIG_VXGE=m +# CONFIG_VXGE_DEBUG_TRACE_ALL is not set +CONFIG_TEHUTI=m +CONFIG_ENIC=m +CONFIG_MLX4_EN=m +# CONFIG_MLX4_DEBUG is not set +CONFIG_QLCNIC=m +CONFIG_QLGE=m +CONFIG_SFC=m +CONFIG_SFC_MTD=y +CONFIG_BE2NET=m + +CONFIG_FDDI=y +# CONFIG_DEFXX is not set +CONFIG_SKFP=m +# CONFIG_HIPPI is not set +CONFIG_PLIP=m +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_IPPP_FILTER=y +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +CONFIG_PPP_MPPE=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +# CONFIG_SLIP_MODE_SLIP6 is not set + +# +# Wireless LAN +# +# +CONFIG_WLAN=y +# CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_NETWAVE=m +# CONFIG_PCMCIA_RAYCS is not set + +CONFIG_WIRELESS=y +CONFIG_CFG80211=m +CONFIG_CFG80211_WEXT=y +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_CFG80211_DEBUGFS=y +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +CONFIG_CFG80211_DEFAULT_PS=y +CONFIG_NL80211=y +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_WIRELESS_OLD_REGULATORY is not set +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set + +CONFIG_MAC80211=m +CONFIG_MAC80211_RC_MINSTREL=y +# CONFIG_MAC80211_RC_DEFAULT_PID is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel" +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_DEBUG_MENU is not set + +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 +CONFIG_WIMAX_I2400M_USB=m +CONFIG_WIMAX_I2400M_SDIO=m +CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8 +CONFIG_WIMAX_IWMC3200_SDIO=y + +CONFIG_ADM8211=m +CONFIG_ATH_COMMON=m +CONFIG_ATH5K=m +CONFIG_ATH5K_DEBUG=y +CONFIG_ATH9K=m +# CONFIG_ATH9K_DEBUG is not set +CONFIG_ATH9K_DEBUGFS=y +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +CONFIG_AT76C50X_USB=m +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ATMEL=m +CONFIG_B43=m +CONFIG_B43_PCMCIA=y +CONFIG_B43_SDIO=y +# CONFIG_B43_DEBUG is not set +CONFIG_B43_PHY_LP=y +# CONFIG_B43_FORCE_PIO is not set +CONFIG_B43LEGACY=m +# CONFIG_B43LEGACY_DEBUG is not set +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_PIO=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_HERMES=m +CONFIG_HERMES_CACHE_FW_ON_INIT=y +# CONFIG_HERMES_PRISM is not set +CONFIG_NORTEL_HERMES=m +CONFIG_PCI_HERMES=m +CONFIG_PLX_HERMES=m +CONFIG_PCMCIA_HERMES=m +CONFIG_ORINOCO_USB=m +CONFIG_HOSTAP=m +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_CS=m +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_IPW2100_DEBUG is not set +# CONFIG_IPW2200_DEBUG is not set +# CONFIG_LIBIPW_DEBUG is not set +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_CS=m +CONFIG_LIBERTAS_SDIO=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_THINFIRM=m +CONFIG_LIBERTAS_THINFIRM_USB=m +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +CONFIG_LIBERTAS_MESH=y +CONFIG_IWLWIFI=m +CONFIG_IWLWIFI_DEBUG=y +CONFIG_IWLWIFI_DEBUGFS=y +CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT=y +CONFIG_IWLAGN=m +CONFIG_IWL4965=y +CONFIG_IWL5000=y +CONFIG_IWL3945=m +CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y +CONFIG_IWM=m +# CONFIG_IWM_DEBUG is not set +# CONFIG_IWM_TRACING is not set +CONFIG_MAC80211_HWSIM=m +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +CONFIG_P54_PCI=m +CONFIG_PCI_ATMEL=m +CONFIG_MWL8K=m +# CONFIG_PRISM54 is not set +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_WL3501=m +CONFIG_RT2X00=m +CONFIG_RT2X00_LIB_DEBUGFS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT61PCI=m +CONFIG_RT2500USB=m +CONFIG_RT2800USB=m +# CONFIG_RT2800USB_RT30XX is not set +# CONFIG_RT2800USB_RT35XX is not set +# CONFIG_RT2800USB_UNKNOWN is not set +CONFIG_RT2800PCI=m +# CONFIG_RT2800PCI_RT30XX is not set +# CONFIG_RT2800PCI_RT35XX is not set +CONFIG_RT73USB=m +CONFIG_RTL8180=m +CONFIG_RTL8187=m +CONFIG_TMD_HERMES=m +CONFIG_USB_ZD1201=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_AR9170_USB=m + +CONFIG_WL12XX=y +CONFIG_WL1251=m +CONFIG_WL1251_SPI=m +CONFIG_WL1251_SDIO=m +CONFIG_WL1271=m + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_IBMOL is not set +# CONFIG_3C359 is not set +# Broken with gcc4.1 +# CONFIG_TMS380TR is not set +# CONFIG_TMSPCI is not set +# CONFIG_ABYSS is not set +# CONFIG_IBMLS is not set +# CONFIG_PCMCIA_IBMTR is not set + + +CONFIG_NET_FC=y + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_AXNET=m + +# +# Amateur Radio support +# +CONFIG_HAMRADIO=y +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_CAN=m +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m +CONFIG_CAN_VCAN=m +CONFIG_CAN_DEV=m +CONFIG_CAN_CALC_BITTIMING=y +CONFIG_CAN_SJA1000=m +CONFIG_CAN_SJA1000_ISA=m +CONFIG_CAN_SJA1000_PLATFORM=m +CONFIG_CAN_EMS_PCI=m +CONFIG_CAN_EMS_USB=m +CONFIG_CAN_KVASER_PCI=m +CONFIG_CAN_PLX_PCI=m +CONFIG_NETROM=m +CONFIG_ROSE=m +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_SCC=m +CONFIG_DMASCC=m +# CONFIG_SCC_DELAY is not set +CONFIG_SCC_TRXECHO=y +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_EPP=m +CONFIG_YAM=m + +# +# IrDA (infrared) support +# +CONFIG_IRDA=m +# CONFIG_IRDA_DEBUG is not set +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRTTY_SIR=m +CONFIG_DONGLE=y +CONFIG_ACTISYS_DONGLE=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ESI_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KS959_DONGLE=m +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m + +CONFIG_ALI_FIR=m +CONFIG_MCS_FIR=m +CONFIG_NSC_FIR=m +CONFIG_SIGMATEL_FIR=m +CONFIG_SMC_IRCC_FIR=m +# CONFIG_TOSHIBA_FIR is not set +CONFIG_USB_IRDA=m +CONFIG_VLSI_FIR=m +CONFIG_VIA_FIR=m +CONFIG_WINBOND_FIR=m + +# +# Bluetooth support +# +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_L2CAP_EXT_FEATURES=y +CONFIG_BT_SCO=m +CONFIG_BT_CMTP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=m +# Disable the BT_HCIUSB driver. +# It sucks more power than BT_HCIBTUSB which has the same functionality. +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m + +# +# ISDN subsystem +# +CONFIG_ISDN=y +CONFIG_MISDN=m +CONFIG_MISDN_DSP=m +CONFIG_MISDN_L1OIP=m +CONFIG_MISDN_AVMFRITZ=m +CONFIG_MISDN_SPEEDFAX=m +CONFIG_MISDN_INFINEON=m +CONFIG_MISDN_W6692=m +CONFIG_MISDN_NETJET=m + +# +# mISDN hardware drivers +# +CONFIG_MISDN_HFCPCI=m +CONFIG_MISDN_HFCMULTI=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_C4=m + +CONFIG_MISDN_HFCUSB=m + +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_MPP=y +# CONFIG_ISDN_PPP_BSDCOMP is not set +CONFIG_ISDN_TTY_FAX=y +CONFIG_DE_AOC=y + +CONFIG_ISDN_AUDIO=y + +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m + +CONFIG_ISDN_CAPI_CAPIDRV=m +CONFIG_ISDN_DIVERSION=m + +CONFIG_HISAX_EURO=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_16_3=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NICCY=y +CONFIG_HISAX_BKM_A4T=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_W6692=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_ENTERNOW_PCI=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_ST5481=m +# CONFIG_HISAX_HFCUSB is not set +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_NO_SENDCOMPLETE=y +CONFIG_HISAX_NO_LLC=y +CONFIG_HISAX_NO_KEYPAD=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_TELES_CS=m +CONFIG_HISAX_HFC4S8S=m + +CONFIG_ISDN_DRV_LOOP=m +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y + + +# +# CAPI subsystem +# +CONFIG_ISDN_CAPI=m +# CONFIG_CAPI_TRACE is not set +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_CAPIFS=m + +# +# CAPI hardware drivers +# + +# +# Active AVM cards +# +CONFIG_CAPI_AVM=y + +# +# Active Eicon DIVA Server cards +# +# CONFIG_CAPI_EICON is not set +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVAS_MAINT=m + +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_GIGASET_CAPI=y +CONFIG_GIGASET_BASE=m +CONFIG_GIGASET_M101=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_DEBUG is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=m + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +CONFIG_INPUT_TABLET=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m + +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_YEALINK=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_SPARSEKMAP=m + +# +# Input I/O drivers +# +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_RAW=m +CONFIG_SERIO_ALTERA_PS2=m + +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_LM8323 is not set +# FIXME: Do we really need these keyboards enabled ? +CONFIG_KEYBOARD_ADP5588=m +CONFIG_KEYBOARD_MAX7359=m +CONFIG_KEYBOARD_OPENCORES=m +CONFIG_KEYBOARD_QT2160=m +# CONFIG_KEYBOARD_TCA6416 is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_ELANTECH=y +CONFIG_MOUSE_PS2_SENTELIC=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_BCM5974=m +CONFIG_MOUSE_SYNAPTICS_I2C=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WALKERA0701=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_ZHENHUA=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_HTCPEN=m +CONFIG_TOUCHSCREEN_INEXIO=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TSC2007=m +CONFIG_TOUCHSCREEN_AD7879_I2C=m +CONFIG_TOUCHSCREEN_TOUCHIT213=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_WACOM_W8001=m +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_DYNAPRO=m +# CONFIG_TOUCHSCREEN_WM97XX is not set +CONFIG_TOUCHSCREEN_EETI=m +CONFIG_TOUCHSCREEN_W90X900=m +CONFIG_TOUCHSCREEN_MCS5000=m +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_WISTRON_BTNS=m +CONFIG_INPUT_ATLAS_BTNS=m + +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_KEYSPAN_REMOTE=m + +CONFIG_MAC_EMUMOUSEBTN=y + +CONFIG_INPUT_WM831X_ON=m + +CONFIG_INPUT_APPLEIR=m + +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_PCF8574 is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_ROCKETPORT=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_GT=m +CONFIG_N_HDLC=m +CONFIG_N_GSM=m +# CONFIG_STALDRV is not set +# CONFIG_IBM_ASM is not set +CONFIG_TIFM_CORE=m +CONFIG_TIFM_7XX1=m +CONFIG_TCG_TPM=m +CONFIG_TCG_TIS=m +CONFIG_TCG_NSC=m +CONFIG_TCG_ATMEL=m +# CONFIG_TCG_INFINEON is not set +CONFIG_TELCLOCK=m + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y +# CONFIG_COMPUTONE is not set +CONFIG_CYCLADES=m +# CONFIG_CYZ_INTR is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALLION is not set +# CONFIG_ISTALLION is not set +CONFIG_SERIAL_JSM=m + +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +CONFIG_UNIX98_PTYS=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_PRINTER=m +CONFIG_LP_CONSOLE=y +CONFIG_PPDEV=m + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +# CONFIG_I2C_DEBUG_ALGO is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCF=m + +# +# I2C Hardware Bus support +# + +CONFIG_I2C_ALGOPCA=m +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD756_S4882 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_ELEKTOR is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_NFORCE2_S4985 is not set + +CONFIG_EEPROM_AT24=m +CONFIG_EEPROM_LEGACY=m +CONFIG_EEPROM_93CX6=m +CONFIG_EEPROM_MAX6875=m + +CONFIG_I2C_NFORCE2=m +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PASEMI=m +CONFIG_I2C_PCA_ISA=m +CONFIG_I2C_PCA_PLATFORM=m +# CONFIG_I2C_PIIX4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_DESIGNWARE is not set +# CONFIG_I2C_XILINX is not set + +# +# I2C Hardware Sensors Chip support +# +CONFIG_SENSORS_ATK0110=m +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADS7828=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7473=m +CONFIG_SENSORS_ADT7475=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_DS1621=m +# CONFIG_DS1682 is not set +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_G760A=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +# CONFIG_SENSORS_I5K_AMB is not set +# FIXME: IBMAEM x86 only? +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_K10TEMP=m +CONFIG_SENSORS_LIS3LV02D=m +CONFIG_SENSORS_LIS3_I2C=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_LTC4245=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SHT15=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TMP401=m +CONFIG_SENSORS_TSL2550=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VIA_CPUTEMP=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_LTC4215=m +CONFIG_SENSORS_LM95241=m +CONFIG_SENSORS_TMP421=m +CONFIG_SENSORS_WM8350=m +CONFIG_SENSORS_WM831X=m +CONFIG_SENSORS_LM73=m +CONFIG_SENSORS_AMC6821=m +CONFIG_SENSORS_ADT7411=m +CONFIG_SENSORS_ASC7621=m +CONFIG_SENSORS_EMC1403=m +CONFIG_SENSORS_TMP102=m + +CONFIG_W1=m +CONFIG_W1_CON=y +# This is busted. +# If we enable it, it steals Matrox cards, and the +# framebuffer drivers stop working. +# CONFIG_W1_MASTER_MATROX is not set +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS1WM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2431=m +CONFIG_W1_SLAVE_DS2433=m +CONFIG_W1_SLAVE_DS2433_CRC=y +CONFIG_W1_SLAVE_DS2760=m +# +# Mice +# + +# +# IPMI +# +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_POWEROFF=m + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_SOFT_WATCHDOG=m +CONFIG_WDTPCI=m +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_EUROTECH_WDT is not set +CONFIG_IB700_WDT=m +# CONFIG_MIXCOMWD is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_60XX_WDT is not set +CONFIG_W83877F_WDT=m +CONFIG_W83627HF_WDT=m +CONFIG_MACHZ_WDT=m +# CONFIG_SC520_WDT is not set +CONFIG_ALIM7101_WDT=m +CONFIG_ALIM1535_WDT=m +CONFIG_ITCO_WDT=m +CONFIG_ITCO_VENDOR_SUPPORT=y +# CONFIG_SC1200_WDT is not set +# CONFIG_PC87413_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_CPU5_WDT is not set +CONFIG_I6300ESB_WDT=m +CONFIG_IT8712F_WDT=m +# CONFIG_SBC8360_WDT is not set +# CONFIG_SBC7240_WDT is not set +CONFIG_SMSC_SCH311X_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_PCIPCWATCHDOG=m +CONFIG_USBPCWATCHDOG=m +# CONFIG_SBC_EPX_C3_WATCHDOG is not set +CONFIG_WM8350_WATCHDOG=m +CONFIG_WM831X_WATCHDOG=m +# CONFIG_MAX63XX_WATCHDOG is not set + +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_TIMERIOMEM=m +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_DEBUG is not set +# CONFIG_GEN_RTC is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +CONFIG_RTC_DRV_CMOS=y +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_DS1374=m +# CONFIG_RTC_DRV_EP93XX is not set +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_MAX6900=m +# CONFIG_RTC_DRV_M48T86 is not set +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C372=m +# CONFIG_RTC_DRV_SA1100 is not set +# CONFIG_RTC_DRV_TEST is not set +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_STK17TA8=m +# CONFIG_RTC_DRV_S35390A is not set +CONFIG_RTC_DRV_RX8581=m +CONFIG_RTC_DRV_RX8025=m +CONFIG_RTC_DRV_DS1286=m +CONFIG_RTC_DRV_M48T35=m +CONFIG_RTC_DRV_BQ4802=m +CONFIG_RTC_DRV_WM8350=m +# CONFIG_RTC_DRV_AB3100 is not set +CONFIG_RTC_DRV_WM831X=m +CONFIG_RTC_DRV_BQ32K=m +CONFIG_RTC_DRV_MSM6242=m +CONFIG_RTC_DRV_RP5C01=m + +CONFIG_DTLK=m +CONFIG_R3964=m +# CONFIG_APPLICOM is not set +# CONFIG_SONYPI is not set + +# +# Ftape, the floppy tape device driver +# +CONFIG_AGP=y +CONFIG_AGP_ALI=y +CONFIG_AGP_ATI=y +CONFIG_AGP_AMD=y +CONFIG_AGP_AMD64=y +CONFIG_AGP_INTEL=y +CONFIG_AGP_NVIDIA=y +CONFIG_AGP_SIS=y +CONFIG_AGP_SWORKS=y +CONFIG_AGP_VIA=y +CONFIG_AGP_EFFICEON=y +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +CONFIG_DRM=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_RADEON_KMS=y +CONFIG_DRM_I810=m +# CONFIG_DRM_I830 is not set +CONFIG_DRM_MGA=m +CONFIG_DRM_SIS=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_I915=m +CONFIG_DRM_I915_KMS=y +CONFIG_DRM_VIA=m +CONFIG_DRM_NOUVEAU=m +CONFIG_DRM_NOUVEAU_BACKLIGHT=y +CONFIG_DRM_NOUVEAU_DEBUG=y +CONFIG_DRM_I2C_CH7006=m +CONFIG_DRM_I2C_SIL164=m +CONFIG_DRM_VMWGFX=m + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set + +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m + +CONFIG_MWAVE=m +CONFIG_RAW_DRIVER=y +CONFIG_MAX_RAW_DEVS=8192 +CONFIG_HANGCHECK_TIMER=m + +# +# Multimedia devices +# +CONFIG_MEDIA_SUPPORT=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +# CONFIG_VIDEO_VIVI is not set + +# +# Video For Linux +# + +# +# Video Adapters +# +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BWQCAM=m +# CONFIG_VIDEO_CAFE_CCIC is not set +# CONFIG_VIDEO_CPIA is not set +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CX23885=m +CONFIG_VIDEO_CX18=m +CONFIG_VIDEO_CX18_ALSA=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_VIDEO_CX231XX_RC=y +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MXB=m +# CONFIG_VIDEO_OVCAMCHIP is not set +CONFIG_VIDEO_PVRUSB2_DVB=y +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7134_RC=y +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIDEO_FB_IVTV=m +CONFIG_VIDEO_SAA7164=m +CONFIG_VIDEO_TLG2300=m +# CONFIG_VIDEO_TIMBERDALE is not set +CONFIG_VIDEO_SR030PC30=m +# Doesn't build on 2.6.35 +# CONFIG_VIDEO_VIA_CAMERA is not set +# CONFIG_VIDEO_NOON010PC30 is not set + +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y + +# +# Radio Adapters +# +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_MAESTRO=m + +CONFIG_MEDIA_ATTACH=y +CONFIG_MEDIA_TUNER_CUSTOMISE=y +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MAX2165=m + +# +# Digital Video Broadcasting Devices +# +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CORE=m +CONFIG_DVB_MAX_ADAPTERS=8 +CONFIG_DVB_DYNAMIC_MINORS=y + +CONFIG_DVB_FE_CUSTOMISE=y +CONFIG_DVB_STB0899=m +CONFIG_DVB_STB6100=m +CONFIG_DVB_STV090x=m +CONFIG_DVB_STV6110x=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_ZL10036=m +CONFIG_DVB_ZL10039=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8261=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_DS3000=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_L64781=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_S5H1411=m +CONFIG_DVB_DIB8000=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_DIB0090=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_ISL6423=m +CONFIG_DVB_LGS8GXX=m +CONFIG_DVB_ATBM8830=m +CONFIG_DVB_TDA665x=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_MB86A16=m +CONFIG_DVB_USB_LME2510=m +CONFIG_DVB_S5H1432=m +CONFIG_DVB_MB86A20S=m +CONFIG_DVB_IX2505V=m + +# +# Supported Frontend Modules +# +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET_CORE=m +CONFIG_DVB_PLUTO2=m +CONFIG_SMS_SIANO_MDTV=m +CONFIG_SMS_USB_DRV=m +CONFIG_SMS_SDIO_DRV=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_FRIIO=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_DM1105=m +CONFIG_DVB_DRX397XD=m +CONFIG_DVB_LGDT3304=m +CONFIG_DVB_S921=m +CONFIG_DVB_ISL6405=m +CONFIG_DVB_LGS8GL5=m +CONFIG_DVB_DUMMY_FE=m +CONFIG_DVB_FIREDTV=m +CONFIG_DVB_NGENE=m +# CONFIG_DVB_CXD2099 is not set + +# +# Supported SAA7146 based PCI Adapters +# +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_PATCH=m + +# +# Supported USB Adapters +# +CONFIG_DVB_TTUSB_BUDGET=m + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_AZ6027=m + +CONFIG_DVB_PT1=m + +CONFIG_MANTIS_CORE=m +CONFIG_DVB_MANTIS=m +CONFIG_DVB_HOPPER=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_DIB9000=m + +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set + +CONFIG_RC_MAP=m +CONFIG_RC_CORE=m +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_RC5_SZ_DECODER=m +CONFIG_IR_LIRC_CODEC=m +CONFIG_IR_ENE=m +CONFIG_IR_IMON=m +CONFIG_IR_ITE_CIR=m +CONFIG_IR_MCEUSB=m +CONFIG_IR_NUVOTON=m +CONFIG_IR_STREAMZAP=m +CONFIG_IR_WINBOND_CIR=m +CONFIG_RC_LOOPBACK=m + +CONFIG_V4L_MEM2MEM_DRIVERS=y +# CONFIG_VIDEO_MEM2MEM_TESTDEV is not set + +# +# Broadcom Crystal HD video decoder driver +# +CONFIG_CRYSTALHD=m + +# +# Graphics support +# + +CONFIG_DISPLAY_SUPPORT=m +CONFIG_VIDEO_OUTPUT_CONTROL=m + +CONFIG_FB=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_3DFX=m +CONFIG_FB_3DFX_ACCEL=y +CONFIG_FB_3DFX_I2C=y +# CONFIG_FB_ARC is not set +# CONFIG_FB_ARK is not set +CONFIG_FB_ATY128=m +CONFIG_FB_ATY=m +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_ATY_GENERIC_LCD=y +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_CARMINE is not set +CONFIG_FB_CIRRUS=m +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_GEODE is not set +# CONFIG_FB_HECUBA is not set +# CONFIG_FB_HGA is not set +CONFIG_FB_I810=m +CONFIG_FB_I810_GTF=y +CONFIG_FB_I810_I2C=y +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_INTEL is not set +# CONFIG_FB_INTEL_DEBUG is not set +# CONFIG_FB_INTEL_I2C is not set +CONFIG_FB_KYRO=m +# CONFIG_FB_LE80578 is not set +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM2_FIFO_DISCONNECT is not set +# CONFIG_FB_PM3 is not set +CONFIG_FB_RADEON=m +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +# CONFIG_FB_RIVA_DEBUG is not set +# CONFIG_FB_RIVA_I2C is not set +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SAVAGE_ACCEL=y +# CONFIG_FB_SIS is not set +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_TILEBLITTING=y +CONFIG_FB_TRIDENT=m +# CONFIG_FB_UVESA is not set +CONFIG_FB_VESA=y +CONFIG_FB_VGA16=m +CONFIG_FB_VIRTUAL=m +CONFIG_FB_VOODOO1=m +# CONFIG_FB_VT8623 is not set +CONFIG_FB_EFI=y +CONFIG_FB_VIA=m +# CONFIG_FB_VIA_DIRECT_PROCFS is not set +CONFIG_FB_METRONOME=m +CONFIG_FB_MB862XX=m +CONFIG_FB_MB862XX_PCI_GDC=y +CONFIG_FB_MB862XX_LIME=y +# CONFIG_FB_PRE_INIT_FB is not set +# CONFIG_FB_TMIO is not set +# CONFIG_FB_BROADSHEET is not set + +# CONFIG_FIRMWARE_EDID is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_VGACON_SOFT_SCROLLBACK=y +CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64 +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FONTS is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +# CONFIG_SND_DEBUG_VERBOSE is not set +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_SND_SEQUENCER=y +CONFIG_SND_HRTIMER=y +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_RTCTIMER=y +CONFIG_SND_DYNAMIC_MINORS=y +# CONFIG_SND_SUPPORT_OLD_API is not set + +# +# Generic devices +# +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 + +CONFIG_SND_DRIVERS=y + +# +# ISA devices +# +CONFIG_SND_AD1889=m +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_MSND_PINNACLE is not set +# CONFIG_SND_MSND_CLASSIC is not set + +# +# PCI devices +# +CONFIG_SND_PCI=y +CONFIG_SND_ADLIB=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +# CONFIG_SND_AW2 is not set +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS4281=m +CONFIG_SND_CS5530=m +CONFIG_SND_CS5535AUDIO=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_ES1968_INPUT=y +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_CTXFI=m +CONFIG_SND_LX6464ES=m +CONFIG_SND_HDA_INTEL=y +CONFIG_SND_HDA_INPUT_BEEP=y +CONFIG_SND_HDA_INPUT_BEEP_MODE=0 +CONFIG_SND_HDA_INPUT_JACK=y +CONFIG_SND_HDA_PATCH_LOADER=y +CONFIG_SND_HDA_HWDEP=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_CA0110=y +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_CODEC_ATIHDMI=y +CONFIG_SND_HDA_CODEC_CIRRUS=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_INTELHDMI=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_CODEC_NVHDMI=y +CONFIG_SND_HDA_GENERIC=y +CONFIG_SND_HDA_POWER_SAVE=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_HDA_RECONFIG=y +CONFIG_SND_HDSPM=m +CONFIG_SND_HIFIER=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INTEL8X0=y +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_INPUT=y +CONFIG_SND_MIRO=m +CONFIG_SND_MIXART=m +CONFIG_SND_NM256=m +CONFIG_SND_OXYGEN=m +CONFIG_SND_RME32=m +CONFIG_SND_PCSP=m +CONFIG_SND_PCXHR=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SC6000=m +CONFIG_SND_SIS7019=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_HDSP=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRTUOSO=m +CONFIG_SND_VX222=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_ASIHPI=m + +# +# ALSA USB devices +# +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_USX2Y=m +CONFIG_SND_USB_US122L=m +CONFIG_SND_USB_UA101=m + +# +# PCMCIA devices +# +CONFIG_SND_PCMCIA=y +CONFIG_SND_VXPOCKET=m +CONFIG_SND_PDAUDIOCF=m + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB=y +CONFIG_USB_SUPPORT=y +# CONFIG_USB_DEBUG is not set + +# DEPRECATED: See bug 362221. Fix udev. +# CONFIG_USB_DEVICE_CLASS is not set + + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_HCD_SSB is not set +CONFIG_USB_UHCI_HCD=y +# CONFIG_USB_SL811_CS is not set +# CONFIG_USB_R8A66597_HCD is not set +CONFIG_USB_XHCI_HCD=m +# CONFIG_USB_XHCI_HCD_DEBUGGING is not set +CONFIG_USB_ISP1362_HCD=m + +# +# USB Device Class drivers +# + +# +# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_ONETOUCH=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_KARMA=y +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y + +CONFIG_HID_SUPPORT=y + +CONFIG_HID=m +# debugging default is y upstream now +CONFIG_HIDRAW=y +CONFIG_HID_PID=y +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_PANTHERLORD_FF=y +CONFIG_THRUSTMASTER_FF=y +CONFIG_HID_WACOM=m +CONFIG_HID_WACOM_POWER_SUPPLY=y +CONFIG_ZEROPLUS_FF=y +CONFIG_USB_HIDDEV=y +CONFIG_USB_IDMOUSE=m +CONFIG_DRAGONRISE_FF=y +CONFIG_GREENASIA_FF=y +CONFIG_SMARTJOYPLUS_FF=y +CONFIG_HID_3M_PCT=y +CONFIG_LOGIG940_FF=y +CONFIG_HID_MAGICMOUSE=y +CONFIG_HID_MOSART=y +CONFIG_HID_NTRIG=y +CONFIG_HID_QUANTA=y +CONFIG_HID_STANTUM=y +CONFIG_HID_CANDO=m +CONFIG_HID_PRODIKEYS=m +CONFIG_HID_DRAGONRISE=m +CONFIG_HID_EGALAX=m +CONFIG_HID_GYRATION=m +CONFIG_HID_TWINHAN=m +CONFIG_HID_ORTEK=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_PICOLCD=m +CONFIG_HID_ROCCAT=m +CONFIG_HID_ROCCAT_KONE=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_GREENASIA=m +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_HID_TOPSEED=m +CONFIG_HID_THRUSTMASTER=m +CONFIG_HID_ZEROPLUS=m +CONFIG_HID_ZYDACRON=m + + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m + +# +# USB Multimedia devices +# +CONFIG_DAB=y +CONFIG_USB_DABUSB=m + +CONFIG_USB_VICAM=m +CONFIG_USB_DSBR=m +# CONFIG_USB_ET61X251 is not set +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GSPCA=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_BENQ=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_CPIA1=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_OV534_9=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SN9C2028=m +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SN9C20X_EVDEV=y +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_PAC7302=m +CONFIG_USB_GSPCA_STV0680=m +CONFIG_USB_GL860=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_USB_GSPCA_SPCA1528=m +CONFIG_USB_GSPCA_SQ930X=m +CONFIG_USB_GSPCA_KONICA=m +CONFIG_USB_GSPCA_XIRLINK_CIT=m + +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +# CONFIG_USB_OV511 is not set +CONFIG_USB_S2255=m +CONFIG_USB_SE401=m +# CONFIG_VIDEO_SH_MOBILE_CEU is not set +# CONFIG_VIDEO_SH_MOBILE_CSI2 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_SN9C102 is not set +CONFIG_USB_ZR364XX=m +CONFIG_SOC_CAMERA=m +CONFIG_SOC_CAMERA_MT9M001=m +CONFIG_SOC_CAMERA_MT9V022=m +CONFIG_SOC_CAMERA_PLATFORM=m +CONFIG_SOC_CAMERA_MT9M111=m +CONFIG_SOC_CAMERA_MT9T031=m +CONFIG_SOC_CAMERA_TW9910=m +CONFIG_SOC_CAMERA_OV772X=m +CONFIG_SOC_CAMERA_MT9T112=m +CONFIG_SOC_CAMERA_RJ54N1=m +CONFIG_SOC_CAMERA_OV9640=m +CONFIG_SOC_CAMERA_IMX074=m +CONFIG_SOC_CAMERA_OV6650=m +CONFIG_SOC_CAMERA_OV2640=m + +# +# USB Network adaptors +# +CONFIG_USB_CATC=m +CONFIG_USB_HSO=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_ZAURUS=m +CONFIG_USB_NET_INT51X1=m +CONFIG_USB_CDC_PHONET=m +CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m + +# +# USB Host-to-Host Cables +# +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y + +# +# Intelligent USB Devices/Gadgets +# +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y + +# CONFIG_USB_MUSB_HDRC is not set + +# +# USB port drivers +# +CONFIG_USB_USS720=m + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SYMBOL=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7715_PARPORT=y +# CONFIG_USB_SERIAL_ZIO is not set +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OPTION=y +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SIEMENS_MPI=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_QCAUX=m +CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m +CONFIG_USB_SERIAL_DEBUG=m + +CONFIG_USB_EZUSB=y +CONFIG_USB_EMI62=m +CONFIG_USB_LED=m +# CONFIG_USB_CYPRESS_CY7C63 is not set +CONFIG_USB_G_SERIAL=m + +# +# USB Miscellaneous drivers +# + +CONFIG_USB_ADUTUX=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ATM=m +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CXACRU=m +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_CYTHERM is not set +CONFIG_USB_EMI26=m +CONFIG_USB_ETH=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_GADGET is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_VST=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_MON=y +CONFIG_USB_PWC=m +CONFIG_USB_PWC_INPUT_EVDEV=y +# CONFIG_USB_PWC_DEBUG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_QUICKCAM_MESSENGER is not set +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_RADIO_SI470X=y +CONFIG_USB_SI470X=m +CONFIG_I2C_SI470X=m +CONFIG_RADIO_SI4713=m +# CONFIG_RADIO_TEF6862 is not set +CONFIG_USB_MR800=m +CONFIG_USB_STKWEBCAM=m +# CONFIG_USB_TEST is not set +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m +# CONFIG_USB_ZC0301 is not set +CONFIG_USB_ZERO=m + +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB=m +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_SDIOHOST=y +CONFIG_SSB_PCMCIAHOST=y +# CONFIG_SSB_SILENT is not set +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE=y + +# Multifunction USB devices +# CONFIG_MFD_PCF50633 is not set +CONFIG_PCF50633_ADC=m +CONFIG_PCF50633_GPIO=m +# CONFIG_AB3100_CORE is not set +CONFIG_INPUT_PCF50633_PMU=m +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m +CONFIG_CHARGER_PCF50633=m +CONFIG_RTC_DRV_PCF50633=m + +CONFIG_MFD_SUPPORT=y +CONFIG_MFD_SM501=m +CONFIG_MFD_SM501_GPIO=y +# CONFIG_MFD_TC6393XB is not set +CONFIG_MFD_WM8400=m +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8350 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_AB3100_OTP is not set +# CONFIG_MFD_TIMBERDALE is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_LPC_SCH is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_TPS6507X is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_JANZ_CMODIO is not set + +# +# File systems +# +CONFIG_MISC_FILESYSTEMS=y + +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XIP=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_DEFAULTS_TO_ORDERED=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_JBD2=y +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_XFS_FS=m +# CONFIG_XFS_DEBUG is not set +# CONFIG_XFS_RT is not set +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_MINIX_FS=m +CONFIG_ROMFS_FS=m +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +# CONFIG_PRINT_QUOTA_WARNING is not set +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +CONFIG_DNOTIFY=y +# Autofsv3 is obsolete. +# CONFIG_AUTOFS_FS is not set +# systemd is dependant upon AUTOFS, so build it in. +CONFIG_AUTOFS4_FS=y +CONFIG_EXOFS_FS=m +# CONFIG_EXOFS_DEBUG is not set +CONFIG_NILFS2_FS=m +CONFIG_LOGFS=m +CONFIG_CEPH_FS=m + +CONFIG_FSCACHE=m +CONFIG_FSCACHE_STATS=y +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +CONFIG_FSCACHE_OBJECT_LIST=y + +CONFIG_CACHEFILES=m +# CONFIG_CACHEFILES_DEBUG is not set +# CONFIG_CACHEFILES_HISTOGRAM is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_VMCORE=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_DEBUG_FS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTRS=y +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_VXFS_FS=m +# CONFIG_HPFS_FS is not set +CONFIG_QNX4FS_FS=m +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_9P_FS=m +CONFIG_9P_FSCACHE=y +CONFIG_FUSE_FS=m +CONFIG_OMFS_FS=m +CONFIG_CUSE=m + +# +# Network File Systems +# +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFS_FSCACHE=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +# CONFIG_SMB_FS is not set +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +# CONFIG_CIFS_STATS2 is not set +CONFIG_CIFS_EXPERIMENTAL=y +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_WEAK_PW_HASH=y +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_NCP_FS=m +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_SMALLDOS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +CONFIG_CODA_FS=m +# CONFIG_AFS_FS is not set +# CONFIG_AF_RXRPC is not set + +CONFIG_OCFS2_FS=m +# CONFIG_OCFS2_DEBUG_FS is not set +# CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +# CONFIG_OCFS2_FS_STATS is not set + +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y + +CONFIG_CONFIGFS_FS=m + +CONFIG_DLM=m +CONFIG_DLM_DEBUG=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=y + +CONFIG_UBIFS_FS=m +CONFIG_UBIFS_FS_XATTR=y +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +# CONFIG_UBIFS_FS_DEBUG is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +CONFIG_AMIGA_PARTITION=y +# CONFIG_ATARI_PARTITION is not set +CONFIG_BSD_DISKLABEL=y +CONFIG_EFI_PARTITION=y +CONFIG_KARMA_PARTITION=y +# CONFIG_LDM_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_OSF_PARTITION=y +CONFIG_SGI_PARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_SUN_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +CONFIG_UNIXWARE_DISKLABEL=y +# CONFIG_ULTRIX_PARTITION is not set + +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_NLS_ASCII=y + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=m +CONFIG_OPROFILE_EVENT_MULTIPLEX=y + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_INFO=y +CONFIG_FRAME_POINTER=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_DEBUG_DRIVER is not set +CONFIG_HEADERS_CHECK=y +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_LKDTM is not set + +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_LOCKDEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set + +CONFIG_KGDB=y +CONFIG_KGDB_SERIAL_CONSOLE=y +CONFIG_KGDB_TESTS=y +CONFIG_KGDB_LOW_LEVEL_TRAP=y +# CONFIG_KGDB_TESTS_ON_BOOT is not set + +# +# Security options +# +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y +# CONFIG_SECURITY_PATH is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_AVC_STATS=y +# CONFIG_SECURITY_SMACK is not set +# CONFIG_SECURITY_TOMOYO is not set +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_FIPS=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER_TESTS=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SALSA20_586=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_VMAC=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_TEST=m +CONFIG_LIBCRC32C=m +CONFIG_CRYPTO_CRC32C_INTEL=m +CONFIG_CRYPTO_GHASH=m +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_DEV_HIFN_795X=m +CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y +CONFIG_CRYPTO_PCRYPT=m + +# Random number generation + +# +# Library routines +# +CONFIG_CRC16=y +CONFIG_CRC32=m +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRC_T10DIF=m + +CONFIG_CRYPTO_ZLIB=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m + +CONFIG_INITRAMFS_SOURCE="" +CONFIG_KEYS=y +CONFIG_KEYS_DEBUG_PROC_KEYS=y +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set + +CONFIG_ATA_OVER_ETH=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=m +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_PROGEAR=m +# CONFIG_BACKLIGHT_ADP8860 is not set +CONFIG_FB_NVIDIA_BACKLIGHT=y +CONFIG_FB_RIVA_BACKLIGHT=y +CONFIG_FB_RADEON_BACKLIGHT=y +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +# CONFIG_BACKLIGHT_SAHARA is not set +CONFIG_BACKLIGHT_WM831X=m + +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_PLATFORM=m + +CONFIG_SCHEDSTATS=y +CONFIG_SCHED_DEBUG=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_GROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y + +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y + +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_NS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_SCHED=y +CONFIG_CGROUP_MEM_RES_CTLR=y +CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set + +# CONFIG_SYSFS_DEPRECATED_V2 is not set + +CONFIG_RELAY=y +CONFIG_PRINTK_TIME=y + +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set + +CONFIG_KEXEC=y + +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y + +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y + +CONFIG_IBMASR=m + +CONFIG_PM_DEBUG=y +CONFIG_PM_TRACE=y +# CONFIG_PM_VERBOSE is not set +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_PM_RUNTIME=y + +## BEGIN ISA Junk. + +CONFIG_I82365=m +# CONFIG_TCIC is not set +# CONFIG_PCMCIA_PROBE is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set + +CONFIG_SCSI_AHA152X=m +CONFIG_SCSI_AHA1542=m +# CONFIG_SCSI_IN2000 is not set +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ARCMSR_AER=y +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_ULTRASTOR is not set + +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set +CONFIG_EL3=m +# CONFIG_3C515 is not set +# CONFIG_LANCE is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +CONFIG_ULTRA=m +# CONFIG_SMC9194 is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NI52 is not set +# CONFIG_NI65 is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +CONFIG_NET_ISA=y +CONFIG_NE2000=m +# CONFIG_E2100 is not set +CONFIG_EWRK3=m +# CONFIG_EEXPRESS is not set +# CONFIG_EEXPRESS_PRO is not set +# CONFIG_HPLAN_PLUS is not set +# CONFIG_HPLAN is not set +# CONFIG_LP486E is not set +# CONFIG_ETH16I is not set +# CONFIG_ZNET is not set +# CONFIG_SEEQ8005 is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +# CONFIG_IBMTR is not set +# CONFIG_SKISA is not set +# CONFIG_PROTEON is not set +# CONFIG_SMCTR is not set +# CONFIG_WAVELAN is not set +# CONFIG_HISAX_16_0 is not set +# CONFIG_HISAX_AVM_A1 is not set +# CONFIG_HISAX_IX1MICROR2 is not set +# CONFIG_HISAX_ASUSCOM is not set +# CONFIG_HISAX_TELEINT is not set +# CONFIG_HISAX_HFCS is not set +# CONFIG_HISAX_SPORTSTER is not set +# CONFIG_HISAX_MIC is not set +# CONFIG_HISAX_ISURF is not set +# CONFIG_HISAX_HSTSAPHIR is not set +# CONFIG_ISDN_DRV_ICN is not set +# CONFIG_ISDN_DRV_PCBIT is not set +# CONFIG_ISDN_DRV_SC is not set +# CONFIG_ISDN_DRV_ACT2000 is not set +# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set +# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set + +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_ATIXL is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set + +# CONFIG_SERIAL_8250_FOURPORT is not set +# CONFIG_SERIAL_8250_ACCENT is not set +# CONFIG_SERIAL_8250_BOCA is not set +# CONFIG_SERIAL_8250_HUB6 is not set +# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set + +# CONFIG_PCWATCHDOG is not set +# CONFIG_WDT is not set + +# CONFIG_VIDEO_PMS is not set +CONFIG_RADIO_ADAPTERS=y +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TEA5764 is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_ZOLTRIX is not set +# CONFIG_RADIO_SAA7706H is not set +# CONFIG_RADIO_WL1273 is not set + +# CONFIG_SND_OPL4_LIB is not set +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +CONFIG_SND_CS4236=m +# CONFIG_SND_ES968 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_JAZZ16 is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_SB8 is not set +CONFIG_SND_SB16=m +CONFIG_SND_SBAWE=m +# CONFIG_SND_SB16_CSP is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_DT019X is not set +CONFIG_SND_OPL3SA2=m +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set +CONFIG_SND_DARLA20=m +CONFIG_SND_GINA20=m +CONFIG_SND_LAYLA20=m +CONFIG_SND_DARLA24=m +CONFIG_SND_GINA24=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MONA=m +CONFIG_SND_MIA=m +CONFIG_SND_ECHO3G=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIOX=m +CONFIG_SND_INDIGODJX=m +# CONFIG_SND_SOC is not set + +## END of ISA options. + +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +# CONFIG_LEDS_AMS_DELTA is not set +# CONFIG_LEDS_LOCOMO is not set +# CONFIG_LEDS_NET48XX is not set +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_S3C24XX is not set +CONFIG_LEDS_DELL_NETBOOKS=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m +CONFIG_LEDS_ALIX2=m +CONFIG_LEDS_WM8350=m +CONFIG_LEDS_LP3944=m +CONFIG_LEDS_WM831X_STATUS=m +CONFIG_LEDS_REGULATOR=m +CONFIG_LEDS_LT3593=m +CONFIG_LEDS_TRIGGER_GPIO=m +CONFIG_LEDS_INTEL_SS4200=m + +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +# CONFIG_TIMB_DMA is not set +CONFIG_NET_DMA=y +# CONFIG_DMATEST is not set +CONFIG_ASYNC_TX_DMA=y + +CONFIG_UNUSED_SYMBOLS=y + +CONFIG_UTRACE=y + +CONFIG_FTRACE=y +CONFIG_DYNAMIC_FTRACE=y +# CONFIG_IRQSOFF_TRACER is not set +CONFIG_SCHED_TRACER=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_WORKQUEUE_TRACER=y +CONFIG_FTRACE_SYSCALLS=y +CONFIG_KMEMTRACE=y +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +CONFIG_FUNCTION_PROFILER=y +CONFIG_RING_BUFFER_BENCHMARK=m +CONFIG_FUNCTION_TRACER=y +CONFIG_STACK_TRACER=y + +CONFIG_KPROBES=y +CONFIG_OPTPROBES=y + +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set + +CONFIG_HZ_1000=y + +CONFIG_TIMER_STATS=y + +# Auxillary displays +CONFIG_KS0108=m +CONFIG_KS0108_PORT=0x378 +CONFIG_KS0108_DELAY=2 +CONFIG_CFAG12864B=y +CONFIG_CFAG12864B_RATE=20 + +# CONFIG_PHANTOM is not set + +CONFIG_POWER_SUPPLY=m +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_TEST_POWER is not set +CONFIG_APM_POWER=m +CONFIG_WM831X_POWER=m +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2782 is not set +CONFIG_BATTERY_PMU=m +CONFIG_BATTERY_BQ27x00=m +CONFIG_BATTERY_MAX17040=m +# CONFIG_PDA_POWER is not set + +CONFIG_AUXDISPLAY=y + +CONFIG_UIO=m +CONFIG_UIO_CIF=m +CONFIG_UIO_SMX=m +# CONFIG_UIO_PDRV is not set +# CONFIG_UIO_PDRV_GENIRQ is not set +CONFIG_UIO_AEC=m +CONFIG_UIO_SERCOS3=m +CONFIG_UIO_PCI_GENERIC=m +# CONFIG_UIO_NETX is not set + +# CONFIG_CRC7 is not set + + +# LIRC +CONFIG_LIRC_STAGING=y +CONFIG_LIRC_BT829=m +CONFIG_LIRC_I2C=m +CONFIG_LIRC_IGORPLUGUSB=m +CONFIG_LIRC_IMON=m +CONFIG_LIRC_ZILOG=m +CONFIG_LIRC_PARALLEL=m +CONFIG_LIRC_SERIAL=m +CONFIG_LIRC_SERIAL_TRANSMITTER=y +CONFIG_LIRC_SASEM=m +CONFIG_LIRC_SIR=m +# CONFIG_LIRC_STREAMZAP is not set +CONFIG_LIRC_TTUSBIR=m + +# CONFIG_SAMPLES is not set + +# CONFIG_DEVKMEM is not set + +CONFIG_PM_TRACE_RTC=y +CONFIG_R6040=m + +CONFIG_BNX2X=m +CONFIG_NOZOMI=m +# CONFIG_TPS65010 is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +# CONFIG_KPROBES_SANITY_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +CONFIG_LATENCYTOP=y +CONFIG_RESOURCE_COUNTERS=y +# CONFIG_COMPAT_BRK is not set + + +#FIXME: x86 generic? +CONFIG_LEDS_CLEVO_MAIL=m +CONFIG_I8K=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_X38=m +CONFIG_INPUT_APANEL=m + +# CONFIG_INTEL_MENLOW is not set +CONFIG_ENCLOSURE_SERVICES=m +CONFIG_ISL29003=m +CONFIG_IPWIRELESS=m +CONFIG_RTC_DRV_DS1511=m + +# CONFIG_BLK_DEV_XIP is not set +CONFIG_MEMSTICK=m +# CONFIG_MEMSTICK_DEBUG is not set +# CONFIG_MEMSTICK_UNSAFE_RESUME is not set +CONFIG_MSPRO_BLOCK=m +CONFIG_MEMSTICK_TIFM_MS=m +CONFIG_MEMSTICK_JMICRON_38X=m + +CONFIG_ACCESSIBILITY=y +CONFIG_A11Y_BRAILLE_CONSOLE=y + +# CONFIG_HTC_PASIC3 is not set + +# MT9V022_PCA9536_SWITCH is not set + +CONFIG_THERMAL_HWMON=y + +CONFIG_OPTIMIZE_INLINING=y + +# FIXME: This should be x86/ia64 only +# CONFIG_HP_ILO is not set + +# CONFIG_GPIOLIB is not set + + +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +CONFIG_NETFILTER_XT_MATCH_SOCKET=m + +# CONFIG_IP_VS_IPV6 is not set + +CONFIG_NET_DSA=y +CONFIG_NET_DSA_MV88E6060=y +CONFIG_NET_DSA_MV88E6131=y +CONFIG_NET_DSA_MV88E6123_61_65=y + +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_ACT_SKBEDIT=m + +CONFIG_PHONET=m + +CONFIG_ICS932S401=m +# CONFIG_C2PORT is not set +CONFIG_W1_SLAVE_BQ27000=m + + +CONFIG_IT87_WDT=m +CONFIG_W83697UG_WDT=m + +# CONFIG_REGULATOR is not set +# CONFIG_REGULATOR_DEBUG is not set + +CONFIG_WM8350_POWER=m + +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set + +CONFIG_USB_WUSB=m +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set +CONFIG_USB_WHCI_HCD=m +CONFIG_USB_HWA_HCD=m + +CONFIG_UWB=m +CONFIG_UWB_HWA=m +CONFIG_UWB_WHCI=m +CONFIG_UWB_WLP=m +CONFIG_UWB_I1480U=m +CONFIG_UWB_I1480U_WLP=m + +CONFIG_STAGING=y +# CONFIG_STAGING_EXCLUDE_BUILD is not set +# CONFIG_ET131X is not set +# CONFIG_SLICOSS is not set +# CONFIG_VIDEO_TM6000 is not set +# CONFIG_WLAGS49_H2 is not set +# CONFIG_WLAGS49_H25 is not set +# CONFIG_VIDEO_DT3155 is not set +# CONFIG_TI_ST is not set +# CONFIG_ST_BT is not set +# CONFIG_FB_XGI is not set +# CONFIG_VIDEO_GO7007 is not set +# CONFIG_USB_IP_COMMON is not set +# CONFIG_DT3155 is not set +# CONFIG_W35UND is not set +# CONFIG_PRISM2_USB is not set +# CONFIG_ECHO is not set +CONFIG_USB_ATMEL=m +# CONFIG_POCH is not set +# CONFIG_OTUS is not set +# CONFIG_RT2860 is not set +# CONFIG_RT2870 is not set +# CONFIG_COMEDI is not set +# CONFIG_ASUS_OLED is not set +# CONFIG_PANEL is not set +# CONFIG_ALTERA_PCIE_CHDMA is not set +# CONFIG_INPUT_MIMIO is not set +# CONFIG_TRANZPORT is not set +# CONFIG_POHMELFS is not set +# CONFIG_B3DFG is not set +# CONFIG_IDE_PHISON is not set +# CONFIG_PLAN9AUTH is not set +# CONFIG_LINE6_USB is not set +# CONFIG_RTL8192SU is not set +# CONFIG_IIO is not set +# CONFIG_VME_BUS is not set +# CONFIG_RAR_REGISTER is not set +# CONFIG_VT6656 is not set +# CONFIG_USB_SERIAL_QUATECH_USB2 is not set +# CONFIG_RTL8192E is not set +# CONFIG_INPUT_GPIO is not set +# CONFIG_VIDEO_CX25821 is not set +# CONFIG_HYPERV is not set +# CONFIG_R8187SE is not set +# CONFIG_RTL8192U is not set +# CONFIG_RAMZSWAP is not set +# CONFIG_BATMAN_ADV is not set +# CONFIG_FB_SM7XX is not set + +# +# Android +# + +# CONFIG_DEBUG_VIRTUAL is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FUNCTION_GRAPH_TRACER is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_EARLY_PRINTK_DBGP=y + +CONFIG_SECURITYFS=y + +CONFIG_SCSI_CXGB3_ISCSI=m +CONFIG_LIBFC=m +CONFIG_LIBFCOE=m +CONFIG_FCOE=m +CONFIG_FCOE_FNIC=m +# CONFIG_SCSI_LPFC_DEBUG_FS is not set + +CONFIG_NOP_USB_XCEIV=m + +CONFIG_IMA=y +CONFIG_IMA_MEASURE_PCR_IDX=10 +CONFIG_IMA_AUDIT=y +CONFIG_IMA_LSM_RULES=y + +CONFIG_LSM_MMAP_MIN_ADDR=65536 + +# CONFIG_PAGE_POISONING is not set + +CONFIG_SLOW_WORK=y +CONFIG_SLOW_WORK_DEBUG=y + +# CONFIG_CRASH_DUMP is not set +# CONFIG_CRASH is not set + +CONFIG_STRIP_ASM_SYMS=y + +# CONFIG_RCU_FANOUT_EXACT is not set +CONFIG_RCU_FAST_NO_HZ=y + +CONFIG_KSM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 + +CONFIG_FSNOTIFY=y + +CONFIG_IEEE802154=m +CONFIG_IEEE802154_DRIVERS=m +CONFIG_IEEE802154_FAKEHARD=m + +# CONFIG_GCOV_KERNEL is not set + +CONFIG_PPS=m +# CONFIG_PPS_CLIENT_KTIMER is not set +CONFIG_PPS_CLIENT_LDISC=m +# CONFIG_PPS_DEBUG is not set + +# CONFIG_USB_SERIAL_QUATECH2 is not set +# CONFIG_VT6655 is not set +# CONFIG_FB_UDL is not set + +# DEBUG options that don't get enabled/disabled with 'make debug/release' +# +# Kmemleak still produces a lot of false positives. +# CONFIG_DEBUG_KMEMLEAK is not set +# +# This generates a huge amount of dmesg spew +# CONFIG_DEBUG_KOBJECT is not set +# +# +# These debug options are deliberatly left on (even in 'make release' kernels). +# They aren't that much of a performance impact, and the value +# from getting useful bug-reports makes it worth leaving them on. +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DEBUG_HIGHMEM=y +CONFIG_DEBUG_SPINLOCK_SLEEP=y +CONFIG_BOOT_PRINTK_DELAY=y +CONFIG_DEBUG_LIST=y +CONFIG_DEBUG_SHIRQ=y +CONFIG_DEBUG_DEVRES=y +CONFIG_DEBUG_RODATA_TEST=y +CONFIG_DEBUG_NX_TEST=m +CONFIG_DEBUG_BOOT_PARAMS=y +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_ATOMIC64_SELFTEST=y + +CONFIG_MEMORY_FAILURE=y +CONFIG_HWPOISON_INJECT=m + +CONFIG_BLK_DEV_DRBD=m + +# CONFIG_MDIO_GPIO is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_DEBUG_GPIO is not set +# CONFIG_W1_MASTER_GPIO is not set +# CONFIG_LEDS_GPIO is not set +CONFIG_GPIO_SYSFS=y +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_CS5535 is not set +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_IT8761E is not set +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_UCB1400_CORE is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_GPIO_SCH is not set +# CONFIG_GPIO_LANGWELL is not set +# CONFIG_GPIO_RDC321X is not set + + +CONFIG_KSYM_TRACER=y +CONFIG_PROFILE_KSYM_TRACER=y +CONFIG_KPROBE_EVENT=y + +# CONFIG_RAMOOPS is not set diff --git a/config-i686-PAE b/config-i686-PAE new file mode 100644 index 000000000..eebaa6fba --- /dev/null +++ b/config-i686-PAE @@ -0,0 +1,8 @@ +# CONFIG_HIGHMEM4G is not set +CONFIG_HIGHMEM64G=y + +CONFIG_XEN_DEV_EVTCHN=m +CONFIG_XEN_SYS_HYPERVISOR=y + +# I2O only works on non-PAE 32-bit x86 +# CONFIG_I2O is not set diff --git a/config-ia64-generic b/config-ia64-generic new file mode 100644 index 000000000..f1581b40c --- /dev/null +++ b/config-ia64-generic @@ -0,0 +1,206 @@ +# +# Automatically generated make config: don't edit +# + +# +# Processor type and features +# +CONFIG_IA64=y +CONFIG_64BIT=y +# CONFIG_XEN is not set +CONFIG_MMU=y +CONFIG_EFI=y +# CONFIG_ITANIUM is not set +CONFIG_MCKINLEY=y +CONFIG_IA64_GENERIC=y +# CONFIG_IA64_DIG is not set +# CONFIG_IA64_HP_ZX1 is not set +# CONFIG_IA64_SGI_SN2 is not set +CONFIG_IA64_ESI=y +CONFIG_IA64_HP_AML_NFW=y +CONFIG_MSPEC=y +# CONFIG_IA64_HP_SIM is not set +# CONFIG_IA64_PAGE_SIZE_4KB is not set +# CONFIG_IA64_PAGE_SIZE_8KB is not set +CONFIG_IA64_PAGE_SIZE_16KB=y +# CONFIG_IA64_PAGE_SIZE_64KB is not set +CONFIG_IA64_L1_CACHE_SHIFT=7 +CONFIG_NUMA=y +# CONFIG_VIRTUAL_MEM_MAP is not set +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_IA64_MCA_RECOVERY=m +CONFIG_IA64_CYCLONE=y +CONFIG_MMTIMER=y +CONFIG_IOSAPIC=y +CONFIG_FORCE_MAX_ZONEORDER=18 +CONFIG_NR_CPUS=1024 +# CONFIG_IA32_SUPPORT is not set +# CONFIG_COMPAT is not set +CONFIG_PERFMON=y +CONFIG_IA64_PALINFO=y +CONFIG_EFI_VARS=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=16 +CONFIG_EFI_PCDP=y +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_BLK_DEV_SGIIOC4=y + +# +# Character devices +# +CONFIG_TCG_INFINEON=m + +# +# Watchdog Cards +# +# CONFIG_HW_RANDOM is not set +# CONFIG_GEN_RTC is not set +CONFIG_EFI_RTC=y +CONFIG_RTC_DRV_EFI=y + + +# +# AGP +# +CONFIG_AGP_I460=y +CONFIG_AGP_HP_ZX1=y +CONFIG_AGP_SGI_TIOCA=y + +# +# HP Simulator drivers +# +# CONFIG_HP_SIMETH is not set +# CONFIG_HP_SIMSERIAL is not set +# CONFIG_HP_SIMSCSI is not set + +# +# Kernel hacking +# +# CONFIG_IA64_PRINT_HAZARDS is not set +# CONFIG_DISABLE_VHPT is not set +# CONFIG_IA64_DEBUG_CMPXCHG is not set +# CONFIG_IA64_DEBUG_IRQ is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# SGI +# +CONFIG_SGI_SNSC=y +CONFIG_SGI_TIOCX=y +CONFIG_SGI_MBCS=m +CONFIG_SGI_IOC3=m +CONFIG_SGI_IOC4=y +CONFIG_SGI_XP=m +CONFIG_SGI_GRU=m +# CONFIG_SGI_GRU_DEBUG is not set +CONFIG_SERIAL_SGI_L1_CONSOLE=y +CONFIG_SERIAL_SGI_IOC3=m +CONFIG_SERIAL_SGI_IOC4=m + + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_BUSLOGIC is not set + +# +CONFIG_ACPI=y +CONFIG_ACPI_AC=y +# CONFIG_ACPI_ASUS is not set +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_SYSFS_POWER=y +# CONFIG_ACPI_BATTERY is not set +CONFIG_ACPI_BLACKLIST_YEAR=0 +CONFIG_ACPI_BUTTON=y +# CONFIG_ACPI_DOCK is not set +CONFIG_ACPI_FAN=y +CONFIG_ACPI_HOTPLUG_MEMORY=y +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_THERMAL=y +# CONFIG_ACPI_TOSHIBA is not set +CONFIG_ACPI_VIDEO=m +# CONFIG_ACPI_PROC_EVENT is not set +CONFIG_ACPI_HED=m + +CONFIG_PM=y +CONFIG_HOTPLUG_PCI=y +# CONFIG_HPET is not set +# CONFIG_HOTPLUG_PCI_CPCI is not set +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HOTPLUG_PCI_SGI=m +CONFIG_PNPACPI=y + +CONFIG_SCHED_SMT=y + +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y + +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEBUG=y +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y + +CONFIG_IA64_ACPI_CPUFREQ=m + +# CONFIG_PERMIT_BSP_REMOVE is not set +# CONFIG_FORCE_CPEI_RETARGET is not set + +CONFIG_NODES_SHIFT=10 + + +CONFIG_HW_RANDOM_INTEL=m + +CONFIG_CRASH_DUMP=y +CONFIG_PROC_VMCORE=y + +# drivers/media/video/usbvision/usbvision-i2c.c:64:39: error: macro "outb" passed 4 arguments, but takes just 2 +# CONFIG_VIDEO_USBVISION is not set + +# CONFIG_IA64_MC_ERR_INJECT is not set + +CONFIG_DMIID=y + +CONFIG_SENSORS_I5K_AMB=m + +CONFIG_SPARSEMEM_VMEMMAP=y + +CONFIG_FRAME_WARN=2048 + +CONFIG_VIRT_CPU_ACCOUNTING=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=m +CONFIG_KVM_INTEL=m + +CONFIG_HP_ILO=m + +CONFIG_PARAVIRT_GUEST=y +CONFIG_PARAVIRT=y + +CONFIG_DMAR_DEFAULT_ON=y + +CONFIG_RCU_FANOUT=64 + +CONFIG_ACPI_POWER_METER=m +CONFIG_I2C_SCMI=m diff --git a/kernel-local b/config-local similarity index 100% rename from kernel-local rename to config-local diff --git a/config-nodebug b/config-nodebug new file mode 100644 index 000000000..99a780cf0 --- /dev/null +++ b/config-nodebug @@ -0,0 +1,93 @@ +CONFIG_SND_VERBOSE_PRINTK=y +CONFIG_SND_DEBUG=y +CONFIG_SND_PCM_XRUN_DEBUG=y + +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_PROVE_RCU is not set +# CONFIG_PROVE_RCU_REPEATEDLY is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_CPUMASK_OFFSTACK=y + +# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set + +# CONFIG_FAULT_INJECTION is not set +# CONFIG_FAILSLAB is not set +# CONFIG_FAIL_PAGE_ALLOC is not set +# CONFIG_FAIL_MAKE_REQUEST is not set +# CONFIG_FAULT_INJECTION_DEBUG_FS is not set +# CONFIG_FAULT_INJECTION_STACKTRACE_FILTER is not set +# CONFIG_FAIL_IO_TIMEOUT is not set + +# CONFIG_SLUB_DEBUG_ON is not set + +# CONFIG_LOCK_STAT is not set + +# CONFIG_DEBUG_STACK_USAGE is not set + +# CONFIG_ACPI_DEBUG is not set +# CONFIG_ACPI_DEBUG_FUNC_TRACE is not set + +# CONFIG_DEBUG_SG is not set + +# CONFIG_DEBUG_PAGEALLOC is not set + +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_OBJECTS_SELFTEST is not set +# CONFIG_DEBUG_OBJECTS_FREE is not set +# CONFIG_DEBUG_OBJECTS_TIMERS is not set +CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1 + +# CONFIG_X86_PTDUMP is not set + +# CONFIG_CAN_DEBUG_DEVICES is not set + +# CONFIG_MODULE_FORCE_UNLOAD is not set + +# CONFIG_SYSCTL_SYSCALL_CHECK is not set + +# CONFIG_DEBUG_NOTIFIERS is not set + +# CONFIG_DMA_API_DEBUG is not set + +# CONFIG_MMIOTRACE is not set + +# CONFIG_DEBUG_CREDENTIALS is not set + +# off in both production debug and nodebug builds, +# on in rawhide nodebug builds +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set + +# CONFIG_EXT4_DEBUG is not set + +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set + +# CONFIG_JBD2_DEBUG is not set + +# CONFIG_DEBUG_CFQ_IOSCHED is not set + +# CONFIG_DRBD_FAULT_INJECTION is not set + +# CONFIG_ATH_DEBUG is not set +# CONFIG_IWLWIFI_DEVICE_TRACING is not set + +# CONFIG_DEBUG_OBJECTS_WORK is not set +# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set + +# CONFIG_DMADEVICES_DEBUG is not set +# CONFIG_DMADEVICES_VDEBUG is not set + +CONFIG_PM_ADVANCED_DEBUG=y + +# CONFIG_CEPH_FS_PRETTYDEBUG is not set +# CONFIG_QUOTA_DEBUG is not set + +# CONFIG_PCI_DEFAULT_USE_CRS is not set + +CONFIG_KGDB_KDB=y +CONFIG_KDB_KEYBOARD=y diff --git a/config-powerpc-generic b/config-powerpc-generic new file mode 100644 index 000000000..430396dfc --- /dev/null +++ b/config-powerpc-generic @@ -0,0 +1,334 @@ +# Most PowerPC kernels we build are SMP +CONFIG_SMP=y +CONFIG_IRQ_ALL_CPUS=y +CONFIG_PPC=y +CONFIG_WATCHDOG_RTAS=m +CONFIG_DEBUGGER=y +CONFIG_GENERIC_NVRAM=y +CONFIG_ALTIVEC=y + +CONFIG_TAU=y +# CONFIG_TAU_INT is not set +CONFIG_TAU_AVERAGE=y + +CONFIG_SECCOMP=y + +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEBUG=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y + +CONFIG_PM=y + +CONFIG_PM_STD_PARTITION="" + +CONFIG_SUSPEND=y +CONFIG_HIBERNATION=y +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_GEN_RTC_X is not set +CONFIG_RTC_DRV_GENERIC=y +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set + +CONFIG_ADB=y +CONFIG_ADB_PMU=y +CONFIG_WINDFARM=y +CONFIG_WINDFARM_PM112=y +CONFIG_I2C_POWERMAC=y +CONFIG_APPLE_AIRPORT=m +CONFIG_SERIAL_PMACZILOG=m +# CONFIG_SERIAL_PMACZILOG_TTYS is not set +CONFIG_AGP_UNINORTH=y +CONFIG_FB_OF=y +# CONFIG_FB_CONTROL is not set +CONFIG_FB_IBM_GXT4500=y +CONFIG_FB_RADEON=y +CONFIG_FB_MATROX=y +CONFIG_FB_NVIDIA=m +# CONFIG_FB_VGA16 is not set +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_RADEON_BACKLIGHT=y +CONFIG_FB_RIVA_BACKLIGHT=y +CONFIG_FB_NVIDIA_BACKLIGHT=y + +CONFIG_SND_POWERMAC=m +CONFIG_SND_POWERMAC_AUTO_DRC=y +CONFIG_SND_AOA=m +CONFIG_SND_AOA_SOUNDBUS=m +CONFIG_SND_AOA_FABRIC_LAYOUT=m +CONFIG_SND_AOA_ONYX=m +CONFIG_SND_AOA_TAS=m +CONFIG_SND_AOA_TOONIE=m +CONFIG_SND_AOA_SOUNDBUS_I2S=m + +CONFIG_XMON=y +# CONFIG_XMON_DEFAULT is not set +CONFIG_XMON_DISASSEMBLY=y + +CONFIG_BOOTX_TEXT=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_CAPI_EICON=y + +CONFIG_NVRAM=y + +# CONFIG_PCMCIA_M8XX is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_NI52 is not set +# CONFIG_NI65 is not set +# CONFIG_LANCE is not set +# CONFIG_3C515 is not set +# CONFIG_ELPLUS is not set + +CONFIG_MEMORY_HOTPLUG=y + +# Stuff which wants bus_to_virt() or virt_to_bus() +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_ATM_HORIZON is not set +# CONFIG_ATM_FIRESTREAM is not set +# CONFIG_ATM_AMBASSADOR is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_BUSLOGIC is not set + + +# CONFIG_PPC_EARLY_DEBUG is not set + +# CONFIG_PMAC_BACKLIGHT_LEGACY is not set +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_GPIO=m + +# FIXME: Should depend on IA64/x86 +# CONFIG_SGI_IOC4 is not set + +CONFIG_PPC_EFIKA=y +CONFIG_PPC_MEDIA5200=y + +# CONFIG_PPC_LITE5200 is not set +CONFIG_PPC_BESTCOMM=y +CONFIG_PMAC_RACKMETER=m +CONFIG_USB_OHCI_HCD_PPC_SOC=y +CONFIG_USB_OHCI_HCD_PCI=y +CONFIG_USB_OHCI_HCD_PPC_OF=y +CONFIG_USB_OHCI_HCD_PPC_OF_BE=y +CONFIG_USB_OHCI_HCD_PPC_OF_LE=y + +CONFIG_SERIAL_UARTLITE=m +CONFIG_SERIAL_UARTLITE_CONSOLE=y + +CONFIG_SENSORS_AMS=m +CONFIG_SENSORS_AMS_PMU=y +CONFIG_SENSORS_AMS_I2C=y + +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_IDE_TASK_IOCTL=y +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_BLK_DEV_IDEPNP is not set +# CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SL82C105 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_IDE_PMAC=y +CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_BLK_DEV_HD is not set +# CONFIG_USB_STORAGE_ISD200 is not set +CONFIG_MTD_PHYSMAP_OF=m +CONFIG_IDE_PROC_FS=y +CONFIG_MACINTOSH_DRIVERS=y + +CONFIG_PPC_PASEMI_MDIO=m +CONFIG_SPU_FS_64K_LS=y +CONFIG_PPC_PASEMI_CPUFREQ=y +CONFIG_PMAC_APM_EMU=m +CONFIG_HW_RANDOM_PASEMI=m + +CONFIG_EDAC=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_PASEMI=m +CONFIG_EDAC_AMD8131=m +CONFIG_EDAC_AMD8111=m + +CONFIG_AXON_RAM=m +CONFIG_OPROFILE_CELL=y + +CONFIG_SUSPEND_FREEZER=y +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +CONFIG_PATA_PLATFORM=m +CONFIG_PATA_OF_PLATFORM=m +CONFIG_USB_EHCI_HCD_PPC_OF=y + +# CONFIG_MPC5121_ADS is not set +# CONFIG_MPC5121_GENERIC is not set +CONFIG_MTD_OF_PARTS=m +# CONFIG_MTD_NAND_FSL_ELBC is not set +CONFIG_THERMAL=y + +# CONFIG_MEMORY_HOTREMOVE is not set + +CONFIG_DMADEVICES=y +# CONFIG_FSL_DMA is not set + +CONFIG_SND_PPC=y + +CONFIG_PPC_82xx=y +CONFIG_PPC_83xx=y +CONFIG_PPC_86xx=y +CONFIG_EXTRA_TARGETS="" +# CONFIG_CODE_PATCHING_SELFTEST is not set +# CONFIG_FTR_FIXUP_SELFTEST is not set + +# CONFIG_MATH_EMULATION is not set +# CONFIG_RAPIDIO is not set +# CONFIG_FS_ENET is not set +# CONFIG_UCC_GETH is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_SERIAL_CPM is not set +# CONFIG_SERIAL_QE is not set +# CONFIG_I2C_CPM is not set + + +CONFIG_SERIO_XILINX_XPS_PS2=m + +# CONFIG_PPC_SMLPAR is not set + +CONFIG_MGCOGE=y +CONFIG_GEF_SBC610=y +CONFIG_GEF_PPC9A=y +CONFIG_GEF_SBC310=y + +CONFIG_QUICC_ENGINE=y +CONFIG_QE_GPIO=y +CONFIG_MPC8xxx_GPIO=y + +CONFIG_IDE_GD=y +CONFIG_IDE_GD_ATA=y +CONFIG_IDE_GD_ATAPI=y + +CONFIG_MCU_MPC8349EMITX=m + +CONFIG_GPIO_XILINX=y + +CONFIG_PMIC_DA903X=y +CONFIG_BACKLIGHT_DA903X=m +CONFIG_LEDS_DA903X=m + +CONFIG_MSI_BITMAP_SELFTEST=y + +CONFIG_RELOCATABLE=y + +# CONFIG_HVC_UDBG is not set +CONFIG_PRINT_STACK_DEPTH=64 + +CONFIG_BATTERY_DA9030=m +# CONFIG_TWL4030_CORE is not set + +CONFIG_BLK_DEV_IT8172=m +CONFIG_TOUCHSCREEN_DA9034=m + +CONFIG_SIMPLE_GPIO=y + +CONFIG_FSL_PQ_MDIO=m + +CONFIG_PS3_VRAM=m +CONFIG_MDIO_GPIO=m +CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL=m +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_PCA953X=m +CONFIG_GPIO_PCF857X=m + +# CONFIG_USB_FHCI_HCD is not set +# CONFIG_FHCI_DEBUG is not set + +# CONFIG_DRM_RADEON_KMS is not set + +# CONFIG_AMIGAONE is not set + +CONFIG_PPC_OF_BOOT_TRAMPOLINE=y + +CONFIG_DTL=y + +CONFIG_MMC_SDHCI_OF=m + +# CONFIG_CONSISTENT_SIZE_BOOL is not set + +CONFIG_CAN_SJA1000_OF_PLATFORM=m + +CONFIG_PPC_EMULATED_STATS=y + +CONFIG_SWIOTLB=y + +# CONFIG_RDS is not set + +CONFIG_PPC_DISABLE_WERROR=y + +CONFIG_XILINX_LL_TEMAC=m +CONFIG_XILINX_EMACLITE=m + +CONFIG_GPIO_WM831X=m +# CONFIG_GPIO_LANGWELL is not set +# CONFIG_GPIO_UCB1400 is not set +CONFIG_EDAC_MPC85XX=m + +CONFIG_NR_IRQS=512 +CONFIG_SPARSE_IRQ=y + +CONFIG_PPC_MPC5200_LPBFIFO=m +CONFIG_CAN_MSCAN=m +CONFIG_CAN_MPC5XXX=m +CONFIG_PATA_MACIO=m +CONFIG_SERIAL_GRLIB_GAISLER_APBUART=m +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_88PM8607 is not set +# CONFIG_XPS_USB_HCD_XILINX is not set +# CONFIG_MMC_SDHCI_OF_ESDHC is not set +# CONFIG_MMC_SDHCI_OF_HLWD is not set + +# CONFIG_MFD_TC35892 is not set + +# CONFIG_GPIO_SCH is not set diff --git a/config-powerpc32-generic b/config-powerpc32-generic new file mode 100644 index 000000000..07b450ad3 --- /dev/null +++ b/config-powerpc32-generic @@ -0,0 +1,183 @@ +# CONFIG_SMP is not set +CONFIG_PPC32=y +# CONFIG_PPC64 is not set +# CONFIG_RTAS_PROC is not set +# CONFIG_PCMCIA_M8XX is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_CPU_FREQ_PMAC=y +CONFIG_PPC_CHRP=y +CONFIG_PPC_PMAC=y +CONFIG_PPC_MPC52xx=y +CONFIG_PPC_PREP=y + +# CONFIG_PPC_MPC5200_SIMPLE is not set +CONFIG_SATA_FSL=m +# CONFIG_SATA_NV is not set + +# busted in .28git1 +# ERROR: "cacheable_memzero" [drivers/net/gianfar_driver.ko] undefined! +# CONFIG_GIANFAR is not set +CONFIG_USB_EHCI_FSL=y + +CONFIG_PMAC_APM_EMU=y +CONFIG_PMAC_BACKLIGHT=y + +CONFIG_HIGHMEM=y +# CONFIG_HIGHMEM_START_BOOL is not set +# CONFIG_LOWMEM_SIZE_BOOL is not set +# CONFIG_TASK_SIZE_BOOL is not set +# CONFIG_KERNEL_START_BOOL is not set +# CONFIG_PPC601_SYNC_FIX is not set +CONFIG_ADVANCED_OPTIONS=y +CONFIG_SCSI_MESH=m +CONFIG_SCSI_MESH_SYNC_RATE=5 +CONFIG_SCSI_MESH_RESET_DELAY_MS=4000 + +CONFIG_SCSI_MAC53C94=m +CONFIG_ADB_CUDA=y +CONFIG_ADB_MACIO=y +CONFIG_INPUT_ADBHID=y +CONFIG_ADB_PMU_LED=y +CONFIG_ADB_PMU_LED_IDE=y + +CONFIG_PMAC_MEDIABAY=y +CONFIG_BMAC=m +CONFIG_MACE=m +# CONFIG_MACE_AAUI_PORT is not set +CONFIG_MV643XX_ETH=m +CONFIG_I2C_HYDRA=m +CONFIG_I2C_MPC=m +CONFIG_THERM_WINDTUNNEL=m +CONFIG_THERM_ADT746X=m +# CONFIG_ANSLCD is not set + +CONFIG_FB_PLATINUM=y +CONFIG_FB_VALKYRIE=y +CONFIG_FB_CT65550=y +# CONFIG_BDI_SWITCH is not set + +CONFIG_MAC_FLOPPY=m +# CONFIG_BLK_DEV_FD is not set + +CONFIG_FB_ATY128=y +CONFIG_FB_ATY=y +CONFIG_FB_MATROX=y +# CONFIG_KEXEC is not set + +# CONFIG_HVC_RTAS is not set + +# CONFIG_UDBG_RTAS_CONSOLE is not set +CONFIG_BRIQ_PANEL=m + +# CONFIG_ATA_PIIX is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ATIIXP is not set +CONFIG_PATA_MPC52xx=m +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_SERVERWORKS is not set + +CONFIG_SERIAL_MPC52xx=y +CONFIG_SERIAL_MPC52xx_CONSOLE=y +CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 +# CONFIG_MPC5200_WDT is not set +CONFIG_8xxx_WDT=m +CONFIG_GEF_WDT=m + +CONFIG_PPC_MPC5200_BUGFIX=y +CONFIG_FEC_MPC52xx=m +#CHECK: This may later become a tristate. +CONFIG_FEC_MPC52xx_MDIO=y +CONFIG_PPC_MPC5200_GPIO=y +CONFIG_MDIO_GPIO=m + +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_DEBUG_STACKOVERFLOW=y + +# CONFIG_EMBEDDED6xx is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y + +# CONFIG_BLK_DEV_PLATFORM is not set +# CONFIG_BLK_DEV_4DRIVES is not set +# CONFIG_BLK_DEV_ALI14XX is not set +# CONFIG_BLK_DEV_DTC2278 is not set +# CONFIG_BLK_DEV_HT6560B is not set +# CONFIG_BLK_DEV_QD65XX is not set +# CONFIG_BLK_DEV_UMC8672 is not set + +# CONFIG_VIRQ_DEBUG is not set + +CONFIG_PPC_BESTCOMM_ATA=m +CONFIG_PPC_BESTCOMM_FEC=m +CONFIG_PPC_BESTCOMM_GEN_BD=m + +CONFIG_FORCE_MAX_ZONEORDER=11 +# CONFIG_PAGE_OFFSET_BOOL is not set +# CONFIG_FB_FSL_DIU is not set +CONFIG_IRQSTACKS=y +CONFIG_VIRTUALIZATION=y + +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_HTC_EGPIO is not set + +# CONFIG_TIFM_CORE is not set + +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set + +# CONFIG_I2C_NFORCE2 is not set + +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set + +# CONFIG_MEMSTICK is not set + +# CONFIG_IPMI_HANDLER is not set +# CONFIG_TCG_TPM is not set + +# PPC gets sad with debug alloc (bz 448598) +# CONFIG_DEBUG_PAGEALLOC is not set + +CONFIG_SND_ISA=y +CONFIG_CRYPTO_DEV_TALITOS=m + +CONFIG_FSL_EMB_PERFMON=y +CONFIG_MPC8272_ADS=y +CONFIG_PQ2FADS=y +CONFIG_EP8248E=y +CONFIG_MPC831x_RDB=y +CONFIG_MPC832x_MDS=y +CONFIG_MPC832x_RDB=y +CONFIG_MPC834x_MDS=y +CONFIG_MPC834x_ITX=y +CONFIG_MPC836x_MDS=y +CONFIG_MPC836x_RDK=y +CONFIG_MPC837x_MDS=y +CONFIG_MPC837x_RDB=y +CONFIG_SBC834x=y +CONFIG_ASP834x=y +CONFIG_KMETER1=y +CONFIG_MPC8641_HPCN=y +CONFIG_SBC8641D=y +CONFIG_MPC8610_HPCD=y + +# CONFIG_USB_MUSB_HDRC is not set + +# busted in 2.6.27 +# drivers/mtd/maps/sbc8240.c: In function 'init_sbc8240_mtd': +# drivers/mtd/maps/sbc8240.c:172: warning: passing argument 1 of 'simple_map_init' from incompatible pointer type +# drivers/mtd/maps/sbc8240.c:177: error: 'struct mtd_info' has no member named 'module' + +CONFIG_MTD_NAND_FSL_UPM=m + +CONFIG_RCU_FANOUT=32 + +CONFIG_PERF_COUNTERS=y +CONFIG_PERF_EVENTS=y +CONFIG_EVENT_PROFILE=y + +CONFIG_KVM_BOOK3S_32=m diff --git a/config-powerpc32-smp b/config-powerpc32-smp new file mode 100644 index 000000000..e60f59cdf --- /dev/null +++ b/config-powerpc32-smp @@ -0,0 +1,4 @@ +CONFIG_SMP=y +# CONFIG_HOTPLUG_CPU is not set +CONFIG_NR_CPUS=4 +# CONFIG_BATTERY_PMU is not set diff --git a/config-powerpc64 b/config-powerpc64 new file mode 100644 index 000000000..e2e8f99f0 --- /dev/null +++ b/config-powerpc64 @@ -0,0 +1,184 @@ +CONFIG_WINDFARM_PM81=y +CONFIG_WINDFARM_PM91=y +CONFIG_WINDFARM_PM121=y +CONFIG_PPC_PMAC64=y +CONFIG_PPC_MAPLE=y +CONFIG_PPC_CELL=y +CONFIG_PPC_IBM_CELL_BLADE=y +CONFIG_PPC_ISERIES=y +CONFIG_PPC_PSERIES=y +CONFIG_PPC_PMAC=y +CONFIG_PPC_PASEMI=y +# CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE is not set +CONFIG_PPC_PS3=y +CONFIG_PPC_CELLEB=y +CONFIG_PPC_CELL_QPACE=y +CONFIG_PS3_HTAB_SIZE=20 +# CONFIG_PS3_DYNAMIC_DMA is not set +CONFIG_PS3_ADVANCED=y +CONFIG_PS3_HTAB_SIZE=20 +# CONFIG_PS3_DYNAMIC_DMA is not set +CONFIG_PS3_VUART=y +CONFIG_PS3_PS3AV=y +CONFIG_PS3_STORAGE=m +CONFIG_PS3_DISK=m +CONFIG_PS3_ROM=m +CONFIG_PS3_FLASH=m +CONFIG_PS3_LPM=y +CONFIG_SND_PS3=m +CONFIG_SND_PS3_DEFAULT_START_DELAY=1000 +CONFIG_GELIC_NET=m +CONFIG_GELIC_WIRELESS=y +CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE=y +CONFIG_CBE_THERM=m +CONFIG_CBE_CPUFREQ=m +CONFIG_CBE_CPUFREQ_PMI=m +CONFIG_CBE_CPUFREQ_PMI_ENABLE=y +CONFIG_PMAC_RACKMETER=m +CONFIG_IBMEBUS=y +CONFIG_SPU_FS=m +CONFIG_RTAS_FLASH=y +CONFIG_PPC_SPLPAR=y +CONFIG_SCANLOG=y +CONFIG_LPARCFG=y +CONFIG_SERIAL_ICOM=m +CONFIG_HVCS=m +CONFIG_HVC_CONSOLE=y +CONFIG_HOTPLUG_PCI=y +CONFIG_THERM_PM72=y +CONFIG_IBMVETH=m +CONFIG_SCSI_IBMVSCSI=m +# CONFIG_HOTPLUG_PCI_CPCI is not set +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HOTPLUG_PCI_RPA=m +CONFIG_HOTPLUG_PCI_RPA_DLPAR=y +CONFIG_ADB_PMU_LED=y +CONFIG_ADB_PMU_LED_IDE=y +CONFIG_PMAC_SMU=y +CONFIG_CPU_FREQ_PMAC64=y +CONFIG_SCSI_IPR=m +CONFIG_SCSI_IPR_TRACE=y +CONFIG_SCSI_IPR_DUMP=y +CONFIG_SPIDER_NET=m +CONFIG_HVC_RTAS=y +CONFIG_HVC_ISERIES=y +CONFIG_CBE_RAS=y + +# iSeries device drivers +# +CONFIG_ISERIES_VETH=m +CONFIG_VIODASD=m +CONFIG_VIOCD=m +CONFIG_VIOTAPE=m + +CONFIG_PASEMI_MAC=m +CONFIG_SERIAL_OF_PLATFORM=m + +CONFIG_PPC_PASEMI_IOMMU=y +CONFIG_SERIAL_TXX9=y +CONFIG_SERIAL_TXX9_NR_UARTS=6 +CONFIG_SERIAL_TXX9_CONSOLE=y + +CONFIG_HVC_BEAT=y + +CONFIG_FB_PS3=y +CONFIG_FB_PS3_DEFAULT_SIZE_M=18 + +CONFIG_PPC_PMI=m +CONFIG_PS3_SYS_MANAGER=y +# CONFIG_BLK_DEV_CELLEB is not set + +CONFIG_PATA_SCC=m + +CONFIG_APM_EMULATION=m + +CONFIG_PPC64=y +CONFIG_VIRT_CPU_ACCOUNTING=y +CONFIG_NR_CPUS=128 +# CONFIG_FB_PLATINUM is not set +# CONFIG_FB_VALKYRIE is not set +# CONFIG_FB_CT65550 is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set + +# CONFIG_POWER4_ONLY is not set + +CONFIG_RTAS_PROC=y +CONFIG_IOMMU_VMERGE=y +CONFIG_NUMA=y +# CONFIG_PPC_64K_PAGES is not set +CONFIG_SCHED_SMT=y + +# CONFIG_MV643XX_ETH is not set +CONFIG_IRQSTACKS=y +CONFIG_DEBUG_STACKOVERFLOW=y +# CONFIG_INPUT_PCSPKR is not set + +CONFIG_EHEA=m +CONFIG_INFINIBAND_EHCA=m + +CONFIG_HCALL_STATS=y + +CONFIG_XMON_DISASSEMBLY=y + +CONFIG_SCSI_IBMVSCSIS=m + +CONFIG_SECCOMP=y + +CONFIG_TUNE_CELL=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_BLK_DEV_PLATFORM is not set +CONFIG_IBM_NEW_EMAC=m +CONFIG_IBM_NEW_EMAC_RXB=128 +CONFIG_IBM_NEW_EMAC_TXB=64 +CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 +CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 +CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 +# CONFIG_IBM_NEW_EMAC_DEBUG is not set + +# CONFIG_VIRQ_DEBUG is not set +CONFIG_ELECTRA_CF=m + +CONFIG_MTD_NAND_PASEMI=m +CONFIG_EDAC_CELL=m +CONFIG_EDAC_CPC925=m +CONFIG_FRAME_WARN=2048 + +CONFIG_PHYP_DUMP=y +CONFIG_FORCE_MAX_ZONEORDER=13 +CONFIG_VIRTUALIZATION=y + +CONFIG_VSX=y + +CONFIG_SCSI_IBMVFC=m +# CONFIG_SCSI_IBMVFC_TRACE is not set +CONFIG_IBM_BSR=m + +CONFIG_SERIO_XILINX_XPS_PS2=m + +CONFIG_PPC_IBM_CELL_RESETBUTTON=y +CONFIG_PPC_IBM_CELL_POWERBUTTON=m +CONFIG_CBE_CPUFREQ_SPU_GOVERNOR=m + +CONFIG_RTC_DRV_PS3=y + +CONFIG_CRASH_DUMP=y +CONFIG_RELOCATABLE=y + +CONFIG_RCU_FANOUT=64 + +CONFIG_PERF_COUNTERS=y +CONFIG_PERF_EVENTS=y +CONFIG_EVENT_PROFILE=y + +CONFIG_KVM_BOOK3S_64=m +# CONFIG_KVM_EXIT_TIMING is not set + +#-- bz#607175 +#-- active memory sharing +CONFIG_PPC_SMLPAR=y +CONFIG_CMM=y +#-- DLPAR memory remove +# CONFIG_SPARSEMEM_VMEMMAP is not set diff --git a/config-rhel-generic b/config-rhel-generic new file mode 100644 index 000000000..09dbf8121 --- /dev/null +++ b/config-rhel-generic @@ -0,0 +1,205 @@ +# CONFIG_ISA is not set +# CONFIG_ISAPNP is not set +# CONFIG_I2C_PCA_ISA is not set + +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_DC390T is not set + +# CONFIG_ATALK is not set +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_IPX is not set +# CONFIG_IPDDP is not set +# CONFIG_DECNET is not set +# CONFIG_PLIP is not set + +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_PCMCIA_SYM53C500 is not set + +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_WD80x3 is not set +# CONFIG_I82092 is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SUNDANCE is not set +# CONFIG_ULTRA is not set +# CONFIG_SKFP is not set +# CONFIG_DE600 is not set +# CONFIG_DE620 is not set +# CONFIG_CS89x0 is not set +# CONFIG_AC3200 is not set +# CONFIG_NI52 is not set +# CONFIG_NI65 is not set +# CONFIG_LANCE is not set +# CONFIG_EL16 is not set +# CONFIG_EL3 is not set +# CONFIG_3C515 is not set +# CONFIG_HAMACHI is not set +# CONFIG_HP100 is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_SB1000 is not set +# CONFIG_DEPCA is not set +# CONFIG_ATP is not set + +# CONFIG_TR is not set + +# CONFIG_GAMEPORT is not set + +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_ES968 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_MIRO is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_SB16_CSP is not set +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_DT019X is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set + +# CONFIG_WAN_ROUTER is not set + +# CONFIG_BINFMT_AOUT is not set + +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_SIS is not set + +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_DAC960 is not set + +# CONFIG_PARIDE is not set + +# CONFIG_I2O is not set + +# CONFIG_MWAVE is not set + +# CONFIG_ROCKETPORT is not set +# CONFIG_R3964 is not set + +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set + +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_ZOLTRIX is not set + + +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA_PP is not set +# CONFIG_VIDEO_CPIA_USB is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_DC30 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZORAN_LML33R10 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_SAA5246A is not set + +# CONFIG_INFTL is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PCI is not set + +# CONFIG_FB_MATROX is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_HGA_ACCEL is not set +# CONFIG_FB_3DFX_ACCEL is not set + +# CONFIG_JFS_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_9P_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set + diff --git a/config-s390x b/config-s390x new file mode 100644 index 000000000..0d3a14b06 --- /dev/null +++ b/config-s390x @@ -0,0 +1,228 @@ +CONFIG_64BIT=y +# CONFIG_MARCH_G5 is not set +# CONFIG_MARCH_Z900 is not set +CONFIG_MARCH_Z9_109=y +# CONFIG_MARCH_Z990 is not set + +CONFIG_NR_CPUS=64 +CONFIG_COMPAT=y + +# See bug 496596 +CONFIG_HZ_100=y +# CONFIG_HZ_1000 is not set +# See bug 496605 +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + +CONFIG_MMU=y + +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_NO_IDLE_HZ=y + +CONFIG_SMP=y + +# +# I/O subsystem configuration +# +CONFIG_QDIO=m + +# +# Misc +# +CONFIG_IPL=y +# CONFIG_IPL_TAPE is not set +CONFIG_IPL_VM=y +# CONFIG_PROCESS_DEBUG is not set +CONFIG_PFAULT=y +CONFIG_SHARED_KERNEL=y +CONFIG_CMM=m +CONFIG_CMM_PROC=y +# CONFIG_NETIUCV is not set +CONFIG_SMSGIUCV=m + +# +# SCSI low-level drivers +# +CONFIG_ZFCP=m +CONFIG_ZFCPDUMP=y +CONFIG_CCW=y + +# +# S/390 block device drivers +# +CONFIG_DCSSBLK=m +CONFIG_BLK_DEV_XPRAM=m +CONFIG_DASD=m +CONFIG_DASD_PROFILE=y +CONFIG_DASD_ECKD=m +CONFIG_DASD_FBA=m +CONFIG_DASD_DIAG=m +CONFIG_DASD_EER=y + +# +# S/390 character device drivers +# +CONFIG_TN3270=y +CONFIG_TN3270_CONSOLE=y +CONFIG_TN3215=y +CONFIG_TN3215_CONSOLE=y +CONFIG_CCW_CONSOLE=y +CONFIG_SCLP_TTY=y +CONFIG_SCLP_CONSOLE=y +CONFIG_SCLP_VT220_TTY=y +CONFIG_SCLP_VT220_CONSOLE=y +CONFIG_SCLP_CPI=m +CONFIG_SCLP_ASYNC=m +CONFIG_S390_TAPE=m +CONFIG_S390_TAPE_3590=m + +CONFIG_APPLDATA_BASE=y +CONFIG_APPLDATA_MEM=m +CONFIG_APPLDATA_OS=m +CONFIG_APPLDATA_NET_SUM=m +CONFIG_TN3270_TTY=y +CONFIG_TN3270_FS=m + + +# +# S/390 tape interface support +# +CONFIG_S390_TAPE_BLOCK=y + +# +# S/390 tape hardware support +# +CONFIG_S390_TAPE_34XX=m + +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Token Ring devices +# +CONFIG_TR=y +CONFIG_NETCONSOLE=m + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# S/390 network device drivers +# +CONFIG_LCS=m +CONFIG_CTC=m +CONFIG_IUCV=m +CONFIG_QETH=m +CONFIG_QETH_IPV6=y +CONFIG_CCWGROUP=m + +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_B44 is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_OSF_PARTITION is not set +CONFIG_IBM_PARTITION=y +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SGI_PARTITION is not set +# CONFIG_SUN_PARTITION is not set + + +# +# S390 crypto hw +# +CONFIG_CRYPTO_SHA1_S390=m +CONFIG_CRYPTO_SHA256_S390=m +CONFIG_CRYPTO_DES_S390=m +CONFIG_CRYPTO_AES_S390=m + +# +# Kernel hacking +# + +# +# S390 specific stack options; needs gcc 3.5 so off for now +# +CONFIG_PACK_STACK=y +CONFIG_CHECK_STACK=y +# CONFIG_WARN_STACK is not set +# CONFIG_SMALL_STACK is not set + +CONFIG_ZVM_WATCHDOG=m +CONFIG_VMLOGRDR=m +CONFIG_MONREADER=m + +CONFIG_VIRT_CPU_ACCOUNTING=y + +# CONFIG_CLAW is not set + +# CONFIG_ATMEL is not set + +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MII is not set + + +CONFIG_STACK_GUARD=256 +CONFIG_CMM_IUCV=y + +# CONFIG_DETECT_SOFTLOCKUP is not set + +CONFIG_S390_HYPFS_FS=y + +CONFIG_MONWRITER=m +CONFIG_ZCRYPT=m +CONFIG_ZCRYPT_MONOLITHIC=y + +CONFIG_S390_EXEC_PROTECT=y +CONFIG_AFIUCV=m +CONFIG_S390_PRNG=m + +CONFIG_S390_VMUR=m + +# CONFIG_THERMAL is not set + +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_CTCM=m +CONFIG_QETH_L2=m +CONFIG_QETH_L3=m +CONFIG_CRYPTO_SHA512_S390=m +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=m +CONFIG_S390_GUEST=y + + +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_CHSC_SCH=m + +# drivers/isdn/hardware/mISDN/hfcmulti.c:5255:2: error: #error "not running on big endian machines now" +# CONFIG_MISDN_HFCMULTI is not set + +CONFIG_HVC_IUCV=y + +CONFIG_RCU_FANOUT=64 + +CONFIG_SECCOMP=y + +CONFIG_PM=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="/dev/jokes" + +CONFIG_PERF_COUNTERS=y +CONFIG_PERF_EVENTS=y +CONFIG_EVENT_PROFILE=y + +CONFIG_SMSGIUCV_EVENT=m + +# CONFIG_PREEMPT_TRACER is not set + +CONFIG_VMCP=y diff --git a/config-sparc64-generic b/config-sparc64-generic new file mode 100644 index 000000000..1a2cc5cdb --- /dev/null +++ b/config-sparc64-generic @@ -0,0 +1,208 @@ +CONFIG_SMP=y +CONFIG_SPARC=y +CONFIG_SPARC64=y +CONFIG_SECCOMP=y +CONFIG_HZ_100=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=100 + +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=m +CONFIG_CPU_FREQ_DEBUG=y +# CONFIG_CPU_FREQ_STAT is not set +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_US3_FREQ=m +CONFIG_US2E_FREQ=m + +CONFIG_SUN_LDOMS=y +CONFIG_SCHED_SMT=y +CONFIG_SCHED_MC=y +CONFIG_64BIT=y +# CONFIG_BBC_I2C is not set +CONFIG_HUGETLB_PAGE_SIZE_4MB=y +# CONFIG_HUGETLB_PAGE_SIZE_512K is not set +# CONFIG_HUGETLB_PAGE_SIZE_64K is not set +CONFIG_NR_CPUS=256 +CONFIG_US3_FREQ=m +CONFIG_US2E_FREQ=m +CONFIG_SUN_OPENPROMFS=m +CONFIG_COMPAT=y +CONFIG_UID16=y +CONFIG_BINFMT_ELF32=y +CONFIG_ENVCTRL=m +CONFIG_DISPLAY7SEG=m +CONFIG_WATCHDOG_CP1XXX=m +CONFIG_WATCHDOG_RIO=m +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_PARPORT is not set +# CONFIG_BLK_DEV_FD is not set +# CONFIG_LIRC_PARALLEL is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_SIMTEC is not set +CONFIG_I2C_ALI1535=m +# CONFIG_VGASTATE is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BW2 is not set +CONFIG_FB_CG3=y +CONFIG_FB_CG6=y +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +CONFIG_FB_ATY=y +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +CONFIG_FB_SBUS=y +CONFIG_FB_FFB=y +# CONFIG_FB_TCX is not set +# CONFIG_FB_CG14 is not set +CONFIG_FB_PM2=y +CONFIG_FB_P9100=y +# CONFIG_FB_LEO is not set +CONFIG_FB_XVR500=y +CONFIG_FB_XVR2500=y +# CONFIG_VGASTATE is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_KYRO is not set +# CONFIG_AGP is not set +# CONFIG_DRM_NOUVEAU is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_FONTS=y +# CONFIG_FONT_8x8 is not set +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_10x18 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +CONFIG_FONT_SUN8x16=y +CONFIG_FONT_SUN12x22=y +# CONFIG_LOGO_LINUX_CLUT224 is not set +# CONFIG_SERIAL_8250 is not set +CONFIG_SERIAL_SUNZILOG=y +CONFIG_SERIAL_SUNZILOG_CONSOLE=y +CONFIG_SERIAL_SUNSU=y +CONFIG_SERIAL_SUNSU_CONSOLE=y +CONFIG_SERIAL_SUNSAB=y +CONFIG_SERIAL_SUNSAB_CONSOLE=y +CONFIG_SERIAL_SUNHV=y +CONFIG_SUN_OPENPROMIO=y +CONFIG_OBP_FLASH=m +# CONFIG_SERIO_SERPORT is not set +CONFIG_BLK_DEV_FD=y +CONFIG_SUNVDC=m +CONFIG_SUNVNET=m +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +CONFIG_SCSI_QLOGICPTI=m +CONFIG_SCSI_SUNESP=m +CONFIG_SUNLANCE=m +CONFIG_SUNBMAC=m +CONFIG_SUNQE=m +# CONFIG_DM9102 is not set +# CONFIG_HAMACHI is not set +# CONFIG_R8169 is not set +CONFIG_ATM_FORE200E_USE_TASKLET=y +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E_TX_RETRY=16 +# CONFIG_DRM_TDFX is not set +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_SUNKBD=y +# CONFIG_INPUT_PCSPKR is not set +CONFIG_INPUT_SPARCSPKR=m +# CONFIG_SOUND_PRIME is not set +# CONFIG_SND_SUN_AMD7930 is not set +CONFIG_SND_SUN_CS4231=m +# CONFIG_SND_SUN_DBRI is not set +CONFIG_PARPORT_SUNBPP=m +CONFIG_LOGO_SUN_CLUT224=y +CONFIG_MTD_SUN_UFLASH=m +CONFIG_MYRI_SBUS=m +# CONFIG_SGI_IOC4 is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_IEEE1394_SBP2 is not set +# CONFIG_USB_NET2280 is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_DCFLUSH is not set +# CONFIG_DEBUG_BOOTMEM is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_LOCKDEP is not set +# CONFIG_STACK_DEBUG is not set + +CONFIG_SPARSEMEM_VMEMMAP=y + +# CONFIG_THERMAL is not set + +CONFIG_FRAME_WARN=2048 + +CONFIG_NUMA=y + +CONFIG_SND_SPARC=y + +CONFIG_HW_RANDOM_N2RNG=m + +# drivers/isdn/hardware/mISDN/hfcmulti.c:5255:2: error: #error "not running on big endian machines now" +# CONFIG_MISDN_HFCMULTI is not set + +CONFIG_US3_MC=y +CONFIG_SENSORS_ULTRA45=m +CONFIG_LEDS_SUNFIRE=m +CONFIG_TADPOLE_TS102_UCTRL=m + +CONFIG_RCU_FANOUT=64 + +CONFIG_LIRC_ENE0100=m +# CONFIG_BATTERY_DS2782 is not set +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SN9C20X_EVDEV=y +CONFIG_LSM_MMAP_MIN_ADDR=65536 + +CONFIG_PERF_COUNTERS=y +CONFIG_PERF_EVENTS=y +CONFIG_EVENT_PROFILE=y + +CONFIG_EARLYFB=y +CONFIG_SERIAL_GRLIB_GAISLER_APBUART=m + +CONFIG_GRETH=m +CONFIG_FB_XVR1000=y + +CONFIG_CRYPTO_DEV_NIAGARA2=m + +# Bellow is changes made to get the kernel building on sparc again, they need to have upstream fixes +# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_INFINIBAND is not set diff --git a/config-x86-generic b/config-x86-generic new file mode 100644 index 000000000..65e788a08 --- /dev/null +++ b/config-x86-generic @@ -0,0 +1,496 @@ +CONFIG_UID16=y +# CONFIG_64BIT is not set +# CONFIG_KERNEL_LZMA is not set + +# +# Processor type and features +# +# +# Enable summit and co via the generic arch +# +CONFIG_X86_EXTENDED_PLATFORM=y +CONFIG_X86_32_NON_STANDARD=y + +# CONFIG_X86_ELAN is not set +# CONFIG_X86_NUMAQ is not set +# CONFIG_X86_SUMMIT is not set +CONFIG_X86_BIGSMP=y +# CONFIG_X86_VISWS is not set +# CONFIG_X86_RDC321X is not set +# CONFIG_X86_ES7000 is not set +# CONFIG_M386 is not set +# CONFIG_M486 is not set +# CONFIG_M586 is not set +# CONFIG_M586TSC is not set +# CONFIG_M586MMX is not set +CONFIG_M686=y +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPENTIUM4 is not set +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +# CONFIG_MCRUSOE is not set +# CONFIG_MWINCHIPC6 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MCYRIXIII is not set +# CONFIG_MVIAC3_2 is not set +CONFIG_SMP=y +CONFIG_NR_CPUS=64 +CONFIG_X86_GENERIC=y +# CONFIG_X86_PPRO_FENCE is not set +CONFIG_HPET=y +CONFIG_HPET_TIMER=y +# CONFIG_HPET_MMAP is not set +CONFIG_X86_MCE=y +CONFIG_TOSHIBA=m +CONFIG_I8K=m +CONFIG_SONYPI=m +CONFIG_SONYPI_COMPAT=y +CONFIG_MICROCODE=m +CONFIG_X86_MSR=y +CONFIG_X86_CPUID=y +CONFIG_EDD=m +# CONFIG_EDD_OFF is not set +# CONFIG_NUMA is not set + +# CONFIG_NOHIGHMEM is not set +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y + +# CONFIG_MATH_EMULATION is not set +CONFIG_MTRR=y +CONFIG_X86_PAT=y +CONFIG_X86_PM_TIMER=y + +CONFIG_EFI=y +CONFIG_EFI_VARS=y +CONFIG_EFI_PCDP=y +CONFIG_FB_EFI=y +# CONFIG_FB_N411 is not set + +CONFIG_DMAR=y +CONFIG_DMAR_BROKEN_GFX_WA=y +CONFIG_DMAR_FLOPPY_WA=y +CONFIG_DMAR_DEFAULT_ON=y + +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_LX=y +CONFIG_FB_GEODE_GX=y +# CONFIG_FB_GEODE_GX1 is not set + +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOMMCONFIG is not set +CONFIG_PCI_GOANY=y + +# +# x86 specific drivers +# +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_ADVANSYS=m + +CONFIG_CC_STACKPROTECTOR=y + +CONFIG_SECCOMP=y + +CONFIG_CAPI_EICON=y + +# I2O enabled only for 32-bit x86, disabled for PAE kernel +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_SCSI=m +CONFIG_I2O_PROC=m +CONFIG_I2O_CONFIG=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_BUS=m + +# +# APM (Advanced Power Management) BIOS Support +# +CONFIG_APM=y +# CONFIG_APM_IGNORE_USER_SUSPEND is not set +# CONFIG_APM_DO_ENABLE is not set +CONFIG_APM_CPU_IDLE=y +# CONFIG_APM_DISPLAY_BLANK is not set +# CONFIG_APM_ALLOW_INTS is not set + +# +# Kernel debugging +# +CONFIG_X86_MPPARSE=y + +CONFIG_ACPI=y +CONFIG_ACPI_AC=y +# CONFIG_ACPI_ASUS is not set +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_SYSFS_POWER=y +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BLACKLIST_YEAR=1999 +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_FAN=y +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_SBS=m +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_THERMAL=y +CONFIG_TOPSTAR_LAPTOP=m +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_VIDEO=m +# CONFIG_ACPI_PROC_EVENT is not set +CONFIG_PNPACPI=y +CONFIG_ACPI_POWER_METER=m +CONFIG_ACPI_PROCESSOR_AGGREGATOR=m +CONFIG_ACPI_HED=m +CONFIG_ACPI_APEI=y +CONFIG_ACPI_APEI_GHES=m +# CONFIG_ACPI_APEI_EINJ is not set + +# +# CPUFreq processor drivers +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEBUG=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y + +CONFIG_X86_ACPI_CPUFREQ=m +CONFIG_X86_PCC_CPUFREQ=m +# CONFIG_X86_POWERNOW_K6 is not set +CONFIG_X86_POWERNOW_K7=y +CONFIG_X86_POWERNOW_K8=m +# CONFIG_X86_GX_SUSPMOD is not set +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +CONFIG_X86_SPEEDSTEP_ICH=y +CONFIG_X86_SPEEDSTEP_SMI=y +CONFIG_X86_SPEEDSTEP_LIB=y +# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set +CONFIG_X86_P4_CLOCKMOD=m +CONFIG_X86_LONGRUN=y +# CONFIG_X86_LONGHAUL is not set +# CONFIG_X86_CPUFREQ_NFORCE2 is not set +# e_powersaver is dangerous +# CONFIG_X86_E_POWERSAVER is not set + +CONFIG_X86_HT=y +CONFIG_X86_TRAMPOLINE=y + +# +# various x86 specific drivers +# +CONFIG_NVRAM=y +CONFIG_IBM_ASM=m +CONFIG_CRYPTO_AES_586=m +CONFIG_CRYPTO_TWOFISH_586=m +CONFIG_CRYPTO_DEV_PADLOCK=m +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m + +CONFIG_GENERIC_ISA_DMA=y +CONFIG_SCHED_SMT=y +CONFIG_SUSPEND=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="" + +CONFIG_DEBUG_RODATA=y +CONFIG_DEBUG_STACKOVERFLOW=y +# CONFIG_4KSTACKS is not set +CONFIG_DEBUG_NMI_TIMEOUT=5 + +CONFIG_PCI_DIRECT=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_BIOS=y + +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_COMPAQ=m +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_HOTPLUG_PCI_IBM=m +# CONFIG_HOTPLUG_PCI_CPCI is not set +# SHPC has half-arsed PCI probing, which makes it load on too many systems +# CONFIG_HOTPLUG_PCI_SHPC is not set +CONFIG_PM=y + +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y + +CONFIG_BLK_DEV_AMD74XX=y + +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_NFORCE2_S4985=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m + +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m + +CONFIG_SCx200_ACB=m + +# CONFIG_X86_REBOOTFIXUPS is not set + +CONFIG_DELL_RBU=m +CONFIG_DCDBAS=m + +CONFIG_GPIO_SCH=m +CONFIG_PC8736x_GPIO=m +# CONFIG_NSC_GPIO is not set +CONFIG_CS5535_GPIO=m + +CONFIG_EDAC=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_AMD76X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_E752X=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_I5000=m +CONFIG_EDAC_I5100=m +CONFIG_EDAC_I5400=m +CONFIG_EDAC_R82600=m +CONFIG_EDAC_AMD8131=m +CONFIG_EDAC_AMD8111=m +CONFIG_EDAC_I7CORE=m + +CONFIG_SCHED_MC=y + +CONFIG_SND_ISA=y +CONFIG_SND_ES18XX=m + +CONFIG_TCG_INFINEON=m + +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_VIA=m + + +# CONFIG_COMPAT_VDSO is not set + +# CONFIG_SGI_IOC4 is not set + +CONFIG_X86_PLATFORM_DEVICES=y +CONFIG_ASUS_LAPTOP=m +CONFIG_COMPAL_LAPTOP=m +CONFIG_EEEPC_LAPTOP=m +CONFIG_EEEPC_WMI=m +CONFIG_FUJITSU_LAPTOP=m +# CONFIG_FUJITSU_LAPTOP_DEBUG is not set +CONFIG_MSI_LAPTOP=m +CONFIG_SONY_LAPTOP=m +CONFIG_DELL_LAPTOP=m +CONFIG_ACPI_WMI=m +CONFIG_ACER_WMI=m +CONFIG_ACERHDF=m +CONFIG_TC1100_WMI=m +CONFIG_HP_WMI=m +# CONFIG_INTEL_SCU_IPC is not set +CONFIG_DELL_WMI=m + +# CONFIG_TOUCHSCREEN_INTEL_MID is not set + +# CONFIG_SMSC37B787_WDT is not set +CONFIG_W83697HF_WDT=m +CONFIG_IB700_WDT=m + +CONFIG_RELOCATABLE=y +CONFIG_PHYSICAL_ALIGN=0x400000 +CONFIG_PHYSICAL_START=0x400000 +CONFIG_CRASH_DUMP=y +# CONFIG_KEXEC_JUMP is not set +CONFIG_PROC_VMCORE=y +CONFIG_CRASH=m + +CONFIG_CRYPTO_DEV_GEODE=m + +CONFIG_VIDEO_CAFE_CCIC=m + +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=m +CONFIG_KVM_INTEL=m +CONFIG_KVM_AMD=m +CONFIG_LGUEST=m + +CONFIG_PARAVIRT_GUEST=y +CONFIG_PARAVIRT=y +# CONFIG_PARAVIRT_DEBUG is not set + +# PARAVIRT_SPINLOCKS has a 5% perf hit +# CONFIG_PARAVIRT_SPINLOCKS is not set +CONFIG_KVM_CLOCK=y +CONFIG_KVM_GUEST=y +CONFIG_LGUEST_GUEST=y +CONFIG_VMI=y + +CONFIG_XEN=y +CONFIG_XEN_MAX_DOMAIN_MEMORY=8 +CONFIG_XEN_BALLOON=y +CONFIG_XEN_SCRUB_PAGES=y +CONFIG_XEN_SAVE_RESTORE=y +CONFIG_HVC_XEN=y +CONFIG_XEN_FBDEV_FRONTEND=y +CONFIG_XEN_KBDDEV_FRONTEND=y +CONFIG_XEN_BLKDEV_FRONTEND=m +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XENFS=m +CONFIG_XEN_COMPAT_XENFS=y + +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_NAND_CAFE=m + +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_CPU_IDLE=y +# CONFIG_CPU_IDLE_GOV_LADDER is not set +CONFIG_CPU_IDLE_GOV_MENU=y + +CONFIG_THINKPAD_ACPI=m +# CONFIG_THINKPAD_ACPI_DEBUG is not set +# CONFIG_THINKPAD_ACPI_DEBUGFACILITIES is not set +CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y +CONFIG_THINKPAD_ACPI_VIDEO=y +CONFIG_THINKPAD_ACPI_ALSA_SUPPORT=y +# CONFIG_THINKPAD_ACPI_UNSAFE_LEDS is not set + +CONFIG_MACINTOSH_DRIVERS=y + +CONFIG_DMIID=y +CONFIG_ISCSI_IBFT_FIND=y +CONFIG_ISCSI_IBFT=m + +CONFIG_DMADEVICES=y +CONFIG_INTEL_IOATDMA=m + +CONFIG_SENSORS_I5K_AMB=m + +# CONFIG_CPA_DEBUG is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set + +CONFIG_HP_WATCHDOG=m + +CONFIG_OLPC=y +CONFIG_BATTERY_OLPC=y +CONFIG_MOUSE_PS2_OLPC=y + +CONFIG_STRICT_DEVMEM=y + +# CONFIG_NO_BOOTMEM is not set + +# CONFIG_MEMTEST is not set +# CONFIG_MAXSMP is not set +CONFIG_MTRR_SANITIZER=y +CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=1 +CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 +CONFIG_SYSPROF_TRACER=y + +# CONFIG_X86_VERBOSE_BOOTUP is not set +# CONFIG_MMIOTRACE_TEST is not set + +# CONFIG_DEBUG_PER_CPU_MAPS is not set + +CONFIG_HP_ILO=m + +CONFIG_BACKLIGHT_MBP_NVIDIA=m + +CONFIG_OPROFILE_IBS=y +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_AMD=y + +# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set +CONFIG_X86_RESERVE_LOW_64K=y + +# CONFIG_CMDLINE_BOOL is not set + +CONFIG_PANASONIC_LAPTOP=m + +CONFIG_XEN_DEBUG_FS=y +CONFIG_X86_PTRACE_BTS=y + +CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y + +CONFIG_POWER_TRACER=y +CONFIG_HW_BRANCH_TRACER=y + +# CONFIG_SPARSE_IRQ is not set + +CONFIG_RCU_FANOUT=32 + +# CONFIG_IOMMU_STRESS is not set + +CONFIG_PERF_COUNTERS=y +CONFIG_PERF_EVENTS=y +CONFIG_EVENT_PROFILE=y + +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MCE_AMD=y +# CONFIG_X86_ANCIENT_MCE is not set +# CONFIG_X86_MCE_INJECT is not set + +# CONFIG_X86_MRST is not set +CONFIG_SFI=y + +CONFIG_INPUT_WINBOND_CIR=m +CONFIG_I2C_SCMI=m +CONFIG_SBC_FITPC2_WATCHDOG=m +CONFIG_EDAC_I3200=m +CONFIG_EDAC_DECODE_MCE=m + +CONFIG_GPIO_LANGWELL=y + +# CONFIG_INTEL_TXT is not set + +CONFIG_CS5535_MFGPT=m +CONFIG_GEODE_WDT=m +CONFIG_CS5535_CLOCK_EVENT_SRC=m + +CONFIG_LEDS_INTEL_SS4200=m + +CONFIG_X86_DECODER_SELFTEST=y + +CONFIG_ACPI_CMPC=m +CONFIG_MSI_WMI=m +CONFIG_TOSHIBA_BT_RFKILL=m +# CONFIG_SAMSUNG_LAPTOP is not set + +CONFIG_VGA_SWITCHEROO=y +CONFIG_LPC_SCH=m + +CONFIG_INTEL_IDLE=y + +CONFIG_PCI_CNB20LE_QUIRK=y + +CONFIG_IRQ_TIME_ACCOUNTING=y diff --git a/config-x86_64-generic b/config-x86_64-generic new file mode 100644 index 000000000..4c4924ccb --- /dev/null +++ b/config-x86_64-generic @@ -0,0 +1,413 @@ +CONFIG_64BIT=y +CONFIG_UID16=y +# CONFIG_KERNEL_LZMA is not set + +# CONFIG_MK8 is not set +# CONFIG_MPSC is not set +CONFIG_GENERIC_CPU=y +CONFIG_X86_EXTENDED_PLATFORM=y +# CONFIG_X86_VSMP is not set +# CONFIG_X86_UV is not set +CONFIG_X86_MSR=y +CONFIG_X86_CPUID=y +CONFIG_MTRR=y +CONFIG_NUMA=y +CONFIG_K8_NUMA=y +CONFIG_X86_64_ACPI_NUMA=y +# CONFIG_NUMA_EMU is not set +CONFIG_NR_CPUS=256 +CONFIG_X86_POWERNOW_K8=m +CONFIG_X86_P4_CLOCKMOD=m +CONFIG_IA32_EMULATION=y +# CONFIG_IA32_AOUT is not set +# CONFIG_IOMMU_DEBUG is not set +CONFIG_DEBUG_RODATA=y +CONFIG_MICROCODE=m +CONFIG_SWIOTLB=y +CONFIG_CALGARY_IOMMU=y +CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y +CONFIG_X86_PM_TIMER=y +CONFIG_EDD=m +# CONFIG_EDD_OFF is not set +CONFIG_PCI_BIOS=y +CONFIG_PCI_MMCONFIG=y +CONFIG_DMAR=y +CONFIG_DMAR_BROKEN_GFX_WA=y +CONFIG_DMAR_FLOPPY_WA=y +CONFIG_DMAR_DEFAULT_ON=y + +CONFIG_KEXEC_JUMP=y + +CONFIG_EFI=y +CONFIG_EFI_VARS=y +CONFIG_EFI_PCDP=y +CONFIG_FB_EFI=y + +CONFIG_SECCOMP=y + +CONFIG_CAPI_EICON=y + +CONFIG_GENERIC_ISA_DMA=y +CONFIG_SCHED_SMT=y +CONFIG_SUSPEND=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="" + +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_DEBUG=y +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +CONFIG_X86_PCC_CPUFREQ=m +CONFIG_X86_ACPI_CPUFREQ=m +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y + +CONFIG_ACPI=y +CONFIG_ACPI_AC=y +# CONFIG_ACPI_ASUS is not set +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_SYSFS_POWER=y +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BLACKLIST_YEAR=0 +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_FAN=y +CONFIG_ACPI_HOTPLUG_MEMORY=m +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_SBS=m +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_POWER=y +CONFIG_ACPI_VIDEO=m +# CONFIG_ACPI_PROC_EVENT is not set +CONFIG_ACPI_POWER_METER=m +CONFIG_ACPI_PROCESSOR_AGGREGATOR=m +CONFIG_ACPI_HED=m +CONFIG_ACPI_APEI=y +CONFIG_ACPI_APEI_GHES=m +# CONFIG_ACPI_APEI_EINJ is not set + +CONFIG_X86_PLATFORM_DEVICES=y +CONFIG_ASUS_LAPTOP=m +CONFIG_COMPAL_LAPTOP=m +CONFIG_FUJITSU_LAPTOP=m +# CONFIG_FUJITSU_LAPTOP_DEBUG is not set +CONFIG_MSI_LAPTOP=m +CONFIG_SONY_LAPTOP=m +CONFIG_SONYPI_COMPAT=y +CONFIG_EEEPC_LAPTOP=m +CONFIG_EEEPC_WMI=m +CONFIG_DELL_LAPTOP=m +CONFIG_ACPI_WMI=m +CONFIG_ACER_WMI=m +CONFIG_ACERHDF=m +CONFIG_HP_WMI=m +CONFIG_DELL_WMI=m +# CONFIG_INTEL_SCU_IPC is not set + +# CONFIG_TOUCHSCREEN_INTEL_MID is not set + +CONFIG_THINKPAD_ACPI=m +# CONFIG_THINKPAD_ACPI_DEBUG is not set +# CONFIG_THINKPAD_ACPI_DEBUGFACILITIES is not set +CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y +CONFIG_THINKPAD_ACPI_VIDEO=y +CONFIG_THINKPAD_ACPI_ALSA_SUPPORT=y +# CONFIG_THINKPAD_ACPI_UNSAFE_LEDS is not set + +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_COMPAQ=m +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_HOTPLUG_PCI_IBM=m +# CONFIG_HOTPLUG_PCI_CPCI is not set +# SHPC has half-arsed PCI probing, which makes it load on too many systems +CONFIG_HOTPLUG_PCI_SHPC=m + +CONFIG_HPET=y +# CONFIG_HPET_MMAP is not set +CONFIG_PM=y + +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y + +CONFIG_PNP=y +CONFIG_PNPACPI=y + +CONFIG_BLK_DEV_AMD74XX=y +CONFIG_CRYPTO_DEV_PADLOCK=m +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m +# CONFIG_CRYPTO_AES is not set +CONFIG_CRYPTO_AES_X86_64=m +# CONFIG_CRYPTO_TWOFISH is not set +CONFIG_CRYPTO_TWOFISH_X86_64=m +# CONFIG_CRYPTO_SALSA20 is not set +CONFIG_CRYPTO_SALSA20_X86_64=m +CONFIG_CRYPTO_AES_NI_INTEL=m + +CONFIG_X86_MCE=y +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MCE_AMD=y + +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_NFORCE2_S4985=m +CONFIG_I2C_PIIX4=m +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set + +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m + +CONFIG_DELL_RBU=m +CONFIG_DCDBAS=m + +CONFIG_NVRAM=y + +CONFIG_EDAC=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_AMD76X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_E752X=m +CONFIG_EDAC_I5000=m +CONFIG_EDAC_I5100=m +CONFIG_EDAC_I5400=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_R82600=m +CONFIG_EDAC_AMD8131=m +CONFIG_EDAC_AMD8111=m +CONFIG_EDAC_AMD64=m +# CONFIG_EDAC_AMD64_ERROR_INJECTION is not set +CONFIG_EDAC_DECODE_MCE=m +CONFIG_EDAC_I7CORE=m + +CONFIG_SCHED_MC=y + +CONFIG_TCG_INFINEON=m + +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_VIA=m + +# CONFIG_HW_RANDOM_GEODE is not set + + +CONFIG_DEBUG_STACKOVERFLOW=y +CONFIG_DEBUG_NMI_TIMEOUT=5 + +CONFIG_GPIO_SCH=m +# CONFIG_PC8736x_GPIO is not set + +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTREMOVE=y + +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_CS5535 is not set + +CONFIG_CC_STACKPROTECTOR=y + +CONFIG_SGI_IOC4=m +CONFIG_SGI_XP=m +CONFIG_SGI_GRU=m +# CONFIG_SGI_GRU_DEBUG is not set + +# CONFIG_SMSC37B787_WDT is not set +CONFIG_W83697HF_WDT=m + +# CONFIG_VIDEO_CAFE_CCIC is not set + +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_CK804XROM=m + +CONFIG_RELOCATABLE=y +CONFIG_MACINTOSH_DRIVERS=y + +CONFIG_CRASH_DUMP=y +CONFIG_PHYSICAL_START=0x1000000 +CONFIG_PROC_VMCORE=y +CONFIG_CRASH=m + +CONFIG_DMIID=y +CONFIG_ISCSI_IBFT_FIND=y +CONFIG_ISCSI_IBFT=m + + +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_CPU_IDLE=y +# CONFIG_CPU_IDLE_GOV_LADDER is not set +CONFIG_CPU_IDLE_GOV_MENU=y + +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=m +CONFIG_KVM_INTEL=m +CONFIG_KVM_AMD=m + +CONFIG_PARAVIRT_GUEST=y +CONFIG_PARAVIRT=y +# CONFIG_PARAVIRT_DEBUG is not set +# PARAVIRT_SPINLOCKS has a 5% perf hit +# CONFIG_PARAVIRT_SPINLOCKS is not set +CONFIG_KVM_CLOCK=y +CONFIG_KVM_GUEST=y + +CONFIG_XEN=y +CONFIG_XEN_MAX_DOMAIN_MEMORY=32 +CONFIG_XEN_BALLOON=y +CONFIG_XEN_SCRUB_PAGES=y +CONFIG_XEN_SAVE_RESTORE=y +CONFIG_HVC_XEN=y +CONFIG_XEN_FBDEV_FRONTEND=y +CONFIG_XEN_KBDDEV_FRONTEND=y +CONFIG_XEN_BLKDEV_FRONTEND=m +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XENFS=m +CONFIG_XEN_COMPAT_XENFS=y +CONFIG_XEN_DEV_EVTCHN=m +CONFIG_XEN_SYS_HYPERVISOR=y + +CONFIG_DMADEVICES=y +CONFIG_INTEL_IOATDMA=m + +CONFIG_SENSORS_I5K_AMB=m + +# CONFIG_COMPAT_VDSO is not set +CONFIG_PROVIDE_OHCI1394_DMA_INIT=y +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_CPA_DEBUG is not set + +CONFIG_HP_WATCHDOG=m + +CONFIG_FRAME_WARN=2048 + +CONFIG_NODES_SHIFT=9 +CONFIG_X86_PAT=y +# FIXME: These should be 32bit only +# CONFIG_FB_N411 is not set +CONFIG_STRICT_DEVMEM=y + +CONFIG_DIRECT_GBPAGES=y + +# CONFIG_NO_BOOTMEM is not set + +# CONFIG_MEMTEST is not set +CONFIG_AMD_IOMMU=y +CONFIG_AMD_IOMMU_STATS=y +# CONFIG_MAXSMP is not set +CONFIG_MTRR_SANITIZER=y +CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=1 +CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 +CONFIG_SYSPROF_TRACER=y +# CONFIG_X86_VERBOSE_BOOTUP is not set +# CONFIG_MMIOTRACE_TEST is not set + +CONFIG_X86_MPPARSE=y + +CONFIG_BACKLIGHT_MBP_NVIDIA=m + +CONFIG_OPROFILE_IBS=y +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_AMD=y + +# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set +CONFIG_X86_RESERVE_LOW_64K=y + +# CONFIG_CMDLINE_BOOL is not set + +CONFIG_PANASONIC_LAPTOP=m + +CONFIG_XEN_DEBUG_FS=y +CONFIG_X86_PTRACE_BTS=y + +CONFIG_I7300_IDLE=m +CONFIG_INTR_REMAP=y + +CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y + +CONFIG_POWER_TRACER=y +CONFIG_HW_BRANCH_TRACER=y + +CONFIG_X86_X2APIC=y +CONFIG_SPARSE_IRQ=y + +CONFIG_RCU_FANOUT=64 + +# CONFIG_IOMMU_STRESS is not set + +CONFIG_PERF_COUNTERS=y +CONFIG_PERF_EVENTS=y +CONFIG_EVENT_PROFILE=y + +# CONFIG_X86_MCE_INJECT is not set + +CONFIG_SFI=y +CONFIG_INPUT_WINBOND_CIR=m +CONFIG_I2C_SCMI=m +CONFIG_SBC_FITPC2_WATCHDOG=m +CONFIG_EDAC_I3200=m +CONFIG_TOPSTAR_LAPTOP=m +CONFIG_INTEL_TXT=y +CONFIG_GPIO_LANGWELL=y + +CONFIG_FUNCTION_GRAPH_TRACER=y + +CONFIG_ACPI_CMPC=m +CONFIG_MSI_WMI=m +CONFIG_TOSHIBA_BT_RFKILL=m +# CONFIG_SAMSUNG_LAPTOP is not set + +CONFIG_CS5535_MFGPT=m +CONFIG_GEODE_WDT=m +CONFIG_CS5535_CLOCK_EVENT_SRC=m + +CONFIG_X86_DECODER_SELFTEST=y + +CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m + +CONFIG_VGA_SWITCHEROO=y +CONFIG_LPC_SCH=m + +CONFIG_INTEL_IDLE=y +CONFIG_I7300_IDLE=m + +CONFIG_PCI_CNB20LE_QUIRK=y + +CONFIG_HP_ILO=m + +CONFIG_IRQ_TIME_ACCOUNTING=y diff --git a/create-sys-fs-cgroup-to-mount-cgroupfs-on.patch b/create-sys-fs-cgroup-to-mount-cgroupfs-on.patch new file mode 100644 index 000000000..e1788a316 --- /dev/null +++ b/create-sys-fs-cgroup-to-mount-cgroupfs-on.patch @@ -0,0 +1,56 @@ +From: Greg KH +Date: Thu, 5 Aug 2010 20:53:35 +0000 (-0700) +Subject: cgroupfs: create /sys/fs/cgroup to mount cgroupfs on +X-Git-Tag: v2.6.36-rc1~521^2~7 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=676db4af043014e852f67ba0349dae0071bd11f3 + +cgroupfs: create /sys/fs/cgroup to mount cgroupfs on + +We really shouldn't be asking userspace to create new root filesystems. +So follow along with all of the other in-kernel filesystems, and provide +a mount point in sysfs. + +For cgroupfs, this should be in /sys/fs/cgroup/ This change provides +that mount point when the cgroup filesystem is registered in the kernel. + +Acked-by: Paul Menage +Acked-by: Dhaval Giani +Cc: Li Zefan +Cc: Lennart Poettering +Cc: Kay Sievers +Signed-off-by: Greg Kroah-Hartman +--- + +diff --git a/kernel/cgroup.c b/kernel/cgroup.c +index a8ce099..d83cab0 100644 +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -1623,6 +1623,8 @@ static struct file_system_type cgroup_fs_type = { + .kill_sb = cgroup_kill_sb, + }; + ++static struct kobject *cgroup_kobj; ++ + static inline struct cgroup *__d_cgrp(struct dentry *dentry) + { + return dentry->d_fsdata; +@@ -3894,9 +3896,18 @@ int __init cgroup_init(void) + hhead = css_set_hash(init_css_set.subsys); + hlist_add_head(&init_css_set.hlist, hhead); + BUG_ON(!init_root_id(&rootnode)); ++ ++ cgroup_kobj = kobject_create_and_add("cgroup", fs_kobj); ++ if (!cgroup_kobj) { ++ err = -ENOMEM; ++ goto out; ++ } ++ + err = register_filesystem(&cgroup_fs_type); +- if (err < 0) ++ if (err < 0) { ++ kobject_put(cgroup_kobj); + goto out; ++ } + + proc_create("cgroups", 0, NULL, &proc_cgroupstats_operations); + diff --git a/crypto-Move-md5_transform-to-lib-md5.c.patch b/crypto-Move-md5_transform-to-lib-md5.c.patch new file mode 100644 index 000000000..ef12c3b00 --- /dev/null +++ b/crypto-Move-md5_transform-to-lib-md5.c.patch @@ -0,0 +1,258 @@ +From 44c943562c2e204cddf46db131c53c326b47bd47 Mon Sep 17 00:00:00 2001 +From: "David S. Miller" +Date: Fri, 16 Sep 2011 17:10:29 -0400 +Subject: [PATCH 1/2] crypto: Move md5_transform to lib/md5.c + +We are going to use this for TCP/IP sequence number and fragment ID +generation. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +Backported to 2.6.25.14 by Josh Boyer +--- + crypto/md5.c | 92 +------------------------------------------ + include/linux/cryptohash.h | 5 ++ + lib/Makefile | 2 +- + lib/md5.c | 95 ++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 102 insertions(+), 92 deletions(-) + create mode 100644 lib/md5.c + +diff --git a/crypto/md5.c b/crypto/md5.c +index 30efc7d..7febeaa 100644 +--- a/crypto/md5.c ++++ b/crypto/md5.c +@@ -21,99 +21,9 @@ + #include + #include + #include ++#include + #include + +-#define F1(x, y, z) (z ^ (x & (y ^ z))) +-#define F2(x, y, z) F1(z, x, y) +-#define F3(x, y, z) (x ^ y ^ z) +-#define F4(x, y, z) (y ^ (x | ~z)) +- +-#define MD5STEP(f, w, x, y, z, in, s) \ +- (w += f(x, y, z) + in, w = (w<>(32-s)) + x) +- +-static void md5_transform(u32 *hash, u32 const *in) +-{ +- u32 a, b, c, d; +- +- a = hash[0]; +- b = hash[1]; +- c = hash[2]; +- d = hash[3]; +- +- MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); +- MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); +- MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); +- MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); +- MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); +- MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); +- MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); +- MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); +- MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); +- MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); +- MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); +- MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); +- MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); +- MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); +- MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); +- MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); +- +- MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); +- MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); +- MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); +- MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); +- MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); +- MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); +- MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); +- MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); +- MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); +- MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); +- MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); +- MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); +- MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); +- MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); +- MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); +- MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); +- +- MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); +- MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); +- MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); +- MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); +- MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); +- MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); +- MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); +- MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); +- MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); +- MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); +- MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); +- MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); +- MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); +- MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); +- MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); +- MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); +- +- MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); +- MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); +- MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); +- MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); +- MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); +- MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); +- MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); +- MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); +- MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); +- MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); +- MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); +- MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); +- MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); +- MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); +- MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); +- MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); +- +- hash[0] += a; +- hash[1] += b; +- hash[2] += c; +- hash[3] += d; +-} +- + /* XXX: this stuff can be optimized */ + static inline void le32_to_cpu_array(u32 *buf, unsigned int words) + { +diff --git a/include/linux/cryptohash.h b/include/linux/cryptohash.h +index ec78a4b..d2984fb 100644 +--- a/include/linux/cryptohash.h ++++ b/include/linux/cryptohash.h +@@ -8,6 +8,11 @@ + void sha_init(__u32 *buf); + void sha_transform(__u32 *digest, const char *data, __u32 *W); + ++#define MD5_DIGEST_WORDS 4 ++#define MD5_MESSAGE_BYTES 64 ++ ++void md5_transform(__u32 *hash, __u32 const *in); ++ + __u32 half_md4_transform(__u32 buf[4], __u32 const in[8]); + + #endif +diff --git a/lib/Makefile b/lib/Makefile +index 0bfabba..d07eef3 100644 +--- a/lib/Makefile ++++ b/lib/Makefile +@@ -10,7 +10,7 @@ endif + lib-y := ctype.o string.o vsprintf.o cmdline.o \ + rbtree.o radix-tree.o dump_stack.o \ + idr.o int_sqrt.o extable.o prio_tree.o \ +- sha1.o irq_regs.o reciprocal_div.o argv_split.o \ ++ sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \ + proportions.o prio_heap.o ratelimit.o show_mem.o \ + is_single_threaded.o plist.o decompress.o flex_array.o + +diff --git a/lib/md5.c b/lib/md5.c +new file mode 100644 +index 0000000..c777180 +--- /dev/null ++++ b/lib/md5.c +@@ -0,0 +1,95 @@ ++#include ++#include ++#include ++ ++#define F1(x, y, z) (z ^ (x & (y ^ z))) ++#define F2(x, y, z) F1(z, x, y) ++#define F3(x, y, z) (x ^ y ^ z) ++#define F4(x, y, z) (y ^ (x | ~z)) ++ ++#define MD5STEP(f, w, x, y, z, in, s) \ ++ (w += f(x, y, z) + in, w = (w<>(32-s)) + x) ++ ++void md5_transform(__u32 *hash, __u32 const *in) ++{ ++ u32 a, b, c, d; ++ ++ a = hash[0]; ++ b = hash[1]; ++ c = hash[2]; ++ d = hash[3]; ++ ++ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); ++ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); ++ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); ++ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); ++ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); ++ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); ++ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); ++ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); ++ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); ++ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); ++ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); ++ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); ++ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); ++ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); ++ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); ++ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); ++ ++ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); ++ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); ++ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); ++ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); ++ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); ++ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); ++ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); ++ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); ++ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); ++ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); ++ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); ++ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); ++ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); ++ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); ++ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); ++ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); ++ ++ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); ++ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); ++ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); ++ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); ++ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); ++ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); ++ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); ++ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); ++ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); ++ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); ++ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); ++ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); ++ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); ++ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); ++ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); ++ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); ++ ++ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); ++ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); ++ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); ++ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); ++ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); ++ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); ++ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); ++ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); ++ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); ++ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); ++ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); ++ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); ++ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); ++ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); ++ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); ++ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); ++ ++ hash[0] += a; ++ hash[1] += b; ++ hash[2] += c; ++ hash[3] += d; ++} ++EXPORT_SYMBOL(md5_transform); +-- +1.7.6 + diff --git a/crypto-ghash-Avoid-null-pointer-dereference-if-no-ke.patch b/crypto-ghash-Avoid-null-pointer-dereference-if-no-ke.patch new file mode 100644 index 000000000..8c56d66b2 --- /dev/null +++ b/crypto-ghash-Avoid-null-pointer-dereference-if-no-ke.patch @@ -0,0 +1,105 @@ +From 3e65dd9e26cf5ba791f44c5e15e29d07b84824aa Mon Sep 17 00:00:00 2001 +From: Nick Bowler +Date: Thu, 20 Oct 2011 14:16:55 +0200 +Subject: [PATCH] crypto: ghash - Avoid null pointer dereference if no key is + set + +commit 7ed47b7d142ec99ad6880bbbec51e9f12b3af74c upstream. + +The ghash_update function passes a pointer to gf128mul_4k_lle which will +be NULL if ghash_setkey is not called or if the most recent call to +ghash_setkey failed to allocate memory. This causes an oops. Fix this +up by returning an error code in the null case. + +This is trivially triggered from unprivileged userspace through the +AF_ALG interface by simply writing to the socket without setting a key. + +The ghash_final function has a similar issue, but triggering it requires +a memory allocation failure in ghash_setkey _after_ at least one +successful call to ghash_update. + + BUG: unable to handle kernel NULL pointer dereference at 00000670 + IP: [] gf128mul_4k_lle+0x23/0x60 [gf128mul] + *pde = 00000000 + Oops: 0000 [#1] PREEMPT SMP + Modules linked in: ghash_generic gf128mul algif_hash af_alg nfs lockd nfs_acl sunrpc bridge ipv6 stp llc + + Pid: 1502, comm: hashatron Tainted: G W 3.1.0-rc9-00085-ge9308cf #32 Bochs Bochs + EIP: 0060:[] EFLAGS: 00000202 CPU: 0 + EIP is at gf128mul_4k_lle+0x23/0x60 [gf128mul] + EAX: d69db1f0 EBX: d6b8ddac ECX: 00000004 EDX: 00000000 + ESI: 00000670 EDI: d6b8ddac EBP: d6b8ddc8 ESP: d6b8dda4 + DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 + Process hashatron (pid: 1502, ti=d6b8c000 task=d6810000 task.ti=d6b8c000) + Stack: + 00000000 d69db1f0 00000163 00000000 d6b8ddc8 c101a520 d69db1f0 d52aa000 + 00000ff0 d6b8dde8 d88d310f d6b8a3f8 d52aa000 00001000 d88d502c d6b8ddfc + 00001000 d6b8ddf4 c11676ed d69db1e8 d6b8de24 c11679ad d52aa000 00000000 + Call Trace: + [] ? kmap_atomic_prot+0x37/0xa6 + [] ghash_update+0x85/0xbe [ghash_generic] + [] crypto_shash_update+0x18/0x1b + [] shash_ahash_update+0x22/0x36 + [] shash_async_update+0xb/0xd + [] hash_sendpage+0xba/0xf2 [algif_hash] + [] kernel_sendpage+0x39/0x4e + [] ? 0xd88cdfff + [] sock_sendpage+0x37/0x3e + [] ? kernel_sendpage+0x4e/0x4e + [] pipe_to_sendpage+0x56/0x61 + [] splice_from_pipe_feed+0x58/0xcd + [] ? splice_from_pipe_begin+0x10/0x10 + [] __splice_from_pipe+0x36/0x55 + [] ? splice_from_pipe_begin+0x10/0x10 + [] splice_from_pipe+0x51/0x64 + [] ? default_file_splice_write+0x2c/0x2c + [] generic_splice_sendpage+0x13/0x15 + [] ? splice_from_pipe_begin+0x10/0x10 + [] do_splice_from+0x5d/0x67 + [] sys_splice+0x2bf/0x363 + [] ? sysenter_exit+0xf/0x16 + [] ? trace_hardirqs_on_caller+0x10e/0x13f + [] sysenter_do_call+0x12/0x32 + Code: 83 c4 0c 5b 5e 5f c9 c3 55 b9 04 00 00 00 89 e5 57 8d 7d e4 56 53 8d 5d e4 83 ec 18 89 45 e0 89 55 dc 0f b6 70 0f c1 e6 04 01 d6 a5 be 0f 00 00 00 4e 89 d8 e8 48 ff ff ff 8b 45 e0 89 da 0f + EIP: [] gf128mul_4k_lle+0x23/0x60 [gf128mul] SS:ESP 0068:d6b8dda4 + CR2: 0000000000000670 + ---[ end trace 4eaa2a86a8e2da24 ]--- + note: hashatron[1502] exited with preempt_count 1 + BUG: scheduling while atomic: hashatron/1502/0x10000002 + INFO: lockdep is turned off. + [...] + +Signed-off-by: Nick Bowler +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + crypto/ghash-generic.c | 6 ++++++ + 1 files changed, 6 insertions(+), 0 deletions(-) + +diff --git a/crypto/ghash-generic.c b/crypto/ghash-generic.c +index be44256..7835b8f 100644 +--- a/crypto/ghash-generic.c ++++ b/crypto/ghash-generic.c +@@ -67,6 +67,9 @@ static int ghash_update(struct shash_desc *desc, + struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); + u8 *dst = dctx->buffer; + ++ if (!ctx->gf128) ++ return -ENOKEY; ++ + if (dctx->bytes) { + int n = min(srclen, dctx->bytes); + u8 *pos = dst + (GHASH_BLOCK_SIZE - dctx->bytes); +@@ -119,6 +122,9 @@ static int ghash_final(struct shash_desc *desc, u8 *dst) + struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); + u8 *buf = dctx->buffer; + ++ if (!ctx->gf128) ++ return -ENOKEY; ++ + ghash_flush(ctx, dctx); + memcpy(dst, buf, GHASH_BLOCK_SIZE); + +-- +1.7.6.4 + diff --git a/def_variants.yaml.fedora b/def_variants.yaml.fedora deleted file mode 100644 index 76827545a..000000000 --- a/def_variants.yaml.fedora +++ /dev/null @@ -1,467 +0,0 @@ -packages: - - name: modules-core - depends-on: [] - - name: modules - depends-on: - - modules-core - - name: modules-internal - depends-on: - - modules-core - - modules - - name: modules-extra - depends-on: - - modules-core - - modules - - -rules: - - .*kunit.*: modules-internal - exact_pkg: True - - .*test[^/]*.ko: modules-internal - - - arch/.*: modules-core - - crypto/.*: modules-core - - - drivers/accel/.*: modules-core - - drivers/accessibility/.*: modules-core - - drivers/acpi/video.*: modules - - drivers/acpi/.*: modules-core - - drivers/ata/.*: modules-core - - - drivers/base/regmap/regmap-sdw.*: modules - - drivers/base/.*: modules-core - - drivers/block/floppy.*: modules-extra - - drivers/block/rnbd.*: modules - - drivers/block/.*: modules-core - - drivers/bus/.*: modules-core - - - drivers/cdx/.*: modules-core - - drivers/char/mwave.*: modules - - drivers/char/.*: modules-core - - drivers/clk/.*: modules-core - - drivers/counter/.*: modules-core - - drivers/cpufreq/.*: modules-core - - drivers/crypto/caam/.*: modules - - drivers/crypto/cavium/.*: modules - - drivers/crypto/chelsio/.*: modules - - drivers/crypto/hisilicon/.*: modules - - drivers/crypto/marvell/.*: modules - - drivers/crypto/.*: modules-core - - drivers/cxl/.*: modules-core - - - drivers/dax/.*: modules-core - - drivers/dca/.*: modules-core - - drivers/devfreq/.*: modules-core - - drivers/dma/.*: modules-core - - - drivers/edac/.*: modules-core - - drivers/extcon/.*: modules-core - - - drivers/firmware/iscsi_ibft.*: modules - - drivers/firmware/.*: modules-core - - drivers/fsi/.*: modules-core - - - drivers/gnss/.*: modules-core - - drivers/gpio/gpio-dln2.*: modules-extra - - drivers/gpio/gpio-ljca.*: modules - - drivers/gpio/.*: modules-core - - drivers/gpu/drm/display/drm_.*: modules-core - - drivers/gpu/drm/drm.*: modules-core - - drivers/gpu/drm/etnaviv/.*: modules-core - - drivers/gpu/drm/gud/.*: modules-core - - drivers/gpu/drm/hyperv/.*: modules-core - - drivers/gpu/drm/imagination/.*: modules-core - - drivers/gpu/drm/lima/.*: modules-core - - drivers/gpu/drm/mxsfb/.*: modules-core - - drivers/gpu/drm/panfrost/.*: modules-core - - drivers/gpu/drm/qxl/.*: modules-core - - drivers/gpu/drm/scheduler/.*: modules-core - - drivers/gpu/drm/solomon/.*: modules-core - - drivers/gpu/drm/tidss/.*: modules-core - - drivers/gpu/drm/tiny/.*: modules-core - - drivers/gpu/drm/ttm/.*: modules-core - - drivers/gpu/drm/udl/.*: modules-core - - drivers/gpu/drm/v3d/.*: modules-core - - drivers/gpu/drm/vgem/.*: modules-core - - drivers/gpu/drm/virtio/.*: modules-core - - drivers/gpu/drm/vkms/.*: modules-core - - drivers/gpu/drm/vmwgfx/.*: modules-core - - drivers/gpu/drm/xlnx/.*: modules-core - - drivers/gpu/host1x/.*: modules-core - - - drivers/hid/hid-asus.*: modules - - drivers/hid/hid-nintendo.*: modules - - drivers/hid/hid-picolcd.*: modules - - drivers/hid/hid-playstation.*: modules - - drivers/hid/surface-hid.*: modules - - drivers/hid/hid-prodikeys.*: modules - - drivers/hid/.*: modules-core - - drivers/hte/.*: modules-core - - drivers/hv/.*: modules-core - - drivers/hwmon/asus_wmi_sensors.*: modules - - drivers/hwmon/dell-smm-hwmon.*: modules - - drivers/hwmon/hp-wmi-sensors.*: modules - - drivers/hwmon/intel-m10-bmc-hwmon.*: modules - - drivers/hwmon/nct6775.*: modules - - drivers/hwmon/.*: modules-core - - drivers/hwspinlock/.*: modules-core - - drivers/hwtracing/.*: modules-core - - - drivers/i2c/busses/i2c-dln2.*: modules-extra - - drivers/i2c/busses/i2c-ljca.*: modules - - drivers/i2c/.*: modules-core - - drivers/i3c/.*: modules-core - - drivers/iio/adc/dln2-adc.*: modules-extra - - drivers/iio/accel/.*: modules - - drivers/iio/common/cros_ec_sensors/.*: modules - - drivers/iio/light/.*: modules - - drivers/iio/pressure/.*: modules - - drivers/iio/proximity/.*: modules - - drivers/iio/.*: modules-core - - drivers/input/gameport/.*: modules - - drivers/input/joystick/.*: modules-extra - - drivers/input/misc/pcspkr.*: modules-extra - - drivers/input/tablet/.*: modules - - drivers/input/touchscreen/.*: modules - - drivers/input/.*: modules-core - - drivers/interconnect/.*: modules-core - - drivers/iommu/.*: modules-core - - drivers/irqchip/.*: modules-core - - - drivers/mailbox/.*: modules-core - - drivers/md/.*: modules-core - - drivers/memory/dfl-emif.*: modules - - drivers/memory/.*: modules-core - - drivers/message/fusion/mptctl.*: modules-extra - - drivers/message/fusion/mptfc.*: modules-extra - - drivers/message/fusion/.*: modules - - drivers/message/.*: modules-core - - drivers/mfd/dln2.*: modules-extra - - drivers/misc/.*: modules-core - - drivers/mux/.*: modules-core - - - drivers/net/amt.ko: modules-core - - drivers/net/bareudp.ko: modules-core - - drivers/net/bonding/.*: modules-core - - drivers/net/can/slcan/slcan.*: modules-extra - - drivers/net/can/usb/ems_usb.*: modules-extra - - drivers/net/can/vcan.*: modules-extra - - drivers/net/dummy.ko: modules-core - - drivers/net/eql.ko: modules-core - - - drivers/net/ethernet/8390/.*: modules-core - - drivers/net/ethernet/adi/.*: modules-core - - drivers/net/ethernet/agere/.*: modules-core - - drivers/net/ethernet/altera/.*: modules-core - - drivers/net/ethernet/amazon/.*: modules-core - - drivers/net/ethernet/amd/.*: modules-core - - drivers/net/ethernet/apm/.*: modules-core - - drivers/net/ethernet/asix/.*: modules-core - - drivers/net/ethernet/brocade/.*: modules-core - - drivers/net/ethernet/cavium/.*: modules-core - - drivers/net/ethernet/dnet.ko: modules-core - - drivers/net/ethernet/engleder/.*: modules-core - - drivers/net/ethernet/ethoc.ko: modules-core - - drivers/net/ethernet/fealnx.ko: modules-core - - drivers/net/ethernet/freescale/.*: modules-core - - drivers/net/ethernet/fungible/.*: modules-core - - drivers/net/ethernet/google/.*: modules-core - - drivers/net/ethernet/hisilicon/.*: modules-core - - drivers/net/ethernet/ibm/.*: modules-core - - drivers/net/ethernet/intel/.*: modules-core - - drivers/net/ethernet/jme.ko: modules-core - - drivers/net/ethernet/litex/.*: modules-core - - drivers/net/ethernet/mellanox/.*: modules-core - - drivers/net/ethernet/microsoft/.*: modules-core - - drivers/net/ethernet/natsemi/.*: modules-core - - drivers/net/ethernet/netronome/.*: modules-core - - drivers/net/ethernet/pensando/.*: modules-core - - drivers/net/ethernet/rocker/rocker.*: modules-internal - - drivers/net/ethernet/qualcomm/.*: modules-core - - drivers/net/ethernet/realtek/.*: modules-core - - drivers/net/ethernet/renesas/.*: modules-core - - drivers/net/ethernet/socionext/.*: modules-core - - drivers/net/ethernet/vertexcom/.*: modules-core - - drivers/net/ethernet/wangxun/.*: modules-core - - drivers/net/ethernet/xilinx/.*: modules-core - - - drivers/net/fjes/.*: modules-core - - drivers/net/geneve.ko: modules-core - - drivers/net/gtp.ko: modules-core - - drivers/net/hamradio/.*: modules-extra - - drivers/net/hyperv/.*: modules-core - - drivers/net/ifb.ko: modules-core - - drivers/net/ipa/.*: modules-core - - drivers/net/ipvlan/.*: modules-core - - drivers/net/macsec.ko: modules-core - - drivers/net/macvlan.ko: modules-core - - drivers/net/macvtap.ko: modules-core - - drivers/net/mctp/.*: modules-core - - drivers/net/mdio.*: modules-core - - drivers/net/mhi_net.ko: modules-core - - drivers/net/mii.ko: modules-core - - drivers/net/net_failover.ko: modules-core - - drivers/net/netdevsim/netdevsim.*: modules-internal - - drivers/net/netconsole.ko: modules-core - - drivers/net/nlmon.ko: modules-core - - drivers/net/pcs/.*: modules-core - - drivers/net/phy/.*: modules-core - - drivers/net/rionet.ko: modules-core - - drivers/net/slip/slip.*: modules-extra - - drivers/net/sungem_phy.ko: modules-core - - drivers/net/tap.ko: modules-core - - drivers/net/team/.*: modules-core - - drivers/net/thunderbolt/.*: modules-core - - drivers/net/tun.ko: modules-core - - drivers/net/veth.ko: modules-core - - drivers/net/virtio_net.ko: modules-core - - drivers/net/vmxnet3/.*: modules-core - - drivers/net/vrf.ko: modules-core - - drivers/net/vsockmon.ko: modules-core - - drivers/net/vxlan/.*: modules-core - - drivers/net/wireguard/.*: modules-core - - drivers/net/wireless/virtual/mac80211_hwsim.*: modules-internal - - drivers/net/wwan/wwan_hwsim.*: modules-internal - - drivers/net/wwan/.*: modules-core - - drivers/net/xen.*: modules-core - - - drivers/nvdimm/.*: modules-core - - drivers/nvme/host/nvme-rdma.*: modules - - drivers/nvme/target/nvmet-rdma.*: modules - - drivers/nvme/.*: modules-core - - drivers/nvmem/nvmem_u-boot-env.*: modules - - drivers/nvmem/.*: modules-core - - - drivers/parport/parport_serial.*: modules - - drivers/parport/.*: modules-core - - drivers/pci/pcie/aer_inject.*: modules-extra - - drivers/pci/.*: modules-core - - drivers/perf/.*: modules-core - - drivers/phy/.*: modules-core - - drivers/pinctrl/.*: modules-core - - drivers/pmdomain/.*: modules-core - - drivers/powercap/intel_rapl_tpmi.*: modules - - drivers/powercap/.*: modules-core - - drivers/pps/.*: modules-core - - drivers/ptp/ptp_mock.*: modules-internal - - drivers/ptp/ptp_dfl_tod.*: modules - - drivers/ptp/.*: modules-core - - drivers/pwm/.*: modules-core - - - drivers/rapidio/.*: modules-core - - drivers/regulator/arizona-micsupp.*: modules - - drivers/regulator/.*: modules-core - - drivers/remoteproc/.*: modules-core - - drivers/reset/.*: modules-core - - drivers/rpmsg/.*: modules-core - - drivers/rtc/.*: modules-core - - - drivers/s390/.*: modules-core - - - drivers/scsi/3w.*: modules-core - - drivers/scsi/BusLogic.ko: modules-core - - drivers/scsi/a100u2w.ko: modules-core - - drivers/scsi/advansys.ko: modules-core - - drivers/scsi/am53c974.ko: modules-core - - drivers/scsi/arcmsr.*: modules-core - - drivers/scsi/atp870u.ko: modules-core - - drivers/scsi/ch.ko: modules-core - - drivers/scsi/cxlflash/.*: modules-core - - drivers/scsi/dc395x.ko: modules-core - - drivers/scsi/device_handler/.*: modules-core - - drivers/scsi/dmx3191d.ko: modules-core - - drivers/scsi/elx/.*: modules-core - - drivers/scsi/esp_scsi.ko: modules-core - - drivers/scsi/fdomain.*: modules-core - - drivers/scsi/hpsa.ko: modules-core - - drivers/scsi/hptiop.ko: modules-core - - drivers/scsi/hv_storvsc.ko: modules-core - - drivers/scsi/ibmvscsi.*: modules-core - - drivers/scsi/initio.ko: modules-core - - drivers/scsi/ipr.ko: modules-core - - drivers/scsi/ips.ko: modules-core - - drivers/scsi/iscsi_tcp.ko: modules-core - - drivers/scsi/libfc/.*: modules-core - - drivers/scsi/libiscsi.*: modules-core - - drivers/scsi/mpi3mr/.*: modules-core - - drivers/scsi/mvumi.ko: modules-core - - drivers/scsi/myrb.ko: modules-core - - drivers/scsi/myrs.ko: modules-core - - drivers/scsi/raid_class.ko: modules-core - - drivers/scsi/scsi_debug.ko: modules-core - - drivers/scsi/scsi_transport_.*: modules-core - - drivers/scsi/ses.ko: modules-core - - drivers/scsi/smartpqi/.*: modules-core - - drivers/scsi/snic/.*: modules-core - - drivers/scsi/st.ko: modules-core - - drivers/scsi/stex.ko: modules-core - - drivers/scsi/virtio_scsi.ko: modules-core - - drivers/scsi/vmw_pvscsi.ko: modules-core - - drivers/scsi/wd719x.ko: modules-core - - drivers/scsi/xen-scsifront.ko: modules-core - - - drivers/slimbus/.*: modules-core - - drivers/soc/.*: modules-core - - drivers/spi/spi-altera-dfl.*: modules - - drivers/spi/spi-dln2.*: modules-extra - - drivers/spi/spi-ljca.*: modules - - drivers/spi/.*: modules-core - - drivers/spmi/.*: modules-core - - - drivers/target/iscsi/cxgbit/cxgbit.*: modules - - drivers/target/sbp/sbp_target.*: modules - - drivers/target/target_core_user.*: modules - - drivers/target/.*: modules-core - - drivers/tee/.*: modules-core - - drivers/thermal/intel/int340x_thermal/int3406_thermal.*: modules - - drivers/thermal/.*: modules-core - - drivers/thunderbolt/.*: modules-core - - - drivers/ufs/.*: modules-core - - drivers/usb/atm/.*: modules - - drivers/usb/gadget/function/usb_f_midi2.*: modules - - drivers/usb/image/.*: modules - - drivers/usb/misc/trancevibrator.*: modules-extra - - drivers/usb/misc/.*: modules - - drivers/usb/serial/.*: modules - - drivers/usb/typec/mux/nb7vpq904m.*: modules - - drivers/usb/usbip/.*: modules-extra - - drivers/usb/.*: modules-core - - - drivers/vdpa/mlx5/mlx5_vdpa.*: modules - - drivers/vdpa/pds/pds_vdpa.*: modules - - drivers/vdpa/.*: modules-core - - drivers/vfio/pci/mlx5/mlx5-vfio-pci.*: modules - - drivers/vfio/pci/pds/pds-vfio-pc.*: modules - - drivers/vfio/.*: modules-core - - drivers/vhost/.*: modules-core - - drivers/video/backlight/apple_bl.*: modules - - drivers/video/.*: modules-core - - drivers/virt/.*: modules-core - - drivers/virtio/.*: modules-core - - - drivers/watchdog/iTCO_wdt.*: modules - - drivers/watchdog/.*: modules-core - - - drivers/xen/.*: modules-core - - - drivers/w1/masters/ds2482.*: modules-extra - - drivers/w1/masters/ds2490.*: modules-extra - - drivers/w1/slaves/w1_ds2408.*: modules-extra - - drivers/w1/slaves/w1_ds2423.*: modules-extra - - drivers/w1/slaves/w1_ds2431.*: modules-extra - - drivers/w1/slaves/w1_ds2433.*: modules-extra - - drivers/w1/slaves/w1_ds2780.*: modules-extra - - drivers/w1/slaves/w1_ds2781.*: modules-extra - - drivers/w1/slaves/w1_ds28e04.*: modules-extra - - drivers/w1/slaves/w1_smem.*: modules-extra - - drivers/w1/slaves/w1_therm.*: modules-extra - - - fs/9p/.*: modules-core - - fs/afs/.*: modules-core - - fs/affs/affs.*: modules-extra - - fs/bcachefs/.*: modules-core - - fs/befs/befs.*: modules-extra - - fs/binfmt_misc.ko: modules-core - - fs/cachefiles/.*: modules-core - - fs/ceph/.*: modules-core - - fs/coda/coda.*: modules-extra - - fs/dlm/.*: modules-extra - - fs/erofs/.*: modules-core - - fs/exfat/.*: modules-core - - fs/f2fs/.*: modules-core - - fs/fat/.*: modules-core - - fs/fuse/cuse.*: modules-extra - - fs/fuse/.*: modules-core - - fs/gfs2/.*: modules-extra - - fs/isofs/.*: modules-core - - fs/lockd/.*: modules-core - - fs/netfs/.*: modules-core - - fs/nfs.*: modules-core - - fs/nilfs2/nilfs2.*: modules-extra - - fs/nls/.*: modules-core - - fs/ntfs3/.*: modules-core - - fs/ocfs2/.*: modules-extra - - fs/orangefs/.*: modules-core - - fs/overlayfs/.*: modules-core - - fs/pstore/.*: modules-core - - fs/smb/.*: modules-core - - fs/squashfs/.*: modules-core - - fs/sysv/.*: modules-extra - - fs/ubifs/.*: modules-extra - - fs/udf/.*: modules-core - - fs/ufs/.*: modules-extra - - fs/vboxsf/.*: modules-core - - fs/xfs/.*: modules-core - - fs/zonefs/.*: modules-core - - - kernel/locking/locktorture.*: modules-internal - - kernel/rcu/rcuscale.*: modules-internal - - kernel/rcu/rcutorture.*: modules-internal - - kernel/rcu/refscale.*: modules-internal - - kernel/scftorture.*: modules-internal - - kernel/torture.*: modules-internal - - kernel/.*: modules-core - - - lib/.*: modules-core - - - net/802/.*: modules-core - - net/8021q/.*: modules-core - - net/9p/9pnet_rdma.ko: modules - - net/9p/.*: modules-core - - net/appletalk/appletalk.*: modules-extra - - net/atm/br2684.*: modules-extra - - net/atm/clip.*: modules-extra - - net/atm/lec.*: modules-extra - - net/atm/pppoatm.*: modules-extra - - net/ax25/ax25.*: modules-extra - - net/batman-adv/batman-adv.*: modules-extra - - net/bridge/.*: modules-core - - net/ceph/.*: modules-core - - net/core/pktgen.*: modules-internal - - net/core/.*: modules-core - - net/dns_resolver/.*: modules-core - - net/hsr/.*: modules-core - - net/ife/.*: modules-core - - net/ipv4/tcp_bic.*: modules-extra - - net/ipv4/tcp_highspeed.*: modules-extra - - net/ipv4/tcp_htcp.*: modules-extra - - net/ipv4/tcp_hybla.*: modules-extra - - net/ipv4/tcp_illinois.*: modules-extra - - net/ipv4/tcp_lp.*: modules-extra - - net/ipv4/tcp_scalable.*: modules-extra - - net/ipv4/tcp_vegas.*: modules-extra - - net/ipv4/tcp_veno.*: modules-extra - - net/ipv4/tcp_westwood.*: modules-extra - - net/ipv4/tcp_yeah.*: modules-extra - - net/ipv4/.*: modules-core - - net/ipv6/.*: modules-core - - net/iucv/.*: modules-core - - net/kcm/.*: modules-core - - net/key/.*: modules-core - - net/l2tp/l2tp_debugfs.*: modules-extra - - net/l2tp/l2tp_eth.*: modules-extra - - net/l2tp/l2tp_netlink.*: modules-extra - - net/l2tp/l2tp_ppp.*: modules-extra - - net/llc/.*: modules-core - - net/netfilter/.*: modules-core - - net/netrom/netrom.*: modules-extra - - net/nsh/.*: modules-core - - net/openvswitch/.*: modules-core - - net/psample/.*: modules-core - - net/qrtr/.*: modules-core - - net/rds/rds.*: modules-extra - - net/rose/rose.*: modules-extra - - net/rxrpc/.*: modules-core - - net/sched/.*: modules-core - - net/sunrpc/xprtrdma/rpcrdma.*: modules - - net/sunrpc/.*: modules-core - - net/tipc/.*: modules-core - - net/tls/.*: modules-core - - net/vmw_vsock/.*: modules-core - - net/xdp/.*: modules-core - - net/xfrm/.*: modules-core - - - virt/.*: modules-core - - - default: modules diff --git a/def_variants.yaml.rhel b/def_variants.yaml.rhel deleted file mode 100644 index f4b1f927a..000000000 --- a/def_variants.yaml.rhel +++ /dev/null @@ -1,486 +0,0 @@ -packages: - - name: modules-core - depends-on: [] - - name: modules - depends-on: - - modules-core - - name: modules-internal - depends-on: - - modules-core - - modules - - name: modules-extra - depends-on: - - modules-core - - modules - - name: modules-partner - depends-on: - - modules-core - - modules - -rules: - - .*kunit.*: modules-internal - exact_pkg: True - - .*test[^/]*.ko: modules-internal - - - arch/.*: modules-core - - block/t10-pi.ko: modules-core - - crypto/.*: modules-core - - - drivers/accel/.*: modules-core - - drivers/accessibility/.*: modules-core - - drivers/acpi/video.*: modules - - drivers/acpi/.*: modules-core - - drivers/ata/.*: modules-core - - - drivers/base/regmap/regmap-sdw.*: modules - - drivers/base/.*: modules-core - - drivers/block/floppy.*: modules-extra - - drivers/block/rnbd.*: modules - - drivers/block/.*: modules-core - - drivers/bus/.*: modules-core - - - drivers/cdrom/.*: modules-core - - drivers/cdx/.*: modules-core - - drivers/char/mwave.*: modules - - drivers/char/.*: modules-core - - drivers/clk/.*: modules-core - - drivers/counter/.*: modules-core - - drivers/cpufreq/amd-pstate-ut.ko: modules-internal - - drivers/cpufreq/.*: modules-core - - drivers/crypto/caam/.*: modules - - drivers/crypto/cavium/.*: modules - - drivers/crypto/chelsio/.*: modules - - drivers/crypto/hisilicon/.*: modules - - drivers/crypto/marvell/.*: modules - - drivers/crypto/.*: modules-core - - drivers/cxl/.*: modules-core - - - drivers/dax/.*: modules-core - - drivers/dca/.*: modules-core - - drivers/devfreq/.*: modules-core - - drivers/dma/.*: modules-core - - - drivers/edac/.*: modules-core - - drivers/extcon/.*: modules-core - - - drivers/firmware/iscsi_ibft.*: modules - - drivers/firmware/.*: modules-core - - drivers/fsi/.*: modules-core - - - drivers/gnss/.*: modules-core - - drivers/gpio/gpio-dln2.*: modules-extra - - drivers/gpio/gpio-ljca.*: modules - - drivers/gpio/.*: modules-core - - drivers/gpu/drm/display/drm_.*: modules-core - - drivers/gpu/drm/drm.*: modules-core - - drivers/gpu/drm/etnaviv/.*: modules-core - - drivers/gpu/drm/gud/.*: modules-core - - drivers/gpu/drm/hyperv/.*: modules-core - - drivers/gpu/drm/imagination/.*: modules-core - - drivers/gpu/drm/lima/.*: modules-core - - drivers/gpu/drm/mxsfb/.*: modules-core - - drivers/gpu/drm/panfrost/.*: modules-core - - drivers/gpu/drm/qxl/.*: modules-core - - drivers/gpu/drm/scheduler/.*: modules-core - - drivers/gpu/drm/solomon/.*: modules-core - - drivers/gpu/drm/tidss/.*: modules-core - - drivers/gpu/drm/tiny/.*: modules-core - - drivers/gpu/drm/ttm/.*: modules-core - - drivers/gpu/drm/udl/.*: modules-core - - drivers/gpu/drm/v3d/.*: modules-core - - drivers/gpu/drm/vgem/.*: modules-core - - drivers/gpu/drm/virtio/.*: modules-core - - drivers/gpu/drm/vkms/.*: modules-core - - drivers/gpu/drm/vmwgfx/.*: modules-core - - drivers/gpu/drm/xlnx/.*: modules-core - - drivers/gpu/host1x/.*: modules-core - - - drivers/hid/hid-asus.*: modules - - drivers/hid/hid-nintendo.*: modules - - drivers/hid/hid-picolcd.*: modules - - drivers/hid/hid-playstation.*: modules - - drivers/hid/surface-hid.*: modules - - drivers/hid/hid-prodikeys.*: modules - - drivers/hid/.*: modules-core - - drivers/hte/.*: modules-core - - drivers/hv/.*: modules-core - - drivers/hwmon/asus_wmi_sensors.*: modules - - drivers/hwmon/dell-smm-hwmon.*: modules - - drivers/hwmon/hp-wmi-sensors.*: modules - - drivers/hwmon/intel-m10-bmc-hwmon.*: modules - - drivers/hwmon/nct6775.*: modules - - drivers/hwmon/ntc_thermistor.*: modules - - drivers/hwmon/.*: modules-core - - drivers/hwspinlock/.*: modules-core - - drivers/hwtracing/.*: modules-core - - - drivers/i2c/busses/i2c-dln2.*: modules-extra - - drivers/i2c/busses/i2c-ljca.*: modules - - drivers/i2c/.*: modules-core - - drivers/i3c/.*: modules-core - - drivers/iio/adc/dln2-adc.*: modules-extra - - drivers/input/gameport/.*: modules - - drivers/input/joystick/.*: modules-extra - - drivers/input/tablet/.*: modules - - drivers/input/touchscreen/.*: modules - - drivers/input/.*: modules-core - - drivers/interconnect/.*: modules-core - - drivers/iommu/.*: modules-core - - drivers/irqchip/.*: modules-core - - - drivers/mailbox/.*: modules-core - - drivers/md/.*: modules-core - - drivers/memory/dfl-emif.*: modules - - drivers/memory/.*: modules-core - - drivers/message/fusion/mptctl.*: modules-extra - - drivers/message/fusion/mptfc.*: modules-extra - - drivers/message/fusion/.*: modules - - drivers/message/.*: modules-core - - drivers/mfd/dln2.*: modules-extra - - drivers/misc/.*: modules-core - - drivers/mux/.*: modules-core - - - drivers/net/amt.ko: modules-core - - drivers/net/bareudp.ko: modules-core - - drivers/net/bonding/.*: modules-core - - drivers/net/can/slcan/slcan.*: modules-extra - - drivers/net/can/usb/ems_usb.*: modules-extra - - drivers/net/can/vcan.*: modules-extra - - drivers/net/dummy.ko: modules-core - - drivers/net/eql.ko: modules-core - - - drivers/net/ethernet/8390/.*: modules-core - - drivers/net/ethernet/adi/.*: modules-core - - drivers/net/ethernet/agere/.*: modules-core - - drivers/net/ethernet/altera/.*: modules-core - - drivers/net/ethernet/amazon/.*: modules-core - - drivers/net/ethernet/amd/.*: modules-core - - drivers/net/ethernet/apm/.*: modules-core - - drivers/net/ethernet/asix/.*: modules-core - - drivers/net/ethernet/brocade/.*: modules-core - - drivers/net/ethernet/cavium/.*: modules-core - - drivers/net/ethernet/dnet.ko: modules-core - - drivers/net/ethernet/engleder/.*: modules-core - - drivers/net/ethernet/ethoc.ko: modules-core - - drivers/net/ethernet/fealnx.ko: modules-core - - drivers/net/ethernet/freescale/.*: modules-core - - drivers/net/ethernet/fungible/.*: modules-core - - drivers/net/ethernet/google/.*: modules-core - - drivers/net/ethernet/hisilicon/.*: modules-core - - drivers/net/ethernet/huawei/.*: modules-core - - drivers/net/ethernet/ibm/.*: modules-core - - drivers/net/ethernet/intel/.*: modules-core - - drivers/net/ethernet/jme.ko: modules-core - - drivers/net/ethernet/litex/.*: modules-core - - drivers/net/ethernet/mellanox/.*: modules-core - - drivers/net/ethernet/microsoft/.*: modules-core - - drivers/net/ethernet/myricom/.*: modules-core - - drivers/net/ethernet/natsemi/.*: modules-core - - drivers/net/ethernet/netronome/.*: modules-core - - drivers/net/ethernet/pensando/.*: modules-core - - drivers/net/ethernet/rocker/rocker.*: modules-internal - - drivers/net/ethernet/qualcomm/.*: modules-core - - drivers/net/ethernet/realtek/.*: modules-core - - drivers/net/ethernet/renesas/.*: modules-core - - drivers/net/ethernet/socionext/.*: modules-core - - drivers/net/ethernet/vertexcom/.*: modules-core - - drivers/net/ethernet/wangxun/.*: modules-core - - drivers/net/ethernet/xilinx/.*: modules-core - - - drivers/net/fjes/.*: modules-core - - drivers/net/geneve.ko: modules-core - - drivers/net/gtp.ko: modules-core - - drivers/net/hamradio/.*: modules-extra - - drivers/net/hyperv/.*: modules-core - - drivers/net/ifb.ko: modules-core - - drivers/net/ipa/.*: modules-core - - drivers/net/ipvlan/.*: modules-core - - drivers/net/macsec.ko: modules-core - - drivers/net/macvlan.ko: modules-core - - drivers/net/macvtap.ko: modules-core - - drivers/net/mctp/.*: modules-core - - drivers/net/mdio.*: modules-core - - drivers/net/mhi_net.ko: modules-core - - drivers/net/mii.ko: modules-core - - drivers/net/net_failover.ko: modules-core - - drivers/net/netdevsim/netdevsim.*: modules-internal - - drivers/net/netconsole.ko: modules-core - - drivers/net/nlmon.ko: modules-core - - drivers/net/pcs/.*: modules-core - - drivers/net/phy/.*: modules-core - - drivers/net/rionet.ko: modules-core - - drivers/net/slip/slip.*: modules-extra - - drivers/net/sungem_phy.ko: modules-core - - drivers/net/tap.ko: modules-core - - drivers/net/team/.*: modules-core - - drivers/net/thunderbolt/.*: modules-core - - drivers/net/tun.ko: modules-core - - drivers/net/veth.ko: modules-core - - drivers/net/virtio_net.ko: modules-core - - drivers/net/vmxnet3/.*: modules-core - - drivers/net/vrf.ko: modules-core - - drivers/net/vsockmon.ko: modules-core - - drivers/net/vxlan/.*: modules-core - - drivers/net/wan/hdlc.*: modules-core - - drivers/net/wireguard/.*: modules-core - - drivers/net/wireless/virtual/mac80211_hwsim.*: modules-internal - - drivers/net/wwan/wwan_hwsim.*: modules-internal - - drivers/net/wwan/.*: modules-core - - drivers/net/xen.*: modules-core - - - drivers/nvdimm/.*: modules-core - - drivers/nvme/host/nvme-rdma.*: modules - - drivers/nvme/target/nvmet-rdma.*: modules - - drivers/nvme/.*: modules-core - - drivers/nvmem/nvmem_u-boot-env.*: modules - - drivers/nvmem/.*: modules-core - - - drivers/parport/parport_serial.*: modules - - drivers/parport/.*: modules-core - - drivers/pci/pcie/aer_inject.*: modules-extra - - drivers/pci/.*: modules-core - - drivers/perf/.*: modules-core - - drivers/phy/.*: modules-core - - drivers/pinctrl/.*: modules-core - - drivers/platform/x86/intel/intel_vsec.*: modules-core - - drivers/pmdomain/.*: modules-core - - drivers/powercap/intel_rapl_tpmi.*: modules - - drivers/powercap/.*: modules-core - - drivers/pps/.*: modules-core - - drivers/ptp/ptp_mock.*: modules-internal - - drivers/ptp/ptp_dfl_tod.*: modules - - drivers/ptp/.*: modules-core - - drivers/pwm/.*: modules-core - - - drivers/rapidio/.*: modules-core - - drivers/regulator/arizona-micsupp.*: modules - - drivers/regulator/.*: modules-core - - drivers/remoteproc/.*: modules-core - - drivers/reset/.*: modules-core - - drivers/rpmsg/.*: modules-core - - drivers/rtc/.*: modules-core - - - drivers/s390/net/ism.*: modules - - drivers/s390/.*: modules-core - - - drivers/scsi/3w.*: modules-core - - drivers/scsi/BusLogic.ko: modules-core - - drivers/scsi/a100u2w.ko: modules-core - - drivers/scsi/advansys.ko: modules-core - - drivers/scsi/am53c974.ko: modules-core - - drivers/scsi/arcmsr.*: modules-core - - drivers/scsi/atp870u.ko: modules-core - - drivers/scsi/ch.ko: modules-core - - drivers/scsi/cxlflash/.*: modules-core - - drivers/scsi/dc395x.ko: modules-core - - drivers/scsi/device_handler/.*: modules-core - - drivers/scsi/dmx3191d.ko: modules-core - - drivers/scsi/elx/.*: modules-core - - drivers/scsi/esp_scsi.ko: modules-core - - drivers/scsi/fdomain.*: modules-core - - drivers/scsi/hpsa.ko: modules-core - - drivers/scsi/hptiop.ko: modules-core - - drivers/scsi/hv_storvsc.ko: modules-core - - drivers/scsi/ibmvscsi.*: modules-core - - drivers/scsi/initio.ko: modules-core - - drivers/scsi/ipr.ko: modules-core - - drivers/scsi/ips.ko: modules-core - - drivers/scsi/iscsi_tcp.ko: modules-core - - drivers/scsi/libfc/.*: modules-core - - drivers/scsi/libiscsi.*: modules-core - - drivers/scsi/mpi3mr/.*: modules-core - - drivers/scsi/mvumi.ko: modules-core - - drivers/scsi/myrb.ko: modules-core - - drivers/scsi/myrs.ko: modules-core - - drivers/scsi/raid_class.ko: modules-core - - drivers/scsi/scsi_debug.ko: modules-core - - drivers/scsi/scsi_transport_.*: modules-core - - drivers/scsi/sd_mod.ko: modules-core - - drivers/scsi/ses.ko: modules-core - - drivers/scsi/sg.ko: modules-core - - drivers/scsi/smartpqi/.*: modules-core - - drivers/scsi/snic/.*: modules-core - - drivers/scsi/sr_mod.ko: modules-core - - drivers/scsi/st.ko: modules-core - - drivers/scsi/stex.ko: modules-core - - drivers/scsi/virtio_scsi.ko: modules-core - - drivers/scsi/vmw_pvscsi.ko: modules-core - - drivers/scsi/wd719x.ko: modules-core - - drivers/scsi/xen-scsifront.ko: modules-core - - - drivers/slimbus/.*: modules-core - - drivers/soc/.*: modules-core - - drivers/spi/spi-altera-dfl.*: modules - - drivers/spi/spi-dln2.*: modules-extra - - drivers/spi/spi-ljca.*: modules - - drivers/spi/.*: modules-core - - drivers/spmi/.*: modules-core - - - drivers/target/iscsi/cxgbit/cxgbit.*: modules - - drivers/target/sbp/sbp_target.*: modules - - drivers/target/target_core_user.*: modules - - drivers/target/.*: modules-core - - drivers/tee/.*: modules-core - - drivers/thermal/intel/int340x_thermal/int3406_thermal.*: modules - - drivers/thermal/.*: modules-core - - drivers/thunderbolt/.*: modules-core - - - drivers/ufs/.*: modules-core - - drivers/usb/atm/.*: modules - - drivers/usb/gadget/function/usb_f_midi2.*: modules - - drivers/usb/image/.*: modules - - drivers/usb/misc/trancevibrator.*: modules-extra - - drivers/usb/misc/.*: modules - - drivers/usb/serial/.*: modules - - drivers/usb/typec/mux/nb7vpq904m.*: modules - - drivers/usb/usbip/.*: modules-internal - - drivers/usb/.*: modules-core - - - drivers/vdpa/mlx5/mlx5_vdpa.*: modules - - drivers/vdpa/pds/pds_vdpa.*: modules - - drivers/vdpa/.*: modules-core - - drivers/vfio/pci/mlx5/mlx5-vfio-pci.*: modules - - drivers/vfio/pci/pds/pds-vfio-pc.*: modules - - drivers/vfio/.*: modules-core - - drivers/vhost/.*: modules-core - - drivers/video/backlight/apple_bl.*: modules - - drivers/video/.*: modules-core - - drivers/virt/.*: modules-core - - drivers/virtio/.*: modules-core - - - drivers/watchdog/.*: modules-core - - - drivers/xen/.*: modules-core - - - drivers/w1/masters/ds2482.*: modules-extra - - drivers/w1/masters/ds2490.*: modules-extra - - drivers/w1/slaves/w1_ds2408.*: modules-extra - - drivers/w1/slaves/w1_ds2423.*: modules-extra - - drivers/w1/slaves/w1_ds2431.*: modules-extra - - drivers/w1/slaves/w1_ds2433.*: modules-extra - - drivers/w1/slaves/w1_ds2780.*: modules-extra - - drivers/w1/slaves/w1_ds2781.*: modules-extra - - drivers/w1/slaves/w1_ds28e04.*: modules-extra - - drivers/w1/slaves/w1_smem.*: modules-extra - - drivers/w1/slaves/w1_therm.*: modules-extra - - - fs/9p/.*: modules-core - - fs/afs/.*: modules-partner - - fs/affs/affs.*: modules-extra - - fs/bcachefs/.*: modules-core - - fs/befs/befs.*: modules-extra - - fs/binfmt_misc.ko: modules-core - - fs/cachefiles/.*: modules-core - - fs/ceph/.*: modules-core - - fs/coda/coda.*: modules-extra - - fs/dlm/.*: modules-core - - fs/erofs/.*: modules-core - - fs/exfat/.*: modules-core - - fs/ext4/.*: modules-core - - fs/f2fs/.*: modules-core - - fs/fat/.*: modules-core - - fs/fuse/cuse.*: modules-extra - - fs/fuse/.*: modules-core - - fs/gfs2/.*: modules-core - - fs/isofs/.*: modules-core - - fs/jbd2/.*: modules-core - - fs/lockd/.*: modules-core - - fs/mbcache.ko: modules-core - - fs/netfs/.*: modules-core - - fs/nfs.*: modules-core - - fs/nilfs2/nilfs2.*: modules-extra - - fs/nls/.*: modules-core - - fs/ntfs3/.*: modules-core - - fs/ocfs2/.*: modules-extra - - fs/orangefs/.*: modules-core - - fs/overlayfs/.*: modules-core - - fs/pstore/.*: modules-core - - fs/sysv/.*: modules-extra - - fs/ubifs/.*: modules-extra - - fs/udf/.*: modules-core - - fs/ufs/.*: modules-extra - - fs/vboxsf/.*: modules-core - - fs/xfs/.*: modules-core - - fs/zonefs/.*: modules-core - - - kernel/locking/locktorture.*: modules-internal - - kernel/rcu/rcuscale.*: modules-internal - - kernel/rcu/rcutorture.*: modules-internal - - kernel/rcu/refscale.*: modules-internal - - kernel/scftorture.*: modules-internal - - kernel/torture.*: modules-internal - - kernel/.*: modules-core - - - lib/.*: modules-core - - - mm/zsmalloc.ko: modules-core - - - net/802/.*: modules-core - - net/8021q/.*: modules-core - - net/9p/9pnet_rdma.ko: modules - - net/9p/.*: modules-core - - net/appletalk/appletalk.*: modules-extra - - net/atm/br2684.*: modules-extra - - net/atm/clip.*: modules-extra - - net/atm/lec.*: modules-extra - - net/atm/pppoatm.*: modules-extra - - net/ax25/ax25.*: modules-extra - - net/batman-adv/batman-adv.*: modules-extra - - net/bridge/br_netfilter.*: modules-extra - - net/bridge/netfilter/ebt.*: modules-extra - - net/bridge/.*: modules-core - - net/ceph/.*: modules-core - - net/core/pktgen.*: modules-internal - - net/core/.*: modules-core - - net/dns_resolver/.*: modules-core - - net/hsr/.*: modules-core - - net/ife/.*: modules-core - - net/ipv4/netfilter/arp.*: modules-extra - - net/ipv4/netfilter/ip[_t].*: modules-extra - - net/ipv4/tcp_bic.*: modules-extra - - net/ipv4/tcp_highspeed.*: modules-extra - - net/ipv4/tcp_htcp.*: modules-extra - - net/ipv4/tcp_hybla.*: modules-extra - - net/ipv4/tcp_illinois.*: modules-extra - - net/ipv4/tcp_lp.*: modules-extra - - net/ipv4/tcp_scalable.*: modules-extra - - net/ipv4/tcp_vegas.*: modules-extra - - net/ipv4/tcp_veno.*: modules-extra - - net/ipv4/tcp_westwood.*: modules-extra - - net/ipv4/tcp_yeah.*: modules-extra - - net/ipv4/.*: modules-core - - net/ipv6/netfilter/ebt.*: modules-extra - - net/ipv6/netfilter/ip6[_t].*: modules-extra - - net/ipv6/.*: modules-core - - net/iucv/.*: modules-core - - net/kcm/.*: modules-core - - net/key/.*: modules-core - - net/l2tp/.*: modules-extra - - net/llc/.*: modules-core - - net/netfilter/ipset/.*: modules-extra - - net/netfilter/nft_compat.*: modules-extra - - net/netfilter/xt_.*: modules-extra - - net/netfilter/.*: modules-core - - net/netrom/netrom.*: modules-extra - - net/nsh/.*: modules-core - - net/openvswitch/.*: modules-core - - net/psample/.*: modules-core - - net/qrtr/.*: modules-core - - net/rds/rds.*: modules-extra - - net/rose/rose.*: modules-extra - - net/rxrpc/.*: modules-partner - - net/sched/.*: modules-core - - net/sctp/.*: modules-extra - - net/sunrpc/xprtrdma/rpcrdma.*: modules - - net/sunrpc/.*: modules-core - - net/tipc/.*: modules-extra - - net/tls/.*: modules-core - - net/vmw_vsock/.*: modules-core - - net/xdp/.*: modules-core - - net/xfrm/.*: modules-core - - - samples/.*: modules-internal - - - virt/.*: modules-core - - - default: modules diff --git a/depessimize-rds_copy_page_user.patch b/depessimize-rds_copy_page_user.patch new file mode 100644 index 000000000..aec8bff4d --- /dev/null +++ b/depessimize-rds_copy_page_user.patch @@ -0,0 +1,78 @@ +From 799c10559d60f159ab2232203f222f18fa3c4a5f Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Fri, 15 Oct 2010 11:09:28 -0700 +Subject: [PATCH] De-pessimize rds_page_copy_user + +Don't try to "optimize" rds_page_copy_user() by using kmap_atomic() and +the unsafe atomic user mode accessor functions. It's actually slower +than the straightforward code on any reasonable modern CPU. + +Back when the code was written (although probably not by the time it was +actually merged, though), 32-bit x86 may have been the dominant +architecture. And there kmap_atomic() can be a lot faster than kmap() +(unless you have very good locality, in which case the virtual address +caching by kmap() can overcome all the downsides). + +But these days, x86-64 may not be more populous, but it's getting there +(and if you care about performance, it's definitely already there - +you'd have upgraded your CPU's already in the last few years). And on +x86-64, the non-kmap_atomic() version is faster, simply because the code +is simpler and doesn't have the "re-try page fault" case. + +People with old hardware are not likely to care about RDS anyway, and +the optimization for the 32-bit case is simply buggy, since it doesn't +verify the user addresses properly. + +Reported-by: Dan Rosenberg +Acked-by: Andrew Morton +Cc: stable@kernel.org +Signed-off-by: Linus Torvalds +--- + net/rds/page.c | 27 +++++++-------------------- + 1 files changed, 7 insertions(+), 20 deletions(-) + +diff --git a/net/rds/page.c b/net/rds/page.c +index 595a952..1dfbfea 100644 +--- a/net/rds/page.c ++++ b/net/rds/page.c +@@ -57,30 +57,17 @@ int rds_page_copy_user(struct page *page, unsigned long offset, + unsigned long ret; + void *addr; + +- if (to_user) ++ addr = kmap(page); ++ if (to_user) { + rds_stats_add(s_copy_to_user, bytes); +- else ++ ret = copy_to_user(ptr, addr + offset, bytes); ++ } else { + rds_stats_add(s_copy_from_user, bytes); +- +- addr = kmap_atomic(page, KM_USER0); +- if (to_user) +- ret = __copy_to_user_inatomic(ptr, addr + offset, bytes); +- else +- ret = __copy_from_user_inatomic(addr + offset, ptr, bytes); +- kunmap_atomic(addr, KM_USER0); +- +- if (ret) { +- addr = kmap(page); +- if (to_user) +- ret = copy_to_user(ptr, addr + offset, bytes); +- else +- ret = copy_from_user(addr + offset, ptr, bytes); +- kunmap(page); +- if (ret) +- return -EFAULT; ++ ret = copy_from_user(addr + offset, ptr, bytes); + } ++ kunmap(page); + +- return 0; ++ return ret ? -EFAULT : 0; + } + EXPORT_SYMBOL_GPL(rds_page_copy_user); + +-- +1.7.3.2 + diff --git a/die-floppy-die.patch b/die-floppy-die.patch new file mode 100644 index 000000000..76db31218 --- /dev/null +++ b/die-floppy-die.patch @@ -0,0 +1,30 @@ +From 4ff58b642f80dedb20533978123d89b5ac9b1ed5 Mon Sep 17 00:00:00 2001 +From: Kyle McMartin +Date: Tue, 30 Mar 2010 00:04:29 -0400 +Subject: die-floppy-die + +Kill the floppy.ko pnp modalias. We were surviving just fine without +autoloading floppy drivers, tyvm. + +Please feel free to register all complaints in the wastepaper bin. +--- + drivers/block/floppy.c | 3 +-- + 1 files changed, 1 insertions(+), 2 deletions(-) + +diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c +index 90c4038..f4a0b90 100644 +--- a/drivers/block/floppy.c ++++ b/drivers/block/floppy.c +@@ -4619,8 +4619,7 @@ static const struct pnp_device_id floppy_pnpids[] = { + {"PNP0700", 0}, + {} + }; +- +-MODULE_DEVICE_TABLE(pnp, floppy_pnpids); ++/* MODULE_DEVICE_TABLE(pnp, floppy_pnpids); */ + + #else + +-- +1.7.0.1 + diff --git a/disable-i8042-check-on-apple-mac.patch b/disable-i8042-check-on-apple-mac.patch new file mode 100644 index 000000000..f99d0f900 --- /dev/null +++ b/disable-i8042-check-on-apple-mac.patch @@ -0,0 +1,59 @@ +From 2a79554c864ac58fa2ad982f0fcee2cc2aa33eb5 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Thu, 20 May 2010 10:30:31 -0400 +Subject: Disable i8042 checks on Intel Apple Macs + +As those computers never had any i8042 controllers, and the +current lookup code could potentially lock up/hang/wait for +timeout for long periods of time. + +Fixes intermittent hangs on boot on a MacbookAir1,1 + +Signed-off-by: Bastien Nocera +--- + drivers/input/serio/i8042.c | 22 ++++++++++++++++++++++ + 1 files changed, 22 insertions(+), 0 deletions(-) + +diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c +index 6440a8f..4d7cf98 100644 +--- a/drivers/input/serio/i8042.c ++++ b/drivers/input/serio/i8042.c +@@ -1451,6 +1451,22 @@ static struct platform_driver i8042_driver = { + .shutdown = i8042_shutdown, + }; + ++#ifdef CONFIG_DMI ++static struct dmi_system_id __initdata dmi_system_table[] = { ++ { ++ .matches = { ++ DMI_MATCH(DMI_BIOS_VENDOR, "Apple Computer, Inc.") ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BIOS_VENDOR, "Apple Inc.") ++ }, ++ }, ++ {} ++}; ++#endif /*CONFIG_DMI*/ ++ + static int __init i8042_init(void) + { + struct platform_device *pdev; +@@ -1458,6 +1474,12 @@ static int __init i8042_init(void) + + dbg_init(); + ++#ifdef CONFIG_DMI ++ /* Intel Apple Macs never have an i8042 controller */ ++ if (dmi_check_system(dmi_system_table) > 0) ++ return -ENODEV; ++#endif /*CONFIG_DMI*/ ++ + err = i8042_platform_init(); + if (err) + return err; +-- +1.7.0.1 + diff --git a/disable-xhci-by-default.patch b/disable-xhci-by-default.patch new file mode 100644 index 000000000..dd1c80866 --- /dev/null +++ b/disable-xhci-by-default.patch @@ -0,0 +1,31 @@ +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index 11482b6..b05ff9c 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -179,9 +179,25 @@ static struct pci_driver xhci_pci_driver = { + .shutdown = usb_hcd_pci_shutdown, + }; + ++ ++static int enable; ++module_param(enable, int, S_IRUGO); ++MODULE_PARM_DESC(enable, "Enable XHCI host controller"); ++ + int xhci_register_pci(void) + { +- return pci_register_driver(&xhci_pci_driver); ++ /* xhci will prevent suspend/resume if it's loaded. ++ * force user to pass xhci.enable=1 to the kernel in order ++ * to get usb3.0 support for the time being. ++ * ++ * ugly yes, but there's few enough users out there using ++ * usb3.0, and a lot who just have the hardware breaking ++ * their suspend. ++ */ ++ if (enable) ++ return pci_register_driver(&xhci_pci_driver); ++ else ++ return 0; + } + + void xhci_unregister_pci(void) diff --git a/dm-allow-setting-of-uuid-via-rename-if-not-already-set.patch b/dm-allow-setting-of-uuid-via-rename-if-not-already-set.patch new file mode 100644 index 000000000..fd0f1af41 --- /dev/null +++ b/dm-allow-setting-of-uuid-via-rename-if-not-already-set.patch @@ -0,0 +1,205 @@ +From ce5fa9851090cc5f3de4139bf0f343eb78d1c568 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 11 Oct 2010 15:49:28 -0400 +Subject: [PATCH] device-mapper: Allow setting of UUID via rename if not already set + +This makes it possible to use DM_DEV_RENAME to add a uuid to a device so +long as one has not been previously set either with DM_DEV_CREATE or +with DM_DEV_RENAME. This is needed because sometimes in it's necessary +to create the device before the uuid is known, and in such cases the +uuid must be filled in after the creation. + +Also bump the minor number to 19. + +Signed-off-by: Peter Jones +--- + drivers/md/dm-ioctl.c | 95 ++++++++++++++++++++++++++++++++-------------- + include/linux/dm-ioctl.h | 11 ++++- + 2 files changed, 74 insertions(+), 32 deletions(-) + +diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c +index bb6bdc8..d102269 100644 +--- a/drivers/md/dm-ioctl.c ++++ b/drivers/md/dm-ioctl.c +@@ -298,15 +298,15 @@ retry: + static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old, + const char *new) + { +- char *new_name, *old_name; ++ char *new_data, *old_data; + struct hash_cell *hc; + struct dm_table *table; + + /* + * duplicate new. + */ +- new_name = kstrdup(new, GFP_KERNEL); +- if (!new_name) ++ new_data = kstrdup(new, GFP_KERNEL); ++ if (!new_data) + return -ENOMEM; + + down_write(&_hash_lock); +@@ -314,13 +314,18 @@ static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old, + /* + * Is new free ? + */ +- hc = __get_name_cell(new); ++ if (*flags & DM_NEW_UUID_FLAG) ++ hc = __get_uuid_cell(new); ++ else ++ hc = __get_name_cell(new); + if (hc) { +- DMWARN("asked to rename to an already existing name %s -> %s", ++ DMWARN("Unable to change %s on device, %s to one that " ++ "already exists: %s", ++ (*flags & DM_NEW_UUID_FLAG) ? "uuid" : "name", + old, new); + dm_put(hc->md); + up_write(&_hash_lock); +- kfree(new_name); ++ kfree(new_data); + return -EBUSY; + } + +@@ -329,22 +334,46 @@ static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old, + */ + hc = __get_name_cell(old); + if (!hc) { +- DMWARN("asked to rename a non existent device %s -> %s", ++ DMWARN("Unable to rename non-existent device, %s to %s", + old, new); + up_write(&_hash_lock); +- kfree(new_name); ++ kfree(new_data); + return -ENXIO; + } + +- /* +- * rename and move the name cell. +- */ +- list_del(&hc->name_list); +- old_name = hc->name; +- mutex_lock(&dm_hash_cells_mutex); +- hc->name = new_name; +- mutex_unlock(&dm_hash_cells_mutex); +- list_add(&hc->name_list, _name_buckets + hash_str(new_name)); ++ if (*flags & DM_NEW_UUID_FLAG) { ++ /* ++ * Does this device already have a uuid? ++ */ ++ if (hc->uuid) { ++ DMWARN("Unable to change uuid of device, %s because " ++ "uuid is already set to %s", ++ old, hc->uuid); ++ dm_put(hc->md); ++ up_write(&_hash_lock); ++ kfree(new_data); ++ return -EINVAL; ++ } ++ /* ++ * change uuid and move the uuid cell. ++ */ ++ list_del(&hc->uuid_list); ++ old_data = hc->uuid; ++ mutex_lock(&dm_hash_cells_mutex); ++ hc->uuid = new_data; ++ mutex_unlock(&dm_hash_cells_mutex); ++ list_add(&hc->uuid_list, _uuid_buckets + hash_str(new_data)); ++ } else { ++ /* ++ * rename and move the name cell. ++ */ ++ list_del(&hc->name_list); ++ old_data = hc->name; ++ mutex_lock(&dm_hash_cells_mutex); ++ hc->name = new_data; ++ mutex_unlock(&dm_hash_cells_mutex); ++ list_add(&hc->name_list, _name_buckets + hash_str(new_data)); ++ } + + /* + * Wake up any dm event waiters. +@@ -360,7 +388,7 @@ static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old, + + dm_put(hc->md); + up_write(&_hash_lock); +- kfree(old_name); ++ kfree(old_data); + return 0; + } + +@@ -773,23 +801,32 @@ static int invalid_str(char *str, void *end) + static int dev_rename(struct dm_ioctl *param, size_t param_size) + { + int r; +- char *new_name = (char *) param + param->data_start; ++ char *new_data = (char *) param + param->data_start; + +- if (new_name < param->data || +- invalid_str(new_name, (void *) param + param_size) || +- strlen(new_name) > DM_NAME_LEN - 1) { +- DMWARN("Invalid new logical volume name supplied."); +- return -EINVAL; +- } ++ if (param->flags & DM_NEW_UUID_FLAG) { ++ if (new_data < param->data || ++ invalid_str(new_data, (void *) param + param_size) || ++ strlen(new_data) > DM_UUID_LEN - 1) { ++ DMWARN("Invalid new device uuid supplied."); ++ return -EINVAL; ++ } ++ } else { ++ if (new_data < param->data || ++ invalid_str(new_data, (void *) param + param_size) || ++ strlen(new_data) > DM_NAME_LEN - 1) { ++ DMWARN("Invalid new device name supplied."); ++ return -EINVAL; ++ } + +- r = check_name(new_name); +- if (r) +- return r; ++ r = check_name(new_data); ++ if (r) ++ return r; ++ } + + param->data_size = 0; + + return dm_hash_rename(param->event_nr, ¶m->flags, param->name, +- new_name); ++ new_data); + } + + static int dev_set_geometry(struct dm_ioctl *param, size_t param_size) +diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h +index 2c445e1..3bbcb3a 100644 +--- a/include/linux/dm-ioctl.h ++++ b/include/linux/dm-ioctl.h +@@ -266,9 +266,9 @@ enum { + #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) + + #define DM_VERSION_MAJOR 4 +-#define DM_VERSION_MINOR 17 +-#define DM_VERSION_PATCHLEVEL 0 +-#define DM_VERSION_EXTRA "-ioctl (2010-03-05)" ++#define DM_VERSION_MINOR 19 ++#define DM_VERSION_PATCHLEVEL 1 ++#define DM_VERSION_EXTRA "-ioctl (2010-10-12)" + + /* Status bits */ + #define DM_READONLY_FLAG (1 << 0) /* In/Out */ +@@ -321,4 +321,9 @@ enum { + */ + #define DM_UEVENT_GENERATED_FLAG (1 << 13) /* Out */ + ++/* ++ * If set, rename operates on uuid, not name. ++ */ ++#define DM_NEW_UUID_FLAG (1 << 14) /* In */ ++ + #endif /* _LINUX_DM_IOCTL_H */ +-- +1.7.2.3 + diff --git a/dmar-disable-when-ricoh-multifunction.patch b/dmar-disable-when-ricoh-multifunction.patch new file mode 100644 index 000000000..e0bbf3020 --- /dev/null +++ b/dmar-disable-when-ricoh-multifunction.patch @@ -0,0 +1,35 @@ +From 8d2f6746f7f82e1aee2dc40a937b5954cfc73414 Mon Sep 17 00:00:00 2001 +From: Kyle McMartin +Date: Sun, 17 Oct 2010 15:55:32 -0400 +Subject: [PATCH] dmar: disable if ricoh multifunction detected + +--- + drivers/pci/intel-iommu.c | 10 ++++++++++ + 1 files changed, 10 insertions(+), 0 deletions(-) + +diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c +index 8e499e8..076c5de 100644 +--- a/drivers/pci/intel-iommu.c ++++ b/drivers/pci/intel-iommu.c +@@ -3755,6 +3755,18 @@ static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) + + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); + ++/* https://bugzilla.redhat.com/show_bug.cgi?id=605888 */ ++static void __devinit quirk_ricoh_multifunction(struct pci_dev *dev) ++{ ++ printk(KERN_INFO "intel_iommu: broken Ricoh device %04X detected, disabling...\n", ++ dev->device); ++ dmar_disabled = 1; ++} ++DECLARE_PCI_FIXUP_HEADER(0x1180, 0xe822, quirk_ricoh_multifunction); ++DECLARE_PCI_FIXUP_HEADER(0x1180, 0xe230, quirk_ricoh_multifunction); ++DECLARE_PCI_FIXUP_HEADER(0x1180, 0xe832, quirk_ricoh_multifunction); ++DECLARE_PCI_FIXUP_HEADER(0x1180, 0xe476, quirk_ricoh_multifunction); ++ + /* On Tylersburg chipsets, some BIOSes have been known to enable the + ISOCH DMAR unit for the Azalia sound device, but not give it any + TLB entries, which causes it to deadlock. Check for that. We do +-- +1.7.3.1 + diff --git a/dracut-virt.conf b/dracut-virt.conf deleted file mode 100644 index 56a0813ec..000000000 --- a/dracut-virt.conf +++ /dev/null @@ -1,58 +0,0 @@ -# generic + compressed please -hostonly="no" -compress="xz" - -# VMs can't update microcode anyway -early_microcode="no" - -# modules: basics -dracutmodules+=" dracut-systemd i18n shutdown " - -# modules: storage support -dracutmodules+=" dm lvm rootfs-block fs-lib " - -# modules: tpm and crypto -dracutmodules+=" crypt crypt-loop tpm2-tss systemd-pcrphase " - -# dracut >= 102 separated systemd-cryptsetup into its own module -CSMODULE=`dracut --list-modules --no-kernel | grep '^systemd-cryptsetup$'` -dracutmodules+=" $CSMODULE " - -# modules: support root on virtiofs -dracutmodules+=" virtiofs " - -# modules: use sysext images (see 'man systemd-sysext') -dracutmodules+=" systemd-sysext " - -# modules: root disk integrity protection -dracutmodules+=" systemd-veritysetup " - -# modules: root creation and encryption -dracutmodules+=" systemd-repart " -# FIXME: remove this once RHEL-103385 is merged -install_items+=" /usr/sbin/mkfs.vfat /usr/sbin/mkfs.ext4 /usr/sbin/mkfs.xfs " - -# modules: FIPS -dracutmodules+=" fips " -# FIPS mode requires early crypto drivers test -drivers+=" =crypto " - -# drivers: virtual buses, pci -drivers+=" virtio-pci virtio-mmio " # qemu-kvm -drivers+=" hv-vmbus pci-hyperv " # hyperv -drivers+=" xen-pcifront " # xen - -# drivers: storage -drivers+=" ahci nvme sd_mod sr_mod " # generic -drivers+=" virtio-blk virtio-scsi " # qemu-kvm -drivers+=" hv-storvsc " # hyperv -drivers+=" xen-blkfront " # xen - -# root encryption -drivers+=" dm_crypt " - -# root disk integrity protection -drivers+=" dm_verity overlay " - -# filesystems -filesystems+=" vfat ext4 xfs overlay " diff --git a/drm-edid-invalid.patch b/drm-edid-invalid.patch new file mode 100644 index 000000000..8dcaa35ba --- /dev/null +++ b/drm-edid-invalid.patch @@ -0,0 +1,54 @@ +diff -up linux-2.6.35.x86_64/drivers/gpu/drm/drm_edid.c.da linux-2.6.35.x86_64/drivers/gpu/drm/drm_edid.c +--- linux-2.6.35.x86_64/drivers/gpu/drm/drm_edid.c.da 2010-08-01 18:11:14.000000000 -0400 ++++ linux-2.6.35.x86_64/drivers/gpu/drm/drm_edid.c 2010-11-11 20:46:10.000000000 -0500 +@@ -229,7 +229,7 @@ drm_do_probe_ddc_edid(struct i2c_adapter + .addr = DDC_ADDR, + .flags = I2C_M_RD, + .len = len, +- .buf = buf + start, ++ .buf = buf, + } + }; + +@@ -242,7 +242,7 @@ drm_do_probe_ddc_edid(struct i2c_adapter + static u8 * + drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) + { +- int i, j = 0; ++ int i, j = 0, valid_extensions = 0; + u8 *block, *new; + + if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) +@@ -269,14 +269,28 @@ drm_do_get_edid(struct drm_connector *co + + for (j = 1; j <= block[0x7e]; j++) { + for (i = 0; i < 4; i++) { +- if (drm_do_probe_ddc_edid(adapter, block, j, +- EDID_LENGTH)) ++ if (drm_do_probe_ddc_edid(adapter, ++ block + (valid_extensions + 1) * EDID_LENGTH, ++ j, EDID_LENGTH)) + goto out; +- if (drm_edid_block_valid(block + j * EDID_LENGTH)) ++ if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH)) { ++ valid_extensions++; + break; ++ } + } + if (i == 4) +- goto carp; ++ printk(KERN_WARNING ++ "%s: Ignoring invalid EDID block %d.\n", ++ drm_get_connector_name(connector), j); ++ } ++ ++ if (valid_extensions != block[0x7e]) { ++ block[EDID_LENGTH-1] += block[0x7e] - valid_extensions; ++ block[0x7e] = valid_extensions; ++ new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); ++ if (!new) ++ goto out; ++ block = new; + } + + return block; diff --git a/drm-i2c-ch7006-fix.patch b/drm-i2c-ch7006-fix.patch new file mode 100644 index 000000000..11eef90e7 --- /dev/null +++ b/drm-i2c-ch7006-fix.patch @@ -0,0 +1,57 @@ +From 9fa9e790eb301bade8fe4ea0fd9ecb72617f0928 Mon Sep 17 00:00:00 2001 +From: Francisco Jerez +Date: Thu, 5 Aug 2010 22:57:08 +0200 +Subject: [PATCH 3/5] drm-i2c-ch7006-fix + +drm/i2c/ch7006: Don't use POWER_LEVEL_FULL_POWER_OFF on early chip versions. + +Signed-off-by: Francisco Jerez +--- + drivers/gpu/drm/i2c/ch7006_drv.c | 1 + + drivers/gpu/drm/i2c/ch7006_mode.c | 5 ++++- + drivers/gpu/drm/i2c/ch7006_priv.h | 1 + + 3 files changed, 6 insertions(+), 1 deletions(-) + +diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c +index 81681a0..8c760c7 100644 +--- a/drivers/gpu/drm/i2c/ch7006_drv.c ++++ b/drivers/gpu/drm/i2c/ch7006_drv.c +@@ -454,6 +454,7 @@ static int ch7006_encoder_init(struct i2c_client *client, + priv->hmargin = 50; + priv->vmargin = 50; + priv->last_dpms = -1; ++ priv->chip_version = ch7006_read(client, CH7006_VERSION_ID); + + if (ch7006_tv_norm) { + for (i = 0; i < NUM_TV_NORMS; i++) { +diff --git a/drivers/gpu/drm/i2c/ch7006_mode.c b/drivers/gpu/drm/i2c/ch7006_mode.c +index e447dfb..c860f24 100644 +--- a/drivers/gpu/drm/i2c/ch7006_mode.c ++++ b/drivers/gpu/drm/i2c/ch7006_mode.c +@@ -316,7 +316,10 @@ void ch7006_setup_power_state(struct drm_encoder *encoder) + } + + } else { +- *power |= bitfs(CH7006_POWER_LEVEL, FULL_POWER_OFF); ++ if (priv->chip_version >= 0x20) ++ *power |= bitfs(CH7006_POWER_LEVEL, FULL_POWER_OFF); ++ else ++ *power |= bitfs(CH7006_POWER_LEVEL, POWER_OFF); + } + } + +diff --git a/drivers/gpu/drm/i2c/ch7006_priv.h b/drivers/gpu/drm/i2c/ch7006_priv.h +index b06d3d9..9487123 100644 +--- a/drivers/gpu/drm/i2c/ch7006_priv.h ++++ b/drivers/gpu/drm/i2c/ch7006_priv.h +@@ -95,6 +95,7 @@ struct ch7006_priv { + int flicker; + int scale; + ++ int chip_version; + int last_dpms; + }; + +-- +1.7.2 + diff --git a/drm-i915-blacklist-lighting-edp-pipes.patch b/drm-i915-blacklist-lighting-edp-pipes.patch new file mode 100644 index 000000000..153eb7768 --- /dev/null +++ b/drm-i915-blacklist-lighting-edp-pipes.patch @@ -0,0 +1,50 @@ +https://bugzilla.redhat.com/show_bug.cgi?id=639146 + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index ce8ff0e..3bbd2c4 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1353,6 +1353,27 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev) + return can_switch; + } + ++/* check the VBT to see whether the eDP is on DP-D port */ ++static bool intel_dpd_is_edp(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct child_device_config *p_child; ++ int i; ++ ++ if (!dev_priv->child_dev_num) ++ return false; ++ ++ for (i = 0; i < dev_priv->child_dev_num; i++) { ++ p_child = dev_priv->child_dev + i; ++ ++ if (p_child->dvo_port == PORT_IDPD && ++ p_child->device_type == DEVICE_TYPE_eDP) ++ return true; ++ } ++ ++ return false; ++} ++ + static int i915_load_modeset_init(struct drm_device *dev, + unsigned long prealloc_start, + unsigned long prealloc_size, +@@ -1409,6 +1430,15 @@ static int i915_load_modeset_init(struct drm_device *dev, + if (ret) + DRM_INFO("failed to find VBIOS tables\n"); + ++ /* XXX: eDP doesn't even work in git HEAD, ++ * bail out and pray that text mode still works... ++ */ ++ if (intel_dpd_is_edp(dev)) { ++ DRM_ERROR("eDP support is currently non-functional, please boot with \"nomodeset xdriver=vesa\"\n"); ++ ret = -EINVAL; ++ goto cleanup_ringbuffer; ++ } ++ + /* if we have > 1 VGA cards, then disable the radeon VGA resources */ + ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode); + if (ret) diff --git a/drm-i915-disable-sr-polling.patch b/drm-i915-disable-sr-polling.patch new file mode 100644 index 000000000..71d1fabd7 --- /dev/null +++ b/drm-i915-disable-sr-polling.patch @@ -0,0 +1,70 @@ +From ab7959dd389be36c0bc63e3e883b7891d2c1bfc4 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 8 Sep 2010 09:45:11 +0100 +Subject: [PATCH] drm/i915: Disable output polling across suspend & resume + +Suspending (especially hibernating) may take a finite amount of time, +during which a hotplug event may trigger and we will attempt to handle +it with inconsistent state. Disable hotplug polling around suspend and +resume. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=30070 +Reported-by: Rui Tiago Matos +Signed-off-by: Chris Wilson +--- + drivers/gpu/drm/i915/i915_dma.c | 2 -- + drivers/gpu/drm/i915/i915_drv.c | 11 ++++++++++- + 2 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index ce8ff0e..c569617 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1334,10 +1334,8 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_ + /* i915 resume handler doesn't set to D0 */ + pci_set_power_state(dev->pdev, PCI_D0); + i915_resume(dev); +- drm_kms_helper_poll_enable(dev); + } else { + printk(KERN_ERR "i915: switched off\n"); +- drm_kms_helper_poll_disable(dev); + i915_suspend(dev, pmm); + } + } +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 194e0c4..3ad3ebe 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -263,6 +263,8 @@ int i915_suspend(struct drm_device *dev, pm_message_t state) + if (state.event == PM_EVENT_PRETHAW) + return 0; + ++ drm_kms_helper_poll_disable(dev); ++ + error = i915_drm_freeze(dev); + if (error) + return error; +@@ -306,12 +308,19 @@ static int i915_drm_thaw(struct drm_device *dev) + + int i915_resume(struct drm_device *dev) + { ++ int ret; ++ + if (pci_enable_device(dev->pdev)) + return -EIO; + + pci_set_master(dev->pdev); + +- return i915_drm_thaw(dev); ++ ret = i915_drm_thaw(dev); ++ if (ret) ++ return ret; ++ ++ drm_kms_helper_poll_enable(dev); ++ return 0; + } + + /** +-- +1.7.2.3 + diff --git a/drm-i915-sanity-check-pread-pwrite.patch b/drm-i915-sanity-check-pread-pwrite.patch new file mode 100644 index 000000000..b5eb2dda8 --- /dev/null +++ b/drm-i915-sanity-check-pread-pwrite.patch @@ -0,0 +1,89 @@ +From ce9d419dbecc292cc3e06e8b1d6d123d3fa813a4 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Sun, 26 Sep 2010 20:50:05 +0100 +Subject: drm/i915: Sanity check pread/pwrite + +From: Chris Wilson + +commit ce9d419dbecc292cc3e06e8b1d6d123d3fa813a4 upstream. + +Move the access control up from the fast paths, which are no longer +universally taken first, up into the caller. This then duplicates some +sanity checking along the slow paths, but is much simpler. +Tracked as CVE-2010-2962. + +Reported-by: Kees Cook +Signed-off-by: Chris Wilson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_gem.c | 28 ++++++++++++++++++++-------- + 1 file changed, 20 insertions(+), 8 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -465,8 +465,15 @@ i915_gem_pread_ioctl(struct drm_device * + */ + if (args->offset > obj->size || args->size > obj->size || + args->offset + args->size > obj->size) { +- drm_gem_object_unreference_unlocked(obj); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err; ++ } ++ ++ if (!access_ok(VERIFY_WRITE, ++ (char __user *)(uintptr_t)args->data_ptr, ++ args->size)) { ++ ret = -EFAULT; ++ goto err; + } + + if (i915_gem_object_needs_bit17_swizzle(obj)) { +@@ -478,8 +485,8 @@ i915_gem_pread_ioctl(struct drm_device * + file_priv); + } + ++err: + drm_gem_object_unreference_unlocked(obj); +- + return ret; + } + +@@ -568,8 +575,6 @@ i915_gem_gtt_pwrite_fast(struct drm_devi + + user_data = (char __user *) (uintptr_t) args->data_ptr; + remain = args->size; +- if (!access_ok(VERIFY_READ, user_data, remain)) +- return -EFAULT; + + + mutex_lock(&dev->struct_mutex); +@@ -928,8 +933,15 @@ i915_gem_pwrite_ioctl(struct drm_device + */ + if (args->offset > obj->size || args->size > obj->size || + args->offset + args->size > obj->size) { +- drm_gem_object_unreference_unlocked(obj); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err; ++ } ++ ++ if (!access_ok(VERIFY_READ, ++ (char __user *)(uintptr_t)args->data_ptr, ++ args->size)) { ++ ret = -EFAULT; ++ goto err; + } + + /* We can only do the GTT pwrite on untiled buffers, as otherwise +@@ -963,8 +975,8 @@ i915_gem_pwrite_ioctl(struct drm_device + DRM_INFO("pwrite failed %d\n", ret); + #endif + ++err: + drm_gem_object_unreference_unlocked(obj); +- + return ret; + } + diff --git a/drm-intel-big-hammer.patch b/drm-intel-big-hammer.patch new file mode 100644 index 000000000..63dc016b1 --- /dev/null +++ b/drm-intel-big-hammer.patch @@ -0,0 +1,16 @@ +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 37427e4..08af9db 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2553,6 +2553,11 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, + + mutex_lock(&dev->struct_mutex); + ++ /* We don't get the flushing right for these chipsets, use the ++ * big hamer for now to avoid random crashiness. */ ++ if (IS_I85X(dev) || IS_I865G(dev)) ++ wbinvd(); ++ + i915_verify_inactive(dev, __FILE__, __LINE__); + + if (dev_priv->mm.wedged) { diff --git a/drm-intel-make-lvds-work.patch b/drm-intel-make-lvds-work.patch new file mode 100644 index 000000000..5ca0152da --- /dev/null +++ b/drm-intel-make-lvds-work.patch @@ -0,0 +1,19 @@ +diff -up linux-2.6.33.noarch/drivers/gpu/drm/i915/intel_display.c.orig linux-2.6.33.noarch/drivers/gpu/drm/i915/intel_display.c +--- linux-2.6.33.noarch/drivers/gpu/drm/i915/intel_display.c.orig 2010-03-31 16:59:39.901995671 -0400 ++++ linux-2.6.33.noarch/drivers/gpu/drm/i915/intel_display.c 2010-03-31 17:01:05.416996744 -0400 +@@ -3757,7 +3757,6 @@ struct drm_crtc *intel_get_load_detect_p + void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpms_mode) + { + struct drm_encoder *encoder = &intel_encoder->enc; +- struct drm_device *dev = encoder->dev; + struct drm_crtc *crtc = encoder->crtc; + struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; +@@ -3767,7 +3766,6 @@ void intel_release_load_detect_pipe(stru + intel_encoder->base.encoder = NULL; + intel_encoder->load_detect_temp = false; + crtc->enabled = drm_helper_crtc_in_use(crtc); +- drm_helper_disable_unused_functions(dev); + } + + /* Switch crtc and output back off if necessary */ diff --git a/drm-intel-next.patch b/drm-intel-next.patch new file mode 100644 index 000000000..c6cac6926 --- /dev/null +++ b/drm-intel-next.patch @@ -0,0 +1 @@ +empty diff --git a/drm-lower-severity-radeon-lockup.diff b/drm-lower-severity-radeon-lockup.diff new file mode 100644 index 000000000..a550d48f7 --- /dev/null +++ b/drm-lower-severity-radeon-lockup.diff @@ -0,0 +1,11 @@ +--- linux-2.6.35.noarch/drivers/gpu/drm/radeon/radeon_fence.c~ 2011-10-21 14:08:15.229351796 -0400 ++++ linux-2.6.35.noarch/drivers/gpu/drm/radeon/radeon_fence.c 2011-10-21 14:08:35.140287089 -0400 +@@ -232,7 +232,7 @@ retry: + */ + if (seq == rdev->fence_drv.last_seq && radeon_gpu_is_lockup(rdev)) { + /* good news we believe it's a lockup */ +- WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", fence->seq, seq); ++ printk(KERN_WARNING, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", fence->seq, seq); + /* FIXME: what should we do ? marking everyone + * as signaled for now + */ diff --git a/drm-nouveau-connector-fix.patch b/drm-nouveau-connector-fix.patch new file mode 100644 index 000000000..0f67d44dc --- /dev/null +++ b/drm-nouveau-connector-fix.patch @@ -0,0 +1,21 @@ +diff -up linux-2.6.35.x86_64/drivers/gpu/drm/nouveau/nouveau_connector.c.da linux-2.6.35.x86_64/drivers/gpu/drm/nouveau/nouveau_connector.c +--- linux-2.6.35.x86_64/drivers/gpu/drm/nouveau/nouveau_connector.c.da 2010-11-08 19:55:42.000000000 -0500 ++++ linux-2.6.35.x86_64/drivers/gpu/drm/nouveau/nouveau_connector.c 2010-11-08 19:55:49.000000000 -0500 +@@ -298,7 +298,7 @@ detect_analog: + } + + static enum drm_connector_status +-nouveau_connector_detect_lvds(struct drm_connector *connector) ++nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) + { + struct drm_device *dev = connector->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; +@@ -319,7 +319,7 @@ nouveau_connector_detect_lvds(struct drm + + /* Try retrieving EDID via DDC */ + if (!dev_priv->vbios.fp_no_ddc) { +- status = nouveau_connector_detect(connector); ++ status = nouveau_connector_detect(connector, force); + if (status == connector_status_connected) + goto out; + } diff --git a/drm-nouveau-evo-hang.patch b/drm-nouveau-evo-hang.patch new file mode 100644 index 000000000..aedc9c5b0 --- /dev/null +++ b/drm-nouveau-evo-hang.patch @@ -0,0 +1,32 @@ +From d0301ece9e093c484f880893dc86d97848360892 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Fri, 19 Nov 2010 18:50:57 +1000 +Subject: [PATCH 2/2] drm-nouveau-evo-hang + +On some GF8+ boards, the display engine will stop processing its push +buffer if a wrap-around occurs at a certain point. The exact cause +is not known. + +This patch by David Dillow (rhbz#537065) is a safe enough work-around +until it can be solved properly. + +Signed-off-by: Ben Skeggs +--- + drivers/gpu/drm/nouveau/nv50_display.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c +index 11d366a..4e5402c 100644 +--- a/drivers/gpu/drm/nouveau/nv50_display.c ++++ b/drivers/gpu/drm/nouveau/nv50_display.c +@@ -364,6 +364,7 @@ nv50_display_init(struct drm_device *dev) + nv_wr32(dev, 0x610300, nv_rd32(dev, 0x610300) & ~1); + + evo->dma.max = (4096/4) - 2; ++ evo->dma.max &= ~7; + evo->dma.put = 0; + evo->dma.cur = evo->dma.put; + evo->dma.free = evo->dma.max - evo->dma.cur; +-- +1.7.3.2 + diff --git a/drm-nouveau-imac-g4.patch b/drm-nouveau-imac-g4.patch new file mode 100644 index 000000000..316605e74 --- /dev/null +++ b/drm-nouveau-imac-g4.patch @@ -0,0 +1,167 @@ +From b4166db6d1f951a460e5e7f52bb4b4d96f27f55a Mon Sep 17 00:00:00 2001 +From: Francisco Jerez +Date: Fri, 19 Nov 2010 18:08:47 +1000 +Subject: [PATCH 1/2] drm-nouveau-imac-g4 + +drm/nouveau: fabricate DCB encoder table for iMac G4 + +In typical Apple fashion there's no standard information about what +encoders are present on this machine, this patch adds a quirk to +provide it. + +Signed-off-by: Francisco Jerez +Signed-off-by: Ben Skeggs +--- + drivers/gpu/drm/nouveau/nouveau_bios.c | 102 ++++++++++++-------------------- + 1 files changed, 38 insertions(+), 64 deletions(-) + +diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c +index 72905c9..8c287f8 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_bios.c ++++ b/drivers/gpu/drm/nouveau/nouveau_bios.c +@@ -5985,52 +5985,17 @@ static struct dcb_entry *new_dcb_entry(struct dcb_table *dcb) + return entry; + } + +-static void fabricate_vga_output(struct dcb_table *dcb, int i2c, int heads) ++static void fabricate_dcb_output(struct dcb_table *dcb, int type, int i2c, ++ int heads, int or) + { + struct dcb_entry *entry = new_dcb_entry(dcb); + +- entry->type = 0; ++ entry->type = type; + entry->i2c_index = i2c; + entry->heads = heads; +- entry->location = DCB_LOC_ON_CHIP; +- entry->or = 1; +-} +- +-static void fabricate_dvi_i_output(struct dcb_table *dcb, bool twoHeads) +-{ +- struct dcb_entry *entry = new_dcb_entry(dcb); +- +- entry->type = 2; +- entry->i2c_index = LEGACY_I2C_PANEL; +- entry->heads = twoHeads ? 3 : 1; +- entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */ +- entry->or = 1; /* means |0x10 gets set on CRE_LCD__INDEX */ +- entry->duallink_possible = false; /* SiI164 and co. are single link */ +- +-#if 0 +- /* +- * For dvi-a either crtc probably works, but my card appears to only +- * support dvi-d. "nvidia" still attempts to program it for dvi-a, +- * doing the full fp output setup (program 0x6808.. fp dimension regs, +- * setting 0x680848 to 0x10000111 to enable, maybe setting 0x680880); +- * the monitor picks up the mode res ok and lights up, but no pixel +- * data appears, so the board manufacturer probably connected up the +- * sync lines, but missed the video traces / components +- * +- * with this introduction, dvi-a left as an exercise for the reader. +- */ +- fabricate_vga_output(dcb, LEGACY_I2C_PANEL, entry->heads); +-#endif +-} +- +-static void fabricate_tv_output(struct dcb_table *dcb, bool twoHeads) +-{ +- struct dcb_entry *entry = new_dcb_entry(dcb); +- +- entry->type = 1; +- entry->i2c_index = LEGACY_I2C_TV; +- entry->heads = twoHeads ? 3 : 1; +- entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */ ++ if (type != OUTPUT_ANALOG) ++ entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */ ++ entry->or = or; + } + + static bool +@@ -6297,8 +6262,36 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) + return true; + } + ++static void ++fabricate_dcb_encoder_table(struct drm_device *dev, struct nvbios *bios) ++{ ++ struct dcb_table *dcb = &bios->dcb; ++ int all_heads = (nv_two_heads(dev) ? 3 : 1); ++ ++#ifdef __powerpc__ ++ /* Apple iMac G4 NV17 */ ++ if (of_machine_is_compatible("PowerMac4,5")) { ++ fabricate_dcb_output(dcb, OUTPUT_TMDS, 0, all_heads, 1); ++ fabricate_dcb_output(dcb, OUTPUT_ANALOG, 1, all_heads, 2); ++ return; ++ } ++#endif ++ ++ /* Make up some sane defaults */ ++ fabricate_dcb_output(dcb, OUTPUT_ANALOG, LEGACY_I2C_CRT, 1, 1); ++ ++ if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0) ++ fabricate_dcb_output(dcb, OUTPUT_TV, LEGACY_I2C_TV, ++ all_heads, 0); ++ ++ else if (bios->tmds.output0_script_ptr || ++ bios->tmds.output1_script_ptr) ++ fabricate_dcb_output(dcb, OUTPUT_TMDS, LEGACY_I2C_PANEL, ++ all_heads, 1); ++} ++ + static int +-parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) ++parse_dcb_table(struct drm_device *dev, struct nvbios *bios) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct dcb_table *dcb = &bios->dcb; +@@ -6318,12 +6311,7 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) + + /* this situation likely means a really old card, pre DCB */ + if (dcbptr == 0x0) { +- NV_INFO(dev, "Assuming a CRT output exists\n"); +- fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1); +- +- if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0) +- fabricate_tv_output(dcb, twoHeads); +- ++ fabricate_dcb_encoder_table(dev, bios); + return 0; + } + +@@ -6383,21 +6371,7 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) + */ + NV_TRACEWARN(dev, "No useful information in BIOS output table; " + "adding all possible outputs\n"); +- fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1); +- +- /* +- * Attempt to detect TV before DVI because the test +- * for the former is more accurate and it rules the +- * latter out. +- */ +- if (nv04_tv_identify(dev, +- bios->legacy.i2c_indices.tv) >= 0) +- fabricate_tv_output(dcb, twoHeads); +- +- else if (bios->tmds.output0_script_ptr || +- bios->tmds.output1_script_ptr) +- fabricate_dvi_i_output(dcb, twoHeads); +- ++ fabricate_dcb_encoder_table(dev, bios); + return 0; + } + +@@ -6787,7 +6761,7 @@ nouveau_bios_init(struct drm_device *dev) + if (ret) + return ret; + +- ret = parse_dcb_table(dev, bios, nv_two_heads(dev)); ++ ret = parse_dcb_table(dev, bios); + if (ret) + return ret; + +-- +1.7.3.2 + diff --git a/drm-nouveau-init5c.patch b/drm-nouveau-init5c.patch new file mode 100644 index 000000000..a17cfde32 --- /dev/null +++ b/drm-nouveau-init5c.patch @@ -0,0 +1,72 @@ +From 2120b3b32d96d523b18c82beb99a2d1c6135eb49 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Mon, 21 Mar 2011 21:31:21 +1000 +Subject: [PATCH] drm/nouveau: implement init table opcode 0x5c + +Signed-off-by: Ben Skeggs +--- + drivers/gpu/drm/nouveau/nouveau_bios.c | 27 ++++++++++++++++++++++++--- + 1 files changed, 24 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c +index 8314a49..eca191a 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_bios.c ++++ b/drivers/gpu/drm/nouveau/nouveau_bios.c +@@ -269,7 +269,7 @@ struct init_tbl_entry { + int (*handler)(struct nvbios *, uint16_t, struct init_exec *); + }; + +-static int parse_init_table(struct nvbios *, unsigned int, struct init_exec *); ++static int parse_init_table(struct nvbios *, uint16_t, struct init_exec *); + + #define MACRO_INDEX_SIZE 2 + #define MACRO_SIZE 8 +@@ -2011,6 +2011,27 @@ init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + } + + static int ++init_jump(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ++{ ++ /* ++ * INIT_JUMP opcode: 0x5C ('\') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (16 bit): offset (in bios) ++ * ++ * Continue execution of init table from 'offset' ++ */ ++ ++ uint16_t jmp_offset = ROM16(bios->data[offset + 1]); ++ ++ if (!iexec->execute) ++ return 3; ++ ++ BIOSLOG(bios, "0x%04X: Jump to 0x%04X\n", offset, jmp_offset); ++ return jmp_offset - offset; ++} ++ ++static int + init_i2c_if(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + { + /* +@@ -3659,6 +3680,7 @@ static struct init_tbl_entry itbl_entry[] = { + { "INIT_ZM_REG_SEQUENCE" , 0x58, init_zm_reg_sequence }, + /* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */ + { "INIT_SUB_DIRECT" , 0x5B, init_sub_direct }, ++ { "INIT_JUMP" , 0x5C, init_jump }, + { "INIT_I2C_IF" , 0x5E, init_i2c_if }, + { "INIT_COPY_NV_REG" , 0x5F, init_copy_nv_reg }, + { "INIT_ZM_INDEX_IO" , 0x62, init_zm_index_io }, +@@ -3700,8 +3722,7 @@ static struct init_tbl_entry itbl_entry[] = { + #define MAX_TABLE_OPS 1000 + + static int +-parse_init_table(struct nvbios *bios, unsigned int offset, +- struct init_exec *iexec) ++parse_init_table(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + { + /* + * Parses all commands in an init table. +-- +1.7.4.1 + diff --git a/drm-nouveau-nv50-crtc-update-delay.patch b/drm-nouveau-nv50-crtc-update-delay.patch new file mode 100644 index 000000000..319770cba --- /dev/null +++ b/drm-nouveau-nv50-crtc-update-delay.patch @@ -0,0 +1,33 @@ +From 8f51b07995c55369bfd27921ef10b76c2b203fe8 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Tue, 17 Aug 2010 14:20:29 +1000 +Subject: [PATCH] drm-nouveau-nv50-crtc-update-delay + +rhbz#614552 + +Adds a short delay before doing framebuffer-only CRTC updates. Fixes +an issue that effects some cards (Quadro NVS295/FX580) where two of +these updates in quick succession hangs the display engine. + +Signed-off-by: Ben Skeggs +--- + drivers/gpu/drm/nouveau/nv50_crtc.c | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c +index 2423c92..5c2aa1e 100644 +--- a/drivers/gpu/drm/nouveau/nv50_crtc.c ++++ b/drivers/gpu/drm/nouveau/nv50_crtc.c +@@ -540,6 +540,9 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y, + nouveau_bo_unpin(ofb->nvbo); + } + ++ if (update) ++ mdelay(1); ++ + nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base; + nv_crtc->fb.tile_flags = fb->nvbo->tile_flags; + nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8; +-- +1.7.3.1 + diff --git a/drm-nouveau-nv86-bug.patch b/drm-nouveau-nv86-bug.patch new file mode 100644 index 000000000..aee3bedaf --- /dev/null +++ b/drm-nouveau-nv86-bug.patch @@ -0,0 +1,231 @@ +From e7e3837f6395e44b5b5fb7cdbcccaba5baf76803 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Fri, 22 Oct 2010 10:26:24 +1000 +Subject: [PATCH] drm-nouveau-nv86-bug + +drm/nv50: implement possible workaround for NV86 PGRAPH TLB flush hang + +Signed-off-by: Ben Skeggs +--- + drivers/gpu/drm/nouveau/nouveau_drv.h | 5 +++ + drivers/gpu/drm/nouveau/nouveau_mem.c | 14 +++----- + drivers/gpu/drm/nouveau/nouveau_sgdma.c | 8 ++-- + drivers/gpu/drm/nouveau/nouveau_state.c | 10 ++++++ + drivers/gpu/drm/nouveau/nv50_fifo.c | 5 +++ + drivers/gpu/drm/nouveau/nv50_graph.c | 52 +++++++++++++++++++++++++++++++ + drivers/gpu/drm/nouveau/nv50_instmem.c | 1 - + 7 files changed, 82 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h +index be53e92..4273390 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_drv.h ++++ b/drivers/gpu/drm/nouveau/nouveau_drv.h +@@ -304,6 +304,7 @@ struct nouveau_fifo_engine { + void (*destroy_context)(struct nouveau_channel *); + int (*load_context)(struct nouveau_channel *); + int (*unload_context)(struct drm_device *); ++ void (*tlb_flush)(struct drm_device *dev); + }; + + struct nouveau_pgraph_object_method { +@@ -336,6 +337,7 @@ struct nouveau_pgraph_engine { + void (*destroy_context)(struct nouveau_channel *); + int (*load_context)(struct nouveau_channel *); + int (*unload_context)(struct drm_device *); ++ void (*tlb_flush)(struct drm_device *dev); + + void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr, + uint32_t size, uint32_t pitch); +@@ -944,6 +946,7 @@ extern int nv50_fifo_create_context(struct nouveau_channel *); + extern void nv50_fifo_destroy_context(struct nouveau_channel *); + extern int nv50_fifo_load_context(struct nouveau_channel *); + extern int nv50_fifo_unload_context(struct drm_device *); ++extern void nv50_fifo_tlb_flush(struct drm_device *dev); + + /* nvc0_fifo.c */ + extern int nvc0_fifo_init(struct drm_device *); +@@ -1021,6 +1024,8 @@ extern int nv50_graph_load_context(struct nouveau_channel *); + extern int nv50_graph_unload_context(struct drm_device *); + extern void nv50_graph_context_switch(struct drm_device *); + extern int nv50_grctx_init(struct nouveau_grctx *); ++extern void nv50_graph_tlb_flush(struct drm_device *dev); ++extern void nv86_graph_tlb_flush(struct drm_device *dev); + + /* nvc0_graph.c */ + extern int nvc0_graph_init(struct drm_device *); +diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c +index 4f0ae39..514ad9f 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_mem.c ++++ b/drivers/gpu/drm/nouveau/nouveau_mem.c +@@ -173,11 +173,10 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, + } + } + } +- dev_priv->engine.instmem.flush(dev); + +- nv50_vm_flush(dev, 5); +- nv50_vm_flush(dev, 0); +- nv50_vm_flush(dev, 4); ++ dev_priv->engine.instmem.flush(dev); ++ dev_priv->engine.fifo.tlb_flush(dev); ++ dev_priv->engine.graph.tlb_flush(dev); + nv50_vm_flush(dev, 6); + return 0; + } +@@ -207,11 +206,10 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) + pte++; + } + } +- dev_priv->engine.instmem.flush(dev); + +- nv50_vm_flush(dev, 5); +- nv50_vm_flush(dev, 0); +- nv50_vm_flush(dev, 4); ++ dev_priv->engine.instmem.flush(dev); ++ dev_priv->engine.fifo.tlb_flush(dev); ++ dev_priv->engine.graph.tlb_flush(dev); + nv50_vm_flush(dev, 6); + } + +diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c +index 7f028fe..d55a583 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c ++++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c +@@ -120,8 +120,8 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) + dev_priv->engine.instmem.flush(nvbe->dev); + + if (dev_priv->card_type == NV_50) { +- nv50_vm_flush(dev, 5); /* PGRAPH */ +- nv50_vm_flush(dev, 0); /* PFIFO */ ++ dev_priv->engine.fifo.tlb_flush(dev); ++ dev_priv->engine.graph.tlb_flush(dev); + } + + nvbe->bound = true; +@@ -162,8 +162,8 @@ nouveau_sgdma_unbind(struct ttm_backend *be) + dev_priv->engine.instmem.flush(nvbe->dev); + + if (dev_priv->card_type == NV_50) { +- nv50_vm_flush(dev, 5); +- nv50_vm_flush(dev, 0); ++ dev_priv->engine.fifo.tlb_flush(dev); ++ dev_priv->engine.graph.tlb_flush(dev); + } + + nvbe->bound = false; +diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c +index be85960..47c353c 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_state.c ++++ b/drivers/gpu/drm/nouveau/nouveau_state.c +@@ -333,6 +333,15 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->graph.destroy_context = nv50_graph_destroy_context; + engine->graph.load_context = nv50_graph_load_context; + engine->graph.unload_context = nv50_graph_unload_context; ++ if (dev_priv->chipset != 0x86) ++ engine->graph.tlb_flush = nv50_graph_tlb_flush; ++ else { ++ /* from what i can see nvidia do this on every ++ * pre-NVA3 board except NVAC, but, we've only ++ * ever seen problems on NV86 ++ */ ++ engine->graph.tlb_flush = nv86_graph_tlb_flush; ++ } + engine->fifo.channels = 128; + engine->fifo.init = nv50_fifo_init; + engine->fifo.takedown = nv50_fifo_takedown; +@@ -344,6 +353,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->fifo.destroy_context = nv50_fifo_destroy_context; + engine->fifo.load_context = nv50_fifo_load_context; + engine->fifo.unload_context = nv50_fifo_unload_context; ++ engine->fifo.tlb_flush = nv50_fifo_tlb_flush; + engine->display.early_init = nv50_display_early_init; + engine->display.late_takedown = nv50_display_late_takedown; + engine->display.create = nv50_display_create; +diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c +index a46a961..1da65bd 100644 +--- a/drivers/gpu/drm/nouveau/nv50_fifo.c ++++ b/drivers/gpu/drm/nouveau/nv50_fifo.c +@@ -464,3 +464,8 @@ nv50_fifo_unload_context(struct drm_device *dev) + return 0; + } + ++void ++nv50_fifo_tlb_flush(struct drm_device *dev) ++{ ++ nv50_vm_flush(dev, 5); ++} +diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c +index cbf5ae2..8b669d0 100644 +--- a/drivers/gpu/drm/nouveau/nv50_graph.c ++++ b/drivers/gpu/drm/nouveau/nv50_graph.c +@@ -402,3 +402,55 @@ struct nouveau_pgraph_object_class nv50_graph_grclass[] = { + { 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */ + {} + }; ++ ++void ++nv50_graph_tlb_flush(struct drm_device *dev) ++{ ++ nv50_vm_flush(dev, 0); ++} ++ ++void ++nv86_graph_tlb_flush(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; ++ bool idle, timeout = false; ++ unsigned long flags; ++ u64 start; ++ u32 tmp; ++ ++ spin_lock_irqsave(&dev_priv->context_switch_lock, flags); ++ nv_mask(dev, 0x400500, 0x00000001, 0x00000000); ++ ++ start = ptimer->read(dev); ++ do { ++ idle = true; ++ ++ for (tmp = nv_rd32(dev, 0x400380); tmp && idle; tmp >>= 3) { ++ if ((tmp & 7) == 1) ++ idle = false; ++ } ++ ++ for (tmp = nv_rd32(dev, 0x400384); tmp && idle; tmp >>= 3) { ++ if ((tmp & 7) == 1) ++ idle = false; ++ } ++ ++ for (tmp = nv_rd32(dev, 0x400388); tmp && idle; tmp >>= 3) { ++ if ((tmp & 7) == 1) ++ idle = false; ++ } ++ } while (!idle && !(timeout = ptimer->read(dev) - start > 2000000000)); ++ ++ if (timeout) { ++ NV_ERROR(dev, "PGRAPH TLB flush idle timeout fail: " ++ "0x%08x 0x%08x 0x%08x 0x%08x\n", ++ nv_rd32(dev, 0x400700), nv_rd32(dev, 0x400380), ++ nv_rd32(dev, 0x400384), nv_rd32(dev, 0x400388)); ++ } ++ ++ nv50_vm_flush(dev, 0); ++ ++ nv_mask(dev, 0x400500, 0x00000001, 0x00000001); ++ spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); ++} +diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c +index ac3de05..c836ddc 100644 +--- a/drivers/gpu/drm/nouveau/nv50_instmem.c ++++ b/drivers/gpu/drm/nouveau/nv50_instmem.c +@@ -402,7 +402,6 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) + } + dev_priv->engine.instmem.flush(dev); + +- nv50_vm_flush(dev, 4); + nv50_vm_flush(dev, 6); + + gpuobj->im_bound = 1; +-- +1.7.3.1 + diff --git a/drm-nouveau-nva3-noaccel.patch b/drm-nouveau-nva3-noaccel.patch new file mode 100644 index 000000000..7dd9678f4 --- /dev/null +++ b/drm-nouveau-nva3-noaccel.patch @@ -0,0 +1,106 @@ +From 07a51882863d9e45b0715dcffbb66491adf2fb4e Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Wed, 30 Jun 2010 13:34:05 +1000 +Subject: [PATCH] drm/nouveau: disable acceleration on NVA3/NVA5/NVA8 by default + +There's an GPU lockup problem for which the cause is currently unknown +on these chipsets. + +Until it's resolved, it's better to leave the user with a working system +without acceleration than to have random lockups. + +With this patch, acceleration will be off by default if a known problem +chipset is detected, but can be re-enabled with nouveau.noaccel=0 on +the kernel commandline. + +Signed-off-by: Ben Skeggs +--- + drivers/gpu/drm/nouveau/nouveau_drv.c | 2 +- + drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + + drivers/gpu/drm/nouveau/nouveau_state.c | 23 +++++++++++++++++++---- + 3 files changed, 21 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c +index 946748a..9b69328 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_drv.c ++++ b/drivers/gpu/drm/nouveau/nouveau_drv.c +@@ -72,7 +72,7 @@ int nouveau_ignorelid = 0; + module_param_named(ignorelid, nouveau_ignorelid, int, 0400); + + MODULE_PARM_DESC(noaccel, "Disable all acceleration"); +-int nouveau_noaccel = 0; ++int nouveau_noaccel = -1; + module_param_named(noaccel, nouveau_noaccel, int, 0400); + + MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration"); +diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h +index 24b3d03..0cf1bee 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_drv.h ++++ b/drivers/gpu/drm/nouveau/nouveau_drv.h +@@ -504,6 +504,7 @@ enum nouveau_card_type { + + struct drm_nouveau_private { + struct drm_device *dev; ++ bool noaccel; + + /* the card type, takes NV_* as values */ + enum nouveau_card_type card_type; +diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c +index be85960..896f6ae 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_state.c ++++ b/drivers/gpu/drm/nouveau/nouveau_state.c +@@ -563,7 +563,7 @@ nouveau_card_init(struct drm_device *dev) + if (ret) + goto out_timer; + +- if (nouveau_noaccel) ++ if (dev_priv->noaccel) + engine->graph.accel_blocked = true; + else { + /* PGRAPH */ +@@ -613,10 +613,10 @@ out_irq: + out_display: + engine->display.destroy(dev); + out_fifo: +- if (!nouveau_noaccel) ++ if (!dev_priv->noaccel) + engine->fifo.takedown(dev); + out_graph: +- if (!nouveau_noaccel) ++ if (!dev_priv->noaccel) + engine->graph.takedown(dev); + out_fb: + engine->fb.takedown(dev); +@@ -655,7 +655,7 @@ static void nouveau_card_takedown(struct drm_device *dev) + dev_priv->channel = NULL; + } + +- if (!nouveau_noaccel) { ++ if (!dev_priv->noaccel) { + engine->fifo.takedown(dev); + engine->graph.takedown(dev); + } +@@ -861,6 +861,21 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) + if (ret) + goto err_mmio; + ++ if (nouveau_noaccel == -1) { ++ switch (dev_priv->chipset) { ++ case 0xa3: ++ case 0xa5: ++ case 0xa8: ++ dev_priv->noaccel = true; ++ break; ++ default: ++ dev_priv->noaccel = false; ++ break; ++ } ++ } else { ++ dev_priv->noaccel = (nouveau_noaccel != 0); ++ } ++ + /* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */ + if (dev_priv->card_type >= NV_40) { + int ramin_bar = 2; +-- +1.7.2.2 diff --git a/drm-nouveau-nvaf-grclass.patch b/drm-nouveau-nvaf-grclass.patch new file mode 100644 index 000000000..87e05f47f --- /dev/null +++ b/drm-nouveau-nvaf-grclass.patch @@ -0,0 +1,25 @@ +From 7abba51e3fc9e3fdd43c63eeb1a680a2e258a833 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Fri, 19 Nov 2010 18:59:15 +1000 +Subject: [PATCH] drm-nouveau-nvaf-grclass + +Signed-off-by: Ben Skeggs +--- + drivers/gpu/drm/nouveau/nv50_graph.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c +index 8b669d0..235be5f 100644 +--- a/drivers/gpu/drm/nouveau/nv50_graph.c ++++ b/drivers/gpu/drm/nouveau/nv50_graph.c +@@ -400,6 +400,7 @@ struct nouveau_pgraph_object_class nv50_graph_grclass[] = { + { 0x8297, false, NULL }, /* tesla (nv8x/nv9x) */ + { 0x8397, false, NULL }, /* tesla (nva0, nvaa, nvac) */ + { 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */ ++ { 0x8697, false, NULL }, /* tesla (nvaf) */ + {} + }; + +-- +1.7.3.2 + diff --git a/drm-nouveau-race-fix.patch b/drm-nouveau-race-fix.patch new file mode 100644 index 000000000..bf6cc4f83 --- /dev/null +++ b/drm-nouveau-race-fix.patch @@ -0,0 +1,141 @@ +From 4733f633c4bfb0672d5bd88a8d19a03e27a3c1d0 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Fri, 23 Jul 2010 09:06:52 +1000 +Subject: [PATCH 2/2] drm-nouveau-race-fix + +drm/nouveau: fix race condition when under memory pressure + +rhbz#602663 + +When VRAM is running out it's possible that the client's push buffers get +evicted to main memory. When they're validated back in, the GPU may +be used for the copy back to VRAM, but the existing synchronisation code +only deals with inter-channel sync, not sync between PFIFO and PGRAPH on +the same channel. This leads to PFIFO fetching from command buffers that +haven't quite been copied by PGRAPH yet. + +This patch marks push buffers as so, and forces any GPU-assisted buffer +moves to be done on a different channel, which triggers the correct +synchronisation to happen before we submit them. + +After discussion with another nouveau developer, it was agreed that while +this patch is fine in itself, that we'd prefer to work out a nicer, but +likely much more invasive, fix upstream. + +Signed-off-by: Ben Skeggs +--- + drivers/gpu/drm/nouveau/nouveau_bo.c | 15 +++++++++++++ + drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + + drivers/gpu/drm/nouveau/nouveau_gem.c | 36 +++++++++++++++++++++++--------- + 3 files changed, 42 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c +index 553a01d..5e62d1b 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_bo.c ++++ b/drivers/gpu/drm/nouveau/nouveau_bo.c +@@ -36,6 +36,21 @@ + #include + #include + ++int ++nouveau_bo_sync_gpu(struct nouveau_bo *nvbo, struct nouveau_channel *chan) ++{ ++ struct nouveau_fence *prev_fence = nvbo->bo.sync_obj; ++ int ret; ++ ++ if (!prev_fence || nouveau_fence_channel(prev_fence) == chan) ++ return 0; ++ ++ spin_lock(&nvbo->bo.lock); ++ ret = ttm_bo_wait(&nvbo->bo, false, false, false); ++ spin_unlock(&nvbo->bo.lock); ++ return ret; ++} ++ + static void + nouveau_bo_del_ttm(struct ttm_buffer_object *bo) + { +diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h +index 2eb622b..70a16f3 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_drv.h ++++ b/drivers/gpu/drm/nouveau/nouveau_drv.h +@@ -1167,6 +1167,7 @@ extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); + extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); + extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); + extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); ++extern int nouveau_bo_sync_gpu(struct nouveau_bo *, struct nouveau_channel *); + + /* nouveau_fence.c */ + struct nouveau_fence; +diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c +index 62ac673..613f878 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_gem.c ++++ b/drivers/gpu/drm/nouveau/nouveau_gem.c +@@ -361,16 +361,11 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, + + list_for_each_entry(nvbo, list, entry) { + struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; +- struct nouveau_fence *prev_fence = nvbo->bo.sync_obj; + +- if (prev_fence && nouveau_fence_channel(prev_fence) != chan) { +- spin_lock(&nvbo->bo.lock); +- ret = ttm_bo_wait(&nvbo->bo, false, false, false); +- spin_unlock(&nvbo->bo.lock); +- if (unlikely(ret)) { +- NV_ERROR(dev, "fail wait other chan\n"); +- return ret; +- } ++ ret = nouveau_bo_sync_gpu(nvbo, chan); ++ if (unlikely(ret)) { ++ NV_ERROR(dev, "fail pre-validate sync\n"); ++ return ret; + } + + ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, +@@ -381,7 +376,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, + return ret; + } + +- nvbo->channel = chan; ++ nvbo->channel = (b->read_domains & (1 << 31)) ? NULL : chan; + ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, + false, false, false); + nvbo->channel = NULL; +@@ -390,6 +385,12 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, + return ret; + } + ++ ret = nouveau_bo_sync_gpu(nvbo, chan); ++ if (unlikely(ret)) { ++ NV_ERROR(dev, "fail post-validate sync\n"); ++ return ret; ++ } ++ + if (nvbo->bo.offset == b->presumed.offset && + ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && + b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) || +@@ -615,6 +616,21 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, + + mutex_lock(&dev->struct_mutex); + ++ /* Mark push buffers as being used on PFIFO, the validation code ++ * will then make sure that if the pushbuf bo moves, that they ++ * happen on the kernel channel, which will in turn cause a sync ++ * to happen before we try and submit the push buffer. ++ */ ++ for (i = 0; i < req->nr_push; i++) { ++ if (push[i].bo_index >= req->nr_buffers) { ++ NV_ERROR(dev, "push %d buffer not in list\n", i); ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ bo[push[i].bo_index].read_domains |= (1 << 31); ++ } ++ + /* Validate buffer list */ + ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, + req->nr_buffers, &op, &do_reloc); +-- +1.7.2.2 + diff --git a/drm-nouveau-updates.patch b/drm-nouveau-updates.patch new file mode 100644 index 000000000..ec86a44d9 --- /dev/null +++ b/drm-nouveau-updates.patch @@ -0,0 +1,20420 @@ +From b1bfbda896a9d9d8e8bd86dd08aac2b2f9928ce1 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Tue, 1 Jun 2010 15:32:24 +1000 +Subject: [PATCH] drm-nouveau-updates +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +drm/nouveau: use drm_mm in preference to custom code doing the same thing + +Signed-off-by: Ben Skeggs + +drm/nouveau: remove left-over !DRIVER_MODESET paths + +It's far preferable to have the driver do nothing at all for "nomodeset". + +Signed-off-by: Ben Skeggs + +drm/nouveau: missed some braces + +Luckily this had absolutely no effect whatsoever :) + +Reported-by: Marcin Slusarz +Signed-off-by: Ben Skeggs + +drm/nouveau: move LVDS detection back to connector detect() time + +Signed-off-by: Ben Skeggs + +drm/nouveau: Put the dithering check back in nouveau_connector_create. + +a7b9f9e5adef dropped it by accident. + +Signed-off-by: Francisco Jerez +Tested-by: Thibaut Girka +Signed-off-by: Ben Skeggs + +drm/nouveau: Don't clear AGPCMD completely on INIT_RESET. + +We just need to clear the SBA and ENABLE bits to reset the AGP +controller: If the AGP bridge was configured to use "fast writes", +clearing the FW bit would break the subsequent MMIO writes and +eventually end with a lockup. + +Note that all the BIOSes I've seen do the same as we did (it works for +them because they don't use MMIO), OTOH the blob leaves FW untouched. + +Signed-off-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: Ignore broken legacy I2C entries. + +The nv05 card in the bug report [1] doesn't have usable I2C port +register offsets (they're all filled with zeros). Ignore them and use +the defaults. + +[1] http://bugs.launchpad.net/bugs/569505 + +Signed-off-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: set encoder for lvds + +fixes oops in nouveau_connector_get_modes with nv_encoder is NULL + +Signed-off-by: Albert Damen +Signed-off-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: tidy connector/encoder creation a little + +Create connectors before encoders to avoid having to do another loop across +encoder list whenever we create a new connector. This allows us to pass +the connector to the encoder creation functions, and avoid using a +create_resources() callback since we can now call it directly. + +This can also potentially modify the connector ordering on nv50. On cards +where the DCB connector and encoder tables are in the same order, things +will be unchanged. However, there's some cards where the ordering between +the tables differ, and in one case, leads us to naming the connectors +"wrongly". + +Signed-off-by: Ben Skeggs + +drm/nouveau: downgrade severity of most init table parser errors + +As long as we know the length of the opcode, we're probably better off +trying to parse the remainder of an init table rather than aborting in +the middle of it. + +Signed-off-by: Ben Skeggs + +drm/nv50: fix DP->DVI if output has been programmed for native DP previously + +Signed-off-by: Ben Skeggs + +drm/nv50: DCB quirk for Dell M6300 + +Uncertain if this is a weirdo configuration, or a BIOS bug. If it's not +a BIOS bug, we still don't know how to make it work anyway so ignore a +"conflicting" DCB entry to prevent a display hang. + +Signed-off-by: Ben Skeggs + +drm: disable encoder rather than dpms off in drm_crtc_prepare_encoders() + +Original behaviour will be preserved for drivers that don't implement +disable() hooks for an encoder. + +Signed-off-by: Ben Skeggs + +drm/nv50: supply encoder disable() hook for SOR outputs + +Allows us to remove a driver hack that used to be necessary to disable +encoders in certain situations before setting up a mode. The DRM has +better knowledge of when this is needed than the driver does. + +This fixes a number of display switching issues. + +Signed-off-by: Ben Skeggs + +drm/nv50: fix regression caused by ed15e77b6ee7c4fa6f50c18b3325e7f96ed3aade + +It became possible for us to have connectors present without any encoders +attached (TV out, we don't support TVDAC yet), which caused the DDX to +segfault. + +Signed-off-by: Ben Skeggs + +drm/nv04: fix regression caused by ed15e77b6ee7c4fa6f50c18b3325e7f96ed3aade + +Signed-off-by: Ben Skeggs + +drm/nv50: when debugging on, log which crtc we connect an encoder to + +Signed-off-by: Ben Skeggs + +drm/nv17-nv40: Avoid using active CRTCs for load detection. + +Signed-off-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nv04-nv40: Prevent invalid DAC/TVDAC combinations. + +Signed-off-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nv04-nv40: Disable connector polling when there're no spare CRTCs left. + +Load detection needs the connector wired to a CRTC, when there are no +inactive CRTCs left that means we need to cut some other head off for +a while, causing intermittent flickering. + +Signed-off-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nv50: fix memory detection for cards with >=4GiB VRAM + +Signed-off-by: Ben Skeggs + +drm/nouveau: Fix a couple of sparse warnings. + +Signed-off-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: INIT_CONFIGURE_PREINIT/CLK/MEM on newer BIOSes is not an error. + +No need to spam the logs when they're found, they're equivalent to +INIT_DONE. + +Signed-off-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nv04-nv40: Drop redundant logging. + +Signed-off-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: Move the fence wait before migration resource clean-up. + +Avoids an oops in the fence wait failure path (bug 26521). + +Signed-off-by: Francisco Jerez +Tested-by: Marcin Slusarz +Signed-off-by: Ben Skeggs + +drm/nouveau: Workaround broken TV load detection on a "Zotac FX5200". + +The blob seems to have the same problem so it's probably a hardware +issue (bug 28810). + +Signed-off-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nv50: send evo "update" command after each disconnect + +It turns out that the display engine signals an interrupt for disconnects +too. In order to make it easier to process the display interrupts +correctly, we want to ensure we only get one operation per interrupt +sequence - this is what this commit achieves. + +Signed-off-by: Ben Skeggs + +drm/nv50: rewrite display irq handler + +The previous handler basically worked correctly for a full-blown mode +change. However, it did nothing at all when a partial (encoder only) +reconfiguation was necessary, leading to the display hanging on certain +types of mode switch. + +Signed-off-by: Ben Skeggs + +drm/nouveau: move DP script invocation to nouveau_dp.c + +Signed-off-by: Ben Skeggs + +drm/nv50: set DP display power state during DPMS + +Signed-off-by: Ben Skeggs + +drm/nouveau: add scaler-only modes for eDP too + +Signed-off-by: Ben Skeggs + +drm/nouveau: remove dev_priv->init_state and friends + +Nouveau will no longer load at all if card initialisation fails, so all +these checks are unnecessary. + +Signed-off-by: Ben Skeggs + +drm/nv50: implement DAC disconnect fix missed in earlier commit + +Signed-off-by: Ben Skeggs + +drm/nouveau: reduce usage of fence spinlock to when absolutely necessary + +Signed-off-by: Ben Skeggs + +drm/nouveau: place notifiers in system memory by default + +Signed-off-by: Ben Skeggs + +drm/nouveau: add instmem flush() hook + +This removes the previous prepare_access() and finish_access() hooks, and +replaces it with a much simpler flush() hook. + +All the chipset-specific code before nv50 has its use removed completely, +as it's not required there at all. + +Signed-off-by: Ben Skeggs + +drm/nv50: move tlb flushing to a helper function + +Signed-off-by: Ben Skeggs + +drm/nouveau: remove ability to use external firmware + +This was always really a developer option, and if it's really necessary we +can hack this in ourselves. + +Signed-off-by: Ben Skeggs + +drm/nouveau: allocate fixed amount of PRAMIN per channel on all chipsets + +Previously only done on nv50+ + +This commit also switches unknown NV2x/NV3x chipsets to noaccel mode. + +Signed-off-by: Ben Skeggs + +drm/nouveau: remove unused fbdev_info + +Signed-off-by: Ben Skeggs + +drm/nv50: cleanup nv50_fifo.c + +Signed-off-by: Ben Skeggs + +drm/nv20-nv30: move context table object out of dev_priv + +Signed-off-by: Ben Skeggs + +drm/nv50: fix dp_set_tmds to work on the right OR + +Signed-off-by: Ben Skeggs + +drm/nouveau: fix mtrr cleanup path + +Signed-off-by: Ben Skeggs + +drm/nv50: move dp_set_tmds() function to happen in the last display irq + +It seems on some chipsets that doing this from the 0x20 handler causes the +display engine to not ever signal the final 0x40 stage. + +Signed-off-by: Ben Skeggs + +drm/nouveau: initialise display before enabling interrupts + +In some situations it's possible we can receive a spurious hotplug IRQ +before we're ready to handle it, leading to an oops. + +Calling the display init before enabling interrupts should clear any +pending IRQs on the GPU and prevent this from happening. + +Signed-off-by: Ben Skeggs + +drm/nouveau: Disable PROM access on init. + +On older cards ( + +drm/i2c/ch7006: Fix up suspend/resume. + +Signed-off-by: Francisco Jerez + +drm/nv04: Enable context switching on PFIFO init. + +Fixes a lockup when coming back from suspend. + +Signed-off-by: Francisco Jerez + +drm/nv50: fix RAMHT size + +Signed-off-by: Ben Skeggs + +drm/nv50: use correct PRAMIN flush register on original nv50 + +Signed-off-by: Ben Skeggs + +drm/nouveau: remove quirk to fabricate DVI-A output on DCB 1.5 boards + +There's a report of this quirk breaking modesetting on at least one board. +After discussion with Francisco Jerez, we've decided to remove it: + + it's not worth limiting the quirk to just where we know it can + work? i'm happy either way really :) + hmm, don't think so, most if not all DCB15 cards have just one DAC + and with that quirk there's no way to tell if the load comes from + the VGA or DVI port + +Signed-off-by: Ben Skeggs +Acked-by: Francisco Jerez + +drm/nouveau: support fetching LVDS EDID from ACPI + +Based on a patch from Matthew Garrett. + +Signed-off-by: Ben Skeggs +Acked-by: Matthew Garrett + +drm/nv50: fix regression that break LVDS in some places + +A previous commit started additionally using the SOR link when trying to +match the correct output script. However, we never fill in this field +for LVDS so we can never match a script at all. + +Signed-off-by: Ben Skeggs + +drm/nouveau: Fix a sparse warning. + +It doesn't like variable length arrays. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Don't pick an interlaced mode as the panel native mode. + +Rescaling interlaced modes isn't going to work correctly, and even if +it did, come on, interlaced flat panels? are you pulling my leg? + +Signed-off-by: Francisco Jerez + +drm/nouveau: Add another Zotac FX5200 TV-out quirk. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Add some PFB register defines. + +Also collect all the PFB registers in a single place and remove some +duplicated definitions. + +Signed-off-by: Francisco Jerez + +drm/nv04-nv3x: Implement init-compute-mem. + +Init-compute-mem was the last piece missing for nv0x-nv3x card +cold-booting. This implementation is somewhat lacking but it's been +reported to work on most chipsets it was tested in. Let me know if it +breaks suspend to RAM for you. + +Signed-off-by: Francisco Jerez +Tested-by: Patrice Mandin +Tested-by: Ben Skeggs +Tested-by: Xavier Chantry +Tested-by: Marcin Kościelnicki + +drm/i2c/ch7006: Don't assume that the specified config points to static memory. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Add some generic I2C gadget detection code. + +Clean up and move the external TV encoder detection code to +nouveau_i2c.c, it's also going to be useful for external TMDS and DDC +detection. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Remove useless CRTC_OWNER logging. + +Signed-off-by: Francisco Jerez + +drm/nouveau: No need to lock/unlock the VGA CRTC regs all the time. + +Locking only makes sense in the VBIOS parsing code as it's executed +before CRTC init. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Reset CRTC owner to 0 before BIOS init. + +Fixes suspend+multihead on some boards that also use BIOS scripts for +modesetting. + +Signed-off-by: Francisco Jerez + +drm/nouveau: fix build without CONFIG_ACPI + +Signed-off-by: Ben Skeggs + +drm/nouveau: add nv_mask register accessor + +Signed-off-by: Ben Skeggs + +drm/nv50: add function to control GPIO IRQ reporting + +Signed-off-by: Ben Skeggs + +drm/nouveau: disable hotplug detect around DP link training + +Signed-off-by: Ben Skeggs + +drm/nv30: Init the PFB+0x3xx memory timing regs. + +Fixes the randomly flashing vertical lines seen on some nv3x after a +cold-boot. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Reset AGP before running the init scripts. + +BIOS scripts usually make an attempt to reset the AGP controller, +however on some nv4x cards doing it properly involves switching FW off +and on: if we do that without updating the AGP bridge settings +accordingly (e.g. with the corresponding calls to agp_enable()) we +will be locking ourselves out of the card MMIO space. Do it from +nouveau_mem_reset_agp() before the init scripts are executed. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Put back the old 2-messages I2C slave test. + +I was hoping we could detect I2C devices at a given address without +actually writing data into them, but apparently some DDC slaves get +confused with 0-bytes transactions. Put the good old test back. + +Reported-by: Ben Skeggs +Signed-off-by: Francisco Jerez + +drm/nouveau: Move display init to a new nouveau_engine. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Get rid of the remaining VGA CRTC locking. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Fix TV-out detection on unposted cards lacking a usable DCB table. + +Signed-off-by: Francisco Jerez + +drm/nv50: correct wait condition for instmem flush + +Reported-by: Marcin Kościelnicki +Signed-off-by: Ben Skeggs + +drm/nouveau: introduce gpio engine + +Signed-off-by: Ben Skeggs + +drm/nv50: fix some not-error error messages + +Signed-off-by: Ben Skeggs + +drm/nv50: use custom i2c algo for dp auxch + +This makes it easier to see how this is working, and lets us transfer the +EDID in blocks of 16 bytes. + +The primary reason for this change is because debug logs are rather hard +to read with the hundreds of single-byte auxch transactions that occur. + +Signed-off-by: Ben Skeggs + +drm/nouveau: set TASK_(UN)INTERRUPTIBLE before schedule_timeout() + +set_current_state() is called only once before the first iteration. +After return from schedule_timeout() current state is TASK_RUNNING. If +we are going to wait again, set_current_state() must be called. + +Signed-off-by: Kulikov Vasiliy +Signed-off-by: Francisco Jerez + +drm/nouveau: remove unused ttm bo list + +Signed-off-by: Ben Skeggs + +drm/nouveau: Fix AGP reset when AGP FW is already enabled on init. + +Previously nouveau_mem_reset_agp() was only disabling AGP fast writes +when coming back from suspend. However, the "locked out of the card +because of FW" problem can also be reproduced on init if you +unload/reload nouveau.ko several times. This patch makes the AGP code +reset FW on init. + +Signed-off-by: Francisco Jerez + +drm/nouveau: unwind on load errors + +nouveau_load() just returned directly if there was an error instead of +releasing resources. + +Signed-off-by: Dan Carpenter +Reviewed-by: Marcin Slusarz +Signed-off-by: Francisco Jerez + +drm/nouveau: Don't pass misaligned offsets to io_mapping_map_atomic_wc(). + +Signed-off-by: Francisco Jerez + +drm/nouveau: Fix the INIT_CONFIGURE_PREINIT BIOS opcode. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Ack the context switch interrupt before switching contexts. + +Leaving the IRQ unack'ed while switching contexts makes the switch +fail randomly on some nv1x. + +Signed-off-by: Francisco Jerez + +drm/nv10: Fix up switching of NV10TCL_DMA_VTXBUF. + +Not very nice, but I don't think there's a simpler workaround. + +Signed-off-by: Francisco Jerez + +drm/nv17-nv4x: Attempt to init some external TMDS transmitters. + +sil164 and friends are the most common, usually they just need to be +poked once because a fixed configuration is enough for any modes and +clocks, so they worked without this patch if the BIOS had done a good +job on POST. Display couldn't survive a suspend/resume cycle though. +Unfortunately, BIOS scripts are useless here. + +Signed-off-by: Francisco Jerez + +drm/nouveau: No need to set slave TV encoder configs explicitly. + +Signed-off-by: Francisco Jerez + +drm/nv30: Workaround dual TMDS brain damage. + +Signed-off-by: Francisco Jerez + +drm/nvc0: starting point for GF100 support, everything stubbed + +Signed-off-by: Ben Skeggs + +drm/nvc0: allow INIT_GPIO + +Signed-off-by: Ben Skeggs + +drm/nvc0: implement memory detection + +Signed-off-by: Ben Skeggs + +drm/nvc0: rudimentary instmem support + +Signed-off-by: Ben Skeggs + +drm/nvc0: fix evo dma object so we display something + +Signed-off-by: Ben Skeggs + +drm/nvc0: implement crtc pll setting + +Signed-off-by: Ben Skeggs + +drm/nouveau: implement init table op 0x57, INIT_LTIME + +Signed-off-by: Ben Skeggs +Signed-off-by: Marcin Kościelnicki + +drm/nouveau: implement init table opcodex 0x5e and 0x9a + +Signed-off-by: Ben Skeggs +Signed-off-by: Marcin Kościelnicki + +drm/nvc0: backup bar3 channel on suspend + +Signed-off-by: Ben Skeggs + +drm/nouveau: reduce severity of some "error" messages + +There's some known configurations where the lack of these tables/scripts +is perfectly normal, reduce visibilty of complaint messages to debug. + +Signed-off-by: Ben Skeggs + +drm/nouveau: Init dcb->or on cards that have no usable DCB table. + +We need a valid OR value because there're a few nv17 cards with DCB v1.4. + +Signed-off-by: Francisco Jerez + +drm/nv04: Fix up SGRAM density detection. + +Signed-off-by: Francisco Jerez + +drm/nv30: Fix PFB init for nv31. + +Fixes a regression introduced by 58bbb63720c8997e0136fe1884101e7ca40d68fd +(fdo bug 29324). + +Reported-by: Johannes Obermayr +Signed-off-by: Francisco Jerez + +drm/nouveau: Fix DCB TMDS config parsing. + +Thinko caused by 43bda05428a3d2021f3c12220073e0251c65df8b. + +Signed-off-by: Francisco Jerez + +drm/nvc0: fix typo in PRAMIN flush + +Signed-off-by: Ben Skeggs + +drm/nouveau: Don't try DDC on the dummy I2C channel. + +Signed-off-by: Francisco Jerez + +drm/nv50: fix minor thinko from nvc0 changes + +drm/nouveau: check for error when allocating/mapping dummy page + +Signed-off-by: Ben Skeggs + +drm/nouveau: remove warning about unknown tmds table revisions + +This message is apparently confusing people, and is being blamed for some +modesetting issues. Lets remove the message, and instead replace it +with an unconditional printout of the table revision. + +Signed-off-by: Ben Skeggs + +drm/nouveau: punt some more log messages to debug level + +Signed-off-by: Ben Skeggs + +drm/nv50-nvc0: ramht_size is meant to be in bytes, not entries + +Fixes an infinite loop that can happen in RAMHT lookup. + +Signed-off-by: Ben Skeggs + +drm/nouveau: Add TV-out quirk for an MSI nForce2 IGP. + +The blob also thinks there's a TV connected, so hardware bug... + +Signed-off-by: Francisco Jerez + +drm/nouveau: Workaround missing GPIO tables on an Apple iMac G4 NV18. + +This should fix the reported TV-out load detection false positives +(fdo bug 29455). + +Reported-by: Vlado Plaga +Signed-off-by: Francisco Jerez + +drm/nvc0: fix thinko in instmem suspend/resume + +Signed-off-by: Ben Skeggs + +drm/nv50: calculate vram reordering block size + +Will be used at a later point when we plug in an alternative VRAM memory +manager for GeForce 8+ boards. + +Based on pscnv code to do the same. + +Signed-off-by: Ben Skeggs +Signed-off-by: Marcin Kościelnicki + +drm/nv50: add dcb type 14 to enum to prevent compiler complaint + +Signed-off-by: Ben Skeggs + +drm/nouveau: Use a helper function to match PCI device/subsystem IDs. + +Signed-off-by: Francisco Jerez + +drm/nv30: Apply modesetting to the correct slave encoder + +Signed-off-by: Patrice Mandin +Reviewed-by: Francisco Jerez + +drm/nouveau: Fix backlight control on PPC machines with an internal TMDS panel. + +This commit fixes fdo bug 29685. + +Reported-by: Vlado Plaga +Signed-off-by: Francisco Jerez + +drm/nouveau: Fix TMDS on some DCB1.5 boards. + +The TMDS output of an nv11 was being detected as LVDS, because it uses +DCB type 2 for TMDS instead of type 4. + +Reported-by: Bertrand VIEILLE +Signed-off-by: Francisco Jerez + +drm/nv20: Don't use pushbuf calls on the original nv20. + +The "return" command is buggy on the original nv20, it jumps back to +the caller address as expected, but it doesn't clear the subroutine +active bit making the subsequent pushbuf calls fail with a "stack" +overflow. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Fix suspend on some nv4x AGP cards. + +On some nv4x cards (specifically, the ones that use an internal +PCIE->AGP bridge) the AGP controller state isn't preserved after a +suspend/resume cycle, and the AGP control registers have moved from +0x18xx to 0x100xx, so the FW check in nouveau_mem_reset_agp() doesn't +quite work. Check "dev->agp->mode" instead. + +Signed-off-by: Francisco Jerez + +drm/nv20: Use the nv30 CRTC bandwidth calculation code. + +nv2x CRTC FIFOs are as large as in nv3x (4kB it seems), and the FIFO +control registers have the same layout: we can make them share the +same implementation. + +Previously we were using the nv1x code, but the calculated FIFO +watermarks are usually too low for nv2x and they cause horrible +scanout artifacts. They've gone unnoticed until now because we've been +leaving one of the bandwidth regs uninitialized (CRE 47, which +contains the most significant bits of FFLWM), so everything seemed to +work fine except in some cases after a cold boot, depending on the +memory bandwidth and pixel clocks used. + +Signed-off-by: Francisco Jerez + +drm/nv50: add new accelerated bo move funtion + +Hopefully this one will be better able to cope with moving tiled buffers +around without getting them all scrambled as a result. + +Signed-off-by: Ben Skeggs + +drm/nouveau: move check for no-op bo move before memcpy fallback + +Signed-off-by: Ben Skeggs + +drm/nouveau: remove second map of notifier bo + +Signed-off-by: Ben Skeggs + +drm/nouveau: require explicit unmap of kmapped bos + +Signed-off-by: Ben Skeggs + +drm/nv17-nv4x: Fix analog load detection false positive on rare occasions. + +On some boards the residual current DAC outputs can draw when they're +disconnected can be high enough to give a false load detection +positive (I've only seen it in the S-video luma output of some cards, +but just to be sure). The output line capacitance is limited and +sampling twice should fix it reliably. + +Signed-off-by: Francisco Jerez + +drm/nv40: Try to set up CRE_LCD even if it has unknown bits set. + +They don't seem to do anything useful, and we really want to program +CRE_LCD if we aren't lucky enough to find the right CRTC binding +already set. + +Signed-off-by: Francisco Jerez + +drm/nouveau: have nv_mask return original register value + +Signed-off-by: Ben Skeggs + +drm/nv50: initialize ramht_refs list for faked 0 channel + +We need it for PFIFO_INTR_CACHE_ERROR interrupt handling, +because nouveau_fifo_swmthd looks for matching gpuobj in +ramht_refs list. +It fixes kernel panic in nouveau_gpuobj_ref_find. + +Signed-off-by: Marcin Slusarz +Signed-off-by: Ben Skeggs + +drm/nouveau: move ramht code out of nouveau_object.c, nothing to see here + +Reviewed-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: modify object accessors, offset in bytes rather than dwords + +Reviewed-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nv50: demagic grctx, and add NVAF support + +Signed-off-by: Ben Skeggs +Signed-off-by: Marcin Kościelnicki + +drm/nv50: move vm trap to nv50_fb.c + +Signed-off-by: Ben Skeggs + +drm/nv50: report BAR access faults + +Signed-off-by: Ben Skeggs + +drm/nouveau: rebase per-channel pramin heap offsets to 0 + +Reviewed-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: remove nouveau_gpuobj_ref completely, replace with sanity + +Reviewed-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: simplify fake gpu objects + +Reviewed-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nv50: allow gpuobjs that aren't mapped into aperture + +Reviewed-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: rework init ordering so nv50_instmem.c can be less bad + +Reviewed-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: tidy ram{ht,fc,ro} a bit + +Reviewed-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: add spinlock around ramht modifications + +Reviewed-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: fix gpuobj refcount to use atomics + +Reviewed-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: protect gpuobj list + global instmem heap with spinlock + +Reviewed-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: remove nouveau_gpuobj_late_takedown + +Reviewed-by: Francisco Jerez +Signed-off-by: Ben Skeggs + +drm/nouveau: protect ramht_find() from oopsing if on channel without ramht + +This doesn't actually happen now, but there's a test case for an earlier +kernel where a GPU error is signalled on one of nv50's fake channels, and +the ramht lookup by the IRQ handler triggered an oops. + +This adds a check for RAMHT's existance on a channel before looking up +an object handle. + +Signed-off-by: Ben Skeggs + +drm/nv50: fix SOR count for early chipsets + +Signed-off-by: Ben Skeggs + +drm/nouveau: Break some long lines in the TV-out code. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Don't remove ramht entries from the neighboring channels. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Don't enable AGP FW on nv18. + +FW seems to be broken on nv18, it causes random lockups and breaks +suspend/resume even with the blob. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Add module parameter to override the default AGP rate. + +Signed-off-by: Francisco Jerez + +drm/nouveau: PRAMIN is available from the start on pre-nv50. + +This makes sure that RAMHT is cleared correctly on start up. + +Signed-off-by: Francisco Jerez + +drm/nouveau: Remove implicit argument from nv_wait(). + +Signed-off-by: Francisco Jerez + +drm/nouveau: Simplify tile region handling. + +Instead of emptying the caches to avoid a race with the PFIFO puller, +go straight ahead and try to recover from it when it happens. Also, +kill pfifo->cache_flush and tile->lock, we don't need them anymore. + +Signed-off-by: Francisco Jerez + +drm/nouveau: handle fifo pusher errors better + +The most important part of this change is that we now instruct PFIFO to +drop all pending fetches, rather than attempting to skip a single dword +and hope that things would magically sort themselves out - they usually +don't, and we end up with PFIFO being completely hung. + +This commit also adds somewhat more useful logging when these exceptions +occur. + +Signed-off-by: Ben Skeggs + +fix compile error due to upstream differences + +drm/nouveau: we can't free ACPI EDID, so make a copy that we can + +The rest of the connector code assumes we can kfree() the EDID pointer. +This causes things to blow up with the ACPI EDID pointer we get +passed. + +Signed-off-by: Ben Skeggs + +drm/nv50: mark PCIEGART pages non-present rather than using dummy page + +Signed-off-by: Ben Skeggs + +drm/nouveau: zero dummy page + +Signed-off-by: Ben Skeggs + +drm/nv50: fix 100c90 write on nva3 + +Signed-off-by: Ben Skeggs + +drm/nouveau: Fix build regression, undefined reference to `acpi_video_get_edid' + +Build breakage: + +drivers/built-in.o: In function `nouveau_acpi_edid': +(.text+0x13404e): undefined reference to `acpi_video_get_edid' +make: *** [.tmp_vmlinux1] Error 1 + +Introduced by: + +a6ed76d7ffc62ffa474b41d31b011b6853c5de32 is the first bad commit +commit a6ed76d7ffc62ffa474b41d31b011b6853c5de32 +Author: Ben Skeggs +Date: Mon Jul 12 15:33:07 2010 +1000 + + drm/nouveau: support fetching LVDS EDID from ACPI + + Based on a patch from Matthew Garrett. + + Signed-off-by: Ben Skeggs + Acked-by: Matthew Garrett + +It doesn't seem to revert cleanly, but the problem lies in these +two config entries: + +CONFIG_ACPI=y +CONFIG_ACPI_VIDEO=m + +Adding a select for ACPI_VIDEO appears to be the best solution, and +is comparable to what is done in DRM_I915. Builds, boots, and appears to +work correctly. + +Signed-off-by: Philip J. Turmel +Signed-off-by: Francisco Jerez + +drm/nv50: flush bar1 vm / dma object setup before poking 0x1708 + +Should fix issues noticed on NVAC (MacBook Pro / ION) since gpuobj +rework. + +Signed-off-by: Ben Skeggs + +drm/nouveau: correct INIT_DP_CONDITION subcondition 5 + +Fixes DP output on a GTX 465 board I have. + +Signed-off-by: Ben Skeggs + +drm/nouveau: add debugfs file to forcibly evict everything from vram + +Very useful for debugging buffer migration issues. + +Signed-off-by: Ben Skeggs + +drm/nv50: assume smaller tiles for bo moves + +Somehow fixes some corruption seen in KDE.. + +Signed-off-by: Ben Skeggs + +drm/nouveau: fix panels using straps-based mode detection + +nouveau_bios_fp_mode() zeroes the mode struct before filling in relevant +entries. This nukes the mode id initialised by drm_mode_create(), and +causes warnings from idr when we try to remove the mode. + +Signed-off-by: Ben Skeggs + +drm/nv10: Don't oops if the card wants to switch to a channel with no grctx. + +Signed-off-by: Francisco Jerez + +drm/nouveau: enable enhanced framing only if DP display supports it + +Reported-by: Adam Jackson +Signed-off-by: Ben Skeggs + +drm/nouveau: fix typo in c2aa91afea5f7e7ae4530fabd37414a79c03328c + +Signed-off-by: Ben Skeggs + +drm/nouveau: fix required mode bandwidth calculation for DP + +This should fix eDP on certain laptops with 18-bit panels, we were rejecting +the panel's native mode due to thinking there was insufficient bandwidth +for it. + +Signed-off-by: Ben Skeggs + +drm/nv30-nv40: Fix postdivider mask when writing engine/memory PLLs. + +Signed-off-by: Francisco Jerez + +drm/nv0x-nv4x: Leave the 0x40 bit untouched when changing CRE_LCD. + +It's an unrelated PLL filtering control bit, leave it alone when +changing the CRTC-encoder binding. + +Signed-off-by: Francisco Jerez + +drm/nv50: prevent (IB_PUT == IB_GET) for occurring unless idle + +Should fix a DMA race condition I've never seen myself, but could be +the culprit in some random hangs that have been reported. + +Signed-off-by: Ben Skeggs + +drm/nouveau: Add a module option to force card POST. + +Signed-off-by: Ben Skeggs + +drm/nouveau: Try to fetch an EDID from OF if DDC fails. + +More Apple brain damage, it fixes the modesetting failure on an eMac +G4 (fdo bug 29810). + +Reported-by: Zoltan Varnagy +Signed-off-by: Francisco Jerez + +drm/nouveau: better handling of unmappable vram + +Signed-off-by: Ben Skeggs + +drm/nouveau: fix chipset vs card_type thinko + +Signed-off-by: Ben Skeggs +--- + drivers/gpu/drm/drm_crtc_helper.c | 22 +- + drivers/gpu/drm/i2c/ch7006_drv.c | 22 +- + drivers/gpu/drm/i2c/ch7006_priv.h | 2 +- + drivers/gpu/drm/nouveau/Kconfig | 1 + + drivers/gpu/drm/nouveau/Makefile | 12 +- + drivers/gpu/drm/nouveau/nouveau_acpi.c | 38 +- + drivers/gpu/drm/nouveau/nouveau_bios.c | 914 ++++++-- + drivers/gpu/drm/nouveau/nouveau_bios.h | 6 +- + drivers/gpu/drm/nouveau/nouveau_bo.c | 251 ++- + drivers/gpu/drm/nouveau/nouveau_calc.c | 10 +- + drivers/gpu/drm/nouveau/nouveau_channel.c | 18 +- + drivers/gpu/drm/nouveau/nouveau_connector.c | 473 ++-- + drivers/gpu/drm/nouveau/nouveau_connector.h | 10 +- + drivers/gpu/drm/nouveau/nouveau_debugfs.c | 16 + + drivers/gpu/drm/nouveau/nouveau_dma.c | 23 +- + drivers/gpu/drm/nouveau/nouveau_dp.c | 138 +- + drivers/gpu/drm/nouveau/nouveau_drv.c | 49 +- + drivers/gpu/drm/nouveau/nouveau_drv.h | 310 ++-- + drivers/gpu/drm/nouveau/nouveau_encoder.h | 17 +- + drivers/gpu/drm/nouveau/nouveau_fbcon.c | 4 +- + drivers/gpu/drm/nouveau/nouveau_fence.c | 35 +- + drivers/gpu/drm/nouveau/nouveau_gem.c | 15 +- + drivers/gpu/drm/nouveau/nouveau_grctx.c | 160 -- + drivers/gpu/drm/nouveau/nouveau_grctx.h | 2 +- + drivers/gpu/drm/nouveau/nouveau_hw.c | 15 +- + drivers/gpu/drm/nouveau/nouveau_i2c.c | 83 +- + drivers/gpu/drm/nouveau/nouveau_i2c.h | 11 +- + drivers/gpu/drm/nouveau/nouveau_irq.c | 129 +- + drivers/gpu/drm/nouveau/nouveau_mem.c | 529 ++--- + drivers/gpu/drm/nouveau/nouveau_notifier.c | 37 +- + drivers/gpu/drm/nouveau/nouveau_object.c | 853 +++----- + drivers/gpu/drm/nouveau/nouveau_ramht.c | 289 +++ + drivers/gpu/drm/nouveau/nouveau_ramht.h | 55 + + drivers/gpu/drm/nouveau/nouveau_reg.h | 118 +- + drivers/gpu/drm/nouveau/nouveau_sgdma.c | 118 +- + drivers/gpu/drm/nouveau/nouveau_state.c | 398 ++-- + drivers/gpu/drm/nouveau/nv04_crtc.c | 11 +- + drivers/gpu/drm/nouveau/nv04_dac.c | 61 +- + drivers/gpu/drm/nouveau/nv04_dfp.c | 147 +- + drivers/gpu/drm/nouveau/nv04_display.c | 90 +- + drivers/gpu/drm/nouveau/nv04_fbcon.c | 9 +- + drivers/gpu/drm/nouveau/nv04_fifo.c | 88 +- + drivers/gpu/drm/nouveau/nv04_graph.c | 5 +- + drivers/gpu/drm/nouveau/nv04_instmem.c | 167 +- + drivers/gpu/drm/nouveau/nv04_mc.c | 4 + + drivers/gpu/drm/nouveau/nv04_tv.c | 139 +- + drivers/gpu/drm/nouveau/nv10_fifo.c | 29 +- + drivers/gpu/drm/nouveau/nv10_gpio.c | 92 + + drivers/gpu/drm/nouveau/nv10_graph.c | 177 +- + drivers/gpu/drm/nouveau/nv17_gpio.c | 92 - + drivers/gpu/drm/nouveau/nv17_tv.c | 179 +- + drivers/gpu/drm/nouveau/nv17_tv.h | 15 +- + drivers/gpu/drm/nouveau/nv17_tv_modes.c | 48 +- + drivers/gpu/drm/nouveau/nv20_graph.c | 576 +++--- + drivers/gpu/drm/nouveau/nv30_fb.c | 95 + + drivers/gpu/drm/nouveau/nv40_fifo.c | 28 +- + drivers/gpu/drm/nouveau/nv40_graph.c | 72 +- + drivers/gpu/drm/nouveau/nv40_grctx.c | 6 +- + drivers/gpu/drm/nouveau/nv40_mc.c | 2 +- + drivers/gpu/drm/nouveau/nv50_crtc.c | 67 +- + drivers/gpu/drm/nouveau/nv50_cursor.c | 2 +- + drivers/gpu/drm/nouveau/nv50_dac.c | 47 +- + drivers/gpu/drm/nouveau/nv50_display.c | 496 +++-- + drivers/gpu/drm/nouveau/nv50_display.h | 6 +- + drivers/gpu/drm/nouveau/nv50_fb.c | 40 + + drivers/gpu/drm/nouveau/nv50_fbcon.c | 4 +- + drivers/gpu/drm/nouveau/nv50_fifo.c | 396 ++-- + drivers/gpu/drm/nouveau/nv50_gpio.c | 35 + + drivers/gpu/drm/nouveau/nv50_graph.c | 131 +- + drivers/gpu/drm/nouveau/nv50_grctx.c | 3305 +++++++++++++++++---------- + drivers/gpu/drm/nouveau/nv50_instmem.c | 471 ++--- + drivers/gpu/drm/nouveau/nv50_sor.c | 109 +- + drivers/gpu/drm/nouveau/nvc0_fb.c | 38 + + drivers/gpu/drm/nouveau/nvc0_fifo.c | 89 + + drivers/gpu/drm/nouveau/nvc0_graph.c | 74 + + drivers/gpu/drm/nouveau/nvc0_instmem.c | 229 ++ + drivers/gpu/drm/nouveau/nvreg.h | 23 +- + 77 files changed, 7584 insertions(+), 5293 deletions(-) + delete mode 100644 drivers/gpu/drm/nouveau/nouveau_grctx.c + create mode 100644 drivers/gpu/drm/nouveau/nouveau_ramht.c + create mode 100644 drivers/gpu/drm/nouveau/nouveau_ramht.h + create mode 100644 drivers/gpu/drm/nouveau/nv10_gpio.c + delete mode 100644 drivers/gpu/drm/nouveau/nv17_gpio.c + create mode 100644 drivers/gpu/drm/nouveau/nv30_fb.c + create mode 100644 drivers/gpu/drm/nouveau/nvc0_fb.c + create mode 100644 drivers/gpu/drm/nouveau/nvc0_fifo.c + create mode 100644 drivers/gpu/drm/nouveau/nvc0_graph.c + create mode 100644 drivers/gpu/drm/nouveau/nvc0_instmem.c + +diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c +index 9b2a541..1eaa315 100644 +--- a/drivers/gpu/drm/drm_crtc_helper.c ++++ b/drivers/gpu/drm/drm_crtc_helper.c +@@ -201,6 +201,17 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc) + } + EXPORT_SYMBOL(drm_helper_crtc_in_use); + ++static void ++drm_encoder_disable(struct drm_encoder *encoder) ++{ ++ struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; ++ ++ if (encoder_funcs->disable) ++ (*encoder_funcs->disable)(encoder); ++ else ++ (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); ++} ++ + /** + * drm_helper_disable_unused_functions - disable unused objects + * @dev: DRM device +@@ -215,7 +226,6 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) + { + struct drm_encoder *encoder; + struct drm_connector *connector; +- struct drm_encoder_helper_funcs *encoder_funcs; + struct drm_crtc *crtc; + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { +@@ -226,12 +236,8 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) + } + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { +- encoder_funcs = encoder->helper_private; + if (!drm_helper_encoder_in_use(encoder)) { +- if (encoder_funcs->disable) +- (*encoder_funcs->disable)(encoder); +- else +- (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); ++ drm_encoder_disable(encoder); + /* disconnector encoder from any connector */ + encoder->crtc = NULL; + } +@@ -292,11 +298,11 @@ drm_crtc_prepare_encoders(struct drm_device *dev) + encoder_funcs = encoder->helper_private; + /* Disable unused encoders */ + if (encoder->crtc == NULL) +- (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); ++ drm_encoder_disable(encoder); + /* Disable encoders whose CRTC is about to change */ + if (encoder_funcs->get_crtc && + encoder->crtc != (*encoder_funcs->get_crtc)(encoder)) +- (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); ++ drm_encoder_disable(encoder); + } + } + +diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c +index 8c760c7..08792a7 100644 +--- a/drivers/gpu/drm/i2c/ch7006_drv.c ++++ b/drivers/gpu/drm/i2c/ch7006_drv.c +@@ -33,7 +33,7 @@ static void ch7006_encoder_set_config(struct drm_encoder *encoder, + { + struct ch7006_priv *priv = to_ch7006_priv(encoder); + +- priv->params = params; ++ priv->params = *(struct ch7006_encoder_params *)params; + } + + static void ch7006_encoder_destroy(struct drm_encoder *encoder) +@@ -114,7 +114,7 @@ static void ch7006_encoder_mode_set(struct drm_encoder *encoder, + { + struct i2c_client *client = drm_i2c_encoder_get_client(encoder); + struct ch7006_priv *priv = to_ch7006_priv(encoder); +- struct ch7006_encoder_params *params = priv->params; ++ struct ch7006_encoder_params *params = &priv->params; + struct ch7006_state *state = &priv->state; + uint8_t *regs = state->regs; + struct ch7006_mode *mode = priv->mode; +@@ -428,6 +428,22 @@ static int ch7006_remove(struct i2c_client *client) + return 0; + } + ++static int ch7006_suspend(struct i2c_client *client, pm_message_t mesg) ++{ ++ ch7006_dbg(client, "\n"); ++ ++ return 0; ++} ++ ++static int ch7006_resume(struct i2c_client *client) ++{ ++ ch7006_dbg(client, "\n"); ++ ++ ch7006_write(client, 0x3d, 0x0); ++ ++ return 0; ++} ++ + static int ch7006_encoder_init(struct i2c_client *client, + struct drm_device *dev, + struct drm_encoder_slave *encoder) +@@ -488,6 +504,8 @@ static struct drm_i2c_encoder_driver ch7006_driver = { + .i2c_driver = { + .probe = ch7006_probe, + .remove = ch7006_remove, ++ .suspend = ch7006_suspend, ++ .resume = ch7006_resume, + + .driver = { + .name = "ch7006", +diff --git a/drivers/gpu/drm/i2c/ch7006_priv.h b/drivers/gpu/drm/i2c/ch7006_priv.h +index 9487123..17667b7 100644 +--- a/drivers/gpu/drm/i2c/ch7006_priv.h ++++ b/drivers/gpu/drm/i2c/ch7006_priv.h +@@ -77,7 +77,7 @@ struct ch7006_state { + }; + + struct ch7006_priv { +- struct ch7006_encoder_params *params; ++ struct ch7006_encoder_params params; + struct ch7006_mode *mode; + + struct ch7006_state state; +diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig +index 6b8967a..15ca435 100644 +--- a/drivers/gpu/drm/nouveau/Kconfig ++++ b/drivers/gpu/drm/nouveau/Kconfig +@@ -10,6 +10,7 @@ config DRM_NOUVEAU + select FB + select FRAMEBUFFER_CONSOLE if !EMBEDDED + select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT ++ select ACPI_VIDEO if ACPI + help + Choose this option for open-source nVidia support. + +diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile +index acd31ed..d6cfbf2 100644 +--- a/drivers/gpu/drm/nouveau/Makefile ++++ b/drivers/gpu/drm/nouveau/Makefile +@@ -9,20 +9,20 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ + nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ + nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ + nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ +- nouveau_dp.o nouveau_grctx.o \ ++ nouveau_dp.o nouveau_ramht.o \ + nv04_timer.o \ + nv04_mc.o nv40_mc.o nv50_mc.o \ +- nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \ +- nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ ++ nv04_fb.o nv10_fb.o nv30_fb.o nv40_fb.o nv50_fb.o nvc0_fb.o \ ++ nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o nvc0_fifo.o \ + nv04_graph.o nv10_graph.o nv20_graph.o \ +- nv40_graph.o nv50_graph.o \ ++ nv40_graph.o nv50_graph.o nvc0_graph.o \ + nv40_grctx.o nv50_grctx.o \ +- nv04_instmem.o nv50_instmem.o \ ++ nv04_instmem.o nv50_instmem.o nvc0_instmem.o \ + nv50_crtc.o nv50_dac.o nv50_sor.o \ + nv50_cursor.o nv50_display.o nv50_fbcon.o \ + nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \ + nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \ +- nv17_gpio.o nv50_gpio.o \ ++ nv10_gpio.o nv50_gpio.o \ + nv50_calc.o + + nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o +diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c +index d4bcca8..1191526 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c ++++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include + + #include "drmP.h" + #include "drm.h" +@@ -11,6 +12,7 @@ + #include "nouveau_drv.h" + #include "nouveau_drm.h" + #include "nv50_display.h" ++#include "nouveau_connector.h" + + #include + +@@ -42,7 +44,7 @@ static const char nouveau_dsm_muid[] = { + 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4, + }; + +-static int nouveau_dsm(acpi_handle handle, int func, int arg, int *result) ++static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result) + { + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_object_list input; +@@ -259,3 +261,37 @@ int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) + { + return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len); + } ++ ++int ++nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) ++{ ++ struct nouveau_connector *nv_connector = nouveau_connector(connector); ++ struct acpi_device *acpidev; ++ acpi_handle handle; ++ int type, ret; ++ void *edid; ++ ++ switch (connector->connector_type) { ++ case DRM_MODE_CONNECTOR_LVDS: ++ case DRM_MODE_CONNECTOR_eDP: ++ type = ACPI_VIDEO_DISPLAY_LCD; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev); ++ if (!handle) ++ return -ENODEV; ++ ++ ret = acpi_bus_get_device(handle, &acpidev); ++ if (ret) ++ return -ENODEV; ++ ++ ret = acpi_video_get_edid(acpidev, type, -1, &edid); ++ if (ret < 0) ++ return ret; ++ ++ nv_connector->edid = kmemdup(edid, EDID_LENGTH, GFP_KERNEL); ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c +index e492919..72905c9 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_bios.c ++++ b/drivers/gpu/drm/nouveau/nouveau_bios.c +@@ -28,6 +28,8 @@ + #include "nouveau_hw.h" + #include "nouveau_encoder.h" + ++#include ++ + /* these defines are made up */ + #define NV_CIO_CRE_44_HEADA 0x0 + #define NV_CIO_CRE_44_HEADB 0x3 +@@ -209,20 +211,20 @@ static struct methods shadow_methods[] = { + { "PCIROM", load_vbios_pci, true }, + { "ACPI", load_vbios_acpi, true }, + }; ++#define NUM_SHADOW_METHODS ARRAY_SIZE(shadow_methods) + + static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) + { +- const int nr_methods = ARRAY_SIZE(shadow_methods); + struct methods *methods = shadow_methods; + int testscore = 3; +- int scores[nr_methods], i; ++ int scores[NUM_SHADOW_METHODS], i; + + if (nouveau_vbios) { +- for (i = 0; i < nr_methods; i++) ++ for (i = 0; i < NUM_SHADOW_METHODS; i++) + if (!strcasecmp(nouveau_vbios, methods[i].desc)) + break; + +- if (i < nr_methods) { ++ if (i < NUM_SHADOW_METHODS) { + NV_INFO(dev, "Attempting to use BIOS image from %s\n", + methods[i].desc); + +@@ -234,7 +236,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) + NV_ERROR(dev, "VBIOS source \'%s\' invalid\n", nouveau_vbios); + } + +- for (i = 0; i < nr_methods; i++) { ++ for (i = 0; i < NUM_SHADOW_METHODS; i++) { + NV_TRACE(dev, "Attempting to load BIOS image from %s\n", + methods[i].desc); + data[0] = data[1] = 0; /* avoid reuse of previous image */ +@@ -245,7 +247,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) + } + + while (--testscore > 0) { +- for (i = 0; i < nr_methods; i++) { ++ for (i = 0; i < NUM_SHADOW_METHODS; i++) { + if (scores[i] == testscore) { + NV_TRACE(dev, "Using BIOS image from %s\n", + methods[i].desc); +@@ -920,7 +922,7 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset, + NV_ERROR(bios->dev, + "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", + offset, config, count); +- return -EINVAL; ++ return len; + } + + configval = ROM32(bios->data[offset + 11 + config * 4]); +@@ -1022,7 +1024,7 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset, + NV_ERROR(bios->dev, + "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", + offset, config, count); +- return -EINVAL; ++ return len; + } + + freq = ROM16(bios->data[offset + 12 + config * 2]); +@@ -1194,7 +1196,7 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + dpe = nouveau_bios_dp_table(dev, dcb, &dummy); + if (!dpe) { + NV_ERROR(dev, "0x%04X: INIT_3A: no encoder table!!\n", offset); +- return -EINVAL; ++ return 3; + } + + switch (cond) { +@@ -1218,14 +1220,18 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + int ret; + + auxch = nouveau_i2c_find(dev, bios->display.output->i2c_index); +- if (!auxch) +- return -ENODEV; ++ if (!auxch) { ++ NV_ERROR(dev, "0x%04X: couldn't get auxch\n", offset); ++ return 3; ++ } + + ret = nouveau_dp_auxch(auxch, 9, 0xd, &cond, 1); +- if (ret) +- return ret; ++ if (ret) { ++ NV_ERROR(dev, "0x%04X: auxch rd fail: %d\n", offset, ret); ++ return 3; ++ } + +- if (cond & 1) ++ if (!(cond & 1)) + iexec->execute = false; + } + break; +@@ -1392,7 +1398,7 @@ init_io_restrict_pll2(struct nvbios *bios, uint16_t offset, + NV_ERROR(bios->dev, + "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", + offset, config, count); +- return -EINVAL; ++ return len; + } + + freq = ROM32(bios->data[offset + 11 + config * 4]); +@@ -1452,6 +1458,7 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + * "mask n" and OR it with "data n" before writing it back to the device + */ + ++ struct drm_device *dev = bios->dev; + uint8_t i2c_index = bios->data[offset + 1]; + uint8_t i2c_address = bios->data[offset + 2] >> 1; + uint8_t count = bios->data[offset + 3]; +@@ -1466,9 +1473,11 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + "Count: 0x%02X\n", + offset, i2c_index, i2c_address, count); + +- chan = init_i2c_device_find(bios->dev, i2c_index); +- if (!chan) +- return -ENODEV; ++ chan = init_i2c_device_find(dev, i2c_index); ++ if (!chan) { ++ NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset); ++ return len; ++ } + + for (i = 0; i < count; i++) { + uint8_t reg = bios->data[offset + 4 + i * 3]; +@@ -1479,8 +1488,10 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, + I2C_SMBUS_READ, reg, + I2C_SMBUS_BYTE_DATA, &val); +- if (ret < 0) +- return ret; ++ if (ret < 0) { ++ NV_ERROR(dev, "0x%04X: i2c rd fail: %d\n", offset, ret); ++ return len; ++ } + + BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " + "Mask: 0x%02X, Data: 0x%02X\n", +@@ -1494,8 +1505,10 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_BYTE_DATA, &val); +- if (ret < 0) +- return ret; ++ if (ret < 0) { ++ NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret); ++ return len; ++ } + } + + return len; +@@ -1520,6 +1533,7 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + * "DCB I2C table entry index", set the register to "data n" + */ + ++ struct drm_device *dev = bios->dev; + uint8_t i2c_index = bios->data[offset + 1]; + uint8_t i2c_address = bios->data[offset + 2] >> 1; + uint8_t count = bios->data[offset + 3]; +@@ -1534,9 +1548,11 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + "Count: 0x%02X\n", + offset, i2c_index, i2c_address, count); + +- chan = init_i2c_device_find(bios->dev, i2c_index); +- if (!chan) +- return -ENODEV; ++ chan = init_i2c_device_find(dev, i2c_index); ++ if (!chan) { ++ NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset); ++ return len; ++ } + + for (i = 0; i < count; i++) { + uint8_t reg = bios->data[offset + 4 + i * 2]; +@@ -1553,8 +1569,10 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_BYTE_DATA, &val); +- if (ret < 0) +- return ret; ++ if (ret < 0) { ++ NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret); ++ return len; ++ } + } + + return len; +@@ -1577,6 +1595,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + * address" on the I2C bus given by "DCB I2C table entry index" + */ + ++ struct drm_device *dev = bios->dev; + uint8_t i2c_index = bios->data[offset + 1]; + uint8_t i2c_address = bios->data[offset + 2] >> 1; + uint8_t count = bios->data[offset + 3]; +@@ -1584,7 +1603,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + struct nouveau_i2c_chan *chan; + struct i2c_msg msg; + uint8_t data[256]; +- int i; ++ int ret, i; + + if (!iexec->execute) + return len; +@@ -1593,9 +1612,11 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + "Count: 0x%02X\n", + offset, i2c_index, i2c_address, count); + +- chan = init_i2c_device_find(bios->dev, i2c_index); +- if (!chan) +- return -ENODEV; ++ chan = init_i2c_device_find(dev, i2c_index); ++ if (!chan) { ++ NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset); ++ return len; ++ } + + for (i = 0; i < count; i++) { + data[i] = bios->data[offset + 4 + i]; +@@ -1608,8 +1629,11 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + msg.flags = 0; + msg.len = count; + msg.buf = data; +- if (i2c_transfer(&chan->adapter, &msg, 1) != 1) +- return -EIO; ++ ret = i2c_transfer(&chan->adapter, &msg, 1); ++ if (ret != 1) { ++ NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret); ++ return len; ++ } + } + + return len; +@@ -1633,6 +1657,7 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + * used -- see get_tmds_index_reg() + */ + ++ struct drm_device *dev = bios->dev; + uint8_t mlv = bios->data[offset + 1]; + uint32_t tmdsaddr = bios->data[offset + 2]; + uint8_t mask = bios->data[offset + 3]; +@@ -1647,8 +1672,10 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + offset, mlv, tmdsaddr, mask, data); + + reg = get_tmds_index_reg(bios->dev, mlv); +- if (!reg) +- return -EINVAL; ++ if (!reg) { ++ NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset); ++ return 5; ++ } + + bios_wr32(bios, reg, + tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); +@@ -1678,6 +1705,7 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset, + * register is used -- see get_tmds_index_reg() + */ + ++ struct drm_device *dev = bios->dev; + uint8_t mlv = bios->data[offset + 1]; + uint8_t count = bios->data[offset + 2]; + int len = 3 + count * 2; +@@ -1691,8 +1719,10 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset, + offset, mlv, count); + + reg = get_tmds_index_reg(bios->dev, mlv); +- if (!reg) +- return -EINVAL; ++ if (!reg) { ++ NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset); ++ return len; ++ } + + for (i = 0; i < count; i++) { + uint8_t tmdsaddr = bios->data[offset + 3 + i * 2]; +@@ -1898,6 +1928,31 @@ init_condition_time(struct nvbios *bios, uint16_t offset, + } + + static int ++init_ltime(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ++{ ++ /* ++ * INIT_LTIME opcode: 0x57 ('V') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (16 bit): time ++ * ++ * Sleep for "time" miliseconds. ++ */ ++ ++ unsigned time = ROM16(bios->data[offset + 1]); ++ ++ if (!iexec->execute) ++ return 3; ++ ++ BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X miliseconds\n", ++ offset, time); ++ ++ msleep(time); ++ ++ return 3; ++} ++ ++static int + init_zm_reg_sequence(struct nvbios *bios, uint16_t offset, + struct init_exec *iexec) + { +@@ -1965,6 +2020,64 @@ init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + } + + static int ++init_i2c_if(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ++{ ++ /* ++ * INIT_I2C_IF opcode: 0x5E ('^') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): DCB I2C table entry index ++ * offset + 2 (8 bit): I2C slave address ++ * offset + 3 (8 bit): I2C register ++ * offset + 4 (8 bit): mask ++ * offset + 5 (8 bit): data ++ * ++ * Read the register given by "I2C register" on the device addressed ++ * by "I2C slave address" on the I2C bus given by "DCB I2C table ++ * entry index". Compare the result AND "mask" to "data". ++ * If they're not equal, skip subsequent opcodes until condition is ++ * inverted (INIT_NOT), or we hit INIT_RESUME ++ */ ++ ++ uint8_t i2c_index = bios->data[offset + 1]; ++ uint8_t i2c_address = bios->data[offset + 2] >> 1; ++ uint8_t reg = bios->data[offset + 3]; ++ uint8_t mask = bios->data[offset + 4]; ++ uint8_t data = bios->data[offset + 5]; ++ struct nouveau_i2c_chan *chan; ++ union i2c_smbus_data val; ++ int ret; ++ ++ /* no execute check by design */ ++ ++ BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X\n", ++ offset, i2c_index, i2c_address); ++ ++ chan = init_i2c_device_find(bios->dev, i2c_index); ++ if (!chan) ++ return -ENODEV; ++ ++ ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, ++ I2C_SMBUS_READ, reg, ++ I2C_SMBUS_BYTE_DATA, &val); ++ if (ret < 0) { ++ BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: [no device], " ++ "Mask: 0x%02X, Data: 0x%02X\n", ++ offset, reg, mask, data); ++ iexec->execute = 0; ++ return 6; ++ } ++ ++ BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " ++ "Mask: 0x%02X, Data: 0x%02X\n", ++ offset, reg, val.byte, mask, data); ++ ++ iexec->execute = ((val.byte & mask) == data); ++ ++ return 6; ++} ++ ++static int + init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + { + /* +@@ -2039,6 +2152,325 @@ init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + return 5; + } + ++static inline void ++bios_md32(struct nvbios *bios, uint32_t reg, ++ uint32_t mask, uint32_t val) ++{ ++ bios_wr32(bios, reg, (bios_rd32(bios, reg) & ~mask) | val); ++} ++ ++static uint32_t ++peek_fb(struct drm_device *dev, struct io_mapping *fb, ++ uint32_t off) ++{ ++ uint32_t val = 0; ++ ++ if (off < pci_resource_len(dev->pdev, 1)) { ++ uint8_t __iomem *p = ++ io_mapping_map_atomic_wc(fb, off & PAGE_MASK); ++ ++ val = ioread32(p + (off & ~PAGE_MASK)); ++ ++ io_mapping_unmap_atomic(p); ++ } ++ ++ return val; ++} ++ ++static void ++poke_fb(struct drm_device *dev, struct io_mapping *fb, ++ uint32_t off, uint32_t val) ++{ ++ if (off < pci_resource_len(dev->pdev, 1)) { ++ uint8_t __iomem *p = ++ io_mapping_map_atomic_wc(fb, off & PAGE_MASK); ++ ++ iowrite32(val, p + (off & ~PAGE_MASK)); ++ wmb(); ++ ++ io_mapping_unmap_atomic(p); ++ } ++} ++ ++static inline bool ++read_back_fb(struct drm_device *dev, struct io_mapping *fb, ++ uint32_t off, uint32_t val) ++{ ++ poke_fb(dev, fb, off, val); ++ return val == peek_fb(dev, fb, off); ++} ++ ++static int ++nv04_init_compute_mem(struct nvbios *bios) ++{ ++ struct drm_device *dev = bios->dev; ++ uint32_t patt = 0xdeadbeef; ++ struct io_mapping *fb; ++ int i; ++ ++ /* Map the framebuffer aperture */ ++ fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), ++ pci_resource_len(dev->pdev, 1)); ++ if (!fb) ++ return -ENOMEM; ++ ++ /* Sequencer and refresh off */ ++ NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20); ++ bios_md32(bios, NV04_PFB_DEBUG_0, 0, NV04_PFB_DEBUG_0_REFRESH_OFF); ++ ++ bios_md32(bios, NV04_PFB_BOOT_0, ~0, ++ NV04_PFB_BOOT_0_RAM_AMOUNT_16MB | ++ NV04_PFB_BOOT_0_RAM_WIDTH_128 | ++ NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT); ++ ++ for (i = 0; i < 4; i++) ++ poke_fb(dev, fb, 4 * i, patt); ++ ++ poke_fb(dev, fb, 0x400000, patt + 1); ++ ++ if (peek_fb(dev, fb, 0) == patt + 1) { ++ bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE, ++ NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT); ++ bios_md32(bios, NV04_PFB_DEBUG_0, ++ NV04_PFB_DEBUG_0_REFRESH_OFF, 0); ++ ++ for (i = 0; i < 4; i++) ++ poke_fb(dev, fb, 4 * i, patt); ++ ++ if ((peek_fb(dev, fb, 0xc) & 0xffff) != (patt & 0xffff)) ++ bios_md32(bios, NV04_PFB_BOOT_0, ++ NV04_PFB_BOOT_0_RAM_WIDTH_128 | ++ NV04_PFB_BOOT_0_RAM_AMOUNT, ++ NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); ++ ++ } else if ((peek_fb(dev, fb, 0xc) & 0xffff0000) != ++ (patt & 0xffff0000)) { ++ bios_md32(bios, NV04_PFB_BOOT_0, ++ NV04_PFB_BOOT_0_RAM_WIDTH_128 | ++ NV04_PFB_BOOT_0_RAM_AMOUNT, ++ NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); ++ ++ } else if (peek_fb(dev, fb, 0) != patt) { ++ if (read_back_fb(dev, fb, 0x800000, patt)) ++ bios_md32(bios, NV04_PFB_BOOT_0, ++ NV04_PFB_BOOT_0_RAM_AMOUNT, ++ NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); ++ else ++ bios_md32(bios, NV04_PFB_BOOT_0, ++ NV04_PFB_BOOT_0_RAM_AMOUNT, ++ NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); ++ ++ bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE, ++ NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT); ++ ++ } else if (!read_back_fb(dev, fb, 0x800000, patt)) { ++ bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, ++ NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); ++ ++ } ++ ++ /* Refresh on, sequencer on */ ++ bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0); ++ NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20); ++ ++ io_mapping_free(fb); ++ return 0; ++} ++ ++static const uint8_t * ++nv05_memory_config(struct nvbios *bios) ++{ ++ /* Defaults for BIOSes lacking a memory config table */ ++ static const uint8_t default_config_tab[][2] = { ++ { 0x24, 0x00 }, ++ { 0x28, 0x00 }, ++ { 0x24, 0x01 }, ++ { 0x1f, 0x00 }, ++ { 0x0f, 0x00 }, ++ { 0x17, 0x00 }, ++ { 0x06, 0x00 }, ++ { 0x00, 0x00 } ++ }; ++ int i = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) & ++ NV_PEXTDEV_BOOT_0_RAMCFG) >> 2; ++ ++ if (bios->legacy.mem_init_tbl_ptr) ++ return &bios->data[bios->legacy.mem_init_tbl_ptr + 2 * i]; ++ else ++ return default_config_tab[i]; ++} ++ ++static int ++nv05_init_compute_mem(struct nvbios *bios) ++{ ++ struct drm_device *dev = bios->dev; ++ const uint8_t *ramcfg = nv05_memory_config(bios); ++ uint32_t patt = 0xdeadbeef; ++ struct io_mapping *fb; ++ int i, v; ++ ++ /* Map the framebuffer aperture */ ++ fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), ++ pci_resource_len(dev->pdev, 1)); ++ if (!fb) ++ return -ENOMEM; ++ ++ /* Sequencer off */ ++ NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20); ++ ++ if (bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_UMA_ENABLE) ++ goto out; ++ ++ bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0); ++ ++ /* If present load the hardcoded scrambling table */ ++ if (bios->legacy.mem_init_tbl_ptr) { ++ uint32_t *scramble_tab = (uint32_t *)&bios->data[ ++ bios->legacy.mem_init_tbl_ptr + 0x10]; ++ ++ for (i = 0; i < 8; i++) ++ bios_wr32(bios, NV04_PFB_SCRAMBLE(i), ++ ROM32(scramble_tab[i])); ++ } ++ ++ /* Set memory type/width/length defaults depending on the straps */ ++ bios_md32(bios, NV04_PFB_BOOT_0, 0x3f, ramcfg[0]); ++ ++ if (ramcfg[1] & 0x80) ++ bios_md32(bios, NV04_PFB_CFG0, 0, NV04_PFB_CFG0_SCRAMBLE); ++ ++ bios_md32(bios, NV04_PFB_CFG1, 0x700001, (ramcfg[1] & 1) << 20); ++ bios_md32(bios, NV04_PFB_CFG1, 0, 1); ++ ++ /* Probe memory bus width */ ++ for (i = 0; i < 4; i++) ++ poke_fb(dev, fb, 4 * i, patt); ++ ++ if (peek_fb(dev, fb, 0xc) != patt) ++ bios_md32(bios, NV04_PFB_BOOT_0, ++ NV04_PFB_BOOT_0_RAM_WIDTH_128, 0); ++ ++ /* Probe memory length */ ++ v = bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_RAM_AMOUNT; ++ ++ if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_32MB && ++ (!read_back_fb(dev, fb, 0x1000000, ++patt) || ++ !read_back_fb(dev, fb, 0, ++patt))) ++ bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, ++ NV04_PFB_BOOT_0_RAM_AMOUNT_16MB); ++ ++ if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_16MB && ++ !read_back_fb(dev, fb, 0x800000, ++patt)) ++ bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, ++ NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); ++ ++ if (!read_back_fb(dev, fb, 0x400000, ++patt)) ++ bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, ++ NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); ++ ++out: ++ /* Sequencer on */ ++ NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20); ++ ++ io_mapping_free(fb); ++ return 0; ++} ++ ++static int ++nv10_init_compute_mem(struct nvbios *bios) ++{ ++ struct drm_device *dev = bios->dev; ++ struct drm_nouveau_private *dev_priv = bios->dev->dev_private; ++ const int mem_width[] = { 0x10, 0x00, 0x20 }; ++ const int mem_width_count = (dev_priv->chipset >= 0x17 ? 3 : 2); ++ uint32_t patt = 0xdeadbeef; ++ struct io_mapping *fb; ++ int i, j, k; ++ ++ /* Map the framebuffer aperture */ ++ fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), ++ pci_resource_len(dev->pdev, 1)); ++ if (!fb) ++ return -ENOMEM; ++ ++ bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1); ++ ++ /* Probe memory bus width */ ++ for (i = 0; i < mem_width_count; i++) { ++ bios_md32(bios, NV04_PFB_CFG0, 0x30, mem_width[i]); ++ ++ for (j = 0; j < 4; j++) { ++ for (k = 0; k < 4; k++) ++ poke_fb(dev, fb, 0x1c, 0); ++ ++ poke_fb(dev, fb, 0x1c, patt); ++ poke_fb(dev, fb, 0x3c, 0); ++ ++ if (peek_fb(dev, fb, 0x1c) == patt) ++ goto mem_width_found; ++ } ++ } ++ ++mem_width_found: ++ patt <<= 1; ++ ++ /* Probe amount of installed memory */ ++ for (i = 0; i < 4; i++) { ++ int off = bios_rd32(bios, NV04_PFB_FIFO_DATA) - 0x100000; ++ ++ poke_fb(dev, fb, off, patt); ++ poke_fb(dev, fb, 0, 0); ++ ++ peek_fb(dev, fb, 0); ++ peek_fb(dev, fb, 0); ++ peek_fb(dev, fb, 0); ++ peek_fb(dev, fb, 0); ++ ++ if (peek_fb(dev, fb, off) == patt) ++ goto amount_found; ++ } ++ ++ /* IC missing - disable the upper half memory space. */ ++ bios_md32(bios, NV04_PFB_CFG0, 0x1000, 0); ++ ++amount_found: ++ io_mapping_free(fb); ++ return 0; ++} ++ ++static int ++nv20_init_compute_mem(struct nvbios *bios) ++{ ++ struct drm_device *dev = bios->dev; ++ struct drm_nouveau_private *dev_priv = bios->dev->dev_private; ++ uint32_t mask = (dev_priv->chipset >= 0x25 ? 0x300 : 0x900); ++ uint32_t amount, off; ++ struct io_mapping *fb; ++ ++ /* Map the framebuffer aperture */ ++ fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), ++ pci_resource_len(dev->pdev, 1)); ++ if (!fb) ++ return -ENOMEM; ++ ++ bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1); ++ ++ /* Allow full addressing */ ++ bios_md32(bios, NV04_PFB_CFG0, 0, mask); ++ ++ amount = bios_rd32(bios, NV04_PFB_FIFO_DATA); ++ for (off = amount; off > 0x2000000; off -= 0x2000000) ++ poke_fb(dev, fb, off - 4, off); ++ ++ amount = bios_rd32(bios, NV04_PFB_FIFO_DATA); ++ if (amount != peek_fb(dev, fb, amount - 4)) ++ /* IC missing - disable the upper half memory space. */ ++ bios_md32(bios, NV04_PFB_CFG0, mask, 0); ++ ++ io_mapping_free(fb); ++ return 0; ++} ++ + static int + init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + { +@@ -2047,64 +2479,57 @@ init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + * + * offset (8 bit): opcode + * +- * This opcode is meant to set NV_PFB_CFG0 (0x100200) appropriately so +- * that the hardware can correctly calculate how much VRAM it has +- * (and subsequently report that value in NV_PFB_CSTATUS (0x10020C)) ++ * This opcode is meant to set the PFB memory config registers ++ * appropriately so that we can correctly calculate how much VRAM it ++ * has (on nv10 and better chipsets the amount of installed VRAM is ++ * subsequently reported in NV_PFB_CSTATUS (0x10020C)). + * +- * The implementation of this opcode in general consists of two parts: +- * 1) determination of the memory bus width +- * 2) determination of how many of the card's RAM pads have ICs attached ++ * The implementation of this opcode in general consists of several ++ * parts: + * +- * 1) is done by a cunning combination of writes to offsets 0x1c and +- * 0x3c in the framebuffer, and seeing whether the written values are +- * read back correctly. This then affects bits 4-7 of NV_PFB_CFG0 ++ * 1) Determination of memory type and density. Only necessary for ++ * really old chipsets, the memory type reported by the strap bits ++ * (0x101000) is assumed to be accurate on nv05 and newer. + * +- * 2) is done by a cunning combination of writes to an offset slightly +- * less than the maximum memory reported by NV_PFB_CSTATUS, then seeing +- * if the test pattern can be read back. This then affects bits 12-15 of +- * NV_PFB_CFG0 ++ * 2) Determination of the memory bus width. Usually done by a cunning ++ * combination of writes to offsets 0x1c and 0x3c in the fb, and ++ * seeing whether the written values are read back correctly. + * +- * In this context a "cunning combination" may include multiple reads +- * and writes to varying locations, often alternating the test pattern +- * and 0, doubtless to make sure buffers are filled, residual charges +- * on tracks are removed etc. ++ * Only necessary on nv0x-nv1x and nv34, on the other cards we can ++ * trust the straps. + * +- * Unfortunately, the "cunning combination"s mentioned above, and the +- * changes to the bits in NV_PFB_CFG0 differ with nearly every bios +- * trace I have. ++ * 3) Determination of how many of the card's RAM pads have ICs ++ * attached, usually done by a cunning combination of writes to an ++ * offset slightly less than the maximum memory reported by ++ * NV_PFB_CSTATUS, then seeing if the test pattern can be read back. + * +- * Therefore, we cheat and assume the value of NV_PFB_CFG0 with which +- * we started was correct, and use that instead ++ * This appears to be a NOP on IGPs and NV4x or newer chipsets, both io ++ * logs of the VBIOS and kmmio traces of the binary driver POSTing the ++ * card show nothing being done for this opcode. Why is it still listed ++ * in the table?! + */ + + /* no iexec->execute check by design */ + +- /* +- * This appears to be a NOP on G8x chipsets, both io logs of the VBIOS +- * and kmmio traces of the binary driver POSTing the card show nothing +- * being done for this opcode. why is it still listed in the table?! +- */ +- + struct drm_nouveau_private *dev_priv = bios->dev->dev_private; ++ int ret; + +- if (dev_priv->card_type >= NV_40) +- return 1; +- +- /* +- * On every card I've seen, this step gets done for us earlier in +- * the init scripts +- uint8_t crdata = bios_idxprt_rd(dev, NV_VIO_SRX, 0x01); +- bios_idxprt_wr(dev, NV_VIO_SRX, 0x01, crdata | 0x20); +- */ +- +- /* +- * This also has probably been done in the scripts, but an mmio trace of +- * s3 resume shows nvidia doing it anyway (unlike the NV_VIO_SRX write) +- */ +- bios_wr32(bios, NV_PFB_REFCTRL, NV_PFB_REFCTRL_VALID_1); ++ if (dev_priv->chipset >= 0x40 || ++ dev_priv->chipset == 0x1a || ++ dev_priv->chipset == 0x1f) ++ ret = 0; ++ else if (dev_priv->chipset >= 0x20 && ++ dev_priv->chipset != 0x34) ++ ret = nv20_init_compute_mem(bios); ++ else if (dev_priv->chipset >= 0x10) ++ ret = nv10_init_compute_mem(bios); ++ else if (dev_priv->chipset >= 0x5) ++ ret = nv05_init_compute_mem(bios); ++ else ++ ret = nv04_init_compute_mem(bios); + +- /* write back the saved configuration value */ +- bios_wr32(bios, NV_PFB_CFG0, bios->state.saved_nv_pfb_cfg0); ++ if (ret) ++ return ret; + + return 1; + } +@@ -2131,7 +2556,8 @@ init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + /* no iexec->execute check by design */ + + pci_nv_19 = bios_rd32(bios, NV_PBUS_PCI_NV_19); +- bios_wr32(bios, NV_PBUS_PCI_NV_19, 0); ++ bios_wr32(bios, NV_PBUS_PCI_NV_19, pci_nv_19 & ~0xf00); ++ + bios_wr32(bios, reg, value1); + + udelay(10); +@@ -2167,7 +2593,7 @@ init_configure_mem(struct nvbios *bios, uint16_t offset, + uint32_t reg, data; + + if (bios->major_version > 2) +- return -ENODEV; ++ return 0; + + bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd( + bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20); +@@ -2180,14 +2606,14 @@ init_configure_mem(struct nvbios *bios, uint16_t offset, + reg = ROM32(bios->data[seqtbloffs += 4])) { + + switch (reg) { +- case NV_PFB_PRE: +- data = NV_PFB_PRE_CMD_PRECHARGE; ++ case NV04_PFB_PRE: ++ data = NV04_PFB_PRE_CMD_PRECHARGE; + break; +- case NV_PFB_PAD: +- data = NV_PFB_PAD_CKE_NORMAL; ++ case NV04_PFB_PAD: ++ data = NV04_PFB_PAD_CKE_NORMAL; + break; +- case NV_PFB_REF: +- data = NV_PFB_REF_CMD_REFRESH; ++ case NV04_PFB_REF: ++ data = NV04_PFB_REF_CMD_REFRESH; + break; + default: + data = ROM32(bios->data[meminitdata]); +@@ -2222,7 +2648,7 @@ init_configure_clk(struct nvbios *bios, uint16_t offset, + int clock; + + if (bios->major_version > 2) +- return -ENODEV; ++ return 0; + + clock = ROM16(bios->data[meminitoffs + 4]) * 10; + setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock); +@@ -2252,10 +2678,10 @@ init_configure_preinit(struct nvbios *bios, uint16_t offset, + /* no iexec->execute check by design */ + + uint32_t straps = bios_rd32(bios, NV_PEXTDEV_BOOT_0); +- uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6)); ++ uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & 0x40) >> 6; + + if (bios->major_version > 2) +- return -ENODEV; ++ return 0; + + bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, + NV_CIO_CRE_SCRATCH4__INDEX, cr3c); +@@ -2389,7 +2815,7 @@ init_ram_condition(struct nvbios *bios, uint16_t offset, + * offset + 1 (8 bit): mask + * offset + 2 (8 bit): cmpval + * +- * Test if (NV_PFB_BOOT_0 & "mask") equals "cmpval". ++ * Test if (NV04_PFB_BOOT_0 & "mask") equals "cmpval". + * If condition not met skip subsequent opcodes until condition is + * inverted (INIT_NOT), or we hit INIT_RESUME + */ +@@ -2401,7 +2827,7 @@ init_ram_condition(struct nvbios *bios, uint16_t offset, + if (!iexec->execute) + return 3; + +- data = bios_rd32(bios, NV_PFB_BOOT_0) & mask; ++ data = bios_rd32(bios, NV04_PFB_BOOT_0) & mask; + + BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n", + offset, data, cmpval); +@@ -2795,12 +3221,13 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + */ + + struct drm_nouveau_private *dev_priv = bios->dev->dev_private; ++ struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; + const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; + int i; + +- if (dev_priv->card_type != NV_50) { ++ if (dev_priv->card_type < NV_50) { + NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n"); +- return -ENODEV; ++ return 1; + } + + if (!iexec->execute) +@@ -2815,7 +3242,7 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n", + offset, gpio->tag, gpio->state_default); + if (bios->execute) +- nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default); ++ pgpio->set(bios->dev, gpio->tag, gpio->state_default); + + /* The NVIDIA binary driver doesn't appear to actually do + * any of this, my VBIOS does however. +@@ -2872,10 +3299,7 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, + uint8_t index; + int i; + +- +- if (!iexec->execute) +- return len; +- ++ /* critical! to know the length of the opcode */; + if (!blocklen) { + NV_ERROR(bios->dev, + "0x%04X: Zero block length - has the M table " +@@ -2883,6 +3307,9 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, + return -EINVAL; + } + ++ if (!iexec->execute) ++ return len; ++ + strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; + index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg]; + +@@ -3064,14 +3491,14 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + + if (!bios->display.output) { + NV_ERROR(dev, "INIT_AUXCH: no active output\n"); +- return -EINVAL; ++ return len; + } + + auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); + if (!auxch) { + NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n", + bios->display.output->i2c_index); +- return -ENODEV; ++ return len; + } + + if (!iexec->execute) +@@ -3084,7 +3511,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1); + if (ret) { + NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret); +- return ret; ++ return len; + } + + data &= bios->data[offset + 0]; +@@ -3093,7 +3520,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1); + if (ret) { + NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret); +- return ret; ++ return len; + } + } + +@@ -3123,14 +3550,14 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + + if (!bios->display.output) { + NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n"); +- return -EINVAL; ++ return len; + } + + auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); + if (!auxch) { + NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n", + bios->display.output->i2c_index); +- return -ENODEV; ++ return len; + } + + if (!iexec->execute) +@@ -3141,13 +3568,76 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) + ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1); + if (ret) { + NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret); +- return ret; ++ return len; + } + } + + return len; + } + ++static int ++init_i2c_long_if(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ++{ ++ /* ++ * INIT_I2C_LONG_IF opcode: 0x9A ('') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): DCB I2C table entry index ++ * offset + 2 (8 bit): I2C slave address ++ * offset + 3 (16 bit): I2C register ++ * offset + 5 (8 bit): mask ++ * offset + 6 (8 bit): data ++ * ++ * Read the register given by "I2C register" on the device addressed ++ * by "I2C slave address" on the I2C bus given by "DCB I2C table ++ * entry index". Compare the result AND "mask" to "data". ++ * If they're not equal, skip subsequent opcodes until condition is ++ * inverted (INIT_NOT), or we hit INIT_RESUME ++ */ ++ ++ uint8_t i2c_index = bios->data[offset + 1]; ++ uint8_t i2c_address = bios->data[offset + 2] >> 1; ++ uint8_t reglo = bios->data[offset + 3]; ++ uint8_t reghi = bios->data[offset + 4]; ++ uint8_t mask = bios->data[offset + 5]; ++ uint8_t data = bios->data[offset + 6]; ++ struct nouveau_i2c_chan *chan; ++ uint8_t buf0[2] = { reghi, reglo }; ++ uint8_t buf1[1]; ++ struct i2c_msg msg[2] = { ++ { i2c_address, 0, 1, buf0 }, ++ { i2c_address, I2C_M_RD, 1, buf1 }, ++ }; ++ int ret; ++ ++ /* no execute check by design */ ++ ++ BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X\n", ++ offset, i2c_index, i2c_address); ++ ++ chan = init_i2c_device_find(bios->dev, i2c_index); ++ if (!chan) ++ return -ENODEV; ++ ++ ++ ret = i2c_transfer(&chan->adapter, msg, 2); ++ if (ret < 0) { ++ BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X:0x%02X, Value: [no device], " ++ "Mask: 0x%02X, Data: 0x%02X\n", ++ offset, reghi, reglo, mask, data); ++ iexec->execute = 0; ++ return 7; ++ } ++ ++ BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X:0x%02X, Value: 0x%02X, " ++ "Mask: 0x%02X, Data: 0x%02X\n", ++ offset, reghi, reglo, buf1[0], mask, data); ++ ++ iexec->execute = ((buf1[0] & mask) == data); ++ ++ return 7; ++} ++ + static struct init_tbl_entry itbl_entry[] = { + /* command name , id , length , offset , mult , command handler */ + /* INIT_PROG (0x31, 15, 10, 4) removed due to no example of use */ +@@ -3174,9 +3664,11 @@ static struct init_tbl_entry itbl_entry[] = { + { "INIT_ZM_CR" , 0x53, init_zm_cr }, + { "INIT_ZM_CR_GROUP" , 0x54, init_zm_cr_group }, + { "INIT_CONDITION_TIME" , 0x56, init_condition_time }, ++ { "INIT_LTIME" , 0x57, init_ltime }, + { "INIT_ZM_REG_SEQUENCE" , 0x58, init_zm_reg_sequence }, + /* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */ + { "INIT_SUB_DIRECT" , 0x5B, init_sub_direct }, ++ { "INIT_I2C_IF" , 0x5E, init_i2c_if }, + { "INIT_COPY_NV_REG" , 0x5F, init_copy_nv_reg }, + { "INIT_ZM_INDEX_IO" , 0x62, init_zm_index_io }, + { "INIT_COMPUTE_MEM" , 0x63, init_compute_mem }, +@@ -3210,6 +3702,7 @@ static struct init_tbl_entry itbl_entry[] = { + { "INIT_97" , 0x97, init_97 }, + { "INIT_AUXCH" , 0x98, init_auxch }, + { "INIT_ZM_AUXCH" , 0x99, init_zm_auxch }, ++ { "INIT_I2C_LONG_IF" , 0x9A, init_i2c_long_if }, + { NULL , 0 , NULL } + }; + +@@ -3376,27 +3869,10 @@ static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entr + } + #ifdef __powerpc__ + /* Powerbook specific quirks */ +- if ((dev->pci_device & 0xffff) == 0x0179 || +- (dev->pci_device & 0xffff) == 0x0189 || +- (dev->pci_device & 0xffff) == 0x0329) { +- if (script == LVDS_RESET) { +- nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); +- +- } else if (script == LVDS_PANEL_ON) { +- bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, +- bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) +- | (1 << 31)); +- bios_wr32(bios, NV_PCRTC_GPIO_EXT, +- bios_rd32(bios, NV_PCRTC_GPIO_EXT) | 1); +- +- } else if (script == LVDS_PANEL_OFF) { +- bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, +- bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) +- & ~(1 << 31)); +- bios_wr32(bios, NV_PCRTC_GPIO_EXT, +- bios_rd32(bios, NV_PCRTC_GPIO_EXT) & ~3); +- } +- } ++ if (script == LVDS_RESET && ++ (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || ++ dev->pci_device == 0x0329)) ++ nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); + #endif + + return 0; +@@ -3888,11 +4364,8 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b + * + * For the moment, a quirk will do :) + */ +- if ((dev->pdev->device == 0x01d7) && +- (dev->pdev->subsystem_vendor == 0x1028) && +- (dev->pdev->subsystem_device == 0x01c2)) { ++ if (nv_match_device(dev, 0x01d7, 0x1028, 0x01c2)) + bios->fp.duallink_transition_clk = 80000; +- } + + /* set dual_link flag for EDID case */ + if (pxclk && (chip_version < 0x25 || chip_version > 0x28)) +@@ -4068,7 +4541,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, + bios->display.script_table_ptr, + table[2], table[3], table[0] >= 0x21); + if (!otable) { +- NV_ERROR(dev, "Couldn't find matching output script table\n"); ++ NV_DEBUG_KMS(dev, "failed to match any output table\n"); + return 1; + } + +@@ -4094,7 +4567,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, + return 1; + } + +- NV_TRACE(dev, "0x%04X: parsing output script 0\n", script); ++ NV_DEBUG_KMS(dev, "0x%04X: parsing output script 0\n", script); + nouveau_bios_run_init_table(dev, script, dcbent); + } else + if (pxclk == -1) { +@@ -4104,7 +4577,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, + return 1; + } + +- NV_TRACE(dev, "0x%04X: parsing output script 1\n", script); ++ NV_DEBUG_KMS(dev, "0x%04X: parsing output script 1\n", script); + nouveau_bios_run_init_table(dev, script, dcbent); + } else + if (pxclk == -2) { +@@ -4117,7 +4590,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, + return 1; + } + +- NV_TRACE(dev, "0x%04X: parsing output script 2\n", script); ++ NV_DEBUG_KMS(dev, "0x%04X: parsing output script 2\n", script); + nouveau_bios_run_init_table(dev, script, dcbent); + } else + if (pxclk > 0) { +@@ -4125,11 +4598,11 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, + if (script) + script = clkcmptable(bios, script, pxclk); + if (!script) { +- NV_ERROR(dev, "clock script 0 not found\n"); ++ NV_DEBUG_KMS(dev, "clock script 0 not found\n"); + return 1; + } + +- NV_TRACE(dev, "0x%04X: parsing clock script 0\n", script); ++ NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 0\n", script); + nouveau_bios_run_init_table(dev, script, dcbent); + } else + if (pxclk < 0) { +@@ -4141,7 +4614,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, + return 1; + } + +- NV_TRACE(dev, "0x%04X: parsing clock script 1\n", script); ++ NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 1\n", script); + nouveau_bios_run_init_table(dev, script, dcbent); + } + +@@ -4484,7 +4957,7 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims + pll_lim->min_p = record[12]; + pll_lim->max_p = record[13]; + /* where did this go to?? */ +- if (limit_match == 0x00614100 || limit_match == 0x00614900) ++ if ((entry[0] & 0xf0) == 0x80) + pll_lim->refclk = 27000; + else + pll_lim->refclk = 100000; +@@ -4864,19 +5337,17 @@ static int parse_bit_tmds_tbl_entry(struct drm_device *dev, struct nvbios *bios, + } + + tmdstableptr = ROM16(bios->data[bitentry->offset]); +- +- if (tmdstableptr == 0x0) { ++ if (!tmdstableptr) { + NV_ERROR(dev, "Pointer to TMDS table invalid\n"); + return -EINVAL; + } + ++ NV_INFO(dev, "TMDS table version %d.%d\n", ++ bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); ++ + /* nv50+ has v2.0, but we don't parse it atm */ +- if (bios->data[tmdstableptr] != 0x11) { +- NV_WARN(dev, +- "TMDS table revision %d.%d not currently supported\n", +- bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); ++ if (bios->data[tmdstableptr] != 0x11) + return -ENOSYS; +- } + + /* + * These two scripts are odd: they don't seem to get run even when +@@ -5151,10 +5622,14 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi + bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset]; + bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1]; + bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2]; +- bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4]; +- bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5]; +- bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6]; +- bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7]; ++ if (bios->data[legacy_i2c_offset + 4]) ++ bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4]; ++ if (bios->data[legacy_i2c_offset + 5]) ++ bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5]; ++ if (bios->data[legacy_i2c_offset + 6]) ++ bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6]; ++ if (bios->data[legacy_i2c_offset + 7]) ++ bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7]; + + if (bmplength > 74) { + bios->fmaxvco = ROM32(bmp[67]); +@@ -5312,6 +5787,20 @@ parse_dcb_gpio_table(struct nvbios *bios) + gpio->line = tvdac_gpio[1] >> 4; + gpio->invert = tvdac_gpio[0] & 2; + } ++ } else { ++ /* ++ * No systematic way to store GPIO info on pre-v2.2 ++ * DCBs, try to match the PCI device IDs. ++ */ ++ ++ /* Apple iMac G4 NV18 */ ++ if (nv_match_device(dev, 0x0189, 0x10de, 0x0010)) { ++ struct dcb_gpio_entry *gpio = new_gpio_entry(bios); ++ ++ gpio->tag = DCB_GPIO_TVDAC0; ++ gpio->line = 4; ++ } ++ + } + + if (!gpio_table_ptr) +@@ -5387,9 +5876,7 @@ apply_dcb_connector_quirks(struct nvbios *bios, int idx) + struct drm_device *dev = bios->dev; + + /* Gigabyte NX85T */ +- if ((dev->pdev->device == 0x0421) && +- (dev->pdev->subsystem_vendor == 0x1458) && +- (dev->pdev->subsystem_device == 0x344c)) { ++ if (nv_match_device(dev, 0x0421, 0x1458, 0x344c)) { + if (cte->type == DCB_CONNECTOR_HDMI_1) + cte->type = DCB_CONNECTOR_DVI_I; + } +@@ -5506,7 +5993,7 @@ static void fabricate_vga_output(struct dcb_table *dcb, int i2c, int heads) + entry->i2c_index = i2c; + entry->heads = heads; + entry->location = DCB_LOC_ON_CHIP; +- /* "or" mostly unused in early gen crt modesetting, 0 is fine */ ++ entry->or = 1; + } + + static void fabricate_dvi_i_output(struct dcb_table *dcb, bool twoHeads) +@@ -5589,9 +6076,12 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, + if (conf & 0x4 || conf & 0x8) + entry->lvdsconf.use_power_scripts = true; + } else { +- mask = ~0x5; ++ mask = ~0x7; ++ if (conf & 0x2) ++ entry->lvdsconf.use_acpi_for_edid = true; + if (conf & 0x4) + entry->lvdsconf.use_power_scripts = true; ++ entry->lvdsconf.sor.link = (conf & 0x00000030) >> 4; + } + if (conf & mask) { + /* +@@ -5631,9 +6121,15 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, + } + break; + case OUTPUT_TMDS: +- entry->tmdsconf.sor.link = (conf & 0x00000030) >> 4; ++ if (dcb->version >= 0x40) ++ entry->tmdsconf.sor.link = (conf & 0x00000030) >> 4; ++ else if (dcb->version >= 0x30) ++ entry->tmdsconf.slave_addr = (conf & 0x00000700) >> 8; ++ else if (dcb->version >= 0x22) ++ entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4; ++ + break; +- case 0xe: ++ case OUTPUT_EOL: + /* weird g80 mobile type that "nv" treats as a terminator */ + dcb->entries--; + return false; +@@ -5670,22 +6166,14 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb, + entry->type = OUTPUT_TV; + break; + case 2: +- case 3: +- entry->type = OUTPUT_LVDS; +- break; + case 4: +- switch ((conn & 0x000000f0) >> 4) { +- case 0: +- entry->type = OUTPUT_TMDS; +- break; +- case 1: ++ if (conn & 0x10) + entry->type = OUTPUT_LVDS; +- break; +- default: +- NV_ERROR(dev, "Unknown DCB subtype 4/%d\n", +- (conn & 0x000000f0) >> 4); +- return false; +- } ++ else ++ entry->type = OUTPUT_TMDS; ++ break; ++ case 3: ++ entry->type = OUTPUT_LVDS; + break; + default: + NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f); +@@ -5706,13 +6194,6 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb, + case OUTPUT_TV: + entry->tvconf.has_component_output = false; + break; +- case OUTPUT_TMDS: +- /* +- * Invent a DVI-A output, by copying the fields of the DVI-D +- * output; reported to work by math_b on an NV20(!). +- */ +- fabricate_vga_output(dcb, entry->i2c_index, entry->heads); +- break; + case OUTPUT_LVDS: + if ((conn & 0x00003f00) != 0x10) + entry->lvdsconf.use_straps_for_mode = true; +@@ -5793,6 +6274,29 @@ void merge_like_dcb_entries(struct drm_device *dev, struct dcb_table *dcb) + dcb->entries = newentries; + } + ++static bool ++apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) ++{ ++ /* Dell Precision M6300 ++ * DCB entry 2: 02025312 00000010 ++ * DCB entry 3: 02026312 00000020 ++ * ++ * Identical, except apparently a different connector on a ++ * different SOR link. Not a clue how we're supposed to know ++ * which one is in use if it even shares an i2c line... ++ * ++ * Ignore the connector on the second SOR link to prevent ++ * nasty problems until this is sorted (assuming it's not a ++ * VBIOS bug). ++ */ ++ if (nv_match_device(dev, 0x040d, 0x1028, 0x019b)) { ++ if (*conn == 0x02026312 && *conf == 0x00000020) ++ return false; ++ } ++ ++ return true; ++} ++ + static int + parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) + { +@@ -5903,6 +6407,19 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) + dcb->i2c_table = &bios->data[i2ctabptr]; + if (dcb->version >= 0x30) + dcb->i2c_default_indices = dcb->i2c_table[4]; ++ ++ /* ++ * Parse the "management" I2C bus, used for hardware ++ * monitoring and some external TMDS transmitters. ++ */ ++ if (dcb->version >= 0x22) { ++ int idx = (dcb->version >= 0x40 ? ++ dcb->i2c_default_indices & 0xf : ++ 2); ++ ++ read_dcb_i2c_entry(dev, dcb->version, dcb->i2c_table, ++ idx, &dcb->i2c[idx]); ++ } + } + + if (entries > DCB_MAX_NUM_ENTRIES) +@@ -5926,6 +6443,9 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) + if ((connection & 0x0000000f) == 0x0000000f) + continue; + ++ if (!apply_dcb_encoder_quirks(dev, i, &connection, &config)) ++ continue; ++ + NV_TRACEWARN(dev, "Raw DCB entry %d: %08x %08x\n", + dcb->entries, connection, config); + +@@ -6181,9 +6701,8 @@ nouveau_run_vbios_init(struct drm_device *dev) + struct nvbios *bios = &dev_priv->vbios; + int i, ret = 0; + +- NVLockVgaCrtcs(dev, false); +- if (nv_two_heads(dev)) +- NVSetOwner(dev, bios->state.crtchead); ++ /* Reset the BIOS head to 0. */ ++ bios->state.crtchead = 0; + + if (bios->major_version < 5) /* BMP only */ + load_nv17_hw_sequencer_ucode(dev, bios); +@@ -6216,8 +6735,6 @@ nouveau_run_vbios_init(struct drm_device *dev) + } + } + +- NVLockVgaCrtcs(dev, true); +- + return ret; + } + +@@ -6238,7 +6755,6 @@ static bool + nouveau_bios_posted(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; +- bool was_locked; + unsigned htotal; + + if (dev_priv->chipset >= NV_50) { +@@ -6248,13 +6764,12 @@ nouveau_bios_posted(struct drm_device *dev) + return true; + } + +- was_locked = NVLockVgaCrtcs(dev, false); + htotal = NVReadVgaCrtc(dev, 0, 0x06); + htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8; + htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4; + htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10; + htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11; +- NVLockVgaCrtcs(dev, was_locked); ++ + return (htotal != 0); + } + +@@ -6263,8 +6778,6 @@ nouveau_bios_init(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nvbios *bios = &dev_priv->vbios; +- uint32_t saved_nv_pextdev_boot_0; +- bool was_locked; + int ret; + + if (!NVInitVBIOS(dev)) +@@ -6284,40 +6797,29 @@ nouveau_bios_init(struct drm_device *dev) + if (!bios->major_version) /* we don't run version 0 bios */ + return 0; + +- /* these will need remembering across a suspend */ +- saved_nv_pextdev_boot_0 = bios_rd32(bios, NV_PEXTDEV_BOOT_0); +- bios->state.saved_nv_pfb_cfg0 = bios_rd32(bios, NV_PFB_CFG0); +- + /* init script execution disabled */ + bios->execute = false; + + /* ... unless card isn't POSTed already */ + if (!nouveau_bios_posted(dev)) { +- NV_INFO(dev, "Adaptor not initialised\n"); +- if (dev_priv->card_type < NV_40) { +- NV_ERROR(dev, "Unable to POST this chipset\n"); +- return -ENODEV; +- } +- +- NV_INFO(dev, "Running VBIOS init tables\n"); ++ NV_INFO(dev, "Adaptor not initialised, " ++ "running VBIOS init tables.\n"); + bios->execute = true; + } +- +- bios_wr32(bios, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0); ++ if (nouveau_force_post) ++ bios->execute = true; + + ret = nouveau_run_vbios_init(dev); + if (ret) + return ret; + + /* feature_byte on BMP is poor, but init always sets CR4B */ +- was_locked = NVLockVgaCrtcs(dev, false); + if (bios->major_version < 5) + bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40; + + /* all BIT systems need p_f_m_t for digital_min_front_porch */ + if (bios->is_mobile || bios->major_version >= 5) + ret = parse_fp_mode_table(dev, bios); +- NVLockVgaCrtcs(dev, was_locked); + + /* allow subsequent scripts to execute */ + bios->execute = true; +diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h +index adf4ec2..c1de2f3 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_bios.h ++++ b/drivers/gpu/drm/nouveau/nouveau_bios.h +@@ -81,6 +81,7 @@ struct dcb_connector_table_entry { + enum dcb_connector_type type; + uint8_t index2; + uint8_t gpio_tag; ++ void *drm; + }; + + struct dcb_connector_table { +@@ -94,6 +95,7 @@ enum dcb_type { + OUTPUT_TMDS = 2, + OUTPUT_LVDS = 3, + OUTPUT_DP = 6, ++ OUTPUT_EOL = 14, /* DCB 4.0+, appears to be end-of-list */ + OUTPUT_ANY = -1 + }; + +@@ -117,6 +119,7 @@ struct dcb_entry { + struct { + struct sor_conf sor; + bool use_straps_for_mode; ++ bool use_acpi_for_edid; + bool use_power_scripts; + } lvdsconf; + struct { +@@ -129,6 +132,7 @@ struct dcb_entry { + } dpconf; + struct { + struct sor_conf sor; ++ int slave_addr; + } tmdsconf; + }; + bool i2c_upper_default; +@@ -249,8 +253,6 @@ struct nvbios { + + struct { + int crtchead; +- /* these need remembering across suspend */ +- uint32_t saved_nv_pfb_cfg0; + } state; + + struct { +diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c +index 51746d9..a4011f5 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_bo.c ++++ b/drivers/gpu/drm/nouveau/nouveau_bo.c +@@ -58,17 +58,12 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo) + struct drm_device *dev = dev_priv->dev; + struct nouveau_bo *nvbo = nouveau_bo(bo); + +- ttm_bo_kunmap(&nvbo->kmap); +- + if (unlikely(nvbo->gem)) + DRM_ERROR("bo %p still attached to GEM object\n", bo); + + if (nvbo->tile) + nv10_mem_expire_tiling(dev, nvbo->tile, NULL); + +- spin_lock(&dev_priv->ttm.bo_list_lock); +- list_del(&nvbo->head); +- spin_unlock(&dev_priv->ttm.bo_list_lock); + kfree(nvbo); + } + +@@ -167,8 +162,6 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, + nouveau_bo_fixup_align(dev, tile_mode, tile_flags, &align, &size); + align >>= PAGE_SHIFT; + +- nvbo->placement.fpfn = 0; +- nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0; + nouveau_bo_placement_set(nvbo, flags, 0); + + nvbo->channel = chan; +@@ -181,9 +174,6 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, + } + nvbo->channel = NULL; + +- spin_lock(&dev_priv->ttm.bo_list_lock); +- list_add_tail(&nvbo->head, &dev_priv->ttm.bo_list); +- spin_unlock(&dev_priv->ttm.bo_list_lock); + *pnvbo = nvbo; + return 0; + } +@@ -311,7 +301,8 @@ nouveau_bo_map(struct nouveau_bo *nvbo) + void + nouveau_bo_unmap(struct nouveau_bo *nvbo) + { +- ttm_bo_kunmap(&nvbo->kmap); ++ if (nvbo) ++ ttm_bo_kunmap(&nvbo->kmap); + } + + u16 +@@ -410,7 +401,10 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, + man->available_caching = TTM_PL_FLAG_UNCACHED | + TTM_PL_FLAG_WC; + man->default_caching = TTM_PL_FLAG_WC; +- man->gpu_offset = dev_priv->vm_vram_base; ++ if (dev_priv->card_type == NV_50) ++ man->gpu_offset = 0x40000000; ++ else ++ man->gpu_offset = 0; + break; + case TTM_PL_TT: + switch (dev_priv->gart_info.type) { +@@ -476,18 +470,20 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, + return ret; + + ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL, +- evict, no_wait_reserve, no_wait_gpu, new_mem); +- if (nvbo->channel && nvbo->channel != chan) +- ret = nouveau_fence_wait(fence, NULL, false, false); ++ evict || (nvbo->channel && ++ nvbo->channel != chan), ++ no_wait_reserve, no_wait_gpu, new_mem); + nouveau_fence_unref((void *)&fence); + return ret; + } + + static inline uint32_t +-nouveau_bo_mem_ctxdma(struct nouveau_bo *nvbo, struct nouveau_channel *chan, +- struct ttm_mem_reg *mem) ++nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo, ++ struct nouveau_channel *chan, struct ttm_mem_reg *mem) + { +- if (chan == nouveau_bdev(nvbo->bo.bdev)->channel) { ++ struct nouveau_bo *nvbo = nouveau_bo(bo); ++ ++ if (nvbo->no_vm) { + if (mem->mem_type == TTM_PL_TT) + return NvDmaGART; + return NvDmaVRAM; +@@ -499,86 +495,181 @@ nouveau_bo_mem_ctxdma(struct nouveau_bo *nvbo, struct nouveau_channel *chan, + } + + static int +-nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, +- bool no_wait_reserve, bool no_wait_gpu, +- struct ttm_mem_reg *new_mem) ++nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, ++ struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem) + { +- struct nouveau_bo *nvbo = nouveau_bo(bo); + struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); +- struct ttm_mem_reg *old_mem = &bo->mem; +- struct nouveau_channel *chan; +- uint64_t src_offset, dst_offset; +- uint32_t page_count; ++ struct nouveau_bo *nvbo = nouveau_bo(bo); ++ u64 length = (new_mem->num_pages << PAGE_SHIFT); ++ u64 src_offset, dst_offset; + int ret; + +- chan = nvbo->channel; +- if (!chan || nvbo->tile_flags || nvbo->no_vm) +- chan = dev_priv->channel; +- + src_offset = old_mem->mm_node->start << PAGE_SHIFT; + dst_offset = new_mem->mm_node->start << PAGE_SHIFT; +- if (chan != dev_priv->channel) { +- if (old_mem->mem_type == TTM_PL_TT) +- src_offset += dev_priv->vm_gart_base; +- else ++ if (!nvbo->no_vm) { ++ if (old_mem->mem_type == TTM_PL_VRAM) + src_offset += dev_priv->vm_vram_base; +- +- if (new_mem->mem_type == TTM_PL_TT) +- dst_offset += dev_priv->vm_gart_base; + else ++ src_offset += dev_priv->vm_gart_base; ++ ++ if (new_mem->mem_type == TTM_PL_VRAM) + dst_offset += dev_priv->vm_vram_base; ++ else ++ dst_offset += dev_priv->vm_gart_base; + } + + ret = RING_SPACE(chan, 3); + if (ret) + return ret; +- BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE, 2); +- OUT_RING(chan, nouveau_bo_mem_ctxdma(nvbo, chan, old_mem)); +- OUT_RING(chan, nouveau_bo_mem_ctxdma(nvbo, chan, new_mem)); + +- if (dev_priv->card_type >= NV_50) { +- ret = RING_SPACE(chan, 4); ++ BEGIN_RING(chan, NvSubM2MF, 0x0184, 2); ++ OUT_RING (chan, nouveau_bo_mem_ctxdma(bo, chan, old_mem)); ++ OUT_RING (chan, nouveau_bo_mem_ctxdma(bo, chan, new_mem)); ++ ++ while (length) { ++ u32 amount, stride, height; ++ ++ amount = min(length, (u64)(4 * 1024 * 1024)); ++ stride = 16 * 4; ++ height = amount / stride; ++ ++ if (new_mem->mem_type == TTM_PL_VRAM && nvbo->tile_flags) { ++ ret = RING_SPACE(chan, 8); ++ if (ret) ++ return ret; ++ ++ BEGIN_RING(chan, NvSubM2MF, 0x0200, 7); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, stride); ++ OUT_RING (chan, height); ++ OUT_RING (chan, 1); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 0); ++ } else { ++ ret = RING_SPACE(chan, 2); ++ if (ret) ++ return ret; ++ ++ BEGIN_RING(chan, NvSubM2MF, 0x0200, 1); ++ OUT_RING (chan, 1); ++ } ++ if (old_mem->mem_type == TTM_PL_VRAM && nvbo->tile_flags) { ++ ret = RING_SPACE(chan, 8); ++ if (ret) ++ return ret; ++ ++ BEGIN_RING(chan, NvSubM2MF, 0x021c, 7); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, stride); ++ OUT_RING (chan, height); ++ OUT_RING (chan, 1); ++ OUT_RING (chan, 0); ++ OUT_RING (chan, 0); ++ } else { ++ ret = RING_SPACE(chan, 2); ++ if (ret) ++ return ret; ++ ++ BEGIN_RING(chan, NvSubM2MF, 0x021c, 1); ++ OUT_RING (chan, 1); ++ } ++ ++ ret = RING_SPACE(chan, 14); + if (ret) + return ret; +- BEGIN_RING(chan, NvSubM2MF, 0x0200, 1); +- OUT_RING(chan, 1); +- BEGIN_RING(chan, NvSubM2MF, 0x021c, 1); +- OUT_RING(chan, 1); ++ ++ BEGIN_RING(chan, NvSubM2MF, 0x0238, 2); ++ OUT_RING (chan, upper_32_bits(src_offset)); ++ OUT_RING (chan, upper_32_bits(dst_offset)); ++ BEGIN_RING(chan, NvSubM2MF, 0x030c, 8); ++ OUT_RING (chan, lower_32_bits(src_offset)); ++ OUT_RING (chan, lower_32_bits(dst_offset)); ++ OUT_RING (chan, stride); ++ OUT_RING (chan, stride); ++ OUT_RING (chan, stride); ++ OUT_RING (chan, height); ++ OUT_RING (chan, 0x00000101); ++ OUT_RING (chan, 0x00000000); ++ BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1); ++ OUT_RING (chan, 0); ++ ++ length -= amount; ++ src_offset += amount; ++ dst_offset += amount; + } + ++ return 0; ++} ++ ++static int ++nv04_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, ++ struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem) ++{ ++ u32 src_offset = old_mem->mm_node->start << PAGE_SHIFT; ++ u32 dst_offset = new_mem->mm_node->start << PAGE_SHIFT; ++ u32 page_count = new_mem->num_pages; ++ int ret; ++ ++ ret = RING_SPACE(chan, 3); ++ if (ret) ++ return ret; ++ ++ BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE, 2); ++ OUT_RING (chan, nouveau_bo_mem_ctxdma(bo, chan, old_mem)); ++ OUT_RING (chan, nouveau_bo_mem_ctxdma(bo, chan, new_mem)); ++ + page_count = new_mem->num_pages; + while (page_count) { + int line_count = (page_count > 2047) ? 2047 : page_count; + +- if (dev_priv->card_type >= NV_50) { +- ret = RING_SPACE(chan, 3); +- if (ret) +- return ret; +- BEGIN_RING(chan, NvSubM2MF, 0x0238, 2); +- OUT_RING(chan, upper_32_bits(src_offset)); +- OUT_RING(chan, upper_32_bits(dst_offset)); +- } + ret = RING_SPACE(chan, 11); + if (ret) + return ret; ++ + BEGIN_RING(chan, NvSubM2MF, + NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); +- OUT_RING(chan, lower_32_bits(src_offset)); +- OUT_RING(chan, lower_32_bits(dst_offset)); +- OUT_RING(chan, PAGE_SIZE); /* src_pitch */ +- OUT_RING(chan, PAGE_SIZE); /* dst_pitch */ +- OUT_RING(chan, PAGE_SIZE); /* line_length */ +- OUT_RING(chan, line_count); +- OUT_RING(chan, (1<<8)|(1<<0)); +- OUT_RING(chan, 0); ++ OUT_RING (chan, src_offset); ++ OUT_RING (chan, dst_offset); ++ OUT_RING (chan, PAGE_SIZE); /* src_pitch */ ++ OUT_RING (chan, PAGE_SIZE); /* dst_pitch */ ++ OUT_RING (chan, PAGE_SIZE); /* line_length */ ++ OUT_RING (chan, line_count); ++ OUT_RING (chan, 0x00000101); ++ OUT_RING (chan, 0x00000000); + BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1); +- OUT_RING(chan, 0); ++ OUT_RING (chan, 0); + + page_count -= line_count; + src_offset += (PAGE_SIZE * line_count); + dst_offset += (PAGE_SIZE * line_count); + } + ++ return 0; ++} ++ ++static int ++nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, ++ bool no_wait_reserve, bool no_wait_gpu, ++ struct ttm_mem_reg *new_mem) ++{ ++ struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); ++ struct nouveau_bo *nvbo = nouveau_bo(bo); ++ struct nouveau_channel *chan; ++ int ret; ++ ++ chan = nvbo->channel; ++ if (!chan || nvbo->no_vm) ++ chan = dev_priv->channel; ++ ++ if (dev_priv->card_type < NV_50) ++ ret = nv04_bo_move_m2mf(chan, bo, &bo->mem, new_mem); ++ else ++ ret = nv50_bo_move_m2mf(chan, bo, &bo->mem, new_mem); ++ if (ret) ++ return ret; ++ + return nouveau_bo_move_accel_cleanup(chan, nvbo, evict, no_wait_reserve, no_wait_gpu, new_mem); + } + +@@ -725,13 +816,6 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, + if (ret) + return ret; + +- /* Software copy if the card isn't up and running yet. */ +- if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE || +- !dev_priv->channel) { +- ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); +- goto out; +- } +- + /* Fake bo copy. */ + if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) { + BUG_ON(bo->mem.mm_node != NULL); +@@ -740,6 +824,12 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, + goto out; + } + ++ /* Software copy if the card isn't up and running yet. */ ++ if (!dev_priv->channel) { ++ ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); ++ goto out; ++ } ++ + /* Hardware assisted copy. */ + if (new_mem->mem_type == TTM_PL_SYSTEM) + ret = nouveau_bo_move_flipd(bo, evict, intr, no_wait_reserve, no_wait_gpu, new_mem); +@@ -815,7 +905,26 @@ nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) + static int + nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) + { +- return 0; ++ struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); ++ struct nouveau_bo *nvbo = nouveau_bo(bo); ++ ++ /* as long as the bo isn't in vram, and isn't tiled, we've got ++ * nothing to do here. ++ */ ++ if (bo->mem.mem_type != TTM_PL_VRAM) { ++ if (dev_priv->card_type < NV_50 || !nvbo->tile_flags) ++ return 0; ++ } ++ ++ /* make sure bo is in mappable vram */ ++ if (bo->mem.mm_node->start + bo->mem.num_pages < dev_priv->fb_mappable_pages) ++ return 0; ++ ++ ++ nvbo->placement.fpfn = 0; ++ nvbo->placement.lpfn = dev_priv->fb_mappable_pages; ++ nouveau_bo_placement_set(nvbo, TTM_PL_VRAM, 0); ++ return ttm_bo_validate(bo, &nvbo->placement, false, true, false); + } + + struct ttm_bo_driver nouveau_bo_driver = { +diff --git a/drivers/gpu/drm/nouveau/nouveau_calc.c b/drivers/gpu/drm/nouveau/nouveau_calc.c +index 88f9bc0..23d9896 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_calc.c ++++ b/drivers/gpu/drm/nouveau/nouveau_calc.c +@@ -200,7 +200,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp, + struct nv_sim_state sim_data; + int MClk = nouveau_hw_get_clock(dev, MPLL); + int NVClk = nouveau_hw_get_clock(dev, NVPLL); +- uint32_t cfg1 = nvReadFB(dev, NV_PFB_CFG1); ++ uint32_t cfg1 = nvReadFB(dev, NV04_PFB_CFG1); + + sim_data.pclk_khz = VClk; + sim_data.mclk_khz = MClk; +@@ -218,7 +218,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp, + sim_data.mem_latency = 3; + sim_data.mem_page_miss = 10; + } else { +- sim_data.memory_type = nvReadFB(dev, NV_PFB_CFG0) & 0x1; ++ sim_data.memory_type = nvReadFB(dev, NV04_PFB_CFG0) & 0x1; + sim_data.memory_width = (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64; + sim_data.mem_latency = cfg1 & 0xf; + sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1); +@@ -234,7 +234,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp, + } + + static void +-nv30_update_arb(int *burst, int *lwm) ++nv20_update_arb(int *burst, int *lwm) + { + unsigned int fifo_size, burst_size, graphics_lwm; + +@@ -251,14 +251,14 @@ nouveau_calc_arb(struct drm_device *dev, int vclk, int bpp, int *burst, int *lwm + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + +- if (dev_priv->card_type < NV_30) ++ if (dev_priv->card_type < NV_20) + nv04_update_arb(dev, vclk, bpp, burst, lwm); + else if ((dev->pci_device & 0xfff0) == 0x0240 /*CHIPSET_C51*/ || + (dev->pci_device & 0xfff0) == 0x03d0 /*CHIPSET_C512*/) { + *burst = 128; + *lwm = 0x0480; + } else +- nv30_update_arb(burst, lwm); ++ nv20_update_arb(burst, lwm); + } + + static int +diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c +index 1fc57ef..53c2a6f 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_channel.c ++++ b/drivers/gpu/drm/nouveau/nouveau_channel.c +@@ -69,14 +69,8 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) + chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT; + } + +- ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf); +- if (ret) { +- NV_ERROR(dev, "Error referencing pushbuf ctxdma: %d\n", ret); +- if (pushbuf != dev_priv->gart_info.sg_ctxdma) +- nouveau_gpuobj_del(dev, &pushbuf); +- return ret; +- } +- ++ nouveau_gpuobj_ref(pushbuf, &chan->pushbuf); ++ nouveau_gpuobj_ref(NULL, &pushbuf); + return 0; + } + +@@ -257,9 +251,7 @@ nouveau_channel_free(struct nouveau_channel *chan) + nouveau_debugfs_channel_fini(chan); + + /* Give outstanding push buffers a chance to complete */ +- spin_lock_irqsave(&chan->fence.lock, flags); + nouveau_fence_update(chan); +- spin_unlock_irqrestore(&chan->fence.lock, flags); + if (chan->fence.sequence != chan->fence.sequence_ack) { + struct nouveau_fence *fence = NULL; + +@@ -309,8 +301,9 @@ nouveau_channel_free(struct nouveau_channel *chan) + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); + + /* Release the channel's resources */ +- nouveau_gpuobj_ref_del(dev, &chan->pushbuf); ++ nouveau_gpuobj_ref(NULL, &chan->pushbuf); + if (chan->pushbuf_bo) { ++ nouveau_bo_unmap(chan->pushbuf_bo); + nouveau_bo_unpin(chan->pushbuf_bo); + nouveau_bo_ref(NULL, &chan->pushbuf_bo); + } +@@ -368,8 +361,6 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, + struct nouveau_channel *chan; + int ret; + +- NOUVEAU_CHECK_INITIALISED_WITH_RETURN; +- + if (dev_priv->engine.graph.accel_blocked) + return -ENODEV; + +@@ -418,7 +409,6 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, + struct drm_nouveau_channel_free *cfree = data; + struct nouveau_channel *chan; + +- NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan); + + nouveau_channel_free(chan); +diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c +index 149ed22..46584c3 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_connector.c ++++ b/drivers/gpu/drm/nouveau/nouveau_connector.c +@@ -37,12 +37,6 @@ + #include "nouveau_connector.h" + #include "nouveau_hw.h" + +-static inline struct drm_encoder_slave_funcs * +-get_slave_funcs(struct nouveau_encoder *enc) +-{ +- return to_encoder_slave(to_drm_encoder(enc))->slave_funcs; +-} +- + static struct nouveau_encoder * + find_encoder_by_type(struct drm_connector *connector, int type) + { +@@ -82,6 +76,22 @@ nouveau_encoder_connector_get(struct nouveau_encoder *encoder) + return NULL; + } + ++/*TODO: This could use improvement, and learn to handle the fixed ++ * BIOS tables etc. It's fine currently, for its only user. ++ */ ++int ++nouveau_connector_bpp(struct drm_connector *connector) ++{ ++ struct nouveau_connector *nv_connector = nouveau_connector(connector); ++ ++ if (nv_connector->edid && nv_connector->edid->revision >= 4) { ++ u8 bpc = ((nv_connector->edid->input & 0x70) >> 3) + 4; ++ if (bpc > 4) ++ return bpc; ++ } ++ ++ return 18; ++} + + static void + nouveau_connector_destroy(struct drm_connector *drm_connector) +@@ -102,60 +112,12 @@ nouveau_connector_destroy(struct drm_connector *drm_connector) + kfree(drm_connector); + } + +-static void +-nouveau_connector_ddc_prepare(struct drm_connector *connector, int *flags) +-{ +- struct drm_nouveau_private *dev_priv = connector->dev->dev_private; +- +- if (dev_priv->card_type >= NV_50) +- return; +- +- *flags = 0; +- if (NVLockVgaCrtcs(dev_priv->dev, false)) +- *flags |= 1; +- if (nv_heads_tied(dev_priv->dev)) +- *flags |= 2; +- +- if (*flags & 2) +- NVSetOwner(dev_priv->dev, 0); /* necessary? */ +-} +- +-static void +-nouveau_connector_ddc_finish(struct drm_connector *connector, int flags) +-{ +- struct drm_nouveau_private *dev_priv = connector->dev->dev_private; +- +- if (dev_priv->card_type >= NV_50) +- return; +- +- if (flags & 2) +- NVSetOwner(dev_priv->dev, 4); +- if (flags & 1) +- NVLockVgaCrtcs(dev_priv->dev, true); +-} +- + static struct nouveau_i2c_chan * + nouveau_connector_ddc_detect(struct drm_connector *connector, + struct nouveau_encoder **pnv_encoder) + { + struct drm_device *dev = connector->dev; +- uint8_t out_buf[] = { 0x0, 0x0}, buf[2]; +- int ret, flags, i; +- +- struct i2c_msg msgs[] = { +- { +- .addr = 0x50, +- .flags = 0, +- .len = 1, +- .buf = out_buf, +- }, +- { +- .addr = 0x50, +- .flags = I2C_M_RD, +- .len = 1, +- .buf = buf, +- } +- }; ++ int i; + + for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { + struct nouveau_i2c_chan *i2c = NULL; +@@ -174,14 +136,8 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, + + if (nv_encoder->dcb->i2c_index < 0xf) + i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); +- if (!i2c) +- continue; +- +- nouveau_connector_ddc_prepare(connector, &flags); +- ret = i2c_transfer(&i2c->adapter, msgs, 2); +- nouveau_connector_ddc_finish(connector, flags); + +- if (ret == 2) { ++ if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) { + *pnv_encoder = nv_encoder; + return i2c; + } +@@ -190,6 +146,36 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, + return NULL; + } + ++static struct nouveau_encoder * ++nouveau_connector_of_detect(struct drm_connector *connector) ++{ ++#ifdef __powerpc__ ++ struct drm_device *dev = connector->dev; ++ struct nouveau_connector *nv_connector = nouveau_connector(connector); ++ struct nouveau_encoder *nv_encoder; ++ struct device_node *cn, *dn = pci_device_to_OF_node(dev->pdev); ++ ++ if (!dn || ++ !((nv_encoder = find_encoder_by_type(connector, OUTPUT_TMDS)) || ++ (nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG)))) ++ return NULL; ++ ++ for_each_child_of_node(dn, cn) { ++ const char *name = of_get_property(cn, "name", NULL); ++ const void *edid = of_get_property(cn, "EDID", NULL); ++ int idx = name ? name[strlen(name) - 1] - 'A' : 0; ++ ++ if (nv_encoder->dcb->i2c_index == idx && edid) { ++ nv_connector->edid = ++ kmemdup(edid, EDID_LENGTH, GFP_KERNEL); ++ of_node_put(cn); ++ return nv_encoder; ++ } ++ } ++#endif ++ return NULL; ++} ++ + static void + nouveau_connector_set_encoder(struct drm_connector *connector, + struct nouveau_encoder *nv_encoder) +@@ -234,21 +220,7 @@ nouveau_connector_detect(struct drm_connector *connector) + struct nouveau_connector *nv_connector = nouveau_connector(connector); + struct nouveau_encoder *nv_encoder = NULL; + struct nouveau_i2c_chan *i2c; +- int type, flags; +- +- if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS) +- nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS); +- if (nv_encoder && nv_connector->native_mode) { +- unsigned status = connector_status_connected; +- +-#if defined(CONFIG_ACPI_BUTTON) || \ +- (defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE)) +- if (!nouveau_ignorelid && !acpi_lid_open()) +- status = connector_status_unknown; +-#endif +- nouveau_connector_set_encoder(connector, nv_encoder); +- return status; +- } ++ int type; + + /* Cleanup the previous EDID block. */ + if (nv_connector->edid) { +@@ -259,9 +231,7 @@ nouveau_connector_detect(struct drm_connector *connector) + + i2c = nouveau_connector_ddc_detect(connector, &nv_encoder); + if (i2c) { +- nouveau_connector_ddc_prepare(connector, &flags); + nv_connector->edid = drm_get_edid(connector, &i2c->adapter); +- nouveau_connector_ddc_finish(connector, flags); + drm_mode_connector_update_edid_property(connector, + nv_connector->edid); + if (!nv_connector->edid) { +@@ -301,6 +271,12 @@ nouveau_connector_detect(struct drm_connector *connector) + return connector_status_connected; + } + ++ nv_encoder = nouveau_connector_of_detect(connector); ++ if (nv_encoder) { ++ nouveau_connector_set_encoder(connector, nv_encoder); ++ return connector_status_connected; ++ } ++ + detect_analog: + nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG); + if (!nv_encoder && !nouveau_tv_disable) +@@ -321,6 +297,85 @@ detect_analog: + return connector_status_disconnected; + } + ++static enum drm_connector_status ++nouveau_connector_detect_lvds(struct drm_connector *connector) ++{ ++ struct drm_device *dev = connector->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_connector *nv_connector = nouveau_connector(connector); ++ struct nouveau_encoder *nv_encoder = NULL; ++ enum drm_connector_status status = connector_status_disconnected; ++ ++ /* Cleanup the previous EDID block. */ ++ if (nv_connector->edid) { ++ drm_mode_connector_update_edid_property(connector, NULL); ++ kfree(nv_connector->edid); ++ nv_connector->edid = NULL; ++ } ++ ++ nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS); ++ if (!nv_encoder) ++ return connector_status_disconnected; ++ ++ /* Try retrieving EDID via DDC */ ++ if (!dev_priv->vbios.fp_no_ddc) { ++ status = nouveau_connector_detect(connector); ++ if (status == connector_status_connected) ++ goto out; ++ } ++ ++ /* On some laptops (Sony, i'm looking at you) there appears to ++ * be no direct way of accessing the panel's EDID. The only ++ * option available to us appears to be to ask ACPI for help.. ++ * ++ * It's important this check's before trying straps, one of the ++ * said manufacturer's laptops are configured in such a way ++ * the nouveau decides an entry in the VBIOS FP mode table is ++ * valid - it's not (rh#613284) ++ */ ++ if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { ++ if (!nouveau_acpi_edid(dev, connector)) { ++ status = connector_status_connected; ++ goto out; ++ } ++ } ++ ++ /* If no EDID found above, and the VBIOS indicates a hardcoded ++ * modeline is avalilable for the panel, set it as the panel's ++ * native mode and exit. ++ */ ++ if (nouveau_bios_fp_mode(dev, NULL) && (dev_priv->vbios.fp_no_ddc || ++ nv_encoder->dcb->lvdsconf.use_straps_for_mode)) { ++ status = connector_status_connected; ++ goto out; ++ } ++ ++ /* Still nothing, some VBIOS images have a hardcoded EDID block ++ * stored for the panel stored in them. ++ */ ++ if (!dev_priv->vbios.fp_no_ddc) { ++ struct edid *edid = ++ (struct edid *)nouveau_bios_embedded_edid(dev); ++ if (edid) { ++ nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL); ++ *(nv_connector->edid) = *edid; ++ status = connector_status_connected; ++ } ++ } ++ ++out: ++#if defined(CONFIG_ACPI_BUTTON) || \ ++ (defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE)) ++ if (status == connector_status_connected && ++ !nouveau_ignorelid && !acpi_lid_open()) ++ status = connector_status_unknown; ++#endif ++ ++ drm_mode_connector_update_edid_property(connector, nv_connector->edid); ++ nouveau_connector_set_encoder(connector, nv_encoder); ++ return status; ++} ++ + static void + nouveau_connector_force(struct drm_connector *connector) + { +@@ -353,6 +408,7 @@ nouveau_connector_set_property(struct drm_connector *connector, + { + struct nouveau_connector *nv_connector = nouveau_connector(connector); + struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; ++ struct drm_encoder *encoder = to_drm_encoder(nv_encoder); + struct drm_device *dev = connector->dev; + int ret; + +@@ -425,8 +481,8 @@ nouveau_connector_set_property(struct drm_connector *connector, + } + + if (nv_encoder && nv_encoder->dcb->type == OUTPUT_TV) +- return get_slave_funcs(nv_encoder)-> +- set_property(to_drm_encoder(nv_encoder), connector, property, value); ++ return get_slave_funcs(encoder)->set_property( ++ encoder, connector, property, value); + + return -EINVAL; + } +@@ -441,7 +497,8 @@ nouveau_connector_native_mode(struct drm_connector *connector) + int high_w = 0, high_h = 0, high_v = 0; + + list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { +- if (helper->mode_valid(connector, mode) != MODE_OK) ++ if (helper->mode_valid(connector, mode) != MODE_OK || ++ (mode->flags & DRM_MODE_FLAG_INTERLACE)) + continue; + + /* Use preferred mode if there is one.. */ +@@ -534,21 +591,30 @@ static int + nouveau_connector_get_modes(struct drm_connector *connector) + { + struct drm_device *dev = connector->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_connector *nv_connector = nouveau_connector(connector); + struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; ++ struct drm_encoder *encoder = to_drm_encoder(nv_encoder); + int ret = 0; + +- /* If we're not LVDS, destroy the previous native mode, the attached +- * monitor could have changed. ++ /* destroy the native mode, the attached monitor could have changed. + */ +- if (nv_connector->dcb->type != DCB_CONNECTOR_LVDS && +- nv_connector->native_mode) { ++ if (nv_connector->native_mode) { + drm_mode_destroy(dev, nv_connector->native_mode); + nv_connector->native_mode = NULL; + } + + if (nv_connector->edid) + ret = drm_add_edid_modes(connector, nv_connector->edid); ++ else ++ if (nv_encoder->dcb->type == OUTPUT_LVDS && ++ (nv_encoder->dcb->lvdsconf.use_straps_for_mode || ++ dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) { ++ struct drm_display_mode mode; ++ ++ nouveau_bios_fp_mode(dev, &mode); ++ nv_connector->native_mode = drm_mode_duplicate(dev, &mode); ++ } + + /* Find the native mode if this is a digital panel, if we didn't + * find any modes through DDC previously add the native mode to +@@ -566,10 +632,10 @@ nouveau_connector_get_modes(struct drm_connector *connector) + } + + if (nv_encoder->dcb->type == OUTPUT_TV) +- ret = get_slave_funcs(nv_encoder)-> +- get_modes(to_drm_encoder(nv_encoder), connector); ++ ret = get_slave_funcs(encoder)->get_modes(encoder, connector); + +- if (nv_encoder->dcb->type == OUTPUT_LVDS) ++ if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS || ++ nv_connector->dcb->type == DCB_CONNECTOR_eDP) + ret += nouveau_connector_scaler_modes_add(connector); + + return ret; +@@ -582,6 +648,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector, + struct drm_nouveau_private *dev_priv = connector->dev->dev_private; + struct nouveau_connector *nv_connector = nouveau_connector(connector); + struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; ++ struct drm_encoder *encoder = to_drm_encoder(nv_encoder); + unsigned min_clock = 25000, max_clock = min_clock; + unsigned clock = mode->clock; + +@@ -608,15 +675,14 @@ nouveau_connector_mode_valid(struct drm_connector *connector, + max_clock = 350000; + break; + case OUTPUT_TV: +- return get_slave_funcs(nv_encoder)-> +- mode_valid(to_drm_encoder(nv_encoder), mode); ++ return get_slave_funcs(encoder)->mode_valid(encoder, mode); + case OUTPUT_DP: + if (nv_encoder->dp.link_bw == DP_LINK_BW_2_7) + max_clock = nv_encoder->dp.link_nr * 270000; + else + max_clock = nv_encoder->dp.link_nr * 162000; + +- clock *= 3; ++ clock = clock * nouveau_connector_bpp(connector) / 8; + break; + default: + BUG_ON(1); +@@ -643,6 +709,44 @@ nouveau_connector_best_encoder(struct drm_connector *connector) + return NULL; + } + ++void ++nouveau_connector_set_polling(struct drm_connector *connector) ++{ ++ struct drm_device *dev = connector->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_crtc *crtc; ++ bool spare_crtc = false; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) ++ spare_crtc |= !crtc->enabled; ++ ++ connector->polled = 0; ++ ++ switch (connector->connector_type) { ++ case DRM_MODE_CONNECTOR_VGA: ++ case DRM_MODE_CONNECTOR_TV: ++ if (dev_priv->card_type >= NV_50 || ++ (nv_gf4_disp_arch(dev) && spare_crtc)) ++ connector->polled = DRM_CONNECTOR_POLL_CONNECT; ++ break; ++ ++ case DRM_MODE_CONNECTOR_DVII: ++ case DRM_MODE_CONNECTOR_DVID: ++ case DRM_MODE_CONNECTOR_HDMIA: ++ case DRM_MODE_CONNECTOR_DisplayPort: ++ case DRM_MODE_CONNECTOR_eDP: ++ if (dev_priv->card_type >= NV_50) ++ connector->polled = DRM_CONNECTOR_POLL_HPD; ++ else if (connector->connector_type == DRM_MODE_CONNECTOR_DVID || ++ spare_crtc) ++ connector->polled = DRM_CONNECTOR_POLL_CONNECT; ++ break; ++ ++ default: ++ break; ++ } ++} ++ + static const struct drm_connector_helper_funcs + nouveau_connector_helper_funcs = { + .get_modes = nouveau_connector_get_modes, +@@ -662,148 +766,74 @@ nouveau_connector_funcs = { + .force = nouveau_connector_force + }; + +-static int +-nouveau_connector_create_lvds(struct drm_device *dev, +- struct drm_connector *connector) +-{ +- struct nouveau_connector *nv_connector = nouveau_connector(connector); +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_i2c_chan *i2c = NULL; +- struct nouveau_encoder *nv_encoder; +- struct drm_display_mode native, *mode, *temp; +- bool dummy, if_is_24bit = false; +- int ret, flags; +- +- nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS); +- if (!nv_encoder) +- return -ENODEV; +- +- ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &if_is_24bit); +- if (ret) { +- NV_ERROR(dev, "Error parsing LVDS table, disabling LVDS\n"); +- return ret; +- } +- nv_connector->use_dithering = !if_is_24bit; +- +- /* Firstly try getting EDID over DDC, if allowed and I2C channel +- * is available. +- */ +- if (!dev_priv->vbios.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf) +- i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); +- +- if (i2c) { +- nouveau_connector_ddc_prepare(connector, &flags); +- nv_connector->edid = drm_get_edid(connector, &i2c->adapter); +- nouveau_connector_ddc_finish(connector, flags); +- } +- +- /* If no EDID found above, and the VBIOS indicates a hardcoded +- * modeline is avalilable for the panel, set it as the panel's +- * native mode and exit. +- */ +- if (!nv_connector->edid && nouveau_bios_fp_mode(dev, &native) && +- (nv_encoder->dcb->lvdsconf.use_straps_for_mode || +- dev_priv->vbios.fp_no_ddc)) { +- nv_connector->native_mode = drm_mode_duplicate(dev, &native); +- goto out; +- } +- +- /* Still nothing, some VBIOS images have a hardcoded EDID block +- * stored for the panel stored in them. +- */ +- if (!nv_connector->edid && !nv_connector->native_mode && +- !dev_priv->vbios.fp_no_ddc) { +- struct edid *edid = +- (struct edid *)nouveau_bios_embedded_edid(dev); +- if (edid) { +- nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL); +- *(nv_connector->edid) = *edid; +- } +- } +- +- if (!nv_connector->edid) +- goto out; +- +- /* We didn't find/use a panel mode from the VBIOS, so parse the EDID +- * block and look for the preferred mode there. +- */ +- ret = drm_add_edid_modes(connector, nv_connector->edid); +- if (ret == 0) +- goto out; +- nv_connector->detected_encoder = nv_encoder; +- nv_connector->native_mode = nouveau_connector_native_mode(connector); +- list_for_each_entry_safe(mode, temp, &connector->probed_modes, head) +- drm_mode_remove(connector, mode); +- +-out: +- if (!nv_connector->native_mode) { +- NV_ERROR(dev, "LVDS present in DCB table, but couldn't " +- "determine its native mode. Disabling.\n"); +- return -ENODEV; +- } +- +- drm_mode_connector_update_edid_property(connector, nv_connector->edid); +- return 0; +-} ++static const struct drm_connector_funcs ++nouveau_connector_funcs_lvds = { ++ .dpms = drm_helper_connector_dpms, ++ .save = NULL, ++ .restore = NULL, ++ .detect = nouveau_connector_detect_lvds, ++ .destroy = nouveau_connector_destroy, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .set_property = nouveau_connector_set_property, ++ .force = nouveau_connector_force ++}; + +-int +-nouveau_connector_create(struct drm_device *dev, +- struct dcb_connector_table_entry *dcb) ++struct drm_connector * ++nouveau_connector_create(struct drm_device *dev, int index) + { ++ const struct drm_connector_funcs *funcs = &nouveau_connector_funcs; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_connector *nv_connector = NULL; ++ struct dcb_connector_table_entry *dcb = NULL; + struct drm_connector *connector; +- struct drm_encoder *encoder; +- int ret, type; ++ int type, ret = 0; + + NV_DEBUG_KMS(dev, "\n"); + ++ if (index >= dev_priv->vbios.dcb.connector.entries) ++ return ERR_PTR(-EINVAL); ++ ++ dcb = &dev_priv->vbios.dcb.connector.entry[index]; ++ if (dcb->drm) ++ return dcb->drm; ++ + switch (dcb->type) { +- case DCB_CONNECTOR_NONE: +- return 0; + case DCB_CONNECTOR_VGA: +- NV_INFO(dev, "Detected a VGA connector\n"); + type = DRM_MODE_CONNECTOR_VGA; + break; + case DCB_CONNECTOR_TV_0: + case DCB_CONNECTOR_TV_1: + case DCB_CONNECTOR_TV_3: +- NV_INFO(dev, "Detected a TV connector\n"); + type = DRM_MODE_CONNECTOR_TV; + break; + case DCB_CONNECTOR_DVI_I: +- NV_INFO(dev, "Detected a DVI-I connector\n"); + type = DRM_MODE_CONNECTOR_DVII; + break; + case DCB_CONNECTOR_DVI_D: +- NV_INFO(dev, "Detected a DVI-D connector\n"); + type = DRM_MODE_CONNECTOR_DVID; + break; + case DCB_CONNECTOR_HDMI_0: + case DCB_CONNECTOR_HDMI_1: +- NV_INFO(dev, "Detected a HDMI connector\n"); + type = DRM_MODE_CONNECTOR_HDMIA; + break; + case DCB_CONNECTOR_LVDS: +- NV_INFO(dev, "Detected a LVDS connector\n"); + type = DRM_MODE_CONNECTOR_LVDS; ++ funcs = &nouveau_connector_funcs_lvds; + break; + case DCB_CONNECTOR_DP: +- NV_INFO(dev, "Detected a DisplayPort connector\n"); + type = DRM_MODE_CONNECTOR_DisplayPort; + break; + case DCB_CONNECTOR_eDP: +- NV_INFO(dev, "Detected an eDP connector\n"); + type = DRM_MODE_CONNECTOR_eDP; + break; + default: + NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type); +- return -EINVAL; ++ return ERR_PTR(-EINVAL); + } + + nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); + if (!nv_connector) +- return -ENOMEM; ++ return ERR_PTR(-ENOMEM); + nv_connector->dcb = dcb; + connector = &nv_connector->base; + +@@ -811,27 +841,21 @@ nouveau_connector_create(struct drm_device *dev, + connector->interlace_allowed = false; + connector->doublescan_allowed = false; + +- drm_connector_init(dev, connector, &nouveau_connector_funcs, type); ++ drm_connector_init(dev, connector, funcs, type); + drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); + +- /* attach encoders */ +- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { +- struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); +- +- if (nv_encoder->dcb->connector != dcb->index) +- continue; +- +- if (get_slave_funcs(nv_encoder)) +- get_slave_funcs(nv_encoder)->create_resources(encoder, connector); ++ /* Check if we need dithering enabled */ ++ if (dcb->type == DCB_CONNECTOR_LVDS) { ++ bool dummy, is_24bit = false; + +- drm_mode_connector_attach_encoder(connector, encoder); +- } ++ ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &is_24bit); ++ if (ret) { ++ NV_ERROR(dev, "Error parsing LVDS table, disabling " ++ "LVDS\n"); ++ goto fail; ++ } + +- if (!connector->encoder_ids[0]) { +- NV_WARN(dev, " no encoders, ignoring\n"); +- drm_connector_cleanup(connector); +- kfree(connector); +- return 0; ++ nv_connector->use_dithering = !is_24bit; + } + + /* Init DVI-I specific properties */ +@@ -841,12 +865,8 @@ nouveau_connector_create(struct drm_device *dev, + drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0); + } + +- if (dcb->type != DCB_CONNECTOR_LVDS) +- nv_connector->use_dithering = false; +- + switch (dcb->type) { + case DCB_CONNECTOR_VGA: +- connector->polled = DRM_CONNECTOR_POLL_CONNECT; + if (dev_priv->card_type >= NV_50) { + drm_connector_attach_property(connector, + dev->mode_config.scaling_mode_property, +@@ -858,17 +878,6 @@ nouveau_connector_create(struct drm_device *dev, + case DCB_CONNECTOR_TV_3: + nv_connector->scaling_mode = DRM_MODE_SCALE_NONE; + break; +- case DCB_CONNECTOR_DP: +- case DCB_CONNECTOR_eDP: +- case DCB_CONNECTOR_HDMI_0: +- case DCB_CONNECTOR_HDMI_1: +- case DCB_CONNECTOR_DVI_I: +- case DCB_CONNECTOR_DVI_D: +- if (dev_priv->card_type >= NV_50) +- connector->polled = DRM_CONNECTOR_POLL_HPD; +- else +- connector->polled = DRM_CONNECTOR_POLL_CONNECT; +- /* fall-through */ + default: + nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; + +@@ -882,15 +891,15 @@ nouveau_connector_create(struct drm_device *dev, + break; + } + ++ nouveau_connector_set_polling(connector); ++ + drm_sysfs_connector_add(connector); ++ dcb->drm = connector; ++ return dcb->drm; + +- if (dcb->type == DCB_CONNECTOR_LVDS) { +- ret = nouveau_connector_create_lvds(dev, connector); +- if (ret) { +- connector->funcs->destroy(connector); +- return ret; +- } +- } ++fail: ++ drm_connector_cleanup(connector); ++ kfree(connector); ++ return ERR_PTR(ret); + +- return 0; + } +diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h +index 4ef38ab..c21ed6b 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_connector.h ++++ b/drivers/gpu/drm/nouveau/nouveau_connector.h +@@ -49,7 +49,13 @@ static inline struct nouveau_connector *nouveau_connector( + return container_of(con, struct nouveau_connector, base); + } + +-int nouveau_connector_create(struct drm_device *, +- struct dcb_connector_table_entry *); ++struct drm_connector * ++nouveau_connector_create(struct drm_device *, int index); ++ ++void ++nouveau_connector_set_polling(struct drm_connector *); ++ ++int ++nouveau_connector_bpp(struct drm_connector *); + + #endif /* __NOUVEAU_CONNECTOR_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c +index 7933de4..8e15923 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c ++++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c +@@ -157,7 +157,23 @@ nouveau_debugfs_vbios_image(struct seq_file *m, void *data) + return 0; + } + ++static int ++nouveau_debugfs_evict_vram(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_nouveau_private *dev_priv = node->minor->dev->dev_private; ++ int ret; ++ ++ ret = ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); ++ if (ret) ++ seq_printf(m, "failed: %d", ret); ++ else ++ seq_printf(m, "succeeded\n"); ++ return 0; ++} ++ + static struct drm_info_list nouveau_debugfs_list[] = { ++ { "evict_vram", nouveau_debugfs_evict_vram, 0, NULL }, + { "chipset", nouveau_debugfs_chipset_info, 0, NULL }, + { "memory", nouveau_debugfs_memory_info, 0, NULL }, + { "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL }, +diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c +index 65c441a..eb24e2b 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_dma.c ++++ b/drivers/gpu/drm/nouveau/nouveau_dma.c +@@ -28,6 +28,7 @@ + #include "drm.h" + #include "nouveau_drv.h" + #include "nouveau_dma.h" ++#include "nouveau_ramht.h" + + void + nouveau_dma_pre_init(struct nouveau_channel *chan) +@@ -58,26 +59,27 @@ nouveau_dma_init(struct nouveau_channel *chan) + { + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_gpuobj *m2mf = NULL; +- struct nouveau_gpuobj *nvsw = NULL; ++ struct nouveau_gpuobj *obj = NULL; + int ret, i; + + /* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */ + ret = nouveau_gpuobj_gr_new(chan, dev_priv->card_type < NV_50 ? +- 0x0039 : 0x5039, &m2mf); ++ 0x0039 : 0x5039, &obj); + if (ret) + return ret; + +- ret = nouveau_gpuobj_ref_add(dev, chan, NvM2MF, m2mf, NULL); ++ ret = nouveau_ramht_insert(chan, NvM2MF, obj); ++ nouveau_gpuobj_ref(NULL, &obj); + if (ret) + return ret; + + /* Create an NV_SW object for various sync purposes */ +- ret = nouveau_gpuobj_sw_new(chan, NV_SW, &nvsw); ++ ret = nouveau_gpuobj_sw_new(chan, NV_SW, &obj); + if (ret) + return ret; + +- ret = nouveau_gpuobj_ref_add(dev, chan, NvSw, nvsw, NULL); ++ ret = nouveau_ramht_insert(chan, NvSw, obj); ++ nouveau_gpuobj_ref(NULL, &obj); + if (ret) + return ret; + +@@ -91,13 +93,6 @@ nouveau_dma_init(struct nouveau_channel *chan) + if (ret) + return ret; + +- /* Map M2MF notifier object - fbcon. */ +- if (drm_core_check_feature(dev, DRIVER_MODESET)) { +- ret = nouveau_bo_map(chan->notifier_bo); +- if (ret) +- return ret; +- } +- + /* Insert NOPS for NOUVEAU_DMA_SKIPS */ + ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); + if (ret) +@@ -219,7 +214,7 @@ nv50_dma_push_wait(struct nouveau_channel *chan, int count) + + chan->dma.ib_free = get - chan->dma.ib_put; + if (chan->dma.ib_free <= 0) +- chan->dma.ib_free += chan->dma.ib_max + 1; ++ chan->dma.ib_free += chan->dma.ib_max; + } + + return 0; +diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c +index deeb21c..4562f30 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_dp.c ++++ b/drivers/gpu/drm/nouveau/nouveau_dp.c +@@ -23,8 +23,10 @@ + */ + + #include "drmP.h" ++ + #include "nouveau_drv.h" + #include "nouveau_i2c.h" ++#include "nouveau_connector.h" + #include "nouveau_encoder.h" + + static int +@@ -270,13 +272,39 @@ bool + nouveau_dp_link_train(struct drm_encoder *encoder) + { + struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); +- uint8_t config[4]; +- uint8_t status[3]; ++ struct nouveau_connector *nv_connector; ++ struct bit_displayport_encoder_table *dpe; ++ int dpe_headerlen; ++ uint8_t config[4], status[3]; + bool cr_done, cr_max_vs, eq_done; + int ret = 0, i, tries, voltage; + + NV_DEBUG_KMS(dev, "link training!!\n"); ++ ++ nv_connector = nouveau_encoder_connector_get(nv_encoder); ++ if (!nv_connector) ++ return false; ++ ++ dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen); ++ if (!dpe) { ++ NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or); ++ return false; ++ } ++ ++ /* disable hotplug detect, this flips around on some panels during ++ * link training. ++ */ ++ pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, false); ++ ++ if (dpe->script0) { ++ NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or); ++ nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0), ++ nv_encoder->dcb); ++ } ++ + train: + cr_done = eq_done = false; + +@@ -289,7 +317,8 @@ train: + return false; + + config[0] = nv_encoder->dp.link_nr; +- if (nv_encoder->dp.dpcd_version >= 0x11) ++ if (nv_encoder->dp.dpcd_version >= 0x11 && ++ nv_encoder->dp.enhanced_frame) + config[0] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; + + ret = nouveau_dp_lane_count_set(encoder, config[0]); +@@ -403,6 +432,15 @@ stop: + } + } + ++ if (dpe->script1) { ++ NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or); ++ nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1), ++ nv_encoder->dcb); ++ } ++ ++ /* re-enable hotplug detect */ ++ pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, true); ++ + return eq_done; + } + +@@ -431,10 +469,12 @@ nouveau_dp_detect(struct drm_encoder *encoder) + !nv_encoder->dcb->dpconf.link_bw) + nv_encoder->dp.link_bw = DP_LINK_BW_1_62; + +- nv_encoder->dp.link_nr = dpcd[2] & 0xf; ++ nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK; + if (nv_encoder->dp.link_nr > nv_encoder->dcb->dpconf.link_nr) + nv_encoder->dp.link_nr = nv_encoder->dcb->dpconf.link_nr; + ++ nv_encoder->dp.enhanced_frame = (dpcd[2] & DP_ENHANCED_FRAME_CAP); ++ + return true; + } + +@@ -487,7 +527,8 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr, + nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x80000000); + nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl); + nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x00010000); +- if (!nv_wait(NV50_AUXCH_CTRL(index), 0x00010000, 0x00000000)) { ++ if (!nv_wait(dev, NV50_AUXCH_CTRL(index), ++ 0x00010000, 0x00000000)) { + NV_ERROR(dev, "expected bit 16 == 0, got 0x%08x\n", + nv_rd32(dev, NV50_AUXCH_CTRL(index))); + ret = -EBUSY; +@@ -535,47 +576,64 @@ out: + return ret ? ret : (stat & NV50_AUXCH_STAT_REPLY); + } + +-int +-nouveau_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, +- uint8_t write_byte, uint8_t *read_byte) ++static int ++nouveau_dp_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) + { +- struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; +- struct nouveau_i2c_chan *auxch = (struct nouveau_i2c_chan *)adapter; ++ struct nouveau_i2c_chan *auxch = (struct nouveau_i2c_chan *)adap; + struct drm_device *dev = auxch->dev; +- int ret = 0, cmd, addr = algo_data->address; +- uint8_t *buf; +- +- if (mode == MODE_I2C_READ) { +- cmd = AUX_I2C_READ; +- buf = read_byte; +- } else { +- cmd = (mode & MODE_I2C_READ) ? AUX_I2C_READ : AUX_I2C_WRITE; +- buf = &write_byte; +- } ++ struct i2c_msg *msg = msgs; ++ int ret, mcnt = num; + +- if (!(mode & MODE_I2C_STOP)) +- cmd |= AUX_I2C_MOT; ++ while (mcnt--) { ++ u8 remaining = msg->len; ++ u8 *ptr = msg->buf; + +- if (mode & MODE_I2C_START) +- return 1; ++ while (remaining) { ++ u8 cnt = (remaining > 16) ? 16 : remaining; ++ u8 cmd; + +- for (;;) { +- ret = nouveau_dp_auxch(auxch, cmd, addr, buf, 1); +- if (ret < 0) +- return ret; +- +- switch (ret & NV50_AUXCH_STAT_REPLY_I2C) { +- case NV50_AUXCH_STAT_REPLY_I2C_ACK: +- return 1; +- case NV50_AUXCH_STAT_REPLY_I2C_NACK: +- return -EREMOTEIO; +- case NV50_AUXCH_STAT_REPLY_I2C_DEFER: +- udelay(100); +- break; +- default: +- NV_ERROR(dev, "invalid auxch status: 0x%08x\n", ret); +- return -EREMOTEIO; ++ if (msg->flags & I2C_M_RD) ++ cmd = AUX_I2C_READ; ++ else ++ cmd = AUX_I2C_WRITE; ++ ++ if (mcnt || remaining > 16) ++ cmd |= AUX_I2C_MOT; ++ ++ ret = nouveau_dp_auxch(auxch, cmd, msg->addr, ptr, cnt); ++ if (ret < 0) ++ return ret; ++ ++ switch (ret & NV50_AUXCH_STAT_REPLY_I2C) { ++ case NV50_AUXCH_STAT_REPLY_I2C_ACK: ++ break; ++ case NV50_AUXCH_STAT_REPLY_I2C_NACK: ++ return -EREMOTEIO; ++ case NV50_AUXCH_STAT_REPLY_I2C_DEFER: ++ udelay(100); ++ continue; ++ default: ++ NV_ERROR(dev, "bad auxch reply: 0x%08x\n", ret); ++ return -EREMOTEIO; ++ } ++ ++ ptr += cnt; ++ remaining -= cnt; + } ++ ++ msg++; + } ++ ++ return num; ++} ++ ++static u32 ++nouveau_dp_i2c_func(struct i2c_adapter *adap) ++{ ++ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; + } + ++const struct i2c_algorithm nouveau_dp_i2c_algo = { ++ .master_xfer = nouveau_dp_i2c_xfer, ++ .functionality = nouveau_dp_i2c_func ++}; +diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c +index 2737704..ee2442f 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_drv.c ++++ b/drivers/gpu/drm/nouveau/nouveau_drv.c +@@ -35,13 +35,9 @@ + + #include "drm_pciids.h" + +-MODULE_PARM_DESC(ctxfw, "Use external firmware blob for grctx init (NV40)"); +-int nouveau_ctxfw = 0; +-module_param_named(ctxfw, nouveau_ctxfw, int, 0400); +- +-MODULE_PARM_DESC(noagp, "Disable AGP"); +-int nouveau_noagp; +-module_param_named(noagp, nouveau_noagp, int, 0400); ++MODULE_PARM_DESC(agpmode, "AGP mode (0 to disable AGP)"); ++int nouveau_agpmode = -1; ++module_param_named(agpmode, nouveau_agpmode, int, 0400); + + MODULE_PARM_DESC(modeset, "Enable kernel modesetting"); + static int nouveau_modeset = -1; /* kms */ +@@ -56,7 +52,7 @@ int nouveau_vram_pushbuf; + module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400); + + MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM"); +-int nouveau_vram_notify = 1; ++int nouveau_vram_notify = 0; + module_param_named(vram_notify, nouveau_vram_notify, int, 0400); + + MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)"); +@@ -83,6 +79,10 @@ MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration"); + int nouveau_nofbaccel = 0; + module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400); + ++MODULE_PARM_DESC(force_post, "Force POST"); ++int nouveau_force_post = 0; ++module_param_named(force_post, nouveau_force_post, int, 0400); ++ + MODULE_PARM_DESC(override_conntype, "Ignore DCB connector type"); + int nouveau_override_conntype = 0; + module_param_named(override_conntype, nouveau_override_conntype, int, 0400); +@@ -155,9 +155,6 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) + struct drm_crtc *crtc; + int ret, i; + +- if (!drm_core_check_feature(dev, DRIVER_MODESET)) +- return -ENODEV; +- + if (pm_state.event == PM_EVENT_PRETHAW) + return 0; + +@@ -257,9 +254,6 @@ nouveau_pci_resume(struct pci_dev *pdev) + struct drm_crtc *crtc; + int ret, i; + +- if (!drm_core_check_feature(dev, DRIVER_MODESET)) +- return -ENODEV; +- + nouveau_fbcon_save_disable_accel(dev); + + NV_INFO(dev, "We're back, enabling device...\n"); +@@ -269,6 +263,13 @@ nouveau_pci_resume(struct pci_dev *pdev) + return -1; + pci_set_master(dev->pdev); + ++ /* Make sure the AGP controller is in a consistent state */ ++ if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) ++ nouveau_mem_reset_agp(dev); ++ ++ /* Make the CRTCs accessible */ ++ engine->display.early_init(dev); ++ + NV_INFO(dev, "POSTing device...\n"); + ret = nouveau_run_vbios_init(dev); + if (ret) +@@ -323,7 +324,6 @@ nouveau_pci_resume(struct pci_dev *pdev) + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); +- int ret; + + ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); + if (!ret) +@@ -332,11 +332,7 @@ nouveau_pci_resume(struct pci_dev *pdev) + NV_ERROR(dev, "Could not pin/map cursor.\n"); + } + +- if (dev_priv->card_type < NV_50) { +- nv04_display_restore(dev); +- NVLockVgaCrtcs(dev, false); +- } else +- nv50_display_init(dev); ++ engine->display.init(dev); + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); +@@ -371,7 +367,8 @@ nouveau_pci_resume(struct pci_dev *pdev) + static struct drm_driver driver = { + .driver_features = + DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG | +- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM, ++ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | ++ DRIVER_MODESET, + .load = nouveau_load, + .firstopen = nouveau_firstopen, + .lastclose = nouveau_lastclose, +@@ -438,16 +435,18 @@ static int __init nouveau_init(void) + nouveau_modeset = 1; + } + +- if (nouveau_modeset == 1) { +- driver.driver_features |= DRIVER_MODESET; +- nouveau_register_dsm_handler(); +- } ++ if (!nouveau_modeset) ++ return 0; + ++ nouveau_register_dsm_handler(); + return drm_init(&driver); + } + + static void __exit nouveau_exit(void) + { ++ if (!nouveau_modeset) ++ return; ++ + drm_exit(&driver); + nouveau_unregister_dsm_handler(); + } +diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h +index 8be2f59..be53e92 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_drv.h ++++ b/drivers/gpu/drm/nouveau/nouveau_drv.h +@@ -123,14 +123,6 @@ nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo) + return ioptr; + } + +-struct mem_block { +- struct mem_block *next; +- struct mem_block *prev; +- uint64_t start; +- uint64_t size; +- struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ +-}; +- + enum nouveau_flags { + NV_NFORCE = 0x10000000, + NV_NFORCE2 = 0x20000000 +@@ -141,22 +133,24 @@ enum nouveau_flags { + #define NVOBJ_ENGINE_DISPLAY 2 + #define NVOBJ_ENGINE_INT 0xdeadbeef + +-#define NVOBJ_FLAG_ALLOW_NO_REFS (1 << 0) + #define NVOBJ_FLAG_ZERO_ALLOC (1 << 1) + #define NVOBJ_FLAG_ZERO_FREE (1 << 2) +-#define NVOBJ_FLAG_FAKE (1 << 3) + struct nouveau_gpuobj { ++ struct drm_device *dev; ++ struct kref refcount; + struct list_head list; + +- struct nouveau_channel *im_channel; +- struct mem_block *im_pramin; ++ struct drm_mm_node *im_pramin; + struct nouveau_bo *im_backing; +- uint32_t im_backing_start; + uint32_t *im_backing_suspend; + int im_bound; + + uint32_t flags; +- int refcount; ++ ++ u32 size; ++ u32 pinst; ++ u32 cinst; ++ u64 vinst; + + uint32_t engine; + uint32_t class; +@@ -165,16 +159,6 @@ struct nouveau_gpuobj { + void *priv; + }; + +-struct nouveau_gpuobj_ref { +- struct list_head list; +- +- struct nouveau_gpuobj *gpuobj; +- uint32_t instance; +- +- struct nouveau_channel *channel; +- int handle; +-}; +- + struct nouveau_channel { + struct drm_device *dev; + int id; +@@ -196,37 +180,36 @@ struct nouveau_channel { + struct list_head pending; + uint32_t sequence; + uint32_t sequence_ack; +- uint32_t last_sequence_irq; ++ atomic_t last_sequence_irq; + } fence; + + /* DMA push buffer */ +- struct nouveau_gpuobj_ref *pushbuf; +- struct nouveau_bo *pushbuf_bo; +- uint32_t pushbuf_base; ++ struct nouveau_gpuobj *pushbuf; ++ struct nouveau_bo *pushbuf_bo; ++ uint32_t pushbuf_base; + + /* Notifier memory */ + struct nouveau_bo *notifier_bo; +- struct mem_block *notifier_heap; ++ struct drm_mm notifier_heap; + + /* PFIFO context */ +- struct nouveau_gpuobj_ref *ramfc; +- struct nouveau_gpuobj_ref *cache; ++ struct nouveau_gpuobj *ramfc; ++ struct nouveau_gpuobj *cache; + + /* PGRAPH context */ + /* XXX may be merge 2 pointers as private data ??? */ +- struct nouveau_gpuobj_ref *ramin_grctx; ++ struct nouveau_gpuobj *ramin_grctx; + void *pgraph_ctx; + + /* NV50 VM */ +- struct nouveau_gpuobj *vm_pd; +- struct nouveau_gpuobj_ref *vm_gart_pt; +- struct nouveau_gpuobj_ref *vm_vram_pt[NV50_VM_VRAM_NR]; ++ struct nouveau_gpuobj *vm_pd; ++ struct nouveau_gpuobj *vm_gart_pt; ++ struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; + + /* Objects */ +- struct nouveau_gpuobj_ref *ramin; /* Private instmem */ +- struct mem_block *ramin_heap; /* Private PRAMIN heap */ +- struct nouveau_gpuobj_ref *ramht; /* Hash table */ +- struct list_head ramht_refs; /* Objects referenced by RAMHT */ ++ struct nouveau_gpuobj *ramin; /* Private instmem */ ++ struct drm_mm ramin_heap; /* Private PRAMIN heap */ ++ struct nouveau_ramht *ramht; /* Hash table */ + + /* GPU object info for stuff used in-kernel (mm_enabled) */ + uint32_t m2mf_ntfy; +@@ -277,8 +260,7 @@ struct nouveau_instmem_engine { + void (*clear)(struct drm_device *, struct nouveau_gpuobj *); + int (*bind)(struct drm_device *, struct nouveau_gpuobj *); + int (*unbind)(struct drm_device *, struct nouveau_gpuobj *); +- void (*prepare_access)(struct drm_device *, bool write); +- void (*finish_access)(struct drm_device *); ++ void (*flush)(struct drm_device *); + }; + + struct nouveau_mc_engine { +@@ -303,17 +285,17 @@ struct nouveau_fb_engine { + }; + + struct nouveau_fifo_engine { +- void *priv; +- + int channels; + ++ struct nouveau_gpuobj *playlist[2]; ++ int cur_playlist; ++ + int (*init)(struct drm_device *); + void (*takedown)(struct drm_device *); + + void (*disable)(struct drm_device *); + void (*enable)(struct drm_device *); + bool (*reassign)(struct drm_device *, bool enable); +- bool (*cache_flush)(struct drm_device *dev); + bool (*cache_pull)(struct drm_device *dev, bool enable); + + int (*channel_id)(struct drm_device *); +@@ -339,10 +321,11 @@ struct nouveau_pgraph_object_class { + struct nouveau_pgraph_engine { + struct nouveau_pgraph_object_class *grclass; + bool accel_blocked; +- void *ctxprog; +- void *ctxvals; + int grctx_size; + ++ /* NV2x/NV3x context table (0x400780) */ ++ struct nouveau_gpuobj *ctx_table; ++ + int (*init)(struct drm_device *); + void (*takedown)(struct drm_device *); + +@@ -358,6 +341,24 @@ struct nouveau_pgraph_engine { + uint32_t size, uint32_t pitch); + }; + ++struct nouveau_display_engine { ++ int (*early_init)(struct drm_device *); ++ void (*late_takedown)(struct drm_device *); ++ int (*create)(struct drm_device *); ++ int (*init)(struct drm_device *); ++ void (*destroy)(struct drm_device *); ++}; ++ ++struct nouveau_gpio_engine { ++ int (*init)(struct drm_device *); ++ void (*takedown)(struct drm_device *); ++ ++ int (*get)(struct drm_device *, enum dcb_gpio_tag); ++ int (*set)(struct drm_device *, enum dcb_gpio_tag, int state); ++ ++ void (*irq_enable)(struct drm_device *, enum dcb_gpio_tag, bool on); ++}; ++ + struct nouveau_engine { + struct nouveau_instmem_engine instmem; + struct nouveau_mc_engine mc; +@@ -365,6 +366,8 @@ struct nouveau_engine { + struct nouveau_fb_engine fb; + struct nouveau_pgraph_engine graph; + struct nouveau_fifo_engine fifo; ++ struct nouveau_display_engine display; ++ struct nouveau_gpio_engine gpio; + }; + + struct nouveau_pll_vals { +@@ -397,7 +400,7 @@ enum nv04_fp_display_regs { + + struct nv04_crtc_reg { + unsigned char MiscOutReg; /* */ +- uint8_t CRTC[0x9f]; ++ uint8_t CRTC[0xa0]; + uint8_t CR58[0x10]; + uint8_t Sequencer[5]; + uint8_t Graphics[9]; +@@ -496,15 +499,11 @@ enum nouveau_card_type { + NV_30 = 0x30, + NV_40 = 0x40, + NV_50 = 0x50, ++ NV_C0 = 0xc0, + }; + + struct drm_nouveau_private { + struct drm_device *dev; +- enum { +- NOUVEAU_CARD_INIT_DOWN, +- NOUVEAU_CARD_INIT_DONE, +- NOUVEAU_CARD_INIT_FAILED +- } init_state; + + /* the card type, takes NV_* as values */ + enum nouveau_card_type card_type; +@@ -513,8 +512,14 @@ struct drm_nouveau_private { + int flags; + + void __iomem *mmio; ++ ++ spinlock_t ramin_lock; + void __iomem *ramin; +- uint32_t ramin_size; ++ u32 ramin_size; ++ u32 ramin_base; ++ bool ramin_available; ++ struct drm_mm ramin_heap; ++ struct list_head gpuobj_list; + + struct nouveau_bo *vga_ram; + +@@ -528,13 +533,9 @@ struct drm_nouveau_private { + struct ttm_global_reference mem_global_ref; + struct ttm_bo_global_ref bo_global_ref; + struct ttm_bo_device bdev; +- spinlock_t bo_list_lock; +- struct list_head bo_list; + atomic_t validate_sequence; + } ttm; + +- struct fb_info *fbdev_info; +- + int fifo_alloc_count; + struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR]; + +@@ -545,15 +546,11 @@ struct drm_nouveau_private { + spinlock_t context_switch_lock; + + /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ +- struct nouveau_gpuobj *ramht; ++ struct nouveau_ramht *ramht; ++ struct nouveau_gpuobj *ramfc; ++ struct nouveau_gpuobj *ramro; ++ + uint32_t ramin_rsvd_vram; +- uint32_t ramht_offset; +- uint32_t ramht_size; +- uint32_t ramht_bits; +- uint32_t ramfc_offset; +- uint32_t ramfc_size; +- uint32_t ramro_offset; +- uint32_t ramro_size; + + struct { + enum { +@@ -571,14 +568,12 @@ struct drm_nouveau_private { + } gart_info; + + /* nv10-nv40 tiling regions */ +- struct { +- struct nouveau_tile_reg reg[NOUVEAU_MAX_TILE_NR]; +- spinlock_t lock; +- } tile; ++ struct nouveau_tile_reg tile[NOUVEAU_MAX_TILE_NR]; + + /* VRAM/fb configuration */ + uint64_t vram_size; + uint64_t vram_sys_base; ++ u32 vram_rblock_size; + + uint64_t fb_phys; + uint64_t fb_available_size; +@@ -595,14 +590,6 @@ struct drm_nouveau_private { + struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; + int vm_vram_pt_nr; + +- struct mem_block *ramin_heap; +- +- /* context table pointed to be NV_PGRAPH_CHANNEL_CTX_TABLE (0x400780) */ +- uint32_t ctx_table_size; +- struct nouveau_gpuobj_ref *ctx_table; +- +- struct list_head gpuobj_list; +- + struct nvbios vbios; + + struct nv04_mode_state mode_reg; +@@ -618,6 +605,11 @@ struct drm_nouveau_private { + struct backlight_device *backlight; + + struct nouveau_channel *evo; ++ struct { ++ struct dcb_entry *dcb; ++ u16 script; ++ u32 pclk; ++ } evo_irq; + + struct { + struct dentry *channel_root; +@@ -652,14 +644,6 @@ nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo) + return 0; + } + +-#define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do { \ +- struct drm_nouveau_private *nv = dev->dev_private; \ +- if (nv->init_state != NOUVEAU_CARD_INIT_DONE) { \ +- NV_ERROR(dev, "called without init\n"); \ +- return -EINVAL; \ +- } \ +-} while (0) +- + #define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id, cl, ch) do { \ + struct drm_nouveau_private *nv = dev->dev_private; \ + if (!nouveau_channel_owner(dev, (cl), (id))) { \ +@@ -671,7 +655,7 @@ nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo) + } while (0) + + /* nouveau_drv.c */ +-extern int nouveau_noagp; ++extern int nouveau_agpmode; + extern int nouveau_duallink; + extern int nouveau_uscript_lvds; + extern int nouveau_uscript_tmds; +@@ -682,10 +666,10 @@ extern int nouveau_tv_disable; + extern char *nouveau_tv_norm; + extern int nouveau_reg_debug; + extern char *nouveau_vbios; +-extern int nouveau_ctxfw; + extern int nouveau_ignorelid; + extern int nouveau_nofbaccel; + extern int nouveau_noaccel; ++extern int nouveau_force_post; + extern int nouveau_override_conntype; + + extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state); +@@ -707,17 +691,12 @@ extern bool nouveau_wait_for_idle(struct drm_device *); + extern int nouveau_card_init(struct drm_device *); + + /* nouveau_mem.c */ +-extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start, +- uint64_t size); +-extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *, +- uint64_t size, int align2, +- struct drm_file *, int tail); +-extern void nouveau_mem_takedown(struct mem_block **heap); +-extern void nouveau_mem_free_block(struct mem_block *); +-extern int nouveau_mem_detect(struct drm_device *dev); +-extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap); +-extern int nouveau_mem_init(struct drm_device *); ++extern int nouveau_mem_vram_init(struct drm_device *); ++extern void nouveau_mem_vram_fini(struct drm_device *); ++extern int nouveau_mem_gart_init(struct drm_device *); ++extern void nouveau_mem_gart_fini(struct drm_device *); + extern int nouveau_mem_init_agp(struct drm_device *); ++extern int nouveau_mem_reset_agp(struct drm_device *); + extern void nouveau_mem_close(struct drm_device *); + extern struct nouveau_tile_reg *nv10_mem_set_tiling(struct drm_device *dev, + uint32_t addr, +@@ -759,7 +738,6 @@ extern void nouveau_channel_free(struct nouveau_channel *); + extern int nouveau_gpuobj_early_init(struct drm_device *); + extern int nouveau_gpuobj_init(struct drm_device *); + extern void nouveau_gpuobj_takedown(struct drm_device *); +-extern void nouveau_gpuobj_late_takedown(struct drm_device *); + extern int nouveau_gpuobj_suspend(struct drm_device *dev); + extern void nouveau_gpuobj_suspend_cleanup(struct drm_device *dev); + extern void nouveau_gpuobj_resume(struct drm_device *dev); +@@ -769,24 +747,11 @@ extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *); + extern int nouveau_gpuobj_new(struct drm_device *, struct nouveau_channel *, + uint32_t size, int align, uint32_t flags, + struct nouveau_gpuobj **); +-extern int nouveau_gpuobj_del(struct drm_device *, struct nouveau_gpuobj **); +-extern int nouveau_gpuobj_ref_add(struct drm_device *, struct nouveau_channel *, +- uint32_t handle, struct nouveau_gpuobj *, +- struct nouveau_gpuobj_ref **); +-extern int nouveau_gpuobj_ref_del(struct drm_device *, +- struct nouveau_gpuobj_ref **); +-extern int nouveau_gpuobj_ref_find(struct nouveau_channel *, uint32_t handle, +- struct nouveau_gpuobj_ref **ref_ret); +-extern int nouveau_gpuobj_new_ref(struct drm_device *, +- struct nouveau_channel *alloc_chan, +- struct nouveau_channel *ref_chan, +- uint32_t handle, uint32_t size, int align, +- uint32_t flags, struct nouveau_gpuobj_ref **); +-extern int nouveau_gpuobj_new_fake(struct drm_device *, +- uint32_t p_offset, uint32_t b_offset, +- uint32_t size, uint32_t flags, +- struct nouveau_gpuobj **, +- struct nouveau_gpuobj_ref**); ++extern void nouveau_gpuobj_ref(struct nouveau_gpuobj *, ++ struct nouveau_gpuobj **); ++extern int nouveau_gpuobj_new_fake(struct drm_device *, u32 pinst, u64 vinst, ++ u32 size, u32 flags, ++ struct nouveau_gpuobj **); + extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class, + uint64_t offset, uint64_t size, int access, + int target, struct nouveau_gpuobj **); +@@ -857,11 +822,13 @@ void nouveau_register_dsm_handler(void); + void nouveau_unregister_dsm_handler(void); + int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); + bool nouveau_acpi_rom_supported(struct pci_dev *pdev); ++int nouveau_acpi_edid(struct drm_device *, struct drm_connector *); + #else + static inline void nouveau_register_dsm_handler(void) {} + static inline void nouveau_unregister_dsm_handler(void) {} + static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; } + static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; } ++static inline int nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return -EINVAL; } + #endif + + /* nouveau_backlight.c */ +@@ -924,22 +891,29 @@ extern void nv10_fb_takedown(struct drm_device *); + extern void nv10_fb_set_region_tiling(struct drm_device *, int, uint32_t, + uint32_t, uint32_t); + ++/* nv30_fb.c */ ++extern int nv30_fb_init(struct drm_device *); ++extern void nv30_fb_takedown(struct drm_device *); ++ + /* nv40_fb.c */ + extern int nv40_fb_init(struct drm_device *); + extern void nv40_fb_takedown(struct drm_device *); + extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t, + uint32_t, uint32_t); +- + /* nv50_fb.c */ + extern int nv50_fb_init(struct drm_device *); + extern void nv50_fb_takedown(struct drm_device *); ++extern void nv50_fb_vm_trap(struct drm_device *, int display, const char *); ++ ++/* nvc0_fb.c */ ++extern int nvc0_fb_init(struct drm_device *); ++extern void nvc0_fb_takedown(struct drm_device *); + + /* nv04_fifo.c */ + extern int nv04_fifo_init(struct drm_device *); + extern void nv04_fifo_disable(struct drm_device *); + extern void nv04_fifo_enable(struct drm_device *); + extern bool nv04_fifo_reassign(struct drm_device *, bool); +-extern bool nv04_fifo_cache_flush(struct drm_device *); + extern bool nv04_fifo_cache_pull(struct drm_device *, bool); + extern int nv04_fifo_channel_id(struct drm_device *); + extern int nv04_fifo_create_context(struct nouveau_channel *); +@@ -971,6 +945,19 @@ extern void nv50_fifo_destroy_context(struct nouveau_channel *); + extern int nv50_fifo_load_context(struct nouveau_channel *); + extern int nv50_fifo_unload_context(struct drm_device *); + ++/* nvc0_fifo.c */ ++extern int nvc0_fifo_init(struct drm_device *); ++extern void nvc0_fifo_takedown(struct drm_device *); ++extern void nvc0_fifo_disable(struct drm_device *); ++extern void nvc0_fifo_enable(struct drm_device *); ++extern bool nvc0_fifo_reassign(struct drm_device *, bool); ++extern bool nvc0_fifo_cache_pull(struct drm_device *, bool); ++extern int nvc0_fifo_channel_id(struct drm_device *); ++extern int nvc0_fifo_create_context(struct nouveau_channel *); ++extern void nvc0_fifo_destroy_context(struct nouveau_channel *); ++extern int nvc0_fifo_load_context(struct nouveau_channel *); ++extern int nvc0_fifo_unload_context(struct drm_device *); ++ + /* nv04_graph.c */ + extern struct nouveau_pgraph_object_class nv04_graph_grclass[]; + extern int nv04_graph_init(struct drm_device *); +@@ -1035,11 +1022,15 @@ extern int nv50_graph_unload_context(struct drm_device *); + extern void nv50_graph_context_switch(struct drm_device *); + extern int nv50_grctx_init(struct nouveau_grctx *); + +-/* nouveau_grctx.c */ +-extern int nouveau_grctx_prog_load(struct drm_device *); +-extern void nouveau_grctx_vals_load(struct drm_device *, +- struct nouveau_gpuobj *); +-extern void nouveau_grctx_fini(struct drm_device *); ++/* nvc0_graph.c */ ++extern int nvc0_graph_init(struct drm_device *); ++extern void nvc0_graph_takedown(struct drm_device *); ++extern void nvc0_graph_fifo_access(struct drm_device *, bool); ++extern struct nouveau_channel *nvc0_graph_channel(struct drm_device *); ++extern int nvc0_graph_create_context(struct nouveau_channel *); ++extern void nvc0_graph_destroy_context(struct nouveau_channel *); ++extern int nvc0_graph_load_context(struct nouveau_channel *); ++extern int nvc0_graph_unload_context(struct drm_device *); + + /* nv04_instmem.c */ + extern int nv04_instmem_init(struct drm_device *); +@@ -1051,8 +1042,7 @@ extern int nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, + extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); + extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); + extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); +-extern void nv04_instmem_prepare_access(struct drm_device *, bool write); +-extern void nv04_instmem_finish_access(struct drm_device *); ++extern void nv04_instmem_flush(struct drm_device *); + + /* nv50_instmem.c */ + extern int nv50_instmem_init(struct drm_device *); +@@ -1064,8 +1054,21 @@ extern int nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, + extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); + extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); + extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); +-extern void nv50_instmem_prepare_access(struct drm_device *, bool write); +-extern void nv50_instmem_finish_access(struct drm_device *); ++extern void nv50_instmem_flush(struct drm_device *); ++extern void nv84_instmem_flush(struct drm_device *); ++extern void nv50_vm_flush(struct drm_device *, int engine); ++ ++/* nvc0_instmem.c */ ++extern int nvc0_instmem_init(struct drm_device *); ++extern void nvc0_instmem_takedown(struct drm_device *); ++extern int nvc0_instmem_suspend(struct drm_device *); ++extern void nvc0_instmem_resume(struct drm_device *); ++extern int nvc0_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, ++ uint32_t *size); ++extern void nvc0_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); ++extern int nvc0_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); ++extern int nvc0_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); ++extern void nvc0_instmem_flush(struct drm_device *); + + /* nv04_mc.c */ + extern int nv04_mc_init(struct drm_device *); +@@ -1088,13 +1091,14 @@ extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); + + /* nv04_dac.c */ +-extern int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry); ++extern int nv04_dac_create(struct drm_connector *, struct dcb_entry *); + extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder); + extern int nv04_dac_output_offset(struct drm_encoder *encoder); + extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable); ++extern bool nv04_dac_in_use(struct drm_encoder *encoder); + + /* nv04_dfp.c */ +-extern int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry); ++extern int nv04_dfp_create(struct drm_connector *, struct dcb_entry *); + extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent); + extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent, + int head, bool dl); +@@ -1103,15 +1107,17 @@ extern void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode); + + /* nv04_tv.c */ + extern int nv04_tv_identify(struct drm_device *dev, int i2c_index); +-extern int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry); ++extern int nv04_tv_create(struct drm_connector *, struct dcb_entry *); + + /* nv17_tv.c */ +-extern int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry); ++extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *); + + /* nv04_display.c */ ++extern int nv04_display_early_init(struct drm_device *); ++extern void nv04_display_late_takedown(struct drm_device *); + extern int nv04_display_create(struct drm_device *); ++extern int nv04_display_init(struct drm_device *); + extern void nv04_display_destroy(struct drm_device *); +-extern void nv04_display_restore(struct drm_device *); + + /* nv04_crtc.c */ + extern int nv04_crtc_create(struct drm_device *, int index); +@@ -1148,7 +1154,6 @@ extern int nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr); + extern int nouveau_fence_flush(void *obj, void *arg); + extern void nouveau_fence_unref(void **obj); + extern void *nouveau_fence_ref(void *obj); +-extern void nouveau_fence_handler(struct drm_device *dev, int channel); + + /* nouveau_gem.c */ + extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *, +@@ -1168,13 +1173,15 @@ extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *, + extern int nouveau_gem_ioctl_info(struct drm_device *, void *, + struct drm_file *); + +-/* nv17_gpio.c */ +-int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); +-int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); ++/* nv10_gpio.c */ ++int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); ++int nv10_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); + + /* nv50_gpio.c */ ++int nv50_gpio_init(struct drm_device *dev); + int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); + int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); ++void nv50_gpio_irq_enable(struct drm_device *, enum dcb_gpio_tag, bool on); + + /* nv50_calc. */ + int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk, +@@ -1221,6 +1228,13 @@ static inline void nv_wr32(struct drm_device *dev, unsigned reg, u32 val) + iowrite32_native(val, dev_priv->mmio + reg); + } + ++static inline u32 nv_mask(struct drm_device *dev, u32 reg, u32 mask, u32 val) ++{ ++ u32 tmp = nv_rd32(dev, reg); ++ nv_wr32(dev, reg, (tmp & ~mask) | val); ++ return tmp; ++} ++ + static inline u8 nv_rd08(struct drm_device *dev, unsigned reg) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; +@@ -1233,7 +1247,7 @@ static inline void nv_wr08(struct drm_device *dev, unsigned reg, u8 val) + iowrite8(val, dev_priv->mmio + reg); + } + +-#define nv_wait(reg, mask, val) \ ++#define nv_wait(dev, reg, mask, val) \ + nouveau_wait_until(dev, 2000000000ULL, (reg), (mask), (val)) + + /* PRAMIN access */ +@@ -1250,17 +1264,8 @@ static inline void nv_wi32(struct drm_device *dev, unsigned offset, u32 val) + } + + /* object access */ +-static inline u32 nv_ro32(struct drm_device *dev, struct nouveau_gpuobj *obj, +- unsigned index) +-{ +- return nv_ri32(dev, obj->im_pramin->start + index * 4); +-} +- +-static inline void nv_wo32(struct drm_device *dev, struct nouveau_gpuobj *obj, +- unsigned index, u32 val) +-{ +- nv_wi32(dev, obj->im_pramin->start + index * 4, val); +-} ++extern u32 nv_ro32(struct nouveau_gpuobj *, u32 offset); ++extern void nv_wo32(struct nouveau_gpuobj *, u32 offset, u32 val); + + /* + * Logging +@@ -1347,6 +1352,15 @@ nv_two_reg_pll(struct drm_device *dev) + return false; + } + ++static inline bool ++nv_match_device(struct drm_device *dev, unsigned device, ++ unsigned sub_vendor, unsigned sub_device) ++{ ++ return dev->pdev->device == device && ++ dev->pdev->subsystem_vendor == sub_vendor && ++ dev->pdev->subsystem_device == sub_device; ++} ++ + #define NV_SW 0x0000506e + #define NV_SW_DMA_SEMAPHORE 0x00000060 + #define NV_SW_SEMAPHORE_OFFSET 0x00000064 +diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h +index e1df820..ae69b61 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h ++++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h +@@ -38,13 +38,15 @@ struct nouveau_encoder { + struct dcb_entry *dcb; + int or; + ++ /* different to drm_encoder.crtc, this reflects what's ++ * actually programmed on the hw, not the proposed crtc */ ++ struct drm_crtc *crtc; ++ + struct drm_display_mode mode; + int last_dpms; + + struct nv04_output_reg restore; + +- void (*disconnect)(struct nouveau_encoder *encoder); +- + union { + struct { + int mc_unknown; +@@ -53,6 +55,7 @@ struct nouveau_encoder { + int dpcd_version; + int link_nr; + int link_bw; ++ bool enhanced_frame; + } dp; + }; + }; +@@ -69,10 +72,16 @@ static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc) + return &enc->base.base; + } + ++static inline struct drm_encoder_slave_funcs * ++get_slave_funcs(struct drm_encoder *enc) ++{ ++ return to_encoder_slave(enc)->slave_funcs; ++} ++ + struct nouveau_connector * + nouveau_encoder_connector_get(struct nouveau_encoder *encoder); +-int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry); +-int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry); ++int nv50_sor_create(struct drm_connector *, struct dcb_entry *); ++int nv50_dac_create(struct drm_connector *, struct dcb_entry *); + + struct bit_displayport_encoder_table { + uint32_t match; +diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c +index 257ea13..11f13fc 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c ++++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c +@@ -280,6 +280,8 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, + + if (dev_priv->channel && !nouveau_nofbaccel) { + switch (dev_priv->card_type) { ++ case NV_C0: ++ break; + case NV_50: + nv50_fbcon_accel_init(info); + info->fbops = &nv50_fbcon_ops; +@@ -333,7 +335,7 @@ nouveau_fbcon_output_poll_changed(struct drm_device *dev) + drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper); + } + +-int ++static int + nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev) + { + struct nouveau_framebuffer *nouveau_fb = &nfbdev->nouveau_fb; +diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c +index faddf53..6b208ff 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_fence.c ++++ b/drivers/gpu/drm/nouveau/nouveau_fence.c +@@ -67,12 +67,13 @@ nouveau_fence_update(struct nouveau_channel *chan) + if (USE_REFCNT) + sequence = nvchan_rd32(chan, 0x48); + else +- sequence = chan->fence.last_sequence_irq; ++ sequence = atomic_read(&chan->fence.last_sequence_irq); + + if (chan->fence.sequence_ack == sequence) + return; + chan->fence.sequence_ack = sequence; + ++ spin_lock(&chan->fence.lock); + list_for_each_safe(entry, tmp, &chan->fence.pending) { + fence = list_entry(entry, struct nouveau_fence, entry); + +@@ -84,6 +85,7 @@ nouveau_fence_update(struct nouveau_channel *chan) + if (sequence == chan->fence.sequence_ack) + break; + } ++ spin_unlock(&chan->fence.lock); + } + + int +@@ -119,7 +121,6 @@ nouveau_fence_emit(struct nouveau_fence *fence) + { + struct drm_nouveau_private *dev_priv = fence->channel->dev->dev_private; + struct nouveau_channel *chan = fence->channel; +- unsigned long flags; + int ret; + + ret = RING_SPACE(chan, 2); +@@ -127,9 +128,7 @@ nouveau_fence_emit(struct nouveau_fence *fence) + return ret; + + if (unlikely(chan->fence.sequence == chan->fence.sequence_ack - 1)) { +- spin_lock_irqsave(&chan->fence.lock, flags); + nouveau_fence_update(chan); +- spin_unlock_irqrestore(&chan->fence.lock, flags); + + BUG_ON(chan->fence.sequence == + chan->fence.sequence_ack - 1); +@@ -138,9 +137,9 @@ nouveau_fence_emit(struct nouveau_fence *fence) + fence->sequence = ++chan->fence.sequence; + + kref_get(&fence->refcount); +- spin_lock_irqsave(&chan->fence.lock, flags); ++ spin_lock(&chan->fence.lock); + list_add_tail(&fence->entry, &chan->fence.pending); +- spin_unlock_irqrestore(&chan->fence.lock, flags); ++ spin_unlock(&chan->fence.lock); + + BEGIN_RING(chan, NvSubSw, USE_REFCNT ? 0x0050 : 0x0150, 1); + OUT_RING(chan, fence->sequence); +@@ -173,14 +172,11 @@ nouveau_fence_signalled(void *sync_obj, void *sync_arg) + { + struct nouveau_fence *fence = nouveau_fence(sync_obj); + struct nouveau_channel *chan = fence->channel; +- unsigned long flags; + + if (fence->signalled) + return true; + +- spin_lock_irqsave(&chan->fence.lock, flags); + nouveau_fence_update(chan); +- spin_unlock_irqrestore(&chan->fence.lock, flags); + return fence->signalled; + } + +@@ -190,8 +186,6 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) + unsigned long timeout = jiffies + (3 * DRM_HZ); + int ret = 0; + +- __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); +- + while (1) { + if (nouveau_fence_signalled(sync_obj, sync_arg)) + break; +@@ -201,6 +195,8 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) + break; + } + ++ __set_current_state(intr ? TASK_INTERRUPTIBLE ++ : TASK_UNINTERRUPTIBLE); + if (lazy) + schedule_timeout(1); + +@@ -221,27 +217,12 @@ nouveau_fence_flush(void *sync_obj, void *sync_arg) + return 0; + } + +-void +-nouveau_fence_handler(struct drm_device *dev, int channel) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_channel *chan = NULL; +- +- if (channel >= 0 && channel < dev_priv->engine.fifo.channels) +- chan = dev_priv->fifos[channel]; +- +- if (chan) { +- spin_lock_irq(&chan->fence.lock); +- nouveau_fence_update(chan); +- spin_unlock_irq(&chan->fence.lock); +- } +-} +- + int + nouveau_fence_init(struct nouveau_channel *chan) + { + INIT_LIST_HEAD(&chan->fence.pending); + spin_lock_init(&chan->fence.lock); ++ atomic_set(&chan->fence.last_sequence_irq, 0); + return 0; + } + +diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c +index 6937d53..613f878 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_gem.c ++++ b/drivers/gpu/drm/nouveau/nouveau_gem.c +@@ -137,8 +137,6 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, + uint32_t flags = 0; + int ret = 0; + +- NOUVEAU_CHECK_INITIALISED_WITH_RETURN; +- + if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL)) + dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping; + +@@ -578,10 +576,9 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, + struct drm_nouveau_gem_pushbuf_bo *bo; + struct nouveau_channel *chan; + struct validate_op op; +- struct nouveau_fence *fence = 0; ++ struct nouveau_fence *fence = NULL; + int i, j, ret = 0, do_reloc = 0; + +- NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan); + + req->vram_available = dev_priv->fb_aper_free; +@@ -666,7 +663,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, + push[i].length); + } + } else +- if (dev_priv->card_type >= NV_20) { ++ if (dev_priv->chipset >= 0x25) { + ret = RING_SPACE(chan, req->nr_push * 2); + if (ret) { + NV_ERROR(dev, "cal_space: %d\n", ret); +@@ -741,7 +738,7 @@ out_next: + req->suffix0 = 0x00000000; + req->suffix1 = 0x00000000; + } else +- if (dev_priv->card_type >= NV_20) { ++ if (dev_priv->chipset >= 0x25) { + req->suffix0 = 0x00020000; + req->suffix1 = 0x00000000; + } else { +@@ -776,8 +773,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, + bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT); + int ret = -EINVAL; + +- NOUVEAU_CHECK_INITIALISED_WITH_RETURN; +- + gem = drm_gem_object_lookup(dev, file_priv, req->handle); + if (!gem) + return ret; +@@ -816,8 +811,6 @@ nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data, + struct nouveau_bo *nvbo; + int ret = -EINVAL; + +- NOUVEAU_CHECK_INITIALISED_WITH_RETURN; +- + gem = drm_gem_object_lookup(dev, file_priv, req->handle); + if (!gem) + return ret; +@@ -843,8 +836,6 @@ nouveau_gem_ioctl_info(struct drm_device *dev, void *data, + struct drm_gem_object *gem; + int ret; + +- NOUVEAU_CHECK_INITIALISED_WITH_RETURN; +- + gem = drm_gem_object_lookup(dev, file_priv, req->handle); + if (!gem) + return -EINVAL; +diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.c b/drivers/gpu/drm/nouveau/nouveau_grctx.c +deleted file mode 100644 +index f731c5f..0000000 +--- a/drivers/gpu/drm/nouveau/nouveau_grctx.c ++++ /dev/null +@@ -1,160 +0,0 @@ +-/* +- * Copyright 2009 Red Hat Inc. +- * +- * Permission is hereby granted, free of charge, to any person obtaining a +- * copy of this software and associated documentation files (the "Software"), +- * to deal in the Software without restriction, including without limitation +- * the rights to use, copy, modify, merge, publish, distribute, sublicense, +- * and/or sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following conditions: +- * +- * The above copyright notice and this permission notice shall be included in +- * all copies or substantial portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +- * OTHER DEALINGS IN THE SOFTWARE. +- * +- * Authors: Ben Skeggs +- */ +- +-#include +-#include +- +-#include "drmP.h" +-#include "nouveau_drv.h" +- +-struct nouveau_ctxprog { +- uint32_t signature; +- uint8_t version; +- uint16_t length; +- uint32_t data[]; +-} __attribute__ ((packed)); +- +-struct nouveau_ctxvals { +- uint32_t signature; +- uint8_t version; +- uint32_t length; +- struct { +- uint32_t offset; +- uint32_t value; +- } data[]; +-} __attribute__ ((packed)); +- +-int +-nouveau_grctx_prog_load(struct drm_device *dev) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; +- const int chipset = dev_priv->chipset; +- const struct firmware *fw; +- const struct nouveau_ctxprog *cp; +- const struct nouveau_ctxvals *cv; +- char name[32]; +- int ret, i; +- +- if (pgraph->accel_blocked) +- return -ENODEV; +- +- if (!pgraph->ctxprog) { +- sprintf(name, "nouveau/nv%02x.ctxprog", chipset); +- ret = request_firmware(&fw, name, &dev->pdev->dev); +- if (ret) { +- NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset); +- return ret; +- } +- +- pgraph->ctxprog = kmemdup(fw->data, fw->size, GFP_KERNEL); +- if (!pgraph->ctxprog) { +- NV_ERROR(dev, "OOM copying ctxprog\n"); +- release_firmware(fw); +- return -ENOMEM; +- } +- +- cp = pgraph->ctxprog; +- if (le32_to_cpu(cp->signature) != 0x5043564e || +- cp->version != 0 || +- le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) { +- NV_ERROR(dev, "ctxprog invalid\n"); +- release_firmware(fw); +- nouveau_grctx_fini(dev); +- return -EINVAL; +- } +- release_firmware(fw); +- } +- +- if (!pgraph->ctxvals) { +- sprintf(name, "nouveau/nv%02x.ctxvals", chipset); +- ret = request_firmware(&fw, name, &dev->pdev->dev); +- if (ret) { +- NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset); +- nouveau_grctx_fini(dev); +- return ret; +- } +- +- pgraph->ctxvals = kmemdup(fw->data, fw->size, GFP_KERNEL); +- if (!pgraph->ctxvals) { +- NV_ERROR(dev, "OOM copying ctxvals\n"); +- release_firmware(fw); +- nouveau_grctx_fini(dev); +- return -ENOMEM; +- } +- +- cv = (void *)pgraph->ctxvals; +- if (le32_to_cpu(cv->signature) != 0x5643564e || +- cv->version != 0 || +- le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) { +- NV_ERROR(dev, "ctxvals invalid\n"); +- release_firmware(fw); +- nouveau_grctx_fini(dev); +- return -EINVAL; +- } +- release_firmware(fw); +- } +- +- cp = pgraph->ctxprog; +- +- nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); +- for (i = 0; i < le16_to_cpu(cp->length); i++) +- nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, +- le32_to_cpu(cp->data[i])); +- +- return 0; +-} +- +-void +-nouveau_grctx_fini(struct drm_device *dev) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; +- +- if (pgraph->ctxprog) { +- kfree(pgraph->ctxprog); +- pgraph->ctxprog = NULL; +- } +- +- if (pgraph->ctxvals) { +- kfree(pgraph->ctxprog); +- pgraph->ctxvals = NULL; +- } +-} +- +-void +-nouveau_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; +- struct nouveau_ctxvals *cv = pgraph->ctxvals; +- int i; +- +- if (!cv) +- return; +- +- for (i = 0; i < le32_to_cpu(cv->length); i++) +- nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset), +- le32_to_cpu(cv->data[i].value)); +-} +diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.h b/drivers/gpu/drm/nouveau/nouveau_grctx.h +index 5d39c4c..4a8ad13 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_grctx.h ++++ b/drivers/gpu/drm/nouveau/nouveau_grctx.h +@@ -126,7 +126,7 @@ gr_def(struct nouveau_grctx *ctx, uint32_t reg, uint32_t val) + reg = (reg - 0x00400000) / 4; + reg = (reg - ctx->ctxprog_reg) + ctx->ctxvals_base; + +- nv_wo32(ctx->dev, ctx->data, reg, val); ++ nv_wo32(ctx->data, reg * 4, val); + } + #endif + +diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c +index 7855b35..cb13134 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_hw.c ++++ b/drivers/gpu/drm/nouveau/nouveau_hw.c +@@ -305,7 +305,7 @@ setPLL_double_lowregs(struct drm_device *dev, uint32_t NMNMreg, + bool mpll = Preg == 0x4020; + uint32_t oldPval = nvReadMC(dev, Preg); + uint32_t NMNM = pv->NM2 << 16 | pv->NM1; +- uint32_t Pval = (oldPval & (mpll ? ~(0x11 << 16) : ~(1 << 16))) | ++ uint32_t Pval = (oldPval & (mpll ? ~(0x77 << 16) : ~(7 << 16))) | + 0xc << 28 | pv->log2P << 16; + uint32_t saved4600 = 0; + /* some cards have different maskc040s */ +@@ -865,8 +865,13 @@ nv_save_state_ext(struct drm_device *dev, int head, + rd_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX); + rd_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX); + rd_cio_state(dev, head, regp, NV_CIO_CRE_21); +- if (dev_priv->card_type >= NV_30) ++ ++ if (dev_priv->card_type >= NV_20) + rd_cio_state(dev, head, regp, NV_CIO_CRE_47); ++ ++ if (dev_priv->card_type >= NV_30) ++ rd_cio_state(dev, head, regp, 0x9f); ++ + rd_cio_state(dev, head, regp, NV_CIO_CRE_49); + rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); + rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX); +@@ -971,9 +976,13 @@ nv_load_state_ext(struct drm_device *dev, int head, + wr_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX); + wr_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX); + wr_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX); +- if (dev_priv->card_type >= NV_30) ++ ++ if (dev_priv->card_type >= NV_20) + wr_cio_state(dev, head, regp, NV_CIO_CRE_47); + ++ if (dev_priv->card_type >= NV_30) ++ wr_cio_state(dev, head, regp, 0x9f); ++ + wr_cio_state(dev, head, regp, NV_CIO_CRE_49); + wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); + wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX); +diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c +index 316a3c7..8461485 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_i2c.c ++++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c +@@ -163,7 +163,7 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index) + if (entry->chan) + return -EEXIST; + +- if (dev_priv->card_type == NV_50 && entry->read >= NV50_I2C_PORTS) { ++ if (dev_priv->card_type >= NV_50 && entry->read >= NV50_I2C_PORTS) { + NV_ERROR(dev, "unknown i2c port %d\n", entry->read); + return -EINVAL; + } +@@ -174,26 +174,26 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index) + + switch (entry->port_type) { + case 0: +- i2c->algo.bit.setsda = nv04_i2c_setsda; +- i2c->algo.bit.setscl = nv04_i2c_setscl; +- i2c->algo.bit.getsda = nv04_i2c_getsda; +- i2c->algo.bit.getscl = nv04_i2c_getscl; ++ i2c->bit.setsda = nv04_i2c_setsda; ++ i2c->bit.setscl = nv04_i2c_setscl; ++ i2c->bit.getsda = nv04_i2c_getsda; ++ i2c->bit.getscl = nv04_i2c_getscl; + i2c->rd = entry->read; + i2c->wr = entry->write; + break; + case 4: +- i2c->algo.bit.setsda = nv4e_i2c_setsda; +- i2c->algo.bit.setscl = nv4e_i2c_setscl; +- i2c->algo.bit.getsda = nv4e_i2c_getsda; +- i2c->algo.bit.getscl = nv4e_i2c_getscl; ++ i2c->bit.setsda = nv4e_i2c_setsda; ++ i2c->bit.setscl = nv4e_i2c_setscl; ++ i2c->bit.getsda = nv4e_i2c_getsda; ++ i2c->bit.getscl = nv4e_i2c_getscl; + i2c->rd = 0x600800 + entry->read; + i2c->wr = 0x600800 + entry->write; + break; + case 5: +- i2c->algo.bit.setsda = nv50_i2c_setsda; +- i2c->algo.bit.setscl = nv50_i2c_setscl; +- i2c->algo.bit.getsda = nv50_i2c_getsda; +- i2c->algo.bit.getscl = nv50_i2c_getscl; ++ i2c->bit.setsda = nv50_i2c_setsda; ++ i2c->bit.setscl = nv50_i2c_setscl; ++ i2c->bit.getsda = nv50_i2c_getsda; ++ i2c->bit.getscl = nv50_i2c_getscl; + i2c->rd = nv50_i2c_port[entry->read]; + i2c->wr = i2c->rd; + break; +@@ -216,17 +216,14 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index) + i2c_set_adapdata(&i2c->adapter, i2c); + + if (entry->port_type < 6) { +- i2c->adapter.algo_data = &i2c->algo.bit; +- i2c->algo.bit.udelay = 40; +- i2c->algo.bit.timeout = usecs_to_jiffies(5000); +- i2c->algo.bit.data = i2c; ++ i2c->adapter.algo_data = &i2c->bit; ++ i2c->bit.udelay = 40; ++ i2c->bit.timeout = usecs_to_jiffies(5000); ++ i2c->bit.data = i2c; + ret = i2c_bit_add_bus(&i2c->adapter); + } else { +- i2c->adapter.algo_data = &i2c->algo.dp; +- i2c->algo.dp.running = false; +- i2c->algo.dp.address = 0; +- i2c->algo.dp.aux_ch = nouveau_dp_i2c_aux_ch; +- ret = i2c_dp_aux_add_bus(&i2c->adapter); ++ i2c->adapter.algo = &nouveau_dp_i2c_algo; ++ ret = i2c_add_adapter(&i2c->adapter); + } + + if (ret) { +@@ -278,3 +275,45 @@ nouveau_i2c_find(struct drm_device *dev, int index) + return i2c->chan; + } + ++bool ++nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr) ++{ ++ uint8_t buf[] = { 0 }; ++ struct i2c_msg msgs[] = { ++ { ++ .addr = addr, ++ .flags = 0, ++ .len = 1, ++ .buf = buf, ++ }, ++ { ++ .addr = addr, ++ .flags = I2C_M_RD, ++ .len = 1, ++ .buf = buf, ++ } ++ }; ++ ++ return i2c_transfer(&i2c->adapter, msgs, 2) == 2; ++} ++ ++int ++nouveau_i2c_identify(struct drm_device *dev, const char *what, ++ struct i2c_board_info *info, int index) ++{ ++ struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index); ++ int i; ++ ++ NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index); ++ ++ for (i = 0; info[i].addr; i++) { ++ if (nouveau_probe_i2c_addr(i2c, info[i].addr)) { ++ NV_INFO(dev, "Detected %s: %s\n", what, info[i].type); ++ return i; ++ } ++ } ++ ++ NV_DEBUG(dev, "No devices found.\n"); ++ ++ return -ENODEV; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.h b/drivers/gpu/drm/nouveau/nouveau_i2c.h +index c8eaf7a..f71cb32 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_i2c.h ++++ b/drivers/gpu/drm/nouveau/nouveau_i2c.h +@@ -33,10 +33,7 @@ struct dcb_i2c_entry; + struct nouveau_i2c_chan { + struct i2c_adapter adapter; + struct drm_device *dev; +- union { +- struct i2c_algo_bit_data bit; +- struct i2c_algo_dp_aux_data dp; +- } algo; ++ struct i2c_algo_bit_data bit; + unsigned rd; + unsigned wr; + unsigned data; +@@ -45,8 +42,10 @@ struct nouveau_i2c_chan { + int nouveau_i2c_init(struct drm_device *, struct dcb_i2c_entry *, int index); + void nouveau_i2c_fini(struct drm_device *, struct dcb_i2c_entry *); + struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index); ++bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr); ++int nouveau_i2c_identify(struct drm_device *dev, const char *what, ++ struct i2c_board_info *info, int index); + +-int nouveau_dp_i2c_aux_ch(struct i2c_adapter *, int mode, uint8_t write_byte, +- uint8_t *read_byte); ++extern const struct i2c_algorithm nouveau_dp_i2c_algo; + + #endif /* __NOUVEAU_I2C_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c +index 53360f1..6fd51a5 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_irq.c ++++ b/drivers/gpu/drm/nouveau/nouveau_irq.c +@@ -35,6 +35,7 @@ + #include "nouveau_drm.h" + #include "nouveau_drv.h" + #include "nouveau_reg.h" ++#include "nouveau_ramht.h" + #include + + /* needed for hotplug irq */ +@@ -49,7 +50,7 @@ nouveau_irq_preinstall(struct drm_device *dev) + /* Master disable */ + nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); + +- if (dev_priv->card_type == NV_50) { ++ if (dev_priv->card_type >= NV_50) { + INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); + INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh); + INIT_LIST_HEAD(&dev_priv->vbl_waiting); +@@ -106,15 +107,16 @@ nouveau_fifo_swmthd(struct nouveau_channel *chan, uint32_t addr, uint32_t data) + const int mthd = addr & 0x1ffc; + + if (mthd == 0x0000) { +- struct nouveau_gpuobj_ref *ref = NULL; ++ struct nouveau_gpuobj *gpuobj; + +- if (nouveau_gpuobj_ref_find(chan, data, &ref)) ++ gpuobj = nouveau_ramht_find(chan, data); ++ if (!gpuobj) + return false; + +- if (ref->gpuobj->engine != NVOBJ_ENGINE_SW) ++ if (gpuobj->engine != NVOBJ_ENGINE_SW) + return false; + +- chan->sw_subchannel[subc] = ref->gpuobj->class; ++ chan->sw_subchannel[subc] = gpuobj->class; + nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_rd32(dev, + NV04_PFIFO_CACHE1_ENGINE) & ~(0xf << subc * 4)); + return true; +@@ -200,16 +202,45 @@ nouveau_fifo_irq_handler(struct drm_device *dev) + } + + if (status & NV_PFIFO_INTR_DMA_PUSHER) { +- NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d\n", chid); ++ u32 get = nv_rd32(dev, 0x003244); ++ u32 put = nv_rd32(dev, 0x003240); ++ u32 push = nv_rd32(dev, 0x003220); ++ u32 state = nv_rd32(dev, 0x003228); ++ ++ if (dev_priv->card_type == NV_50) { ++ u32 ho_get = nv_rd32(dev, 0x003328); ++ u32 ho_put = nv_rd32(dev, 0x003320); ++ u32 ib_get = nv_rd32(dev, 0x003334); ++ u32 ib_put = nv_rd32(dev, 0x003330); ++ ++ NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x " ++ "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x " ++ "State 0x%08x Push 0x%08x\n", ++ chid, ho_get, get, ho_put, put, ib_get, ib_put, ++ state, push); ++ ++ /* METHOD_COUNT, in DMA_STATE on earlier chipsets */ ++ nv_wr32(dev, 0x003364, 0x00000000); ++ if (get != put || ho_get != ho_put) { ++ nv_wr32(dev, 0x003244, put); ++ nv_wr32(dev, 0x003328, ho_put); ++ } else ++ if (ib_get != ib_put) { ++ nv_wr32(dev, 0x003334, ib_put); ++ } ++ } else { ++ NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%08x " ++ "Put 0x%08x State 0x%08x Push 0x%08x\n", ++ chid, get, put, state, push); + +- status &= ~NV_PFIFO_INTR_DMA_PUSHER; +- nv_wr32(dev, NV03_PFIFO_INTR_0, +- NV_PFIFO_INTR_DMA_PUSHER); ++ if (get != put) ++ nv_wr32(dev, 0x003244, put); ++ } + +- nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000); +- if (nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT) != get) +- nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, +- get + 4); ++ nv_wr32(dev, 0x003228, 0x00000000); ++ nv_wr32(dev, 0x003220, 0x00000001); ++ nv_wr32(dev, 0x002100, NV_PFIFO_INTR_DMA_PUSHER); ++ status &= ~NV_PFIFO_INTR_DMA_PUSHER; + } + + if (status & NV_PFIFO_INTR_SEMAPHORE) { +@@ -226,6 +257,14 @@ nouveau_fifo_irq_handler(struct drm_device *dev) + nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1); + } + ++ if (dev_priv->card_type == NV_50) { ++ if (status & 0x00000010) { ++ nv50_fb_vm_trap(dev, 1, "PFIFO_BAR_FAULT"); ++ status &= ~0x00000010; ++ nv_wr32(dev, 0x002100, 0x00000010); ++ } ++ } ++ + if (status) { + NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n", + status, chid); +@@ -357,7 +396,7 @@ nouveau_graph_chid_from_grctx(struct drm_device *dev) + if (!chan || !chan->ramin_grctx) + continue; + +- if (inst == chan->ramin_grctx->instance) ++ if (inst == chan->ramin_grctx->pinst) + break; + } + } else { +@@ -369,7 +408,7 @@ nouveau_graph_chid_from_grctx(struct drm_device *dev) + if (!chan || !chan->ramin) + continue; + +- if (inst == chan->ramin->instance) ++ if (inst == chan->ramin->vinst) + break; + } + } +@@ -586,11 +625,11 @@ nouveau_pgraph_irq_handler(struct drm_device *dev) + } + + if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) { +- nouveau_pgraph_intr_context_switch(dev); +- + status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; + nv_wr32(dev, NV03_PGRAPH_INTR, + NV_PGRAPH_INTR_CONTEXT_SWITCH); ++ ++ nouveau_pgraph_intr_context_switch(dev); + } + + if (status) { +@@ -605,40 +644,6 @@ nouveau_pgraph_irq_handler(struct drm_device *dev) + nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); + } + +-static void +-nv50_pfb_vm_trap(struct drm_device *dev, int display, const char *name) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- uint32_t trap[6]; +- int i, ch; +- uint32_t idx = nv_rd32(dev, 0x100c90); +- if (idx & 0x80000000) { +- idx &= 0xffffff; +- if (display) { +- for (i = 0; i < 6; i++) { +- nv_wr32(dev, 0x100c90, idx | i << 24); +- trap[i] = nv_rd32(dev, 0x100c94); +- } +- for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) { +- struct nouveau_channel *chan = dev_priv->fifos[ch]; +- +- if (!chan || !chan->ramin) +- continue; +- +- if (trap[1] == chan->ramin->instance >> 12) +- break; +- } +- NV_INFO(dev, "%s - VM: Trapped %s at %02x%04x%04x status %08x %08x channel %d\n", +- name, (trap[5]&0x100?"read":"write"), +- trap[5]&0xff, trap[4]&0xffff, +- trap[3]&0xffff, trap[0], trap[2], ch); +- } +- nv_wr32(dev, 0x100c90, idx | 0x80000000); +- } else if (display) { +- NV_INFO(dev, "%s - no VM fault?\n", name); +- } +-} +- + static struct nouveau_enum_names nv50_mp_exec_error_names[] = + { + { 3, "STACK_UNDERFLOW" }, +@@ -711,7 +716,7 @@ nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t ustatus_old, + tps++; + switch (type) { + case 6: /* texture error... unknown for now */ +- nv50_pfb_vm_trap(dev, display, name); ++ nv50_fb_vm_trap(dev, display, name); + if (display) { + NV_ERROR(dev, "magic set %d:\n", i); + for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4) +@@ -734,7 +739,7 @@ nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t ustatus_old, + uint32_t e1c = nv_rd32(dev, ustatus_addr + 0x14); + uint32_t e20 = nv_rd32(dev, ustatus_addr + 0x18); + uint32_t e24 = nv_rd32(dev, ustatus_addr + 0x1c); +- nv50_pfb_vm_trap(dev, display, name); ++ nv50_fb_vm_trap(dev, display, name); + /* 2d engine destination */ + if (ustatus & 0x00000010) { + if (display) { +@@ -817,7 +822,7 @@ nv50_pgraph_trap_handler(struct drm_device *dev) + + /* Known to be triggered by screwed up NOTIFY and COND... */ + if (ustatus & 0x00000001) { +- nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_FAULT"); ++ nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_FAULT"); + nv_wr32(dev, 0x400500, 0); + if (nv_rd32(dev, 0x400808) & 0x80000000) { + if (display) { +@@ -842,7 +847,7 @@ nv50_pgraph_trap_handler(struct drm_device *dev) + ustatus &= ~0x00000001; + } + if (ustatus & 0x00000002) { +- nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_QUERY"); ++ nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_QUERY"); + nv_wr32(dev, 0x400500, 0); + if (nv_rd32(dev, 0x40084c) & 0x80000000) { + if (display) { +@@ -884,15 +889,15 @@ nv50_pgraph_trap_handler(struct drm_device *dev) + NV_INFO(dev, "PGRAPH_TRAP_M2MF - no ustatus?\n"); + } + if (ustatus & 0x00000001) { +- nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_NOTIFY"); ++ nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_NOTIFY"); + ustatus &= ~0x00000001; + } + if (ustatus & 0x00000002) { +- nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_IN"); ++ nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_IN"); + ustatus &= ~0x00000002; + } + if (ustatus & 0x00000004) { +- nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_OUT"); ++ nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_OUT"); + ustatus &= ~0x00000004; + } + NV_INFO (dev, "PGRAPH_TRAP_M2MF - %08x %08x %08x %08x\n", +@@ -917,7 +922,7 @@ nv50_pgraph_trap_handler(struct drm_device *dev) + NV_INFO(dev, "PGRAPH_TRAP_VFETCH - no ustatus?\n"); + } + if (ustatus & 0x00000001) { +- nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_VFETCH_FAULT"); ++ nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_VFETCH_FAULT"); + NV_INFO (dev, "PGRAPH_TRAP_VFETCH_FAULT - %08x %08x %08x %08x\n", + nv_rd32(dev, 0x400c00), + nv_rd32(dev, 0x400c08), +@@ -939,7 +944,7 @@ nv50_pgraph_trap_handler(struct drm_device *dev) + NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - no ustatus?\n"); + } + if (ustatus & 0x00000001) { +- nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_STRMOUT_FAULT"); ++ nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_STRMOUT_FAULT"); + NV_INFO (dev, "PGRAPH_TRAP_STRMOUT_FAULT - %08x %08x %08x %08x\n", + nv_rd32(dev, 0x401804), + nv_rd32(dev, 0x401808), +@@ -964,7 +969,7 @@ nv50_pgraph_trap_handler(struct drm_device *dev) + NV_INFO(dev, "PGRAPH_TRAP_CCACHE - no ustatus?\n"); + } + if (ustatus & 0x00000001) { +- nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_CCACHE_FAULT"); ++ nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_CCACHE_FAULT"); + NV_INFO (dev, "PGRAPH_TRAP_CCACHE_FAULT - %08x %08x %08x %08x %08x %08x %08x\n", + nv_rd32(dev, 0x405800), + nv_rd32(dev, 0x405804), +@@ -986,7 +991,7 @@ nv50_pgraph_trap_handler(struct drm_device *dev) + * remaining, so try to handle it anyway. Perhaps related to that + * unknown DMA slot on tesla? */ + if (status & 0x20) { +- nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_UNKC04"); ++ nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_UNKC04"); + ustatus = nv_rd32(dev, 0x402000) & 0x7fffffff; + if (display) + NV_INFO(dev, "PGRAPH_TRAP_UNKC04 - Unhandled ustatus 0x%08x\n", ustatus); +diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c +index c1fd42b..4f0ae39 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_mem.c ++++ b/drivers/gpu/drm/nouveau/nouveau_mem.c +@@ -35,162 +35,6 @@ + #include "drm_sarea.h" + #include "nouveau_drv.h" + +-static struct mem_block * +-split_block(struct mem_block *p, uint64_t start, uint64_t size, +- struct drm_file *file_priv) +-{ +- /* Maybe cut off the start of an existing block */ +- if (start > p->start) { +- struct mem_block *newblock = +- kmalloc(sizeof(*newblock), GFP_KERNEL); +- if (!newblock) +- goto out; +- newblock->start = start; +- newblock->size = p->size - (start - p->start); +- newblock->file_priv = NULL; +- newblock->next = p->next; +- newblock->prev = p; +- p->next->prev = newblock; +- p->next = newblock; +- p->size -= newblock->size; +- p = newblock; +- } +- +- /* Maybe cut off the end of an existing block */ +- if (size < p->size) { +- struct mem_block *newblock = +- kmalloc(sizeof(*newblock), GFP_KERNEL); +- if (!newblock) +- goto out; +- newblock->start = start + size; +- newblock->size = p->size - size; +- newblock->file_priv = NULL; +- newblock->next = p->next; +- newblock->prev = p; +- p->next->prev = newblock; +- p->next = newblock; +- p->size = size; +- } +- +-out: +- /* Our block is in the middle */ +- p->file_priv = file_priv; +- return p; +-} +- +-struct mem_block * +-nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size, +- int align2, struct drm_file *file_priv, int tail) +-{ +- struct mem_block *p; +- uint64_t mask = (1 << align2) - 1; +- +- if (!heap) +- return NULL; +- +- if (tail) { +- list_for_each_prev(p, heap) { +- uint64_t start = ((p->start + p->size) - size) & ~mask; +- +- if (p->file_priv == NULL && start >= p->start && +- start + size <= p->start + p->size) +- return split_block(p, start, size, file_priv); +- } +- } else { +- list_for_each(p, heap) { +- uint64_t start = (p->start + mask) & ~mask; +- +- if (p->file_priv == NULL && +- start + size <= p->start + p->size) +- return split_block(p, start, size, file_priv); +- } +- } +- +- return NULL; +-} +- +-void nouveau_mem_free_block(struct mem_block *p) +-{ +- p->file_priv = NULL; +- +- /* Assumes a single contiguous range. Needs a special file_priv in +- * 'heap' to stop it being subsumed. +- */ +- if (p->next->file_priv == NULL) { +- struct mem_block *q = p->next; +- p->size += q->size; +- p->next = q->next; +- p->next->prev = p; +- kfree(q); +- } +- +- if (p->prev->file_priv == NULL) { +- struct mem_block *q = p->prev; +- q->size += p->size; +- q->next = p->next; +- q->next->prev = q; +- kfree(p); +- } +-} +- +-/* Initialize. How to check for an uninitialized heap? +- */ +-int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start, +- uint64_t size) +-{ +- struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL); +- +- if (!blocks) +- return -ENOMEM; +- +- *heap = kmalloc(sizeof(**heap), GFP_KERNEL); +- if (!*heap) { +- kfree(blocks); +- return -ENOMEM; +- } +- +- blocks->start = start; +- blocks->size = size; +- blocks->file_priv = NULL; +- blocks->next = blocks->prev = *heap; +- +- memset(*heap, 0, sizeof(**heap)); +- (*heap)->file_priv = (struct drm_file *) -1; +- (*heap)->next = (*heap)->prev = blocks; +- return 0; +-} +- +-/* +- * Free all blocks associated with the releasing file_priv +- */ +-void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap) +-{ +- struct mem_block *p; +- +- if (!heap || !heap->next) +- return; +- +- list_for_each(p, heap) { +- if (p->file_priv == file_priv) +- p->file_priv = NULL; +- } +- +- /* Assumes a single contiguous range. Needs a special file_priv in +- * 'heap' to stop it being subsumed. +- */ +- list_for_each(p, heap) { +- while ((p->file_priv == NULL) && +- (p->next->file_priv == NULL) && +- (p->next != heap)) { +- struct mem_block *q = p->next; +- p->size += q->size; +- p->next = q->next; +- p->next->prev = p; +- kfree(q); +- } +- } +-} +- + /* + * NV10-NV40 tiling helpers + */ +@@ -203,18 +47,14 @@ nv10_mem_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; +- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; ++ struct nouveau_tile_reg *tile = &dev_priv->tile[i]; + + tile->addr = addr; + tile->size = size; + tile->used = !!pitch; + nouveau_fence_unref((void **)&tile->fence); + +- if (!pfifo->cache_flush(dev)) +- return; +- + pfifo->reassign(dev, false); +- pfifo->cache_flush(dev); + pfifo->cache_pull(dev, false); + + nouveau_wait_for_idle(dev); +@@ -232,34 +72,36 @@ nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size, + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; +- struct nouveau_tile_reg *tile = dev_priv->tile.reg, *found = NULL; +- int i; ++ struct nouveau_tile_reg *found = NULL; ++ unsigned long i, flags; + +- spin_lock(&dev_priv->tile.lock); ++ spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + + for (i = 0; i < pfb->num_tiles; i++) { +- if (tile[i].used) ++ struct nouveau_tile_reg *tile = &dev_priv->tile[i]; ++ ++ if (tile->used) + /* Tile region in use. */ + continue; + +- if (tile[i].fence && +- !nouveau_fence_signalled(tile[i].fence, NULL)) ++ if (tile->fence && ++ !nouveau_fence_signalled(tile->fence, NULL)) + /* Pending tile region. */ + continue; + +- if (max(tile[i].addr, addr) < +- min(tile[i].addr + tile[i].size, addr + size)) ++ if (max(tile->addr, addr) < ++ min(tile->addr + tile->size, addr + size)) + /* Kill an intersecting tile region. */ + nv10_mem_set_region_tiling(dev, i, 0, 0, 0); + + if (pitch && !found) { + /* Free tile region. */ + nv10_mem_set_region_tiling(dev, i, addr, size, pitch); +- found = &tile[i]; ++ found = tile; + } + } + +- spin_unlock(&dev_priv->tile.lock); ++ spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); + + return found; + } +@@ -299,7 +141,6 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, + phys |= 0x30; + } + +- dev_priv->engine.instmem.prepare_access(dev, true); + while (size) { + unsigned offset_h = upper_32_bits(phys); + unsigned offset_l = lower_32_bits(phys); +@@ -326,41 +167,18 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, + virt += (end - pte); + + while (pte < end) { +- nv_wo32(dev, pgt, pte++, offset_l); +- nv_wo32(dev, pgt, pte++, offset_h); ++ nv_wo32(pgt, (pte * 4) + 0, offset_l); ++ nv_wo32(pgt, (pte * 4) + 4, offset_h); ++ pte += 2; + } + } + } +- dev_priv->engine.instmem.finish_access(dev); +- +- nv_wr32(dev, 0x100c80, 0x00050001); +- if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +- NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +- NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); +- return -EBUSY; +- } +- +- nv_wr32(dev, 0x100c80, 0x00000001); +- if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +- NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +- NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); +- return -EBUSY; +- } +- +- nv_wr32(dev, 0x100c80, 0x00040001); +- if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +- NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +- NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); +- return -EBUSY; +- } +- +- nv_wr32(dev, 0x100c80, 0x00060001); +- if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +- NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +- NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); +- return -EBUSY; +- } ++ dev_priv->engine.instmem.flush(dev); + ++ nv50_vm_flush(dev, 5); ++ nv50_vm_flush(dev, 0); ++ nv50_vm_flush(dev, 4); ++ nv50_vm_flush(dev, 6); + return 0; + } + +@@ -374,7 +192,6 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) + virt -= dev_priv->vm_vram_base; + pages = (size >> 16) << 1; + +- dev_priv->engine.instmem.prepare_access(dev, true); + while (pages) { + pgt = dev_priv->vm_vram_pt[virt >> 29]; + pte = (virt & 0x1ffe0000ULL) >> 15; +@@ -385,60 +202,24 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) + pages -= (end - pte); + virt += (end - pte) << 15; + +- while (pte < end) +- nv_wo32(dev, pgt, pte++, 0); +- } +- dev_priv->engine.instmem.finish_access(dev); +- +- nv_wr32(dev, 0x100c80, 0x00050001); +- if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +- NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +- NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); +- return; +- } +- +- nv_wr32(dev, 0x100c80, 0x00000001); +- if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +- NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +- NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); +- return; +- } +- +- nv_wr32(dev, 0x100c80, 0x00040001); +- if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +- NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +- NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); +- return; ++ while (pte < end) { ++ nv_wo32(pgt, (pte * 4), 0); ++ pte++; ++ } + } ++ dev_priv->engine.instmem.flush(dev); + +- nv_wr32(dev, 0x100c80, 0x00060001); +- if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +- NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +- NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); +- } ++ nv50_vm_flush(dev, 5); ++ nv50_vm_flush(dev, 0); ++ nv50_vm_flush(dev, 4); ++ nv50_vm_flush(dev, 6); + } + + /* + * Cleanup everything + */ +-void nouveau_mem_takedown(struct mem_block **heap) +-{ +- struct mem_block *p; +- +- if (!*heap) +- return; +- +- for (p = (*heap)->next; p != *heap;) { +- struct mem_block *q = p; +- p = p->next; +- kfree(q); +- } +- +- kfree(*heap); +- *heap = NULL; +-} +- +-void nouveau_mem_close(struct drm_device *dev) ++void ++nouveau_mem_vram_fini(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + +@@ -449,8 +230,20 @@ void nouveau_mem_close(struct drm_device *dev) + + nouveau_ttm_global_release(dev_priv); + +- if (drm_core_has_AGP(dev) && dev->agp && +- drm_core_check_feature(dev, DRIVER_MODESET)) { ++ if (dev_priv->fb_mtrr >= 0) { ++ drm_mtrr_del(dev_priv->fb_mtrr, ++ pci_resource_start(dev->pdev, 1), ++ pci_resource_len(dev->pdev, 1), DRM_MTRR_WC); ++ dev_priv->fb_mtrr = -1; ++ } ++} ++ ++void ++nouveau_mem_gart_fini(struct drm_device *dev) ++{ ++ nouveau_sgdma_takedown(dev); ++ ++ if (drm_core_has_AGP(dev) && dev->agp) { + struct drm_agp_mem *entry, *tempe; + + /* Remove AGP resources, but leave dev->agp +@@ -469,30 +262,24 @@ void nouveau_mem_close(struct drm_device *dev) + dev->agp->acquired = 0; + dev->agp->enabled = 0; + } +- +- if (dev_priv->fb_mtrr) { +- drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1), +- drm_get_resource_len(dev, 1), DRM_MTRR_WC); +- dev_priv->fb_mtrr = 0; +- } + } + + static uint32_t + nouveau_mem_detect_nv04(struct drm_device *dev) + { +- uint32_t boot0 = nv_rd32(dev, NV03_BOOT_0); ++ uint32_t boot0 = nv_rd32(dev, NV04_PFB_BOOT_0); + + if (boot0 & 0x00000100) + return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024; + +- switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) { +- case NV04_BOOT_0_RAM_AMOUNT_32MB: ++ switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) { ++ case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB: + return 32 * 1024 * 1024; +- case NV04_BOOT_0_RAM_AMOUNT_16MB: ++ case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB: + return 16 * 1024 * 1024; +- case NV04_BOOT_0_RAM_AMOUNT_8MB: ++ case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB: + return 8 * 1024 * 1024; +- case NV04_BOOT_0_RAM_AMOUNT_4MB: ++ case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB: + return 4 * 1024 * 1024; + } + +@@ -525,8 +312,62 @@ nouveau_mem_detect_nforce(struct drm_device *dev) + return 0; + } + +-/* returns the amount of FB ram in bytes */ +-int ++static void ++nv50_vram_preinit(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int i, parts, colbits, rowbitsa, rowbitsb, banks; ++ u64 rowsize, predicted; ++ u32 r0, r4, rt, ru; ++ ++ r0 = nv_rd32(dev, 0x100200); ++ r4 = nv_rd32(dev, 0x100204); ++ rt = nv_rd32(dev, 0x100250); ++ ru = nv_rd32(dev, 0x001540); ++ NV_DEBUG(dev, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru); ++ ++ for (i = 0, parts = 0; i < 8; i++) { ++ if (ru & (0x00010000 << i)) ++ parts++; ++ } ++ ++ colbits = (r4 & 0x0000f000) >> 12; ++ rowbitsa = ((r4 & 0x000f0000) >> 16) + 8; ++ rowbitsb = ((r4 & 0x00f00000) >> 20) + 8; ++ banks = ((r4 & 0x01000000) ? 8 : 4); ++ ++ rowsize = parts * banks * (1 << colbits) * 8; ++ predicted = rowsize << rowbitsa; ++ if (r0 & 0x00000004) ++ predicted += rowsize << rowbitsb; ++ ++ if (predicted != dev_priv->vram_size) { ++ NV_WARN(dev, "memory controller reports %dMiB VRAM\n", ++ (u32)(dev_priv->vram_size >> 20)); ++ NV_WARN(dev, "we calculated %dMiB VRAM\n", ++ (u32)(predicted >> 20)); ++ } ++ ++ dev_priv->vram_rblock_size = rowsize >> 12; ++ if (rt & 1) ++ dev_priv->vram_rblock_size *= 3; ++ ++ NV_DEBUG(dev, "rblock %lld bytes\n", ++ (u64)dev_priv->vram_rblock_size << 12); ++} ++ ++static void ++nvaa_vram_preinit(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ /* To our knowledge, there's no large scale reordering of pages ++ * that occurs on IGP chipsets. ++ */ ++ dev_priv->vram_rblock_size = 1; ++} ++ ++static int + nouveau_mem_detect(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; +@@ -536,12 +377,31 @@ nouveau_mem_detect(struct drm_device *dev) + } else + if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) { + dev_priv->vram_size = nouveau_mem_detect_nforce(dev); +- } else { +- dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA); +- dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK; +- if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) ++ } else ++ if (dev_priv->card_type < NV_50) { ++ dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA); ++ dev_priv->vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK; ++ } else ++ if (dev_priv->card_type < NV_C0) { ++ dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA); ++ dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32; ++ dev_priv->vram_size &= 0xffffffff00ll; ++ ++ switch (dev_priv->chipset) { ++ case 0xaa: ++ case 0xac: ++ case 0xaf: + dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10); + dev_priv->vram_sys_base <<= 12; ++ nvaa_vram_preinit(dev); ++ break; ++ default: ++ nv50_vram_preinit(dev); ++ break; ++ } ++ } else { ++ dev_priv->vram_size = nv_rd32(dev, 0x10f20c) << 20; ++ dev_priv->vram_size *= nv_rd32(dev, 0x121c74); + } + + NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20)); +@@ -556,17 +416,63 @@ nouveau_mem_detect(struct drm_device *dev) + } + + #if __OS_HAS_AGP +-static void nouveau_mem_reset_agp(struct drm_device *dev) ++static unsigned long ++get_agp_mode(struct drm_device *dev, unsigned long mode) + { +- uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ /* ++ * FW seems to be broken on nv18, it makes the card lock up ++ * randomly. ++ */ ++ if (dev_priv->chipset == 0x18) ++ mode &= ~PCI_AGP_COMMAND_FW; ++ ++ /* ++ * AGP mode set in the command line. ++ */ ++ if (nouveau_agpmode > 0) { ++ bool agpv3 = mode & 0x8; ++ int rate = agpv3 ? nouveau_agpmode / 4 : nouveau_agpmode; ++ ++ mode = (mode & ~0x7) | (rate & 0x7); ++ } ++ ++ return mode; ++} ++#endif ++ ++int ++nouveau_mem_reset_agp(struct drm_device *dev) ++{ ++#if __OS_HAS_AGP ++ uint32_t saved_pci_nv_1, pmc_enable; ++ int ret; ++ ++ /* First of all, disable fast writes, otherwise if it's ++ * already enabled in the AGP bridge and we disable the card's ++ * AGP controller we might be locking ourselves out of it. */ ++ if ((nv_rd32(dev, NV04_PBUS_PCI_NV_19) | ++ dev->agp->mode) & PCI_AGP_COMMAND_FW) { ++ struct drm_agp_info info; ++ struct drm_agp_mode mode; ++ ++ ret = drm_agp_info(dev, &info); ++ if (ret) ++ return ret; ++ ++ mode.mode = get_agp_mode(dev, info.mode) & ~PCI_AGP_COMMAND_FW; ++ ret = drm_agp_enable(dev, mode); ++ if (ret) ++ return ret; ++ } + + saved_pci_nv_1 = nv_rd32(dev, NV04_PBUS_PCI_NV_1); +- saved_pci_nv_19 = nv_rd32(dev, NV04_PBUS_PCI_NV_19); + + /* clear busmaster bit */ + nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4); +- /* clear SBA and AGP bits */ +- nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19 & 0xfffff0ff); ++ /* disable AGP */ ++ nv_wr32(dev, NV04_PBUS_PCI_NV_19, 0); + + /* power cycle pgraph, if enabled */ + pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE); +@@ -578,11 +484,12 @@ static void nouveau_mem_reset_agp(struct drm_device *dev) + } + + /* and restore (gives effect of resetting AGP) */ +- nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19); + nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1); +-} + #endif + ++ return 0; ++} ++ + int + nouveau_mem_init_agp(struct drm_device *dev) + { +@@ -592,11 +499,6 @@ nouveau_mem_init_agp(struct drm_device *dev) + struct drm_agp_mode mode; + int ret; + +- if (nouveau_noagp) +- return 0; +- +- nouveau_mem_reset_agp(dev); +- + if (!dev->agp->acquired) { + ret = drm_agp_acquire(dev); + if (ret) { +@@ -605,6 +507,8 @@ nouveau_mem_init_agp(struct drm_device *dev) + } + } + ++ nouveau_mem_reset_agp(dev); ++ + ret = drm_agp_info(dev, &info); + if (ret) { + NV_ERROR(dev, "Unable to get AGP info: %d\n", ret); +@@ -612,7 +516,7 @@ nouveau_mem_init_agp(struct drm_device *dev) + } + + /* see agp.h for the AGPSTAT_* modes available */ +- mode.mode = info.mode; ++ mode.mode = get_agp_mode(dev, info.mode); + ret = drm_agp_enable(dev, mode); + if (ret) { + NV_ERROR(dev, "Unable to enable AGP: %d\n", ret); +@@ -627,24 +531,27 @@ nouveau_mem_init_agp(struct drm_device *dev) + } + + int +-nouveau_mem_init(struct drm_device *dev) ++nouveau_mem_vram_init(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; +- int ret, dma_bits = 32; +- +- dev_priv->fb_phys = drm_get_resource_start(dev, 1); +- dev_priv->gart_info.type = NOUVEAU_GART_NONE; ++ int ret, dma_bits; + + if (dev_priv->card_type >= NV_50 && + pci_dma_supported(dev->pdev, DMA_BIT_MASK(40))) + dma_bits = 40; ++ else ++ dma_bits = 32; + + ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits)); +- if (ret) { +- NV_ERROR(dev, "Error setting DMA mask: %d\n", ret); ++ if (ret) + return ret; +- } ++ ++ ret = nouveau_mem_detect(dev); ++ if (ret) ++ return ret; ++ ++ dev_priv->fb_phys = pci_resource_start(dev->pdev, 1); + + ret = nouveau_ttm_global_init(dev_priv); + if (ret) +@@ -659,17 +566,22 @@ nouveau_mem_init(struct drm_device *dev) + return ret; + } + +- INIT_LIST_HEAD(&dev_priv->ttm.bo_list); +- spin_lock_init(&dev_priv->ttm.bo_list_lock); +- spin_lock_init(&dev_priv->tile.lock); +- + dev_priv->fb_available_size = dev_priv->vram_size; + dev_priv->fb_mappable_pages = dev_priv->fb_available_size; + if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1)) + dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1); + dev_priv->fb_mappable_pages >>= PAGE_SHIFT; + +- /* remove reserved space at end of vram from available amount */ ++ /* reserve space at end of VRAM for PRAMIN */ ++ if (dev_priv->chipset == 0x40 || dev_priv->chipset == 0x47 || ++ dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b) ++ dev_priv->ramin_rsvd_vram = (2 * 1024 * 1024); ++ else ++ if (dev_priv->card_type >= NV_40) ++ dev_priv->ramin_rsvd_vram = (1 * 1024 * 1024); ++ else ++ dev_priv->ramin_rsvd_vram = (512 * 1024); ++ + dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram; + dev_priv->fb_aper_free = dev_priv->fb_available_size; + +@@ -690,9 +602,23 @@ nouveau_mem_init(struct drm_device *dev) + nouveau_bo_ref(NULL, &dev_priv->vga_ram); + } + +- /* GART */ ++ dev_priv->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 1), ++ pci_resource_len(dev->pdev, 1), ++ DRM_MTRR_WC); ++ return 0; ++} ++ ++int ++nouveau_mem_gart_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; ++ int ret; ++ ++ dev_priv->gart_info.type = NOUVEAU_GART_NONE; ++ + #if !defined(__powerpc__) && !defined(__ia64__) +- if (drm_device_is_agp(dev) && dev->agp) { ++ if (drm_device_is_agp(dev) && dev->agp && nouveau_agpmode) { + ret = nouveau_mem_init_agp(dev); + if (ret) + NV_ERROR(dev, "Error initialising AGP: %d\n", ret); +@@ -718,11 +644,6 @@ nouveau_mem_init(struct drm_device *dev) + return ret; + } + +- dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1), +- drm_get_resource_len(dev, 1), +- DRM_MTRR_WC); +- + return 0; + } + +- +diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c +index 9537f3e..22b8618 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_notifier.c ++++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c +@@ -28,6 +28,7 @@ + #include "drmP.h" + #include "drm.h" + #include "nouveau_drv.h" ++#include "nouveau_ramht.h" + + int + nouveau_notifier_init_channel(struct nouveau_channel *chan) +@@ -55,7 +56,7 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan) + if (ret) + goto out_err; + +- ret = nouveau_mem_init_heap(&chan->notifier_heap, 0, ntfy->bo.mem.size); ++ ret = drm_mm_init(&chan->notifier_heap, 0, ntfy->bo.mem.size); + if (ret) + goto out_err; + +@@ -80,7 +81,7 @@ nouveau_notifier_takedown_channel(struct nouveau_channel *chan) + nouveau_bo_unpin(chan->notifier_bo); + mutex_unlock(&dev->struct_mutex); + drm_gem_object_unreference_unlocked(chan->notifier_bo->gem); +- nouveau_mem_takedown(&chan->notifier_heap); ++ drm_mm_takedown(&chan->notifier_heap); + } + + static void +@@ -90,7 +91,7 @@ nouveau_notifier_gpuobj_dtor(struct drm_device *dev, + NV_DEBUG(dev, "\n"); + + if (gpuobj->priv) +- nouveau_mem_free_block(gpuobj->priv); ++ drm_mm_put_block(gpuobj->priv); + } + + int +@@ -100,18 +101,13 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *nobj = NULL; +- struct mem_block *mem; ++ struct drm_mm_node *mem; + uint32_t offset; + int target, ret; + +- if (!chan->notifier_heap) { +- NV_ERROR(dev, "Channel %d doesn't have a notifier heap!\n", +- chan->id); +- return -EINVAL; +- } +- +- mem = nouveau_mem_alloc_block(chan->notifier_heap, size, 0, +- (struct drm_file *)-2, 0); ++ mem = drm_mm_search_free(&chan->notifier_heap, size, 0, 0); ++ if (mem) ++ mem = drm_mm_get_block(mem, size, 0); + if (!mem) { + NV_ERROR(dev, "Channel %d notifier block full\n", chan->id); + return -ENOMEM; +@@ -144,18 +140,18 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, + mem->size, NV_DMA_ACCESS_RW, target, + &nobj); + if (ret) { +- nouveau_mem_free_block(mem); ++ drm_mm_put_block(mem); + NV_ERROR(dev, "Error creating notifier ctxdma: %d\n", ret); + return ret; + } +- nobj->dtor = nouveau_notifier_gpuobj_dtor; +- nobj->priv = mem; ++ nobj->dtor = nouveau_notifier_gpuobj_dtor; ++ nobj->priv = mem; + +- ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL); ++ ret = nouveau_ramht_insert(chan, handle, nobj); ++ nouveau_gpuobj_ref(NULL, &nobj); + if (ret) { +- nouveau_gpuobj_del(dev, &nobj); +- nouveau_mem_free_block(mem); +- NV_ERROR(dev, "Error referencing notifier ctxdma: %d\n", ret); ++ drm_mm_put_block(mem); ++ NV_ERROR(dev, "Error adding notifier to ramht: %d\n", ret); + return ret; + } + +@@ -170,7 +166,7 @@ nouveau_notifier_offset(struct nouveau_gpuobj *nobj, uint32_t *poffset) + return -EINVAL; + + if (poffset) { +- struct mem_block *mem = nobj->priv; ++ struct drm_mm_node *mem = nobj->priv; + + if (*poffset >= mem->size) + return false; +@@ -189,7 +185,6 @@ nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, + struct nouveau_channel *chan; + int ret; + +- NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan); + + ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset); +diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c +index e7c100b..115904d 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_object.c ++++ b/drivers/gpu/drm/nouveau/nouveau_object.c +@@ -34,6 +34,7 @@ + #include "drm.h" + #include "nouveau_drv.h" + #include "nouveau_drm.h" ++#include "nouveau_ramht.h" + + /* NVidia uses context objects to drive drawing operations. + +@@ -65,141 +66,6 @@ + The key into the hash table depends on the object handle and channel id and + is given as: + */ +-static uint32_t +-nouveau_ramht_hash_handle(struct drm_device *dev, int channel, uint32_t handle) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- uint32_t hash = 0; +- int i; +- +- NV_DEBUG(dev, "ch%d handle=0x%08x\n", channel, handle); +- +- for (i = 32; i > 0; i -= dev_priv->ramht_bits) { +- hash ^= (handle & ((1 << dev_priv->ramht_bits) - 1)); +- handle >>= dev_priv->ramht_bits; +- } +- +- if (dev_priv->card_type < NV_50) +- hash ^= channel << (dev_priv->ramht_bits - 4); +- hash <<= 3; +- +- NV_DEBUG(dev, "hash=0x%08x\n", hash); +- return hash; +-} +- +-static int +-nouveau_ramht_entry_valid(struct drm_device *dev, struct nouveau_gpuobj *ramht, +- uint32_t offset) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- uint32_t ctx = nv_ro32(dev, ramht, (offset + 4)/4); +- +- if (dev_priv->card_type < NV_40) +- return ((ctx & NV_RAMHT_CONTEXT_VALID) != 0); +- return (ctx != 0); +-} +- +-static int +-nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; +- struct nouveau_channel *chan = ref->channel; +- struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL; +- uint32_t ctx, co, ho; +- +- if (!ramht) { +- NV_ERROR(dev, "No hash table!\n"); +- return -EINVAL; +- } +- +- if (dev_priv->card_type < NV_40) { +- ctx = NV_RAMHT_CONTEXT_VALID | (ref->instance >> 4) | +- (chan->id << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) | +- (ref->gpuobj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT); +- } else +- if (dev_priv->card_type < NV_50) { +- ctx = (ref->instance >> 4) | +- (chan->id << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) | +- (ref->gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT); +- } else { +- if (ref->gpuobj->engine == NVOBJ_ENGINE_DISPLAY) { +- ctx = (ref->instance << 10) | 2; +- } else { +- ctx = (ref->instance >> 4) | +- ((ref->gpuobj->engine << +- NV40_RAMHT_CONTEXT_ENGINE_SHIFT)); +- } +- } +- +- instmem->prepare_access(dev, true); +- co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle); +- do { +- if (!nouveau_ramht_entry_valid(dev, ramht, co)) { +- NV_DEBUG(dev, +- "insert ch%d 0x%08x: h=0x%08x, c=0x%08x\n", +- chan->id, co, ref->handle, ctx); +- nv_wo32(dev, ramht, (co + 0)/4, ref->handle); +- nv_wo32(dev, ramht, (co + 4)/4, ctx); +- +- list_add_tail(&ref->list, &chan->ramht_refs); +- instmem->finish_access(dev); +- return 0; +- } +- NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n", +- chan->id, co, nv_ro32(dev, ramht, co/4)); +- +- co += 8; +- if (co >= dev_priv->ramht_size) +- co = 0; +- } while (co != ho); +- instmem->finish_access(dev); +- +- NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", chan->id); +- return -ENOMEM; +-} +- +-static void +-nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; +- struct nouveau_channel *chan = ref->channel; +- struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL; +- uint32_t co, ho; +- +- if (!ramht) { +- NV_ERROR(dev, "No hash table!\n"); +- return; +- } +- +- instmem->prepare_access(dev, true); +- co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle); +- do { +- if (nouveau_ramht_entry_valid(dev, ramht, co) && +- (ref->handle == nv_ro32(dev, ramht, (co/4)))) { +- NV_DEBUG(dev, +- "remove ch%d 0x%08x: h=0x%08x, c=0x%08x\n", +- chan->id, co, ref->handle, +- nv_ro32(dev, ramht, (co + 4))); +- nv_wo32(dev, ramht, (co + 0)/4, 0x00000000); +- nv_wo32(dev, ramht, (co + 4)/4, 0x00000000); +- +- list_del(&ref->list); +- instmem->finish_access(dev); +- return; +- } +- +- co += 8; +- if (co >= dev_priv->ramht_size) +- co = 0; +- } while (co != ho); +- list_del(&ref->list); +- instmem->finish_access(dev); +- +- NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n", +- chan->id, ref->handle); +-} + + int + nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, +@@ -209,7 +75,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->engine; + struct nouveau_gpuobj *gpuobj; +- struct mem_block *pramin = NULL; ++ struct drm_mm_node *ramin = NULL; + int ret; + + NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n", +@@ -222,82 +88,102 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, + if (!gpuobj) + return -ENOMEM; + NV_DEBUG(dev, "gpuobj %p\n", gpuobj); ++ gpuobj->dev = dev; + gpuobj->flags = flags; +- gpuobj->im_channel = chan; ++ kref_init(&gpuobj->refcount); ++ gpuobj->size = size; + ++ spin_lock(&dev_priv->ramin_lock); + list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); ++ spin_unlock(&dev_priv->ramin_lock); + +- /* Choose between global instmem heap, and per-channel private +- * instmem heap. On ramin_heap) { +- NV_DEBUG(dev, "private heap\n"); +- pramin = chan->ramin_heap; +- } else +- if (dev_priv->card_type < NV_50) { +- NV_DEBUG(dev, "global heap fallback\n"); +- pramin = dev_priv->ramin_heap; ++ NV_DEBUG(dev, "channel heap\n"); ++ ++ ramin = drm_mm_search_free(&chan->ramin_heap, size, align, 0); ++ if (ramin) ++ ramin = drm_mm_get_block(ramin, size, align); ++ ++ if (!ramin) { ++ nouveau_gpuobj_ref(NULL, &gpuobj); ++ return -ENOMEM; + } + } else { + NV_DEBUG(dev, "global heap\n"); +- pramin = dev_priv->ramin_heap; +- } + +- if (!pramin) { +- NV_ERROR(dev, "No PRAMIN heap!\n"); +- return -EINVAL; +- } +- +- if (!chan) { ++ /* allocate backing pages, sets vinst */ + ret = engine->instmem.populate(dev, gpuobj, &size); + if (ret) { +- nouveau_gpuobj_del(dev, &gpuobj); ++ nouveau_gpuobj_ref(NULL, &gpuobj); + return ret; + } +- } + +- /* Allocate a chunk of the PRAMIN aperture */ +- gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size, +- drm_order(align), +- (struct drm_file *)-2, 0); +- if (!gpuobj->im_pramin) { +- nouveau_gpuobj_del(dev, &gpuobj); +- return -ENOMEM; ++ /* try and get aperture space */ ++ do { ++ if (drm_mm_pre_get(&dev_priv->ramin_heap)) ++ return -ENOMEM; ++ ++ spin_lock(&dev_priv->ramin_lock); ++ ramin = drm_mm_search_free(&dev_priv->ramin_heap, size, ++ align, 0); ++ if (ramin == NULL) { ++ spin_unlock(&dev_priv->ramin_lock); ++ nouveau_gpuobj_ref(NULL, &gpuobj); ++ return ret; ++ } ++ ++ ramin = drm_mm_get_block_atomic(ramin, size, align); ++ spin_unlock(&dev_priv->ramin_lock); ++ } while (ramin == NULL); ++ ++ /* on nv50 it's ok to fail, we have a fallback path */ ++ if (!ramin && dev_priv->card_type < NV_50) { ++ nouveau_gpuobj_ref(NULL, &gpuobj); ++ return -ENOMEM; ++ } + } + +- if (!chan) { ++ /* if we got a chunk of the aperture, map pages into it */ ++ gpuobj->im_pramin = ramin; ++ if (!chan && gpuobj->im_pramin && dev_priv->ramin_available) { + ret = engine->instmem.bind(dev, gpuobj); + if (ret) { +- nouveau_gpuobj_del(dev, &gpuobj); ++ nouveau_gpuobj_ref(NULL, &gpuobj); + return ret; + } + } + +- if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { +- int i; ++ /* calculate the various different addresses for the object */ ++ if (chan) { ++ gpuobj->pinst = chan->ramin->pinst; ++ if (gpuobj->pinst != ~0) ++ gpuobj->pinst += gpuobj->im_pramin->start; + +- engine->instmem.prepare_access(dev, true); +- for (i = 0; i < gpuobj->im_pramin->size; i += 4) +- nv_wo32(dev, gpuobj, i/4, 0); +- engine->instmem.finish_access(dev); ++ if (dev_priv->card_type < NV_50) { ++ gpuobj->cinst = gpuobj->pinst; ++ } else { ++ gpuobj->cinst = gpuobj->im_pramin->start; ++ gpuobj->vinst = gpuobj->im_pramin->start + ++ chan->ramin->vinst; ++ } ++ } else { ++ if (gpuobj->im_pramin) ++ gpuobj->pinst = gpuobj->im_pramin->start; ++ else ++ gpuobj->pinst = ~0; ++ gpuobj->cinst = 0xdeadbeef; + } + +- *gpuobj_ret = gpuobj; +- return 0; +-} +- +-int +-nouveau_gpuobj_early_init(struct drm_device *dev) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; ++ if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { ++ int i; + +- NV_DEBUG(dev, "\n"); ++ for (i = 0; i < gpuobj->size; i += 4) ++ nv_wo32(gpuobj, i, 0); ++ engine->instmem.flush(dev); ++ } + +- INIT_LIST_HEAD(&dev_priv->gpuobj_list); + ++ *gpuobj_ret = gpuobj; + return 0; + } + +@@ -305,18 +191,12 @@ int + nouveau_gpuobj_init(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; +- int ret; + + NV_DEBUG(dev, "\n"); + +- if (dev_priv->card_type < NV_50) { +- ret = nouveau_gpuobj_new_fake(dev, +- dev_priv->ramht_offset, ~0, dev_priv->ramht_size, +- NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ALLOW_NO_REFS, +- &dev_priv->ramht, NULL); +- if (ret) +- return ret; +- } ++ INIT_LIST_HEAD(&dev_priv->gpuobj_list); ++ spin_lock_init(&dev_priv->ramin_lock); ++ dev_priv->ramin_base = ~0; + + return 0; + } +@@ -328,299 +208,89 @@ nouveau_gpuobj_takedown(struct drm_device *dev) + + NV_DEBUG(dev, "\n"); + +- nouveau_gpuobj_del(dev, &dev_priv->ramht); ++ BUG_ON(!list_empty(&dev_priv->gpuobj_list)); + } + +-void +-nouveau_gpuobj_late_takedown(struct drm_device *dev) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_gpuobj *gpuobj = NULL; +- struct list_head *entry, *tmp; +- +- NV_DEBUG(dev, "\n"); +- +- list_for_each_safe(entry, tmp, &dev_priv->gpuobj_list) { +- gpuobj = list_entry(entry, struct nouveau_gpuobj, list); + +- NV_ERROR(dev, "gpuobj %p still exists at takedown, refs=%d\n", +- gpuobj, gpuobj->refcount); +- gpuobj->refcount = 0; +- nouveau_gpuobj_del(dev, &gpuobj); +- } +-} +- +-int +-nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj) ++static void ++nouveau_gpuobj_del(struct kref *ref) + { ++ struct nouveau_gpuobj *gpuobj = ++ container_of(ref, struct nouveau_gpuobj, refcount); ++ struct drm_device *dev = gpuobj->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->engine; +- struct nouveau_gpuobj *gpuobj; + int i; + +- NV_DEBUG(dev, "gpuobj %p\n", pgpuobj ? *pgpuobj : NULL); +- +- if (!dev_priv || !pgpuobj || !(*pgpuobj)) +- return -EINVAL; +- gpuobj = *pgpuobj; +- +- if (gpuobj->refcount != 0) { +- NV_ERROR(dev, "gpuobj refcount is %d\n", gpuobj->refcount); +- return -EINVAL; +- } ++ NV_DEBUG(dev, "gpuobj %p\n", gpuobj); + + if (gpuobj->im_pramin && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) { +- engine->instmem.prepare_access(dev, true); +- for (i = 0; i < gpuobj->im_pramin->size; i += 4) +- nv_wo32(dev, gpuobj, i/4, 0); +- engine->instmem.finish_access(dev); ++ for (i = 0; i < gpuobj->size; i += 4) ++ nv_wo32(gpuobj, i, 0); ++ engine->instmem.flush(dev); + } + + if (gpuobj->dtor) + gpuobj->dtor(dev, gpuobj); + +- if (gpuobj->im_backing && !(gpuobj->flags & NVOBJ_FLAG_FAKE)) ++ if (gpuobj->im_backing) + engine->instmem.clear(dev, gpuobj); + +- if (gpuobj->im_pramin) { +- if (gpuobj->flags & NVOBJ_FLAG_FAKE) +- kfree(gpuobj->im_pramin); +- else +- nouveau_mem_free_block(gpuobj->im_pramin); +- } +- ++ spin_lock(&dev_priv->ramin_lock); ++ if (gpuobj->im_pramin) ++ drm_mm_put_block(gpuobj->im_pramin); + list_del(&gpuobj->list); ++ spin_unlock(&dev_priv->ramin_lock); + +- *pgpuobj = NULL; + kfree(gpuobj); +- return 0; +-} +- +-static int +-nouveau_gpuobj_instance_get(struct drm_device *dev, +- struct nouveau_channel *chan, +- struct nouveau_gpuobj *gpuobj, uint32_t *inst) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_gpuobj *cpramin; +- +- /* card_type < NV_50) { +- *inst = gpuobj->im_pramin->start; +- return 0; +- } +- +- if (chan && gpuobj->im_channel != chan) { +- NV_ERROR(dev, "Channel mismatch: obj %d, ref %d\n", +- gpuobj->im_channel->id, chan->id); +- return -EINVAL; +- } +- +- /* NV50 channel-local instance */ +- if (chan) { +- cpramin = chan->ramin->gpuobj; +- *inst = gpuobj->im_pramin->start - cpramin->im_pramin->start; +- return 0; +- } +- +- /* NV50 global (VRAM) instance */ +- if (!gpuobj->im_channel) { +- /* ...from global heap */ +- if (!gpuobj->im_backing) { +- NV_ERROR(dev, "AII, no VRAM backing gpuobj\n"); +- return -EINVAL; +- } +- *inst = gpuobj->im_backing_start; +- return 0; +- } else { +- /* ...from local heap */ +- cpramin = gpuobj->im_channel->ramin->gpuobj; +- *inst = cpramin->im_backing_start + +- (gpuobj->im_pramin->start - cpramin->im_pramin->start); +- return 0; +- } +- +- return -EINVAL; +-} +- +-int +-nouveau_gpuobj_ref_add(struct drm_device *dev, struct nouveau_channel *chan, +- uint32_t handle, struct nouveau_gpuobj *gpuobj, +- struct nouveau_gpuobj_ref **ref_ret) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_gpuobj_ref *ref; +- uint32_t instance; +- int ret; +- +- NV_DEBUG(dev, "ch%d h=0x%08x gpuobj=%p\n", +- chan ? chan->id : -1, handle, gpuobj); +- +- if (!dev_priv || !gpuobj || (ref_ret && *ref_ret != NULL)) +- return -EINVAL; +- +- if (!chan && !ref_ret) +- return -EINVAL; +- +- if (gpuobj->engine == NVOBJ_ENGINE_SW && !gpuobj->im_pramin) { +- /* sw object */ +- instance = 0x40; +- } else { +- ret = nouveau_gpuobj_instance_get(dev, chan, gpuobj, &instance); +- if (ret) +- return ret; +- } +- +- ref = kzalloc(sizeof(*ref), GFP_KERNEL); +- if (!ref) +- return -ENOMEM; +- INIT_LIST_HEAD(&ref->list); +- ref->gpuobj = gpuobj; +- ref->channel = chan; +- ref->instance = instance; +- +- if (!ref_ret) { +- ref->handle = handle; +- +- ret = nouveau_ramht_insert(dev, ref); +- if (ret) { +- kfree(ref); +- return ret; +- } +- } else { +- ref->handle = ~0; +- *ref_ret = ref; +- } +- +- ref->gpuobj->refcount++; +- return 0; + } + +-int nouveau_gpuobj_ref_del(struct drm_device *dev, struct nouveau_gpuobj_ref **pref) +-{ +- struct nouveau_gpuobj_ref *ref; +- +- NV_DEBUG(dev, "ref %p\n", pref ? *pref : NULL); +- +- if (!dev || !pref || *pref == NULL) +- return -EINVAL; +- ref = *pref; +- +- if (ref->handle != ~0) +- nouveau_ramht_remove(dev, ref); +- +- if (ref->gpuobj) { +- ref->gpuobj->refcount--; +- +- if (ref->gpuobj->refcount == 0) { +- if (!(ref->gpuobj->flags & NVOBJ_FLAG_ALLOW_NO_REFS)) +- nouveau_gpuobj_del(dev, &ref->gpuobj); +- } +- } +- +- *pref = NULL; +- kfree(ref); +- return 0; +-} +- +-int +-nouveau_gpuobj_new_ref(struct drm_device *dev, +- struct nouveau_channel *oc, struct nouveau_channel *rc, +- uint32_t handle, uint32_t size, int align, +- uint32_t flags, struct nouveau_gpuobj_ref **ref) +-{ +- struct nouveau_gpuobj *gpuobj = NULL; +- int ret; +- +- ret = nouveau_gpuobj_new(dev, oc, size, align, flags, &gpuobj); +- if (ret) +- return ret; +- +- ret = nouveau_gpuobj_ref_add(dev, rc, handle, gpuobj, ref); +- if (ret) { +- nouveau_gpuobj_del(dev, &gpuobj); +- return ret; +- } +- +- return 0; +-} +- +-int +-nouveau_gpuobj_ref_find(struct nouveau_channel *chan, uint32_t handle, +- struct nouveau_gpuobj_ref **ref_ret) ++void ++nouveau_gpuobj_ref(struct nouveau_gpuobj *ref, struct nouveau_gpuobj **ptr) + { +- struct nouveau_gpuobj_ref *ref; +- struct list_head *entry, *tmp; ++ if (ref) ++ kref_get(&ref->refcount); + +- list_for_each_safe(entry, tmp, &chan->ramht_refs) { +- ref = list_entry(entry, struct nouveau_gpuobj_ref, list); ++ if (*ptr) ++ kref_put(&(*ptr)->refcount, nouveau_gpuobj_del); + +- if (ref->handle == handle) { +- if (ref_ret) +- *ref_ret = ref; +- return 0; +- } +- } +- +- return -EINVAL; ++ *ptr = ref; + } + + int +-nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset, +- uint32_t b_offset, uint32_t size, +- uint32_t flags, struct nouveau_gpuobj **pgpuobj, +- struct nouveau_gpuobj_ref **pref) ++nouveau_gpuobj_new_fake(struct drm_device *dev, u32 pinst, u64 vinst, ++ u32 size, u32 flags, struct nouveau_gpuobj **pgpuobj) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *gpuobj = NULL; + int i; + + NV_DEBUG(dev, +- "p_offset=0x%08x b_offset=0x%08x size=0x%08x flags=0x%08x\n", +- p_offset, b_offset, size, flags); ++ "pinst=0x%08x vinst=0x%010llx size=0x%08x flags=0x%08x\n", ++ pinst, vinst, size, flags); + + gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); + if (!gpuobj) + return -ENOMEM; + NV_DEBUG(dev, "gpuobj %p\n", gpuobj); +- gpuobj->im_channel = NULL; +- gpuobj->flags = flags | NVOBJ_FLAG_FAKE; +- +- list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); +- +- if (p_offset != ~0) { +- gpuobj->im_pramin = kzalloc(sizeof(struct mem_block), +- GFP_KERNEL); +- if (!gpuobj->im_pramin) { +- nouveau_gpuobj_del(dev, &gpuobj); +- return -ENOMEM; +- } +- gpuobj->im_pramin->start = p_offset; +- gpuobj->im_pramin->size = size; +- } +- +- if (b_offset != ~0) { +- gpuobj->im_backing = (struct nouveau_bo *)-1; +- gpuobj->im_backing_start = b_offset; +- } ++ gpuobj->dev = dev; ++ gpuobj->flags = flags; ++ kref_init(&gpuobj->refcount); ++ gpuobj->size = size; ++ gpuobj->pinst = pinst; ++ gpuobj->cinst = 0xdeadbeef; ++ gpuobj->vinst = vinst; + + if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { +- dev_priv->engine.instmem.prepare_access(dev, true); +- for (i = 0; i < gpuobj->im_pramin->size; i += 4) +- nv_wo32(dev, gpuobj, i/4, 0); +- dev_priv->engine.instmem.finish_access(dev); ++ for (i = 0; i < gpuobj->size; i += 4) ++ nv_wo32(gpuobj, i, 0); ++ dev_priv->engine.instmem.flush(dev); + } + +- if (pref) { +- i = nouveau_gpuobj_ref_add(dev, NULL, 0, gpuobj, pref); +- if (i) { +- nouveau_gpuobj_del(dev, &gpuobj); +- return i; +- } +- } +- +- if (pgpuobj) +- *pgpuobj = gpuobj; ++ spin_lock(&dev_priv->ramin_lock); ++ list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); ++ spin_unlock(&dev_priv->ramin_lock); ++ *pgpuobj = gpuobj; + return 0; + } + +@@ -696,8 +366,6 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, + return ret; + } + +- instmem->prepare_access(dev, true); +- + if (dev_priv->card_type < NV_50) { + uint32_t frame, adjust, pte_flags = 0; + +@@ -706,14 +374,12 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, + adjust = offset & 0x00000fff; + frame = offset & ~0x00000fff; + +- nv_wo32(dev, *gpuobj, 0, ((1<<12) | (1<<13) | +- (adjust << 20) | +- (access << 14) | +- (target << 16) | +- class)); +- nv_wo32(dev, *gpuobj, 1, size - 1); +- nv_wo32(dev, *gpuobj, 2, frame | pte_flags); +- nv_wo32(dev, *gpuobj, 3, frame | pte_flags); ++ nv_wo32(*gpuobj, 0, ((1<<12) | (1<<13) | (adjust << 20) | ++ (access << 14) | (target << 16) | ++ class)); ++ nv_wo32(*gpuobj, 4, size - 1); ++ nv_wo32(*gpuobj, 8, frame | pte_flags); ++ nv_wo32(*gpuobj, 12, frame | pte_flags); + } else { + uint64_t limit = offset + size - 1; + uint32_t flags0, flags5; +@@ -726,15 +392,15 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, + flags5 = 0x00080000; + } + +- nv_wo32(dev, *gpuobj, 0, flags0 | class); +- nv_wo32(dev, *gpuobj, 1, lower_32_bits(limit)); +- nv_wo32(dev, *gpuobj, 2, lower_32_bits(offset)); +- nv_wo32(dev, *gpuobj, 3, ((upper_32_bits(limit) & 0xff) << 24) | +- (upper_32_bits(offset) & 0xff)); +- nv_wo32(dev, *gpuobj, 5, flags5); ++ nv_wo32(*gpuobj, 0, flags0 | class); ++ nv_wo32(*gpuobj, 4, lower_32_bits(limit)); ++ nv_wo32(*gpuobj, 8, lower_32_bits(offset)); ++ nv_wo32(*gpuobj, 12, ((upper_32_bits(limit) & 0xff) << 24) | ++ (upper_32_bits(offset) & 0xff)); ++ nv_wo32(*gpuobj, 20, flags5); + } + +- instmem->finish_access(dev); ++ instmem->flush(dev); + + (*gpuobj)->engine = NVOBJ_ENGINE_SW; + (*gpuobj)->class = class; +@@ -762,7 +428,7 @@ nouveau_gpuobj_gart_dma_new(struct nouveau_channel *chan, + *o_ret = 0; + } else + if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) { +- *gpuobj = dev_priv->gart_info.sg_ctxdma; ++ nouveau_gpuobj_ref(dev_priv->gart_info.sg_ctxdma, gpuobj); + if (offset & ~0xffffffffULL) { + NV_ERROR(dev, "obj offset exceeds 32-bits\n"); + return -EINVAL; +@@ -849,32 +515,31 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, + return ret; + } + +- dev_priv->engine.instmem.prepare_access(dev, true); + if (dev_priv->card_type >= NV_50) { +- nv_wo32(dev, *gpuobj, 0, class); +- nv_wo32(dev, *gpuobj, 5, 0x00010000); ++ nv_wo32(*gpuobj, 0, class); ++ nv_wo32(*gpuobj, 20, 0x00010000); + } else { + switch (class) { + case NV_CLASS_NULL: +- nv_wo32(dev, *gpuobj, 0, 0x00001030); +- nv_wo32(dev, *gpuobj, 1, 0xFFFFFFFF); ++ nv_wo32(*gpuobj, 0, 0x00001030); ++ nv_wo32(*gpuobj, 4, 0xFFFFFFFF); + break; + default: + if (dev_priv->card_type >= NV_40) { +- nv_wo32(dev, *gpuobj, 0, class); ++ nv_wo32(*gpuobj, 0, class); + #ifdef __BIG_ENDIAN +- nv_wo32(dev, *gpuobj, 2, 0x01000000); ++ nv_wo32(*gpuobj, 8, 0x01000000); + #endif + } else { + #ifdef __BIG_ENDIAN +- nv_wo32(dev, *gpuobj, 0, class | 0x00080000); ++ nv_wo32(*gpuobj, 0, class | 0x00080000); + #else +- nv_wo32(dev, *gpuobj, 0, class); ++ nv_wo32(*gpuobj, 0, class); + #endif + } + } + } +- dev_priv->engine.instmem.finish_access(dev); ++ dev_priv->engine.instmem.flush(dev); + + (*gpuobj)->engine = NVOBJ_ENGINE_GR; + (*gpuobj)->class = class; +@@ -895,10 +560,15 @@ nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, + gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); + if (!gpuobj) + return -ENOMEM; ++ gpuobj->dev = chan->dev; + gpuobj->engine = NVOBJ_ENGINE_SW; + gpuobj->class = class; ++ kref_init(&gpuobj->refcount); ++ gpuobj->cinst = 0x40; + ++ spin_lock(&dev_priv->ramin_lock); + list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); ++ spin_unlock(&dev_priv->ramin_lock); + *gpuobj_ret = gpuobj; + return 0; + } +@@ -908,7 +578,6 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) + { + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_gpuobj *pramin = NULL; + uint32_t size; + uint32_t base; + int ret; +@@ -920,6 +589,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) + base = 0; + + /* PGRAPH context */ ++ size += dev_priv->engine.graph.grctx_size; + + if (dev_priv->card_type == NV_50) { + /* Various fixed table thingos */ +@@ -930,25 +600,18 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) + size += 0x8000; + /* RAMFC */ + size += 0x1000; +- /* PGRAPH context */ +- size += 0x70000; + } + +- NV_DEBUG(dev, "ch%d PRAMIN size: 0x%08x bytes, base alloc=0x%08x\n", +- chan->id, size, base); +- ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, size, 0x1000, 0, +- &chan->ramin); ++ ret = nouveau_gpuobj_new(dev, NULL, size, 0x1000, 0, &chan->ramin); + if (ret) { + NV_ERROR(dev, "Error allocating channel PRAMIN: %d\n", ret); + return ret; + } +- pramin = chan->ramin->gpuobj; + +- ret = nouveau_mem_init_heap(&chan->ramin_heap, +- pramin->im_pramin->start + base, size); ++ ret = drm_mm_init(&chan->ramin_heap, base, size); + if (ret) { + NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret); +- nouveau_gpuobj_ref_del(dev, &chan->ramin); ++ nouveau_gpuobj_ref(NULL, &chan->ramin); + return ret; + } + +@@ -965,19 +628,13 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, + struct nouveau_gpuobj *vram = NULL, *tt = NULL; + int ret, i; + +- INIT_LIST_HEAD(&chan->ramht_refs); +- + NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h); + +- /* Reserve a block of PRAMIN for the channel +- *XXX: maybe on card_type == NV_50) { +- ret = nouveau_gpuobj_channel_init_pramin(chan); +- if (ret) { +- NV_ERROR(dev, "init pramin\n"); +- return ret; +- } ++ /* Allocate a chunk of memory for per-channel object storage */ ++ ret = nouveau_gpuobj_channel_init_pramin(chan); ++ if (ret) { ++ NV_ERROR(dev, "init pramin\n"); ++ return ret; + } + + /* NV50 VM +@@ -986,65 +643,56 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, + * locations determined during init. + */ + if (dev_priv->card_type >= NV_50) { +- uint32_t vm_offset, pde; +- +- instmem->prepare_access(dev, true); ++ u32 pgd_offs = (dev_priv->chipset == 0x50) ? 0x1400 : 0x0200; ++ u64 vm_vinst = chan->ramin->vinst + pgd_offs; ++ u32 vm_pinst = chan->ramin->pinst; ++ u32 pde; + +- vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200; +- vm_offset += chan->ramin->gpuobj->im_pramin->start; ++ if (vm_pinst != ~0) ++ vm_pinst += pgd_offs; + +- ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000, +- 0, &chan->vm_pd, NULL); +- if (ret) { +- instmem->finish_access(dev); ++ ret = nouveau_gpuobj_new_fake(dev, vm_pinst, vm_vinst, 0x4000, ++ 0, &chan->vm_pd); ++ if (ret) + return ret; +- } + for (i = 0; i < 0x4000; i += 8) { +- nv_wo32(dev, chan->vm_pd, (i+0)/4, 0x00000000); +- nv_wo32(dev, chan->vm_pd, (i+4)/4, 0xdeadcafe); ++ nv_wo32(chan->vm_pd, i + 0, 0x00000000); ++ nv_wo32(chan->vm_pd, i + 4, 0xdeadcafe); + } + +- pde = (dev_priv->vm_gart_base / (512*1024*1024)) * 2; +- ret = nouveau_gpuobj_ref_add(dev, NULL, 0, +- dev_priv->gart_info.sg_ctxdma, +- &chan->vm_gart_pt); +- if (ret) { +- instmem->finish_access(dev); +- return ret; +- } +- nv_wo32(dev, chan->vm_pd, pde++, +- chan->vm_gart_pt->instance | 0x03); +- nv_wo32(dev, chan->vm_pd, pde++, 0x00000000); ++ nouveau_gpuobj_ref(dev_priv->gart_info.sg_ctxdma, ++ &chan->vm_gart_pt); ++ pde = (dev_priv->vm_gart_base / (512*1024*1024)) * 8; ++ nv_wo32(chan->vm_pd, pde + 0, chan->vm_gart_pt->vinst | 3); ++ nv_wo32(chan->vm_pd, pde + 4, 0x00000000); + +- pde = (dev_priv->vm_vram_base / (512*1024*1024)) * 2; ++ pde = (dev_priv->vm_vram_base / (512*1024*1024)) * 8; + for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) { +- ret = nouveau_gpuobj_ref_add(dev, NULL, 0, +- dev_priv->vm_vram_pt[i], +- &chan->vm_vram_pt[i]); +- if (ret) { +- instmem->finish_access(dev); +- return ret; +- } ++ nouveau_gpuobj_ref(dev_priv->vm_vram_pt[i], ++ &chan->vm_vram_pt[i]); + +- nv_wo32(dev, chan->vm_pd, pde++, +- chan->vm_vram_pt[i]->instance | 0x61); +- nv_wo32(dev, chan->vm_pd, pde++, 0x00000000); ++ nv_wo32(chan->vm_pd, pde + 0, ++ chan->vm_vram_pt[i]->vinst | 0x61); ++ nv_wo32(chan->vm_pd, pde + 4, 0x00000000); ++ pde += 8; + } + +- instmem->finish_access(dev); ++ instmem->flush(dev); + } + + /* RAMHT */ + if (dev_priv->card_type < NV_50) { +- ret = nouveau_gpuobj_ref_add(dev, NULL, 0, dev_priv->ramht, +- &chan->ramht); ++ nouveau_ramht_ref(dev_priv->ramht, &chan->ramht, NULL); ++ } else { ++ struct nouveau_gpuobj *ramht = NULL; ++ ++ ret = nouveau_gpuobj_new(dev, chan, 0x8000, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, &ramht); + if (ret) + return ret; +- } else { +- ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, +- 0x8000, 16, +- NVOBJ_FLAG_ZERO_ALLOC, +- &chan->ramht); ++ ++ ret = nouveau_ramht_new(dev, ramht, &chan->ramht); ++ nouveau_gpuobj_ref(NULL, &ramht); + if (ret) + return ret; + } +@@ -1061,24 +709,32 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, + } + } else { + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, +- 0, dev_priv->fb_available_size, +- NV_DMA_ACCESS_RW, +- NV_DMA_TARGET_VIDMEM, &vram); ++ 0, dev_priv->fb_available_size, ++ NV_DMA_ACCESS_RW, ++ NV_DMA_TARGET_VIDMEM, &vram); + if (ret) { + NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); + return ret; + } + } + +- ret = nouveau_gpuobj_ref_add(dev, chan, vram_h, vram, NULL); ++ ret = nouveau_ramht_insert(chan, vram_h, vram); ++ nouveau_gpuobj_ref(NULL, &vram); + if (ret) { +- NV_ERROR(dev, "Error referencing VRAM ctxdma: %d\n", ret); ++ NV_ERROR(dev, "Error adding VRAM ctxdma to RAMHT: %d\n", ret); + return ret; + } + + /* TT memory ctxdma */ + if (dev_priv->card_type >= NV_50) { +- tt = vram; ++ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, ++ 0, dev_priv->vm_end, ++ NV_DMA_ACCESS_RW, ++ NV_DMA_TARGET_AGP, &tt); ++ if (ret) { ++ NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); ++ return ret; ++ } + } else + if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) { + ret = nouveau_gpuobj_gart_dma_new(chan, 0, +@@ -1094,9 +750,10 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, + return ret; + } + +- ret = nouveau_gpuobj_ref_add(dev, chan, tt_h, tt, NULL); ++ ret = nouveau_ramht_insert(chan, tt_h, tt); ++ nouveau_gpuobj_ref(NULL, &tt); + if (ret) { +- NV_ERROR(dev, "Error referencing TT ctxdma: %d\n", ret); ++ NV_ERROR(dev, "Error adding TT ctxdma to RAMHT: %d\n", ret); + return ret; + } + +@@ -1108,33 +765,23 @@ nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) + { + struct drm_nouveau_private *dev_priv = chan->dev->dev_private; + struct drm_device *dev = chan->dev; +- struct list_head *entry, *tmp; +- struct nouveau_gpuobj_ref *ref; + int i; + + NV_DEBUG(dev, "ch%d\n", chan->id); + +- if (!chan->ramht_refs.next) ++ if (!chan->ramht) + return; + +- list_for_each_safe(entry, tmp, &chan->ramht_refs) { +- ref = list_entry(entry, struct nouveau_gpuobj_ref, list); ++ nouveau_ramht_ref(NULL, &chan->ramht, chan); + +- nouveau_gpuobj_ref_del(dev, &ref); +- } +- +- nouveau_gpuobj_ref_del(dev, &chan->ramht); +- +- nouveau_gpuobj_del(dev, &chan->vm_pd); +- nouveau_gpuobj_ref_del(dev, &chan->vm_gart_pt); ++ nouveau_gpuobj_ref(NULL, &chan->vm_pd); ++ nouveau_gpuobj_ref(NULL, &chan->vm_gart_pt); + for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) +- nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]); +- +- if (chan->ramin_heap) +- nouveau_mem_takedown(&chan->ramin_heap); +- if (chan->ramin) +- nouveau_gpuobj_ref_del(dev, &chan->ramin); ++ nouveau_gpuobj_ref(NULL, &chan->vm_vram_pt[i]); + ++ if (chan->ramin_heap.fl_entry.next) ++ drm_mm_takedown(&chan->ramin_heap); ++ nouveau_gpuobj_ref(NULL, &chan->ramin); + } + + int +@@ -1155,19 +802,17 @@ nouveau_gpuobj_suspend(struct drm_device *dev) + } + + list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) { +- if (!gpuobj->im_backing || (gpuobj->flags & NVOBJ_FLAG_FAKE)) ++ if (!gpuobj->im_backing) + continue; + +- gpuobj->im_backing_suspend = vmalloc(gpuobj->im_pramin->size); ++ gpuobj->im_backing_suspend = vmalloc(gpuobj->size); + if (!gpuobj->im_backing_suspend) { + nouveau_gpuobj_resume(dev); + return -ENOMEM; + } + +- dev_priv->engine.instmem.prepare_access(dev, false); +- for (i = 0; i < gpuobj->im_pramin->size / 4; i++) +- gpuobj->im_backing_suspend[i] = nv_ro32(dev, gpuobj, i); +- dev_priv->engine.instmem.finish_access(dev); ++ for (i = 0; i < gpuobj->size; i += 4) ++ gpuobj->im_backing_suspend[i/4] = nv_ro32(gpuobj, i); + } + + return 0; +@@ -1212,10 +857,9 @@ nouveau_gpuobj_resume(struct drm_device *dev) + if (!gpuobj->im_backing_suspend) + continue; + +- dev_priv->engine.instmem.prepare_access(dev, true); +- for (i = 0; i < gpuobj->im_pramin->size / 4; i++) +- nv_wo32(dev, gpuobj, i, gpuobj->im_backing_suspend[i]); +- dev_priv->engine.instmem.finish_access(dev); ++ for (i = 0; i < gpuobj->size; i += 4) ++ nv_wo32(gpuobj, i, gpuobj->im_backing_suspend[i/4]); ++ dev_priv->engine.instmem.flush(dev); + } + + nouveau_gpuobj_suspend_cleanup(dev); +@@ -1232,7 +876,6 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, + struct nouveau_channel *chan; + int ret; + +- NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan); + + if (init->handle == ~0) +@@ -1250,25 +893,24 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, + return -EPERM; + } + +- if (nouveau_gpuobj_ref_find(chan, init->handle, NULL) == 0) ++ if (nouveau_ramht_find(chan, init->handle)) + return -EEXIST; + + if (!grc->software) + ret = nouveau_gpuobj_gr_new(chan, grc->id, &gr); + else + ret = nouveau_gpuobj_sw_new(chan, grc->id, &gr); +- + if (ret) { + NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n", + ret, init->channel, init->handle); + return ret; + } + +- ret = nouveau_gpuobj_ref_add(dev, chan, init->handle, gr, NULL); ++ ret = nouveau_ramht_insert(chan, init->handle, gr); ++ nouveau_gpuobj_ref(NULL, &gr); + if (ret) { + NV_ERROR(dev, "Error referencing object: %d (%d/0x%08x)\n", + ret, init->channel, init->handle); +- nouveau_gpuobj_del(dev, &gr); + return ret; + } + +@@ -1279,17 +921,62 @@ int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { + struct drm_nouveau_gpuobj_free *objfree = data; +- struct nouveau_gpuobj_ref *ref; ++ struct nouveau_gpuobj *gpuobj; + struct nouveau_channel *chan; +- int ret; + +- NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan); + +- ret = nouveau_gpuobj_ref_find(chan, objfree->handle, &ref); +- if (ret) +- return ret; +- nouveau_gpuobj_ref_del(dev, &ref); ++ gpuobj = nouveau_ramht_find(chan, objfree->handle); ++ if (!gpuobj) ++ return -ENOENT; + ++ nouveau_ramht_remove(chan, objfree->handle); + return 0; + } ++ ++u32 ++nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset) ++{ ++ struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; ++ struct drm_device *dev = gpuobj->dev; ++ ++ if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { ++ u64 ptr = gpuobj->vinst + offset; ++ u32 base = ptr >> 16; ++ u32 val; ++ ++ spin_lock(&dev_priv->ramin_lock); ++ if (dev_priv->ramin_base != base) { ++ dev_priv->ramin_base = base; ++ nv_wr32(dev, 0x001700, dev_priv->ramin_base); ++ } ++ val = nv_rd32(dev, 0x700000 + (ptr & 0xffff)); ++ spin_unlock(&dev_priv->ramin_lock); ++ return val; ++ } ++ ++ return nv_ri32(dev, gpuobj->pinst + offset); ++} ++ ++void ++nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val) ++{ ++ struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; ++ struct drm_device *dev = gpuobj->dev; ++ ++ if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { ++ u64 ptr = gpuobj->vinst + offset; ++ u32 base = ptr >> 16; ++ ++ spin_lock(&dev_priv->ramin_lock); ++ if (dev_priv->ramin_base != base) { ++ dev_priv->ramin_base = base; ++ nv_wr32(dev, 0x001700, dev_priv->ramin_base); ++ } ++ nv_wr32(dev, 0x700000 + (ptr & 0xffff), val); ++ spin_unlock(&dev_priv->ramin_lock); ++ return; ++ } ++ ++ nv_wi32(dev, gpuobj->pinst + offset, val); ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.c b/drivers/gpu/drm/nouveau/nouveau_ramht.c +new file mode 100644 +index 0000000..7f16697 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_ramht.c +@@ -0,0 +1,289 @@ ++/* ++ * Copyright 2010 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Ben Skeggs ++ */ ++ ++#include "drmP.h" ++ ++#include "nouveau_drv.h" ++#include "nouveau_ramht.h" ++ ++static u32 ++nouveau_ramht_hash_handle(struct nouveau_channel *chan, u32 handle) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_ramht *ramht = chan->ramht; ++ u32 hash = 0; ++ int i; ++ ++ NV_DEBUG(dev, "ch%d handle=0x%08x\n", chan->id, handle); ++ ++ for (i = 32; i > 0; i -= ramht->bits) { ++ hash ^= (handle & ((1 << ramht->bits) - 1)); ++ handle >>= ramht->bits; ++ } ++ ++ if (dev_priv->card_type < NV_50) ++ hash ^= chan->id << (ramht->bits - 4); ++ hash <<= 3; ++ ++ NV_DEBUG(dev, "hash=0x%08x\n", hash); ++ return hash; ++} ++ ++static int ++nouveau_ramht_entry_valid(struct drm_device *dev, struct nouveau_gpuobj *ramht, ++ u32 offset) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ u32 ctx = nv_ro32(ramht, offset + 4); ++ ++ if (dev_priv->card_type < NV_40) ++ return ((ctx & NV_RAMHT_CONTEXT_VALID) != 0); ++ return (ctx != 0); ++} ++ ++static int ++nouveau_ramht_entry_same_channel(struct nouveau_channel *chan, ++ struct nouveau_gpuobj *ramht, u32 offset) ++{ ++ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; ++ u32 ctx = nv_ro32(ramht, offset + 4); ++ ++ if (dev_priv->card_type >= NV_50) ++ return true; ++ else if (dev_priv->card_type >= NV_40) ++ return chan->id == ++ ((ctx >> NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) & 0x1f); ++ else ++ return chan->id == ++ ((ctx >> NV_RAMHT_CONTEXT_CHANNEL_SHIFT) & 0x1f); ++} ++ ++int ++nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle, ++ struct nouveau_gpuobj *gpuobj) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; ++ struct nouveau_ramht_entry *entry; ++ struct nouveau_gpuobj *ramht = chan->ramht->gpuobj; ++ unsigned long flags; ++ u32 ctx, co, ho; ++ ++ if (nouveau_ramht_find(chan, handle)) ++ return -EEXIST; ++ ++ entry = kmalloc(sizeof(*entry), GFP_KERNEL); ++ if (!entry) ++ return -ENOMEM; ++ entry->channel = chan; ++ entry->gpuobj = NULL; ++ entry->handle = handle; ++ nouveau_gpuobj_ref(gpuobj, &entry->gpuobj); ++ ++ if (dev_priv->card_type < NV_40) { ++ ctx = NV_RAMHT_CONTEXT_VALID | (gpuobj->cinst >> 4) | ++ (chan->id << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) | ++ (gpuobj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT); ++ } else ++ if (dev_priv->card_type < NV_50) { ++ ctx = (gpuobj->cinst >> 4) | ++ (chan->id << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) | ++ (gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT); ++ } else { ++ if (gpuobj->engine == NVOBJ_ENGINE_DISPLAY) { ++ ctx = (gpuobj->cinst << 10) | 2; ++ } else { ++ ctx = (gpuobj->cinst >> 4) | ++ ((gpuobj->engine << ++ NV40_RAMHT_CONTEXT_ENGINE_SHIFT)); ++ } ++ } ++ ++ spin_lock_irqsave(&chan->ramht->lock, flags); ++ list_add(&entry->head, &chan->ramht->entries); ++ ++ co = ho = nouveau_ramht_hash_handle(chan, handle); ++ do { ++ if (!nouveau_ramht_entry_valid(dev, ramht, co)) { ++ NV_DEBUG(dev, ++ "insert ch%d 0x%08x: h=0x%08x, c=0x%08x\n", ++ chan->id, co, handle, ctx); ++ nv_wo32(ramht, co + 0, handle); ++ nv_wo32(ramht, co + 4, ctx); ++ ++ spin_unlock_irqrestore(&chan->ramht->lock, flags); ++ instmem->flush(dev); ++ return 0; ++ } ++ NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n", ++ chan->id, co, nv_ro32(ramht, co)); ++ ++ co += 8; ++ if (co >= ramht->size) ++ co = 0; ++ } while (co != ho); ++ ++ NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", chan->id); ++ list_del(&entry->head); ++ spin_unlock_irqrestore(&chan->ramht->lock, flags); ++ kfree(entry); ++ return -ENOMEM; ++} ++ ++static void ++nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; ++ struct nouveau_gpuobj *ramht = chan->ramht->gpuobj; ++ struct nouveau_ramht_entry *entry, *tmp; ++ u32 co, ho; ++ ++ list_for_each_entry_safe(entry, tmp, &chan->ramht->entries, head) { ++ if (entry->channel != chan || entry->handle != handle) ++ continue; ++ ++ nouveau_gpuobj_ref(NULL, &entry->gpuobj); ++ list_del(&entry->head); ++ kfree(entry); ++ break; ++ } ++ ++ co = ho = nouveau_ramht_hash_handle(chan, handle); ++ do { ++ if (nouveau_ramht_entry_valid(dev, ramht, co) && ++ nouveau_ramht_entry_same_channel(chan, ramht, co) && ++ (handle == nv_ro32(ramht, co))) { ++ NV_DEBUG(dev, ++ "remove ch%d 0x%08x: h=0x%08x, c=0x%08x\n", ++ chan->id, co, handle, nv_ro32(ramht, co + 4)); ++ nv_wo32(ramht, co + 0, 0x00000000); ++ nv_wo32(ramht, co + 4, 0x00000000); ++ instmem->flush(dev); ++ return; ++ } ++ ++ co += 8; ++ if (co >= ramht->size) ++ co = 0; ++ } while (co != ho); ++ ++ NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n", ++ chan->id, handle); ++} ++ ++void ++nouveau_ramht_remove(struct nouveau_channel *chan, u32 handle) ++{ ++ struct nouveau_ramht *ramht = chan->ramht; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ramht->lock, flags); ++ nouveau_ramht_remove_locked(chan, handle); ++ spin_unlock_irqrestore(&ramht->lock, flags); ++} ++ ++struct nouveau_gpuobj * ++nouveau_ramht_find(struct nouveau_channel *chan, u32 handle) ++{ ++ struct nouveau_ramht *ramht = chan->ramht; ++ struct nouveau_ramht_entry *entry; ++ struct nouveau_gpuobj *gpuobj = NULL; ++ unsigned long flags; ++ ++ if (unlikely(!chan->ramht)) ++ return NULL; ++ ++ spin_lock_irqsave(&ramht->lock, flags); ++ list_for_each_entry(entry, &chan->ramht->entries, head) { ++ if (entry->channel == chan && entry->handle == handle) { ++ gpuobj = entry->gpuobj; ++ break; ++ } ++ } ++ spin_unlock_irqrestore(&ramht->lock, flags); ++ ++ return gpuobj; ++} ++ ++int ++nouveau_ramht_new(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, ++ struct nouveau_ramht **pramht) ++{ ++ struct nouveau_ramht *ramht; ++ ++ ramht = kzalloc(sizeof(*ramht), GFP_KERNEL); ++ if (!ramht) ++ return -ENOMEM; ++ ++ ramht->dev = dev; ++ kref_init(&ramht->refcount); ++ ramht->bits = drm_order(gpuobj->size / 8); ++ INIT_LIST_HEAD(&ramht->entries); ++ spin_lock_init(&ramht->lock); ++ nouveau_gpuobj_ref(gpuobj, &ramht->gpuobj); ++ ++ *pramht = ramht; ++ return 0; ++} ++ ++static void ++nouveau_ramht_del(struct kref *ref) ++{ ++ struct nouveau_ramht *ramht = ++ container_of(ref, struct nouveau_ramht, refcount); ++ ++ nouveau_gpuobj_ref(NULL, &ramht->gpuobj); ++ kfree(ramht); ++} ++ ++void ++nouveau_ramht_ref(struct nouveau_ramht *ref, struct nouveau_ramht **ptr, ++ struct nouveau_channel *chan) ++{ ++ struct nouveau_ramht_entry *entry, *tmp; ++ struct nouveau_ramht *ramht; ++ unsigned long flags; ++ ++ if (ref) ++ kref_get(&ref->refcount); ++ ++ ramht = *ptr; ++ if (ramht) { ++ spin_lock_irqsave(&ramht->lock, flags); ++ list_for_each_entry_safe(entry, tmp, &ramht->entries, head) { ++ if (entry->channel != chan) ++ continue; ++ ++ nouveau_ramht_remove_locked(chan, entry->handle); ++ } ++ spin_unlock_irqrestore(&ramht->lock, flags); ++ ++ kref_put(&ramht->refcount, nouveau_ramht_del); ++ } ++ *ptr = ref; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.h b/drivers/gpu/drm/nouveau/nouveau_ramht.h +new file mode 100644 +index 0000000..b79cb5e +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_ramht.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright 2010 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Ben Skeggs ++ */ ++ ++#ifndef __NOUVEAU_RAMHT_H__ ++#define __NOUVEAU_RAMHT_H__ ++ ++struct nouveau_ramht_entry { ++ struct list_head head; ++ struct nouveau_channel *channel; ++ struct nouveau_gpuobj *gpuobj; ++ u32 handle; ++}; ++ ++struct nouveau_ramht { ++ struct drm_device *dev; ++ struct kref refcount; ++ spinlock_t lock; ++ struct nouveau_gpuobj *gpuobj; ++ struct list_head entries; ++ int bits; ++}; ++ ++extern int nouveau_ramht_new(struct drm_device *, struct nouveau_gpuobj *, ++ struct nouveau_ramht **); ++extern void nouveau_ramht_ref(struct nouveau_ramht *, struct nouveau_ramht **, ++ struct nouveau_channel *unref_channel); ++ ++extern int nouveau_ramht_insert(struct nouveau_channel *, u32 handle, ++ struct nouveau_gpuobj *); ++extern void nouveau_ramht_remove(struct nouveau_channel *, u32 handle); ++extern struct nouveau_gpuobj * ++nouveau_ramht_find(struct nouveau_channel *chan, u32 handle); ++ ++#endif +diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h +index 6ca80a3..1b42541 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_reg.h ++++ b/drivers/gpu/drm/nouveau/nouveau_reg.h +@@ -1,19 +1,64 @@ + ++#define NV04_PFB_BOOT_0 0x00100000 ++# define NV04_PFB_BOOT_0_RAM_AMOUNT 0x00000003 ++# define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000 ++# define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001 ++# define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002 ++# define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003 ++# define NV04_PFB_BOOT_0_RAM_WIDTH_128 0x00000004 ++# define NV04_PFB_BOOT_0_RAM_TYPE 0x00000028 ++# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT 0x00000000 ++# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT 0x00000008 ++# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK 0x00000010 ++# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT 0x00000018 ++# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT 0x00000020 ++# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16 0x00000028 ++# define NV04_PFB_BOOT_0_UMA_ENABLE 0x00000100 ++# define NV04_PFB_BOOT_0_UMA_SIZE 0x0000f000 ++#define NV04_PFB_DEBUG_0 0x00100080 ++# define NV04_PFB_DEBUG_0_PAGE_MODE 0x00000001 ++# define NV04_PFB_DEBUG_0_REFRESH_OFF 0x00000010 ++# define NV04_PFB_DEBUG_0_REFRESH_COUNTX64 0x00003f00 ++# define NV04_PFB_DEBUG_0_REFRESH_SLOW_CLK 0x00004000 ++# define NV04_PFB_DEBUG_0_SAFE_MODE 0x00008000 ++# define NV04_PFB_DEBUG_0_ALOM_ENABLE 0x00010000 ++# define NV04_PFB_DEBUG_0_CASOE 0x00100000 ++# define NV04_PFB_DEBUG_0_CKE_INVERT 0x10000000 ++# define NV04_PFB_DEBUG_0_REFINC 0x20000000 ++# define NV04_PFB_DEBUG_0_SAVE_POWER_OFF 0x40000000 ++#define NV04_PFB_CFG0 0x00100200 ++# define NV04_PFB_CFG0_SCRAMBLE 0x20000000 ++#define NV04_PFB_CFG1 0x00100204 ++#define NV04_PFB_FIFO_DATA 0x0010020c ++# define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000 ++# define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20 ++#define NV10_PFB_REFCTRL 0x00100210 ++# define NV10_PFB_REFCTRL_VALID_1 (1 << 31) ++#define NV04_PFB_PAD 0x0010021c ++# define NV04_PFB_PAD_CKE_NORMAL (1 << 0) ++#define NV10_PFB_TILE(i) (0x00100240 + (i*16)) ++#define NV10_PFB_TILE__SIZE 8 ++#define NV10_PFB_TLIMIT(i) (0x00100244 + (i*16)) ++#define NV10_PFB_TSIZE(i) (0x00100248 + (i*16)) ++#define NV10_PFB_TSTATUS(i) (0x0010024c + (i*16)) ++#define NV04_PFB_REF 0x001002d0 ++# define NV04_PFB_REF_CMD_REFRESH (1 << 0) ++#define NV04_PFB_PRE 0x001002d4 ++# define NV04_PFB_PRE_CMD_PRECHARGE (1 << 0) ++#define NV10_PFB_CLOSE_PAGE2 0x0010033c ++#define NV04_PFB_SCRAMBLE(i) (0x00100400 + 4 * (i)) ++#define NV40_PFB_TILE(i) (0x00100600 + (i*16)) ++#define NV40_PFB_TILE__SIZE_0 12 ++#define NV40_PFB_TILE__SIZE_1 15 ++#define NV40_PFB_TLIMIT(i) (0x00100604 + (i*16)) ++#define NV40_PFB_TSIZE(i) (0x00100608 + (i*16)) ++#define NV40_PFB_TSTATUS(i) (0x0010060c + (i*16)) ++#define NV40_PFB_UNK_800 0x00100800 + +-#define NV03_BOOT_0 0x00100000 +-# define NV03_BOOT_0_RAM_AMOUNT 0x00000003 +-# define NV03_BOOT_0_RAM_AMOUNT_8MB 0x00000000 +-# define NV03_BOOT_0_RAM_AMOUNT_2MB 0x00000001 +-# define NV03_BOOT_0_RAM_AMOUNT_4MB 0x00000002 +-# define NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM 0x00000003 +-# define NV04_BOOT_0_RAM_AMOUNT_32MB 0x00000000 +-# define NV04_BOOT_0_RAM_AMOUNT_4MB 0x00000001 +-# define NV04_BOOT_0_RAM_AMOUNT_8MB 0x00000002 +-# define NV04_BOOT_0_RAM_AMOUNT_16MB 0x00000003 +- +-#define NV04_FIFO_DATA 0x0010020c +-# define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000 +-# define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20 ++#define NV_PEXTDEV_BOOT_0 0x00101000 ++#define NV_PEXTDEV_BOOT_0_RAMCFG 0x0000003c ++# define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT (8 << 12) ++#define NV_PEXTDEV_BOOT_3 0x0010100c + + #define NV_RAMIN 0x00700000 + +@@ -131,23 +176,6 @@ + #define NV04_PTIMER_TIME_1 0x00009410 + #define NV04_PTIMER_ALARM_0 0x00009420 + +-#define NV04_PFB_CFG0 0x00100200 +-#define NV04_PFB_CFG1 0x00100204 +-#define NV40_PFB_020C 0x0010020C +-#define NV10_PFB_TILE(i) (0x00100240 + (i*16)) +-#define NV10_PFB_TILE__SIZE 8 +-#define NV10_PFB_TLIMIT(i) (0x00100244 + (i*16)) +-#define NV10_PFB_TSIZE(i) (0x00100248 + (i*16)) +-#define NV10_PFB_TSTATUS(i) (0x0010024C + (i*16)) +-#define NV10_PFB_CLOSE_PAGE2 0x0010033C +-#define NV40_PFB_TILE(i) (0x00100600 + (i*16)) +-#define NV40_PFB_TILE__SIZE_0 12 +-#define NV40_PFB_TILE__SIZE_1 15 +-#define NV40_PFB_TLIMIT(i) (0x00100604 + (i*16)) +-#define NV40_PFB_TSIZE(i) (0x00100608 + (i*16)) +-#define NV40_PFB_TSTATUS(i) (0x0010060C + (i*16)) +-#define NV40_PFB_UNK_800 0x00100800 +- + #define NV04_PGRAPH_DEBUG_0 0x00400080 + #define NV04_PGRAPH_DEBUG_1 0x00400084 + #define NV04_PGRAPH_DEBUG_2 0x00400088 +@@ -192,28 +220,21 @@ + # define NV_PGRAPH_INTR_ERROR (1<<20) + #define NV10_PGRAPH_CTX_CONTROL 0x00400144 + #define NV10_PGRAPH_CTX_USER 0x00400148 +-#define NV10_PGRAPH_CTX_SWITCH1 0x0040014C +-#define NV10_PGRAPH_CTX_SWITCH2 0x00400150 +-#define NV10_PGRAPH_CTX_SWITCH3 0x00400154 +-#define NV10_PGRAPH_CTX_SWITCH4 0x00400158 +-#define NV10_PGRAPH_CTX_SWITCH5 0x0040015C ++#define NV10_PGRAPH_CTX_SWITCH(i) (0x0040014C + 0x4*(i)) + #define NV04_PGRAPH_CTX_SWITCH1 0x00400160 +-#define NV10_PGRAPH_CTX_CACHE1 0x00400160 ++#define NV10_PGRAPH_CTX_CACHE(i, j) (0x00400160 \ ++ + 0x4*(i) + 0x20*(j)) + #define NV04_PGRAPH_CTX_SWITCH2 0x00400164 + #define NV04_PGRAPH_CTX_SWITCH3 0x00400168 + #define NV04_PGRAPH_CTX_SWITCH4 0x0040016C + #define NV04_PGRAPH_CTX_CONTROL 0x00400170 + #define NV04_PGRAPH_CTX_USER 0x00400174 + #define NV04_PGRAPH_CTX_CACHE1 0x00400180 +-#define NV10_PGRAPH_CTX_CACHE2 0x00400180 + #define NV03_PGRAPH_CTX_CONTROL 0x00400190 + #define NV03_PGRAPH_CTX_USER 0x00400194 + #define NV04_PGRAPH_CTX_CACHE2 0x004001A0 +-#define NV10_PGRAPH_CTX_CACHE3 0x004001A0 + #define NV04_PGRAPH_CTX_CACHE3 0x004001C0 +-#define NV10_PGRAPH_CTX_CACHE4 0x004001C0 + #define NV04_PGRAPH_CTX_CACHE4 0x004001E0 +-#define NV10_PGRAPH_CTX_CACHE5 0x004001E0 + #define NV40_PGRAPH_CTXCTL_0304 0x00400304 + #define NV40_PGRAPH_CTXCTL_0304_XFER_CTX 0x00000001 + #define NV40_PGRAPH_CTXCTL_UCODE_STAT 0x00400308 +@@ -328,9 +349,12 @@ + #define NV04_PGRAPH_FFINTFC_ST2 0x00400754 + #define NV10_PGRAPH_RDI_DATA 0x00400754 + #define NV04_PGRAPH_DMA_PITCH 0x00400760 +-#define NV10_PGRAPH_FFINTFC_ST2 0x00400764 ++#define NV10_PGRAPH_FFINTFC_FIFO_PTR 0x00400760 + #define NV04_PGRAPH_DVD_COLORFMT 0x00400764 ++#define NV10_PGRAPH_FFINTFC_ST2 0x00400764 + #define NV04_PGRAPH_SCALED_FORMAT 0x00400768 ++#define NV10_PGRAPH_FFINTFC_ST2_DL 0x00400768 ++#define NV10_PGRAPH_FFINTFC_ST2_DH 0x0040076c + #define NV10_PGRAPH_DMA_PITCH 0x00400770 + #define NV10_PGRAPH_DVD_COLORFMT 0x00400774 + #define NV10_PGRAPH_SCALED_FORMAT 0x00400778 +@@ -527,6 +551,8 @@ + #define NV10_PFIFO_CACHE1_DMA_SUBROUTINE 0x0000324C + #define NV03_PFIFO_CACHE1_PULL0 0x00003240 + #define NV04_PFIFO_CACHE1_PULL0 0x00003250 ++# define NV04_PFIFO_CACHE1_PULL0_HASH_FAILED 0x00000010 ++# define NV04_PFIFO_CACHE1_PULL0_HASH_BUSY 0x00001000 + #define NV03_PFIFO_CACHE1_PULL1 0x00003250 + #define NV04_PFIFO_CACHE1_PULL1 0x00003254 + #define NV04_PFIFO_CACHE1_HASH 0x00003258 +@@ -761,15 +787,12 @@ + #define NV50_PDISPLAY_DAC_MODE_CTRL_C(i) (0x00610b5c + (i) * 0x8) + #define NV50_PDISPLAY_SOR_MODE_CTRL_P(i) (0x00610b70 + (i) * 0x8) + #define NV50_PDISPLAY_SOR_MODE_CTRL_C(i) (0x00610b74 + (i) * 0x8) ++#define NV50_PDISPLAY_EXT_MODE_CTRL_P(i) (0x00610b80 + (i) * 0x8) ++#define NV50_PDISPLAY_EXT_MODE_CTRL_C(i) (0x00610b84 + (i) * 0x8) + #define NV50_PDISPLAY_DAC_MODE_CTRL2_P(i) (0x00610bdc + (i) * 0x8) + #define NV50_PDISPLAY_DAC_MODE_CTRL2_C(i) (0x00610be0 + (i) * 0x8) +- + #define NV90_PDISPLAY_SOR_MODE_CTRL_P(i) (0x00610794 + (i) * 0x8) + #define NV90_PDISPLAY_SOR_MODE_CTRL_C(i) (0x00610798 + (i) * 0x8) +-#define NV90_PDISPLAY_DAC_MODE_CTRL_P(i) (0x00610b58 + (i) * 0x8) +-#define NV90_PDISPLAY_DAC_MODE_CTRL_C(i) (0x00610b5c + (i) * 0x8) +-#define NV90_PDISPLAY_DAC_MODE_CTRL2_P(i) (0x00610b80 + (i) * 0x8) +-#define NV90_PDISPLAY_DAC_MODE_CTRL2_C(i) (0x00610b84 + (i) * 0x8) + + #define NV50_PDISPLAY_CRTC_CLK 0x00614000 + #define NV50_PDISPLAY_CRTC_CLK_CTRL1(i) ((i) * 0x800 + 0x614100) +@@ -814,6 +837,7 @@ + #define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE 0x80000000 + #define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL 0x00000fff + #define NV50_SOR_DP_CTRL(i,l) (0x0061c10c + (i) * 0x800 + (l) * 0x80) ++#define NV50_SOR_DP_CTRL_ENABLED 0x00000001 + #define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000 + #define NV50_SOR_DP_CTRL_LANE_MASK 0x001f0000 + #define NV50_SOR_DP_CTRL_LANE_0_ENABLED 0x00010000 +diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c +index 1d6ee8b..7f028fe 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c ++++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c +@@ -97,7 +97,6 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) + + NV_DEBUG(dev, "pg=0x%lx\n", mem->mm_node->start); + +- dev_priv->engine.instmem.prepare_access(nvbe->dev, true); + pte = nouveau_sgdma_pte(nvbe->dev, mem->mm_node->start << PAGE_SHIFT); + nvbe->pte_start = pte; + for (i = 0; i < nvbe->nr_pages; i++) { +@@ -106,34 +105,23 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) + uint32_t offset_h = upper_32_bits(dma_offset); + + for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) { +- if (dev_priv->card_type < NV_50) +- nv_wo32(dev, gpuobj, pte++, offset_l | 3); +- else { +- nv_wo32(dev, gpuobj, pte++, offset_l | 0x21); +- nv_wo32(dev, gpuobj, pte++, offset_h & 0xff); ++ if (dev_priv->card_type < NV_50) { ++ nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 3); ++ pte += 1; ++ } else { ++ nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 0x21); ++ nv_wo32(gpuobj, (pte * 4) + 4, offset_h & 0xff); ++ pte += 2; + } + + dma_offset += NV_CTXDMA_PAGE_SIZE; + } + } +- dev_priv->engine.instmem.finish_access(nvbe->dev); ++ dev_priv->engine.instmem.flush(nvbe->dev); + + if (dev_priv->card_type == NV_50) { +- nv_wr32(dev, 0x100c80, 0x00050001); +- if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +- NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +- NV_ERROR(dev, "0x100c80 = 0x%08x\n", +- nv_rd32(dev, 0x100c80)); +- return -EBUSY; +- } +- +- nv_wr32(dev, 0x100c80, 0x00000001); +- if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +- NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +- NV_ERROR(dev, "0x100c80 = 0x%08x\n", +- nv_rd32(dev, 0x100c80)); +- return -EBUSY; +- } ++ nv50_vm_flush(dev, 5); /* PGRAPH */ ++ nv50_vm_flush(dev, 0); /* PFIFO */ + } + + nvbe->bound = true; +@@ -154,40 +142,28 @@ nouveau_sgdma_unbind(struct ttm_backend *be) + if (!nvbe->bound) + return 0; + +- dev_priv->engine.instmem.prepare_access(nvbe->dev, true); + pte = nvbe->pte_start; + for (i = 0; i < nvbe->nr_pages; i++) { + dma_addr_t dma_offset = dev_priv->gart_info.sg_dummy_bus; + + for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) { +- if (dev_priv->card_type < NV_50) +- nv_wo32(dev, gpuobj, pte++, dma_offset | 3); +- else { +- nv_wo32(dev, gpuobj, pte++, dma_offset | 0x21); +- nv_wo32(dev, gpuobj, pte++, 0x00000000); ++ if (dev_priv->card_type < NV_50) { ++ nv_wo32(gpuobj, (pte * 4) + 0, dma_offset | 3); ++ pte += 1; ++ } else { ++ nv_wo32(gpuobj, (pte * 4) + 0, 0x00000000); ++ nv_wo32(gpuobj, (pte * 4) + 4, 0x00000000); ++ pte += 2; + } + + dma_offset += NV_CTXDMA_PAGE_SIZE; + } + } +- dev_priv->engine.instmem.finish_access(nvbe->dev); ++ dev_priv->engine.instmem.flush(nvbe->dev); + + if (dev_priv->card_type == NV_50) { +- nv_wr32(dev, 0x100c80, 0x00050001); +- if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +- NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +- NV_ERROR(dev, "0x100c80 = 0x%08x\n", +- nv_rd32(dev, 0x100c80)); +- return -EBUSY; +- } +- +- nv_wr32(dev, 0x100c80, 0x00000001); +- if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +- NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +- NV_ERROR(dev, "0x100c80 = 0x%08x\n", +- nv_rd32(dev, 0x100c80)); +- return -EBUSY; +- } ++ nv50_vm_flush(dev, 5); ++ nv50_vm_flush(dev, 0); + } + + nvbe->bound = false; +@@ -242,6 +218,7 @@ int + nouveau_sgdma_init(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct pci_dev *pdev = dev->pdev; + struct nouveau_gpuobj *gpuobj = NULL; + uint32_t aper_size, obj_size; + int i, ret; +@@ -257,7 +234,6 @@ nouveau_sgdma_init(struct drm_device *dev) + } + + ret = nouveau_gpuobj_new(dev, NULL, obj_size, 16, +- NVOBJ_FLAG_ALLOW_NO_REFS | + NVOBJ_FLAG_ZERO_ALLOC | + NVOBJ_FLAG_ZERO_FREE, &gpuobj); + if (ret) { +@@ -266,35 +242,48 @@ nouveau_sgdma_init(struct drm_device *dev) + } + + dev_priv->gart_info.sg_dummy_page = +- alloc_page(GFP_KERNEL|__GFP_DMA32); ++ alloc_page(GFP_KERNEL|__GFP_DMA32|__GFP_ZERO); ++ if (!dev_priv->gart_info.sg_dummy_page) { ++ nouveau_gpuobj_ref(NULL, &gpuobj); ++ return -ENOMEM; ++ } ++ + set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags); + dev_priv->gart_info.sg_dummy_bus = +- pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0, ++ pci_map_page(pdev, dev_priv->gart_info.sg_dummy_page, 0, + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); ++ if (pci_dma_mapping_error(pdev, dev_priv->gart_info.sg_dummy_bus)) { ++ nouveau_gpuobj_ref(NULL, &gpuobj); ++ return -EFAULT; ++ } + +- dev_priv->engine.instmem.prepare_access(dev, true); + if (dev_priv->card_type < NV_50) { ++ /* special case, allocated from global instmem heap so ++ * cinst is invalid, we use it on all channels though so ++ * cinst needs to be valid, set it the same as pinst ++ */ ++ gpuobj->cinst = gpuobj->pinst; ++ + /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and + * confirmed to work on c51. Perhaps means NV_DMA_TARGET_PCIE + * on those cards? */ +- nv_wo32(dev, gpuobj, 0, NV_CLASS_DMA_IN_MEMORY | +- (1 << 12) /* PT present */ | +- (0 << 13) /* PT *not* linear */ | +- (NV_DMA_ACCESS_RW << 14) | +- (NV_DMA_TARGET_PCI << 16)); +- nv_wo32(dev, gpuobj, 1, aper_size - 1); ++ nv_wo32(gpuobj, 0, NV_CLASS_DMA_IN_MEMORY | ++ (1 << 12) /* PT present */ | ++ (0 << 13) /* PT *not* linear */ | ++ (NV_DMA_ACCESS_RW << 14) | ++ (NV_DMA_TARGET_PCI << 16)); ++ nv_wo32(gpuobj, 4, aper_size - 1); + for (i = 2; i < 2 + (aper_size >> 12); i++) { +- nv_wo32(dev, gpuobj, i, +- dev_priv->gart_info.sg_dummy_bus | 3); ++ nv_wo32(gpuobj, i * 4, ++ dev_priv->gart_info.sg_dummy_bus | 3); + } + } else { + for (i = 0; i < obj_size; i += 8) { +- nv_wo32(dev, gpuobj, (i+0)/4, +- dev_priv->gart_info.sg_dummy_bus | 0x21); +- nv_wo32(dev, gpuobj, (i+4)/4, 0); ++ nv_wo32(gpuobj, i + 0, 0x00000000); ++ nv_wo32(gpuobj, i + 4, 0x00000000); + } + } +- dev_priv->engine.instmem.finish_access(dev); ++ dev_priv->engine.instmem.flush(dev); + + dev_priv->gart_info.type = NOUVEAU_GART_SGDMA; + dev_priv->gart_info.aper_base = 0; +@@ -317,7 +306,7 @@ nouveau_sgdma_takedown(struct drm_device *dev) + dev_priv->gart_info.sg_dummy_bus = 0; + } + +- nouveau_gpuobj_del(dev, &dev_priv->gart_info.sg_ctxdma); ++ nouveau_gpuobj_ref(NULL, &dev_priv->gart_info.sg_ctxdma); + } + + int +@@ -325,14 +314,11 @@ nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; +- struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; + int pte; + +- pte = (offset >> NV_CTXDMA_PAGE_SHIFT); ++ pte = (offset >> NV_CTXDMA_PAGE_SHIFT) << 2; + if (dev_priv->card_type < NV_50) { +- instmem->prepare_access(dev, false); +- *page = nv_ro32(dev, gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK; +- instmem->finish_access(dev); ++ *page = nv_ro32(gpuobj, (pte + 8)) & ~NV_CTXDMA_PAGE_MASK; + return 0; + } + +diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c +index b02a231..be85960 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_state.c ++++ b/drivers/gpu/drm/nouveau/nouveau_state.c +@@ -35,9 +35,11 @@ + #include "nouveau_drv.h" + #include "nouveau_drm.h" + #include "nouveau_fbcon.h" ++#include "nouveau_ramht.h" + #include "nv50_display.h" + + static void nouveau_stub_takedown(struct drm_device *dev) {} ++static int nouveau_stub_init(struct drm_device *dev) { return 0; } + + static int nouveau_init_engine_ptrs(struct drm_device *dev) + { +@@ -54,8 +56,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->instmem.clear = nv04_instmem_clear; + engine->instmem.bind = nv04_instmem_bind; + engine->instmem.unbind = nv04_instmem_unbind; +- engine->instmem.prepare_access = nv04_instmem_prepare_access; +- engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->instmem.flush = nv04_instmem_flush; + engine->mc.init = nv04_mc_init; + engine->mc.takedown = nv04_mc_takedown; + engine->timer.init = nv04_timer_init; +@@ -78,13 +79,22 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->fifo.disable = nv04_fifo_disable; + engine->fifo.enable = nv04_fifo_enable; + engine->fifo.reassign = nv04_fifo_reassign; +- engine->fifo.cache_flush = nv04_fifo_cache_flush; + engine->fifo.cache_pull = nv04_fifo_cache_pull; + engine->fifo.channel_id = nv04_fifo_channel_id; + engine->fifo.create_context = nv04_fifo_create_context; + engine->fifo.destroy_context = nv04_fifo_destroy_context; + engine->fifo.load_context = nv04_fifo_load_context; + engine->fifo.unload_context = nv04_fifo_unload_context; ++ engine->display.early_init = nv04_display_early_init; ++ engine->display.late_takedown = nv04_display_late_takedown; ++ engine->display.create = nv04_display_create; ++ engine->display.init = nv04_display_init; ++ engine->display.destroy = nv04_display_destroy; ++ engine->gpio.init = nouveau_stub_init; ++ engine->gpio.takedown = nouveau_stub_takedown; ++ engine->gpio.get = NULL; ++ engine->gpio.set = NULL; ++ engine->gpio.irq_enable = NULL; + break; + case 0x10: + engine->instmem.init = nv04_instmem_init; +@@ -95,8 +105,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->instmem.clear = nv04_instmem_clear; + engine->instmem.bind = nv04_instmem_bind; + engine->instmem.unbind = nv04_instmem_unbind; +- engine->instmem.prepare_access = nv04_instmem_prepare_access; +- engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->instmem.flush = nv04_instmem_flush; + engine->mc.init = nv04_mc_init; + engine->mc.takedown = nv04_mc_takedown; + engine->timer.init = nv04_timer_init; +@@ -121,13 +130,22 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->fifo.disable = nv04_fifo_disable; + engine->fifo.enable = nv04_fifo_enable; + engine->fifo.reassign = nv04_fifo_reassign; +- engine->fifo.cache_flush = nv04_fifo_cache_flush; + engine->fifo.cache_pull = nv04_fifo_cache_pull; + engine->fifo.channel_id = nv10_fifo_channel_id; + engine->fifo.create_context = nv10_fifo_create_context; + engine->fifo.destroy_context = nv10_fifo_destroy_context; + engine->fifo.load_context = nv10_fifo_load_context; + engine->fifo.unload_context = nv10_fifo_unload_context; ++ engine->display.early_init = nv04_display_early_init; ++ engine->display.late_takedown = nv04_display_late_takedown; ++ engine->display.create = nv04_display_create; ++ engine->display.init = nv04_display_init; ++ engine->display.destroy = nv04_display_destroy; ++ engine->gpio.init = nouveau_stub_init; ++ engine->gpio.takedown = nouveau_stub_takedown; ++ engine->gpio.get = nv10_gpio_get; ++ engine->gpio.set = nv10_gpio_set; ++ engine->gpio.irq_enable = NULL; + break; + case 0x20: + engine->instmem.init = nv04_instmem_init; +@@ -138,8 +156,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->instmem.clear = nv04_instmem_clear; + engine->instmem.bind = nv04_instmem_bind; + engine->instmem.unbind = nv04_instmem_unbind; +- engine->instmem.prepare_access = nv04_instmem_prepare_access; +- engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->instmem.flush = nv04_instmem_flush; + engine->mc.init = nv04_mc_init; + engine->mc.takedown = nv04_mc_takedown; + engine->timer.init = nv04_timer_init; +@@ -164,13 +181,22 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->fifo.disable = nv04_fifo_disable; + engine->fifo.enable = nv04_fifo_enable; + engine->fifo.reassign = nv04_fifo_reassign; +- engine->fifo.cache_flush = nv04_fifo_cache_flush; + engine->fifo.cache_pull = nv04_fifo_cache_pull; + engine->fifo.channel_id = nv10_fifo_channel_id; + engine->fifo.create_context = nv10_fifo_create_context; + engine->fifo.destroy_context = nv10_fifo_destroy_context; + engine->fifo.load_context = nv10_fifo_load_context; + engine->fifo.unload_context = nv10_fifo_unload_context; ++ engine->display.early_init = nv04_display_early_init; ++ engine->display.late_takedown = nv04_display_late_takedown; ++ engine->display.create = nv04_display_create; ++ engine->display.init = nv04_display_init; ++ engine->display.destroy = nv04_display_destroy; ++ engine->gpio.init = nouveau_stub_init; ++ engine->gpio.takedown = nouveau_stub_takedown; ++ engine->gpio.get = nv10_gpio_get; ++ engine->gpio.set = nv10_gpio_set; ++ engine->gpio.irq_enable = NULL; + break; + case 0x30: + engine->instmem.init = nv04_instmem_init; +@@ -181,15 +207,14 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->instmem.clear = nv04_instmem_clear; + engine->instmem.bind = nv04_instmem_bind; + engine->instmem.unbind = nv04_instmem_unbind; +- engine->instmem.prepare_access = nv04_instmem_prepare_access; +- engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->instmem.flush = nv04_instmem_flush; + engine->mc.init = nv04_mc_init; + engine->mc.takedown = nv04_mc_takedown; + engine->timer.init = nv04_timer_init; + engine->timer.read = nv04_timer_read; + engine->timer.takedown = nv04_timer_takedown; +- engine->fb.init = nv10_fb_init; +- engine->fb.takedown = nv10_fb_takedown; ++ engine->fb.init = nv30_fb_init; ++ engine->fb.takedown = nv30_fb_takedown; + engine->fb.set_region_tiling = nv10_fb_set_region_tiling; + engine->graph.grclass = nv30_graph_grclass; + engine->graph.init = nv30_graph_init; +@@ -207,13 +232,22 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->fifo.disable = nv04_fifo_disable; + engine->fifo.enable = nv04_fifo_enable; + engine->fifo.reassign = nv04_fifo_reassign; +- engine->fifo.cache_flush = nv04_fifo_cache_flush; + engine->fifo.cache_pull = nv04_fifo_cache_pull; + engine->fifo.channel_id = nv10_fifo_channel_id; + engine->fifo.create_context = nv10_fifo_create_context; + engine->fifo.destroy_context = nv10_fifo_destroy_context; + engine->fifo.load_context = nv10_fifo_load_context; + engine->fifo.unload_context = nv10_fifo_unload_context; ++ engine->display.early_init = nv04_display_early_init; ++ engine->display.late_takedown = nv04_display_late_takedown; ++ engine->display.create = nv04_display_create; ++ engine->display.init = nv04_display_init; ++ engine->display.destroy = nv04_display_destroy; ++ engine->gpio.init = nouveau_stub_init; ++ engine->gpio.takedown = nouveau_stub_takedown; ++ engine->gpio.get = nv10_gpio_get; ++ engine->gpio.set = nv10_gpio_set; ++ engine->gpio.irq_enable = NULL; + break; + case 0x40: + case 0x60: +@@ -225,8 +259,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->instmem.clear = nv04_instmem_clear; + engine->instmem.bind = nv04_instmem_bind; + engine->instmem.unbind = nv04_instmem_unbind; +- engine->instmem.prepare_access = nv04_instmem_prepare_access; +- engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->instmem.flush = nv04_instmem_flush; + engine->mc.init = nv40_mc_init; + engine->mc.takedown = nv40_mc_takedown; + engine->timer.init = nv04_timer_init; +@@ -251,13 +284,22 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->fifo.disable = nv04_fifo_disable; + engine->fifo.enable = nv04_fifo_enable; + engine->fifo.reassign = nv04_fifo_reassign; +- engine->fifo.cache_flush = nv04_fifo_cache_flush; + engine->fifo.cache_pull = nv04_fifo_cache_pull; + engine->fifo.channel_id = nv10_fifo_channel_id; + engine->fifo.create_context = nv40_fifo_create_context; + engine->fifo.destroy_context = nv40_fifo_destroy_context; + engine->fifo.load_context = nv40_fifo_load_context; + engine->fifo.unload_context = nv40_fifo_unload_context; ++ engine->display.early_init = nv04_display_early_init; ++ engine->display.late_takedown = nv04_display_late_takedown; ++ engine->display.create = nv04_display_create; ++ engine->display.init = nv04_display_init; ++ engine->display.destroy = nv04_display_destroy; ++ engine->gpio.init = nouveau_stub_init; ++ engine->gpio.takedown = nouveau_stub_takedown; ++ engine->gpio.get = nv10_gpio_get; ++ engine->gpio.set = nv10_gpio_set; ++ engine->gpio.irq_enable = NULL; + break; + case 0x50: + case 0x80: /* gotta love NVIDIA's consistency.. */ +@@ -271,8 +313,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->instmem.clear = nv50_instmem_clear; + engine->instmem.bind = nv50_instmem_bind; + engine->instmem.unbind = nv50_instmem_unbind; +- engine->instmem.prepare_access = nv50_instmem_prepare_access; +- engine->instmem.finish_access = nv50_instmem_finish_access; ++ if (dev_priv->chipset == 0x50) ++ engine->instmem.flush = nv50_instmem_flush; ++ else ++ engine->instmem.flush = nv84_instmem_flush; + engine->mc.init = nv50_mc_init; + engine->mc.takedown = nv50_mc_takedown; + engine->timer.init = nv04_timer_init; +@@ -300,6 +344,64 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->fifo.destroy_context = nv50_fifo_destroy_context; + engine->fifo.load_context = nv50_fifo_load_context; + engine->fifo.unload_context = nv50_fifo_unload_context; ++ engine->display.early_init = nv50_display_early_init; ++ engine->display.late_takedown = nv50_display_late_takedown; ++ engine->display.create = nv50_display_create; ++ engine->display.init = nv50_display_init; ++ engine->display.destroy = nv50_display_destroy; ++ engine->gpio.init = nv50_gpio_init; ++ engine->gpio.takedown = nouveau_stub_takedown; ++ engine->gpio.get = nv50_gpio_get; ++ engine->gpio.set = nv50_gpio_set; ++ engine->gpio.irq_enable = nv50_gpio_irq_enable; ++ break; ++ case 0xC0: ++ engine->instmem.init = nvc0_instmem_init; ++ engine->instmem.takedown = nvc0_instmem_takedown; ++ engine->instmem.suspend = nvc0_instmem_suspend; ++ engine->instmem.resume = nvc0_instmem_resume; ++ engine->instmem.populate = nvc0_instmem_populate; ++ engine->instmem.clear = nvc0_instmem_clear; ++ engine->instmem.bind = nvc0_instmem_bind; ++ engine->instmem.unbind = nvc0_instmem_unbind; ++ engine->instmem.flush = nvc0_instmem_flush; ++ engine->mc.init = nv50_mc_init; ++ engine->mc.takedown = nv50_mc_takedown; ++ engine->timer.init = nv04_timer_init; ++ engine->timer.read = nv04_timer_read; ++ engine->timer.takedown = nv04_timer_takedown; ++ engine->fb.init = nvc0_fb_init; ++ engine->fb.takedown = nvc0_fb_takedown; ++ engine->graph.grclass = NULL; //nvc0_graph_grclass; ++ engine->graph.init = nvc0_graph_init; ++ engine->graph.takedown = nvc0_graph_takedown; ++ engine->graph.fifo_access = nvc0_graph_fifo_access; ++ engine->graph.channel = nvc0_graph_channel; ++ engine->graph.create_context = nvc0_graph_create_context; ++ engine->graph.destroy_context = nvc0_graph_destroy_context; ++ engine->graph.load_context = nvc0_graph_load_context; ++ engine->graph.unload_context = nvc0_graph_unload_context; ++ engine->fifo.channels = 128; ++ engine->fifo.init = nvc0_fifo_init; ++ engine->fifo.takedown = nvc0_fifo_takedown; ++ engine->fifo.disable = nvc0_fifo_disable; ++ engine->fifo.enable = nvc0_fifo_enable; ++ engine->fifo.reassign = nvc0_fifo_reassign; ++ engine->fifo.channel_id = nvc0_fifo_channel_id; ++ engine->fifo.create_context = nvc0_fifo_create_context; ++ engine->fifo.destroy_context = nvc0_fifo_destroy_context; ++ engine->fifo.load_context = nvc0_fifo_load_context; ++ engine->fifo.unload_context = nvc0_fifo_unload_context; ++ engine->display.early_init = nv50_display_early_init; ++ engine->display.late_takedown = nv50_display_late_takedown; ++ engine->display.create = nv50_display_create; ++ engine->display.init = nv50_display_init; ++ engine->display.destroy = nv50_display_destroy; ++ engine->gpio.init = nv50_gpio_init; ++ engine->gpio.takedown = nouveau_stub_takedown; ++ engine->gpio.get = nv50_gpio_get; ++ engine->gpio.set = nv50_gpio_set; ++ engine->gpio.irq_enable = nv50_gpio_irq_enable; + break; + default: + NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); +@@ -331,16 +433,14 @@ static int + nouveau_card_init_channel(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_gpuobj *gpuobj; ++ struct nouveau_gpuobj *gpuobj = NULL; + int ret; + + ret = nouveau_channel_alloc(dev, &dev_priv->channel, +- (struct drm_file *)-2, +- NvDmaFB, NvDmaTT); ++ (struct drm_file *)-2, NvDmaFB, NvDmaTT); + if (ret) + return ret; + +- gpuobj = NULL; + ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, + 0, dev_priv->vram_size, + NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, +@@ -348,26 +448,25 @@ nouveau_card_init_channel(struct drm_device *dev) + if (ret) + goto out_err; + +- ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM, +- gpuobj, NULL); ++ ret = nouveau_ramht_insert(dev_priv->channel, NvDmaVRAM, gpuobj); ++ nouveau_gpuobj_ref(NULL, &gpuobj); + if (ret) + goto out_err; + +- gpuobj = NULL; + ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0, + dev_priv->gart_info.aper_size, + NV_DMA_ACCESS_RW, &gpuobj, NULL); + if (ret) + goto out_err; + +- ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART, +- gpuobj, NULL); ++ ret = nouveau_ramht_insert(dev_priv->channel, NvDmaGART, gpuobj); ++ nouveau_gpuobj_ref(NULL, &gpuobj); + if (ret) + goto out_err; + + return 0; ++ + out_err: +- nouveau_gpuobj_del(dev, &gpuobj); + nouveau_channel_free(dev_priv->channel); + dev_priv->channel = NULL; + return ret; +@@ -407,11 +506,6 @@ nouveau_card_init(struct drm_device *dev) + struct nouveau_engine *engine; + int ret; + +- NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); +- +- if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE) +- return 0; +- + vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); + vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, + nouveau_switcheroo_can_switch); +@@ -421,50 +515,48 @@ nouveau_card_init(struct drm_device *dev) + if (ret) + goto out; + engine = &dev_priv->engine; +- dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; + spin_lock_init(&dev_priv->context_switch_lock); + ++ /* Make the CRTCs and I2C buses accessible */ ++ ret = engine->display.early_init(dev); ++ if (ret) ++ goto out; ++ + /* Parse BIOS tables / Run init tables if card not POSTed */ +- if (drm_core_check_feature(dev, DRIVER_MODESET)) { +- ret = nouveau_bios_init(dev); +- if (ret) +- goto out; +- } ++ ret = nouveau_bios_init(dev); ++ if (ret) ++ goto out_display_early; + +- ret = nouveau_mem_detect(dev); ++ ret = nouveau_mem_vram_init(dev); + if (ret) + goto out_bios; + +- ret = nouveau_gpuobj_early_init(dev); ++ ret = nouveau_gpuobj_init(dev); + if (ret) +- goto out_bios; ++ goto out_vram; + +- /* Initialise instance memory, must happen before mem_init so we +- * know exactly how much VRAM we're able to use for "normal" +- * purposes. +- */ + ret = engine->instmem.init(dev); + if (ret) +- goto out_gpuobj_early; ++ goto out_gpuobj; + +- /* Setup the memory manager */ +- ret = nouveau_mem_init(dev); ++ ret = nouveau_mem_gart_init(dev); + if (ret) + goto out_instmem; + +- ret = nouveau_gpuobj_init(dev); +- if (ret) +- goto out_mem; +- + /* PMC */ + ret = engine->mc.init(dev); + if (ret) +- goto out_gpuobj; ++ goto out_gart; ++ ++ /* PGPIO */ ++ ret = engine->gpio.init(dev); ++ if (ret) ++ goto out_mc; + + /* PTIMER */ + ret = engine->timer.init(dev); + if (ret) +- goto out_mc; ++ goto out_gpio; + + /* PFB */ + ret = engine->fb.init(dev); +@@ -485,12 +577,16 @@ nouveau_card_init(struct drm_device *dev) + goto out_graph; + } + ++ ret = engine->display.create(dev); ++ if (ret) ++ goto out_fifo; ++ + /* this call irq_preinstall, register irq handler and + * call irq_postinstall + */ + ret = drm_irq_install(dev); + if (ret) +- goto out_fifo; ++ goto out_display; + + ret = drm_vblank_init(dev, 0); + if (ret) +@@ -504,35 +600,18 @@ nouveau_card_init(struct drm_device *dev) + goto out_irq; + } + +- if (drm_core_check_feature(dev, DRIVER_MODESET)) { +- if (dev_priv->card_type >= NV_50) +- ret = nv50_display_create(dev); +- else +- ret = nv04_display_create(dev); +- if (ret) +- goto out_channel; +- } +- + ret = nouveau_backlight_init(dev); + if (ret) + NV_ERROR(dev, "Error %d registering backlight\n", ret); + +- dev_priv->init_state = NOUVEAU_CARD_INIT_DONE; +- +- if (drm_core_check_feature(dev, DRIVER_MODESET)) { +- nouveau_fbcon_init(dev); +- drm_kms_helper_poll_init(dev); +- } +- ++ nouveau_fbcon_init(dev); ++ drm_kms_helper_poll_init(dev); + return 0; + +-out_channel: +- if (dev_priv->channel) { +- nouveau_channel_free(dev_priv->channel); +- dev_priv->channel = NULL; +- } + out_irq: + drm_irq_uninstall(dev); ++out_display: ++ engine->display.destroy(dev); + out_fifo: + if (!nouveau_noaccel) + engine->fifo.takedown(dev); +@@ -543,19 +622,22 @@ out_fb: + engine->fb.takedown(dev); + out_timer: + engine->timer.takedown(dev); ++out_gpio: ++ engine->gpio.takedown(dev); + out_mc: + engine->mc.takedown(dev); +-out_gpuobj: +- nouveau_gpuobj_takedown(dev); +-out_mem: +- nouveau_sgdma_takedown(dev); +- nouveau_mem_close(dev); ++out_gart: ++ nouveau_mem_gart_fini(dev); + out_instmem: + engine->instmem.takedown(dev); +-out_gpuobj_early: +- nouveau_gpuobj_late_takedown(dev); ++out_gpuobj: ++ nouveau_gpuobj_takedown(dev); ++out_vram: ++ nouveau_mem_vram_fini(dev); + out_bios: + nouveau_bios_takedown(dev); ++out_display_early: ++ engine->display.late_takedown(dev); + out: + vga_client_register(dev->pdev, NULL, NULL, NULL); + return ret; +@@ -566,45 +648,38 @@ static void nouveau_card_takedown(struct drm_device *dev) + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->engine; + +- NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); +- +- if (dev_priv->init_state != NOUVEAU_CARD_INIT_DOWN) { ++ nouveau_backlight_exit(dev); + +- nouveau_backlight_exit(dev); +- +- if (dev_priv->channel) { +- nouveau_channel_free(dev_priv->channel); +- dev_priv->channel = NULL; +- } +- +- if (!nouveau_noaccel) { +- engine->fifo.takedown(dev); +- engine->graph.takedown(dev); +- } +- engine->fb.takedown(dev); +- engine->timer.takedown(dev); +- engine->mc.takedown(dev); ++ if (dev_priv->channel) { ++ nouveau_channel_free(dev_priv->channel); ++ dev_priv->channel = NULL; ++ } + +- mutex_lock(&dev->struct_mutex); +- ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); +- ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); +- mutex_unlock(&dev->struct_mutex); +- nouveau_sgdma_takedown(dev); ++ if (!nouveau_noaccel) { ++ engine->fifo.takedown(dev); ++ engine->graph.takedown(dev); ++ } ++ engine->fb.takedown(dev); ++ engine->timer.takedown(dev); ++ engine->gpio.takedown(dev); ++ engine->mc.takedown(dev); ++ engine->display.late_takedown(dev); + +- nouveau_gpuobj_takedown(dev); +- nouveau_mem_close(dev); +- engine->instmem.takedown(dev); ++ mutex_lock(&dev->struct_mutex); ++ ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); ++ ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); ++ mutex_unlock(&dev->struct_mutex); ++ nouveau_mem_gart_fini(dev); + +- if (drm_core_check_feature(dev, DRIVER_MODESET)) +- drm_irq_uninstall(dev); ++ engine->instmem.takedown(dev); ++ nouveau_gpuobj_takedown(dev); ++ nouveau_mem_vram_fini(dev); + +- nouveau_gpuobj_late_takedown(dev); +- nouveau_bios_takedown(dev); ++ drm_irq_uninstall(dev); + +- vga_client_register(dev->pdev, NULL, NULL, NULL); ++ nouveau_bios_takedown(dev); + +- dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN; +- } ++ vga_client_register(dev->pdev, NULL, NULL, NULL); + } + + /* here a client dies, release the stuff that was allocated for its +@@ -691,22 +766,26 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) + struct drm_nouveau_private *dev_priv; + uint32_t reg0; + resource_size_t mmio_start_offs; ++ int ret; + + dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); +- if (!dev_priv) +- return -ENOMEM; ++ if (!dev_priv) { ++ ret = -ENOMEM; ++ goto err_out; ++ } + dev->dev_private = dev_priv; + dev_priv->dev = dev; + + dev_priv->flags = flags & NOUVEAU_FLAGS; +- dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN; + + NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", + dev->pci_vendor, dev->pci_device, dev->pdev->class); + + dev_priv->wq = create_workqueue("nouveau"); +- if (!dev_priv->wq) +- return -EINVAL; ++ if (!dev_priv->wq) { ++ ret = -EINVAL; ++ goto err_priv; ++ } + + /* resource 0 is mmio regs */ + /* resource 1 is linear FB */ +@@ -719,7 +798,8 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) + if (!dev_priv->mmio) { + NV_ERROR(dev, "Unable to initialize the mmio mapping. " + "Please report your setup to " DRIVER_EMAIL "\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_wq; + } + NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", + (unsigned long long)mmio_start_offs); +@@ -765,19 +845,21 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) + case 0xa0: + dev_priv->card_type = NV_50; + break; ++ case 0xc0: ++ dev_priv->card_type = NV_C0; ++ break; + default: + NV_INFO(dev, "Unsupported chipset 0x%08x\n", reg0); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_mmio; + } + + NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n", + dev_priv->card_type, reg0); + +- if (drm_core_check_feature(dev, DRIVER_MODESET)) { +- int ret = nouveau_remove_conflicting_drivers(dev); +- if (ret) +- return ret; +- } ++ ret = nouveau_remove_conflicting_drivers(dev); ++ if (ret) ++ goto err_mmio; + + /* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */ + if (dev_priv->card_type >= NV_40) { +@@ -791,7 +873,8 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) + dev_priv->ramin_size); + if (!dev_priv->ramin) { + NV_ERROR(dev, "Failed to PRAMIN BAR"); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto err_mmio; + } + } else { + dev_priv->ramin_size = 1 * 1024 * 1024; +@@ -799,7 +882,8 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) + dev_priv->ramin_size); + if (!dev_priv->ramin) { + NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n"); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto err_mmio; + } + } + +@@ -812,46 +896,38 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) + dev_priv->flags |= NV_NFORCE2; + + /* For kernel modesetting, init card now and bring up fbcon */ +- if (drm_core_check_feature(dev, DRIVER_MODESET)) { +- int ret = nouveau_card_init(dev); +- if (ret) +- return ret; +- } ++ ret = nouveau_card_init(dev); ++ if (ret) ++ goto err_ramin; + + return 0; +-} +- +-static void nouveau_close(struct drm_device *dev) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; + +- /* In the case of an error dev_priv may not be allocated yet */ +- if (dev_priv) +- nouveau_card_takedown(dev); ++err_ramin: ++ iounmap(dev_priv->ramin); ++err_mmio: ++ iounmap(dev_priv->mmio); ++err_wq: ++ destroy_workqueue(dev_priv->wq); ++err_priv: ++ kfree(dev_priv); ++ dev->dev_private = NULL; ++err_out: ++ return ret; + } + +-/* KMS: we need mmio at load time, not when the first drm client opens. */ + void nouveau_lastclose(struct drm_device *dev) + { +- if (drm_core_check_feature(dev, DRIVER_MODESET)) +- return; +- +- nouveau_close(dev); + } + + int nouveau_unload(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; + +- if (drm_core_check_feature(dev, DRIVER_MODESET)) { +- drm_kms_helper_poll_fini(dev); +- nouveau_fbcon_fini(dev); +- if (dev_priv->card_type >= NV_50) +- nv50_display_destroy(dev); +- else +- nv04_display_destroy(dev); +- nouveau_close(dev); +- } ++ drm_kms_helper_poll_fini(dev); ++ nouveau_fbcon_fini(dev); ++ engine->display.destroy(dev); ++ nouveau_card_takedown(dev); + + iounmap(dev_priv->mmio); + iounmap(dev_priv->ramin); +@@ -867,8 +943,6 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_getparam *getparam = data; + +- NOUVEAU_CHECK_INITIALISED_WITH_RETURN; +- + switch (getparam->param) { + case NOUVEAU_GETPARAM_CHIPSET_ID: + getparam->value = dev_priv->chipset; +@@ -937,8 +1011,6 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data, + { + struct drm_nouveau_setparam *setparam = data; + +- NOUVEAU_CHECK_INITIALISED_WITH_RETURN; +- + switch (setparam->param) { + default: + NV_ERROR(dev, "unknown parameter %lld\n", setparam->param); +@@ -967,7 +1039,7 @@ bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout, + /* Waits for PGRAPH to go completely idle */ + bool nouveau_wait_for_idle(struct drm_device *dev) + { +- if (!nv_wait(NV04_PGRAPH_STATUS, 0xffffffff, 0x00000000)) { ++ if (!nv_wait(dev, NV04_PGRAPH_STATUS, 0xffffffff, 0x00000000)) { + NV_ERROR(dev, "PGRAPH idle timed out with status 0x%08x\n", + nv_rd32(dev, NV04_PGRAPH_STATUS)); + return false; +diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c +index eba687f..291a4cb 100644 +--- a/drivers/gpu/drm/nouveau/nv04_crtc.c ++++ b/drivers/gpu/drm/nouveau/nv04_crtc.c +@@ -157,6 +157,7 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) + { + struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); + struct drm_device *dev = crtc->dev; ++ struct drm_connector *connector; + unsigned char seq1 = 0, crtc17 = 0; + unsigned char crtc1A; + +@@ -211,6 +212,10 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) + NVVgaSeqReset(dev, nv_crtc->index, false); + + NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A); ++ ++ /* Update connector polling modes */ ++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) ++ nouveau_connector_set_polling(connector); + } + + static bool +@@ -537,6 +542,9 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode) + * 1 << 30 on 0x60.830), for no apparent reason */ + regp->CRTC[NV_CIO_CRE_59] = off_chip_digital; + ++ if (dev_priv->card_type >= NV_30) ++ regp->CRTC[0x9f] = off_chip_digital ? 0x11 : 0x1; ++ + regp->crtc_830 = mode->crtc_vdisplay - 3; + regp->crtc_834 = mode->crtc_vdisplay - 1; + +@@ -710,6 +718,7 @@ static void nv_crtc_destroy(struct drm_crtc *crtc) + + drm_crtc_cleanup(crtc); + ++ nouveau_bo_unmap(nv_crtc->cursor.nvbo); + nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); + kfree(nv_crtc); + } +@@ -820,7 +829,7 @@ nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, + crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_FF_INDEX); + crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_FFLWM__INDEX); + +- if (dev_priv->card_type >= NV_30) { ++ if (dev_priv->card_type >= NV_20) { + regp->CRTC[NV_CIO_CRE_47] = arb_lwm >> 8; + crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_47); + } +diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c +index 1cb19e3..ba6423f 100644 +--- a/drivers/gpu/drm/nouveau/nv04_dac.c ++++ b/drivers/gpu/drm/nouveau/nv04_dac.c +@@ -220,6 +220,7 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) + { + struct drm_device *dev = encoder->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio; + struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; + uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder); + uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, +@@ -251,22 +252,21 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) + nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf); + } + +- saved_gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1); +- saved_gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0); ++ saved_gpio1 = gpio->get(dev, DCB_GPIO_TVDAC1); ++ saved_gpio0 = gpio->get(dev, DCB_GPIO_TVDAC0); + +- nv17_gpio_set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV); +- nv17_gpio_set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV); ++ gpio->set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV); ++ gpio->set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV); + + msleep(4); + + saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); + head = (saved_routput & 0x100) >> 8; +-#if 0 +- /* if there's a spare crtc, using it will minimise flicker for the case +- * where the in-use crtc is in use by an off-chip tmds encoder */ +- if (xf86_config->crtc[head]->enabled && !xf86_config->crtc[head ^ 1]->enabled) ++ ++ /* if there's a spare crtc, using it will minimise flicker */ ++ if (!(NVReadVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX) & 0xC0)) + head ^= 1; +-#endif ++ + /* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */ + routput = (saved_routput & 0xfffffece) | head << 8; + +@@ -291,6 +291,8 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) + msleep(5); + + sample = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); ++ /* do it again just in case it's a residual current */ ++ sample &= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); + + temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL); + NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL, +@@ -304,8 +306,8 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) + nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4); + nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2); + +- nv17_gpio_set(dev, DCB_GPIO_TVDAC1, saved_gpio1); +- nv17_gpio_set(dev, DCB_GPIO_TVDAC0, saved_gpio0); ++ gpio->set(dev, DCB_GPIO_TVDAC1, saved_gpio1); ++ gpio->set(dev, DCB_GPIO_TVDAC0, saved_gpio0); + + return sample; + } +@@ -315,9 +317,12 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) + { + struct drm_device *dev = encoder->dev; + struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; +- uint32_t sample = nv17_dac_sample_load(encoder); + +- if (sample & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { ++ if (nv04_dac_in_use(encoder)) ++ return connector_status_disconnected; ++ ++ if (nv17_dac_sample_load(encoder) & ++ NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { + NV_INFO(dev, "Load detected on output %c\n", + '@' + ffs(dcb->or)); + return connector_status_connected; +@@ -330,6 +335,9 @@ static bool nv04_dac_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) + { ++ if (nv04_dac_in_use(encoder)) ++ return false; ++ + return true; + } + +@@ -337,22 +345,13 @@ static void nv04_dac_prepare(struct drm_encoder *encoder) + { + struct drm_encoder_helper_funcs *helper = encoder->helper_private; + struct drm_device *dev = encoder->dev; +- struct drm_nouveau_private *dev_priv = dev->dev_private; + int head = nouveau_crtc(encoder->crtc)->index; +- struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg; + + helper->dpms(encoder, DRM_MODE_DPMS_OFF); + + nv04_dfp_disable(dev, head); +- +- /* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f) +- * at LCD__INDEX which we don't alter +- */ +- if (!(crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX] & 0x44)) +- crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX] = 0; + } + +- + static void nv04_dac_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +@@ -428,6 +427,17 @@ void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable) + } + } + ++/* Check if the DAC corresponding to 'encoder' is being used by ++ * someone else. */ ++bool nv04_dac_in_use(struct drm_encoder *encoder) ++{ ++ struct drm_nouveau_private *dev_priv = encoder->dev->dev_private; ++ struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; ++ ++ return nv_gf4_disp_arch(encoder->dev) && ++ (dev_priv->dac_users[ffs(dcb->or) - 1] & ~(1 << dcb->index)); ++} ++ + static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) + { + struct drm_device *dev = encoder->dev; +@@ -501,11 +511,13 @@ static const struct drm_encoder_funcs nv04_dac_funcs = { + .destroy = nv04_dac_destroy, + }; + +-int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry) ++int ++nv04_dac_create(struct drm_connector *connector, struct dcb_entry *entry) + { + const struct drm_encoder_helper_funcs *helper; +- struct drm_encoder *encoder; + struct nouveau_encoder *nv_encoder = NULL; ++ struct drm_device *dev = connector->dev; ++ struct drm_encoder *encoder; + + nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); + if (!nv_encoder) +@@ -527,5 +539,6 @@ int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry) + encoder->possible_crtcs = entry->heads; + encoder->possible_clones = 0; + ++ drm_mode_connector_attach_encoder(connector, encoder); + return 0; + } +diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c +index 41634d4..762d9f2 100644 +--- a/drivers/gpu/drm/nouveau/nv04_dfp.c ++++ b/drivers/gpu/drm/nouveau/nv04_dfp.c +@@ -34,6 +34,8 @@ + #include "nouveau_hw.h" + #include "nvreg.h" + ++#include "i2c/sil164.h" ++ + #define FP_TG_CONTROL_ON (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | \ + NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | \ + NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS) +@@ -102,6 +104,8 @@ void nv04_dfp_disable(struct drm_device *dev, int head) + } + /* don't inadvertently turn it on when state written later */ + crtcstate[head].fp_control = FP_TG_CONTROL_OFF; ++ crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX] &= ++ ~NV_CIO_CRE_LCD_ROUTE_MASK; + } + + void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode) +@@ -144,6 +148,36 @@ void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode) + } + } + ++static struct drm_encoder *get_tmds_slave(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; ++ struct drm_encoder *slave; ++ ++ if (dcb->type != OUTPUT_TMDS || dcb->location == DCB_LOC_ON_CHIP) ++ return NULL; ++ ++ /* Some BIOSes (e.g. the one in a Quadro FX1000) report several ++ * TMDS transmitters at the same I2C address, in the same I2C ++ * bus. This can still work because in that case one of them is ++ * always hard-wired to a reasonable configuration using straps, ++ * and the other one needs to be programmed. ++ * ++ * I don't think there's a way to know which is which, even the ++ * blob programs the one exposed via I2C for *both* heads, so ++ * let's do the same. ++ */ ++ list_for_each_entry(slave, &dev->mode_config.encoder_list, head) { ++ struct dcb_entry *slave_dcb = nouveau_encoder(slave)->dcb; ++ ++ if (slave_dcb->type == OUTPUT_TMDS && get_slave_funcs(slave) && ++ slave_dcb->tmdsconf.slave_addr == dcb->tmdsconf.slave_addr) ++ return slave; ++ } ++ ++ return NULL; ++} ++ + static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +@@ -221,26 +255,21 @@ static void nv04_dfp_prepare(struct drm_encoder *encoder) + + nv04_dfp_prepare_sel_clk(dev, nv_encoder, head); + +- /* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f) +- * at LCD__INDEX which we don't alter +- */ +- if (!(*cr_lcd & 0x44)) { +- *cr_lcd = 0x3; +- +- if (nv_two_heads(dev)) { +- if (nv_encoder->dcb->location == DCB_LOC_ON_CHIP) +- *cr_lcd |= head ? 0x0 : 0x8; +- else { +- *cr_lcd |= (nv_encoder->dcb->or << 4) & 0x30; +- if (nv_encoder->dcb->type == OUTPUT_LVDS) +- *cr_lcd |= 0x30; +- if ((*cr_lcd & 0x30) == (*cr_lcd_oth & 0x30)) { +- /* avoid being connected to both crtcs */ +- *cr_lcd_oth &= ~0x30; +- NVWriteVgaCrtc(dev, head ^ 1, +- NV_CIO_CRE_LCD__INDEX, +- *cr_lcd_oth); +- } ++ *cr_lcd = (*cr_lcd & ~NV_CIO_CRE_LCD_ROUTE_MASK) | 0x3; ++ ++ if (nv_two_heads(dev)) { ++ if (nv_encoder->dcb->location == DCB_LOC_ON_CHIP) ++ *cr_lcd |= head ? 0x0 : 0x8; ++ else { ++ *cr_lcd |= (nv_encoder->dcb->or << 4) & 0x30; ++ if (nv_encoder->dcb->type == OUTPUT_LVDS) ++ *cr_lcd |= 0x30; ++ if ((*cr_lcd & 0x30) == (*cr_lcd_oth & 0x30)) { ++ /* avoid being connected to both crtcs */ ++ *cr_lcd_oth &= ~0x30; ++ NVWriteVgaCrtc(dev, head ^ 1, ++ NV_CIO_CRE_LCD__INDEX, ++ *cr_lcd_oth); + } + } + } +@@ -412,10 +441,7 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + struct dcb_entry *dcbe = nv_encoder->dcb; + int head = nouveau_crtc(encoder->crtc)->index; +- +- NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", +- drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), +- nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); ++ struct drm_encoder *slave_encoder; + + if (dcbe->type == OUTPUT_TMDS) + run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); +@@ -433,6 +459,12 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) + else + NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); + ++ /* Init external transmitters */ ++ slave_encoder = get_tmds_slave(encoder); ++ if (slave_encoder) ++ get_slave_funcs(slave_encoder)->mode_set( ++ slave_encoder, &nv_encoder->mode, &nv_encoder->mode); ++ + helper->dpms(encoder, DRM_MODE_DPMS_ON); + + NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", +@@ -440,6 +472,27 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) + nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); + } + ++static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) ++{ ++#ifdef __powerpc__ ++ struct drm_device *dev = encoder->dev; ++ ++ /* BIOS scripts usually take care of the backlight, thanks ++ * Apple for your consistency. ++ */ ++ if (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || ++ dev->pci_device == 0x0329) { ++ if (mode == DRM_MODE_DPMS_ON) { ++ nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 0, 1 << 31); ++ nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 1); ++ } else { ++ nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 1 << 31, 0); ++ nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 0); ++ } ++ } ++#endif ++} ++ + static inline bool is_powersaving_dpms(int mode) + { + return (mode != DRM_MODE_DPMS_ON); +@@ -487,6 +540,7 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) + LVDS_PANEL_OFF, 0); + } + ++ nv04_dfp_update_backlight(encoder, mode); + nv04_dfp_update_fp_control(encoder, mode); + + if (mode == DRM_MODE_DPMS_ON) +@@ -510,6 +564,7 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) + NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", + mode, nv_encoder->dcb->index); + ++ nv04_dfp_update_backlight(encoder, mode); + nv04_dfp_update_fp_control(encoder, mode); + } + +@@ -554,10 +609,42 @@ static void nv04_dfp_destroy(struct drm_encoder *encoder) + + NV_DEBUG_KMS(encoder->dev, "\n"); + ++ if (get_slave_funcs(encoder)) ++ get_slave_funcs(encoder)->destroy(encoder); ++ + drm_encoder_cleanup(encoder); + kfree(nv_encoder); + } + ++static void nv04_tmds_slave_init(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; ++ struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, 2); ++ struct i2c_board_info info[] = { ++ { ++ .type = "sil164", ++ .addr = (dcb->tmdsconf.slave_addr == 0x7 ? 0x3a : 0x38), ++ .platform_data = &(struct sil164_encoder_params) { ++ SIL164_INPUT_EDGE_RISING ++ } ++ }, ++ { } ++ }; ++ int type; ++ ++ if (!nv_gf4_disp_arch(dev) || !i2c || ++ get_tmds_slave(encoder)) ++ return; ++ ++ type = nouveau_i2c_identify(dev, "TMDS transmitter", info, 2); ++ if (type < 0) ++ return; ++ ++ drm_i2c_encoder_init(dev, to_encoder_slave(encoder), ++ &i2c->adapter, &info[type]); ++} ++ + static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = { + .dpms = nv04_lvds_dpms, + .save = nv04_dfp_save, +@@ -584,11 +671,12 @@ static const struct drm_encoder_funcs nv04_dfp_funcs = { + .destroy = nv04_dfp_destroy, + }; + +-int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry) ++int ++nv04_dfp_create(struct drm_connector *connector, struct dcb_entry *entry) + { + const struct drm_encoder_helper_funcs *helper; +- struct drm_encoder *encoder; + struct nouveau_encoder *nv_encoder = NULL; ++ struct drm_encoder *encoder; + int type; + + switch (entry->type) { +@@ -613,11 +701,16 @@ int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry) + nv_encoder->dcb = entry; + nv_encoder->or = ffs(entry->or) - 1; + +- drm_encoder_init(dev, encoder, &nv04_dfp_funcs, type); ++ drm_encoder_init(connector->dev, encoder, &nv04_dfp_funcs, type); + drm_encoder_helper_add(encoder, helper); + + encoder->possible_crtcs = entry->heads; + encoder->possible_clones = 0; + ++ if (entry->type == OUTPUT_TMDS && ++ entry->location != DCB_LOC_ON_CHIP) ++ nv04_tmds_slave_init(encoder); ++ ++ drm_mode_connector_attach_encoder(connector, encoder); + return 0; + } +diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c +index c7898b4..9e28cf7 100644 +--- a/drivers/gpu/drm/nouveau/nv04_display.c ++++ b/drivers/gpu/drm/nouveau/nv04_display.c +@@ -32,8 +32,6 @@ + #include "nouveau_encoder.h" + #include "nouveau_connector.h" + +-#define MULTIPLE_ENCODERS(e) (e & (e - 1)) +- + static void + nv04_display_store_initial_head_owner(struct drm_device *dev) + { +@@ -41,7 +39,7 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) + + if (dev_priv->chipset != 0x11) { + dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44); +- goto ownerknown; ++ return; + } + + /* reading CR44 is broken on nv11, so we attempt to infer it */ +@@ -52,8 +50,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) + bool tvA = false; + bool tvB = false; + +- NVLockVgaCrtcs(dev, false); +- + slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) & + 0x80; + if (slaved_on_B) +@@ -66,8 +62,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) + tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) & + MASK(NV_CIO_CRE_LCD_LCD_SELECT)); + +- NVLockVgaCrtcs(dev, true); +- + if (slaved_on_A && !tvA) + dev_priv->crtc_owner = 0x0; + else if (slaved_on_B && !tvB) +@@ -79,14 +73,40 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) + else + dev_priv->crtc_owner = 0x0; + } ++} ++ ++int ++nv04_display_early_init(struct drm_device *dev) ++{ ++ /* Make the I2C buses accessible. */ ++ if (!nv_gf4_disp_arch(dev)) { ++ uint32_t pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE); ++ ++ if (!(pmc_enable & 1)) ++ nv_wr32(dev, NV03_PMC_ENABLE, pmc_enable | 1); ++ } + +-ownerknown: +- NV_INFO(dev, "Initial CRTC_OWNER is %d\n", dev_priv->crtc_owner); ++ /* Unlock the VGA CRTCs. */ ++ NVLockVgaCrtcs(dev, false); ++ ++ /* Make sure the CRTCs aren't in slaved mode. */ ++ if (nv_two_heads(dev)) { ++ nv04_display_store_initial_head_owner(dev); ++ NVSetOwner(dev, 0); ++ } ++ ++ return 0; ++} ++ ++void ++nv04_display_late_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (nv_two_heads(dev)) ++ NVSetOwner(dev, dev_priv->crtc_owner); + +- /* we need to ensure the heads are not tied henceforth, or reading any +- * 8 bit reg on head B will fail +- * setting a single arbitrary head solves that */ +- NVSetOwner(dev, 0); ++ NVLockVgaCrtcs(dev, true); + } + + int +@@ -94,14 +114,13 @@ nv04_display_create(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct dcb_table *dcb = &dev_priv->vbios.dcb; ++ struct drm_connector *connector, *ct; + struct drm_encoder *encoder; + struct drm_crtc *crtc; + int i, ret; + + NV_DEBUG_KMS(dev, "\n"); + +- if (nv_two_heads(dev)) +- nv04_display_store_initial_head_owner(dev); + nouveau_hw_save_vga_fonts(dev, 1); + + drm_mode_config_init(dev); +@@ -132,19 +151,23 @@ nv04_display_create(struct drm_device *dev) + for (i = 0; i < dcb->entries; i++) { + struct dcb_entry *dcbent = &dcb->entry[i]; + ++ connector = nouveau_connector_create(dev, dcbent->connector); ++ if (IS_ERR(connector)) ++ continue; ++ + switch (dcbent->type) { + case OUTPUT_ANALOG: +- ret = nv04_dac_create(dev, dcbent); ++ ret = nv04_dac_create(connector, dcbent); + break; + case OUTPUT_LVDS: + case OUTPUT_TMDS: +- ret = nv04_dfp_create(dev, dcbent); ++ ret = nv04_dfp_create(connector, dcbent); + break; + case OUTPUT_TV: + if (dcbent->location == DCB_LOC_ON_CHIP) +- ret = nv17_tv_create(dev, dcbent); ++ ret = nv17_tv_create(connector, dcbent); + else +- ret = nv04_tv_create(dev, dcbent); ++ ret = nv04_tv_create(connector, dcbent); + break; + default: + NV_WARN(dev, "DCB type %d not known\n", dcbent->type); +@@ -155,12 +178,16 @@ nv04_display_create(struct drm_device *dev) + continue; + } + +- for (i = 0; i < dcb->connector.entries; i++) +- nouveau_connector_create(dev, &dcb->connector.entry[i]); ++ list_for_each_entry_safe(connector, ct, ++ &dev->mode_config.connector_list, head) { ++ if (!connector->encoder_ids[0]) { ++ NV_WARN(dev, "%s has no encoders, removing\n", ++ drm_get_connector_name(connector)); ++ connector->funcs->destroy(connector); ++ } ++ } + + /* Save previous state */ +- NVLockVgaCrtcs(dev, false); +- + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + crtc->funcs->save(crtc); + +@@ -191,8 +218,6 @@ nv04_display_destroy(struct drm_device *dev) + } + + /* Restore state */ +- NVLockVgaCrtcs(dev, false); +- + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + struct drm_encoder_helper_funcs *func = encoder->helper_private; + +@@ -207,15 +232,12 @@ nv04_display_destroy(struct drm_device *dev) + nouveau_hw_save_vga_fonts(dev, 0); + } + +-void +-nv04_display_restore(struct drm_device *dev) ++int ++nv04_display_init(struct drm_device *dev) + { +- struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_encoder *encoder; + struct drm_crtc *crtc; + +- NVLockVgaCrtcs(dev, false); +- + /* meh.. modeset apparently doesn't setup all the regs and depends + * on pre-existing state, for now load the state of the card *before* + * nouveau was loaded, and then do a modeset. +@@ -233,12 +255,6 @@ nv04_display_restore(struct drm_device *dev) + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + crtc->funcs->restore(crtc); + +- if (nv_two_heads(dev)) { +- NV_INFO(dev, "Restoring CRTC_OWNER to %d.\n", +- dev_priv->crtc_owner); +- NVSetOwner(dev, dev_priv->crtc_owner); +- } +- +- NVLockVgaCrtcs(dev, true); ++ return 0; + } + +diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c +index 1eeac4f..33e4c93 100644 +--- a/drivers/gpu/drm/nouveau/nv04_fbcon.c ++++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c +@@ -25,6 +25,7 @@ + #include "drmP.h" + #include "nouveau_drv.h" + #include "nouveau_dma.h" ++#include "nouveau_ramht.h" + #include "nouveau_fbcon.h" + + void +@@ -169,11 +170,9 @@ nv04_fbcon_grobj_new(struct drm_device *dev, int class, uint32_t handle) + if (ret) + return ret; + +- ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, handle, obj, NULL); +- if (ret) +- return ret; +- +- return 0; ++ ret = nouveau_ramht_insert(dev_priv->channel, handle, obj); ++ nouveau_gpuobj_ref(NULL, &obj); ++ return ret; + } + + int +diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c +index 66fe559..708293b 100644 +--- a/drivers/gpu/drm/nouveau/nv04_fifo.c ++++ b/drivers/gpu/drm/nouveau/nv04_fifo.c +@@ -27,8 +27,9 @@ + #include "drmP.h" + #include "drm.h" + #include "nouveau_drv.h" ++#include "nouveau_ramht.h" + +-#define NV04_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV04_RAMFC__SIZE)) ++#define NV04_RAMFC(c) (dev_priv->ramfc->pinst + ((c) * NV04_RAMFC__SIZE)) + #define NV04_RAMFC__SIZE 32 + #define NV04_RAMFC_DMA_PUT 0x00 + #define NV04_RAMFC_DMA_GET 0x04 +@@ -38,10 +39,8 @@ + #define NV04_RAMFC_ENGINE 0x14 + #define NV04_RAMFC_PULL1_ENGINE 0x18 + +-#define RAMFC_WR(offset, val) nv_wo32(dev, chan->ramfc->gpuobj, \ +- NV04_RAMFC_##offset/4, (val)) +-#define RAMFC_RD(offset) nv_ro32(dev, chan->ramfc->gpuobj, \ +- NV04_RAMFC_##offset/4) ++#define RAMFC_WR(offset, val) nv_wo32(chan->ramfc, NV04_RAMFC_##offset, (val)) ++#define RAMFC_RD(offset) nv_ro32(chan->ramfc, NV04_RAMFC_##offset) + + void + nv04_fifo_disable(struct drm_device *dev) +@@ -72,37 +71,32 @@ nv04_fifo_reassign(struct drm_device *dev, bool enable) + } + + bool +-nv04_fifo_cache_flush(struct drm_device *dev) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; +- uint64_t start = ptimer->read(dev); +- +- do { +- if (nv_rd32(dev, NV03_PFIFO_CACHE1_GET) == +- nv_rd32(dev, NV03_PFIFO_CACHE1_PUT)) +- return true; +- +- } while (ptimer->read(dev) - start < 100000000); +- +- NV_ERROR(dev, "Timeout flushing the PFIFO cache.\n"); +- +- return false; +-} +- +-bool + nv04_fifo_cache_pull(struct drm_device *dev, bool enable) + { +- uint32_t pull = nv_rd32(dev, NV04_PFIFO_CACHE1_PULL0); ++ int pull = nv_mask(dev, NV04_PFIFO_CACHE1_PULL0, 1, enable); ++ ++ if (!enable) { ++ /* In some cases the PFIFO puller may be left in an ++ * inconsistent state if you try to stop it when it's ++ * busy translating handles. Sometimes you get a ++ * PFIFO_CACHE_ERROR, sometimes it just fails silently ++ * sending incorrect instance offsets to PGRAPH after ++ * it's started up again. To avoid the latter we ++ * invalidate the most recently calculated instance. ++ */ ++ if (!nv_wait(dev, NV04_PFIFO_CACHE1_PULL0, ++ NV04_PFIFO_CACHE1_PULL0_HASH_BUSY, 0)) ++ NV_ERROR(dev, "Timeout idling the PFIFO puller.\n"); ++ ++ if (nv_rd32(dev, NV04_PFIFO_CACHE1_PULL0) & ++ NV04_PFIFO_CACHE1_PULL0_HASH_FAILED) ++ nv_wr32(dev, NV03_PFIFO_INTR_0, ++ NV_PFIFO_INTR_CACHE_ERROR); + +- if (enable) { +- nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, pull | 1); +- } else { +- nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, pull & ~1); + nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0); + } + +- return !!(pull & 1); ++ return pull & 1; + } + + int +@@ -112,6 +106,12 @@ nv04_fifo_channel_id(struct drm_device *dev) + NV03_PFIFO_CACHE1_PUSH1_CHID_MASK; + } + ++#ifdef __BIG_ENDIAN ++#define DMA_FETCH_ENDIANNESS NV_PFIFO_CACHE1_BIG_ENDIAN ++#else ++#define DMA_FETCH_ENDIANNESS 0 ++#endif ++ + int + nv04_fifo_create_context(struct nouveau_channel *chan) + { +@@ -124,25 +124,20 @@ nv04_fifo_create_context(struct nouveau_channel *chan) + NV04_RAMFC__SIZE, + NVOBJ_FLAG_ZERO_ALLOC | + NVOBJ_FLAG_ZERO_FREE, +- NULL, &chan->ramfc); ++ &chan->ramfc); + if (ret) + return ret; + + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + + /* Setup initial state */ +- dev_priv->engine.instmem.prepare_access(dev, true); + RAMFC_WR(DMA_PUT, chan->pushbuf_base); + RAMFC_WR(DMA_GET, chan->pushbuf_base); +- RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4); ++ RAMFC_WR(DMA_INSTANCE, chan->pushbuf->pinst >> 4); + RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | + NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | + NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | +-#ifdef __BIG_ENDIAN +- NV_PFIFO_CACHE1_BIG_ENDIAN | +-#endif +- 0)); +- dev_priv->engine.instmem.finish_access(dev); ++ DMA_FETCH_ENDIANNESS)); + + /* enable the fifo dma operation */ + nv_wr32(dev, NV04_PFIFO_MODE, +@@ -160,7 +155,7 @@ nv04_fifo_destroy_context(struct nouveau_channel *chan) + nv_wr32(dev, NV04_PFIFO_MODE, + nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id)); + +- nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++ nouveau_gpuobj_ref(NULL, &chan->ramfc); + } + + static void +@@ -169,8 +164,6 @@ nv04_fifo_do_load_context(struct drm_device *dev, int chid) + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t fc = NV04_RAMFC(chid), tmp; + +- dev_priv->engine.instmem.prepare_access(dev, false); +- + nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); + nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); + tmp = nv_ri32(dev, fc + 8); +@@ -181,8 +174,6 @@ nv04_fifo_do_load_context(struct drm_device *dev, int chid) + nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 20)); + nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 24)); + +- dev_priv->engine.instmem.finish_access(dev); +- + nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); + nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); + } +@@ -223,7 +214,6 @@ nv04_fifo_unload_context(struct drm_device *dev) + return -EINVAL; + } + +- dev_priv->engine.instmem.prepare_access(dev, true); + RAMFC_WR(DMA_PUT, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); + RAMFC_WR(DMA_GET, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); + tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16; +@@ -233,7 +223,6 @@ nv04_fifo_unload_context(struct drm_device *dev) + RAMFC_WR(DMA_FETCH, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH)); + RAMFC_WR(ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE)); + RAMFC_WR(PULL1_ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1)); +- dev_priv->engine.instmem.finish_access(dev); + + nv04_fifo_do_load_context(dev, pfifo->channels - 1); + nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); +@@ -269,10 +258,10 @@ nv04_fifo_init_ramxx(struct drm_device *dev) + struct drm_nouveau_private *dev_priv = dev->dev_private; + + nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | +- ((dev_priv->ramht_bits - 9) << 16) | +- (dev_priv->ramht_offset >> 8)); +- nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8); +- nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc_offset >> 8); ++ ((dev_priv->ramht->bits - 9) << 16) | ++ (dev_priv->ramht->gpuobj->pinst >> 8)); ++ nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro->pinst >> 8); ++ nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc->pinst >> 8); + } + + static void +@@ -297,6 +286,7 @@ nv04_fifo_init(struct drm_device *dev) + + nv04_fifo_init_intr(dev); + pfifo->enable(dev); ++ pfifo->reassign(dev, true); + + for (i = 0; i < dev_priv->engine.fifo.channels; i++) { + if (dev_priv->fifos[i]) { +diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c +index 618355e..c897342 100644 +--- a/drivers/gpu/drm/nouveau/nv04_graph.c ++++ b/drivers/gpu/drm/nouveau/nv04_graph.c +@@ -342,7 +342,7 @@ static uint32_t nv04_graph_ctx_regs[] = { + }; + + struct graph_state { +- int nv04[ARRAY_SIZE(nv04_graph_ctx_regs)]; ++ uint32_t nv04[ARRAY_SIZE(nv04_graph_ctx_regs)]; + }; + + struct nouveau_channel * +@@ -527,8 +527,7 @@ static int + nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass, + int mthd, uint32_t data) + { +- chan->fence.last_sequence_irq = data; +- nouveau_fence_handler(chan->dev, chan->id); ++ atomic_set(&chan->fence.last_sequence_irq, data); + return 0; + } + +diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c +index a3b9563..0b5ae29 100644 +--- a/drivers/gpu/drm/nouveau/nv04_instmem.c ++++ b/drivers/gpu/drm/nouveau/nv04_instmem.c +@@ -1,6 +1,7 @@ + #include "drmP.h" + #include "drm.h" + #include "nouveau_drv.h" ++#include "nouveau_ramht.h" + + /* returns the size of fifo context */ + static int +@@ -17,104 +18,51 @@ nouveau_fifo_ctx_size(struct drm_device *dev) + return 32; + } + +-static void +-nv04_instmem_determine_amount(struct drm_device *dev) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- int i; +- +- /* Figure out how much instance memory we need */ +- if (dev_priv->card_type >= NV_40) { +- /* We'll want more instance memory than this on some NV4x cards. +- * There's a 16MB aperture to play with that maps onto the end +- * of vram. For now, only reserve a small piece until we know +- * more about what each chipset requires. +- */ +- switch (dev_priv->chipset) { +- case 0x40: +- case 0x47: +- case 0x49: +- case 0x4b: +- dev_priv->ramin_rsvd_vram = (2 * 1024 * 1024); +- break; +- default: +- dev_priv->ramin_rsvd_vram = (1 * 1024 * 1024); +- break; +- } +- } else { +- /*XXX: what *are* the limits on ramin_rsvd_vram = (512 * 1024); +- } +- NV_DEBUG(dev, "RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram >> 10); +- +- /* Clear all of it, except the BIOS image that's in the first 64KiB */ +- dev_priv->engine.instmem.prepare_access(dev, true); +- for (i = 64 * 1024; i < dev_priv->ramin_rsvd_vram; i += 4) +- nv_wi32(dev, i, 0x00000000); +- dev_priv->engine.instmem.finish_access(dev); +-} +- +-static void +-nv04_instmem_configure_fixed_tables(struct drm_device *dev) ++int nv04_instmem_init(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_engine *engine = &dev_priv->engine; +- +- /* FIFO hash table (RAMHT) +- * use 4k hash table at RAMIN+0x10000 +- * TODO: extend the hash table +- */ +- dev_priv->ramht_offset = 0x10000; +- dev_priv->ramht_bits = 9; +- dev_priv->ramht_size = (1 << dev_priv->ramht_bits); /* nr entries */ +- dev_priv->ramht_size *= 8; /* 2 32-bit values per entry in RAMHT */ +- NV_DEBUG(dev, "RAMHT offset=0x%x, size=%d\n", dev_priv->ramht_offset, +- dev_priv->ramht_size); +- +- /* FIFO runout table (RAMRO) - 512k at 0x11200 */ +- dev_priv->ramro_offset = 0x11200; +- dev_priv->ramro_size = 512; +- NV_DEBUG(dev, "RAMRO offset=0x%x, size=%d\n", dev_priv->ramro_offset, +- dev_priv->ramro_size); +- +- /* FIFO context table (RAMFC) +- * NV40 : Not sure exactly how to position RAMFC on some cards, +- * 0x30002 seems to position it at RAMIN+0x20000 on these +- * cards. RAMFC is 4kb (32 fifos, 128byte entries). +- * Others: Position RAMFC at RAMIN+0x11400 +- */ +- dev_priv->ramfc_size = engine->fifo.channels * +- nouveau_fifo_ctx_size(dev); ++ struct nouveau_gpuobj *ramht = NULL; ++ u32 offset, length; ++ int ret; ++ ++ /* RAMIN always available */ ++ dev_priv->ramin_available = true; ++ ++ /* Setup shared RAMHT */ ++ ret = nouveau_gpuobj_new_fake(dev, 0x10000, ~0, 4096, ++ NVOBJ_FLAG_ZERO_ALLOC, &ramht); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_ramht_new(dev, ramht, &dev_priv->ramht); ++ nouveau_gpuobj_ref(NULL, &ramht); ++ if (ret) ++ return ret; ++ ++ /* And RAMRO */ ++ ret = nouveau_gpuobj_new_fake(dev, 0x11200, ~0, 512, ++ NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramro); ++ if (ret) ++ return ret; ++ ++ /* And RAMFC */ ++ length = dev_priv->engine.fifo.channels * nouveau_fifo_ctx_size(dev); + switch (dev_priv->card_type) { + case NV_40: +- dev_priv->ramfc_offset = 0x20000; ++ offset = 0x20000; + break; +- case NV_30: +- case NV_20: +- case NV_10: +- case NV_04: + default: +- dev_priv->ramfc_offset = 0x11400; ++ offset = 0x11400; + break; + } +- NV_DEBUG(dev, "RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset, +- dev_priv->ramfc_size); +-} + +-int nv04_instmem_init(struct drm_device *dev) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- uint32_t offset; +- int ret = 0; ++ ret = nouveau_gpuobj_new_fake(dev, offset, ~0, length, ++ NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramfc); ++ if (ret) ++ return ret; + +- nv04_instmem_determine_amount(dev); +- nv04_instmem_configure_fixed_tables(dev); +- +- /* Create a heap to manage RAMIN allocations, we don't allocate +- * the space that was reserved for RAMHT/FC/RO. +- */ +- offset = dev_priv->ramfc_offset + dev_priv->ramfc_size; ++ /* Only allow space after RAMFC to be used for object allocation */ ++ offset += length; + + /* It appears RAMRO (or something?) is controlled by 0x2220/0x2230 + * on certain NV4x chipsets as well as RAMFC. When 0x2230 == 0 +@@ -129,69 +77,52 @@ int nv04_instmem_init(struct drm_device *dev) + offset = 0x40000; + } + +- ret = nouveau_mem_init_heap(&dev_priv->ramin_heap, +- offset, dev_priv->ramin_rsvd_vram - offset); ++ ret = drm_mm_init(&dev_priv->ramin_heap, offset, ++ dev_priv->ramin_rsvd_vram - offset); + if (ret) { +- dev_priv->ramin_heap = NULL; +- NV_ERROR(dev, "Failed to init RAMIN heap\n"); ++ NV_ERROR(dev, "Failed to init RAMIN heap: %d\n", ret); ++ return ret; + } + +- return ret; ++ return 0; + } + + void + nv04_instmem_takedown(struct drm_device *dev) + { ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ nouveau_ramht_ref(NULL, &dev_priv->ramht, NULL); ++ nouveau_gpuobj_ref(NULL, &dev_priv->ramro); ++ nouveau_gpuobj_ref(NULL, &dev_priv->ramfc); + } + + int +-nv04_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, uint32_t *sz) ++nv04_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, ++ uint32_t *sz) + { +- if (gpuobj->im_backing) +- return -EINVAL; +- + return 0; + } + + void + nv04_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) + { +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- +- if (gpuobj && gpuobj->im_backing) { +- if (gpuobj->im_bound) +- dev_priv->engine.instmem.unbind(dev, gpuobj); +- gpuobj->im_backing = NULL; +- } + } + + int + nv04_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) + { +- if (!gpuobj->im_pramin || gpuobj->im_bound) +- return -EINVAL; +- +- gpuobj->im_bound = 1; + return 0; + } + + int + nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) + { +- if (gpuobj->im_bound == 0) +- return -EINVAL; +- +- gpuobj->im_bound = 0; + return 0; + } + + void +-nv04_instmem_prepare_access(struct drm_device *dev, bool write) +-{ +-} +- +-void +-nv04_instmem_finish_access(struct drm_device *dev) ++nv04_instmem_flush(struct drm_device *dev) + { + } + +diff --git a/drivers/gpu/drm/nouveau/nv04_mc.c b/drivers/gpu/drm/nouveau/nv04_mc.c +index 617ed1e..2af43a1 100644 +--- a/drivers/gpu/drm/nouveau/nv04_mc.c ++++ b/drivers/gpu/drm/nouveau/nv04_mc.c +@@ -11,6 +11,10 @@ nv04_mc_init(struct drm_device *dev) + */ + + nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); ++ ++ /* Disable PROM access. */ ++ nv_wr32(dev, NV_PBUS_PCI_NV_20, NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED); ++ + return 0; + } + +diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c +index c4e3404..9915a3b 100644 +--- a/drivers/gpu/drm/nouveau/nv04_tv.c ++++ b/drivers/gpu/drm/nouveau/nv04_tv.c +@@ -34,69 +34,26 @@ + + #include "i2c/ch7006.h" + +-static struct { +- struct i2c_board_info board_info; +- struct drm_encoder_funcs funcs; +- struct drm_encoder_helper_funcs hfuncs; +- void *params; +- +-} nv04_tv_encoder_info[] = { ++static struct i2c_board_info nv04_tv_encoder_info[] = { + { +- .board_info = { I2C_BOARD_INFO("ch7006", 0x75) }, +- .params = &(struct ch7006_encoder_params) { ++ I2C_BOARD_INFO("ch7006", 0x75), ++ .platform_data = &(struct ch7006_encoder_params) { + CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER, + 0, 0, 0, + CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED, + CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC +- }, ++ } + }, ++ { } + }; + +-static bool probe_i2c_addr(struct i2c_adapter *adapter, int addr) +-{ +- struct i2c_msg msg = { +- .addr = addr, +- .len = 0, +- }; +- +- return i2c_transfer(adapter, &msg, 1) == 1; +-} +- + int nv04_tv_identify(struct drm_device *dev, int i2c_index) + { +- struct nouveau_i2c_chan *i2c; +- bool was_locked; +- int i, ret; +- +- NV_TRACE(dev, "Probing TV encoders on I2C bus: %d\n", i2c_index); +- +- i2c = nouveau_i2c_find(dev, i2c_index); +- if (!i2c) +- return -ENODEV; +- +- was_locked = NVLockVgaCrtcs(dev, false); +- +- for (i = 0; i < ARRAY_SIZE(nv04_tv_encoder_info); i++) { +- if (probe_i2c_addr(&i2c->adapter, +- nv04_tv_encoder_info[i].board_info.addr)) { +- ret = i; +- break; +- } +- } +- +- if (i < ARRAY_SIZE(nv04_tv_encoder_info)) { +- NV_TRACE(dev, "Detected TV encoder: %s\n", +- nv04_tv_encoder_info[i].board_info.type); +- +- } else { +- NV_TRACE(dev, "No TV encoders found.\n"); +- i = -ENODEV; +- } +- +- NVLockVgaCrtcs(dev, was_locked); +- return i; ++ return nouveau_i2c_identify(dev, "TV encoder", ++ nv04_tv_encoder_info, i2c_index); + } + ++ + #define PLLSEL_TV_CRTC1_MASK \ + (NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1 \ + | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1) +@@ -132,7 +89,7 @@ static void nv04_tv_dpms(struct drm_encoder *encoder, int mode) + + NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel); + +- to_encoder_slave(encoder)->slave_funcs->dpms(encoder, mode); ++ get_slave_funcs(encoder)->dpms(encoder, mode); + } + + static void nv04_tv_bind(struct drm_device *dev, int head, bool bind) +@@ -142,12 +99,10 @@ static void nv04_tv_bind(struct drm_device *dev, int head, bool bind) + + state->tv_setup = 0; + +- if (bind) { +- state->CRTC[NV_CIO_CRE_LCD__INDEX] = 0; ++ if (bind) + state->CRTC[NV_CIO_CRE_49] |= 0x10; +- } else { ++ else + state->CRTC[NV_CIO_CRE_49] &= ~0x10; +- } + + NVWriteVgaCrtc(dev, head, NV_CIO_CRE_LCD__INDEX, + state->CRTC[NV_CIO_CRE_LCD__INDEX]); +@@ -195,7 +150,7 @@ static void nv04_tv_mode_set(struct drm_encoder *encoder, + regp->tv_vskew = 1; + regp->tv_vsync_delay = 1; + +- to_encoder_slave(encoder)->slave_funcs->mode_set(encoder, mode, adjusted_mode); ++ get_slave_funcs(encoder)->mode_set(encoder, mode, adjusted_mode); + } + + static void nv04_tv_commit(struct drm_encoder *encoder) +@@ -214,30 +169,31 @@ static void nv04_tv_commit(struct drm_encoder *encoder) + + static void nv04_tv_destroy(struct drm_encoder *encoder) + { +- struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); +- +- to_encoder_slave(encoder)->slave_funcs->destroy(encoder); +- ++ get_slave_funcs(encoder)->destroy(encoder); + drm_encoder_cleanup(encoder); + +- kfree(nv_encoder); ++ kfree(encoder->helper_private); ++ kfree(nouveau_encoder(encoder)); + } + +-int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) ++static const struct drm_encoder_funcs nv04_tv_funcs = { ++ .destroy = nv04_tv_destroy, ++}; ++ ++int ++nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry) + { + struct nouveau_encoder *nv_encoder; + struct drm_encoder *encoder; +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct i2c_adapter *adap; +- struct drm_encoder_funcs *funcs = NULL; +- struct drm_encoder_helper_funcs *hfuncs = NULL; +- struct drm_encoder_slave_funcs *sfuncs = NULL; +- int i2c_index = entry->i2c_index; ++ struct drm_device *dev = connector->dev; ++ struct drm_encoder_helper_funcs *hfuncs; ++ struct drm_encoder_slave_funcs *sfuncs; ++ struct nouveau_i2c_chan *i2c = ++ nouveau_i2c_find(dev, entry->i2c_index); + int type, ret; +- bool was_locked; + + /* Ensure that we can talk to this encoder */ +- type = nv04_tv_identify(dev, i2c_index); ++ type = nv04_tv_identify(dev, entry->i2c_index); + if (type < 0) + return type; + +@@ -246,40 +202,31 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) + if (!nv_encoder) + return -ENOMEM; + ++ hfuncs = kzalloc(sizeof(*hfuncs), GFP_KERNEL); ++ if (!hfuncs) { ++ ret = -ENOMEM; ++ goto fail_free; ++ } ++ + /* Initialize the common members */ + encoder = to_drm_encoder(nv_encoder); + +- funcs = &nv04_tv_encoder_info[type].funcs; +- hfuncs = &nv04_tv_encoder_info[type].hfuncs; +- +- drm_encoder_init(dev, encoder, funcs, DRM_MODE_ENCODER_TVDAC); ++ drm_encoder_init(dev, encoder, &nv04_tv_funcs, DRM_MODE_ENCODER_TVDAC); + drm_encoder_helper_add(encoder, hfuncs); + + encoder->possible_crtcs = entry->heads; + encoder->possible_clones = 0; +- + nv_encoder->dcb = entry; + nv_encoder->or = ffs(entry->or) - 1; + + /* Run the slave-specific initialization */ +- adap = &dev_priv->vbios.dcb.i2c[i2c_index].chan->adapter; +- +- was_locked = NVLockVgaCrtcs(dev, false); +- +- ret = drm_i2c_encoder_init(encoder->dev, to_encoder_slave(encoder), adap, +- &nv04_tv_encoder_info[type].board_info); +- +- NVLockVgaCrtcs(dev, was_locked); +- ++ ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), ++ &i2c->adapter, &nv04_tv_encoder_info[type]); + if (ret < 0) +- goto fail; ++ goto fail_cleanup; + + /* Fill the function pointers */ +- sfuncs = to_encoder_slave(encoder)->slave_funcs; +- +- *funcs = (struct drm_encoder_funcs) { +- .destroy = nv04_tv_destroy, +- }; ++ sfuncs = get_slave_funcs(encoder); + + *hfuncs = (struct drm_encoder_helper_funcs) { + .dpms = nv04_tv_dpms, +@@ -292,14 +239,16 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) + .detect = sfuncs->detect, + }; + +- /* Set the slave encoder configuration */ +- sfuncs->set_config(encoder, nv04_tv_encoder_info[type].params); ++ /* Attach it to the specified connector. */ ++ sfuncs->create_resources(encoder, connector); ++ drm_mode_connector_attach_encoder(connector, encoder); + + return 0; + +-fail: ++fail_cleanup: + drm_encoder_cleanup(encoder); +- ++ kfree(hfuncs); ++fail_free: + kfree(nv_encoder); + return ret; + } +diff --git a/drivers/gpu/drm/nouveau/nv10_fifo.c b/drivers/gpu/drm/nouveau/nv10_fifo.c +index 7aeabf2..f1b03ad 100644 +--- a/drivers/gpu/drm/nouveau/nv10_fifo.c ++++ b/drivers/gpu/drm/nouveau/nv10_fifo.c +@@ -27,8 +27,9 @@ + #include "drmP.h" + #include "drm.h" + #include "nouveau_drv.h" ++#include "nouveau_ramht.h" + +-#define NV10_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV10_RAMFC__SIZE)) ++#define NV10_RAMFC(c) (dev_priv->ramfc->pinst + ((c) * NV10_RAMFC__SIZE)) + #define NV10_RAMFC__SIZE ((dev_priv->chipset) >= 0x17 ? 64 : 32) + + int +@@ -48,17 +49,16 @@ nv10_fifo_create_context(struct nouveau_channel *chan) + + ret = nouveau_gpuobj_new_fake(dev, NV10_RAMFC(chan->id), ~0, + NV10_RAMFC__SIZE, NVOBJ_FLAG_ZERO_ALLOC | +- NVOBJ_FLAG_ZERO_FREE, NULL, &chan->ramfc); ++ NVOBJ_FLAG_ZERO_FREE, &chan->ramfc); + if (ret) + return ret; + + /* Fill entries that are seen filled in dumps of nvidia driver just + * after channel's is put into DMA mode + */ +- dev_priv->engine.instmem.prepare_access(dev, true); + nv_wi32(dev, fc + 0, chan->pushbuf_base); + nv_wi32(dev, fc + 4, chan->pushbuf_base); +- nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4); ++ nv_wi32(dev, fc + 12, chan->pushbuf->pinst >> 4); + nv_wi32(dev, fc + 20, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | + NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | + NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | +@@ -66,7 +66,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan) + NV_PFIFO_CACHE1_BIG_ENDIAN | + #endif + 0); +- dev_priv->engine.instmem.finish_access(dev); + + /* enable the fifo dma operation */ + nv_wr32(dev, NV04_PFIFO_MODE, +@@ -82,7 +81,7 @@ nv10_fifo_destroy_context(struct nouveau_channel *chan) + nv_wr32(dev, NV04_PFIFO_MODE, + nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id)); + +- nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++ nouveau_gpuobj_ref(NULL, &chan->ramfc); + } + + static void +@@ -91,8 +90,6 @@ nv10_fifo_do_load_context(struct drm_device *dev, int chid) + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t fc = NV10_RAMFC(chid), tmp; + +- dev_priv->engine.instmem.prepare_access(dev, false); +- + nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); + nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); + nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); +@@ -117,8 +114,6 @@ nv10_fifo_do_load_context(struct drm_device *dev, int chid) + nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 48)); + + out: +- dev_priv->engine.instmem.finish_access(dev); +- + nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); + nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); + } +@@ -155,8 +150,6 @@ nv10_fifo_unload_context(struct drm_device *dev) + return 0; + fc = NV10_RAMFC(chid); + +- dev_priv->engine.instmem.prepare_access(dev, true); +- + nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); + nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); + nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); +@@ -179,8 +172,6 @@ nv10_fifo_unload_context(struct drm_device *dev) + nv_wi32(dev, fc + 48, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); + + out: +- dev_priv->engine.instmem.finish_access(dev); +- + nv10_fifo_do_load_context(dev, pfifo->channels - 1); + nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); + return 0; +@@ -212,14 +203,14 @@ nv10_fifo_init_ramxx(struct drm_device *dev) + struct drm_nouveau_private *dev_priv = dev->dev_private; + + nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | +- ((dev_priv->ramht_bits - 9) << 16) | +- (dev_priv->ramht_offset >> 8)); +- nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8); ++ ((dev_priv->ramht->bits - 9) << 16) | ++ (dev_priv->ramht->gpuobj->pinst >> 8)); ++ nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro->pinst >> 8); + + if (dev_priv->chipset < 0x17) { +- nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc_offset >> 8); ++ nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc->pinst >> 8); + } else { +- nv_wr32(dev, NV03_PFIFO_RAMFC, (dev_priv->ramfc_offset >> 8) | ++ nv_wr32(dev, NV03_PFIFO_RAMFC, (dev_priv->ramfc->pinst >> 8) | + (1 << 16) /* 64 Bytes entry*/); + /* XXX nvidia blob set bit 18, 21,23 for nv20 & nv30 */ + } +diff --git a/drivers/gpu/drm/nouveau/nv10_gpio.c b/drivers/gpu/drm/nouveau/nv10_gpio.c +new file mode 100644 +index 0000000..007fc29 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv10_gpio.c +@@ -0,0 +1,92 @@ ++/* ++ * Copyright (C) 2009 Francisco Jerez. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_hw.h" ++ ++static bool ++get_gpio_location(struct dcb_gpio_entry *ent, uint32_t *reg, uint32_t *shift, ++ uint32_t *mask) ++{ ++ if (ent->line < 2) { ++ *reg = NV_PCRTC_GPIO; ++ *shift = ent->line * 16; ++ *mask = 0x11; ++ ++ } else if (ent->line < 10) { ++ *reg = NV_PCRTC_GPIO_EXT; ++ *shift = (ent->line - 2) * 4; ++ *mask = 0x3; ++ ++ } else if (ent->line < 14) { ++ *reg = NV_PCRTC_850; ++ *shift = (ent->line - 10) * 4; ++ *mask = 0x3; ++ ++ } else { ++ return false; ++ } ++ ++ return true; ++} ++ ++int ++nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag) ++{ ++ struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag); ++ uint32_t reg, shift, mask, value; ++ ++ if (!ent) ++ return -ENODEV; ++ ++ if (!get_gpio_location(ent, ®, &shift, &mask)) ++ return -ENODEV; ++ ++ value = NVReadCRTC(dev, 0, reg) >> shift; ++ ++ return (ent->invert ? 1 : 0) ^ (value & 1); ++} ++ ++int ++nv10_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state) ++{ ++ struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag); ++ uint32_t reg, shift, mask, value; ++ ++ if (!ent) ++ return -ENODEV; ++ ++ if (!get_gpio_location(ent, ®, &shift, &mask)) ++ return -ENODEV; ++ ++ value = ((ent->invert ? 1 : 0) ^ (state ? 1 : 0)) << shift; ++ mask = ~(mask << shift); ++ ++ NVWriteCRTC(dev, 0, reg, value | (NVReadCRTC(dev, 0, reg) & mask)); ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c +index fcf2cdd..8e68c97 100644 +--- a/drivers/gpu/drm/nouveau/nv10_graph.c ++++ b/drivers/gpu/drm/nouveau/nv10_graph.c +@@ -43,51 +43,51 @@ struct pipe_state { + }; + + static int nv10_graph_ctx_regs[] = { +- NV10_PGRAPH_CTX_SWITCH1, +- NV10_PGRAPH_CTX_SWITCH2, +- NV10_PGRAPH_CTX_SWITCH3, +- NV10_PGRAPH_CTX_SWITCH4, +- NV10_PGRAPH_CTX_SWITCH5, +- NV10_PGRAPH_CTX_CACHE1, /* 8 values from 0x400160 to 0x40017c */ +- NV10_PGRAPH_CTX_CACHE2, /* 8 values from 0x400180 to 0x40019c */ +- NV10_PGRAPH_CTX_CACHE3, /* 8 values from 0x4001a0 to 0x4001bc */ +- NV10_PGRAPH_CTX_CACHE4, /* 8 values from 0x4001c0 to 0x4001dc */ +- NV10_PGRAPH_CTX_CACHE5, /* 8 values from 0x4001e0 to 0x4001fc */ +- 0x00400164, +- 0x00400184, +- 0x004001a4, +- 0x004001c4, +- 0x004001e4, +- 0x00400168, +- 0x00400188, +- 0x004001a8, +- 0x004001c8, +- 0x004001e8, +- 0x0040016c, +- 0x0040018c, +- 0x004001ac, +- 0x004001cc, +- 0x004001ec, +- 0x00400170, +- 0x00400190, +- 0x004001b0, +- 0x004001d0, +- 0x004001f0, +- 0x00400174, +- 0x00400194, +- 0x004001b4, +- 0x004001d4, +- 0x004001f4, +- 0x00400178, +- 0x00400198, +- 0x004001b8, +- 0x004001d8, +- 0x004001f8, +- 0x0040017c, +- 0x0040019c, +- 0x004001bc, +- 0x004001dc, +- 0x004001fc, ++ NV10_PGRAPH_CTX_SWITCH(0), ++ NV10_PGRAPH_CTX_SWITCH(1), ++ NV10_PGRAPH_CTX_SWITCH(2), ++ NV10_PGRAPH_CTX_SWITCH(3), ++ NV10_PGRAPH_CTX_SWITCH(4), ++ NV10_PGRAPH_CTX_CACHE(0, 0), ++ NV10_PGRAPH_CTX_CACHE(0, 1), ++ NV10_PGRAPH_CTX_CACHE(0, 2), ++ NV10_PGRAPH_CTX_CACHE(0, 3), ++ NV10_PGRAPH_CTX_CACHE(0, 4), ++ NV10_PGRAPH_CTX_CACHE(1, 0), ++ NV10_PGRAPH_CTX_CACHE(1, 1), ++ NV10_PGRAPH_CTX_CACHE(1, 2), ++ NV10_PGRAPH_CTX_CACHE(1, 3), ++ NV10_PGRAPH_CTX_CACHE(1, 4), ++ NV10_PGRAPH_CTX_CACHE(2, 0), ++ NV10_PGRAPH_CTX_CACHE(2, 1), ++ NV10_PGRAPH_CTX_CACHE(2, 2), ++ NV10_PGRAPH_CTX_CACHE(2, 3), ++ NV10_PGRAPH_CTX_CACHE(2, 4), ++ NV10_PGRAPH_CTX_CACHE(3, 0), ++ NV10_PGRAPH_CTX_CACHE(3, 1), ++ NV10_PGRAPH_CTX_CACHE(3, 2), ++ NV10_PGRAPH_CTX_CACHE(3, 3), ++ NV10_PGRAPH_CTX_CACHE(3, 4), ++ NV10_PGRAPH_CTX_CACHE(4, 0), ++ NV10_PGRAPH_CTX_CACHE(4, 1), ++ NV10_PGRAPH_CTX_CACHE(4, 2), ++ NV10_PGRAPH_CTX_CACHE(4, 3), ++ NV10_PGRAPH_CTX_CACHE(4, 4), ++ NV10_PGRAPH_CTX_CACHE(5, 0), ++ NV10_PGRAPH_CTX_CACHE(5, 1), ++ NV10_PGRAPH_CTX_CACHE(5, 2), ++ NV10_PGRAPH_CTX_CACHE(5, 3), ++ NV10_PGRAPH_CTX_CACHE(5, 4), ++ NV10_PGRAPH_CTX_CACHE(6, 0), ++ NV10_PGRAPH_CTX_CACHE(6, 1), ++ NV10_PGRAPH_CTX_CACHE(6, 2), ++ NV10_PGRAPH_CTX_CACHE(6, 3), ++ NV10_PGRAPH_CTX_CACHE(6, 4), ++ NV10_PGRAPH_CTX_CACHE(7, 0), ++ NV10_PGRAPH_CTX_CACHE(7, 1), ++ NV10_PGRAPH_CTX_CACHE(7, 2), ++ NV10_PGRAPH_CTX_CACHE(7, 3), ++ NV10_PGRAPH_CTX_CACHE(7, 4), + NV10_PGRAPH_CTX_USER, + NV04_PGRAPH_DMA_START_0, + NV04_PGRAPH_DMA_START_1, +@@ -653,6 +653,78 @@ static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg) + return -1; + } + ++static void nv10_graph_load_dma_vtxbuf(struct nouveau_channel *chan, ++ uint32_t inst) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; ++ uint32_t st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4]; ++ uint32_t ctx_user, ctx_switch[5]; ++ int i, subchan = -1; ++ ++ /* NV10TCL_DMA_VTXBUF (method 0x18c) modifies hidden state ++ * that cannot be restored via MMIO. Do it through the FIFO ++ * instead. ++ */ ++ ++ /* Look for a celsius object */ ++ for (i = 0; i < 8; i++) { ++ int class = nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(i, 0)) & 0xfff; ++ ++ if (class == 0x56 || class == 0x96 || class == 0x99) { ++ subchan = i; ++ break; ++ } ++ } ++ ++ if (subchan < 0 || !inst) ++ return; ++ ++ /* Save the current ctx object */ ++ ctx_user = nv_rd32(dev, NV10_PGRAPH_CTX_USER); ++ for (i = 0; i < 5; i++) ++ ctx_switch[i] = nv_rd32(dev, NV10_PGRAPH_CTX_SWITCH(i)); ++ ++ /* Save the FIFO state */ ++ st2 = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2); ++ st2_dl = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DL); ++ st2_dh = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DH); ++ fifo_ptr = nv_rd32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR); ++ ++ for (i = 0; i < ARRAY_SIZE(fifo); i++) ++ fifo[i] = nv_rd32(dev, 0x4007a0 + 4 * i); ++ ++ /* Switch to the celsius subchannel */ ++ for (i = 0; i < 5; i++) ++ nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i), ++ nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(subchan, i))); ++ nv_mask(dev, NV10_PGRAPH_CTX_USER, 0xe000, subchan << 13); ++ ++ /* Inject NV10TCL_DMA_VTXBUF */ ++ nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, 0); ++ nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, ++ 0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c); ++ nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst); ++ nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000); ++ pgraph->fifo_access(dev, true); ++ pgraph->fifo_access(dev, false); ++ ++ /* Restore the FIFO state */ ++ for (i = 0; i < ARRAY_SIZE(fifo); i++) ++ nv_wr32(dev, 0x4007a0 + 4 * i, fifo[i]); ++ ++ nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, fifo_ptr); ++ nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, st2); ++ nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, st2_dl); ++ nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DH, st2_dh); ++ ++ /* Restore the current ctx object */ ++ for (i = 0; i < 5; i++) ++ nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i), ctx_switch[i]); ++ nv_wr32(dev, NV10_PGRAPH_CTX_USER, ctx_user); ++} ++ + int nv10_graph_load_context(struct nouveau_channel *chan) + { + struct drm_device *dev = chan->dev; +@@ -670,6 +742,8 @@ int nv10_graph_load_context(struct nouveau_channel *chan) + } + + nv10_graph_load_pipe(chan); ++ nv10_graph_load_dma_vtxbuf(chan, (nv_rd32(dev, NV10_PGRAPH_GLOBALSTATE1) ++ & 0xffff)); + + nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100); + tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER); +@@ -729,7 +803,7 @@ nv10_graph_context_switch(struct drm_device *dev) + /* Load context for next channel */ + chid = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; + chan = dev_priv->fifos[chid]; +- if (chan) ++ if (chan && chan->pgraph_ctx) + nv10_graph_load_context(chan); + + pgraph->fifo_access(dev, true); +@@ -856,11 +930,12 @@ int nv10_graph_init(struct drm_device *dev) + for (i = 0; i < NV10_PFB_TILE__SIZE; i++) + nv10_graph_set_region_tiling(dev, i, 0, 0, 0); + +- nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH1, 0x00000000); +- nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH2, 0x00000000); +- nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH3, 0x00000000); +- nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH4, 0x00000000); +- nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); ++ nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000); ++ nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000); ++ nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000); ++ nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000); ++ nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(4), 0x00000000); ++ nv_wr32(dev, NV10_PGRAPH_STATE, 0xFFFFFFFF); + + tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff; + tmp |= (dev_priv->engine.fifo.channels - 1) << 24; +diff --git a/drivers/gpu/drm/nouveau/nv17_gpio.c b/drivers/gpu/drm/nouveau/nv17_gpio.c +deleted file mode 100644 +index 2e58c33..0000000 +--- a/drivers/gpu/drm/nouveau/nv17_gpio.c ++++ /dev/null +@@ -1,92 +0,0 @@ +-/* +- * Copyright (C) 2009 Francisco Jerez. +- * All Rights Reserved. +- * +- * Permission is hereby granted, free of charge, to any person obtaining +- * a copy of this software and associated documentation files (the +- * "Software"), to deal in the Software without restriction, including +- * without limitation the rights to use, copy, modify, merge, publish, +- * distribute, sublicense, and/or sell copies of the Software, and to +- * permit persons to whom the Software is furnished to do so, subject to +- * the following conditions: +- * +- * The above copyright notice and this permission notice (including the +- * next paragraph) shall be included in all copies or substantial +- * portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- * +- */ +- +-#include "drmP.h" +-#include "nouveau_drv.h" +-#include "nouveau_hw.h" +- +-static bool +-get_gpio_location(struct dcb_gpio_entry *ent, uint32_t *reg, uint32_t *shift, +- uint32_t *mask) +-{ +- if (ent->line < 2) { +- *reg = NV_PCRTC_GPIO; +- *shift = ent->line * 16; +- *mask = 0x11; +- +- } else if (ent->line < 10) { +- *reg = NV_PCRTC_GPIO_EXT; +- *shift = (ent->line - 2) * 4; +- *mask = 0x3; +- +- } else if (ent->line < 14) { +- *reg = NV_PCRTC_850; +- *shift = (ent->line - 10) * 4; +- *mask = 0x3; +- +- } else { +- return false; +- } +- +- return true; +-} +- +-int +-nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag) +-{ +- struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag); +- uint32_t reg, shift, mask, value; +- +- if (!ent) +- return -ENODEV; +- +- if (!get_gpio_location(ent, ®, &shift, &mask)) +- return -ENODEV; +- +- value = NVReadCRTC(dev, 0, reg) >> shift; +- +- return (ent->invert ? 1 : 0) ^ (value & 1); +-} +- +-int +-nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state) +-{ +- struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag); +- uint32_t reg, shift, mask, value; +- +- if (!ent) +- return -ENODEV; +- +- if (!get_gpio_location(ent, ®, &shift, &mask)) +- return -ENODEV; +- +- value = ((ent->invert ? 1 : 0) ^ (state ? 1 : 0)) << shift; +- mask = ~(mask << shift); +- +- NVWriteCRTC(dev, 0, reg, value | (NVReadCRTC(dev, 0, reg) & mask)); +- +- return 0; +-} +diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c +index 74c8803..28119fd 100644 +--- a/drivers/gpu/drm/nouveau/nv17_tv.c ++++ b/drivers/gpu/drm/nouveau/nv17_tv.c +@@ -37,6 +37,7 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) + { + struct drm_device *dev = encoder->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio; + uint32_t testval, regoffset = nv04_dac_output_offset(encoder); + uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end, + fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c; +@@ -52,8 +53,8 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) + head = (dacclk & 0x100) >> 8; + + /* Save the previous state. */ +- gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1); +- gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0); ++ gpio1 = gpio->get(dev, DCB_GPIO_TVDAC1); ++ gpio0 = gpio->get(dev, DCB_GPIO_TVDAC0); + fp_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL); + fp_hsync_start = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START); + fp_hsync_end = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END); +@@ -64,8 +65,8 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) + ctv_6c = NVReadRAMDAC(dev, head, 0x680c6c); + + /* Prepare the DAC for load detection. */ +- nv17_gpio_set(dev, DCB_GPIO_TVDAC1, true); +- nv17_gpio_set(dev, DCB_GPIO_TVDAC0, true); ++ gpio->set(dev, DCB_GPIO_TVDAC1, true); ++ gpio->set(dev, DCB_GPIO_TVDAC0, true); + + NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, 1343); + NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, 1047); +@@ -110,12 +111,31 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) + NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, fp_hsync_end); + NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, fp_hsync_start); + NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, fp_htotal); +- nv17_gpio_set(dev, DCB_GPIO_TVDAC1, gpio1); +- nv17_gpio_set(dev, DCB_GPIO_TVDAC0, gpio0); ++ gpio->set(dev, DCB_GPIO_TVDAC1, gpio1); ++ gpio->set(dev, DCB_GPIO_TVDAC0, gpio0); + + return sample; + } + ++static bool ++get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask) ++{ ++ /* Zotac FX5200 */ ++ if (nv_match_device(dev, 0x0322, 0x19da, 0x1035) || ++ nv_match_device(dev, 0x0322, 0x19da, 0x2035)) { ++ *pin_mask = 0xc; ++ return false; ++ } ++ ++ /* MSI nForce2 IGP */ ++ if (nv_match_device(dev, 0x01f0, 0x1462, 0x5710)) { ++ *pin_mask = 0xc; ++ return false; ++ } ++ ++ return true; ++} ++ + static enum drm_connector_status + nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) + { +@@ -124,12 +144,20 @@ nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) + struct drm_mode_config *conf = &dev->mode_config; + struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); + struct dcb_entry *dcb = tv_enc->base.dcb; ++ bool reliable = get_tv_detect_quirks(dev, &tv_enc->pin_mask); + +- if (dev_priv->chipset == 0x42 || +- dev_priv->chipset == 0x43) +- tv_enc->pin_mask = nv42_tv_sample_load(encoder) >> 28 & 0xe; +- else +- tv_enc->pin_mask = nv17_dac_sample_load(encoder) >> 28 & 0xe; ++ if (nv04_dac_in_use(encoder)) ++ return connector_status_disconnected; ++ ++ if (reliable) { ++ if (dev_priv->chipset == 0x42 || ++ dev_priv->chipset == 0x43) ++ tv_enc->pin_mask = ++ nv42_tv_sample_load(encoder) >> 28 & 0xe; ++ else ++ tv_enc->pin_mask = ++ nv17_dac_sample_load(encoder) >> 28 & 0xe; ++ } + + switch (tv_enc->pin_mask) { + case 0x2: +@@ -154,7 +182,9 @@ nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) + conf->tv_subconnector_property, + tv_enc->subconnector); + +- if (tv_enc->subconnector) { ++ if (!reliable) { ++ return connector_status_unknown; ++ } else if (tv_enc->subconnector) { + NV_INFO(dev, "Load detected on output %c\n", + '@' + ffs(dcb->or)); + return connector_status_connected; +@@ -163,55 +193,56 @@ nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) + } + } + +-static const struct { +- int hdisplay; +- int vdisplay; +-} modes[] = { +- { 640, 400 }, +- { 640, 480 }, +- { 720, 480 }, +- { 720, 576 }, +- { 800, 600 }, +- { 1024, 768 }, +- { 1280, 720 }, +- { 1280, 1024 }, +- { 1920, 1080 } +-}; +- +-static int nv17_tv_get_modes(struct drm_encoder *encoder, +- struct drm_connector *connector) ++static int nv17_tv_get_ld_modes(struct drm_encoder *encoder, ++ struct drm_connector *connector) + { + struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); +- struct drm_display_mode *mode; +- struct drm_display_mode *output_mode; ++ struct drm_display_mode *mode, *tv_mode; + int n = 0; +- int i; + +- if (tv_norm->kind != CTV_ENC_MODE) { +- struct drm_display_mode *tv_mode; ++ for (tv_mode = nv17_tv_modes; tv_mode->hdisplay; tv_mode++) { ++ mode = drm_mode_duplicate(encoder->dev, tv_mode); + +- for (tv_mode = nv17_tv_modes; tv_mode->hdisplay; tv_mode++) { +- mode = drm_mode_duplicate(encoder->dev, tv_mode); ++ mode->clock = tv_norm->tv_enc_mode.vrefresh * ++ mode->htotal / 1000 * ++ mode->vtotal / 1000; + +- mode->clock = tv_norm->tv_enc_mode.vrefresh * +- mode->htotal / 1000 * +- mode->vtotal / 1000; +- +- if (mode->flags & DRM_MODE_FLAG_DBLSCAN) +- mode->clock *= 2; ++ if (mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ mode->clock *= 2; + +- if (mode->hdisplay == tv_norm->tv_enc_mode.hdisplay && +- mode->vdisplay == tv_norm->tv_enc_mode.vdisplay) +- mode->type |= DRM_MODE_TYPE_PREFERRED; ++ if (mode->hdisplay == tv_norm->tv_enc_mode.hdisplay && ++ mode->vdisplay == tv_norm->tv_enc_mode.vdisplay) ++ mode->type |= DRM_MODE_TYPE_PREFERRED; + +- drm_mode_probed_add(connector, mode); +- n++; +- } +- return n; ++ drm_mode_probed_add(connector, mode); ++ n++; + } + +- /* tv_norm->kind == CTV_ENC_MODE */ +- output_mode = &tv_norm->ctv_enc_mode.mode; ++ return n; ++} ++ ++static int nv17_tv_get_hd_modes(struct drm_encoder *encoder, ++ struct drm_connector *connector) ++{ ++ struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); ++ struct drm_display_mode *output_mode = &tv_norm->ctv_enc_mode.mode; ++ struct drm_display_mode *mode; ++ const struct { ++ int hdisplay; ++ int vdisplay; ++ } modes[] = { ++ { 640, 400 }, ++ { 640, 480 }, ++ { 720, 480 }, ++ { 720, 576 }, ++ { 800, 600 }, ++ { 1024, 768 }, ++ { 1280, 720 }, ++ { 1280, 1024 }, ++ { 1920, 1080 } ++ }; ++ int i, n = 0; ++ + for (i = 0; i < ARRAY_SIZE(modes); i++) { + if (modes[i].hdisplay > output_mode->hdisplay || + modes[i].vdisplay > output_mode->vdisplay) +@@ -221,11 +252,12 @@ static int nv17_tv_get_modes(struct drm_encoder *encoder, + modes[i].vdisplay == output_mode->vdisplay) { + mode = drm_mode_duplicate(encoder->dev, output_mode); + mode->type |= DRM_MODE_TYPE_PREFERRED; ++ + } else { + mode = drm_cvt_mode(encoder->dev, modes[i].hdisplay, +- modes[i].vdisplay, 60, false, +- output_mode->flags & DRM_MODE_FLAG_INTERLACE, +- false); ++ modes[i].vdisplay, 60, false, ++ (output_mode->flags & ++ DRM_MODE_FLAG_INTERLACE), false); + } + + /* CVT modes are sometimes unsuitable... */ +@@ -236,6 +268,7 @@ static int nv17_tv_get_modes(struct drm_encoder *encoder, + - mode->hdisplay) * 9 / 10) & ~7; + mode->hsync_end = mode->hsync_start + 8; + } ++ + if (output_mode->vdisplay >= 1024) { + mode->vtotal = output_mode->vtotal; + mode->vsync_start = output_mode->vsync_start; +@@ -246,9 +279,21 @@ static int nv17_tv_get_modes(struct drm_encoder *encoder, + drm_mode_probed_add(connector, mode); + n++; + } ++ + return n; + } + ++static int nv17_tv_get_modes(struct drm_encoder *encoder, ++ struct drm_connector *connector) ++{ ++ struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); ++ ++ if (tv_norm->kind == CTV_ENC_MODE) ++ return nv17_tv_get_hd_modes(encoder, connector); ++ else ++ return nv17_tv_get_ld_modes(encoder, connector); ++} ++ + static int nv17_tv_mode_valid(struct drm_encoder *encoder, + struct drm_display_mode *mode) + { +@@ -296,6 +341,9 @@ static bool nv17_tv_mode_fixup(struct drm_encoder *encoder, + { + struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); + ++ if (nv04_dac_in_use(encoder)) ++ return false; ++ + if (tv_norm->kind == CTV_ENC_MODE) + adjusted_mode->clock = tv_norm->ctv_enc_mode.mode.clock; + else +@@ -307,6 +355,8 @@ static bool nv17_tv_mode_fixup(struct drm_encoder *encoder, + static void nv17_tv_dpms(struct drm_encoder *encoder, int mode) + { + struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio; + struct nv17_tv_state *regs = &to_tv_enc(encoder)->state; + struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); + +@@ -331,8 +381,8 @@ static void nv17_tv_dpms(struct drm_encoder *encoder, int mode) + + nv_load_ptv(dev, regs, 200); + +- nv17_gpio_set(dev, DCB_GPIO_TVDAC1, mode == DRM_MODE_DPMS_ON); +- nv17_gpio_set(dev, DCB_GPIO_TVDAC0, mode == DRM_MODE_DPMS_ON); ++ gpio->set(dev, DCB_GPIO_TVDAC1, mode == DRM_MODE_DPMS_ON); ++ gpio->set(dev, DCB_GPIO_TVDAC0, mode == DRM_MODE_DPMS_ON); + + nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); + } +@@ -373,15 +423,8 @@ static void nv17_tv_prepare(struct drm_encoder *encoder) + + } + +- /* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f) +- * at LCD__INDEX which we don't alter +- */ +- if (!(*cr_lcd & 0x44)) { +- if (tv_norm->kind == CTV_ENC_MODE) +- *cr_lcd = 0x1 | (head ? 0x0 : 0x8); +- else +- *cr_lcd = 0; +- } ++ if (tv_norm->kind == CTV_ENC_MODE) ++ *cr_lcd |= 0x1 | (head ? 0x0 : 0x8); + + /* Set the DACCLK register */ + dacclk = (NVReadRAMDAC(dev, 0, dacclk_off) & ~0x30) | 0x1; +@@ -744,8 +787,10 @@ static struct drm_encoder_funcs nv17_tv_funcs = { + .destroy = nv17_tv_destroy, + }; + +-int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry) ++int ++nv17_tv_create(struct drm_connector *connector, struct dcb_entry *entry) + { ++ struct drm_device *dev = connector->dev; + struct drm_encoder *encoder; + struct nv17_tv_encoder *tv_enc = NULL; + +@@ -774,5 +819,7 @@ int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry) + encoder->possible_crtcs = entry->heads; + encoder->possible_clones = 0; + ++ nv17_tv_create_resources(encoder, connector); ++ drm_mode_connector_attach_encoder(connector, encoder); + return 0; + } +diff --git a/drivers/gpu/drm/nouveau/nv17_tv.h b/drivers/gpu/drm/nouveau/nv17_tv.h +index c00977c..6bf0384 100644 +--- a/drivers/gpu/drm/nouveau/nv17_tv.h ++++ b/drivers/gpu/drm/nouveau/nv17_tv.h +@@ -127,7 +127,8 @@ void nv17_ctv_update_rescaler(struct drm_encoder *encoder); + + /* TV hardware access functions */ + +-static inline void nv_write_ptv(struct drm_device *dev, uint32_t reg, uint32_t val) ++static inline void nv_write_ptv(struct drm_device *dev, uint32_t reg, ++ uint32_t val) + { + nv_wr32(dev, reg, val); + } +@@ -137,7 +138,8 @@ static inline uint32_t nv_read_ptv(struct drm_device *dev, uint32_t reg) + return nv_rd32(dev, reg); + } + +-static inline void nv_write_tv_enc(struct drm_device *dev, uint8_t reg, uint8_t val) ++static inline void nv_write_tv_enc(struct drm_device *dev, uint8_t reg, ++ uint8_t val) + { + nv_write_ptv(dev, NV_PTV_TV_INDEX, reg); + nv_write_ptv(dev, NV_PTV_TV_DATA, val); +@@ -149,8 +151,11 @@ static inline uint8_t nv_read_tv_enc(struct drm_device *dev, uint8_t reg) + return nv_read_ptv(dev, NV_PTV_TV_DATA); + } + +-#define nv_load_ptv(dev, state, reg) nv_write_ptv(dev, NV_PTV_OFFSET + 0x##reg, state->ptv_##reg) +-#define nv_save_ptv(dev, state, reg) state->ptv_##reg = nv_read_ptv(dev, NV_PTV_OFFSET + 0x##reg) +-#define nv_load_tv_enc(dev, state, reg) nv_write_tv_enc(dev, 0x##reg, state->tv_enc[0x##reg]) ++#define nv_load_ptv(dev, state, reg) \ ++ nv_write_ptv(dev, NV_PTV_OFFSET + 0x##reg, state->ptv_##reg) ++#define nv_save_ptv(dev, state, reg) \ ++ state->ptv_##reg = nv_read_ptv(dev, NV_PTV_OFFSET + 0x##reg) ++#define nv_load_tv_enc(dev, state, reg) \ ++ nv_write_tv_enc(dev, 0x##reg, state->tv_enc[0x##reg]) + + #endif +diff --git a/drivers/gpu/drm/nouveau/nv17_tv_modes.c b/drivers/gpu/drm/nouveau/nv17_tv_modes.c +index d64683d..9d3893c 100644 +--- a/drivers/gpu/drm/nouveau/nv17_tv_modes.c ++++ b/drivers/gpu/drm/nouveau/nv17_tv_modes.c +@@ -336,12 +336,17 @@ static void tv_setup_filter(struct drm_encoder *encoder) + struct filter_params *p = &fparams[k][j]; + + for (i = 0; i < 7; i++) { +- int64_t c = (p->k1 + p->ki*i + p->ki2*i*i + p->ki3*i*i*i) +- + (p->kr + p->kir*i + p->ki2r*i*i + p->ki3r*i*i*i)*rs[k] +- + (p->kf + p->kif*i + p->ki2f*i*i + p->ki3f*i*i*i)*flicker +- + (p->krf + p->kirf*i + p->ki2rf*i*i + p->ki3rf*i*i*i)*flicker*rs[k]; +- +- (*filters[k])[j][i] = (c + id5/2) >> 39 & (0x1 << 31 | 0x7f << 9); ++ int64_t c = (p->k1 + p->ki*i + p->ki2*i*i + ++ p->ki3*i*i*i) ++ + (p->kr + p->kir*i + p->ki2r*i*i + ++ p->ki3r*i*i*i) * rs[k] ++ + (p->kf + p->kif*i + p->ki2f*i*i + ++ p->ki3f*i*i*i) * flicker ++ + (p->krf + p->kirf*i + p->ki2rf*i*i + ++ p->ki3rf*i*i*i) * flicker * rs[k]; ++ ++ (*filters[k])[j][i] = (c + id5/2) >> 39 ++ & (0x1 << 31 | 0x7f << 9); + } + } + } +@@ -349,7 +354,8 @@ static void tv_setup_filter(struct drm_encoder *encoder) + + /* Hardware state saving/restoring */ + +-static void tv_save_filter(struct drm_device *dev, uint32_t base, uint32_t regs[4][7]) ++static void tv_save_filter(struct drm_device *dev, uint32_t base, ++ uint32_t regs[4][7]) + { + int i, j; + uint32_t offsets[] = { base, base + 0x1c, base + 0x40, base + 0x5c }; +@@ -360,7 +366,8 @@ static void tv_save_filter(struct drm_device *dev, uint32_t base, uint32_t regs[ + } + } + +-static void tv_load_filter(struct drm_device *dev, uint32_t base, uint32_t regs[4][7]) ++static void tv_load_filter(struct drm_device *dev, uint32_t base, ++ uint32_t regs[4][7]) + { + int i, j; + uint32_t offsets[] = { base, base + 0x1c, base + 0x40, base + 0x5c }; +@@ -504,10 +511,10 @@ void nv17_tv_update_properties(struct drm_encoder *encoder) + break; + } + +- regs->tv_enc[0x20] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x20], 255, +- tv_enc->saturation); +- regs->tv_enc[0x22] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x22], 255, +- tv_enc->saturation); ++ regs->tv_enc[0x20] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x20], ++ 255, tv_enc->saturation); ++ regs->tv_enc[0x22] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x22], ++ 255, tv_enc->saturation); + regs->tv_enc[0x25] = tv_enc->hue * 255 / 100; + + nv_load_ptv(dev, regs, 204); +@@ -541,7 +548,8 @@ void nv17_ctv_update_rescaler(struct drm_encoder *encoder) + int head = nouveau_crtc(encoder->crtc)->index; + struct nv04_crtc_reg *regs = &dev_priv->mode_reg.crtc_reg[head]; + struct drm_display_mode *crtc_mode = &encoder->crtc->mode; +- struct drm_display_mode *output_mode = &get_tv_norm(encoder)->ctv_enc_mode.mode; ++ struct drm_display_mode *output_mode = ++ &get_tv_norm(encoder)->ctv_enc_mode.mode; + int overscan, hmargin, vmargin, hratio, vratio; + + /* The rescaler doesn't do the right thing for interlaced modes. */ +@@ -553,13 +561,15 @@ void nv17_ctv_update_rescaler(struct drm_encoder *encoder) + hmargin = (output_mode->hdisplay - crtc_mode->hdisplay) / 2; + vmargin = (output_mode->vdisplay - crtc_mode->vdisplay) / 2; + +- hmargin = interpolate(0, min(hmargin, output_mode->hdisplay/20), hmargin, +- overscan); +- vmargin = interpolate(0, min(vmargin, output_mode->vdisplay/20), vmargin, +- overscan); ++ hmargin = interpolate(0, min(hmargin, output_mode->hdisplay/20), ++ hmargin, overscan); ++ vmargin = interpolate(0, min(vmargin, output_mode->vdisplay/20), ++ vmargin, overscan); + +- hratio = crtc_mode->hdisplay * 0x800 / (output_mode->hdisplay - 2*hmargin); +- vratio = crtc_mode->vdisplay * 0x800 / (output_mode->vdisplay - 2*vmargin) & ~3; ++ hratio = crtc_mode->hdisplay * 0x800 / ++ (output_mode->hdisplay - 2*hmargin); ++ vratio = crtc_mode->vdisplay * 0x800 / ++ (output_mode->vdisplay - 2*vmargin) & ~3; + + regs->fp_horiz_regs[FP_VALID_START] = hmargin; + regs->fp_horiz_regs[FP_VALID_END] = output_mode->hdisplay - hmargin - 1; +diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c +index d6fc0a8..93f0d8a 100644 +--- a/drivers/gpu/drm/nouveau/nv20_graph.c ++++ b/drivers/gpu/drm/nouveau/nv20_graph.c +@@ -37,49 +37,49 @@ nv20_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) + { + int i; + +- nv_wo32(dev, ctx, 0x033c/4, 0xffff0000); +- nv_wo32(dev, ctx, 0x03a0/4, 0x0fff0000); +- nv_wo32(dev, ctx, 0x03a4/4, 0x0fff0000); +- nv_wo32(dev, ctx, 0x047c/4, 0x00000101); +- nv_wo32(dev, ctx, 0x0490/4, 0x00000111); +- nv_wo32(dev, ctx, 0x04a8/4, 0x44400000); ++ nv_wo32(ctx, 0x033c, 0xffff0000); ++ nv_wo32(ctx, 0x03a0, 0x0fff0000); ++ nv_wo32(ctx, 0x03a4, 0x0fff0000); ++ nv_wo32(ctx, 0x047c, 0x00000101); ++ nv_wo32(ctx, 0x0490, 0x00000111); ++ nv_wo32(ctx, 0x04a8, 0x44400000); + for (i = 0x04d4; i <= 0x04e0; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00030303); ++ nv_wo32(ctx, i, 0x00030303); + for (i = 0x04f4; i <= 0x0500; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00080000); ++ nv_wo32(ctx, i, 0x00080000); + for (i = 0x050c; i <= 0x0518; i += 4) +- nv_wo32(dev, ctx, i/4, 0x01012000); ++ nv_wo32(ctx, i, 0x01012000); + for (i = 0x051c; i <= 0x0528; i += 4) +- nv_wo32(dev, ctx, i/4, 0x000105b8); ++ nv_wo32(ctx, i, 0x000105b8); + for (i = 0x052c; i <= 0x0538; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(ctx, i, 0x00080008); + for (i = 0x055c; i <= 0x0598; i += 4) +- nv_wo32(dev, ctx, i/4, 0x07ff0000); +- nv_wo32(dev, ctx, 0x05a4/4, 0x4b7fffff); +- nv_wo32(dev, ctx, 0x05fc/4, 0x00000001); +- nv_wo32(dev, ctx, 0x0604/4, 0x00004000); +- nv_wo32(dev, ctx, 0x0610/4, 0x00000001); +- nv_wo32(dev, ctx, 0x0618/4, 0x00040000); +- nv_wo32(dev, ctx, 0x061c/4, 0x00010000); ++ nv_wo32(ctx, i, 0x07ff0000); ++ nv_wo32(ctx, 0x05a4, 0x4b7fffff); ++ nv_wo32(ctx, 0x05fc, 0x00000001); ++ nv_wo32(ctx, 0x0604, 0x00004000); ++ nv_wo32(ctx, 0x0610, 0x00000001); ++ nv_wo32(ctx, 0x0618, 0x00040000); ++ nv_wo32(ctx, 0x061c, 0x00010000); + for (i = 0x1c1c; i <= 0x248c; i += 16) { +- nv_wo32(dev, ctx, (i + 0)/4, 0x10700ff9); +- nv_wo32(dev, ctx, (i + 4)/4, 0x0436086c); +- nv_wo32(dev, ctx, (i + 8)/4, 0x000c001b); ++ nv_wo32(ctx, (i + 0), 0x10700ff9); ++ nv_wo32(ctx, (i + 4), 0x0436086c); ++ nv_wo32(ctx, (i + 8), 0x000c001b); + } +- nv_wo32(dev, ctx, 0x281c/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x2830/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x285c/4, 0x40000000); +- nv_wo32(dev, ctx, 0x2860/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x2864/4, 0x3f000000); +- nv_wo32(dev, ctx, 0x286c/4, 0x40000000); +- nv_wo32(dev, ctx, 0x2870/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x2878/4, 0xbf800000); +- nv_wo32(dev, ctx, 0x2880/4, 0xbf800000); +- nv_wo32(dev, ctx, 0x34a4/4, 0x000fe000); +- nv_wo32(dev, ctx, 0x3530/4, 0x000003f8); +- nv_wo32(dev, ctx, 0x3540/4, 0x002fe000); ++ nv_wo32(ctx, 0x281c, 0x3f800000); ++ nv_wo32(ctx, 0x2830, 0x3f800000); ++ nv_wo32(ctx, 0x285c, 0x40000000); ++ nv_wo32(ctx, 0x2860, 0x3f800000); ++ nv_wo32(ctx, 0x2864, 0x3f000000); ++ nv_wo32(ctx, 0x286c, 0x40000000); ++ nv_wo32(ctx, 0x2870, 0x3f800000); ++ nv_wo32(ctx, 0x2878, 0xbf800000); ++ nv_wo32(ctx, 0x2880, 0xbf800000); ++ nv_wo32(ctx, 0x34a4, 0x000fe000); ++ nv_wo32(ctx, 0x3530, 0x000003f8); ++ nv_wo32(ctx, 0x3540, 0x002fe000); + for (i = 0x355c; i <= 0x3578; i += 4) +- nv_wo32(dev, ctx, i/4, 0x001c527c); ++ nv_wo32(ctx, i, 0x001c527c); + } + + static void +@@ -87,58 +87,58 @@ nv25_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) + { + int i; + +- nv_wo32(dev, ctx, 0x035c/4, 0xffff0000); +- nv_wo32(dev, ctx, 0x03c0/4, 0x0fff0000); +- nv_wo32(dev, ctx, 0x03c4/4, 0x0fff0000); +- nv_wo32(dev, ctx, 0x049c/4, 0x00000101); +- nv_wo32(dev, ctx, 0x04b0/4, 0x00000111); +- nv_wo32(dev, ctx, 0x04c8/4, 0x00000080); +- nv_wo32(dev, ctx, 0x04cc/4, 0xffff0000); +- nv_wo32(dev, ctx, 0x04d0/4, 0x00000001); +- nv_wo32(dev, ctx, 0x04e4/4, 0x44400000); +- nv_wo32(dev, ctx, 0x04fc/4, 0x4b800000); ++ nv_wo32(ctx, 0x035c, 0xffff0000); ++ nv_wo32(ctx, 0x03c0, 0x0fff0000); ++ nv_wo32(ctx, 0x03c4, 0x0fff0000); ++ nv_wo32(ctx, 0x049c, 0x00000101); ++ nv_wo32(ctx, 0x04b0, 0x00000111); ++ nv_wo32(ctx, 0x04c8, 0x00000080); ++ nv_wo32(ctx, 0x04cc, 0xffff0000); ++ nv_wo32(ctx, 0x04d0, 0x00000001); ++ nv_wo32(ctx, 0x04e4, 0x44400000); ++ nv_wo32(ctx, 0x04fc, 0x4b800000); + for (i = 0x0510; i <= 0x051c; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00030303); ++ nv_wo32(ctx, i, 0x00030303); + for (i = 0x0530; i <= 0x053c; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00080000); ++ nv_wo32(ctx, i, 0x00080000); + for (i = 0x0548; i <= 0x0554; i += 4) +- nv_wo32(dev, ctx, i/4, 0x01012000); ++ nv_wo32(ctx, i, 0x01012000); + for (i = 0x0558; i <= 0x0564; i += 4) +- nv_wo32(dev, ctx, i/4, 0x000105b8); ++ nv_wo32(ctx, i, 0x000105b8); + for (i = 0x0568; i <= 0x0574; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(ctx, i, 0x00080008); + for (i = 0x0598; i <= 0x05d4; i += 4) +- nv_wo32(dev, ctx, i/4, 0x07ff0000); +- nv_wo32(dev, ctx, 0x05e0/4, 0x4b7fffff); +- nv_wo32(dev, ctx, 0x0620/4, 0x00000080); +- nv_wo32(dev, ctx, 0x0624/4, 0x30201000); +- nv_wo32(dev, ctx, 0x0628/4, 0x70605040); +- nv_wo32(dev, ctx, 0x062c/4, 0xb0a09080); +- nv_wo32(dev, ctx, 0x0630/4, 0xf0e0d0c0); +- nv_wo32(dev, ctx, 0x0664/4, 0x00000001); +- nv_wo32(dev, ctx, 0x066c/4, 0x00004000); +- nv_wo32(dev, ctx, 0x0678/4, 0x00000001); +- nv_wo32(dev, ctx, 0x0680/4, 0x00040000); +- nv_wo32(dev, ctx, 0x0684/4, 0x00010000); ++ nv_wo32(ctx, i, 0x07ff0000); ++ nv_wo32(ctx, 0x05e0, 0x4b7fffff); ++ nv_wo32(ctx, 0x0620, 0x00000080); ++ nv_wo32(ctx, 0x0624, 0x30201000); ++ nv_wo32(ctx, 0x0628, 0x70605040); ++ nv_wo32(ctx, 0x062c, 0xb0a09080); ++ nv_wo32(ctx, 0x0630, 0xf0e0d0c0); ++ nv_wo32(ctx, 0x0664, 0x00000001); ++ nv_wo32(ctx, 0x066c, 0x00004000); ++ nv_wo32(ctx, 0x0678, 0x00000001); ++ nv_wo32(ctx, 0x0680, 0x00040000); ++ nv_wo32(ctx, 0x0684, 0x00010000); + for (i = 0x1b04; i <= 0x2374; i += 16) { +- nv_wo32(dev, ctx, (i + 0)/4, 0x10700ff9); +- nv_wo32(dev, ctx, (i + 4)/4, 0x0436086c); +- nv_wo32(dev, ctx, (i + 8)/4, 0x000c001b); ++ nv_wo32(ctx, (i + 0), 0x10700ff9); ++ nv_wo32(ctx, (i + 4), 0x0436086c); ++ nv_wo32(ctx, (i + 8), 0x000c001b); + } +- nv_wo32(dev, ctx, 0x2704/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x2718/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x2744/4, 0x40000000); +- nv_wo32(dev, ctx, 0x2748/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x274c/4, 0x3f000000); +- nv_wo32(dev, ctx, 0x2754/4, 0x40000000); +- nv_wo32(dev, ctx, 0x2758/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x2760/4, 0xbf800000); +- nv_wo32(dev, ctx, 0x2768/4, 0xbf800000); +- nv_wo32(dev, ctx, 0x308c/4, 0x000fe000); +- nv_wo32(dev, ctx, 0x3108/4, 0x000003f8); +- nv_wo32(dev, ctx, 0x3468/4, 0x002fe000); ++ nv_wo32(ctx, 0x2704, 0x3f800000); ++ nv_wo32(ctx, 0x2718, 0x3f800000); ++ nv_wo32(ctx, 0x2744, 0x40000000); ++ nv_wo32(ctx, 0x2748, 0x3f800000); ++ nv_wo32(ctx, 0x274c, 0x3f000000); ++ nv_wo32(ctx, 0x2754, 0x40000000); ++ nv_wo32(ctx, 0x2758, 0x3f800000); ++ nv_wo32(ctx, 0x2760, 0xbf800000); ++ nv_wo32(ctx, 0x2768, 0xbf800000); ++ nv_wo32(ctx, 0x308c, 0x000fe000); ++ nv_wo32(ctx, 0x3108, 0x000003f8); ++ nv_wo32(ctx, 0x3468, 0x002fe000); + for (i = 0x3484; i <= 0x34a0; i += 4) +- nv_wo32(dev, ctx, i/4, 0x001c527c); ++ nv_wo32(ctx, i, 0x001c527c); + } + + static void +@@ -146,49 +146,49 @@ nv2a_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) + { + int i; + +- nv_wo32(dev, ctx, 0x033c/4, 0xffff0000); +- nv_wo32(dev, ctx, 0x03a0/4, 0x0fff0000); +- nv_wo32(dev, ctx, 0x03a4/4, 0x0fff0000); +- nv_wo32(dev, ctx, 0x047c/4, 0x00000101); +- nv_wo32(dev, ctx, 0x0490/4, 0x00000111); +- nv_wo32(dev, ctx, 0x04a8/4, 0x44400000); ++ nv_wo32(ctx, 0x033c, 0xffff0000); ++ nv_wo32(ctx, 0x03a0, 0x0fff0000); ++ nv_wo32(ctx, 0x03a4, 0x0fff0000); ++ nv_wo32(ctx, 0x047c, 0x00000101); ++ nv_wo32(ctx, 0x0490, 0x00000111); ++ nv_wo32(ctx, 0x04a8, 0x44400000); + for (i = 0x04d4; i <= 0x04e0; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00030303); ++ nv_wo32(ctx, i, 0x00030303); + for (i = 0x04f4; i <= 0x0500; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00080000); ++ nv_wo32(ctx, i, 0x00080000); + for (i = 0x050c; i <= 0x0518; i += 4) +- nv_wo32(dev, ctx, i/4, 0x01012000); ++ nv_wo32(ctx, i, 0x01012000); + for (i = 0x051c; i <= 0x0528; i += 4) +- nv_wo32(dev, ctx, i/4, 0x000105b8); ++ nv_wo32(ctx, i, 0x000105b8); + for (i = 0x052c; i <= 0x0538; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(ctx, i, 0x00080008); + for (i = 0x055c; i <= 0x0598; i += 4) +- nv_wo32(dev, ctx, i/4, 0x07ff0000); +- nv_wo32(dev, ctx, 0x05a4/4, 0x4b7fffff); +- nv_wo32(dev, ctx, 0x05fc/4, 0x00000001); +- nv_wo32(dev, ctx, 0x0604/4, 0x00004000); +- nv_wo32(dev, ctx, 0x0610/4, 0x00000001); +- nv_wo32(dev, ctx, 0x0618/4, 0x00040000); +- nv_wo32(dev, ctx, 0x061c/4, 0x00010000); ++ nv_wo32(ctx, i, 0x07ff0000); ++ nv_wo32(ctx, 0x05a4, 0x4b7fffff); ++ nv_wo32(ctx, 0x05fc, 0x00000001); ++ nv_wo32(ctx, 0x0604, 0x00004000); ++ nv_wo32(ctx, 0x0610, 0x00000001); ++ nv_wo32(ctx, 0x0618, 0x00040000); ++ nv_wo32(ctx, 0x061c, 0x00010000); + for (i = 0x1a9c; i <= 0x22fc; i += 16) { /*XXX: check!! */ +- nv_wo32(dev, ctx, (i + 0)/4, 0x10700ff9); +- nv_wo32(dev, ctx, (i + 4)/4, 0x0436086c); +- nv_wo32(dev, ctx, (i + 8)/4, 0x000c001b); ++ nv_wo32(ctx, (i + 0), 0x10700ff9); ++ nv_wo32(ctx, (i + 4), 0x0436086c); ++ nv_wo32(ctx, (i + 8), 0x000c001b); + } +- nv_wo32(dev, ctx, 0x269c/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x26b0/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x26dc/4, 0x40000000); +- nv_wo32(dev, ctx, 0x26e0/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x26e4/4, 0x3f000000); +- nv_wo32(dev, ctx, 0x26ec/4, 0x40000000); +- nv_wo32(dev, ctx, 0x26f0/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x26f8/4, 0xbf800000); +- nv_wo32(dev, ctx, 0x2700/4, 0xbf800000); +- nv_wo32(dev, ctx, 0x3024/4, 0x000fe000); +- nv_wo32(dev, ctx, 0x30a0/4, 0x000003f8); +- nv_wo32(dev, ctx, 0x33fc/4, 0x002fe000); ++ nv_wo32(ctx, 0x269c, 0x3f800000); ++ nv_wo32(ctx, 0x26b0, 0x3f800000); ++ nv_wo32(ctx, 0x26dc, 0x40000000); ++ nv_wo32(ctx, 0x26e0, 0x3f800000); ++ nv_wo32(ctx, 0x26e4, 0x3f000000); ++ nv_wo32(ctx, 0x26ec, 0x40000000); ++ nv_wo32(ctx, 0x26f0, 0x3f800000); ++ nv_wo32(ctx, 0x26f8, 0xbf800000); ++ nv_wo32(ctx, 0x2700, 0xbf800000); ++ nv_wo32(ctx, 0x3024, 0x000fe000); ++ nv_wo32(ctx, 0x30a0, 0x000003f8); ++ nv_wo32(ctx, 0x33fc, 0x002fe000); + for (i = 0x341c; i <= 0x3438; i += 4) +- nv_wo32(dev, ctx, i/4, 0x001c527c); ++ nv_wo32(ctx, i, 0x001c527c); + } + + static void +@@ -196,57 +196,57 @@ nv30_31_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) + { + int i; + +- nv_wo32(dev, ctx, 0x0410/4, 0x00000101); +- nv_wo32(dev, ctx, 0x0424/4, 0x00000111); +- nv_wo32(dev, ctx, 0x0428/4, 0x00000060); +- nv_wo32(dev, ctx, 0x0444/4, 0x00000080); +- nv_wo32(dev, ctx, 0x0448/4, 0xffff0000); +- nv_wo32(dev, ctx, 0x044c/4, 0x00000001); +- nv_wo32(dev, ctx, 0x0460/4, 0x44400000); +- nv_wo32(dev, ctx, 0x048c/4, 0xffff0000); ++ nv_wo32(ctx, 0x0410, 0x00000101); ++ nv_wo32(ctx, 0x0424, 0x00000111); ++ nv_wo32(ctx, 0x0428, 0x00000060); ++ nv_wo32(ctx, 0x0444, 0x00000080); ++ nv_wo32(ctx, 0x0448, 0xffff0000); ++ nv_wo32(ctx, 0x044c, 0x00000001); ++ nv_wo32(ctx, 0x0460, 0x44400000); ++ nv_wo32(ctx, 0x048c, 0xffff0000); + for (i = 0x04e0; i < 0x04e8; i += 4) +- nv_wo32(dev, ctx, i/4, 0x0fff0000); +- nv_wo32(dev, ctx, 0x04ec/4, 0x00011100); ++ nv_wo32(ctx, i, 0x0fff0000); ++ nv_wo32(ctx, 0x04ec, 0x00011100); + for (i = 0x0508; i < 0x0548; i += 4) +- nv_wo32(dev, ctx, i/4, 0x07ff0000); +- nv_wo32(dev, ctx, 0x0550/4, 0x4b7fffff); +- nv_wo32(dev, ctx, 0x058c/4, 0x00000080); +- nv_wo32(dev, ctx, 0x0590/4, 0x30201000); +- nv_wo32(dev, ctx, 0x0594/4, 0x70605040); +- nv_wo32(dev, ctx, 0x0598/4, 0xb8a89888); +- nv_wo32(dev, ctx, 0x059c/4, 0xf8e8d8c8); +- nv_wo32(dev, ctx, 0x05b0/4, 0xb0000000); ++ nv_wo32(ctx, i, 0x07ff0000); ++ nv_wo32(ctx, 0x0550, 0x4b7fffff); ++ nv_wo32(ctx, 0x058c, 0x00000080); ++ nv_wo32(ctx, 0x0590, 0x30201000); ++ nv_wo32(ctx, 0x0594, 0x70605040); ++ nv_wo32(ctx, 0x0598, 0xb8a89888); ++ nv_wo32(ctx, 0x059c, 0xf8e8d8c8); ++ nv_wo32(ctx, 0x05b0, 0xb0000000); + for (i = 0x0600; i < 0x0640; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00010588); ++ nv_wo32(ctx, i, 0x00010588); + for (i = 0x0640; i < 0x0680; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00030303); ++ nv_wo32(ctx, i, 0x00030303); + for (i = 0x06c0; i < 0x0700; i += 4) +- nv_wo32(dev, ctx, i/4, 0x0008aae4); ++ nv_wo32(ctx, i, 0x0008aae4); + for (i = 0x0700; i < 0x0740; i += 4) +- nv_wo32(dev, ctx, i/4, 0x01012000); ++ nv_wo32(ctx, i, 0x01012000); + for (i = 0x0740; i < 0x0780; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00080008); +- nv_wo32(dev, ctx, 0x085c/4, 0x00040000); +- nv_wo32(dev, ctx, 0x0860/4, 0x00010000); ++ nv_wo32(ctx, i, 0x00080008); ++ nv_wo32(ctx, 0x085c, 0x00040000); ++ nv_wo32(ctx, 0x0860, 0x00010000); + for (i = 0x0864; i < 0x0874; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00040004); ++ nv_wo32(ctx, i, 0x00040004); + for (i = 0x1f18; i <= 0x3088 ; i += 16) { +- nv_wo32(dev, ctx, i/4 + 0, 0x10700ff9); +- nv_wo32(dev, ctx, i/4 + 1, 0x0436086c); +- nv_wo32(dev, ctx, i/4 + 2, 0x000c001b); ++ nv_wo32(ctx, i + 0, 0x10700ff9); ++ nv_wo32(ctx, i + 1, 0x0436086c); ++ nv_wo32(ctx, i + 2, 0x000c001b); + } + for (i = 0x30b8; i < 0x30c8; i += 4) +- nv_wo32(dev, ctx, i/4, 0x0000ffff); +- nv_wo32(dev, ctx, 0x344c/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x3808/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x381c/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x3848/4, 0x40000000); +- nv_wo32(dev, ctx, 0x384c/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x3850/4, 0x3f000000); +- nv_wo32(dev, ctx, 0x3858/4, 0x40000000); +- nv_wo32(dev, ctx, 0x385c/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x3864/4, 0xbf800000); +- nv_wo32(dev, ctx, 0x386c/4, 0xbf800000); ++ nv_wo32(ctx, i, 0x0000ffff); ++ nv_wo32(ctx, 0x344c, 0x3f800000); ++ nv_wo32(ctx, 0x3808, 0x3f800000); ++ nv_wo32(ctx, 0x381c, 0x3f800000); ++ nv_wo32(ctx, 0x3848, 0x40000000); ++ nv_wo32(ctx, 0x384c, 0x3f800000); ++ nv_wo32(ctx, 0x3850, 0x3f000000); ++ nv_wo32(ctx, 0x3858, 0x40000000); ++ nv_wo32(ctx, 0x385c, 0x3f800000); ++ nv_wo32(ctx, 0x3864, 0xbf800000); ++ nv_wo32(ctx, 0x386c, 0xbf800000); + } + + static void +@@ -254,57 +254,57 @@ nv34_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) + { + int i; + +- nv_wo32(dev, ctx, 0x040c/4, 0x01000101); +- nv_wo32(dev, ctx, 0x0420/4, 0x00000111); +- nv_wo32(dev, ctx, 0x0424/4, 0x00000060); +- nv_wo32(dev, ctx, 0x0440/4, 0x00000080); +- nv_wo32(dev, ctx, 0x0444/4, 0xffff0000); +- nv_wo32(dev, ctx, 0x0448/4, 0x00000001); +- nv_wo32(dev, ctx, 0x045c/4, 0x44400000); +- nv_wo32(dev, ctx, 0x0480/4, 0xffff0000); ++ nv_wo32(ctx, 0x040c, 0x01000101); ++ nv_wo32(ctx, 0x0420, 0x00000111); ++ nv_wo32(ctx, 0x0424, 0x00000060); ++ nv_wo32(ctx, 0x0440, 0x00000080); ++ nv_wo32(ctx, 0x0444, 0xffff0000); ++ nv_wo32(ctx, 0x0448, 0x00000001); ++ nv_wo32(ctx, 0x045c, 0x44400000); ++ nv_wo32(ctx, 0x0480, 0xffff0000); + for (i = 0x04d4; i < 0x04dc; i += 4) +- nv_wo32(dev, ctx, i/4, 0x0fff0000); +- nv_wo32(dev, ctx, 0x04e0/4, 0x00011100); ++ nv_wo32(ctx, i, 0x0fff0000); ++ nv_wo32(ctx, 0x04e0, 0x00011100); + for (i = 0x04fc; i < 0x053c; i += 4) +- nv_wo32(dev, ctx, i/4, 0x07ff0000); +- nv_wo32(dev, ctx, 0x0544/4, 0x4b7fffff); +- nv_wo32(dev, ctx, 0x057c/4, 0x00000080); +- nv_wo32(dev, ctx, 0x0580/4, 0x30201000); +- nv_wo32(dev, ctx, 0x0584/4, 0x70605040); +- nv_wo32(dev, ctx, 0x0588/4, 0xb8a89888); +- nv_wo32(dev, ctx, 0x058c/4, 0xf8e8d8c8); +- nv_wo32(dev, ctx, 0x05a0/4, 0xb0000000); ++ nv_wo32(ctx, i, 0x07ff0000); ++ nv_wo32(ctx, 0x0544, 0x4b7fffff); ++ nv_wo32(ctx, 0x057c, 0x00000080); ++ nv_wo32(ctx, 0x0580, 0x30201000); ++ nv_wo32(ctx, 0x0584, 0x70605040); ++ nv_wo32(ctx, 0x0588, 0xb8a89888); ++ nv_wo32(ctx, 0x058c, 0xf8e8d8c8); ++ nv_wo32(ctx, 0x05a0, 0xb0000000); + for (i = 0x05f0; i < 0x0630; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00010588); ++ nv_wo32(ctx, i, 0x00010588); + for (i = 0x0630; i < 0x0670; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00030303); ++ nv_wo32(ctx, i, 0x00030303); + for (i = 0x06b0; i < 0x06f0; i += 4) +- nv_wo32(dev, ctx, i/4, 0x0008aae4); ++ nv_wo32(ctx, i, 0x0008aae4); + for (i = 0x06f0; i < 0x0730; i += 4) +- nv_wo32(dev, ctx, i/4, 0x01012000); ++ nv_wo32(ctx, i, 0x01012000); + for (i = 0x0730; i < 0x0770; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00080008); +- nv_wo32(dev, ctx, 0x0850/4, 0x00040000); +- nv_wo32(dev, ctx, 0x0854/4, 0x00010000); ++ nv_wo32(ctx, i, 0x00080008); ++ nv_wo32(ctx, 0x0850, 0x00040000); ++ nv_wo32(ctx, 0x0854, 0x00010000); + for (i = 0x0858; i < 0x0868; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00040004); ++ nv_wo32(ctx, i, 0x00040004); + for (i = 0x15ac; i <= 0x271c ; i += 16) { +- nv_wo32(dev, ctx, i/4 + 0, 0x10700ff9); +- nv_wo32(dev, ctx, i/4 + 1, 0x0436086c); +- nv_wo32(dev, ctx, i/4 + 2, 0x000c001b); ++ nv_wo32(ctx, i + 0, 0x10700ff9); ++ nv_wo32(ctx, i + 1, 0x0436086c); ++ nv_wo32(ctx, i + 2, 0x000c001b); + } + for (i = 0x274c; i < 0x275c; i += 4) +- nv_wo32(dev, ctx, i/4, 0x0000ffff); +- nv_wo32(dev, ctx, 0x2ae0/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x2e9c/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x2eb0/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x2edc/4, 0x40000000); +- nv_wo32(dev, ctx, 0x2ee0/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x2ee4/4, 0x3f000000); +- nv_wo32(dev, ctx, 0x2eec/4, 0x40000000); +- nv_wo32(dev, ctx, 0x2ef0/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x2ef8/4, 0xbf800000); +- nv_wo32(dev, ctx, 0x2f00/4, 0xbf800000); ++ nv_wo32(ctx, i, 0x0000ffff); ++ nv_wo32(ctx, 0x2ae0, 0x3f800000); ++ nv_wo32(ctx, 0x2e9c, 0x3f800000); ++ nv_wo32(ctx, 0x2eb0, 0x3f800000); ++ nv_wo32(ctx, 0x2edc, 0x40000000); ++ nv_wo32(ctx, 0x2ee0, 0x3f800000); ++ nv_wo32(ctx, 0x2ee4, 0x3f000000); ++ nv_wo32(ctx, 0x2eec, 0x40000000); ++ nv_wo32(ctx, 0x2ef0, 0x3f800000); ++ nv_wo32(ctx, 0x2ef8, 0xbf800000); ++ nv_wo32(ctx, 0x2f00, 0xbf800000); + } + + static void +@@ -312,57 +312,57 @@ nv35_36_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) + { + int i; + +- nv_wo32(dev, ctx, 0x040c/4, 0x00000101); +- nv_wo32(dev, ctx, 0x0420/4, 0x00000111); +- nv_wo32(dev, ctx, 0x0424/4, 0x00000060); +- nv_wo32(dev, ctx, 0x0440/4, 0x00000080); +- nv_wo32(dev, ctx, 0x0444/4, 0xffff0000); +- nv_wo32(dev, ctx, 0x0448/4, 0x00000001); +- nv_wo32(dev, ctx, 0x045c/4, 0x44400000); +- nv_wo32(dev, ctx, 0x0488/4, 0xffff0000); ++ nv_wo32(ctx, 0x040c, 0x00000101); ++ nv_wo32(ctx, 0x0420, 0x00000111); ++ nv_wo32(ctx, 0x0424, 0x00000060); ++ nv_wo32(ctx, 0x0440, 0x00000080); ++ nv_wo32(ctx, 0x0444, 0xffff0000); ++ nv_wo32(ctx, 0x0448, 0x00000001); ++ nv_wo32(ctx, 0x045c, 0x44400000); ++ nv_wo32(ctx, 0x0488, 0xffff0000); + for (i = 0x04dc; i < 0x04e4; i += 4) +- nv_wo32(dev, ctx, i/4, 0x0fff0000); +- nv_wo32(dev, ctx, 0x04e8/4, 0x00011100); ++ nv_wo32(ctx, i, 0x0fff0000); ++ nv_wo32(ctx, 0x04e8, 0x00011100); + for (i = 0x0504; i < 0x0544; i += 4) +- nv_wo32(dev, ctx, i/4, 0x07ff0000); +- nv_wo32(dev, ctx, 0x054c/4, 0x4b7fffff); +- nv_wo32(dev, ctx, 0x0588/4, 0x00000080); +- nv_wo32(dev, ctx, 0x058c/4, 0x30201000); +- nv_wo32(dev, ctx, 0x0590/4, 0x70605040); +- nv_wo32(dev, ctx, 0x0594/4, 0xb8a89888); +- nv_wo32(dev, ctx, 0x0598/4, 0xf8e8d8c8); +- nv_wo32(dev, ctx, 0x05ac/4, 0xb0000000); ++ nv_wo32(ctx, i, 0x07ff0000); ++ nv_wo32(ctx, 0x054c, 0x4b7fffff); ++ nv_wo32(ctx, 0x0588, 0x00000080); ++ nv_wo32(ctx, 0x058c, 0x30201000); ++ nv_wo32(ctx, 0x0590, 0x70605040); ++ nv_wo32(ctx, 0x0594, 0xb8a89888); ++ nv_wo32(ctx, 0x0598, 0xf8e8d8c8); ++ nv_wo32(ctx, 0x05ac, 0xb0000000); + for (i = 0x0604; i < 0x0644; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00010588); ++ nv_wo32(ctx, i, 0x00010588); + for (i = 0x0644; i < 0x0684; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00030303); ++ nv_wo32(ctx, i, 0x00030303); + for (i = 0x06c4; i < 0x0704; i += 4) +- nv_wo32(dev, ctx, i/4, 0x0008aae4); ++ nv_wo32(ctx, i, 0x0008aae4); + for (i = 0x0704; i < 0x0744; i += 4) +- nv_wo32(dev, ctx, i/4, 0x01012000); ++ nv_wo32(ctx, i, 0x01012000); + for (i = 0x0744; i < 0x0784; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00080008); +- nv_wo32(dev, ctx, 0x0860/4, 0x00040000); +- nv_wo32(dev, ctx, 0x0864/4, 0x00010000); ++ nv_wo32(ctx, i, 0x00080008); ++ nv_wo32(ctx, 0x0860, 0x00040000); ++ nv_wo32(ctx, 0x0864, 0x00010000); + for (i = 0x0868; i < 0x0878; i += 4) +- nv_wo32(dev, ctx, i/4, 0x00040004); ++ nv_wo32(ctx, i, 0x00040004); + for (i = 0x1f1c; i <= 0x308c ; i += 16) { +- nv_wo32(dev, ctx, i/4 + 0, 0x10700ff9); +- nv_wo32(dev, ctx, i/4 + 1, 0x0436086c); +- nv_wo32(dev, ctx, i/4 + 2, 0x000c001b); ++ nv_wo32(ctx, i + 0, 0x10700ff9); ++ nv_wo32(ctx, i + 4, 0x0436086c); ++ nv_wo32(ctx, i + 8, 0x000c001b); + } + for (i = 0x30bc; i < 0x30cc; i += 4) +- nv_wo32(dev, ctx, i/4, 0x0000ffff); +- nv_wo32(dev, ctx, 0x3450/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x380c/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x3820/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x384c/4, 0x40000000); +- nv_wo32(dev, ctx, 0x3850/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x3854/4, 0x3f000000); +- nv_wo32(dev, ctx, 0x385c/4, 0x40000000); +- nv_wo32(dev, ctx, 0x3860/4, 0x3f800000); +- nv_wo32(dev, ctx, 0x3868/4, 0xbf800000); +- nv_wo32(dev, ctx, 0x3870/4, 0xbf800000); ++ nv_wo32(ctx, i, 0x0000ffff); ++ nv_wo32(ctx, 0x3450, 0x3f800000); ++ nv_wo32(ctx, 0x380c, 0x3f800000); ++ nv_wo32(ctx, 0x3820, 0x3f800000); ++ nv_wo32(ctx, 0x384c, 0x40000000); ++ nv_wo32(ctx, 0x3850, 0x3f800000); ++ nv_wo32(ctx, 0x3854, 0x3f000000); ++ nv_wo32(ctx, 0x385c, 0x40000000); ++ nv_wo32(ctx, 0x3860, 0x3f800000); ++ nv_wo32(ctx, 0x3868, 0xbf800000); ++ nv_wo32(ctx, 0x3870, 0xbf800000); + } + + int +@@ -370,68 +370,52 @@ nv20_graph_create_context(struct nouveau_channel *chan) + { + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *); +- unsigned int ctx_size; +- unsigned int idoffs = 0x28/4; ++ unsigned int idoffs = 0x28; + int ret; + + switch (dev_priv->chipset) { + case 0x20: +- ctx_size = NV20_GRCTX_SIZE; + ctx_init = nv20_graph_context_init; + idoffs = 0; + break; + case 0x25: + case 0x28: +- ctx_size = NV25_GRCTX_SIZE; + ctx_init = nv25_graph_context_init; + break; + case 0x2a: +- ctx_size = NV2A_GRCTX_SIZE; + ctx_init = nv2a_graph_context_init; + idoffs = 0; + break; + case 0x30: + case 0x31: +- ctx_size = NV30_31_GRCTX_SIZE; + ctx_init = nv30_31_graph_context_init; + break; + case 0x34: +- ctx_size = NV34_GRCTX_SIZE; + ctx_init = nv34_graph_context_init; + break; + case 0x35: + case 0x36: +- ctx_size = NV35_36_GRCTX_SIZE; + ctx_init = nv35_36_graph_context_init; + break; + default: +- ctx_size = 0; +- ctx_init = nv35_36_graph_context_init; +- NV_ERROR(dev, "Please contact the devs if you want your NV%x" +- " card to work\n", dev_priv->chipset); +- return -ENOSYS; +- break; ++ BUG_ON(1); + } + +- ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16, +- NVOBJ_FLAG_ZERO_ALLOC, +- &chan->ramin_grctx); ++ ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin_grctx); + if (ret) + return ret; + + /* Initialise default context values */ +- dev_priv->engine.instmem.prepare_access(dev, true); +- ctx_init(dev, chan->ramin_grctx->gpuobj); ++ ctx_init(dev, chan->ramin_grctx); + + /* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */ +- nv_wo32(dev, chan->ramin_grctx->gpuobj, idoffs, +- (chan->id << 24) | 0x1); /* CTX_USER */ ++ nv_wo32(chan->ramin_grctx, idoffs, ++ (chan->id << 24) | 0x1); /* CTX_USER */ + +- nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id, +- chan->ramin_grctx->instance >> 4); +- +- dev_priv->engine.instmem.finish_access(dev); ++ nv_wo32(pgraph->ctx_table, chan->id * 4, chan->ramin_grctx->pinst >> 4); + return 0; + } + +@@ -440,13 +424,10 @@ nv20_graph_destroy_context(struct nouveau_channel *chan) + { + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + +- if (chan->ramin_grctx) +- nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); +- +- dev_priv->engine.instmem.prepare_access(dev, true); +- nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id, 0); +- dev_priv->engine.instmem.finish_access(dev); ++ nouveau_gpuobj_ref(NULL, &chan->ramin_grctx); ++ nv_wo32(pgraph->ctx_table, chan->id * 4, 0); + } + + int +@@ -457,7 +438,7 @@ nv20_graph_load_context(struct nouveau_channel *chan) + + if (!chan->ramin_grctx) + return -EINVAL; +- inst = chan->ramin_grctx->instance >> 4; ++ inst = chan->ramin_grctx->pinst >> 4; + + nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); + nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER, +@@ -480,7 +461,7 @@ nv20_graph_unload_context(struct drm_device *dev) + chan = pgraph->channel(dev); + if (!chan) + return 0; +- inst = chan->ramin_grctx->instance >> 4; ++ inst = chan->ramin_grctx->pinst >> 4; + + nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); + nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER, +@@ -538,29 +519,44 @@ nv20_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, + int + nv20_graph_init(struct drm_device *dev) + { +- struct drm_nouveau_private *dev_priv = +- (struct drm_nouveau_private *)dev->dev_private; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + uint32_t tmp, vramsz; + int ret, i; + ++ switch (dev_priv->chipset) { ++ case 0x20: ++ pgraph->grctx_size = NV20_GRCTX_SIZE; ++ break; ++ case 0x25: ++ case 0x28: ++ pgraph->grctx_size = NV25_GRCTX_SIZE; ++ break; ++ case 0x2a: ++ pgraph->grctx_size = NV2A_GRCTX_SIZE; ++ break; ++ default: ++ NV_ERROR(dev, "unknown chipset, disabling acceleration\n"); ++ pgraph->accel_blocked = true; ++ return 0; ++ } ++ + nv_wr32(dev, NV03_PMC_ENABLE, + nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); + nv_wr32(dev, NV03_PMC_ENABLE, + nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); + +- if (!dev_priv->ctx_table) { ++ if (!pgraph->ctx_table) { + /* Create Context Pointer Table */ +- dev_priv->ctx_table_size = 32 * 4; +- ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, +- dev_priv->ctx_table_size, 16, +- NVOBJ_FLAG_ZERO_ALLOC, +- &dev_priv->ctx_table); ++ ret = nouveau_gpuobj_new(dev, NULL, 32 * 4, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, ++ &pgraph->ctx_table); + if (ret) + return ret; + } + + nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, +- dev_priv->ctx_table->instance >> 4); ++ pgraph->ctx_table->pinst >> 4); + + nv20_graph_rdi(dev); + +@@ -644,34 +640,52 @@ void + nv20_graph_takedown(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + +- nouveau_gpuobj_ref_del(dev, &dev_priv->ctx_table); ++ nouveau_gpuobj_ref(NULL, &pgraph->ctx_table); + } + + int + nv30_graph_init(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + int ret, i; + ++ switch (dev_priv->chipset) { ++ case 0x30: ++ case 0x31: ++ pgraph->grctx_size = NV30_31_GRCTX_SIZE; ++ break; ++ case 0x34: ++ pgraph->grctx_size = NV34_GRCTX_SIZE; ++ break; ++ case 0x35: ++ case 0x36: ++ pgraph->grctx_size = NV35_36_GRCTX_SIZE; ++ break; ++ default: ++ NV_ERROR(dev, "unknown chipset, disabling acceleration\n"); ++ pgraph->accel_blocked = true; ++ return 0; ++ } ++ + nv_wr32(dev, NV03_PMC_ENABLE, + nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); + nv_wr32(dev, NV03_PMC_ENABLE, + nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); + +- if (!dev_priv->ctx_table) { ++ if (!pgraph->ctx_table) { + /* Create Context Pointer Table */ +- dev_priv->ctx_table_size = 32 * 4; +- ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, +- dev_priv->ctx_table_size, 16, +- NVOBJ_FLAG_ZERO_ALLOC, +- &dev_priv->ctx_table); ++ ret = nouveau_gpuobj_new(dev, NULL, 32 * 4, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, ++ &pgraph->ctx_table); + if (ret) + return ret; + } + + nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, +- dev_priv->ctx_table->instance >> 4); ++ pgraph->ctx_table->pinst >> 4); + + nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); + nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); +diff --git a/drivers/gpu/drm/nouveau/nv30_fb.c b/drivers/gpu/drm/nouveau/nv30_fb.c +new file mode 100644 +index 0000000..4a3f2f0 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv30_fb.c +@@ -0,0 +1,95 @@ ++/* ++ * Copyright (C) 2010 Francisco Jerez. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++static int ++calc_bias(struct drm_device *dev, int k, int i, int j) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int b = (dev_priv->chipset > 0x30 ? ++ nv_rd32(dev, 0x122c + 0x10 * k + 0x4 * j) >> (4 * (i ^ 1)) : ++ 0) & 0xf; ++ ++ return 2 * (b & 0x8 ? b - 0x10 : b); ++} ++ ++static int ++calc_ref(struct drm_device *dev, int l, int k, int i) ++{ ++ int j, x = 0; ++ ++ for (j = 0; j < 4; j++) { ++ int m = (l >> (8 * i) & 0xff) + calc_bias(dev, k, i, j); ++ ++ x |= (0x80 | clamp(m, 0, 0x1f)) << (8 * j); ++ } ++ ++ return x; ++} ++ ++int ++nv30_fb_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; ++ int i, j; ++ ++ pfb->num_tiles = NV10_PFB_TILE__SIZE; ++ ++ /* Turn all the tiling regions off. */ ++ for (i = 0; i < pfb->num_tiles; i++) ++ pfb->set_region_tiling(dev, i, 0, 0, 0); ++ ++ /* Init the memory timing regs at 0x10037c/0x1003ac */ ++ if (dev_priv->chipset == 0x30 || ++ dev_priv->chipset == 0x31 || ++ dev_priv->chipset == 0x35) { ++ /* Related to ROP count */ ++ int n = (dev_priv->chipset == 0x31 ? 2 : 4); ++ int l = nv_rd32(dev, 0x1003d0); ++ ++ for (i = 0; i < n; i++) { ++ for (j = 0; j < 3; j++) ++ nv_wr32(dev, 0x10037c + 0xc * i + 0x4 * j, ++ calc_ref(dev, l, 0, j)); ++ ++ for (j = 0; j < 2; j++) ++ nv_wr32(dev, 0x1003ac + 0x8 * i + 0x4 * j, ++ calc_ref(dev, l, 1, j)); ++ } ++ } ++ ++ return 0; ++} ++ ++void ++nv30_fb_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c +index 500ccfd..d337b8b 100644 +--- a/drivers/gpu/drm/nouveau/nv40_fifo.c ++++ b/drivers/gpu/drm/nouveau/nv40_fifo.c +@@ -27,8 +27,9 @@ + #include "drmP.h" + #include "nouveau_drv.h" + #include "nouveau_drm.h" ++#include "nouveau_ramht.h" + +-#define NV40_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV40_RAMFC__SIZE)) ++#define NV40_RAMFC(c) (dev_priv->ramfc->pinst + ((c) * NV40_RAMFC__SIZE)) + #define NV40_RAMFC__SIZE 128 + + int +@@ -42,16 +43,15 @@ nv40_fifo_create_context(struct nouveau_channel *chan) + + ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(chan->id), ~0, + NV40_RAMFC__SIZE, NVOBJ_FLAG_ZERO_ALLOC | +- NVOBJ_FLAG_ZERO_FREE, NULL, &chan->ramfc); ++ NVOBJ_FLAG_ZERO_FREE, &chan->ramfc); + if (ret) + return ret; + + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + +- dev_priv->engine.instmem.prepare_access(dev, true); + nv_wi32(dev, fc + 0, chan->pushbuf_base); + nv_wi32(dev, fc + 4, chan->pushbuf_base); +- nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4); ++ nv_wi32(dev, fc + 12, chan->pushbuf->pinst >> 4); + nv_wi32(dev, fc + 24, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | + NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | + NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | +@@ -59,9 +59,8 @@ nv40_fifo_create_context(struct nouveau_channel *chan) + NV_PFIFO_CACHE1_BIG_ENDIAN | + #endif + 0x30000000 /* no idea.. */); +- nv_wi32(dev, fc + 56, chan->ramin_grctx->instance >> 4); ++ nv_wi32(dev, fc + 56, chan->ramin_grctx->pinst >> 4); + nv_wi32(dev, fc + 60, 0x0001FFFF); +- dev_priv->engine.instmem.finish_access(dev); + + /* enable the fifo dma operation */ + nv_wr32(dev, NV04_PFIFO_MODE, +@@ -79,8 +78,7 @@ nv40_fifo_destroy_context(struct nouveau_channel *chan) + nv_wr32(dev, NV04_PFIFO_MODE, + nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id)); + +- if (chan->ramfc) +- nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++ nouveau_gpuobj_ref(NULL, &chan->ramfc); + } + + static void +@@ -89,8 +87,6 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid) + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t fc = NV40_RAMFC(chid), tmp, tmp2; + +- dev_priv->engine.instmem.prepare_access(dev, false); +- + nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); + nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); + nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); +@@ -127,8 +123,6 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid) + nv_wr32(dev, 0x2088, nv_ri32(dev, fc + 76)); + nv_wr32(dev, 0x3300, nv_ri32(dev, fc + 80)); + +- dev_priv->engine.instmem.finish_access(dev); +- + nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); + nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); + } +@@ -166,7 +160,6 @@ nv40_fifo_unload_context(struct drm_device *dev) + return 0; + fc = NV40_RAMFC(chid); + +- dev_priv->engine.instmem.prepare_access(dev, true); + nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); + nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); + nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); +@@ -200,7 +193,6 @@ nv40_fifo_unload_context(struct drm_device *dev) + tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16); + nv_wi32(dev, fc + 72, tmp); + #endif +- dev_priv->engine.instmem.finish_access(dev); + + nv40_fifo_do_load_context(dev, pfifo->channels - 1); + nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, +@@ -249,9 +241,9 @@ nv40_fifo_init_ramxx(struct drm_device *dev) + struct drm_nouveau_private *dev_priv = dev->dev_private; + + nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | +- ((dev_priv->ramht_bits - 9) << 16) | +- (dev_priv->ramht_offset >> 8)); +- nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8); ++ ((dev_priv->ramht->bits - 9) << 16) | ++ (dev_priv->ramht->gpuobj->pinst >> 8)); ++ nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro->pinst >> 8); + + switch (dev_priv->chipset) { + case 0x47: +@@ -279,7 +271,7 @@ nv40_fifo_init_ramxx(struct drm_device *dev) + nv_wr32(dev, 0x2230, 0); + nv_wr32(dev, NV40_PFIFO_RAMFC, + ((dev_priv->vram_size - 512 * 1024 + +- dev_priv->ramfc_offset) >> 16) | (3 << 16)); ++ dev_priv->ramfc->pinst) >> 16) | (3 << 16)); + break; + } + } +diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c +index 704a25d..2424289 100644 +--- a/drivers/gpu/drm/nouveau/nv40_graph.c ++++ b/drivers/gpu/drm/nouveau/nv40_graph.c +@@ -45,7 +45,7 @@ nv40_graph_channel(struct drm_device *dev) + struct nouveau_channel *chan = dev_priv->fifos[i]; + + if (chan && chan->ramin_grctx && +- chan->ramin_grctx->instance == inst) ++ chan->ramin_grctx->pinst == inst) + return chan; + } + +@@ -58,36 +58,28 @@ nv40_graph_create_context(struct nouveau_channel *chan) + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; ++ struct nouveau_grctx ctx = {}; + int ret; + +- ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size, +- 16, NVOBJ_FLAG_ZERO_ALLOC, +- &chan->ramin_grctx); ++ ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin_grctx); + if (ret) + return ret; + + /* Initialise default context values */ +- dev_priv->engine.instmem.prepare_access(dev, true); +- if (!pgraph->ctxprog) { +- struct nouveau_grctx ctx = {}; +- +- ctx.dev = chan->dev; +- ctx.mode = NOUVEAU_GRCTX_VALS; +- ctx.data = chan->ramin_grctx->gpuobj; +- nv40_grctx_init(&ctx); +- } else { +- nouveau_grctx_vals_load(dev, chan->ramin_grctx->gpuobj); +- } +- nv_wo32(dev, chan->ramin_grctx->gpuobj, 0, +- chan->ramin_grctx->gpuobj->im_pramin->start); +- dev_priv->engine.instmem.finish_access(dev); ++ ctx.dev = chan->dev; ++ ctx.mode = NOUVEAU_GRCTX_VALS; ++ ctx.data = chan->ramin_grctx; ++ nv40_grctx_init(&ctx); ++ ++ nv_wo32(chan->ramin_grctx, 0, chan->ramin_grctx->pinst); + return 0; + } + + void + nv40_graph_destroy_context(struct nouveau_channel *chan) + { +- nouveau_gpuobj_ref_del(chan->dev, &chan->ramin_grctx); ++ nouveau_gpuobj_ref(NULL, &chan->ramin_grctx); + } + + static int +@@ -141,7 +133,7 @@ nv40_graph_load_context(struct nouveau_channel *chan) + + if (!chan->ramin_grctx) + return -EINVAL; +- inst = chan->ramin_grctx->instance >> 4; ++ inst = chan->ramin_grctx->pinst >> 4; + + ret = nv40_graph_transfer_context(dev, inst, 0); + if (ret) +@@ -238,7 +230,8 @@ nv40_graph_init(struct drm_device *dev) + struct drm_nouveau_private *dev_priv = + (struct drm_nouveau_private *)dev->dev_private; + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; +- uint32_t vramsz; ++ struct nouveau_grctx ctx = {}; ++ uint32_t vramsz, *cp; + int i, j; + + nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & +@@ -246,32 +239,22 @@ nv40_graph_init(struct drm_device *dev) + nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | + NV_PMC_ENABLE_PGRAPH); + +- if (nouveau_ctxfw) { +- nouveau_grctx_prog_load(dev); +- dev_priv->engine.graph.grctx_size = 175 * 1024; +- } ++ cp = kmalloc(sizeof(*cp) * 256, GFP_KERNEL); ++ if (!cp) ++ return -ENOMEM; + +- if (!dev_priv->engine.graph.ctxprog) { +- struct nouveau_grctx ctx = {}; +- uint32_t *cp; ++ ctx.dev = dev; ++ ctx.mode = NOUVEAU_GRCTX_PROG; ++ ctx.data = cp; ++ ctx.ctxprog_max = 256; ++ nv40_grctx_init(&ctx); ++ dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; + +- cp = kmalloc(sizeof(*cp) * 256, GFP_KERNEL); +- if (!cp) +- return -ENOMEM; ++ nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); ++ for (i = 0; i < ctx.ctxprog_len; i++) ++ nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); + +- ctx.dev = dev; +- ctx.mode = NOUVEAU_GRCTX_PROG; +- ctx.data = cp; +- ctx.ctxprog_max = 256; +- nv40_grctx_init(&ctx); +- dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; +- +- nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); +- for (i = 0; i < ctx.ctxprog_len; i++) +- nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); +- +- kfree(cp); +- } ++ kfree(cp); + + /* No context present currently */ + nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); +@@ -407,7 +390,6 @@ nv40_graph_init(struct drm_device *dev) + + void nv40_graph_takedown(struct drm_device *dev) + { +- nouveau_grctx_fini(dev); + } + + struct nouveau_pgraph_object_class nv40_graph_grclass[] = { +diff --git a/drivers/gpu/drm/nouveau/nv40_grctx.c b/drivers/gpu/drm/nouveau/nv40_grctx.c +index 9b5c974..ce58509 100644 +--- a/drivers/gpu/drm/nouveau/nv40_grctx.c ++++ b/drivers/gpu/drm/nouveau/nv40_grctx.c +@@ -596,13 +596,13 @@ nv40_graph_construct_shader(struct nouveau_grctx *ctx) + + offset += 0x0280/4; + for (i = 0; i < 16; i++, offset += 2) +- nv_wo32(dev, obj, offset, 0x3f800000); ++ nv_wo32(obj, offset * 4, 0x3f800000); + + for (vs = 0; vs < vs_nr; vs++, offset += vs_len) { + for (i = 0; i < vs_nr_b0 * 6; i += 6) +- nv_wo32(dev, obj, offset + b0_offset + i, 0x00000001); ++ nv_wo32(obj, (offset + b0_offset + i) * 4, 0x00000001); + for (i = 0; i < vs_nr_b1 * 4; i += 4) +- nv_wo32(dev, obj, offset + b1_offset + i, 0x3f800000); ++ nv_wo32(obj, (offset + b1_offset + i) * 4, 0x3f800000); + } + } + +diff --git a/drivers/gpu/drm/nouveau/nv40_mc.c b/drivers/gpu/drm/nouveau/nv40_mc.c +index 2a3495e..e4e72c1 100644 +--- a/drivers/gpu/drm/nouveau/nv40_mc.c ++++ b/drivers/gpu/drm/nouveau/nv40_mc.c +@@ -19,7 +19,7 @@ nv40_mc_init(struct drm_device *dev) + case 0x46: /* G72 */ + case 0x4e: + case 0x4c: /* C51_G7X */ +- tmp = nv_rd32(dev, NV40_PFB_020C); ++ tmp = nv_rd32(dev, NV04_PFB_FIFO_DATA); + nv_wr32(dev, NV40_PMC_1700, tmp); + nv_wr32(dev, NV40_PMC_1704, 0); + nv_wr32(dev, NV40_PMC_1708, 0); +diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c +index b4e4a3b..2423c92 100644 +--- a/drivers/gpu/drm/nouveau/nv50_crtc.c ++++ b/drivers/gpu/drm/nouveau/nv50_crtc.c +@@ -264,11 +264,16 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode, bool update) + int + nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk) + { +- uint32_t reg = NV50_PDISPLAY_CRTC_CLK_CTRL1(head); ++ struct drm_nouveau_private *dev_priv = dev->dev_private; + struct pll_lims pll; +- uint32_t reg1, reg2; ++ uint32_t reg, reg1, reg2; + int ret, N1, M1, N2, M2, P; + ++ if (dev_priv->chipset < NV_C0) ++ reg = NV50_PDISPLAY_CRTC_CLK_CTRL1(head); ++ else ++ reg = 0x614140 + (head * 0x800); ++ + ret = get_pll_limits(dev, reg, &pll); + if (ret) + return ret; +@@ -286,7 +291,8 @@ nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk) + nv_wr32(dev, reg, 0x10000611); + nv_wr32(dev, reg + 4, reg1 | (M1 << 16) | N1); + nv_wr32(dev, reg + 8, reg2 | (P << 28) | (M2 << 16) | N2); +- } else { ++ } else ++ if (dev_priv->chipset < NV_C0) { + ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P); + if (ret <= 0) + return 0; +@@ -298,6 +304,17 @@ nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk) + nv_wr32(dev, reg, 0x50000610); + nv_wr32(dev, reg + 4, reg1 | (P << 16) | (M1 << 8) | N1); + nv_wr32(dev, reg + 8, N2); ++ } else { ++ ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P); ++ if (ret <= 0) ++ return 0; ++ ++ NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n", ++ pclk, ret, N1, N2, M1, P); ++ ++ nv_mask(dev, reg + 0x0c, 0x00000000, 0x00000100); ++ nv_wr32(dev, reg + 0x04, (P << 16) | (N1 << 8) | M1); ++ nv_wr32(dev, reg + 0x10, N2 << 16); + } + + return 0; +@@ -321,7 +338,9 @@ nv50_crtc_destroy(struct drm_crtc *crtc) + + nv50_cursor_fini(nv_crtc); + ++ nouveau_bo_unmap(nv_crtc->lut.nvbo); + nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo); ++ nouveau_bo_unmap(nv_crtc->cursor.nvbo); + nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); + kfree(nv_crtc->mode); + kfree(nv_crtc); +@@ -440,47 +459,15 @@ nv50_crtc_prepare(struct drm_crtc *crtc) + { + struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); + struct drm_device *dev = crtc->dev; +- struct drm_encoder *encoder; +- uint32_t dac = 0, sor = 0; + + NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); + +- /* Disconnect all unused encoders. */ +- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { +- struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); +- +- if (!drm_helper_encoder_in_use(encoder)) +- continue; +- +- if (nv_encoder->dcb->type == OUTPUT_ANALOG || +- nv_encoder->dcb->type == OUTPUT_TV) +- dac |= (1 << nv_encoder->or); +- else +- sor |= (1 << nv_encoder->or); +- } +- +- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { +- struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); +- +- if (nv_encoder->dcb->type == OUTPUT_ANALOG || +- nv_encoder->dcb->type == OUTPUT_TV) { +- if (dac & (1 << nv_encoder->or)) +- continue; +- } else { +- if (sor & (1 << nv_encoder->or)) +- continue; +- } +- +- nv_encoder->disconnect(nv_encoder); +- } +- + nv50_crtc_blank(nv_crtc, true); + } + + static void + nv50_crtc_commit(struct drm_crtc *crtc) + { +- struct drm_crtc *crtc2; + struct drm_device *dev = crtc->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *evo = dev_priv->evo; +@@ -491,20 +478,14 @@ nv50_crtc_commit(struct drm_crtc *crtc) + + nv50_crtc_blank(nv_crtc, false); + +- /* Explicitly blank all unused crtc's. */ +- list_for_each_entry(crtc2, &dev->mode_config.crtc_list, head) { +- if (!drm_helper_crtc_in_use(crtc2)) +- nv50_crtc_blank(nouveau_crtc(crtc2), true); +- } +- + ret = RING_SPACE(evo, 2); + if (ret) { + NV_ERROR(dev, "no space while committing crtc\n"); + return; + } + BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); +- OUT_RING(evo, 0); +- FIRE_RING(evo); ++ OUT_RING (evo, 0); ++ FIRE_RING (evo); + } + + static bool +diff --git a/drivers/gpu/drm/nouveau/nv50_cursor.c b/drivers/gpu/drm/nouveau/nv50_cursor.c +index 03ad7ab..1b9ce30 100644 +--- a/drivers/gpu/drm/nouveau/nv50_cursor.c ++++ b/drivers/gpu/drm/nouveau/nv50_cursor.c +@@ -147,7 +147,7 @@ nv50_cursor_fini(struct nouveau_crtc *nv_crtc) + NV_DEBUG_KMS(dev, "\n"); + + nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0); +- if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), ++ if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), + NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) { + NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n"); + NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n", +diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c +index 1fd9537..875414b 100644 +--- a/drivers/gpu/drm/nouveau/nv50_dac.c ++++ b/drivers/gpu/drm/nouveau/nv50_dac.c +@@ -37,22 +37,31 @@ + #include "nv50_display.h" + + static void +-nv50_dac_disconnect(struct nouveau_encoder *nv_encoder) ++nv50_dac_disconnect(struct drm_encoder *encoder) + { +- struct drm_device *dev = to_drm_encoder(nv_encoder)->dev; ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_device *dev = encoder->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *evo = dev_priv->evo; + int ret; + ++ if (!nv_encoder->crtc) ++ return; ++ nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true); ++ + NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or); + +- ret = RING_SPACE(evo, 2); ++ ret = RING_SPACE(evo, 4); + if (ret) { + NV_ERROR(dev, "no space while disconnecting DAC\n"); + return; + } + BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1); +- OUT_RING(evo, 0); ++ OUT_RING (evo, 0); ++ BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); ++ OUT_RING (evo, 0); ++ ++ nv_encoder->crtc = NULL; + } + + static enum drm_connector_status +@@ -70,7 +79,7 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) + + nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), + 0x00150000 | NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); +- if (!nv_wait(NV50_PDISPLAY_DAC_DPMS_CTRL(or), ++ if (!nv_wait(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), + NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) { + NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or); + NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or, +@@ -121,7 +130,7 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode) + NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode); + + /* wait for it to be done */ +- if (!nv_wait(NV50_PDISPLAY_DAC_DPMS_CTRL(or), ++ if (!nv_wait(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), + NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) { + NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or); + NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or, +@@ -213,7 +222,8 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + uint32_t mode_ctl = 0, mode_ctl2 = 0; + int ret; + +- NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or); ++ NV_DEBUG_KMS(dev, "or %d type %d crtc %d\n", ++ nv_encoder->or, nv_encoder->dcb->type, crtc->index); + + nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON); + +@@ -243,6 +253,14 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 2); + OUT_RING(evo, mode_ctl); + OUT_RING(evo, mode_ctl2); ++ ++ nv_encoder->crtc = encoder->crtc; ++} ++ ++static struct drm_crtc * ++nv50_dac_crtc_get(struct drm_encoder *encoder) ++{ ++ return nouveau_encoder(encoder)->crtc; + } + + static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { +@@ -253,7 +271,9 @@ static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { + .prepare = nv50_dac_prepare, + .commit = nv50_dac_commit, + .mode_set = nv50_dac_mode_set, +- .detect = nv50_dac_detect ++ .get_crtc = nv50_dac_crtc_get, ++ .detect = nv50_dac_detect, ++ .disable = nv50_dac_disconnect + }; + + static void +@@ -275,14 +295,11 @@ static const struct drm_encoder_funcs nv50_dac_encoder_funcs = { + }; + + int +-nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry) ++nv50_dac_create(struct drm_connector *connector, struct dcb_entry *entry) + { + struct nouveau_encoder *nv_encoder; + struct drm_encoder *encoder; + +- NV_DEBUG_KMS(dev, "\n"); +- NV_INFO(dev, "Detected a DAC output\n"); +- + nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); + if (!nv_encoder) + return -ENOMEM; +@@ -291,14 +308,14 @@ nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry) + nv_encoder->dcb = entry; + nv_encoder->or = ffs(entry->or) - 1; + +- nv_encoder->disconnect = nv50_dac_disconnect; +- +- drm_encoder_init(dev, encoder, &nv50_dac_encoder_funcs, ++ drm_encoder_init(connector->dev, encoder, &nv50_dac_encoder_funcs, + DRM_MODE_ENCODER_DAC); + drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs); + + encoder->possible_crtcs = entry->heads; + encoder->possible_clones = 0; ++ ++ drm_mode_connector_attach_encoder(connector, encoder); + return 0; + } + +diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c +index 580a5d1..11d366a 100644 +--- a/drivers/gpu/drm/nouveau/nv50_display.c ++++ b/drivers/gpu/drm/nouveau/nv50_display.c +@@ -30,8 +30,22 @@ + #include "nouveau_connector.h" + #include "nouveau_fb.h" + #include "nouveau_fbcon.h" ++#include "nouveau_ramht.h" + #include "drm_crtc_helper.h" + ++static inline int ++nv50_sor_nr(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->chipset < 0x90 || ++ dev_priv->chipset == 0x92 || ++ dev_priv->chipset == 0xa0) ++ return 2; ++ ++ return 4; ++} ++ + static void + nv50_evo_channel_del(struct nouveau_channel **pchan) + { +@@ -42,6 +56,7 @@ nv50_evo_channel_del(struct nouveau_channel **pchan) + *pchan = NULL; + + nouveau_gpuobj_channel_takedown(chan); ++ nouveau_bo_unmap(chan->pushbuf_bo); + nouveau_bo_ref(NULL, &chan->pushbuf_bo); + + if (chan->user) +@@ -65,21 +80,23 @@ nv50_evo_dmaobj_new(struct nouveau_channel *evo, uint32_t class, uint32_t name, + return ret; + obj->engine = NVOBJ_ENGINE_DISPLAY; + +- ret = nouveau_gpuobj_ref_add(dev, evo, name, obj, NULL); ++ nv_wo32(obj, 0, (tile_flags << 22) | (magic_flags << 16) | class); ++ nv_wo32(obj, 4, limit); ++ nv_wo32(obj, 8, offset); ++ nv_wo32(obj, 12, 0x00000000); ++ nv_wo32(obj, 16, 0x00000000); ++ if (dev_priv->card_type < NV_C0) ++ nv_wo32(obj, 20, 0x00010000); ++ else ++ nv_wo32(obj, 20, 0x00020000); ++ dev_priv->engine.instmem.flush(dev); ++ ++ ret = nouveau_ramht_insert(evo, name, obj); ++ nouveau_gpuobj_ref(NULL, &obj); + if (ret) { +- nouveau_gpuobj_del(dev, &obj); + return ret; + } + +- dev_priv->engine.instmem.prepare_access(dev, true); +- nv_wo32(dev, obj, 0, (tile_flags << 22) | (magic_flags << 16) | class); +- nv_wo32(dev, obj, 1, limit); +- nv_wo32(dev, obj, 2, offset); +- nv_wo32(dev, obj, 3, 0x00000000); +- nv_wo32(dev, obj, 4, 0x00000000); +- nv_wo32(dev, obj, 5, 0x00010000); +- dev_priv->engine.instmem.finish_access(dev); +- + return 0; + } + +@@ -87,6 +104,7 @@ static int + nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *ramht = NULL; + struct nouveau_channel *chan; + int ret; + +@@ -100,32 +118,35 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan) + chan->user_get = 4; + chan->user_put = 0; + +- INIT_LIST_HEAD(&chan->ramht_refs); +- +- ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 32768, 0x1000, +- NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin); ++ ret = nouveau_gpuobj_new(dev, NULL, 32768, 0x1000, ++ NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin); + if (ret) { + NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret); + nv50_evo_channel_del(pchan); + return ret; + } + +- ret = nouveau_mem_init_heap(&chan->ramin_heap, chan->ramin->gpuobj-> +- im_pramin->start, 32768); ++ ret = drm_mm_init(&chan->ramin_heap, 0, 32768); + if (ret) { + NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret); + nv50_evo_channel_del(pchan); + return ret; + } + +- ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 4096, 16, +- 0, &chan->ramht); ++ ret = nouveau_gpuobj_new(dev, chan, 4096, 16, 0, &ramht); + if (ret) { + NV_ERROR(dev, "Unable to allocate EVO RAMHT: %d\n", ret); + nv50_evo_channel_del(pchan); + return ret; + } + ++ ret = nouveau_ramht_new(dev, ramht, &chan->ramht); ++ nouveau_gpuobj_ref(NULL, &ramht); ++ if (ret) { ++ nv50_evo_channel_del(pchan); ++ return ret; ++ } ++ + if (dev_priv->chipset != 0x50) { + ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB16, 0x70, 0x19, + 0, 0xffffffff); +@@ -179,13 +200,25 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan) + } + + int ++nv50_display_early_init(struct drm_device *dev) ++{ ++ return 0; ++} ++ ++void ++nv50_display_late_takedown(struct drm_device *dev) ++{ ++} ++ ++int + nv50_display_init(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; ++ struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; + struct nouveau_channel *evo = dev_priv->evo; + struct drm_connector *connector; +- uint32_t val, ram_amount, hpd_en[2]; ++ uint32_t val, ram_amount; + uint64_t start; + int ret, i; + +@@ -213,11 +246,11 @@ nv50_display_init(struct drm_device *dev) + nv_wr32(dev, 0x006101d0 + (i * 0x04), val); + } + /* SOR */ +- for (i = 0; i < 4; i++) { ++ for (i = 0; i < nv50_sor_nr(dev); i++) { + val = nv_rd32(dev, 0x0061c000 + (i * 0x800)); + nv_wr32(dev, 0x006101e0 + (i * 0x04), val); + } +- /* Something not yet in use, tv-out maybe. */ ++ /* EXT */ + for (i = 0; i < 3; i++) { + val = nv_rd32(dev, 0x0061e000 + (i * 0x800)); + nv_wr32(dev, 0x006101f0 + (i * 0x04), val); +@@ -246,7 +279,7 @@ nv50_display_init(struct drm_device *dev) + if (nv_rd32(dev, NV50_PDISPLAY_INTR_1) & 0x100) { + nv_wr32(dev, NV50_PDISPLAY_INTR_1, 0x100); + nv_wr32(dev, 0x006194e8, nv_rd32(dev, 0x006194e8) & ~1); +- if (!nv_wait(0x006194e8, 2, 0)) { ++ if (!nv_wait(dev, 0x006194e8, 2, 0)) { + NV_ERROR(dev, "timeout: (0x6194e8 & 2) != 0\n"); + NV_ERROR(dev, "0x6194e8 = 0x%08x\n", + nv_rd32(dev, 0x6194e8)); +@@ -277,7 +310,8 @@ nv50_display_init(struct drm_device *dev) + + nv_wr32(dev, NV50_PDISPLAY_CTRL_STATE, NV50_PDISPLAY_CTRL_STATE_ENABLE); + nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x1000b03); +- if (!nv_wait(NV50_PDISPLAY_CHANNEL_STAT(0), 0x40000000, 0x40000000)) { ++ if (!nv_wait(dev, NV50_PDISPLAY_CHANNEL_STAT(0), ++ 0x40000000, 0x40000000)) { + NV_ERROR(dev, "timeout: (0x610200 & 0x40000000) == 0x40000000\n"); + NV_ERROR(dev, "0x610200 = 0x%08x\n", + nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0))); +@@ -286,7 +320,7 @@ nv50_display_init(struct drm_device *dev) + + for (i = 0; i < 2; i++) { + nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000); +- if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), ++ if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), + NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) { + NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n"); + NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n", +@@ -296,7 +330,7 @@ nv50_display_init(struct drm_device *dev) + + nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), + NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON); +- if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), ++ if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), + NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, + NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) { + NV_ERROR(dev, "timeout: " +@@ -307,7 +341,7 @@ nv50_display_init(struct drm_device *dev) + } + } + +- nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->instance >> 8) | 9); ++ nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->vinst >> 8) | 9); + + /* initialise fifo */ + nv_wr32(dev, NV50_PDISPLAY_CHANNEL_DMA_CB(0), +@@ -316,7 +350,7 @@ nv50_display_init(struct drm_device *dev) + NV50_PDISPLAY_CHANNEL_DMA_CB_VALID); + nv_wr32(dev, NV50_PDISPLAY_CHANNEL_UNK2(0), 0x00010000); + nv_wr32(dev, NV50_PDISPLAY_CHANNEL_UNK3(0), 0x00000002); +- if (!nv_wait(0x610200, 0x80000000, 0x00000000)) { ++ if (!nv_wait(dev, 0x610200, 0x80000000, 0x00000000)) { + NV_ERROR(dev, "timeout: (0x610200 & 0x80000000) == 0\n"); + NV_ERROR(dev, "0x610200 = 0x%08x\n", nv_rd32(dev, 0x610200)); + return -EBUSY; +@@ -356,7 +390,7 @@ nv50_display_init(struct drm_device *dev) + BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK082C), 1); + OUT_RING(evo, 0); + FIRE_RING(evo); +- if (!nv_wait(0x640004, 0xffffffff, evo->dma.put << 2)) ++ if (!nv_wait(dev, 0x640004, 0xffffffff, evo->dma.put << 2)) + NV_ERROR(dev, "evo pushbuf stalled\n"); + + /* enable clock change interrupts. */ +@@ -366,26 +400,13 @@ nv50_display_init(struct drm_device *dev) + NV50_PDISPLAY_INTR_EN_CLK_UNK40)); + + /* enable hotplug interrupts */ +- hpd_en[0] = hpd_en[1] = 0; + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct nouveau_connector *conn = nouveau_connector(connector); +- struct dcb_gpio_entry *gpio; + + if (conn->dcb->gpio_tag == 0xff) + continue; + +- gpio = nouveau_bios_gpio_entry(dev, conn->dcb->gpio_tag); +- if (!gpio) +- continue; +- +- hpd_en[gpio->line >> 4] |= (0x00010001 << (gpio->line & 0xf)); +- } +- +- nv_wr32(dev, 0xe054, 0xffffffff); +- nv_wr32(dev, 0xe050, hpd_en[0]); +- if (dev_priv->chipset >= 0x90) { +- nv_wr32(dev, 0xe074, 0xffffffff); +- nv_wr32(dev, 0xe070, hpd_en[1]); ++ pgpio->irq_enable(dev, conn->dcb->gpio_tag, true); + } + + return 0; +@@ -423,7 +444,7 @@ static int nv50_display_disable(struct drm_device *dev) + continue; + + nv_wr32(dev, NV50_PDISPLAY_INTR_1, mask); +- if (!nv_wait(NV50_PDISPLAY_INTR_1, mask, mask)) { ++ if (!nv_wait(dev, NV50_PDISPLAY_INTR_1, mask, mask)) { + NV_ERROR(dev, "timeout: (0x610024 & 0x%08x) == " + "0x%08x\n", mask, mask); + NV_ERROR(dev, "0x610024 = 0x%08x\n", +@@ -433,14 +454,14 @@ static int nv50_display_disable(struct drm_device *dev) + + nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0); + nv_wr32(dev, NV50_PDISPLAY_CTRL_STATE, 0); +- if (!nv_wait(NV50_PDISPLAY_CHANNEL_STAT(0), 0x1e0000, 0)) { ++ if (!nv_wait(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x1e0000, 0)) { + NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) == 0\n"); + NV_ERROR(dev, "0x610200 = 0x%08x\n", + nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0))); + } + + for (i = 0; i < 3; i++) { +- if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_STATE(i), ++ if (!nv_wait(dev, NV50_PDISPLAY_SOR_DPMS_STATE(i), + NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) { + NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", i); + NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", i, +@@ -465,6 +486,7 @@ int nv50_display_create(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct dcb_table *dcb = &dev_priv->vbios.dcb; ++ struct drm_connector *connector, *ct; + int ret, i; + + NV_DEBUG_KMS(dev, "\n"); +@@ -507,14 +529,18 @@ int nv50_display_create(struct drm_device *dev) + continue; + } + ++ connector = nouveau_connector_create(dev, entry->connector); ++ if (IS_ERR(connector)) ++ continue; ++ + switch (entry->type) { + case OUTPUT_TMDS: + case OUTPUT_LVDS: + case OUTPUT_DP: +- nv50_sor_create(dev, entry); ++ nv50_sor_create(connector, entry); + break; + case OUTPUT_ANALOG: +- nv50_dac_create(dev, entry); ++ nv50_dac_create(connector, entry); + break; + default: + NV_WARN(dev, "DCB encoder %d unknown\n", entry->type); +@@ -522,11 +548,13 @@ int nv50_display_create(struct drm_device *dev) + } + } + +- for (i = 0 ; i < dcb->connector.entries; i++) { +- if (i != 0 && dcb->connector.entry[i].index2 == +- dcb->connector.entry[i - 1].index2) +- continue; +- nouveau_connector_create(dev, &dcb->connector.entry[i]); ++ list_for_each_entry_safe(connector, ct, ++ &dev->mode_config.connector_list, head) { ++ if (!connector->encoder_ids[0]) { ++ NV_WARN(dev, "%s has no encoders, removing\n", ++ drm_get_connector_name(connector)); ++ connector->funcs->destroy(connector); ++ } + } + + ret = nv50_display_init(dev); +@@ -538,7 +566,8 @@ int nv50_display_create(struct drm_device *dev) + return 0; + } + +-int nv50_display_destroy(struct drm_device *dev) ++void ++nv50_display_destroy(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + +@@ -548,135 +577,30 @@ int nv50_display_destroy(struct drm_device *dev) + + nv50_display_disable(dev); + nv50_evo_channel_del(&dev_priv->evo); +- +- return 0; +-} +- +-static inline uint32_t +-nv50_display_mode_ctrl(struct drm_device *dev, bool sor, int or) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- uint32_t mc; +- +- if (sor) { +- if (dev_priv->chipset < 0x90 || +- dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0) +- mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(or)); +- else +- mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(or)); +- } else { +- mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(or)); +- } +- +- return mc; +-} +- +-static int +-nv50_display_irq_head(struct drm_device *dev, int *phead, +- struct dcb_entry **pdcbent) +-{ +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- uint32_t unk30 = nv_rd32(dev, NV50_PDISPLAY_UNK30_CTRL); +- uint32_t dac = 0, sor = 0; +- int head, i, or = 0, type = OUTPUT_ANY; +- +- /* We're assuming that head 0 *or* head 1 will be active here, +- * and not both. I'm not sure if the hw will even signal both +- * ever, but it definitely shouldn't for us as we commit each +- * CRTC separately, and submission will be blocked by the GPU +- * until we handle each in turn. +- */ +- NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); +- head = ffs((unk30 >> 9) & 3) - 1; +- if (head < 0) +- return -EINVAL; +- +- /* This assumes CRTCs are never bound to multiple encoders, which +- * should be the case. +- */ +- for (i = 0; i < 3 && type == OUTPUT_ANY; i++) { +- uint32_t mc = nv50_display_mode_ctrl(dev, false, i); +- if (!(mc & (1 << head))) +- continue; +- +- switch ((mc >> 8) & 0xf) { +- case 0: type = OUTPUT_ANALOG; break; +- case 1: type = OUTPUT_TV; break; +- default: +- NV_ERROR(dev, "unknown dac mode_ctrl: 0x%08x\n", dac); +- return -1; +- } +- +- or = i; +- } +- +- for (i = 0; i < 4 && type == OUTPUT_ANY; i++) { +- uint32_t mc = nv50_display_mode_ctrl(dev, true, i); +- if (!(mc & (1 << head))) +- continue; +- +- switch ((mc >> 8) & 0xf) { +- case 0: type = OUTPUT_LVDS; break; +- case 1: type = OUTPUT_TMDS; break; +- case 2: type = OUTPUT_TMDS; break; +- case 5: type = OUTPUT_TMDS; break; +- case 8: type = OUTPUT_DP; break; +- case 9: type = OUTPUT_DP; break; +- default: +- NV_ERROR(dev, "unknown sor mode_ctrl: 0x%08x\n", sor); +- return -1; +- } +- +- or = i; +- } +- +- NV_DEBUG_KMS(dev, "type %d, or %d\n", type, or); +- if (type == OUTPUT_ANY) { +- NV_ERROR(dev, "unknown encoder!!\n"); +- return -1; +- } +- +- for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { +- struct dcb_entry *dcbent = &dev_priv->vbios.dcb.entry[i]; +- +- if (dcbent->type != type) +- continue; +- +- if (!(dcbent->or & (1 << or))) +- continue; +- +- *phead = head; +- *pdcbent = dcbent; +- return 0; +- } +- +- NV_ERROR(dev, "no DCB entry for %d %d\n", dac != 0, or); +- return 0; + } + +-static uint32_t +-nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent, +- int pxclk) ++static u16 ++nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb, ++ u32 mc, int pxclk) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_connector *nv_connector = NULL; + struct drm_encoder *encoder; + struct nvbios *bios = &dev_priv->vbios; +- uint32_t mc, script = 0, or; ++ u32 script = 0, or; + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + +- if (nv_encoder->dcb != dcbent) ++ if (nv_encoder->dcb != dcb) + continue; + + nv_connector = nouveau_encoder_connector_get(nv_encoder); + break; + } + +- or = ffs(dcbent->or) - 1; +- mc = nv50_display_mode_ctrl(dev, dcbent->type != OUTPUT_ANALOG, or); +- switch (dcbent->type) { ++ or = ffs(dcb->or) - 1; ++ switch (dcb->type) { + case OUTPUT_LVDS: + script = (mc >> 8) & 0xf; + if (bios->fp_no_ddc) { +@@ -767,17 +691,88 @@ nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr) + static void + nv50_display_unk10_handler(struct drm_device *dev) + { +- struct dcb_entry *dcbent; +- int head, ret; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ u32 unk30 = nv_rd32(dev, 0x610030), mc; ++ int i, crtc, or, type = OUTPUT_ANY; + +- ret = nv50_display_irq_head(dev, &head, &dcbent); +- if (ret) +- goto ack; ++ NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); ++ dev_priv->evo_irq.dcb = NULL; + + nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8); + +- nouveau_bios_run_display_table(dev, dcbent, 0, -1); ++ /* Determine which CRTC we're dealing with, only 1 ever will be ++ * signalled at the same time with the current nouveau code. ++ */ ++ crtc = ffs((unk30 & 0x00000060) >> 5) - 1; ++ if (crtc < 0) ++ goto ack; ++ ++ /* Nothing needs to be done for the encoder */ ++ crtc = ffs((unk30 & 0x00000180) >> 7) - 1; ++ if (crtc < 0) ++ goto ack; ++ ++ /* Find which encoder was connected to the CRTC */ ++ for (i = 0; type == OUTPUT_ANY && i < 3; i++) { ++ mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_C(i)); ++ NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc); ++ if (!(mc & (1 << crtc))) ++ continue; ++ ++ switch ((mc & 0x00000f00) >> 8) { ++ case 0: type = OUTPUT_ANALOG; break; ++ case 1: type = OUTPUT_TV; break; ++ default: ++ NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc); ++ goto ack; ++ } ++ ++ or = i; ++ } ++ ++ for (i = 0; type == OUTPUT_ANY && i < nv50_sor_nr(dev); i++) { ++ if (dev_priv->chipset < 0x90 || ++ dev_priv->chipset == 0x92 || ++ dev_priv->chipset == 0xa0) ++ mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(i)); ++ else ++ mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(i)); ++ ++ NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc); ++ if (!(mc & (1 << crtc))) ++ continue; ++ ++ switch ((mc & 0x00000f00) >> 8) { ++ case 0: type = OUTPUT_LVDS; break; ++ case 1: type = OUTPUT_TMDS; break; ++ case 2: type = OUTPUT_TMDS; break; ++ case 5: type = OUTPUT_TMDS; break; ++ case 8: type = OUTPUT_DP; break; ++ case 9: type = OUTPUT_DP; break; ++ default: ++ NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc); ++ goto ack; ++ } ++ ++ or = i; ++ } ++ ++ /* There was no encoder to disable */ ++ if (type == OUTPUT_ANY) ++ goto ack; ++ ++ /* Disable the encoder */ ++ for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { ++ struct dcb_entry *dcb = &dev_priv->vbios.dcb.entry[i]; ++ ++ if (dcb->type == type && (dcb->or & (1 << or))) { ++ nouveau_bios_run_display_table(dev, dcb, 0, -1); ++ dev_priv->evo_irq.dcb = dcb; ++ goto ack; ++ } ++ } + ++ NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc); + ack: + nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10); + nv_wr32(dev, 0x610030, 0x80000000); +@@ -817,33 +812,103 @@ nv50_display_unk20_dp_hack(struct drm_device *dev, struct dcb_entry *dcb) + static void + nv50_display_unk20_handler(struct drm_device *dev) + { +- struct dcb_entry *dcbent; +- uint32_t tmp, pclk, script; +- int head, or, ret; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc; ++ struct dcb_entry *dcb; ++ int i, crtc, or, type = OUTPUT_ANY; + +- ret = nv50_display_irq_head(dev, &head, &dcbent); +- if (ret) ++ NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); ++ dcb = dev_priv->evo_irq.dcb; ++ if (dcb) { ++ nouveau_bios_run_display_table(dev, dcb, 0, -2); ++ dev_priv->evo_irq.dcb = NULL; ++ } ++ ++ /* CRTC clock change requested? */ ++ crtc = ffs((unk30 & 0x00000600) >> 9) - 1; ++ if (crtc >= 0) { ++ pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK)); ++ pclk &= 0x003fffff; ++ ++ nv50_crtc_set_clock(dev, crtc, pclk); ++ ++ tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc)); ++ tmp &= ~0x000000f; ++ nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc), tmp); ++ } ++ ++ /* Nothing needs to be done for the encoder */ ++ crtc = ffs((unk30 & 0x00000180) >> 7) - 1; ++ if (crtc < 0) + goto ack; +- or = ffs(dcbent->or) - 1; +- pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff; +- script = nv50_display_script_select(dev, dcbent, pclk); ++ pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK)) & 0x003fffff; ++ ++ /* Find which encoder is connected to the CRTC */ ++ for (i = 0; type == OUTPUT_ANY && i < 3; i++) { ++ mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(i)); ++ NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc); ++ if (!(mc & (1 << crtc))) ++ continue; ++ ++ switch ((mc & 0x00000f00) >> 8) { ++ case 0: type = OUTPUT_ANALOG; break; ++ case 1: type = OUTPUT_TV; break; ++ default: ++ NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc); ++ goto ack; ++ } ++ ++ or = i; ++ } ++ ++ for (i = 0; type == OUTPUT_ANY && i < nv50_sor_nr(dev); i++) { ++ if (dev_priv->chipset < 0x90 || ++ dev_priv->chipset == 0x92 || ++ dev_priv->chipset == 0xa0) ++ mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(i)); ++ else ++ mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(i)); ++ ++ NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc); ++ if (!(mc & (1 << crtc))) ++ continue; ++ ++ switch ((mc & 0x00000f00) >> 8) { ++ case 0: type = OUTPUT_LVDS; break; ++ case 1: type = OUTPUT_TMDS; break; ++ case 2: type = OUTPUT_TMDS; break; ++ case 5: type = OUTPUT_TMDS; break; ++ case 8: type = OUTPUT_DP; break; ++ case 9: type = OUTPUT_DP; break; ++ default: ++ NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc); ++ goto ack; ++ } + +- NV_DEBUG_KMS(dev, "head %d pxclk: %dKHz\n", head, pclk); ++ or = i; ++ } + +- if (dcbent->type != OUTPUT_DP) +- nouveau_bios_run_display_table(dev, dcbent, 0, -2); ++ if (type == OUTPUT_ANY) ++ goto ack; + +- nv50_crtc_set_clock(dev, head, pclk); ++ /* Enable the encoder */ ++ for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { ++ dcb = &dev_priv->vbios.dcb.entry[i]; ++ if (dcb->type == type && (dcb->or & (1 << or))) ++ break; ++ } + +- nouveau_bios_run_display_table(dev, dcbent, script, pclk); ++ if (i == dev_priv->vbios.dcb.entries) { ++ NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc); ++ goto ack; ++ } + +- nv50_display_unk20_dp_hack(dev, dcbent); ++ script = nv50_display_script_select(dev, dcb, mc, pclk); ++ nouveau_bios_run_display_table(dev, dcb, script, pclk); + +- tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head)); +- tmp &= ~0x000000f; +- nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head), tmp); ++ nv50_display_unk20_dp_hack(dev, dcb); + +- if (dcbent->type != OUTPUT_ANALOG) { ++ if (dcb->type != OUTPUT_ANALOG) { + tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or)); + tmp &= ~0x00000f0f; + if (script & 0x0100) +@@ -853,24 +918,61 @@ nv50_display_unk20_handler(struct drm_device *dev) + nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0); + } + ++ dev_priv->evo_irq.dcb = dcb; ++ dev_priv->evo_irq.pclk = pclk; ++ dev_priv->evo_irq.script = script; ++ + ack: + nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20); + nv_wr32(dev, 0x610030, 0x80000000); + } + ++/* If programming a TMDS output on a SOR that can also be configured for ++ * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off. ++ * ++ * It looks like the VBIOS TMDS scripts make an attempt at this, however, ++ * the VBIOS scripts on at least one board I have only switch it off on ++ * link 0, causing a blank display if the output has previously been ++ * programmed for DisplayPort. ++ */ ++static void ++nv50_display_unk40_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb) ++{ ++ int or = ffs(dcb->or) - 1, link = !(dcb->dpconf.sor.link & 1); ++ struct drm_encoder *encoder; ++ u32 tmp; ++ ++ if (dcb->type != OUTPUT_TMDS) ++ return; ++ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ ++ if (nv_encoder->dcb->type == OUTPUT_DP && ++ nv_encoder->dcb->or & (1 << or)) { ++ tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link)); ++ tmp &= ~NV50_SOR_DP_CTRL_ENABLED; ++ nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp); ++ break; ++ } ++ } ++} ++ + static void + nv50_display_unk40_handler(struct drm_device *dev) + { +- struct dcb_entry *dcbent; +- int head, pclk, script, ret; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct dcb_entry *dcb = dev_priv->evo_irq.dcb; ++ u16 script = dev_priv->evo_irq.script; ++ u32 unk30 = nv_rd32(dev, 0x610030), pclk = dev_priv->evo_irq.pclk; + +- ret = nv50_display_irq_head(dev, &head, &dcbent); +- if (ret) ++ NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); ++ dev_priv->evo_irq.dcb = NULL; ++ if (!dcb) + goto ack; +- pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff; +- script = nv50_display_script_select(dev, dcbent, pclk); + +- nouveau_bios_run_display_table(dev, dcbent, script, -pclk); ++ nouveau_bios_run_display_table(dev, dcb, script, -pclk); ++ nv50_display_unk40_dp_set_tmds(dev, dcb); + + ack: + nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40); +diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h +index 581d405..c551f0b 100644 +--- a/drivers/gpu/drm/nouveau/nv50_display.h ++++ b/drivers/gpu/drm/nouveau/nv50_display.h +@@ -38,9 +38,11 @@ + void nv50_display_irq_handler(struct drm_device *dev); + void nv50_display_irq_handler_bh(struct work_struct *work); + void nv50_display_irq_hotplug_bh(struct work_struct *work); +-int nv50_display_init(struct drm_device *dev); ++int nv50_display_early_init(struct drm_device *dev); ++void nv50_display_late_takedown(struct drm_device *dev); + int nv50_display_create(struct drm_device *dev); +-int nv50_display_destroy(struct drm_device *dev); ++int nv50_display_init(struct drm_device *dev); ++void nv50_display_destroy(struct drm_device *dev); + int nv50_crtc_blank(struct nouveau_crtc *, bool blank); + int nv50_crtc_set_clock(struct drm_device *, int head, int pclk); + +diff --git a/drivers/gpu/drm/nouveau/nv50_fb.c b/drivers/gpu/drm/nouveau/nv50_fb.c +index 32611bd..cd1988b 100644 +--- a/drivers/gpu/drm/nouveau/nv50_fb.c ++++ b/drivers/gpu/drm/nouveau/nv50_fb.c +@@ -20,6 +20,7 @@ nv50_fb_init(struct drm_device *dev) + case 0x50: + nv_wr32(dev, 0x100c90, 0x0707ff); + break; ++ case 0xa3: + case 0xa5: + case 0xa8: + nv_wr32(dev, 0x100c90, 0x0d0fff); +@@ -36,3 +37,42 @@ void + nv50_fb_takedown(struct drm_device *dev) + { + } ++ ++void ++nv50_fb_vm_trap(struct drm_device *dev, int display, const char *name) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ u32 trap[6], idx, chinst; ++ int i, ch; ++ ++ idx = nv_rd32(dev, 0x100c90); ++ if (!(idx & 0x80000000)) ++ return; ++ idx &= 0x00ffffff; ++ ++ for (i = 0; i < 6; i++) { ++ nv_wr32(dev, 0x100c90, idx | i << 24); ++ trap[i] = nv_rd32(dev, 0x100c94); ++ } ++ nv_wr32(dev, 0x100c90, idx | 0x80000000); ++ ++ if (!display) ++ return; ++ ++ chinst = (trap[2] << 16) | trap[1]; ++ for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) { ++ struct nouveau_channel *chan = dev_priv->fifos[ch]; ++ ++ if (!chan || !chan->ramin) ++ continue; ++ ++ if (chinst == chan->ramin->vinst >> 12) ++ break; ++ } ++ ++ NV_INFO(dev, "%s - VM: Trapped %s at %02x%04x%04x status %08x " ++ "channel %d (0x%08x)\n", ++ name, (trap[5] & 0x100 ? "read" : "write"), ++ trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, ++ trap[0], ch, chinst); ++} +diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c +index 6bf025c..6dcf048 100644 +--- a/drivers/gpu/drm/nouveau/nv50_fbcon.c ++++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c +@@ -1,6 +1,7 @@ + #include "drmP.h" + #include "nouveau_drv.h" + #include "nouveau_dma.h" ++#include "nouveau_ramht.h" + #include "nouveau_fbcon.h" + + void +@@ -193,7 +194,8 @@ nv50_fbcon_accel_init(struct fb_info *info) + if (ret) + return ret; + +- ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, Nv2D, eng2d, NULL); ++ ret = nouveau_ramht_insert(dev_priv->channel, Nv2D, eng2d); ++ nouveau_gpuobj_ref(NULL, &eng2d); + if (ret) + return ret; + +diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c +index e20c0e2..a46a961 100644 +--- a/drivers/gpu/drm/nouveau/nv50_fifo.c ++++ b/drivers/gpu/drm/nouveau/nv50_fifo.c +@@ -27,42 +27,37 @@ + #include "drmP.h" + #include "drm.h" + #include "nouveau_drv.h" +- +-struct nv50_fifo_priv { +- struct nouveau_gpuobj_ref *thingo[2]; +- int cur_thingo; +-}; +- +-#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) ++#include "nouveau_ramht.h" + + static void +-nv50_fifo_init_thingo(struct drm_device *dev) ++nv50_fifo_playlist_update(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv; +- struct nouveau_gpuobj_ref *cur; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; ++ struct nouveau_gpuobj *cur; + int i, nr; + + NV_DEBUG(dev, "\n"); + +- cur = priv->thingo[priv->cur_thingo]; +- priv->cur_thingo = !priv->cur_thingo; ++ cur = pfifo->playlist[pfifo->cur_playlist]; ++ pfifo->cur_playlist = !pfifo->cur_playlist; + + /* We never schedule channel 0 or 127 */ +- dev_priv->engine.instmem.prepare_access(dev, true); + for (i = 1, nr = 0; i < 127; i++) { +- if (dev_priv->fifos[i] && dev_priv->fifos[i]->ramfc) +- nv_wo32(dev, cur->gpuobj, nr++, i); ++ if (dev_priv->fifos[i] && dev_priv->fifos[i]->ramfc) { ++ nv_wo32(cur, (nr * 4), i); ++ nr++; ++ } + } +- dev_priv->engine.instmem.finish_access(dev); ++ dev_priv->engine.instmem.flush(dev); + +- nv_wr32(dev, 0x32f4, cur->instance >> 12); ++ nv_wr32(dev, 0x32f4, cur->vinst >> 12); + nv_wr32(dev, 0x32ec, nr); + nv_wr32(dev, 0x2500, 0x101); + } + +-static int +-nv50_fifo_channel_enable(struct drm_device *dev, int channel, bool nt) ++static void ++nv50_fifo_channel_enable(struct drm_device *dev, int channel) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan = dev_priv->fifos[channel]; +@@ -70,37 +65,28 @@ nv50_fifo_channel_enable(struct drm_device *dev, int channel, bool nt) + + NV_DEBUG(dev, "ch%d\n", channel); + +- if (!chan->ramfc) +- return -EINVAL; +- +- if (IS_G80) +- inst = chan->ramfc->instance >> 12; ++ if (dev_priv->chipset == 0x50) ++ inst = chan->ramfc->vinst >> 12; + else +- inst = chan->ramfc->instance >> 8; +- nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), +- inst | NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED); ++ inst = chan->ramfc->vinst >> 8; + +- if (!nt) +- nv50_fifo_init_thingo(dev); +- return 0; ++ nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst | ++ NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED); + } + + static void +-nv50_fifo_channel_disable(struct drm_device *dev, int channel, bool nt) ++nv50_fifo_channel_disable(struct drm_device *dev, int channel) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t inst; + +- NV_DEBUG(dev, "ch%d, nt=%d\n", channel, nt); ++ NV_DEBUG(dev, "ch%d\n", channel); + +- if (IS_G80) ++ if (dev_priv->chipset == 0x50) + inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80; + else + inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84; + nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst); +- +- if (!nt) +- nv50_fifo_init_thingo(dev); + } + + static void +@@ -133,12 +119,12 @@ nv50_fifo_init_context_table(struct drm_device *dev) + + for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) { + if (dev_priv->fifos[i]) +- nv50_fifo_channel_enable(dev, i, true); ++ nv50_fifo_channel_enable(dev, i); + else +- nv50_fifo_channel_disable(dev, i, true); ++ nv50_fifo_channel_disable(dev, i); + } + +- nv50_fifo_init_thingo(dev); ++ nv50_fifo_playlist_update(dev); + } + + static void +@@ -162,41 +148,38 @@ nv50_fifo_init_regs(struct drm_device *dev) + nv_wr32(dev, 0x3270, 0); + + /* Enable dummy channels setup by nv50_instmem.c */ +- nv50_fifo_channel_enable(dev, 0, true); +- nv50_fifo_channel_enable(dev, 127, true); ++ nv50_fifo_channel_enable(dev, 0); ++ nv50_fifo_channel_enable(dev, 127); + } + + int + nv50_fifo_init(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nv50_fifo_priv *priv; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; + int ret; + + NV_DEBUG(dev, "\n"); + +- priv = dev_priv->engine.fifo.priv; +- if (priv) { +- priv->cur_thingo = !priv->cur_thingo; ++ if (pfifo->playlist[0]) { ++ pfifo->cur_playlist = !pfifo->cur_playlist; + goto just_reset; + } + +- priv = kzalloc(sizeof(*priv), GFP_KERNEL); +- if (!priv) +- return -ENOMEM; +- dev_priv->engine.fifo.priv = priv; +- +- ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000, +- NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[0]); ++ ret = nouveau_gpuobj_new(dev, NULL, 128*4, 0x1000, ++ NVOBJ_FLAG_ZERO_ALLOC, ++ &pfifo->playlist[0]); + if (ret) { +- NV_ERROR(dev, "error creating thingo0: %d\n", ret); ++ NV_ERROR(dev, "error creating playlist 0: %d\n", ret); + return ret; + } + +- ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000, +- NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[1]); ++ ret = nouveau_gpuobj_new(dev, NULL, 128*4, 0x1000, ++ NVOBJ_FLAG_ZERO_ALLOC, ++ &pfifo->playlist[1]); + if (ret) { +- NV_ERROR(dev, "error creating thingo1: %d\n", ret); ++ nouveau_gpuobj_ref(NULL, &pfifo->playlist[0]); ++ NV_ERROR(dev, "error creating playlist 1: %d\n", ret); + return ret; + } + +@@ -216,18 +199,15 @@ void + nv50_fifo_takedown(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; + + NV_DEBUG(dev, "\n"); + +- if (!priv) ++ if (!pfifo->playlist[0]) + return; + +- nouveau_gpuobj_ref_del(dev, &priv->thingo[0]); +- nouveau_gpuobj_ref_del(dev, &priv->thingo[1]); +- +- dev_priv->engine.fifo.priv = NULL; +- kfree(priv); ++ nouveau_gpuobj_ref(NULL, &pfifo->playlist[0]); ++ nouveau_gpuobj_ref(NULL, &pfifo->playlist[1]); + } + + int +@@ -248,72 +228,61 @@ nv50_fifo_create_context(struct nouveau_channel *chan) + + NV_DEBUG(dev, "ch%d\n", chan->id); + +- if (IS_G80) { +- uint32_t ramin_poffset = chan->ramin->gpuobj->im_pramin->start; +- uint32_t ramin_voffset = chan->ramin->gpuobj->im_backing_start; +- +- ret = nouveau_gpuobj_new_fake(dev, ramin_poffset, ramin_voffset, +- 0x100, NVOBJ_FLAG_ZERO_ALLOC | +- NVOBJ_FLAG_ZERO_FREE, &ramfc, ++ if (dev_priv->chipset == 0x50) { ++ ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst, ++ chan->ramin->vinst, 0x100, ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, + &chan->ramfc); + if (ret) + return ret; + +- ret = nouveau_gpuobj_new_fake(dev, ramin_poffset + 0x0400, +- ramin_voffset + 0x0400, 4096, +- 0, NULL, &chan->cache); ++ ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst + 0x0400, ++ chan->ramin->vinst + 0x0400, ++ 4096, 0, &chan->cache); + if (ret) + return ret; + } else { +- ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 0x100, 256, +- NVOBJ_FLAG_ZERO_ALLOC | +- NVOBJ_FLAG_ZERO_FREE, +- &chan->ramfc); ++ ret = nouveau_gpuobj_new(dev, chan, 0x100, 256, ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, &chan->ramfc); + if (ret) + return ret; +- ramfc = chan->ramfc->gpuobj; + +- ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 4096, 1024, +- 0, &chan->cache); ++ ret = nouveau_gpuobj_new(dev, chan, 4096, 1024, ++ 0, &chan->cache); + if (ret) + return ret; + } ++ ramfc = chan->ramfc; + + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + +- dev_priv->engine.instmem.prepare_access(dev, true); +- +- nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4); +- nv_wo32(dev, ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4)); +- nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff); +- nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff); +- nv_wo32(dev, ramfc, 0x40/4, 0x00000000); +- nv_wo32(dev, ramfc, 0x7c/4, 0x30000001); +- nv_wo32(dev, ramfc, 0x78/4, 0x00000000); +- nv_wo32(dev, ramfc, 0x3c/4, 0x403f6078); +- nv_wo32(dev, ramfc, 0x50/4, chan->pushbuf_base + +- chan->dma.ib_base * 4); +- nv_wo32(dev, ramfc, 0x54/4, drm_order(chan->dma.ib_max + 1) << 16); +- +- if (!IS_G80) { +- nv_wo32(dev, chan->ramin->gpuobj, 0, chan->id); +- nv_wo32(dev, chan->ramin->gpuobj, 1, +- chan->ramfc->instance >> 8); +- +- nv_wo32(dev, ramfc, 0x88/4, chan->cache->instance >> 10); +- nv_wo32(dev, ramfc, 0x98/4, chan->ramin->instance >> 12); ++ nv_wo32(ramfc, 0x48, chan->pushbuf->cinst >> 4); ++ nv_wo32(ramfc, 0x80, ((chan->ramht->bits - 9) << 27) | ++ (4 << 24) /* SEARCH_FULL */ | ++ (chan->ramht->gpuobj->cinst >> 4)); ++ nv_wo32(ramfc, 0x44, 0x2101ffff); ++ nv_wo32(ramfc, 0x60, 0x7fffffff); ++ nv_wo32(ramfc, 0x40, 0x00000000); ++ nv_wo32(ramfc, 0x7c, 0x30000001); ++ nv_wo32(ramfc, 0x78, 0x00000000); ++ nv_wo32(ramfc, 0x3c, 0x403f6078); ++ nv_wo32(ramfc, 0x50, chan->pushbuf_base + chan->dma.ib_base * 4); ++ nv_wo32(ramfc, 0x54, drm_order(chan->dma.ib_max + 1) << 16); ++ ++ if (dev_priv->chipset != 0x50) { ++ nv_wo32(chan->ramin, 0, chan->id); ++ nv_wo32(chan->ramin, 4, chan->ramfc->vinst >> 8); ++ ++ nv_wo32(ramfc, 0x88, chan->cache->vinst >> 10); ++ nv_wo32(ramfc, 0x98, chan->ramin->vinst >> 12); + } + +- dev_priv->engine.instmem.finish_access(dev); +- +- ret = nv50_fifo_channel_enable(dev, chan->id, false); +- if (ret) { +- NV_ERROR(dev, "error enabling ch%d: %d\n", chan->id, ret); +- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); +- nouveau_gpuobj_ref_del(dev, &chan->ramfc); +- return ret; +- } ++ dev_priv->engine.instmem.flush(dev); + ++ nv50_fifo_channel_enable(dev, chan->id); ++ nv50_fifo_playlist_update(dev); + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); + return 0; + } +@@ -322,20 +291,22 @@ void + nv50_fifo_destroy_context(struct nouveau_channel *chan) + { + struct drm_device *dev = chan->dev; +- struct nouveau_gpuobj_ref *ramfc = chan->ramfc; ++ struct nouveau_gpuobj *ramfc = NULL; + + NV_DEBUG(dev, "ch%d\n", chan->id); + + /* This will ensure the channel is seen as disabled. */ +- chan->ramfc = NULL; +- nv50_fifo_channel_disable(dev, chan->id, false); ++ nouveau_gpuobj_ref(chan->ramfc, &ramfc); ++ nouveau_gpuobj_ref(NULL, &chan->ramfc); ++ nv50_fifo_channel_disable(dev, chan->id); + + /* Dummy channel, also used on ch 127 */ + if (chan->id == 0) +- nv50_fifo_channel_disable(dev, 127, false); ++ nv50_fifo_channel_disable(dev, 127); ++ nv50_fifo_playlist_update(dev); + +- nouveau_gpuobj_ref_del(dev, &ramfc); +- nouveau_gpuobj_ref_del(dev, &chan->cache); ++ nouveau_gpuobj_ref(NULL, &ramfc); ++ nouveau_gpuobj_ref(NULL, &chan->cache); + } + + int +@@ -343,69 +314,65 @@ nv50_fifo_load_context(struct nouveau_channel *chan) + { + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_gpuobj *ramfc = chan->ramfc->gpuobj; +- struct nouveau_gpuobj *cache = chan->cache->gpuobj; ++ struct nouveau_gpuobj *ramfc = chan->ramfc; ++ struct nouveau_gpuobj *cache = chan->cache; + int ptr, cnt; + + NV_DEBUG(dev, "ch%d\n", chan->id); + +- dev_priv->engine.instmem.prepare_access(dev, false); +- +- nv_wr32(dev, 0x3330, nv_ro32(dev, ramfc, 0x00/4)); +- nv_wr32(dev, 0x3334, nv_ro32(dev, ramfc, 0x04/4)); +- nv_wr32(dev, 0x3240, nv_ro32(dev, ramfc, 0x08/4)); +- nv_wr32(dev, 0x3320, nv_ro32(dev, ramfc, 0x0c/4)); +- nv_wr32(dev, 0x3244, nv_ro32(dev, ramfc, 0x10/4)); +- nv_wr32(dev, 0x3328, nv_ro32(dev, ramfc, 0x14/4)); +- nv_wr32(dev, 0x3368, nv_ro32(dev, ramfc, 0x18/4)); +- nv_wr32(dev, 0x336c, nv_ro32(dev, ramfc, 0x1c/4)); +- nv_wr32(dev, 0x3370, nv_ro32(dev, ramfc, 0x20/4)); +- nv_wr32(dev, 0x3374, nv_ro32(dev, ramfc, 0x24/4)); +- nv_wr32(dev, 0x3378, nv_ro32(dev, ramfc, 0x28/4)); +- nv_wr32(dev, 0x337c, nv_ro32(dev, ramfc, 0x2c/4)); +- nv_wr32(dev, 0x3228, nv_ro32(dev, ramfc, 0x30/4)); +- nv_wr32(dev, 0x3364, nv_ro32(dev, ramfc, 0x34/4)); +- nv_wr32(dev, 0x32a0, nv_ro32(dev, ramfc, 0x38/4)); +- nv_wr32(dev, 0x3224, nv_ro32(dev, ramfc, 0x3c/4)); +- nv_wr32(dev, 0x324c, nv_ro32(dev, ramfc, 0x40/4)); +- nv_wr32(dev, 0x2044, nv_ro32(dev, ramfc, 0x44/4)); +- nv_wr32(dev, 0x322c, nv_ro32(dev, ramfc, 0x48/4)); +- nv_wr32(dev, 0x3234, nv_ro32(dev, ramfc, 0x4c/4)); +- nv_wr32(dev, 0x3340, nv_ro32(dev, ramfc, 0x50/4)); +- nv_wr32(dev, 0x3344, nv_ro32(dev, ramfc, 0x54/4)); +- nv_wr32(dev, 0x3280, nv_ro32(dev, ramfc, 0x58/4)); +- nv_wr32(dev, 0x3254, nv_ro32(dev, ramfc, 0x5c/4)); +- nv_wr32(dev, 0x3260, nv_ro32(dev, ramfc, 0x60/4)); +- nv_wr32(dev, 0x3264, nv_ro32(dev, ramfc, 0x64/4)); +- nv_wr32(dev, 0x3268, nv_ro32(dev, ramfc, 0x68/4)); +- nv_wr32(dev, 0x326c, nv_ro32(dev, ramfc, 0x6c/4)); +- nv_wr32(dev, 0x32e4, nv_ro32(dev, ramfc, 0x70/4)); +- nv_wr32(dev, 0x3248, nv_ro32(dev, ramfc, 0x74/4)); +- nv_wr32(dev, 0x2088, nv_ro32(dev, ramfc, 0x78/4)); +- nv_wr32(dev, 0x2058, nv_ro32(dev, ramfc, 0x7c/4)); +- nv_wr32(dev, 0x2210, nv_ro32(dev, ramfc, 0x80/4)); +- +- cnt = nv_ro32(dev, ramfc, 0x84/4); ++ nv_wr32(dev, 0x3330, nv_ro32(ramfc, 0x00)); ++ nv_wr32(dev, 0x3334, nv_ro32(ramfc, 0x04)); ++ nv_wr32(dev, 0x3240, nv_ro32(ramfc, 0x08)); ++ nv_wr32(dev, 0x3320, nv_ro32(ramfc, 0x0c)); ++ nv_wr32(dev, 0x3244, nv_ro32(ramfc, 0x10)); ++ nv_wr32(dev, 0x3328, nv_ro32(ramfc, 0x14)); ++ nv_wr32(dev, 0x3368, nv_ro32(ramfc, 0x18)); ++ nv_wr32(dev, 0x336c, nv_ro32(ramfc, 0x1c)); ++ nv_wr32(dev, 0x3370, nv_ro32(ramfc, 0x20)); ++ nv_wr32(dev, 0x3374, nv_ro32(ramfc, 0x24)); ++ nv_wr32(dev, 0x3378, nv_ro32(ramfc, 0x28)); ++ nv_wr32(dev, 0x337c, nv_ro32(ramfc, 0x2c)); ++ nv_wr32(dev, 0x3228, nv_ro32(ramfc, 0x30)); ++ nv_wr32(dev, 0x3364, nv_ro32(ramfc, 0x34)); ++ nv_wr32(dev, 0x32a0, nv_ro32(ramfc, 0x38)); ++ nv_wr32(dev, 0x3224, nv_ro32(ramfc, 0x3c)); ++ nv_wr32(dev, 0x324c, nv_ro32(ramfc, 0x40)); ++ nv_wr32(dev, 0x2044, nv_ro32(ramfc, 0x44)); ++ nv_wr32(dev, 0x322c, nv_ro32(ramfc, 0x48)); ++ nv_wr32(dev, 0x3234, nv_ro32(ramfc, 0x4c)); ++ nv_wr32(dev, 0x3340, nv_ro32(ramfc, 0x50)); ++ nv_wr32(dev, 0x3344, nv_ro32(ramfc, 0x54)); ++ nv_wr32(dev, 0x3280, nv_ro32(ramfc, 0x58)); ++ nv_wr32(dev, 0x3254, nv_ro32(ramfc, 0x5c)); ++ nv_wr32(dev, 0x3260, nv_ro32(ramfc, 0x60)); ++ nv_wr32(dev, 0x3264, nv_ro32(ramfc, 0x64)); ++ nv_wr32(dev, 0x3268, nv_ro32(ramfc, 0x68)); ++ nv_wr32(dev, 0x326c, nv_ro32(ramfc, 0x6c)); ++ nv_wr32(dev, 0x32e4, nv_ro32(ramfc, 0x70)); ++ nv_wr32(dev, 0x3248, nv_ro32(ramfc, 0x74)); ++ nv_wr32(dev, 0x2088, nv_ro32(ramfc, 0x78)); ++ nv_wr32(dev, 0x2058, nv_ro32(ramfc, 0x7c)); ++ nv_wr32(dev, 0x2210, nv_ro32(ramfc, 0x80)); ++ ++ cnt = nv_ro32(ramfc, 0x84); + for (ptr = 0; ptr < cnt; ptr++) { + nv_wr32(dev, NV40_PFIFO_CACHE1_METHOD(ptr), +- nv_ro32(dev, cache, (ptr * 2) + 0)); ++ nv_ro32(cache, (ptr * 8) + 0)); + nv_wr32(dev, NV40_PFIFO_CACHE1_DATA(ptr), +- nv_ro32(dev, cache, (ptr * 2) + 1)); ++ nv_ro32(cache, (ptr * 8) + 4)); + } + nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, cnt << 2); + nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); + + /* guessing that all the 0x34xx regs aren't on NV50 */ +- if (!IS_G80) { +- nv_wr32(dev, 0x340c, nv_ro32(dev, ramfc, 0x88/4)); +- nv_wr32(dev, 0x3400, nv_ro32(dev, ramfc, 0x8c/4)); +- nv_wr32(dev, 0x3404, nv_ro32(dev, ramfc, 0x90/4)); +- nv_wr32(dev, 0x3408, nv_ro32(dev, ramfc, 0x94/4)); +- nv_wr32(dev, 0x3410, nv_ro32(dev, ramfc, 0x98/4)); ++ if (dev_priv->chipset != 0x50) { ++ nv_wr32(dev, 0x340c, nv_ro32(ramfc, 0x88)); ++ nv_wr32(dev, 0x3400, nv_ro32(ramfc, 0x8c)); ++ nv_wr32(dev, 0x3404, nv_ro32(ramfc, 0x90)); ++ nv_wr32(dev, 0x3408, nv_ro32(ramfc, 0x94)); ++ nv_wr32(dev, 0x3410, nv_ro32(ramfc, 0x98)); + } + +- dev_priv->engine.instmem.finish_access(dev); +- + nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16)); + return 0; + } +@@ -431,67 +398,66 @@ nv50_fifo_unload_context(struct drm_device *dev) + return -EINVAL; + } + NV_DEBUG(dev, "ch%d\n", chan->id); +- ramfc = chan->ramfc->gpuobj; +- cache = chan->cache->gpuobj; +- +- dev_priv->engine.instmem.prepare_access(dev, true); +- +- nv_wo32(dev, ramfc, 0x00/4, nv_rd32(dev, 0x3330)); +- nv_wo32(dev, ramfc, 0x04/4, nv_rd32(dev, 0x3334)); +- nv_wo32(dev, ramfc, 0x08/4, nv_rd32(dev, 0x3240)); +- nv_wo32(dev, ramfc, 0x0c/4, nv_rd32(dev, 0x3320)); +- nv_wo32(dev, ramfc, 0x10/4, nv_rd32(dev, 0x3244)); +- nv_wo32(dev, ramfc, 0x14/4, nv_rd32(dev, 0x3328)); +- nv_wo32(dev, ramfc, 0x18/4, nv_rd32(dev, 0x3368)); +- nv_wo32(dev, ramfc, 0x1c/4, nv_rd32(dev, 0x336c)); +- nv_wo32(dev, ramfc, 0x20/4, nv_rd32(dev, 0x3370)); +- nv_wo32(dev, ramfc, 0x24/4, nv_rd32(dev, 0x3374)); +- nv_wo32(dev, ramfc, 0x28/4, nv_rd32(dev, 0x3378)); +- nv_wo32(dev, ramfc, 0x2c/4, nv_rd32(dev, 0x337c)); +- nv_wo32(dev, ramfc, 0x30/4, nv_rd32(dev, 0x3228)); +- nv_wo32(dev, ramfc, 0x34/4, nv_rd32(dev, 0x3364)); +- nv_wo32(dev, ramfc, 0x38/4, nv_rd32(dev, 0x32a0)); +- nv_wo32(dev, ramfc, 0x3c/4, nv_rd32(dev, 0x3224)); +- nv_wo32(dev, ramfc, 0x40/4, nv_rd32(dev, 0x324c)); +- nv_wo32(dev, ramfc, 0x44/4, nv_rd32(dev, 0x2044)); +- nv_wo32(dev, ramfc, 0x48/4, nv_rd32(dev, 0x322c)); +- nv_wo32(dev, ramfc, 0x4c/4, nv_rd32(dev, 0x3234)); +- nv_wo32(dev, ramfc, 0x50/4, nv_rd32(dev, 0x3340)); +- nv_wo32(dev, ramfc, 0x54/4, nv_rd32(dev, 0x3344)); +- nv_wo32(dev, ramfc, 0x58/4, nv_rd32(dev, 0x3280)); +- nv_wo32(dev, ramfc, 0x5c/4, nv_rd32(dev, 0x3254)); +- nv_wo32(dev, ramfc, 0x60/4, nv_rd32(dev, 0x3260)); +- nv_wo32(dev, ramfc, 0x64/4, nv_rd32(dev, 0x3264)); +- nv_wo32(dev, ramfc, 0x68/4, nv_rd32(dev, 0x3268)); +- nv_wo32(dev, ramfc, 0x6c/4, nv_rd32(dev, 0x326c)); +- nv_wo32(dev, ramfc, 0x70/4, nv_rd32(dev, 0x32e4)); +- nv_wo32(dev, ramfc, 0x74/4, nv_rd32(dev, 0x3248)); +- nv_wo32(dev, ramfc, 0x78/4, nv_rd32(dev, 0x2088)); +- nv_wo32(dev, ramfc, 0x7c/4, nv_rd32(dev, 0x2058)); +- nv_wo32(dev, ramfc, 0x80/4, nv_rd32(dev, 0x2210)); ++ ramfc = chan->ramfc; ++ cache = chan->cache; ++ ++ nv_wo32(ramfc, 0x00, nv_rd32(dev, 0x3330)); ++ nv_wo32(ramfc, 0x04, nv_rd32(dev, 0x3334)); ++ nv_wo32(ramfc, 0x08, nv_rd32(dev, 0x3240)); ++ nv_wo32(ramfc, 0x0c, nv_rd32(dev, 0x3320)); ++ nv_wo32(ramfc, 0x10, nv_rd32(dev, 0x3244)); ++ nv_wo32(ramfc, 0x14, nv_rd32(dev, 0x3328)); ++ nv_wo32(ramfc, 0x18, nv_rd32(dev, 0x3368)); ++ nv_wo32(ramfc, 0x1c, nv_rd32(dev, 0x336c)); ++ nv_wo32(ramfc, 0x20, nv_rd32(dev, 0x3370)); ++ nv_wo32(ramfc, 0x24, nv_rd32(dev, 0x3374)); ++ nv_wo32(ramfc, 0x28, nv_rd32(dev, 0x3378)); ++ nv_wo32(ramfc, 0x2c, nv_rd32(dev, 0x337c)); ++ nv_wo32(ramfc, 0x30, nv_rd32(dev, 0x3228)); ++ nv_wo32(ramfc, 0x34, nv_rd32(dev, 0x3364)); ++ nv_wo32(ramfc, 0x38, nv_rd32(dev, 0x32a0)); ++ nv_wo32(ramfc, 0x3c, nv_rd32(dev, 0x3224)); ++ nv_wo32(ramfc, 0x40, nv_rd32(dev, 0x324c)); ++ nv_wo32(ramfc, 0x44, nv_rd32(dev, 0x2044)); ++ nv_wo32(ramfc, 0x48, nv_rd32(dev, 0x322c)); ++ nv_wo32(ramfc, 0x4c, nv_rd32(dev, 0x3234)); ++ nv_wo32(ramfc, 0x50, nv_rd32(dev, 0x3340)); ++ nv_wo32(ramfc, 0x54, nv_rd32(dev, 0x3344)); ++ nv_wo32(ramfc, 0x58, nv_rd32(dev, 0x3280)); ++ nv_wo32(ramfc, 0x5c, nv_rd32(dev, 0x3254)); ++ nv_wo32(ramfc, 0x60, nv_rd32(dev, 0x3260)); ++ nv_wo32(ramfc, 0x64, nv_rd32(dev, 0x3264)); ++ nv_wo32(ramfc, 0x68, nv_rd32(dev, 0x3268)); ++ nv_wo32(ramfc, 0x6c, nv_rd32(dev, 0x326c)); ++ nv_wo32(ramfc, 0x70, nv_rd32(dev, 0x32e4)); ++ nv_wo32(ramfc, 0x74, nv_rd32(dev, 0x3248)); ++ nv_wo32(ramfc, 0x78, nv_rd32(dev, 0x2088)); ++ nv_wo32(ramfc, 0x7c, nv_rd32(dev, 0x2058)); ++ nv_wo32(ramfc, 0x80, nv_rd32(dev, 0x2210)); + + put = (nv_rd32(dev, NV03_PFIFO_CACHE1_PUT) & 0x7ff) >> 2; + get = (nv_rd32(dev, NV03_PFIFO_CACHE1_GET) & 0x7ff) >> 2; + ptr = 0; + while (put != get) { +- nv_wo32(dev, cache, ptr++, +- nv_rd32(dev, NV40_PFIFO_CACHE1_METHOD(get))); +- nv_wo32(dev, cache, ptr++, +- nv_rd32(dev, NV40_PFIFO_CACHE1_DATA(get))); ++ nv_wo32(cache, ptr + 0, ++ nv_rd32(dev, NV40_PFIFO_CACHE1_METHOD(get))); ++ nv_wo32(cache, ptr + 4, ++ nv_rd32(dev, NV40_PFIFO_CACHE1_DATA(get))); + get = (get + 1) & 0x1ff; ++ ptr += 8; + } + + /* guessing that all the 0x34xx regs aren't on NV50 */ +- if (!IS_G80) { +- nv_wo32(dev, ramfc, 0x84/4, ptr >> 1); +- nv_wo32(dev, ramfc, 0x88/4, nv_rd32(dev, 0x340c)); +- nv_wo32(dev, ramfc, 0x8c/4, nv_rd32(dev, 0x3400)); +- nv_wo32(dev, ramfc, 0x90/4, nv_rd32(dev, 0x3404)); +- nv_wo32(dev, ramfc, 0x94/4, nv_rd32(dev, 0x3408)); +- nv_wo32(dev, ramfc, 0x98/4, nv_rd32(dev, 0x3410)); ++ if (dev_priv->chipset != 0x50) { ++ nv_wo32(ramfc, 0x84, ptr >> 3); ++ nv_wo32(ramfc, 0x88, nv_rd32(dev, 0x340c)); ++ nv_wo32(ramfc, 0x8c, nv_rd32(dev, 0x3400)); ++ nv_wo32(ramfc, 0x90, nv_rd32(dev, 0x3404)); ++ nv_wo32(ramfc, 0x94, nv_rd32(dev, 0x3408)); ++ nv_wo32(ramfc, 0x98, nv_rd32(dev, 0x3410)); + } + +- dev_priv->engine.instmem.finish_access(dev); ++ dev_priv->engine.instmem.flush(dev); + + /*XXX: probably reload ch127 (NULL) state back too */ + nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, 127); +diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c +index bb47ad7..b2fab2b 100644 +--- a/drivers/gpu/drm/nouveau/nv50_gpio.c ++++ b/drivers/gpu/drm/nouveau/nv50_gpio.c +@@ -74,3 +74,38 @@ nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state) + nv_wr32(dev, r, v); + return 0; + } ++ ++void ++nv50_gpio_irq_enable(struct drm_device *dev, enum dcb_gpio_tag tag, bool on) ++{ ++ struct dcb_gpio_entry *gpio; ++ u32 reg, mask; ++ ++ gpio = nouveau_bios_gpio_entry(dev, tag); ++ if (!gpio) { ++ NV_ERROR(dev, "gpio tag 0x%02x not found\n", tag); ++ return; ++ } ++ ++ reg = gpio->line < 16 ? 0xe050 : 0xe070; ++ mask = 0x00010001 << (gpio->line & 0xf); ++ ++ nv_wr32(dev, reg + 4, mask); ++ nv_mask(dev, reg + 0, mask, on ? mask : 0); ++} ++ ++int ++nv50_gpio_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ /* disable, and ack any pending gpio interrupts */ ++ nv_wr32(dev, 0xe050, 0x00000000); ++ nv_wr32(dev, 0xe054, 0xffffffff); ++ if (dev_priv->chipset >= 0x90) { ++ nv_wr32(dev, 0xe070, 0x00000000); ++ nv_wr32(dev, 0xe074, 0xffffffff); ++ } ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c +index b203d06..cbf5ae2 100644 +--- a/drivers/gpu/drm/nouveau/nv50_graph.c ++++ b/drivers/gpu/drm/nouveau/nv50_graph.c +@@ -27,11 +27,9 @@ + #include "drmP.h" + #include "drm.h" + #include "nouveau_drv.h" +- ++#include "nouveau_ramht.h" + #include "nouveau_grctx.h" + +-#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) +- + static void + nv50_graph_init_reset(struct drm_device *dev) + { +@@ -103,37 +101,33 @@ static int + nv50_graph_init_ctxctl(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_grctx ctx = {}; ++ uint32_t *cp; ++ int i; + + NV_DEBUG(dev, "\n"); + +- if (nouveau_ctxfw) { +- nouveau_grctx_prog_load(dev); +- dev_priv->engine.graph.grctx_size = 0x70000; ++ cp = kmalloc(512 * 4, GFP_KERNEL); ++ if (!cp) { ++ NV_ERROR(dev, "failed to allocate ctxprog\n"); ++ dev_priv->engine.graph.accel_blocked = true; ++ return 0; + } +- if (!dev_priv->engine.graph.ctxprog) { +- struct nouveau_grctx ctx = {}; +- uint32_t *cp = kmalloc(512 * 4, GFP_KERNEL); +- int i; +- if (!cp) { +- NV_ERROR(dev, "Couldn't alloc ctxprog! Disabling acceleration.\n"); +- dev_priv->engine.graph.accel_blocked = true; +- return 0; +- } +- ctx.dev = dev; +- ctx.mode = NOUVEAU_GRCTX_PROG; +- ctx.data = cp; +- ctx.ctxprog_max = 512; +- if (!nv50_grctx_init(&ctx)) { +- dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; +- +- nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); +- for (i = 0; i < ctx.ctxprog_len; i++) +- nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); +- } else { +- dev_priv->engine.graph.accel_blocked = true; +- } +- kfree(cp); ++ ++ ctx.dev = dev; ++ ctx.mode = NOUVEAU_GRCTX_PROG; ++ ctx.data = cp; ++ ctx.ctxprog_max = 512; ++ if (!nv50_grctx_init(&ctx)) { ++ dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; ++ ++ nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); ++ for (i = 0; i < ctx.ctxprog_len; i++) ++ nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); ++ } else { ++ dev_priv->engine.graph.accel_blocked = true; + } ++ kfree(cp); + + nv_wr32(dev, 0x400320, 4); + nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); +@@ -164,7 +158,6 @@ void + nv50_graph_takedown(struct drm_device *dev) + { + NV_DEBUG(dev, "\n"); +- nouveau_grctx_fini(dev); + } + + void +@@ -188,7 +181,7 @@ nv50_graph_channel(struct drm_device *dev) + /* Be sure we're not in the middle of a context switch or bad things + * will happen, such as unloading the wrong pgraph context. + */ +- if (!nv_wait(0x400300, 0x00000001, 0x00000000)) ++ if (!nv_wait(dev, 0x400300, 0x00000001, 0x00000000)) + NV_ERROR(dev, "Ctxprog is still running\n"); + + inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR); +@@ -199,7 +192,7 @@ nv50_graph_channel(struct drm_device *dev) + for (i = 0; i < dev_priv->engine.fifo.channels; i++) { + struct nouveau_channel *chan = dev_priv->fifos[i]; + +- if (chan && chan->ramin && chan->ramin->instance == inst) ++ if (chan && chan->ramin && chan->ramin->vinst == inst) + return chan; + } + +@@ -211,44 +204,36 @@ nv50_graph_create_context(struct nouveau_channel *chan) + { + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; +- struct nouveau_gpuobj *ctx; ++ struct nouveau_gpuobj *ramin = chan->ramin; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; ++ struct nouveau_grctx ctx = {}; + int hdr, ret; + + NV_DEBUG(dev, "ch%d\n", chan->id); + +- ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size, +- 0x1000, NVOBJ_FLAG_ZERO_ALLOC | +- NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx); ++ ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 0x1000, ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx); + if (ret) + return ret; +- ctx = chan->ramin_grctx->gpuobj; +- +- hdr = IS_G80 ? 0x200 : 0x20; +- dev_priv->engine.instmem.prepare_access(dev, true); +- nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002); +- nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance + +- pgraph->grctx_size - 1); +- nv_wo32(dev, ramin, (hdr + 0x08)/4, chan->ramin_grctx->instance); +- nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0); +- nv_wo32(dev, ramin, (hdr + 0x10)/4, 0); +- nv_wo32(dev, ramin, (hdr + 0x14)/4, 0x00010000); +- dev_priv->engine.instmem.finish_access(dev); +- +- dev_priv->engine.instmem.prepare_access(dev, true); +- if (!pgraph->ctxprog) { +- struct nouveau_grctx ctx = {}; +- ctx.dev = chan->dev; +- ctx.mode = NOUVEAU_GRCTX_VALS; +- ctx.data = chan->ramin_grctx->gpuobj; +- nv50_grctx_init(&ctx); +- } else { +- nouveau_grctx_vals_load(dev, ctx); +- } +- nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); +- dev_priv->engine.instmem.finish_access(dev); + ++ hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20; ++ nv_wo32(ramin, hdr + 0x00, 0x00190002); ++ nv_wo32(ramin, hdr + 0x04, chan->ramin_grctx->vinst + ++ pgraph->grctx_size - 1); ++ nv_wo32(ramin, hdr + 0x08, chan->ramin_grctx->vinst); ++ nv_wo32(ramin, hdr + 0x0c, 0); ++ nv_wo32(ramin, hdr + 0x10, 0); ++ nv_wo32(ramin, hdr + 0x14, 0x00010000); ++ ++ ctx.dev = chan->dev; ++ ctx.mode = NOUVEAU_GRCTX_VALS; ++ ctx.data = chan->ramin_grctx; ++ nv50_grctx_init(&ctx); ++ ++ nv_wo32(chan->ramin_grctx, 0x00000, chan->ramin->vinst >> 12); ++ ++ dev_priv->engine.instmem.flush(dev); + return 0; + } + +@@ -257,19 +242,18 @@ nv50_graph_destroy_context(struct nouveau_channel *chan) + { + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; +- int i, hdr = IS_G80 ? 0x200 : 0x20; ++ int i, hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20; + + NV_DEBUG(dev, "ch%d\n", chan->id); + +- if (!chan->ramin || !chan->ramin->gpuobj) ++ if (!chan->ramin) + return; + +- dev_priv->engine.instmem.prepare_access(dev, true); + for (i = hdr; i < hdr + 24; i += 4) +- nv_wo32(dev, chan->ramin->gpuobj, i/4, 0); +- dev_priv->engine.instmem.finish_access(dev); ++ nv_wo32(chan->ramin, i, 0); ++ dev_priv->engine.instmem.flush(dev); + +- nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); ++ nouveau_gpuobj_ref(NULL, &chan->ramin_grctx); + } + + static int +@@ -296,7 +280,7 @@ nv50_graph_do_load_context(struct drm_device *dev, uint32_t inst) + int + nv50_graph_load_context(struct nouveau_channel *chan) + { +- uint32_t inst = chan->ramin->instance >> 12; ++ uint32_t inst = chan->ramin->vinst >> 12; + + NV_DEBUG(chan->dev, "ch%d\n", chan->id); + return nv50_graph_do_load_context(chan->dev, inst); +@@ -341,15 +325,16 @@ static int + nv50_graph_nvsw_dma_vblsem(struct nouveau_channel *chan, int grclass, + int mthd, uint32_t data) + { +- struct nouveau_gpuobj_ref *ref = NULL; ++ struct nouveau_gpuobj *gpuobj; + +- if (nouveau_gpuobj_ref_find(chan, data, &ref)) ++ gpuobj = nouveau_ramht_find(chan, data); ++ if (!gpuobj) + return -ENOENT; + +- if (nouveau_notifier_offset(ref->gpuobj, NULL)) ++ if (nouveau_notifier_offset(gpuobj, NULL)) + return -EINVAL; + +- chan->nvsw.vblsem = ref->gpuobj; ++ chan->nvsw.vblsem = gpuobj; + chan->nvsw.vblsem_offset = ~0; + return 0; + } +diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c +index 42a8fb2..336aab2 100644 +--- a/drivers/gpu/drm/nouveau/nv50_grctx.c ++++ b/drivers/gpu/drm/nouveau/nv50_grctx.c +@@ -103,6 +103,9 @@ + #include "nouveau_drv.h" + #include "nouveau_grctx.h" + ++#define IS_NVA3F(x) (((x) > 0xa0 && (x) < 0xaa) || (x) == 0xaf) ++#define IS_NVAAF(x) ((x) >= 0xaa && (x) <= 0xac) ++ + /* + * This code deals with PGRAPH contexts on NV50 family cards. Like NV40, it's + * the GPU itself that does context-switching, but it needs a special +@@ -182,6 +185,7 @@ nv50_grctx_init(struct nouveau_grctx *ctx) + case 0xa8: + case 0xaa: + case 0xac: ++ case 0xaf: + break; + default: + NV_ERROR(ctx->dev, "I don't know how to make a ctxprog for " +@@ -268,6 +272,9 @@ nv50_grctx_init(struct nouveau_grctx *ctx) + */ + + static void ++nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx); ++ ++static void + nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + { + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; +@@ -286,7 +293,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + gr_def(ctx, 0x400840, 0xffe806a8); + } + gr_def(ctx, 0x400844, 0x00000002); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) ++ if (IS_NVA3F(dev_priv->chipset)) + gr_def(ctx, 0x400894, 0x00001000); + gr_def(ctx, 0x4008e8, 0x00000003); + gr_def(ctx, 0x4008ec, 0x00001000); +@@ -299,13 +306,15 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + + if (dev_priv->chipset >= 0xa0) + cp_ctx(ctx, 0x400b00, 0x1); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { ++ if (IS_NVA3F(dev_priv->chipset)) { + cp_ctx(ctx, 0x400b10, 0x1); + gr_def(ctx, 0x400b10, 0x0001629d); + cp_ctx(ctx, 0x400b20, 0x1); + gr_def(ctx, 0x400b20, 0x0001629d); + } + ++ nv50_graph_construct_mmio_ddata(ctx); ++ + /* 0C00: VFETCH */ + cp_ctx(ctx, 0x400c08, 0x2); + gr_def(ctx, 0x400c08, 0x0000fe0c); +@@ -314,7 +323,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + if (dev_priv->chipset < 0xa0) { + cp_ctx(ctx, 0x401008, 0x4); + gr_def(ctx, 0x401014, 0x00001000); +- } else if (dev_priv->chipset == 0xa0 || dev_priv->chipset >= 0xaa) { ++ } else if (!IS_NVA3F(dev_priv->chipset)) { + cp_ctx(ctx, 0x401008, 0x5); + gr_def(ctx, 0x401018, 0x00001000); + } else { +@@ -368,10 +377,13 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + case 0xa3: + case 0xa5: + case 0xa8: ++ case 0xaf: + gr_def(ctx, 0x401c00, 0x142500df); + break; + } + ++ /* 2000 */ ++ + /* 2400 */ + cp_ctx(ctx, 0x402400, 0x1); + if (dev_priv->chipset == 0x50) +@@ -380,12 +392,12 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + cp_ctx(ctx, 0x402408, 0x2); + gr_def(ctx, 0x402408, 0x00000600); + +- /* 2800 */ ++ /* 2800: CSCHED */ + cp_ctx(ctx, 0x402800, 0x1); + if (dev_priv->chipset == 0x50) + gr_def(ctx, 0x402800, 0x00000006); + +- /* 2C00 */ ++ /* 2C00: ZCULL */ + cp_ctx(ctx, 0x402c08, 0x6); + if (dev_priv->chipset != 0x50) + gr_def(ctx, 0x402c14, 0x01000000); +@@ -396,23 +408,23 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + cp_ctx(ctx, 0x402ca0, 0x2); + if (dev_priv->chipset < 0xa0) + gr_def(ctx, 0x402ca0, 0x00000400); +- else if (dev_priv->chipset == 0xa0 || dev_priv->chipset >= 0xaa) ++ else if (!IS_NVA3F(dev_priv->chipset)) + gr_def(ctx, 0x402ca0, 0x00000800); + else + gr_def(ctx, 0x402ca0, 0x00000400); + cp_ctx(ctx, 0x402cac, 0x4); + +- /* 3000 */ ++ /* 3000: ENG2D */ + cp_ctx(ctx, 0x403004, 0x1); + gr_def(ctx, 0x403004, 0x00000001); + +- /* 3404 */ ++ /* 3400 */ + if (dev_priv->chipset >= 0xa0) { + cp_ctx(ctx, 0x403404, 0x1); + gr_def(ctx, 0x403404, 0x00000001); + } + +- /* 5000 */ ++ /* 5000: CCACHE */ + cp_ctx(ctx, 0x405000, 0x1); + switch (dev_priv->chipset) { + case 0x50: +@@ -425,6 +437,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + case 0xa8: + case 0xaa: + case 0xac: ++ case 0xaf: + gr_def(ctx, 0x405000, 0x000e0080); + break; + case 0x86: +@@ -441,210 +454,6 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + cp_ctx(ctx, 0x405024, 0x1); + cp_ctx(ctx, 0x40502c, 0x1); + +- /* 5400 or maybe 4800 */ +- if (dev_priv->chipset == 0x50) { +- offset = 0x405400; +- cp_ctx(ctx, 0x405400, 0xea); +- } else if (dev_priv->chipset < 0x94) { +- offset = 0x405400; +- cp_ctx(ctx, 0x405400, 0xcb); +- } else if (dev_priv->chipset < 0xa0) { +- offset = 0x405400; +- cp_ctx(ctx, 0x405400, 0xcc); +- } else if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { +- offset = 0x404800; +- cp_ctx(ctx, 0x404800, 0xda); +- } else { +- offset = 0x405400; +- cp_ctx(ctx, 0x405400, 0xd4); +- } +- gr_def(ctx, offset + 0x0c, 0x00000002); +- gr_def(ctx, offset + 0x10, 0x00000001); +- if (dev_priv->chipset >= 0x94) +- offset += 4; +- gr_def(ctx, offset + 0x1c, 0x00000001); +- gr_def(ctx, offset + 0x20, 0x00000100); +- gr_def(ctx, offset + 0x38, 0x00000002); +- gr_def(ctx, offset + 0x3c, 0x00000001); +- gr_def(ctx, offset + 0x40, 0x00000001); +- gr_def(ctx, offset + 0x50, 0x00000001); +- gr_def(ctx, offset + 0x54, 0x003fffff); +- gr_def(ctx, offset + 0x58, 0x00001fff); +- gr_def(ctx, offset + 0x60, 0x00000001); +- gr_def(ctx, offset + 0x64, 0x00000001); +- gr_def(ctx, offset + 0x6c, 0x00000001); +- gr_def(ctx, offset + 0x70, 0x00000001); +- gr_def(ctx, offset + 0x74, 0x00000001); +- gr_def(ctx, offset + 0x78, 0x00000004); +- gr_def(ctx, offset + 0x7c, 0x00000001); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- offset += 4; +- gr_def(ctx, offset + 0x80, 0x00000001); +- gr_def(ctx, offset + 0x84, 0x00000001); +- gr_def(ctx, offset + 0x88, 0x00000007); +- gr_def(ctx, offset + 0x8c, 0x00000001); +- gr_def(ctx, offset + 0x90, 0x00000007); +- gr_def(ctx, offset + 0x94, 0x00000001); +- gr_def(ctx, offset + 0x98, 0x00000001); +- gr_def(ctx, offset + 0x9c, 0x00000001); +- if (dev_priv->chipset == 0x50) { +- gr_def(ctx, offset + 0xb0, 0x00000001); +- gr_def(ctx, offset + 0xb4, 0x00000001); +- gr_def(ctx, offset + 0xbc, 0x00000001); +- gr_def(ctx, offset + 0xc0, 0x0000000a); +- gr_def(ctx, offset + 0xd0, 0x00000040); +- gr_def(ctx, offset + 0xd8, 0x00000002); +- gr_def(ctx, offset + 0xdc, 0x00000100); +- gr_def(ctx, offset + 0xe0, 0x00000001); +- gr_def(ctx, offset + 0xe4, 0x00000100); +- gr_def(ctx, offset + 0x100, 0x00000001); +- gr_def(ctx, offset + 0x124, 0x00000004); +- gr_def(ctx, offset + 0x13c, 0x00000001); +- gr_def(ctx, offset + 0x140, 0x00000100); +- gr_def(ctx, offset + 0x148, 0x00000001); +- gr_def(ctx, offset + 0x154, 0x00000100); +- gr_def(ctx, offset + 0x158, 0x00000001); +- gr_def(ctx, offset + 0x15c, 0x00000100); +- gr_def(ctx, offset + 0x164, 0x00000001); +- gr_def(ctx, offset + 0x170, 0x00000100); +- gr_def(ctx, offset + 0x174, 0x00000001); +- gr_def(ctx, offset + 0x17c, 0x00000001); +- gr_def(ctx, offset + 0x188, 0x00000002); +- gr_def(ctx, offset + 0x190, 0x00000001); +- gr_def(ctx, offset + 0x198, 0x00000001); +- gr_def(ctx, offset + 0x1ac, 0x00000003); +- offset += 0xd0; +- } else { +- gr_def(ctx, offset + 0xb0, 0x00000001); +- gr_def(ctx, offset + 0xb4, 0x00000100); +- gr_def(ctx, offset + 0xbc, 0x00000001); +- gr_def(ctx, offset + 0xc8, 0x00000100); +- gr_def(ctx, offset + 0xcc, 0x00000001); +- gr_def(ctx, offset + 0xd0, 0x00000100); +- gr_def(ctx, offset + 0xd8, 0x00000001); +- gr_def(ctx, offset + 0xe4, 0x00000100); +- } +- gr_def(ctx, offset + 0xf8, 0x00000004); +- gr_def(ctx, offset + 0xfc, 0x00000070); +- gr_def(ctx, offset + 0x100, 0x00000080); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- offset += 4; +- gr_def(ctx, offset + 0x114, 0x0000000c); +- if (dev_priv->chipset == 0x50) +- offset -= 4; +- gr_def(ctx, offset + 0x11c, 0x00000008); +- gr_def(ctx, offset + 0x120, 0x00000014); +- if (dev_priv->chipset == 0x50) { +- gr_def(ctx, offset + 0x124, 0x00000026); +- offset -= 0x18; +- } else { +- gr_def(ctx, offset + 0x128, 0x00000029); +- gr_def(ctx, offset + 0x12c, 0x00000027); +- gr_def(ctx, offset + 0x130, 0x00000026); +- gr_def(ctx, offset + 0x134, 0x00000008); +- gr_def(ctx, offset + 0x138, 0x00000004); +- gr_def(ctx, offset + 0x13c, 0x00000027); +- } +- gr_def(ctx, offset + 0x148, 0x00000001); +- gr_def(ctx, offset + 0x14c, 0x00000002); +- gr_def(ctx, offset + 0x150, 0x00000003); +- gr_def(ctx, offset + 0x154, 0x00000004); +- gr_def(ctx, offset + 0x158, 0x00000005); +- gr_def(ctx, offset + 0x15c, 0x00000006); +- gr_def(ctx, offset + 0x160, 0x00000007); +- gr_def(ctx, offset + 0x164, 0x00000001); +- gr_def(ctx, offset + 0x1a8, 0x000000cf); +- if (dev_priv->chipset == 0x50) +- offset -= 4; +- gr_def(ctx, offset + 0x1d8, 0x00000080); +- gr_def(ctx, offset + 0x1dc, 0x00000004); +- gr_def(ctx, offset + 0x1e0, 0x00000004); +- if (dev_priv->chipset == 0x50) +- offset -= 4; +- else +- gr_def(ctx, offset + 0x1e4, 0x00000003); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { +- gr_def(ctx, offset + 0x1ec, 0x00000003); +- offset += 8; +- } +- gr_def(ctx, offset + 0x1e8, 0x00000001); +- if (dev_priv->chipset == 0x50) +- offset -= 4; +- gr_def(ctx, offset + 0x1f4, 0x00000012); +- gr_def(ctx, offset + 0x1f8, 0x00000010); +- gr_def(ctx, offset + 0x1fc, 0x0000000c); +- gr_def(ctx, offset + 0x200, 0x00000001); +- gr_def(ctx, offset + 0x210, 0x00000004); +- gr_def(ctx, offset + 0x214, 0x00000002); +- gr_def(ctx, offset + 0x218, 0x00000004); +- if (dev_priv->chipset >= 0xa0) +- offset += 4; +- gr_def(ctx, offset + 0x224, 0x003fffff); +- gr_def(ctx, offset + 0x228, 0x00001fff); +- if (dev_priv->chipset == 0x50) +- offset -= 0x20; +- else if (dev_priv->chipset >= 0xa0) { +- gr_def(ctx, offset + 0x250, 0x00000001); +- gr_def(ctx, offset + 0x254, 0x00000001); +- gr_def(ctx, offset + 0x258, 0x00000002); +- offset += 0x10; +- } +- gr_def(ctx, offset + 0x250, 0x00000004); +- gr_def(ctx, offset + 0x254, 0x00000014); +- gr_def(ctx, offset + 0x258, 0x00000001); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- offset += 4; +- gr_def(ctx, offset + 0x264, 0x00000002); +- if (dev_priv->chipset >= 0xa0) +- offset += 8; +- gr_def(ctx, offset + 0x270, 0x00000001); +- gr_def(ctx, offset + 0x278, 0x00000002); +- gr_def(ctx, offset + 0x27c, 0x00001000); +- if (dev_priv->chipset == 0x50) +- offset -= 0xc; +- else { +- gr_def(ctx, offset + 0x280, 0x00000e00); +- gr_def(ctx, offset + 0x284, 0x00001000); +- gr_def(ctx, offset + 0x288, 0x00001e00); +- } +- gr_def(ctx, offset + 0x290, 0x00000001); +- gr_def(ctx, offset + 0x294, 0x00000001); +- gr_def(ctx, offset + 0x298, 0x00000001); +- gr_def(ctx, offset + 0x29c, 0x00000001); +- gr_def(ctx, offset + 0x2a0, 0x00000001); +- gr_def(ctx, offset + 0x2b0, 0x00000200); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { +- gr_def(ctx, offset + 0x2b4, 0x00000200); +- offset += 4; +- } +- if (dev_priv->chipset < 0xa0) { +- gr_def(ctx, offset + 0x2b8, 0x00000001); +- gr_def(ctx, offset + 0x2bc, 0x00000070); +- gr_def(ctx, offset + 0x2c0, 0x00000080); +- gr_def(ctx, offset + 0x2cc, 0x00000001); +- gr_def(ctx, offset + 0x2d0, 0x00000070); +- gr_def(ctx, offset + 0x2d4, 0x00000080); +- } else { +- gr_def(ctx, offset + 0x2b8, 0x00000001); +- gr_def(ctx, offset + 0x2bc, 0x000000f0); +- gr_def(ctx, offset + 0x2c0, 0x000000ff); +- gr_def(ctx, offset + 0x2cc, 0x00000001); +- gr_def(ctx, offset + 0x2d0, 0x000000f0); +- gr_def(ctx, offset + 0x2d4, 0x000000ff); +- gr_def(ctx, offset + 0x2dc, 0x00000009); +- offset += 4; +- } +- gr_def(ctx, offset + 0x2e4, 0x00000001); +- gr_def(ctx, offset + 0x2e8, 0x000000cf); +- gr_def(ctx, offset + 0x2f0, 0x00000001); +- gr_def(ctx, offset + 0x300, 0x000000cf); +- gr_def(ctx, offset + 0x308, 0x00000002); +- gr_def(ctx, offset + 0x310, 0x00000001); +- gr_def(ctx, offset + 0x318, 0x00000001); +- gr_def(ctx, offset + 0x320, 0x000000cf); +- gr_def(ctx, offset + 0x324, 0x000000cf); +- gr_def(ctx, offset + 0x328, 0x00000001); +- + /* 6000? */ + if (dev_priv->chipset == 0x50) + cp_ctx(ctx, 0x4063e0, 0x1); +@@ -661,7 +470,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + gr_def(ctx, 0x406818, 0x00000f80); + else + gr_def(ctx, 0x406818, 0x00001f80); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) ++ if (IS_NVA3F(dev_priv->chipset)) + gr_def(ctx, 0x40681c, 0x00000030); + cp_ctx(ctx, 0x406830, 0x3); + } +@@ -706,7 +515,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + + if (dev_priv->chipset < 0xa0) + cp_ctx(ctx, 0x407094 + (i<<8), 1); +- else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) ++ else if (!IS_NVA3F(dev_priv->chipset)) + cp_ctx(ctx, 0x407094 + (i<<8), 3); + else { + cp_ctx(ctx, 0x407094 + (i<<8), 4); +@@ -799,6 +608,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + case 0xa8: + case 0xaa: + case 0xac: ++ case 0xaf: + gr_def(ctx, offset + 0x1c, 0x300c0000); + break; + } +@@ -825,7 +635,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + gr_def(ctx, base + 0x304, 0x00007070); + else if (dev_priv->chipset < 0xa0) + gr_def(ctx, base + 0x304, 0x00027070); +- else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) ++ else if (!IS_NVA3F(dev_priv->chipset)) + gr_def(ctx, base + 0x304, 0x01127070); + else + gr_def(ctx, base + 0x304, 0x05127070); +@@ -849,7 +659,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + if (dev_priv->chipset < 0xa0) { + cp_ctx(ctx, base + 0x340, 9); + offset = base + 0x340; +- } else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) { ++ } else if (!IS_NVA3F(dev_priv->chipset)) { + cp_ctx(ctx, base + 0x33c, 0xb); + offset = base + 0x344; + } else { +@@ -880,7 +690,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + gr_def(ctx, offset + 0x0, 0x000001f0); + gr_def(ctx, offset + 0x4, 0x00000001); + gr_def(ctx, offset + 0x8, 0x00000003); +- if (dev_priv->chipset == 0x50 || dev_priv->chipset >= 0xaa) ++ if (dev_priv->chipset == 0x50 || IS_NVAAF(dev_priv->chipset)) + gr_def(ctx, offset + 0xc, 0x00008000); + gr_def(ctx, offset + 0x14, 0x00039e00); + cp_ctx(ctx, offset + 0x1c, 2); +@@ -892,7 +702,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + + if (dev_priv->chipset >= 0xa0) { + cp_ctx(ctx, base + 0x54c, 2); +- if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) ++ if (!IS_NVA3F(dev_priv->chipset)) + gr_def(ctx, base + 0x54c, 0x003fe006); + else + gr_def(ctx, base + 0x54c, 0x003fe007); +@@ -948,6 +758,336 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + } + } + ++static void ++dd_emit(struct nouveau_grctx *ctx, int num, uint32_t val) { ++ int i; ++ if (val && ctx->mode == NOUVEAU_GRCTX_VALS) ++ for (i = 0; i < num; i++) ++ nv_wo32(ctx->data, 4 * (ctx->ctxvals_pos + i), val); ++ ctx->ctxvals_pos += num; ++} ++ ++static void ++nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx) ++{ ++ struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; ++ int base, num; ++ base = ctx->ctxvals_pos; ++ ++ /* tesla state */ ++ dd_emit(ctx, 1, 0); /* 00000001 UNK0F90 */ ++ dd_emit(ctx, 1, 0); /* 00000001 UNK135C */ ++ ++ /* SRC_TIC state */ ++ dd_emit(ctx, 1, 0); /* 00000007 SRC_TILE_MODE_Z */ ++ dd_emit(ctx, 1, 2); /* 00000007 SRC_TILE_MODE_Y */ ++ dd_emit(ctx, 1, 1); /* 00000001 SRC_LINEAR #1 */ ++ dd_emit(ctx, 1, 0); /* 000000ff SRC_ADDRESS_HIGH */ ++ dd_emit(ctx, 1, 0); /* 00000001 SRC_SRGB */ ++ if (dev_priv->chipset >= 0x94) ++ dd_emit(ctx, 1, 0); /* 00000003 eng2d UNK0258 */ ++ dd_emit(ctx, 1, 1); /* 00000fff SRC_DEPTH */ ++ dd_emit(ctx, 1, 0x100); /* 0000ffff SRC_HEIGHT */ ++ ++ /* turing state */ ++ dd_emit(ctx, 1, 0); /* 0000000f TEXTURES_LOG2 */ ++ dd_emit(ctx, 1, 0); /* 0000000f SAMPLERS_LOG2 */ ++ dd_emit(ctx, 1, 0); /* 000000ff CB_DEF_ADDRESS_HIGH */ ++ dd_emit(ctx, 1, 0); /* ffffffff CB_DEF_ADDRESS_LOW */ ++ dd_emit(ctx, 1, 0); /* ffffffff SHARED_SIZE */ ++ dd_emit(ctx, 1, 2); /* ffffffff REG_MODE */ ++ dd_emit(ctx, 1, 1); /* 0000ffff BLOCK_ALLOC_THREADS */ ++ dd_emit(ctx, 1, 1); /* 00000001 LANES32 */ ++ dd_emit(ctx, 1, 0); /* 000000ff UNK370 */ ++ dd_emit(ctx, 1, 0); /* 000000ff USER_PARAM_UNK */ ++ dd_emit(ctx, 1, 0); /* 000000ff USER_PARAM_COUNT */ ++ dd_emit(ctx, 1, 1); /* 000000ff UNK384 bits 8-15 */ ++ dd_emit(ctx, 1, 0x3fffff); /* 003fffff TIC_LIMIT */ ++ dd_emit(ctx, 1, 0x1fff); /* 000fffff TSC_LIMIT */ ++ dd_emit(ctx, 1, 0); /* 0000ffff CB_ADDR_INDEX */ ++ dd_emit(ctx, 1, 1); /* 000007ff BLOCKDIM_X */ ++ dd_emit(ctx, 1, 1); /* 000007ff BLOCKDIM_XMY */ ++ dd_emit(ctx, 1, 0); /* 00000001 BLOCKDIM_XMY_OVERFLOW */ ++ dd_emit(ctx, 1, 1); /* 0003ffff BLOCKDIM_XMYMZ */ ++ dd_emit(ctx, 1, 1); /* 000007ff BLOCKDIM_Y */ ++ dd_emit(ctx, 1, 1); /* 0000007f BLOCKDIM_Z */ ++ dd_emit(ctx, 1, 4); /* 000000ff CP_REG_ALLOC_TEMP */ ++ dd_emit(ctx, 1, 1); /* 00000001 BLOCKDIM_DIRTY */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ dd_emit(ctx, 1, 0); /* 00000003 UNK03E8 */ ++ dd_emit(ctx, 1, 1); /* 0000007f BLOCK_ALLOC_HALFWARPS */ ++ dd_emit(ctx, 1, 1); /* 00000007 LOCAL_WARPS_NO_CLAMP */ ++ dd_emit(ctx, 1, 7); /* 00000007 LOCAL_WARPS_LOG_ALLOC */ ++ dd_emit(ctx, 1, 1); /* 00000007 STACK_WARPS_NO_CLAMP */ ++ dd_emit(ctx, 1, 7); /* 00000007 STACK_WARPS_LOG_ALLOC */ ++ dd_emit(ctx, 1, 1); /* 00001fff BLOCK_ALLOC_REGSLOTS_PACKED */ ++ dd_emit(ctx, 1, 1); /* 00001fff BLOCK_ALLOC_REGSLOTS_STRIDED */ ++ dd_emit(ctx, 1, 1); /* 000007ff BLOCK_ALLOC_THREADS */ ++ ++ /* compat 2d state */ ++ if (dev_priv->chipset == 0x50) { ++ dd_emit(ctx, 4, 0); /* 0000ffff clip X, Y, W, H */ ++ ++ dd_emit(ctx, 1, 1); /* ffffffff chroma COLOR_FORMAT */ ++ ++ dd_emit(ctx, 1, 1); /* ffffffff pattern COLOR_FORMAT */ ++ dd_emit(ctx, 1, 0); /* ffffffff pattern SHAPE */ ++ dd_emit(ctx, 1, 1); /* ffffffff pattern PATTERN_SELECT */ ++ ++ dd_emit(ctx, 1, 0xa); /* ffffffff surf2d SRC_FORMAT */ ++ dd_emit(ctx, 1, 0); /* ffffffff surf2d DMA_SRC */ ++ dd_emit(ctx, 1, 0); /* 000000ff surf2d SRC_ADDRESS_HIGH */ ++ dd_emit(ctx, 1, 0); /* ffffffff surf2d SRC_ADDRESS_LOW */ ++ dd_emit(ctx, 1, 0x40); /* 0000ffff surf2d SRC_PITCH */ ++ dd_emit(ctx, 1, 0); /* 0000000f surf2d SRC_TILE_MODE_Z */ ++ dd_emit(ctx, 1, 2); /* 0000000f surf2d SRC_TILE_MODE_Y */ ++ dd_emit(ctx, 1, 0x100); /* ffffffff surf2d SRC_HEIGHT */ ++ dd_emit(ctx, 1, 1); /* 00000001 surf2d SRC_LINEAR */ ++ dd_emit(ctx, 1, 0x100); /* ffffffff surf2d SRC_WIDTH */ ++ ++ dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_B_X */ ++ dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_B_Y */ ++ dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_C_X */ ++ dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_C_Y */ ++ dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_D_X */ ++ dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_D_Y */ ++ dd_emit(ctx, 1, 1); /* ffffffff gdirect COLOR_FORMAT */ ++ dd_emit(ctx, 1, 0); /* ffffffff gdirect OPERATION */ ++ dd_emit(ctx, 1, 0); /* 0000ffff gdirect POINT_X */ ++ dd_emit(ctx, 1, 0); /* 0000ffff gdirect POINT_Y */ ++ ++ dd_emit(ctx, 1, 0); /* 0000ffff blit SRC_Y */ ++ dd_emit(ctx, 1, 0); /* ffffffff blit OPERATION */ ++ ++ dd_emit(ctx, 1, 0); /* ffffffff ifc OPERATION */ ++ ++ dd_emit(ctx, 1, 0); /* ffffffff iifc INDEX_FORMAT */ ++ dd_emit(ctx, 1, 0); /* ffffffff iifc LUT_OFFSET */ ++ dd_emit(ctx, 1, 4); /* ffffffff iifc COLOR_FORMAT */ ++ dd_emit(ctx, 1, 0); /* ffffffff iifc OPERATION */ ++ } ++ ++ /* m2mf state */ ++ dd_emit(ctx, 1, 0); /* ffffffff m2mf LINE_COUNT */ ++ dd_emit(ctx, 1, 0); /* ffffffff m2mf LINE_LENGTH_IN */ ++ dd_emit(ctx, 2, 0); /* ffffffff m2mf OFFSET_IN, OFFSET_OUT */ ++ dd_emit(ctx, 1, 1); /* ffffffff m2mf TILING_DEPTH_OUT */ ++ dd_emit(ctx, 1, 0x100); /* ffffffff m2mf TILING_HEIGHT_OUT */ ++ dd_emit(ctx, 1, 0); /* ffffffff m2mf TILING_POSITION_OUT_Z */ ++ dd_emit(ctx, 1, 1); /* 00000001 m2mf LINEAR_OUT */ ++ dd_emit(ctx, 2, 0); /* 0000ffff m2mf TILING_POSITION_OUT_X, Y */ ++ dd_emit(ctx, 1, 0x100); /* ffffffff m2mf TILING_PITCH_OUT */ ++ dd_emit(ctx, 1, 1); /* ffffffff m2mf TILING_DEPTH_IN */ ++ dd_emit(ctx, 1, 0x100); /* ffffffff m2mf TILING_HEIGHT_IN */ ++ dd_emit(ctx, 1, 0); /* ffffffff m2mf TILING_POSITION_IN_Z */ ++ dd_emit(ctx, 1, 1); /* 00000001 m2mf LINEAR_IN */ ++ dd_emit(ctx, 2, 0); /* 0000ffff m2mf TILING_POSITION_IN_X, Y */ ++ dd_emit(ctx, 1, 0x100); /* ffffffff m2mf TILING_PITCH_IN */ ++ ++ /* more compat 2d state */ ++ if (dev_priv->chipset == 0x50) { ++ dd_emit(ctx, 1, 1); /* ffffffff line COLOR_FORMAT */ ++ dd_emit(ctx, 1, 0); /* ffffffff line OPERATION */ ++ ++ dd_emit(ctx, 1, 1); /* ffffffff triangle COLOR_FORMAT */ ++ dd_emit(ctx, 1, 0); /* ffffffff triangle OPERATION */ ++ ++ dd_emit(ctx, 1, 0); /* 0000000f sifm TILE_MODE_Z */ ++ dd_emit(ctx, 1, 2); /* 0000000f sifm TILE_MODE_Y */ ++ dd_emit(ctx, 1, 0); /* 000000ff sifm FORMAT_FILTER */ ++ dd_emit(ctx, 1, 1); /* 000000ff sifm FORMAT_ORIGIN */ ++ dd_emit(ctx, 1, 0); /* 0000ffff sifm SRC_PITCH */ ++ dd_emit(ctx, 1, 1); /* 00000001 sifm SRC_LINEAR */ ++ dd_emit(ctx, 1, 0); /* 000000ff sifm SRC_OFFSET_HIGH */ ++ dd_emit(ctx, 1, 0); /* ffffffff sifm SRC_OFFSET */ ++ dd_emit(ctx, 1, 0); /* 0000ffff sifm SRC_HEIGHT */ ++ dd_emit(ctx, 1, 0); /* 0000ffff sifm SRC_WIDTH */ ++ dd_emit(ctx, 1, 3); /* ffffffff sifm COLOR_FORMAT */ ++ dd_emit(ctx, 1, 0); /* ffffffff sifm OPERATION */ ++ ++ dd_emit(ctx, 1, 0); /* ffffffff sifc OPERATION */ ++ } ++ ++ /* tesla state */ ++ dd_emit(ctx, 1, 0); /* 0000000f GP_TEXTURES_LOG2 */ ++ dd_emit(ctx, 1, 0); /* 0000000f GP_SAMPLERS_LOG2 */ ++ dd_emit(ctx, 1, 0); /* 000000ff */ ++ dd_emit(ctx, 1, 0); /* ffffffff */ ++ dd_emit(ctx, 1, 4); /* 000000ff UNK12B0_0 */ ++ dd_emit(ctx, 1, 0x70); /* 000000ff UNK12B0_1 */ ++ dd_emit(ctx, 1, 0x80); /* 000000ff UNK12B0_3 */ ++ dd_emit(ctx, 1, 0); /* 000000ff UNK12B0_2 */ ++ dd_emit(ctx, 1, 0); /* 0000000f FP_TEXTURES_LOG2 */ ++ dd_emit(ctx, 1, 0); /* 0000000f FP_SAMPLERS_LOG2 */ ++ if (IS_NVA3F(dev_priv->chipset)) { ++ dd_emit(ctx, 1, 0); /* ffffffff */ ++ dd_emit(ctx, 1, 0); /* 0000007f MULTISAMPLE_SAMPLES_LOG2 */ ++ } else { ++ dd_emit(ctx, 1, 0); /* 0000000f MULTISAMPLE_SAMPLES_LOG2 */ ++ } ++ dd_emit(ctx, 1, 0xc); /* 000000ff SEMANTIC_COLOR.BFC0_ID */ ++ if (dev_priv->chipset != 0x50) ++ dd_emit(ctx, 1, 0); /* 00000001 SEMANTIC_COLOR.CLMP_EN */ ++ dd_emit(ctx, 1, 8); /* 000000ff SEMANTIC_COLOR.COLR_NR */ ++ dd_emit(ctx, 1, 0x14); /* 000000ff SEMANTIC_COLOR.FFC0_ID */ ++ if (dev_priv->chipset == 0x50) { ++ dd_emit(ctx, 1, 0); /* 000000ff SEMANTIC_LAYER */ ++ dd_emit(ctx, 1, 0); /* 00000001 */ ++ } else { ++ dd_emit(ctx, 1, 0); /* 00000001 SEMANTIC_PTSZ.ENABLE */ ++ dd_emit(ctx, 1, 0x29); /* 000000ff SEMANTIC_PTSZ.PTSZ_ID */ ++ dd_emit(ctx, 1, 0x27); /* 000000ff SEMANTIC_PRIM */ ++ dd_emit(ctx, 1, 0x26); /* 000000ff SEMANTIC_LAYER */ ++ dd_emit(ctx, 1, 8); /* 0000000f SMENATIC_CLIP.CLIP_HIGH */ ++ dd_emit(ctx, 1, 4); /* 000000ff SEMANTIC_CLIP.CLIP_LO */ ++ dd_emit(ctx, 1, 0x27); /* 000000ff UNK0FD4 */ ++ dd_emit(ctx, 1, 0); /* 00000001 UNK1900 */ ++ } ++ dd_emit(ctx, 1, 0); /* 00000007 RT_CONTROL_MAP0 */ ++ dd_emit(ctx, 1, 1); /* 00000007 RT_CONTROL_MAP1 */ ++ dd_emit(ctx, 1, 2); /* 00000007 RT_CONTROL_MAP2 */ ++ dd_emit(ctx, 1, 3); /* 00000007 RT_CONTROL_MAP3 */ ++ dd_emit(ctx, 1, 4); /* 00000007 RT_CONTROL_MAP4 */ ++ dd_emit(ctx, 1, 5); /* 00000007 RT_CONTROL_MAP5 */ ++ dd_emit(ctx, 1, 6); /* 00000007 RT_CONTROL_MAP6 */ ++ dd_emit(ctx, 1, 7); /* 00000007 RT_CONTROL_MAP7 */ ++ dd_emit(ctx, 1, 1); /* 0000000f RT_CONTROL_COUNT */ ++ dd_emit(ctx, 8, 0); /* 00000001 RT_HORIZ_UNK */ ++ dd_emit(ctx, 8, 0); /* ffffffff RT_ADDRESS_LOW */ ++ dd_emit(ctx, 1, 0xcf); /* 000000ff RT_FORMAT */ ++ dd_emit(ctx, 7, 0); /* 000000ff RT_FORMAT */ ++ if (dev_priv->chipset != 0x50) ++ dd_emit(ctx, 3, 0); /* 1, 1, 1 */ ++ else ++ dd_emit(ctx, 2, 0); /* 1, 1 */ ++ dd_emit(ctx, 1, 0); /* ffffffff GP_ENABLE */ ++ dd_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT*/ ++ dd_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_RESULT */ ++ dd_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ ++ if (IS_NVA3F(dev_priv->chipset)) { ++ dd_emit(ctx, 1, 3); /* 00000003 */ ++ dd_emit(ctx, 1, 0); /* 00000001 UNK1418. Alone. */ ++ } ++ if (dev_priv->chipset != 0x50) ++ dd_emit(ctx, 1, 3); /* 00000003 UNK15AC */ ++ dd_emit(ctx, 1, 1); /* ffffffff RASTERIZE_ENABLE */ ++ dd_emit(ctx, 1, 0); /* 00000001 FP_CONTROL.EXPORTS_Z */ ++ if (dev_priv->chipset != 0x50) ++ dd_emit(ctx, 1, 0); /* 00000001 FP_CONTROL.MULTIPLE_RESULTS */ ++ dd_emit(ctx, 1, 0x12); /* 000000ff FP_INTERPOLANT_CTRL.COUNT */ ++ dd_emit(ctx, 1, 0x10); /* 000000ff FP_INTERPOLANT_CTRL.COUNT_NONFLAT */ ++ dd_emit(ctx, 1, 0xc); /* 000000ff FP_INTERPOLANT_CTRL.OFFSET */ ++ dd_emit(ctx, 1, 1); /* 00000001 FP_INTERPOLANT_CTRL.UMASK.W */ ++ dd_emit(ctx, 1, 0); /* 00000001 FP_INTERPOLANT_CTRL.UMASK.X */ ++ dd_emit(ctx, 1, 0); /* 00000001 FP_INTERPOLANT_CTRL.UMASK.Y */ ++ dd_emit(ctx, 1, 0); /* 00000001 FP_INTERPOLANT_CTRL.UMASK.Z */ ++ dd_emit(ctx, 1, 4); /* 000000ff FP_RESULT_COUNT */ ++ dd_emit(ctx, 1, 2); /* ffffffff REG_MODE */ ++ dd_emit(ctx, 1, 4); /* 000000ff FP_REG_ALLOC_TEMP */ ++ if (dev_priv->chipset >= 0xa0) ++ dd_emit(ctx, 1, 0); /* ffffffff */ ++ dd_emit(ctx, 1, 0); /* 00000001 GP_BUILTIN_RESULT_EN.LAYER_IDX */ ++ dd_emit(ctx, 1, 0); /* ffffffff STRMOUT_ENABLE */ ++ dd_emit(ctx, 1, 0x3fffff); /* 003fffff TIC_LIMIT */ ++ dd_emit(ctx, 1, 0x1fff); /* 000fffff TSC_LIMIT */ ++ dd_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE*/ ++ if (dev_priv->chipset != 0x50) ++ dd_emit(ctx, 8, 0); /* 00000001 */ ++ if (dev_priv->chipset >= 0xa0) { ++ dd_emit(ctx, 1, 1); /* 00000007 VTX_ATTR_DEFINE.COMP */ ++ dd_emit(ctx, 1, 1); /* 00000007 VTX_ATTR_DEFINE.SIZE */ ++ dd_emit(ctx, 1, 2); /* 00000007 VTX_ATTR_DEFINE.TYPE */ ++ dd_emit(ctx, 1, 0); /* 000000ff VTX_ATTR_DEFINE.ATTR */ ++ } ++ dd_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ ++ dd_emit(ctx, 1, 0x14); /* 0000001f ZETA_FORMAT */ ++ dd_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ ++ dd_emit(ctx, 1, 0); /* 0000000f VP_TEXTURES_LOG2 */ ++ dd_emit(ctx, 1, 0); /* 0000000f VP_SAMPLERS_LOG2 */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ dd_emit(ctx, 1, 0); /* 00000001 */ ++ dd_emit(ctx, 1, 2); /* 00000003 POLYGON_MODE_BACK */ ++ if (dev_priv->chipset >= 0xa0) ++ dd_emit(ctx, 1, 0); /* 00000003 VTX_ATTR_DEFINE.SIZE - 1 */ ++ dd_emit(ctx, 1, 0); /* 0000ffff CB_ADDR_INDEX */ ++ if (dev_priv->chipset >= 0xa0) ++ dd_emit(ctx, 1, 0); /* 00000003 */ ++ dd_emit(ctx, 1, 0); /* 00000001 CULL_FACE_ENABLE */ ++ dd_emit(ctx, 1, 1); /* 00000003 CULL_FACE */ ++ dd_emit(ctx, 1, 0); /* 00000001 FRONT_FACE */ ++ dd_emit(ctx, 1, 2); /* 00000003 POLYGON_MODE_FRONT */ ++ dd_emit(ctx, 1, 0x1000); /* 00007fff UNK141C */ ++ if (dev_priv->chipset != 0x50) { ++ dd_emit(ctx, 1, 0xe00); /* 7fff */ ++ dd_emit(ctx, 1, 0x1000); /* 7fff */ ++ dd_emit(ctx, 1, 0x1e00); /* 7fff */ ++ } ++ dd_emit(ctx, 1, 0); /* 00000001 BEGIN_END_ACTIVE */ ++ dd_emit(ctx, 1, 1); /* 00000001 POLYGON_MODE_??? */ ++ dd_emit(ctx, 1, 1); /* 000000ff GP_REG_ALLOC_TEMP / 4 rounded up */ ++ dd_emit(ctx, 1, 1); /* 000000ff FP_REG_ALLOC_TEMP... without /4? */ ++ dd_emit(ctx, 1, 1); /* 000000ff VP_REG_ALLOC_TEMP / 4 rounded up */ ++ dd_emit(ctx, 1, 1); /* 00000001 */ ++ dd_emit(ctx, 1, 0); /* 00000001 */ ++ dd_emit(ctx, 1, 0); /* 00000001 VTX_ATTR_MASK_UNK0 nonempty */ ++ dd_emit(ctx, 1, 0); /* 00000001 VTX_ATTR_MASK_UNK1 nonempty */ ++ dd_emit(ctx, 1, 0x200); /* 0003ffff GP_VERTEX_OUTPUT_COUNT*GP_REG_ALLOC_RESULT */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ dd_emit(ctx, 1, 0x200); ++ dd_emit(ctx, 1, 0); /* 00000001 */ ++ if (dev_priv->chipset < 0xa0) { ++ dd_emit(ctx, 1, 1); /* 00000001 */ ++ dd_emit(ctx, 1, 0x70); /* 000000ff */ ++ dd_emit(ctx, 1, 0x80); /* 000000ff */ ++ dd_emit(ctx, 1, 0); /* 000000ff */ ++ dd_emit(ctx, 1, 0); /* 00000001 */ ++ dd_emit(ctx, 1, 1); /* 00000001 */ ++ dd_emit(ctx, 1, 0x70); /* 000000ff */ ++ dd_emit(ctx, 1, 0x80); /* 000000ff */ ++ dd_emit(ctx, 1, 0); /* 000000ff */ ++ } else { ++ dd_emit(ctx, 1, 1); /* 00000001 */ ++ dd_emit(ctx, 1, 0xf0); /* 000000ff */ ++ dd_emit(ctx, 1, 0xff); /* 000000ff */ ++ dd_emit(ctx, 1, 0); /* 000000ff */ ++ dd_emit(ctx, 1, 0); /* 00000001 */ ++ dd_emit(ctx, 1, 1); /* 00000001 */ ++ dd_emit(ctx, 1, 0xf0); /* 000000ff */ ++ dd_emit(ctx, 1, 0xff); /* 000000ff */ ++ dd_emit(ctx, 1, 0); /* 000000ff */ ++ dd_emit(ctx, 1, 9); /* 0000003f UNK114C.COMP,SIZE */ ++ } ++ ++ /* eng2d state */ ++ dd_emit(ctx, 1, 0); /* 00000001 eng2d COLOR_KEY_ENABLE */ ++ dd_emit(ctx, 1, 0); /* 00000007 eng2d COLOR_KEY_FORMAT */ ++ dd_emit(ctx, 1, 1); /* ffffffff eng2d DST_DEPTH */ ++ dd_emit(ctx, 1, 0xcf); /* 000000ff eng2d DST_FORMAT */ ++ dd_emit(ctx, 1, 0); /* ffffffff eng2d DST_LAYER */ ++ dd_emit(ctx, 1, 1); /* 00000001 eng2d DST_LINEAR */ ++ dd_emit(ctx, 1, 0); /* 00000007 eng2d PATTERN_COLOR_FORMAT */ ++ dd_emit(ctx, 1, 0); /* 00000007 eng2d OPERATION */ ++ dd_emit(ctx, 1, 0); /* 00000003 eng2d PATTERN_SELECT */ ++ dd_emit(ctx, 1, 0xcf); /* 000000ff eng2d SIFC_FORMAT */ ++ dd_emit(ctx, 1, 0); /* 00000001 eng2d SIFC_BITMAP_ENABLE */ ++ dd_emit(ctx, 1, 2); /* 00000003 eng2d SIFC_BITMAP_UNK808 */ ++ dd_emit(ctx, 1, 0); /* ffffffff eng2d BLIT_DU_DX_FRACT */ ++ dd_emit(ctx, 1, 1); /* ffffffff eng2d BLIT_DU_DX_INT */ ++ dd_emit(ctx, 1, 0); /* ffffffff eng2d BLIT_DV_DY_FRACT */ ++ dd_emit(ctx, 1, 1); /* ffffffff eng2d BLIT_DV_DY_INT */ ++ dd_emit(ctx, 1, 0); /* 00000001 eng2d BLIT_CONTROL_FILTER */ ++ dd_emit(ctx, 1, 0xcf); /* 000000ff eng2d DRAW_COLOR_FORMAT */ ++ dd_emit(ctx, 1, 0xcf); /* 000000ff eng2d SRC_FORMAT */ ++ dd_emit(ctx, 1, 1); /* 00000001 eng2d SRC_LINEAR #2 */ ++ ++ num = ctx->ctxvals_pos - base; ++ ctx->ctxvals_pos = base; ++ if (IS_NVA3F(dev_priv->chipset)) ++ cp_ctx(ctx, 0x404800, num); ++ else ++ cp_ctx(ctx, 0x405400, num); ++} ++ + /* + * xfer areas. These are a pain. + * +@@ -990,28 +1130,33 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) + * without the help of ctxprog. + */ + +-static inline void ++static void + xf_emit(struct nouveau_grctx *ctx, int num, uint32_t val) { + int i; + if (val && ctx->mode == NOUVEAU_GRCTX_VALS) + for (i = 0; i < num; i++) +- nv_wo32(ctx->dev, ctx->data, ctx->ctxvals_pos + (i << 3), val); ++ nv_wo32(ctx->data, 4 * (ctx->ctxvals_pos + (i << 3)), val); + ctx->ctxvals_pos += num << 3; + } + + /* Gene declarations... */ + ++static void nv50_graph_construct_gene_dispatch(struct nouveau_grctx *ctx); + static void nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx); +-static void nv50_graph_construct_gene_unk1(struct nouveau_grctx *ctx); +-static void nv50_graph_construct_gene_unk2(struct nouveau_grctx *ctx); +-static void nv50_graph_construct_gene_unk3(struct nouveau_grctx *ctx); +-static void nv50_graph_construct_gene_unk4(struct nouveau_grctx *ctx); +-static void nv50_graph_construct_gene_unk5(struct nouveau_grctx *ctx); +-static void nv50_graph_construct_gene_unk6(struct nouveau_grctx *ctx); +-static void nv50_graph_construct_gene_unk7(struct nouveau_grctx *ctx); +-static void nv50_graph_construct_gene_unk8(struct nouveau_grctx *ctx); +-static void nv50_graph_construct_gene_unk9(struct nouveau_grctx *ctx); +-static void nv50_graph_construct_gene_unk10(struct nouveau_grctx *ctx); ++static void nv50_graph_construct_gene_ccache(struct nouveau_grctx *ctx); ++static void nv50_graph_construct_gene_unk10xx(struct nouveau_grctx *ctx); ++static void nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx); ++static void nv50_graph_construct_gene_zcull(struct nouveau_grctx *ctx); ++static void nv50_graph_construct_gene_clipid(struct nouveau_grctx *ctx); ++static void nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx); ++static void nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx); ++static void nv50_graph_construct_gene_eng2d(struct nouveau_grctx *ctx); ++static void nv50_graph_construct_gene_csched(struct nouveau_grctx *ctx); ++static void nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx); ++static void nv50_graph_construct_gene_strmout(struct nouveau_grctx *ctx); ++static void nv50_graph_construct_gene_unk34xx(struct nouveau_grctx *ctx); ++static void nv50_graph_construct_gene_ropm1(struct nouveau_grctx *ctx); ++static void nv50_graph_construct_gene_ropm2(struct nouveau_grctx *ctx); + static void nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx); + static void nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx); + +@@ -1030,102 +1175,32 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx) + if (dev_priv->chipset < 0xa0) { + /* Strand 0 */ + ctx->ctxvals_pos = offset; +- switch (dev_priv->chipset) { +- case 0x50: +- xf_emit(ctx, 0x99, 0); +- break; +- case 0x84: +- case 0x86: +- xf_emit(ctx, 0x384, 0); +- break; +- case 0x92: +- case 0x94: +- case 0x96: +- case 0x98: +- xf_emit(ctx, 0x380, 0); +- break; +- } +- nv50_graph_construct_gene_m2mf (ctx); +- switch (dev_priv->chipset) { +- case 0x50: +- case 0x84: +- case 0x86: +- case 0x98: +- xf_emit(ctx, 0x4c4, 0); +- break; +- case 0x92: +- case 0x94: +- case 0x96: +- xf_emit(ctx, 0x984, 0); +- break; +- } +- nv50_graph_construct_gene_unk5(ctx); +- if (dev_priv->chipset == 0x50) +- xf_emit(ctx, 0xa, 0); +- else +- xf_emit(ctx, 0xb, 0); +- nv50_graph_construct_gene_unk4(ctx); +- nv50_graph_construct_gene_unk3(ctx); ++ nv50_graph_construct_gene_dispatch(ctx); ++ nv50_graph_construct_gene_m2mf(ctx); ++ nv50_graph_construct_gene_unk24xx(ctx); ++ nv50_graph_construct_gene_clipid(ctx); ++ nv50_graph_construct_gene_zcull(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 1 */ + ctx->ctxvals_pos = offset + 0x1; +- nv50_graph_construct_gene_unk6(ctx); +- nv50_graph_construct_gene_unk7(ctx); +- nv50_graph_construct_gene_unk8(ctx); +- switch (dev_priv->chipset) { +- case 0x50: +- case 0x92: +- xf_emit(ctx, 0xfb, 0); +- break; +- case 0x84: +- xf_emit(ctx, 0xd3, 0); +- break; +- case 0x94: +- case 0x96: +- xf_emit(ctx, 0xab, 0); +- break; +- case 0x86: +- case 0x98: +- xf_emit(ctx, 0x6b, 0); +- break; +- } +- xf_emit(ctx, 2, 0x4e3bfdf); +- xf_emit(ctx, 4, 0); +- xf_emit(ctx, 1, 0x0fac6881); +- xf_emit(ctx, 0xb, 0); +- xf_emit(ctx, 2, 0x4e3bfdf); ++ nv50_graph_construct_gene_vfetch(ctx); ++ nv50_graph_construct_gene_eng2d(ctx); ++ nv50_graph_construct_gene_csched(ctx); ++ nv50_graph_construct_gene_ropm1(ctx); ++ nv50_graph_construct_gene_ropm2(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 2 */ + ctx->ctxvals_pos = offset + 0x2; +- switch (dev_priv->chipset) { +- case 0x50: +- case 0x92: +- xf_emit(ctx, 0xa80, 0); +- break; +- case 0x84: +- xf_emit(ctx, 0xa7e, 0); +- break; +- case 0x94: +- case 0x96: +- xf_emit(ctx, 0xa7c, 0); +- break; +- case 0x86: +- case 0x98: +- xf_emit(ctx, 0xa7a, 0); +- break; +- } +- xf_emit(ctx, 1, 0x3fffff); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 0x1fff); +- xf_emit(ctx, 0xe, 0); +- nv50_graph_construct_gene_unk9(ctx); +- nv50_graph_construct_gene_unk2(ctx); +- nv50_graph_construct_gene_unk1(ctx); +- nv50_graph_construct_gene_unk10(ctx); ++ nv50_graph_construct_gene_ccache(ctx); ++ nv50_graph_construct_gene_unk1cxx(ctx); ++ nv50_graph_construct_gene_strmout(ctx); ++ nv50_graph_construct_gene_unk14xx(ctx); ++ nv50_graph_construct_gene_unk10xx(ctx); ++ nv50_graph_construct_gene_unk34xx(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + +@@ -1150,86 +1225,46 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx) + } else { + /* Strand 0 */ + ctx->ctxvals_pos = offset; +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 0x385, 0); +- else +- xf_emit(ctx, 0x384, 0); ++ nv50_graph_construct_gene_dispatch(ctx); + nv50_graph_construct_gene_m2mf(ctx); +- xf_emit(ctx, 0x950, 0); +- nv50_graph_construct_gene_unk10(ctx); +- xf_emit(ctx, 1, 0x0fac6881); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 3, 0); +- } +- nv50_graph_construct_gene_unk8(ctx); +- if (dev_priv->chipset == 0xa0) +- xf_emit(ctx, 0x189, 0); +- else if (dev_priv->chipset == 0xa3) +- xf_emit(ctx, 0xd5, 0); +- else if (dev_priv->chipset == 0xa5) +- xf_emit(ctx, 0x99, 0); +- else if (dev_priv->chipset == 0xaa) +- xf_emit(ctx, 0x65, 0); +- else +- xf_emit(ctx, 0x6d, 0); +- nv50_graph_construct_gene_unk9(ctx); ++ nv50_graph_construct_gene_unk34xx(ctx); ++ nv50_graph_construct_gene_csched(ctx); ++ nv50_graph_construct_gene_unk1cxx(ctx); ++ nv50_graph_construct_gene_strmout(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 1 */ + ctx->ctxvals_pos = offset + 1; +- nv50_graph_construct_gene_unk1(ctx); ++ nv50_graph_construct_gene_unk10xx(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 2 */ + ctx->ctxvals_pos = offset + 2; +- if (dev_priv->chipset == 0xa0) { +- nv50_graph_construct_gene_unk2(ctx); +- } +- xf_emit(ctx, 0x36, 0); +- nv50_graph_construct_gene_unk5(ctx); ++ if (dev_priv->chipset == 0xa0) ++ nv50_graph_construct_gene_unk14xx(ctx); ++ nv50_graph_construct_gene_unk24xx(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 3 */ + ctx->ctxvals_pos = offset + 3; +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- nv50_graph_construct_gene_unk6(ctx); ++ nv50_graph_construct_gene_vfetch(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 4 */ + ctx->ctxvals_pos = offset + 4; +- if (dev_priv->chipset == 0xa0) +- xf_emit(ctx, 0xa80, 0); +- else if (dev_priv->chipset == 0xa3) +- xf_emit(ctx, 0xa7c, 0); +- else +- xf_emit(ctx, 0xa7a, 0); +- xf_emit(ctx, 1, 0x3fffff); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 0x1fff); ++ nv50_graph_construct_gene_ccache(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 5 */ + ctx->ctxvals_pos = offset + 5; +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x0fac6881); +- xf_emit(ctx, 0xb, 0); +- xf_emit(ctx, 2, 0x4e3bfdf); +- xf_emit(ctx, 3, 0); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 2, 0x4e3bfdf); +- xf_emit(ctx, 2, 0); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 1, 0); ++ nv50_graph_construct_gene_ropm2(ctx); ++ nv50_graph_construct_gene_ropm1(ctx); ++ /* per-ROP context */ + for (i = 0; i < 8; i++) + if (units & (1<<(i+16))) + nv50_graph_construct_gene_ropc(ctx); +@@ -1238,10 +1273,9 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx) + + /* Strand 6 */ + ctx->ctxvals_pos = offset + 6; +- nv50_graph_construct_gene_unk3(ctx); +- xf_emit(ctx, 0xb, 0); +- nv50_graph_construct_gene_unk4(ctx); +- nv50_graph_construct_gene_unk7(ctx); ++ nv50_graph_construct_gene_zcull(ctx); ++ nv50_graph_construct_gene_clipid(ctx); ++ nv50_graph_construct_gene_eng2d(ctx); + if (units & (1 << 0)) + nv50_graph_construct_xfer_tp(ctx); + if (units & (1 << 1)) +@@ -1269,7 +1303,7 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx) + if (units & (1 << 9)) + nv50_graph_construct_xfer_tp(ctx); + } else { +- nv50_graph_construct_gene_unk2(ctx); ++ nv50_graph_construct_gene_unk14xx(ctx); + } + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; +@@ -1290,9 +1324,70 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx) + */ + + static void ++nv50_graph_construct_gene_dispatch(struct nouveau_grctx *ctx) ++{ ++ /* start of strand 0 */ ++ struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; ++ /* SEEK */ ++ if (dev_priv->chipset == 0x50) ++ xf_emit(ctx, 5, 0); ++ else if (!IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 6, 0); ++ else ++ xf_emit(ctx, 4, 0); ++ /* SEEK */ ++ /* the PGRAPH's internal FIFO */ ++ if (dev_priv->chipset == 0x50) ++ xf_emit(ctx, 8*3, 0); ++ else ++ xf_emit(ctx, 0x100*3, 0); ++ /* and another bonus slot?!? */ ++ xf_emit(ctx, 3, 0); ++ /* and YET ANOTHER bonus slot? */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 3, 0); ++ /* SEEK */ ++ /* CTX_SWITCH: caches of gr objects bound to subchannels. 8 values, last used index */ ++ xf_emit(ctx, 9, 0); ++ /* SEEK */ ++ xf_emit(ctx, 9, 0); ++ /* SEEK */ ++ xf_emit(ctx, 9, 0); ++ /* SEEK */ ++ xf_emit(ctx, 9, 0); ++ /* SEEK */ ++ if (dev_priv->chipset < 0x90) ++ xf_emit(ctx, 4, 0); ++ /* SEEK */ ++ xf_emit(ctx, 2, 0); ++ /* SEEK */ ++ xf_emit(ctx, 6*2, 0); ++ xf_emit(ctx, 2, 0); ++ /* SEEK */ ++ xf_emit(ctx, 2, 0); ++ /* SEEK */ ++ xf_emit(ctx, 6*2, 0); ++ xf_emit(ctx, 2, 0); ++ /* SEEK */ ++ if (dev_priv->chipset == 0x50) ++ xf_emit(ctx, 0x1c, 0); ++ else if (dev_priv->chipset < 0xa0) ++ xf_emit(ctx, 0x1e, 0); ++ else ++ xf_emit(ctx, 0x22, 0); ++ /* SEEK */ ++ xf_emit(ctx, 0x15, 0); ++} ++ ++static void + nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx) + { +- /* m2mf state */ ++ /* Strand 0, right after dispatch */ ++ struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; ++ int smallm2mf = 0; ++ if (dev_priv->chipset < 0x92 || dev_priv->chipset == 0x98) ++ smallm2mf = 1; ++ /* SEEK */ + xf_emit (ctx, 1, 0); /* DMA_NOTIFY instance >> 4 */ + xf_emit (ctx, 1, 0); /* DMA_BUFFER_IN instance >> 4 */ + xf_emit (ctx, 1, 0); /* DMA_BUFFER_OUT instance >> 4 */ +@@ -1319,427 +1414,975 @@ nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx) + xf_emit (ctx, 1, 0); /* TILING_POSITION_OUT */ + xf_emit (ctx, 1, 0); /* OFFSET_IN_HIGH */ + xf_emit (ctx, 1, 0); /* OFFSET_OUT_HIGH */ ++ /* SEEK */ ++ if (smallm2mf) ++ xf_emit(ctx, 0x40, 0); /* 20 * ffffffff, 3ffff */ ++ else ++ xf_emit(ctx, 0x100, 0); /* 80 * ffffffff, 3ffff */ ++ xf_emit(ctx, 4, 0); /* 1f/7f, 0, 1f/7f, 0 [1f for smallm2mf, 7f otherwise] */ ++ /* SEEK */ ++ if (smallm2mf) ++ xf_emit(ctx, 0x400, 0); /* ffffffff */ ++ else ++ xf_emit(ctx, 0x800, 0); /* ffffffff */ ++ xf_emit(ctx, 4, 0); /* ff/1ff, 0, 0, 0 [ff for smallm2mf, 1ff otherwise] */ ++ /* SEEK */ ++ xf_emit(ctx, 0x40, 0); /* 20 * bits ffffffff, 3ffff */ ++ xf_emit(ctx, 0x6, 0); /* 1f, 0, 1f, 0, 1f, 0 */ + } + + static void +-nv50_graph_construct_gene_unk1(struct nouveau_grctx *ctx) ++nv50_graph_construct_gene_ccache(struct nouveau_grctx *ctx) + { + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; +- /* end of area 2 on pre-NVA0, area 1 on NVAx */ +- xf_emit(ctx, 2, 4); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x80); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 0x80c14); +- xf_emit(ctx, 1, 0); +- if (dev_priv->chipset == 0x50) +- xf_emit(ctx, 1, 0x3ff); +- else +- xf_emit(ctx, 1, 0x7ff); ++ xf_emit(ctx, 2, 0); /* RO */ ++ xf_emit(ctx, 0x800, 0); /* ffffffff */ + switch (dev_priv->chipset) { + case 0x50: +- case 0x86: +- case 0x98: +- case 0xaa: +- case 0xac: +- xf_emit(ctx, 0x542, 0); ++ case 0x92: ++ case 0xa0: ++ xf_emit(ctx, 0x2b, 0); + break; + case 0x84: +- case 0x92: ++ xf_emit(ctx, 0x29, 0); ++ break; + case 0x94: + case 0x96: +- xf_emit(ctx, 0x942, 0); +- break; +- case 0xa0: + case 0xa3: +- xf_emit(ctx, 0x2042, 0); ++ xf_emit(ctx, 0x27, 0); + break; ++ case 0x86: ++ case 0x98: + case 0xa5: + case 0xa8: +- xf_emit(ctx, 0x842, 0); ++ case 0xaa: ++ case 0xac: ++ case 0xaf: ++ xf_emit(ctx, 0x25, 0); + break; + } +- xf_emit(ctx, 2, 4); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x80); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x27); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x26); +- xf_emit(ctx, 3, 0); ++ /* CB bindings, 0x80 of them. first word is address >> 8, second is ++ * size >> 4 | valid << 24 */ ++ xf_emit(ctx, 0x100, 0); /* ffffffff CB_DEF */ ++ xf_emit(ctx, 1, 0); /* 0000007f CB_ADDR_BUFFER */ ++ xf_emit(ctx, 1, 0); /* 0 */ ++ xf_emit(ctx, 0x30, 0); /* ff SET_PROGRAM_CB */ ++ xf_emit(ctx, 1, 0); /* 3f last SET_PROGRAM_CB */ ++ xf_emit(ctx, 4, 0); /* RO */ ++ xf_emit(ctx, 0x100, 0); /* ffffffff */ ++ xf_emit(ctx, 8, 0); /* 1f, 0, 0, ... */ ++ xf_emit(ctx, 8, 0); /* ffffffff */ ++ xf_emit(ctx, 4, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* 3 */ ++ xf_emit(ctx, 1, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_CODE_CB */ ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_TIC */ ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_TSC */ ++ xf_emit(ctx, 1, 0); /* 00000001 LINKED_TSC */ ++ xf_emit(ctx, 1, 0); /* 000000ff TIC_ADDRESS_HIGH */ ++ xf_emit(ctx, 1, 0); /* ffffffff TIC_ADDRESS_LOW */ ++ xf_emit(ctx, 1, 0x3fffff); /* 003fffff TIC_LIMIT */ ++ xf_emit(ctx, 1, 0); /* 000000ff TSC_ADDRESS_HIGH */ ++ xf_emit(ctx, 1, 0); /* ffffffff TSC_ADDRESS_LOW */ ++ xf_emit(ctx, 1, 0x1fff); /* 000fffff TSC_LIMIT */ ++ xf_emit(ctx, 1, 0); /* 000000ff VP_ADDRESS_HIGH */ ++ xf_emit(ctx, 1, 0); /* ffffffff VP_ADDRESS_LOW */ ++ xf_emit(ctx, 1, 0); /* 00ffffff VP_START_ID */ ++ xf_emit(ctx, 1, 0); /* 000000ff CB_DEF_ADDRESS_HIGH */ ++ xf_emit(ctx, 1, 0); /* ffffffff CB_DEF_ADDRESS_LOW */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 000000ff GP_ADDRESS_HIGH */ ++ xf_emit(ctx, 1, 0); /* ffffffff GP_ADDRESS_LOW */ ++ xf_emit(ctx, 1, 0); /* 00ffffff GP_START_ID */ ++ xf_emit(ctx, 1, 0); /* 000000ff FP_ADDRESS_HIGH */ ++ xf_emit(ctx, 1, 0); /* ffffffff FP_ADDRESS_LOW */ ++ xf_emit(ctx, 1, 0); /* 00ffffff FP_START_ID */ + } + + static void +-nv50_graph_construct_gene_unk10(struct nouveau_grctx *ctx) ++nv50_graph_construct_gene_unk10xx(struct nouveau_grctx *ctx) + { ++ struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; ++ int i; + /* end of area 2 on pre-NVA0, area 1 on NVAx */ +- xf_emit(ctx, 0x10, 0x04000000); +- xf_emit(ctx, 0x24, 0); +- xf_emit(ctx, 2, 0x04e3bfdf); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 0x1fe21); ++ xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT */ ++ xf_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_RESULT */ ++ xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ ++ xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ ++ if (dev_priv->chipset == 0x50) ++ xf_emit(ctx, 1, 0x3ff); ++ else ++ xf_emit(ctx, 1, 0x7ff); /* 000007ff */ ++ xf_emit(ctx, 1, 0); /* 111/113 */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ for (i = 0; i < 8; i++) { ++ switch (dev_priv->chipset) { ++ case 0x50: ++ case 0x86: ++ case 0x98: ++ case 0xaa: ++ case 0xac: ++ xf_emit(ctx, 0xa0, 0); /* ffffffff */ ++ break; ++ case 0x84: ++ case 0x92: ++ case 0x94: ++ case 0x96: ++ xf_emit(ctx, 0x120, 0); ++ break; ++ case 0xa5: ++ case 0xa8: ++ xf_emit(ctx, 0x100, 0); /* ffffffff */ ++ break; ++ case 0xa0: ++ case 0xa3: ++ case 0xaf: ++ xf_emit(ctx, 0x400, 0); /* ffffffff */ ++ break; ++ } ++ xf_emit(ctx, 4, 0); /* 3f, 0, 0, 0 */ ++ xf_emit(ctx, 4, 0); /* ffffffff */ ++ } ++ xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT */ ++ xf_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_TEMP */ ++ xf_emit(ctx, 1, 1); /* 00000001 RASTERIZE_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ ++ xf_emit(ctx, 1, 0x27); /* 000000ff UNK0FD4 */ ++ xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ ++ xf_emit(ctx, 1, 0x26); /* 000000ff SEMANTIC_LAYER */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++} ++ ++static void ++nv50_graph_construct_gene_unk34xx(struct nouveau_grctx *ctx) ++{ ++ struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; ++ /* end of area 2 on pre-NVA0, area 1 on NVAx */ ++ xf_emit(ctx, 1, 0); /* 00000001 VIEWPORT_CLIP_RECTS_EN */ ++ xf_emit(ctx, 1, 0); /* 00000003 VIEWPORT_CLIP_MODE */ ++ xf_emit(ctx, 0x10, 0x04000000); /* 07ffffff VIEWPORT_CLIP_HORIZ*8, VIEWPORT_CLIP_VERT*8 */ ++ xf_emit(ctx, 1, 0); /* 00000001 POLYGON_STIPPLE_ENABLE */ ++ xf_emit(ctx, 0x20, 0); /* ffffffff POLYGON_STIPPLE */ ++ xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY */ ++ xf_emit(ctx, 1, 0); /* ffff0ff3 */ ++ xf_emit(ctx, 1, 0x04e3bfdf); /* ffffffff UNK0D64 */ ++ xf_emit(ctx, 1, 0x04e3bfdf); /* ffffffff UNK0DF4 */ ++ xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ ++ xf_emit(ctx, 1, 0); /* 00000007 */ ++ xf_emit(ctx, 1, 0x1fe21); /* 0001ffff tesla UNK0FAC */ ++ if (dev_priv->chipset >= 0xa0) ++ xf_emit(ctx, 1, 0x0fac6881); ++ if (IS_NVA3F(dev_priv->chipset)) { ++ xf_emit(ctx, 1, 1); ++ xf_emit(ctx, 3, 0); ++ } + } + + static void +-nv50_graph_construct_gene_unk2(struct nouveau_grctx *ctx) ++nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx) + { + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; + /* middle of area 2 on pre-NVA0, beginning of area 2 on NVA0, area 7 on >NVA0 */ + if (dev_priv->chipset != 0x50) { +- xf_emit(ctx, 5, 0); +- xf_emit(ctx, 1, 0x80c14); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 0x804); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 2, 4); +- xf_emit(ctx, 1, 0x8100c12); ++ xf_emit(ctx, 5, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ ++ xf_emit(ctx, 1, 0); /* 00000001 */ ++ xf_emit(ctx, 1, 0); /* 000003ff */ ++ xf_emit(ctx, 1, 0x804); /* 00000fff SEMANTIC_CLIP */ ++ xf_emit(ctx, 1, 0); /* 00000001 */ ++ xf_emit(ctx, 2, 4); /* 7f, ff */ ++ xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ + } +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 2, 4); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x10); +- if (dev_priv->chipset == 0x50) +- xf_emit(ctx, 3, 0); +- else +- xf_emit(ctx, 4, 0); +- xf_emit(ctx, 1, 0x804); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0x1a); ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ ++ xf_emit(ctx, 1, 0); /* 000000ff VP_CLIP_DISTANCE_ENABLE */ + if (dev_priv->chipset != 0x50) +- xf_emit(ctx, 1, 0x7f); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0x80c14); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x8100c12); +- xf_emit(ctx, 2, 4); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x10); +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0x8100c12); +- xf_emit(ctx, 6, 0); +- if (dev_priv->chipset == 0x50) +- xf_emit(ctx, 1, 0x3ff); +- else +- xf_emit(ctx, 1, 0x7ff); +- xf_emit(ctx, 1, 0x80c14); +- xf_emit(ctx, 0x38, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 0x10); +- xf_emit(ctx, 0x38, 0); +- xf_emit(ctx, 2, 0x88); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 0x16, 0); +- xf_emit(ctx, 1, 0x26); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 0x3f800000); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 4, 0); +- else +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 0x1a); +- xf_emit(ctx, 1, 0x10); ++ xf_emit(ctx, 1, 0); /* 3ff */ ++ xf_emit(ctx, 1, 0); /* 000000ff tesla UNK1940 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0D7C */ ++ xf_emit(ctx, 1, 0x804); /* 00000fff SEMANTIC_CLIP */ ++ xf_emit(ctx, 1, 1); /* 00000001 VIEWPORT_TRANSFORM_EN */ ++ xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ + if (dev_priv->chipset != 0x50) +- xf_emit(ctx, 0x28, 0); ++ xf_emit(ctx, 1, 0x7f); /* 000000ff tesla UNK0FFC */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ xf_emit(ctx, 1, 1); /* 00000001 SHADE_MODEL */ ++ xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ ++ xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ ++ xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0D7C */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0F8C */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ xf_emit(ctx, 1, 1); /* 00000001 VIEWPORT_TRANSFORM_EN */ ++ xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ ++ xf_emit(ctx, 4, 0); /* ffffffff NOPERSPECTIVE_BITMAP */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ ++ xf_emit(ctx, 1, 0); /* 0000000f */ ++ if (dev_priv->chipset == 0x50) ++ xf_emit(ctx, 1, 0x3ff); /* 000003ff tesla UNK0D68 */ + else +- xf_emit(ctx, 0x25, 0); +- xf_emit(ctx, 1, 0x52); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x26); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 2, 4); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x1a); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 0x00ffff00); +- xf_emit(ctx, 1, 0); ++ xf_emit(ctx, 1, 0x7ff); /* 000007ff tesla UNK0D68 */ ++ xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ ++ xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ ++ xf_emit(ctx, 0x30, 0); /* ffffffff VIEWPORT_SCALE: X0, Y0, Z0, X1, Y1, ... */ ++ xf_emit(ctx, 3, 0); /* f, 0, 0 */ ++ xf_emit(ctx, 3, 0); /* ffffffff last VIEWPORT_SCALE? */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ xf_emit(ctx, 1, 1); /* 00000001 VIEWPORT_TRANSFORM_EN */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1924 */ ++ xf_emit(ctx, 1, 0x10); /* 000000ff VIEW_VOLUME_CLIP_CTRL */ ++ xf_emit(ctx, 1, 0); /* 00000001 */ ++ xf_emit(ctx, 0x30, 0); /* ffffffff VIEWPORT_TRANSLATE */ ++ xf_emit(ctx, 3, 0); /* f, 0, 0 */ ++ xf_emit(ctx, 3, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ xf_emit(ctx, 2, 0x88); /* 000001ff tesla UNK19D8 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1924 */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ xf_emit(ctx, 1, 4); /* 0000000f CULL_MODE */ ++ xf_emit(ctx, 2, 0); /* 07ffffff SCREEN_SCISSOR */ ++ xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY */ ++ xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ ++ xf_emit(ctx, 0x10, 0); /* 00000001 SCISSOR_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ ++ xf_emit(ctx, 1, 0x26); /* 000000ff SEMANTIC_LAYER */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ ++ xf_emit(ctx, 1, 0); /* 0000000f */ ++ xf_emit(ctx, 1, 0x3f800000); /* ffffffff LINE_WIDTH */ ++ xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 0); /* 00000001 */ ++ xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ ++ xf_emit(ctx, 1, 0x10); /* 000000ff VIEW_VOLUME_CLIP_CTRL */ ++ if (dev_priv->chipset != 0x50) { ++ xf_emit(ctx, 1, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* 00000001 */ ++ xf_emit(ctx, 1, 0); /* 000003ff */ ++ } ++ xf_emit(ctx, 0x20, 0); /* 10xbits ffffffff, 3fffff. SCISSOR_* */ ++ xf_emit(ctx, 1, 0); /* f */ ++ xf_emit(ctx, 1, 0); /* 0? */ ++ xf_emit(ctx, 1, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* 003fffff */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ xf_emit(ctx, 1, 0x52); /* 000001ff SEMANTIC_PTSZ */ ++ xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ ++ xf_emit(ctx, 1, 0x26); /* 000000ff SEMANTIC_LAYER */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ ++ xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ ++ xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ ++ xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ ++ xf_emit(ctx, 1, 0); /* 0000000f */ + } + + static void +-nv50_graph_construct_gene_unk3(struct nouveau_grctx *ctx) ++nv50_graph_construct_gene_zcull(struct nouveau_grctx *ctx) + { + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; +- /* end of area 0 on pre-NVA0, beginning of area 6 on NVAx */ +- xf_emit(ctx, 1, 0x3f); +- xf_emit(ctx, 0xa, 0); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 2, 0x04000000); +- xf_emit(ctx, 8, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 4); +- if (dev_priv->chipset == 0x50) +- xf_emit(ctx, 0x10, 0); +- else +- xf_emit(ctx, 0x11, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0x1001); +- xf_emit(ctx, 4, 0xffff); +- xf_emit(ctx, 0x20, 0); +- xf_emit(ctx, 0x10, 0x3f800000); +- xf_emit(ctx, 1, 0x10); +- if (dev_priv->chipset == 0x50) +- xf_emit(ctx, 1, 0); +- else +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 3); +- xf_emit(ctx, 2, 0); ++ /* end of strand 0 on pre-NVA0, beginning of strand 6 on NVAx */ ++ /* SEEK */ ++ xf_emit(ctx, 1, 0x3f); /* 0000003f UNK1590 */ ++ xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ ++ xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_REF */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ ++ xf_emit(ctx, 3, 0); /* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */ ++ xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ ++ xf_emit(ctx, 2, 0x04000000); /* 07ffffff tesla UNK0D6C */ ++ xf_emit(ctx, 1, 0); /* ffff0ff3 */ ++ xf_emit(ctx, 1, 0); /* 00000001 CLIPID_ENABLE */ ++ xf_emit(ctx, 2, 0); /* ffffffff DEPTH_BOUNDS */ ++ xf_emit(ctx, 1, 0); /* 00000001 */ ++ xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ ++ xf_emit(ctx, 1, 4); /* 0000000f CULL_MODE */ ++ xf_emit(ctx, 1, 0); /* 0000ffff */ ++ xf_emit(ctx, 1, 0); /* 00000001 UNK0FB0 */ ++ xf_emit(ctx, 1, 0); /* 00000001 POLYGON_STIPPLE_ENABLE */ ++ xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ ++ xf_emit(ctx, 1, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ ++ xf_emit(ctx, 1, 0); /* 000000ff CLEAR_STENCIL */ ++ xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_REF */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ ++ xf_emit(ctx, 3, 0); /* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ ++ xf_emit(ctx, 1, 0); /* ffffffff CLEAR_DEPTH */ ++ xf_emit(ctx, 1, 0); /* 00000007 */ ++ if (dev_priv->chipset != 0x50) ++ xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1108 */ ++ xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ ++ xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ ++ xf_emit(ctx, 1, 0x1001); /* 00001fff ZETA_ARRAY_MODE */ ++ /* SEEK */ ++ xf_emit(ctx, 4, 0xffff); /* 0000ffff MSAA_MASK */ ++ xf_emit(ctx, 0x10, 0); /* 00000001 SCISSOR_ENABLE */ ++ xf_emit(ctx, 0x10, 0); /* ffffffff DEPTH_RANGE_NEAR */ ++ xf_emit(ctx, 0x10, 0x3f800000); /* ffffffff DEPTH_RANGE_FAR */ ++ xf_emit(ctx, 1, 0x10); /* 7f/ff/3ff VIEW_VOLUME_CLIP_CTRL */ ++ xf_emit(ctx, 1, 0); /* 00000001 VIEWPORT_CLIP_RECTS_EN */ ++ xf_emit(ctx, 1, 3); /* 00000003 FP_CTRL_UNK196C */ ++ xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1968 */ ++ if (dev_priv->chipset != 0x50) ++ xf_emit(ctx, 1, 0); /* 0fffffff tesla UNK1104 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK151C */ + } + + static void +-nv50_graph_construct_gene_unk4(struct nouveau_grctx *ctx) ++nv50_graph_construct_gene_clipid(struct nouveau_grctx *ctx) + { +- /* middle of area 0 on pre-NVA0, middle of area 6 on NVAx */ +- xf_emit(ctx, 2, 0x04000000); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x80); +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 0x80); +- xf_emit(ctx, 1, 0); ++ /* middle of strand 0 on pre-NVA0 [after 24xx], middle of area 6 on NVAx */ ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* 00000007 UNK0FB4 */ ++ /* SEEK */ ++ xf_emit(ctx, 4, 0); /* 07ffffff CLIPID_REGION_HORIZ */ ++ xf_emit(ctx, 4, 0); /* 07ffffff CLIPID_REGION_VERT */ ++ xf_emit(ctx, 2, 0); /* 07ffffff SCREEN_SCISSOR */ ++ xf_emit(ctx, 2, 0x04000000); /* 07ffffff UNK1508 */ ++ xf_emit(ctx, 1, 0); /* 00000001 CLIPID_ENABLE */ ++ xf_emit(ctx, 1, 0x80); /* 00003fff CLIPID_WIDTH */ ++ xf_emit(ctx, 1, 0); /* 000000ff CLIPID_ID */ ++ xf_emit(ctx, 1, 0); /* 000000ff CLIPID_ADDRESS_HIGH */ ++ xf_emit(ctx, 1, 0); /* ffffffff CLIPID_ADDRESS_LOW */ ++ xf_emit(ctx, 1, 0x80); /* 00003fff CLIPID_HEIGHT */ ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_CLIPID */ + } + + static void +-nv50_graph_construct_gene_unk5(struct nouveau_grctx *ctx) ++nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx) + { + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; +- /* middle of area 0 on pre-NVA0 [after m2mf], end of area 2 on NVAx */ +- xf_emit(ctx, 2, 4); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 0x1c4d, 0); ++ int i; ++ /* middle of strand 0 on pre-NVA0 [after m2mf], end of strand 2 on NVAx */ ++ /* SEEK */ ++ xf_emit(ctx, 0x33, 0); ++ /* SEEK */ ++ xf_emit(ctx, 2, 0); ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ ++ /* SEEK */ ++ if (IS_NVA3F(dev_priv->chipset)) { ++ xf_emit(ctx, 4, 0); /* RO */ ++ xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */ ++ xf_emit(ctx, 1, 0); /* 1ff */ ++ xf_emit(ctx, 8, 0); /* 0? */ ++ xf_emit(ctx, 9, 0); /* ffffffff, 7ff */ ++ ++ xf_emit(ctx, 4, 0); /* RO */ ++ xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */ ++ xf_emit(ctx, 1, 0); /* 1ff */ ++ xf_emit(ctx, 8, 0); /* 0? */ ++ xf_emit(ctx, 9, 0); /* ffffffff, 7ff */ ++ } + else +- xf_emit(ctx, 0x1c4b, 0); +- xf_emit(ctx, 2, 4); +- xf_emit(ctx, 1, 0x8100c12); ++ { ++ xf_emit(ctx, 0xc, 0); /* RO */ ++ /* SEEK */ ++ xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */ ++ xf_emit(ctx, 1, 0); /* 1ff */ ++ xf_emit(ctx, 8, 0); /* 0? */ ++ ++ /* SEEK */ ++ xf_emit(ctx, 0xc, 0); /* RO */ ++ /* SEEK */ ++ xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */ ++ xf_emit(ctx, 1, 0); /* 1ff */ ++ xf_emit(ctx, 8, 0); /* 0? */ ++ } ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ + if (dev_priv->chipset != 0x50) +- xf_emit(ctx, 1, 3); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x8100c12); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x80c14); +- xf_emit(ctx, 1, 1); ++ xf_emit(ctx, 1, 3); /* 00000003 tesla UNK1100 */ ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ ++ xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ ++ xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ ++ xf_emit(ctx, 1, 1); /* 00000001 */ ++ /* SEEK */ + if (dev_priv->chipset >= 0xa0) +- xf_emit(ctx, 2, 4); +- xf_emit(ctx, 1, 0x80c14); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 0x8100c12); +- xf_emit(ctx, 1, 0x27); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 0x3c1, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 0x16, 0); +- xf_emit(ctx, 1, 0x8100c12); +- xf_emit(ctx, 1, 0); ++ xf_emit(ctx, 2, 4); /* 000000ff */ ++ xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ ++ xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 POINT_SPRITE_ENABLE */ ++ xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ ++ xf_emit(ctx, 1, 0x27); /* 000000ff SEMANTIC_PRIM_ID */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 0000000f */ ++ xf_emit(ctx, 1, 1); /* 00000001 */ ++ for (i = 0; i < 10; i++) { ++ /* SEEK */ ++ xf_emit(ctx, 0x40, 0); /* ffffffff */ ++ xf_emit(ctx, 0x10, 0); /* 3, 0, 0.... */ ++ xf_emit(ctx, 0x10, 0); /* ffffffff */ ++ } ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* 00000001 POINT_SPRITE_CTRL */ ++ xf_emit(ctx, 1, 1); /* 00000001 */ ++ xf_emit(ctx, 1, 0); /* ffffffff */ ++ xf_emit(ctx, 4, 0); /* ffffffff NOPERSPECTIVE_BITMAP */ ++ xf_emit(ctx, 0x10, 0); /* 00ffffff POINT_COORD_REPLACE_MAP */ ++ xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ ++ xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ ++ if (dev_priv->chipset != 0x50) ++ xf_emit(ctx, 1, 0); /* 000003ff */ + } + + static void +-nv50_graph_construct_gene_unk6(struct nouveau_grctx *ctx) ++nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx) + { + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; +- /* beginning of area 1 on pre-NVA0 [after m2mf], area 3 on NVAx */ +- xf_emit(ctx, 4, 0); +- xf_emit(ctx, 1, 0xf); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 8, 0); +- else +- xf_emit(ctx, 4, 0); +- xf_emit(ctx, 1, 0x20); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 0x11, 0); ++ int acnt = 0x10, rep, i; ++ /* beginning of strand 1 on pre-NVA0, strand 3 on NVAx */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ acnt = 0x20; ++ /* SEEK */ ++ if (dev_priv->chipset >= 0xa0) { ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK13A4 */ ++ xf_emit(ctx, 1, 1); /* 00000fff tesla UNK1318 */ ++ } ++ xf_emit(ctx, 1, 0); /* ffffffff VERTEX_BUFFER_FIRST */ ++ xf_emit(ctx, 1, 0); /* 00000001 PRIMITIVE_RESTART_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 UNK0DE8 */ ++ xf_emit(ctx, 1, 0); /* ffffffff PRIMITIVE_RESTART_INDEX */ ++ xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ ++ xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ ++ xf_emit(ctx, acnt/8, 0); /* ffffffff VTX_ATR_MASK_UNK0DD0 */ ++ xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ ++ xf_emit(ctx, 1, 0x20); /* 0000ffff tesla UNK129C */ ++ xf_emit(ctx, 1, 0); /* 000000ff turing UNK370??? */ ++ xf_emit(ctx, 1, 0); /* 0000ffff turing USER_PARAM_COUNT */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ /* SEEK */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 0xb, 0); /* RO */ + else if (dev_priv->chipset >= 0xa0) +- xf_emit(ctx, 0xf, 0); ++ xf_emit(ctx, 0x9, 0); /* RO */ + else +- xf_emit(ctx, 0xe, 0); +- xf_emit(ctx, 1, 0x1a); +- xf_emit(ctx, 0xd, 0); +- xf_emit(ctx, 2, 4); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 8); +- xf_emit(ctx, 1, 0); ++ xf_emit(ctx, 0x8, 0); /* RO */ ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* 00000001 EDGE_FLAG */ ++ xf_emit(ctx, 1, 0); /* 00000001 PROVOKING_VERTEX_LAST */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ ++ /* SEEK */ ++ xf_emit(ctx, 0xc, 0); /* RO */ ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* 7f/ff */ ++ xf_emit(ctx, 1, 4); /* 7f/ff VP_REG_ALLOC_RESULT */ ++ xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ ++ xf_emit(ctx, 1, 4); /* 000001ff UNK1A28 */ ++ xf_emit(ctx, 1, 8); /* 000001ff UNK0DF0 */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + if (dev_priv->chipset == 0x50) +- xf_emit(ctx, 1, 0x3ff); ++ xf_emit(ctx, 1, 0x3ff); /* 3ff tesla UNK0D68 */ + else +- xf_emit(ctx, 1, 0x7ff); ++ xf_emit(ctx, 1, 0x7ff); /* 7ff tesla UNK0D68 */ + if (dev_priv->chipset == 0xa8) +- xf_emit(ctx, 1, 0x1e00); +- xf_emit(ctx, 0xc, 0); +- xf_emit(ctx, 1, 0xf); +- if (dev_priv->chipset == 0x50) +- xf_emit(ctx, 0x125, 0); +- else if (dev_priv->chipset < 0xa0) +- xf_emit(ctx, 0x126, 0); +- else if (dev_priv->chipset == 0xa0 || dev_priv->chipset >= 0xaa) +- xf_emit(ctx, 0x124, 0); ++ xf_emit(ctx, 1, 0x1e00); /* 7fff */ ++ /* SEEK */ ++ xf_emit(ctx, 0xc, 0); /* RO or close */ ++ /* SEEK */ ++ xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ ++ xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ ++ xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ ++ if (dev_priv->chipset > 0x50 && dev_priv->chipset < 0xa0) ++ xf_emit(ctx, 2, 0); /* ffffffff */ + else +- xf_emit(ctx, 0x1f7, 0); +- xf_emit(ctx, 1, 0xf); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 3, 0); ++ xf_emit(ctx, 1, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* 00000003 tesla UNK0FD8 */ ++ /* SEEK */ ++ if (IS_NVA3F(dev_priv->chipset)) { ++ xf_emit(ctx, 0x10, 0); /* 0? */ ++ xf_emit(ctx, 2, 0); /* weird... */ ++ xf_emit(ctx, 2, 0); /* RO */ ++ } else { ++ xf_emit(ctx, 8, 0); /* 0? */ ++ xf_emit(ctx, 1, 0); /* weird... */ ++ xf_emit(ctx, 2, 0); /* RO */ ++ } ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* ffffffff VB_ELEMENT_BASE */ ++ xf_emit(ctx, 1, 0); /* ffffffff UNK1438 */ ++ xf_emit(ctx, acnt, 0); /* 1 tesla UNK1000 */ ++ if (dev_priv->chipset >= 0xa0) ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1118? */ ++ /* SEEK */ ++ xf_emit(ctx, acnt, 0); /* ffffffff VERTEX_ARRAY_UNK90C */ ++ xf_emit(ctx, 1, 0); /* f/1f */ ++ /* SEEK */ ++ xf_emit(ctx, acnt, 0); /* ffffffff VERTEX_ARRAY_UNK90C */ ++ xf_emit(ctx, 1, 0); /* f/1f */ ++ /* SEEK */ ++ xf_emit(ctx, acnt, 0); /* RO */ ++ xf_emit(ctx, 2, 0); /* RO */ ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK111C? */ ++ xf_emit(ctx, 1, 0); /* RO */ ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* 000000ff UNK15F4_ADDRESS_HIGH */ ++ xf_emit(ctx, 1, 0); /* ffffffff UNK15F4_ADDRESS_LOW */ ++ xf_emit(ctx, 1, 0); /* 000000ff UNK0F84_ADDRESS_HIGH */ ++ xf_emit(ctx, 1, 0); /* ffffffff UNK0F84_ADDRESS_LOW */ ++ /* SEEK */ ++ xf_emit(ctx, acnt, 0); /* 00003fff VERTEX_ARRAY_ATTRIB_OFFSET */ ++ xf_emit(ctx, 3, 0); /* f/1f */ ++ /* SEEK */ ++ xf_emit(ctx, acnt, 0); /* 00000fff VERTEX_ARRAY_STRIDE */ ++ xf_emit(ctx, 3, 0); /* f/1f */ ++ /* SEEK */ ++ xf_emit(ctx, acnt, 0); /* ffffffff VERTEX_ARRAY_LOW */ ++ xf_emit(ctx, 3, 0); /* f/1f */ ++ /* SEEK */ ++ xf_emit(ctx, acnt, 0); /* 000000ff VERTEX_ARRAY_HIGH */ ++ xf_emit(ctx, 3, 0); /* f/1f */ ++ /* SEEK */ ++ xf_emit(ctx, acnt, 0); /* ffffffff VERTEX_LIMIT_LOW */ ++ xf_emit(ctx, 3, 0); /* f/1f */ ++ /* SEEK */ ++ xf_emit(ctx, acnt, 0); /* 000000ff VERTEX_LIMIT_HIGH */ ++ xf_emit(ctx, 3, 0); /* f/1f */ ++ /* SEEK */ ++ if (IS_NVA3F(dev_priv->chipset)) { ++ xf_emit(ctx, acnt, 0); /* f */ ++ xf_emit(ctx, 3, 0); /* f/1f */ ++ } ++ /* SEEK */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 2, 0); /* RO */ ++ else ++ xf_emit(ctx, 5, 0); /* RO */ ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* ffff DMA_VTXBUF */ ++ /* SEEK */ ++ if (dev_priv->chipset < 0xa0) { ++ xf_emit(ctx, 0x41, 0); /* RO */ ++ /* SEEK */ ++ xf_emit(ctx, 0x11, 0); /* RO */ ++ } else if (!IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 0x50, 0); /* RO */ + else +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 0xa1, 0); ++ xf_emit(ctx, 0x58, 0); /* RO */ ++ /* SEEK */ ++ xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ ++ xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ ++ xf_emit(ctx, 1, 1); /* 1 UNK0DEC */ ++ /* SEEK */ ++ xf_emit(ctx, acnt*4, 0); /* ffffffff VTX_ATTR */ ++ xf_emit(ctx, 4, 0); /* f/1f, 0, 0, 0 */ ++ /* SEEK */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 0x1d, 0); /* RO */ + else +- xf_emit(ctx, 0x5a, 0); +- xf_emit(ctx, 1, 0xf); ++ xf_emit(ctx, 0x16, 0); /* RO */ ++ /* SEEK */ ++ xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ ++ xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ ++ /* SEEK */ + if (dev_priv->chipset < 0xa0) +- xf_emit(ctx, 0x834, 0); +- else if (dev_priv->chipset == 0xa0) +- xf_emit(ctx, 0x1873, 0); +- else if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 0x8ba, 0); ++ xf_emit(ctx, 8, 0); /* RO */ ++ else if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 0xc, 0); /* RO */ ++ else ++ xf_emit(ctx, 7, 0); /* RO */ ++ /* SEEK */ ++ xf_emit(ctx, 0xa, 0); /* RO */ ++ if (dev_priv->chipset == 0xa0) ++ rep = 0xc; ++ else ++ rep = 4; ++ for (i = 0; i < rep; i++) { ++ /* SEEK */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 0x20, 0); /* ffffffff */ ++ xf_emit(ctx, 0x200, 0); /* ffffffff */ ++ xf_emit(ctx, 4, 0); /* 7f/ff, 0, 0, 0 */ ++ xf_emit(ctx, 4, 0); /* ffffffff */ ++ } ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* 113/111 */ ++ xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ ++ xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ ++ xf_emit(ctx, acnt/8, 0); /* ffffffff VTX_ATTR_MASK_UNK0DD0 */ ++ xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ /* SEEK */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 7, 0); /* weird... */ + else +- xf_emit(ctx, 0x833, 0); +- xf_emit(ctx, 1, 0xf); +- xf_emit(ctx, 0xf, 0); ++ xf_emit(ctx, 5, 0); /* weird... */ + } + + static void +-nv50_graph_construct_gene_unk7(struct nouveau_grctx *ctx) ++nv50_graph_construct_gene_eng2d(struct nouveau_grctx *ctx) + { + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; +- /* middle of area 1 on pre-NVA0 [after m2mf], middle of area 6 on NVAx */ +- xf_emit(ctx, 2, 0); +- if (dev_priv->chipset == 0x50) +- xf_emit(ctx, 2, 1); +- else +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 2, 0x100); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 8); +- xf_emit(ctx, 5, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 3, 1); +- xf_emit(ctx, 1, 0xcf); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 6, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 3, 1); +- xf_emit(ctx, 4, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0x15); +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 0x4444480); +- xf_emit(ctx, 0x37, 0); ++ /* middle of strand 1 on pre-NVA0 [after vfetch], middle of strand 6 on NVAx */ ++ /* SEEK */ ++ xf_emit(ctx, 2, 0); /* 0001ffff CLIP_X, CLIP_Y */ ++ xf_emit(ctx, 2, 0); /* 0000ffff CLIP_W, CLIP_H */ ++ xf_emit(ctx, 1, 0); /* 00000001 CLIP_ENABLE */ ++ if (dev_priv->chipset < 0xa0) { ++ /* this is useless on everything but the original NV50, ++ * guess they forgot to nuke it. Or just didn't bother. */ ++ xf_emit(ctx, 2, 0); /* 0000ffff IFC_CLIP_X, Y */ ++ xf_emit(ctx, 2, 1); /* 0000ffff IFC_CLIP_W, H */ ++ xf_emit(ctx, 1, 0); /* 00000001 IFC_CLIP_ENABLE */ ++ } ++ xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ ++ xf_emit(ctx, 1, 0x100); /* 0001ffff DST_WIDTH */ ++ xf_emit(ctx, 1, 0x100); /* 0001ffff DST_HEIGHT */ ++ xf_emit(ctx, 1, 0x11); /* 3f[NV50]/7f[NV84+] DST_FORMAT */ ++ xf_emit(ctx, 1, 0); /* 0001ffff DRAW_POINT_X */ ++ xf_emit(ctx, 1, 8); /* 0000000f DRAW_UNK58C */ ++ xf_emit(ctx, 1, 0); /* 000fffff SIFC_DST_X_FRACT */ ++ xf_emit(ctx, 1, 0); /* 0001ffff SIFC_DST_X_INT */ ++ xf_emit(ctx, 1, 0); /* 000fffff SIFC_DST_Y_FRACT */ ++ xf_emit(ctx, 1, 0); /* 0001ffff SIFC_DST_Y_INT */ ++ xf_emit(ctx, 1, 0); /* 000fffff SIFC_DX_DU_FRACT */ ++ xf_emit(ctx, 1, 1); /* 0001ffff SIFC_DX_DU_INT */ ++ xf_emit(ctx, 1, 0); /* 000fffff SIFC_DY_DV_FRACT */ ++ xf_emit(ctx, 1, 1); /* 0001ffff SIFC_DY_DV_INT */ ++ xf_emit(ctx, 1, 1); /* 0000ffff SIFC_WIDTH */ ++ xf_emit(ctx, 1, 1); /* 0000ffff SIFC_HEIGHT */ ++ xf_emit(ctx, 1, 0xcf); /* 000000ff SIFC_FORMAT */ ++ xf_emit(ctx, 1, 2); /* 00000003 SIFC_BITMAP_UNK808 */ ++ xf_emit(ctx, 1, 0); /* 00000003 SIFC_BITMAP_LINE_PACK_MODE */ ++ xf_emit(ctx, 1, 0); /* 00000001 SIFC_BITMAP_LSB_FIRST */ ++ xf_emit(ctx, 1, 0); /* 00000001 SIFC_BITMAP_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 0000ffff BLIT_DST_X */ ++ xf_emit(ctx, 1, 0); /* 0000ffff BLIT_DST_Y */ ++ xf_emit(ctx, 1, 0); /* 000fffff BLIT_DU_DX_FRACT */ ++ xf_emit(ctx, 1, 1); /* 0001ffff BLIT_DU_DX_INT */ ++ xf_emit(ctx, 1, 0); /* 000fffff BLIT_DV_DY_FRACT */ ++ xf_emit(ctx, 1, 1); /* 0001ffff BLIT_DV_DY_INT */ ++ xf_emit(ctx, 1, 1); /* 0000ffff BLIT_DST_W */ ++ xf_emit(ctx, 1, 1); /* 0000ffff BLIT_DST_H */ ++ xf_emit(ctx, 1, 0); /* 000fffff BLIT_SRC_X_FRACT */ ++ xf_emit(ctx, 1, 0); /* 0001ffff BLIT_SRC_X_INT */ ++ xf_emit(ctx, 1, 0); /* 000fffff BLIT_SRC_Y_FRACT */ ++ xf_emit(ctx, 1, 0); /* 00000001 UNK888 */ ++ xf_emit(ctx, 1, 4); /* 0000003f UNK884 */ ++ xf_emit(ctx, 1, 0); /* 00000007 UNK880 */ ++ xf_emit(ctx, 1, 1); /* 0000001f tesla UNK0FB8 */ ++ xf_emit(ctx, 1, 0x15); /* 000000ff tesla UNK128C */ ++ xf_emit(ctx, 2, 0); /* 00000007, ffff0ff3 */ ++ xf_emit(ctx, 1, 0); /* 00000001 UNK260 */ ++ xf_emit(ctx, 1, 0x4444480); /* 1fffffff UNK870 */ ++ /* SEEK */ ++ xf_emit(ctx, 0x10, 0); ++ /* SEEK */ ++ xf_emit(ctx, 0x27, 0); + } + + static void +-nv50_graph_construct_gene_unk8(struct nouveau_grctx *ctx) ++nv50_graph_construct_gene_csched(struct nouveau_grctx *ctx) + { +- /* middle of area 1 on pre-NVA0 [after m2mf], middle of area 0 on NVAx */ +- xf_emit(ctx, 4, 0); +- xf_emit(ctx, 1, 0x8100c12); +- xf_emit(ctx, 4, 0); +- xf_emit(ctx, 1, 0x100); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 0x10001); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x10001); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0x10001); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 2); ++ struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; ++ /* middle of strand 1 on pre-NVA0 [after eng2d], middle of strand 0 on NVAx */ ++ /* SEEK */ ++ xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY... what is it doing here??? */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1924 */ ++ xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ ++ xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ ++ xf_emit(ctx, 1, 0); /* 000003ff */ ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* ffffffff turing UNK364 */ ++ xf_emit(ctx, 1, 0); /* 0000000f turing UNK36C */ ++ xf_emit(ctx, 1, 0); /* 0000ffff USER_PARAM_COUNT */ ++ xf_emit(ctx, 1, 0x100); /* 00ffffff turing UNK384 */ ++ xf_emit(ctx, 1, 0); /* 0000000f turing UNK2A0 */ ++ xf_emit(ctx, 1, 0); /* 0000ffff GRIDID */ ++ xf_emit(ctx, 1, 0x10001); /* ffffffff GRIDDIM_XY */ ++ xf_emit(ctx, 1, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0x10001); /* ffffffff BLOCKDIM_XY */ ++ xf_emit(ctx, 1, 1); /* 0000ffff BLOCKDIM_Z */ ++ xf_emit(ctx, 1, 0x10001); /* 00ffffff BLOCK_ALLOC */ ++ xf_emit(ctx, 1, 1); /* 00000001 LANES32 */ ++ xf_emit(ctx, 1, 4); /* 000000ff FP_REG_ALLOC_TEMP */ ++ xf_emit(ctx, 1, 2); /* 00000003 REG_MODE */ ++ /* SEEK */ ++ xf_emit(ctx, 0x40, 0); /* ffffffff USER_PARAM */ ++ switch (dev_priv->chipset) { ++ case 0x50: ++ case 0x92: ++ xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ ++ xf_emit(ctx, 0x80, 0); /* fff */ ++ xf_emit(ctx, 2, 0); /* ff, fff */ ++ xf_emit(ctx, 0x10*2, 0); /* ffffffff, 1f */ ++ break; ++ case 0x84: ++ xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ ++ xf_emit(ctx, 0x60, 0); /* fff */ ++ xf_emit(ctx, 2, 0); /* ff, fff */ ++ xf_emit(ctx, 0xc*2, 0); /* ffffffff, 1f */ ++ break; ++ case 0x94: ++ case 0x96: ++ xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ ++ xf_emit(ctx, 0x40, 0); /* fff */ ++ xf_emit(ctx, 2, 0); /* ff, fff */ ++ xf_emit(ctx, 8*2, 0); /* ffffffff, 1f */ ++ break; ++ case 0x86: ++ case 0x98: ++ xf_emit(ctx, 4, 0); /* f, 0, 0, 0 */ ++ xf_emit(ctx, 0x10, 0); /* fff */ ++ xf_emit(ctx, 2, 0); /* ff, fff */ ++ xf_emit(ctx, 2*2, 0); /* ffffffff, 1f */ ++ break; ++ case 0xa0: ++ xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ ++ xf_emit(ctx, 0xf0, 0); /* fff */ ++ xf_emit(ctx, 2, 0); /* ff, fff */ ++ xf_emit(ctx, 0x1e*2, 0); /* ffffffff, 1f */ ++ break; ++ case 0xa3: ++ xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ ++ xf_emit(ctx, 0x60, 0); /* fff */ ++ xf_emit(ctx, 2, 0); /* ff, fff */ ++ xf_emit(ctx, 0xc*2, 0); /* ffffffff, 1f */ ++ break; ++ case 0xa5: ++ case 0xaf: ++ xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ ++ xf_emit(ctx, 0x30, 0); /* fff */ ++ xf_emit(ctx, 2, 0); /* ff, fff */ ++ xf_emit(ctx, 6*2, 0); /* ffffffff, 1f */ ++ break; ++ case 0xaa: ++ xf_emit(ctx, 0x12, 0); ++ break; ++ case 0xa8: ++ case 0xac: ++ xf_emit(ctx, 4, 0); /* f, 0, 0, 0 */ ++ xf_emit(ctx, 0x10, 0); /* fff */ ++ xf_emit(ctx, 2, 0); /* ff, fff */ ++ xf_emit(ctx, 2*2, 0); /* ffffffff, 1f */ ++ break; ++ } ++ xf_emit(ctx, 1, 0); /* 0000000f */ ++ xf_emit(ctx, 1, 0); /* 00000000 */ ++ xf_emit(ctx, 1, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* 0000001f */ ++ xf_emit(ctx, 4, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* 00000003 turing UNK35C */ ++ xf_emit(ctx, 1, 0); /* ffffffff */ ++ xf_emit(ctx, 4, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* 00000003 turing UNK35C */ ++ xf_emit(ctx, 1, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* 000000ff */ + } + + static void +-nv50_graph_construct_gene_unk9(struct nouveau_grctx *ctx) ++nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx) + { + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; +- /* middle of area 2 on pre-NVA0 [after m2mf], end of area 0 on NVAx */ +- xf_emit(ctx, 1, 0x3f800000); +- xf_emit(ctx, 6, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 0x1a); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 0x12, 0); +- xf_emit(ctx, 1, 0x00ffff00); +- xf_emit(ctx, 6, 0); +- xf_emit(ctx, 1, 0xf); +- xf_emit(ctx, 7, 0); +- xf_emit(ctx, 1, 0x0fac6881); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 0xf, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 2, 0); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 1, 3); ++ xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY */ ++ xf_emit(ctx, 1, 0x3f800000); /* ffffffff LINE_WIDTH */ ++ xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1658 */ ++ xf_emit(ctx, 1, 0); /* 00000001 POLYGON_SMOOTH_ENABLE */ ++ xf_emit(ctx, 3, 0); /* 00000001 POLYGON_OFFSET_*_ENABLE */ ++ xf_emit(ctx, 1, 4); /* 0000000f CULL_MODE */ ++ xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ ++ xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ ++ xf_emit(ctx, 1, 0); /* 00000001 POINT_SPRITE_ENABLE */ ++ xf_emit(ctx, 1, 1); /* 00000001 tesla UNK165C */ ++ xf_emit(ctx, 0x10, 0); /* 00000001 SCISSOR_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ ++ xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ ++ xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ ++ xf_emit(ctx, 1, 0); /* ffffffff POLYGON_OFFSET_UNITS */ ++ xf_emit(ctx, 1, 0); /* ffffffff POLYGON_OFFSET_FACTOR */ ++ xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1668 */ ++ xf_emit(ctx, 2, 0); /* 07ffffff SCREEN_SCISSOR */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ ++ xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ ++ xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ ++ xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ ++ xf_emit(ctx, 1, 0x11); /* 0000007f RT_FORMAT */ ++ xf_emit(ctx, 7, 0); /* 0000007f RT_FORMAT */ ++ xf_emit(ctx, 8, 0); /* 00000001 RT_HORIZ_LINEAR */ ++ xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ ++ xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 3); /* 00000003 UNK16B4 */ + else if (dev_priv->chipset >= 0xa0) +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 2, 0x04000000); +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 5); +- xf_emit(ctx, 1, 0x52); +- if (dev_priv->chipset == 0x50) { +- xf_emit(ctx, 0x13, 0); +- } else { +- xf_emit(ctx, 4, 0); +- xf_emit(ctx, 1, 1); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 0x11, 0); +- else +- xf_emit(ctx, 0x10, 0); ++ xf_emit(ctx, 1, 1); /* 00000001 UNK16B4 */ ++ xf_emit(ctx, 1, 0); /* 00000003 MULTISAMPLE_CTRL */ ++ xf_emit(ctx, 1, 0); /* 00000003 tesla UNK0F90 */ ++ xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ ++ xf_emit(ctx, 2, 0x04000000); /* 07ffffff tesla UNK0D6C */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ ++ xf_emit(ctx, 1, 5); /* 0000000f UNK1408 */ ++ xf_emit(ctx, 1, 0x52); /* 000001ff SEMANTIC_PTSZ */ ++ xf_emit(ctx, 1, 0); /* ffffffff POINT_SIZE */ ++ xf_emit(ctx, 1, 0); /* 00000001 */ ++ xf_emit(ctx, 1, 0); /* 00000007 tesla UNK0FB4 */ ++ if (dev_priv->chipset != 0x50) { ++ xf_emit(ctx, 1, 0); /* 3ff */ ++ xf_emit(ctx, 1, 1); /* 00000001 tesla UNK1110 */ + } +- xf_emit(ctx, 0x10, 0x3f800000); +- xf_emit(ctx, 1, 0x10); +- xf_emit(ctx, 0x26, 0); +- xf_emit(ctx, 1, 0x8100c12); +- xf_emit(ctx, 1, 5); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 4, 0xffff); ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1928 */ ++ xf_emit(ctx, 0x10, 0); /* ffffffff DEPTH_RANGE_NEAR */ ++ xf_emit(ctx, 0x10, 0x3f800000); /* ffffffff DEPTH_RANGE_FAR */ ++ xf_emit(ctx, 1, 0x10); /* 000000ff VIEW_VOLUME_CLIP_CTRL */ ++ xf_emit(ctx, 0x20, 0); /* 07ffffff VIEWPORT_HORIZ, then VIEWPORT_VERT. (W&0x3fff)<<13 | (X&0x1fff). */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK187C */ ++ xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ ++ xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ ++ xf_emit(ctx, 1, 5); /* 0000000f tesla UNK1220 */ ++ xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 1, 0); /* 000000ff tesla UNK1A20 */ ++ xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ ++ xf_emit(ctx, 4, 0xffff); /* 0000ffff MSAA_MASK */ + if (dev_priv->chipset != 0x50) +- xf_emit(ctx, 1, 3); ++ xf_emit(ctx, 1, 3); /* 00000003 tesla UNK1100 */ + if (dev_priv->chipset < 0xa0) +- xf_emit(ctx, 0x1f, 0); +- else if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 0xc, 0); +- else +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 0x00ffff00); +- xf_emit(ctx, 1, 0x1a); ++ xf_emit(ctx, 0x1c, 0); /* RO */ ++ else if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 0x9, 0); ++ xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */ ++ xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ ++ xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ ++ xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ ++ xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ + if (dev_priv->chipset != 0x50) { +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 3); ++ xf_emit(ctx, 1, 3); /* 00000003 tesla UNK1100 */ ++ xf_emit(ctx, 1, 0); /* 3ff */ + } ++ /* XXX: the following block could belong either to unk1cxx, or ++ * to STRMOUT. Rather hard to tell. */ + if (dev_priv->chipset < 0xa0) +- xf_emit(ctx, 0x26, 0); ++ xf_emit(ctx, 0x25, 0); + else +- xf_emit(ctx, 0x3c, 0); +- xf_emit(ctx, 1, 0x102); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 4, 4); +- if (dev_priv->chipset >= 0xa0) +- xf_emit(ctx, 8, 0); +- xf_emit(ctx, 2, 4); +- xf_emit(ctx, 1, 0); ++ xf_emit(ctx, 0x3b, 0); ++} ++ ++static void ++nv50_graph_construct_gene_strmout(struct nouveau_grctx *ctx) ++{ ++ struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; ++ xf_emit(ctx, 1, 0x102); /* 0000ffff STRMOUT_BUFFER_CTRL */ ++ xf_emit(ctx, 1, 0); /* ffffffff STRMOUT_PRIMITIVE_COUNT */ ++ xf_emit(ctx, 4, 4); /* 000000ff STRMOUT_NUM_ATTRIBS */ ++ if (dev_priv->chipset >= 0xa0) { ++ xf_emit(ctx, 4, 0); /* ffffffff UNK1A8C */ ++ xf_emit(ctx, 4, 0); /* ffffffff UNK1780 */ ++ } ++ xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + if (dev_priv->chipset == 0x50) +- xf_emit(ctx, 1, 0x3ff); ++ xf_emit(ctx, 1, 0x3ff); /* 000003ff tesla UNK0D68 */ + else +- xf_emit(ctx, 1, 0x7ff); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x102); +- xf_emit(ctx, 9, 0); +- xf_emit(ctx, 4, 4); +- xf_emit(ctx, 0x2c, 0); ++ xf_emit(ctx, 1, 0x7ff); /* 000007ff tesla UNK0D68 */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ /* SEEK */ ++ xf_emit(ctx, 1, 0x102); /* 0000ffff STRMOUT_BUFFER_CTRL */ ++ xf_emit(ctx, 1, 0); /* ffffffff STRMOUT_PRIMITIVE_COUNT */ ++ xf_emit(ctx, 4, 0); /* 000000ff STRMOUT_ADDRESS_HIGH */ ++ xf_emit(ctx, 4, 0); /* ffffffff STRMOUT_ADDRESS_LOW */ ++ xf_emit(ctx, 4, 4); /* 000000ff STRMOUT_NUM_ATTRIBS */ ++ if (dev_priv->chipset >= 0xa0) { ++ xf_emit(ctx, 4, 0); /* ffffffff UNK1A8C */ ++ xf_emit(ctx, 4, 0); /* ffffffff UNK1780 */ ++ } ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_STRMOUT */ ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_QUERY */ ++ xf_emit(ctx, 1, 0); /* 000000ff QUERY_ADDRESS_HIGH */ ++ xf_emit(ctx, 2, 0); /* ffffffff QUERY_ADDRESS_LOW QUERY_COUNTER */ ++ xf_emit(ctx, 2, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ /* SEEK */ ++ xf_emit(ctx, 0x20, 0); /* ffffffff STRMOUT_MAP */ ++ xf_emit(ctx, 1, 0); /* 0000000f */ ++ xf_emit(ctx, 1, 0); /* 00000000? */ ++ xf_emit(ctx, 2, 0); /* ffffffff */ ++} ++ ++static void ++nv50_graph_construct_gene_ropm1(struct nouveau_grctx *ctx) ++{ ++ struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; ++ xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0D64 */ ++ xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0DF4 */ ++ xf_emit(ctx, 1, 0); /* 00000007 */ ++ xf_emit(ctx, 1, 0); /* 000003ff */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 0x11); /* 000000ff tesla UNK1968 */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ ++} ++ ++static void ++nv50_graph_construct_gene_ropm2(struct nouveau_grctx *ctx) ++{ ++ struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_QUERY */ ++ xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ ++ xf_emit(ctx, 2, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* 000000ff QUERY_ADDRESS_HIGH */ ++ xf_emit(ctx, 2, 0); /* ffffffff QUERY_ADDRESS_LOW, COUNTER */ ++ xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 7 */ ++ /* SEEK */ ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_QUERY */ ++ xf_emit(ctx, 1, 0); /* 000000ff QUERY_ADDRESS_HIGH */ ++ xf_emit(ctx, 2, 0); /* ffffffff QUERY_ADDRESS_LOW, COUNTER */ ++ xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0D64 */ ++ xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0DF4 */ ++ xf_emit(ctx, 1, 0); /* 00000001 eng2d UNK260 */ ++ xf_emit(ctx, 1, 0); /* ff/3ff */ ++ xf_emit(ctx, 1, 0); /* 00000007 */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 0x11); /* 000000ff tesla UNK1968 */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ + } + + static void +@@ -1749,443 +2392,709 @@ nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx) + int magic2; + if (dev_priv->chipset == 0x50) { + magic2 = 0x00003e60; +- } else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) { ++ } else if (!IS_NVA3F(dev_priv->chipset)) { + magic2 = 0x001ffe67; + } else { + magic2 = 0x00087e67; + } +- xf_emit(ctx, 8, 0); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, magic2); +- xf_emit(ctx, 4, 0); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 7, 0); +- if (dev_priv->chipset >= 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 1, 0x15); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0x10); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 4, 0); ++ xf_emit(ctx, 1, 0); /* f/7 MUTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ ++ xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ ++ xf_emit(ctx, 3, 0); /* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */ ++ xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ ++ xf_emit(ctx, 1, 0); /* ffff0ff3 */ ++ xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ ++ xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ ++ xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ ++ xf_emit(ctx, 3, 0); /* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ ++ if (dev_priv->chipset >= 0xa0 && !IS_NVAAF(dev_priv->chipset)) ++ xf_emit(ctx, 1, 0x15); /* 000000ff */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ ++ xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ ++ xf_emit(ctx, 1, 0x10); /* 3ff/ff VIEW_VOLUME_CLIP_CTRL */ ++ xf_emit(ctx, 1, 0); /* ffffffff CLEAR_DEPTH */ ++ xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ ++ xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ + if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x92 || dev_priv->chipset == 0x98 || dev_priv->chipset >= 0xa0) { +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 0x400); +- xf_emit(ctx, 1, 0x300); +- xf_emit(ctx, 1, 0x1001); ++ xf_emit(ctx, 3, 0); /* ff, ffffffff, ffffffff */ ++ xf_emit(ctx, 1, 4); /* 7 */ ++ xf_emit(ctx, 1, 0x400); /* fffffff */ ++ xf_emit(ctx, 1, 0x300); /* ffff */ ++ xf_emit(ctx, 1, 0x1001); /* 1fff */ + if (dev_priv->chipset != 0xa0) { +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 1, 0); ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 0); /* 0000000f UNK15C8 */ + else +- xf_emit(ctx, 1, 0x15); ++ xf_emit(ctx, 1, 0x15); /* ff */ + } +- xf_emit(ctx, 3, 0); + } +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 8, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0x10); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 0x13, 0); +- xf_emit(ctx, 1, 0x10); +- xf_emit(ctx, 0x10, 0); +- xf_emit(ctx, 0x10, 0x3f800000); +- xf_emit(ctx, 0x19, 0); +- xf_emit(ctx, 1, 0x10); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x3f); +- xf_emit(ctx, 6, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); ++ xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ ++ xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ ++ xf_emit(ctx, 1, 0); /* ffff0ff3 */ ++ xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ ++ xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ ++ xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ ++ xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ ++ xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ ++ xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ ++ xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_REF */ ++ xf_emit(ctx, 2, 0); /* ffffffff DEPTH_BOUNDS */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ ++ xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 0000000f */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0FB0 */ ++ xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_REF */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ ++ xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ ++ xf_emit(ctx, 0x10, 0); /* ffffffff DEPTH_RANGE_NEAR */ ++ xf_emit(ctx, 0x10, 0x3f800000); /* ffffffff DEPTH_RANGE_FAR */ ++ xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ ++ xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_REF */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ ++ xf_emit(ctx, 3, 0); /* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */ ++ xf_emit(ctx, 2, 0); /* ffffffff DEPTH_BOUNDS */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ ++ xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 000000ff CLEAR_STENCIL */ ++ xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_REF */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ ++ xf_emit(ctx, 3, 0); /* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ ++ xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ ++ xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ ++ xf_emit(ctx, 1, 0x3f); /* 0000003f UNK1590 */ ++ xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ ++ xf_emit(ctx, 2, 0); /* ffff0ff3, ffff */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0FB0 */ ++ xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ ++ xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ ++ xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ ++ xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ ++ xf_emit(ctx, 1, 0); /* ffffffff CLEAR_DEPTH */ ++ xf_emit(ctx, 1, 1); /* 00000001 tesla UNK19CC */ + if (dev_priv->chipset >= 0xa0) { + xf_emit(ctx, 2, 0); + xf_emit(ctx, 1, 0x1001); + xf_emit(ctx, 0xb, 0); + } else { +- xf_emit(ctx, 0xc, 0); ++ xf_emit(ctx, 1, 0); /* 00000007 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ ++ xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ ++ xf_emit(ctx, 1, 0); /* ffff0ff3 */ + } +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 7, 0); +- xf_emit(ctx, 1, 0xf); +- xf_emit(ctx, 7, 0); +- xf_emit(ctx, 1, 0x11); +- if (dev_priv->chipset == 0x50) +- xf_emit(ctx, 4, 0); +- else +- xf_emit(ctx, 6, 0); +- xf_emit(ctx, 3, 1); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, magic2); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x0fac6881); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 0x18, 1); +- xf_emit(ctx, 8, 2); +- xf_emit(ctx, 8, 1); +- xf_emit(ctx, 8, 2); +- xf_emit(ctx, 8, 1); +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 5, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 0x16, 0); ++ xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ ++ xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ ++ xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ ++ xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ ++ xf_emit(ctx, 1, 0x11); /* 3f/7f */ ++ xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ ++ if (dev_priv->chipset != 0x50) { ++ xf_emit(ctx, 1, 0); /* 0000000f LOGIC_OP */ ++ xf_emit(ctx, 1, 0); /* 000000ff */ ++ } ++ xf_emit(ctx, 1, 0); /* 00000007 OPERATION */ ++ xf_emit(ctx, 1, 0); /* ff/3ff */ ++ xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ ++ xf_emit(ctx, 2, 1); /* 00000007 BLEND_EQUATION_RGB, ALPHA */ ++ xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ ++ xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ ++ xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ ++ xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ ++ xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ ++ xf_emit(ctx, 1, 0); /* 00000001 */ ++ xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ ++ xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ ++ if (IS_NVA3F(dev_priv->chipset)) { ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK12E4 */ ++ xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */ ++ xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_ALPHA */ ++ xf_emit(ctx, 8, 1); /* 00000001 IBLEND_UNK00 */ ++ xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_RGB */ ++ xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_RGB */ ++ xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_ALPHA */ ++ xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_ALPHA */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1140 */ ++ xf_emit(ctx, 2, 0); /* 00000001 */ ++ xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ ++ xf_emit(ctx, 1, 0); /* 0000000f */ ++ xf_emit(ctx, 1, 0); /* 00000003 */ ++ xf_emit(ctx, 1, 0); /* ffffffff */ ++ xf_emit(ctx, 2, 0); /* 00000001 */ ++ xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ ++ xf_emit(ctx, 1, 0); /* 00000001 */ ++ xf_emit(ctx, 1, 0); /* 000003ff */ ++ } else if (dev_priv->chipset >= 0xa0) { ++ xf_emit(ctx, 2, 0); /* 00000001 */ ++ xf_emit(ctx, 1, 0); /* 00000007 */ ++ xf_emit(ctx, 1, 0); /* 00000003 */ ++ xf_emit(ctx, 1, 0); /* ffffffff */ ++ xf_emit(ctx, 2, 0); /* 00000001 */ + } else { +- if (dev_priv->chipset >= 0xa0) +- xf_emit(ctx, 0x1b, 0); +- else +- xf_emit(ctx, 0x15, 0); ++ xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1430 */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ + } +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 2, 1); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 2, 1); ++ xf_emit(ctx, 4, 0); /* ffffffff CLEAR_COLOR */ ++ xf_emit(ctx, 4, 0); /* ffffffff BLEND_COLOR A R G B */ ++ xf_emit(ctx, 1, 0); /* 00000fff eng2d UNK2B0 */ + if (dev_priv->chipset >= 0xa0) +- xf_emit(ctx, 4, 0); +- else +- xf_emit(ctx, 3, 0); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { +- xf_emit(ctx, 0x10, 1); +- xf_emit(ctx, 8, 2); +- xf_emit(ctx, 0x10, 1); +- xf_emit(ctx, 8, 2); +- xf_emit(ctx, 8, 1); +- xf_emit(ctx, 3, 0); ++ xf_emit(ctx, 2, 0); /* 00000001 */ ++ xf_emit(ctx, 1, 0); /* 000003ff */ ++ xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ ++ xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ ++ xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ ++ xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ ++ xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_RGB */ ++ xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ ++ xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ ++ xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_ALPHA */ ++ xf_emit(ctx, 1, 0); /* 00000001 UNK19C0 */ ++ xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 0000000f LOGIC_OP */ ++ if (dev_priv->chipset >= 0xa0) ++ xf_emit(ctx, 1, 0); /* 00000001 UNK12E4? NVA3+ only? */ ++ if (IS_NVA3F(dev_priv->chipset)) { ++ xf_emit(ctx, 8, 1); /* 00000001 IBLEND_UNK00 */ ++ xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */ ++ xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_RGB */ ++ xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_RGB */ ++ xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_ALPHA */ ++ xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_ALPHA */ ++ xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_ALPHA */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK15C4 */ ++ xf_emit(ctx, 1, 0); /* 00000001 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1140 */ + } +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 0x5b, 0); ++ xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ ++ xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ ++ xf_emit(ctx, 1, 0); /* 00000007 PATTERN_COLOR_FORMAT */ ++ xf_emit(ctx, 2, 0); /* ffffffff PATTERN_MONO_COLOR */ ++ xf_emit(ctx, 1, 0); /* 00000001 PATTERN_MONO_FORMAT */ ++ xf_emit(ctx, 2, 0); /* ffffffff PATTERN_MONO_BITMAP */ ++ xf_emit(ctx, 1, 0); /* 00000003 PATTERN_SELECT */ ++ xf_emit(ctx, 1, 0); /* 000000ff ROP */ ++ xf_emit(ctx, 1, 0); /* ffffffff BETA1 */ ++ xf_emit(ctx, 1, 0); /* ffffffff BETA4 */ ++ xf_emit(ctx, 1, 0); /* 00000007 OPERATION */ ++ xf_emit(ctx, 0x50, 0); /* 10x ffffff, ffffff, ffffff, ffffff, 3 PATTERN */ + } + + static void +-nv50_graph_construct_xfer_tp_x1(struct nouveau_grctx *ctx) ++nv50_graph_construct_xfer_unk84xx(struct nouveau_grctx *ctx) + { + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; + int magic3; +- if (dev_priv->chipset == 0x50) ++ switch (dev_priv->chipset) { ++ case 0x50: + magic3 = 0x1000; +- else if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x98 || dev_priv->chipset >= 0xa8) ++ break; ++ case 0x86: ++ case 0x98: ++ case 0xa8: ++ case 0xaa: ++ case 0xac: ++ case 0xaf: + magic3 = 0x1e00; +- else ++ break; ++ default: + magic3 = 0; +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 4); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 0x24, 0); ++ } ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 4); /* 7f/ff[NVA0+] VP_REG_ALLOC_RESULT */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ xf_emit(ctx, 1, 0); /* 111/113[NVA0+] */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 0x1f, 0); /* ffffffff */ + else if (dev_priv->chipset >= 0xa0) +- xf_emit(ctx, 0x14, 0); ++ xf_emit(ctx, 0x0f, 0); /* ffffffff */ + else +- xf_emit(ctx, 0x15, 0); +- xf_emit(ctx, 2, 4); ++ xf_emit(ctx, 0x10, 0); /* fffffff VP_RESULT_MAP_1 up */ ++ xf_emit(ctx, 2, 0); /* f/1f[NVA3], fffffff/ffffffff[NVA0+] */ ++ xf_emit(ctx, 1, 4); /* 7f/ff VP_REG_ALLOC_RESULT */ ++ xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ + if (dev_priv->chipset >= 0xa0) +- xf_emit(ctx, 1, 0x03020100); ++ xf_emit(ctx, 1, 0x03020100); /* ffffffff */ + else +- xf_emit(ctx, 1, 0x00608080); +- xf_emit(ctx, 4, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 2, 4); +- xf_emit(ctx, 1, 0x80); ++ xf_emit(ctx, 1, 0x00608080); /* fffffff VP_RESULT_MAP_0 */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ xf_emit(ctx, 2, 0); /* 111/113, 7f/ff */ ++ xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_RESULT */ ++ xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT */ + if (magic3) +- xf_emit(ctx, 1, magic3); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 0x24, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 0x80); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 0x03020100); +- xf_emit(ctx, 1, 3); ++ xf_emit(ctx, 1, magic3); /* 00007fff tesla UNK141C */ ++ xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ xf_emit(ctx, 1, 0); /* 111/113 */ ++ xf_emit(ctx, 0x1f, 0); /* ffffffff GP_RESULT_MAP_1 up */ ++ xf_emit(ctx, 1, 0); /* 0000001f */ ++ xf_emit(ctx, 1, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_RESULT */ ++ xf_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT */ ++ xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 0x03020100); /* ffffffff GP_RESULT_MAP_0 */ ++ xf_emit(ctx, 1, 3); /* 00000003 GP_OUTPUT_PRIMITIVE_TYPE */ + if (magic3) +- xf_emit(ctx, 1, magic3); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 4, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 3); +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 4); ++ xf_emit(ctx, 1, magic3); /* 7fff tesla UNK141C */ ++ xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 0); /* 00000001 PROVOKING_VERTEX_LAST */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ xf_emit(ctx, 1, 0); /* 111/113 */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 3); /* 00000003 GP_OUTPUT_PRIMITIVE_TYPE */ ++ xf_emit(ctx, 1, 0); /* 00000001 PROVOKING_VERTEX_LAST */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ xf_emit(ctx, 1, 0); /* 00000003 tesla UNK13A0 */ ++ xf_emit(ctx, 1, 4); /* 7f/ff VP_REG_ALLOC_RESULT */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ xf_emit(ctx, 1, 0); /* 111/113 */ + if (dev_priv->chipset == 0x94 || dev_priv->chipset == 0x96) +- xf_emit(ctx, 0x1024, 0); ++ xf_emit(ctx, 0x1020, 0); /* 4 x (0x400 x 0xffffffff, ff, 0, 0, 0, 4 x ffffffff) */ + else if (dev_priv->chipset < 0xa0) +- xf_emit(ctx, 0xa24, 0); +- else if (dev_priv->chipset == 0xa0 || dev_priv->chipset >= 0xaa) +- xf_emit(ctx, 0x214, 0); ++ xf_emit(ctx, 0xa20, 0); /* 4 x (0x280 x 0xffffffff, ff, 0, 0, 0, 4 x ffffffff) */ ++ else if (!IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 0x210, 0); /* ffffffff */ + else +- xf_emit(ctx, 0x414, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 3); +- xf_emit(ctx, 2, 0); ++ xf_emit(ctx, 0x410, 0); /* ffffffff */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ ++ xf_emit(ctx, 1, 3); /* 00000003 GP_OUTPUT_PRIMITIVE_TYPE */ ++ xf_emit(ctx, 1, 0); /* 00000001 PROVOKING_VERTEX_LAST */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + } + + static void +-nv50_graph_construct_xfer_tp_x2(struct nouveau_grctx *ctx) ++nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx) + { + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; + int magic1, magic2; + if (dev_priv->chipset == 0x50) { + magic1 = 0x3ff; + magic2 = 0x00003e60; +- } else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) { ++ } else if (!IS_NVA3F(dev_priv->chipset)) { + magic1 = 0x7ff; + magic2 = 0x001ffe67; + } else { + magic1 = 0x7ff; + magic2 = 0x00087e67; + } +- xf_emit(ctx, 3, 0); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 0xc, 0); +- xf_emit(ctx, 1, 0xf); +- xf_emit(ctx, 0xb, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 4, 0xffff); +- xf_emit(ctx, 8, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 5, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 2, 0); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { +- xf_emit(ctx, 1, 3); +- xf_emit(ctx, 1, 0); +- } else if (dev_priv->chipset >= 0xa0) +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 0xa, 0); +- xf_emit(ctx, 2, 1); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 2, 1); +- xf_emit(ctx, 1, 2); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 0x18, 1); +- xf_emit(ctx, 8, 2); +- xf_emit(ctx, 8, 1); +- xf_emit(ctx, 8, 2); +- xf_emit(ctx, 8, 1); +- xf_emit(ctx, 1, 0); ++ xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */ ++ xf_emit(ctx, 1, 0); /* ffffffff ALPHA_TEST_REF */ ++ xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 1); /* 0000000f UNK16A0 */ ++ xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ ++ xf_emit(ctx, 3, 0); /* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */ ++ xf_emit(ctx, 4, 0); /* ffffffff BLEND_COLOR */ ++ xf_emit(ctx, 1, 0); /* 00000001 UNK19C0 */ ++ xf_emit(ctx, 1, 0); /* 00000001 UNK0FDC */ ++ xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ ++ xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ ++ xf_emit(ctx, 1, 0); /* ff[NV50]/3ff[NV84+] */ ++ xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ ++ xf_emit(ctx, 4, 0xffff); /* 0000ffff MSAA_MASK */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ ++ xf_emit(ctx, 3, 0); /* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ ++ xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY */ ++ xf_emit(ctx, 1, 1); /* 00000001 tesla UNK19CC */ ++ xf_emit(ctx, 1, 0); /* 7 */ ++ xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ ++ xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ ++ xf_emit(ctx, 1, 0); /* ffffffff COLOR_KEY */ ++ xf_emit(ctx, 1, 0); /* 00000001 COLOR_KEY_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000007 COLOR_KEY_FORMAT */ ++ xf_emit(ctx, 2, 0); /* ffffffff SIFC_BITMAP_COLOR */ ++ xf_emit(ctx, 1, 1); /* 00000001 SIFC_BITMAP_WRITE_BIT0_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */ ++ xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ ++ if (IS_NVA3F(dev_priv->chipset)) { ++ xf_emit(ctx, 1, 3); /* 00000003 tesla UNK16B4 */ ++ xf_emit(ctx, 1, 0); /* 00000003 */ ++ xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1298 */ ++ } else if (dev_priv->chipset >= 0xa0) { ++ xf_emit(ctx, 1, 1); /* 00000001 tesla UNK16B4 */ ++ xf_emit(ctx, 1, 0); /* 00000003 */ ++ } else { ++ xf_emit(ctx, 1, 0); /* 00000003 MULTISAMPLE_CTRL */ + } +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 7, 0); +- xf_emit(ctx, 1, 0x0fac6881); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 3, 0xcf); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 0xa, 0); +- xf_emit(ctx, 2, 1); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 2, 1); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 8, 1); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 7, 0); +- xf_emit(ctx, 1, 0x0fac6881); +- xf_emit(ctx, 1, 0xf); +- xf_emit(ctx, 7, 0); +- xf_emit(ctx, 1, magic2); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 0x11); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 2, 1); +- else +- xf_emit(ctx, 1, 1); ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ ++ xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ ++ xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ ++ xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_ALPHA */ ++ xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ ++ xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ ++ xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_RGB */ ++ xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ ++ if (IS_NVA3F(dev_priv->chipset)) { ++ xf_emit(ctx, 1, 0); /* 00000001 UNK12E4 */ ++ xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */ ++ xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_ALPHA */ ++ xf_emit(ctx, 8, 1); /* 00000001 IBLEND_UNK00 */ ++ xf_emit(ctx, 8, 2); /* 0000001f IBLEND_SRC_RGB */ ++ xf_emit(ctx, 8, 1); /* 0000001f IBLEND_DST_RGB */ ++ xf_emit(ctx, 8, 2); /* 0000001f IBLEND_SRC_ALPHA */ ++ xf_emit(ctx, 8, 1); /* 0000001f IBLEND_DST_ALPHA */ ++ xf_emit(ctx, 1, 0); /* 00000001 UNK1140 */ ++ } ++ xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ ++ xf_emit(ctx, 1, 0); /* ffff0ff3 */ ++ xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ ++ xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ ++ xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ ++ xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ ++ xf_emit(ctx, 1, 0); /* ff/3ff */ ++ xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ ++ xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ ++ xf_emit(ctx, 1, 0); /* 00000001 FRAMEBUFFER_SRGB */ ++ xf_emit(ctx, 1, 0); /* 7 */ ++ xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ ++ xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ ++ xf_emit(ctx, 1, 0); /* 00000007 OPERATION */ ++ xf_emit(ctx, 1, 0xcf); /* 000000ff SIFC_FORMAT */ ++ xf_emit(ctx, 1, 0xcf); /* 000000ff DRAW_COLOR_FORMAT */ ++ xf_emit(ctx, 1, 0xcf); /* 000000ff SRC_FORMAT */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ ++ xf_emit(ctx, 1, 0); /* 7/f[NVA3] MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ ++ xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ ++ xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_ALPHA */ ++ xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ ++ xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ ++ xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_RGB */ ++ xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ ++ xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ ++ xf_emit(ctx, 1, 0); /* ffff0ff3 */ ++ xf_emit(ctx, 8, 1); /* 00000001 UNK19E0 */ ++ xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ ++ xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ ++ xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ ++ xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ ++ xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ ++ xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ ++ xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ + if(dev_priv->chipset == 0x50) +- xf_emit(ctx, 1, 0); ++ xf_emit(ctx, 1, 0); /* ff */ + else +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 5, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 4, 0); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 7, 0); +- xf_emit(ctx, 1, 0x0fac6881); +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, magic1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 2, 0); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 0x28, 0); +- xf_emit(ctx, 8, 8); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 7, 0); +- xf_emit(ctx, 1, 0x0fac6881); +- xf_emit(ctx, 8, 0x400); +- xf_emit(ctx, 8, 0x300); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0xf); +- xf_emit(ctx, 7, 0); +- xf_emit(ctx, 1, 0x20); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 1, 0x100); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 0x40); +- xf_emit(ctx, 1, 0x100); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 3); +- xf_emit(ctx, 4, 0); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, magic2); +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 1, 0x0fac6881); +- xf_emit(ctx, 9, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 4, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0x400); +- xf_emit(ctx, 1, 0x300); +- xf_emit(ctx, 1, 0x1001); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 4, 0); +- else +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 7, 0); +- xf_emit(ctx, 1, 0x0fac6881); +- xf_emit(ctx, 1, 0xf); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { +- xf_emit(ctx, 0x15, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 3, 0); +- } else +- xf_emit(ctx, 0x17, 0); ++ xf_emit(ctx, 3, 0); /* 1, 7, 3ff */ ++ xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ ++ xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000007 */ ++ xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ ++ xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ ++ xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ ++ xf_emit(ctx, 1, 0); /* ffff0ff3 */ ++ xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ ++ xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ ++ xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ ++ xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ ++ xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ ++ xf_emit(ctx, 1, 0); /* 000fffff BLIT_DU_DX_FRACT */ ++ xf_emit(ctx, 1, 1); /* 0001ffff BLIT_DU_DX_INT */ ++ xf_emit(ctx, 1, 0); /* 000fffff BLIT_DV_DY_FRACT */ ++ xf_emit(ctx, 1, 1); /* 0001ffff BLIT_DV_DY_INT */ ++ xf_emit(ctx, 1, 0); /* ff/3ff */ ++ xf_emit(ctx, 1, magic1); /* 3ff/7ff tesla UNK0D68 */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ ++ xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ ++ xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ ++ xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000007 */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ ++ xf_emit(ctx, 8, 0); /* 0000ffff DMA_COLOR */ ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_GLOBAL */ ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_LOCAL */ ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_STACK */ ++ xf_emit(ctx, 1, 0); /* ff/3ff */ ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_DST */ ++ xf_emit(ctx, 1, 0); /* 7 */ ++ xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 1, 0); /* ffff0ff3 */ ++ xf_emit(ctx, 8, 0); /* 000000ff RT_ADDRESS_HIGH */ ++ xf_emit(ctx, 8, 0); /* ffffffff RT_LAYER_STRIDE */ ++ xf_emit(ctx, 8, 0); /* ffffffff RT_ADDRESS_LOW */ ++ xf_emit(ctx, 8, 8); /* 0000007f RT_TILE_MODE */ ++ xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ ++ xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ ++ xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ ++ xf_emit(ctx, 8, 0x400); /* 0fffffff RT_HORIZ */ ++ xf_emit(ctx, 8, 0x300); /* 0000ffff RT_VERT */ ++ xf_emit(ctx, 1, 1); /* 00001fff RT_ARRAY_MODE */ ++ xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ ++ xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ ++ xf_emit(ctx, 1, 0x20); /* 00000fff DST_TILE_MODE */ ++ xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ ++ xf_emit(ctx, 1, 0x100); /* 0001ffff DST_HEIGHT */ ++ xf_emit(ctx, 1, 0); /* 000007ff DST_LAYER */ ++ xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ ++ xf_emit(ctx, 1, 0); /* ffffffff DST_ADDRESS_LOW */ ++ xf_emit(ctx, 1, 0); /* 000000ff DST_ADDRESS_HIGH */ ++ xf_emit(ctx, 1, 0x40); /* 0007ffff DST_PITCH */ ++ xf_emit(ctx, 1, 0x100); /* 0001ffff DST_WIDTH */ ++ xf_emit(ctx, 1, 0); /* 0000ffff */ ++ xf_emit(ctx, 1, 3); /* 00000003 tesla UNK15AC */ ++ xf_emit(ctx, 1, 0); /* ff/3ff */ ++ xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ ++ xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ ++ xf_emit(ctx, 1, 0); /* 00000007 */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ ++ xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ ++ xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ ++ xf_emit(ctx, 1, 0); /* ffff0ff3 */ ++ xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ ++ xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_ZETA */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ ++ xf_emit(ctx, 2, 0); /* ffff, ff/3ff */ ++ xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ ++ xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ ++ xf_emit(ctx, 1, 0); /* 00000007 */ ++ xf_emit(ctx, 1, 0); /* ffffffff ZETA_LAYER_STRIDE */ ++ xf_emit(ctx, 1, 0); /* 000000ff ZETA_ADDRESS_HIGH */ ++ xf_emit(ctx, 1, 0); /* ffffffff ZETA_ADDRESS_LOW */ ++ xf_emit(ctx, 1, 4); /* 00000007 ZETA_TILE_MODE */ ++ xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ ++ xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ ++ xf_emit(ctx, 1, 0x400); /* 0fffffff ZETA_HORIZ */ ++ xf_emit(ctx, 1, 0x300); /* 0000ffff ZETA_VERT */ ++ xf_emit(ctx, 1, 0x1001); /* 00001fff ZETA_ARRAY_MODE */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ ++ xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 0); /* 00000001 */ ++ xf_emit(ctx, 1, 0); /* ffff0ff3 */ ++ xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ ++ xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ ++ xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ ++ xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ ++ xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ ++ xf_emit(ctx, 1, 0); /* ff/3ff */ ++ xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ ++ xf_emit(ctx, 1, 0); /* 00000001 FRAMEBUFFER_SRGB */ ++ xf_emit(ctx, 1, 0); /* 7 */ ++ xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ ++ if (IS_NVA3F(dev_priv->chipset)) { ++ xf_emit(ctx, 1, 0); /* 00000001 UNK1140 */ ++ xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ ++ } ++ xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */ ++ xf_emit(ctx, 1, 0); /* ffff0ff3 */ + if (dev_priv->chipset >= 0xa0) +- xf_emit(ctx, 1, 0x0fac6881); +- xf_emit(ctx, 1, magic2); +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 2, 1); +- xf_emit(ctx, 3, 0); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 2, 1); +- else +- xf_emit(ctx, 1, 1); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 2, 0); +- else if (dev_priv->chipset != 0x50) +- xf_emit(ctx, 1, 0); ++ xf_emit(ctx, 1, 0x0fac6881); /* fffffff */ ++ xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ ++ xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0FB0 */ ++ xf_emit(ctx, 1, 0); /* ff/3ff */ ++ xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ ++ xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ ++ xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ ++ xf_emit(ctx, 1, 1); /* 00000001 tesla UNK19CC */ ++ xf_emit(ctx, 1, 0); /* 00000007 */ ++ xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ ++ xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ ++ if (IS_NVA3F(dev_priv->chipset)) { ++ xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ ++ xf_emit(ctx, 1, 0); /* 0000000f tesla UNK15C8 */ ++ } ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ ++ if (dev_priv->chipset >= 0xa0) { ++ xf_emit(ctx, 3, 0); /* 7/f, 1, ffff0ff3 */ ++ xf_emit(ctx, 1, 0xfac6881); /* fffffff */ ++ xf_emit(ctx, 4, 0); /* 1, 1, 1, 3ff */ ++ xf_emit(ctx, 1, 4); /* 7 */ ++ xf_emit(ctx, 1, 0); /* 1 */ ++ xf_emit(ctx, 2, 1); /* 1 */ ++ xf_emit(ctx, 2, 0); /* 7, f */ ++ xf_emit(ctx, 1, 1); /* 1 */ ++ xf_emit(ctx, 1, 0); /* 7/f */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 0x9, 0); /* 1 */ ++ else ++ xf_emit(ctx, 0x8, 0); /* 1 */ ++ xf_emit(ctx, 1, 0); /* ffff0ff3 */ ++ xf_emit(ctx, 8, 1); /* 1 */ ++ xf_emit(ctx, 1, 0x11); /* 7f */ ++ xf_emit(ctx, 7, 0); /* 7f */ ++ xf_emit(ctx, 1, 0xfac6881); /* fffffff */ ++ xf_emit(ctx, 1, 0xf); /* f */ ++ xf_emit(ctx, 7, 0); /* f */ ++ xf_emit(ctx, 1, 0x11); /* 7f */ ++ xf_emit(ctx, 1, 1); /* 1 */ ++ xf_emit(ctx, 5, 0); /* 1, 7, 3ff, 3, 7 */ ++ if (IS_NVA3F(dev_priv->chipset)) { ++ xf_emit(ctx, 1, 0); /* 00000001 UNK1140 */ ++ xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ ++ } ++ } + } + + static void +-nv50_graph_construct_xfer_tp_x3(struct nouveau_grctx *ctx) ++nv50_graph_construct_xfer_tex(struct nouveau_grctx *ctx) + { + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); ++ xf_emit(ctx, 2, 0); /* 1 LINKED_TSC. yes, 2. */ ++ if (dev_priv->chipset != 0x50) ++ xf_emit(ctx, 1, 0); /* 3 */ ++ xf_emit(ctx, 1, 1); /* 1ffff BLIT_DU_DX_INT */ ++ xf_emit(ctx, 1, 0); /* fffff BLIT_DU_DX_FRACT */ ++ xf_emit(ctx, 1, 1); /* 1ffff BLIT_DV_DY_INT */ ++ xf_emit(ctx, 1, 0); /* fffff BLIT_DV_DY_FRACT */ + if (dev_priv->chipset == 0x50) +- xf_emit(ctx, 2, 0); ++ xf_emit(ctx, 1, 0); /* 3 BLIT_CONTROL */ + else +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 0x2a712488); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x4085c000); +- xf_emit(ctx, 1, 0x40); +- xf_emit(ctx, 1, 0x100); +- xf_emit(ctx, 1, 0x10100); +- xf_emit(ctx, 1, 0x02800000); ++ xf_emit(ctx, 2, 0); /* 3ff, 1 */ ++ xf_emit(ctx, 1, 0x2a712488); /* ffffffff SRC_TIC_0 */ ++ xf_emit(ctx, 1, 0); /* ffffffff SRC_TIC_1 */ ++ xf_emit(ctx, 1, 0x4085c000); /* ffffffff SRC_TIC_2 */ ++ xf_emit(ctx, 1, 0x40); /* ffffffff SRC_TIC_3 */ ++ xf_emit(ctx, 1, 0x100); /* ffffffff SRC_TIC_4 */ ++ xf_emit(ctx, 1, 0x10100); /* ffffffff SRC_TIC_5 */ ++ xf_emit(ctx, 1, 0x02800000); /* ffffffff SRC_TIC_6 */ ++ xf_emit(ctx, 1, 0); /* ffffffff SRC_TIC_7 */ ++ if (dev_priv->chipset == 0x50) { ++ xf_emit(ctx, 1, 0); /* 00000001 turing UNK358 */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34? */ ++ xf_emit(ctx, 1, 0); /* 00000003 turing UNK37C tesla UNK1690 */ ++ xf_emit(ctx, 1, 0); /* 00000003 BLIT_CONTROL */ ++ xf_emit(ctx, 1, 0); /* 00000001 turing UNK32C tesla UNK0F94 */ ++ } else if (!IS_NVAAF(dev_priv->chipset)) { ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34? */ ++ xf_emit(ctx, 1, 0); /* 00000003 */ ++ xf_emit(ctx, 1, 0); /* 000003ff */ ++ xf_emit(ctx, 1, 0); /* 00000003 */ ++ xf_emit(ctx, 1, 0); /* 000003ff */ ++ xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1664 / turing UNK03E8 */ ++ xf_emit(ctx, 1, 0); /* 00000003 */ ++ xf_emit(ctx, 1, 0); /* 000003ff */ ++ } else { ++ xf_emit(ctx, 0x6, 0); ++ } ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34 */ ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_TEXTURE */ ++ xf_emit(ctx, 1, 0); /* 0000ffff DMA_SRC */ + } + + static void +-nv50_graph_construct_xfer_tp_x4(struct nouveau_grctx *ctx) ++nv50_graph_construct_xfer_unk8cxx(struct nouveau_grctx *ctx) + { + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; +- xf_emit(ctx, 2, 0x04e3bfdf); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x00ffff00); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 2, 1); +- else +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 0x00ffff00); +- xf_emit(ctx, 8, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0x30201000); +- xf_emit(ctx, 1, 0x70605040); +- xf_emit(ctx, 1, 0xb8a89888); +- xf_emit(ctx, 1, 0xf8e8d8c8); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x1a); +-} +- +-static void +-nv50_graph_construct_xfer_tp_x5(struct nouveau_grctx *ctx) +-{ +- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 0xfac6881); +- xf_emit(ctx, 4, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 2, 1); +- xf_emit(ctx, 2, 0); +- xf_emit(ctx, 1, 1); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 0xb, 0); +- else +- xf_emit(ctx, 0xa, 0); +- xf_emit(ctx, 8, 1); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 7, 0); +- xf_emit(ctx, 1, 0xfac6881); +- xf_emit(ctx, 1, 0xf); +- xf_emit(ctx, 7, 0); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 1, 1); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { +- xf_emit(ctx, 6, 0); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 6, 0); +- } else { +- xf_emit(ctx, 0xb, 0); +- } ++ xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */ ++ xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 2, 0); /* 7, ffff0ff3 */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE */ ++ xf_emit(ctx, 1, 0x04e3bfdf); /* ffffffff UNK0D64 */ ++ xf_emit(ctx, 1, 0x04e3bfdf); /* ffffffff UNK0DF4 */ ++ xf_emit(ctx, 1, 1); /* 00000001 UNK15B4 */ ++ xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ ++ xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ ++ xf_emit(ctx, 1, 1); /* 00000001 tesla UNK0F98 */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ ++ xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1668 */ ++ xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ ++ xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ ++ xf_emit(ctx, 1, 0); /* 00000001 POLYGON_SMOOTH_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */ ++ xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1658 */ ++ xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ ++ xf_emit(ctx, 1, 0); /* ffff0ff3 */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE */ ++ xf_emit(ctx, 1, 1); /* 00000001 UNK15B4 */ ++ xf_emit(ctx, 1, 0); /* 00000001 POINT_SPRITE_ENABLE */ ++ xf_emit(ctx, 1, 1); /* 00000001 tesla UNK165C */ ++ xf_emit(ctx, 1, 0x30201000); /* ffffffff tesla UNK1670 */ ++ xf_emit(ctx, 1, 0x70605040); /* ffffffff tesla UNK1670 */ ++ xf_emit(ctx, 1, 0xb8a89888); /* ffffffff tesla UNK1670 */ ++ xf_emit(ctx, 1, 0xf8e8d8c8); /* ffffffff tesla UNK1670 */ ++ xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ ++ xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ + } + + static void +@@ -2193,108 +3102,136 @@ nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx) + { + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; + if (dev_priv->chipset < 0xa0) { +- nv50_graph_construct_xfer_tp_x1(ctx); +- nv50_graph_construct_xfer_tp_x2(ctx); +- nv50_graph_construct_xfer_tp_x3(ctx); +- if (dev_priv->chipset == 0x50) +- xf_emit(ctx, 0xf, 0); +- else +- xf_emit(ctx, 0x12, 0); +- nv50_graph_construct_xfer_tp_x4(ctx); ++ nv50_graph_construct_xfer_unk84xx(ctx); ++ nv50_graph_construct_xfer_tprop(ctx); ++ nv50_graph_construct_xfer_tex(ctx); ++ nv50_graph_construct_xfer_unk8cxx(ctx); + } else { +- nv50_graph_construct_xfer_tp_x3(ctx); +- if (dev_priv->chipset < 0xaa) +- xf_emit(ctx, 0xc, 0); +- else +- xf_emit(ctx, 0xa, 0); +- nv50_graph_construct_xfer_tp_x2(ctx); +- nv50_graph_construct_xfer_tp_x5(ctx); +- nv50_graph_construct_xfer_tp_x4(ctx); +- nv50_graph_construct_xfer_tp_x1(ctx); ++ nv50_graph_construct_xfer_tex(ctx); ++ nv50_graph_construct_xfer_tprop(ctx); ++ nv50_graph_construct_xfer_unk8cxx(ctx); ++ nv50_graph_construct_xfer_unk84xx(ctx); + } + } + + static void +-nv50_graph_construct_xfer_tp2(struct nouveau_grctx *ctx) ++nv50_graph_construct_xfer_mpc(struct nouveau_grctx *ctx) + { + struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; +- int i, mpcnt; +- if (dev_priv->chipset == 0x98 || dev_priv->chipset == 0xaa) +- mpcnt = 1; +- else if (dev_priv->chipset < 0xa0 || dev_priv->chipset >= 0xa8) +- mpcnt = 2; +- else +- mpcnt = 3; ++ int i, mpcnt = 2; ++ switch (dev_priv->chipset) { ++ case 0x98: ++ case 0xaa: ++ mpcnt = 1; ++ break; ++ case 0x50: ++ case 0x84: ++ case 0x86: ++ case 0x92: ++ case 0x94: ++ case 0x96: ++ case 0xa8: ++ case 0xac: ++ mpcnt = 2; ++ break; ++ case 0xa0: ++ case 0xa3: ++ case 0xa5: ++ case 0xaf: ++ mpcnt = 3; ++ break; ++ } + for (i = 0; i < mpcnt; i++) { +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x80); +- xf_emit(ctx, 1, 0x80007004); +- xf_emit(ctx, 1, 0x04000400); ++ xf_emit(ctx, 1, 0); /* ff */ ++ xf_emit(ctx, 1, 0x80); /* ffffffff tesla UNK1404 */ ++ xf_emit(ctx, 1, 0x80007004); /* ffffffff tesla UNK12B0 */ ++ xf_emit(ctx, 1, 0x04000400); /* ffffffff */ + if (dev_priv->chipset >= 0xa0) +- xf_emit(ctx, 1, 0xc0); +- xf_emit(ctx, 1, 0x1000); +- xf_emit(ctx, 2, 0); +- if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x98 || dev_priv->chipset >= 0xa8) { +- xf_emit(ctx, 1, 0xe00); +- xf_emit(ctx, 1, 0x1e00); ++ xf_emit(ctx, 1, 0xc0); /* 00007fff tesla UNK152C */ ++ xf_emit(ctx, 1, 0x1000); /* 0000ffff tesla UNK0D60 */ ++ xf_emit(ctx, 1, 0); /* ff/3ff */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ ++ if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x98 || dev_priv->chipset == 0xa8 || IS_NVAAF(dev_priv->chipset)) { ++ xf_emit(ctx, 1, 0xe00); /* 7fff */ ++ xf_emit(ctx, 1, 0x1e00); /* 7fff */ + } +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 2, 0); ++ xf_emit(ctx, 1, 1); /* 000000ff VP_REG_ALLOC_TEMP */ ++ xf_emit(ctx, 1, 0); /* 00000001 LINKED_TSC */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + if (dev_priv->chipset == 0x50) +- xf_emit(ctx, 2, 0x1000); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 2); +- if (dev_priv->chipset >= 0xaa) +- xf_emit(ctx, 0xb, 0); ++ xf_emit(ctx, 2, 0x1000); /* 7fff tesla UNK141C */ ++ xf_emit(ctx, 1, 1); /* 000000ff GP_REG_ALLOC_TEMP */ ++ xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ ++ xf_emit(ctx, 1, 4); /* 000000ff FP_REG_ALLOC_TEMP */ ++ xf_emit(ctx, 1, 2); /* 00000003 REG_MODE */ ++ if (IS_NVAAF(dev_priv->chipset)) ++ xf_emit(ctx, 0xb, 0); /* RO */ + else if (dev_priv->chipset >= 0xa0) +- xf_emit(ctx, 0xc, 0); ++ xf_emit(ctx, 0xc, 0); /* RO */ + else +- xf_emit(ctx, 0xa, 0); ++ xf_emit(ctx, 0xa, 0); /* RO */ + } +- xf_emit(ctx, 1, 0x08100c12); +- xf_emit(ctx, 1, 0); ++ xf_emit(ctx, 1, 0x08100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ ++ xf_emit(ctx, 1, 0); /* ff/3ff */ + if (dev_priv->chipset >= 0xa0) { +- xf_emit(ctx, 1, 0x1fe21); ++ xf_emit(ctx, 1, 0x1fe21); /* 0003ffff tesla UNK0FAC */ + } +- xf_emit(ctx, 5, 0); +- xf_emit(ctx, 4, 0xffff); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 2, 0x10001); +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 0x1fe21); +- xf_emit(ctx, 1, 0); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 1, 1); +- xf_emit(ctx, 4, 0); +- xf_emit(ctx, 1, 0x08100c12); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 8, 0); +- xf_emit(ctx, 1, 0xfac6881); +- xf_emit(ctx, 1, 0); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) +- xf_emit(ctx, 1, 3); +- xf_emit(ctx, 3, 0); +- xf_emit(ctx, 1, 4); +- xf_emit(ctx, 9, 0); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 2, 1); +- xf_emit(ctx, 1, 2); +- xf_emit(ctx, 3, 1); +- xf_emit(ctx, 1, 0); +- if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { +- xf_emit(ctx, 8, 2); +- xf_emit(ctx, 0x10, 1); +- xf_emit(ctx, 8, 2); +- xf_emit(ctx, 0x18, 1); +- xf_emit(ctx, 3, 0); ++ xf_emit(ctx, 3, 0); /* 7fff, 0, 0 */ ++ xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ ++ xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ ++ xf_emit(ctx, 4, 0xffff); /* 0000ffff MSAA_MASK */ ++ xf_emit(ctx, 1, 1); /* 00000001 LANES32 */ ++ xf_emit(ctx, 1, 0x10001); /* 00ffffff BLOCK_ALLOC */ ++ xf_emit(ctx, 1, 0x10001); /* ffffffff BLOCKDIM_XY */ ++ xf_emit(ctx, 1, 1); /* 0000ffff BLOCKDIM_Z */ ++ xf_emit(ctx, 1, 0); /* ffffffff SHARED_SIZE */ ++ xf_emit(ctx, 1, 0x1fe21); /* 1ffff/3ffff[NVA0+] tesla UNk0FAC */ ++ xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34 */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ ++ xf_emit(ctx, 1, 0); /* ff/3ff */ ++ xf_emit(ctx, 1, 0); /* 1 LINKED_TSC */ ++ xf_emit(ctx, 1, 0); /* ff FP_ADDRESS_HIGH */ ++ xf_emit(ctx, 1, 0); /* ffffffff FP_ADDRESS_LOW */ ++ xf_emit(ctx, 1, 0x08100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ ++ xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ ++ xf_emit(ctx, 1, 0); /* 000000ff FRAG_COLOR_CLAMP_EN */ ++ xf_emit(ctx, 1, 2); /* 00000003 REG_MODE */ ++ xf_emit(ctx, 1, 0x11); /* 0000007f RT_FORMAT */ ++ xf_emit(ctx, 7, 0); /* 0000007f RT_FORMAT */ ++ xf_emit(ctx, 1, 0); /* 00000007 */ ++ xf_emit(ctx, 1, 0xfac6881); /* 0fffffff RT_CONTROL */ ++ xf_emit(ctx, 1, 0); /* 00000003 MULTISAMPLE_CTRL */ ++ if (IS_NVA3F(dev_priv->chipset)) ++ xf_emit(ctx, 1, 3); /* 00000003 tesla UNK16B4 */ ++ xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */ ++ xf_emit(ctx, 1, 0); /* 00000001 FRAMEBUFFER_SRGB */ ++ xf_emit(ctx, 1, 4); /* ffffffff tesla UNK1400 */ ++ xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ ++ xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ ++ xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ ++ xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ ++ xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_RGB */ ++ xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ ++ xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ ++ xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_ALPHA */ ++ xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ ++ if (IS_NVA3F(dev_priv->chipset)) { ++ xf_emit(ctx, 1, 0); /* 00000001 UNK12E4 */ ++ xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_RGB */ ++ xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_RGB */ ++ xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */ ++ xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_ALPHA */ ++ xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_ALPHA */ ++ xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_ALPHA */ ++ xf_emit(ctx, 8, 1); /* 00000001 IBLEND_UNK00 */ ++ xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1928 */ ++ xf_emit(ctx, 1, 0); /* 00000001 UNK1140 */ + } +- xf_emit(ctx, 1, 4); ++ xf_emit(ctx, 1, 0); /* 00000003 tesla UNK0F90 */ ++ xf_emit(ctx, 1, 4); /* 000000ff FP_RESULT_COUNT */ ++ /* XXX: demagic this part some day */ + if (dev_priv->chipset == 0x50) + xf_emit(ctx, 0x3a0, 0); + else if (dev_priv->chipset < 0x94) +@@ -2303,9 +3240,9 @@ nv50_graph_construct_xfer_tp2(struct nouveau_grctx *ctx) + xf_emit(ctx, 0x39f, 0); + else + xf_emit(ctx, 0x3a3, 0); +- xf_emit(ctx, 1, 0x11); +- xf_emit(ctx, 1, 0); +- xf_emit(ctx, 1, 1); ++ xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ ++ xf_emit(ctx, 1, 0); /* 7 OPERATION */ ++ xf_emit(ctx, 1, 1); /* 1 DST_LINEAR */ + xf_emit(ctx, 0x2d, 0); + } + +@@ -2323,52 +3260,56 @@ nv50_graph_construct_xfer2(struct nouveau_grctx *ctx) + if (dev_priv->chipset < 0xa0) { + for (i = 0; i < 8; i++) { + ctx->ctxvals_pos = offset + i; ++ /* that little bugger belongs to csched. No idea ++ * what it's doing here. */ + if (i == 0) +- xf_emit(ctx, 1, 0x08100c12); ++ xf_emit(ctx, 1, 0x08100c12); /* FP_INTERPOLANT_CTRL */ + if (units & (1 << i)) +- nv50_graph_construct_xfer_tp2(ctx); ++ nv50_graph_construct_xfer_mpc(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + } + } else { + /* Strand 0: TPs 0, 1 */ + ctx->ctxvals_pos = offset; +- xf_emit(ctx, 1, 0x08100c12); ++ /* that little bugger belongs to csched. No idea ++ * what it's doing here. */ ++ xf_emit(ctx, 1, 0x08100c12); /* FP_INTERPOLANT_CTRL */ + if (units & (1 << 0)) +- nv50_graph_construct_xfer_tp2(ctx); ++ nv50_graph_construct_xfer_mpc(ctx); + if (units & (1 << 1)) +- nv50_graph_construct_xfer_tp2(ctx); ++ nv50_graph_construct_xfer_mpc(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + +- /* Strand 0: TPs 2, 3 */ ++ /* Strand 1: TPs 2, 3 */ + ctx->ctxvals_pos = offset + 1; + if (units & (1 << 2)) +- nv50_graph_construct_xfer_tp2(ctx); ++ nv50_graph_construct_xfer_mpc(ctx); + if (units & (1 << 3)) +- nv50_graph_construct_xfer_tp2(ctx); ++ nv50_graph_construct_xfer_mpc(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + +- /* Strand 0: TPs 4, 5, 6 */ ++ /* Strand 2: TPs 4, 5, 6 */ + ctx->ctxvals_pos = offset + 2; + if (units & (1 << 4)) +- nv50_graph_construct_xfer_tp2(ctx); ++ nv50_graph_construct_xfer_mpc(ctx); + if (units & (1 << 5)) +- nv50_graph_construct_xfer_tp2(ctx); ++ nv50_graph_construct_xfer_mpc(ctx); + if (units & (1 << 6)) +- nv50_graph_construct_xfer_tp2(ctx); ++ nv50_graph_construct_xfer_mpc(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + +- /* Strand 0: TPs 7, 8, 9 */ ++ /* Strand 3: TPs 7, 8, 9 */ + ctx->ctxvals_pos = offset + 3; + if (units & (1 << 7)) +- nv50_graph_construct_xfer_tp2(ctx); ++ nv50_graph_construct_xfer_mpc(ctx); + if (units & (1 << 8)) +- nv50_graph_construct_xfer_tp2(ctx); ++ nv50_graph_construct_xfer_mpc(ctx); + if (units & (1 << 9)) +- nv50_graph_construct_xfer_tp2(ctx); ++ nv50_graph_construct_xfer_mpc(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + } +diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c +index 5f21df3..ac3de05 100644 +--- a/drivers/gpu/drm/nouveau/nv50_instmem.c ++++ b/drivers/gpu/drm/nouveau/nv50_instmem.c +@@ -32,41 +32,87 @@ + struct nv50_instmem_priv { + uint32_t save1700[5]; /* 0x1700->0x1710 */ + +- struct nouveau_gpuobj_ref *pramin_pt; +- struct nouveau_gpuobj_ref *pramin_bar; +- struct nouveau_gpuobj_ref *fb_bar; +- +- bool last_access_wr; ++ struct nouveau_gpuobj *pramin_pt; ++ struct nouveau_gpuobj *pramin_bar; ++ struct nouveau_gpuobj *fb_bar; + }; + +-#define NV50_INSTMEM_PAGE_SHIFT 12 +-#define NV50_INSTMEM_PAGE_SIZE (1 << NV50_INSTMEM_PAGE_SHIFT) +-#define NV50_INSTMEM_PT_SIZE(a) (((a) >> 12) << 3) ++static void ++nv50_channel_del(struct nouveau_channel **pchan) ++{ ++ struct nouveau_channel *chan; + +-/*NOTE: - Assumes 0x1700 already covers the correct MiB of PRAMIN +- */ +-#define BAR0_WI32(g, o, v) do { \ +- uint32_t offset; \ +- if ((g)->im_backing) { \ +- offset = (g)->im_backing_start; \ +- } else { \ +- offset = chan->ramin->gpuobj->im_backing_start; \ +- offset += (g)->im_pramin->start; \ +- } \ +- offset += (o); \ +- nv_wr32(dev, NV_RAMIN + (offset & 0xfffff), (v)); \ +-} while (0) ++ chan = *pchan; ++ *pchan = NULL; ++ if (!chan) ++ return; ++ ++ nouveau_gpuobj_ref(NULL, &chan->ramfc); ++ nouveau_gpuobj_ref(NULL, &chan->vm_pd); ++ if (chan->ramin_heap.fl_entry.next) ++ drm_mm_takedown(&chan->ramin_heap); ++ nouveau_gpuobj_ref(NULL, &chan->ramin); ++ kfree(chan); ++} ++ ++static int ++nv50_channel_new(struct drm_device *dev, u32 size, ++ struct nouveau_channel **pchan) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ u32 pgd = (dev_priv->chipset == 0x50) ? 0x1400 : 0x0200; ++ u32 fc = (dev_priv->chipset == 0x50) ? 0x0000 : 0x4200; ++ struct nouveau_channel *chan; ++ int ret; ++ ++ chan = kzalloc(sizeof(*chan), GFP_KERNEL); ++ if (!chan) ++ return -ENOMEM; ++ chan->dev = dev; ++ ++ ret = nouveau_gpuobj_new(dev, NULL, size, 0x1000, 0, &chan->ramin); ++ if (ret) { ++ nv50_channel_del(&chan); ++ return ret; ++ } ++ ++ ret = drm_mm_init(&chan->ramin_heap, 0x6000, chan->ramin->size); ++ if (ret) { ++ nv50_channel_del(&chan); ++ return ret; ++ } ++ ++ ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst == ~0 ? ~0 : ++ chan->ramin->pinst + pgd, ++ chan->ramin->vinst + pgd, ++ 0x4000, NVOBJ_FLAG_ZERO_ALLOC, ++ &chan->vm_pd); ++ if (ret) { ++ nv50_channel_del(&chan); ++ return ret; ++ } ++ ++ ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst == ~0 ? ~0 : ++ chan->ramin->pinst + fc, ++ chan->ramin->vinst + fc, 0x100, ++ NVOBJ_FLAG_ZERO_ALLOC, &chan->ramfc); ++ if (ret) { ++ nv50_channel_del(&chan); ++ return ret; ++ } ++ ++ *pchan = chan; ++ return 0; ++} + + int + nv50_instmem_init(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nouveau_channel *chan; +- uint32_t c_offset, c_size, c_ramfc, c_vmpd, c_base, pt_size; +- uint32_t save_nv001700; +- uint64_t v; + struct nv50_instmem_priv *priv; ++ struct nouveau_channel *chan; + int ret, i; ++ u32 tmp; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) +@@ -77,215 +123,115 @@ nv50_instmem_init(struct drm_device *dev) + for (i = 0x1700; i <= 0x1710; i += 4) + priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i); + +- /* Reserve the last MiB of VRAM, we should probably try to avoid +- * setting up the below tables over the top of the VBIOS image at +- * some point. +- */ +- dev_priv->ramin_rsvd_vram = 1 << 20; +- c_offset = dev_priv->vram_size - dev_priv->ramin_rsvd_vram; +- c_size = 128 << 10; +- c_vmpd = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x1400 : 0x200; +- c_ramfc = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x0 : 0x20; +- c_base = c_vmpd + 0x4000; +- pt_size = NV50_INSTMEM_PT_SIZE(dev_priv->ramin_size); +- +- NV_DEBUG(dev, " Rsvd VRAM base: 0x%08x\n", c_offset); +- NV_DEBUG(dev, " VBIOS image: 0x%08x\n", +- (nv_rd32(dev, 0x619f04) & ~0xff) << 8); +- NV_DEBUG(dev, " Aperture size: %d MiB\n", dev_priv->ramin_size >> 20); +- NV_DEBUG(dev, " PT size: %d KiB\n", pt_size >> 10); +- +- /* Determine VM layout, we need to do this first to make sure +- * we allocate enough memory for all the page tables. +- */ +- dev_priv->vm_gart_base = roundup(NV50_VM_BLOCK, NV50_VM_BLOCK); +- dev_priv->vm_gart_size = NV50_VM_BLOCK; +- +- dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size; +- dev_priv->vm_vram_size = dev_priv->vram_size; +- if (dev_priv->vm_vram_size > NV50_VM_MAX_VRAM) +- dev_priv->vm_vram_size = NV50_VM_MAX_VRAM; +- dev_priv->vm_vram_size = roundup(dev_priv->vm_vram_size, NV50_VM_BLOCK); +- dev_priv->vm_vram_pt_nr = dev_priv->vm_vram_size / NV50_VM_BLOCK; +- +- dev_priv->vm_end = dev_priv->vm_vram_base + dev_priv->vm_vram_size; +- +- NV_DEBUG(dev, "NV50VM: GART 0x%016llx-0x%016llx\n", +- dev_priv->vm_gart_base, +- dev_priv->vm_gart_base + dev_priv->vm_gart_size - 1); +- NV_DEBUG(dev, "NV50VM: VRAM 0x%016llx-0x%016llx\n", +- dev_priv->vm_vram_base, +- dev_priv->vm_vram_base + dev_priv->vm_vram_size - 1); +- +- c_size += dev_priv->vm_vram_pt_nr * (NV50_VM_BLOCK / 65536 * 8); +- +- /* Map BAR0 PRAMIN aperture over the memory we want to use */ +- save_nv001700 = nv_rd32(dev, NV50_PUNK_BAR0_PRAMIN); +- nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, (c_offset >> 16)); +- +- /* Create a fake channel, and use it as our "dummy" channels 0/127. +- * The main reason for creating a channel is so we can use the gpuobj +- * code. However, it's probably worth noting that NVIDIA also setup +- * their channels 0/127 with the same values they configure here. +- * So, there may be some other reason for doing this. +- * +- * Have to create the entire channel manually, as the real channel +- * creation code assumes we have PRAMIN access, and we don't until +- * we're done here. +- */ +- chan = kzalloc(sizeof(*chan), GFP_KERNEL); +- if (!chan) ++ /* Global PRAMIN heap */ ++ ret = drm_mm_init(&dev_priv->ramin_heap, 0, dev_priv->ramin_size); ++ if (ret) { ++ NV_ERROR(dev, "Failed to init RAMIN heap\n"); + return -ENOMEM; +- chan->id = 0; +- chan->dev = dev; +- chan->file_priv = (struct drm_file *)-2; +- dev_priv->fifos[0] = dev_priv->fifos[127] = chan; ++ } + +- /* Channel's PRAMIN object + heap */ +- ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, c_size, 0, +- NULL, &chan->ramin); ++ /* we need a channel to plug into the hw to control the BARs */ ++ ret = nv50_channel_new(dev, 128*1024, &dev_priv->fifos[0]); + if (ret) + return ret; ++ chan = dev_priv->fifos[127] = dev_priv->fifos[0]; + +- if (nouveau_mem_init_heap(&chan->ramin_heap, c_base, c_size - c_base)) +- return -ENOMEM; +- +- /* RAMFC + zero channel's PRAMIN up to start of VM pagedir */ +- ret = nouveau_gpuobj_new_fake(dev, c_ramfc, c_offset + c_ramfc, +- 0x4000, 0, NULL, &chan->ramfc); ++ /* allocate page table for PRAMIN BAR */ ++ ret = nouveau_gpuobj_new(dev, chan, (dev_priv->ramin_size >> 12) * 8, ++ 0x1000, NVOBJ_FLAG_ZERO_ALLOC, ++ &priv->pramin_pt); + if (ret) + return ret; + +- for (i = 0; i < c_vmpd; i += 4) +- BAR0_WI32(chan->ramin->gpuobj, i, 0); ++ nv_wo32(chan->vm_pd, 0x0000, priv->pramin_pt->vinst | 0x63); ++ nv_wo32(chan->vm_pd, 0x0004, 0); + +- /* VM page directory */ +- ret = nouveau_gpuobj_new_fake(dev, c_vmpd, c_offset + c_vmpd, +- 0x4000, 0, &chan->vm_pd, NULL); ++ /* DMA object for PRAMIN BAR */ ++ ret = nouveau_gpuobj_new(dev, chan, 6*4, 16, 0, &priv->pramin_bar); + if (ret) + return ret; +- for (i = 0; i < 0x4000; i += 8) { +- BAR0_WI32(chan->vm_pd, i + 0x00, 0x00000000); +- BAR0_WI32(chan->vm_pd, i + 0x04, 0x00000000); +- } +- +- /* PRAMIN page table, cheat and map into VM at 0x0000000000. +- * We map the entire fake channel into the start of the PRAMIN BAR +- */ +- ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pt_size, 0x1000, +- 0, &priv->pramin_pt); ++ nv_wo32(priv->pramin_bar, 0x00, 0x7fc00000); ++ nv_wo32(priv->pramin_bar, 0x04, dev_priv->ramin_size - 1); ++ nv_wo32(priv->pramin_bar, 0x08, 0x00000000); ++ nv_wo32(priv->pramin_bar, 0x0c, 0x00000000); ++ nv_wo32(priv->pramin_bar, 0x10, 0x00000000); ++ nv_wo32(priv->pramin_bar, 0x14, 0x00000000); ++ ++ /* map channel into PRAMIN, gpuobj didn't do it for us */ ++ ret = nv50_instmem_bind(dev, chan->ramin); + if (ret) + return ret; + +- v = c_offset | 1; +- if (dev_priv->vram_sys_base) { +- v += dev_priv->vram_sys_base; +- v |= 0x30; +- } ++ /* poke regs... */ ++ nv_wr32(dev, 0x001704, 0x00000000 | (chan->ramin->vinst >> 12)); ++ nv_wr32(dev, 0x001704, 0x40000000 | (chan->ramin->vinst >> 12)); ++ nv_wr32(dev, 0x00170c, 0x80000000 | (priv->pramin_bar->cinst >> 4)); + +- i = 0; +- while (v < dev_priv->vram_sys_base + c_offset + c_size) { +- BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, lower_32_bits(v)); +- BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, upper_32_bits(v)); +- v += 0x1000; +- i += 8; ++ tmp = nv_ri32(dev, 0); ++ nv_wi32(dev, 0, ~tmp); ++ if (nv_ri32(dev, 0) != ~tmp) { ++ NV_ERROR(dev, "PRAMIN readback failed\n"); ++ return -EIO; + } ++ nv_wi32(dev, 0, tmp); + +- while (i < pt_size) { +- BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, 0x00000000); +- BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000); +- i += 8; +- } ++ dev_priv->ramin_available = true; ++ ++ /* Determine VM layout */ ++ dev_priv->vm_gart_base = roundup(NV50_VM_BLOCK, NV50_VM_BLOCK); ++ dev_priv->vm_gart_size = NV50_VM_BLOCK; ++ ++ dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size; ++ dev_priv->vm_vram_size = dev_priv->vram_size; ++ if (dev_priv->vm_vram_size > NV50_VM_MAX_VRAM) ++ dev_priv->vm_vram_size = NV50_VM_MAX_VRAM; ++ dev_priv->vm_vram_size = roundup(dev_priv->vm_vram_size, NV50_VM_BLOCK); ++ dev_priv->vm_vram_pt_nr = dev_priv->vm_vram_size / NV50_VM_BLOCK; ++ ++ dev_priv->vm_end = dev_priv->vm_vram_base + dev_priv->vm_vram_size; + +- BAR0_WI32(chan->vm_pd, 0x00, priv->pramin_pt->instance | 0x63); +- BAR0_WI32(chan->vm_pd, 0x04, 0x00000000); ++ NV_DEBUG(dev, "NV50VM: GART 0x%016llx-0x%016llx\n", ++ dev_priv->vm_gart_base, ++ dev_priv->vm_gart_base + dev_priv->vm_gart_size - 1); ++ NV_DEBUG(dev, "NV50VM: VRAM 0x%016llx-0x%016llx\n", ++ dev_priv->vm_vram_base, ++ dev_priv->vm_vram_base + dev_priv->vm_vram_size - 1); + + /* VRAM page table(s), mapped into VM at +1GiB */ + for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) { +- ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, +- NV50_VM_BLOCK/65536*8, 0, 0, +- &chan->vm_vram_pt[i]); ++ ret = nouveau_gpuobj_new(dev, NULL, NV50_VM_BLOCK / 0x10000 * 8, ++ 0, NVOBJ_FLAG_ZERO_ALLOC, ++ &chan->vm_vram_pt[i]); + if (ret) { +- NV_ERROR(dev, "Error creating VRAM page tables: %d\n", +- ret); ++ NV_ERROR(dev, "Error creating VRAM PGT: %d\n", ret); + dev_priv->vm_vram_pt_nr = i; + return ret; + } +- dev_priv->vm_vram_pt[i] = chan->vm_vram_pt[i]->gpuobj; +- +- for (v = 0; v < dev_priv->vm_vram_pt[i]->im_pramin->size; +- v += 4) +- BAR0_WI32(dev_priv->vm_vram_pt[i], v, 0); ++ dev_priv->vm_vram_pt[i] = chan->vm_vram_pt[i]; + +- BAR0_WI32(chan->vm_pd, 0x10 + (i*8), +- chan->vm_vram_pt[i]->instance | 0x61); +- BAR0_WI32(chan->vm_pd, 0x14 + (i*8), 0); ++ nv_wo32(chan->vm_pd, 0x10 + (i*8), ++ chan->vm_vram_pt[i]->vinst | 0x61); ++ nv_wo32(chan->vm_pd, 0x14 + (i*8), 0); + } + +- /* DMA object for PRAMIN BAR */ +- ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 6*4, 16, 0, +- &priv->pramin_bar); +- if (ret) +- return ret; +- BAR0_WI32(priv->pramin_bar->gpuobj, 0x00, 0x7fc00000); +- BAR0_WI32(priv->pramin_bar->gpuobj, 0x04, dev_priv->ramin_size - 1); +- BAR0_WI32(priv->pramin_bar->gpuobj, 0x08, 0x00000000); +- BAR0_WI32(priv->pramin_bar->gpuobj, 0x0c, 0x00000000); +- BAR0_WI32(priv->pramin_bar->gpuobj, 0x10, 0x00000000); +- BAR0_WI32(priv->pramin_bar->gpuobj, 0x14, 0x00000000); +- + /* DMA object for FB BAR */ +- ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 6*4, 16, 0, +- &priv->fb_bar); ++ ret = nouveau_gpuobj_new(dev, chan, 6*4, 16, 0, &priv->fb_bar); + if (ret) + return ret; +- BAR0_WI32(priv->fb_bar->gpuobj, 0x00, 0x7fc00000); +- BAR0_WI32(priv->fb_bar->gpuobj, 0x04, 0x40000000 + +- drm_get_resource_len(dev, 1) - 1); +- BAR0_WI32(priv->fb_bar->gpuobj, 0x08, 0x40000000); +- BAR0_WI32(priv->fb_bar->gpuobj, 0x0c, 0x00000000); +- BAR0_WI32(priv->fb_bar->gpuobj, 0x10, 0x00000000); +- BAR0_WI32(priv->fb_bar->gpuobj, 0x14, 0x00000000); ++ nv_wo32(priv->fb_bar, 0x00, 0x7fc00000); ++ nv_wo32(priv->fb_bar, 0x04, 0x40000000 + ++ pci_resource_len(dev->pdev, 1) - 1); ++ nv_wo32(priv->fb_bar, 0x08, 0x40000000); ++ nv_wo32(priv->fb_bar, 0x0c, 0x00000000); ++ nv_wo32(priv->fb_bar, 0x10, 0x00000000); ++ nv_wo32(priv->fb_bar, 0x14, 0x00000000); + +- /* Poke the relevant regs, and pray it works :) */ +- nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12)); +- nv_wr32(dev, NV50_PUNK_UNK1710, 0); +- nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12) | +- NV50_PUNK_BAR_CFG_BASE_VALID); +- nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->fb_bar->instance >> 4) | +- NV50_PUNK_BAR1_CTXDMA_VALID); +- nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->instance >> 4) | +- NV50_PUNK_BAR3_CTXDMA_VALID); ++ dev_priv->engine.instmem.flush(dev); + ++ nv_wr32(dev, 0x001708, 0x80000000 | (priv->fb_bar->cinst >> 4)); + for (i = 0; i < 8; i++) + nv_wr32(dev, 0x1900 + (i*4), 0); + +- /* Assume that praying isn't enough, check that we can re-read the +- * entire fake channel back from the PRAMIN BAR */ +- dev_priv->engine.instmem.prepare_access(dev, false); +- for (i = 0; i < c_size; i += 4) { +- if (nv_rd32(dev, NV_RAMIN + i) != nv_ri32(dev, i)) { +- NV_ERROR(dev, "Error reading back PRAMIN at 0x%08x\n", +- i); +- dev_priv->engine.instmem.finish_access(dev); +- return -EINVAL; +- } +- } +- dev_priv->engine.instmem.finish_access(dev); +- +- nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, save_nv001700); +- +- /* Global PRAMIN heap */ +- if (nouveau_mem_init_heap(&dev_priv->ramin_heap, +- c_size, dev_priv->ramin_size - c_size)) { +- dev_priv->ramin_heap = NULL; +- NV_ERROR(dev, "Failed to init RAMIN heap\n"); +- } +- +- /*XXX: incorrect, but needed to make hash func "work" */ +- dev_priv->ramht_offset = 0x10000; +- dev_priv->ramht_bits = 9; +- dev_priv->ramht_size = (1 << dev_priv->ramht_bits); + return 0; + } + +@@ -302,29 +248,24 @@ nv50_instmem_takedown(struct drm_device *dev) + if (!priv) + return; + ++ dev_priv->ramin_available = false; ++ + /* Restore state from before init */ + for (i = 0x1700; i <= 0x1710; i += 4) + nv_wr32(dev, i, priv->save1700[(i - 0x1700) / 4]); + +- nouveau_gpuobj_ref_del(dev, &priv->fb_bar); +- nouveau_gpuobj_ref_del(dev, &priv->pramin_bar); +- nouveau_gpuobj_ref_del(dev, &priv->pramin_pt); ++ nouveau_gpuobj_ref(NULL, &priv->fb_bar); ++ nouveau_gpuobj_ref(NULL, &priv->pramin_bar); ++ nouveau_gpuobj_ref(NULL, &priv->pramin_pt); + + /* Destroy dummy channel */ + if (chan) { +- for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) { +- nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]); +- dev_priv->vm_vram_pt[i] = NULL; +- } ++ for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) ++ nouveau_gpuobj_ref(NULL, &chan->vm_vram_pt[i]); + dev_priv->vm_vram_pt_nr = 0; + +- nouveau_gpuobj_del(dev, &chan->vm_pd); +- nouveau_gpuobj_ref_del(dev, &chan->ramfc); +- nouveau_gpuobj_ref_del(dev, &chan->ramin); +- nouveau_mem_takedown(&chan->ramin_heap); +- +- dev_priv->fifos[0] = dev_priv->fifos[127] = NULL; +- kfree(chan); ++ nv50_channel_del(&dev_priv->fifos[0]); ++ dev_priv->fifos[127] = NULL; + } + + dev_priv->engine.instmem.priv = NULL; +@@ -336,14 +277,14 @@ nv50_instmem_suspend(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan = dev_priv->fifos[0]; +- struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; ++ struct nouveau_gpuobj *ramin = chan->ramin; + int i; + +- ramin->im_backing_suspend = vmalloc(ramin->im_pramin->size); ++ ramin->im_backing_suspend = vmalloc(ramin->size); + if (!ramin->im_backing_suspend) + return -ENOMEM; + +- for (i = 0; i < ramin->im_pramin->size; i += 4) ++ for (i = 0; i < ramin->size; i += 4) + ramin->im_backing_suspend[i/4] = nv_ri32(dev, i); + return 0; + } +@@ -354,23 +295,25 @@ nv50_instmem_resume(struct drm_device *dev) + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; + struct nouveau_channel *chan = dev_priv->fifos[0]; +- struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; ++ struct nouveau_gpuobj *ramin = chan->ramin; + int i; + +- nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, (ramin->im_backing_start >> 16)); +- for (i = 0; i < ramin->im_pramin->size; i += 4) +- BAR0_WI32(ramin, i, ramin->im_backing_suspend[i/4]); ++ dev_priv->ramin_available = false; ++ dev_priv->ramin_base = ~0; ++ for (i = 0; i < ramin->size; i += 4) ++ nv_wo32(ramin, i, ramin->im_backing_suspend[i/4]); ++ dev_priv->ramin_available = true; + vfree(ramin->im_backing_suspend); + ramin->im_backing_suspend = NULL; + + /* Poke the relevant regs, and pray it works :) */ +- nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12)); ++ nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12)); + nv_wr32(dev, NV50_PUNK_UNK1710, 0); +- nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12) | ++ nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12) | + NV50_PUNK_BAR_CFG_BASE_VALID); +- nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->fb_bar->instance >> 4) | ++ nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->fb_bar->cinst >> 4) | + NV50_PUNK_BAR1_CTXDMA_VALID); +- nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->instance >> 4) | ++ nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->cinst >> 4) | + NV50_PUNK_BAR3_CTXDMA_VALID); + + for (i = 0; i < 8; i++) +@@ -386,7 +329,7 @@ nv50_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, + if (gpuobj->im_backing) + return -EINVAL; + +- *sz = ALIGN(*sz, NV50_INSTMEM_PAGE_SIZE); ++ *sz = ALIGN(*sz, 4096); + if (*sz == 0) + return -EINVAL; + +@@ -404,9 +347,7 @@ nv50_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, + return ret; + } + +- gpuobj->im_backing_start = gpuobj->im_backing->bo.mem.mm_node->start; +- gpuobj->im_backing_start <<= PAGE_SHIFT; +- ++ gpuobj->vinst = gpuobj->im_backing->bo.mem.mm_node->start << PAGE_SHIFT; + return 0; + } + +@@ -429,23 +370,23 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; +- struct nouveau_gpuobj *pramin_pt = priv->pramin_pt->gpuobj; ++ struct nouveau_gpuobj *pramin_pt = priv->pramin_pt; + uint32_t pte, pte_end; + uint64_t vram; + + if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound) + return -EINVAL; + +- NV_DEBUG(dev, "st=0x%0llx sz=0x%0llx\n", ++ NV_DEBUG(dev, "st=0x%lx sz=0x%lx\n", + gpuobj->im_pramin->start, gpuobj->im_pramin->size); + + pte = (gpuobj->im_pramin->start >> 12) << 1; + pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; +- vram = gpuobj->im_backing_start; ++ vram = gpuobj->vinst; + +- NV_DEBUG(dev, "pramin=0x%llx, pte=%d, pte_end=%d\n", ++ NV_DEBUG(dev, "pramin=0x%lx, pte=%d, pte_end=%d\n", + gpuobj->im_pramin->start, pte, pte_end); +- NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start); ++ NV_DEBUG(dev, "first vram page: 0x%010llx\n", gpuobj->vinst); + + vram |= 1; + if (dev_priv->vram_sys_base) { +@@ -453,27 +394,16 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) + vram |= 0x30; + } + +- dev_priv->engine.instmem.prepare_access(dev, true); + while (pte < pte_end) { +- nv_wo32(dev, pramin_pt, pte++, lower_32_bits(vram)); +- nv_wo32(dev, pramin_pt, pte++, upper_32_bits(vram)); +- vram += NV50_INSTMEM_PAGE_SIZE; +- } +- dev_priv->engine.instmem.finish_access(dev); +- +- nv_wr32(dev, 0x100c80, 0x00040001); +- if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +- NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (1)\n"); +- NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); +- return -EBUSY; ++ nv_wo32(pramin_pt, (pte * 4) + 0, lower_32_bits(vram)); ++ nv_wo32(pramin_pt, (pte * 4) + 4, upper_32_bits(vram)); ++ vram += 0x1000; ++ pte += 2; + } ++ dev_priv->engine.instmem.flush(dev); + +- nv_wr32(dev, 0x100c80, 0x00060001); +- if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +- NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +- NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); +- return -EBUSY; +- } ++ nv50_vm_flush(dev, 4); ++ nv50_vm_flush(dev, 6); + + gpuobj->im_bound = 1; + return 0; +@@ -489,39 +419,44 @@ nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) + if (gpuobj->im_bound == 0) + return -EINVAL; + ++ /* can happen during late takedown */ ++ if (unlikely(!dev_priv->ramin_available)) ++ return 0; ++ + pte = (gpuobj->im_pramin->start >> 12) << 1; + pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; + +- dev_priv->engine.instmem.prepare_access(dev, true); + while (pte < pte_end) { +- nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000); +- nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000); ++ nv_wo32(priv->pramin_pt, (pte * 4) + 0, 0x00000000); ++ nv_wo32(priv->pramin_pt, (pte * 4) + 4, 0x00000000); ++ pte += 2; + } +- dev_priv->engine.instmem.finish_access(dev); ++ dev_priv->engine.instmem.flush(dev); + + gpuobj->im_bound = 0; + return 0; + } + + void +-nv50_instmem_prepare_access(struct drm_device *dev, bool write) ++nv50_instmem_flush(struct drm_device *dev) + { +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; +- +- priv->last_access_wr = write; ++ nv_wr32(dev, 0x00330c, 0x00000001); ++ if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) ++ NV_ERROR(dev, "PRAMIN flush timeout\n"); + } + + void +-nv50_instmem_finish_access(struct drm_device *dev) ++nv84_instmem_flush(struct drm_device *dev) + { +- struct drm_nouveau_private *dev_priv = dev->dev_private; +- struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; +- +- if (priv->last_access_wr) { +- nv_wr32(dev, 0x070000, 0x00000001); +- if (!nv_wait(0x070000, 0x00000001, 0x00000000)) +- NV_ERROR(dev, "PRAMIN flush timeout\n"); +- } ++ nv_wr32(dev, 0x070000, 0x00000001); ++ if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) ++ NV_ERROR(dev, "PRAMIN flush timeout\n"); + } + ++void ++nv50_vm_flush(struct drm_device *dev, int engine) ++{ ++ nv_wr32(dev, 0x100c80, (engine << 16) | 1); ++ if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) ++ NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); ++} +diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c +index 812778d..b4a5ecb 100644 +--- a/drivers/gpu/drm/nouveau/nv50_sor.c ++++ b/drivers/gpu/drm/nouveau/nv50_sor.c +@@ -37,52 +37,32 @@ + #include "nv50_display.h" + + static void +-nv50_sor_disconnect(struct nouveau_encoder *nv_encoder) ++nv50_sor_disconnect(struct drm_encoder *encoder) + { +- struct drm_device *dev = to_drm_encoder(nv_encoder)->dev; ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_device *dev = encoder->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *evo = dev_priv->evo; + int ret; + ++ if (!nv_encoder->crtc) ++ return; ++ nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true); ++ + NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or); + +- ret = RING_SPACE(evo, 2); ++ ret = RING_SPACE(evo, 4); + if (ret) { + NV_ERROR(dev, "no space while disconnecting SOR\n"); + return; + } + BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); +- OUT_RING(evo, 0); +-} +- +-static void +-nv50_sor_dp_link_train(struct drm_encoder *encoder) +-{ +- struct drm_device *dev = encoder->dev; +- struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); +- struct bit_displayport_encoder_table *dpe; +- int dpe_headerlen; +- +- dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen); +- if (!dpe) { +- NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or); +- return; +- } ++ OUT_RING (evo, 0); ++ BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); ++ OUT_RING (evo, 0); + +- if (dpe->script0) { +- NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or); +- nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0), +- nv_encoder->dcb); +- } +- +- if (!nouveau_dp_link_train(encoder)) +- NV_ERROR(dev, "SOR-%d: link training failed\n", nv_encoder->or); +- +- if (dpe->script1) { +- NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or); +- nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1), +- nv_encoder->dcb); +- } ++ nv_encoder->crtc = NULL; ++ nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; + } + + static void +@@ -94,14 +74,16 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) + uint32_t val; + int or = nv_encoder->or; + +- NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode); ++ NV_DEBUG_KMS(dev, "or %d type %d mode %d\n", or, nv_encoder->dcb->type, mode); + + nv_encoder->last_dpms = mode; + list_for_each_entry(enc, &dev->mode_config.encoder_list, head) { + struct nouveau_encoder *nvenc = nouveau_encoder(enc); + + if (nvenc == nv_encoder || +- nvenc->disconnect != nv50_sor_disconnect || ++ (nvenc->dcb->type != OUTPUT_TMDS && ++ nvenc->dcb->type != OUTPUT_LVDS && ++ nvenc->dcb->type != OUTPUT_DP) || + nvenc->dcb->or != nv_encoder->dcb->or) + continue; + +@@ -110,7 +92,7 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) + } + + /* wait for it to be done */ +- if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_CTRL(or), ++ if (!nv_wait(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or), + NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING, 0)) { + NV_ERROR(dev, "timeout: SOR_DPMS_CTRL_PENDING(%d) == 0\n", or); + NV_ERROR(dev, "SOR_DPMS_CTRL(%d) = 0x%08x\n", or, +@@ -126,15 +108,29 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) + + nv_wr32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or), val | + NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING); +- if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_STATE(or), ++ if (!nv_wait(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or), + NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) { + NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", or); + NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", or, + nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or))); + } + +- if (nv_encoder->dcb->type == OUTPUT_DP && mode == DRM_MODE_DPMS_ON) +- nv50_sor_dp_link_train(encoder); ++ if (nv_encoder->dcb->type == OUTPUT_DP) { ++ struct nouveau_i2c_chan *auxch; ++ ++ auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); ++ if (!auxch) ++ return; ++ ++ if (mode == DRM_MODE_DPMS_ON) { ++ u8 status = DP_SET_POWER_D0; ++ nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1); ++ nouveau_dp_link_train(encoder); ++ } else { ++ u8 status = DP_SET_POWER_D3; ++ nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1); ++ } ++ } + } + + static void +@@ -196,7 +192,8 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + uint32_t mode_ctl = 0; + int ret; + +- NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or); ++ NV_DEBUG_KMS(dev, "or %d type %d -> crtc %d\n", ++ nv_encoder->or, nv_encoder->dcb->type, crtc->index); + + nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON); + +@@ -239,6 +236,14 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + } + BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); + OUT_RING(evo, mode_ctl); ++ ++ nv_encoder->crtc = encoder->crtc; ++} ++ ++static struct drm_crtc * ++nv50_sor_crtc_get(struct drm_encoder *encoder) ++{ ++ return nouveau_encoder(encoder)->crtc; + } + + static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = { +@@ -249,7 +254,9 @@ static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = { + .prepare = nv50_sor_prepare, + .commit = nv50_sor_commit, + .mode_set = nv50_sor_mode_set, +- .detect = NULL ++ .get_crtc = nv50_sor_crtc_get, ++ .detect = NULL, ++ .disable = nv50_sor_disconnect + }; + + static void +@@ -272,32 +279,22 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = { + }; + + int +-nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) ++nv50_sor_create(struct drm_connector *connector, struct dcb_entry *entry) + { + struct nouveau_encoder *nv_encoder = NULL; ++ struct drm_device *dev = connector->dev; + struct drm_encoder *encoder; +- bool dum; + int type; + + NV_DEBUG_KMS(dev, "\n"); + + switch (entry->type) { + case OUTPUT_TMDS: +- NV_INFO(dev, "Detected a TMDS output\n"); ++ case OUTPUT_DP: + type = DRM_MODE_ENCODER_TMDS; + break; + case OUTPUT_LVDS: +- NV_INFO(dev, "Detected a LVDS output\n"); + type = DRM_MODE_ENCODER_LVDS; +- +- if (nouveau_bios_parse_lvds_table(dev, 0, &dum, &dum)) { +- NV_ERROR(dev, "Failed parsing LVDS table\n"); +- return -EINVAL; +- } +- break; +- case OUTPUT_DP: +- NV_INFO(dev, "Detected a DP output\n"); +- type = DRM_MODE_ENCODER_TMDS; + break; + default: + return -EINVAL; +@@ -310,8 +307,7 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) + + nv_encoder->dcb = entry; + nv_encoder->or = ffs(entry->or) - 1; +- +- nv_encoder->disconnect = nv50_sor_disconnect; ++ nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; + + drm_encoder_init(dev, encoder, &nv50_sor_encoder_funcs, type); + drm_encoder_helper_add(encoder, &nv50_sor_helper_funcs); +@@ -342,5 +338,6 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) + nv_encoder->dp.mc_unknown = 5; + } + ++ drm_mode_connector_attach_encoder(connector, encoder); + return 0; + } +diff --git a/drivers/gpu/drm/nouveau/nvc0_fb.c b/drivers/gpu/drm/nouveau/nvc0_fb.c +new file mode 100644 +index 0000000..26a9960 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nvc0_fb.c +@@ -0,0 +1,38 @@ ++/* ++ * Copyright 2010 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Ben Skeggs ++ */ ++ ++#include "drmP.h" ++ ++#include "nouveau_drv.h" ++ ++int ++nvc0_fb_init(struct drm_device *dev) ++{ ++ return 0; ++} ++ ++void ++nvc0_fb_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nvc0_fifo.c b/drivers/gpu/drm/nouveau/nvc0_fifo.c +new file mode 100644 +index 0000000..2cdb7c3 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nvc0_fifo.c +@@ -0,0 +1,89 @@ ++/* ++ * Copyright 2010 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Ben Skeggs ++ */ ++ ++#include "drmP.h" ++ ++#include "nouveau_drv.h" ++ ++void ++nvc0_fifo_disable(struct drm_device *dev) ++{ ++} ++ ++void ++nvc0_fifo_enable(struct drm_device *dev) ++{ ++} ++ ++bool ++nvc0_fifo_reassign(struct drm_device *dev, bool enable) ++{ ++ return false; ++} ++ ++bool ++nvc0_fifo_cache_pull(struct drm_device *dev, bool enable) ++{ ++ return false; ++} ++ ++int ++nvc0_fifo_channel_id(struct drm_device *dev) ++{ ++ return 127; ++} ++ ++int ++nvc0_fifo_create_context(struct nouveau_channel *chan) ++{ ++ return 0; ++} ++ ++void ++nvc0_fifo_destroy_context(struct nouveau_channel *chan) ++{ ++} ++ ++int ++nvc0_fifo_load_context(struct nouveau_channel *chan) ++{ ++ return 0; ++} ++ ++int ++nvc0_fifo_unload_context(struct drm_device *dev) ++{ ++ return 0; ++} ++ ++void ++nvc0_fifo_takedown(struct drm_device *dev) ++{ ++} ++ ++int ++nvc0_fifo_init(struct drm_device *dev) ++{ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c +new file mode 100644 +index 0000000..edf2b21 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nvc0_graph.c +@@ -0,0 +1,74 @@ ++/* ++ * Copyright 2010 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Ben Skeggs ++ */ ++ ++#include "drmP.h" ++ ++#include "nouveau_drv.h" ++ ++void ++nvc0_graph_fifo_access(struct drm_device *dev, bool enabled) ++{ ++} ++ ++struct nouveau_channel * ++nvc0_graph_channel(struct drm_device *dev) ++{ ++ return NULL; ++} ++ ++int ++nvc0_graph_create_context(struct nouveau_channel *chan) ++{ ++ return 0; ++} ++ ++void ++nvc0_graph_destroy_context(struct nouveau_channel *chan) ++{ ++} ++ ++int ++nvc0_graph_load_context(struct nouveau_channel *chan) ++{ ++ return 0; ++} ++ ++int ++nvc0_graph_unload_context(struct drm_device *dev) ++{ ++ return 0; ++} ++ ++void ++nvc0_graph_takedown(struct drm_device *dev) ++{ ++} ++ ++int ++nvc0_graph_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ dev_priv->engine.graph.accel_blocked = true; ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nvc0_instmem.c b/drivers/gpu/drm/nouveau/nvc0_instmem.c +new file mode 100644 +index 0000000..152d8e8 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nvc0_instmem.c +@@ -0,0 +1,229 @@ ++/* ++ * Copyright 2010 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Ben Skeggs ++ */ ++ ++#include "drmP.h" ++ ++#include "nouveau_drv.h" ++ ++int ++nvc0_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, ++ uint32_t *size) ++{ ++ int ret; ++ ++ *size = ALIGN(*size, 4096); ++ if (*size == 0) ++ return -EINVAL; ++ ++ ret = nouveau_bo_new(dev, NULL, *size, 0, TTM_PL_FLAG_VRAM, 0, 0x0000, ++ true, false, &gpuobj->im_backing); ++ if (ret) { ++ NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret); ++ return ret; ++ } ++ ++ ret = nouveau_bo_pin(gpuobj->im_backing, TTM_PL_FLAG_VRAM); ++ if (ret) { ++ NV_ERROR(dev, "error pinning PRAMIN backing VRAM: %d\n", ret); ++ nouveau_bo_ref(NULL, &gpuobj->im_backing); ++ return ret; ++ } ++ ++ gpuobj->vinst = gpuobj->im_backing->bo.mem.mm_node->start << PAGE_SHIFT; ++ return 0; ++} ++ ++void ++nvc0_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (gpuobj && gpuobj->im_backing) { ++ if (gpuobj->im_bound) ++ dev_priv->engine.instmem.unbind(dev, gpuobj); ++ nouveau_bo_unpin(gpuobj->im_backing); ++ nouveau_bo_ref(NULL, &gpuobj->im_backing); ++ gpuobj->im_backing = NULL; ++ } ++} ++ ++int ++nvc0_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t pte, pte_end; ++ uint64_t vram; ++ ++ if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound) ++ return -EINVAL; ++ ++ NV_DEBUG(dev, "st=0x%lx sz=0x%lx\n", ++ gpuobj->im_pramin->start, gpuobj->im_pramin->size); ++ ++ pte = gpuobj->im_pramin->start >> 12; ++ pte_end = (gpuobj->im_pramin->size >> 12) + pte; ++ vram = gpuobj->vinst; ++ ++ NV_DEBUG(dev, "pramin=0x%lx, pte=%d, pte_end=%d\n", ++ gpuobj->im_pramin->start, pte, pte_end); ++ NV_DEBUG(dev, "first vram page: 0x%010llx\n", gpuobj->vinst); ++ ++ while (pte < pte_end) { ++ nv_wr32(dev, 0x702000 + (pte * 8), (vram >> 8) | 1); ++ nv_wr32(dev, 0x702004 + (pte * 8), 0); ++ vram += 4096; ++ pte++; ++ } ++ dev_priv->engine.instmem.flush(dev); ++ ++ if (1) { ++ u32 chan = nv_rd32(dev, 0x1700) << 16; ++ nv_wr32(dev, 0x100cb8, (chan + 0x1000) >> 8); ++ nv_wr32(dev, 0x100cbc, 0x80000005); ++ } ++ ++ gpuobj->im_bound = 1; ++ return 0; ++} ++ ++int ++nvc0_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t pte, pte_end; ++ ++ if (gpuobj->im_bound == 0) ++ return -EINVAL; ++ ++ pte = gpuobj->im_pramin->start >> 12; ++ pte_end = (gpuobj->im_pramin->size >> 12) + pte; ++ while (pte < pte_end) { ++ nv_wr32(dev, 0x702000 + (pte * 8), 0); ++ nv_wr32(dev, 0x702004 + (pte * 8), 0); ++ pte++; ++ } ++ dev_priv->engine.instmem.flush(dev); ++ ++ gpuobj->im_bound = 0; ++ return 0; ++} ++ ++void ++nvc0_instmem_flush(struct drm_device *dev) ++{ ++ nv_wr32(dev, 0x070000, 1); ++ if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) ++ NV_ERROR(dev, "PRAMIN flush timeout\n"); ++} ++ ++int ++nvc0_instmem_suspend(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ u32 *buf; ++ int i; ++ ++ dev_priv->susres.ramin_copy = vmalloc(65536); ++ if (!dev_priv->susres.ramin_copy) ++ return -ENOMEM; ++ buf = dev_priv->susres.ramin_copy; ++ ++ for (i = 0; i < 65536; i += 4) ++ buf[i/4] = nv_rd32(dev, NV04_PRAMIN + i); ++ return 0; ++} ++ ++void ++nvc0_instmem_resume(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ u32 *buf = dev_priv->susres.ramin_copy; ++ u64 chan; ++ int i; ++ ++ chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram; ++ nv_wr32(dev, 0x001700, chan >> 16); ++ ++ for (i = 0; i < 65536; i += 4) ++ nv_wr32(dev, NV04_PRAMIN + i, buf[i/4]); ++ vfree(dev_priv->susres.ramin_copy); ++ dev_priv->susres.ramin_copy = NULL; ++ ++ nv_wr32(dev, 0x001714, 0xc0000000 | (chan >> 12)); ++} ++ ++int ++nvc0_instmem_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ u64 chan, pgt3, imem, lim3 = dev_priv->ramin_size - 1; ++ int ret, i; ++ ++ dev_priv->ramin_rsvd_vram = 1 * 1024 * 1024; ++ chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram; ++ imem = 4096 + 4096 + 32768; ++ ++ nv_wr32(dev, 0x001700, chan >> 16); ++ ++ /* channel setup */ ++ nv_wr32(dev, 0x700200, lower_32_bits(chan + 0x1000)); ++ nv_wr32(dev, 0x700204, upper_32_bits(chan + 0x1000)); ++ nv_wr32(dev, 0x700208, lower_32_bits(lim3)); ++ nv_wr32(dev, 0x70020c, upper_32_bits(lim3)); ++ ++ /* point pgd -> pgt */ ++ nv_wr32(dev, 0x701000, 0); ++ nv_wr32(dev, 0x701004, ((chan + 0x2000) >> 8) | 1); ++ ++ /* point pgt -> physical vram for channel */ ++ pgt3 = 0x2000; ++ for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4096, pgt3 += 8) { ++ nv_wr32(dev, 0x700000 + pgt3, ((chan + i) >> 8) | 1); ++ nv_wr32(dev, 0x700004 + pgt3, 0); ++ } ++ ++ /* clear rest of pgt */ ++ for (; i < dev_priv->ramin_size; i += 4096, pgt3 += 8) { ++ nv_wr32(dev, 0x700000 + pgt3, 0); ++ nv_wr32(dev, 0x700004 + pgt3, 0); ++ } ++ ++ /* point bar3 at the channel */ ++ nv_wr32(dev, 0x001714, 0xc0000000 | (chan >> 12)); ++ ++ /* Global PRAMIN heap */ ++ ret = drm_mm_init(&dev_priv->ramin_heap, imem, ++ dev_priv->ramin_size - imem); ++ if (ret) { ++ NV_ERROR(dev, "Failed to init RAMIN heap\n"); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++void ++nvc0_instmem_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nvreg.h b/drivers/gpu/drm/nouveau/nvreg.h +index 5998c35..881f8a5 100644 +--- a/drivers/gpu/drm/nouveau/nvreg.h ++++ b/drivers/gpu/drm/nouveau/nvreg.h +@@ -147,28 +147,6 @@ + # define NV_VIO_GX_DONT_CARE_INDEX 0x07 + # define NV_VIO_GX_BIT_MASK_INDEX 0x08 + +-#define NV_PFB_BOOT_0 0x00100000 +-#define NV_PFB_CFG0 0x00100200 +-#define NV_PFB_CFG1 0x00100204 +-#define NV_PFB_CSTATUS 0x0010020C +-#define NV_PFB_REFCTRL 0x00100210 +-# define NV_PFB_REFCTRL_VALID_1 (1 << 31) +-#define NV_PFB_PAD 0x0010021C +-# define NV_PFB_PAD_CKE_NORMAL (1 << 0) +-#define NV_PFB_TILE_NV10 0x00100240 +-#define NV_PFB_TILE_SIZE_NV10 0x00100244 +-#define NV_PFB_REF 0x001002D0 +-# define NV_PFB_REF_CMD_REFRESH (1 << 0) +-#define NV_PFB_PRE 0x001002D4 +-# define NV_PFB_PRE_CMD_PRECHARGE (1 << 0) +-#define NV_PFB_CLOSE_PAGE2 0x0010033C +-#define NV_PFB_TILE_NV40 0x00100600 +-#define NV_PFB_TILE_SIZE_NV40 0x00100604 +- +-#define NV_PEXTDEV_BOOT_0 0x00101000 +-# define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT (8 << 12) +-#define NV_PEXTDEV_BOOT_3 0x0010100c +- + #define NV_PCRTC_INTR_0 0x00600100 + # define NV_PCRTC_INTR_0_VBLANK (1 << 0) + #define NV_PCRTC_INTR_EN_0 0x00600140 +@@ -285,6 +263,7 @@ + # define NV_CIO_CRE_HCUR_ADDR1_ADR 7:2 + # define NV_CIO_CRE_LCD__INDEX 0x33 + # define NV_CIO_CRE_LCD_LCD_SELECT 0:0 ++# define NV_CIO_CRE_LCD_ROUTE_MASK 0x3b + # define NV_CIO_CRE_DDC0_STATUS__INDEX 0x36 + # define NV_CIO_CRE_DDC0_WR__INDEX 0x37 + # define NV_CIO_CRE_ILACE__INDEX 0x39 /* interlace */ +-- +1.7.3 + diff --git a/drm-polling-fixes.patch b/drm-polling-fixes.patch new file mode 100644 index 000000000..ebb1be826 --- /dev/null +++ b/drm-polling-fixes.patch @@ -0,0 +1,601 @@ +commit 879d56da9b89b52de2109cadf1369967522428e8 +Author: Dave Airlie +Date: Tue Oct 26 12:55:52 2010 +1000 + + drm/radeon/kms: don't poll dac load detect. + + This is slightly destructive, cpu intensive and can cause lockups. + + Signed-off-by: Dave Airlie + +commit 2563a90cdda1fe490947dc032ce17bf1118afc39 +Author: Dave Airlie +Date: Tue Nov 9 10:26:00 2010 +1000 + + drm: Use a nondestructive mode for output detect when polling (v2) + + v2: Julien Cristau pointed out that @nondestructive results in + double-negatives and confusion when trying to interpret the parameter, + so use @force instead. Much easier to type as well. ;-) + + And fix the miscompilation of vmgfx reported by Sedat Dilek. + + Signed-off-by: Chris Wilson + Cc: stable@kernel.org + Signed-off-by: Dave Airlie + + Conflicts: + + drivers/gpu/drm/i915/intel_tv.c + drivers/gpu/drm/nouveau/nouveau_connector.c + +commit deb557bbbcaa7fa8281d51490c73b51f579bc84d +Author: Dave Airlie +Date: Tue Nov 9 10:24:06 2010 +1000 + + drm: Use a nondestructive mode for output detect when polling + + Destructive load-detection is very expensive and due to failings + elsewhere can trigger system wide stalls of up to 600ms. A simple + first step to correcting this is not to invoke such an expensive + and destructive load-detection operation automatically. + + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=29536 + Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=16265 + Reported-by: Bruno Prémont + Tested-by: Sitsofe Wheeler + Signed-off-by: Chris Wilson + Cc: stable@kernel.org + Signed-off-by: Dave Airlie + + Conflicts: + + drivers/gpu/drm/i915/intel_tv.c + drivers/gpu/drm/nouveau/nouveau_connector.c + +commit 8d5d3cd3612618a3c2214048788f0b2cc463ce0f +Author: Chris Wilson +Date: Mon Sep 6 23:53:47 2010 +0100 + + drm: Fix regression in disable polling e58f637 + + I broke out my trusty i845 and found a new boot failure, which upon + inspection turned out to be a recursion within: + + drm_helper_probe_single_connector_modes() -> drm_helper_hpd_irq_event() + -> intel_crt_detect() -> drm_helper_probe_single_connector_modes() + + Calling drm_kms_helper_poll_enable() instead performs the desired + re-initialisation of the polling should the user have toggled the + parameter, without the recursive side-effect. + + Signed-off-by: Chris Wilson + Cc: Dave Airlie + Signed-off-by: Dave Airlie + +commit ec0becade1eae9b0f40b12ea4fcc3ea36e993ba3 +Author: Dave Airlie +Date: Tue Nov 9 09:48:34 2010 +1000 + + drm/kms: Add a module parameter to disable polling + + Polling for a VGA device on an old system can be quite expensive, + causing latencies on the order of 600ms. As we hold the mode mutex for + this time and also need the same mutex to move the cursor, we trigger a + user-visible stall. + + The real solution would involve improving the granulatity of the + locking and so perhaps performing some of the probing not under the lock + or some other updates can be done under different locks. Also reducing the + cost of probing for a non-existent monitor would be worthwhile. However, + exposing a parameter to disable polling is a simple workaround in the + meantime. + + In order to accommodate users turning polling on and off at runtime, the + polling is potentially re-enabled on every probe. This is coupled to + the user calling xrandr, which seems to be a vaild time to reset the + polling timeout since the information on the connection has just been + updated. (The presumption being that all connections are probed in a + single xrandr pass, which is currently valid.) + + References: + + Bug 29536 - 2.6.35 causes ~600ms latency every 10s + https://bugs.freedesktop.org/show_bug.cgi?id=29536 + + Bug 16265 - Why is kslowd accumulating so much CPU time? + https://bugzilla.kernel.org/show_bug.cgi?id=16265 + + Signed-off-by: Chris Wilson + Reported-and-tested-by: Bruno Prémont + Signed-off-by: Dave Airlie + + Conflicts: + + drivers/gpu/drm/drm_crtc_helper.c + +commit 77e90256db2f7e6424717f7cc984b22d2832243f +Author: Dan Carpenter +Date: Thu Aug 19 11:46:29 2010 +0200 + + drm: move dereference below check + + "fb_helper_conn" is dereferenced before the check for NULL. It's never + actually NULL here, so this is mostly to keep the static checkers happy. + + Signed-off-by: Dan Carpenter + Signed-off-by: Dave Airlie + +commit 86e25290d9df7a84d185dfc037851d72d270a6c0 +Author: Alex Deucher +Date: Tue Jul 20 03:24:11 2010 -0400 + + drm/radeon/kms: make sure HPD is set to NONE on analog-only connectors + + HPD is digital only. + + Signed-off-by: Alex Deucher + Signed-off-by: Dave Airlie + +diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c +index 25d70d6..d537039 100644 +--- a/drivers/gpu/drm/drm_crtc_helper.c ++++ b/drivers/gpu/drm/drm_crtc_helper.c +@@ -34,6 +34,9 @@ + #include "drm_crtc_helper.h" + #include "drm_fb_helper.h" + ++static bool drm_kms_helper_poll = true; ++module_param_named(poll, drm_kms_helper_poll, bool, 0600); ++ + static void drm_mode_validate_flag(struct drm_connector *connector, + int flags) + { +@@ -98,8 +101,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, + connector->status = connector_status_disconnected; + if (connector->funcs->force) + connector->funcs->force(connector); +- } else +- connector->status = connector->funcs->detect(connector); ++ } else { ++ connector->status = connector->funcs->detect(connector, true); ++ drm_kms_helper_poll_enable(dev); ++ } + + if (connector->status == connector_status_disconnected) { + DRM_DEBUG_KMS("%s is disconnected\n", +@@ -820,6 +825,9 @@ static void output_poll_execute(struct slow_work *work) + bool repoll = false, changed = false; + int ret; + ++ if (!drm_kms_helper_poll) ++ return; ++ + mutex_lock(&dev->mode_config.mutex); + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + +@@ -839,7 +847,7 @@ static void output_poll_execute(struct slow_work *work) + !(connector->polled & DRM_CONNECTOR_POLL_HPD)) + continue; + +- status = connector->funcs->detect(connector); ++ status = connector->funcs->detect(connector, false); + if (old_status != status) + changed = true; + } +@@ -874,6 +882,9 @@ void drm_kms_helper_poll_enable(struct drm_device *dev) + struct drm_connector *connector; + int ret; + ++ if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll) ++ return; ++ + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + if (connector->polled) + poll = true; +@@ -909,9 +920,12 @@ void drm_helper_hpd_irq_event(struct drm_device *dev) + { + if (!dev->mode_config.poll_enabled) + return; ++ + delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work); + /* schedule a slow work asap */ +- delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, 0); ++ if (drm_kms_helper_poll) ++ delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, 0); ++ + } + EXPORT_SYMBOL(drm_helper_hpd_irq_event); + +diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c +index 7196620..cef8d8d 100644 +--- a/drivers/gpu/drm/drm_fb_helper.c ++++ b/drivers/gpu/drm/drm_fb_helper.c +@@ -94,10 +94,11 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_fb_helper_conn + int i; + enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; + struct drm_fb_helper_cmdline_mode *cmdline_mode; +- struct drm_connector *connector = fb_helper_conn->connector; ++ struct drm_connector *connector; + + if (!fb_helper_conn) + return false; ++ connector = fb_helper_conn->connector; + + cmdline_mode = &fb_helper_conn->cmdline_mode; + if (!mode_option) +diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c +index 101d381..9500af1 100644 +--- a/drivers/gpu/drm/drm_sysfs.c ++++ b/drivers/gpu/drm/drm_sysfs.c +@@ -159,7 +159,7 @@ static ssize_t status_show(struct device *device, + struct drm_connector *connector = to_drm_connector(device); + enum drm_connector_status status; + +- status = connector->funcs->detect(connector); ++ status = connector->funcs->detect(connector, true); + return snprintf(buf, PAGE_SIZE, "%s\n", + drm_get_connector_status_name(status)); + } +diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c +index ee0732b..3886b47 100644 +--- a/drivers/gpu/drm/i915/intel_crt.c ++++ b/drivers/gpu/drm/i915/intel_crt.c +@@ -402,7 +402,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder + return status; + } + +-static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) ++static enum drm_connector_status ++intel_crt_detect(struct drm_connector *connector, bool force) + { + struct drm_device *dev = connector->dev; + struct drm_encoder *encoder = intel_attached_encoder(connector); +@@ -421,6 +422,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto + if (intel_crt_detect_ddc(encoder)) + return connector_status_connected; + ++ if (!force) ++ return connector->status; ++ + /* for pre-945g platforms use load detect */ + if (encoder->crtc && encoder->crtc->enabled) { + status = intel_crt_load_detect(encoder->crtc, intel_encoder); +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index d9de8f1..b58249d 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1287,7 +1287,7 @@ ironlake_dp_detect(struct drm_connector *connector) + * \return false if DP port is disconnected. + */ + static enum drm_connector_status +-intel_dp_detect(struct drm_connector *connector) ++intel_dp_detect(struct drm_connector *connector, bool force) + { + struct drm_encoder *encoder = intel_attached_encoder(connector); + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c +index 227feca..48a1889 100644 +--- a/drivers/gpu/drm/i915/intel_dvo.c ++++ b/drivers/gpu/drm/i915/intel_dvo.c +@@ -211,7 +211,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, + * + * Unimplemented. + */ +-static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) ++static enum drm_connector_status ++intel_dvo_detect(struct drm_connector *connector, bool force) + { + struct drm_encoder *encoder = intel_attached_encoder(connector); + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 83bd764..d1decfc 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -134,7 +134,7 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, + } + + static enum drm_connector_status +-intel_hdmi_detect(struct drm_connector *connector) ++intel_hdmi_detect(struct drm_connector *connector, bool force) + { + struct drm_encoder *encoder = intel_attached_encoder(connector); + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 7d42ff1..9ad3425 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -546,7 +546,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, + * connected and closed means disconnected. We also send hotplug events as + * needed, using lid status notification from the input layer. + */ +-static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector) ++static enum drm_connector_status ++intel_lvds_detect(struct drm_connector *connector, bool force) + { + struct drm_device *dev = connector->dev; + enum drm_connector_status status = connector_status_connected; +@@ -641,7 +642,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, + * the LID nofication event. + */ + if (connector) +- connector->status = connector->funcs->detect(connector); ++ connector->status = connector->funcs->detect(connector, ++ false); ++ + /* Don't force modeset on machines where it causes a GPU lockup */ + if (dmi_check_system(intel_no_modeset_on_lid)) + return NOTIFY_OK; +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 76993ac..76c9b3d 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1496,7 +1496,7 @@ intel_analog_is_connected(struct drm_device *dev) + if (!analog_connector) + return false; + +- if (analog_connector->funcs->detect(analog_connector) == ++ if (analog_connector->funcs->detect(analog_connector, false) == + connector_status_disconnected) + return false; + +@@ -1567,7 +1567,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) + return status; + } + +-static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) ++static enum drm_connector_status ++intel_sdvo_detect(struct drm_connector *connector, bool force) + { + uint16_t response; + u8 status; +diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c +index 6d553c2..ad40f1b 100644 +--- a/drivers/gpu/drm/i915/intel_tv.c ++++ b/drivers/gpu/drm/i915/intel_tv.c +@@ -1336,7 +1336,7 @@ static void intel_tv_find_better_format(struct drm_connector *connector) + * we have a pipe programmed in order to probe the TV. + */ + static enum drm_connector_status +-intel_tv_detect(struct drm_connector *connector) ++intel_tv_detect(struct drm_connector *connector, bool force) + { + struct drm_crtc *crtc; + struct drm_display_mode mode; +@@ -1351,7 +1351,7 @@ intel_tv_detect(struct drm_connector *connector) + + if (encoder->crtc && encoder->crtc->enabled) { + type = intel_tv_detect_type(encoder->crtc, intel_encoder); +- } else { ++ } else if (force) { + crtc = intel_get_load_detect_pipe(intel_encoder, connector, + &mode, &dpms_mode); + if (crtc) { +@@ -1359,8 +1359,9 @@ intel_tv_detect(struct drm_connector *connector) + intel_release_load_detect_pipe(intel_encoder, connector, + dpms_mode); + } else +- type = -1; +- } ++ return connector_status_unknown; ++ } else ++ return connector->status; + + tv_priv->type = type; + +diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c +index 149ed22..1085376 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_connector.c ++++ b/drivers/gpu/drm/nouveau/nouveau_connector.c +@@ -228,7 +228,7 @@ nouveau_connector_set_encoder(struct drm_connector *connector, + } + + static enum drm_connector_status +-nouveau_connector_detect(struct drm_connector *connector) ++nouveau_connector_detect(struct drm_connector *connector, bool force) + { + struct drm_device *dev = connector->dev; + struct nouveau_connector *nv_connector = nouveau_connector(connector); +diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c +index adccbc2..1680600 100644 +--- a/drivers/gpu/drm/radeon/radeon_connectors.c ++++ b/drivers/gpu/drm/radeon/radeon_connectors.c +@@ -467,7 +467,8 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector, + return MODE_OK; + } + +-static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector) ++static enum drm_connector_status ++radeon_lvds_detect(struct drm_connector *connector, bool force) + { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct drm_encoder *encoder = radeon_best_single_encoder(connector); +@@ -582,7 +583,8 @@ static int radeon_vga_mode_valid(struct drm_connector *connector, + return MODE_OK; + } + +-static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector) ++static enum drm_connector_status ++radeon_vga_detect(struct drm_connector *connector, bool force) + { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct drm_encoder *encoder; +@@ -621,6 +623,11 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect + ret = connector_status_connected; + } + } else { ++ ++ /* if we aren't forcing don't do destructive polling */ ++ if (!force) ++ return connector->status; ++ + if (radeon_connector->dac_load_detect && encoder) { + encoder_funcs = encoder->helper_private; + ret = encoder_funcs->detect(encoder, connector); +@@ -679,7 +686,8 @@ static int radeon_tv_mode_valid(struct drm_connector *connector, + return MODE_OK; + } + +-static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector) ++static enum drm_connector_status ++radeon_tv_detect(struct drm_connector *connector, bool force) + { + struct drm_encoder *encoder; + struct drm_encoder_helper_funcs *encoder_funcs; +@@ -736,7 +744,8 @@ static int radeon_dvi_get_modes(struct drm_connector *connector) + * we have to check if this analog encoder is shared with anyone else (TV) + * if its shared we have to set the other connector to disconnected. + */ +-static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector) ++static enum drm_connector_status ++radeon_dvi_detect(struct drm_connector *connector, bool force) + { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct drm_encoder *encoder = NULL; +@@ -806,6 +815,11 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect + if ((ret == connector_status_connected) && (radeon_connector->use_digital == true)) + goto out; + ++ if (!force) { ++ ret = connector->status; ++ goto out; ++ } ++ + /* find analog encoder */ + if (radeon_connector->dac_load_detect) { + for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { +@@ -962,7 +976,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector) + return ret; + } + +-static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector) ++static enum drm_connector_status ++radeon_dp_detect(struct drm_connector *connector, bool force) + { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + enum drm_connector_status ret = connector_status_disconnected; +@@ -1082,6 +1097,8 @@ radeon_add_atom_connector(struct drm_device *dev, + drm_connector_attach_property(&radeon_connector->base, + rdev->mode_info.load_detect_property, + 1); ++ /* no HPD on analog connectors */ ++ radeon_connector->hpd.hpd = RADEON_HPD_NONE; + connector->polled = DRM_CONNECTOR_POLL_CONNECT; + connector->interlace_allowed = true; + connector->doublescan_allowed = true; +@@ -1096,6 +1113,8 @@ radeon_add_atom_connector(struct drm_device *dev, + drm_connector_attach_property(&radeon_connector->base, + rdev->mode_info.load_detect_property, + 1); ++ /* no HPD on analog connectors */ ++ radeon_connector->hpd.hpd = RADEON_HPD_NONE; + connector->interlace_allowed = true; + connector->doublescan_allowed = true; + break; +@@ -1186,6 +1205,8 @@ radeon_add_atom_connector(struct drm_device *dev, + drm_connector_attach_property(&radeon_connector->base, + rdev->mode_info.tv_std_property, + radeon_atombios_get_tv_info(rdev)); ++ /* no HPD on analog connectors */ ++ radeon_connector->hpd.hpd = RADEON_HPD_NONE; + } + connector->interlace_allowed = false; + connector->doublescan_allowed = false; +@@ -1209,7 +1230,7 @@ radeon_add_atom_connector(struct drm_device *dev, + break; + } + +- if (hpd->hpd == RADEON_HPD_NONE) { ++ if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { + if (i2c_bus->valid) + connector->polled = DRM_CONNECTOR_POLL_CONNECT; + } else +@@ -1276,6 +1297,8 @@ radeon_add_legacy_connector(struct drm_device *dev, + drm_connector_attach_property(&radeon_connector->base, + rdev->mode_info.load_detect_property, + 1); ++ /* no HPD on analog connectors */ ++ radeon_connector->hpd.hpd = RADEON_HPD_NONE; + connector->polled = DRM_CONNECTOR_POLL_CONNECT; + connector->interlace_allowed = true; + connector->doublescan_allowed = true; +@@ -1290,6 +1313,8 @@ radeon_add_legacy_connector(struct drm_device *dev, + drm_connector_attach_property(&radeon_connector->base, + rdev->mode_info.load_detect_property, + 1); ++ /* no HPD on analog connectors */ ++ radeon_connector->hpd.hpd = RADEON_HPD_NONE; + connector->interlace_allowed = true; + connector->doublescan_allowed = true; + break; +@@ -1328,6 +1353,8 @@ radeon_add_legacy_connector(struct drm_device *dev, + drm_connector_attach_property(&radeon_connector->base, + rdev->mode_info.tv_std_property, + radeon_combios_get_tv_info(rdev)); ++ /* no HPD on analog connectors */ ++ radeon_connector->hpd.hpd = RADEON_HPD_NONE; + } + connector->interlace_allowed = false; + connector->doublescan_allowed = false; +@@ -1345,7 +1372,7 @@ radeon_add_legacy_connector(struct drm_device *dev, + break; + } + +- if (hpd->hpd == RADEON_HPD_NONE) { ++ if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { + if (i2c_bus->valid) + connector->polled = DRM_CONNECTOR_POLL_CONNECT; + } else +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +index cfaf690..5b638cb 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +@@ -335,7 +335,8 @@ static void vmw_ldu_connector_restore(struct drm_connector *connector) + } + + static enum drm_connector_status +- vmw_ldu_connector_detect(struct drm_connector *connector) ++ vmw_ldu_connector_detect(struct drm_connector *connector, ++ bool force) + { + if (vmw_connector_to_ldu(connector)->pref_active) + return connector_status_connected; +@@ -516,7 +517,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) + + drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, + DRM_MODE_CONNECTOR_LVDS); +- connector->status = vmw_ldu_connector_detect(connector); ++ connector->status = vmw_ldu_connector_detect(connector, true); + + drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, + DRM_MODE_ENCODER_LVDS); +@@ -610,7 +611,7 @@ int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num, + ldu->pref_height = 600; + ldu->pref_active = false; + } +- con->status = vmw_ldu_connector_detect(con); ++ con->status = vmw_ldu_connector_detect(con, true); + } + + mutex_unlock(&dev->mode_config.mutex); +diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h +index 93a1a31..afbb578 100644 +--- a/include/drm/drm_crtc.h ++++ b/include/drm/drm_crtc.h +@@ -420,7 +420,15 @@ struct drm_connector_funcs { + void (*dpms)(struct drm_connector *connector, int mode); + void (*save)(struct drm_connector *connector); + void (*restore)(struct drm_connector *connector); +- enum drm_connector_status (*detect)(struct drm_connector *connector); ++ ++ /* Check to see if anything is attached to the connector. ++ * @force is set to false whilst polling, true when checking the ++ * connector due to user request. @force can be used by the driver ++ * to avoid expensive, destructive operations during automated ++ * probing. ++ */ ++ enum drm_connector_status (*detect)(struct drm_connector *connector, ++ bool force); + int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); + int (*set_property)(struct drm_connector *connector, struct drm_property *property, + uint64_t val); diff --git a/drm-radeon-r600-cs-checker-fixes.patch b/drm-radeon-r600-cs-checker-fixes.patch new file mode 100644 index 000000000..02fe41701 --- /dev/null +++ b/drm-radeon-r600-cs-checker-fixes.patch @@ -0,0 +1,854 @@ +commit 4adf332cc24ee2d46064aaafd8216169d29566d5 +Author: Alex Deucher +Date: Sun Nov 14 20:24:35 2010 -0500 + + drm/radeon/kms: fix and unify tiled buffer alignment checking for r6xx/7xx + + Tiled buffers have the same alignment requirements regardless of + whether the surface is for db, cb, or textures. Previously, the + calculations where inconsistent for each buffer type. + + - Unify the alignment calculations in a common function + - Standardize the alignment units (pixels for pitch/height/depth, + bytes for base) + - properly check the buffer base alignments + + Signed-off-by: Alex Deucher + Signed-off-by: Dave Airlie + +commit c37cb9e61dce7437f63280d9347a9ffdf4ec34e7 +Author: Alex Deucher +Date: Wed Oct 27 01:44:35 2010 -0400 + + drm/radeon/kms: fix tiled db height calculation on 6xx/7xx + + Calculate height based on the slice bitfield rather than the size. + Same as Dave's CB fix. + + Signed-off-by: Alex Deucher + Signed-off-by: Dave Airlie + +commit b80c8fdc2fadd8182b958e91a10f2fa287f993e4 +Author: Alex Deucher +Date: Tue Oct 26 20:22:42 2010 -0400 + + drm/radeon/kms: fix r6xx/7xx 1D tiling CS checker v2 + + broken by: + drm/radeon/r600: fix tiling issues in CS checker. + + v2: only apply it to 1D tiling case. + + Signed-off-by: Alex Deucher + Signed-off-by: Dave Airlie + +commit 4336ac5c0a4e5dfbb51631ad680d6a5d0b295cd3 +Author: Alex Deucher +Date: Mon Oct 18 23:45:39 2010 -0400 + + drm/radeon/kms: fix 2D tile height alignment in the r600 CS checker + + macro tile heights are aligned to num channels, not num banks. + + Noticed by Dave Airlie. + + Signed-off-by: Alex Deucher + Cc: stable@kernel.org + Signed-off-by: Dave Airlie + +commit 5c76976a1419a633f9f33c6547bae00348b855d2 +Author: Dave Airlie +Date: Thu Oct 21 13:55:40 2010 +1000 + + drm/radeon/r600: fix tiling issues in CS checker. + + The CS checker had some incorrect alignment requirements for 2D surfaces, + this made rendering to mipmap levels that were 2D broken. + + Also the CB height was being worked out from the BO size, this doesn't work + at all when rendering mipmap levels, instead we work out what height userspace + wanted from slice max and use that to check it fits inside the BO, however + the DDX send the wrong slice max for an unaligned buffer so we have to workaround + for that even though its a userspace bug. + + Reviewed-by: Alex Deucher + Signed-off-by: Dave Airlie + +commit fa479e9df4558af6f091c45be37f713e64b836a1 +Author: Alex Deucher +Date: Tue Sep 14 10:10:47 2010 -0400 + + drm/radeon/kms: only warn on mipmap size checks in r600 cs checker (v2) + + The texture base address registers are in units of 256 bytes. + The original CS checker treated these offsets as bytes, so the + original check was wrong. I fixed the units in a patch during + the 2.6.36 cycle, but this ended up breaking some existing + userspace (probably due to a bug in either userspace texture allocation + or the drm texture mipmap checker). So for now, until we come + up with a better fix, just warn if the mipmap size it too large. + This will keep existing userspace working and it should be just + as safe as before when we were checking the wrong units. These + are GPU MC addresses, so if they fall outside of the VRAM or + GART apertures, they end up at the GPU default page, so this should + be safe from a security perspective. + + v2: Just disable the warning. It just spams the log and there's + nothing the user can do about it. + + Signed-off-by: Alex Deucher + Cc: Jerome Glisse + Signed-off-by: Dave Airlie + +commit 6e8df81d43d5c95fe37db7f0ef55332de1a4b698 +Author: Dave Airlie +Date: Thu Aug 12 09:40:05 2010 +1000 + + drm/radeon: drop old and broken mesa warning + + This never really got fixed in mesa, and the kernel deals with the problem + just fine, so don't got reporting things that confuse people. + + Signed-off-by: Dave Airlie + +commit 23f012fb9a0633f2f8901440e314d6276255b1c0 +Author: Alex Deucher +Date: Wed Aug 11 11:54:25 2010 -0400 + + drm/radeon/kms: another r6xx/r7xx CS checker fix + + add default case for buffer formats + + Signed-off-by: Alex Deucher + Cc: Andre Maasikas + Signed-off-by: Dave Airlie + +commit 2c7e76decda2d437f0ca064fef1a2d5d8892288e +Author: Alex Deucher +Date: Fri Aug 6 02:54:05 2010 -0400 + + drm/radeon/kms: r600 CS parser fixes + + - buffer offsets in the base regs are 256b aligned so + shift properly when comparing, fixed by Andre Maasikas + - mipmap size was calculated wrong when nlevel=0 + - texture bo offsets were used after the bo base address was added + - vertex resource size register is size - 1, not size + + Signed-off-by: Alex Deucher + Cc: Andre Maasikas + Signed-off-by: Dave Airlie + +commit 85d1363c9f15b5d4303b635142cee0ba9d1473fc +Author: Alex Deucher +Date: Fri Jun 4 18:41:42 2010 -0400 + + drm/radeon/kms: fix CS alignment checking for tiling (v2) + + Covers depth, cb, and textures. Hopefully I got this right. + + v2: - fix bugs: + https://bugs.freedesktop.org/show_bug.cgi?id=28327 + https://bugs.freedesktop.org/show_bug.cgi?id=28381 + - use ALIGNED(), IS_ALIGNED() macros + + Signed-off-by: Alex Deucher + Signed-off-by: Dave Airlie + +commit b956b6e7c7fb207daf32520c0a72c8c06ef1d5f5 +Author: Alex Deucher +Date: Thu May 20 12:43:52 2010 -0400 + + drm/radeon/kms: add tiling support to the cs checker for r6xx/r7xx + + Check for relocs for DB_DEPTH_INFO, CB_COLOR*_INFO, and texture + resources. + + Signed-off-by: Alex Deucher + Signed-off-by: Dave Airlie + + drivers/gpu/drm/radeon/r600_cs.c | 391 ++++++++++++++++++++++++++++++-------- + drivers/gpu/drm/radeon/r600d.h | 12 ++ + 2 files changed, 324 insertions(+), 79 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c +index 144c32d..0f90fc3 100644 +--- a/drivers/gpu/drm/radeon/r600_cs.c ++++ b/drivers/gpu/drm/radeon/r600_cs.c +@@ -25,6 +25,7 @@ + * Alex Deucher + * Jerome Glisse + */ ++#include + #include "drmP.h" + #include "radeon.h" + #include "r600d.h" +@@ -49,6 +50,7 @@ struct r600_cs_track { + u32 nsamples; + u32 cb_color_base_last[8]; + struct radeon_bo *cb_color_bo[8]; ++ u64 cb_color_bo_mc[8]; + u32 cb_color_bo_offset[8]; + struct radeon_bo *cb_color_frag_bo[8]; + struct radeon_bo *cb_color_tile_bo[8]; +@@ -66,6 +68,7 @@ struct r600_cs_track { + u32 db_depth_size; + u32 db_offset; + struct radeon_bo *db_bo; ++ u64 db_bo_mc; + }; + + static inline int r600_bpe_from_format(u32 *bpe, u32 format) +@@ -132,12 +135,75 @@ static inline int r600_bpe_from_format(u32 *bpe, u32 format) + case V_038004_FMT_GB_GR: + case V_038004_FMT_BG_RG: + case V_038004_COLOR_INVALID: ++ default: + *bpe = 16; + return -EINVAL; + } + return 0; + } + ++struct array_mode_checker { ++ int array_mode; ++ u32 group_size; ++ u32 nbanks; ++ u32 npipes; ++ u32 nsamples; ++ u32 bpe; ++}; ++ ++/* returns alignment in pixels for pitch/height/depth and bytes for base */ ++static inline int r600_get_array_mode_alignment(struct array_mode_checker *values, ++ u32 *pitch_align, ++ u32 *height_align, ++ u32 *depth_align, ++ u64 *base_align) ++{ ++ u32 tile_width = 8; ++ u32 tile_height = 8; ++ u32 macro_tile_width = values->nbanks; ++ u32 macro_tile_height = values->npipes; ++ u32 tile_bytes = tile_width * tile_height * values->bpe * values->nsamples; ++ u32 macro_tile_bytes = macro_tile_width * macro_tile_height * tile_bytes; ++ ++ switch (values->array_mode) { ++ case ARRAY_LINEAR_GENERAL: ++ /* technically tile_width/_height for pitch/height */ ++ *pitch_align = 1; /* tile_width */ ++ *height_align = 1; /* tile_height */ ++ *depth_align = 1; ++ *base_align = 1; ++ break; ++ case ARRAY_LINEAR_ALIGNED: ++ *pitch_align = max((u32)64, (u32)(values->group_size / values->bpe)); ++ *height_align = tile_height; ++ *depth_align = 1; ++ *base_align = values->group_size; ++ break; ++ case ARRAY_1D_TILED_THIN1: ++ *pitch_align = max((u32)tile_width, ++ (u32)(values->group_size / ++ (tile_height * values->bpe * values->nsamples))); ++ *height_align = tile_height; ++ *depth_align = 1; ++ *base_align = values->group_size; ++ break; ++ case ARRAY_2D_TILED_THIN1: ++ *pitch_align = max((u32)macro_tile_width, ++ (u32)(((values->group_size / tile_height) / ++ (values->bpe * values->nsamples)) * ++ values->nbanks)) * tile_width; ++ *height_align = macro_tile_height * tile_height; ++ *depth_align = 1; ++ *base_align = max(macro_tile_bytes, ++ (*pitch_align) * values->bpe * (*height_align) * values->nsamples); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static void r600_cs_track_init(struct r600_cs_track *track) + { + int i; +@@ -151,10 +217,12 @@ static void r600_cs_track_init(struct r600_cs_track *track) + track->cb_color_info[i] = 0; + track->cb_color_bo[i] = NULL; + track->cb_color_bo_offset[i] = 0xFFFFFFFF; ++ track->cb_color_bo_mc[i] = 0xFFFFFFFF; + } + track->cb_target_mask = 0xFFFFFFFF; + track->cb_shader_mask = 0xFFFFFFFF; + track->db_bo = NULL; ++ track->db_bo_mc = 0xFFFFFFFF; + /* assume the biggest format and that htile is enabled */ + track->db_depth_info = 7 | (1 << 25); + track->db_depth_view = 0xFFFFC000; +@@ -166,70 +234,58 @@ static void r600_cs_track_init(struct r600_cs_track *track) + static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) + { + struct r600_cs_track *track = p->track; +- u32 bpe = 0, pitch, slice_tile_max, size, tmp, height; ++ u32 bpe = 0, slice_tile_max, size, tmp; ++ u32 height, height_align, pitch, pitch_align, depth_align; ++ u64 base_offset, base_align; ++ struct array_mode_checker array_check; + volatile u32 *ib = p->ib->ptr; ++ unsigned array_mode; + + if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { + dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n"); + return -EINVAL; + } +- size = radeon_bo_size(track->cb_color_bo[i]); ++ size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; + if (r600_bpe_from_format(&bpe, G_0280A0_FORMAT(track->cb_color_info[i]))) { + dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08X)\n", + __func__, __LINE__, G_0280A0_FORMAT(track->cb_color_info[i]), + i, track->cb_color_info[i]); + return -EINVAL; + } +- pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) << 3; ++ /* pitch in pixels */ ++ pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) * 8; + slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1; +- if (!pitch) { +- dev_warn(p->dev, "%s:%d cb pitch (%d) for %d invalid (0x%08X)\n", +- __func__, __LINE__, pitch, i, track->cb_color_size[i]); +- return -EINVAL; +- } +- height = size / (pitch * bpe); ++ slice_tile_max *= 64; ++ height = slice_tile_max / pitch; + if (height > 8192) + height = 8192; +- switch (G_0280A0_ARRAY_MODE(track->cb_color_info[i])) { ++ array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]); ++ ++ base_offset = track->cb_color_bo_mc[i] + track->cb_color_bo_offset[i]; ++ array_check.array_mode = array_mode; ++ array_check.group_size = track->group_size; ++ array_check.nbanks = track->nbanks; ++ array_check.npipes = track->npipes; ++ array_check.nsamples = track->nsamples; ++ array_check.bpe = bpe; ++ if (r600_get_array_mode_alignment(&array_check, ++ &pitch_align, &height_align, &depth_align, &base_align)) { ++ dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, ++ G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i, ++ track->cb_color_info[i]); ++ return -EINVAL; ++ } ++ switch (array_mode) { + case V_0280A0_ARRAY_LINEAR_GENERAL: ++ break; + case V_0280A0_ARRAY_LINEAR_ALIGNED: +- if (pitch & 0x3f) { +- dev_warn(p->dev, "%s:%d cb pitch (%d x %d = %d) invalid\n", +- __func__, __LINE__, pitch, bpe, pitch * bpe); +- return -EINVAL; +- } +- if ((pitch * bpe) & (track->group_size - 1)) { +- dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", +- __func__, __LINE__, pitch); +- return -EINVAL; +- } + break; + case V_0280A0_ARRAY_1D_TILED_THIN1: +- if ((pitch * 8 * bpe * track->nsamples) & (track->group_size - 1)) { +- dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", +- __func__, __LINE__, pitch); +- return -EINVAL; +- } +- height &= ~0x7; +- if (!height) +- height = 8; ++ /* avoid breaking userspace */ ++ if (height > 7) ++ height &= ~0x7; + break; + case V_0280A0_ARRAY_2D_TILED_THIN1: +- if (pitch & ((8 * track->nbanks) - 1)) { +- dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", +- __func__, __LINE__, pitch); +- return -EINVAL; +- } +- tmp = pitch * 8 * bpe * track->nsamples; +- tmp = tmp / track->nbanks; +- if (tmp & (track->group_size - 1)) { +- dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", +- __func__, __LINE__, pitch); +- return -EINVAL; +- } +- height &= ~((16 * track->npipes) - 1); +- if (!height) +- height = 16 * track->npipes; + break; + default: + dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, +@@ -237,17 +293,43 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) + track->cb_color_info[i]); + return -EINVAL; + } ++ ++ if (!IS_ALIGNED(pitch, pitch_align)) { ++ dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", ++ __func__, __LINE__, pitch); ++ return -EINVAL; ++ } ++ if (!IS_ALIGNED(height, height_align)) { ++ dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", ++ __func__, __LINE__, height); ++ return -EINVAL; ++ } ++ if (!IS_ALIGNED(base_offset, base_align)) { ++ dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset); ++ return -EINVAL; ++ } ++ + /* check offset */ +- tmp = height * pitch; ++ tmp = height * pitch * bpe; + if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { +- dev_warn(p->dev, "%s offset[%d] %d to big\n", __func__, i, track->cb_color_bo_offset[i]); +- return -EINVAL; ++ if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { ++ /* the initial DDX does bad things with the CB size occasionally */ ++ /* it rounds up height too far for slice tile max but the BO is smaller */ ++ tmp = (height - 7) * 8 * bpe; ++ if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { ++ dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); ++ return -EINVAL; ++ } ++ } else { ++ dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); ++ return -EINVAL; ++ } + } + /* limit max tile */ + tmp = (height * pitch) >> 6; + if (tmp < slice_tile_max) + slice_tile_max = tmp; +- tmp = S_028060_PITCH_TILE_MAX((pitch >> 3) - 1) | ++ tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) | + S_028060_SLICE_TILE_MAX(slice_tile_max - 1); + ib[track->cb_color_size_idx[i]] = tmp; + return 0; +@@ -289,7 +371,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) + /* Check depth buffer */ + if (G_028800_STENCIL_ENABLE(track->db_depth_control) || + G_028800_Z_ENABLE(track->db_depth_control)) { +- u32 nviews, bpe, ntiles; ++ u32 nviews, bpe, ntiles, size, slice_tile_max; ++ u32 height, height_align, pitch, pitch_align, depth_align; ++ u64 base_offset, base_align; ++ struct array_mode_checker array_check; ++ int array_mode; ++ + if (track->db_bo == NULL) { + dev_warn(p->dev, "z/stencil with no depth buffer\n"); + return -EINVAL; +@@ -321,7 +408,6 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) + dev_warn(p->dev, "z/stencil buffer size not set\n"); + return -EINVAL; + } +- printk_once(KERN_WARNING "You have old & broken userspace please consider updating mesa\n"); + tmp = radeon_bo_size(track->db_bo) - track->db_offset; + tmp = (tmp / bpe) >> 6; + if (!tmp) { +@@ -332,11 +418,63 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) + } + ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF); + } else { ++ size = radeon_bo_size(track->db_bo); ++ /* pitch in pixels */ ++ pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8; ++ slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; ++ slice_tile_max *= 64; ++ height = slice_tile_max / pitch; ++ if (height > 8192) ++ height = 8192; ++ base_offset = track->db_bo_mc + track->db_offset; ++ array_mode = G_028010_ARRAY_MODE(track->db_depth_info); ++ array_check.array_mode = array_mode; ++ array_check.group_size = track->group_size; ++ array_check.nbanks = track->nbanks; ++ array_check.npipes = track->npipes; ++ array_check.nsamples = track->nsamples; ++ array_check.bpe = bpe; ++ if (r600_get_array_mode_alignment(&array_check, ++ &pitch_align, &height_align, &depth_align, &base_align)) { ++ dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, ++ G_028010_ARRAY_MODE(track->db_depth_info), ++ track->db_depth_info); ++ return -EINVAL; ++ } ++ switch (array_mode) { ++ case V_028010_ARRAY_1D_TILED_THIN1: ++ /* don't break userspace */ ++ height &= ~0x7; ++ break; ++ case V_028010_ARRAY_2D_TILED_THIN1: ++ break; ++ default: ++ dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, ++ G_028010_ARRAY_MODE(track->db_depth_info), ++ track->db_depth_info); ++ return -EINVAL; ++ } ++ ++ if (!IS_ALIGNED(pitch, pitch_align)) { ++ dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", ++ __func__, __LINE__, pitch); ++ return -EINVAL; ++ } ++ if (!IS_ALIGNED(height, height_align)) { ++ dev_warn(p->dev, "%s:%d db height (%d) invalid\n", ++ __func__, __LINE__, height); ++ return -EINVAL; ++ } ++ if (!IS_ALIGNED(base_offset, base_align)) { ++ dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset); ++ return -EINVAL; ++ } ++ + ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; + nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; + tmp = ntiles * bpe * 64 * nviews; + if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { +- dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %d have %ld)\n", ++ dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %u have %lu)\n", + track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, + radeon_bo_size(track->db_bo)); + return -EINVAL; +@@ -724,7 +862,25 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx + track->db_depth_control = radeon_get_ib_value(p, idx); + break; + case R_028010_DB_DEPTH_INFO: +- track->db_depth_info = radeon_get_ib_value(p, idx); ++ if (r600_cs_packet_next_is_pkt3_nop(p)) { ++ r = r600_cs_packet_next_reloc(p, &reloc); ++ if (r) { ++ dev_warn(p->dev, "bad SET_CONTEXT_REG " ++ "0x%04X\n", reg); ++ return -EINVAL; ++ } ++ track->db_depth_info = radeon_get_ib_value(p, idx); ++ ib[idx] &= C_028010_ARRAY_MODE; ++ track->db_depth_info &= C_028010_ARRAY_MODE; ++ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { ++ ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1); ++ track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1); ++ } else { ++ ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1); ++ track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1); ++ } ++ } else ++ track->db_depth_info = radeon_get_ib_value(p, idx); + break; + case R_028004_DB_DEPTH_VIEW: + track->db_depth_view = radeon_get_ib_value(p, idx); +@@ -757,8 +913,25 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx + case R_0280B4_CB_COLOR5_INFO: + case R_0280B8_CB_COLOR6_INFO: + case R_0280BC_CB_COLOR7_INFO: +- tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4; +- track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); ++ if (r600_cs_packet_next_is_pkt3_nop(p)) { ++ r = r600_cs_packet_next_reloc(p, &reloc); ++ if (r) { ++ dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); ++ return -EINVAL; ++ } ++ tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4; ++ track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); ++ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { ++ ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1); ++ track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1); ++ } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { ++ ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1); ++ track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1); ++ } ++ } else { ++ tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4; ++ track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); ++ } + break; + case R_028060_CB_COLOR0_SIZE: + case R_028064_CB_COLOR1_SIZE: +@@ -796,8 +969,6 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx + return -EINVAL; + } + ib[idx] = track->cb_color_base_last[tmp]; +- printk_once(KERN_WARNING "You have old & broken userspace " +- "please consider updating mesa & xf86-video-ati\n"); + track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; + } else { + r = r600_cs_packet_next_reloc(p, &reloc); +@@ -824,8 +995,6 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx + return -EINVAL; + } + ib[idx] = track->cb_color_base_last[tmp]; +- printk_once(KERN_WARNING "You have old & broken userspace " +- "please consider updating mesa & xf86-video-ati\n"); + track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; + } else { + r = r600_cs_packet_next_reloc(p, &reloc); +@@ -852,10 +1021,11 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx + return -EINVAL; + } + tmp = (reg - CB_COLOR0_BASE) / 4; +- track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx); ++ track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8; + ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + track->cb_color_base_last[tmp] = ib[idx]; + track->cb_color_bo[tmp] = reloc->robj; ++ track->cb_color_bo_mc[tmp] = reloc->lobj.gpu_offset; + break; + case DB_DEPTH_BASE: + r = r600_cs_packet_next_reloc(p, &reloc); +@@ -864,9 +1034,10 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx + "0x%04X\n", reg); + return -EINVAL; + } +- track->db_offset = radeon_get_ib_value(p, idx); ++ track->db_offset = radeon_get_ib_value(p, idx) << 8; + ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + track->db_bo = reloc->robj; ++ track->db_bo_mc = reloc->lobj.gpu_offset; + break; + case DB_HTILE_DATA_BASE: + case SQ_PGM_START_FS: +@@ -946,8 +1117,9 @@ static inline unsigned minify(unsigned size, unsigned levels) + } + + static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels, +- unsigned w0, unsigned h0, unsigned d0, unsigned bpe, +- unsigned *l0_size, unsigned *mipmap_size) ++ unsigned w0, unsigned h0, unsigned d0, unsigned bpe, ++ unsigned pitch_align, ++ unsigned *l0_size, unsigned *mipmap_size) + { + unsigned offset, i, level, face; + unsigned width, height, depth, rowstride, size; +@@ -960,18 +1132,18 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels + height = minify(h0, i); + depth = minify(d0, i); + for(face = 0; face < nfaces; face++) { +- rowstride = ((width * bpe) + 255) & ~255; ++ rowstride = ALIGN((width * bpe), pitch_align); + size = height * rowstride * depth; + offset += size; + offset = (offset + 0x1f) & ~0x1f; + } + } +- *l0_size = (((w0 * bpe) + 255) & ~255) * h0 * d0; ++ *l0_size = ALIGN((w0 * bpe), pitch_align) * h0 * d0; + *mipmap_size = offset; +- if (!blevel) +- *mipmap_size -= *l0_size; + if (!nlevels) + *mipmap_size = *l0_size; ++ if (!blevel) ++ *mipmap_size -= *l0_size; + } + + /** +@@ -985,16 +1157,32 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels + * the texture and mipmap bo object are big enough to cover this resource. + */ + static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, +- struct radeon_bo *texture, +- struct radeon_bo *mipmap) ++ struct radeon_bo *texture, ++ struct radeon_bo *mipmap, ++ u64 base_offset, ++ u64 mip_offset, ++ u32 tiling_flags) + { ++ struct r600_cs_track *track = p->track; + u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0; + u32 word0, word1, l0_size, mipmap_size; ++ u32 height_align, pitch, pitch_align, depth_align; ++ u64 base_align; ++ struct array_mode_checker array_check; + + /* on legacy kernel we don't perform advanced check */ + if (p->rdev == NULL) + return 0; ++ ++ /* convert to bytes */ ++ base_offset <<= 8; ++ mip_offset <<= 8; ++ + word0 = radeon_get_ib_value(p, idx + 0); ++ if (tiling_flags & RADEON_TILING_MACRO) ++ word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); ++ else if (tiling_flags & RADEON_TILING_MICRO) ++ word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); + word1 = radeon_get_ib_value(p, idx + 1); + w0 = G_038000_TEX_WIDTH(word0) + 1; + h0 = G_038004_TEX_HEIGHT(word1) + 1; +@@ -1021,24 +1209,59 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i + __func__, __LINE__, G_038004_DATA_FORMAT(word1)); + return -EINVAL; + } ++ ++ /* pitch in texels */ ++ pitch = (G_038000_PITCH(word0) + 1) * 8; ++ array_check.array_mode = G_038000_TILE_MODE(word0); ++ array_check.group_size = track->group_size; ++ array_check.nbanks = track->nbanks; ++ array_check.npipes = track->npipes; ++ array_check.nsamples = 1; ++ array_check.bpe = bpe; ++ if (r600_get_array_mode_alignment(&array_check, ++ &pitch_align, &height_align, &depth_align, &base_align)) { ++ dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", ++ __func__, __LINE__, G_038000_TILE_MODE(word0)); ++ return -EINVAL; ++ } ++ ++ /* XXX check height as well... */ ++ ++ if (!IS_ALIGNED(pitch, pitch_align)) { ++ dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", ++ __func__, __LINE__, pitch); ++ return -EINVAL; ++ } ++ if (!IS_ALIGNED(base_offset, base_align)) { ++ dev_warn(p->dev, "%s:%d tex base offset (0x%llx) invalid\n", ++ __func__, __LINE__, base_offset); ++ return -EINVAL; ++ } ++ if (!IS_ALIGNED(mip_offset, base_align)) { ++ dev_warn(p->dev, "%s:%d tex mip offset (0x%llx) invalid\n", ++ __func__, __LINE__, mip_offset); ++ return -EINVAL; ++ } ++ + word0 = radeon_get_ib_value(p, idx + 4); + word1 = radeon_get_ib_value(p, idx + 5); + blevel = G_038010_BASE_LEVEL(word0); + nlevels = G_038014_LAST_LEVEL(word1); +- r600_texture_size(nfaces, blevel, nlevels, w0, h0, d0, bpe, &l0_size, &mipmap_size); ++ r600_texture_size(nfaces, blevel, nlevels, w0, h0, d0, bpe, ++ (pitch_align * bpe), ++ &l0_size, &mipmap_size); + /* using get ib will give us the offset into the texture bo */ +- word0 = radeon_get_ib_value(p, idx + 2); ++ word0 = radeon_get_ib_value(p, idx + 2) << 8; + if ((l0_size + word0) > radeon_bo_size(texture)) { + dev_warn(p->dev, "texture bo too small (%d %d %d %d -> %d have %ld)\n", + w0, h0, bpe, word0, l0_size, radeon_bo_size(texture)); + return -EINVAL; + } + /* using get ib will give us the offset into the mipmap bo */ +- word0 = radeon_get_ib_value(p, idx + 3); ++ word0 = radeon_get_ib_value(p, idx + 3) << 8; + if ((mipmap_size + word0) > radeon_bo_size(mipmap)) { +- dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", +- w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture)); +- return -EINVAL; ++ /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", ++ w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture));*/ + } + return 0; + } +@@ -1228,7 +1451,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, + } + for (i = 0; i < (pkt->count / 7); i++) { + struct radeon_bo *texture, *mipmap; +- u32 size, offset; ++ u32 size, offset, base_offset, mip_offset; + + switch (G__SQ_VTX_CONSTANT_TYPE(radeon_get_ib_value(p, idx+(i*7)+6+1))) { + case SQ_TEX_VTX_VALID_TEXTURE: +@@ -1238,7 +1461,11 @@ static int r600_packet3_check(struct radeon_cs_parser *p, + DRM_ERROR("bad SET_RESOURCE\n"); + return -EINVAL; + } +- ib[idx+1+(i*7)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); ++ base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); ++ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) ++ ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); ++ else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) ++ ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); + texture = reloc->robj; + /* tex mip base */ + r = r600_cs_packet_next_reloc(p, &reloc); +@@ -1246,12 +1473,17 @@ static int r600_packet3_check(struct radeon_cs_parser *p, + DRM_ERROR("bad SET_RESOURCE\n"); + return -EINVAL; + } +- ib[idx+1+(i*7)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); ++ mip_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + mipmap = reloc->robj; + r = r600_check_texture_resource(p, idx+(i*7)+1, +- texture, mipmap); ++ texture, mipmap, ++ base_offset + radeon_get_ib_value(p, idx+1+(i*7)+2), ++ mip_offset + radeon_get_ib_value(p, idx+1+(i*7)+3), ++ reloc->lobj.tiling_flags); + if (r) + return r; ++ ib[idx+1+(i*7)+2] += base_offset; ++ ib[idx+1+(i*7)+3] += mip_offset; + break; + case SQ_TEX_VTX_VALID_BUFFER: + /* vtx base */ +@@ -1261,10 +1493,11 @@ static int r600_packet3_check(struct radeon_cs_parser *p, + return -EINVAL; + } + offset = radeon_get_ib_value(p, idx+1+(i*7)+0); +- size = radeon_get_ib_value(p, idx+1+(i*7)+1); ++ size = radeon_get_ib_value(p, idx+1+(i*7)+1) + 1; + if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) { + /* force size to size of the buffer */ +- dev_warn(p->dev, "vbo resource seems too big for the bo\n"); ++ dev_warn(p->dev, "vbo resource seems too big (%d) for the bo (%ld)\n", ++ size + offset, radeon_bo_size(reloc->robj)); + ib[idx+1+(i*7)+1] = radeon_bo_size(reloc->robj); + } + ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff); +diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h +index 84bc28e..9577945 100644 +--- a/drivers/gpu/drm/radeon/r600d.h ++++ b/drivers/gpu/drm/radeon/r600d.h +@@ -51,6 +51,12 @@ + #define PTE_READABLE (1 << 5) + #define PTE_WRITEABLE (1 << 6) + ++/* tiling bits */ ++#define ARRAY_LINEAR_GENERAL 0x00000000 ++#define ARRAY_LINEAR_ALIGNED 0x00000001 ++#define ARRAY_1D_TILED_THIN1 0x00000002 ++#define ARRAY_2D_TILED_THIN1 0x00000004 ++ + /* Registers */ + #define ARB_POP 0x2418 + #define ENABLE_TC128 (1 << 30) +@@ -1155,6 +1161,10 @@ + #define S_038000_TILE_MODE(x) (((x) & 0xF) << 3) + #define G_038000_TILE_MODE(x) (((x) >> 3) & 0xF) + #define C_038000_TILE_MODE 0xFFFFFF87 ++#define V_038000_ARRAY_LINEAR_GENERAL 0x00000000 ++#define V_038000_ARRAY_LINEAR_ALIGNED 0x00000001 ++#define V_038000_ARRAY_1D_TILED_THIN1 0x00000002 ++#define V_038000_ARRAY_2D_TILED_THIN1 0x00000004 + #define S_038000_TILE_TYPE(x) (((x) & 0x1) << 7) + #define G_038000_TILE_TYPE(x) (((x) >> 7) & 0x1) + #define C_038000_TILE_TYPE 0xFFFFFF7F +@@ -1358,6 +1368,8 @@ + #define S_028010_ARRAY_MODE(x) (((x) & 0xF) << 15) + #define G_028010_ARRAY_MODE(x) (((x) >> 15) & 0xF) + #define C_028010_ARRAY_MODE 0xFFF87FFF ++#define V_028010_ARRAY_1D_TILED_THIN1 0x00000002 ++#define V_028010_ARRAY_2D_TILED_THIN1 0x00000004 + #define S_028010_TILE_SURFACE_ENABLE(x) (((x) & 0x1) << 25) + #define G_028010_TILE_SURFACE_ENABLE(x) (((x) >> 25) & 0x1) + #define C_028010_TILE_SURFACE_ENABLE 0xFDFFFFFF diff --git a/drm-sil164-module.patch b/drm-sil164-module.patch new file mode 100644 index 000000000..06194e6a1 --- /dev/null +++ b/drm-sil164-module.patch @@ -0,0 +1,592 @@ +From f1719f0dcd68ca4de42c7b00ef2b37658007dda7 Mon Sep 17 00:00:00 2001 +From: Francisco Jerez +Date: Thu, 22 Jul 2010 17:06:18 +0200 +Subject: [PATCH 2/5] drm-sil164-module + +drm: Import driver for the sil164 I2C TMDS transmitter. + +sil164 transmitters are used for DVI outputs on Intel/nvidia and ATI setups. + +So far only nouveau can use this driver. + +Signed-off-by: Francisco Jerez +Tested-by: Patrice Mandin +Signed-off-by: Dave Airlie +--- + drivers/gpu/drm/i2c/Makefile | 3 + + drivers/gpu/drm/i2c/sil164_drv.c | 462 ++++++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/nouveau/Kconfig | 9 + + include/drm/i2c/sil164.h | 63 +++++ + 4 files changed, 537 insertions(+), 0 deletions(-) + create mode 100644 drivers/gpu/drm/i2c/sil164_drv.c + create mode 100644 include/drm/i2c/sil164.h + +diff --git a/drivers/gpu/drm/i2c/Makefile b/drivers/gpu/drm/i2c/Makefile +index 6d2abaf..9286256 100644 +--- a/drivers/gpu/drm/i2c/Makefile ++++ b/drivers/gpu/drm/i2c/Makefile +@@ -2,3 +2,6 @@ ccflags-y := -Iinclude/drm + + ch7006-y := ch7006_drv.o ch7006_mode.o + obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o ++ ++sil164-y := sil164_drv.o ++obj-$(CONFIG_DRM_I2C_SIL164) += sil164.o +diff --git a/drivers/gpu/drm/i2c/sil164_drv.c b/drivers/gpu/drm/i2c/sil164_drv.c +new file mode 100644 +index 0000000..0b67732 +--- /dev/null ++++ b/drivers/gpu/drm/i2c/sil164_drv.c +@@ -0,0 +1,462 @@ ++/* ++ * Copyright (C) 2010 Francisco Jerez. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#include "drmP.h" ++#include "drm_crtc_helper.h" ++#include "drm_encoder_slave.h" ++#include "i2c/sil164.h" ++ ++struct sil164_priv { ++ struct sil164_encoder_params config; ++ struct i2c_client *duallink_slave; ++ ++ uint8_t saved_state[0x10]; ++ uint8_t saved_slave_state[0x10]; ++}; ++ ++#define to_sil164_priv(x) \ ++ ((struct sil164_priv *)to_encoder_slave(x)->slave_priv) ++ ++#define sil164_dbg(client, format, ...) do { \ ++ if (drm_debug & DRM_UT_KMS) \ ++ dev_printk(KERN_DEBUG, &client->dev, \ ++ "%s: " format, __func__, ## __VA_ARGS__); \ ++ } while (0) ++#define sil164_info(client, format, ...) \ ++ dev_info(&client->dev, format, __VA_ARGS__) ++#define sil164_err(client, format, ...) \ ++ dev_err(&client->dev, format, __VA_ARGS__) ++ ++#define SIL164_I2C_ADDR_MASTER 0x38 ++#define SIL164_I2C_ADDR_SLAVE 0x39 ++ ++/* HW register definitions */ ++ ++#define SIL164_VENDOR_LO 0x0 ++#define SIL164_VENDOR_HI 0x1 ++#define SIL164_DEVICE_LO 0x2 ++#define SIL164_DEVICE_HI 0x3 ++#define SIL164_REVISION 0x4 ++#define SIL164_FREQ_MIN 0x6 ++#define SIL164_FREQ_MAX 0x7 ++#define SIL164_CONTROL0 0x8 ++# define SIL164_CONTROL0_POWER_ON 0x01 ++# define SIL164_CONTROL0_EDGE_RISING 0x02 ++# define SIL164_CONTROL0_INPUT_24BIT 0x04 ++# define SIL164_CONTROL0_DUAL_EDGE 0x08 ++# define SIL164_CONTROL0_HSYNC_ON 0x10 ++# define SIL164_CONTROL0_VSYNC_ON 0x20 ++#define SIL164_DETECT 0x9 ++# define SIL164_DETECT_INTR_STAT 0x01 ++# define SIL164_DETECT_HOTPLUG_STAT 0x02 ++# define SIL164_DETECT_RECEIVER_STAT 0x04 ++# define SIL164_DETECT_INTR_MODE_RECEIVER 0x00 ++# define SIL164_DETECT_INTR_MODE_HOTPLUG 0x08 ++# define SIL164_DETECT_OUT_MODE_HIGH 0x00 ++# define SIL164_DETECT_OUT_MODE_INTR 0x10 ++# define SIL164_DETECT_OUT_MODE_RECEIVER 0x20 ++# define SIL164_DETECT_OUT_MODE_HOTPLUG 0x30 ++# define SIL164_DETECT_VSWING_STAT 0x80 ++#define SIL164_CONTROL1 0xa ++# define SIL164_CONTROL1_DESKEW_ENABLE 0x10 ++# define SIL164_CONTROL1_DESKEW_INCR_SHIFT 5 ++#define SIL164_GPIO 0xb ++#define SIL164_CONTROL2 0xc ++# define SIL164_CONTROL2_FILTER_ENABLE 0x01 ++# define SIL164_CONTROL2_FILTER_SETTING_SHIFT 1 ++# define SIL164_CONTROL2_DUALLINK_MASTER 0x40 ++# define SIL164_CONTROL2_SYNC_CONT 0x80 ++#define SIL164_DUALLINK 0xd ++# define SIL164_DUALLINK_ENABLE 0x10 ++# define SIL164_DUALLINK_SKEW_SHIFT 5 ++#define SIL164_PLLZONE 0xe ++# define SIL164_PLLZONE_STAT 0x08 ++# define SIL164_PLLZONE_FORCE_ON 0x10 ++# define SIL164_PLLZONE_FORCE_HIGH 0x20 ++ ++/* HW access functions */ ++ ++static void ++sil164_write(struct i2c_client *client, uint8_t addr, uint8_t val) ++{ ++ uint8_t buf[] = {addr, val}; ++ int ret; ++ ++ ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); ++ if (ret < 0) ++ sil164_err(client, "Error %d writing to subaddress 0x%x\n", ++ ret, addr); ++} ++ ++static uint8_t ++sil164_read(struct i2c_client *client, uint8_t addr) ++{ ++ uint8_t val; ++ int ret; ++ ++ ret = i2c_master_send(client, &addr, sizeof(addr)); ++ if (ret < 0) ++ goto fail; ++ ++ ret = i2c_master_recv(client, &val, sizeof(val)); ++ if (ret < 0) ++ goto fail; ++ ++ return val; ++ ++fail: ++ sil164_err(client, "Error %d reading from subaddress 0x%x\n", ++ ret, addr); ++ return 0; ++} ++ ++static void ++sil164_save_state(struct i2c_client *client, uint8_t *state) ++{ ++ int i; ++ ++ for (i = 0x8; i <= 0xe; i++) ++ state[i] = sil164_read(client, i); ++} ++ ++static void ++sil164_restore_state(struct i2c_client *client, uint8_t *state) ++{ ++ int i; ++ ++ for (i = 0x8; i <= 0xe; i++) ++ sil164_write(client, i, state[i]); ++} ++ ++static void ++sil164_set_power_state(struct i2c_client *client, bool on) ++{ ++ uint8_t control0 = sil164_read(client, SIL164_CONTROL0); ++ ++ if (on) ++ control0 |= SIL164_CONTROL0_POWER_ON; ++ else ++ control0 &= ~SIL164_CONTROL0_POWER_ON; ++ ++ sil164_write(client, SIL164_CONTROL0, control0); ++} ++ ++static void ++sil164_init_state(struct i2c_client *client, ++ struct sil164_encoder_params *config, ++ bool duallink) ++{ ++ sil164_write(client, SIL164_CONTROL0, ++ SIL164_CONTROL0_HSYNC_ON | ++ SIL164_CONTROL0_VSYNC_ON | ++ (config->input_edge ? SIL164_CONTROL0_EDGE_RISING : 0) | ++ (config->input_width ? SIL164_CONTROL0_INPUT_24BIT : 0) | ++ (config->input_dual ? SIL164_CONTROL0_DUAL_EDGE : 0)); ++ ++ sil164_write(client, SIL164_DETECT, ++ SIL164_DETECT_INTR_STAT | ++ SIL164_DETECT_OUT_MODE_RECEIVER); ++ ++ sil164_write(client, SIL164_CONTROL1, ++ (config->input_skew ? SIL164_CONTROL1_DESKEW_ENABLE : 0) | ++ (((config->input_skew + 4) & 0x7) ++ << SIL164_CONTROL1_DESKEW_INCR_SHIFT)); ++ ++ sil164_write(client, SIL164_CONTROL2, ++ SIL164_CONTROL2_SYNC_CONT | ++ (config->pll_filter ? 0 : SIL164_CONTROL2_FILTER_ENABLE) | ++ (4 << SIL164_CONTROL2_FILTER_SETTING_SHIFT)); ++ ++ sil164_write(client, SIL164_PLLZONE, 0); ++ ++ if (duallink) ++ sil164_write(client, SIL164_DUALLINK, ++ SIL164_DUALLINK_ENABLE | ++ (((config->duallink_skew + 4) & 0x7) ++ << SIL164_DUALLINK_SKEW_SHIFT)); ++ else ++ sil164_write(client, SIL164_DUALLINK, 0); ++} ++ ++/* DRM encoder functions */ ++ ++static void ++sil164_encoder_set_config(struct drm_encoder *encoder, void *params) ++{ ++ struct sil164_priv *priv = to_sil164_priv(encoder); ++ ++ priv->config = *(struct sil164_encoder_params *)params; ++} ++ ++static void ++sil164_encoder_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct sil164_priv *priv = to_sil164_priv(encoder); ++ bool on = (mode == DRM_MODE_DPMS_ON); ++ bool duallink = (on && encoder->crtc->mode.clock > 165000); ++ ++ sil164_set_power_state(drm_i2c_encoder_get_client(encoder), on); ++ ++ if (priv->duallink_slave) ++ sil164_set_power_state(priv->duallink_slave, duallink); ++} ++ ++static void ++sil164_encoder_save(struct drm_encoder *encoder) ++{ ++ struct sil164_priv *priv = to_sil164_priv(encoder); ++ ++ sil164_save_state(drm_i2c_encoder_get_client(encoder), ++ priv->saved_state); ++ ++ if (priv->duallink_slave) ++ sil164_save_state(priv->duallink_slave, ++ priv->saved_slave_state); ++} ++ ++static void ++sil164_encoder_restore(struct drm_encoder *encoder) ++{ ++ struct sil164_priv *priv = to_sil164_priv(encoder); ++ ++ sil164_restore_state(drm_i2c_encoder_get_client(encoder), ++ priv->saved_state); ++ ++ if (priv->duallink_slave) ++ sil164_restore_state(priv->duallink_slave, ++ priv->saved_slave_state); ++} ++ ++static bool ++sil164_encoder_mode_fixup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ return true; ++} ++ ++static int ++sil164_encoder_mode_valid(struct drm_encoder *encoder, ++ struct drm_display_mode *mode) ++{ ++ struct sil164_priv *priv = to_sil164_priv(encoder); ++ ++ if (mode->clock < 32000) ++ return MODE_CLOCK_LOW; ++ ++ if (mode->clock > 330000 || ++ (mode->clock > 165000 && !priv->duallink_slave)) ++ return MODE_CLOCK_HIGH; ++ ++ return MODE_OK; ++} ++ ++static void ++sil164_encoder_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct sil164_priv *priv = to_sil164_priv(encoder); ++ bool duallink = adjusted_mode->clock > 165000; ++ ++ sil164_init_state(drm_i2c_encoder_get_client(encoder), ++ &priv->config, duallink); ++ ++ if (priv->duallink_slave) ++ sil164_init_state(priv->duallink_slave, ++ &priv->config, duallink); ++ ++ sil164_encoder_dpms(encoder, DRM_MODE_DPMS_ON); ++} ++ ++static enum drm_connector_status ++sil164_encoder_detect(struct drm_encoder *encoder, ++ struct drm_connector *connector) ++{ ++ struct i2c_client *client = drm_i2c_encoder_get_client(encoder); ++ ++ if (sil164_read(client, SIL164_DETECT) & SIL164_DETECT_HOTPLUG_STAT) ++ return connector_status_connected; ++ else ++ return connector_status_disconnected; ++} ++ ++static int ++sil164_encoder_get_modes(struct drm_encoder *encoder, ++ struct drm_connector *connector) ++{ ++ return 0; ++} ++ ++static int ++sil164_encoder_create_resources(struct drm_encoder *encoder, ++ struct drm_connector *connector) ++{ ++ return 0; ++} ++ ++static int ++sil164_encoder_set_property(struct drm_encoder *encoder, ++ struct drm_connector *connector, ++ struct drm_property *property, ++ uint64_t val) ++{ ++ return 0; ++} ++ ++static void ++sil164_encoder_destroy(struct drm_encoder *encoder) ++{ ++ struct sil164_priv *priv = to_sil164_priv(encoder); ++ ++ if (priv->duallink_slave) ++ i2c_unregister_device(priv->duallink_slave); ++ ++ kfree(priv); ++ drm_i2c_encoder_destroy(encoder); ++} ++ ++static struct drm_encoder_slave_funcs sil164_encoder_funcs = { ++ .set_config = sil164_encoder_set_config, ++ .destroy = sil164_encoder_destroy, ++ .dpms = sil164_encoder_dpms, ++ .save = sil164_encoder_save, ++ .restore = sil164_encoder_restore, ++ .mode_fixup = sil164_encoder_mode_fixup, ++ .mode_valid = sil164_encoder_mode_valid, ++ .mode_set = sil164_encoder_mode_set, ++ .detect = sil164_encoder_detect, ++ .get_modes = sil164_encoder_get_modes, ++ .create_resources = sil164_encoder_create_resources, ++ .set_property = sil164_encoder_set_property, ++}; ++ ++/* I2C driver functions */ ++ ++static int ++sil164_probe(struct i2c_client *client, const struct i2c_device_id *id) ++{ ++ int vendor = sil164_read(client, SIL164_VENDOR_HI) << 8 | ++ sil164_read(client, SIL164_VENDOR_LO); ++ int device = sil164_read(client, SIL164_DEVICE_HI) << 8 | ++ sil164_read(client, SIL164_DEVICE_LO); ++ int rev = sil164_read(client, SIL164_REVISION); ++ ++ if (vendor != 0x1 || device != 0x6) { ++ sil164_dbg(client, "Unknown device %x:%x.%x\n", ++ vendor, device, rev); ++ return -ENODEV; ++ } ++ ++ sil164_info(client, "Detected device %x:%x.%x\n", ++ vendor, device, rev); ++ ++ return 0; ++} ++ ++static int ++sil164_remove(struct i2c_client *client) ++{ ++ return 0; ++} ++ ++static struct i2c_client * ++sil164_detect_slave(struct i2c_client *client) ++{ ++ struct i2c_adapter *adap = client->adapter; ++ struct i2c_msg msg = { ++ .addr = SIL164_I2C_ADDR_SLAVE, ++ .len = 0, ++ }; ++ const struct i2c_board_info info = { ++ I2C_BOARD_INFO("sil164", SIL164_I2C_ADDR_SLAVE) ++ }; ++ ++ if (i2c_transfer(adap, &msg, 1) != 1) { ++ sil164_dbg(adap, "No dual-link slave found."); ++ return NULL; ++ } ++ ++ return i2c_new_device(adap, &info); ++} ++ ++static int ++sil164_encoder_init(struct i2c_client *client, ++ struct drm_device *dev, ++ struct drm_encoder_slave *encoder) ++{ ++ struct sil164_priv *priv; ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ encoder->slave_priv = priv; ++ encoder->slave_funcs = &sil164_encoder_funcs; ++ ++ priv->duallink_slave = sil164_detect_slave(client); ++ ++ return 0; ++} ++ ++static struct i2c_device_id sil164_ids[] = { ++ { "sil164", 0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(i2c, sil164_ids); ++ ++static struct drm_i2c_encoder_driver sil164_driver = { ++ .i2c_driver = { ++ .probe = sil164_probe, ++ .remove = sil164_remove, ++ .driver = { ++ .name = "sil164", ++ }, ++ .id_table = sil164_ids, ++ }, ++ .encoder_init = sil164_encoder_init, ++}; ++ ++/* Module initialization */ ++ ++static int __init ++sil164_init(void) ++{ ++ return drm_i2c_encoder_register(THIS_MODULE, &sil164_driver); ++} ++ ++static void __exit ++sil164_exit(void) ++{ ++ drm_i2c_encoder_unregister(&sil164_driver); ++} ++ ++MODULE_AUTHOR("Francisco Jerez "); ++MODULE_DESCRIPTION("Silicon Image sil164 TMDS transmitter driver"); ++MODULE_LICENSE("GPL and additional rights"); ++ ++module_init(sil164_init); ++module_exit(sil164_exit); +diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig +index 1175429..6b8967a 100644 +--- a/drivers/gpu/drm/nouveau/Kconfig ++++ b/drivers/gpu/drm/nouveau/Kconfig +@@ -41,4 +41,13 @@ config DRM_I2C_CH7006 + + This driver is currently only useful if you're also using + the nouveau driver. ++ ++config DRM_I2C_SIL164 ++ tristate "Silicon Image sil164 TMDS transmitter" ++ default m if DRM_NOUVEAU ++ help ++ Support for sil164 and similar single-link (or dual-link ++ when used in pairs) TMDS transmitters, used in some nVidia ++ video cards. ++ + endmenu +diff --git a/include/drm/i2c/sil164.h b/include/drm/i2c/sil164.h +new file mode 100644 +index 0000000..205e273 +--- /dev/null ++++ b/include/drm/i2c/sil164.h +@@ -0,0 +1,63 @@ ++/* ++ * Copyright (C) 2010 Francisco Jerez. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ */ ++ ++#ifndef __DRM_I2C_SIL164_H__ ++#define __DRM_I2C_SIL164_H__ ++ ++/** ++ * struct sil164_encoder_params ++ * ++ * Describes how the sil164 is connected to the GPU. It should be used ++ * as the @params parameter of its @set_config method. ++ * ++ * See "http://www.siliconimage.com/docs/SiI-DS-0021-E-164.pdf". ++ */ ++struct sil164_encoder_params { ++ enum { ++ SIL164_INPUT_EDGE_FALLING = 0, ++ SIL164_INPUT_EDGE_RISING ++ } input_edge; ++ ++ enum { ++ SIL164_INPUT_WIDTH_12BIT = 0, ++ SIL164_INPUT_WIDTH_24BIT ++ } input_width; ++ ++ enum { ++ SIL164_INPUT_SINGLE_EDGE = 0, ++ SIL164_INPUT_DUAL_EDGE ++ } input_dual; ++ ++ enum { ++ SIL164_PLL_FILTER_ON = 0, ++ SIL164_PLL_FILTER_OFF, ++ } pll_filter; ++ ++ int input_skew; /** < Allowed range [-4, 3], use 0 for no de-skew. */ ++ int duallink_skew; /** < Allowed range [-4, 3]. */ ++}; ++ ++#endif +-- +1.7.2 + diff --git a/drm-simplify-i2c-config.patch b/drm-simplify-i2c-config.patch new file mode 100644 index 000000000..c1fed73d7 --- /dev/null +++ b/drm-simplify-i2c-config.patch @@ -0,0 +1,45 @@ +From 74ef65374ae6d0eead4a631aea3aca80d016ff0f Mon Sep 17 00:00:00 2001 +From: Francisco Jerez +Date: Thu, 22 Jul 2010 17:07:38 +0200 +Subject: [PATCH 1/5] drm-simplify-i2c-config + +drm/kms: Simplify setup of the initial I2C encoder config. + +In most use cases the driver will be using the same static config all +the time: interpreting i2c_board_info::platform_data as the default +config we can can save the GPU driver a redundant set_config() call. + +Signed-off-by: Francisco Jerez +Signed-off-by: Dave Airlie +--- + drivers/gpu/drm/drm_encoder_slave.c | 7 +++++++ + 1 files changed, 7 insertions(+), 0 deletions(-) + +diff --git a/drivers/gpu/drm/drm_encoder_slave.c b/drivers/gpu/drm/drm_encoder_slave.c +index f018469..d62c064 100644 +--- a/drivers/gpu/drm/drm_encoder_slave.c ++++ b/drivers/gpu/drm/drm_encoder_slave.c +@@ -41,6 +41,9 @@ + * &drm_encoder_slave. The @slave_funcs field will be initialized with + * the hooks provided by the slave driver. + * ++ * If @info->platform_data is non-NULL it will be used as the initial ++ * slave config. ++ * + * Returns 0 on success or a negative errno on failure, in particular, + * -ENODEV is returned when no matching driver is found. + */ +@@ -85,6 +88,10 @@ int drm_i2c_encoder_init(struct drm_device *dev, + if (err) + goto fail_unregister; + ++ if (info->platform_data) ++ encoder->slave_funcs->set_config(&encoder->base, ++ info->platform_data); ++ + return 0; + + fail_unregister: +-- +1.7.2 + diff --git a/drm-ttm-fix-two-race-conditions-fix-busy-codepaths.patch b/drm-ttm-fix-two-race-conditions-fix-busy-codepaths.patch new file mode 100644 index 000000000..0eed9edd1 --- /dev/null +++ b/drm-ttm-fix-two-race-conditions-fix-busy-codepaths.patch @@ -0,0 +1,171 @@ +From 08ae078a33245bc01dcf895bd886f30103cc6178 Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom +Date: Thu, 30 Sep 2010 12:36:45 +0200 +Subject: drm/ttm: Fix two race conditions + fix busy codepaths + +This fixes a race pointed out by Dave Airlie where we don't take a buffer +object about to be destroyed off the LRU lists properly. It also fixes a rare +case where a buffer object could be destroyed in the middle of an +accelerated eviction. + +The patch also adds a utility function that can be used to prematurely +release GPU memory space usage of an object waiting to be destroyed. +For example during eviction or swapout. + +The above mentioned commit didn't queue the buffer on the delayed destroy +list under some rare circumstances. It also didn't completely honor the +remove_all parameter. + +Fixes: +https://bugzilla.redhat.com/show_bug.cgi?id=615505 +http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=591061 + +Signed-off-by: Thomas Hellstrom +Signed-off-by: Dave Airlie +--- + drivers/gpu/drm/ttm/ttm_bo.c | 84 +++++++++++++++++++++++++++++++++++------ + include/drm/ttm/ttm_bo_api.h | 4 +- + 2 files changed, 74 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c +index 555ebb1..77f22ba 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo.c ++++ b/drivers/gpu/drm/ttm/ttm_bo.c +@@ -442,6 +442,43 @@ out_err: + } + + /** ++ * Call bo::reserved and with the lru lock held. ++ * Will release GPU memory type usage on destruction. ++ * This is the place to put in driver specific hooks. ++ * Will release the bo::reserved lock and the ++ * lru lock on exit. ++ */ ++ ++static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo) ++{ ++ struct ttm_bo_global *glob = bo->glob; ++ ++ if (bo->ttm) { ++ ++ /** ++ * Release the lru_lock, since we don't want to have ++ * an atomic requirement on ttm_tt[unbind|destroy]. ++ */ ++ ++ spin_unlock(&glob->lru_lock); ++ ttm_tt_unbind(bo->ttm); ++ ttm_tt_destroy(bo->ttm); ++ bo->ttm = NULL; ++ spin_lock(&glob->lru_lock); ++ } ++ ++ if (bo->mem.mm_node) { ++ drm_mm_put_block(bo->mem.mm_node); ++ bo->mem.mm_node = NULL; ++ } ++ ++ atomic_set(&bo->reserved, 0); ++ wake_up_all(&bo->event_queue); ++ spin_unlock(&glob->lru_lock); ++} ++ ++ ++/** + * If bo idle, remove from delayed- and lru lists, and unref. + * If not idle, and already on delayed list, do nothing. + * If not idle, and not on delayed list, put on delayed list, +@@ -456,6 +493,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) + int ret; + + spin_lock(&bo->lock); ++retry: + (void) ttm_bo_wait(bo, false, false, !remove_all); + + if (!bo->sync_obj) { +@@ -464,32 +502,52 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) + spin_unlock(&bo->lock); + + spin_lock(&glob->lru_lock); +- put_count = ttm_bo_del_from_lru(bo); ++ ret = ttm_bo_reserve_locked(bo, false, !remove_all, false, 0); ++ ++ /** ++ * Someone else has the object reserved. Bail and retry. ++ */ + +- ret = ttm_bo_reserve_locked(bo, false, false, false, 0); +- BUG_ON(ret); +- if (bo->ttm) +- ttm_tt_unbind(bo->ttm); ++ if (unlikely(ret == -EBUSY)) { ++ spin_unlock(&glob->lru_lock); ++ spin_lock(&bo->lock); ++ goto requeue; ++ } ++ ++ /** ++ * We can re-check for sync object without taking ++ * the bo::lock since setting the sync object requires ++ * also bo::reserved. A busy object at this point may ++ * be caused by another thread starting an accelerated ++ * eviction. ++ */ ++ ++ if (unlikely(bo->sync_obj)) { ++ atomic_set(&bo->reserved, 0); ++ wake_up_all(&bo->event_queue); ++ spin_unlock(&glob->lru_lock); ++ spin_lock(&bo->lock); ++ if (remove_all) ++ goto retry; ++ else ++ goto requeue; ++ } ++ ++ put_count = ttm_bo_del_from_lru(bo); + + if (!list_empty(&bo->ddestroy)) { + list_del_init(&bo->ddestroy); + ++put_count; + } +- if (bo->mem.mm_node) { +- bo->mem.mm_node->private = NULL; +- drm_mm_put_block(bo->mem.mm_node); +- bo->mem.mm_node = NULL; +- } +- spin_unlock(&glob->lru_lock); + +- atomic_set(&bo->reserved, 0); ++ ttm_bo_cleanup_memtype_use(bo); + + while (put_count--) + kref_put(&bo->list_kref, ttm_bo_ref_bug); + + return 0; + } +- ++requeue: + spin_lock(&glob->lru_lock); + if (list_empty(&bo->ddestroy)) { + void *sync_obj = bo->sync_obj; +diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h +index 267a86c..2040e6c 100644 +--- a/include/drm/ttm/ttm_bo_api.h ++++ b/include/drm/ttm/ttm_bo_api.h +@@ -246,9 +246,11 @@ struct ttm_buffer_object { + + atomic_t reserved; + +- + /** + * Members protected by the bo::lock ++ * In addition, setting sync_obj to anything else ++ * than NULL requires bo::reserved to be held. This allows for ++ * checking NULL while reserved but not holding bo::lock. + */ + + void *sync_obj_arg; +-- +1.7.3.2 + diff --git a/drm-ttm-fix.patch b/drm-ttm-fix.patch new file mode 100644 index 000000000..f0b0c1204 --- /dev/null +++ b/drm-ttm-fix.patch @@ -0,0 +1,39 @@ +From 0fbecd400dd0a82d465b3086f209681e8c54cb0f Mon Sep 17 00:00:00 2001 +From: Francisco Jerez +Date: Tue, 21 Sep 2010 02:15:15 +0200 +Subject: [PATCH] drm/ttm: Clear the ghost cpu_writers flag on ttm_buffer_object_transfer. + +It makes sense for a BO to move after a process has requested +exclusive RW access on it (e.g. because the BO used to be located in +unmappable VRAM and we intercepted the CPU access from the fault +handler). + +If we let the ghost object inherit cpu_writers from the original +object, ttm_bo_release_list() will raise a kernel BUG when the ghost +object is destroyed. This can be reproduced with the nouveau driver on +nv5x. + +Reported-by: Marcin Slusarz +Reviewed-by: Jerome Glisse +Tested-by: Marcin Slusarz +Signed-off-by: Francisco Jerez +Signed-off-by: Dave Airlie +--- + drivers/gpu/drm/ttm/ttm_bo_util.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c +index 7cffb3e..3451a82 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo_util.c ++++ b/drivers/gpu/drm/ttm/ttm_bo_util.c +@@ -351,6 +351,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, + INIT_LIST_HEAD(&fbo->lru); + INIT_LIST_HEAD(&fbo->swap); + fbo->vm_node = NULL; ++ atomic_set(&fbo->cpu_writers, 0); + + fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); + kref_init(&fbo->list_kref); +-- +1.7.3.1 + diff --git a/e1000e-82566DC-fails-to-get-link.patch b/e1000e-82566DC-fails-to-get-link.patch new file mode 100644 index 000000000..5a0c1dc27 --- /dev/null +++ b/e1000e-82566DC-fails-to-get-link.patch @@ -0,0 +1,55 @@ +From: Bruce Allan +Date: Wed, 22 Sep 2010 17:15:54 +0000 (+0000) +Subject: e1000e: 82566DC fails to get link +X-Git-Tag: v2.6.36-rc6~6^2~23 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=5f3eed6fe0e36e4b56c8dd9160241a868ee0de2a + +e1000e: 82566DC fails to get link + +Two recent patches to cleanup the reset[1] and initial PHY configuration[2] +code paths for ICH/PCH devices inadvertently left out a 10msec delay and +device ID check respectively which are necessary for the 82566DC (device id +0x104b) to be configured properly, otherwise it will not get link. + +[1] commit e98cac447cc1cc418dff1d610a5c79c4f2bdec7f +[2] commit 3f0c16e84438d657d29446f85fe375794a93f159 + +CC: stable@kernel.org +Signed-off-by: Bruce Allan +Tested-by: Jeff Pieper +Signed-off-by: Jeff Kirsher +Signed-off-by: David S. Miller +--- + +diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c +index fc8c3ce..6f9cb0d 100644 +--- a/drivers/net/e1000e/ich8lan.c ++++ b/drivers/net/e1000e/ich8lan.c +@@ -932,7 +932,6 @@ out: + **/ + static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) + { +- struct e1000_adapter *adapter = hw->adapter; + struct e1000_phy_info *phy = &hw->phy; + u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; + s32 ret_val = 0; +@@ -950,7 +949,8 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) + if (phy->type != e1000_phy_igp_3) + return ret_val; + +- if (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) { ++ if ((hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) || ++ (hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_C)) { + sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; + break; + } +@@ -1626,6 +1626,9 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) + if (e1000_check_reset_block(hw)) + goto out; + ++ /* Allow time for h/w to get to quiescent state after reset */ ++ msleep(10); ++ + /* Perform any necessary post-reset workarounds */ + switch (hw->mac.type) { + case e1000_pchlan: diff --git a/e1000e-cleanup-e1000_sw_lcd_config_ich8lan.patch b/e1000e-cleanup-e1000_sw_lcd_config_ich8lan.patch new file mode 100644 index 000000000..d56ae5c00 --- /dev/null +++ b/e1000e-cleanup-e1000_sw_lcd_config_ich8lan.patch @@ -0,0 +1,68 @@ +From: Bruce Allan +Date: Wed, 16 Jun 2010 13:26:17 +0000 (+0000) +Subject: e1000e: cleanup e1000_sw_lcd_config_ich8lan() +X-Git-Tag: v2.6.36-rc1~571^2~529 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=3f0c16e84438d657d29446f85fe375794a93f159 + +e1000e: cleanup e1000_sw_lcd_config_ich8lan() + +Do not acquire and release the PHY unnecessarily for parts that return +from this workaround without actually accessing the PHY registers. + +Signed-off-by: Bruce Allan +Tested-by: Jeff Pieper +Signed-off-by: Jeff Kirsher +Signed-off-by: David S. Miller +--- + +diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c +index b2507d9..5d8fad3 100644 +--- a/drivers/net/e1000e/ich8lan.c ++++ b/drivers/net/e1000e/ich8lan.c +@@ -820,14 +820,6 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) + s32 ret_val = 0; + u16 word_addr, reg_data, reg_addr, phy_page = 0; + +- if (!(hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) && +- !(hw->mac.type == e1000_pchlan)) +- return ret_val; +- +- ret_val = hw->phy.ops.acquire(hw); +- if (ret_val) +- return ret_val; +- + /* + * Initialize the PHY from the NVM on ICH platforms. This + * is needed due to an issue where the NVM configuration is +@@ -835,12 +827,26 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) + * Therefore, after each PHY reset, we will load the + * configuration data out of the NVM manually. + */ +- if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) || +- (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M) || +- (hw->mac.type == e1000_pchlan)) ++ switch (hw->mac.type) { ++ case e1000_ich8lan: ++ if (phy->type != e1000_phy_igp_3) ++ return ret_val; ++ ++ if (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) { ++ sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; ++ break; ++ } ++ /* Fall-thru */ ++ case e1000_pchlan: + sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; +- else +- sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; ++ break; ++ default: ++ return ret_val; ++ } ++ ++ ret_val = hw->phy.ops.acquire(hw); ++ if (ret_val) ++ return ret_val; + + data = er32(FEXTNVM); + if (!(data & sw_cfg_mask)) diff --git a/efifb-add-more-models.patch b/efifb-add-more-models.patch new file mode 100644 index 000000000..81c4ecf6a --- /dev/null +++ b/efifb-add-more-models.patch @@ -0,0 +1,124 @@ +commit a5757c2a474a15f87e5baa9a4caacc31cde2bae6 +Author: Luke Macken +Date: Wed Sep 22 13:05:04 2010 -0700 + + efifb: support the EFI framebuffer on more Apple hardware + + Enable the EFI framebuffer on 14 more Macs, including the iMac11,1 + iMac10,1 iMac8,1 Macmini3,1 Macmini4,1 MacBook5,1 MacBook6,1 MacBook7,1 + MacBookPro2,2 MacBookPro5,2 MacBookPro5,3 MacBookPro6,1 MacBookPro6,2 and + MacBookPro7,1 + + Information gathered from various user submissions. + + https://bugzilla.redhat.com/show_bug.cgi?id=528232 + http://ubuntuforums.org/showthread.php?t=1557326 + + [akpm@linux-foundation.org: coding-style fixes] + Signed-off-by: Luke Macken + Signed-off-by: Peter Jones + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + +diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c +index c082b61..70477c2 100644 +--- a/drivers/video/efifb.c ++++ b/drivers/video/efifb.c +@@ -39,17 +39,31 @@ enum { + M_I20, /* 20-Inch iMac */ + M_I20_SR, /* 20-Inch iMac (Santa Rosa) */ + M_I24, /* 24-Inch iMac */ ++ M_I24_8_1, /* 24-Inch iMac, 8,1th gen */ ++ M_I24_10_1, /* 24-Inch iMac, 10,1th gen */ ++ M_I27_11_1, /* 27-Inch iMac, 11,1th gen */ + M_MINI, /* Mac Mini */ ++ M_MINI_3_1, /* Mac Mini, 3,1th gen */ ++ M_MINI_4_1, /* Mac Mini, 4,1th gen */ + M_MB, /* MacBook */ + M_MB_2, /* MacBook, 2nd rev. */ + M_MB_3, /* MacBook, 3rd rev. */ ++ M_MB_5_1, /* MacBook, 5th rev. */ ++ M_MB_6_1, /* MacBook, 6th rev. */ ++ M_MB_7_1, /* MacBook, 7th rev. */ + M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ + M_MBA, /* MacBook Air */ + M_MBP, /* MacBook Pro */ + M_MBP_2, /* MacBook Pro 2nd gen */ ++ M_MBP_2_2, /* MacBook Pro 2,2nd gen */ + M_MBP_SR, /* MacBook Pro (Santa Rosa) */ + M_MBP_4, /* MacBook Pro, 4th gen */ + M_MBP_5_1, /* MacBook Pro, 5,1th gen */ ++ M_MBP_5_2, /* MacBook Pro, 5,2th gen */ ++ M_MBP_5_3, /* MacBook Pro, 5,3rd gen */ ++ M_MBP_6_1, /* MacBook Pro, 6,1th gen */ ++ M_MBP_6_2, /* MacBook Pro, 6,2th gen */ ++ M_MBP_7_1, /* MacBook Pro, 7,1th gen */ + M_UNKNOWN /* placeholder */ + }; + +@@ -64,14 +78,28 @@ static struct efifb_dmi_info { + [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */ + [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 }, + [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */ ++ [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200 }, ++ [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080 }, ++ [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440 }, + [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 }, ++ [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768 }, ++ [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200 }, + [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 }, ++ [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800 }, ++ [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800 }, ++ [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800 }, + [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 }, + [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 }, + [M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */ ++ [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900 }, + [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 }, + [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 }, + [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 }, ++ [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200 }, ++ [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900 }, ++ [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200 }, ++ [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050 }, ++ [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800 }, + [M_UNKNOWN] = { NULL, 0, 0, 0, 0 } + }; + +@@ -92,7 +120,12 @@ static const struct dmi_system_id dmi_system_table[] __initconst = { + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24), + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24), + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR), ++ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1), ++ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1), ++ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1), + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI), ++ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1), ++ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1), + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB), + /* At least one of these two will be right; maybe both? */ + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB), +@@ -101,14 +134,23 @@ static const struct dmi_system_id dmi_system_table[] __initconst = { + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB), + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB), + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB), ++ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1), ++ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1), ++ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1), + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), ++ EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2), + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2), + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR), + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR), + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4), + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1), ++ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2), ++ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3), ++ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1), ++ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2), ++ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1), + {}, + }; + diff --git a/efifb-check-that-the-base-addr-is-plausible-on-pci-systems.patch b/efifb-check-that-the-base-addr-is-plausible-on-pci-systems.patch new file mode 100644 index 000000000..a96fd9805 --- /dev/null +++ b/efifb-check-that-the-base-addr-is-plausible-on-pci-systems.patch @@ -0,0 +1,135 @@ +commit 85a00d9bbfb4704fbf368944b1cb9fed8f1598c5 +Author: Peter Jones +Date: Wed Sep 22 13:05:04 2010 -0700 + + efifb: check that the base address is plausible on pci systems + + Some Apple machines have identical DMI data but different memory + configurations for the video. Given that, check that the address in our + table is actually within the range of a PCI BAR on a VGA device in the + machine. + + This also fixes up the return value from set_system(), which has always + been wrong, but never resulted in bad behavior since there's only ever + been one matching entry in the dmi table. + + The patch + + 1) stops people's machines from crashing when we get their display wrong, + which seems to be unfortunately inevitable, + + 2) allows us to support identical dmi data with differing video memory + configurations + + This also adds me as the efifb maintainer, since I've effectively been + acting as such for quite some time. + + Signed-off-by: Peter Jones + Signed-off-by: Andrew Morton + Signed-off-by: Linus Torvalds + +diff --git a/MAINTAINERS b/MAINTAINERS +index 726433a..4d4881d 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -2199,6 +2199,12 @@ W: http://acpi4asus.sf.net + S: Maintained + F: drivers/platform/x86/eeepc-laptop.c + ++EFIFB FRAMEBUFFER DRIVER ++L: linux-fbdev@vger.kernel.org ++M: Peter Jones ++S: Maintained ++F: drivers/video/efifb.c ++ + EFS FILESYSTEM + W: http://aeschi.ch.eu.org/efs/ + S: Orphan +diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c +index 815f84b..c082b61 100644 +--- a/drivers/video/efifb.c ++++ b/drivers/video/efifb.c +@@ -13,7 +13,7 @@ + #include + #include + #include +- ++#include + #include