From 4efc3fff0056774a530ef1fda5cbf87fdfcada09 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Jun 30 2011 18:25:29 +0000 Subject: 2.6.39 rebase --- diff --git a/TODO b/TODO deleted file mode 100644 index abaefae..0000000 --- a/TODO +++ /dev/null @@ -1,61 +0,0 @@ -# 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/acpi_reboot.patch b/acpi_reboot.patch deleted file mode 100644 index 82bffaa..0000000 --- a/acpi_reboot.patch +++ /dev/null @@ -1,106 +0,0 @@ -Improve our reboot handling for compatibility with Windows. - -Upstream commits: -660e34cebf0a11d54f2d5dd8838607452355f321 -f17d9cbf20c4734c4199caa6dee87047f2f8278f - -diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c -index c495aa8..c770e66 100644 ---- a/arch/x86/kernel/reboot.c -+++ b/arch/x86/kernel/reboot.c -@@ -34,7 +34,7 @@ EXPORT_SYMBOL(pm_power_off); - - static const struct desc_ptr no_idt = {}; - static int reboot_mode; --enum reboot_type reboot_type = BOOT_KBD; -+enum reboot_type reboot_type = BOOT_ACPI; - int reboot_force; - - #if defined(CONFIG_X86_32) && defined(CONFIG_SMP) -@@ -538,9 +538,23 @@ void __attribute__((weak)) mach_reboot_fixups(void) - { - } - -+/* -+ * Windows does the following on reboot: -+ * 1) If the FADT has the ACPI reboot register flag set, try it -+ * 2) If still alive, write to the keyboard controller -+ * 3) If still alive, write to the ACPI reboot register again -+ * 4) Ig still alive, write to the keyboard controller again -+ * -+ * If the machine is still alive at this stage, it gives up. We default to -+ * following the same pattern, except that if we're still alive after (4) we'll -+ * try to force a triple fault and then cycle between hitting the keyboard -+ * controller and doing that -+ */ - static void native_machine_emergency_restart(void) - { - int i; -+ int attempt = 0; -+ int orig_reboot_type = reboot_type; - - if (reboot_emergency) - emergency_vmx_disable_all(); -@@ -562,6 +576,13 @@ static void native_machine_emergency_restart(void) - outb(0xfe, 0x64); /* pulse reset low */ - udelay(50); - } -+ if (attempt == 0 && orig_reboot_type == BOOT_ACPI) { -+ attempt = 1; -+ reboot_type = BOOT_ACPI; -+ } else { -+ reboot_type = BOOT_TRIPLE; -+ } -+ break; - - case BOOT_TRIPLE: - load_idt(&no_idt); -diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c -index 50cc3be..c6a4e63 100644 ---- a/drivers/acpi/acpica/hwxface.c -+++ b/drivers/acpi/acpica/hwxface.c -@@ -82,12 +82,11 @@ acpi_status acpi_reset(void) - /* - * For I/O space, write directly to the OSL. This bypasses the port - * validation mechanism, which may block a valid write to the reset -- * register. -+ * register. Spec section 4.7.3.6 requires register width to be 8. - */ - status = - acpi_os_write_port((acpi_io_address) reset_reg->address, -- acpi_gbl_FADT.reset_value, -- reset_reg->bit_width); -+ acpi_gbl_FADT.reset_value, 8); - } else { - /* Write the reset value to the reset register */ - -diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c -index 93f9114..a6c77e8b 100644 ---- a/drivers/acpi/reboot.c -+++ b/drivers/acpi/reboot.c -@@ -15,9 +15,15 @@ void acpi_reboot(void) - - rr = &acpi_gbl_FADT.reset_register; - -- /* Is the reset register supported? */ -- if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || -- rr->bit_width != 8 || rr->bit_offset != 0) -+ /* ACPI reset register was only introduced with v2 of the FADT */ -+ -+ if (acpi_gbl_FADT.header.revision < 2) -+ return; -+ -+ /* Is the reset register supported? The spec says we should be -+ * checking the bit width and bit offset, but Windows ignores -+ * these fields */ -+ if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)) - return; - - reset_value = acpi_gbl_FADT.reset_value; -@@ -45,6 +51,4 @@ void acpi_reboot(void) - acpi_reset(); - break; - } -- /* Wait ten seconds */ -- acpi_os_stall(10000000); - } diff --git a/ahci-add-another-pci-id-for-marvell.patch b/ahci-add-another-pci-id-for-marvell.patch deleted file mode 100644 index e7ac983..0000000 --- a/ahci-add-another-pci-id-for-marvell.patch +++ /dev/null @@ -1,32 +0,0 @@ -From: Tejun Heo -Date: Mon, 29 Nov 2010 14:57:14 +0000 (+0100) -Subject: ahci: add another PCI ID for marvell -X-Git-Tag: v2.6.39-rc1~490^2 -X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=50be5e3657cd2851a297dc0b3fd459f25829d29b - -ahci: add another PCI ID for marvell - -1b4b:91a3 seems to be another PCI ID for marvell ahci. Add it. -Reported and tested in the following thread. - - http://thread.gmane.org/gmane.linux.kernel/1068354 - -Signed-off-by: Tejun Heo -Reported-by: Borislav Petkov -Reported-by: Alessandro Tagliapietra -Signed-off-by: Jeff Garzik ---- - -diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c -index 0c22ebd..e62f693 100644 ---- a/drivers/ata/ahci.c -+++ b/drivers/ata/ahci.c -@@ -385,6 +385,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { - .driver_data = board_ahci_yes_fbs }, /* 88se9128 */ - { PCI_DEVICE(0x1b4b, 0x9125), - .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ -+ { PCI_DEVICE(0x1b4b, 0x91a3), -+ .driver_data = board_ahci_yes_fbs }, - - /* Promise */ - { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ diff --git a/apple_backlight.patch b/apple_backlight.patch deleted file mode 100644 index c7d5a81..0000000 --- a/apple_backlight.patch +++ /dev/null @@ -1,688 +0,0 @@ -Various fixes to the Apple backlight driver. Upstream in .38? - -diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig -index e54a337..fb5df46 100644 ---- a/drivers/video/backlight/Kconfig -+++ b/drivers/video/backlight/Kconfig -@@ -236,12 +236,12 @@ config BACKLIGHT_MAX8925 - If you have a LCD backlight connected to the WLED output of MAX8925 - WLED output, say Y here to enable this driver. - --config BACKLIGHT_MBP_NVIDIA -- tristate "MacBook Pro Nvidia Backlight Driver" -+config BACKLIGHT_APPLE -+ tristate "Apple Backlight Driver" - depends on X86 - help -- If you have an Apple Macbook Pro with Nvidia graphics hardware say Y -- to enable a driver for its backlight -+ If you have an Intel-based Apple say Y to enable a driver for its -+ backlight - - config BACKLIGHT_TOSA - tristate "Sharp SL-6000 Backlight Driver" -diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile -index 44c0f81..ebaecc0 100644 ---- a/drivers/video/backlight/Makefile -+++ b/drivers/video/backlight/Makefile -@@ -26,7 +26,7 @@ obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o - obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o - obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o - obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o --obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o -+obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o - obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o - obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o - obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o -diff --git a/drivers/video/backlight/apple_bl.c b/drivers/video/backlight/apple_bl.c -new file mode 100644 -index 0000000..8f808c7 ---- /dev/null -+++ b/drivers/video/backlight/apple_bl.c -@@ -0,0 +1,240 @@ -+/* -+ * Backlight Driver for Intel-based Apples -+ * -+ * Copyright (c) Red Hat -+ * Based on code from Pommed: -+ * Copyright (C) 2006 Nicolas Boichat -+ * Copyright (C) 2006 Felipe Alfaro Solana -+ * Copyright (C) 2007 Julien BLACHE -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This driver triggers SMIs which cause the firmware to change the -+ * backlight brightness. This is icky in many ways, but it's impractical to -+ * get at the firmware code in order to figure out what it's actually doing. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static struct backlight_device *apple_backlight_device; -+ -+struct hw_data { -+ /* I/O resource to allocate. */ -+ unsigned long iostart; -+ unsigned long iolen; -+ /* Backlight operations structure. */ -+ const struct backlight_ops backlight_ops; -+ void (*set_brightness)(int); -+}; -+ -+static const struct hw_data *hw_data; -+ -+#define DRIVER "apple_backlight: " -+ -+/* Module parameters. */ -+static int debug; -+module_param_named(debug, debug, int, 0644); -+MODULE_PARM_DESC(debug, "Set to one to enable debugging messages."); -+ -+/* -+ * Implementation for machines with Intel chipset. -+ */ -+static void intel_chipset_set_brightness(int intensity) -+{ -+ outb(0x04 | (intensity << 4), 0xb3); -+ outb(0xbf, 0xb2); -+} -+ -+static int intel_chipset_send_intensity(struct backlight_device *bd) -+{ -+ int intensity = bd->props.brightness; -+ -+ if (debug) -+ printk(KERN_DEBUG DRIVER "setting brightness to %d\n", -+ intensity); -+ -+ intel_chipset_set_brightness(intensity); -+ return 0; -+} -+ -+static int intel_chipset_get_intensity(struct backlight_device *bd) -+{ -+ int intensity; -+ -+ outb(0x03, 0xb3); -+ outb(0xbf, 0xb2); -+ intensity = inb(0xb3) >> 4; -+ -+ if (debug) -+ printk(KERN_DEBUG DRIVER "read brightness of %d\n", -+ intensity); -+ -+ return intensity; -+} -+ -+static const struct hw_data intel_chipset_data = { -+ .iostart = 0xb2, -+ .iolen = 2, -+ .backlight_ops = { -+ .options = BL_CORE_SUSPENDRESUME, -+ .get_brightness = intel_chipset_get_intensity, -+ .update_status = intel_chipset_send_intensity, -+ }, -+ .set_brightness = intel_chipset_set_brightness, -+}; -+ -+/* -+ * Implementation for machines with Nvidia chipset. -+ */ -+static void nvidia_chipset_set_brightness(int intensity) -+{ -+ outb(0x04 | (intensity << 4), 0x52f); -+ outb(0xbf, 0x52e); -+} -+ -+static int nvidia_chipset_send_intensity(struct backlight_device *bd) -+{ -+ int intensity = bd->props.brightness; -+ -+ if (debug) -+ printk(KERN_DEBUG DRIVER "setting brightness to %d\n", -+ intensity); -+ -+ nvidia_chipset_set_brightness(intensity); -+ return 0; -+} -+ -+static int nvidia_chipset_get_intensity(struct backlight_device *bd) -+{ -+ int intensity; -+ -+ outb(0x03, 0x52f); -+ outb(0xbf, 0x52e); -+ intensity = inb(0x52f) >> 4; -+ -+ if (debug) -+ printk(KERN_DEBUG DRIVER "read brightness of %d\n", -+ intensity); -+ -+ return intensity; -+} -+ -+static const struct hw_data nvidia_chipset_data = { -+ .iostart = 0x52e, -+ .iolen = 2, -+ .backlight_ops = { -+ .options = BL_CORE_SUSPENDRESUME, -+ .get_brightness = nvidia_chipset_get_intensity, -+ .update_status = nvidia_chipset_send_intensity -+ }, -+ .set_brightness = nvidia_chipset_set_brightness, -+}; -+ -+static int __devinit apple_bl_add(struct acpi_device *dev) -+{ -+ struct backlight_properties props; -+ struct pci_dev *host; -+ int intensity; -+ -+ host = pci_get_bus_and_slot(0, 0); -+ -+ if (!host) { -+ printk(KERN_ERR DRIVER "unable to find PCI host\n"); -+ return -ENODEV; -+ } -+ -+ if (host->vendor == PCI_VENDOR_ID_INTEL) -+ hw_data = &intel_chipset_data; -+ else if (host->vendor == PCI_VENDOR_ID_NVIDIA) -+ hw_data = &nvidia_chipset_data; -+ -+ pci_dev_put(host); -+ -+ if (!hw_data) { -+ printk(KERN_ERR DRIVER "unknown hardware\n"); -+ return -ENODEV; -+ } -+ -+ /* Check that the hardware responds - this may not work under EFI */ -+ -+ intensity = hw_data->backlight_ops.get_brightness(NULL); -+ -+ if (!intensity) { -+ hw_data->set_brightness(1); -+ if (!hw_data->backlight_ops.get_brightness(NULL)) -+ return -ENODEV; -+ -+ hw_data->set_brightness(0); -+ } -+ -+ if (!request_region(hw_data->iostart, hw_data->iolen, -+ "Apple backlight")) -+ return -ENXIO; -+ -+ memset(&props, 0, sizeof(struct backlight_properties)); -+ props.max_brightness = 15; -+ apple_backlight_device = backlight_device_register("apple_backlight", -+ NULL, NULL, &hw_data->backlight_ops, &props); -+ -+ if (IS_ERR(apple_backlight_device)) { -+ release_region(hw_data->iostart, hw_data->iolen); -+ return PTR_ERR(apple_backlight_device); -+ } -+ -+ apple_backlight_device->props.brightness = -+ hw_data->backlight_ops.get_brightness(apple_backlight_device); -+ backlight_update_status(apple_backlight_device); -+ -+ return 0; -+} -+ -+static int __devexit apple_bl_remove(struct acpi_device *dev, int type) -+{ -+ backlight_device_unregister(apple_backlight_device); -+ -+ release_region(hw_data->iostart, hw_data->iolen); -+ hw_data = NULL; -+ return 0; -+} -+ -+static const struct acpi_device_id apple_bl_ids[] = { -+ {"APP0002", 0}, -+ {"", 0}, -+}; -+ -+static struct acpi_driver apple_bl_driver = { -+ .name = "Apple backlight", -+ .ids = apple_bl_ids, -+ .ops = { -+ .add = apple_bl_add, -+ .remove = apple_bl_remove, -+ }, -+}; -+ -+static int __init apple_bl_init(void) -+{ -+ return acpi_bus_register_driver(&apple_bl_driver); -+} -+ -+static void __exit apple_bl_exit(void) -+{ -+ acpi_bus_unregister_driver(&apple_bl_driver); -+} -+ -+module_init(apple_bl_init); -+module_exit(apple_bl_exit); -+ -+MODULE_AUTHOR("Matthew Garrett "); -+MODULE_DESCRIPTION("Apple Backlight Driver"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(acpi, apple_bl_ids); -+MODULE_ALIAS("mbp_nvidia_bl"); -diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c -deleted file mode 100644 -index 1485f73..0000000 ---- a/drivers/video/backlight/mbp_nvidia_bl.c -+++ /dev/null -@@ -1,400 +0,0 @@ --/* -- * Backlight Driver for Nvidia 8600 in Macbook Pro -- * -- * Copyright (c) Red Hat -- * Based on code from Pommed: -- * Copyright (C) 2006 Nicolas Boichat -- * Copyright (C) 2006 Felipe Alfaro Solana -- * Copyright (C) 2007 Julien BLACHE -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This driver triggers SMIs which cause the firmware to change the -- * backlight brightness. This is icky in many ways, but it's impractical to -- * get at the firmware code in order to figure out what it's actually doing. -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include -- --static struct backlight_device *mbp_backlight_device; -- --/* Structure to be passed to the DMI_MATCH function. */ --struct dmi_match_data { -- /* I/O resource to allocate. */ -- unsigned long iostart; -- unsigned long iolen; -- /* Backlight operations structure. */ -- const struct backlight_ops backlight_ops; --}; -- --/* Module parameters. */ --static int debug; --module_param_named(debug, debug, int, 0644); --MODULE_PARM_DESC(debug, "Set to one to enable debugging messages."); -- --/* -- * Implementation for MacBooks with Intel chipset. -- */ --static int intel_chipset_send_intensity(struct backlight_device *bd) --{ -- int intensity = bd->props.brightness; -- -- if (debug) -- printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n", -- intensity); -- -- outb(0x04 | (intensity << 4), 0xb3); -- outb(0xbf, 0xb2); -- return 0; --} -- --static int intel_chipset_get_intensity(struct backlight_device *bd) --{ -- int intensity; -- -- outb(0x03, 0xb3); -- outb(0xbf, 0xb2); -- intensity = inb(0xb3) >> 4; -- -- if (debug) -- printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n", -- intensity); -- -- return intensity; --} -- --static const struct dmi_match_data intel_chipset_data = { -- .iostart = 0xb2, -- .iolen = 2, -- .backlight_ops = { -- .options = BL_CORE_SUSPENDRESUME, -- .get_brightness = intel_chipset_get_intensity, -- .update_status = intel_chipset_send_intensity, -- } --}; -- --/* -- * Implementation for MacBooks with Nvidia chipset. -- */ --static int nvidia_chipset_send_intensity(struct backlight_device *bd) --{ -- int intensity = bd->props.brightness; -- -- if (debug) -- printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n", -- intensity); -- -- outb(0x04 | (intensity << 4), 0x52f); -- outb(0xbf, 0x52e); -- return 0; --} -- --static int nvidia_chipset_get_intensity(struct backlight_device *bd) --{ -- int intensity; -- -- outb(0x03, 0x52f); -- outb(0xbf, 0x52e); -- intensity = inb(0x52f) >> 4; -- -- if (debug) -- printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n", -- intensity); -- -- return intensity; --} -- --static const struct dmi_match_data nvidia_chipset_data = { -- .iostart = 0x52e, -- .iolen = 2, -- .backlight_ops = { -- .options = BL_CORE_SUSPENDRESUME, -- .get_brightness = nvidia_chipset_get_intensity, -- .update_status = nvidia_chipset_send_intensity -- } --}; -- --/* -- * DMI matching. -- */ --static /* const */ struct dmi_match_data *driver_data; -- --static int mbp_dmi_match(const struct dmi_system_id *id) --{ -- driver_data = id->driver_data; -- -- printk(KERN_INFO "mbp_nvidia_bl: %s detected\n", id->ident); -- return 1; --} -- --static const struct dmi_system_id __initdata mbp_device_table[] = { -- { -- .callback = mbp_dmi_match, -- .ident = "MacBook 1,1", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), -- }, -- .driver_data = (void *)&intel_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBook 2,1", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"), -- }, -- .driver_data = (void *)&intel_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBook 3,1", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBook3,1"), -- }, -- .driver_data = (void *)&intel_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBook 4,1", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,1"), -- }, -- .driver_data = (void *)&intel_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBook 4,2", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,2"), -- }, -- .driver_data = (void *)&intel_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookPro 1,1", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,1"), -- }, -- .driver_data = (void *)&intel_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookPro 1,2", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,2"), -- }, -- .driver_data = (void *)&intel_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookPro 2,1", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,1"), -- }, -- .driver_data = (void *)&intel_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookPro 2,2", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2"), -- }, -- .driver_data = (void *)&intel_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookPro 3,1", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"), -- }, -- .driver_data = (void *)&intel_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookPro 3,2", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,2"), -- }, -- .driver_data = (void *)&intel_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookPro 4,1", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4,1"), -- }, -- .driver_data = (void *)&intel_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookAir 1,1", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir1,1"), -- }, -- .driver_data = (void *)&intel_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBook 5,1", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,1"), -- }, -- .driver_data = (void *)&nvidia_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBook 5,2", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,2"), -- }, -- .driver_data = (void *)&nvidia_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBook 6,1", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBook6,1"), -- }, -- .driver_data = (void *)&nvidia_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookAir 2,1", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2,1"), -- }, -- .driver_data = (void *)&nvidia_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookPro 5,1", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,1"), -- }, -- .driver_data = (void *)&nvidia_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookPro 5,2", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,2"), -- }, -- .driver_data = (void *)&nvidia_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookPro 5,3", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3"), -- }, -- .driver_data = (void *)&nvidia_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookPro 5,4", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4"), -- }, -- .driver_data = (void *)&nvidia_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookPro 5,5", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,5"), -- }, -- .driver_data = (void *)&nvidia_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookAir 3,1", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,1"), -- }, -- .driver_data = (void *)&nvidia_chipset_data, -- }, -- { -- .callback = mbp_dmi_match, -- .ident = "MacBookAir 3,2", -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,2"), -- }, -- .driver_data = (void *)&nvidia_chipset_data, -- }, -- { } --}; -- --static int __init mbp_init(void) --{ -- struct backlight_properties props; -- if (!dmi_check_system(mbp_device_table)) -- return -ENODEV; -- -- if (!request_region(driver_data->iostart, driver_data->iolen, -- "Macbook Pro backlight")) -- return -ENXIO; -- -- memset(&props, 0, sizeof(struct backlight_properties)); -- props.max_brightness = 15; -- mbp_backlight_device = backlight_device_register("mbp_backlight", NULL, -- NULL, -- &driver_data->backlight_ops, -- &props); -- if (IS_ERR(mbp_backlight_device)) { -- release_region(driver_data->iostart, driver_data->iolen); -- return PTR_ERR(mbp_backlight_device); -- } -- -- mbp_backlight_device->props.brightness = -- driver_data->backlight_ops.get_brightness(mbp_backlight_device); -- backlight_update_status(mbp_backlight_device); -- -- return 0; --} -- --static void __exit mbp_exit(void) --{ -- backlight_device_unregister(mbp_backlight_device); -- -- release_region(driver_data->iostart, driver_data->iolen); --} -- --module_init(mbp_init); --module_exit(mbp_exit); -- --MODULE_AUTHOR("Matthew Garrett "); --MODULE_DESCRIPTION("Nvidia-based Macbook Pro Backlight Driver"); --MODULE_LICENSE("GPL"); --MODULE_DEVICE_TABLE(dmi, mbp_device_table); diff --git a/ath5k-disable-fast-channel-switching-by-default.patch b/ath5k-disable-fast-channel-switching-by-default.patch index 86ebf83..a26eb51 100644 --- a/ath5k-disable-fast-channel-switching-by-default.patch +++ b/ath5k-disable-fast-channel-switching-by-default.patch @@ -40,10 +40,10 @@ index 09ae4ef..0fb6333 100644 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); -@@ -2685,7 +2691,8 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, +@@ -2669,7 +2669,8 @@ ath5k_reset(struct ath5k_softc *sc, stru + ath5k_drain_tx_buffs(sc); + if (chan) sc->curchan = chan; - sc->curband = &sc->sbands[chan->band]; - } - ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL, + fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0; + ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast, diff --git a/block-blkdev_get-should-access-bd_disk-only-after.patch b/block-blkdev_get-should-access-bd_disk-only-after.patch deleted file mode 100644 index 956b041..0000000 --- a/block-blkdev_get-should-access-bd_disk-only-after.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 4c49ff3fe128ca68dabd07537415c419ad7f82f9 Mon Sep 17 00:00:00 2001 -From: Tejun Heo -Date: Wed, 1 Jun 2011 08:27:41 +0200 -Subject: block: blkdev_get() should access ->bd_disk only after - success - -From: Tejun Heo - -commit 4c49ff3fe128ca68dabd07537415c419ad7f82f9 upstream. - -d4dc210f69 (block: don't block events on excl write for non-optical -devices) added dereferencing of bdev->bd_disk to test -GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; however, bdev->bd_disk can be -%NULL if open failed which can lead to an oops. - -Test the flag after testing open was successful, not before. - -Signed-off-by: Tejun Heo -Reported-by: David Miller -Tested-by: David Miller -Signed-off-by: Jens Axboe -Signed-off-by: Greg Kroah-Hartman - ---- - fs/block_dev.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/fs/block_dev.c -+++ b/fs/block_dev.c -@@ -1272,8 +1272,8 @@ int blkdev_get(struct block_device *bdev - * individual writeable reference is too fragile given the - * way @mode is used in blkdev_get/put(). - */ -- if ((disk->flags & GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE) && -- !res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) { -+ if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder && -+ (disk->flags & GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE)) { - bdev->bd_write_holder = true; - disk_block_events(disk); - } diff --git a/block-export-blk_-get-put-_queue.patch b/block-export-blk_-get-put-_queue.patch deleted file mode 100644 index 05db7bd..0000000 --- a/block-export-blk_-get-put-_queue.patch +++ /dev/null @@ -1,39 +0,0 @@ -From d86e0e83b32bc84600adb0b6ea1fce389b266682 Mon Sep 17 00:00:00 2001 -From: Jens Axboe -Date: Fri, 27 May 2011 07:44:43 +0200 -Subject: block: export blk_{get,put}_queue() - -From: Jens Axboe - -commit d86e0e83b32bc84600adb0b6ea1fce389b266682 upstream. -[ backport to 2.6.38 ] - -We need them in SCSI to fix a bug, but currently they are not -exported to modules. Export them. - -Signed-off-by: Jens Axboe -Signed-off-by: Greg Kroah-Hartman -Signed-off-by: Chuck Ebbert - ---- - block/blk-core.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/block/blk-core.c -+++ b/block/blk-core.c -@@ -345,6 +345,7 @@ void blk_put_queue(struct request_queue - { - kobject_put(&q->kobj); - } -+EXPORT_SYMBOL(blk_put_queue); - - void blk_cleanup_queue(struct request_queue *q) - { -@@ -566,6 +567,7 @@ int blk_get_queue(struct request_queue * - - return 1; - } -+EXPORT_SYMBOL(blk_get_queue); - - static inline void blk_free_request(struct request_queue *q, struct request *rq) - { diff --git a/block-queue-refcount.patch b/block-queue-refcount.patch deleted file mode 100644 index d53dd1b..0000000 --- a/block-queue-refcount.patch +++ /dev/null @@ -1,43 +0,0 @@ -commit e73e079bf128d68284efedeba1fbbc18d78610f9 -Author: James Bottomley -Date: Wed May 25 15:52:14 2011 -0500 - - [SCSI] Fix oops caused by queue refcounting failure - - In certain circumstances, we can get an oops from a torn down device. - Most notably this is from CD roms trying to call scsi_ioctl. The root - cause of the problem is the fact that after scsi_remove_device() has - been called, the queue is fully torn down. This is actually wrong - since the queue can be used until the sdev release function is called. - Therefore, we add an extra reference to the queue which is released in - sdev->release, so the queue always exists. - - Reported-by: Parag Warudkar - Cc: stable@kernel.org - Signed-off-by: James Bottomley - -diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c -index 58584dc..44e8ca3 100644 ---- a/drivers/scsi/scsi_scan.c -+++ b/drivers/scsi/scsi_scan.c -@@ -297,7 +297,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, - kfree(sdev); - goto out; - } -- -+ blk_get_queue(sdev->request_queue); - sdev->request_queue->queuedata = sdev; - scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); - -diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c -index e639125..e0bd3f7 100644 ---- a/drivers/scsi/scsi_sysfs.c -+++ b/drivers/scsi/scsi_sysfs.c -@@ -322,6 +322,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) - kfree(evt); - } - -+ blk_put_queue(sdev->request_queue); - /* NULL queue means the device can't be used */ - sdev->request_queue = NULL; - diff --git a/bonding-incorrect-tx-queue-offset.patch b/bonding-incorrect-tx-queue-offset.patch deleted file mode 100644 index ebc33de..0000000 --- a/bonding-incorrect-tx-queue-offset.patch +++ /dev/null @@ -1,54 +0,0 @@ -From: Phil Oester -Date: Mon, 14 Mar 2011 06:22:04 +0000 (+0000) -Subject: bonding: Incorrect TX queue offset -X-Git-Tag: v2.6.39-rc1~468^2~15 -X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=fd0e435b0fe85622f167b84432552885a4856ac8 - -bonding: Incorrect TX queue offset - -When packets come in from a device with >= 16 receive queues -headed out a bonding interface, syslog gets filled with this: - - kernel: bond0 selects TX queue 16, but real number of TX queues is 16 - -because queue_mapping is offset by 1. Adjust return value -to account for the offset. - -This is a revision of my earlier patch (which did not use the -skb_rx_queue_* helpers - thanks to Ben for the suggestion). -Andy submitted a similar patch which emits a pr_warning on -invalid queue selection, but I believe the log spew is -not useful. We can revisit that question in the future, -but in the interim I believe fixing the core problem is -worthwhile. - -Signed-off-by: Phil Oester -Signed-off-by: Andy Gospodarek -Signed-off-by: David S. Miller ---- - -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index 3ad4f50..a93d941 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -4341,11 +4341,18 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb) - { - /* - * This helper function exists to help dev_pick_tx get the correct -- * destination queue. Using a helper function skips the a call to -+ * destination queue. Using a helper function skips a call to - * skb_tx_hash and will put the skbs in the queue we expect on their - * way down to the bonding driver. - */ -- return skb->queue_mapping; -+ u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; -+ -+ if (unlikely(txq >= dev->real_num_tx_queues)) { -+ do -+ txq -= dev->real_num_tx_queues; -+ while (txq >= dev->real_num_tx_queues); -+ } -+ return txq; - } - - static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) diff --git a/config-arm b/config-arm index 47a024d..dd6f90a 100644 --- a/config-arm +++ b/config-arm @@ -135,3 +135,15 @@ CONFIG_STRICT_DEVMEM=y # CONFIG_HVC_DCC is not set CONFIG_SPARSE_IRQ=y + +# CONFIG_ARM_PATCH_PHYS_VIRT is not set + +CONFIG_FTMAC100=m + +CONFIG_HWSPINLOCK_OMAP=m + +CONFIG_USE_OF=y +CONFIG_PROC_DEVICETREE=y +CONFIG_MTD_PHYSMAP_OF=m +CONFIG_SERIAL_OF_PLATFORM=m +CONFIG_MMC_SDHCI_OF=m diff --git a/config-debug b/config-debug index 7301794..7bbaa0b 100644 --- a/config-debug +++ b/config-debug @@ -41,6 +41,7 @@ CONFIG_DEBUG_OBJECTS=y # CONFIG_DEBUG_OBJECTS_SELFTEST is not set CONFIG_DEBUG_OBJECTS_FREE=y CONFIG_DEBUG_OBJECTS_TIMERS=y +CONFIG_DEBUG_OBJECTS_RCU_HEAD=y CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1 CONFIG_X86_PTDUMP=y diff --git a/config-generic b/config-generic index 6266d37..83a056b 100644 --- a/config-generic +++ b/config-generic @@ -6,6 +6,7 @@ CONFIG_SMP=y CONFIG_HOTPLUG_CPU=y CONFIG_LOCALVERSION="" CONFIG_CROSS_COMPILE="" +CONFIG_DEFAULT_HOSTNAME="(none)" # # Code maturity level options @@ -32,6 +33,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_FHANDLE=y CONFIG_TASKSTATS=y CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y @@ -138,6 +140,7 @@ CONFIG_MMC_SDHCI_PLTFM=m CONFIG_MMC_CB710=m CONFIG_MMC_RICOH_MMC=y CONFIG_MMC_USHC=m +CONFIG_MMC_VUB300=m CONFIG_CB710_CORE=m # CONFIG_CB710_DEBUG is not set @@ -191,6 +194,7 @@ CONFIG_EXTRA_FIRMWARE="" # CONFIG_MTD=m # CONFIG_MTD_DEBUG is not set +CONFIG_MTD_SWAP=m CONFIG_MTD_PARTITIONS=y CONFIG_MTD_AR7_PARTS=m CONFIG_MTD_CONCAT=m @@ -240,6 +244,7 @@ CONFIG_MTD_ABSENT=m # CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_LATCH_ADDR is not set CONFIG_MTD_SC520CDP=m CONFIG_MTD_NETSC520=m # CONFIG_MTD_SBC_GXX is not set @@ -282,6 +287,7 @@ 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_ECC_BCH is not set # CONFIG_MTD_NAND_CAFE is not set CONFIG_MTD_NAND_IDS=m CONFIG_MTD_NAND_NANDSIM=m @@ -569,6 +575,7 @@ CONFIG_SATA_ACARD_AHCI=m CONFIG_PATA_ACPI=m CONFIG_PATA_ALI=m CONFIG_PATA_AMD=m +CONFIG_PATA_ARASAN_CF=m CONFIG_PATA_ARTOP=m CONFIG_PATA_ATIIXP=m CONFIG_PATA_CMD640_PCI=m @@ -689,6 +696,7 @@ CONFIG_DM_LOG_USERSPACE=m CONFIG_DM_MULTIPATH_QL=m CONFIG_DM_MULTIPATH_ST=m CONFIG_DM_RAID=m +CONFIG_DM_FLAKEY=m # # Fusion MPT device support @@ -759,6 +767,7 @@ CONFIG_INET_TUNNEL=m CONFIG_INET_DIAG=m CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_FIB_TRIE_STATS=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_VERBOSE=y @@ -806,7 +815,7 @@ CONFIG_IP_VS_NQ=m CONFIG_IP_VS_FTP=m CONFIG_IP_VS_PE_SIP=m -CONFIG_IPV6=m +CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y @@ -842,11 +851,12 @@ CONFIG_BRIDGE_IGMP_SNOOPING=y # CONFIG_NETWORK_PHY_TIMESTAMPING is not set CONFIG_NETFILTER=y CONFIG_NETFILTER_ADVANCED=y -CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK=m CONFIG_NETFILTER_NETLINK=m CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NETFILTER_NETLINK_LOG=m CONFIG_NETFILTER_XTABLES=y +CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_MARK=m CONFIG_NETFILTER_XT_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m @@ -902,6 +912,9 @@ CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m CONFIG_NETFILTER_XT_MATCH_CPU=m CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m # CONFIG_NETFILTER_DEBUG is not set CONFIG_BRIDGE_NETFILTER=y @@ -927,6 +940,8 @@ CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_CONNTRACK_IPV4=y CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_NAT=m CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_NF_CT_PROTO_DCCP=m @@ -1016,6 +1031,19 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_IP_SET=m +CONFIG_IP_SET_MAX=256 +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_LIST_SET=m + # # SCTP Configuration (EXPERIMENTAL) # @@ -1077,6 +1105,10 @@ CONFIG_NET_SCH_RED=m CONFIG_NET_SCH_SFQ=m CONFIG_NET_SCH_TBF=m CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m CONFIG_NET_CLS=y CONFIG_NET_CLS_ACT=y CONFIG_NET_CLS_BASIC=m @@ -1421,7 +1453,10 @@ CONFIG_ADM8211=m CONFIG_ATH_COMMON=m CONFIG_ATH5K=m CONFIG_ATH5K_DEBUG=y +# CONFIG_ATH5K_TRACER is not set CONFIG_ATH9K=m +CONFIG_ATH9K_PCI=y +CONFIG_ATH9K_AHB=y # CONFIG_ATH9K_DEBUG is not set CONFIG_ATH9K_DEBUGFS=y CONFIG_ATH9K_HTC=m @@ -1479,7 +1514,13 @@ CONFIG_IWLWIFI=m CONFIG_IWLWIFI_DEBUG=y CONFIG_IWLWIFI_DEBUGFS=y CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT=y +CONFIG_IWLWIFI_DEVICE_SVTOOL=y +# CONFIG_IWL_P2P is not set CONFIG_IWLAGN=m +CONFIG_IWLWIFI_LEGACY=m +CONFIG_IWLWIFI_LEGACY_DEBUG=y +CONFIG_IWLWIFI_LEGACY_DEBUGFS=y +# CONFIG_IWLWIFI_LEGACY_DEVICE_TRACING is not set CONFIG_IWL4965=y CONFIG_IWL5000=y CONFIG_IWL3945=m @@ -1508,16 +1549,19 @@ CONFIG_RT2500USB=m CONFIG_RT2800USB=m CONFIG_RT2800USB_RT33XX=y CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT53XX=y CONFIG_RT2800USB_UNKNOWN=y CONFIG_RT2800PCI=m CONFIG_RT2800PCI_RT33XX=y CONFIG_RT2800PCI_RT35XX=y +CONFIG_RT2800PCI_RT53XX=y 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_KALMIA=m CONFIG_USB_NET_SMSC75XX=m CONFIG_ZD1211RW=m # CONFIG_ZD1211RW_DEBUG is not set @@ -1538,6 +1582,11 @@ CONFIG_WL1271_SDIO=m CONFIG_WL1271_SPI=m CONFIG_RTL8192CE=m +CONFIG_RTL8192SE=m +CONFIG_RTL8192CU=m + +CONFIG_MWIFIEX=m +CONFIG_MWIFIEX_SDIO=m # # Token Ring devices @@ -1597,6 +1646,8 @@ CONFIG_CAN_TSCAN1=m CONFIG_CAN_SLCAN=m CONFIG_CAN_SOFTING=m CONFIG_CAN_SOFTING_CS=m +CONFIG_CAN_C_CAN=m +CONFIG_CAN_C_CAN_PLATFORM=m # CONFIG_PCH_CAN is not set CONFIG_NETROM=m CONFIG_ROSE=m @@ -1655,9 +1706,9 @@ CONFIG_WINBOND_FIR=m # Bluetooth support # CONFIG_BT=m -CONFIG_BT_L2CAP=m +CONFIG_BT_L2CAP=y CONFIG_BT_L2CAP_EXT_FEATURES=y -CONFIG_BT_SCO=m +CONFIG_BT_SCO=y CONFIG_BT_CMTP=m CONFIG_BT_RFCOMM=m CONFIG_BT_RFCOMM_TTY=y @@ -1689,6 +1740,7 @@ CONFIG_BT_HCIUART_LL=y CONFIG_BT_MRVL=m CONFIG_BT_MRVL_SDIO=m CONFIG_BT_ATH3K=m +CONFIG_BT_WILINK=m # # ISDN subsystem @@ -1880,12 +1932,14 @@ CONFIG_KEYBOARD_ATKBD=y # 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_ADP5588 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_QT1070 is not set # CONFIG_KEYBOARD_MCS is not set -CONFIG_KEYBOARD_OPENCORES=m -CONFIG_KEYBOARD_QT2160=m +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_QT2160 is not set # CONFIG_KEYBOARD_TCA6416 is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y @@ -1959,6 +2013,8 @@ CONFIG_TOUCHSCREEN_USB_COMPOSITE=m CONFIG_TOUCHSCREEN_W90X900=m # CONFIG_TOUCHSCREEN_BU21013 is not set CONFIG_TOUCHSCREEN_ST1232=m +CONFIG_TOUCHSCREEN_ATMEL_MXT=m +# CONFIG_TOUCHSCREEN_MAX11801 is not set CONFIG_INPUT_MISC=y CONFIG_INPUT_PCSPKR=m @@ -1993,6 +2049,7 @@ CONFIG_SYNCLINKMP=m CONFIG_SYNCLINK_GT=m CONFIG_N_HDLC=m CONFIG_N_GSM=m +# CONFIG_TRACE_SINK is not set # CONFIG_STALDRV is not set # CONFIG_IBM_ASM is not set CONFIG_TIFM_CORE=m @@ -2041,6 +2098,7 @@ CONFIG_SERIAL_JSM=m # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_XILINX_PS_UART is not set # CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y CONFIG_DEVPTS_MULTIPLE_INSTANCES=y @@ -2113,6 +2171,8 @@ CONFIG_I2C_TINY_USB=m # CONFIG_I2C_DESIGNWARE is not set # CONFIG_I2C_XILINX is not set +CONFIG_I2C_DIOLAN_U2C=m + # # I2C Hardware Sensors Chip support # @@ -2219,6 +2279,23 @@ CONFIG_SENSORS_W83795=m # CONFIG_SENSORS_W83795_FANCTRL is not set CONFIG_SENSORS_DS620=m CONFIG_SENSORS_SHT21=m +CONFIG_SENSORS_LINEAGE=m +CONFIG_SENSORS_LTC4151=m +CONFIG_SENSORS_MAX6639=m +CONFIG_SENSORS_SCH5627=m +CONFIG_SENSORS_ADS1015=m +CONFIG_SENSORS_MAX16065=m +CONFIG_SENSORS_MAX6642=m +CONFIG_SENSORS_ADM1275=m +CONFIG_SENSORS_UCD9000=m +CONFIG_SENSORS_UCD9200=m +CONFIG_SENSORS_EMC6W201=m + +CONFIG_PMBUS=m +CONFIG_SENSORS_PMBUS=m +CONFIG_SENSORS_MAX16064=m +CONFIG_SENSORS_MAX34440=m +CONFIG_SENSORS_MAX8688=m # CONFIG_HMC6352 is not set # CONFIG_BMP085 is not set @@ -2241,6 +2318,9 @@ CONFIG_W1_SLAVE_DS2433=m CONFIG_W1_SLAVE_DS2433_CRC=y CONFIG_W1_SLAVE_DS2760=m CONFIG_W1_SLAVE_DS2423=m +CONFIG_W1_SLAVE_DS2408=m +CONFIG_W1_SLAVE_DS2780=m +CONFIG_W1_SLAVE_BQ27000=m # # Mice @@ -2342,6 +2422,8 @@ CONFIG_RTC_DRV_WM831X=m CONFIG_RTC_DRV_BQ32K=m CONFIG_RTC_DRV_MSM6242=m CONFIG_RTC_DRV_RP5C01=m +CONFIG_RTC_DRV_EM3027=m +CONFIG_RTC_DRV_RV3029C2=m CONFIG_DTLK=m CONFIG_R3964=m @@ -2402,12 +2484,14 @@ CONFIG_HANGCHECK_TIMER=m # Multimedia devices # CONFIG_MEDIA_SUPPORT=m +CONFIG_MEDIA_CONTROLLER=y 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_V4L2_SUBDEV_API=y # CONFIG_VIDEO_VIVI is not set # @@ -2424,11 +2508,13 @@ CONFIG_VIDEO_BT848=m CONFIG_VIDEO_BT848_DVB=y CONFIG_VIDEO_BWQCAM=m CONFIG_VIDEO_SR030PC30=m +CONFIG_VIDEO_NOON010PC30=m CONFIG_VIDEO_CAFE_CCIC=m # CONFIG_VIDEO_CPIA is not set CONFIG_VIDEO_CPIA2=m CONFIG_VIDEO_CQCAM=m CONFIG_VIDEO_CX23885=m +# CONFIG_MEDIA_ALTERA_CI is not set CONFIG_VIDEO_CX18=m CONFIG_VIDEO_CX18_ALSA=m CONFIG_VIDEO_CX88=m @@ -2473,6 +2559,7 @@ CONFIG_VIDEO_FB_IVTV=m CONFIG_VIDEO_SAA7164=m CONFIG_VIDEO_TLG2300=m # CONFIG_VIDEO_TIMBERDALE is not set +# CONFIG_VIDEO_M5MOLS is not set CONFIG_USB_VIDEO_CLASS=m CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y @@ -2484,6 +2571,7 @@ CONFIG_RADIO_GEMTEK_PCI=m CONFIG_RADIO_MAXIRADIO=m CONFIG_RADIO_MAESTRO=m CONFIG_RADIO_WL1273=m +CONFIG_RADIO_WL128X=m CONFIG_MEDIA_ATTACH=y CONFIG_MEDIA_TUNER_CUSTOMISE=y @@ -2503,6 +2591,7 @@ CONFIG_MEDIA_TUNER_MXL5007T=m CONFIG_MEDIA_TUNER_MC44S803=m CONFIG_MEDIA_TUNER_MAX2165=m CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_TDA18212=m # # Digital Video Broadcasting Devices @@ -2574,6 +2663,8 @@ CONFIG_DVB_ATBM8830=m CONFIG_DVB_TDA665x=m CONFIG_DVB_STV0299=m CONFIG_DVB_MB86A16=m +CONFIG_DVB_DRXD=m +CONFIG_DVB_CXD2820R=m # # Supported Frontend Modules @@ -2601,6 +2692,9 @@ CONFIG_DVB_DUMMY_FE=m CONFIG_DVB_FIREDTV=m CONFIG_DVB_NGENE=m CONFIG_DVB_MB86A20S=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_DIB9000=m +CONFIG_DVB_STV0367=m # # Supported SAA7146 based PCI Adapters @@ -2675,6 +2769,12 @@ CONFIG_IR_JVC_DECODER=m CONFIG_IR_SONY_DECODER=m CONFIG_IR_RC5_SZ_DECODER=m CONFIG_IR_LIRC_CODEC=m +CONFIG_IR_IMON=m +CONFIG_IR_MCEUSB=m +CONFIG_IR_ITE_CIR=m +CONFIG_IR_NUVOTON=m +CONFIG_IR_FINTEK=m +CONFIG_IR_REDRAT3=m CONFIG_V4L_MEM2MEM_DRIVERS=y # CONFIG_VIDEO_MEM2MEM_TESTDEV is not set @@ -2740,6 +2840,7 @@ CONFIG_FB_RIVA=m # CONFIG_FB_RIVA_I2C is not set # CONFIG_FB_S1D13XXX is not set CONFIG_FB_S3=m +CONFIG_FB_S3_DDC=y CONFIG_FB_SAVAGE=m CONFIG_FB_SAVAGE_I2C=y CONFIG_FB_SAVAGE_ACCEL=y @@ -2757,11 +2858,13 @@ CONFIG_FB_VOODOO1=m # CONFIG_FB_VT8623 is not set CONFIG_FB_EFI=y CONFIG_FB_VIA=m +CONFIG_FB_VIA_X_COMPATIBILITY=y # 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_MB862XX_I2C=y # CONFIG_FB_PRE_INIT_FB is not set # CONFIG_FB_TMIO is not set # CONFIG_FB_BROADSHEET is not set @@ -2872,6 +2975,7 @@ CONFIG_SND_ENS1371=m CONFIG_SND_ES1938=m CONFIG_SND_ES1968=m CONFIG_SND_ES1968_INPUT=y +CONFIG_SND_ES1968_RADIO=y CONFIG_SND_FM801=m CONFIG_SND_FM801_TEA575X_BOOL=y CONFIG_SND_CTXFI=m @@ -2929,6 +3033,7 @@ CONFIG_SND_VIRTUOSO=m CONFIG_SND_VX222=m CONFIG_SND_YMFPCI=m CONFIG_SND_ASIHPI=m +CONFIG_SND_LOLA=m # # ALSA USB devices @@ -2940,6 +3045,7 @@ CONFIG_SND_USB_CAIAQ_INPUT=y CONFIG_SND_USB_USX2Y=m CONFIG_SND_USB_US122L=m CONFIG_SND_USB_UA101=m +CONFIG_SND_USB_6FIRE=m # # PCMCIA devices @@ -2948,6 +3054,10 @@ CONFIG_SND_PCMCIA=y CONFIG_SND_VXPOCKET=m CONFIG_SND_PDAUDIOCF=m +CONFIG_SND_FIREWIRE=y +CONFIG_SND_FIREWIRE_SPEAKERS=m +CONFIG_SND_ISIGHT=m + # # Open Sound System # @@ -2980,6 +3090,8 @@ 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_HCD=m +CONFIG_USB_SL811_HCD_ISO=y # CONFIG_USB_SL811_CS is not set # CONFIG_USB_R8A66597_HCD is not set CONFIG_USB_XHCI_HCD=m @@ -3000,17 +3112,19 @@ 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_CYPRESS_ATACB=m +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m CONFIG_USB_STORAGE_USBAT=y -CONFIG_USB_STORAGE_ONETOUCH=y -CONFIG_USB_STORAGE_ALAUDA=y -CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_REALTEK=m +CONFIG_USB_STORAGE_ENE_UB6250=m # CONFIG_USB_LIBUSUAL is not set CONFIG_USB_UAS=m @@ -3064,12 +3178,10 @@ CONFIG_HID_SONY=m CONFIG_HID_SUNPLUS=m CONFIG_HID_GREENASIA=m CONFIG_HID_SMARTJOYPLUS=m -CONFIG_HID_TIVO_SLIDE=m CONFIG_HID_TOPSEED=m CONFIG_HID_THRUSTMASTER=m CONFIG_HID_ZEROPLUS=m CONFIG_HID_ZYDACRON=m -CONFIG_HID_ACRUX=m CONFIG_HID_ACRUX_FF=m CONFIG_HID_EMS_FF=m CONFIG_HID_ELECOM=m @@ -3077,6 +3189,11 @@ CONFIG_HID_UCLOGIC=m CONFIG_HID_WALTOP=m CONFIG_HID_ROCCAT_PYRA=m CONFIG_HID_ROCCAT_KONEPLUS=m +CONFIG_HID_ACRUX=m +CONFIG_HID_KEYTOUCH=m +CONFIG_HID_LCPOWER=m +CONFIG_HID_ROCCAT_ARVO=m +CONFIG_HID_ROCCAT_KOVAPLUS=m # # USB Imaging devices @@ -3135,6 +3252,9 @@ CONFIG_USB_GSPCA_KONICA=m CONFIG_USB_GSPCA_XIRLINK_CIT=m CONFIG_USB_GSPCA_SPCA1528=m CONFIG_USB_GSPCA_SQ930X=m +CONFIG_USB_GSPCA_NW80X=m +CONFIG_USB_GSPCA_VICAM=m +CONFIG_USB_GSPCA_KINECT=m CONFIG_USB_IBMCAM=m CONFIG_USB_KONICAWC=m @@ -3160,6 +3280,7 @@ CONFIG_SOC_CAMERA_OV9640=m CONFIG_SOC_CAMERA_OV6650=m CONFIG_SOC_CAMERA_IMX074=m CONFIG_SOC_CAMERA_OV2640=m +CONFIG_SOC_CAMERA_OV9740=m # # USB Network adaptors @@ -3188,6 +3309,7 @@ CONFIG_USB_NET_INT51X1=m CONFIG_USB_CDC_PHONET=m CONFIG_USB_IPHETH=m CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m # # USB Host-to-Host Cables @@ -3212,7 +3334,7 @@ CONFIG_USB_USS720=m # # USB Serial Converter support # -CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL=y CONFIG_USB_SERIAL_GENERIC=y CONFIG_USB_SERIAL_AIRCABLE=m CONFIG_USB_SERIAL_ARK3116=m @@ -3278,6 +3400,8 @@ CONFIG_USB_SERIAL_DEBUG=m CONFIG_USB_SERIAL_SSU100=m CONFIG_USB_SERIAL_SAMBA=m +CONFIG_USB_SERIAL_CONSOLE=y + CONFIG_USB_EZUSB=y CONFIG_USB_EMI62=m CONFIG_USB_LED=m @@ -3321,7 +3445,6 @@ 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 @@ -3361,7 +3484,6 @@ 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_RTC_DRV_DS3232=m CONFIG_RTC_DRV_ISL12022=m @@ -3487,6 +3609,7 @@ CONFIG_PROC_KCORE=y CONFIG_PROC_VMCORE=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_DEBUG_FS=y @@ -3549,9 +3672,10 @@ CONFIG_NFS_FSCACHE=y # CONFIG_NFS_USE_LEGACY_DNS is not set # CONFIG_NFS_USE_NEW_IDMAPPER is not set # CONFIG_NFSD_DEPRECATED is not set +CONFIG_PNFS_OBJLAYOUT=m CONFIG_LOCKD=m CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=m +CONFIG_EXPORTFS=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_SUNRPC_XPRT_RDMA=m @@ -3571,6 +3695,7 @@ CONFIG_CIFS_ACL=y CONFIG_CIFS_WEAK_PW_HASH=y # CONFIG_CIFS_DEBUG2 is not set CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_NFSD_EXPORT=y CONFIG_NCP_FS=m CONFIG_NCPFS_PACKET_SIGNING=y CONFIG_NCPFS_IOCTL_LOCKING=y @@ -3825,6 +3950,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=m # CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_PROGEAR=m # CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set CONFIG_FB_NVIDIA_BACKLIGHT=y CONFIG_FB_RIVA_BACKLIGHT=y CONFIG_FB_RADEON_BACKLIGHT=y @@ -3857,6 +3983,7 @@ CONFIG_CGROUP_SCHED=y CONFIG_CGROUP_MEM_RES_CTLR=y CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y # XXX disabled by default, pass 'swapaccount' # CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED is not set +CONFIG_CGROUP_PERF=y CONFIG_BLK_CGROUP=y # CONFIG_DEBUG_BLK_CGROUP is not set @@ -4068,9 +4195,11 @@ CONFIG_LEDS_TRIGGER_GPIO=m CONFIG_LEDS_INTEL_SS4200=m CONFIG_LEDS_LP5521=m CONFIG_LEDS_LP5523=m +CONFIG_LEDS_LM3530=m CONFIG_DMADEVICES=y CONFIG_DMA_ENGINE=y +CONFIG_DW_DMAC=m # CONFIG_TIMB_DMA is not set CONFIG_NET_DMA=y # CONFIG_DMATEST is not set @@ -4122,13 +4251,15 @@ CONFIG_APM_POWER=m # CONFIG_BATTERY_DS2760 is not set # CONFIG_BATTERY_DS2782 is not set # CONFIG_BATTERY_BQ20Z75 is not set +# CONFIG_BATTERY_DS2780 is not set # CONFIG_CHARGER_ISP1704 is not set -CONFIG_BATTERY_PMU=m +# CONFIG_CHARGER_MAX8903 is not set # CONFIG_BATTERY_BQ27x00 is not set # CONFIG_BATTERY_MAX17040 is not set # CONFIG_PDA_POWER is not set # CONFIG_CHARGER_GPIO is not set # CONFIG_BATTERY_MAX17042 is not set +# CONFIG_CHARGER_PCF50633 is not set CONFIG_AUXDISPLAY=y @@ -4172,6 +4303,8 @@ CONFIG_PM_TRACE_RTC=y CONFIG_R6040=m CONFIG_BNX2X=m +CONFIG_SCSI_BNX2X_FCOE=m + CONFIG_NOZOMI=m # CONFIG_TPS65010 is not set # CONFIG_DEBUG_SECTION_MISMATCH is not set @@ -4199,6 +4332,7 @@ CONFIG_MEMSTICK=m CONFIG_MSPRO_BLOCK=m CONFIG_MEMSTICK_TIFM_MS=m CONFIG_MEMSTICK_JMICRON_38X=m +CONFIG_MEMSTICK_R592=m CONFIG_ACCESSIBILITY=y CONFIG_A11Y_BRAILLE_CONSOLE=y @@ -4238,7 +4372,6 @@ CONFIG_PHONET=m CONFIG_ICS932S401=m # CONFIG_C2PORT is not set -CONFIG_W1_SLAVE_BQ27000=m CONFIG_IT87_WDT=m @@ -4327,6 +4460,15 @@ CONFIG_USB_ATMEL=m # CONFIG_DX_SEP is not set # CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set # CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set +# CONFIG_RTS_PSTOR is not set +# CONFIG_DRM_PSB is not set +# CONFIG_ALTERA_STAPL is not set +# CONFIG_DVB_CXD2099 is not set +# CONFIG_USBIP_CORE is not set +# CONFIG_BRCMSMAC is not set +# CONFIG_BRCMFMAC is not set +# CONFIG_INTEL_MEI is not set +# CONFIG_ZCACHE is not set # # Android @@ -4370,6 +4512,7 @@ CONFIG_STRIP_ASM_SYMS=y # CONFIG_RCU_FANOUT_EXACT is not set CONFIG_RCU_FAST_NO_HZ=y CONFIG_SRCU_SYNCHRONIZE_DELAY=10 +CONFIG_RCU_CPU_STALL_TIMEOUT=60 CONFIG_KSM=y CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -4392,6 +4535,8 @@ CONFIG_PPS_CLIENT_PARPORT=m CONFIG_PPS_GENERATOR_PARPORT=m CONFIG_NTP_PPS=y +CONFIG_PTP_1588_CLOCK=m + # CONFIG_USB_SERIAL_QUATECH2 is not set # CONFIG_VT6655 is not set CONFIG_FB_UDL=m @@ -4422,12 +4567,14 @@ CONFIG_DETECT_SOFTLOCKUP=y CONFIG_LOCKUP_DETECTOR=y # CONFIG_DEBUG_INFO_REDUCED is not set # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +# CONFIG_BOOTPARAM_HARDLOCKUP_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_CLEANCACHE=y CONFIG_BLK_DEV_DRBD=m @@ -4448,6 +4595,7 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_IT8761E is not set # CONFIG_GPIO_MAX7300 is not set # CONFIG_UCB1400_CORE is not set +# CONFIG_TPS6105X is not set # CONFIG_RADIO_MIROPCM20 is not set # CONFIG_USB_GPIO_VBUS is not set # CONFIG_GPIO_SCH is not set @@ -4468,10 +4616,6 @@ CONFIG_IR_CORE=m CONFIG_IR_ENE=m CONFIG_IR_STREAMZAP=m CONFIG_IR_WINBOND_CIR=m -CONFIG_IR_IMON=m -CONFIG_IR_MCEUSB=m -CONFIG_IR_NUVOTON=m -CONFIG_IR_ITE_CIR=m # CONFIG_GPIO_SX150X is not set # CONFIG_MFD_STMPE is not set @@ -4493,8 +4637,28 @@ CONFIG_NFC_DEVICES=y CONFIG_PN544_NFC=m CONFIG_TARGET_CORE=m +CONFIG_LOOPBACK_TARGET=m +# CONFIG_LOOPBACK_TARGET_CDB_DEBUG is not set CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m CONFIG_TCM_PSCSI=m +CONFIG_TCM_FC=m + +CONFIG_HWSPINLOCK=m + +CONFIG_PSTORE=y + +# CONFIG_AVERAGE is not set + +# CONFIG_SIGMA is not set + +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 CONFIG_TEST_KSTRTOX=m + +CONFIG_BCMA=m +CONFIG_BCMA_HOST_PCI=y +# CONFIG_BCMA_DEBUG is not set + +# CONFIG_GOOGLE_FIRMWARE is not set +CONFIG_INTEL_MID_PTI=m diff --git a/config-ia64-generic b/config-ia64-generic index 5c864b3..704c704 100644 --- a/config-ia64-generic +++ b/config-ia64-generic @@ -140,6 +140,8 @@ CONFIG_ACPI_VIDEO=m CONFIG_ACPI_HED=m CONFIG_ACPI_EC_DEBUGFS=m CONFIG_ACPI_IPMI=m +CONFIG_ACPI_CUSTOM_METHOD=m +CONFIG_SENSORS_ACPI_POWER=m CONFIG_PM=y CONFIG_HOTPLUG_PCI=y @@ -183,6 +185,7 @@ CONFIG_PROC_VMCORE=y # CONFIG_IA64_MC_ERR_INJECT is not set CONFIG_DMIID=y +CONFIG_DMI_SYSFS=y CONFIG_SENSORS_I5K_AMB=m @@ -206,3 +209,5 @@ CONFIG_RCU_FANOUT=64 CONFIG_ACPI_POWER_METER=m CONFIG_I2C_SCMI=m + +# CONFIG_HP_ACCEL is not set diff --git a/config-nodebug b/config-nodebug index 7510184..62650aa 100644 --- a/config-nodebug +++ b/config-nodebug @@ -41,6 +41,7 @@ CONFIG_CPUMASK_OFFSTACK=y # CONFIG_DEBUG_OBJECTS_SELFTEST is not set # CONFIG_DEBUG_OBJECTS_FREE is not set # CONFIG_DEBUG_OBJECTS_TIMERS is not set +# CONFIG_DEBUG_OBJECTS_RCU_HEAD is not set CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1 # CONFIG_X86_PTDUMP is not set diff --git a/config-powerpc-generic b/config-powerpc-generic index 3c8d8f0..e47c315 100644 --- a/config-powerpc-generic +++ b/config-powerpc-generic @@ -325,6 +325,9 @@ CONFIG_PATA_MACIO=m CONFIG_SERIAL_GRLIB_GAISLER_APBUART=m # CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_88PM8607 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_WL1273_CORE 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 @@ -339,5 +342,16 @@ CONFIG_MPC512X_DMA=m CONFIG_KVM_GUEST=y +CONFIG_I2C_MPC=m + # CONFIG_IMA is not set # CONFIG_TCG_TPM is not set + +CONFIG_RFKILL_GPIO=m + +CONFIG_CRYPTO_DEV_FSL_CAAM=m +CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9 +CONFIG_CRYPTO_DEV_FSL_CAAM_INTC=y +CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD=255 +CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD=2048 +CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=m diff --git a/config-powerpc32-generic b/config-powerpc32-generic index daa06ab..31c399e 100644 --- a/config-powerpc32-generic +++ b/config-powerpc32-generic @@ -182,5 +182,6 @@ CONFIG_EVENT_PROFILE=y CONFIG_KVM_BOOK3S_32=m -### needs non-existant readq/writeq # CONFIG_SCSI_QLA_ISCSI is not set + +CONFIG_BATTERY_PMU=m diff --git a/config-powerpc64 b/config-powerpc64 index 2946a06..8866a53 100644 --- a/config-powerpc64 +++ b/config-powerpc64 @@ -184,3 +184,7 @@ CONFIG_CMM=y # CONFIG_SPARSEMEM_VMEMMAP is not set CONFIG_PSERIES_ENERGY=m + +CONFIG_PPC_ICSWX=y +CONFIG_IO_EVENT_IRQ=y +CONFIG_HW_RANDOM_AMD=m diff --git a/config-s390x b/config-s390x index 780fc91..da9db13 100644 --- a/config-s390x +++ b/config-s390x @@ -233,3 +233,8 @@ CONFIG_SCHED_MC=y CONFIG_SCHED_BOOK=y CONFIG_STRICT_DEVMEM=y + +# CONFIG_WARN_DYNAMIC_STACK is not set + +CONFIG_JUMP_LABEL=y +CONFIG_CRYPTO_GHASH_S390=m diff --git a/config-x86-generic b/config-x86-generic index d6feae8..79a63a8 100644 --- a/config-x86-generic +++ b/config-x86-generic @@ -152,9 +152,11 @@ CONFIG_ACPI_POWER_METER=m CONFIG_ACPI_PROCESSOR_AGGREGATOR=m CONFIG_ACPI_HED=m CONFIG_ACPI_APEI=y +CONFIG_ACPI_APEI_PCIEAER=y CONFIG_ACPI_APEI_GHES=m # CONFIG_ACPI_APEI_EINJ is not set CONFIG_ACPI_IPMI=m +CONFIG_ACPI_CUSTOM_METHOD=m # # CPUFreq processor drivers @@ -198,7 +200,6 @@ CONFIG_X86_TRAMPOLINE=y # 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 @@ -324,6 +325,11 @@ CONFIG_TC1100_WMI=m CONFIG_HP_WMI=m # CONFIG_INTEL_SCU_IPC is not set CONFIG_DELL_WMI=m +CONFIG_DELL_WMI_AIO=m +CONFIG_ASUS_WMI=m +CONFIG_ASUS_NB_WMI=m +CONFIG_XO15_EBOOK=m +CONFIG_INTEL_OAKTRAIL=m # CONFIG_TOUCHSCREEN_INTEL_MID is not set @@ -362,6 +368,7 @@ CONFIG_LGUEST_GUEST=y CONFIG_VMI=y CONFIG_XEN=y +# CONFIG_XEN_DEBUG is not set CONFIG_XEN_MAX_DOMAIN_MEMORY=8 CONFIG_XEN_BALLOON=y CONFIG_XEN_SCRUB_PAGES=y @@ -371,13 +378,18 @@ CONFIG_XEN_FBDEV_FRONTEND=y CONFIG_XEN_KBDDEV_FRONTEND=y CONFIG_XEN_BLKDEV_FRONTEND=m CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XEN_NETDEV_BACKEND=m +CONFIG_XEN_WDT=m +CONFIG_XEN_GRANT_DEV_ALLOC=m CONFIG_XEN_PCIDEV_FRONTEND=m CONFIG_XENFS=m CONFIG_XEN_COMPAT_XENFS=y CONFIG_XEN_BACKEND=y +CONFIG_XEN_BLKDEV_BACKEND=m CONFIG_XEN_DEBUG_FS=y CONFIG_XEN_PLATFORM_PCI=m CONFIG_XEN_GNTDEV=m +CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m CONFIG_MTD_ESB2ROM=m CONFIG_MTD_CK804XROM=m @@ -400,6 +412,8 @@ CONFIG_THINKPAD_ACPI_ALSA_SUPPORT=y CONFIG_MACINTOSH_DRIVERS=y CONFIG_DMIID=y +CONFIG_DMI_SYSFS=y + CONFIG_ISCSI_IBFT_FIND=y CONFIG_ISCSI_IBFT=m @@ -407,6 +421,8 @@ CONFIG_DMADEVICES=y CONFIG_INTEL_IOATDMA=m CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_FAM15H_POWER=m +CONFIG_SENSORS_ACPI_POWER=m # CONFIG_CPA_DEBUG is not set # CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set @@ -420,6 +436,9 @@ CONFIG_OLPC_OPENFIRMWARE=y CONFIG_BATTERY_OLPC=y CONFIG_MOUSE_PS2_OLPC=y +# staging +# CONFIG_FB_OLPC_DCON is not set + CONFIG_STRICT_DEVMEM=y # CONFIG_NO_BOOTMEM is not set @@ -478,6 +497,7 @@ CONFIG_SFI=y CONFIG_INPUT_WINBOND_CIR=m CONFIG_I2C_SCMI=m +CONFIG_I2C_PXA=m CONFIG_SBC_FITPC2_WATCHDOG=m CONFIG_EDAC_I3200=m CONFIG_EDAC_DECODE_MCE=m @@ -536,7 +556,8 @@ CONFIG_X86_32_IRIS=m CONFIG_TRANSPARENT_HUGEPAGE=y -CONFIG_CRYPTO_AES_NI_INTEL=m +CONFIG_CRYPTO_AES_NI_INTEL=y +CONFIG_CRYPTO_AES_586=y CONFIG_MTD_OF_PARTS=m CONFIG_MTD_PHYSMAP_OF=m @@ -544,3 +565,7 @@ CONFIG_PROC_DEVICETREE=y CONFIG_SERIAL_OF_PLATFORM=m CONFIG_SERIAL_GRLIB_GAISLER_APBUART=m # CONFIG_MMC_SDHCI_OF is not set + +CONFIG_HP_ACCEL=m + +# CONFIG_RAPIDIO is not set diff --git a/config-x86_64-generic b/config-x86_64-generic index 0154cf1..d4a9a5f 100644 --- a/config-x86_64-generic +++ b/config-x86_64-generic @@ -98,9 +98,11 @@ CONFIG_ACPI_POWER_METER=m CONFIG_ACPI_PROCESSOR_AGGREGATOR=m CONFIG_ACPI_HED=m CONFIG_ACPI_APEI=y +CONFIG_ACPI_APEI_PCIEAER=y CONFIG_ACPI_APEI_GHES=m # CONFIG_ACPI_APEI_EINJ is not set CONFIG_ACPI_IPMI=m +CONFIG_ACPI_CUSTOM_METHOD=m CONFIG_X86_PLATFORM_DEVICES=y CONFIG_ASUS_LAPTOP=m @@ -118,6 +120,12 @@ CONFIG_ACER_WMI=m CONFIG_ACERHDF=m CONFIG_HP_WMI=m CONFIG_DELL_WMI=m +CONFIG_DELL_WMI_AIO=m +CONFIG_ASUS_WMI=m +CONFIG_ASUS_NB_WMI=m +# CONFIG_XO15_EBOOK is not set +CONFIG_INTEL_OAKTRAIL=m + # CONFIG_INTEL_SCU_IPC is not set # CONFIG_TOUCHSCREEN_INTEL_MID is not set @@ -160,6 +168,7 @@ CONFIG_CRYPTO_DEV_PADLOCK_SHA=m CONFIG_CRYPTO_AES_X86_64=y CONFIG_CRYPTO_AES_NI_INTEL=y + CONFIG_CRYPTO_TWOFISH_X86_64=m CONFIG_CRYPTO_SALSA20_X86_64=m @@ -269,6 +278,8 @@ CONFIG_PROC_VMCORE=y CONFIG_CRASH=m CONFIG_DMIID=y +CONFIG_DMI_SYSFS=y + CONFIG_ISCSI_IBFT_FIND=y CONFIG_ISCSI_IBFT=m @@ -294,6 +305,7 @@ CONFIG_KVM_GUEST=y CONFIG_KVM_MMU_AUDIT=y CONFIG_XEN=y +# CONFIG_XEN_DEBUG is not set CONFIG_XEN_MAX_DOMAIN_MEMORY=32 CONFIG_XEN_BALLOON=y CONFIG_XEN_SCRUB_PAGES=y @@ -303,20 +315,27 @@ CONFIG_XEN_FBDEV_FRONTEND=y CONFIG_XEN_KBDDEV_FRONTEND=y CONFIG_XEN_BLKDEV_FRONTEND=m CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XEN_NETDEV_BACKEND=m +CONFIG_XEN_WDT=m +CONFIG_XEN_GRANT_DEV_ALLOC=m CONFIG_XEN_PCIDEV_FRONTEND=m CONFIG_XENFS=m CONFIG_XEN_COMPAT_XENFS=y CONFIG_XEN_DEV_EVTCHN=m CONFIG_XEN_SYS_HYPERVISOR=y CONFIG_XEN_BACKEND=y +CONFIG_XEN_BLKDEV_BACKEND=m CONFIG_XEN_GNTDEV=m CONFIG_XEN_DEBUG_FS=y CONFIG_XEN_PLATFORM_PCI=m +CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m CONFIG_DMADEVICES=y CONFIG_INTEL_IOATDMA=m CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_FAM15H_POWER=m +CONFIG_SENSORS_ACPI_POWER=m # CONFIG_COMPAT_VDSO is not set CONFIG_PROVIDE_OHCI1394_DMA_INIT=y @@ -449,3 +468,9 @@ CONFIG_JUMP_LABEL=y CONFIG_HP_ILO=m CONFIG_TRANSPARENT_HUGEPAGE=y + +CONFIG_HP_ACCEL=m + +# CONFIG_RAPIDIO is not set + +CONFIG_BPF_JIT=y diff --git a/cx88-Fix-HVR4000-IR-keymap.patch b/cx88-Fix-HVR4000-IR-keymap.patch deleted file mode 100644 index b145cd2..0000000 --- a/cx88-Fix-HVR4000-IR-keymap.patch +++ /dev/null @@ -1,55 +0,0 @@ -From linux-kernel-owner@vger.kernel.org Thu May 5 20:14:44 2011 -Date: Thu, 05 May 2011 17:11:08 -0700 -From: Greg KH -To: linux-kernel@vger.kernel.org, stable@kernel.org, - Greg KH -Cc: stable-review@kernel.org, torvalds@linux-foundation.org, - akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, - Jarod Wilson , - Lawrence Rust , - Linux Media Mailing List , - Lawrence Rust , - Mauro Carvalho Chehab -Subject: [patch 36/38] [media] cx88: Fix HVR4000 IR keymap -In-Reply-To: <20110506001225.GA10547@kroah.com> -X-Mailing-List: linux-kernel@vger.kernel.org - -2.6.38-stable review patch. If anyone has any objections, please let us know. - ------------------- - -From: Lawrence Rust - -[fixed in .39 in a much different way that is too big to backport to -.38 - gregkh] - -Fixes the RC key input for Nova-S plus, HVR1100, HVR3000 and HVR4000 in -the 2.6.38 kernel. - -Signed-off-by: Lawrence Rust -Acked-by: Jarod Wilson -Signed-off-by: Mauro Carvalho Chehab - ---- - drivers/media/video/cx88/cx88-input.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/media/video/cx88/cx88-input.c -+++ b/drivers/media/video/cx88/cx88-input.c -@@ -283,7 +283,7 @@ int cx88_ir_init(struct cx88_core *core, - case CX88_BOARD_PCHDTV_HD3000: - case CX88_BOARD_PCHDTV_HD5500: - case CX88_BOARD_HAUPPAUGE_IRONLY: -- ir_codes = RC_MAP_HAUPPAUGE_NEW; -+ ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW; - ir->sampling = 1; - break; - case CX88_BOARD_WINFAST_DTV2000H: - - --- -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html -Please read the FAQ at http://www.tux.org/lkml/ - diff --git a/drm-i915-fix-pipelined-fencing.patch b/drm-i915-fix-pipelined-fencing.patch deleted file mode 100644 index b6c016c..0000000 --- a/drm-i915-fix-pipelined-fencing.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 3b936797f5e4623ae1b80a5f0c4df30a17360bf5 Mon Sep 17 00:00:00 2001 -From: Chris Wilson -Date: Thu, 17 Mar 2011 15:23:22 +0000 -Subject: [PATCH] drm/i915: Fix pipelined fencing - -Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=34584 -Cc: Andy Whitcroft -Cc: Daniel Vetter -Signed-off-by: Chris Wilson ---- - drivers/gpu/drm/i915/i915_gem.c | 46 ++++++++++++++++---------------------- - 1 files changed, 19 insertions(+), 27 deletions(-) - -diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c -index 36e66cc..10378a3 100644 ---- a/drivers/gpu/drm/i915/i915_gem.c -+++ b/drivers/gpu/drm/i915/i915_gem.c -@@ -2544,8 +2544,25 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj, - reg = &dev_priv->fence_regs[obj->fence_reg]; - list_move_tail(®->lru_list, &dev_priv->mm.fence_list); - -- if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) -- pipelined = NULL; -+ if (obj->tiling_changed) { -+ ret = i915_gem_object_flush_fence(obj, -+ pipelined, -+ interruptible); -+ if (ret) -+ return ret; -+ -+ if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) -+ pipelined = NULL; -+ -+ if (pipelined) { -+ reg->setup_seqno = -+ i915_gem_next_request_seqno(dev, pipelined); -+ obj->last_fenced_seqno = reg->setup_seqno; -+ obj->last_fenced_ring = pipelined; -+ } -+ -+ goto update; -+ } - - if (!pipelined) { - if (reg->setup_seqno) { -@@ -2568,31 +2585,6 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj, - interruptible); - if (ret) - return ret; -- } else if (obj->tiling_changed) { -- if (obj->fenced_gpu_access) { -- if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { -- ret = i915_gem_flush_ring(obj->base.dev, obj->ring, -- 0, obj->base.write_domain); -- if (ret) -- return ret; -- } -- -- obj->fenced_gpu_access = false; -- } -- } -- -- if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) -- pipelined = NULL; -- BUG_ON(!pipelined && reg->setup_seqno); -- -- if (obj->tiling_changed) { -- if (pipelined) { -- reg->setup_seqno = -- i915_gem_next_request_seqno(dev, pipelined); -- obj->last_fenced_seqno = reg->setup_seqno; -- obj->last_fenced_ring = pipelined; -- } -- goto update; - } - - return 0; --- -1.5.6.5 - diff --git a/drm-intel-edp-fixes.patch b/drm-intel-edp-fixes.patch index c77ef11..9e8c829 100644 --- a/drm-intel-edp-fixes.patch +++ b/drm-intel-edp-fixes.patch @@ -25,20 +25,12 @@ index 300f64b..2e3db37 100644 if (I915_READ(PCH_PP_STATUS) & PP_ON) return true; -@@ -816,7 +817,7 @@ static bool ironlake_edp_panel_on (struct intel_dp *intel_dp) - */ - msleep(300); +@@ -851,7 +851,7 @@ static bool ironlake_edp_panel_on (struc + I915_WRITE(PCH_PP_CONTROL, pp); + POSTING_READ(PCH_PP_CONTROL); - if (wait_for((I915_READ(PCH_PP_STATUS) & idle_on_mask) == idle_on_mask, + if (wait_for((I915_READ(PCH_PP_STATUS) & idle_on_mask) == idle_on, 5000)) DRM_ERROR("panel on wait timed out: 0x%08x\n", I915_READ(PCH_PP_STATUS)); -@@ -922,6 +923,7 @@ static void intel_dp_prepare(struct drm_encoder *encoder) - - if (is_edp(intel_dp)) { - ironlake_edp_backlight_off(dev); -+ ironlake_edp_panel_off(dev); - ironlake_edp_panel_on(intel_dp); - if (!is_pch_edp(intel_dp)) - ironlake_edp_pll_on(encoder); diff --git a/drm-intel-eeebox-eb1007-quirk.patch b/drm-intel-eeebox-eb1007-quirk.patch deleted file mode 100644 index 9ae3604..0000000 --- a/drm-intel-eeebox-eb1007-quirk.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ab737b006568d01204cc51368c7e2067eecb2cff Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Thu, 7 Apr 2011 13:31:57 +0200 -Subject: [PATCH] drm/i915: Add a no lvds quirk for the Asus EeeBox PC EB1007 - -I found this while figuring out why gnome-shell would not run on my -Asus EeeBox PC EB1007. As a standalone "pc" this device cleary does not have -an internal panel, yet it claims it does. Add a quirk to fix this. - -Signed-off-by: Hans de Goede ---- - drivers/gpu/drm/i915/intel_lvds.c | 8 ++++++++ - 1 files changed, 8 insertions(+), 0 deletions(-) - -diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c -index a562bd2..954822a 100644 ---- a/drivers/gpu/drm/i915/intel_lvds.c -+++ b/drivers/gpu/drm/i915/intel_lvds.c -@@ -724,6 +724,14 @@ static const struct dmi_system_id intel_no_lvds[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "U800"), - }, - }, -+ { -+ .callback = intel_no_lvds_dmi_callback, -+ .ident = "Asus EeeBox PC EB1007", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."), -+ DMI_MATCH(DMI_PRODUCT_NAME, "EB1007"), -+ }, -+ }, - - { } /* terminating entry */ - }; --- -1.7.4.2 - diff --git a/drm-intel-restore-mode.patch b/drm-intel-restore-mode.patch deleted file mode 100644 index b394ca0..0000000 --- a/drm-intel-restore-mode.patch +++ /dev/null @@ -1,128 +0,0 @@ -From e8e7a2b8ccfdae0d4cb6bd25824bbedcd42da316 Mon Sep 17 00:00:00 2001 -From: Dave Airlie -Date: Thu, 21 Apr 2011 22:18:32 +0100 -Subject: [PATCH] drm/i915: restore only the mode of this driver on lastclose (v2) - -i915 calls the panic handler function on last close to reset the modes, -however this is a really bad idea for multi-gpu machines, esp shareable -gpus machines. So add a new entry point for the driver to just restore -its own fbcon mode. - -v2: move code into fb helper, fix panic code to block mode change on -powered off GPUs. - -[airlied: this hits drm core and I wrote it and it was reviewed on intel-gfx - so really I signed it off twice ;-).] -Signed-off-by: Chris Wilson -Signed-off-by: Dave Airlie ---- - drivers/gpu/drm/drm_fb_helper.c | 27 ++++++++++++++++++++------- - drivers/gpu/drm/i915/i915_dma.c | 2 +- - drivers/gpu/drm/i915/intel_drv.h | 1 + - drivers/gpu/drm/i915/intel_fb.c | 10 ++++++++++ - include/drm/drm_fb_helper.h | 1 + - 5 files changed, 33 insertions(+), 8 deletions(-) - -diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c -index 9507204..11d7a72 100644 ---- a/drivers/gpu/drm/drm_fb_helper.c -+++ b/drivers/gpu/drm/drm_fb_helper.c -@@ -342,9 +342,22 @@ int drm_fb_helper_debug_leave(struct fb_info *info) - } - EXPORT_SYMBOL(drm_fb_helper_debug_leave); - -+bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper) -+{ -+ bool error = false; -+ int i, ret; -+ for (i = 0; i < fb_helper->crtc_count; i++) { -+ struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; -+ ret = drm_crtc_helper_set_config(mode_set); -+ if (ret) -+ error = true; -+ } -+ return error; -+} -+EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode); -+ - bool drm_fb_helper_force_kernel_mode(void) - { -- int i = 0; - bool ret, error = false; - struct drm_fb_helper *helper; - -@@ -352,12 +365,12 @@ bool drm_fb_helper_force_kernel_mode(void) - return false; - - list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { -- for (i = 0; i < helper->crtc_count; i++) { -- struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set; -- ret = drm_crtc_helper_set_config(mode_set); -- if (ret) -- error = true; -- } -+ if (helper->dev->switch_power_state == DRM_SWITCH_POWER_OFF) -+ continue; -+ -+ ret = drm_fb_helper_restore_fbdev_mode(helper); -+ if (ret) -+ error = true; - } - return error; - } -diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c -index 7273037..12876f2 100644 ---- a/drivers/gpu/drm/i915/i915_dma.c -+++ b/drivers/gpu/drm/i915/i915_dma.c -@@ -2207,7 +2207,7 @@ void i915_driver_lastclose(struct drm_device * dev) - drm_i915_private_t *dev_priv = dev->dev_private; - - if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { -- drm_fb_helper_restore(); -+ intel_fb_restore_mode(dev); - vga_switcheroo_process_delayed_switch(); - return; - } -diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h -index f5b0d83..1d20712 100644 ---- a/drivers/gpu/drm/i915/intel_drv.h -+++ b/drivers/gpu/drm/i915/intel_drv.h -@@ -338,4 +338,5 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data, - struct drm_file *file_priv); - - extern void intel_fb_output_poll_changed(struct drm_device *dev); -+extern void intel_fb_restore_mode(struct drm_device *dev); - #endif /* __INTEL_DRV_H__ */ -diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c -index 5127827..ec49bae 100644 ---- a/drivers/gpu/drm/i915/intel_fb.c -+++ b/drivers/gpu/drm/i915/intel_fb.c -@@ -264,3 +264,13 @@ void intel_fb_output_poll_changed(struct drm_device *dev) - drm_i915_private_t *dev_priv = dev->dev_private; - drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); - } -+ -+void intel_fb_restore_mode(struct drm_device *dev) -+{ -+ int ret; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ -+ ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); -+ if (ret) -+ DRM_DEBUG("failed to restore crtc mode\n"); -+} -diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h -index f22e7fe..ade09d7 100644 ---- a/include/drm/drm_fb_helper.h -+++ b/include/drm/drm_fb_helper.h -@@ -118,6 +118,7 @@ int drm_fb_helper_setcolreg(unsigned regno, - unsigned transp, - struct fb_info *info); - -+bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper); - void drm_fb_helper_restore(void); - void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper, - uint32_t fb_width, uint32_t fb_height); --- -1.7.1 - diff --git a/drm-nouveau-updates.patch b/drm-nouveau-updates.patch index 7a703e8..e69de29 100644 --- a/drm-nouveau-updates.patch +++ b/drm-nouveau-updates.patch @@ -1,6777 +0,0 @@ -diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c -index 6bdab89..729d5fd 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 -@@ -282,7 +282,7 @@ static void still_alive(void) - { - #if 0 - sync(); -- msleep(2); -+ mdelay(2); - #endif - } - -@@ -1904,7 +1904,7 @@ init_condition_time(struct nvbios *bios, uint16_t offset, - BIOSLOG(bios, "0x%04X: " - "Condition not met, sleeping for 20ms\n", - offset); -- msleep(20); -+ mdelay(20); - } - } - -@@ -1938,7 +1938,7 @@ init_ltime(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) - BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X milliseconds\n", - offset, time); - -- msleep(time); -+ mdelay(time); - - return 3; - } -@@ -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) - { - /* -@@ -2962,7 +2983,7 @@ init_time(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) - if (time < 1000) - udelay(time); - else -- msleep((time + 900) / 1000); -+ mdelay((time + 900) / 1000); - - return 3; - } -@@ -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. -@@ -3856,7 +3877,7 @@ static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entr - - if (script == LVDS_PANEL_OFF) { - /* off-on delay in ms */ -- msleep(ROM16(bios->data[bios->fp.xlated_entry + 7])); -+ mdelay(ROM16(bios->data[bios->fp.xlated_entry + 7])); - } - #ifdef __powerpc__ - /* Powerbook specific quirks */ -@@ -5028,11 +5049,7 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims - pll_lim->vco1.max_n = record[11]; - pll_lim->min_p = record[12]; - pll_lim->max_p = record[13]; -- /* where did this go to?? */ -- if ((entry[0] & 0xf0) == 0x80) -- pll_lim->refclk = 27000; -- else -- pll_lim->refclk = 100000; -+ pll_lim->refclk = ROM16(entry[9]) * 1000; - } - - /* -@@ -5950,6 +5967,11 @@ apply_dcb_connector_quirks(struct nvbios *bios, int idx) - } - } - -+static const u8 hpd_gpio[16] = { -+ 0xff, 0x07, 0x08, 0xff, 0xff, 0x51, 0x52, 0xff, -+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x5e, 0x5f, 0x60, -+}; -+ - static void - parse_dcb_connector_table(struct nvbios *bios) - { -@@ -5986,23 +6008,9 @@ parse_dcb_connector_table(struct nvbios *bios) - - cte->type = (cte->entry & 0x000000ff) >> 0; - cte->index2 = (cte->entry & 0x00000f00) >> 8; -- switch (cte->entry & 0x00033000) { -- case 0x00001000: -- cte->gpio_tag = 0x07; -- break; -- case 0x00002000: -- cte->gpio_tag = 0x08; -- break; -- case 0x00010000: -- cte->gpio_tag = 0x51; -- break; -- case 0x00020000: -- cte->gpio_tag = 0x52; -- break; -- default: -- cte->gpio_tag = 0xff; -- break; -- } -+ -+ cte->gpio_tag = ffs((cte->entry & 0x07033000) >> 12); -+ cte->gpio_tag = hpd_gpio[cte->gpio_tag]; - - if (cte->type == 0xff) - continue; -@@ -6023,6 +6031,7 @@ parse_dcb_connector_table(struct nvbios *bios) - case DCB_CONNECTOR_DVI_I: - case DCB_CONNECTOR_DVI_D: - case DCB_CONNECTOR_LVDS: -+ case DCB_CONNECTOR_LVDS_SPWG: - case DCB_CONNECTOR_DP: - case DCB_CONNECTOR_eDP: - case DCB_CONNECTOR_HDMI_0: -@@ -6342,6 +6351,32 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) - } - } - -+ /* XFX GT-240X-YA -+ * -+ * So many things wrong here, replace the entire encoder table.. -+ */ -+ if (nv_match_device(dev, 0x0ca3, 0x1682, 0x3003)) { -+ if (idx == 0) { -+ *conn = 0x02001300; /* VGA, connector 1 */ -+ *conf = 0x00000028; -+ } else -+ if (idx == 1) { -+ *conn = 0x01010312; /* DVI, connector 0 */ -+ *conf = 0x00020030; -+ } else -+ if (idx == 2) { -+ *conn = 0x01010310; /* VGA, connector 0 */ -+ *conf = 0x00000028; -+ } else -+ if (idx == 3) { -+ *conn = 0x02022362; /* HDMI, connector 2 */ -+ *conf = 0x00020010; -+ } else { -+ *conn = 0x0000000e; /* EOL */ -+ *conf = 0x00000000; -+ } -+ } -+ - return true; - } - -@@ -6702,11 +6737,11 @@ nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table, - struct nvbios *bios = &dev_priv->vbios; - struct init_exec iexec = { true, false }; - -- mutex_lock(&bios->lock); -+ spin_lock_bh(&bios->lock); - bios->display.output = dcbent; - parse_init_table(bios, table, &iexec); - bios->display.output = NULL; -- mutex_unlock(&bios->lock); -+ spin_unlock_bh(&bios->lock); - } - - static bool NVInitVBIOS(struct drm_device *dev) -@@ -6715,7 +6750,7 @@ static bool NVInitVBIOS(struct drm_device *dev) - struct nvbios *bios = &dev_priv->vbios; - - memset(bios, 0, sizeof(struct nvbios)); -- mutex_init(&bios->lock); -+ spin_lock_init(&bios->lock); - bios->dev = dev; - - if (!NVShadowVBIOS(dev, bios->data)) -diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h -index 50a648e..050c314 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_bios.h -+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h -@@ -82,6 +82,7 @@ enum dcb_connector_type { - DCB_CONNECTOR_DVI_I = 0x30, - DCB_CONNECTOR_DVI_D = 0x31, - DCB_CONNECTOR_LVDS = 0x40, -+ DCB_CONNECTOR_LVDS_SPWG = 0x41, - DCB_CONNECTOR_DP = 0x46, - DCB_CONNECTOR_eDP = 0x47, - DCB_CONNECTOR_HDMI_0 = 0x60, -@@ -251,7 +252,7 @@ struct nvbios { - uint8_t digital_min_front_porch; - bool fp_no_ddc; - -- struct mutex lock; -+ spinlock_t lock; - - uint8_t data[NV_PROM_SIZE]; - unsigned int length; -diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c -index a521840..2ad49cb 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_bo.c -+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c -@@ -57,8 +57,8 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo) - } - - static void --nouveau_bo_fixup_align(struct nouveau_bo *nvbo, int *align, int *size, -- int *page_shift) -+nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags, -+ int *align, int *size, int *page_shift) - { - struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); - -@@ -83,7 +83,7 @@ nouveau_bo_fixup_align(struct nouveau_bo *nvbo, int *align, int *size, - } - } else { - if (likely(dev_priv->chan_vm)) { -- if (*size > 256 * 1024) -+ if (!(flags & TTM_PL_FLAG_TT) && *size > 256 * 1024) - *page_shift = dev_priv->chan_vm->lpg_shift; - else - *page_shift = dev_priv->chan_vm->spg_shift; -@@ -101,8 +101,7 @@ nouveau_bo_fixup_align(struct nouveau_bo *nvbo, int *align, int *size, - int - nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, - int size, int align, uint32_t flags, uint32_t tile_mode, -- uint32_t tile_flags, bool no_vm, bool mappable, -- struct nouveau_bo **pnvbo) -+ uint32_t tile_flags, struct nouveau_bo **pnvbo) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_bo *nvbo; -@@ -113,16 +112,14 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, - return -ENOMEM; - INIT_LIST_HEAD(&nvbo->head); - INIT_LIST_HEAD(&nvbo->entry); -- nvbo->mappable = mappable; -- nvbo->no_vm = no_vm; - nvbo->tile_mode = tile_mode; - nvbo->tile_flags = tile_flags; - nvbo->bo.bdev = &dev_priv->ttm.bdev; - -- nouveau_bo_fixup_align(nvbo, &align, &size, &page_shift); -+ nouveau_bo_fixup_align(nvbo, flags, &align, &size, &page_shift); - align >>= PAGE_SHIFT; - -- if (!nvbo->no_vm && dev_priv->chan_vm) { -+ if (dev_priv->chan_vm) { - ret = nouveau_vm_get(dev_priv->chan_vm, size, page_shift, - NV_MEM_ACCESS_RW, &nvbo->vma); - if (ret) { -@@ -144,11 +141,8 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, - } - nvbo->channel = NULL; - -- if (nvbo->vma.node) { -- if (nvbo->bo.mem.mem_type == TTM_PL_VRAM) -- nvbo->bo.offset = nvbo->vma.offset; -- } -- -+ if (nvbo->vma.node) -+ nvbo->bo.offset = nvbo->vma.offset; - *pnvbo = nvbo; - return 0; - } -@@ -318,11 +312,8 @@ nouveau_bo_validate(struct nouveau_bo *nvbo, bool interruptible, - if (ret) - return ret; - -- if (nvbo->vma.node) { -- if (nvbo->bo.mem.mem_type == TTM_PL_VRAM) -- nvbo->bo.offset = nvbo->vma.offset; -- } -- -+ if (nvbo->vma.node) -+ nvbo->bo.offset = nvbo->vma.offset; - return 0; - } - -@@ -385,7 +376,8 @@ nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev) - case NOUVEAU_GART_AGP: - return ttm_agp_backend_init(bdev, dev->agp->bridge); - #endif -- case NOUVEAU_GART_SGDMA: -+ case NOUVEAU_GART_PDMA: -+ case NOUVEAU_GART_HW: - return nouveau_sgdma_init_ttm(dev); - default: - NV_ERROR(dev, "Unknown GART type %d\n", -@@ -431,7 +423,10 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, - man->default_caching = TTM_PL_FLAG_WC; - break; - case TTM_PL_TT: -- man->func = &ttm_bo_manager_func; -+ if (dev_priv->card_type >= NV_50) -+ man->func = &nouveau_gart_manager; -+ else -+ man->func = &ttm_bo_manager_func; - switch (dev_priv->gart_info.type) { - case NOUVEAU_GART_AGP: - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; -@@ -439,7 +434,8 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, - TTM_PL_FLAG_WC; - man->default_caching = TTM_PL_FLAG_WC; - break; -- case NOUVEAU_GART_SGDMA: -+ case NOUVEAU_GART_PDMA: -+ case NOUVEAU_GART_HW: - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | - TTM_MEMTYPE_FLAG_CMA; - man->available_caching = TTM_PL_MASK_CACHING; -@@ -501,45 +497,22 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, - return ret; - } - --static inline uint32_t --nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo, -- struct nouveau_channel *chan, struct ttm_mem_reg *mem) --{ -- struct nouveau_bo *nvbo = nouveau_bo(bo); -- -- if (nvbo->no_vm) { -- if (mem->mem_type == TTM_PL_TT) -- return NvDmaGART; -- return NvDmaVRAM; -- } -- -- if (mem->mem_type == TTM_PL_TT) -- return chan->gart_handle; -- return chan->vram_handle; --} -- - static int - nvc0_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 drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); -+ struct nouveau_mem *old_node = old_mem->mm_node; -+ struct nouveau_mem *new_node = new_mem->mm_node; - struct nouveau_bo *nvbo = nouveau_bo(bo); -- u64 src_offset = old_mem->start << PAGE_SHIFT; -- u64 dst_offset = new_mem->start << PAGE_SHIFT; - u32 page_count = new_mem->num_pages; -+ u64 src_offset, dst_offset; - int ret; - -- if (!nvbo->no_vm) { -- if (old_mem->mem_type == TTM_PL_VRAM) -- src_offset = nvbo->vma.offset; -- else -- src_offset += dev_priv->gart_info.aper_base; -- -- if (new_mem->mem_type == TTM_PL_VRAM) -- dst_offset = nvbo->vma.offset; -- else -- dst_offset += dev_priv->gart_info.aper_base; -- } -+ src_offset = old_node->tmp_vma.offset; -+ if (new_node->tmp_vma.node) -+ dst_offset = new_node->tmp_vma.offset; -+ else -+ dst_offset = nvbo->vma.offset; - - page_count = new_mem->num_pages; - while (page_count) { -@@ -574,33 +547,18 @@ static int - 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 drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); -+ struct nouveau_mem *old_node = old_mem->mm_node; -+ struct nouveau_mem *new_node = new_mem->mm_node; - struct nouveau_bo *nvbo = nouveau_bo(bo); - u64 length = (new_mem->num_pages << PAGE_SHIFT); - u64 src_offset, dst_offset; - int ret; - -- src_offset = old_mem->start << PAGE_SHIFT; -- dst_offset = new_mem->start << PAGE_SHIFT; -- if (!nvbo->no_vm) { -- if (old_mem->mem_type == TTM_PL_VRAM) -- src_offset = nvbo->vma.offset; -- else -- src_offset += dev_priv->gart_info.aper_base; -- -- if (new_mem->mem_type == TTM_PL_VRAM) -- dst_offset = nvbo->vma.offset; -- else -- dst_offset += dev_priv->gart_info.aper_base; -- } -- -- ret = RING_SPACE(chan, 3); -- if (ret) -- return ret; -- -- 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)); -+ src_offset = old_node->tmp_vma.offset; -+ if (new_node->tmp_vma.node) -+ dst_offset = new_node->tmp_vma.offset; -+ else -+ dst_offset = nvbo->vma.offset; - - while (length) { - u32 amount, stride, height; -@@ -681,6 +639,15 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, - return 0; - } - -+static inline uint32_t -+nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo, -+ struct nouveau_channel *chan, struct ttm_mem_reg *mem) -+{ -+ if (mem->mem_type == TTM_PL_TT) -+ return chan->gart_handle; -+ return chan->vram_handle; -+} -+ - 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) -@@ -734,15 +701,43 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, - { - struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); - struct nouveau_bo *nvbo = nouveau_bo(bo); -+ struct ttm_mem_reg *old_mem = &bo->mem; - struct nouveau_channel *chan; - int ret; - - chan = nvbo->channel; -- if (!chan || nvbo->no_vm) { -+ if (!chan) { - chan = dev_priv->channel; - mutex_lock_nested(&chan->mutex, NOUVEAU_KCHANNEL_MUTEX); - } - -+ /* create temporary vma for old memory, this will get cleaned -+ * up after ttm destroys the ttm_mem_reg -+ */ -+ if (dev_priv->card_type >= NV_50) { -+ struct nouveau_mem *node = old_mem->mm_node; -+ if (!node->tmp_vma.node) { -+ u32 page_shift = nvbo->vma.node->type; -+ if (old_mem->mem_type == TTM_PL_TT) -+ page_shift = nvbo->vma.vm->spg_shift; -+ -+ ret = nouveau_vm_get(chan->vm, -+ old_mem->num_pages << PAGE_SHIFT, -+ page_shift, NV_MEM_ACCESS_RO, -+ &node->tmp_vma); -+ if (ret) -+ goto out; -+ } -+ -+ if (old_mem->mem_type == TTM_PL_VRAM) -+ nouveau_vm_map(&node->tmp_vma, node); -+ else { -+ nouveau_vm_map_sg(&node->tmp_vma, 0, -+ old_mem->num_pages << PAGE_SHIFT, -+ node, node->pages); -+ } -+ } -+ - if (dev_priv->card_type < NV_50) - ret = nv04_bo_move_m2mf(chan, bo, &bo->mem, new_mem); - else -@@ -756,6 +751,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, - no_wait_gpu, new_mem); - } - -+out: - if (chan == dev_priv->channel) - mutex_unlock(&chan->mutex); - return ret; -@@ -766,6 +762,7 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool 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); - u32 placement_memtype = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; - struct ttm_placement placement; - struct ttm_mem_reg tmp_mem; -@@ -785,7 +782,23 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, - if (ret) - goto out; - -+ if (dev_priv->card_type >= NV_50) { -+ struct nouveau_bo *nvbo = nouveau_bo(bo); -+ struct nouveau_mem *node = tmp_mem.mm_node; -+ struct nouveau_vma *vma = &nvbo->vma; -+ if (vma->node->type != vma->vm->spg_shift) -+ vma = &node->tmp_vma; -+ nouveau_vm_map_sg(vma, 0, tmp_mem.num_pages << PAGE_SHIFT, -+ node, node->pages); -+ } -+ - ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait_reserve, no_wait_gpu, &tmp_mem); -+ -+ if (dev_priv->card_type >= NV_50) { -+ struct nouveau_bo *nvbo = nouveau_bo(bo); -+ nouveau_vm_unmap(&nvbo->vma); -+ } -+ - if (ret) - goto out; - -@@ -828,6 +841,36 @@ out: - return ret; - } - -+static void -+nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem) -+{ -+ struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); -+ struct nouveau_mem *node = new_mem->mm_node; -+ struct nouveau_bo *nvbo = nouveau_bo(bo); -+ struct nouveau_vma *vma = &nvbo->vma; -+ struct nouveau_vm *vm = vma->vm; -+ -+ if (dev_priv->card_type < NV_50) -+ return; -+ -+ switch (new_mem->mem_type) { -+ case TTM_PL_VRAM: -+ nouveau_vm_map(vma, node); -+ break; -+ case TTM_PL_TT: -+ if (vma->node->type != vm->spg_shift) { -+ nouveau_vm_unmap(vma); -+ vma = &node->tmp_vma; -+ } -+ nouveau_vm_map_sg(vma, 0, new_mem->num_pages << PAGE_SHIFT, -+ node, node->pages); -+ break; -+ default: -+ nouveau_vm_unmap(&nvbo->vma); -+ break; -+ } -+} -+ - static int - nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem, - struct nouveau_tile_reg **new_tile) -@@ -835,19 +878,13 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem, - struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); - struct drm_device *dev = dev_priv->dev; - struct nouveau_bo *nvbo = nouveau_bo(bo); -- uint64_t offset; -+ u64 offset = new_mem->start << PAGE_SHIFT; - -- if (nvbo->no_vm || new_mem->mem_type != TTM_PL_VRAM) { -- /* Nothing to do. */ -- *new_tile = NULL; -+ *new_tile = NULL; -+ if (new_mem->mem_type != TTM_PL_VRAM) - return 0; -- } -- -- offset = new_mem->start << PAGE_SHIFT; - -- if (dev_priv->chan_vm) { -- nouveau_vm_map(&nvbo->vma, new_mem->mm_node); -- } else if (dev_priv->card_type >= NV_10) { -+ if (dev_priv->card_type >= NV_10) { - *new_tile = nv10_mem_set_tiling(dev, offset, new_mem->size, - nvbo->tile_mode, - nvbo->tile_flags); -@@ -864,11 +901,8 @@ nouveau_bo_vm_cleanup(struct ttm_buffer_object *bo, - struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); - struct drm_device *dev = dev_priv->dev; - -- if (dev_priv->card_type >= NV_10 && -- dev_priv->card_type < NV_50) { -- nv10_mem_put_tile_region(dev, *old_tile, bo->sync_obj); -- *old_tile = new_tile; -- } -+ nv10_mem_put_tile_region(dev, *old_tile, bo->sync_obj); -+ *old_tile = new_tile; - } - - static int -@@ -882,9 +916,11 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, - struct nouveau_tile_reg *new_tile = NULL; - int ret = 0; - -- ret = nouveau_bo_vm_bind(bo, new_mem, &new_tile); -- if (ret) -- return ret; -+ if (dev_priv->card_type < NV_50) { -+ ret = nouveau_bo_vm_bind(bo, new_mem, &new_tile); -+ if (ret) -+ return ret; -+ } - - /* Fake bo copy. */ - if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) { -@@ -915,10 +951,12 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, - ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); - - out: -- if (ret) -- nouveau_bo_vm_cleanup(bo, NULL, &new_tile); -- else -- nouveau_bo_vm_cleanup(bo, new_tile, &nvbo->tile); -+ if (dev_priv->card_type < NV_50) { -+ if (ret) -+ nouveau_bo_vm_cleanup(bo, NULL, &new_tile); -+ else -+ nouveau_bo_vm_cleanup(bo, new_tile, &nvbo->tile); -+ } - - return ret; - } -@@ -959,7 +997,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) - break; - case TTM_PL_VRAM: - { -- struct nouveau_vram *vram = mem->mm_node; -+ struct nouveau_mem *node = mem->mm_node; - u8 page_shift; - - if (!dev_priv->bar1_vm) { -@@ -970,23 +1008,23 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) - } - - if (dev_priv->card_type == NV_C0) -- page_shift = vram->page_shift; -+ page_shift = node->page_shift; - else - page_shift = 12; - - ret = nouveau_vm_get(dev_priv->bar1_vm, mem->bus.size, - page_shift, NV_MEM_ACCESS_RW, -- &vram->bar_vma); -+ &node->bar_vma); - if (ret) - return ret; - -- nouveau_vm_map(&vram->bar_vma, vram); -+ nouveau_vm_map(&node->bar_vma, node); - if (ret) { -- nouveau_vm_put(&vram->bar_vma); -+ nouveau_vm_put(&node->bar_vma); - return ret; - } - -- mem->bus.offset = vram->bar_vma.offset; -+ mem->bus.offset = node->bar_vma.offset; - if (dev_priv->card_type == NV_50) /*XXX*/ - mem->bus.offset -= 0x0020000000ULL; - mem->bus.base = pci_resource_start(dev->pdev, 1); -@@ -1003,16 +1041,16 @@ static void - nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) - { - struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev); -- struct nouveau_vram *vram = mem->mm_node; -+ struct nouveau_mem *node = mem->mm_node; - - if (!dev_priv->bar1_vm || mem->mem_type != TTM_PL_VRAM) - return; - -- if (!vram->bar_vma.node) -+ if (!node->bar_vma.node) - return; - -- nouveau_vm_unmap(&vram->bar_vma); -- nouveau_vm_put(&vram->bar_vma); -+ nouveau_vm_unmap(&node->bar_vma); -+ nouveau_vm_put(&node->bar_vma); - } - - static int -@@ -1062,6 +1100,7 @@ struct ttm_bo_driver nouveau_bo_driver = { - .invalidate_caches = nouveau_bo_invalidate_caches, - .init_mem_type = nouveau_bo_init_mem_type, - .evict_flags = nouveau_bo_evict_flags, -+ .move_notify = nouveau_bo_move_ntfy, - .move = nouveau_bo_move, - .verify_access = nouveau_bo_verify_access, - .sync_obj_signaled = __nouveau_fence_signalled, -diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c -index 3960d66..3837090 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_channel.c -+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c -@@ -35,7 +35,7 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_bo *pb = chan->pushbuf_bo; - struct nouveau_gpuobj *pushbuf = NULL; -- int ret; -+ int ret = 0; - - if (dev_priv->card_type >= NV_50) { - if (dev_priv->card_type < NV_C0) { -@@ -90,8 +90,7 @@ nouveau_channel_user_pushbuf_alloc(struct drm_device *dev) - else - location = TTM_PL_FLAG_TT; - -- ret = nouveau_bo_new(dev, NULL, 65536, 0, location, 0, 0x0000, false, -- true, &pushbuf); -+ ret = nouveau_bo_new(dev, NULL, 65536, 0, location, 0, 0x0000, &pushbuf); - if (ret) { - NV_ERROR(dev, "error allocating DMA push buffer: %d\n", ret); - return NULL; -diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c -index 390d82c..084c089 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_connector.c -+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c -@@ -438,7 +438,7 @@ nouveau_connector_set_property(struct drm_connector *connector, - } - - /* LVDS always needs gpu scaling */ -- if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS && -+ if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS && - value == DRM_MODE_SCALE_NONE) - return -EINVAL; - -@@ -646,6 +646,7 @@ nouveau_connector_get_modes(struct drm_connector *connector) - ret = get_slave_funcs(encoder)->get_modes(encoder, connector); - - if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS || -+ nv_connector->dcb->type == DCB_CONNECTOR_LVDS_SPWG || - nv_connector->dcb->type == DCB_CONNECTOR_eDP) - ret += nouveau_connector_scaler_modes_add(connector); - -@@ -806,6 +807,7 @@ nouveau_connector_create(struct drm_device *dev, int index) - type = DRM_MODE_CONNECTOR_HDMIA; - break; - case DCB_CONNECTOR_LVDS: -+ case DCB_CONNECTOR_LVDS_SPWG: - type = DRM_MODE_CONNECTOR_LVDS; - funcs = &nouveau_connector_funcs_lvds; - break; -@@ -834,7 +836,7 @@ nouveau_connector_create(struct drm_device *dev, int index) - drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); - - /* Check if we need dithering enabled */ -- if (dcb->type == DCB_CONNECTOR_LVDS) { -+ if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { - bool dummy, is_24bit = false; - - ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &is_24bit); -@@ -879,7 +881,7 @@ nouveau_connector_create(struct drm_device *dev, int index) - nv_connector->use_dithering ? - DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF); - -- if (dcb->type != DCB_CONNECTOR_LVDS) { -+ if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS) { - if (dev_priv->card_type >= NV_50) - connector->polled = DRM_CONNECTOR_POLL_HPD; - else -diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c -index 505c6bf..764c15d 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_display.c -+++ b/drivers/gpu/drm/nouveau/nouveau_display.c -@@ -32,6 +32,7 @@ - #include "nouveau_hw.h" - #include "nouveau_crtc.h" - #include "nouveau_dma.h" -+#include "nv50_display.h" - - static void - nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) -@@ -61,18 +62,59 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { - }; - - int --nouveau_framebuffer_init(struct drm_device *dev, struct nouveau_framebuffer *nouveau_fb, -- struct drm_mode_fb_cmd *mode_cmd, struct nouveau_bo *nvbo) -+nouveau_framebuffer_init(struct drm_device *dev, -+ struct nouveau_framebuffer *nv_fb, -+ struct drm_mode_fb_cmd *mode_cmd, -+ struct nouveau_bo *nvbo) - { -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct drm_framebuffer *fb = &nv_fb->base; - int ret; - -- ret = drm_framebuffer_init(dev, &nouveau_fb->base, &nouveau_framebuffer_funcs); -+ ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs); - if (ret) { - return ret; - } - -- drm_helper_mode_fill_fb_struct(&nouveau_fb->base, mode_cmd); -- nouveau_fb->nvbo = nvbo; -+ drm_helper_mode_fill_fb_struct(fb, mode_cmd); -+ nv_fb->nvbo = nvbo; -+ -+ if (dev_priv->card_type >= NV_50) { -+ u32 tile_flags = nouveau_bo_tile_layout(nvbo); -+ if (tile_flags == 0x7a00 || -+ tile_flags == 0xfe00) -+ nv_fb->r_dma = NvEvoFB32; -+ else -+ if (tile_flags == 0x7000) -+ nv_fb->r_dma = NvEvoFB16; -+ else -+ nv_fb->r_dma = NvEvoVRAM_LP; -+ -+ switch (fb->depth) { -+ case 8: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_8; break; -+ case 15: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_15; break; -+ case 16: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_16; break; -+ case 24: -+ case 32: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_24; break; -+ case 30: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_30; break; -+ default: -+ NV_ERROR(dev, "unknown depth %d\n", fb->depth); -+ return -EINVAL; -+ } -+ -+ if (dev_priv->chipset == 0x50) -+ nv_fb->r_format |= (tile_flags << 8); -+ -+ if (!tile_flags) -+ nv_fb->r_pitch = 0x00100000 | fb->pitch; -+ else { -+ u32 mode = nvbo->tile_mode; -+ if (dev_priv->card_type >= NV_C0) -+ mode >>= 4; -+ nv_fb->r_pitch = ((fb->pitch / 4) << 4) | mode; -+ } -+ } -+ - return 0; - } - -@@ -182,6 +224,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan, - struct nouveau_page_flip_state *s, - struct nouveau_fence **pfence) - { -+ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct drm_device *dev = chan->dev; - unsigned long flags; - int ret; -@@ -201,9 +244,12 @@ nouveau_page_flip_emit(struct nouveau_channel *chan, - if (ret) - goto fail; - -- BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); -- OUT_RING(chan, 0); -- FIRE_RING(chan); -+ if (dev_priv->card_type < NV_C0) -+ BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); -+ else -+ BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0500, 1); -+ OUT_RING (chan, 0); -+ FIRE_RING (chan); - - ret = nouveau_fence_new(chan, pfence, true); - if (ret) -@@ -244,7 +290,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, - - /* Initialize a page flip struct */ - *s = (struct nouveau_page_flip_state) -- { { }, s->event, nouveau_crtc(crtc)->index, -+ { { }, event, nouveau_crtc(crtc)->index, - fb->bits_per_pixel, fb->pitch, crtc->x, crtc->y, - new_bo->bo.offset }; - -@@ -255,6 +301,14 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, - mutex_lock(&chan->mutex); - - /* Emit a page flip */ -+ if (dev_priv->card_type >= NV_50) { -+ ret = nv50_display_flip_next(crtc, fb, chan); -+ if (ret) { -+ nouveau_channel_put(&chan); -+ goto fail_unreserve; -+ } -+ } -+ - ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); - nouveau_channel_put(&chan); - if (ret) -@@ -305,7 +359,8 @@ nouveau_finish_page_flip(struct nouveau_channel *chan, - } - - list_del(&s->head); -- *ps = *s; -+ if (ps) -+ *ps = *s; - kfree(s); - - spin_unlock_irqrestore(&dev->event_lock, flags); -diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c -index b368ed7..568caed 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_dma.c -+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c -@@ -83,7 +83,7 @@ nouveau_dma_init(struct nouveau_channel *chan) - return ret; - - /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ -- ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfd0, 0x1000, -+ ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000, - &chan->m2mf_ntfy); - if (ret) - return ret; -@@ -97,13 +97,15 @@ nouveau_dma_init(struct nouveau_channel *chan) - OUT_RING(chan, 0); - - /* Initialise NV_MEMORY_TO_MEMORY_FORMAT */ -- ret = RING_SPACE(chan, 4); -+ ret = RING_SPACE(chan, 6); - if (ret) - return ret; - BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1); -- OUT_RING(chan, NvM2MF); -- BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); -- OUT_RING(chan, NvNotify0); -+ OUT_RING (chan, NvM2MF); -+ BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3); -+ OUT_RING (chan, NvNotify0); -+ OUT_RING (chan, chan->vram_handle); -+ OUT_RING (chan, chan->gart_handle); - - /* Sit back and pray the channel works.. */ - FIRE_RING(chan); -diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h -index c36f176..23d4edf 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_dma.h -+++ b/drivers/gpu/drm/nouveau/nouveau_dma.h -@@ -61,8 +61,6 @@ enum { - NvM2MF = 0x80000001, - NvDmaFB = 0x80000002, - NvDmaTT = 0x80000003, -- NvDmaVRAM = 0x80000004, -- NvDmaGART = 0x80000005, - NvNotify0 = 0x80000006, - Nv2D = 0x80000007, - NvCtxSurf2D = 0x80000008, -@@ -73,12 +71,15 @@ enum { - NvImageBlit = 0x8000000d, - NvSw = 0x8000000e, - NvSema = 0x8000000f, -+ NvEvoSema0 = 0x80000010, -+ NvEvoSema1 = 0x80000011, - - /* G80+ display objects */ - NvEvoVRAM = 0x01000000, - NvEvoFB16 = 0x01000001, - NvEvoFB32 = 0x01000002, -- NvEvoVRAM_LP = 0x01000003 -+ NvEvoVRAM_LP = 0x01000003, -+ NvEvoSync = 0xcafe0000 - }; - - #define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039 -diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c -index 38d5995..7beb82a 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_dp.c -+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c -@@ -175,7 +175,6 @@ nouveau_dp_link_train_adjust(struct drm_encoder *encoder, uint8_t *config) - { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; -- struct bit_displayport_encoder_table_entry *dpse; - struct bit_displayport_encoder_table *dpe; - int ret, i, dpe_headerlen, vs = 0, pre = 0; - uint8_t request[2]; -@@ -183,7 +182,6 @@ nouveau_dp_link_train_adjust(struct drm_encoder *encoder, uint8_t *config) - dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen); - if (!dpe) - return false; -- dpse = (void *)((char *)dpe + dpe_headerlen); - - ret = auxch_rd(encoder, DP_ADJUST_REQUEST_LANE0_1, request, 2); - if (ret) -diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h -index 982d70b..b260c55 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_drv.h -+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h -@@ -57,7 +57,7 @@ struct nouveau_fpriv { - #include "nouveau_util.h" - - struct nouveau_grctx; --struct nouveau_vram; -+struct nouveau_mem; - #include "nouveau_vm.h" - - #define MAX_NUM_DCB_ENTRIES 16 -@@ -65,13 +65,16 @@ struct nouveau_vram; - #define NOUVEAU_MAX_CHANNEL_NR 128 - #define NOUVEAU_MAX_TILE_NR 15 - --struct nouveau_vram { -+struct nouveau_mem { - struct drm_device *dev; - - struct nouveau_vma bar_vma; -+ struct nouveau_vma tmp_vma; - u8 page_shift; - -+ struct drm_mm_node *tag; - struct list_head regions; -+ dma_addr_t *pages; - u32 memtype; - u64 offset; - u64 size; -@@ -90,6 +93,7 @@ struct nouveau_tile_reg { - struct nouveau_bo { - struct ttm_buffer_object bo; - struct ttm_placement placement; -+ u32 valid_domains; - u32 placements[3]; - u32 busy_placements[3]; - struct ttm_bo_kmap_obj kmap; -@@ -104,8 +108,6 @@ struct nouveau_bo { - struct nouveau_channel *channel; - - struct nouveau_vma vma; -- bool mappable; -- bool no_vm; - - uint32_t tile_mode; - uint32_t tile_flags; -@@ -387,6 +389,7 @@ struct nouveau_pgraph_engine { - }; - - struct nouveau_display_engine { -+ void *priv; - int (*early_init)(struct drm_device *); - void (*late_takedown)(struct drm_device *); - int (*create)(struct drm_device *); -@@ -433,6 +436,7 @@ struct nouveau_pm_level { - u32 memory; - u32 shader; - u32 unk05; -+ u32 unk0a; - - u8 voltage; - u8 fanspeed; -@@ -463,6 +467,7 @@ struct nouveau_pm_memtiming { - u32 reg_100234; - u32 reg_100238; - u32 reg_10023c; -+ u32 reg_100240; - }; - - struct nouveau_pm_memtimings { -@@ -509,8 +514,8 @@ struct nouveau_crypt_engine { - struct nouveau_vram_engine { - int (*init)(struct drm_device *); - int (*get)(struct drm_device *, u64, u32 align, u32 size_nc, -- u32 type, struct nouveau_vram **); -- void (*put)(struct drm_device *, struct nouveau_vram **); -+ u32 type, struct nouveau_mem **); -+ void (*put)(struct drm_device *, struct nouveau_mem **); - - bool (*flags_valid)(struct drm_device *, u32 tile_flags); - }; -@@ -634,6 +639,7 @@ struct drm_nouveau_private { - enum nouveau_card_type card_type; - /* exact chipset, derived from NV_PMC_BOOT_0 */ - int chipset; -+ int stepping; - int flags; - - void __iomem *mmio; -@@ -652,8 +658,6 @@ struct drm_nouveau_private { - /* interrupt handling */ - void (*irq_handler[32])(struct drm_device *); - bool msi_enabled; -- struct workqueue_struct *wq; -- struct work_struct irq_work; - - struct list_head vbl_waiting; - -@@ -681,6 +685,9 @@ struct drm_nouveau_private { - /* For PFIFO and PGRAPH. */ - spinlock_t context_switch_lock; - -+ /* VM/PRAMIN flush, legacy PRAMIN aperture */ -+ spinlock_t vm_lock; -+ - /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ - struct nouveau_ramht *ramht; - struct nouveau_gpuobj *ramfc; -@@ -691,15 +698,22 @@ struct drm_nouveau_private { - struct { - enum { - NOUVEAU_GART_NONE = 0, -- NOUVEAU_GART_AGP, -- NOUVEAU_GART_SGDMA -+ NOUVEAU_GART_AGP, /* AGP */ -+ NOUVEAU_GART_PDMA, /* paged dma object */ -+ NOUVEAU_GART_HW /* on-chip gart/vm */ - } type; - uint64_t aper_base; - uint64_t aper_size; - uint64_t aper_free; - -+ struct ttm_backend_func *func; -+ -+ struct { -+ struct page *page; -+ dma_addr_t addr; -+ } dummy; -+ - struct nouveau_gpuobj *sg_ctxdma; -- struct nouveau_vma vma; - } gart_info; - - /* nv10-nv40 tiling regions */ -@@ -740,14 +754,6 @@ struct drm_nouveau_private { - - struct backlight_device *backlight; - -- struct nouveau_channel *evo; -- u32 evo_alloc; -- struct { -- struct dcb_entry *dcb; -- u16 script; -- u32 pclk; -- } evo_irq; -- - struct { - struct dentry *channel_root; - } debugfs; -@@ -847,6 +853,7 @@ extern void nv10_mem_put_tile_region(struct drm_device *dev, - struct nouveau_tile_reg *tile, - struct nouveau_fence *fence); - extern const struct ttm_mem_type_manager_func nouveau_vram_manager; -+extern const struct ttm_mem_type_manager_func nouveau_gart_manager; - - /* nouveau_notifier.c */ - extern int nouveau_notifier_init_channel(struct nouveau_channel *); -@@ -879,17 +886,17 @@ extern void nouveau_channel_ref(struct nouveau_channel *chan, - extern void nouveau_channel_idle(struct nouveau_channel *chan); - - /* nouveau_object.c */ --#define NVOBJ_CLASS(d,c,e) do { \ -+#define NVOBJ_CLASS(d, c, e) do { \ - int ret = nouveau_gpuobj_class_new((d), (c), NVOBJ_ENGINE_##e); \ - if (ret) \ - return ret; \ --} while(0) -+} while (0) - --#define NVOBJ_MTHD(d,c,m,e) do { \ -+#define NVOBJ_MTHD(d, c, m, e) do { \ - int ret = nouveau_gpuobj_mthd_new((d), (c), (m), (e)); \ - if (ret) \ - return ret; \ --} while(0) -+} while (0) - - extern int nouveau_gpuobj_early_init(struct drm_device *); - extern int nouveau_gpuobj_init(struct drm_device *); -@@ -899,7 +906,7 @@ extern void nouveau_gpuobj_resume(struct drm_device *dev); - extern int nouveau_gpuobj_class_new(struct drm_device *, u32 class, u32 eng); - extern int nouveau_gpuobj_mthd_new(struct drm_device *, u32 class, u32 mthd, - int (*exec)(struct nouveau_channel *, -- u32 class, u32 mthd, u32 data)); -+ u32 class, u32 mthd, u32 data)); - extern int nouveau_gpuobj_mthd_call(struct nouveau_channel *, u32, u32, u32); - extern int nouveau_gpuobj_mthd_call2(struct drm_device *, int, u32, u32, u32); - extern int nouveau_gpuobj_channel_init(struct nouveau_channel *, -@@ -1076,7 +1083,7 @@ extern void nv40_fb_set_tile_region(struct drm_device *dev, int i); - /* 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 *); -+extern void nv50_fb_vm_trap(struct drm_device *, int display); - - /* nvc0_fb.c */ - extern int nvc0_fb_init(struct drm_device *); -@@ -1189,7 +1196,7 @@ extern int nv50_graph_load_context(struct nouveau_channel *); - extern int nv50_graph_unload_context(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); -+extern void nv84_graph_tlb_flush(struct drm_device *dev); - extern struct nouveau_enum nv50_data_error_names[]; - - /* nvc0_graph.c */ -@@ -1295,7 +1302,7 @@ extern struct ttm_bo_driver nouveau_bo_driver; - extern int nouveau_bo_new(struct drm_device *, struct nouveau_channel *, - int size, int align, uint32_t flags, - uint32_t tile_mode, uint32_t tile_flags, -- bool no_vm, bool mappable, struct nouveau_bo **); -+ struct nouveau_bo **); - extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags); - extern int nouveau_bo_unpin(struct nouveau_bo *); - extern int nouveau_bo_map(struct nouveau_bo *); -@@ -1356,9 +1363,9 @@ static inline struct nouveau_fence *nouveau_fence_ref(struct nouveau_fence *obj) - - /* nouveau_gem.c */ - extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *, -- int size, int align, uint32_t flags, -+ int size, int align, uint32_t domain, - uint32_t tile_mode, uint32_t tile_flags, -- bool no_vm, bool mappable, struct nouveau_bo **); -+ struct nouveau_bo **); - extern int nouveau_gem_object_new(struct drm_gem_object *); - extern void nouveau_gem_object_del(struct drm_gem_object *); - extern int nouveau_gem_ioctl_new(struct drm_device *, void *, -@@ -1398,8 +1405,8 @@ bool 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, - int *N1, int *M1, int *N2, int *M2, int *P); --int nv50_calc_pll2(struct drm_device *, struct pll_lims *, -- int clk, int *N, int *fN, int *M, int *P); -+int nva3_calc_pll(struct drm_device *, struct pll_lims *, -+ int clk, int *N, int *fN, int *M, int *P); - - #ifndef ioread32_native - #ifdef __BIG_ENDIAN -diff --git a/drivers/gpu/drm/nouveau/nouveau_fb.h b/drivers/gpu/drm/nouveau/nouveau_fb.h -index d432134..a3a88ad 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_fb.h -+++ b/drivers/gpu/drm/nouveau/nouveau_fb.h -@@ -30,6 +30,9 @@ - struct nouveau_framebuffer { - struct drm_framebuffer base; - struct nouveau_bo *nvbo; -+ u32 r_dma; -+ u32 r_format; -+ u32 r_pitch; - }; - - static inline struct nouveau_framebuffer * -diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c -index 7826be0..39aee6d 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c -+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c -@@ -296,8 +296,8 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, - size = mode_cmd.pitch * mode_cmd.height; - size = roundup(size, PAGE_SIZE); - -- ret = nouveau_gem_new(dev, dev_priv->channel, size, 0, TTM_PL_FLAG_VRAM, -- 0, 0x0000, false, true, &nvbo); -+ ret = nouveau_gem_new(dev, dev_priv->channel, size, 0, -+ NOUVEAU_GEM_DOMAIN_VRAM, 0, 0x0000, &nvbo); - if (ret) { - NV_ERROR(dev, "failed to allocate framebuffer\n"); - goto out; -diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c -index 221b846..4b9f449 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_fence.c -+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c -@@ -27,13 +27,15 @@ - #include "drmP.h" - #include "drm.h" - -+#include -+#include -+ - #include "nouveau_drv.h" - #include "nouveau_ramht.h" - #include "nouveau_dma.h" - - #define USE_REFCNT(dev) (nouveau_private(dev)->chipset >= 0x10) --#define USE_SEMA(dev) (nouveau_private(dev)->chipset >= 0x17 && \ -- nouveau_private(dev)->card_type < NV_C0) -+#define USE_SEMA(dev) (nouveau_private(dev)->chipset >= 0x17) - - struct nouveau_fence { - struct nouveau_channel *channel; -@@ -230,7 +232,8 @@ int - __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) - { - unsigned long timeout = jiffies + (3 * DRM_HZ); -- unsigned long sleep_time = jiffies + 1; -+ unsigned long sleep_time = NSEC_PER_MSEC / 1000; -+ ktime_t t; - int ret = 0; - - while (1) { -@@ -244,8 +247,13 @@ __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) - - __set_current_state(intr ? TASK_INTERRUPTIBLE - : TASK_UNINTERRUPTIBLE); -- if (lazy && time_after_eq(jiffies, sleep_time)) -- schedule_timeout(1); -+ if (lazy) { -+ t = ktime_set(0, sleep_time); -+ schedule_hrtimeout(&t, HRTIMER_MODE_REL); -+ sleep_time *= 2; -+ if (sleep_time > NSEC_PER_MSEC) -+ sleep_time = NSEC_PER_MSEC; -+ } - - if (intr && signal_pending(current)) { - ret = -ERESTARTSYS; -@@ -259,11 +267,12 @@ __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) - } - - static struct nouveau_semaphore * --alloc_semaphore(struct drm_device *dev) -+semaphore_alloc(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_semaphore *sema; -- int ret; -+ int size = (dev_priv->chipset < 0x84) ? 4 : 16; -+ int ret, i; - - if (!USE_SEMA(dev)) - return NULL; -@@ -277,9 +286,9 @@ alloc_semaphore(struct drm_device *dev) - goto fail; - - spin_lock(&dev_priv->fence.lock); -- sema->mem = drm_mm_search_free(&dev_priv->fence.heap, 4, 0, 0); -+ sema->mem = drm_mm_search_free(&dev_priv->fence.heap, size, 0, 0); - if (sema->mem) -- sema->mem = drm_mm_get_block_atomic(sema->mem, 4, 0); -+ sema->mem = drm_mm_get_block_atomic(sema->mem, size, 0); - spin_unlock(&dev_priv->fence.lock); - - if (!sema->mem) -@@ -287,7 +296,8 @@ alloc_semaphore(struct drm_device *dev) - - kref_init(&sema->ref); - sema->dev = dev; -- nouveau_bo_wr32(dev_priv->fence.bo, sema->mem->start / 4, 0); -+ for (i = sema->mem->start; i < sema->mem->start + size; i += 4) -+ nouveau_bo_wr32(dev_priv->fence.bo, i / 4, 0); - - return sema; - fail: -@@ -296,7 +306,7 @@ fail: - } - - static void --free_semaphore(struct kref *ref) -+semaphore_free(struct kref *ref) - { - struct nouveau_semaphore *sema = - container_of(ref, struct nouveau_semaphore, ref); -@@ -318,61 +328,107 @@ semaphore_work(void *priv, bool signalled) - if (unlikely(!signalled)) - nouveau_bo_wr32(dev_priv->fence.bo, sema->mem->start / 4, 1); - -- kref_put(&sema->ref, free_semaphore); -+ kref_put(&sema->ref, semaphore_free); - } - - static int --emit_semaphore(struct nouveau_channel *chan, int method, -- struct nouveau_semaphore *sema) -+semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema) - { -- struct drm_nouveau_private *dev_priv = sema->dev->dev_private; -- struct nouveau_fence *fence; -- bool smart = (dev_priv->card_type >= NV_50); -+ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; -+ struct nouveau_fence *fence = NULL; - int ret; - -- ret = RING_SPACE(chan, smart ? 8 : 4); -+ if (dev_priv->chipset < 0x84) { -+ ret = RING_SPACE(chan, 3); -+ if (ret) -+ return ret; -+ -+ BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 2); -+ OUT_RING (chan, sema->mem->start); -+ OUT_RING (chan, 1); -+ } else -+ if (dev_priv->chipset < 0xc0) { -+ struct nouveau_vma *vma = &dev_priv->fence.bo->vma; -+ u64 offset = vma->offset + sema->mem->start; -+ -+ ret = RING_SPACE(chan, 5); -+ if (ret) -+ return ret; -+ -+ BEGIN_RING(chan, NvSubSw, 0x0010, 4); -+ OUT_RING (chan, upper_32_bits(offset)); -+ OUT_RING (chan, lower_32_bits(offset)); -+ OUT_RING (chan, 1); -+ OUT_RING (chan, 1); /* ACQUIRE_EQ */ -+ } else { -+ struct nouveau_vma *vma = &dev_priv->fence.bo->vma; -+ u64 offset = vma->offset + sema->mem->start; -+ -+ ret = RING_SPACE(chan, 5); -+ if (ret) -+ return ret; -+ -+ BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4); -+ OUT_RING (chan, upper_32_bits(offset)); -+ OUT_RING (chan, lower_32_bits(offset)); -+ OUT_RING (chan, 1); -+ OUT_RING (chan, 0x1001); /* ACQUIRE_EQ */ -+ } -+ -+ /* Delay semaphore destruction until its work is done */ -+ ret = nouveau_fence_new(chan, &fence, true); - if (ret) - return ret; - -- if (smart) { -- BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1); -- OUT_RING(chan, NvSema); -- } -- BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 1); -- OUT_RING(chan, sema->mem->start); -- -- if (smart && method == NV_SW_SEMAPHORE_ACQUIRE) { -- /* -- * NV50 tries to be too smart and context-switch -- * between semaphores instead of doing a "first come, -- * first served" strategy like previous cards -- * do. -- * -- * That's bad because the ACQUIRE latency can get as -- * large as the PFIFO context time slice in the -- * typical DRI2 case where you have several -- * outstanding semaphores at the same moment. -- * -- * If we're going to ACQUIRE, force the card to -- * context switch before, just in case the matching -- * RELEASE is already scheduled to be executed in -- * another channel. -- */ -- BEGIN_RING(chan, NvSubSw, NV_SW_YIELD, 1); -- OUT_RING(chan, 0); -- } -+ kref_get(&sema->ref); -+ nouveau_fence_work(fence, semaphore_work, sema); -+ nouveau_fence_unref(&fence); -+ return 0; -+} -+ -+static int -+semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema) -+{ -+ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; -+ struct nouveau_fence *fence = NULL; -+ int ret; -+ -+ if (dev_priv->chipset < 0x84) { -+ ret = RING_SPACE(chan, 4); -+ if (ret) -+ return ret; -+ -+ BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 1); -+ OUT_RING (chan, sema->mem->start); -+ BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_RELEASE, 1); -+ OUT_RING (chan, 1); -+ } else -+ if (dev_priv->chipset < 0xc0) { -+ struct nouveau_vma *vma = &dev_priv->fence.bo->vma; -+ u64 offset = vma->offset + sema->mem->start; -+ -+ ret = RING_SPACE(chan, 5); -+ if (ret) -+ return ret; -+ -+ BEGIN_RING(chan, NvSubSw, 0x0010, 4); -+ OUT_RING (chan, upper_32_bits(offset)); -+ OUT_RING (chan, lower_32_bits(offset)); -+ OUT_RING (chan, 1); -+ OUT_RING (chan, 2); /* RELEASE */ -+ } else { -+ struct nouveau_vma *vma = &dev_priv->fence.bo->vma; -+ u64 offset = vma->offset + sema->mem->start; - -- BEGIN_RING(chan, NvSubSw, method, 1); -- OUT_RING(chan, 1); -- -- if (smart && method == NV_SW_SEMAPHORE_RELEASE) { -- /* -- * Force the card to context switch, there may be -- * another channel waiting for the semaphore we just -- * released. -- */ -- BEGIN_RING(chan, NvSubSw, NV_SW_YIELD, 1); -- OUT_RING(chan, 0); -+ ret = RING_SPACE(chan, 5); -+ if (ret) -+ return ret; -+ -+ BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4); -+ OUT_RING (chan, upper_32_bits(offset)); -+ OUT_RING (chan, lower_32_bits(offset)); -+ OUT_RING (chan, 1); -+ OUT_RING (chan, 0x1002); /* RELEASE */ - } - - /* Delay semaphore destruction until its work is done */ -@@ -383,7 +439,6 @@ emit_semaphore(struct nouveau_channel *chan, int method, - kref_get(&sema->ref); - nouveau_fence_work(fence, semaphore_work, sema); - nouveau_fence_unref(&fence); -- - return 0; - } - -@@ -400,7 +455,7 @@ nouveau_fence_sync(struct nouveau_fence *fence, - nouveau_fence_signalled(fence))) - goto out; - -- sema = alloc_semaphore(dev); -+ sema = semaphore_alloc(dev); - if (!sema) { - /* Early card or broken userspace, fall back to - * software sync. */ -@@ -418,17 +473,17 @@ nouveau_fence_sync(struct nouveau_fence *fence, - } - - /* Make wchan wait until it gets signalled */ -- ret = emit_semaphore(wchan, NV_SW_SEMAPHORE_ACQUIRE, sema); -+ ret = semaphore_acquire(wchan, sema); - if (ret) - goto out_unlock; - - /* Signal the semaphore from chan */ -- ret = emit_semaphore(chan, NV_SW_SEMAPHORE_RELEASE, sema); -+ ret = semaphore_release(chan, sema); - - out_unlock: - mutex_unlock(&chan->mutex); - out_unref: -- kref_put(&sema->ref, free_semaphore); -+ kref_put(&sema->ref, semaphore_free); - out: - if (chan) - nouveau_channel_put_unlocked(&chan); -@@ -449,22 +504,23 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) - struct nouveau_gpuobj *obj = NULL; - int ret; - -+ if (dev_priv->card_type >= NV_C0) -+ goto out_initialised; -+ - /* Create an NV_SW object for various sync purposes */ - ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW); - if (ret) - return ret; - - /* we leave subchannel empty for nvc0 */ -- if (dev_priv->card_type < NV_C0) { -- ret = RING_SPACE(chan, 2); -- if (ret) -- return ret; -- BEGIN_RING(chan, NvSubSw, 0, 1); -- OUT_RING(chan, NvSw); -- } -+ ret = RING_SPACE(chan, 2); -+ if (ret) -+ return ret; -+ BEGIN_RING(chan, NvSubSw, 0, 1); -+ OUT_RING(chan, NvSw); - - /* Create a DMA object for the shared cross-channel sync area. */ -- if (USE_SEMA(dev)) { -+ if (USE_SEMA(dev) && dev_priv->chipset < 0x84) { - struct ttm_mem_reg *mem = &dev_priv->fence.bo->bo.mem; - - ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, -@@ -484,14 +540,20 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) - return ret; - BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1); - OUT_RING(chan, NvSema); -+ } else { -+ ret = RING_SPACE(chan, 2); -+ if (ret) -+ return ret; -+ BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1); -+ OUT_RING (chan, chan->vram_handle); /* whole VM */ - } - - FIRE_RING(chan); - -+out_initialised: - INIT_LIST_HEAD(&chan->fence.pending); - spin_lock_init(&chan->fence.lock); - atomic_set(&chan->fence.last_sequence_irq, 0); -- - return 0; - } - -@@ -519,12 +581,13 @@ int - nouveau_fence_init(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -+ int size = (dev_priv->chipset < 0x84) ? 4096 : 16384; - int ret; - - /* Create a shared VRAM heap for cross-channel sync. */ - if (USE_SEMA(dev)) { -- ret = nouveau_bo_new(dev, NULL, 4096, 0, TTM_PL_FLAG_VRAM, -- 0, 0, false, true, &dev_priv->fence.bo); -+ ret = nouveau_bo_new(dev, NULL, size, 0, TTM_PL_FLAG_VRAM, -+ 0, 0, &dev_priv->fence.bo); - if (ret) - return ret; - -diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c -index 506c508..e8b04f4 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_gem.c -+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c -@@ -61,19 +61,36 @@ nouveau_gem_object_del(struct drm_gem_object *gem) - - int - nouveau_gem_new(struct drm_device *dev, struct nouveau_channel *chan, -- int size, int align, uint32_t flags, uint32_t tile_mode, -- uint32_t tile_flags, bool no_vm, bool mappable, -- struct nouveau_bo **pnvbo) -+ int size, int align, uint32_t domain, uint32_t tile_mode, -+ uint32_t tile_flags, struct nouveau_bo **pnvbo) - { -+ struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_bo *nvbo; -+ u32 flags = 0; - int ret; - -+ if (domain & NOUVEAU_GEM_DOMAIN_VRAM) -+ flags |= TTM_PL_FLAG_VRAM; -+ if (domain & NOUVEAU_GEM_DOMAIN_GART) -+ flags |= TTM_PL_FLAG_TT; -+ if (!flags || domain & NOUVEAU_GEM_DOMAIN_CPU) -+ flags |= TTM_PL_FLAG_SYSTEM; -+ - ret = nouveau_bo_new(dev, chan, size, align, flags, tile_mode, -- tile_flags, no_vm, mappable, pnvbo); -+ tile_flags, pnvbo); - if (ret) - return ret; - nvbo = *pnvbo; - -+ /* we restrict allowed domains on nv50+ to only the types -+ * that were requested at creation time. not possibly on -+ * earlier chips without busting the ABI. -+ */ -+ nvbo->valid_domains = NOUVEAU_GEM_DOMAIN_VRAM | -+ NOUVEAU_GEM_DOMAIN_GART; -+ if (dev_priv->card_type >= NV_50) -+ nvbo->valid_domains &= domain; -+ - nvbo->gem = drm_gem_object_alloc(dev, nvbo->bo.mem.size); - if (!nvbo->gem) { - nouveau_bo_ref(NULL, pnvbo); -@@ -97,7 +114,7 @@ nouveau_gem_info(struct drm_gem_object *gem, struct drm_nouveau_gem_info *rep) - - rep->size = nvbo->bo.mem.num_pages << PAGE_SHIFT; - rep->offset = nvbo->bo.offset; -- rep->map_handle = nvbo->mappable ? nvbo->bo.addr_space_offset : 0; -+ rep->map_handle = nvbo->bo.addr_space_offset; - rep->tile_mode = nvbo->tile_mode; - rep->tile_flags = nvbo->tile_flags; - return 0; -@@ -111,19 +128,11 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, - struct drm_nouveau_gem_new *req = data; - struct nouveau_bo *nvbo = NULL; - struct nouveau_channel *chan = NULL; -- uint32_t flags = 0; - int ret = 0; - - if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL)) - dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping; - -- if (req->info.domain & NOUVEAU_GEM_DOMAIN_VRAM) -- flags |= TTM_PL_FLAG_VRAM; -- if (req->info.domain & NOUVEAU_GEM_DOMAIN_GART) -- flags |= TTM_PL_FLAG_TT; -- if (!flags || req->info.domain & NOUVEAU_GEM_DOMAIN_CPU) -- flags |= TTM_PL_FLAG_SYSTEM; -- - if (!dev_priv->engine.vram.flags_valid(dev, req->info.tile_flags)) { - NV_ERROR(dev, "bad page flags: 0x%08x\n", req->info.tile_flags); - return -EINVAL; -@@ -135,10 +144,9 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, - return PTR_ERR(chan); - } - -- ret = nouveau_gem_new(dev, chan, req->info.size, req->align, flags, -- req->info.tile_mode, req->info.tile_flags, false, -- (req->info.domain & NOUVEAU_GEM_DOMAIN_MAPPABLE), -- &nvbo); -+ ret = nouveau_gem_new(dev, chan, req->info.size, req->align, -+ req->info.domain, req->info.tile_mode, -+ req->info.tile_flags, &nvbo); - if (chan) - nouveau_channel_put(&chan); - if (ret) -@@ -161,7 +169,7 @@ nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains, - { - struct nouveau_bo *nvbo = gem->driver_private; - struct ttm_buffer_object *bo = &nvbo->bo; -- uint32_t domains = valid_domains & -+ uint32_t domains = valid_domains & nvbo->valid_domains & - (write_domains ? write_domains : read_domains); - uint32_t pref_flags = 0, valid_flags = 0; - -@@ -592,7 +600,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, - if (push[i].bo_index >= req->nr_buffers) { - NV_ERROR(dev, "push %d buffer not in list\n", i); - ret = -EINVAL; -- goto out; -+ goto out_prevalid; - } - - bo[push[i].bo_index].read_domains |= (1 << 31); -@@ -604,7 +612,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, - if (ret) { - if (ret != -ERESTARTSYS) - NV_ERROR(dev, "validate: %d\n", ret); -- goto out; -+ goto out_prevalid; - } - - /* Apply any relocations that are required */ -@@ -697,6 +705,8 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, - out: - validate_fini(&op, fence); - nouveau_fence_unref(&fence); -+ -+out_prevalid: - kfree(bo); - kfree(push); - -diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.h b/drivers/gpu/drm/nouveau/nouveau_grctx.h -index 4a8ad13..86c2e37 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_grctx.h -+++ b/drivers/gpu/drm/nouveau/nouveau_grctx.h -@@ -87,10 +87,10 @@ _cp_bra(struct nouveau_grctx *ctx, u32 mod, int flag, int state, int name) - cp_out(ctx, CP_BRA | (mod << 18) | ip | flag | - (state ? 0 : CP_BRA_IF_CLEAR)); - } --#define cp_bra(c,f,s,n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n) -+#define cp_bra(c, f, s, n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n) - #ifdef CP_BRA_MOD --#define cp_cal(c,f,s,n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n) --#define cp_ret(c,f,s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0) -+#define cp_cal(c, f, s, n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n) -+#define cp_ret(c, f, s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0) - #endif - - static inline void -@@ -98,14 +98,14 @@ _cp_wait(struct nouveau_grctx *ctx, int flag, int state) - { - cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0)); - } --#define cp_wait(c,f,s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s) -+#define cp_wait(c, f, s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s) - - static inline void - _cp_set(struct nouveau_grctx *ctx, int flag, int state) - { - cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0)); - } --#define cp_set(c,f,s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s) -+#define cp_set(c, f, s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s) - - static inline void - cp_pos(struct nouveau_grctx *ctx, int offset) -diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c -index 053edf9..ba896e5 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_hw.c -+++ b/drivers/gpu/drm/nouveau/nouveau_hw.c -@@ -900,6 +900,7 @@ nv_save_state_ext(struct drm_device *dev, int head, - } - /* NV11 and NV20 don't have this, they stop at 0x52. */ - if (nv_gf4_disp_arch(dev)) { -+ rd_cio_state(dev, head, regp, NV_CIO_CRE_42); - rd_cio_state(dev, head, regp, NV_CIO_CRE_53); - rd_cio_state(dev, head, regp, NV_CIO_CRE_54); - -@@ -1003,6 +1004,7 @@ nv_load_state_ext(struct drm_device *dev, int head, - nouveau_wait_eq(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0); - } - -+ wr_cio_state(dev, head, regp, NV_CIO_CRE_42); - wr_cio_state(dev, head, regp, NV_CIO_CRE_53); - wr_cio_state(dev, head, regp, NV_CIO_CRE_54); - -diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c -index b0fb9bd..4942294 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_mem.c -+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c -@@ -152,9 +152,6 @@ nouveau_mem_vram_fini(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - -- nouveau_bo_unpin(dev_priv->vga_ram); -- nouveau_bo_ref(NULL, &dev_priv->vga_ram); -- - ttm_bo_device_release(&dev_priv->ttm.bdev); - - nouveau_ttm_global_release(dev_priv); -@@ -393,11 +390,17 @@ nouveau_mem_vram_init(struct drm_device *dev) - struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; - 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; -+ dma_bits = 32; -+ if (dev_priv->card_type >= NV_50) { -+ if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(40))) -+ dma_bits = 40; -+ } else -+ if (0 && drm_device_is_pcie(dev) && -+ dev_priv->chipset > 0x40 && -+ dev_priv->chipset != 0x45) { -+ if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(39))) -+ dma_bits = 39; -+ } - - ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits)); - if (ret) -@@ -419,14 +422,32 @@ nouveau_mem_vram_init(struct drm_device *dev) - } - - /* 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); -+ if (dev_priv->card_type >= NV_50) { -+ dev_priv->ramin_rsvd_vram = 1 * 1024 * 1024; -+ } else -+ if (dev_priv->card_type >= NV_40) { -+ u32 vs = hweight8((nv_rd32(dev, 0x001540) & 0x0000ff00) >> 8); -+ u32 rsvd; -+ -+ /* estimate grctx size, the magics come from nv40_grctx.c */ -+ if (dev_priv->chipset == 0x40) rsvd = 0x6aa0 * vs; -+ else if (dev_priv->chipset < 0x43) rsvd = 0x4f00 * vs; -+ else if (nv44_graph_class(dev)) rsvd = 0x4980 * vs; -+ else rsvd = 0x4a40 * vs; -+ rsvd += 16 * 1024; -+ rsvd *= dev_priv->engine.fifo.channels; -+ -+ /* pciegart table */ -+ if (drm_device_is_pcie(dev)) -+ rsvd += 512 * 1024; -+ -+ /* object storage */ -+ rsvd += 512 * 1024; -+ -+ dev_priv->ramin_rsvd_vram = round_up(rsvd, 4096); -+ } else { -+ dev_priv->ramin_rsvd_vram = 512 * 1024; -+ } - - ret = dev_priv->engine.vram.init(dev); - if (ret) -@@ -455,13 +476,17 @@ nouveau_mem_vram_init(struct drm_device *dev) - return ret; - } - -- ret = nouveau_bo_new(dev, NULL, 256*1024, 0, TTM_PL_FLAG_VRAM, -- 0, 0, true, true, &dev_priv->vga_ram); -- if (ret == 0) -- ret = nouveau_bo_pin(dev_priv->vga_ram, TTM_PL_FLAG_VRAM); -- if (ret) { -- NV_WARN(dev, "failed to reserve VGA memory\n"); -- nouveau_bo_ref(NULL, &dev_priv->vga_ram); -+ if (dev_priv->card_type < NV_50) { -+ ret = nouveau_bo_new(dev, NULL, 256*1024, 0, TTM_PL_FLAG_VRAM, -+ 0, 0, &dev_priv->vga_ram); -+ if (ret == 0) -+ ret = nouveau_bo_pin(dev_priv->vga_ram, -+ TTM_PL_FLAG_VRAM); -+ -+ if (ret) { -+ NV_WARN(dev, "failed to reserve VGA memory\n"); -+ nouveau_bo_ref(NULL, &dev_priv->vga_ram); -+ } - } - - dev_priv->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 1), -@@ -525,6 +550,7 @@ nouveau_mem_timing_init(struct drm_device *dev) - u8 tRC; /* Byte 9 */ - u8 tUNK_10, tUNK_11, tUNK_12, tUNK_13, tUNK_14; - u8 tUNK_18, tUNK_19, tUNK_20, tUNK_21; -+ u8 magic_number = 0; /* Yeah... sorry*/ - u8 *mem = NULL, *entry; - int i, recordlen, entries; - -@@ -569,6 +595,12 @@ nouveau_mem_timing_init(struct drm_device *dev) - if (!memtimings->timing) - return; - -+ /* Get "some number" from the timing reg for NV_40 and NV_50 -+ * Used in calculations later */ -+ if (dev_priv->card_type >= NV_40 && dev_priv->chipset < 0x98) { -+ magic_number = (nv_rd32(dev, 0x100228) & 0x0f000000) >> 24; -+ } -+ - entry = mem + mem[1]; - for (i = 0; i < entries; i++, entry += recordlen) { - struct nouveau_pm_memtiming *timing = &pm->memtimings.timing[i]; -@@ -608,36 +640,67 @@ nouveau_mem_timing_init(struct drm_device *dev) - - /* XXX: I don't trust the -1's and +1's... they must come - * from somewhere! */ -- timing->reg_100224 = ((tUNK_0 + tUNK_19 + 1) << 24 | -- tUNK_18 << 16 | -- (tUNK_1 + tUNK_19 + 1) << 8 | -- (tUNK_2 - 1)); -+ timing->reg_100224 = (tUNK_0 + tUNK_19 + 1 + magic_number) << 24 | -+ max(tUNK_18, (u8) 1) << 16 | -+ (tUNK_1 + tUNK_19 + 1 + magic_number) << 8; -+ if (dev_priv->chipset == 0xa8) { -+ timing->reg_100224 |= (tUNK_2 - 1); -+ } else { -+ timing->reg_100224 |= (tUNK_2 + 2 - magic_number); -+ } - - timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10); -- if(recordlen > 19) { -- timing->reg_100228 += (tUNK_19 - 1) << 24; -- }/* I cannot back-up this else-statement right now -- else { -- timing->reg_100228 += tUNK_12 << 24; -- }*/ -- -- /* XXX: reg_10022c */ -- timing->reg_10022c = tUNK_2 - 1; -- -- timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 | -- tUNK_13 << 8 | tUNK_13); -- -- /* XXX: +6? */ -- timing->reg_100234 = (tRAS << 24 | (tUNK_19 + 6) << 8 | tRC); -- timing->reg_100234 += max(tUNK_10,tUNK_11) << 16; -- -- /* XXX; reg_100238, reg_10023c -- * reg: 0x00?????? -- * reg_10023c: -- * 0 for pre-NV50 cards -- * 0x????0202 for NV50+ cards (empirical evidence) */ -- if(dev_priv->card_type >= NV_50) { -+ if (dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa) -+ timing->reg_100228 |= (tUNK_19 - 1) << 24; -+ else -+ timing->reg_100228 |= magic_number << 24; -+ -+ if (dev_priv->card_type == NV_40) { -+ /* NV40: don't know what the rest of the regs are.. -+ * And don't need to know either */ -+ timing->reg_100228 |= 0x20200000; -+ } else if (dev_priv->card_type >= NV_50) { -+ if (dev_priv->chipset < 0x98 || -+ (dev_priv->chipset == 0x98 && -+ dev_priv->stepping <= 0xa1)) { -+ timing->reg_10022c = (0x14 + tUNK_2) << 24 | -+ 0x16 << 16 | -+ (tUNK_2 - 1) << 8 | -+ (tUNK_2 - 1); -+ } else { -+ /* XXX: reg_10022c for recentish cards */ -+ timing->reg_10022c = tUNK_2 - 1; -+ } -+ -+ timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 | -+ tUNK_13 << 8 | tUNK_13); -+ -+ timing->reg_100234 = (tRAS << 24 | tRC); -+ timing->reg_100234 += max(tUNK_10, tUNK_11) << 16; -+ -+ if (dev_priv->chipset < 0x98 || -+ (dev_priv->chipset == 0x98 && -+ dev_priv->stepping <= 0xa1)) { -+ timing->reg_100234 |= (tUNK_2 + 2) << 8; -+ } else { -+ /* XXX: +6? */ -+ timing->reg_100234 |= (tUNK_19 + 6) << 8; -+ } -+ -+ /* XXX; reg_100238 -+ * reg_100238: 0x00?????? */ - timing->reg_10023c = 0x202; -+ if (dev_priv->chipset < 0x98 || -+ (dev_priv->chipset == 0x98 && -+ dev_priv->stepping <= 0xa1)) { -+ timing->reg_10023c |= 0x4000000 | (tUNK_2 - 1) << 16; -+ } else { -+ /* XXX: reg_10023c -+ * currently unknown -+ * 10023c seen as 06xxxxxx, 0bxxxxxx or 0fxxxxxx */ -+ } -+ -+ /* XXX: reg_100240? */ - } - - NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i, -@@ -646,9 +709,10 @@ nouveau_mem_timing_init(struct drm_device *dev) - NV_DEBUG(dev, " 230: %08x %08x %08x %08x\n", - timing->reg_100230, timing->reg_100234, - timing->reg_100238, timing->reg_10023c); -+ NV_DEBUG(dev, " 240: %08x\n", timing->reg_100240); - } - -- memtimings->nr_timing = entries; -+ memtimings->nr_timing = entries; - memtimings->supported = true; - } - -@@ -666,13 +730,14 @@ nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long p_size - { - struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); - struct nouveau_mm *mm; -- u32 b_size; -+ u64 size, block, rsvd; - int ret; - -- p_size = (p_size << PAGE_SHIFT) >> 12; -- b_size = dev_priv->vram_rblock_size >> 12; -+ rsvd = (256 * 1024); /* vga memory */ -+ size = (p_size << PAGE_SHIFT) - rsvd; -+ block = dev_priv->vram_rblock_size; - -- ret = nouveau_mm_init(&mm, 0, p_size, b_size); -+ ret = nouveau_mm_init(&mm, rsvd >> 12, size >> 12, block >> 12); - if (ret) - return ret; - -@@ -700,9 +765,15 @@ nouveau_vram_manager_del(struct ttm_mem_type_manager *man, - { - struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); - struct nouveau_vram_engine *vram = &dev_priv->engine.vram; -+ struct nouveau_mem *node = mem->mm_node; - struct drm_device *dev = dev_priv->dev; - -- vram->put(dev, (struct nouveau_vram **)&mem->mm_node); -+ if (node->tmp_vma.node) { -+ nouveau_vm_unmap(&node->tmp_vma); -+ nouveau_vm_put(&node->tmp_vma); -+ } -+ -+ vram->put(dev, (struct nouveau_mem **)&mem->mm_node); - } - - static int -@@ -715,7 +786,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, - struct nouveau_vram_engine *vram = &dev_priv->engine.vram; - struct drm_device *dev = dev_priv->dev; - struct nouveau_bo *nvbo = nouveau_bo(bo); -- struct nouveau_vram *node; -+ struct nouveau_mem *node; - u32 size_nc = 0; - int ret; - -@@ -724,7 +795,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, - - ret = vram->get(dev, mem->num_pages << PAGE_SHIFT, - mem->page_alignment << PAGE_SHIFT, size_nc, -- (nvbo->tile_flags >> 8) & 0xff, &node); -+ (nvbo->tile_flags >> 8) & 0x3ff, &node); - if (ret) { - mem->mm_node = NULL; - return (ret == -ENOSPC) ? 0 : ret; -@@ -771,3 +842,84 @@ const struct ttm_mem_type_manager_func nouveau_vram_manager = { - nouveau_vram_manager_del, - nouveau_vram_manager_debug - }; -+ -+static int -+nouveau_gart_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) -+{ -+ return 0; -+} -+ -+static int -+nouveau_gart_manager_fini(struct ttm_mem_type_manager *man) -+{ -+ return 0; -+} -+ -+static void -+nouveau_gart_manager_del(struct ttm_mem_type_manager *man, -+ struct ttm_mem_reg *mem) -+{ -+ struct nouveau_mem *node = mem->mm_node; -+ -+ if (node->tmp_vma.node) { -+ nouveau_vm_unmap(&node->tmp_vma); -+ nouveau_vm_put(&node->tmp_vma); -+ } -+ mem->mm_node = NULL; -+} -+ -+static int -+nouveau_gart_manager_new(struct ttm_mem_type_manager *man, -+ struct ttm_buffer_object *bo, -+ struct ttm_placement *placement, -+ struct ttm_mem_reg *mem) -+{ -+ struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); -+ struct nouveau_bo *nvbo = nouveau_bo(bo); -+ struct nouveau_vma *vma = &nvbo->vma; -+ struct nouveau_vm *vm = vma->vm; -+ struct nouveau_mem *node; -+ int ret; -+ -+ if (unlikely((mem->num_pages << PAGE_SHIFT) >= -+ dev_priv->gart_info.aper_size)) -+ return -ENOMEM; -+ -+ node = kzalloc(sizeof(*node), GFP_KERNEL); -+ if (!node) -+ return -ENOMEM; -+ -+ /* This node must be for evicting large-paged VRAM -+ * to system memory. Due to a nv50 limitation of -+ * not being able to mix large/small pages within -+ * the same PDE, we need to create a temporary -+ * small-paged VMA for the eviction. -+ */ -+ if (vma->node->type != vm->spg_shift) { -+ ret = nouveau_vm_get(vm, (u64)vma->node->length << 12, -+ vm->spg_shift, NV_MEM_ACCESS_RW, -+ &node->tmp_vma); -+ if (ret) { -+ kfree(node); -+ return ret; -+ } -+ } -+ -+ node->page_shift = nvbo->vma.node->type; -+ mem->mm_node = node; -+ mem->start = 0; -+ return 0; -+} -+ -+void -+nouveau_gart_manager_debug(struct ttm_mem_type_manager *man, const char *prefix) -+{ -+} -+ -+const struct ttm_mem_type_manager_func nouveau_gart_manager = { -+ nouveau_gart_manager_init, -+ nouveau_gart_manager_fini, -+ nouveau_gart_manager_new, -+ nouveau_gart_manager_del, -+ nouveau_gart_manager_debug -+}; -diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.h b/drivers/gpu/drm/nouveau/nouveau_mm.h -index 798eaf3..1f7483a 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_mm.h -+++ b/drivers/gpu/drm/nouveau/nouveau_mm.h -@@ -53,13 +53,13 @@ void nouveau_mm_put(struct nouveau_mm *, struct nouveau_mm_node *); - - int nv50_vram_init(struct drm_device *); - int nv50_vram_new(struct drm_device *, u64 size, u32 align, u32 size_nc, -- u32 memtype, struct nouveau_vram **); --void nv50_vram_del(struct drm_device *, struct nouveau_vram **); -+ u32 memtype, struct nouveau_mem **); -+void nv50_vram_del(struct drm_device *, struct nouveau_mem **); - bool nv50_vram_flags_valid(struct drm_device *, u32 tile_flags); - - int nvc0_vram_init(struct drm_device *); - int nvc0_vram_new(struct drm_device *, u64 size, u32 align, u32 ncmin, -- u32 memtype, struct nouveau_vram **); -+ u32 memtype, struct nouveau_mem **); - bool nvc0_vram_flags_valid(struct drm_device *, u32 tile_flags); - - #endif -diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c -index 5ea1676..5b39718 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_notifier.c -+++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c -@@ -35,20 +35,22 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan) - { - struct drm_device *dev = chan->dev; - struct nouveau_bo *ntfy = NULL; -- uint32_t flags; -+ uint32_t flags, ttmpl; - int ret; - -- if (nouveau_vram_notify) -- flags = TTM_PL_FLAG_VRAM; -- else -- flags = TTM_PL_FLAG_TT; -+ if (nouveau_vram_notify) { -+ flags = NOUVEAU_GEM_DOMAIN_VRAM; -+ ttmpl = TTM_PL_FLAG_VRAM; -+ } else { -+ flags = NOUVEAU_GEM_DOMAIN_GART; -+ ttmpl = TTM_PL_FLAG_TT; -+ } - -- ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, flags, -- 0, 0x0000, false, true, &ntfy); -+ ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, flags, 0, 0, &ntfy); - if (ret) - return ret; - -- ret = nouveau_bo_pin(ntfy, flags); -+ ret = nouveau_bo_pin(ntfy, ttmpl); - if (ret) - goto out_err; - -@@ -100,6 +102,7 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, - uint32_t *b_offset) - { - struct drm_device *dev = chan->dev; -+ struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *nobj = NULL; - struct drm_mm_node *mem; - uint32_t offset; -@@ -114,11 +117,16 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, - return -ENOMEM; - } - -- if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM) -- target = NV_MEM_TARGET_VRAM; -- else -- target = NV_MEM_TARGET_GART; -- offset = chan->notifier_bo->bo.mem.start << PAGE_SHIFT; -+ if (dev_priv->card_type < NV_50) { -+ if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM) -+ target = NV_MEM_TARGET_VRAM; -+ else -+ target = NV_MEM_TARGET_GART; -+ offset = chan->notifier_bo->bo.mem.start << PAGE_SHIFT; -+ } else { -+ target = NV_MEM_TARGET_VM; -+ offset = chan->notifier_bo->vma.offset; -+ } - offset += mem->start; - - ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, offset, -diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c -index 30b6544..59b446e 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_object.c -+++ b/drivers/gpu/drm/nouveau/nouveau_object.c -@@ -36,6 +36,7 @@ - #include "nouveau_drm.h" - #include "nouveau_ramht.h" - #include "nouveau_vm.h" -+#include "nv50_display.h" - - struct nouveau_gpuobj_method { - struct list_head head; -@@ -490,16 +491,22 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base, - } - - if (target == NV_MEM_TARGET_GART) { -- if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) { -- target = NV_MEM_TARGET_PCI_NOSNOOP; -- base += dev_priv->gart_info.aper_base; -- } else -- if (base != 0) { -- base = nouveau_sgdma_get_physical(dev, base); -+ struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma; -+ -+ if (dev_priv->gart_info.type == NOUVEAU_GART_PDMA) { -+ if (base == 0) { -+ nouveau_gpuobj_ref(gart, pobj); -+ return 0; -+ } -+ -+ base = nouveau_sgdma_get_physical(dev, base); - target = NV_MEM_TARGET_PCI; - } else { -- nouveau_gpuobj_ref(dev_priv->gart_info.sg_ctxdma, pobj); -- return 0; -+ base += dev_priv->gart_info.aper_base; -+ if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) -+ target = NV_MEM_TARGET_PCI_NOSNOOP; -+ else -+ target = NV_MEM_TARGET_PCI; - } - } - -@@ -776,7 +783,7 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *vram = NULL, *tt = NULL; -- int ret; -+ int ret, i; - - NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h); - -@@ -841,6 +848,25 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, - nouveau_gpuobj_ref(NULL, &ramht); - if (ret) - return ret; -+ -+ /* dma objects for display sync channel semaphore blocks */ -+ for (i = 0; i < 2; i++) { -+ struct nouveau_gpuobj *sem = NULL; -+ struct nv50_display_crtc *dispc = -+ &nv50_display(dev)->crtc[i]; -+ u64 offset = dispc->sem.bo->bo.mem.start << PAGE_SHIFT; -+ -+ ret = nouveau_gpuobj_dma_new(chan, 0x3d, offset, 0xfff, -+ NV_MEM_ACCESS_RW, -+ NV_MEM_TARGET_VRAM, &sem); -+ if (ret) -+ return ret; -+ -+ ret = nouveau_ramht_insert(chan, NvEvoSema0 + i, sem); -+ nouveau_gpuobj_ref(NULL, &sem); -+ if (ret) -+ return ret; -+ } - } - - /* VRAM ctxdma */ -@@ -1013,19 +1039,20 @@ nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset) - { - struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; - struct drm_device *dev = gpuobj->dev; -+ unsigned long flags; - - 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); -+ spin_lock_irqsave(&dev_priv->vm_lock, flags); - 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); -+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); - return val; - } - -@@ -1037,18 +1064,19 @@ 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; -+ unsigned long flags; - - if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { - u64 ptr = gpuobj->vinst + offset; - u32 base = ptr >> 16; - -- spin_lock(&dev_priv->ramin_lock); -+ spin_lock_irqsave(&dev_priv->vm_lock, flags); - 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); -+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); - return; - } - -diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c -index ac62a1b..3045566 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_perf.c -+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c -@@ -134,7 +134,7 @@ nouveau_perf_init(struct drm_device *dev) - case 0x13: - case 0x15: - perflvl->fanspeed = entry[55]; -- perflvl->voltage = entry[56]; -+ perflvl->voltage = (recordlen > 56) ? entry[56] : 0; - perflvl->core = ROM32(entry[1]) * 10; - perflvl->memory = ROM32(entry[5]) * 20; - break; -@@ -174,9 +174,21 @@ nouveau_perf_init(struct drm_device *dev) - #define subent(n) entry[perf[2] + ((n) * perf[3])] - perflvl->fanspeed = 0; /*XXX*/ - perflvl->voltage = entry[2]; -- perflvl->core = (ROM16(subent(0)) & 0xfff) * 1000; -- perflvl->shader = (ROM16(subent(1)) & 0xfff) * 1000; -- perflvl->memory = (ROM16(subent(2)) & 0xfff) * 1000; -+ if (dev_priv->card_type == NV_50) { -+ perflvl->core = ROM16(subent(0)) & 0xfff; -+ perflvl->shader = ROM16(subent(1)) & 0xfff; -+ perflvl->memory = ROM16(subent(2)) & 0xfff; -+ } else { -+ perflvl->shader = ROM16(subent(3)) & 0xfff; -+ perflvl->core = perflvl->shader / 2; -+ perflvl->unk0a = ROM16(subent(4)) & 0xfff; -+ perflvl->memory = ROM16(subent(5)) & 0xfff; -+ } -+ -+ perflvl->core *= 1000; -+ perflvl->shader *= 1000; -+ perflvl->memory *= 1000; -+ perflvl->unk0a *= 1000; - break; - } - -diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c -index 4399e2f..0b1caeb 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_pm.c -+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c -@@ -490,6 +490,7 @@ nouveau_pm_init(struct drm_device *dev) - /* determine current ("boot") performance level */ - ret = nouveau_pm_perflvl_get(dev, &pm->boot); - if (ret == 0) { -+ strncpy(pm->boot.name, "boot", 4); - pm->cur = &pm->boot; - - nouveau_pm_perflvl_info(&pm->boot, info, sizeof(info)); -diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.c b/drivers/gpu/drm/nouveau/nouveau_ramht.c -index bef3e69..a24a81f 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_ramht.c -+++ b/drivers/gpu/drm/nouveau/nouveau_ramht.c -@@ -114,7 +114,9 @@ nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle, - (gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT); - } else { - if (gpuobj->engine == NVOBJ_ENGINE_DISPLAY) { -- ctx = (gpuobj->cinst << 10) | chan->id; -+ ctx = (gpuobj->cinst << 10) | -+ (chan->id << 28) | -+ chan->id; /* HASH_TAG */ - } else { - ctx = (gpuobj->cinst >> 4) | - ((gpuobj->engine << -diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h -index 04e8fb7..f18cdfc 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_reg.h -+++ b/drivers/gpu/drm/nouveau/nouveau_reg.h -@@ -639,9 +639,9 @@ - # define NV50_PCONNECTOR_I2C_PORT_4 0x0000e240 - # define NV50_PCONNECTOR_I2C_PORT_5 0x0000e258 - --#define NV50_AUXCH_DATA_OUT(i,n) ((n) * 4 + (i) * 0x50 + 0x0000e4c0) -+#define NV50_AUXCH_DATA_OUT(i, n) ((n) * 4 + (i) * 0x50 + 0x0000e4c0) - #define NV50_AUXCH_DATA_OUT__SIZE 4 --#define NV50_AUXCH_DATA_IN(i,n) ((n) * 4 + (i) * 0x50 + 0x0000e4d0) -+#define NV50_AUXCH_DATA_IN(i, n) ((n) * 4 + (i) * 0x50 + 0x0000e4d0) - #define NV50_AUXCH_DATA_IN__SIZE 4 - #define NV50_AUXCH_ADDR(i) ((i) * 0x50 + 0x0000e4e0) - #define NV50_AUXCH_CTRL(i) ((i) * 0x50 + 0x0000e4e4) -@@ -829,7 +829,7 @@ - #define NV50_PDISPLAY_SOR_BACKLIGHT 0x0061c084 - #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(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 -@@ -841,10 +841,10 @@ - #define NV50_SOR_DP_CTRL_TRAINING_PATTERN_DISABLED 0x00000000 - #define NV50_SOR_DP_CTRL_TRAINING_PATTERN_1 0x01000000 - #define NV50_SOR_DP_CTRL_TRAINING_PATTERN_2 0x02000000 --#define NV50_SOR_DP_UNK118(i,l) (0x0061c118 + (i) * 0x800 + (l) * 0x80) --#define NV50_SOR_DP_UNK120(i,l) (0x0061c120 + (i) * 0x800 + (l) * 0x80) --#define NV50_SOR_DP_UNK128(i,l) (0x0061c128 + (i) * 0x800 + (l) * 0x80) --#define NV50_SOR_DP_UNK130(i,l) (0x0061c130 + (i) * 0x800 + (l) * 0x80) -+#define NV50_SOR_DP_UNK118(i, l) (0x0061c118 + (i) * 0x800 + (l) * 0x80) -+#define NV50_SOR_DP_UNK120(i, l) (0x0061c120 + (i) * 0x800 + (l) * 0x80) -+#define NV50_SOR_DP_UNK128(i, l) (0x0061c128 + (i) * 0x800 + (l) * 0x80) -+#define NV50_SOR_DP_UNK130(i, l) (0x0061c130 + (i) * 0x800 + (l) * 0x80) - - #define NV50_PDISPLAY_USER(i) ((i) * 0x1000 + 0x00640000) - #define NV50_PDISPLAY_USER_PUT(i) ((i) * 0x1000 + 0x00640000) -diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c -index 9a250eb..2bf9686 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c -+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c -@@ -74,8 +74,24 @@ nouveau_sgdma_clear(struct ttm_backend *be) - } - } - -+static void -+nouveau_sgdma_destroy(struct ttm_backend *be) -+{ -+ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; -+ -+ if (be) { -+ NV_DEBUG(nvbe->dev, "\n"); -+ -+ if (nvbe) { -+ if (nvbe->pages) -+ be->func->clear(be); -+ kfree(nvbe); -+ } -+ } -+} -+ - static int --nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) -+nv04_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) - { - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; - struct drm_device *dev = nvbe->dev; -@@ -102,7 +118,7 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) - } - - static int --nouveau_sgdma_unbind(struct ttm_backend *be) -+nv04_sgdma_unbind(struct ttm_backend *be) - { - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; - struct drm_device *dev = nvbe->dev; -@@ -125,59 +141,245 @@ nouveau_sgdma_unbind(struct ttm_backend *be) - return 0; - } - -+static struct ttm_backend_func nv04_sgdma_backend = { -+ .populate = nouveau_sgdma_populate, -+ .clear = nouveau_sgdma_clear, -+ .bind = nv04_sgdma_bind, -+ .unbind = nv04_sgdma_unbind, -+ .destroy = nouveau_sgdma_destroy -+}; -+ - static void --nouveau_sgdma_destroy(struct ttm_backend *be) -+nv41_sgdma_flush(struct nouveau_sgdma_be *nvbe) -+{ -+ struct drm_device *dev = nvbe->dev; -+ -+ nv_wr32(dev, 0x100810, 0x00000022); -+ if (!nv_wait(dev, 0x100810, 0x00000100, 0x00000100)) -+ NV_ERROR(dev, "vm flush timeout: 0x%08x\n", -+ nv_rd32(dev, 0x100810)); -+ nv_wr32(dev, 0x100810, 0x00000000); -+} -+ -+static int -+nv41_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) - { - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; -+ struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private; -+ struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma; -+ dma_addr_t *list = nvbe->pages; -+ u32 pte = mem->start << 2; -+ u32 cnt = nvbe->nr_pages; - -- if (be) { -- NV_DEBUG(nvbe->dev, "\n"); -+ nvbe->offset = mem->start << PAGE_SHIFT; - -- if (nvbe) { -- if (nvbe->pages) -- be->func->clear(be); -- kfree(nvbe); -+ while (cnt--) { -+ nv_wo32(pgt, pte, (*list++ >> 7) | 1); -+ pte += 4; -+ } -+ -+ nv41_sgdma_flush(nvbe); -+ nvbe->bound = true; -+ return 0; -+} -+ -+static int -+nv41_sgdma_unbind(struct ttm_backend *be) -+{ -+ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; -+ struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private; -+ struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma; -+ u32 pte = (nvbe->offset >> 12) << 2; -+ u32 cnt = nvbe->nr_pages; -+ -+ while (cnt--) { -+ nv_wo32(pgt, pte, 0x00000000); -+ pte += 4; -+ } -+ -+ nv41_sgdma_flush(nvbe); -+ nvbe->bound = false; -+ return 0; -+} -+ -+static struct ttm_backend_func nv41_sgdma_backend = { -+ .populate = nouveau_sgdma_populate, -+ .clear = nouveau_sgdma_clear, -+ .bind = nv41_sgdma_bind, -+ .unbind = nv41_sgdma_unbind, -+ .destroy = nouveau_sgdma_destroy -+}; -+ -+static void -+nv44_sgdma_flush(struct nouveau_sgdma_be *nvbe) -+{ -+ struct drm_device *dev = nvbe->dev; -+ -+ nv_wr32(dev, 0x100814, (nvbe->nr_pages - 1) << 12); -+ nv_wr32(dev, 0x100808, nvbe->offset | 0x20); -+ if (!nv_wait(dev, 0x100808, 0x00000001, 0x00000001)) -+ NV_ERROR(dev, "gart flush timeout: 0x%08x\n", -+ nv_rd32(dev, 0x100808)); -+ nv_wr32(dev, 0x100808, 0x00000000); -+} -+ -+static void -+nv44_sgdma_fill(struct nouveau_gpuobj *pgt, dma_addr_t *list, u32 base, u32 cnt) -+{ -+ struct drm_nouveau_private *dev_priv = pgt->dev->dev_private; -+ dma_addr_t dummy = dev_priv->gart_info.dummy.addr; -+ u32 pte, tmp[4]; -+ -+ pte = base >> 2; -+ base &= ~0x0000000f; -+ -+ tmp[0] = nv_ro32(pgt, base + 0x0); -+ tmp[1] = nv_ro32(pgt, base + 0x4); -+ tmp[2] = nv_ro32(pgt, base + 0x8); -+ tmp[3] = nv_ro32(pgt, base + 0xc); -+ while (cnt--) { -+ u32 addr = list ? (*list++ >> 12) : (dummy >> 12); -+ switch (pte++ & 0x3) { -+ case 0: -+ tmp[0] &= ~0x07ffffff; -+ tmp[0] |= addr; -+ break; -+ case 1: -+ tmp[0] &= ~0xf8000000; -+ tmp[0] |= addr << 27; -+ tmp[1] &= ~0x003fffff; -+ tmp[1] |= addr >> 5; -+ break; -+ case 2: -+ tmp[1] &= ~0xffc00000; -+ tmp[1] |= addr << 22; -+ tmp[2] &= ~0x0001ffff; -+ tmp[2] |= addr >> 10; -+ break; -+ case 3: -+ tmp[2] &= ~0xfffe0000; -+ tmp[2] |= addr << 17; -+ tmp[3] &= ~0x00000fff; -+ tmp[3] |= addr >> 15; -+ break; - } - } -+ -+ tmp[3] |= 0x40000000; -+ -+ nv_wo32(pgt, base + 0x0, tmp[0]); -+ nv_wo32(pgt, base + 0x4, tmp[1]); -+ nv_wo32(pgt, base + 0x8, tmp[2]); -+ nv_wo32(pgt, base + 0xc, tmp[3]); - } - - static int --nv50_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) -+nv44_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) - { - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; - struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private; -+ struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma; -+ dma_addr_t *list = nvbe->pages; -+ u32 pte = mem->start << 2, tmp[4]; -+ u32 cnt = nvbe->nr_pages; -+ int i; - - nvbe->offset = mem->start << PAGE_SHIFT; - -- nouveau_vm_map_sg(&dev_priv->gart_info.vma, nvbe->offset, -- nvbe->nr_pages << PAGE_SHIFT, nvbe->pages); -+ if (pte & 0x0000000c) { -+ u32 max = 4 - ((pte >> 2) & 0x3); -+ u32 part = (cnt > max) ? max : cnt; -+ nv44_sgdma_fill(pgt, list, pte, part); -+ pte += (part << 2); -+ list += part; -+ cnt -= part; -+ } -+ -+ while (cnt >= 4) { -+ for (i = 0; i < 4; i++) -+ tmp[i] = *list++ >> 12; -+ nv_wo32(pgt, pte + 0x0, tmp[0] >> 0 | tmp[1] << 27); -+ nv_wo32(pgt, pte + 0x4, tmp[1] >> 5 | tmp[2] << 22); -+ nv_wo32(pgt, pte + 0x8, tmp[2] >> 10 | tmp[3] << 17); -+ nv_wo32(pgt, pte + 0xc, tmp[3] >> 15 | 0x40000000); -+ pte += 0x10; -+ cnt -= 4; -+ } -+ -+ if (cnt) -+ nv44_sgdma_fill(pgt, list, pte, cnt); -+ -+ nv44_sgdma_flush(nvbe); - nvbe->bound = true; - return 0; - } - - static int --nv50_sgdma_unbind(struct ttm_backend *be) -+nv44_sgdma_unbind(struct ttm_backend *be) - { - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; - struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private; -+ struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma; -+ u32 pte = (nvbe->offset >> 12) << 2; -+ u32 cnt = nvbe->nr_pages; -+ -+ if (pte & 0x0000000c) { -+ u32 max = 4 - ((pte >> 2) & 0x3); -+ u32 part = (cnt > max) ? max : cnt; -+ nv44_sgdma_fill(pgt, NULL, pte, part); -+ pte += (part << 2); -+ cnt -= part; -+ } - -- if (!nvbe->bound) -- return 0; -+ while (cnt >= 4) { -+ nv_wo32(pgt, pte + 0x0, 0x00000000); -+ nv_wo32(pgt, pte + 0x4, 0x00000000); -+ nv_wo32(pgt, pte + 0x8, 0x00000000); -+ nv_wo32(pgt, pte + 0xc, 0x00000000); -+ pte += 0x10; -+ cnt -= 4; -+ } - -- nouveau_vm_unmap_at(&dev_priv->gart_info.vma, nvbe->offset, -- nvbe->nr_pages << PAGE_SHIFT); -+ if (cnt) -+ nv44_sgdma_fill(pgt, NULL, pte, cnt); -+ -+ nv44_sgdma_flush(nvbe); - nvbe->bound = false; - return 0; - } - --static struct ttm_backend_func nouveau_sgdma_backend = { -+static struct ttm_backend_func nv44_sgdma_backend = { - .populate = nouveau_sgdma_populate, - .clear = nouveau_sgdma_clear, -- .bind = nouveau_sgdma_bind, -- .unbind = nouveau_sgdma_unbind, -+ .bind = nv44_sgdma_bind, -+ .unbind = nv44_sgdma_unbind, - .destroy = nouveau_sgdma_destroy - }; - -+static int -+nv50_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) -+{ -+ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; -+ struct nouveau_mem *node = mem->mm_node; -+ /* noop: bound in move_notify() */ -+ node->pages = nvbe->pages; -+ nvbe->pages = (dma_addr_t *)node; -+ nvbe->bound = true; -+ return 0; -+} -+ -+static int -+nv50_sgdma_unbind(struct ttm_backend *be) -+{ -+ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; -+ struct nouveau_mem *node = (struct nouveau_mem *)nvbe->pages; -+ /* noop: unbound in move_notify() */ -+ nvbe->pages = node->pages; -+ node->pages = NULL; -+ nvbe->bound = false; -+ return 0; -+} -+ - static struct ttm_backend_func nv50_sgdma_backend = { - .populate = nouveau_sgdma_populate, - .clear = nouveau_sgdma_clear, -@@ -198,10 +400,7 @@ nouveau_sgdma_init_ttm(struct drm_device *dev) - - nvbe->dev = dev; - -- if (dev_priv->card_type < NV_50) -- nvbe->backend.func = &nouveau_sgdma_backend; -- else -- nvbe->backend.func = &nv50_sgdma_backend; -+ nvbe->backend.func = dev_priv->gart_info.func; - return &nvbe->backend; - } - -@@ -210,21 +409,64 @@ nouveau_sgdma_init(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *gpuobj = NULL; -- uint32_t aper_size, obj_size; -- int i, ret; -+ u32 aper_size, align; -+ int ret; - -- if (dev_priv->card_type < NV_50) { -- if(dev_priv->ramin_rsvd_vram < 2 * 1024 * 1024) -- aper_size = 64 * 1024 * 1024; -- else -- aper_size = 512 * 1024 * 1024; -+ if (dev_priv->card_type >= NV_40 && drm_device_is_pcie(dev)) -+ aper_size = 512 * 1024 * 1024; -+ else -+ aper_size = 64 * 1024 * 1024; -+ -+ /* Dear NVIDIA, NV44+ would like proper present bits in PTEs for -+ * christmas. The cards before it have them, the cards after -+ * it have them, why is NV44 so unloved? -+ */ -+ dev_priv->gart_info.dummy.page = alloc_page(GFP_DMA32 | GFP_KERNEL); -+ if (!dev_priv->gart_info.dummy.page) -+ return -ENOMEM; - -- obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4; -- obj_size += 8; /* ctxdma header */ -+ dev_priv->gart_info.dummy.addr = -+ pci_map_page(dev->pdev, dev_priv->gart_info.dummy.page, -+ 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); -+ if (pci_dma_mapping_error(dev->pdev, dev_priv->gart_info.dummy.addr)) { -+ NV_ERROR(dev, "error mapping dummy page\n"); -+ __free_page(dev_priv->gart_info.dummy.page); -+ dev_priv->gart_info.dummy.page = NULL; -+ return -ENOMEM; -+ } - -- ret = nouveau_gpuobj_new(dev, NULL, obj_size, 16, -- NVOBJ_FLAG_ZERO_ALLOC | -- NVOBJ_FLAG_ZERO_FREE, &gpuobj); -+ if (dev_priv->card_type >= NV_50) { -+ dev_priv->gart_info.aper_base = 0; -+ dev_priv->gart_info.aper_size = aper_size; -+ dev_priv->gart_info.type = NOUVEAU_GART_HW; -+ dev_priv->gart_info.func = &nv50_sgdma_backend; -+ } else -+ if (0 && drm_device_is_pcie(dev) && -+ dev_priv->chipset > 0x40 && dev_priv->chipset != 0x45) { -+ if (nv44_graph_class(dev)) { -+ dev_priv->gart_info.func = &nv44_sgdma_backend; -+ align = 512 * 1024; -+ } else { -+ dev_priv->gart_info.func = &nv41_sgdma_backend; -+ align = 16; -+ } -+ -+ ret = nouveau_gpuobj_new(dev, NULL, aper_size / 1024, align, -+ NVOBJ_FLAG_ZERO_ALLOC | -+ NVOBJ_FLAG_ZERO_FREE, &gpuobj); -+ if (ret) { -+ NV_ERROR(dev, "Error creating sgdma object: %d\n", ret); -+ return ret; -+ } -+ -+ dev_priv->gart_info.sg_ctxdma = gpuobj; -+ dev_priv->gart_info.aper_base = 0; -+ dev_priv->gart_info.aper_size = aper_size; -+ dev_priv->gart_info.type = NOUVEAU_GART_HW; -+ } else { -+ ret = nouveau_gpuobj_new(dev, NULL, (aper_size / 1024) + 8, 16, -+ NVOBJ_FLAG_ZERO_ALLOC | -+ NVOBJ_FLAG_ZERO_FREE, &gpuobj); - if (ret) { - NV_ERROR(dev, "Error creating sgdma object: %d\n", ret); - return ret; -@@ -236,25 +478,14 @@ nouveau_sgdma_init(struct drm_device *dev) - (0 << 14) /* RW */ | - (2 << 16) /* PCI */); - nv_wo32(gpuobj, 4, aper_size - 1); -- for (i = 2; i < 2 + (aper_size >> 12); i++) -- nv_wo32(gpuobj, i * 4, 0x00000000); - - dev_priv->gart_info.sg_ctxdma = gpuobj; - dev_priv->gart_info.aper_base = 0; - dev_priv->gart_info.aper_size = aper_size; -- } else -- if (dev_priv->chan_vm) { -- ret = nouveau_vm_get(dev_priv->chan_vm, 512 * 1024 * 1024, -- 12, NV_MEM_ACCESS_RW, -- &dev_priv->gart_info.vma); -- if (ret) -- return ret; -- -- dev_priv->gart_info.aper_base = dev_priv->gart_info.vma.offset; -- dev_priv->gart_info.aper_size = 512 * 1024 * 1024; -+ dev_priv->gart_info.type = NOUVEAU_GART_PDMA; -+ dev_priv->gart_info.func = &nv04_sgdma_backend; - } - -- dev_priv->gart_info.type = NOUVEAU_GART_SGDMA; - return 0; - } - -@@ -264,7 +495,13 @@ nouveau_sgdma_takedown(struct drm_device *dev) - struct drm_nouveau_private *dev_priv = dev->dev_private; - - nouveau_gpuobj_ref(NULL, &dev_priv->gart_info.sg_ctxdma); -- nouveau_vm_put(&dev_priv->gart_info.vma); -+ -+ if (dev_priv->gart_info.dummy.page) { -+ pci_unmap_page(dev->pdev, dev_priv->gart_info.dummy.addr, -+ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); -+ __free_page(dev_priv->gart_info.dummy.page); -+ dev_priv->gart_info.dummy.page = NULL; -+ } - } - - uint32_t -diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c -index a54fc43..adf6dac 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_state.c -+++ b/drivers/gpu/drm/nouveau/nouveau_state.c -@@ -376,15 +376,11 @@ 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) -+ if (dev_priv->chipset == 0x50 || -+ dev_priv->chipset == 0xac) - 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; -- } -+ else -+ engine->graph.tlb_flush = nv84_graph_tlb_flush; - engine->fifo.channels = 128; - engine->fifo.init = nv50_fifo_init; - engine->fifo.takedown = nv50_fifo_takedown; -@@ -513,6 +509,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) - engine->vram.get = nvc0_vram_new; - engine->vram.put = nv50_vram_del; - engine->vram.flags_valid = nvc0_vram_flags_valid; -+ engine->pm.temp_get = nv84_temp_get; - break; - default: - NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); -@@ -544,7 +541,6 @@ static int - nouveau_card_init_channel(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_gpuobj *gpuobj = NULL; - int ret; - - ret = nouveau_channel_alloc(dev, &dev_priv->channel, -@@ -552,41 +548,8 @@ nouveau_card_init_channel(struct drm_device *dev) - if (ret) - return ret; - -- /* no dma objects on fermi... */ -- if (dev_priv->card_type >= NV_C0) -- goto out_done; -- -- ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, -- 0, dev_priv->vram_size, -- NV_MEM_ACCESS_RW, NV_MEM_TARGET_VRAM, -- &gpuobj); -- if (ret) -- goto out_err; -- -- ret = nouveau_ramht_insert(dev_priv->channel, NvDmaVRAM, gpuobj); -- nouveau_gpuobj_ref(NULL, &gpuobj); -- if (ret) -- goto out_err; -- -- ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, -- 0, dev_priv->gart_info.aper_size, -- NV_MEM_ACCESS_RW, NV_MEM_TARGET_GART, -- &gpuobj); -- if (ret) -- goto out_err; -- -- ret = nouveau_ramht_insert(dev_priv->channel, NvDmaGART, gpuobj); -- nouveau_gpuobj_ref(NULL, &gpuobj); -- if (ret) -- goto out_err; -- --out_done: - mutex_unlock(&dev_priv->channel->mutex); - return 0; -- --out_err: -- nouveau_channel_put(&dev_priv->channel); -- return ret; - } - - static void nouveau_switcheroo_set_state(struct pci_dev *pdev, -@@ -646,6 +609,7 @@ nouveau_card_init(struct drm_device *dev) - spin_lock_init(&dev_priv->channels.lock); - spin_lock_init(&dev_priv->tile.lock); - spin_lock_init(&dev_priv->context_switch_lock); -+ spin_lock_init(&dev_priv->vm_lock); - - /* Make the CRTCs and I2C buses accessible */ - ret = engine->display.early_init(dev); -@@ -811,6 +775,11 @@ static void nouveau_card_takedown(struct drm_device *dev) - engine->mc.takedown(dev); - engine->display.late_takedown(dev); - -+ if (dev_priv->vga_ram) { -+ nouveau_bo_unpin(dev_priv->vga_ram); -+ nouveau_bo_ref(NULL, &dev_priv->vga_ram); -+ } -+ - 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); -@@ -904,7 +873,7 @@ static int nouveau_remove_conflicting_drivers(struct drm_device *dev) - #ifdef CONFIG_X86 - primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; - #endif -- -+ - remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary); - return 0; - } -@@ -929,12 +898,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) - 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) { -- ret = -EINVAL; -- goto err_priv; -- } -- - /* resource 0 is mmio regs */ - /* resource 1 is linear FB */ - /* resource 2 is RAMIN (mmio regs + 0x1000000) */ -@@ -947,7 +910,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) - NV_ERROR(dev, "Unable to initialize the mmio mapping. " - "Please report your setup to " DRIVER_EMAIL "\n"); - ret = -EINVAL; -- goto err_wq; -+ goto err_priv; - } - NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", - (unsigned long long)mmio_start_offs); -@@ -962,11 +925,13 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) - - /* Time to determine the card architecture */ - reg0 = nv_rd32(dev, NV03_PMC_BOOT_0); -+ dev_priv->stepping = 0; /* XXX: add stepping for pre-NV10? */ - - /* We're dealing with >=NV10 */ - if ((reg0 & 0x0f000000) > 0) { - /* Bit 27-20 contain the architecture in hex */ - dev_priv->chipset = (reg0 & 0xff00000) >> 20; -+ dev_priv->stepping = (reg0 & 0xff); - /* NV04 or NV05 */ - } else if ((reg0 & 0xff00fff0) == 0x20004000) { - if (reg0 & 0x00f00000) -@@ -1054,8 +1019,6 @@ 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; -@@ -1126,7 +1089,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, - getparam->value = 1; - break; - case NOUVEAU_GETPARAM_HAS_PAGEFLIP: -- getparam->value = (dev_priv->card_type < NV_50); -+ getparam->value = 1; - break; - case NOUVEAU_GETPARAM_GRAPH_UNITS: - /* NV40 and NV50 versions are quite different, but register -diff --git a/drivers/gpu/drm/nouveau/nouveau_temp.c b/drivers/gpu/drm/nouveau/nouveau_temp.c -index 8d9968e..649b041 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_temp.c -+++ b/drivers/gpu/drm/nouveau/nouveau_temp.c -@@ -239,11 +239,9 @@ static bool - probe_monitoring_device(struct nouveau_i2c_chan *i2c, - struct i2c_board_info *info) - { -- char modalias[16] = "i2c:"; - struct i2c_client *client; - -- strlcat(modalias, info->type, sizeof(modalias)); -- request_module(modalias); -+ request_module("%s%s", I2C_MODULE_PREFIX, info->type); - - client = i2c_new_device(&i2c->adapter, info); - if (!client) -diff --git a/drivers/gpu/drm/nouveau/nouveau_util.c b/drivers/gpu/drm/nouveau/nouveau_util.c -index fbe0fb1..e51b515 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_util.c -+++ b/drivers/gpu/drm/nouveau/nouveau_util.c -@@ -47,18 +47,27 @@ nouveau_bitfield_print(const struct nouveau_bitfield *bf, u32 value) - printk(" (unknown bits 0x%08x)", value); - } - --void --nouveau_enum_print(const struct nouveau_enum *en, u32 value) -+const struct nouveau_enum * -+nouveau_enum_find(const struct nouveau_enum *en, u32 value) - { - while (en->name) { -- if (value == en->value) { -- printk("%s", en->name); -- return; -- } -- -+ if (en->value == value) -+ return en; - en++; - } - -+ return NULL; -+} -+ -+void -+nouveau_enum_print(const struct nouveau_enum *en, u32 value) -+{ -+ en = nouveau_enum_find(en, value); -+ if (en) { -+ printk("%s", en->name); -+ return; -+ } -+ - printk("(unknown enum 0x%08x)", value); - } - -diff --git a/drivers/gpu/drm/nouveau/nouveau_util.h b/drivers/gpu/drm/nouveau/nouveau_util.h -index d9ceaea..b97719f 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_util.h -+++ b/drivers/gpu/drm/nouveau/nouveau_util.h -@@ -36,10 +36,14 @@ struct nouveau_bitfield { - struct nouveau_enum { - u32 value; - const char *name; -+ void *data; - }; - - void nouveau_bitfield_print(const struct nouveau_bitfield *, u32 value); - void nouveau_enum_print(const struct nouveau_enum *, u32 value); -+const struct nouveau_enum * -+nouveau_enum_find(const struct nouveau_enum *, u32 value); -+ - int nouveau_ratelimit(void); - - #endif -diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.c b/drivers/gpu/drm/nouveau/nouveau_vm.c -index 97d82ae..0059e6f 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_vm.c -+++ b/drivers/gpu/drm/nouveau/nouveau_vm.c -@@ -28,7 +28,7 @@ - #include "nouveau_vm.h" - - void --nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_vram *vram) -+nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node) - { - struct nouveau_vm *vm = vma->vm; - struct nouveau_mm_node *r; -@@ -40,7 +40,8 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_vram *vram) - u32 max = 1 << (vm->pgt_bits - bits); - u32 end, len; - -- list_for_each_entry(r, &vram->regions, rl_entry) { -+ delta = 0; -+ list_for_each_entry(r, &node->regions, rl_entry) { - u64 phys = (u64)r->offset << 12; - u32 num = r->length >> bits; - -@@ -52,7 +53,7 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_vram *vram) - end = max; - len = end - pte; - -- vm->map(vma, pgt, vram, pte, len, phys); -+ vm->map(vma, pgt, node, pte, len, phys, delta); - - num -= len; - pte += len; -@@ -60,6 +61,8 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_vram *vram) - pde++; - pte = 0; - } -+ -+ delta += (u64)len << vma->node->type; - } - } - -@@ -67,14 +70,14 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_vram *vram) - } - - void --nouveau_vm_map(struct nouveau_vma *vma, struct nouveau_vram *vram) -+nouveau_vm_map(struct nouveau_vma *vma, struct nouveau_mem *node) - { -- nouveau_vm_map_at(vma, 0, vram); -+ nouveau_vm_map_at(vma, 0, node); - } - - void - nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length, -- dma_addr_t *list) -+ struct nouveau_mem *mem, dma_addr_t *list) - { - struct nouveau_vm *vm = vma->vm; - int big = vma->node->type != vm->spg_shift; -@@ -94,7 +97,7 @@ nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length, - end = max; - len = end - pte; - -- vm->map_sg(vma, pgt, pte, list, len); -+ vm->map_sg(vma, pgt, mem, pte, len, list); - - num -= len; - pte += len; -@@ -311,18 +314,7 @@ nouveau_vm_new(struct drm_device *dev, u64 offset, u64 length, u64 mm_offset, - vm->spg_shift = 12; - vm->lpg_shift = 17; - pgt_bits = 27; -- -- /* Should be 4096 everywhere, this is a hack that's -- * currently necessary to avoid an elusive bug that -- * causes corruption when mixing small/large pages -- */ -- if (length < (1ULL << 40)) -- block = 4096; -- else { -- block = (1 << pgt_bits); -- if (length < block) -- block = length; -- } -+ block = 4096; - } else { - kfree(vm); - return -ENOSYS; -diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.h b/drivers/gpu/drm/nouveau/nouveau_vm.h -index e119351..2e06b55 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_vm.h -+++ b/drivers/gpu/drm/nouveau/nouveau_vm.h -@@ -67,9 +67,10 @@ struct nouveau_vm { - void (*map_pgt)(struct nouveau_gpuobj *pgd, u32 pde, - struct nouveau_gpuobj *pgt[2]); - void (*map)(struct nouveau_vma *, struct nouveau_gpuobj *, -- struct nouveau_vram *, u32 pte, u32 cnt, u64 phys); -+ struct nouveau_mem *, u32 pte, u32 cnt, -+ u64 phys, u64 delta); - void (*map_sg)(struct nouveau_vma *, struct nouveau_gpuobj *, -- u32 pte, dma_addr_t *, u32 cnt); -+ struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *); - void (*unmap)(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt); - void (*flush)(struct nouveau_vm *); - }; -@@ -82,20 +83,20 @@ int nouveau_vm_ref(struct nouveau_vm *, struct nouveau_vm **, - int nouveau_vm_get(struct nouveau_vm *, u64 size, u32 page_shift, - u32 access, struct nouveau_vma *); - void nouveau_vm_put(struct nouveau_vma *); --void nouveau_vm_map(struct nouveau_vma *, struct nouveau_vram *); --void nouveau_vm_map_at(struct nouveau_vma *, u64 offset, struct nouveau_vram *); -+void nouveau_vm_map(struct nouveau_vma *, struct nouveau_mem *); -+void nouveau_vm_map_at(struct nouveau_vma *, u64 offset, struct nouveau_mem *); - void nouveau_vm_unmap(struct nouveau_vma *); - void nouveau_vm_unmap_at(struct nouveau_vma *, u64 offset, u64 length); - void nouveau_vm_map_sg(struct nouveau_vma *, u64 offset, u64 length, -- dma_addr_t *); -+ struct nouveau_mem *, dma_addr_t *); - - /* nv50_vm.c */ - void nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde, - struct nouveau_gpuobj *pgt[2]); - void nv50_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *, -- struct nouveau_vram *, u32 pte, u32 cnt, u64 phys); -+ struct nouveau_mem *, u32 pte, u32 cnt, u64 phys, u64 delta); - void nv50_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *, -- u32 pte, dma_addr_t *, u32 cnt); -+ struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *); - void nv50_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt); - void nv50_vm_flush(struct nouveau_vm *); - void nv50_vm_flush_engine(struct drm_device *, int engine); -@@ -104,9 +105,9 @@ void nv50_vm_flush_engine(struct drm_device *, int engine); - void nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde, - struct nouveau_gpuobj *pgt[2]); - void nvc0_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *, -- struct nouveau_vram *, u32 pte, u32 cnt, u64 phys); -+ struct nouveau_mem *, u32 pte, u32 cnt, u64 phys, u64 delta); - void nvc0_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *, -- u32 pte, dma_addr_t *, u32 cnt); -+ struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *); - void nvc0_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt); - void nvc0_vm_flush(struct nouveau_vm *); - -diff --git a/drivers/gpu/drm/nouveau/nouveau_volt.c b/drivers/gpu/drm/nouveau/nouveau_volt.c -index 04fdc00..75e87274 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_volt.c -+++ b/drivers/gpu/drm/nouveau/nouveau_volt.c -@@ -159,8 +159,16 @@ nouveau_volt_init(struct drm_device *dev) - headerlen = volt[1]; - recordlen = volt[2]; - entries = volt[3]; -- vidshift = hweight8(volt[5]); - vidmask = volt[4]; -+ /* no longer certain what volt[5] is, if it's related to -+ * the vid shift then it's definitely not a function of -+ * how many bits are set. -+ * -+ * after looking at a number of nva3+ vbios images, they -+ * all seem likely to have a static shift of 2.. lets -+ * go with that for now until proven otherwise. -+ */ -+ vidshift = 2; - break; - default: - NV_WARN(dev, "voltage table 0x%02x unknown\n", volt[0]); -diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c -index 297505e..9eaafcc 100644 ---- a/drivers/gpu/drm/nouveau/nv04_crtc.c -+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c -@@ -376,7 +376,10 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode) - */ - - /* framebuffer can be larger than crtc scanout area. */ -- regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = XLATE(fb->pitch / 8, 8, NV_CIO_CRE_RPC0_OFFSET_10_8); -+ regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = -+ XLATE(fb->pitch / 8, 8, NV_CIO_CRE_RPC0_OFFSET_10_8); -+ regp->CRTC[NV_CIO_CRE_42] = -+ XLATE(fb->pitch / 8, 11, NV_CIO_CRE_42_OFFSET_11); - regp->CRTC[NV_CIO_CRE_RPC1_INDEX] = mode->crtc_hdisplay < 1280 ? - MASK(NV_CIO_CRE_RPC1_LARGE) : 0x00; - regp->CRTC[NV_CIO_CRE_LSR_INDEX] = XLATE(horizBlankEnd, 6, NV_CIO_CRE_LSR_HBE_6) | -@@ -790,8 +793,7 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, - if (atomic) { - drm_fb = passed_fb; - fb = nouveau_framebuffer(passed_fb); -- } -- else { -+ } else { - /* If not atomic, we can go ahead and pin, and unpin the - * old fb we were passed. - */ -@@ -825,8 +827,11 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, - regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = drm_fb->pitch >> 3; - regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = - XLATE(drm_fb->pitch >> 3, 8, NV_CIO_CRE_RPC0_OFFSET_10_8); -+ regp->CRTC[NV_CIO_CRE_42] = -+ XLATE(drm_fb->pitch / 8, 11, NV_CIO_CRE_42_OFFSET_11); - crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_RPC0_INDEX); - crtc_wr_cio_state(crtc, regp, NV_CIO_CR_OFFSET_INDEX); -+ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_42); - - /* Update the framebuffer location. */ - regp->fb_start = nv_crtc->fb.offset & ~3; -@@ -944,14 +949,14 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, - struct drm_gem_object *gem; - int ret = 0; - -- if (width != 64 || height != 64) -- return -EINVAL; -- - if (!buffer_handle) { - nv_crtc->cursor.hide(nv_crtc, true); - return 0; - } - -+ if (width != 64 || height != 64) -+ return -EINVAL; -+ - gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); - if (!gem) - return -ENOENT; -@@ -1031,7 +1036,7 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num) - drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256); - - ret = nouveau_bo_new(dev, NULL, 64*64*4, 0x100, TTM_PL_FLAG_VRAM, -- 0, 0x0000, false, true, &nv_crtc->cursor.nvbo); -+ 0, 0x0000, &nv_crtc->cursor.nvbo); - if (!ret) { - ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); - if (!ret) -diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c -index c82db37..12098bf 100644 ---- a/drivers/gpu/drm/nouveau/nv04_dfp.c -+++ b/drivers/gpu/drm/nouveau/nv04_dfp.c -@@ -581,12 +581,13 @@ static void nv04_dfp_restore(struct drm_encoder *encoder) - int head = nv_encoder->restore.head; - - if (nv_encoder->dcb->type == OUTPUT_LVDS) { -- struct drm_display_mode *native_mode = nouveau_encoder_connector_get(nv_encoder)->native_mode; -- if (native_mode) -- call_lvds_script(dev, nv_encoder->dcb, head, LVDS_PANEL_ON, -- native_mode->clock); -- else -- NV_ERROR(dev, "Not restoring LVDS without native mode\n"); -+ struct nouveau_connector *connector = -+ nouveau_encoder_connector_get(nv_encoder); -+ -+ if (connector && connector->native_mode) -+ call_lvds_script(dev, nv_encoder->dcb, head, -+ LVDS_PANEL_ON, -+ connector->native_mode->clock); - - } else if (nv_encoder->dcb->type == OUTPUT_TMDS) { - int clock = nouveau_hw_pllvals_to_clk -diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c -index f89d104..db465a3 100644 ---- a/drivers/gpu/drm/nouveau/nv04_fifo.c -+++ b/drivers/gpu/drm/nouveau/nv04_fifo.c -@@ -379,6 +379,15 @@ out: - return handled; - } - -+static const char *nv_dma_state_err(u32 state) -+{ -+ static const char * const desc[] = { -+ "NONE", "CALL_SUBR_ACTIVE", "INVALID_MTHD", "RET_SUBR_INACTIVE", -+ "INVALID_CMD", "IB_EMPTY"/* NV50+ */, "MEM_FAULT", "UNK" -+ }; -+ return desc[(state >> 29) & 0x7]; -+} -+ - void - nv04_fifo_isr(struct drm_device *dev) - { -@@ -460,9 +469,10 @@ nv04_fifo_isr(struct drm_device *dev) - if (nouveau_ratelimit()) - 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", -+ "State 0x%08x (err: %s) Push 0x%08x\n", - chid, ho_get, dma_get, ho_put, - dma_put, ib_get, ib_put, state, -+ nv_dma_state_err(state), - push); - - /* METHOD_COUNT, in DMA_STATE on earlier chipsets */ -@@ -476,8 +486,9 @@ nv04_fifo_isr(struct drm_device *dev) - } - } else { - NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%08x " -- "Put 0x%08x State 0x%08x Push 0x%08x\n", -- chid, dma_get, dma_put, state, push); -+ "Put 0x%08x State 0x%08x (err: %s) Push 0x%08x\n", -+ chid, dma_get, dma_put, state, -+ nv_dma_state_err(state), push); - - if (dma_get != dma_put) - nv_wr32(dev, 0x003244, dma_put); -@@ -505,7 +516,7 @@ nv04_fifo_isr(struct drm_device *dev) - - if (dev_priv->card_type == NV_50) { - if (status & 0x00000010) { -- nv50_fb_vm_trap(dev, 1, "PFIFO_BAR_FAULT"); -+ nv50_fb_vm_trap(dev, nouveau_ratelimit()); - status &= ~0x00000010; - nv_wr32(dev, 0x002100, 0x00000010); - } -diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c -index af75015..055677a 100644 ---- a/drivers/gpu/drm/nouveau/nv04_graph.c -+++ b/drivers/gpu/drm/nouveau/nv04_graph.c -@@ -507,7 +507,7 @@ int nv04_graph_init(struct drm_device *dev) - nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/ - nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x1231c000); - /*1231C000 blob, 001 haiku*/ -- //*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/ -+ /*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/ - nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x72111100); - /*0x72111100 blob , 01 haiku*/ - /*nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/ -@@ -1232,8 +1232,7 @@ static struct nouveau_bitfield nv04_graph_intr[] = { - {} - }; - --static struct nouveau_bitfield nv04_graph_nstatus[] = --{ -+static struct nouveau_bitfield nv04_graph_nstatus[] = { - { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, - { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, - { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, -@@ -1241,8 +1240,7 @@ static struct nouveau_bitfield nv04_graph_nstatus[] = - {} - }; - --struct nouveau_bitfield nv04_graph_nsource[] = --{ -+struct nouveau_bitfield nv04_graph_nsource[] = { - { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" }, - { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" }, - { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" }, -diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c -index b8e3edb..0671b7f 100644 ---- a/drivers/gpu/drm/nouveau/nv04_instmem.c -+++ b/drivers/gpu/drm/nouveau/nv04_instmem.c -@@ -95,6 +95,9 @@ nv04_instmem_takedown(struct drm_device *dev) - nouveau_ramht_ref(NULL, &dev_priv->ramht, NULL); - nouveau_gpuobj_ref(NULL, &dev_priv->ramro); - nouveau_gpuobj_ref(NULL, &dev_priv->ramfc); -+ -+ if (dev_priv->ramin_heap.free_stack.next) -+ drm_mm_takedown(&dev_priv->ramin_heap); - } - - int -diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c -index 8c92edb..531d7ba 100644 ---- a/drivers/gpu/drm/nouveau/nv10_graph.c -+++ b/drivers/gpu/drm/nouveau/nv10_graph.c -@@ -1117,8 +1117,7 @@ struct nouveau_bitfield nv10_graph_intr[] = { - {} - }; - --struct nouveau_bitfield nv10_graph_nstatus[] = --{ -+struct nouveau_bitfield nv10_graph_nstatus[] = { - { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, - { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, - { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, -diff --git a/drivers/gpu/drm/nouveau/nv40_fb.c b/drivers/gpu/drm/nouveau/nv40_fb.c -index f3d9c05..f0ac2a7 100644 ---- a/drivers/gpu/drm/nouveau/nv40_fb.c -+++ b/drivers/gpu/drm/nouveau/nv40_fb.c -@@ -24,6 +24,53 @@ nv40_fb_set_tile_region(struct drm_device *dev, int i) - } - } - -+static void -+nv40_fb_init_gart(struct drm_device *dev) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma; -+ -+ if (dev_priv->gart_info.type != NOUVEAU_GART_HW) { -+ nv_wr32(dev, 0x100800, 0x00000001); -+ return; -+ } -+ -+ nv_wr32(dev, 0x100800, gart->pinst | 0x00000002); -+ nv_mask(dev, 0x10008c, 0x00000100, 0x00000100); -+ nv_wr32(dev, 0x100820, 0x00000000); -+} -+ -+static void -+nv44_fb_init_gart(struct drm_device *dev) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma; -+ u32 vinst; -+ -+ if (dev_priv->gart_info.type != NOUVEAU_GART_HW) { -+ nv_wr32(dev, 0x100850, 0x80000000); -+ nv_wr32(dev, 0x100800, 0x00000001); -+ return; -+ } -+ -+ /* calculate vram address of this PRAMIN block, object -+ * must be allocated on 512KiB alignment, and not exceed -+ * a total size of 512KiB for this to work correctly -+ */ -+ vinst = nv_rd32(dev, 0x10020c); -+ vinst -= ((gart->pinst >> 19) + 1) << 19; -+ -+ nv_wr32(dev, 0x100850, 0x80000000); -+ nv_wr32(dev, 0x100818, dev_priv->gart_info.dummy.addr); -+ -+ nv_wr32(dev, 0x100804, dev_priv->gart_info.aper_size); -+ nv_wr32(dev, 0x100850, 0x00008000); -+ nv_mask(dev, 0x10008c, 0x00000200, 0x00000200); -+ nv_wr32(dev, 0x100820, 0x00000000); -+ nv_wr32(dev, 0x10082c, 0x00000001); -+ nv_wr32(dev, 0x100800, vinst | 0x00000010); -+} -+ - int - nv40_fb_init(struct drm_device *dev) - { -@@ -32,12 +79,12 @@ nv40_fb_init(struct drm_device *dev) - uint32_t tmp; - int i; - -- /* This is strictly a NV4x register (don't know about NV5x). */ -- /* The blob sets these to all kinds of values, and they mess up our setup. */ -- /* I got value 0x52802 instead. For some cards the blob even sets it back to 0x1. */ -- /* Note: the blob doesn't read this value, so i'm pretty sure this is safe for all cards. */ -- /* Any idea what this is? */ -- nv_wr32(dev, NV40_PFB_UNK_800, 0x1); -+ if (dev_priv->chipset != 0x40 && dev_priv->chipset != 0x45) { -+ if (nv44_graph_class(dev)) -+ nv44_fb_init_gart(dev); -+ else -+ nv40_fb_init_gart(dev); -+ } - - switch (dev_priv->chipset) { - case 0x40: -diff --git a/drivers/gpu/drm/nouveau/nv50_calc.c b/drivers/gpu/drm/nouveau/nv50_calc.c -index de81151..8cf63a8 100644 ---- a/drivers/gpu/drm/nouveau/nv50_calc.c -+++ b/drivers/gpu/drm/nouveau/nv50_calc.c -@@ -23,7 +23,6 @@ - */ - - #include "drmP.h" --#include "drm_fixed.h" - #include "nouveau_drv.h" - #include "nouveau_hw.h" - -@@ -47,45 +46,52 @@ nv50_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk, - } - - int --nv50_calc_pll2(struct drm_device *dev, struct pll_lims *pll, int clk, -- int *N, int *fN, int *M, int *P) -+nva3_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk, -+ int *pN, int *pfN, int *pM, int *P) - { -- fixed20_12 fb_div, a, b; -- u32 refclk = pll->refclk / 10; -- u32 max_vco_freq = pll->vco1.maxfreq / 10; -- u32 max_vco_inputfreq = pll->vco1.max_inputfreq / 10; -- clk /= 10; -+ u32 best_err = ~0, err; -+ int M, lM, hM, N, fN; - -- *P = max_vco_freq / clk; -+ *P = pll->vco1.maxfreq / clk; - if (*P > pll->max_p) - *P = pll->max_p; - if (*P < pll->min_p) - *P = pll->min_p; - -- /* *M = floor((refclk + max_vco_inputfreq) / max_vco_inputfreq); */ -- a.full = dfixed_const(refclk + max_vco_inputfreq); -- b.full = dfixed_const(max_vco_inputfreq); -- a.full = dfixed_div(a, b); -- a.full = dfixed_floor(a); -- *M = dfixed_trunc(a); -+ lM = (pll->refclk + pll->vco1.max_inputfreq) / pll->vco1.max_inputfreq; -+ lM = max(lM, (int)pll->vco1.min_m); -+ hM = (pll->refclk + pll->vco1.min_inputfreq) / pll->vco1.min_inputfreq; -+ hM = min(hM, (int)pll->vco1.max_m); - -- /* fb_div = (vco * *M) / refclk; */ -- fb_div.full = dfixed_const(clk * *P); -- fb_div.full = dfixed_mul(fb_div, a); -- a.full = dfixed_const(refclk); -- fb_div.full = dfixed_div(fb_div, a); -+ for (M = lM; M <= hM; M++) { -+ u32 tmp = clk * *P * M; -+ N = tmp / pll->refclk; -+ fN = tmp % pll->refclk; -+ if (!pfN && fN >= pll->refclk / 2) -+ N++; - -- /* *N = floor(fb_div); */ -- a.full = dfixed_floor(fb_div); -- *N = dfixed_trunc(fb_div); -+ if (N < pll->vco1.min_n) -+ continue; -+ if (N > pll->vco1.max_n) -+ break; - -- /* *fN = (fmod(fb_div, 1.0) * 8192) - 4096; */ -- b.full = dfixed_const(8192); -- a.full = dfixed_mul(a, b); -- fb_div.full = dfixed_mul(fb_div, b); -- fb_div.full = fb_div.full - a.full; -- *fN = dfixed_trunc(fb_div) - 4096; -- *fN &= 0xffff; -+ err = abs(clk - (pll->refclk * N / M / *P)); -+ if (err < best_err) { -+ best_err = err; -+ *pN = N; -+ *pM = M; -+ } - -- return clk; -+ if (pfN) { -+ *pfN = (((fN << 13) / pll->refclk) - 4096) & 0xffff; -+ return clk; -+ } -+ } -+ -+ if (unlikely(best_err == ~0)) { -+ NV_ERROR(dev, "unable to find matching pll values\n"); -+ return -EINVAL; -+ } -+ -+ return pll->refclk * *pN / *pM / *P; - } -diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c -index 9023c4d..ebabacf 100644 ---- a/drivers/gpu/drm/nouveau/nv50_crtc.c -+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c -@@ -65,7 +65,7 @@ nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked) - { - struct drm_device *dev = nv_crtc->base.dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_channel *evo = dev_priv->evo; -+ struct nouveau_channel *evo = nv50_display(dev)->master; - int index = nv_crtc->index, ret; - - NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); -@@ -135,8 +135,7 @@ static int - nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool on, bool update) - { - struct drm_device *dev = nv_crtc->base.dev; -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_channel *evo = dev_priv->evo; -+ struct nouveau_channel *evo = nv50_display(dev)->master; - int ret; - - NV_DEBUG_KMS(dev, "\n"); -@@ -186,8 +185,7 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode, bool update) - struct nouveau_connector *nv_connector = - nouveau_crtc_connector_get(nv_crtc); - struct drm_device *dev = nv_crtc->base.dev; -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_channel *evo = dev_priv->evo; -+ struct nouveau_channel *evo = nv50_display(dev)->master; - struct drm_display_mode *native_mode = NULL; - struct drm_display_mode *mode = &nv_crtc->base.mode; - uint32_t outX, outY, horiz, vert; -@@ -288,7 +286,7 @@ nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk) - nv_wr32(dev, pll.reg + 8, reg2 | (P << 28) | (M2 << 16) | N2); - } else - if (dev_priv->chipset < NV_C0) { -- ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P); -+ ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P); - if (ret <= 0) - return 0; - -@@ -300,7 +298,7 @@ nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk) - nv_wr32(dev, pll.reg + 4, reg1 | (P << 16) | (M1 << 8) | N1); - nv_wr32(dev, pll.reg + 8, N2); - } else { -- ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P); -+ ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P); - if (ret <= 0) - return 0; - -@@ -351,14 +349,14 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, - struct drm_gem_object *gem; - int ret = 0, i; - -- if (width != 64 || height != 64) -- return -EINVAL; -- - if (!buffer_handle) { - nv_crtc->cursor.hide(nv_crtc, true); - return 0; - } - -+ if (width != 64 || height != 64) -+ return -EINVAL; -+ - gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); - if (!gem) - return -ENOENT; -@@ -445,6 +443,39 @@ nv50_crtc_dpms(struct drm_crtc *crtc, int mode) - { - } - -+static int -+nv50_crtc_wait_complete(struct drm_crtc *crtc) -+{ -+ struct drm_device *dev = crtc->dev; -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; -+ struct nv50_display *disp = nv50_display(dev); -+ struct nouveau_channel *evo = disp->master; -+ u64 start; -+ int ret; -+ -+ ret = RING_SPACE(evo, 6); -+ if (ret) -+ return ret; -+ BEGIN_RING(evo, 0, 0x0084, 1); -+ OUT_RING (evo, 0x80000000); -+ BEGIN_RING(evo, 0, 0x0080, 1); -+ OUT_RING (evo, 0); -+ BEGIN_RING(evo, 0, 0x0084, 1); -+ OUT_RING (evo, 0x00000000); -+ -+ nv_wo32(disp->ntfy, 0x000, 0x00000000); -+ FIRE_RING (evo); -+ -+ start = ptimer->read(dev); -+ do { -+ if (nv_ro32(disp->ntfy, 0x000)) -+ return 0; -+ } while (ptimer->read(dev) - start < 2000000000ULL); -+ -+ return -EBUSY; -+} -+ - static void - nv50_crtc_prepare(struct drm_crtc *crtc) - { -@@ -453,6 +484,7 @@ nv50_crtc_prepare(struct drm_crtc *crtc) - - NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); - -+ nv50_display_flip_stop(crtc); - drm_vblank_pre_modeset(dev, nv_crtc->index); - nv50_crtc_blank(nv_crtc, true); - } -@@ -461,24 +493,14 @@ static void - nv50_crtc_commit(struct drm_crtc *crtc) - { - struct drm_device *dev = crtc->dev; -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_channel *evo = dev_priv->evo; - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); -- int ret; - - NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); - - nv50_crtc_blank(nv_crtc, false); - drm_vblank_post_modeset(dev, nv_crtc->index); -- -- 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); -+ nv50_crtc_wait_complete(crtc); -+ nv50_display_flip_next(crtc, crtc->fb, NULL); - } - - static bool -@@ -491,15 +513,15 @@ nv50_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode, - static int - nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, - struct drm_framebuffer *passed_fb, -- int x, int y, bool update, bool atomic) -+ int x, int y, bool atomic) - { - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct drm_device *dev = nv_crtc->base.dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_channel *evo = dev_priv->evo; -+ struct nouveau_channel *evo = nv50_display(dev)->master; - struct drm_framebuffer *drm_fb = nv_crtc->base.fb; - struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); -- int ret, format; -+ int ret; - - NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); - -@@ -510,8 +532,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, - if (atomic) { - drm_fb = passed_fb; - fb = nouveau_framebuffer(passed_fb); -- } -- else { -+ } else { - /* If not atomic, we can go ahead and pin, and unpin the - * old fb we were passed. - */ -@@ -525,28 +546,6 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, - } - } - -- switch (drm_fb->depth) { -- case 8: -- format = NV50_EVO_CRTC_FB_DEPTH_8; -- break; -- case 15: -- format = NV50_EVO_CRTC_FB_DEPTH_15; -- break; -- case 16: -- format = NV50_EVO_CRTC_FB_DEPTH_16; -- break; -- case 24: -- case 32: -- format = NV50_EVO_CRTC_FB_DEPTH_24; -- break; -- case 30: -- format = NV50_EVO_CRTC_FB_DEPTH_30; -- break; -- default: -- NV_ERROR(dev, "unknown depth %d\n", drm_fb->depth); -- return -EINVAL; -- } -- - nv_crtc->fb.offset = fb->nvbo->bo.mem.start << PAGE_SHIFT; - nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo); - nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8; -@@ -556,14 +555,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, - return ret; - - BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1); -- if (nv_crtc->fb.tile_flags == 0x7a00 || -- nv_crtc->fb.tile_flags == 0xfe00) -- OUT_RING(evo, NvEvoFB32); -- else -- if (nv_crtc->fb.tile_flags == 0x7000) -- OUT_RING(evo, NvEvoFB16); -- else -- OUT_RING(evo, NvEvoVRAM_LP); -+ OUT_RING (evo, fb->r_dma); - } - - ret = RING_SPACE(evo, 12); -@@ -571,45 +563,26 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, - return ret; - - BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_OFFSET), 5); -- OUT_RING(evo, nv_crtc->fb.offset >> 8); -- OUT_RING(evo, 0); -- OUT_RING(evo, (drm_fb->height << 16) | drm_fb->width); -- if (!nv_crtc->fb.tile_flags) { -- OUT_RING(evo, drm_fb->pitch | (1 << 20)); -- } else { -- u32 tile_mode = fb->nvbo->tile_mode; -- if (dev_priv->card_type >= NV_C0) -- tile_mode >>= 4; -- OUT_RING(evo, ((drm_fb->pitch / 4) << 4) | tile_mode); -- } -- if (dev_priv->chipset == 0x50) -- OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format); -- else -- OUT_RING(evo, format); -+ OUT_RING (evo, nv_crtc->fb.offset >> 8); -+ OUT_RING (evo, 0); -+ OUT_RING (evo, (drm_fb->height << 16) | drm_fb->width); -+ OUT_RING (evo, fb->r_pitch); -+ OUT_RING (evo, fb->r_format); - - BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1); -- OUT_RING(evo, fb->base.depth == 8 ? -- NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON); -+ OUT_RING (evo, fb->base.depth == 8 ? -+ NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON); - - BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, COLOR_CTRL), 1); -- OUT_RING(evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR); -+ OUT_RING (evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR); - BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_POS), 1); -- OUT_RING(evo, (y << 16) | x); -+ OUT_RING (evo, (y << 16) | x); - - if (nv_crtc->lut.depth != fb->base.depth) { - nv_crtc->lut.depth = fb->base.depth; - nv50_crtc_lut_load(crtc); - } - -- if (update) { -- ret = RING_SPACE(evo, 2); -- if (ret) -- return ret; -- BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); -- OUT_RING(evo, 0); -- FIRE_RING(evo); -- } -- - return 0; - } - -@@ -619,8 +592,7 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_framebuffer *old_fb) - { - struct drm_device *dev = crtc->dev; -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_channel *evo = dev_priv->evo; -+ struct nouveau_channel *evo = nv50_display(dev)->master; - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct nouveau_connector *nv_connector = NULL; - uint32_t hsync_dur, vsync_dur, hsync_start_to_end, vsync_start_to_end; -@@ -700,14 +672,25 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, - nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering, false); - nv_crtc->set_scale(nv_crtc, nv_connector->scaling_mode, false); - -- return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false, false); -+ return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false); - } - - static int - nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) - { -- return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, true, false); -+ int ret; -+ -+ nv50_display_flip_stop(crtc); -+ ret = nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false); -+ if (ret) -+ return ret; -+ -+ ret = nv50_crtc_wait_complete(crtc); -+ if (ret) -+ return ret; -+ -+ return nv50_display_flip_next(crtc, crtc->fb, NULL); - } - - static int -@@ -715,7 +698,14 @@ nv50_crtc_mode_set_base_atomic(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, enum mode_set_atomic state) - { -- return nv50_crtc_do_mode_set_base(crtc, fb, x, y, true, true); -+ int ret; -+ -+ nv50_display_flip_stop(crtc); -+ ret = nv50_crtc_do_mode_set_base(crtc, fb, x, y, true); -+ if (ret) -+ return ret; -+ -+ return nv50_crtc_wait_complete(crtc); - } - - static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = { -@@ -758,7 +748,7 @@ nv50_crtc_create(struct drm_device *dev, int index) - nv_crtc->lut.depth = 0; - - ret = nouveau_bo_new(dev, NULL, 4096, 0x100, TTM_PL_FLAG_VRAM, -- 0, 0x0000, false, true, &nv_crtc->lut.nvbo); -+ 0, 0x0000, &nv_crtc->lut.nvbo); - if (!ret) { - ret = nouveau_bo_pin(nv_crtc->lut.nvbo, TTM_PL_FLAG_VRAM); - if (!ret) -@@ -784,7 +774,7 @@ nv50_crtc_create(struct drm_device *dev, int index) - drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256); - - ret = nouveau_bo_new(dev, NULL, 64*64*4, 0x100, TTM_PL_FLAG_VRAM, -- 0, 0x0000, false, true, &nv_crtc->cursor.nvbo); -+ 0, 0x0000, &nv_crtc->cursor.nvbo); - if (!ret) { - ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); - if (!ret) -diff --git a/drivers/gpu/drm/nouveau/nv50_cursor.c b/drivers/gpu/drm/nouveau/nv50_cursor.c -index 1b9ce30..9752c35 100644 ---- a/drivers/gpu/drm/nouveau/nv50_cursor.c -+++ b/drivers/gpu/drm/nouveau/nv50_cursor.c -@@ -36,9 +36,9 @@ - static void - nv50_cursor_show(struct nouveau_crtc *nv_crtc, bool update) - { -- struct drm_nouveau_private *dev_priv = nv_crtc->base.dev->dev_private; -- struct nouveau_channel *evo = dev_priv->evo; - struct drm_device *dev = nv_crtc->base.dev; -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_channel *evo = nv50_display(dev)->master; - int ret; - - NV_DEBUG_KMS(dev, "\n"); -@@ -71,9 +71,9 @@ nv50_cursor_show(struct nouveau_crtc *nv_crtc, bool update) - static void - nv50_cursor_hide(struct nouveau_crtc *nv_crtc, bool update) - { -- struct drm_nouveau_private *dev_priv = nv_crtc->base.dev->dev_private; -- struct nouveau_channel *evo = dev_priv->evo; - struct drm_device *dev = nv_crtc->base.dev; -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_channel *evo = nv50_display(dev)->master; - int ret; - - NV_DEBUG_KMS(dev, "\n"); -diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c -index 875414b..808f3ec 100644 ---- a/drivers/gpu/drm/nouveau/nv50_dac.c -+++ b/drivers/gpu/drm/nouveau/nv50_dac.c -@@ -41,8 +41,7 @@ nv50_dac_disconnect(struct drm_encoder *encoder) - { - 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; -+ struct nouveau_channel *evo = nv50_display(dev)->master; - int ret; - - if (!nv_encoder->crtc) -@@ -216,8 +215,7 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, - { - 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; -+ struct nouveau_channel *evo = nv50_display(dev)->master; - struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc); - uint32_t mode_ctl = 0, mode_ctl2 = 0; - int ret; -diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c -index 7cc94ed..74a3f68 100644 ---- a/drivers/gpu/drm/nouveau/nv50_display.c -+++ b/drivers/gpu/drm/nouveau/nv50_display.c -@@ -24,6 +24,7 @@ - * - */ - -+#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO) - #include "nv50_display.h" - #include "nouveau_crtc.h" - #include "nouveau_encoder.h" -@@ -34,6 +35,7 @@ - #include "drm_crtc_helper.h" - - static void nv50_display_isr(struct drm_device *); -+static void nv50_display_bh(unsigned long); - - static inline int - nv50_sor_nr(struct drm_device *dev) -@@ -172,16 +174,16 @@ nv50_display_init(struct drm_device *dev) - ret = nv50_evo_init(dev); - if (ret) - return ret; -- evo = dev_priv->evo; -+ evo = nv50_display(dev)->master; - - nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->vinst >> 8) | 9); - -- ret = RING_SPACE(evo, 11); -+ ret = RING_SPACE(evo, 15); - if (ret) - return ret; - BEGIN_RING(evo, 0, NV50_EVO_UNK84, 2); - OUT_RING(evo, NV50_EVO_UNK84_NOTIFY_DISABLED); -- OUT_RING(evo, NV50_EVO_DMA_NOTIFY_HANDLE_NONE); -+ OUT_RING(evo, NvEvoSync); - BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, FB_DMA), 1); - OUT_RING(evo, NV50_EVO_CRTC_FB_DMA_HANDLE_NONE); - BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK0800), 1); -@@ -190,6 +192,11 @@ nv50_display_init(struct drm_device *dev) - OUT_RING(evo, 0); - BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK082C), 1); - OUT_RING(evo, 0); -+ /* required to make display sync channels not hate life */ -+ BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK900), 1); -+ OUT_RING (evo, 0x00000311); -+ BEGIN_RING(evo, 0, NV50_EVO_CRTC(1, UNK900), 1); -+ OUT_RING (evo, 0x00000311); - FIRE_RING(evo); - if (!nv_wait(dev, 0x640004, 0xffffffff, evo->dma.put << 2)) - NV_ERROR(dev, "evo pushbuf stalled\n"); -@@ -201,6 +208,8 @@ nv50_display_init(struct drm_device *dev) - static int nv50_display_disable(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nv50_display *disp = nv50_display(dev); -+ struct nouveau_channel *evo = disp->master; - struct drm_crtc *drm_crtc; - int ret, i; - -@@ -212,12 +221,12 @@ static int nv50_display_disable(struct drm_device *dev) - nv50_crtc_blank(crtc, true); - } - -- ret = RING_SPACE(dev_priv->evo, 2); -+ ret = RING_SPACE(evo, 2); - if (ret == 0) { -- BEGIN_RING(dev_priv->evo, 0, NV50_EVO_UPDATE, 1); -- OUT_RING(dev_priv->evo, 0); -+ BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); -+ OUT_RING(evo, 0); - } -- FIRE_RING(dev_priv->evo); -+ FIRE_RING(evo); - - /* Almost like ack'ing a vblank interrupt, maybe in the spirit of - * cleaning up? -@@ -267,10 +276,16 @@ 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; -+ struct nv50_display *priv; - int ret, i; - - NV_DEBUG_KMS(dev, "\n"); - -+ priv = kzalloc(sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ dev_priv->engine.display.priv = priv; -+ - /* init basic kernel modesetting */ - drm_mode_config_init(dev); - -@@ -330,7 +345,7 @@ int nv50_display_create(struct drm_device *dev) - } - } - -- INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); -+ tasklet_init(&priv->tasklet, nv50_display_bh, (unsigned long)dev); - nouveau_irq_register(dev, 26, nv50_display_isr); - - ret = nv50_display_init(dev); -@@ -345,12 +360,131 @@ int nv50_display_create(struct drm_device *dev) - void - nv50_display_destroy(struct drm_device *dev) - { -+ struct nv50_display *disp = nv50_display(dev); -+ - NV_DEBUG_KMS(dev, "\n"); - - drm_mode_config_cleanup(dev); - - nv50_display_disable(dev); - nouveau_irq_unregister(dev, 26); -+ kfree(disp); -+} -+ -+void -+nv50_display_flip_stop(struct drm_crtc *crtc) -+{ -+ struct nv50_display *disp = nv50_display(crtc->dev); -+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); -+ struct nv50_display_crtc *dispc = &disp->crtc[nv_crtc->index]; -+ struct nouveau_channel *evo = dispc->sync; -+ int ret; -+ -+ ret = RING_SPACE(evo, 8); -+ if (ret) { -+ WARN_ON(1); -+ return; -+ } -+ -+ BEGIN_RING(evo, 0, 0x0084, 1); -+ OUT_RING (evo, 0x00000000); -+ BEGIN_RING(evo, 0, 0x0094, 1); -+ OUT_RING (evo, 0x00000000); -+ BEGIN_RING(evo, 0, 0x00c0, 1); -+ OUT_RING (evo, 0x00000000); -+ BEGIN_RING(evo, 0, 0x0080, 1); -+ OUT_RING (evo, 0x00000000); -+ FIRE_RING (evo); -+} -+ -+int -+nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, -+ struct nouveau_channel *chan) -+{ -+ struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; -+ struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb); -+ struct nv50_display *disp = nv50_display(crtc->dev); -+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); -+ struct nv50_display_crtc *dispc = &disp->crtc[nv_crtc->index]; -+ struct nouveau_channel *evo = dispc->sync; -+ int ret; -+ -+ ret = RING_SPACE(evo, 24); -+ if (unlikely(ret)) -+ return ret; -+ -+ /* synchronise with the rendering channel, if necessary */ -+ if (likely(chan)) { -+ u64 offset = dispc->sem.bo->vma.offset + dispc->sem.offset; -+ -+ ret = RING_SPACE(chan, 10); -+ if (ret) { -+ WIND_RING(evo); -+ return ret; -+ } -+ -+ if (dev_priv->chipset < 0xc0) { -+ BEGIN_RING(chan, NvSubSw, 0x0060, 2); -+ OUT_RING (chan, NvEvoSema0 + nv_crtc->index); -+ OUT_RING (chan, dispc->sem.offset); -+ BEGIN_RING(chan, NvSubSw, 0x006c, 1); -+ OUT_RING (chan, 0xf00d0000 | dispc->sem.value); -+ BEGIN_RING(chan, NvSubSw, 0x0064, 2); -+ OUT_RING (chan, dispc->sem.offset ^ 0x10); -+ OUT_RING (chan, 0x74b1e000); -+ BEGIN_RING(chan, NvSubSw, 0x0060, 1); -+ if (dev_priv->chipset < 0x84) -+ OUT_RING (chan, NvSema); -+ else -+ OUT_RING (chan, chan->vram_handle); -+ } else { -+ BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4); -+ OUT_RING (chan, upper_32_bits(offset)); -+ OUT_RING (chan, lower_32_bits(offset)); -+ OUT_RING (chan, 0xf00d0000 | dispc->sem.value); -+ OUT_RING (chan, 0x1002); -+ BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4); -+ OUT_RING (chan, upper_32_bits(offset)); -+ OUT_RING (chan, lower_32_bits(offset ^ 0x10)); -+ OUT_RING (chan, 0x74b1e000); -+ OUT_RING (chan, 0x1001); -+ } -+ FIRE_RING (chan); -+ } else { -+ nouveau_bo_wr32(dispc->sem.bo, dispc->sem.offset / 4, -+ 0xf00d0000 | dispc->sem.value); -+ } -+ -+ /* queue the flip on the crtc's "display sync" channel */ -+ BEGIN_RING(evo, 0, 0x0100, 1); -+ OUT_RING (evo, 0xfffe0000); -+ BEGIN_RING(evo, 0, 0x0084, 5); -+ OUT_RING (evo, chan ? 0x00000100 : 0x00000010); -+ OUT_RING (evo, dispc->sem.offset); -+ OUT_RING (evo, 0xf00d0000 | dispc->sem.value); -+ OUT_RING (evo, 0x74b1e000); -+ OUT_RING (evo, NvEvoSync); -+ BEGIN_RING(evo, 0, 0x00a0, 2); -+ OUT_RING (evo, 0x00000000); -+ OUT_RING (evo, 0x00000000); -+ BEGIN_RING(evo, 0, 0x00c0, 1); -+ OUT_RING (evo, nv_fb->r_dma); -+ BEGIN_RING(evo, 0, 0x0110, 2); -+ OUT_RING (evo, 0x00000000); -+ OUT_RING (evo, 0x00000000); -+ BEGIN_RING(evo, 0, 0x0800, 5); -+ OUT_RING (evo, (nv_fb->nvbo->bo.mem.start << PAGE_SHIFT) >> 8); -+ OUT_RING (evo, 0); -+ OUT_RING (evo, (fb->height << 16) | fb->width); -+ OUT_RING (evo, nv_fb->r_pitch); -+ OUT_RING (evo, nv_fb->r_format); -+ BEGIN_RING(evo, 0, 0x0080, 1); -+ OUT_RING (evo, 0x00000000); -+ FIRE_RING (evo); -+ -+ dispc->sem.offset ^= 0x10; -+ dispc->sem.value++; -+ return 0; - } - - static u16 -@@ -383,13 +517,25 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb, - if (bios->fp.if_is_24bit) - script |= 0x0200; - } else { -+ /* determine number of lvds links */ -+ if (nv_connector && nv_connector->edid && -+ nv_connector->dcb->type == DCB_CONNECTOR_LVDS_SPWG) { -+ /* http://www.spwg.org */ -+ if (((u8 *)nv_connector->edid)[121] == 2) -+ script |= 0x0100; -+ } else - if (pxclk >= bios->fp.duallink_transition_clk) { - script |= 0x0100; -+ } -+ -+ /* determine panel depth */ -+ if (script & 0x0100) { - if (bios->fp.strapless_is_24bit & 2) - script |= 0x0200; -- } else -- if (bios->fp.strapless_is_24bit & 1) -- script |= 0x0200; -+ } else { -+ if (bios->fp.strapless_is_24bit & 1) -+ script |= 0x0200; -+ } - - if (nv_connector && nv_connector->edid && - (nv_connector->edid->revision >= 4) && -@@ -466,11 +612,12 @@ static void - nv50_display_unk10_handler(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nv50_display *disp = nv50_display(dev); - u32 unk30 = nv_rd32(dev, 0x610030), mc; - int i, crtc, or, type = OUTPUT_ANY; - - NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); -- dev_priv->evo_irq.dcb = NULL; -+ disp->irq.dcb = NULL; - - nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8); - -@@ -541,7 +688,7 @@ nv50_display_unk10_handler(struct drm_device *dev) - - if (dcb->type == type && (dcb->or & (1 << or))) { - nouveau_bios_run_display_table(dev, dcb, 0, -1); -- dev_priv->evo_irq.dcb = dcb; -+ disp->irq.dcb = dcb; - goto ack; - } - } -@@ -587,15 +734,16 @@ static void - nv50_display_unk20_handler(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -- u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc; -+ struct nv50_display *disp = nv50_display(dev); -+ u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc = 0; - struct dcb_entry *dcb; - int i, crtc, or, type = OUTPUT_ANY; - - NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); -- dcb = dev_priv->evo_irq.dcb; -+ dcb = disp->irq.dcb; - if (dcb) { - nouveau_bios_run_display_table(dev, dcb, 0, -2); -- dev_priv->evo_irq.dcb = NULL; -+ disp->irq.dcb = NULL; - } - - /* CRTC clock change requested? */ -@@ -692,9 +840,9 @@ 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; -+ disp->irq.dcb = dcb; -+ disp->irq.pclk = pclk; -+ disp->irq.script = script; - - ack: - nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20); -@@ -735,13 +883,13 @@ nv50_display_unk40_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb) - static void - nv50_display_unk40_handler(struct drm_device *dev) - { -- 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; -+ struct nv50_display *disp = nv50_display(dev); -+ struct dcb_entry *dcb = disp->irq.dcb; -+ u16 script = disp->irq.script; -+ u32 unk30 = nv_rd32(dev, 0x610030), pclk = disp->irq.pclk; - - NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); -- dev_priv->evo_irq.dcb = NULL; -+ disp->irq.dcb = NULL; - if (!dcb) - goto ack; - -@@ -754,12 +902,10 @@ ack: - nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) | 8); - } - --void --nv50_display_irq_handler_bh(struct work_struct *work) -+static void -+nv50_display_bh(unsigned long data) - { -- struct drm_nouveau_private *dev_priv = -- container_of(work, struct drm_nouveau_private, irq_work); -- struct drm_device *dev = dev_priv->dev; -+ struct drm_device *dev = (struct drm_device *)data; - - for (;;) { - uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); -@@ -807,7 +953,7 @@ nv50_display_error_handler(struct drm_device *dev) - static void - nv50_display_isr(struct drm_device *dev) - { -- struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nv50_display *disp = nv50_display(dev); - uint32_t delayed = 0; - - while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) { -@@ -835,8 +981,7 @@ nv50_display_isr(struct drm_device *dev) - NV50_PDISPLAY_INTR_1_CLK_UNK40)); - if (clock) { - nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); -- if (!work_pending(&dev_priv->irq_work)) -- queue_work(dev_priv->wq, &dev_priv->irq_work); -+ tasklet_schedule(&disp->tasklet); - delayed |= clock; - intr1 &= ~clock; - } -diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h -index f0e30b78..c2da503 100644 ---- a/drivers/gpu/drm/nouveau/nv50_display.h -+++ b/drivers/gpu/drm/nouveau/nv50_display.h -@@ -35,7 +35,36 @@ - #include "nouveau_crtc.h" - #include "nv50_evo.h" - --void nv50_display_irq_handler_bh(struct work_struct *work); -+struct nv50_display_crtc { -+ struct nouveau_channel *sync; -+ struct { -+ struct nouveau_bo *bo; -+ u32 offset; -+ u16 value; -+ } sem; -+}; -+ -+struct nv50_display { -+ struct nouveau_channel *master; -+ struct nouveau_gpuobj *ntfy; -+ -+ struct nv50_display_crtc crtc[2]; -+ -+ struct tasklet_struct tasklet; -+ struct { -+ struct dcb_entry *dcb; -+ u16 script; -+ u32 pclk; -+ } irq; -+}; -+ -+static inline struct nv50_display * -+nv50_display(struct drm_device *dev) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ return dev_priv->engine.display.priv; -+} -+ - 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); -@@ -44,4 +73,15 @@ 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); - -+int nv50_display_flip_next(struct drm_crtc *, struct drm_framebuffer *, -+ struct nouveau_channel *chan); -+void nv50_display_flip_stop(struct drm_crtc *); -+ -+int nv50_evo_init(struct drm_device *dev); -+void nv50_evo_fini(struct drm_device *dev); -+void nv50_evo_dmaobj_init(struct nouveau_gpuobj *, u32 memtype, u64 base, -+ u64 size); -+int nv50_evo_dmaobj_new(struct nouveau_channel *, u32 handle, u32 memtype, -+ u64 base, u64 size, struct nouveau_gpuobj **); -+ - #endif /* __NV50_DISPLAY_H__ */ -diff --git a/drivers/gpu/drm/nouveau/nv50_evo.c b/drivers/gpu/drm/nouveau/nv50_evo.c -index 0ea090f..c8e83c1 100644 ---- a/drivers/gpu/drm/nouveau/nv50_evo.c -+++ b/drivers/gpu/drm/nouveau/nv50_evo.c -@@ -27,20 +27,17 @@ - #include "nouveau_drv.h" - #include "nouveau_dma.h" - #include "nouveau_ramht.h" -+#include "nv50_display.h" - - static void - nv50_evo_channel_del(struct nouveau_channel **pevo) - { -- struct drm_nouveau_private *dev_priv; - struct nouveau_channel *evo = *pevo; - - if (!evo) - return; - *pevo = NULL; - -- dev_priv = evo->dev->dev_private; -- dev_priv->evo_alloc &= ~(1 << evo->id); -- - nouveau_gpuobj_channel_takedown(evo); - nouveau_bo_unmap(evo->pushbuf_bo); - nouveau_bo_ref(NULL, &evo->pushbuf_bo); -@@ -51,42 +48,61 @@ nv50_evo_channel_del(struct nouveau_channel **pevo) - kfree(evo); - } - -+void -+nv50_evo_dmaobj_init(struct nouveau_gpuobj *obj, u32 memtype, u64 base, u64 size) -+{ -+ struct drm_nouveau_private *dev_priv = obj->dev->dev_private; -+ u32 flags5; -+ -+ if (dev_priv->chipset < 0xc0) { -+ /* not supported on 0x50, specified in format mthd */ -+ if (dev_priv->chipset == 0x50) -+ memtype = 0; -+ flags5 = 0x00010000; -+ } else { -+ if (memtype & 0x80000000) -+ flags5 = 0x00000000; /* large pages */ -+ else -+ flags5 = 0x00020000; -+ } -+ -+ nv50_gpuobj_dma_init(obj, 0, 0x3d, base, size, NV_MEM_TARGET_VRAM, -+ NV_MEM_ACCESS_RW, (memtype >> 8) & 0xff, 0); -+ nv_wo32(obj, 0x14, flags5); -+ dev_priv->engine.instmem.flush(obj->dev); -+} -+ - int --nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 class, u32 name, -- u32 tile_flags, u32 magic_flags, u32 offset, u32 limit, -- u32 flags5) -+nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 handle, u32 memtype, -+ u64 base, u64 size, struct nouveau_gpuobj **pobj) - { -- struct drm_nouveau_private *dev_priv = evo->dev->dev_private; -- struct drm_device *dev = evo->dev; -+ struct nv50_display *disp = nv50_display(evo->dev); - struct nouveau_gpuobj *obj = NULL; - int ret; - -- ret = nouveau_gpuobj_new(dev, dev_priv->evo, 6*4, 32, 0, &obj); -+ ret = nouveau_gpuobj_new(evo->dev, disp->master, 6*4, 32, 0, &obj); - if (ret) - return ret; - obj->engine = NVOBJ_ENGINE_DISPLAY; - -- 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); -- nv_wo32(obj, 20, flags5); -- dev_priv->engine.instmem.flush(dev); -+ nv50_evo_dmaobj_init(obj, memtype, base, size); - -- ret = nouveau_ramht_insert(evo, name, obj); -- nouveau_gpuobj_ref(NULL, &obj); -- if (ret) { -- return ret; -- } -+ ret = nouveau_ramht_insert(evo, handle, obj); -+ if (ret) -+ goto out; - -- return 0; -+ if (pobj) -+ nouveau_gpuobj_ref(obj, pobj); -+out: -+ nouveau_gpuobj_ref(NULL, &obj); -+ return ret; - } - - static int --nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pevo) -+nv50_evo_channel_new(struct drm_device *dev, int chid, -+ struct nouveau_channel **pevo) - { -- struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nv50_display *disp = nv50_display(dev); - struct nouveau_channel *evo; - int ret; - -@@ -95,25 +111,13 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pevo) - return -ENOMEM; - *pevo = evo; - -- for (evo->id = 0; evo->id < 5; evo->id++) { -- if (dev_priv->evo_alloc & (1 << evo->id)) -- continue; -- -- dev_priv->evo_alloc |= (1 << evo->id); -- break; -- } -- -- if (evo->id == 5) { -- kfree(evo); -- return -ENODEV; -- } -- -+ evo->id = chid; - evo->dev = dev; - evo->user_get = 4; - evo->user_put = 0; - - ret = nouveau_bo_new(dev, NULL, 4096, 0, TTM_PL_FLAG_VRAM, 0, 0, -- false, true, &evo->pushbuf_bo); -+ &evo->pushbuf_bo); - if (ret == 0) - ret = nouveau_bo_pin(evo->pushbuf_bo, TTM_PL_FLAG_VRAM); - if (ret) { -@@ -138,8 +142,8 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pevo) - } - - /* bind primary evo channel's ramht to the channel */ -- if (dev_priv->evo && evo != dev_priv->evo) -- nouveau_ramht_ref(dev_priv->evo->ramht, &evo->ramht, NULL); -+ if (disp->master && evo != disp->master) -+ nouveau_ramht_ref(disp->master->ramht, &evo->ramht, NULL); - - return 0; - } -@@ -182,6 +186,7 @@ nv50_evo_channel_init(struct nouveau_channel *evo) - nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << id); - - 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; -@@ -212,21 +217,39 @@ nv50_evo_channel_fini(struct nouveau_channel *evo) - } - } - -+static void -+nv50_evo_destroy(struct drm_device *dev) -+{ -+ struct nv50_display *disp = nv50_display(dev); -+ int i; -+ -+ for (i = 0; i < 2; i++) { -+ if (disp->crtc[i].sem.bo) { -+ nouveau_bo_unmap(disp->crtc[i].sem.bo); -+ nouveau_bo_ref(NULL, &disp->crtc[i].sem.bo); -+ } -+ nv50_evo_channel_del(&disp->crtc[i].sync); -+ } -+ nouveau_gpuobj_ref(NULL, &disp->ntfy); -+ nv50_evo_channel_del(&disp->master); -+} -+ - static int - nv50_evo_create(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nv50_display *disp = nv50_display(dev); - struct nouveau_gpuobj *ramht = NULL; - struct nouveau_channel *evo; -- int ret; -+ int ret, i, j; - - /* create primary evo channel, the one we use for modesetting - * purporses - */ -- ret = nv50_evo_channel_new(dev, &dev_priv->evo); -+ ret = nv50_evo_channel_new(dev, 0, &disp->master); - if (ret) - return ret; -- evo = dev_priv->evo; -+ evo = disp->master; - - /* setup object management on it, any other evo channel will - * use this also as there's no per-channel support on the -@@ -236,109 +259,167 @@ nv50_evo_create(struct drm_device *dev) - NVOBJ_FLAG_ZERO_ALLOC, &evo->ramin); - if (ret) { - NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret); -- nv50_evo_channel_del(&dev_priv->evo); -- return ret; -+ goto err; - } - - ret = drm_mm_init(&evo->ramin_heap, 0, 32768); - if (ret) { - NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret); -- nv50_evo_channel_del(&dev_priv->evo); -- return ret; -+ goto err; - } - - ret = nouveau_gpuobj_new(dev, evo, 4096, 16, 0, &ramht); - if (ret) { - NV_ERROR(dev, "Unable to allocate EVO RAMHT: %d\n", ret); -- nv50_evo_channel_del(&dev_priv->evo); -- return ret; -+ goto err; - } - - ret = nouveau_ramht_new(dev, ramht, &evo->ramht); - nouveau_gpuobj_ref(NULL, &ramht); -- if (ret) { -- nv50_evo_channel_del(&dev_priv->evo); -- return ret; -- } -+ if (ret) -+ goto err; -+ -+ /* not sure exactly what this is.. -+ * -+ * the first dword of the structure is used by nvidia to wait on -+ * full completion of an EVO "update" command. -+ * -+ * method 0x8c on the master evo channel will fill a lot more of -+ * this structure with some undefined info -+ */ -+ ret = nouveau_gpuobj_new(dev, disp->master, 0x1000, 0, -+ NVOBJ_FLAG_ZERO_ALLOC, &disp->ntfy); -+ if (ret) -+ goto err; -+ -+ ret = nv50_evo_dmaobj_new(disp->master, NvEvoSync, 0x0000, -+ disp->ntfy->vinst, disp->ntfy->size, NULL); -+ if (ret) -+ goto err; - - /* create some default objects for the scanout memtypes we support */ -- if (dev_priv->card_type >= NV_C0) { -- ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB32, 0xfe, 0x19, -- 0, 0xffffffff, 0x00000000); -- if (ret) { -- nv50_evo_channel_del(&dev_priv->evo); -- return ret; -- } -+ ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM, 0x0000, -+ 0, dev_priv->vram_size, NULL); -+ if (ret) -+ goto err; - -- ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM, 0, 0x19, -- 0, dev_priv->vram_size, 0x00020000); -- if (ret) { -- nv50_evo_channel_del(&dev_priv->evo); -- return ret; -- } -+ ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM_LP, 0x80000000, -+ 0, dev_priv->vram_size, NULL); -+ if (ret) -+ goto err; - -- ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM_LP, 0, 0x19, -- 0, dev_priv->vram_size, 0x00000000); -- if (ret) { -- nv50_evo_channel_del(&dev_priv->evo); -- return ret; -- } -- } else { -- ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB16, 0x70, 0x19, -- 0, 0xffffffff, 0x00010000); -- if (ret) { -- nv50_evo_channel_del(&dev_priv->evo); -- return ret; -- } -+ ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB32, 0x80000000 | -+ (dev_priv->chipset < 0xc0 ? 0x7a00 : 0xfe00), -+ 0, dev_priv->vram_size, NULL); -+ if (ret) -+ goto err; - -+ ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB16, 0x80000000 | -+ (dev_priv->chipset < 0xc0 ? 0x7000 : 0xfe00), -+ 0, dev_priv->vram_size, NULL); -+ if (ret) -+ goto err; - -- ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB32, 0x7a, 0x19, -- 0, 0xffffffff, 0x00010000); -- if (ret) { -- nv50_evo_channel_del(&dev_priv->evo); -- return ret; -- } -+ /* create "display sync" channels and other structures we need -+ * to implement page flipping -+ */ -+ for (i = 0; i < 2; i++) { -+ struct nv50_display_crtc *dispc = &disp->crtc[i]; -+ u64 offset; - -- ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM, 0, 0x19, -- 0, dev_priv->vram_size, 0x00010000); -- if (ret) { -- nv50_evo_channel_del(&dev_priv->evo); -- return ret; -+ ret = nv50_evo_channel_new(dev, 1 + i, &dispc->sync); -+ if (ret) -+ goto err; -+ -+ ret = nouveau_bo_new(dev, NULL, 4096, 0x1000, TTM_PL_FLAG_VRAM, -+ 0, 0x0000, &dispc->sem.bo); -+ if (!ret) { -+ offset = dispc->sem.bo->bo.mem.start << PAGE_SHIFT; -+ -+ ret = nouveau_bo_pin(dispc->sem.bo, TTM_PL_FLAG_VRAM); -+ if (!ret) -+ ret = nouveau_bo_map(dispc->sem.bo); -+ if (ret) -+ nouveau_bo_ref(NULL, &dispc->sem.bo); - } - -- ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM_LP, 0, 0x19, -- 0, dev_priv->vram_size, 0x00010000); -- if (ret) { -- nv50_evo_channel_del(&dev_priv->evo); -- return ret; -- } -+ if (ret) -+ goto err; -+ -+ ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoSync, 0x0000, -+ offset, 4096, NULL); -+ if (ret) -+ goto err; -+ -+ ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoVRAM_LP, 0x80000000, -+ 0, dev_priv->vram_size, NULL); -+ if (ret) -+ goto err; -+ -+ ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB32, 0x80000000 | -+ (dev_priv->chipset < 0xc0 ? -+ 0x7a00 : 0xfe00), -+ 0, dev_priv->vram_size, NULL); -+ if (ret) -+ goto err; -+ -+ ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB16, 0x80000000 | -+ (dev_priv->chipset < 0xc0 ? -+ 0x7000 : 0xfe00), -+ 0, dev_priv->vram_size, NULL); -+ if (ret) -+ goto err; -+ -+ for (j = 0; j < 4096; j += 4) -+ nouveau_bo_wr32(dispc->sem.bo, j / 4, 0x74b1e000); -+ dispc->sem.offset = 0; - } - - return 0; -+ -+err: -+ nv50_evo_destroy(dev); -+ return ret; - } - - int - nv50_evo_init(struct drm_device *dev) - { -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- int ret; -+ struct nv50_display *disp = nv50_display(dev); -+ int ret, i; - -- if (!dev_priv->evo) { -+ if (!disp->master) { - ret = nv50_evo_create(dev); - if (ret) - return ret; - } - -- return nv50_evo_channel_init(dev_priv->evo); -+ ret = nv50_evo_channel_init(disp->master); -+ if (ret) -+ return ret; -+ -+ for (i = 0; i < 2; i++) { -+ ret = nv50_evo_channel_init(disp->crtc[i].sync); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; - } - - void - nv50_evo_fini(struct drm_device *dev) - { -- struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nv50_display *disp = nv50_display(dev); -+ int i; - -- if (dev_priv->evo) { -- nv50_evo_channel_fini(dev_priv->evo); -- nv50_evo_channel_del(&dev_priv->evo); -+ for (i = 0; i < 2; i++) { -+ if (disp->crtc[i].sync) -+ nv50_evo_channel_fini(disp->crtc[i].sync); - } -+ -+ if (disp->master) -+ nv50_evo_channel_fini(disp->master); -+ -+ nv50_evo_destroy(dev); - } -diff --git a/drivers/gpu/drm/nouveau/nv50_evo.h b/drivers/gpu/drm/nouveau/nv50_evo.h -index aa4f0d3..3860ca6 100644 ---- a/drivers/gpu/drm/nouveau/nv50_evo.h -+++ b/drivers/gpu/drm/nouveau/nv50_evo.h -@@ -27,12 +27,6 @@ - #ifndef __NV50_EVO_H__ - #define __NV50_EVO_H__ - --int nv50_evo_init(struct drm_device *dev); --void nv50_evo_fini(struct drm_device *dev); --int nv50_evo_dmaobj_new(struct nouveau_channel *, u32 class, u32 name, -- u32 tile_flags, u32 magic_flags, -- u32 offset, u32 limit); -- - #define NV50_EVO_UPDATE 0x00000080 - #define NV50_EVO_UNK84 0x00000084 - #define NV50_EVO_UNK84_NOTIFY 0x40000000 -@@ -119,5 +113,7 @@ int nv50_evo_dmaobj_new(struct nouveau_channel *, u32 class, u32 name, - /* Both of these are needed, otherwise nothing happens. */ - #define NV50_EVO_CRTC_SCALE_RES1 0x000008d8 - #define NV50_EVO_CRTC_SCALE_RES2 0x000008dc -+#define NV50_EVO_CRTC_UNK900 0x00000900 -+#define NV50_EVO_CRTC_UNK904 0x00000904 - - #endif -diff --git a/drivers/gpu/drm/nouveau/nv50_fb.c b/drivers/gpu/drm/nouveau/nv50_fb.c -index 50290de..ddebd71 100644 ---- a/drivers/gpu/drm/nouveau/nv50_fb.c -+++ b/drivers/gpu/drm/nouveau/nv50_fb.c -@@ -8,31 +8,61 @@ struct nv50_fb_priv { - dma_addr_t r100c08; - }; - -+static void -+nv50_fb_destroy(struct drm_device *dev) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; -+ struct nv50_fb_priv *priv = pfb->priv; -+ -+ if (pfb->tag_heap.free_stack.next) -+ drm_mm_takedown(&pfb->tag_heap); -+ -+ if (priv->r100c08_page) { -+ pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE, -+ PCI_DMA_BIDIRECTIONAL); -+ __free_page(priv->r100c08_page); -+ } -+ -+ kfree(priv); -+ pfb->priv = NULL; -+} -+ - static int - nv50_fb_create(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - struct nv50_fb_priv *priv; -+ u32 tagmem; -+ int ret; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; -+ pfb->priv = priv; - - priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO); - if (!priv->r100c08_page) { -- kfree(priv); -+ nv50_fb_destroy(dev); - return -ENOMEM; - } - - priv->r100c08 = pci_map_page(dev->pdev, priv->r100c08_page, 0, - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(dev->pdev, priv->r100c08)) { -- __free_page(priv->r100c08_page); -- kfree(priv); -+ nv50_fb_destroy(dev); - return -EFAULT; - } - -- dev_priv->engine.fb.priv = priv; -+ tagmem = nv_rd32(dev, 0x100320); -+ NV_DEBUG(dev, "%d tags available\n", tagmem); -+ ret = drm_mm_init(&pfb->tag_heap, 0, tagmem); -+ if (ret) { -+ nv50_fb_destroy(dev); -+ return ret; -+ } -+ - return 0; - } - -@@ -81,26 +111,112 @@ nv50_fb_init(struct drm_device *dev) - void - nv50_fb_takedown(struct drm_device *dev) - { -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nv50_fb_priv *priv; -+ nv50_fb_destroy(dev); -+} - -- priv = dev_priv->engine.fb.priv; -- if (!priv) -- return; -- dev_priv->engine.fb.priv = NULL; -+static struct nouveau_enum vm_dispatch_subclients[] = { -+ { 0x00000000, "GRCTX", NULL }, -+ { 0x00000001, "NOTIFY", NULL }, -+ { 0x00000002, "QUERY", NULL }, -+ { 0x00000003, "COND", NULL }, -+ { 0x00000004, "M2M_IN", NULL }, -+ { 0x00000005, "M2M_OUT", NULL }, -+ { 0x00000006, "M2M_NOTIFY", NULL }, -+ {} -+}; - -- pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE, -- PCI_DMA_BIDIRECTIONAL); -- __free_page(priv->r100c08_page); -- kfree(priv); --} -+static struct nouveau_enum vm_ccache_subclients[] = { -+ { 0x00000000, "CB", NULL }, -+ { 0x00000001, "TIC", NULL }, -+ { 0x00000002, "TSC", NULL }, -+ {} -+}; -+ -+static struct nouveau_enum vm_prop_subclients[] = { -+ { 0x00000000, "RT0", NULL }, -+ { 0x00000001, "RT1", NULL }, -+ { 0x00000002, "RT2", NULL }, -+ { 0x00000003, "RT3", NULL }, -+ { 0x00000004, "RT4", NULL }, -+ { 0x00000005, "RT5", NULL }, -+ { 0x00000006, "RT6", NULL }, -+ { 0x00000007, "RT7", NULL }, -+ { 0x00000008, "ZETA", NULL }, -+ { 0x00000009, "LOCAL", NULL }, -+ { 0x0000000a, "GLOBAL", NULL }, -+ { 0x0000000b, "STACK", NULL }, -+ { 0x0000000c, "DST2D", NULL }, -+ {} -+}; -+ -+static struct nouveau_enum vm_pfifo_subclients[] = { -+ { 0x00000000, "PUSHBUF", NULL }, -+ { 0x00000001, "SEMAPHORE", NULL }, -+ {} -+}; -+ -+static struct nouveau_enum vm_bar_subclients[] = { -+ { 0x00000000, "FB", NULL }, -+ { 0x00000001, "IN", NULL }, -+ {} -+}; -+ -+static struct nouveau_enum vm_client[] = { -+ { 0x00000000, "STRMOUT", NULL }, -+ { 0x00000003, "DISPATCH", vm_dispatch_subclients }, -+ { 0x00000004, "PFIFO_WRITE", NULL }, -+ { 0x00000005, "CCACHE", vm_ccache_subclients }, -+ { 0x00000006, "PPPP", NULL }, -+ { 0x00000007, "CLIPID", NULL }, -+ { 0x00000008, "PFIFO_READ", NULL }, -+ { 0x00000009, "VFETCH", NULL }, -+ { 0x0000000a, "TEXTURE", NULL }, -+ { 0x0000000b, "PROP", vm_prop_subclients }, -+ { 0x0000000c, "PVP", NULL }, -+ { 0x0000000d, "PBSP", NULL }, -+ { 0x0000000e, "PCRYPT", NULL }, -+ { 0x0000000f, "PCOUNTER", NULL }, -+ { 0x00000011, "PDAEMON", NULL }, -+ {} -+}; -+ -+static struct nouveau_enum vm_engine[] = { -+ { 0x00000000, "PGRAPH", NULL }, -+ { 0x00000001, "PVP", NULL }, -+ { 0x00000004, "PEEPHOLE", NULL }, -+ { 0x00000005, "PFIFO", vm_pfifo_subclients }, -+ { 0x00000006, "BAR", vm_bar_subclients }, -+ { 0x00000008, "PPPP", NULL }, -+ { 0x00000009, "PBSP", NULL }, -+ { 0x0000000a, "PCRYPT", NULL }, -+ { 0x0000000b, "PCOUNTER", NULL }, -+ { 0x0000000c, "SEMAPHORE_BG", NULL }, -+ { 0x0000000d, "PCOPY", NULL }, -+ { 0x0000000e, "PDAEMON", NULL }, -+ {} -+}; -+ -+static struct nouveau_enum vm_fault[] = { -+ { 0x00000000, "PT_NOT_PRESENT", NULL }, -+ { 0x00000001, "PT_TOO_SHORT", NULL }, -+ { 0x00000002, "PAGE_NOT_PRESENT", NULL }, -+ { 0x00000003, "PAGE_SYSTEM_ONLY", NULL }, -+ { 0x00000004, "PAGE_READ_ONLY", NULL }, -+ { 0x00000006, "NULL_DMAOBJ", NULL }, -+ { 0x00000007, "WRONG_MEMTYPE", NULL }, -+ { 0x0000000b, "VRAM_LIMIT", NULL }, -+ { 0x0000000f, "DMAOBJ_LIMIT", NULL }, -+ {} -+}; - - void --nv50_fb_vm_trap(struct drm_device *dev, int display, const char *name) -+nv50_fb_vm_trap(struct drm_device *dev, int display) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -+ const struct nouveau_enum *en, *cl; - unsigned long flags; - u32 trap[6], idx, chinst; -+ u8 st0, st1, st2, st3; - int i, ch; - - idx = nv_rd32(dev, 0x100c90); -@@ -117,8 +233,8 @@ nv50_fb_vm_trap(struct drm_device *dev, int display, const char *name) - if (!display) - return; - -+ /* lookup channel id */ - chinst = (trap[2] << 16) | trap[1]; -- - spin_lock_irqsave(&dev_priv->channels.lock, flags); - for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) { - struct nouveau_channel *chan = dev_priv->channels.ptr[ch]; -@@ -131,9 +247,48 @@ nv50_fb_vm_trap(struct drm_device *dev, int display, const char *name) - } - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - -- 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); -+ /* decode status bits into something more useful */ -+ if (dev_priv->chipset < 0xa3 || -+ dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) { -+ st0 = (trap[0] & 0x0000000f) >> 0; -+ st1 = (trap[0] & 0x000000f0) >> 4; -+ st2 = (trap[0] & 0x00000f00) >> 8; -+ st3 = (trap[0] & 0x0000f000) >> 12; -+ } else { -+ st0 = (trap[0] & 0x000000ff) >> 0; -+ st1 = (trap[0] & 0x0000ff00) >> 8; -+ st2 = (trap[0] & 0x00ff0000) >> 16; -+ st3 = (trap[0] & 0xff000000) >> 24; -+ } -+ -+ NV_INFO(dev, "VM: trapped %s at 0x%02x%04x%04x on ch %d [0x%08x] ", -+ (trap[5] & 0x00000100) ? "read" : "write", -+ trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, ch, chinst); -+ -+ en = nouveau_enum_find(vm_engine, st0); -+ if (en) -+ printk("%s/", en->name); -+ else -+ printk("%02x/", st0); -+ -+ cl = nouveau_enum_find(vm_client, st2); -+ if (cl) -+ printk("%s/", cl->name); -+ else -+ printk("%02x/", st2); -+ -+ if (cl && cl->data) cl = nouveau_enum_find(cl->data, st3); -+ else if (en && en->data) cl = nouveau_enum_find(en->data, st3); -+ else cl = NULL; -+ if (cl) -+ printk("%s", cl->name); -+ else -+ printk("%02x", st3); -+ -+ printk(" reason: "); -+ en = nouveau_enum_find(vm_fault, st1); -+ if (en) -+ printk("%s\n", en->name); -+ else -+ printk("0x%08x\n", st1); - } -diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c -index 8dd04c5..c34a074 100644 ---- a/drivers/gpu/drm/nouveau/nv50_fifo.c -+++ b/drivers/gpu/drm/nouveau/nv50_fifo.c -@@ -149,6 +149,7 @@ nv50_fifo_init_regs(struct drm_device *dev) - nv_wr32(dev, 0x3204, 0); - nv_wr32(dev, 0x3210, 0); - nv_wr32(dev, 0x3270, 0); -+ nv_wr32(dev, 0x2044, 0x01003fff); - - /* Enable dummy channels setup by nv50_instmem.c */ - nv50_fifo_channel_enable(dev, 0); -@@ -273,7 +274,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan) - 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, 0x44, 0x01003fff); - nv_wo32(ramfc, 0x60, 0x7fffffff); - nv_wo32(ramfc, 0x40, 0x00000000); - nv_wo32(ramfc, 0x7c, 0x30000001); -diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c -index 6b149c0..d4f4206 100644 ---- a/drivers/gpu/drm/nouveau/nv50_gpio.c -+++ b/drivers/gpu/drm/nouveau/nv50_gpio.c -@@ -137,6 +137,7 @@ nv50_gpio_irq_unregister(struct drm_device *dev, enum dcb_gpio_tag tag, - struct nv50_gpio_priv *priv = pgpio->priv; - struct nv50_gpio_handler *gpioh, *tmp; - struct dcb_gpio_entry *gpio; -+ LIST_HEAD(tofree); - unsigned long flags; - - gpio = nouveau_bios_gpio_entry(dev, tag); -@@ -149,10 +150,14 @@ nv50_gpio_irq_unregister(struct drm_device *dev, enum dcb_gpio_tag tag, - gpioh->handler != handler || - gpioh->data != data) - continue; -- list_del(&gpioh->head); -- kfree(gpioh); -+ list_move(&gpioh->head, &tofree); - } - spin_unlock_irqrestore(&priv->lock, flags); -+ -+ list_for_each_entry_safe(gpioh, tmp, &tofree, head) { -+ flush_work_sync(&gpioh->work); -+ kfree(gpioh); -+ } - } - - bool -@@ -205,7 +210,6 @@ nv50_gpio_init(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; -- struct nv50_gpio_priv *priv; - int ret; - - if (!pgpio->priv) { -@@ -213,7 +217,6 @@ nv50_gpio_init(struct drm_device *dev) - if (ret) - return ret; - } -- priv = pgpio->priv; - - /* disable, and ack any pending gpio interrupts */ - nv_wr32(dev, 0xe050, 0x00000000); -@@ -293,7 +296,7 @@ nv50_gpio_isr(struct drm_device *dev) - continue; - gpioh->inhibit = true; - -- queue_work(dev_priv->wq, &gpioh->work); -+ schedule_work(&gpioh->work); - } - spin_unlock(&priv->lock); - } -diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c -index 37e21d2..7950bac 100644 ---- a/drivers/gpu/drm/nouveau/nv50_graph.c -+++ b/drivers/gpu/drm/nouveau/nv50_graph.c -@@ -95,13 +95,41 @@ nv50_graph_init_regs__nv(struct drm_device *dev) - } - - static void --nv50_graph_init_regs(struct drm_device *dev) -+nv50_graph_init_zcull(struct drm_device *dev) - { -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ int i; -+ - NV_DEBUG(dev, "\n"); - -- nv_wr32(dev, NV04_PGRAPH_DEBUG_3, -- (1 << 2) /* HW_CONTEXT_SWITCH_ENABLED */); -- nv_wr32(dev, 0x402ca8, 0x800); -+ switch (dev_priv->chipset & 0xf0) { -+ case 0x50: -+ case 0x80: -+ case 0x90: -+ nv_wr32(dev, 0x402ca8, 0x00000800); -+ break; -+ case 0xa0: -+ default: -+ nv_wr32(dev, 0x402cc0, 0x00000000); -+ if (dev_priv->chipset == 0xa0 || -+ dev_priv->chipset == 0xaa || -+ dev_priv->chipset == 0xac) { -+ nv_wr32(dev, 0x402ca8, 0x00000802); -+ } else { -+ nv_wr32(dev, 0x402cc0, 0x00000000); -+ nv_wr32(dev, 0x402ca8, 0x00000002); -+ } -+ -+ break; -+ } -+ -+ /* zero out zcull regions */ -+ for (i = 0; i < 8; i++) { -+ nv_wr32(dev, 0x402c20 + (i * 8), 0x00000000); -+ nv_wr32(dev, 0x402c24 + (i * 8), 0x00000000); -+ nv_wr32(dev, 0x402c28 + (i * 8), 0x00000000); -+ nv_wr32(dev, 0x402c2c + (i * 8), 0x00000000); -+ } - } - - static int -@@ -136,6 +164,7 @@ nv50_graph_init_ctxctl(struct drm_device *dev) - } - kfree(cp); - -+ nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */ - nv_wr32(dev, 0x400320, 4); - nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); - nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, 0); -@@ -151,7 +180,7 @@ nv50_graph_init(struct drm_device *dev) - - nv50_graph_init_reset(dev); - nv50_graph_init_regs__nv(dev); -- nv50_graph_init_regs(dev); -+ nv50_graph_init_zcull(dev); - - ret = nv50_graph_init_ctxctl(dev); - if (ret) -@@ -409,12 +438,7 @@ static int - nv50_graph_nvsw_mthd_page_flip(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) - { -- struct nouveau_page_flip_state s; -- -- if (!nouveau_finish_page_flip(chan, &s)) { -- /* XXX - Do something here */ -- } -- -+ nouveau_finish_page_flip(chan, NULL); - return 0; - } - -@@ -479,7 +503,7 @@ nv50_graph_tlb_flush(struct drm_device *dev) - } - - void --nv86_graph_tlb_flush(struct drm_device *dev) -+nv84_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; -@@ -524,13 +548,12 @@ nv86_graph_tlb_flush(struct drm_device *dev) - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - } - --static struct nouveau_enum nv50_mp_exec_error_names[] = --{ -- { 3, "STACK_UNDERFLOW" }, -- { 4, "QUADON_ACTIVE" }, -- { 8, "TIMEOUT" }, -- { 0x10, "INVALID_OPCODE" }, -- { 0x40, "BREAKPOINT" }, -+static struct nouveau_enum nv50_mp_exec_error_names[] = { -+ { 3, "STACK_UNDERFLOW", NULL }, -+ { 4, "QUADON_ACTIVE", NULL }, -+ { 8, "TIMEOUT", NULL }, -+ { 0x10, "INVALID_OPCODE", NULL }, -+ { 0x40, "BREAKPOINT", NULL }, - {} - }; - -@@ -558,47 +581,47 @@ static struct nouveau_bitfield nv50_graph_trap_ccache[] = { - - /* There must be a *lot* of these. Will take some time to gather them up. */ - struct nouveau_enum nv50_data_error_names[] = { -- { 0x00000003, "INVALID_QUERY_OR_TEXTURE" }, -- { 0x00000004, "INVALID_VALUE" }, -- { 0x00000005, "INVALID_ENUM" }, -- { 0x00000008, "INVALID_OBJECT" }, -- { 0x00000009, "READ_ONLY_OBJECT" }, -- { 0x0000000a, "SUPERVISOR_OBJECT" }, -- { 0x0000000b, "INVALID_ADDRESS_ALIGNMENT" }, -- { 0x0000000c, "INVALID_BITFIELD" }, -- { 0x0000000d, "BEGIN_END_ACTIVE" }, -- { 0x0000000e, "SEMANTIC_COLOR_BACK_OVER_LIMIT" }, -- { 0x0000000f, "VIEWPORT_ID_NEEDS_GP" }, -- { 0x00000010, "RT_DOUBLE_BIND" }, -- { 0x00000011, "RT_TYPES_MISMATCH" }, -- { 0x00000012, "RT_LINEAR_WITH_ZETA" }, -- { 0x00000015, "FP_TOO_FEW_REGS" }, -- { 0x00000016, "ZETA_FORMAT_CSAA_MISMATCH" }, -- { 0x00000017, "RT_LINEAR_WITH_MSAA" }, -- { 0x00000018, "FP_INTERPOLANT_START_OVER_LIMIT" }, -- { 0x00000019, "SEMANTIC_LAYER_OVER_LIMIT" }, -- { 0x0000001a, "RT_INVALID_ALIGNMENT" }, -- { 0x0000001b, "SAMPLER_OVER_LIMIT" }, -- { 0x0000001c, "TEXTURE_OVER_LIMIT" }, -- { 0x0000001e, "GP_TOO_MANY_OUTPUTS" }, -- { 0x0000001f, "RT_BPP128_WITH_MS8" }, -- { 0x00000021, "Z_OUT_OF_BOUNDS" }, -- { 0x00000023, "XY_OUT_OF_BOUNDS" }, -- { 0x00000027, "CP_MORE_PARAMS_THAN_SHARED" }, -- { 0x00000028, "CP_NO_REG_SPACE_STRIPED" }, -- { 0x00000029, "CP_NO_REG_SPACE_PACKED" }, -- { 0x0000002a, "CP_NOT_ENOUGH_WARPS" }, -- { 0x0000002b, "CP_BLOCK_SIZE_MISMATCH" }, -- { 0x0000002c, "CP_NOT_ENOUGH_LOCAL_WARPS" }, -- { 0x0000002d, "CP_NOT_ENOUGH_STACK_WARPS" }, -- { 0x0000002e, "CP_NO_BLOCKDIM_LATCH" }, -- { 0x00000031, "ENG2D_FORMAT_MISMATCH" }, -- { 0x0000003f, "PRIMITIVE_ID_NEEDS_GP" }, -- { 0x00000044, "SEMANTIC_VIEWPORT_OVER_LIMIT" }, -- { 0x00000045, "SEMANTIC_COLOR_FRONT_OVER_LIMIT" }, -- { 0x00000046, "LAYER_ID_NEEDS_GP" }, -- { 0x00000047, "SEMANTIC_CLIP_OVER_LIMIT" }, -- { 0x00000048, "SEMANTIC_PTSZ_OVER_LIMIT" }, -+ { 0x00000003, "INVALID_QUERY_OR_TEXTURE", NULL }, -+ { 0x00000004, "INVALID_VALUE", NULL }, -+ { 0x00000005, "INVALID_ENUM", NULL }, -+ { 0x00000008, "INVALID_OBJECT", NULL }, -+ { 0x00000009, "READ_ONLY_OBJECT", NULL }, -+ { 0x0000000a, "SUPERVISOR_OBJECT", NULL }, -+ { 0x0000000b, "INVALID_ADDRESS_ALIGNMENT", NULL }, -+ { 0x0000000c, "INVALID_BITFIELD", NULL }, -+ { 0x0000000d, "BEGIN_END_ACTIVE", NULL }, -+ { 0x0000000e, "SEMANTIC_COLOR_BACK_OVER_LIMIT", NULL }, -+ { 0x0000000f, "VIEWPORT_ID_NEEDS_GP", NULL }, -+ { 0x00000010, "RT_DOUBLE_BIND", NULL }, -+ { 0x00000011, "RT_TYPES_MISMATCH", NULL }, -+ { 0x00000012, "RT_LINEAR_WITH_ZETA", NULL }, -+ { 0x00000015, "FP_TOO_FEW_REGS", NULL }, -+ { 0x00000016, "ZETA_FORMAT_CSAA_MISMATCH", NULL }, -+ { 0x00000017, "RT_LINEAR_WITH_MSAA", NULL }, -+ { 0x00000018, "FP_INTERPOLANT_START_OVER_LIMIT", NULL }, -+ { 0x00000019, "SEMANTIC_LAYER_OVER_LIMIT", NULL }, -+ { 0x0000001a, "RT_INVALID_ALIGNMENT", NULL }, -+ { 0x0000001b, "SAMPLER_OVER_LIMIT", NULL }, -+ { 0x0000001c, "TEXTURE_OVER_LIMIT", NULL }, -+ { 0x0000001e, "GP_TOO_MANY_OUTPUTS", NULL }, -+ { 0x0000001f, "RT_BPP128_WITH_MS8", NULL }, -+ { 0x00000021, "Z_OUT_OF_BOUNDS", NULL }, -+ { 0x00000023, "XY_OUT_OF_BOUNDS", NULL }, -+ { 0x00000027, "CP_MORE_PARAMS_THAN_SHARED", NULL }, -+ { 0x00000028, "CP_NO_REG_SPACE_STRIPED", NULL }, -+ { 0x00000029, "CP_NO_REG_SPACE_PACKED", NULL }, -+ { 0x0000002a, "CP_NOT_ENOUGH_WARPS", NULL }, -+ { 0x0000002b, "CP_BLOCK_SIZE_MISMATCH", NULL }, -+ { 0x0000002c, "CP_NOT_ENOUGH_LOCAL_WARPS", NULL }, -+ { 0x0000002d, "CP_NOT_ENOUGH_STACK_WARPS", NULL }, -+ { 0x0000002e, "CP_NO_BLOCKDIM_LATCH", NULL }, -+ { 0x00000031, "ENG2D_FORMAT_MISMATCH", NULL }, -+ { 0x0000003f, "PRIMITIVE_ID_NEEDS_GP", NULL }, -+ { 0x00000044, "SEMANTIC_VIEWPORT_OVER_LIMIT", NULL }, -+ { 0x00000045, "SEMANTIC_COLOR_FRONT_OVER_LIMIT", NULL }, -+ { 0x00000046, "LAYER_ID_NEEDS_GP", NULL }, -+ { 0x00000047, "SEMANTIC_CLIP_OVER_LIMIT", NULL }, -+ { 0x00000048, "SEMANTIC_PTSZ_OVER_LIMIT", NULL }, - {} - }; - -@@ -639,7 +662,7 @@ nv50_pgraph_mp_trap(struct drm_device *dev, int tpid, int display) - nv_rd32(dev, addr + 0x20); - pc = nv_rd32(dev, addr + 0x24); - oplow = nv_rd32(dev, addr + 0x70); -- ophigh= nv_rd32(dev, addr + 0x74); -+ ophigh = nv_rd32(dev, addr + 0x74); - NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - " - "TP %d MP %d: ", tpid, i); - nouveau_enum_print(nv50_mp_exec_error_names, status); -@@ -678,7 +701,6 @@ 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_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) -@@ -701,7 +723,6 @@ 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_fb_vm_trap(dev, display, name); - /* 2d engine destination */ - if (ustatus & 0x00000010) { - if (display) { -@@ -912,10 +933,10 @@ nv50_pgraph_trap_handler(struct drm_device *dev, u32 display, u64 inst, u32 chid - printk("\n"); - NV_INFO(dev, "PGRAPH - TRAP_CCACHE %08x %08x %08x %08x" - " %08x %08x %08x\n", -- nv_rd32(dev, 0x405800), nv_rd32(dev, 0x405804), -- nv_rd32(dev, 0x405808), nv_rd32(dev, 0x40580c), -- nv_rd32(dev, 0x405810), nv_rd32(dev, 0x405814), -- nv_rd32(dev, 0x40581c)); -+ nv_rd32(dev, 0x405000), nv_rd32(dev, 0x405004), -+ nv_rd32(dev, 0x405008), nv_rd32(dev, 0x40500c), -+ nv_rd32(dev, 0x405010), nv_rd32(dev, 0x405014), -+ nv_rd32(dev, 0x40501c)); - - } - -@@ -1044,6 +1065,7 @@ nv50_graph_isr(struct drm_device *dev) - NV_INFO(dev, "PGRAPH - ch %d (0x%010llx) subc %d " - "class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, inst, subc, class, mthd, data); -+ nv50_fb_vm_trap(dev, 1); - } - } - -diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c -index 336aab2..de9abff 100644 ---- a/drivers/gpu/drm/nouveau/nv50_grctx.c -+++ b/drivers/gpu/drm/nouveau/nv50_grctx.c -@@ -747,7 +747,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) - gr_def(ctx, offset + 0x64, 0x0000001f); - gr_def(ctx, offset + 0x68, 0x0000000f); - gr_def(ctx, offset + 0x6c, 0x0000000f); -- } else if(dev_priv->chipset < 0xa0) { -+ } else if (dev_priv->chipset < 0xa0) { - cp_ctx(ctx, offset + 0x50, 1); - cp_ctx(ctx, offset + 0x70, 1); - } else { -@@ -924,7 +924,7 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx) - 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 */ -@@ -1803,9 +1803,7 @@ nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx) - xf_emit(ctx, 1, 0); /* 1ff */ - xf_emit(ctx, 8, 0); /* 0? */ - xf_emit(ctx, 9, 0); /* ffffffff, 7ff */ -- } -- else -- { -+ } else { - xf_emit(ctx, 0xc, 0); /* RO */ - /* SEEK */ - xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */ -@@ -2836,7 +2834,7 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx) - 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) -+ if (dev_priv->chipset == 0x50) - xf_emit(ctx, 1, 0); /* ff */ - else - xf_emit(ctx, 3, 0); /* 1, 7, 3ff */ -diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c -index e57caa2..993ad3f 100644 ---- a/drivers/gpu/drm/nouveau/nv50_instmem.c -+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c -@@ -300,7 +300,7 @@ nv50_instmem_resume(struct drm_device *dev) - } - - struct nv50_gpuobj_node { -- struct nouveau_vram *vram; -+ struct nouveau_mem *vram; - struct nouveau_vma chan_vma; - u32 align; - }; -@@ -404,23 +404,25 @@ void - nv50_instmem_flush(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -+ unsigned long flags; - -- spin_lock(&dev_priv->ramin_lock); -+ spin_lock_irqsave(&dev_priv->vm_lock, flags); - nv_wr32(dev, 0x00330c, 0x00000001); - if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) - NV_ERROR(dev, "PRAMIN flush timeout\n"); -- spin_unlock(&dev_priv->ramin_lock); -+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); - } - - void - nv84_instmem_flush(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -+ unsigned long flags; - -- spin_lock(&dev_priv->ramin_lock); -+ spin_lock_irqsave(&dev_priv->vm_lock, flags); - nv_wr32(dev, 0x070000, 0x00000001); - if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) - NV_ERROR(dev, "PRAMIN flush timeout\n"); -- spin_unlock(&dev_priv->ramin_lock); -+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); - } - -diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c -index b4a5ecb..c25c593 100644 ---- a/drivers/gpu/drm/nouveau/nv50_sor.c -+++ b/drivers/gpu/drm/nouveau/nv50_sor.c -@@ -41,8 +41,7 @@ nv50_sor_disconnect(struct drm_encoder *encoder) - { - 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; -+ struct nouveau_channel *evo = nv50_display(dev)->master; - int ret; - - if (!nv_encoder->crtc) -@@ -184,8 +183,7 @@ static void - nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) - { -- struct drm_nouveau_private *dev_priv = encoder->dev->dev_private; -- struct nouveau_channel *evo = dev_priv->evo; -+ struct nouveau_channel *evo = nv50_display(encoder->dev)->master; - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc); -diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c -index 6144156..6c26944 100644 ---- a/drivers/gpu/drm/nouveau/nv50_vm.c -+++ b/drivers/gpu/drm/nouveau/nv50_vm.c -@@ -31,7 +31,6 @@ void - nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde, - struct nouveau_gpuobj *pgt[2]) - { -- struct drm_nouveau_private *dev_priv = pgd->dev->dev_private; - u64 phys = 0xdeadcafe00000000ULL; - u32 coverage = 0; - -@@ -58,10 +57,9 @@ nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde, - } - - static inline u64 --nv50_vm_addr(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, -- u64 phys, u32 memtype, u32 target) -+nv50_vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target) - { -- struct drm_nouveau_private *dev_priv = pgt->dev->dev_private; -+ struct drm_nouveau_private *dev_priv = vma->vm->dev->dev_private; - - phys |= 1; /* present */ - phys |= (u64)memtype << 40; -@@ -85,12 +83,13 @@ nv50_vm_addr(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, - - void - nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, -- struct nouveau_vram *mem, u32 pte, u32 cnt, u64 phys) -+ struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) - { -+ u32 comp = (mem->memtype & 0x180) >> 7; - u32 block; - int i; - -- phys = nv50_vm_addr(vma, pgt, phys, mem->memtype, 0); -+ phys = nv50_vm_addr(vma, phys, mem->memtype, 0); - pte <<= 3; - cnt <<= 3; - -@@ -107,6 +106,11 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, - - phys += block << (vma->node->type - 3); - cnt -= block; -+ if (comp) { -+ u32 tag = mem->tag->start + ((delta >> 16) * comp); -+ offset_h |= (tag << 17); -+ delta += block << (vma->node->type - 3); -+ } - - while (block) { - nv_wo32(pgt, pte + 0, offset_l); -@@ -119,11 +123,11 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, - - void - nv50_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, -- u32 pte, dma_addr_t *list, u32 cnt) -+ struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) - { - pte <<= 3; - while (cnt--) { -- u64 phys = nv50_vm_addr(vma, pgt, (u64)*list++, 0, 2); -+ u64 phys = nv50_vm_addr(vma, (u64)*list++, mem->memtype, 2); - nv_wo32(pgt, pte + 0, lower_32_bits(phys)); - nv_wo32(pgt, pte + 4, upper_32_bits(phys)); - pte += 8; -@@ -170,10 +174,11 @@ void - nv50_vm_flush_engine(struct drm_device *dev, int engine) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -+ unsigned long flags; - -- spin_lock(&dev_priv->ramin_lock); -+ spin_lock_irqsave(&dev_priv->vm_lock, flags); - nv_wr32(dev, 0x100c80, (engine << 16) | 1); - if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) - NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); -- spin_unlock(&dev_priv->ramin_lock); -+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); - } -diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c -index 58e98ad..ffbc3d8 100644 ---- a/drivers/gpu/drm/nouveau/nv50_vram.c -+++ b/drivers/gpu/drm/nouveau/nv50_vram.c -@@ -48,42 +48,49 @@ nv50_vram_flags_valid(struct drm_device *dev, u32 tile_flags) - } - - void --nv50_vram_del(struct drm_device *dev, struct nouveau_vram **pvram) -+nv50_vram_del(struct drm_device *dev, struct nouveau_mem **pmem) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; - struct ttm_mem_type_manager *man = &bdev->man[TTM_PL_VRAM]; - struct nouveau_mm *mm = man->priv; - struct nouveau_mm_node *this; -- struct nouveau_vram *vram; -+ struct nouveau_mem *mem; - -- vram = *pvram; -- *pvram = NULL; -- if (unlikely(vram == NULL)) -+ mem = *pmem; -+ *pmem = NULL; -+ if (unlikely(mem == NULL)) - return; - - mutex_lock(&mm->mutex); -- while (!list_empty(&vram->regions)) { -- this = list_first_entry(&vram->regions, struct nouveau_mm_node, rl_entry); -+ while (!list_empty(&mem->regions)) { -+ this = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry); - - list_del(&this->rl_entry); - nouveau_mm_put(mm, this); - } -+ -+ if (mem->tag) { -+ drm_mm_put_block(mem->tag); -+ mem->tag = NULL; -+ } - mutex_unlock(&mm->mutex); - -- kfree(vram); -+ kfree(mem); - } - - int - nv50_vram_new(struct drm_device *dev, u64 size, u32 align, u32 size_nc, -- u32 type, struct nouveau_vram **pvram) -+ u32 memtype, struct nouveau_mem **pmem) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; - struct ttm_mem_type_manager *man = &bdev->man[TTM_PL_VRAM]; - struct nouveau_mm *mm = man->priv; - struct nouveau_mm_node *r; -- struct nouveau_vram *vram; -+ struct nouveau_mem *mem; -+ int comp = (memtype & 0x300) >> 8; -+ int type = (memtype & 0x07f); - int ret; - - if (!types[type]) -@@ -92,32 +99,46 @@ nv50_vram_new(struct drm_device *dev, u64 size, u32 align, u32 size_nc, - align >>= 12; - size_nc >>= 12; - -- vram = kzalloc(sizeof(*vram), GFP_KERNEL); -- if (!vram) -+ mem = kzalloc(sizeof(*mem), GFP_KERNEL); -+ if (!mem) - return -ENOMEM; - -- INIT_LIST_HEAD(&vram->regions); -- vram->dev = dev_priv->dev; -- vram->memtype = type; -- vram->size = size; -- - mutex_lock(&mm->mutex); -+ if (comp) { -+ if (align == 16) { -+ struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; -+ int n = (size >> 4) * comp; -+ -+ mem->tag = drm_mm_search_free(&pfb->tag_heap, n, 0, 0); -+ if (mem->tag) -+ mem->tag = drm_mm_get_block(mem->tag, n, 0); -+ } -+ -+ if (unlikely(!mem->tag)) -+ comp = 0; -+ } -+ -+ INIT_LIST_HEAD(&mem->regions); -+ mem->dev = dev_priv->dev; -+ mem->memtype = (comp << 7) | type; -+ mem->size = size; -+ - do { - ret = nouveau_mm_get(mm, types[type], size, size_nc, align, &r); - if (ret) { - mutex_unlock(&mm->mutex); -- nv50_vram_del(dev, &vram); -+ nv50_vram_del(dev, &mem); - return ret; - } - -- list_add_tail(&r->rl_entry, &vram->regions); -+ list_add_tail(&r->rl_entry, &mem->regions); - size -= r->length; - } while (size); - mutex_unlock(&mm->mutex); - -- r = list_first_entry(&vram->regions, struct nouveau_mm_node, rl_entry); -- vram->offset = (u64)r->offset << 12; -- *pvram = vram; -+ r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry); -+ mem->offset = (u64)r->offset << 12; -+ *pmem = mem; - return 0; - } - -diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c -index ec18ae1..fabc7fd 100644 ---- a/drivers/gpu/drm/nouveau/nv84_crypt.c -+++ b/drivers/gpu/drm/nouveau/nv84_crypt.c -@@ -136,5 +136,5 @@ nv84_crypt_isr(struct drm_device *dev) - nv_wr32(dev, 0x102130, stat); - nv_wr32(dev, 0x10200c, 0x10); - -- nv50_fb_vm_trap(dev, show, "PCRYPT"); -+ nv50_fb_vm_trap(dev, show); - } -diff --git a/drivers/gpu/drm/nouveau/nva3_pm.c b/drivers/gpu/drm/nouveau/nva3_pm.c -index dbbafed..e4b2b9e 100644 ---- a/drivers/gpu/drm/nouveau/nva3_pm.c -+++ b/drivers/gpu/drm/nouveau/nva3_pm.c -@@ -27,32 +27,74 @@ - #include "nouveau_bios.h" - #include "nouveau_pm.h" - --/*XXX: boards using limits 0x40 need fixing, the register layout -- * is correct here, but, there's some other funny magic -- * that modifies things, so it's not likely we'll set/read -- * the correct timings yet.. working on it... -+/* This is actually a lot more complex than it appears here, but hopefully -+ * this should be able to deal with what the VBIOS leaves for us.. -+ * -+ * If not, well, I'll jump off that bridge when I come to it. - */ - - struct nva3_pm_state { -- struct pll_lims pll; -- int N, M, P; -+ enum pll_types type; -+ u32 src0; -+ u32 src1; -+ u32 ctrl; -+ u32 coef; -+ u32 old_pnm; -+ u32 new_pnm; -+ u32 new_div; - }; - -+static int -+nva3_pm_pll_offset(u32 id) -+{ -+ static const u32 pll_map[] = { -+ 0x00, PLL_CORE, -+ 0x01, PLL_SHADER, -+ 0x02, PLL_MEMORY, -+ 0x00, 0x00 -+ }; -+ const u32 *map = pll_map; -+ -+ while (map[1]) { -+ if (id == map[1]) -+ return map[0]; -+ map += 2; -+ } -+ -+ return -ENOENT; -+} -+ - int - nva3_pm_clock_get(struct drm_device *dev, u32 id) - { -+ u32 src0, src1, ctrl, coef; - struct pll_lims pll; -- int P, N, M, ret; -- u32 reg; -+ int ret, off; -+ int P, N, M; - - ret = get_pll_limits(dev, id, &pll); - if (ret) - return ret; - -- reg = nv_rd32(dev, pll.reg + 4); -- P = (reg & 0x003f0000) >> 16; -- N = (reg & 0x0000ff00) >> 8; -- M = (reg & 0x000000ff); -+ off = nva3_pm_pll_offset(id); -+ if (off < 0) -+ return off; -+ -+ src0 = nv_rd32(dev, 0x4120 + (off * 4)); -+ src1 = nv_rd32(dev, 0x4160 + (off * 4)); -+ ctrl = nv_rd32(dev, pll.reg + 0); -+ coef = nv_rd32(dev, pll.reg + 4); -+ NV_DEBUG(dev, "PLL %02x: 0x%08x 0x%08x 0x%08x 0x%08x\n", -+ id, src0, src1, ctrl, coef); -+ -+ if (ctrl & 0x00000008) { -+ u32 div = ((src1 & 0x003c0000) >> 18) + 1; -+ return (pll.refclk * 2) / div; -+ } -+ -+ P = (coef & 0x003f0000) >> 16; -+ N = (coef & 0x0000ff00) >> 8; -+ M = (coef & 0x000000ff); - return pll.refclk * N / M / P; - } - -@@ -60,36 +102,103 @@ void * - nva3_pm_clock_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl, - u32 id, int khz) - { -- struct nva3_pm_state *state; -- int dummy, ret; -+ struct nva3_pm_state *pll; -+ struct pll_lims limits; -+ int N, M, P, diff; -+ int ret, off; -+ -+ ret = get_pll_limits(dev, id, &limits); -+ if (ret < 0) -+ return (ret == -ENOENT) ? NULL : ERR_PTR(ret); -+ -+ off = nva3_pm_pll_offset(id); -+ if (id < 0) -+ return ERR_PTR(-EINVAL); - -- state = kzalloc(sizeof(*state), GFP_KERNEL); -- if (!state) -+ -+ pll = kzalloc(sizeof(*pll), GFP_KERNEL); -+ if (!pll) - return ERR_PTR(-ENOMEM); -+ pll->type = id; -+ pll->src0 = 0x004120 + (off * 4); -+ pll->src1 = 0x004160 + (off * 4); -+ pll->ctrl = limits.reg + 0; -+ pll->coef = limits.reg + 4; - -- ret = get_pll_limits(dev, id, &state->pll); -- if (ret < 0) { -- kfree(state); -- return (ret == -ENOENT) ? NULL : ERR_PTR(ret); -+ /* If target clock is within [-2, 3) MHz of a divisor, we'll -+ * use that instead of calculating MNP values -+ */ -+ pll->new_div = min((limits.refclk * 2) / (khz - 2999), 16); -+ if (pll->new_div) { -+ diff = khz - ((limits.refclk * 2) / pll->new_div); -+ if (diff < -2000 || diff >= 3000) -+ pll->new_div = 0; - } - -- ret = nv50_calc_pll2(dev, &state->pll, khz, &state->N, &dummy, -- &state->M, &state->P); -- if (ret < 0) { -- kfree(state); -- return ERR_PTR(ret); -+ if (!pll->new_div) { -+ ret = nva3_calc_pll(dev, &limits, khz, &N, NULL, &M, &P); -+ if (ret < 0) -+ return ERR_PTR(ret); -+ -+ pll->new_pnm = (P << 16) | (N << 8) | M; -+ pll->new_div = 2 - 1; -+ } else { -+ pll->new_pnm = 0; -+ pll->new_div--; - } - -- return state; -+ if ((nv_rd32(dev, pll->src1) & 0x00000101) != 0x00000101) -+ pll->old_pnm = nv_rd32(dev, pll->coef); -+ return pll; - } - - void - nva3_pm_clock_set(struct drm_device *dev, void *pre_state) - { -- struct nva3_pm_state *state = pre_state; -- u32 reg = state->pll.reg; -+ struct nva3_pm_state *pll = pre_state; -+ u32 ctrl = 0; -+ -+ /* For the memory clock, NVIDIA will build a "script" describing -+ * the reclocking process and ask PDAEMON to execute it. -+ */ -+ if (pll->type == PLL_MEMORY) { -+ nv_wr32(dev, 0x100210, 0); -+ nv_wr32(dev, 0x1002dc, 1); -+ nv_wr32(dev, 0x004018, 0x00001000); -+ ctrl = 0x18000100; -+ } -+ -+ if (pll->old_pnm || !pll->new_pnm) { -+ nv_mask(dev, pll->src1, 0x003c0101, 0x00000101 | -+ (pll->new_div << 18)); -+ nv_wr32(dev, pll->ctrl, 0x0001001d | ctrl); -+ nv_mask(dev, pll->ctrl, 0x00000001, 0x00000000); -+ } -+ -+ if (pll->new_pnm) { -+ nv_mask(dev, pll->src0, 0x00000101, 0x00000101); -+ nv_wr32(dev, pll->coef, pll->new_pnm); -+ nv_wr32(dev, pll->ctrl, 0x0001001d | ctrl); -+ nv_mask(dev, pll->ctrl, 0x00000010, 0x00000000); -+ nv_mask(dev, pll->ctrl, 0x00020010, 0x00020010); -+ nv_wr32(dev, pll->ctrl, 0x00010015 | ctrl); -+ nv_mask(dev, pll->src1, 0x00000100, 0x00000000); -+ nv_mask(dev, pll->src1, 0x00000001, 0x00000000); -+ if (pll->type == PLL_MEMORY) -+ nv_wr32(dev, 0x4018, 0x10005000); -+ } else { -+ nv_mask(dev, pll->ctrl, 0x00000001, 0x00000000); -+ nv_mask(dev, pll->src0, 0x00000100, 0x00000000); -+ nv_mask(dev, pll->src0, 0x00000001, 0x00000000); -+ if (pll->type == PLL_MEMORY) -+ nv_wr32(dev, 0x4018, 0x1000d000); -+ } -+ -+ if (pll->type == PLL_MEMORY) { -+ nv_wr32(dev, 0x1002dc, 0); -+ nv_wr32(dev, 0x100210, 0x80000000); -+ } - -- nv_wr32(dev, reg + 4, (state->P << 16) | (state->N << 8) | state->M); -- kfree(state); -+ kfree(pll); - } - -diff --git a/drivers/gpu/drm/nouveau/nvc0_fb.c b/drivers/gpu/drm/nouveau/nvc0_fb.c -index 26a9960..08e6b11 100644 ---- a/drivers/gpu/drm/nouveau/nvc0_fb.c -+++ b/drivers/gpu/drm/nouveau/nvc0_fb.c -@@ -1,5 +1,5 @@ - /* -- * Copyright 2010 Red Hat Inc. -+ * Copyright 2011 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"), -@@ -23,16 +23,80 @@ - */ - - #include "drmP.h" -- -+#include "drm.h" - #include "nouveau_drv.h" -+#include "nouveau_drm.h" -+ -+struct nvc0_fb_priv { -+ struct page *r100c10_page; -+ dma_addr_t r100c10; -+}; -+ -+static void -+nvc0_fb_destroy(struct drm_device *dev) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; -+ struct nvc0_fb_priv *priv = pfb->priv; -+ -+ if (priv->r100c10_page) { -+ pci_unmap_page(dev->pdev, priv->r100c10, PAGE_SIZE, -+ PCI_DMA_BIDIRECTIONAL); -+ __free_page(priv->r100c10_page); -+ } -+ -+ kfree(priv); -+ pfb->priv = NULL; -+} -+ -+static int -+nvc0_fb_create(struct drm_device *dev) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; -+ struct nvc0_fb_priv *priv; -+ -+ priv = kzalloc(sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ pfb->priv = priv; -+ -+ priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO); -+ if (!priv->r100c10_page) { -+ nvc0_fb_destroy(dev); -+ return -ENOMEM; -+ } -+ -+ priv->r100c10 = pci_map_page(dev->pdev, priv->r100c10_page, 0, -+ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); -+ if (pci_dma_mapping_error(dev->pdev, priv->r100c10)) { -+ nvc0_fb_destroy(dev); -+ return -EFAULT; -+ } -+ -+ return 0; -+} - - int - nvc0_fb_init(struct drm_device *dev) - { -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nvc0_fb_priv *priv; -+ int ret; -+ -+ if (!dev_priv->engine.fb.priv) { -+ ret = nvc0_fb_create(dev); -+ if (ret) -+ return ret; -+ } -+ priv = dev_priv->engine.fb.priv; -+ -+ nv_wr32(dev, 0x100c10, priv->r100c10 >> 8); - return 0; - } - - void - nvc0_fb_takedown(struct drm_device *dev) - { -+ nvc0_fb_destroy(dev); - } -diff --git a/drivers/gpu/drm/nouveau/nvc0_fifo.c b/drivers/gpu/drm/nouveau/nvc0_fifo.c -index e6f92c5..55a4245 100644 ---- a/drivers/gpu/drm/nouveau/nvc0_fifo.c -+++ b/drivers/gpu/drm/nouveau/nvc0_fifo.c -@@ -116,7 +116,7 @@ nvc0_fifo_create_context(struct nouveau_channel *chan) - - /* allocate vram for control regs, map into polling area */ - ret = nouveau_bo_new(dev, NULL, 0x1000, 0, TTM_PL_FLAG_VRAM, -- 0, 0, true, true, &fifoch->user); -+ 0, 0, &fifoch->user); - if (ret) - goto error; - -@@ -355,19 +355,57 @@ nvc0_fifo_init(struct drm_device *dev) - } - - struct nouveau_enum nvc0_fifo_fault_unit[] = { -- { 0, "PGRAPH" }, -- { 3, "PEEPHOLE" }, -- { 4, "BAR1" }, -- { 5, "BAR3" }, -- { 7, "PFIFO" }, -+ { 0x00, "PGRAPH" }, -+ { 0x03, "PEEPHOLE" }, -+ { 0x04, "BAR1" }, -+ { 0x05, "BAR3" }, -+ { 0x07, "PFIFO" }, -+ { 0x10, "PBSP" }, -+ { 0x11, "PPPP" }, -+ { 0x13, "PCOUNTER" }, -+ { 0x14, "PVP" }, -+ { 0x15, "PCOPY0" }, -+ { 0x16, "PCOPY1" }, -+ { 0x17, "PDAEMON" }, - {} - }; - - struct nouveau_enum nvc0_fifo_fault_reason[] = { -- { 0, "PT_NOT_PRESENT" }, -- { 1, "PT_TOO_SHORT" }, -- { 2, "PAGE_NOT_PRESENT" }, -- { 3, "VM_LIMIT_EXCEEDED" }, -+ { 0x00, "PT_NOT_PRESENT" }, -+ { 0x01, "PT_TOO_SHORT" }, -+ { 0x02, "PAGE_NOT_PRESENT" }, -+ { 0x03, "VM_LIMIT_EXCEEDED" }, -+ { 0x04, "NO_CHANNEL" }, -+ { 0x05, "PAGE_SYSTEM_ONLY" }, -+ { 0x06, "PAGE_READ_ONLY" }, -+ { 0x0a, "COMPRESSED_SYSRAM" }, -+ { 0x0c, "INVALID_STORAGE_TYPE" }, -+ {} -+}; -+ -+struct nouveau_enum nvc0_fifo_fault_hubclient[] = { -+ { 0x01, "PCOPY0" }, -+ { 0x02, "PCOPY1" }, -+ { 0x04, "DISPATCH" }, -+ { 0x05, "CTXCTL" }, -+ { 0x06, "PFIFO" }, -+ { 0x07, "BAR_READ" }, -+ { 0x08, "BAR_WRITE" }, -+ { 0x0b, "PVP" }, -+ { 0x0c, "PPPP" }, -+ { 0x0d, "PBSP" }, -+ { 0x11, "PCOUNTER" }, -+ { 0x12, "PDAEMON" }, -+ { 0x14, "CCACHE" }, -+ { 0x15, "CCACHE_POST" }, -+ {} -+}; -+ -+struct nouveau_enum nvc0_fifo_fault_gpcclient[] = { -+ { 0x01, "TEX" }, -+ { 0x0c, "ESETUP" }, -+ { 0x0e, "CTXCTL" }, -+ { 0x0f, "PROP" }, - {} - }; - -@@ -385,12 +423,20 @@ nvc0_fifo_isr_vm_fault(struct drm_device *dev, int unit) - u32 valo = nv_rd32(dev, 0x2804 + (unit * 0x10)); - u32 vahi = nv_rd32(dev, 0x2808 + (unit * 0x10)); - u32 stat = nv_rd32(dev, 0x280c + (unit * 0x10)); -+ u32 client = (stat & 0x00001f00) >> 8; - - NV_INFO(dev, "PFIFO: %s fault at 0x%010llx [", - (stat & 0x00000080) ? "write" : "read", (u64)vahi << 32 | valo); - nouveau_enum_print(nvc0_fifo_fault_reason, stat & 0x0000000f); - printk("] from "); - nouveau_enum_print(nvc0_fifo_fault_unit, unit); -+ if (stat & 0x00000040) { -+ printk("/"); -+ nouveau_enum_print(nvc0_fifo_fault_hubclient, client); -+ } else { -+ printk("/GPC%d/", (stat & 0x1f000000) >> 24); -+ nouveau_enum_print(nvc0_fifo_fault_gpcclient, client); -+ } - printk(" on channel 0x%010llx\n", (u64)inst << 12); - } - -@@ -418,6 +464,12 @@ nvc0_fifo_isr(struct drm_device *dev) - { - u32 stat = nv_rd32(dev, 0x002100); - -+ if (stat & 0x00000100) { -+ NV_INFO(dev, "PFIFO: unknown status 0x00000100\n"); -+ nv_wr32(dev, 0x002100, 0x00000100); -+ stat &= ~0x00000100; -+ } -+ - if (stat & 0x10000000) { - u32 units = nv_rd32(dev, 0x00259c); - u32 u = units; -@@ -446,10 +498,15 @@ nvc0_fifo_isr(struct drm_device *dev) - stat &= ~0x20000000; - } - -+ if (stat & 0x40000000) { -+ NV_INFO(dev, "PFIFO: unknown status 0x40000000\n"); -+ nv_mask(dev, 0x002a00, 0x00000000, 0x00000000); -+ stat &= ~0x40000000; -+ } -+ - if (stat) { - NV_INFO(dev, "PFIFO: unhandled status 0x%08x\n", stat); - nv_wr32(dev, 0x002100, stat); -+ nv_wr32(dev, 0x002140, 0); - } -- -- nv_wr32(dev, 0x2140, 0); - } -diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c -index eb18a7e..68f5c3f 100644 ---- a/drivers/gpu/drm/nouveau/nvc0_graph.c -+++ b/drivers/gpu/drm/nouveau/nvc0_graph.c -@@ -200,15 +200,15 @@ nvc0_graph_create_context(struct nouveau_channel *chan) - for (i = 0; i < priv->grctx_size; i += 4) - nv_wo32(grctx, i, priv->grctx_vals[i / 4]); - -- nv_wo32(grctx, 0xf4, 0); -- nv_wo32(grctx, 0xf8, 0); -- nv_wo32(grctx, 0x10, grch->mmio_nr); -- nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio->vinst)); -- nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio->vinst)); -- nv_wo32(grctx, 0x1c, 1); -- nv_wo32(grctx, 0x20, 0); -- nv_wo32(grctx, 0x28, 0); -- nv_wo32(grctx, 0x2c, 0); -+ nv_wo32(grctx, 0xf4, 0); -+ nv_wo32(grctx, 0xf8, 0); -+ nv_wo32(grctx, 0x10, grch->mmio_nr); -+ nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio->vinst)); -+ nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio->vinst)); -+ nv_wo32(grctx, 0x1c, 1); -+ nv_wo32(grctx, 0x20, 0); -+ nv_wo32(grctx, 0x28, 0); -+ nv_wo32(grctx, 0x2c, 0); - pinstmem->flush(dev); - return 0; - -@@ -299,6 +299,14 @@ nvc0_graph_takedown(struct drm_device *dev) - } - - static int -+nvc0_graph_mthd_page_flip(struct nouveau_channel *chan, -+ u32 class, u32 mthd, u32 data) -+{ -+ nouveau_finish_page_flip(chan, NULL); -+ return 0; -+} -+ -+static int - nvc0_graph_create(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -@@ -395,6 +403,7 @@ nvc0_graph_create(struct drm_device *dev) - nouveau_irq_register(dev, 25, nvc0_runk140_isr); - NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */ - NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */ -+ NVOBJ_MTHD (dev, 0x9039, 0x0500, nvc0_graph_mthd_page_flip); - NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */ - NVOBJ_CLASS(dev, 0x90c0, GR); /* COMPUTE */ - return 0; -@@ -443,28 +452,30 @@ nvc0_graph_init_gpc_0(struct drm_device *dev) - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; - int gpc; -- -- // TP ROP UNKVAL(magic_not_rop_nr) -- // 450: 4/0/0/0 2 3 -- // 460: 3/4/0/0 4 1 -- // 465: 3/4/4/0 4 7 -- // 470: 3/3/4/4 5 5 -- // 480: 3/4/4/4 6 6 -- -- // magicgpc918 -- // 450: 00200000 00000000001000000000000000000000 -- // 460: 00124925 00000000000100100100100100100101 -- // 465: 000ba2e9 00000000000010111010001011101001 -- // 470: 00092493 00000000000010010010010010010011 -- // 480: 00088889 00000000000010001000100010001001 -- -- /* filled values up to tp_total, remainder 0 */ -- // 450: 00003210 00000000 00000000 00000000 -- // 460: 02321100 00000000 00000000 00000000 -- // 465: 22111000 00000233 00000000 00000000 -- // 470: 11110000 00233222 00000000 00000000 -- // 480: 11110000 03332222 00000000 00000000 -- -+ -+ /* -+ * TP ROP UNKVAL(magic_not_rop_nr) -+ * 450: 4/0/0/0 2 3 -+ * 460: 3/4/0/0 4 1 -+ * 465: 3/4/4/0 4 7 -+ * 470: 3/3/4/4 5 5 -+ * 480: 3/4/4/4 6 6 -+ -+ * magicgpc918 -+ * 450: 00200000 00000000001000000000000000000000 -+ * 460: 00124925 00000000000100100100100100100101 -+ * 465: 000ba2e9 00000000000010111010001011101001 -+ * 470: 00092493 00000000000010010010010010010011 -+ * 480: 00088889 00000000000010001000100010001001 -+ -+ * filled values up to tp_total, remainder 0 -+ * 450: 00003210 00000000 00000000 00000000 -+ * 460: 02321100 00000000 00000000 00000000 -+ * 465: 22111000 00000233 00000000 00000000 -+ * 470: 11110000 00233222 00000000 00000000 -+ * 480: 11110000 03332222 00000000 00000000 -+ */ -+ - nv_wr32(dev, GPC_BCAST(0x0980), priv->magicgpc980[0]); - nv_wr32(dev, GPC_BCAST(0x0984), priv->magicgpc980[1]); - nv_wr32(dev, GPC_BCAST(0x0988), priv->magicgpc980[2]); -@@ -640,7 +651,6 @@ nvc0_graph_init(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; -- struct nvc0_graph_priv *priv; - int ret; - - dev_priv->engine.graph.accel_blocked = true; -@@ -665,13 +675,12 @@ nvc0_graph_init(struct drm_device *dev) - if (ret) - return ret; - } -- priv = pgraph->priv; - - nvc0_graph_init_obj418880(dev); - nvc0_graph_init_regs(dev); -- //nvc0_graph_init_unitplemented_magics(dev); -+ /*nvc0_graph_init_unitplemented_magics(dev);*/ - nvc0_graph_init_gpc_0(dev); -- //nvc0_graph_init_unitplemented_c242(dev); -+ /*nvc0_graph_init_unitplemented_c242(dev);*/ - - nv_wr32(dev, 0x400500, 0x00010001); - nv_wr32(dev, 0x400100, 0xffffffff); -@@ -730,9 +739,12 @@ nvc0_graph_isr(struct drm_device *dev) - u32 class = nv_rd32(dev, 0x404200 + (subc * 4)); - - if (stat & 0x00000010) { -- NV_INFO(dev, "PGRAPH: ILLEGAL_MTHD ch %d [0x%010llx] subc %d " -- "class 0x%04x mthd 0x%04x data 0x%08x\n", -- chid, inst, subc, class, mthd, data); -+ if (nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) { -+ NV_INFO(dev, "PGRAPH: ILLEGAL_MTHD ch %d [0x%010llx] " -+ "subc %d class 0x%04x mthd 0x%04x " -+ "data 0x%08x\n", -+ chid, inst, subc, class, mthd, data); -+ } - nv_wr32(dev, 0x400100, 0x00000010); - stat &= ~0x00000010; - } -diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.h b/drivers/gpu/drm/nouveau/nvc0_graph.h -index 40e26f9..d32b385 100644 ---- a/drivers/gpu/drm/nouveau/nvc0_graph.h -+++ b/drivers/gpu/drm/nouveau/nvc0_graph.h -@@ -28,11 +28,11 @@ - #define GPC_MAX 4 - #define TP_MAX 32 - --#define ROP_BCAST(r) (0x408800 + (r)) --#define ROP_UNIT(u,r) (0x410000 + (u) * 0x400 + (r)) --#define GPC_BCAST(r) (0x418000 + (r)) --#define GPC_UNIT(t,r) (0x500000 + (t) * 0x8000 + (r)) --#define TP_UNIT(t,m,r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r)) -+#define ROP_BCAST(r) (0x408800 + (r)) -+#define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r)) -+#define GPC_BCAST(r) (0x418000 + (r)) -+#define GPC_UNIT(t, r) (0x500000 + (t) * 0x8000 + (r)) -+#define TP_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r)) - - struct nvc0_graph_priv { - u8 gpc_nr; -@@ -52,9 +52,9 @@ struct nvc0_graph_priv { - - struct nvc0_graph_chan { - struct nouveau_gpuobj *grctx; -- struct nouveau_gpuobj *unk408004; // 0x418810 too -- struct nouveau_gpuobj *unk40800c; // 0x419004 too -- struct nouveau_gpuobj *unk418810; // 0x419848 too -+ struct nouveau_gpuobj *unk408004; /* 0x418810 too */ -+ struct nouveau_gpuobj *unk40800c; /* 0x419004 too */ -+ struct nouveau_gpuobj *unk418810; /* 0x419848 too */ - struct nouveau_gpuobj *mmio; - int mmio_nr; - }; -diff --git a/drivers/gpu/drm/nouveau/nvc0_grctx.c b/drivers/gpu/drm/nouveau/nvc0_grctx.c -index f880ff7..6cede9f 100644 ---- a/drivers/gpu/drm/nouveau/nvc0_grctx.c -+++ b/drivers/gpu/drm/nouveau/nvc0_grctx.c -@@ -1623,7 +1623,7 @@ nvc0_grctx_generate_rop(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - -- // ROPC_BROADCAST -+ /* ROPC_BROADCAST */ - nv_wr32(dev, 0x408800, 0x02802a3c); - nv_wr32(dev, 0x408804, 0x00000040); - nv_wr32(dev, 0x408808, 0x0003e00d); -@@ -1647,7 +1647,7 @@ nvc0_grctx_generate_gpc(struct drm_device *dev) - { - int i; - -- // GPC_BROADCAST -+ /* GPC_BROADCAST */ - nv_wr32(dev, 0x418380, 0x00000016); - nv_wr32(dev, 0x418400, 0x38004e00); - nv_wr32(dev, 0x418404, 0x71e0ffff); -@@ -1728,7 +1728,7 @@ nvc0_grctx_generate_tp(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - -- // GPC_BROADCAST.TP_BROADCAST -+ /* GPC_BROADCAST.TP_BROADCAST */ - nv_wr32(dev, 0x419848, 0x00000000); - nv_wr32(dev, 0x419864, 0x0000012a); - nv_wr32(dev, 0x419888, 0x00000000); -@@ -1741,7 +1741,7 @@ nvc0_grctx_generate_tp(struct drm_device *dev) - nv_wr32(dev, 0x419a1c, 0x00000000); - nv_wr32(dev, 0x419a20, 0x00000800); - if (dev_priv->chipset != 0xc0) -- nv_wr32(dev, 0x00419ac4, 0x0007f440); // 0xc3 -+ nv_wr32(dev, 0x00419ac4, 0x0007f440); /* 0xc3 */ - nv_wr32(dev, 0x419b00, 0x0a418820); - nv_wr32(dev, 0x419b04, 0x062080e6); - nv_wr32(dev, 0x419b08, 0x020398a4); -@@ -1912,13 +1912,13 @@ nvc0_grctx_generate(struct nouveau_channel *chan) - for (i = 1; i < 7; i++) - data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5); - -- // GPC_BROADCAST -+ /* GPC_BROADCAST */ - nv_wr32(dev, 0x418bb8, (priv->tp_total << 8) | - priv->magic_not_rop_nr); - for (i = 0; i < 6; i++) - nv_wr32(dev, 0x418b08 + (i * 4), data[i]); - -- // GPC_BROADCAST.TP_BROADCAST -+ /* GPC_BROADCAST.TP_BROADCAST */ - nv_wr32(dev, 0x419bd0, (priv->tp_total << 8) | - priv->magic_not_rop_nr | - data2[0]); -@@ -1926,7 +1926,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan) - for (i = 0; i < 6; i++) - nv_wr32(dev, 0x419b00 + (i * 4), data[i]); - -- // UNK78xx -+ /* UNK78xx */ - nv_wr32(dev, 0x4078bc, (priv->tp_total << 8) | - priv->magic_not_rop_nr); - for (i = 0; i < 6; i++) -@@ -1944,7 +1944,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan) - gpc = -1; - for (i = 0, gpc = -1; i < 32; i++) { - int ltp = i * (priv->tp_total - 1) / 32; -- -+ - do { - gpc = (gpc + 1) % priv->gpc_nr; - } while (!tpnr[gpc]); -diff --git a/drivers/gpu/drm/nouveau/nvc0_vm.c b/drivers/gpu/drm/nouveau/nvc0_vm.c -index e4e83c2..a179e6c 100644 ---- a/drivers/gpu/drm/nouveau/nvc0_vm.c -+++ b/drivers/gpu/drm/nouveau/nvc0_vm.c -@@ -59,7 +59,7 @@ nvc0_vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target) - - void - nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, -- struct nouveau_vram *mem, u32 pte, u32 cnt, u64 phys) -+ struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) - { - u32 next = 1 << (vma->node->type - 8); - -@@ -75,11 +75,11 @@ nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, - - void - nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, -- u32 pte, dma_addr_t *list, u32 cnt) -+ struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) - { - pte <<= 3; - while (cnt--) { -- u64 phys = nvc0_vm_addr(vma, *list++, 0, 5); -+ u64 phys = nvc0_vm_addr(vma, *list++, mem->memtype, 5); - nv_wo32(pgt, pte + 0, lower_32_bits(phys)); - nv_wo32(pgt, pte + 4, upper_32_bits(phys)); - pte += 8; -@@ -104,20 +104,27 @@ nvc0_vm_flush(struct nouveau_vm *vm) - struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; - struct drm_device *dev = vm->dev; - struct nouveau_vm_pgd *vpgd; -- u32 r100c80, engine; -+ unsigned long flags; -+ u32 engine = (dev_priv->chan_vm == vm) ? 1 : 5; - - pinstmem->flush(vm->dev); - -- if (vm == dev_priv->chan_vm) -- engine = 1; -- else -- engine = 5; -- -+ spin_lock_irqsave(&dev_priv->vm_lock, flags); - list_for_each_entry(vpgd, &vm->pgd_list, head) { -- r100c80 = nv_rd32(dev, 0x100c80); -+ /* looks like maybe a "free flush slots" counter, the -+ * faster you write to 0x100cbc to more it decreases -+ */ -+ if (!nv_wait_ne(dev, 0x100c80, 0x00ff0000, 0x00000000)) { -+ NV_ERROR(dev, "vm timeout 0: 0x%08x %d\n", -+ nv_rd32(dev, 0x100c80), engine); -+ } - nv_wr32(dev, 0x100cb8, vpgd->obj->vinst >> 8); - nv_wr32(dev, 0x100cbc, 0x80000000 | engine); -- if (!nv_wait(dev, 0x100c80, 0xffffffff, r100c80)) -- NV_ERROR(dev, "vm flush timeout eng %d\n", engine); -+ /* wait for flush to be queued? */ -+ if (!nv_wait(dev, 0x100c80, 0x00008000, 0x00008000)) { -+ NV_ERROR(dev, "vm timeout 1: 0x%08x %d\n", -+ nv_rd32(dev, 0x100c80), engine); -+ } - } -+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); - } -diff --git a/drivers/gpu/drm/nouveau/nvc0_vram.c b/drivers/gpu/drm/nouveau/nvc0_vram.c -index 858eda5..67c6ec6 100644 ---- a/drivers/gpu/drm/nouveau/nvc0_vram.c -+++ b/drivers/gpu/drm/nouveau/nvc0_vram.c -@@ -26,64 +26,78 @@ - #include "nouveau_drv.h" - #include "nouveau_mm.h" - -+/* 0 = unsupported -+ * 1 = non-compressed -+ * 3 = compressed -+ */ -+static const u8 types[256] = { -+ 1, 1, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, -+ 0, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, -+ 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 1, 1, 1, 1, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -+ 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, -+ 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3, -+ 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0, -+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0 -+}; -+ - bool - nvc0_vram_flags_valid(struct drm_device *dev, u32 tile_flags) - { -- switch (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) { -- case 0x0000: -- case 0xfe00: -- case 0xdb00: -- case 0x1100: -- return true; -- default: -- break; -- } -- -- return false; -+ u8 memtype = (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) >> 8; -+ return likely((types[memtype] == 1)); - } - - int - nvc0_vram_new(struct drm_device *dev, u64 size, u32 align, u32 ncmin, -- u32 type, struct nouveau_vram **pvram) -+ u32 type, struct nouveau_mem **pmem) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; - struct ttm_mem_type_manager *man = &bdev->man[TTM_PL_VRAM]; - struct nouveau_mm *mm = man->priv; - struct nouveau_mm_node *r; -- struct nouveau_vram *vram; -+ struct nouveau_mem *mem; - int ret; - - size >>= 12; - align >>= 12; - ncmin >>= 12; - -- vram = kzalloc(sizeof(*vram), GFP_KERNEL); -- if (!vram) -+ mem = kzalloc(sizeof(*mem), GFP_KERNEL); -+ if (!mem) - return -ENOMEM; - -- INIT_LIST_HEAD(&vram->regions); -- vram->dev = dev_priv->dev; -- vram->memtype = type; -- vram->size = size; -+ INIT_LIST_HEAD(&mem->regions); -+ mem->dev = dev_priv->dev; -+ mem->memtype = (type & 0xff); -+ mem->size = size; - - mutex_lock(&mm->mutex); - do { - ret = nouveau_mm_get(mm, 1, size, ncmin, align, &r); - if (ret) { - mutex_unlock(&mm->mutex); -- nv50_vram_del(dev, &vram); -+ nv50_vram_del(dev, &mem); - return ret; - } - -- list_add_tail(&r->rl_entry, &vram->regions); -+ list_add_tail(&r->rl_entry, &mem->regions); - size -= r->length; - } while (size); - mutex_unlock(&mm->mutex); - -- r = list_first_entry(&vram->regions, struct nouveau_mm_node, rl_entry); -- vram->offset = (u64)r->offset << 12; -- *pvram = vram; -+ r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry); -+ mem->offset = (u64)r->offset << 12; -+ *pmem = mem; - return 0; - } - -diff --git a/drivers/gpu/drm/nouveau/nvreg.h b/drivers/gpu/drm/nouveau/nvreg.h -index fe0f253..bbfb1a6 100644 ---- a/drivers/gpu/drm/nouveau/nvreg.h -+++ b/drivers/gpu/drm/nouveau/nvreg.h -@@ -277,6 +277,8 @@ - # define NV_CIO_CRE_EBR_VDE_11 2:2 - # define NV_CIO_CRE_EBR_VRS_11 4:4 - # define NV_CIO_CRE_EBR_VBS_11 6:6 -+# define NV_CIO_CRE_42 0x42 -+# define NV_CIO_CRE_42_OFFSET_11 6:6 - # define NV_CIO_CRE_43 0x43 - # define NV_CIO_CRE_44 0x44 /* head control */ - # define NV_CIO_CRE_CSB 0x45 /* colour saturation boost */ diff --git a/drm-radeon-pageflip-oops-fix.patch b/drm-radeon-pageflip-oops-fix.patch deleted file mode 100644 index dd9cab8..0000000 --- a/drm-radeon-pageflip-oops-fix.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 498c555f56a02ec1059bc150cde84411ba0ac010 Mon Sep 17 00:00:00 2001 -From: Dave Airlie -Date: Sun, 29 May 2011 17:48:32 +1000 -Subject: [PATCH] drm/radeon: fix oops in ttm reserve when pageflipping (v2) - -We need to take a reference to this object, pinning doesn't take a reference -so if userspace deletes the object it can disappear even if pinned. - -v2: fix error paths to unreference properly also. - -should fix: -https://bugzilla.kernel.org/show_bug.cgi?id=32402 -and -https://bugzilla.redhat.com/show_bug.cgi?id=680651 - -Signed-off-by: Dave Airlie ---- - drivers/gpu/drm/radeon/radeon_display.c | 13 ++++++++----- - 1 files changed, 8 insertions(+), 5 deletions(-) - -diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c -index ae247ee..292f73f 100644 ---- a/drivers/gpu/drm/radeon/radeon_display.c -+++ b/drivers/gpu/drm/radeon/radeon_display.c -@@ -264,6 +264,8 @@ static void radeon_unpin_work_func(struct work_struct *__work) - radeon_bo_unreserve(work->old_rbo); - } else - DRM_ERROR("failed to reserve buffer after flip\n"); -+ -+ drm_gem_object_unreference_unlocked(work->old_rbo->gobj); - kfree(work); - } - -@@ -371,6 +373,8 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc, - new_radeon_fb = to_radeon_framebuffer(fb); - /* schedule unpin of the old buffer */ - obj = old_radeon_fb->obj; -+ /* take a reference to the old object */ -+ drm_gem_object_reference(obj); - rbo = obj->driver_private; - work->old_rbo = rbo; - INIT_WORK(&work->work, radeon_unpin_work_func); -@@ -378,12 +382,9 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc, - /* We borrow the event spin lock for protecting unpin_work */ - spin_lock_irqsave(&dev->event_lock, flags); - if (radeon_crtc->unpin_work) { -- spin_unlock_irqrestore(&dev->event_lock, flags); -- kfree(work); -- radeon_fence_unref(&fence); -- - DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); -- return -EBUSY; -+ r = -EBUSY; -+ goto unlock_free; - } - radeon_crtc->unpin_work = work; - radeon_crtc->deferred_flip_completion = 0; -@@ -497,6 +498,8 @@ pflip_cleanup1: - pflip_cleanup: - spin_lock_irqsave(&dev->event_lock, flags); - radeon_crtc->unpin_work = NULL; -+unlock_free: -+ drm_gem_object_unreference_unlocked(old_radeon_fb->obj); - spin_unlock_irqrestore(&dev->event_lock, flags); - radeon_fence_unref(&fence); - kfree(work); --- -1.7.4.4 - diff --git a/drm-radeon-update.patch b/drm-radeon-update.patch deleted file mode 100644 index 2051414..0000000 --- a/drm-radeon-update.patch +++ /dev/null @@ -1,4835 +0,0 @@ -commit 6d7f810bacd0fc2cf3966ec5d756a23735cb781e -Author: Alex Deucher -Date: Tue May 3 19:28:02 2011 -0400 - - drm/radeon/kms: fix gart setup on fusion parts (v2) - - Out of the entire GART/VM subsystem, the hw designers changed - the location of 3 regs. - - v2: airlied: add parameter for userspace to work from. - - Signed-off-by: Alex Deucher - Signed-off-by: Jerome Glisse - Cc: stable@kernel.org - Signed-off-by: Dave Airlie - -commit 00a99cbeca8ffb6d6165f388230ad49786a1a64e -Author: Dave Airlie -Date: Sun May 1 20:16:30 2011 +1000 - - drm/radeon: fix regression on atom cards with hardcoded EDID record. - - Since fafcf94e2b5732d1e13b440291c53115d2b172e9 introduced an edid size, it seems to have broken this path. - - This manifest as oops on T500 Lenovo laptops with dual graphics primarily. - - Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=33812 - - cc: stable@kernel.org - Reviewed-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit ea9254cde5e773424d3af177012ab8019a9a1664 -Author: Alex Deucher -Date: Tue Apr 26 13:27:43 2011 -0400 - - drm/radeon/kms: add info query for tile pipes - - needed by mesa for htile setup. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 5ac5da9419c4b51efa17ef222b0ac82d1af63af8 -Author: Alex Deucher -Date: Tue Apr 26 13:10:20 2011 -0400 - - drm/radeon/kms: add missing safe regs for 6xx/7xx - - needed for HiS in mesa. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 7ad87e13c92ac772cc1eced43df0555ec4a71bbc -Author: Cédric Cano -Date: Tue Apr 19 11:07:13 2011 -0400 - - drm/radeon/kms: fix IH writeback on r6xx+ on big endian machines - - agd5f: fix commit message. - - Signed-off-by: Cedric Cano - Reviewed-by: Michel Dänzer - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 10045c9e73dfa9e53fb429c6d5b1a2261da0ad51 -Author: Alex Deucher -Date: Thu Apr 14 19:07:34 2011 -0400 - - drm/radeon/kms: adjust evergreen display watermark setup - - This patch fixes two issues: - - A disabled crtc does not use any lb, so return 0 for - lb size. This makes the display priority calculation - more exact. - - Only use 1/2 and whole lb partitions. Using smaller - partitions can cause underflow to one of the displays - if you have multiple large displays on the same lb. - - Fixes: - https://bugs.freedesktop.org/show_bug.cgi?id=34534 - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit ea7537dfbe693d8a0d9a3f8dc040fea8d74db625 -Author: Alex Deucher -Date: Tue Apr 12 14:49:24 2011 -0400 - - drm/radeon/kms: properly program vddci on evergreen+ - - Change vddci as well as vddc when changing power modes - on evergreen/ni. Also, properly set vddci on boot up - for ni cards. The vbios only sets the limited clocks - and voltages on boot until the mc ucode is loaded. This - should fix stability problems on some btc cards. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit d45b8c22db23566ec99d330afe69ca0eb99877e3 -Author: Alex Deucher -Date: Tue Apr 12 14:49:23 2011 -0400 - - drm/radeon/kms: add voltage type to atom set voltage function - - This is needed for setting voltages other than vddc. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit ced08b02a89170bfcb0a7cff2b89000fce712efa -Author: Alex Deucher -Date: Tue Apr 12 13:40:18 2011 -0400 - - drm/radeon/kms: fix pcie_p callbacks on btc and cayman - - btc and cayman asics use the same callback for - pcie port registers. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 7e2f10779d1b11b9dc086d95dada8f2d441fcb7c -Author: Alex Deucher -Date: Sat Apr 2 09:15:50 2011 -0400 - - drm/radeon/kms: pageflipping cleanup for avivo+ - - Avoid touching the flip setup regs while - acceleration is running. Set them at modeset - rather than during pageflip. Touching these - regs while acceleration is active caused hangs - on pre-avivo chips. These chips do not seem - to be affected, but better safe than sorry, - plus it avoids repeatedly reprogramming the - regs every flip. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit c079101fc0747d6924edf6b476793267c8707731 -Author: Alex Deucher -Date: Sat Apr 2 09:09:08 2011 -0400 - - drm/radeon/kms: Add support for tv-out dongle on G5 9600 - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 80b359eb082c7e84c9ee970a98578dd409211f52 -Author: Alex Deucher -Date: Wed Mar 2 10:21:05 2011 -0500 - - drm/radeon/kms: allow max clock of 340 Mhz on hdmi 1.3+ - - hdmi 1.3 raises the max clock from 165 Mhz to 340 Mhz. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 4b77fd7824c73fd19a06b3942f498eb23740826d -Author: Alex Deucher -Date: Wed Mar 2 20:07:40 2011 -0500 - - drm/radeon/kms: cayman/evergreen cs checker updates - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 8f62b708e5f4a3e7b617fa7e5ddd9e9becf85920 -Author: Alex Deucher -Date: Wed Mar 2 20:07:39 2011 -0500 - - drm/radeon/kms/cayman: always set certain VGT regs at CP init - - These should be handled by the clear_state setup, but set them - directly as well just to be sure. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 25bfa1ee008f6d8871dd71c529ba25f6492e6b27 -Author: Alex Deucher -Date: Wed Mar 2 20:07:38 2011 -0500 - - drm/radeon/kms: additional default context regs for cayman - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 65a9c7094637d67ffec51dc7373c53f1e4836b79 -Author: Alex Deucher -Date: Wed Mar 2 20:07:37 2011 -0500 - - drm/radeon/kms: add cayman CS check support - - Added to existing evergreen CS checker. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 4655de2aadf3ef4d885600214f8bf989e35087fb -Author: Alex Deucher -Date: Wed Mar 2 20:07:36 2011 -0500 - - drm/radeon/kms: add radeon_asic entry for cayman - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 6110f1c930fa057a0380cbf786350dbd01e9dab9 -Author: Alex Deucher -Date: Wed Mar 2 20:07:35 2011 -0500 - - drm/radeon/kms: add cayman safe regs - - For the CS checker. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit f0c8c61d41e93b1b616b5eb5d29b1bdccb50b6ec -Author: Alex Deucher -Date: Wed Mar 2 20:07:34 2011 -0500 - - drm/radeon/kms/cayman: add asic init/startup/fini/suspend/resume functions - - Cayman is different enough from evergreen to warrant it's own functions. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit f772bd94e036bf8809359b4e37c1aa2ec2dcf4f3 -Author: Alex Deucher -Date: Wed Mar 2 20:07:33 2011 -0500 - - drm/radeon/kms: add cayman asic reset support - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit f83146d1532f80351e8b08ae6063d5792e56914f -Author: Alex Deucher -Date: Wed Mar 2 20:07:32 2011 -0500 - - drm/radeon/kms: add support for cayman irqs - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 004e9f16d1a0dbf2a8787f64b70e8bb3b86abe21 -Author: Alex Deucher -Date: Wed Mar 2 20:07:31 2011 -0500 - - drm/radeon/kms: add support for CP setup on cayman asics - - Cayman asics have 3 ring buffers: - ring 0 supports both gfx and compute - rings 1 and 2 are compute only - - At the moment we only support ring 0. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 5ca642f168996cd6f1dda99ffb17855cc65e493e -Author: Alex Deucher -Date: Wed Mar 2 20:07:30 2011 -0500 - - drm/radeon/kms: add support for cayman gart setup - - This patch sets up the gart in legacy mode. We - probably want to switch to full VM mode at some point. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 8e72474ace85f7a13c88dc360cbfc28dc2fe67e5 -Author: Alex Deucher -Date: Wed Mar 2 20:07:29 2011 -0500 - - drm/radeon/kms: add gpu_init function for cayman - - This may some work to get accel going. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 5b22a85481f452a23dd625e9a389d8f5c0f9b269 -Author: Alex Deucher -Date: Wed Mar 2 20:07:28 2011 -0500 - - drm/radeon/kms: add ucode loader for cayman - - The MC ucode is no longer loaded by the vbios - tables as on previous asics. It now must be loaded - by the driver. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 11fa70b2e7022d25933fc1d17518aeb054752dc9 -Author: Alex Deucher -Date: Wed Mar 2 20:07:27 2011 -0500 - - drm/radeon/kms: add cayman chip family - - Cayman is DCE5 display plus a new 4-way shader block. - 3D state programming is similar to evergreen. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit fe4608d030a121d61dfbc7a80c57706b89fbdabd -Author: Dave Airlie -Date: Tue Mar 1 14:32:27 2011 +1000 - - drm/radeon: add new getparam for number of backends. - - This allows userspace to work out how many DBs there are - for conditional rendering to work. - - Signed-off-by: Dave Airlie - -commit cd3e8f6393bce904aad911b8c261e14d5201d347 -Author: Dave Airlie -Date: Tue Mar 1 12:10:43 2011 +1000 - - drm/radeon: bump version to 2.9 - - This lets r600g enable texture formats and some more extensions. - - Signed-off-by: Dave Airlie - -commit 7855f7a2d8095e04916a097d14cad09c85ebf08a -Author: Dave Airlie -Date: Mon Feb 28 16:11:48 2011 +1000 - - drm/r600: parse the set predication command. (v2) - - This is required for NV_conditional_render and EXT_transform_feedback. - - v2: add evergreen support. - - Signed-off-by: Dave Airlie - -commit 85d824cf58fec0921e4e559cd91dbea50cb7bc20 -Author: Dave Airlie -Date: Mon Feb 28 14:27:03 2011 +1000 - - drm/radeon: make sure ib reads are in-order. - - have to read values from the IB in order as we could cross - a page boundary at any time and won't be able to go backwards. - - Signed-off-by: Dave Airlie - -commit a3f1872b53f046631f48faf19e932f6c9b020446 -Author: Dan Carpenter -Date: Sat Feb 26 04:48:18 2011 +0300 - - drm/radeon/r600_cs: off by one errors - - There are a bunch of off by one errors in the sanity checks here. - - Signed-off-by: Dan Carpenter - Signed-off-by: Dave Airlie - -commit 6c23a39f630acd5c792b731372f5fa227009c7ee -Author: Dave Airlie -Date: Fri Feb 18 05:51:58 2011 +0000 - - drm/radeon: overhaul texture checking. (v3) - - the texture checking code didn't work for block formats like s3tc, - this overhauls it to work for all types. - - v2: add texture array support. - v3: add subsampled formats - - Signed-off-by: Dave Airlie -diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile -index e47eecf..3896ef8 100644 ---- a/drivers/gpu/drm/radeon/Makefile -+++ b/drivers/gpu/drm/radeon/Makefile -@@ -36,6 +36,9 @@ $(obj)/r600_reg_safe.h: $(src)/reg_srcs/r600 $(obj)/mkregtable - $(obj)/evergreen_reg_safe.h: $(src)/reg_srcs/evergreen $(obj)/mkregtable - $(call if_changed,mkregtable) - -+$(obj)/cayman_reg_safe.h: $(src)/reg_srcs/cayman $(obj)/mkregtable -+ $(call if_changed,mkregtable) -+ - $(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h - - $(obj)/r200.o: $(obj)/r200_reg_safe.h -@@ -50,7 +53,7 @@ $(obj)/rs600.o: $(obj)/rs600_reg_safe.h - - $(obj)/r600_cs.o: $(obj)/r600_reg_safe.h - --$(obj)/evergreen_cs.o: $(obj)/evergreen_reg_safe.h -+$(obj)/evergreen_cs.o: $(obj)/evergreen_reg_safe.h $(obj)/cayman_reg_safe.h - - radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ - radeon_irq.o r300_cmdbuf.o r600_cp.o -@@ -66,7 +69,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ - r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ - r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ - evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ -- radeon_trace_points.o ni.o -+ radeon_trace_points.o ni.o cayman_blit_shaders.o - - radeon-$(CONFIG_COMPAT) += radeon_ioc32.o - radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o -diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c -index bede31c..2bab32f 100644 ---- a/drivers/gpu/drm/radeon/atombios_crtc.c -+++ b/drivers/gpu/drm/radeon/atombios_crtc.c -@@ -1011,6 +1011,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, - uint64_t fb_location; - uint32_t fb_format, fb_pitch_pixels, tiling_flags; - u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); -+ u32 tmp; - int r; - - /* no fb bound */ -@@ -1139,6 +1140,15 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, - WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, - (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); - -+ /* pageflip setup */ -+ /* make sure flip is at vb rather than hb */ -+ tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); -+ tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN; -+ WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); -+ -+ /* set pageflip to happen anywhere in vblank interval */ -+ WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); -+ - if (!atomic && fb && fb != crtc->fb) { - radeon_fb = to_radeon_framebuffer(fb); - rbo = radeon_fb->obj->driver_private; -@@ -1169,6 +1179,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, - uint64_t fb_location; - uint32_t fb_format, fb_pitch_pixels, tiling_flags; - u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE; -+ u32 tmp; - int r; - - /* no fb bound */ -@@ -1296,6 +1307,15 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, - WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, - (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); - -+ /* pageflip setup */ -+ /* make sure flip is at vb rather than hb */ -+ tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); -+ tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN; -+ WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); -+ -+ /* set pageflip to happen anywhere in vblank interval */ -+ WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); -+ - if (!atomic && fb && fb != crtc->fb) { - radeon_fb = to_radeon_framebuffer(fb); - rbo = radeon_fb->obj->driver_private; -diff --git a/drivers/gpu/drm/radeon/cayman_blit_shaders.c b/drivers/gpu/drm/radeon/cayman_blit_shaders.c -new file mode 100644 -index 0000000..e148ab0 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/cayman_blit_shaders.c -@@ -0,0 +1,55 @@ -+/* -+ * Copyright 2010 Advanced Micro Devices, 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 (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 HOLDER(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. -+ * -+ * Authors: -+ * Alex Deucher -+ */ -+ -+#include -+#include -+ -+/* -+ * evergreen cards need to use the 3D engine to blit data which requires -+ * quite a bit of hw state setup. Rather than pull the whole 3D driver -+ * (which normally generates the 3D state) into the DRM, we opt to use -+ * statically generated state tables. The regsiter state and shaders -+ * were hand generated to support blitting functionality. See the 3D -+ * driver or documentation for descriptions of the registers and -+ * shader instructions. -+ */ -+ -+const u32 cayman_default_state[] = -+{ -+ /* XXX fill in additional blit state */ -+ -+ 0xc0026900, -+ 0x00000316, -+ 0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */ -+ 0x00000010, /* */ -+ -+ 0xc0026900, -+ 0x000000d9, -+ 0x00000000, /* CP_RINGID */ -+ 0x00000000, /* CP_VMID */ -+}; -+ -+const u32 cayman_default_size = ARRAY_SIZE(cayman_default_state); -diff --git a/drivers/gpu/drm/radeon/cayman_blit_shaders.h b/drivers/gpu/drm/radeon/cayman_blit_shaders.h -new file mode 100644 -index 0000000..33b75e5 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/cayman_blit_shaders.h -@@ -0,0 +1,32 @@ -+/* -+ * Copyright 2010 Advanced Micro Devices, 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 (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 HOLDER(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 CAYMAN_BLIT_SHADERS_H -+#define CAYMAN_BLIT_SHADERS_H -+ -+extern const u32 cayman_default_state[]; -+ -+extern const u32 cayman_default_size; -+ -+#endif -diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c -index 6140ea1..f7e0376 100644 ---- a/drivers/gpu/drm/radeon/evergreen.c -+++ b/drivers/gpu/drm/radeon/evergreen.c -@@ -43,17 +43,6 @@ static void evergreen_pcie_gen2_enable(struct radeon_device *rdev); - - void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) - { -- struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; -- u32 tmp; -- -- /* make sure flip is at vb rather than hb */ -- tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); -- tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN; -- WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); -- -- /* set pageflip to happen anywhere in vblank interval */ -- WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); -- - /* enable the pflip int */ - radeon_irq_kms_pflip_irq_get(rdev, crtc); - } -@@ -131,11 +120,16 @@ void evergreen_pm_misc(struct radeon_device *rdev) - struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx]; - struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; - -- if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { -- if (voltage->voltage != rdev->pm.current_vddc) { -- radeon_atom_set_voltage(rdev, voltage->voltage); -+ if (voltage->type == VOLTAGE_SW) { -+ if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) { -+ radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); - rdev->pm.current_vddc = voltage->voltage; -- DRM_DEBUG("Setting: v: %d\n", voltage->voltage); -+ DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage); -+ } -+ if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) { -+ radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI); -+ rdev->pm.current_vddci = voltage->vddci; -+ DRM_DEBUG("Setting: vddci: %d\n", voltage->vddci); - } - } - } -@@ -359,7 +353,7 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, - struct drm_display_mode *mode, - struct drm_display_mode *other_mode) - { -- u32 tmp = 0; -+ u32 tmp; - /* - * Line Buffer Setup - * There are 3 line buffers, each one shared by 2 display controllers. -@@ -369,64 +363,63 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, - * first display controller - * 0 - first half of lb (3840 * 2) - * 1 - first 3/4 of lb (5760 * 2) -- * 2 - whole lb (7680 * 2) -+ * 2 - whole lb (7680 * 2), other crtc must be disabled - * 3 - first 1/4 of lb (1920 * 2) - * second display controller - * 4 - second half of lb (3840 * 2) - * 5 - second 3/4 of lb (5760 * 2) -- * 6 - whole lb (7680 * 2) -+ * 6 - whole lb (7680 * 2), other crtc must be disabled - * 7 - last 1/4 of lb (1920 * 2) - */ -- if (mode && other_mode) { -- if (mode->hdisplay > other_mode->hdisplay) { -- if (mode->hdisplay > 2560) -- tmp = 1; /* 3/4 */ -- else -- tmp = 0; /* 1/2 */ -- } else if (other_mode->hdisplay > mode->hdisplay) { -- if (other_mode->hdisplay > 2560) -- tmp = 3; /* 1/4 */ -- else -- tmp = 0; /* 1/2 */ -- } else -+ /* this can get tricky if we have two large displays on a paired group -+ * of crtcs. Ideally for multiple large displays we'd assign them to -+ * non-linked crtcs for maximum line buffer allocation. -+ */ -+ if (radeon_crtc->base.enabled && mode) { -+ if (other_mode) - tmp = 0; /* 1/2 */ -- } else if (mode) -- tmp = 2; /* whole */ -- else if (other_mode) -- tmp = 3; /* 1/4 */ -+ else -+ tmp = 2; /* whole */ -+ } else -+ tmp = 0; - - /* second controller of the pair uses second half of the lb */ - if (radeon_crtc->crtc_id % 2) - tmp += 4; - WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp); - -- switch (tmp) { -- case 0: -- case 4: -- default: -- if (ASIC_IS_DCE5(rdev)) -- return 4096 * 2; -- else -- return 3840 * 2; -- case 1: -- case 5: -- if (ASIC_IS_DCE5(rdev)) -- return 6144 * 2; -- else -- return 5760 * 2; -- case 2: -- case 6: -- if (ASIC_IS_DCE5(rdev)) -- return 8192 * 2; -- else -- return 7680 * 2; -- case 3: -- case 7: -- if (ASIC_IS_DCE5(rdev)) -- return 2048 * 2; -- else -- return 1920 * 2; -+ if (radeon_crtc->base.enabled && mode) { -+ switch (tmp) { -+ case 0: -+ case 4: -+ default: -+ if (ASIC_IS_DCE5(rdev)) -+ return 4096 * 2; -+ else -+ return 3840 * 2; -+ case 1: -+ case 5: -+ if (ASIC_IS_DCE5(rdev)) -+ return 6144 * 2; -+ else -+ return 5760 * 2; -+ case 2: -+ case 6: -+ if (ASIC_IS_DCE5(rdev)) -+ return 8192 * 2; -+ else -+ return 7680 * 2; -+ case 3: -+ case 7: -+ if (ASIC_IS_DCE5(rdev)) -+ return 2048 * 2; -+ else -+ return 1920 * 2; -+ } - } -+ -+ /* controller not enabled, so no lb used */ -+ return 0; - } - - static u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev) -@@ -804,7 +797,7 @@ void evergreen_bandwidth_update(struct radeon_device *rdev) - } - } - --static int evergreen_mc_wait_for_idle(struct radeon_device *rdev) -+int evergreen_mc_wait_for_idle(struct radeon_device *rdev) - { - unsigned i; - u32 tmp; -@@ -869,9 +862,15 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev) - SYSTEM_ACCESS_MODE_NOT_IN_SYS | - SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | - EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); -- WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); -- WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); -- WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); -+ if (rdev->flags & RADEON_IS_IGP) { -+ WREG32(FUS_MC_VM_MD_L1_TLB0_CNTL, tmp); -+ WREG32(FUS_MC_VM_MD_L1_TLB1_CNTL, tmp); -+ WREG32(FUS_MC_VM_MD_L1_TLB2_CNTL, tmp); -+ } else { -+ WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); -+ WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); -+ WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); -+ } - WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); -@@ -957,7 +956,7 @@ void evergreen_agp_enable(struct radeon_device *rdev) - WREG32(VM_CONTEXT1_CNTL, 0); - } - --static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) -+void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) - { - save->vga_control[0] = RREG32(D1VGA_CONTROL); - save->vga_control[1] = RREG32(D2VGA_CONTROL); -@@ -1011,7 +1010,7 @@ static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_sa - WREG32(EVERGREEN_D6VGA_CONTROL, 0); - } - --static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) -+void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) - { - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); -@@ -1108,7 +1107,7 @@ static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_ - WREG32(VGA_RENDER_CONTROL, save->vga_render_control); - } - --static void evergreen_mc_program(struct radeon_device *rdev) -+void evergreen_mc_program(struct radeon_device *rdev) - { - struct evergreen_mc_save save; - u32 tmp; -@@ -2576,7 +2575,7 @@ void evergreen_irq_disable(struct radeon_device *rdev) - evergreen_disable_interrupt_state(rdev); - } - --static void evergreen_irq_suspend(struct radeon_device *rdev) -+void evergreen_irq_suspend(struct radeon_device *rdev) - { - evergreen_irq_disable(rdev); - r600_rlc_stop(rdev); -@@ -2587,7 +2586,7 @@ static inline u32 evergreen_get_ih_wptr(struct radeon_device *rdev) - u32 wptr, tmp; - - if (rdev->wb.enabled) -- wptr = rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]; -+ wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); - else - wptr = RREG32(IH_RB_WPTR); - -@@ -2899,7 +2898,7 @@ static int evergreen_startup(struct radeon_device *rdev) - return r; - } - } -- r = btc_mc_load_microcode(rdev); -+ r = ni_mc_load_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load MC firmware!\n"); - return r; -@@ -2930,11 +2929,6 @@ static int evergreen_startup(struct radeon_device *rdev) - rdev->asic->copy = NULL; - dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); - } -- /* XXX: ontario has problems blitting to gart at the moment */ -- if (rdev->family == CHIP_PALM) { -- rdev->asic->copy = NULL; -- radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); -- } - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); -@@ -2981,7 +2975,7 @@ int evergreen_resume(struct radeon_device *rdev) - - r = evergreen_startup(rdev); - if (r) { -- DRM_ERROR("r600 startup failed on resume\n"); -+ DRM_ERROR("evergreen startup failed on resume\n"); - return r; - } - -@@ -3061,7 +3055,7 @@ int evergreen_init(struct radeon_device *rdev) - } - /* Must be an ATOMBIOS */ - if (!rdev->is_atom_bios) { -- dev_err(rdev->dev, "Expecting atombios for R600 GPU\n"); -+ dev_err(rdev->dev, "Expecting atombios for evergreen GPU\n"); - return -EINVAL; - } - r = radeon_atombios_init(rdev); -diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c -index 345a75a..5e4f9f8 100644 ---- a/drivers/gpu/drm/radeon/evergreen_cs.c -+++ b/drivers/gpu/drm/radeon/evergreen_cs.c -@@ -29,6 +29,7 @@ - #include "radeon.h" - #include "evergreend.h" - #include "evergreen_reg_safe.h" -+#include "cayman_reg_safe.h" - - static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc); -@@ -425,18 +426,28 @@ static inline int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u3 - { - struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track; - struct radeon_cs_reloc *reloc; -- u32 last_reg = ARRAY_SIZE(evergreen_reg_safe_bm); -+ u32 last_reg; - u32 m, i, tmp, *ib; - int r; - -+ if (p->rdev->family >= CHIP_CAYMAN) -+ last_reg = ARRAY_SIZE(cayman_reg_safe_bm); -+ else -+ last_reg = ARRAY_SIZE(evergreen_reg_safe_bm); -+ - i = (reg >> 7); - if (i > last_reg) { - dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); - return -EINVAL; - } - m = 1 << ((reg >> 2) & 31); -- if (!(evergreen_reg_safe_bm[i] & m)) -- return 0; -+ if (p->rdev->family >= CHIP_CAYMAN) { -+ if (!(cayman_reg_safe_bm[i] & m)) -+ return 0; -+ } else { -+ if (!(evergreen_reg_safe_bm[i] & m)) -+ return 0; -+ } - ib = p->ib->ptr; - switch (reg) { - /* force following reg to 0 in an attemp to disable out buffer -@@ -468,12 +479,42 @@ static inline int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u3 - case SQ_VSTMP_RING_ITEMSIZE: - case VGT_TF_RING_SIZE: - /* get value to populate the IB don't remove */ -- tmp =radeon_get_ib_value(p, idx); -- ib[idx] = 0; -+ /*tmp =radeon_get_ib_value(p, idx); -+ ib[idx] = 0;*/ -+ break; -+ case SQ_ESGS_RING_BASE: -+ case SQ_GSVS_RING_BASE: -+ case SQ_ESTMP_RING_BASE: -+ case SQ_GSTMP_RING_BASE: -+ case SQ_HSTMP_RING_BASE: -+ case SQ_LSTMP_RING_BASE: -+ case SQ_PSTMP_RING_BASE: -+ case SQ_VSTMP_RING_BASE: -+ r = evergreen_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ dev_warn(p->dev, "bad SET_CONTEXT_REG " -+ "0x%04X\n", reg); -+ return -EINVAL; -+ } -+ ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - break; - case DB_DEPTH_CONTROL: - track->db_depth_control = radeon_get_ib_value(p, idx); - break; -+ case CAYMAN_DB_EQAA: -+ if (p->rdev->family < CHIP_CAYMAN) { -+ dev_warn(p->dev, "bad SET_CONTEXT_REG " -+ "0x%04X\n", reg); -+ return -EINVAL; -+ } -+ break; -+ case CAYMAN_DB_DEPTH_INFO: -+ if (p->rdev->family < CHIP_CAYMAN) { -+ dev_warn(p->dev, "bad SET_CONTEXT_REG " -+ "0x%04X\n", reg); -+ return -EINVAL; -+ } -+ break; - case DB_Z_INFO: - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { -@@ -559,9 +600,23 @@ static inline int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u3 - track->cb_shader_mask = radeon_get_ib_value(p, idx); - break; - case PA_SC_AA_CONFIG: -+ if (p->rdev->family >= CHIP_CAYMAN) { -+ dev_warn(p->dev, "bad SET_CONTEXT_REG " -+ "0x%04X\n", reg); -+ return -EINVAL; -+ } - tmp = radeon_get_ib_value(p, idx) & MSAA_NUM_SAMPLES_MASK; - track->nsamples = 1 << tmp; - break; -+ case CAYMAN_PA_SC_AA_CONFIG: -+ if (p->rdev->family < CHIP_CAYMAN) { -+ dev_warn(p->dev, "bad SET_CONTEXT_REG " -+ "0x%04X\n", reg); -+ return -EINVAL; -+ } -+ tmp = radeon_get_ib_value(p, idx) & CAYMAN_MSAA_NUM_SAMPLES_MASK; -+ track->nsamples = 1 << tmp; -+ break; - case CB_COLOR0_VIEW: - case CB_COLOR1_VIEW: - case CB_COLOR2_VIEW: -@@ -942,6 +997,37 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, - idx_value = radeon_get_ib_value(p, idx); - - switch (pkt->opcode) { -+ case PACKET3_SET_PREDICATION: -+ { -+ int pred_op; -+ int tmp; -+ if (pkt->count != 1) { -+ DRM_ERROR("bad SET PREDICATION\n"); -+ return -EINVAL; -+ } -+ -+ tmp = radeon_get_ib_value(p, idx + 1); -+ pred_op = (tmp >> 16) & 0x7; -+ -+ /* for the clear predicate operation */ -+ if (pred_op == 0) -+ return 0; -+ -+ if (pred_op > 2) { -+ DRM_ERROR("bad SET PREDICATION operation %d\n", pred_op); -+ return -EINVAL; -+ } -+ -+ r = evergreen_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("bad SET PREDICATION\n"); -+ return -EINVAL; -+ } -+ -+ ib[idx + 0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff); -+ ib[idx + 1] = tmp + (upper_32_bits(reloc->lobj.gpu_offset) & 0xff); -+ } -+ break; - case PACKET3_CONTEXT_CONTROL: - if (pkt->count != 1) { - DRM_ERROR("bad CONTEXT_CONTROL\n"); -@@ -956,6 +1042,16 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, - return -EINVAL; - } - break; -+ case CAYMAN_PACKET3_DEALLOC_STATE: -+ if (p->rdev->family < CHIP_CAYMAN) { -+ DRM_ERROR("bad PACKET3_DEALLOC_STATE\n"); -+ return -EINVAL; -+ } -+ if (pkt->count) { -+ DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n"); -+ return -EINVAL; -+ } -+ break; - case PACKET3_INDEX_BASE: - if (pkt->count != 1) { - DRM_ERROR("bad INDEX_BASE\n"); -diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h -index eb4acf4..9453384 100644 ---- a/drivers/gpu/drm/radeon/evergreend.h -+++ b/drivers/gpu/drm/radeon/evergreend.h -@@ -221,6 +221,11 @@ - #define MC_VM_MD_L1_TLB0_CNTL 0x2654 - #define MC_VM_MD_L1_TLB1_CNTL 0x2658 - #define MC_VM_MD_L1_TLB2_CNTL 0x265C -+ -+#define FUS_MC_VM_MD_L1_TLB0_CNTL 0x265C -+#define FUS_MC_VM_MD_L1_TLB1_CNTL 0x2660 -+#define FUS_MC_VM_MD_L1_TLB2_CNTL 0x2664 -+ - #define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C - #define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 - #define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 -@@ -755,13 +760,21 @@ - - #define SQ_CONST_MEM_BASE 0x8df8 - -+#define SQ_ESGS_RING_BASE 0x8c40 - #define SQ_ESGS_RING_SIZE 0x8c44 -+#define SQ_GSVS_RING_BASE 0x8c48 - #define SQ_GSVS_RING_SIZE 0x8c4c -+#define SQ_ESTMP_RING_BASE 0x8c50 - #define SQ_ESTMP_RING_SIZE 0x8c54 -+#define SQ_GSTMP_RING_BASE 0x8c58 - #define SQ_GSTMP_RING_SIZE 0x8c5c -+#define SQ_VSTMP_RING_BASE 0x8c60 - #define SQ_VSTMP_RING_SIZE 0x8c64 -+#define SQ_PSTMP_RING_BASE 0x8c68 - #define SQ_PSTMP_RING_SIZE 0x8c6c -+#define SQ_LSTMP_RING_BASE 0x8e10 - #define SQ_LSTMP_RING_SIZE 0x8e14 -+#define SQ_HSTMP_RING_BASE 0x8e18 - #define SQ_HSTMP_RING_SIZE 0x8e1c - #define VGT_TF_RING_SIZE 0x8988 - -@@ -1093,5 +1106,14 @@ - #define SQ_TEX_RESOURCE_WORD6_0 0x30018 - #define SQ_TEX_RESOURCE_WORD7_0 0x3001c - -+/* cayman 3D regs */ -+#define CAYMAN_VGT_OFFCHIP_LDS_BASE 0x89B0 -+#define CAYMAN_DB_EQAA 0x28804 -+#define CAYMAN_DB_DEPTH_INFO 0x2803C -+#define CAYMAN_PA_SC_AA_CONFIG 0x28BE0 -+#define CAYMAN_MSAA_NUM_SAMPLES_SHIFT 0 -+#define CAYMAN_MSAA_NUM_SAMPLES_MASK 0x7 -+/* cayman packet3 addition */ -+#define CAYMAN_PACKET3_DEALLOC_STATE 0x14 - - #endif -diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c -index 5e0bef8..8c199c4 100644 ---- a/drivers/gpu/drm/radeon/ni.c -+++ b/drivers/gpu/drm/radeon/ni.c -@@ -31,12 +31,25 @@ - #include "nid.h" - #include "atom.h" - #include "ni_reg.h" -+#include "cayman_blit_shaders.h" -+ -+extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save); -+extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save); -+extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev); -+extern void evergreen_mc_program(struct radeon_device *rdev); -+extern void evergreen_irq_suspend(struct radeon_device *rdev); -+extern int evergreen_mc_init(struct radeon_device *rdev); - - #define EVERGREEN_PFP_UCODE_SIZE 1120 - #define EVERGREEN_PM4_UCODE_SIZE 1376 - #define EVERGREEN_RLC_UCODE_SIZE 768 - #define BTC_MC_UCODE_SIZE 6024 - -+#define CAYMAN_PFP_UCODE_SIZE 2176 -+#define CAYMAN_PM4_UCODE_SIZE 2176 -+#define CAYMAN_RLC_UCODE_SIZE 1024 -+#define CAYMAN_MC_UCODE_SIZE 6037 -+ - /* Firmware Names */ - MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); - MODULE_FIRMWARE("radeon/BARTS_me.bin"); -@@ -48,6 +61,10 @@ MODULE_FIRMWARE("radeon/TURKS_mc.bin"); - MODULE_FIRMWARE("radeon/CAICOS_pfp.bin"); - MODULE_FIRMWARE("radeon/CAICOS_me.bin"); - MODULE_FIRMWARE("radeon/CAICOS_mc.bin"); -+MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin"); -+MODULE_FIRMWARE("radeon/CAYMAN_me.bin"); -+MODULE_FIRMWARE("radeon/CAYMAN_mc.bin"); -+MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin"); - - #define BTC_IO_MC_REGS_SIZE 29 - -@@ -147,12 +164,44 @@ static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { - {0x0000009f, 0x00916a00} - }; - --int btc_mc_load_microcode(struct radeon_device *rdev) -+static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { -+ {0x00000077, 0xff010100}, -+ {0x00000078, 0x00000000}, -+ {0x00000079, 0x00001434}, -+ {0x0000007a, 0xcc08ec08}, -+ {0x0000007b, 0x00040000}, -+ {0x0000007c, 0x000080c0}, -+ {0x0000007d, 0x09000000}, -+ {0x0000007e, 0x00210404}, -+ {0x00000081, 0x08a8e800}, -+ {0x00000082, 0x00030444}, -+ {0x00000083, 0x00000000}, -+ {0x00000085, 0x00000001}, -+ {0x00000086, 0x00000002}, -+ {0x00000087, 0x48490000}, -+ {0x00000088, 0x20244647}, -+ {0x00000089, 0x00000005}, -+ {0x0000008b, 0x66030000}, -+ {0x0000008c, 0x00006603}, -+ {0x0000008d, 0x00000100}, -+ {0x0000008f, 0x00001c0a}, -+ {0x00000090, 0xff000001}, -+ {0x00000094, 0x00101101}, -+ {0x00000095, 0x00000fff}, -+ {0x00000096, 0x00116fff}, -+ {0x00000097, 0x60010000}, -+ {0x00000098, 0x10010000}, -+ {0x00000099, 0x00006000}, -+ {0x0000009a, 0x00001000}, -+ {0x0000009f, 0x00976b00} -+}; -+ -+int ni_mc_load_microcode(struct radeon_device *rdev) - { - const __be32 *fw_data; - u32 mem_type, running, blackout = 0; - u32 *io_mc_regs; -- int i; -+ int i, ucode_size, regs_size; - - if (!rdev->mc_fw) - return -EINVAL; -@@ -160,13 +209,24 @@ int btc_mc_load_microcode(struct radeon_device *rdev) - switch (rdev->family) { - case CHIP_BARTS: - io_mc_regs = (u32 *)&barts_io_mc_regs; -+ ucode_size = BTC_MC_UCODE_SIZE; -+ regs_size = BTC_IO_MC_REGS_SIZE; - break; - case CHIP_TURKS: - io_mc_regs = (u32 *)&turks_io_mc_regs; -+ ucode_size = BTC_MC_UCODE_SIZE; -+ regs_size = BTC_IO_MC_REGS_SIZE; - break; - case CHIP_CAICOS: - default: - io_mc_regs = (u32 *)&caicos_io_mc_regs; -+ ucode_size = BTC_MC_UCODE_SIZE; -+ regs_size = BTC_IO_MC_REGS_SIZE; -+ break; -+ case CHIP_CAYMAN: -+ io_mc_regs = (u32 *)&cayman_io_mc_regs; -+ ucode_size = CAYMAN_MC_UCODE_SIZE; -+ regs_size = BTC_IO_MC_REGS_SIZE; - break; - } - -@@ -184,13 +244,13 @@ int btc_mc_load_microcode(struct radeon_device *rdev) - WREG32(MC_SEQ_SUP_CNTL, 0x00000010); - - /* load mc io regs */ -- for (i = 0; i < BTC_IO_MC_REGS_SIZE; i++) { -+ for (i = 0; i < regs_size; i++) { - WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]); - WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]); - } - /* load the MC ucode */ - fw_data = (const __be32 *)rdev->mc_fw->data; -- for (i = 0; i < BTC_MC_UCODE_SIZE; i++) -+ for (i = 0; i < ucode_size; i++) - WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++)); - - /* put the engine back into the active state */ -@@ -231,23 +291,38 @@ int ni_init_microcode(struct radeon_device *rdev) - case CHIP_BARTS: - chip_name = "BARTS"; - rlc_chip_name = "BTC"; -+ pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; -+ me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; -+ rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; -+ mc_req_size = BTC_MC_UCODE_SIZE * 4; - break; - case CHIP_TURKS: - chip_name = "TURKS"; - rlc_chip_name = "BTC"; -+ pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; -+ me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; -+ rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; -+ mc_req_size = BTC_MC_UCODE_SIZE * 4; - break; - case CHIP_CAICOS: - chip_name = "CAICOS"; - rlc_chip_name = "BTC"; -+ pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; -+ me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; -+ rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; -+ mc_req_size = BTC_MC_UCODE_SIZE * 4; -+ break; -+ case CHIP_CAYMAN: -+ chip_name = "CAYMAN"; -+ rlc_chip_name = "CAYMAN"; -+ pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4; -+ me_req_size = CAYMAN_PM4_UCODE_SIZE * 4; -+ rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4; -+ mc_req_size = CAYMAN_MC_UCODE_SIZE * 4; - break; - default: BUG(); - } - -- pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; -- me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; -- rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; -- mc_req_size = BTC_MC_UCODE_SIZE * 4; -- - DRM_INFO("Loading %s Microcode\n", chip_name); - - snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); -@@ -314,3 +389,1204 @@ out: - return err; - } - -+/* -+ * Core functions -+ */ -+static u32 cayman_get_tile_pipe_to_backend_map(struct radeon_device *rdev, -+ u32 num_tile_pipes, -+ u32 num_backends_per_asic, -+ u32 *backend_disable_mask_per_asic, -+ u32 num_shader_engines) -+{ -+ u32 backend_map = 0; -+ u32 enabled_backends_mask = 0; -+ u32 enabled_backends_count = 0; -+ u32 num_backends_per_se; -+ u32 cur_pipe; -+ u32 swizzle_pipe[CAYMAN_MAX_PIPES]; -+ u32 cur_backend = 0; -+ u32 i; -+ bool force_no_swizzle; -+ -+ /* force legal values */ -+ if (num_tile_pipes < 1) -+ num_tile_pipes = 1; -+ if (num_tile_pipes > rdev->config.cayman.max_tile_pipes) -+ num_tile_pipes = rdev->config.cayman.max_tile_pipes; -+ if (num_shader_engines < 1) -+ num_shader_engines = 1; -+ if (num_shader_engines > rdev->config.cayman.max_shader_engines) -+ num_shader_engines = rdev->config.cayman.max_shader_engines; -+ if (num_backends_per_asic > num_shader_engines) -+ num_backends_per_asic = num_shader_engines; -+ if (num_backends_per_asic > (rdev->config.cayman.max_backends_per_se * num_shader_engines)) -+ num_backends_per_asic = rdev->config.cayman.max_backends_per_se * num_shader_engines; -+ -+ /* make sure we have the same number of backends per se */ -+ num_backends_per_asic = ALIGN(num_backends_per_asic, num_shader_engines); -+ /* set up the number of backends per se */ -+ num_backends_per_se = num_backends_per_asic / num_shader_engines; -+ if (num_backends_per_se > rdev->config.cayman.max_backends_per_se) { -+ num_backends_per_se = rdev->config.cayman.max_backends_per_se; -+ num_backends_per_asic = num_backends_per_se * num_shader_engines; -+ } -+ -+ /* create enable mask and count for enabled backends */ -+ for (i = 0; i < CAYMAN_MAX_BACKENDS; ++i) { -+ if (((*backend_disable_mask_per_asic >> i) & 1) == 0) { -+ enabled_backends_mask |= (1 << i); -+ ++enabled_backends_count; -+ } -+ if (enabled_backends_count == num_backends_per_asic) -+ break; -+ } -+ -+ /* force the backends mask to match the current number of backends */ -+ if (enabled_backends_count != num_backends_per_asic) { -+ u32 this_backend_enabled; -+ u32 shader_engine; -+ u32 backend_per_se; -+ -+ enabled_backends_mask = 0; -+ enabled_backends_count = 0; -+ *backend_disable_mask_per_asic = CAYMAN_MAX_BACKENDS_MASK; -+ for (i = 0; i < CAYMAN_MAX_BACKENDS; ++i) { -+ /* calc the current se */ -+ shader_engine = i / rdev->config.cayman.max_backends_per_se; -+ /* calc the backend per se */ -+ backend_per_se = i % rdev->config.cayman.max_backends_per_se; -+ /* default to not enabled */ -+ this_backend_enabled = 0; -+ if ((shader_engine < num_shader_engines) && -+ (backend_per_se < num_backends_per_se)) -+ this_backend_enabled = 1; -+ if (this_backend_enabled) { -+ enabled_backends_mask |= (1 << i); -+ *backend_disable_mask_per_asic &= ~(1 << i); -+ ++enabled_backends_count; -+ } -+ } -+ } -+ -+ -+ memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * CAYMAN_MAX_PIPES); -+ switch (rdev->family) { -+ case CHIP_CAYMAN: -+ force_no_swizzle = true; -+ break; -+ default: -+ force_no_swizzle = false; -+ break; -+ } -+ if (force_no_swizzle) { -+ bool last_backend_enabled = false; -+ -+ force_no_swizzle = false; -+ for (i = 0; i < CAYMAN_MAX_BACKENDS; ++i) { -+ if (((enabled_backends_mask >> i) & 1) == 1) { -+ if (last_backend_enabled) -+ force_no_swizzle = true; -+ last_backend_enabled = true; -+ } else -+ last_backend_enabled = false; -+ } -+ } -+ -+ switch (num_tile_pipes) { -+ case 1: -+ case 3: -+ case 5: -+ case 7: -+ DRM_ERROR("odd number of pipes!\n"); -+ break; -+ case 2: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 1; -+ break; -+ case 4: -+ if (force_no_swizzle) { -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 1; -+ swizzle_pipe[2] = 2; -+ swizzle_pipe[3] = 3; -+ } else { -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 2; -+ swizzle_pipe[2] = 1; -+ swizzle_pipe[3] = 3; -+ } -+ break; -+ case 6: -+ if (force_no_swizzle) { -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 1; -+ swizzle_pipe[2] = 2; -+ swizzle_pipe[3] = 3; -+ swizzle_pipe[4] = 4; -+ swizzle_pipe[5] = 5; -+ } else { -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 2; -+ swizzle_pipe[2] = 4; -+ swizzle_pipe[3] = 1; -+ swizzle_pipe[4] = 3; -+ swizzle_pipe[5] = 5; -+ } -+ break; -+ case 8: -+ if (force_no_swizzle) { -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 1; -+ swizzle_pipe[2] = 2; -+ swizzle_pipe[3] = 3; -+ swizzle_pipe[4] = 4; -+ swizzle_pipe[5] = 5; -+ swizzle_pipe[6] = 6; -+ swizzle_pipe[7] = 7; -+ } else { -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 2; -+ swizzle_pipe[2] = 4; -+ swizzle_pipe[3] = 6; -+ swizzle_pipe[4] = 1; -+ swizzle_pipe[5] = 3; -+ swizzle_pipe[6] = 5; -+ swizzle_pipe[7] = 7; -+ } -+ break; -+ } -+ -+ for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { -+ while (((1 << cur_backend) & enabled_backends_mask) == 0) -+ cur_backend = (cur_backend + 1) % CAYMAN_MAX_BACKENDS; -+ -+ backend_map |= (((cur_backend & 0xf) << (swizzle_pipe[cur_pipe] * 4))); -+ -+ cur_backend = (cur_backend + 1) % CAYMAN_MAX_BACKENDS; -+ } -+ -+ return backend_map; -+} -+ -+static void cayman_program_channel_remap(struct radeon_device *rdev) -+{ -+ u32 tcp_chan_steer_lo, tcp_chan_steer_hi, mc_shared_chremap, tmp; -+ -+ tmp = RREG32(MC_SHARED_CHMAP); -+ switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { -+ case 0: -+ case 1: -+ case 2: -+ case 3: -+ default: -+ /* default mapping */ -+ mc_shared_chremap = 0x00fac688; -+ break; -+ } -+ -+ switch (rdev->family) { -+ case CHIP_CAYMAN: -+ default: -+ //tcp_chan_steer_lo = 0x54763210 -+ tcp_chan_steer_lo = 0x76543210; -+ tcp_chan_steer_hi = 0x0000ba98; -+ break; -+ } -+ -+ WREG32(TCP_CHAN_STEER_LO, tcp_chan_steer_lo); -+ WREG32(TCP_CHAN_STEER_HI, tcp_chan_steer_hi); -+ WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); -+} -+ -+static u32 cayman_get_disable_mask_per_asic(struct radeon_device *rdev, -+ u32 disable_mask_per_se, -+ u32 max_disable_mask_per_se, -+ u32 num_shader_engines) -+{ -+ u32 disable_field_width_per_se = r600_count_pipe_bits(disable_mask_per_se); -+ u32 disable_mask_per_asic = disable_mask_per_se & max_disable_mask_per_se; -+ -+ if (num_shader_engines == 1) -+ return disable_mask_per_asic; -+ else if (num_shader_engines == 2) -+ return disable_mask_per_asic | (disable_mask_per_asic << disable_field_width_per_se); -+ else -+ return 0xffffffff; -+} -+ -+static void cayman_gpu_init(struct radeon_device *rdev) -+{ -+ u32 cc_rb_backend_disable = 0; -+ u32 cc_gc_shader_pipe_config; -+ u32 gb_addr_config = 0; -+ u32 mc_shared_chmap, mc_arb_ramcfg; -+ u32 gb_backend_map; -+ u32 cgts_tcc_disable; -+ u32 sx_debug_1; -+ u32 smx_dc_ctl0; -+ u32 gc_user_shader_pipe_config; -+ u32 gc_user_rb_backend_disable; -+ u32 cgts_user_tcc_disable; -+ u32 cgts_sm_ctrl_reg; -+ u32 hdp_host_path_cntl; -+ u32 tmp; -+ int i, j; -+ -+ switch (rdev->family) { -+ case CHIP_CAYMAN: -+ default: -+ rdev->config.cayman.max_shader_engines = 2; -+ rdev->config.cayman.max_pipes_per_simd = 4; -+ rdev->config.cayman.max_tile_pipes = 8; -+ rdev->config.cayman.max_simds_per_se = 12; -+ rdev->config.cayman.max_backends_per_se = 4; -+ rdev->config.cayman.max_texture_channel_caches = 8; -+ rdev->config.cayman.max_gprs = 256; -+ rdev->config.cayman.max_threads = 256; -+ rdev->config.cayman.max_gs_threads = 32; -+ rdev->config.cayman.max_stack_entries = 512; -+ rdev->config.cayman.sx_num_of_sets = 8; -+ rdev->config.cayman.sx_max_export_size = 256; -+ rdev->config.cayman.sx_max_export_pos_size = 64; -+ rdev->config.cayman.sx_max_export_smx_size = 192; -+ rdev->config.cayman.max_hw_contexts = 8; -+ rdev->config.cayman.sq_num_cf_insts = 2; -+ -+ rdev->config.cayman.sc_prim_fifo_size = 0x100; -+ rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30; -+ rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130; -+ break; -+ } -+ -+ /* Initialize HDP */ -+ for (i = 0, j = 0; i < 32; i++, j += 0x18) { -+ WREG32((0x2c14 + j), 0x00000000); -+ WREG32((0x2c18 + j), 0x00000000); -+ WREG32((0x2c1c + j), 0x00000000); -+ WREG32((0x2c20 + j), 0x00000000); -+ WREG32((0x2c24 + j), 0x00000000); -+ } -+ -+ WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); -+ -+ mc_shared_chmap = RREG32(MC_SHARED_CHMAP); -+ mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); -+ -+ cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE); -+ cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG); -+ cgts_tcc_disable = RREG32(CGTS_TCC_DISABLE); -+ gc_user_rb_backend_disable = RREG32(GC_USER_RB_BACKEND_DISABLE); -+ gc_user_shader_pipe_config = RREG32(GC_USER_SHADER_PIPE_CONFIG); -+ cgts_user_tcc_disable = RREG32(CGTS_USER_TCC_DISABLE); -+ -+ rdev->config.cayman.num_shader_engines = rdev->config.cayman.max_shader_engines; -+ tmp = ((~gc_user_shader_pipe_config) & INACTIVE_QD_PIPES_MASK) >> INACTIVE_QD_PIPES_SHIFT; -+ rdev->config.cayman.num_shader_pipes_per_simd = r600_count_pipe_bits(tmp); -+ rdev->config.cayman.num_tile_pipes = rdev->config.cayman.max_tile_pipes; -+ tmp = ((~gc_user_shader_pipe_config) & INACTIVE_SIMDS_MASK) >> INACTIVE_SIMDS_SHIFT; -+ rdev->config.cayman.num_simds_per_se = r600_count_pipe_bits(tmp); -+ tmp = ((~gc_user_rb_backend_disable) & BACKEND_DISABLE_MASK) >> BACKEND_DISABLE_SHIFT; -+ rdev->config.cayman.num_backends_per_se = r600_count_pipe_bits(tmp); -+ tmp = (gc_user_rb_backend_disable & BACKEND_DISABLE_MASK) >> BACKEND_DISABLE_SHIFT; -+ rdev->config.cayman.backend_disable_mask_per_asic = -+ cayman_get_disable_mask_per_asic(rdev, tmp, CAYMAN_MAX_BACKENDS_PER_SE_MASK, -+ rdev->config.cayman.num_shader_engines); -+ rdev->config.cayman.backend_map = -+ cayman_get_tile_pipe_to_backend_map(rdev, rdev->config.cayman.num_tile_pipes, -+ rdev->config.cayman.num_backends_per_se * -+ rdev->config.cayman.num_shader_engines, -+ &rdev->config.cayman.backend_disable_mask_per_asic, -+ rdev->config.cayman.num_shader_engines); -+ tmp = ((~cgts_user_tcc_disable) & TCC_DISABLE_MASK) >> TCC_DISABLE_SHIFT; -+ rdev->config.cayman.num_texture_channel_caches = r600_count_pipe_bits(tmp); -+ tmp = (mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT; -+ rdev->config.cayman.mem_max_burst_length_bytes = (tmp + 1) * 256; -+ if (rdev->config.cayman.mem_max_burst_length_bytes > 512) -+ rdev->config.cayman.mem_max_burst_length_bytes = 512; -+ tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT; -+ rdev->config.cayman.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024; -+ if (rdev->config.cayman.mem_row_size_in_kb > 4) -+ rdev->config.cayman.mem_row_size_in_kb = 4; -+ /* XXX use MC settings? */ -+ rdev->config.cayman.shader_engine_tile_size = 32; -+ rdev->config.cayman.num_gpus = 1; -+ rdev->config.cayman.multi_gpu_tile_size = 64; -+ -+ //gb_addr_config = 0x02011003 -+#if 0 -+ gb_addr_config = RREG32(GB_ADDR_CONFIG); -+#else -+ gb_addr_config = 0; -+ switch (rdev->config.cayman.num_tile_pipes) { -+ case 1: -+ default: -+ gb_addr_config |= NUM_PIPES(0); -+ break; -+ case 2: -+ gb_addr_config |= NUM_PIPES(1); -+ break; -+ case 4: -+ gb_addr_config |= NUM_PIPES(2); -+ break; -+ case 8: -+ gb_addr_config |= NUM_PIPES(3); -+ break; -+ } -+ -+ tmp = (rdev->config.cayman.mem_max_burst_length_bytes / 256) - 1; -+ gb_addr_config |= PIPE_INTERLEAVE_SIZE(tmp); -+ gb_addr_config |= NUM_SHADER_ENGINES(rdev->config.cayman.num_shader_engines - 1); -+ tmp = (rdev->config.cayman.shader_engine_tile_size / 16) - 1; -+ gb_addr_config |= SHADER_ENGINE_TILE_SIZE(tmp); -+ switch (rdev->config.cayman.num_gpus) { -+ case 1: -+ default: -+ gb_addr_config |= NUM_GPUS(0); -+ break; -+ case 2: -+ gb_addr_config |= NUM_GPUS(1); -+ break; -+ case 4: -+ gb_addr_config |= NUM_GPUS(2); -+ break; -+ } -+ switch (rdev->config.cayman.multi_gpu_tile_size) { -+ case 16: -+ gb_addr_config |= MULTI_GPU_TILE_SIZE(0); -+ break; -+ case 32: -+ default: -+ gb_addr_config |= MULTI_GPU_TILE_SIZE(1); -+ break; -+ case 64: -+ gb_addr_config |= MULTI_GPU_TILE_SIZE(2); -+ break; -+ case 128: -+ gb_addr_config |= MULTI_GPU_TILE_SIZE(3); -+ break; -+ } -+ switch (rdev->config.cayman.mem_row_size_in_kb) { -+ case 1: -+ default: -+ gb_addr_config |= ROW_SIZE(0); -+ break; -+ case 2: -+ gb_addr_config |= ROW_SIZE(1); -+ break; -+ case 4: -+ gb_addr_config |= ROW_SIZE(2); -+ break; -+ } -+#endif -+ -+ tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT; -+ rdev->config.cayman.num_tile_pipes = (1 << tmp); -+ tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT; -+ rdev->config.cayman.mem_max_burst_length_bytes = (tmp + 1) * 256; -+ tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT; -+ rdev->config.cayman.num_shader_engines = tmp + 1; -+ tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT; -+ rdev->config.cayman.num_gpus = tmp + 1; -+ tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT; -+ rdev->config.cayman.multi_gpu_tile_size = 1 << tmp; -+ tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT; -+ rdev->config.cayman.mem_row_size_in_kb = 1 << tmp; -+ -+ //gb_backend_map = 0x76541032; -+#if 0 -+ gb_backend_map = RREG32(GB_BACKEND_MAP); -+#else -+ gb_backend_map = -+ cayman_get_tile_pipe_to_backend_map(rdev, rdev->config.cayman.num_tile_pipes, -+ rdev->config.cayman.num_backends_per_se * -+ rdev->config.cayman.num_shader_engines, -+ &rdev->config.cayman.backend_disable_mask_per_asic, -+ rdev->config.cayman.num_shader_engines); -+#endif -+ /* setup tiling info dword. gb_addr_config is not adequate since it does -+ * not have bank info, so create a custom tiling dword. -+ * bits 3:0 num_pipes -+ * bits 7:4 num_banks -+ * bits 11:8 group_size -+ * bits 15:12 row_size -+ */ -+ rdev->config.cayman.tile_config = 0; -+ switch (rdev->config.cayman.num_tile_pipes) { -+ case 1: -+ default: -+ rdev->config.cayman.tile_config |= (0 << 0); -+ break; -+ case 2: -+ rdev->config.cayman.tile_config |= (1 << 0); -+ break; -+ case 4: -+ rdev->config.cayman.tile_config |= (2 << 0); -+ break; -+ case 8: -+ rdev->config.cayman.tile_config |= (3 << 0); -+ break; -+ } -+ rdev->config.cayman.tile_config |= -+ ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; -+ rdev->config.cayman.tile_config |= -+ (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT; -+ rdev->config.cayman.tile_config |= -+ ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; -+ -+ WREG32(GB_BACKEND_MAP, gb_backend_map); -+ WREG32(GB_ADDR_CONFIG, gb_addr_config); -+ WREG32(DMIF_ADDR_CONFIG, gb_addr_config); -+ WREG32(HDP_ADDR_CONFIG, gb_addr_config); -+ -+ cayman_program_channel_remap(rdev); -+ -+ /* primary versions */ -+ WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); -+ WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); -+ WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); -+ -+ WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable); -+ WREG32(CGTS_SYS_TCC_DISABLE, cgts_tcc_disable); -+ -+ /* user versions */ -+ WREG32(GC_USER_RB_BACKEND_DISABLE, cc_rb_backend_disable); -+ WREG32(GC_USER_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); -+ WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); -+ -+ WREG32(CGTS_USER_SYS_TCC_DISABLE, cgts_tcc_disable); -+ WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable); -+ -+ /* reprogram the shader complex */ -+ cgts_sm_ctrl_reg = RREG32(CGTS_SM_CTRL_REG); -+ for (i = 0; i < 16; i++) -+ WREG32(CGTS_SM_CTRL_REG, OVERRIDE); -+ WREG32(CGTS_SM_CTRL_REG, cgts_sm_ctrl_reg); -+ -+ /* set HW defaults for 3D engine */ -+ WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60)); -+ -+ sx_debug_1 = RREG32(SX_DEBUG_1); -+ sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS; -+ WREG32(SX_DEBUG_1, sx_debug_1); -+ -+ smx_dc_ctl0 = RREG32(SMX_DC_CTL0); -+ smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff); -+ smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets); -+ WREG32(SMX_DC_CTL0, smx_dc_ctl0); -+ -+ WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE); -+ -+ /* need to be explicitly zero-ed */ -+ WREG32(VGT_OFFCHIP_LDS_BASE, 0); -+ WREG32(SQ_LSTMP_RING_BASE, 0); -+ WREG32(SQ_HSTMP_RING_BASE, 0); -+ WREG32(SQ_ESTMP_RING_BASE, 0); -+ WREG32(SQ_GSTMP_RING_BASE, 0); -+ WREG32(SQ_VSTMP_RING_BASE, 0); -+ WREG32(SQ_PSTMP_RING_BASE, 0); -+ -+ WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO); -+ -+ WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) | -+ POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) | -+ SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1))); -+ -+ WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.evergreen.sc_prim_fifo_size) | -+ SC_HIZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_hiz_tile_fifo_size) | -+ SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_earlyz_tile_fifo_size))); -+ -+ -+ WREG32(VGT_NUM_INSTANCES, 1); -+ -+ WREG32(CP_PERFMON_CNTL, 0); -+ -+ WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.evergreen.sq_num_cf_insts) | -+ FETCH_FIFO_HIWATER(0x4) | -+ DONE_FIFO_HIWATER(0xe0) | -+ ALU_UPDATE_FIFO_HIWATER(0x8))); -+ -+ WREG32(SQ_GPR_RESOURCE_MGMT_1, NUM_CLAUSE_TEMP_GPRS(4)); -+ WREG32(SQ_CONFIG, (VC_ENABLE | -+ EXPORT_SRC_C | -+ GFX_PRIO(0) | -+ CS1_PRIO(0) | -+ CS2_PRIO(1))); -+ WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, DYN_GPR_ENABLE); -+ -+ WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | -+ FORCE_EOV_MAX_REZ_CNT(255))); -+ -+ WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) | -+ AUTO_INVLD_EN(ES_AND_GS_AUTO)); -+ -+ WREG32(VGT_GS_VERTEX_REUSE, 16); -+ WREG32(PA_SC_LINE_STIPPLE_STATE, 0); -+ -+ WREG32(CB_PERF_CTR0_SEL_0, 0); -+ WREG32(CB_PERF_CTR0_SEL_1, 0); -+ WREG32(CB_PERF_CTR1_SEL_0, 0); -+ WREG32(CB_PERF_CTR1_SEL_1, 0); -+ WREG32(CB_PERF_CTR2_SEL_0, 0); -+ WREG32(CB_PERF_CTR2_SEL_1, 0); -+ WREG32(CB_PERF_CTR3_SEL_0, 0); -+ WREG32(CB_PERF_CTR3_SEL_1, 0); -+ -+ hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); -+ WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); -+ -+ WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3)); -+ -+ udelay(50); -+} -+ -+/* -+ * GART -+ */ -+void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev) -+{ -+ /* flush hdp cache */ -+ WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); -+ -+ /* bits 0-7 are the VM contexts0-7 */ -+ WREG32(VM_INVALIDATE_REQUEST, 1); -+} -+ -+int cayman_pcie_gart_enable(struct radeon_device *rdev) -+{ -+ int r; -+ -+ if (rdev->gart.table.vram.robj == NULL) { -+ dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); -+ return -EINVAL; -+ } -+ r = radeon_gart_table_vram_pin(rdev); -+ if (r) -+ return r; -+ radeon_gart_restore(rdev); -+ /* Setup TLB control */ -+ WREG32(MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB | -+ ENABLE_L1_FRAGMENT_PROCESSING | -+ SYSTEM_ACCESS_MODE_NOT_IN_SYS | -+ SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); -+ /* Setup L2 cache */ -+ WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | -+ ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | -+ ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE | -+ EFFECTIVE_L2_QUEUE_SIZE(7) | -+ CONTEXT1_IDENTITY_ACCESS_MODE(1)); -+ WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE); -+ WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | -+ L2_CACHE_BIGK_FRAGMENT_SIZE(6)); -+ /* setup context0 */ -+ WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); -+ WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); -+ WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); -+ WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, -+ (u32)(rdev->dummy_page.addr >> 12)); -+ WREG32(VM_CONTEXT0_CNTL2, 0); -+ WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | -+ RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); -+ /* disable context1-7 */ -+ WREG32(VM_CONTEXT1_CNTL2, 0); -+ WREG32(VM_CONTEXT1_CNTL, 0); -+ -+ cayman_pcie_gart_tlb_flush(rdev); -+ rdev->gart.ready = true; -+ return 0; -+} -+ -+void cayman_pcie_gart_disable(struct radeon_device *rdev) -+{ -+ int r; -+ -+ /* Disable all tables */ -+ WREG32(VM_CONTEXT0_CNTL, 0); -+ WREG32(VM_CONTEXT1_CNTL, 0); -+ /* Setup TLB control */ -+ WREG32(MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_FRAGMENT_PROCESSING | -+ SYSTEM_ACCESS_MODE_NOT_IN_SYS | -+ SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); -+ /* Setup L2 cache */ -+ WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | -+ ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE | -+ EFFECTIVE_L2_QUEUE_SIZE(7) | -+ CONTEXT1_IDENTITY_ACCESS_MODE(1)); -+ WREG32(VM_L2_CNTL2, 0); -+ WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | -+ L2_CACHE_BIGK_FRAGMENT_SIZE(6)); -+ if (rdev->gart.table.vram.robj) { -+ r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); -+ if (likely(r == 0)) { -+ radeon_bo_kunmap(rdev->gart.table.vram.robj); -+ radeon_bo_unpin(rdev->gart.table.vram.robj); -+ radeon_bo_unreserve(rdev->gart.table.vram.robj); -+ } -+ } -+} -+ -+void cayman_pcie_gart_fini(struct radeon_device *rdev) -+{ -+ cayman_pcie_gart_disable(rdev); -+ radeon_gart_table_vram_free(rdev); -+ radeon_gart_fini(rdev); -+} -+ -+/* -+ * CP. -+ */ -+static void cayman_cp_enable(struct radeon_device *rdev, bool enable) -+{ -+ if (enable) -+ WREG32(CP_ME_CNTL, 0); -+ else { -+ radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); -+ WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); -+ WREG32(SCRATCH_UMSK, 0); -+ } -+} -+ -+static int cayman_cp_load_microcode(struct radeon_device *rdev) -+{ -+ const __be32 *fw_data; -+ int i; -+ -+ if (!rdev->me_fw || !rdev->pfp_fw) -+ return -EINVAL; -+ -+ cayman_cp_enable(rdev, false); -+ -+ fw_data = (const __be32 *)rdev->pfp_fw->data; -+ WREG32(CP_PFP_UCODE_ADDR, 0); -+ for (i = 0; i < CAYMAN_PFP_UCODE_SIZE; i++) -+ WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); -+ WREG32(CP_PFP_UCODE_ADDR, 0); -+ -+ fw_data = (const __be32 *)rdev->me_fw->data; -+ WREG32(CP_ME_RAM_WADDR, 0); -+ for (i = 0; i < CAYMAN_PM4_UCODE_SIZE; i++) -+ WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); -+ -+ WREG32(CP_PFP_UCODE_ADDR, 0); -+ WREG32(CP_ME_RAM_WADDR, 0); -+ WREG32(CP_ME_RAM_RADDR, 0); -+ return 0; -+} -+ -+static int cayman_cp_start(struct radeon_device *rdev) -+{ -+ int r, i; -+ -+ r = radeon_ring_lock(rdev, 7); -+ if (r) { -+ DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); -+ return r; -+ } -+ radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5)); -+ radeon_ring_write(rdev, 0x1); -+ radeon_ring_write(rdev, 0x0); -+ radeon_ring_write(rdev, rdev->config.cayman.max_hw_contexts - 1); -+ radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); -+ radeon_ring_write(rdev, 0); -+ radeon_ring_write(rdev, 0); -+ radeon_ring_unlock_commit(rdev); -+ -+ cayman_cp_enable(rdev, true); -+ -+ r = radeon_ring_lock(rdev, cayman_default_size + 19); -+ if (r) { -+ DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); -+ return r; -+ } -+ -+ /* setup clear context state */ -+ radeon_ring_write(rdev, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); -+ radeon_ring_write(rdev, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); -+ -+ for (i = 0; i < cayman_default_size; i++) -+ radeon_ring_write(rdev, cayman_default_state[i]); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); -+ radeon_ring_write(rdev, PACKET3_PREAMBLE_END_CLEAR_STATE); -+ -+ /* set clear context state */ -+ radeon_ring_write(rdev, PACKET3(PACKET3_CLEAR_STATE, 0)); -+ radeon_ring_write(rdev, 0); -+ -+ /* SQ_VTX_BASE_VTX_LOC */ -+ radeon_ring_write(rdev, 0xc0026f00); -+ radeon_ring_write(rdev, 0x00000000); -+ radeon_ring_write(rdev, 0x00000000); -+ radeon_ring_write(rdev, 0x00000000); -+ -+ /* Clear consts */ -+ radeon_ring_write(rdev, 0xc0036f00); -+ radeon_ring_write(rdev, 0x00000bc4); -+ radeon_ring_write(rdev, 0xffffffff); -+ radeon_ring_write(rdev, 0xffffffff); -+ radeon_ring_write(rdev, 0xffffffff); -+ -+ radeon_ring_write(rdev, 0xc0026900); -+ radeon_ring_write(rdev, 0x00000316); -+ radeon_ring_write(rdev, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ -+ radeon_ring_write(rdev, 0x00000010); /* */ -+ -+ radeon_ring_unlock_commit(rdev); -+ -+ /* XXX init other rings */ -+ -+ return 0; -+} -+ -+static void cayman_cp_fini(struct radeon_device *rdev) -+{ -+ cayman_cp_enable(rdev, false); -+ radeon_ring_fini(rdev); -+} -+ -+int cayman_cp_resume(struct radeon_device *rdev) -+{ -+ u32 tmp; -+ u32 rb_bufsz; -+ int r; -+ -+ /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */ -+ WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP | -+ SOFT_RESET_PA | -+ SOFT_RESET_SH | -+ SOFT_RESET_VGT | -+ SOFT_RESET_SX)); -+ RREG32(GRBM_SOFT_RESET); -+ mdelay(15); -+ WREG32(GRBM_SOFT_RESET, 0); -+ RREG32(GRBM_SOFT_RESET); -+ -+ WREG32(CP_SEM_WAIT_TIMER, 0x4); -+ -+ /* Set the write pointer delay */ -+ WREG32(CP_RB_WPTR_DELAY, 0); -+ -+ WREG32(CP_DEBUG, (1 << 27)); -+ -+ /* ring 0 - compute and gfx */ -+ /* Set ring buffer size */ -+ rb_bufsz = drm_order(rdev->cp.ring_size / 8); -+ tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; -+#ifdef __BIG_ENDIAN -+ tmp |= BUF_SWAP_32BIT; -+#endif -+ WREG32(CP_RB0_CNTL, tmp); -+ -+ /* Initialize the ring buffer's read and write pointers */ -+ WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); -+ WREG32(CP_RB0_WPTR, 0); -+ -+ /* set the wb address wether it's enabled or not */ -+ WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); -+ WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); -+ WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); -+ -+ if (rdev->wb.enabled) -+ WREG32(SCRATCH_UMSK, 0xff); -+ else { -+ tmp |= RB_NO_UPDATE; -+ WREG32(SCRATCH_UMSK, 0); -+ } -+ -+ mdelay(1); -+ WREG32(CP_RB0_CNTL, tmp); -+ -+ WREG32(CP_RB0_BASE, rdev->cp.gpu_addr >> 8); -+ -+ rdev->cp.rptr = RREG32(CP_RB0_RPTR); -+ rdev->cp.wptr = RREG32(CP_RB0_WPTR); -+ -+ /* ring1 - compute only */ -+ /* Set ring buffer size */ -+ rb_bufsz = drm_order(rdev->cp1.ring_size / 8); -+ tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; -+#ifdef __BIG_ENDIAN -+ tmp |= BUF_SWAP_32BIT; -+#endif -+ WREG32(CP_RB1_CNTL, tmp); -+ -+ /* Initialize the ring buffer's read and write pointers */ -+ WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); -+ WREG32(CP_RB1_WPTR, 0); -+ -+ /* set the wb address wether it's enabled or not */ -+ WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC); -+ WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFF); -+ -+ mdelay(1); -+ WREG32(CP_RB1_CNTL, tmp); -+ -+ WREG32(CP_RB1_BASE, rdev->cp1.gpu_addr >> 8); -+ -+ rdev->cp1.rptr = RREG32(CP_RB1_RPTR); -+ rdev->cp1.wptr = RREG32(CP_RB1_WPTR); -+ -+ /* ring2 - compute only */ -+ /* Set ring buffer size */ -+ rb_bufsz = drm_order(rdev->cp2.ring_size / 8); -+ tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; -+#ifdef __BIG_ENDIAN -+ tmp |= BUF_SWAP_32BIT; -+#endif -+ WREG32(CP_RB2_CNTL, tmp); -+ -+ /* Initialize the ring buffer's read and write pointers */ -+ WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA); -+ WREG32(CP_RB2_WPTR, 0); -+ -+ /* set the wb address wether it's enabled or not */ -+ WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC); -+ WREG32(CP_RB2_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFF); -+ -+ mdelay(1); -+ WREG32(CP_RB2_CNTL, tmp); -+ -+ WREG32(CP_RB2_BASE, rdev->cp2.gpu_addr >> 8); -+ -+ rdev->cp2.rptr = RREG32(CP_RB2_RPTR); -+ rdev->cp2.wptr = RREG32(CP_RB2_WPTR); -+ -+ /* start the rings */ -+ cayman_cp_start(rdev); -+ rdev->cp.ready = true; -+ rdev->cp1.ready = true; -+ rdev->cp2.ready = true; -+ /* this only test cp0 */ -+ r = radeon_ring_test(rdev); -+ if (r) { -+ rdev->cp.ready = false; -+ rdev->cp1.ready = false; -+ rdev->cp2.ready = false; -+ return r; -+ } -+ -+ return 0; -+} -+ -+bool cayman_gpu_is_lockup(struct radeon_device *rdev) -+{ -+ u32 srbm_status; -+ u32 grbm_status; -+ u32 grbm_status_se0, grbm_status_se1; -+ struct r100_gpu_lockup *lockup = &rdev->config.cayman.lockup; -+ int r; -+ -+ srbm_status = RREG32(SRBM_STATUS); -+ grbm_status = RREG32(GRBM_STATUS); -+ grbm_status_se0 = RREG32(GRBM_STATUS_SE0); -+ grbm_status_se1 = RREG32(GRBM_STATUS_SE1); -+ if (!(grbm_status & GUI_ACTIVE)) { -+ r100_gpu_lockup_update(lockup, &rdev->cp); -+ return false; -+ } -+ /* force CP activities */ -+ r = radeon_ring_lock(rdev, 2); -+ if (!r) { -+ /* PACKET2 NOP */ -+ radeon_ring_write(rdev, 0x80000000); -+ radeon_ring_write(rdev, 0x80000000); -+ radeon_ring_unlock_commit(rdev); -+ } -+ /* XXX deal with CP0,1,2 */ -+ rdev->cp.rptr = RREG32(CP_RB0_RPTR); -+ return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp); -+} -+ -+static int cayman_gpu_soft_reset(struct radeon_device *rdev) -+{ -+ struct evergreen_mc_save save; -+ u32 grbm_reset = 0; -+ -+ if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) -+ return 0; -+ -+ dev_info(rdev->dev, "GPU softreset \n"); -+ dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", -+ RREG32(GRBM_STATUS)); -+ dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", -+ RREG32(GRBM_STATUS_SE0)); -+ dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", -+ RREG32(GRBM_STATUS_SE1)); -+ dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", -+ RREG32(SRBM_STATUS)); -+ evergreen_mc_stop(rdev, &save); -+ if (evergreen_mc_wait_for_idle(rdev)) { -+ dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); -+ } -+ /* Disable CP parsing/prefetching */ -+ WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); -+ -+ /* reset all the gfx blocks */ -+ grbm_reset = (SOFT_RESET_CP | -+ SOFT_RESET_CB | -+ SOFT_RESET_DB | -+ SOFT_RESET_GDS | -+ SOFT_RESET_PA | -+ SOFT_RESET_SC | -+ SOFT_RESET_SPI | -+ SOFT_RESET_SH | -+ SOFT_RESET_SX | -+ SOFT_RESET_TC | -+ SOFT_RESET_TA | -+ SOFT_RESET_VGT | -+ SOFT_RESET_IA); -+ -+ dev_info(rdev->dev, " GRBM_SOFT_RESET=0x%08X\n", grbm_reset); -+ WREG32(GRBM_SOFT_RESET, grbm_reset); -+ (void)RREG32(GRBM_SOFT_RESET); -+ udelay(50); -+ WREG32(GRBM_SOFT_RESET, 0); -+ (void)RREG32(GRBM_SOFT_RESET); -+ /* Wait a little for things to settle down */ -+ udelay(50); -+ dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", -+ RREG32(GRBM_STATUS)); -+ dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", -+ RREG32(GRBM_STATUS_SE0)); -+ dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", -+ RREG32(GRBM_STATUS_SE1)); -+ dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", -+ RREG32(SRBM_STATUS)); -+ evergreen_mc_resume(rdev, &save); -+ return 0; -+} -+ -+int cayman_asic_reset(struct radeon_device *rdev) -+{ -+ return cayman_gpu_soft_reset(rdev); -+} -+ -+static int cayman_startup(struct radeon_device *rdev) -+{ -+ int r; -+ -+ if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { -+ r = ni_init_microcode(rdev); -+ if (r) { -+ DRM_ERROR("Failed to load firmware!\n"); -+ return r; -+ } -+ } -+ r = ni_mc_load_microcode(rdev); -+ if (r) { -+ DRM_ERROR("Failed to load MC firmware!\n"); -+ return r; -+ } -+ -+ evergreen_mc_program(rdev); -+ r = cayman_pcie_gart_enable(rdev); -+ if (r) -+ return r; -+ cayman_gpu_init(rdev); -+ -+#if 0 -+ r = cayman_blit_init(rdev); -+ if (r) { -+ cayman_blit_fini(rdev); -+ rdev->asic->copy = NULL; -+ dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); -+ } -+#endif -+ -+ /* allocate wb buffer */ -+ r = radeon_wb_init(rdev); -+ if (r) -+ return r; -+ -+ /* Enable IRQ */ -+ r = r600_irq_init(rdev); -+ if (r) { -+ DRM_ERROR("radeon: IH init failed (%d).\n", r); -+ radeon_irq_kms_fini(rdev); -+ return r; -+ } -+ evergreen_irq_set(rdev); -+ -+ r = radeon_ring_init(rdev, rdev->cp.ring_size); -+ if (r) -+ return r; -+ r = cayman_cp_load_microcode(rdev); -+ if (r) -+ return r; -+ r = cayman_cp_resume(rdev); -+ if (r) -+ return r; -+ -+ return 0; -+} -+ -+int cayman_resume(struct radeon_device *rdev) -+{ -+ int r; -+ -+ /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, -+ * posting will perform necessary task to bring back GPU into good -+ * shape. -+ */ -+ /* post card */ -+ atom_asic_init(rdev->mode_info.atom_context); -+ -+ r = cayman_startup(rdev); -+ if (r) { -+ DRM_ERROR("cayman startup failed on resume\n"); -+ return r; -+ } -+ -+ r = r600_ib_test(rdev); -+ if (r) { -+ DRM_ERROR("radeon: failled testing IB (%d).\n", r); -+ return r; -+ } -+ -+ return r; -+ -+} -+ -+int cayman_suspend(struct radeon_device *rdev) -+{ -+ /* int r; */ -+ -+ /* FIXME: we should wait for ring to be empty */ -+ cayman_cp_enable(rdev, false); -+ rdev->cp.ready = false; -+ evergreen_irq_suspend(rdev); -+ radeon_wb_disable(rdev); -+ cayman_pcie_gart_disable(rdev); -+ -+#if 0 -+ /* unpin shaders bo */ -+ r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); -+ if (likely(r == 0)) { -+ radeon_bo_unpin(rdev->r600_blit.shader_obj); -+ radeon_bo_unreserve(rdev->r600_blit.shader_obj); -+ } -+#endif -+ return 0; -+} -+ -+/* Plan is to move initialization in that function and use -+ * helper function so that radeon_device_init pretty much -+ * do nothing more than calling asic specific function. This -+ * should also allow to remove a bunch of callback function -+ * like vram_info. -+ */ -+int cayman_init(struct radeon_device *rdev) -+{ -+ int r; -+ -+ /* This don't do much */ -+ r = radeon_gem_init(rdev); -+ if (r) -+ return r; -+ /* Read BIOS */ -+ if (!radeon_get_bios(rdev)) { -+ if (ASIC_IS_AVIVO(rdev)) -+ return -EINVAL; -+ } -+ /* Must be an ATOMBIOS */ -+ if (!rdev->is_atom_bios) { -+ dev_err(rdev->dev, "Expecting atombios for cayman GPU\n"); -+ return -EINVAL; -+ } -+ r = radeon_atombios_init(rdev); -+ if (r) -+ return r; -+ -+ /* Post card if necessary */ -+ if (!radeon_card_posted(rdev)) { -+ if (!rdev->bios) { -+ dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); -+ return -EINVAL; -+ } -+ DRM_INFO("GPU not posted. posting now...\n"); -+ atom_asic_init(rdev->mode_info.atom_context); -+ } -+ /* Initialize scratch registers */ -+ r600_scratch_init(rdev); -+ /* Initialize surface registers */ -+ radeon_surface_init(rdev); -+ /* Initialize clocks */ -+ radeon_get_clock_info(rdev->ddev); -+ /* Fence driver */ -+ r = radeon_fence_driver_init(rdev); -+ if (r) -+ return r; -+ /* initialize memory controller */ -+ r = evergreen_mc_init(rdev); -+ if (r) -+ return r; -+ /* Memory manager */ -+ r = radeon_bo_init(rdev); -+ if (r) -+ return r; -+ -+ r = radeon_irq_kms_init(rdev); -+ if (r) -+ return r; -+ -+ rdev->cp.ring_obj = NULL; -+ r600_ring_init(rdev, 1024 * 1024); -+ -+ rdev->ih.ring_obj = NULL; -+ r600_ih_ring_init(rdev, 64 * 1024); -+ -+ r = r600_pcie_gart_init(rdev); -+ if (r) -+ return r; -+ -+ rdev->accel_working = true; -+ r = cayman_startup(rdev); -+ if (r) { -+ dev_err(rdev->dev, "disabling GPU acceleration\n"); -+ cayman_cp_fini(rdev); -+ r600_irq_fini(rdev); -+ radeon_wb_fini(rdev); -+ radeon_irq_kms_fini(rdev); -+ cayman_pcie_gart_fini(rdev); -+ rdev->accel_working = false; -+ } -+ if (rdev->accel_working) { -+ r = radeon_ib_pool_init(rdev); -+ if (r) { -+ DRM_ERROR("radeon: failed initializing IB pool (%d).\n", r); -+ rdev->accel_working = false; -+ } -+ r = r600_ib_test(rdev); -+ if (r) { -+ DRM_ERROR("radeon: failed testing IB (%d).\n", r); -+ rdev->accel_working = false; -+ } -+ } -+ -+ /* Don't start up if the MC ucode is missing. -+ * The default clocks and voltages before the MC ucode -+ * is loaded are not suffient for advanced operations. -+ */ -+ if (!rdev->mc_fw) { -+ DRM_ERROR("radeon: MC ucode required for NI+.\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+void cayman_fini(struct radeon_device *rdev) -+{ -+ /* cayman_blit_fini(rdev); */ -+ cayman_cp_fini(rdev); -+ r600_irq_fini(rdev); -+ radeon_wb_fini(rdev); -+ radeon_irq_kms_fini(rdev); -+ cayman_pcie_gart_fini(rdev); -+ radeon_gem_fini(rdev); -+ radeon_fence_driver_fini(rdev); -+ radeon_bo_fini(rdev); -+ radeon_atombios_fini(rdev); -+ kfree(rdev->bios); -+ rdev->bios = NULL; -+} -+ -diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h -index f7b4453..0f9a08b 100644 ---- a/drivers/gpu/drm/radeon/nid.h -+++ b/drivers/gpu/drm/radeon/nid.h -@@ -24,7 +24,101 @@ - #ifndef NI_H - #define NI_H - -+#define CAYMAN_MAX_SH_GPRS 256 -+#define CAYMAN_MAX_TEMP_GPRS 16 -+#define CAYMAN_MAX_SH_THREADS 256 -+#define CAYMAN_MAX_SH_STACK_ENTRIES 4096 -+#define CAYMAN_MAX_FRC_EOV_CNT 16384 -+#define CAYMAN_MAX_BACKENDS 8 -+#define CAYMAN_MAX_BACKENDS_MASK 0xFF -+#define CAYMAN_MAX_BACKENDS_PER_SE_MASK 0xF -+#define CAYMAN_MAX_SIMDS 16 -+#define CAYMAN_MAX_SIMDS_MASK 0xFFFF -+#define CAYMAN_MAX_SIMDS_PER_SE_MASK 0xFFF -+#define CAYMAN_MAX_PIPES 8 -+#define CAYMAN_MAX_PIPES_MASK 0xFF -+#define CAYMAN_MAX_LDS_NUM 0xFFFF -+#define CAYMAN_MAX_TCC 16 -+#define CAYMAN_MAX_TCC_MASK 0xFF -+ -+#define DMIF_ADDR_CONFIG 0xBD4 -+#define SRBM_STATUS 0x0E50 -+ -+#define VM_CONTEXT0_REQUEST_RESPONSE 0x1470 -+#define REQUEST_TYPE(x) (((x) & 0xf) << 0) -+#define RESPONSE_TYPE_MASK 0x000000F0 -+#define RESPONSE_TYPE_SHIFT 4 -+#define VM_L2_CNTL 0x1400 -+#define ENABLE_L2_CACHE (1 << 0) -+#define ENABLE_L2_FRAGMENT_PROCESSING (1 << 1) -+#define ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE (1 << 9) -+#define ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE (1 << 10) -+#define EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 7) << 14) -+#define CONTEXT1_IDENTITY_ACCESS_MODE(x) (((x) & 3) << 18) -+/* CONTEXT1_IDENTITY_ACCESS_MODE -+ * 0 physical = logical -+ * 1 logical via context1 page table -+ * 2 inside identity aperture use translation, outside physical = logical -+ * 3 inside identity aperture physical = logical, outside use translation -+ */ -+#define VM_L2_CNTL2 0x1404 -+#define INVALIDATE_ALL_L1_TLBS (1 << 0) -+#define INVALIDATE_L2_CACHE (1 << 1) -+#define VM_L2_CNTL3 0x1408 -+#define BANK_SELECT(x) ((x) << 0) -+#define CACHE_UPDATE_MODE(x) ((x) << 6) -+#define L2_CACHE_BIGK_ASSOCIATIVITY (1 << 20) -+#define L2_CACHE_BIGK_FRAGMENT_SIZE(x) ((x) << 15) -+#define VM_L2_STATUS 0x140C -+#define L2_BUSY (1 << 0) -+#define VM_CONTEXT0_CNTL 0x1410 -+#define ENABLE_CONTEXT (1 << 0) -+#define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1) -+#define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4) -+#define VM_CONTEXT1_CNTL 0x1414 -+#define VM_CONTEXT0_CNTL2 0x1430 -+#define VM_CONTEXT1_CNTL2 0x1434 -+#define VM_INVALIDATE_REQUEST 0x1478 -+#define VM_INVALIDATE_RESPONSE 0x147c -+#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR 0x1518 -+#define VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR 0x151c -+#define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153C -+#define VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155C -+#define VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157C -+ -+#define MC_SHARED_CHMAP 0x2004 -+#define NOOFCHAN_SHIFT 12 -+#define NOOFCHAN_MASK 0x00003000 -+#define MC_SHARED_CHREMAP 0x2008 -+ -+#define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 -+#define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 -+#define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C -+#define MC_VM_MX_L1_TLB_CNTL 0x2064 -+#define ENABLE_L1_TLB (1 << 0) -+#define ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) -+#define SYSTEM_ACCESS_MODE_PA_ONLY (0 << 3) -+#define SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 3) -+#define SYSTEM_ACCESS_MODE_IN_SYS (2 << 3) -+#define SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 3) -+#define SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5) -+#define ENABLE_ADVANCED_DRIVER_MODEL (1 << 6) -+ - #define MC_SHARED_BLACKOUT_CNTL 0x20ac -+#define MC_ARB_RAMCFG 0x2760 -+#define NOOFBANK_SHIFT 0 -+#define NOOFBANK_MASK 0x00000003 -+#define NOOFRANK_SHIFT 2 -+#define NOOFRANK_MASK 0x00000004 -+#define NOOFROWS_SHIFT 3 -+#define NOOFROWS_MASK 0x00000038 -+#define NOOFCOLS_SHIFT 6 -+#define NOOFCOLS_MASK 0x000000C0 -+#define CHANSIZE_SHIFT 8 -+#define CHANSIZE_MASK 0x00000100 -+#define BURSTLENGTH_SHIFT 9 -+#define BURSTLENGTH_MASK 0x00000200 -+#define CHANSIZE_OVERRIDE (1 << 11) - #define MC_SEQ_SUP_CNTL 0x28c8 - #define RUN_MASK (1 << 0) - #define MC_SEQ_SUP_PGM 0x28cc -@@ -37,5 +131,406 @@ - #define MC_SEQ_IO_DEBUG_INDEX 0x2a44 - #define MC_SEQ_IO_DEBUG_DATA 0x2a48 - -+#define HDP_HOST_PATH_CNTL 0x2C00 -+#define HDP_NONSURFACE_BASE 0x2C04 -+#define HDP_NONSURFACE_INFO 0x2C08 -+#define HDP_NONSURFACE_SIZE 0x2C0C -+#define HDP_ADDR_CONFIG 0x2F48 -+ -+#define CC_SYS_RB_BACKEND_DISABLE 0x3F88 -+#define GC_USER_SYS_RB_BACKEND_DISABLE 0x3F8C -+#define CGTS_SYS_TCC_DISABLE 0x3F90 -+#define CGTS_USER_SYS_TCC_DISABLE 0x3F94 -+ -+#define CONFIG_MEMSIZE 0x5428 -+ -+#define HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 -+#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 -+ -+#define GRBM_CNTL 0x8000 -+#define GRBM_READ_TIMEOUT(x) ((x) << 0) -+#define GRBM_STATUS 0x8010 -+#define CMDFIFO_AVAIL_MASK 0x0000000F -+#define RING2_RQ_PENDING (1 << 4) -+#define SRBM_RQ_PENDING (1 << 5) -+#define RING1_RQ_PENDING (1 << 6) -+#define CF_RQ_PENDING (1 << 7) -+#define PF_RQ_PENDING (1 << 8) -+#define GDS_DMA_RQ_PENDING (1 << 9) -+#define GRBM_EE_BUSY (1 << 10) -+#define SX_CLEAN (1 << 11) -+#define DB_CLEAN (1 << 12) -+#define CB_CLEAN (1 << 13) -+#define TA_BUSY (1 << 14) -+#define GDS_BUSY (1 << 15) -+#define VGT_BUSY_NO_DMA (1 << 16) -+#define VGT_BUSY (1 << 17) -+#define IA_BUSY_NO_DMA (1 << 18) -+#define IA_BUSY (1 << 19) -+#define SX_BUSY (1 << 20) -+#define SH_BUSY (1 << 21) -+#define SPI_BUSY (1 << 22) -+#define SC_BUSY (1 << 24) -+#define PA_BUSY (1 << 25) -+#define DB_BUSY (1 << 26) -+#define CP_COHERENCY_BUSY (1 << 28) -+#define CP_BUSY (1 << 29) -+#define CB_BUSY (1 << 30) -+#define GUI_ACTIVE (1 << 31) -+#define GRBM_STATUS_SE0 0x8014 -+#define GRBM_STATUS_SE1 0x8018 -+#define SE_SX_CLEAN (1 << 0) -+#define SE_DB_CLEAN (1 << 1) -+#define SE_CB_CLEAN (1 << 2) -+#define SE_VGT_BUSY (1 << 23) -+#define SE_PA_BUSY (1 << 24) -+#define SE_TA_BUSY (1 << 25) -+#define SE_SX_BUSY (1 << 26) -+#define SE_SPI_BUSY (1 << 27) -+#define SE_SH_BUSY (1 << 28) -+#define SE_SC_BUSY (1 << 29) -+#define SE_DB_BUSY (1 << 30) -+#define SE_CB_BUSY (1 << 31) -+#define GRBM_SOFT_RESET 0x8020 -+#define SOFT_RESET_CP (1 << 0) -+#define SOFT_RESET_CB (1 << 1) -+#define SOFT_RESET_DB (1 << 3) -+#define SOFT_RESET_GDS (1 << 4) -+#define SOFT_RESET_PA (1 << 5) -+#define SOFT_RESET_SC (1 << 6) -+#define SOFT_RESET_SPI (1 << 8) -+#define SOFT_RESET_SH (1 << 9) -+#define SOFT_RESET_SX (1 << 10) -+#define SOFT_RESET_TC (1 << 11) -+#define SOFT_RESET_TA (1 << 12) -+#define SOFT_RESET_VGT (1 << 14) -+#define SOFT_RESET_IA (1 << 15) -+ -+#define SCRATCH_REG0 0x8500 -+#define SCRATCH_REG1 0x8504 -+#define SCRATCH_REG2 0x8508 -+#define SCRATCH_REG3 0x850C -+#define SCRATCH_REG4 0x8510 -+#define SCRATCH_REG5 0x8514 -+#define SCRATCH_REG6 0x8518 -+#define SCRATCH_REG7 0x851C -+#define SCRATCH_UMSK 0x8540 -+#define SCRATCH_ADDR 0x8544 -+#define CP_SEM_WAIT_TIMER 0x85BC -+#define CP_ME_CNTL 0x86D8 -+#define CP_ME_HALT (1 << 28) -+#define CP_PFP_HALT (1 << 26) -+#define CP_RB2_RPTR 0x86f8 -+#define CP_RB1_RPTR 0x86fc -+#define CP_RB0_RPTR 0x8700 -+#define CP_RB_WPTR_DELAY 0x8704 -+#define CP_MEQ_THRESHOLDS 0x8764 -+#define MEQ1_START(x) ((x) << 0) -+#define MEQ2_START(x) ((x) << 8) -+#define CP_PERFMON_CNTL 0x87FC -+ -+#define VGT_CACHE_INVALIDATION 0x88C4 -+#define CACHE_INVALIDATION(x) ((x) << 0) -+#define VC_ONLY 0 -+#define TC_ONLY 1 -+#define VC_AND_TC 2 -+#define AUTO_INVLD_EN(x) ((x) << 6) -+#define NO_AUTO 0 -+#define ES_AUTO 1 -+#define GS_AUTO 2 -+#define ES_AND_GS_AUTO 3 -+#define VGT_GS_VERTEX_REUSE 0x88D4 -+ -+#define CC_GC_SHADER_PIPE_CONFIG 0x8950 -+#define GC_USER_SHADER_PIPE_CONFIG 0x8954 -+#define INACTIVE_QD_PIPES(x) ((x) << 8) -+#define INACTIVE_QD_PIPES_MASK 0x0000FF00 -+#define INACTIVE_QD_PIPES_SHIFT 8 -+#define INACTIVE_SIMDS(x) ((x) << 16) -+#define INACTIVE_SIMDS_MASK 0xFFFF0000 -+#define INACTIVE_SIMDS_SHIFT 16 -+ -+#define VGT_PRIMITIVE_TYPE 0x8958 -+#define VGT_NUM_INSTANCES 0x8974 -+#define VGT_TF_RING_SIZE 0x8988 -+#define VGT_OFFCHIP_LDS_BASE 0x89b4 -+ -+#define PA_SC_LINE_STIPPLE_STATE 0x8B10 -+#define PA_CL_ENHANCE 0x8A14 -+#define CLIP_VTX_REORDER_ENA (1 << 0) -+#define NUM_CLIP_SEQ(x) ((x) << 1) -+#define PA_SC_FIFO_SIZE 0x8BCC -+#define SC_PRIM_FIFO_SIZE(x) ((x) << 0) -+#define SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 12) -+#define SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 20) -+#define PA_SC_FORCE_EOV_MAX_CNTS 0x8B24 -+#define FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) -+#define FORCE_EOV_MAX_REZ_CNT(x) ((x) << 16) -+ -+#define SQ_CONFIG 0x8C00 -+#define VC_ENABLE (1 << 0) -+#define EXPORT_SRC_C (1 << 1) -+#define GFX_PRIO(x) ((x) << 2) -+#define CS1_PRIO(x) ((x) << 4) -+#define CS2_PRIO(x) ((x) << 6) -+#define SQ_GPR_RESOURCE_MGMT_1 0x8C04 -+#define NUM_PS_GPRS(x) ((x) << 0) -+#define NUM_VS_GPRS(x) ((x) << 16) -+#define NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28) -+#define SQ_ESGS_RING_SIZE 0x8c44 -+#define SQ_GSVS_RING_SIZE 0x8c4c -+#define SQ_ESTMP_RING_BASE 0x8c50 -+#define SQ_ESTMP_RING_SIZE 0x8c54 -+#define SQ_GSTMP_RING_BASE 0x8c58 -+#define SQ_GSTMP_RING_SIZE 0x8c5c -+#define SQ_VSTMP_RING_BASE 0x8c60 -+#define SQ_VSTMP_RING_SIZE 0x8c64 -+#define SQ_PSTMP_RING_BASE 0x8c68 -+#define SQ_PSTMP_RING_SIZE 0x8c6c -+#define SQ_MS_FIFO_SIZES 0x8CF0 -+#define CACHE_FIFO_SIZE(x) ((x) << 0) -+#define FETCH_FIFO_HIWATER(x) ((x) << 8) -+#define DONE_FIFO_HIWATER(x) ((x) << 16) -+#define ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24) -+#define SQ_LSTMP_RING_BASE 0x8e10 -+#define SQ_LSTMP_RING_SIZE 0x8e14 -+#define SQ_HSTMP_RING_BASE 0x8e18 -+#define SQ_HSTMP_RING_SIZE 0x8e1c -+#define SQ_DYN_GPR_CNTL_PS_FLUSH_REQ 0x8D8C -+#define DYN_GPR_ENABLE (1 << 8) -+#define SQ_CONST_MEM_BASE 0x8df8 -+ -+#define SX_EXPORT_BUFFER_SIZES 0x900C -+#define COLOR_BUFFER_SIZE(x) ((x) << 0) -+#define POSITION_BUFFER_SIZE(x) ((x) << 8) -+#define SMX_BUFFER_SIZE(x) ((x) << 16) -+#define SX_DEBUG_1 0x9058 -+#define ENABLE_NEW_SMX_ADDRESS (1 << 16) -+ -+#define SPI_CONFIG_CNTL 0x9100 -+#define GPR_WRITE_PRIORITY(x) ((x) << 0) -+#define SPI_CONFIG_CNTL_1 0x913C -+#define VTX_DONE_DELAY(x) ((x) << 0) -+#define INTERP_ONE_PRIM_PER_ROW (1 << 4) -+#define CRC_SIMD_ID_WADDR_DISABLE (1 << 8) -+ -+#define CGTS_TCC_DISABLE 0x9148 -+#define CGTS_USER_TCC_DISABLE 0x914C -+#define TCC_DISABLE_MASK 0xFFFF0000 -+#define TCC_DISABLE_SHIFT 16 -+#define CGTS_SM_CTRL_REG 0x915C -+#define OVERRIDE (1 << 21) -+ -+#define TA_CNTL_AUX 0x9508 -+#define DISABLE_CUBE_WRAP (1 << 0) -+#define DISABLE_CUBE_ANISO (1 << 1) -+ -+#define TCP_CHAN_STEER_LO 0x960c -+#define TCP_CHAN_STEER_HI 0x9610 -+ -+#define CC_RB_BACKEND_DISABLE 0x98F4 -+#define BACKEND_DISABLE(x) ((x) << 16) -+#define GB_ADDR_CONFIG 0x98F8 -+#define NUM_PIPES(x) ((x) << 0) -+#define NUM_PIPES_MASK 0x00000007 -+#define NUM_PIPES_SHIFT 0 -+#define PIPE_INTERLEAVE_SIZE(x) ((x) << 4) -+#define PIPE_INTERLEAVE_SIZE_MASK 0x00000070 -+#define PIPE_INTERLEAVE_SIZE_SHIFT 4 -+#define BANK_INTERLEAVE_SIZE(x) ((x) << 8) -+#define NUM_SHADER_ENGINES(x) ((x) << 12) -+#define NUM_SHADER_ENGINES_MASK 0x00003000 -+#define NUM_SHADER_ENGINES_SHIFT 12 -+#define SHADER_ENGINE_TILE_SIZE(x) ((x) << 16) -+#define SHADER_ENGINE_TILE_SIZE_MASK 0x00070000 -+#define SHADER_ENGINE_TILE_SIZE_SHIFT 16 -+#define NUM_GPUS(x) ((x) << 20) -+#define NUM_GPUS_MASK 0x00700000 -+#define NUM_GPUS_SHIFT 20 -+#define MULTI_GPU_TILE_SIZE(x) ((x) << 24) -+#define MULTI_GPU_TILE_SIZE_MASK 0x03000000 -+#define MULTI_GPU_TILE_SIZE_SHIFT 24 -+#define ROW_SIZE(x) ((x) << 28) -+#define ROW_SIZE_MASK 0x30000007 -+#define ROW_SIZE_SHIFT 28 -+#define NUM_LOWER_PIPES(x) ((x) << 30) -+#define NUM_LOWER_PIPES_MASK 0x40000000 -+#define NUM_LOWER_PIPES_SHIFT 30 -+#define GB_BACKEND_MAP 0x98FC -+ -+#define CB_PERF_CTR0_SEL_0 0x9A20 -+#define CB_PERF_CTR0_SEL_1 0x9A24 -+#define CB_PERF_CTR1_SEL_0 0x9A28 -+#define CB_PERF_CTR1_SEL_1 0x9A2C -+#define CB_PERF_CTR2_SEL_0 0x9A30 -+#define CB_PERF_CTR2_SEL_1 0x9A34 -+#define CB_PERF_CTR3_SEL_0 0x9A38 -+#define CB_PERF_CTR3_SEL_1 0x9A3C -+ -+#define GC_USER_RB_BACKEND_DISABLE 0x9B7C -+#define BACKEND_DISABLE_MASK 0x00FF0000 -+#define BACKEND_DISABLE_SHIFT 16 -+ -+#define SMX_DC_CTL0 0xA020 -+#define USE_HASH_FUNCTION (1 << 0) -+#define NUMBER_OF_SETS(x) ((x) << 1) -+#define FLUSH_ALL_ON_EVENT (1 << 10) -+#define STALL_ON_EVENT (1 << 11) -+#define SMX_EVENT_CTL 0xA02C -+#define ES_FLUSH_CTL(x) ((x) << 0) -+#define GS_FLUSH_CTL(x) ((x) << 3) -+#define ACK_FLUSH_CTL(x) ((x) << 6) -+#define SYNC_FLUSH_CTL (1 << 8) -+ -+#define CP_RB0_BASE 0xC100 -+#define CP_RB0_CNTL 0xC104 -+#define RB_BUFSZ(x) ((x) << 0) -+#define RB_BLKSZ(x) ((x) << 8) -+#define RB_NO_UPDATE (1 << 27) -+#define RB_RPTR_WR_ENA (1 << 31) -+#define BUF_SWAP_32BIT (2 << 16) -+#define CP_RB0_RPTR_ADDR 0xC10C -+#define CP_RB0_RPTR_ADDR_HI 0xC110 -+#define CP_RB0_WPTR 0xC114 -+#define CP_RB1_BASE 0xC180 -+#define CP_RB1_CNTL 0xC184 -+#define CP_RB1_RPTR_ADDR 0xC188 -+#define CP_RB1_RPTR_ADDR_HI 0xC18C -+#define CP_RB1_WPTR 0xC190 -+#define CP_RB2_BASE 0xC194 -+#define CP_RB2_CNTL 0xC198 -+#define CP_RB2_RPTR_ADDR 0xC19C -+#define CP_RB2_RPTR_ADDR_HI 0xC1A0 -+#define CP_RB2_WPTR 0xC1A4 -+#define CP_PFP_UCODE_ADDR 0xC150 -+#define CP_PFP_UCODE_DATA 0xC154 -+#define CP_ME_RAM_RADDR 0xC158 -+#define CP_ME_RAM_WADDR 0xC15C -+#define CP_ME_RAM_DATA 0xC160 -+#define CP_DEBUG 0xC1FC -+ -+/* -+ * PM4 -+ */ -+#define PACKET_TYPE0 0 -+#define PACKET_TYPE1 1 -+#define PACKET_TYPE2 2 -+#define PACKET_TYPE3 3 -+ -+#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -+#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -+#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2) -+#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) -+#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \ -+ (((reg) >> 2) & 0xFFFF) | \ -+ ((n) & 0x3FFF) << 16) -+#define CP_PACKET2 0x80000000 -+#define PACKET2_PAD_SHIFT 0 -+#define PACKET2_PAD_MASK (0x3fffffff << 0) -+ -+#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) -+ -+#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \ -+ (((op) & 0xFF) << 8) | \ -+ ((n) & 0x3FFF) << 16) -+ -+/* Packet 3 types */ -+#define PACKET3_NOP 0x10 -+#define PACKET3_SET_BASE 0x11 -+#define PACKET3_CLEAR_STATE 0x12 -+#define PACKET3_INDEX_BUFFER_SIZE 0x13 -+#define PACKET3_DEALLOC_STATE 0x14 -+#define PACKET3_DISPATCH_DIRECT 0x15 -+#define PACKET3_DISPATCH_INDIRECT 0x16 -+#define PACKET3_INDIRECT_BUFFER_END 0x17 -+#define PACKET3_SET_PREDICATION 0x20 -+#define PACKET3_REG_RMW 0x21 -+#define PACKET3_COND_EXEC 0x22 -+#define PACKET3_PRED_EXEC 0x23 -+#define PACKET3_DRAW_INDIRECT 0x24 -+#define PACKET3_DRAW_INDEX_INDIRECT 0x25 -+#define PACKET3_INDEX_BASE 0x26 -+#define PACKET3_DRAW_INDEX_2 0x27 -+#define PACKET3_CONTEXT_CONTROL 0x28 -+#define PACKET3_DRAW_INDEX_OFFSET 0x29 -+#define PACKET3_INDEX_TYPE 0x2A -+#define PACKET3_DRAW_INDEX 0x2B -+#define PACKET3_DRAW_INDEX_AUTO 0x2D -+#define PACKET3_DRAW_INDEX_IMMD 0x2E -+#define PACKET3_NUM_INSTANCES 0x2F -+#define PACKET3_DRAW_INDEX_MULTI_AUTO 0x30 -+#define PACKET3_INDIRECT_BUFFER 0x32 -+#define PACKET3_STRMOUT_BUFFER_UPDATE 0x34 -+#define PACKET3_DRAW_INDEX_OFFSET_2 0x35 -+#define PACKET3_DRAW_INDEX_MULTI_ELEMENT 0x36 -+#define PACKET3_WRITE_DATA 0x37 -+#define PACKET3_MEM_SEMAPHORE 0x39 -+#define PACKET3_MPEG_INDEX 0x3A -+#define PACKET3_WAIT_REG_MEM 0x3C -+#define PACKET3_MEM_WRITE 0x3D -+#define PACKET3_SURFACE_SYNC 0x43 -+# define PACKET3_CB0_DEST_BASE_ENA (1 << 6) -+# define PACKET3_CB1_DEST_BASE_ENA (1 << 7) -+# define PACKET3_CB2_DEST_BASE_ENA (1 << 8) -+# define PACKET3_CB3_DEST_BASE_ENA (1 << 9) -+# define PACKET3_CB4_DEST_BASE_ENA (1 << 10) -+# define PACKET3_CB5_DEST_BASE_ENA (1 << 11) -+# define PACKET3_CB6_DEST_BASE_ENA (1 << 12) -+# define PACKET3_CB7_DEST_BASE_ENA (1 << 13) -+# define PACKET3_DB_DEST_BASE_ENA (1 << 14) -+# define PACKET3_CB8_DEST_BASE_ENA (1 << 15) -+# define PACKET3_CB9_DEST_BASE_ENA (1 << 16) -+# define PACKET3_CB10_DEST_BASE_ENA (1 << 17) -+# define PACKET3_CB11_DEST_BASE_ENA (1 << 18) -+# define PACKET3_FULL_CACHE_ENA (1 << 20) -+# define PACKET3_TC_ACTION_ENA (1 << 23) -+# define PACKET3_CB_ACTION_ENA (1 << 25) -+# define PACKET3_DB_ACTION_ENA (1 << 26) -+# define PACKET3_SH_ACTION_ENA (1 << 27) -+# define PACKET3_SX_ACTION_ENA (1 << 28) -+#define PACKET3_ME_INITIALIZE 0x44 -+#define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) -+#define PACKET3_COND_WRITE 0x45 -+#define PACKET3_EVENT_WRITE 0x46 -+#define PACKET3_EVENT_WRITE_EOP 0x47 -+#define PACKET3_EVENT_WRITE_EOS 0x48 -+#define PACKET3_PREAMBLE_CNTL 0x4A -+# define PACKET3_PREAMBLE_BEGIN_CLEAR_STATE (2 << 28) -+# define PACKET3_PREAMBLE_END_CLEAR_STATE (3 << 28) -+#define PACKET3_ALU_PS_CONST_BUFFER_COPY 0x4C -+#define PACKET3_ALU_VS_CONST_BUFFER_COPY 0x4D -+#define PACKET3_ALU_PS_CONST_UPDATE 0x4E -+#define PACKET3_ALU_VS_CONST_UPDATE 0x4F -+#define PACKET3_ONE_REG_WRITE 0x57 -+#define PACKET3_SET_CONFIG_REG 0x68 -+#define PACKET3_SET_CONFIG_REG_START 0x00008000 -+#define PACKET3_SET_CONFIG_REG_END 0x0000ac00 -+#define PACKET3_SET_CONTEXT_REG 0x69 -+#define PACKET3_SET_CONTEXT_REG_START 0x00028000 -+#define PACKET3_SET_CONTEXT_REG_END 0x00029000 -+#define PACKET3_SET_ALU_CONST 0x6A -+/* alu const buffers only; no reg file */ -+#define PACKET3_SET_BOOL_CONST 0x6B -+#define PACKET3_SET_BOOL_CONST_START 0x0003a500 -+#define PACKET3_SET_BOOL_CONST_END 0x0003a518 -+#define PACKET3_SET_LOOP_CONST 0x6C -+#define PACKET3_SET_LOOP_CONST_START 0x0003a200 -+#define PACKET3_SET_LOOP_CONST_END 0x0003a500 -+#define PACKET3_SET_RESOURCE 0x6D -+#define PACKET3_SET_RESOURCE_START 0x00030000 -+#define PACKET3_SET_RESOURCE_END 0x00038000 -+#define PACKET3_SET_SAMPLER 0x6E -+#define PACKET3_SET_SAMPLER_START 0x0003c000 -+#define PACKET3_SET_SAMPLER_END 0x0003c600 -+#define PACKET3_SET_CTL_CONST 0x6F -+#define PACKET3_SET_CTL_CONST_START 0x0003cff0 -+#define PACKET3_SET_CTL_CONST_END 0x0003ff0c -+#define PACKET3_SET_RESOURCE_OFFSET 0x70 -+#define PACKET3_SET_ALU_CONST_VS 0x71 -+#define PACKET3_SET_ALU_CONST_DI 0x72 -+#define PACKET3_SET_CONTEXT_REG_INDIRECT 0x73 -+#define PACKET3_SET_RESOURCE_INDIRECT 0x74 -+#define PACKET3_SET_APPEND_CNT 0x75 -+ - #endif - -diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c -index 9b3fad2..70e9fb0 100644 ---- a/drivers/gpu/drm/radeon/r600.c -+++ b/drivers/gpu/drm/radeon/r600.c -@@ -47,6 +47,7 @@ - #define EVERGREEN_PFP_UCODE_SIZE 1120 - #define EVERGREEN_PM4_UCODE_SIZE 1376 - #define EVERGREEN_RLC_UCODE_SIZE 768 -+#define CAYMAN_RLC_UCODE_SIZE 1024 - - /* Firmware Names */ - MODULE_FIRMWARE("radeon/R600_pfp.bin"); -@@ -586,7 +587,7 @@ void r600_pm_misc(struct radeon_device *rdev) - - if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { - if (voltage->voltage != rdev->pm.current_vddc) { -- radeon_atom_set_voltage(rdev, voltage->voltage); -+ radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); - rdev->pm.current_vddc = voltage->voltage; - DRM_DEBUG_DRIVER("Setting: v: %d\n", voltage->voltage); - } -@@ -2820,13 +2821,20 @@ static int r600_rlc_init(struct radeon_device *rdev) - WREG32(RLC_HB_CNTL, 0); - WREG32(RLC_HB_RPTR, 0); - WREG32(RLC_HB_WPTR, 0); -- WREG32(RLC_HB_WPTR_LSB_ADDR, 0); -- WREG32(RLC_HB_WPTR_MSB_ADDR, 0); -+ if (rdev->family <= CHIP_CAICOS) { -+ WREG32(RLC_HB_WPTR_LSB_ADDR, 0); -+ WREG32(RLC_HB_WPTR_MSB_ADDR, 0); -+ } - WREG32(RLC_MC_CNTL, 0); - WREG32(RLC_UCODE_CNTL, 0); - - fw_data = (const __be32 *)rdev->rlc_fw->data; -- if (rdev->family >= CHIP_CEDAR) { -+ if (rdev->family >= CHIP_CAYMAN) { -+ for (i = 0; i < CAYMAN_RLC_UCODE_SIZE; i++) { -+ WREG32(RLC_UCODE_ADDR, i); -+ WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); -+ } -+ } else if (rdev->family >= CHIP_CEDAR) { - for (i = 0; i < EVERGREEN_RLC_UCODE_SIZE; i++) { - WREG32(RLC_UCODE_ADDR, i); - WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); -@@ -3227,7 +3235,7 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) - u32 wptr, tmp; - - if (rdev->wb.enabled) -- wptr = rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]; -+ wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); - else - wptr = RREG32(IH_RB_WPTR); - -diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c -index 153095f..0a0848f 100644 ---- a/drivers/gpu/drm/radeon/r600_cs.c -+++ b/drivers/gpu/drm/radeon/r600_cs.c -@@ -71,75 +71,167 @@ struct r600_cs_track { - u64 db_bo_mc; - }; - -+#define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc } -+#define FMT_16_BIT(fmt, vc) [fmt] = { 1, 1, 2, vc } -+#define FMT_24_BIT(fmt) [fmt] = { 1, 1, 3, 0 } -+#define FMT_32_BIT(fmt, vc) [fmt] = { 1, 1, 4, vc } -+#define FMT_48_BIT(fmt) [fmt] = { 1, 1, 6, 0 } -+#define FMT_64_BIT(fmt, vc) [fmt] = { 1, 1, 8, vc } -+#define FMT_96_BIT(fmt) [fmt] = { 1, 1, 12, 0 } -+#define FMT_128_BIT(fmt, vc) [fmt] = { 1, 1, 16, vc } -+ -+struct gpu_formats { -+ unsigned blockwidth; -+ unsigned blockheight; -+ unsigned blocksize; -+ unsigned valid_color; -+}; -+ -+static const struct gpu_formats color_formats_table[] = { -+ /* 8 bit */ -+ FMT_8_BIT(V_038004_COLOR_8, 1), -+ FMT_8_BIT(V_038004_COLOR_4_4, 1), -+ FMT_8_BIT(V_038004_COLOR_3_3_2, 1), -+ FMT_8_BIT(V_038004_FMT_1, 0), -+ -+ /* 16-bit */ -+ FMT_16_BIT(V_038004_COLOR_16, 1), -+ FMT_16_BIT(V_038004_COLOR_16_FLOAT, 1), -+ FMT_16_BIT(V_038004_COLOR_8_8, 1), -+ FMT_16_BIT(V_038004_COLOR_5_6_5, 1), -+ FMT_16_BIT(V_038004_COLOR_6_5_5, 1), -+ FMT_16_BIT(V_038004_COLOR_1_5_5_5, 1), -+ FMT_16_BIT(V_038004_COLOR_4_4_4_4, 1), -+ FMT_16_BIT(V_038004_COLOR_5_5_5_1, 1), -+ -+ /* 24-bit */ -+ FMT_24_BIT(V_038004_FMT_8_8_8), -+ -+ /* 32-bit */ -+ FMT_32_BIT(V_038004_COLOR_32, 1), -+ FMT_32_BIT(V_038004_COLOR_32_FLOAT, 1), -+ FMT_32_BIT(V_038004_COLOR_16_16, 1), -+ FMT_32_BIT(V_038004_COLOR_16_16_FLOAT, 1), -+ FMT_32_BIT(V_038004_COLOR_8_24, 1), -+ FMT_32_BIT(V_038004_COLOR_8_24_FLOAT, 1), -+ FMT_32_BIT(V_038004_COLOR_24_8, 1), -+ FMT_32_BIT(V_038004_COLOR_24_8_FLOAT, 1), -+ FMT_32_BIT(V_038004_COLOR_10_11_11, 1), -+ FMT_32_BIT(V_038004_COLOR_10_11_11_FLOAT, 1), -+ FMT_32_BIT(V_038004_COLOR_11_11_10, 1), -+ FMT_32_BIT(V_038004_COLOR_11_11_10_FLOAT, 1), -+ FMT_32_BIT(V_038004_COLOR_2_10_10_10, 1), -+ FMT_32_BIT(V_038004_COLOR_8_8_8_8, 1), -+ FMT_32_BIT(V_038004_COLOR_10_10_10_2, 1), -+ FMT_32_BIT(V_038004_FMT_5_9_9_9_SHAREDEXP, 0), -+ FMT_32_BIT(V_038004_FMT_32_AS_8, 0), -+ FMT_32_BIT(V_038004_FMT_32_AS_8_8, 0), -+ -+ /* 48-bit */ -+ FMT_48_BIT(V_038004_FMT_16_16_16), -+ FMT_48_BIT(V_038004_FMT_16_16_16_FLOAT), -+ -+ /* 64-bit */ -+ FMT_64_BIT(V_038004_COLOR_X24_8_32_FLOAT, 1), -+ FMT_64_BIT(V_038004_COLOR_32_32, 1), -+ FMT_64_BIT(V_038004_COLOR_32_32_FLOAT, 1), -+ FMT_64_BIT(V_038004_COLOR_16_16_16_16, 1), -+ FMT_64_BIT(V_038004_COLOR_16_16_16_16_FLOAT, 1), -+ -+ FMT_96_BIT(V_038004_FMT_32_32_32), -+ FMT_96_BIT(V_038004_FMT_32_32_32_FLOAT), -+ -+ /* 128-bit */ -+ FMT_128_BIT(V_038004_COLOR_32_32_32_32, 1), -+ FMT_128_BIT(V_038004_COLOR_32_32_32_32_FLOAT, 1), -+ -+ [V_038004_FMT_GB_GR] = { 2, 1, 4, 0 }, -+ [V_038004_FMT_BG_RG] = { 2, 1, 4, 0 }, -+ -+ /* block compressed formats */ -+ [V_038004_FMT_BC1] = { 4, 4, 8, 0 }, -+ [V_038004_FMT_BC2] = { 4, 4, 16, 0 }, -+ [V_038004_FMT_BC3] = { 4, 4, 16, 0 }, -+ [V_038004_FMT_BC4] = { 4, 4, 8, 0 }, -+ [V_038004_FMT_BC5] = { 4, 4, 16, 0}, -+ -+}; -+ -+static inline bool fmt_is_valid_color(u32 format) -+{ -+ if (format >= ARRAY_SIZE(color_formats_table)) -+ return false; -+ -+ if (color_formats_table[format].valid_color) -+ return true; -+ -+ return false; -+} -+ -+static inline bool fmt_is_valid_texture(u32 format) -+{ -+ if (format >= ARRAY_SIZE(color_formats_table)) -+ return false; -+ -+ if (color_formats_table[format].blockwidth > 0) -+ return true; -+ -+ return false; -+} -+ -+static inline int fmt_get_blocksize(u32 format) -+{ -+ if (format >= ARRAY_SIZE(color_formats_table)) -+ return 0; -+ -+ return color_formats_table[format].blocksize; -+} -+ -+static inline int fmt_get_nblocksx(u32 format, u32 w) -+{ -+ unsigned bw; -+ -+ if (format >= ARRAY_SIZE(color_formats_table)) -+ return 0; -+ -+ bw = color_formats_table[format].blockwidth; -+ if (bw == 0) -+ return 0; -+ -+ return (w + bw - 1) / bw; -+} -+ -+static inline int fmt_get_nblocksy(u32 format, u32 h) -+{ -+ unsigned bh; -+ -+ if (format >= ARRAY_SIZE(color_formats_table)) -+ return 0; -+ -+ bh = color_formats_table[format].blockheight; -+ if (bh == 0) -+ return 0; -+ -+ return (h + bh - 1) / bh; -+} -+ - static inline int r600_bpe_from_format(u32 *bpe, u32 format) - { -- switch (format) { -- case V_038004_COLOR_8: -- case V_038004_COLOR_4_4: -- case V_038004_COLOR_3_3_2: -- case V_038004_FMT_1: -- *bpe = 1; -- break; -- case V_038004_COLOR_16: -- case V_038004_COLOR_16_FLOAT: -- case V_038004_COLOR_8_8: -- case V_038004_COLOR_5_6_5: -- case V_038004_COLOR_6_5_5: -- case V_038004_COLOR_1_5_5_5: -- case V_038004_COLOR_4_4_4_4: -- case V_038004_COLOR_5_5_5_1: -- *bpe = 2; -- break; -- case V_038004_FMT_8_8_8: -- *bpe = 3; -- break; -- case V_038004_COLOR_32: -- case V_038004_COLOR_32_FLOAT: -- case V_038004_COLOR_16_16: -- case V_038004_COLOR_16_16_FLOAT: -- case V_038004_COLOR_8_24: -- case V_038004_COLOR_8_24_FLOAT: -- case V_038004_COLOR_24_8: -- case V_038004_COLOR_24_8_FLOAT: -- case V_038004_COLOR_10_11_11: -- case V_038004_COLOR_10_11_11_FLOAT: -- case V_038004_COLOR_11_11_10: -- case V_038004_COLOR_11_11_10_FLOAT: -- case V_038004_COLOR_2_10_10_10: -- case V_038004_COLOR_8_8_8_8: -- case V_038004_COLOR_10_10_10_2: -- case V_038004_FMT_5_9_9_9_SHAREDEXP: -- case V_038004_FMT_32_AS_8: -- case V_038004_FMT_32_AS_8_8: -- *bpe = 4; -- break; -- case V_038004_COLOR_X24_8_32_FLOAT: -- case V_038004_COLOR_32_32: -- case V_038004_COLOR_32_32_FLOAT: -- case V_038004_COLOR_16_16_16_16: -- case V_038004_COLOR_16_16_16_16_FLOAT: -- *bpe = 8; -- break; -- case V_038004_FMT_16_16_16: -- case V_038004_FMT_16_16_16_FLOAT: -- *bpe = 6; -- break; -- case V_038004_FMT_32_32_32: -- case V_038004_FMT_32_32_32_FLOAT: -- *bpe = 12; -- break; -- case V_038004_COLOR_32_32_32_32: -- case V_038004_COLOR_32_32_32_32_FLOAT: -- *bpe = 16; -- break; -- case V_038004_FMT_GB_GR: -- case V_038004_FMT_BG_RG: -- case V_038004_COLOR_INVALID: -- default: -- *bpe = 16; -- return -EINVAL; -- } -+ unsigned res; -+ -+ if (format >= ARRAY_SIZE(color_formats_table)) -+ goto fail; -+ -+ res = color_formats_table[format].blocksize; -+ if (res == 0) -+ goto fail; -+ -+ *bpe = res; - return 0; -+ -+fail: -+ *bpe = 16; -+ return -EINVAL; - } - - struct array_mode_checker { -@@ -148,7 +240,7 @@ struct array_mode_checker { - u32 nbanks; - u32 npipes; - u32 nsamples; -- u32 bpe; -+ u32 blocksize; - }; - - /* returns alignment in pixels for pitch/height/depth and bytes for base */ -@@ -162,7 +254,7 @@ static inline int r600_get_array_mode_alignment(struct array_mode_checker *value - 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 tile_bytes = tile_width * tile_height * values->blocksize * values->nsamples; - u32 macro_tile_bytes = macro_tile_width * macro_tile_height * tile_bytes; - - switch (values->array_mode) { -@@ -174,7 +266,7 @@ static inline int r600_get_array_mode_alignment(struct array_mode_checker *value - *base_align = 1; - break; - case ARRAY_LINEAR_ALIGNED: -- *pitch_align = max((u32)64, (u32)(values->group_size / values->bpe)); -+ *pitch_align = max((u32)64, (u32)(values->group_size / values->blocksize)); - *height_align = tile_height; - *depth_align = 1; - *base_align = values->group_size; -@@ -182,7 +274,7 @@ static inline int r600_get_array_mode_alignment(struct array_mode_checker *value - case ARRAY_1D_TILED_THIN1: - *pitch_align = max((u32)tile_width, - (u32)(values->group_size / -- (tile_height * values->bpe * values->nsamples))); -+ (tile_height * values->blocksize * values->nsamples))); - *height_align = tile_height; - *depth_align = 1; - *base_align = values->group_size; -@@ -190,12 +282,12 @@ static inline int r600_get_array_mode_alignment(struct array_mode_checker *value - case ARRAY_2D_TILED_THIN1: - *pitch_align = max((u32)macro_tile_width, - (u32)(((values->group_size / tile_height) / -- (values->bpe * values->nsamples)) * -+ (values->blocksize * 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); -+ (*pitch_align) * values->blocksize * (*height_align) * values->nsamples); - break; - default: - return -EINVAL; -@@ -234,21 +326,22 @@ 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, slice_tile_max, size, tmp; -+ u32 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; -- -+ u32 format; - 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]) - track->cb_color_bo_offset[i]; -- if (r600_bpe_from_format(&bpe, G_0280A0_FORMAT(track->cb_color_info[i]))) { -+ format = G_0280A0_FORMAT(track->cb_color_info[i]); -+ if (!fmt_is_valid_color(format)) { - 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]), -+ __func__, __LINE__, format, - i, track->cb_color_info[i]); - return -EINVAL; - } -@@ -267,7 +360,7 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) - array_check.nbanks = track->nbanks; - array_check.npipes = track->npipes; - array_check.nsamples = track->nsamples; -- array_check.bpe = bpe; -+ array_check.blocksize = fmt_get_blocksize(format); - 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__, -@@ -311,7 +404,7 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) - } - - /* check offset */ -- tmp = height * pitch * bpe; -+ tmp = fmt_get_nblocksy(format, height) * fmt_get_nblocksx(format, pitch) * fmt_get_blocksize(format); - if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { - if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { - /* the initial DDX does bad things with the CB size occasionally */ -@@ -436,7 +529,7 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) - array_check.nbanks = track->nbanks; - array_check.npipes = track->npipes; - array_check.nsamples = track->nsamples; -- array_check.bpe = bpe; -+ array_check.blocksize = 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__, -@@ -1113,39 +1206,61 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx - return 0; - } - --static inline unsigned minify(unsigned size, unsigned levels) -+static inline unsigned mip_minify(unsigned size, unsigned level) - { -- size = size >> levels; -- if (size < 1) -- size = 1; -- return size; -+ unsigned val; -+ -+ val = max(1U, size >> level); -+ if (level > 0) -+ val = roundup_pow_of_two(val); -+ return val; - } - --static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels, -- unsigned w0, unsigned h0, unsigned d0, unsigned bpe, -- unsigned pitch_align, -+static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, -+ unsigned w0, unsigned h0, unsigned d0, unsigned format, -+ unsigned block_align, unsigned height_align, unsigned base_align, - unsigned *l0_size, unsigned *mipmap_size) - { -- unsigned offset, i, level, face; -- unsigned width, height, depth, rowstride, size; -- -- w0 = minify(w0, 0); -- h0 = minify(h0, 0); -- d0 = minify(d0, 0); -+ unsigned offset, i, level; -+ unsigned width, height, depth, size; -+ unsigned blocksize; -+ unsigned nbx, nby; -+ unsigned nlevels = llevel - blevel + 1; -+ -+ *l0_size = -1; -+ blocksize = fmt_get_blocksize(format); -+ -+ w0 = mip_minify(w0, 0); -+ h0 = mip_minify(h0, 0); -+ d0 = mip_minify(d0, 0); - for(i = 0, offset = 0, level = blevel; i < nlevels; i++, level++) { -- width = minify(w0, i); -- height = minify(h0, i); -- depth = minify(d0, i); -- for(face = 0; face < nfaces; face++) { -- rowstride = ALIGN((width * bpe), pitch_align); -- size = height * rowstride * depth; -- offset += size; -- offset = (offset + 0x1f) & ~0x1f; -- } -+ width = mip_minify(w0, i); -+ nbx = fmt_get_nblocksx(format, width); -+ -+ nbx = round_up(nbx, block_align); -+ -+ height = mip_minify(h0, i); -+ nby = fmt_get_nblocksy(format, height); -+ nby = round_up(nby, height_align); -+ -+ depth = mip_minify(d0, i); -+ -+ size = nbx * nby * blocksize; -+ if (nfaces) -+ size *= nfaces; -+ else -+ size *= depth; -+ -+ if (i == 0) -+ *l0_size = size; -+ -+ if (i == 0 || i == 1) -+ offset = round_up(offset, base_align); -+ -+ offset += size; - } -- *l0_size = ALIGN((w0 * bpe), pitch_align) * h0 * d0; - *mipmap_size = offset; -- if (!nlevels) -+ if (llevel == 0) - *mipmap_size = *l0_size; - if (!blevel) - *mipmap_size -= *l0_size; -@@ -1169,11 +1284,13 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i - 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 nfaces, llevel, blevel, w0, h0, d0; -+ u32 word0, word1, l0_size, mipmap_size, word2, word3; - u32 height_align, pitch, pitch_align, depth_align; -+ u32 array, barray, larray; - u64 base_align; - struct array_mode_checker array_check; -+ u32 format; - - /* on legacy kernel we don't perform advanced check */ - if (p->rdev == NULL) -@@ -1199,19 +1316,25 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i - case V_038000_SQ_TEX_DIM_3D: - break; - case V_038000_SQ_TEX_DIM_CUBEMAP: -- nfaces = 6; -+ if (p->family >= CHIP_RV770) -+ nfaces = 8; -+ else -+ nfaces = 6; - break; - case V_038000_SQ_TEX_DIM_1D_ARRAY: - case V_038000_SQ_TEX_DIM_2D_ARRAY: -+ array = 1; -+ break; - case V_038000_SQ_TEX_DIM_2D_MSAA: - case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: - default: - dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); - return -EINVAL; - } -- if (r600_bpe_from_format(&bpe, G_038004_DATA_FORMAT(word1))) { -+ format = G_038004_DATA_FORMAT(word1); -+ if (!fmt_is_valid_texture(format)) { - dev_warn(p->dev, "%s:%d texture invalid format %d\n", -- __func__, __LINE__, G_038004_DATA_FORMAT(word1)); -+ __func__, __LINE__, format); - return -EINVAL; - } - -@@ -1222,7 +1345,7 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i - array_check.nbanks = track->nbanks; - array_check.npipes = track->npipes; - array_check.nsamples = 1; -- array_check.bpe = bpe; -+ array_check.blocksize = fmt_get_blocksize(format); - 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", -@@ -1248,25 +1371,34 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i - return -EINVAL; - } - -+ word2 = radeon_get_ib_value(p, idx + 2) << 8; -+ word3 = radeon_get_ib_value(p, idx + 3) << 8; -+ - 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, -- (pitch_align * bpe), -+ llevel = G_038014_LAST_LEVEL(word1); -+ if (array == 1) { -+ barray = G_038014_BASE_ARRAY(word1); -+ larray = G_038014_LAST_ARRAY(word1); -+ -+ nfaces = larray - barray + 1; -+ } -+ r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, format, -+ pitch_align, height_align, base_align, - &l0_size, &mipmap_size); - /* using get ib will give us the offset into the texture bo */ -- word0 = radeon_get_ib_value(p, idx + 2) << 8; -- if ((l0_size + word0) > radeon_bo_size(texture)) { -+ if ((l0_size + word2) > 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)); -+ w0, h0, format, word2, l0_size, radeon_bo_size(texture)); -+ dev_warn(p->dev, "alignments %d %d %d %lld\n", pitch, pitch_align, height_align, base_align); - return -EINVAL; - } - /* using get ib will give us the offset into the mipmap bo */ -- word0 = radeon_get_ib_value(p, idx + 3) << 8; -- if ((mipmap_size + word0) > radeon_bo_size(mipmap)) { -+ word3 = radeon_get_ib_value(p, idx + 3) << 8; -+ if ((mipmap_size + word3) > 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));*/ -+ w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ - } - return 0; - } -@@ -1289,6 +1421,38 @@ static int r600_packet3_check(struct radeon_cs_parser *p, - idx_value = radeon_get_ib_value(p, idx); - - switch (pkt->opcode) { -+ case PACKET3_SET_PREDICATION: -+ { -+ int pred_op; -+ int tmp; -+ if (pkt->count != 1) { -+ DRM_ERROR("bad SET PREDICATION\n"); -+ return -EINVAL; -+ } -+ -+ tmp = radeon_get_ib_value(p, idx + 1); -+ pred_op = (tmp >> 16) & 0x7; -+ -+ /* for the clear predicate operation */ -+ if (pred_op == 0) -+ return 0; -+ -+ if (pred_op > 2) { -+ DRM_ERROR("bad SET PREDICATION operation %d\n", pred_op); -+ return -EINVAL; -+ } -+ -+ r = r600_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("bad SET PREDICATION\n"); -+ return -EINVAL; -+ } -+ -+ ib[idx + 0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff); -+ ib[idx + 1] = tmp + (upper_32_bits(reloc->lobj.gpu_offset) & 0xff); -+ } -+ break; -+ - case PACKET3_START_3D_CMDBUF: - if (p->family >= CHIP_RV770 || pkt->count) { - DRM_ERROR("bad START_3D\n"); -diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h -index 04bac0b..b2b944b 100644 ---- a/drivers/gpu/drm/radeon/r600d.h -+++ b/drivers/gpu/drm/radeon/r600d.h -@@ -1304,6 +1304,11 @@ - #define V_038004_FMT_16_16_16_FLOAT 0x0000002E - #define V_038004_FMT_32_32_32 0x0000002F - #define V_038004_FMT_32_32_32_FLOAT 0x00000030 -+#define V_038004_FMT_BC1 0x00000031 -+#define V_038004_FMT_BC2 0x00000032 -+#define V_038004_FMT_BC3 0x00000033 -+#define V_038004_FMT_BC4 0x00000034 -+#define V_038004_FMT_BC5 0x00000035 - #define R_038010_SQ_TEX_RESOURCE_WORD4_0 0x038010 - #define S_038010_FORMAT_COMP_X(x) (((x) & 0x3) << 0) - #define G_038010_FORMAT_COMP_X(x) (((x) >> 0) & 0x3) -diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h -index 6b34294..27df931 100644 ---- a/drivers/gpu/drm/radeon/radeon.h -+++ b/drivers/gpu/drm/radeon/radeon.h -@@ -177,7 +177,7 @@ void radeon_pm_suspend(struct radeon_device *rdev); - void radeon_pm_resume(struct radeon_device *rdev); - void radeon_combios_get_power_modes(struct radeon_device *rdev); - void radeon_atombios_get_power_modes(struct radeon_device *rdev); --void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level); -+void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type); - void rs690_pm_info(struct radeon_device *rdev); - extern int rv6xx_get_temp(struct radeon_device *rdev); - extern int rv770_get_temp(struct radeon_device *rdev); -@@ -651,6 +651,8 @@ struct radeon_wb { - - #define RADEON_WB_SCRATCH_OFFSET 0 - #define RADEON_WB_CP_RPTR_OFFSET 1024 -+#define RADEON_WB_CP1_RPTR_OFFSET 1280 -+#define RADEON_WB_CP2_RPTR_OFFSET 1536 - #define R600_WB_IH_WPTR_OFFSET 2048 - #define R600_WB_EVENT_OFFSET 3072 - -@@ -753,7 +755,9 @@ struct radeon_voltage { - u8 vddci_id; /* index into vddci voltage table */ - bool vddci_enabled; - /* r6xx+ sw */ -- u32 voltage; -+ u16 voltage; -+ /* evergreen+ vddci */ -+ u16 vddci; - }; - - /* clock mode flags */ -@@ -821,10 +825,12 @@ struct radeon_pm { - int default_power_state_index; - u32 current_sclk; - u32 current_mclk; -- u32 current_vddc; -+ u16 current_vddc; -+ u16 current_vddci; - u32 default_sclk; - u32 default_mclk; -- u32 default_vddc; -+ u16 default_vddc; -+ u16 default_vddci; - struct radeon_i2c_chan *i2c_bus; - /* selected pm method */ - enum radeon_pm_method pm_method; -@@ -1037,12 +1043,52 @@ struct evergreen_asic { - struct r100_gpu_lockup lockup; - }; - -+struct cayman_asic { -+ unsigned max_shader_engines; -+ unsigned max_pipes_per_simd; -+ unsigned max_tile_pipes; -+ unsigned max_simds_per_se; -+ unsigned max_backends_per_se; -+ unsigned max_texture_channel_caches; -+ unsigned max_gprs; -+ unsigned max_threads; -+ unsigned max_gs_threads; -+ unsigned max_stack_entries; -+ unsigned sx_num_of_sets; -+ unsigned sx_max_export_size; -+ unsigned sx_max_export_pos_size; -+ unsigned sx_max_export_smx_size; -+ unsigned max_hw_contexts; -+ unsigned sq_num_cf_insts; -+ unsigned sc_prim_fifo_size; -+ unsigned sc_hiz_tile_fifo_size; -+ unsigned sc_earlyz_tile_fifo_size; -+ -+ unsigned num_shader_engines; -+ unsigned num_shader_pipes_per_simd; -+ unsigned num_tile_pipes; -+ unsigned num_simds_per_se; -+ unsigned num_backends_per_se; -+ unsigned backend_disable_mask_per_asic; -+ unsigned backend_map; -+ unsigned num_texture_channel_caches; -+ unsigned mem_max_burst_length_bytes; -+ unsigned mem_row_size_in_kb; -+ unsigned shader_engine_tile_size; -+ unsigned num_gpus; -+ unsigned multi_gpu_tile_size; -+ -+ unsigned tile_config; -+ struct r100_gpu_lockup lockup; -+}; -+ - union radeon_asic_config { - struct r300_asic r300; - struct r100_asic r100; - struct r600_asic r600; - struct rv770_asic rv770; - struct evergreen_asic evergreen; -+ struct cayman_asic cayman; - }; - - /* -@@ -1133,6 +1179,9 @@ struct radeon_device { - struct radeon_mman mman; - struct radeon_fence_driver fence_drv; - struct radeon_cp cp; -+ /* cayman compute rings */ -+ struct radeon_cp cp1; -+ struct radeon_cp cp2; - struct radeon_ib_pool ib_pool; - struct radeon_irq irq; - struct radeon_asic *asic; -@@ -1504,7 +1553,7 @@ extern int evergreen_blit_init(struct radeon_device *rdev); - extern void evergreen_blit_fini(struct radeon_device *rdev); - - extern int ni_init_microcode(struct radeon_device *rdev); --extern int btc_mc_load_microcode(struct radeon_device *rdev); -+extern int ni_mc_load_microcode(struct radeon_device *rdev); - - /* radeon_acpi.c */ - #if defined(CONFIG_ACPI) -diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c -index 793c5e6..ca57619 100644 ---- a/drivers/gpu/drm/radeon/radeon_asic.c -+++ b/drivers/gpu/drm/radeon/radeon_asic.c -@@ -94,7 +94,7 @@ static void radeon_register_accessor_init(struct radeon_device *rdev) - rdev->mc_rreg = &rs600_mc_rreg; - rdev->mc_wreg = &rs600_mc_wreg; - } -- if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_HEMLOCK)) { -+ if (rdev->family >= CHIP_R600) { - rdev->pciep_rreg = &r600_pciep_rreg; - rdev->pciep_wreg = &r600_pciep_wreg; - } -@@ -885,6 +885,52 @@ static struct radeon_asic btc_asic = { - .post_page_flip = &evergreen_post_page_flip, - }; - -+static struct radeon_asic cayman_asic = { -+ .init = &cayman_init, -+ .fini = &cayman_fini, -+ .suspend = &cayman_suspend, -+ .resume = &cayman_resume, -+ .cp_commit = &r600_cp_commit, -+ .gpu_is_lockup = &cayman_gpu_is_lockup, -+ .asic_reset = &cayman_asic_reset, -+ .vga_set_state = &r600_vga_set_state, -+ .gart_tlb_flush = &cayman_pcie_gart_tlb_flush, -+ .gart_set_page = &rs600_gart_set_page, -+ .ring_test = &r600_ring_test, -+ .ring_ib_execute = &evergreen_ring_ib_execute, -+ .irq_set = &evergreen_irq_set, -+ .irq_process = &evergreen_irq_process, -+ .get_vblank_counter = &evergreen_get_vblank_counter, -+ .fence_ring_emit = &r600_fence_ring_emit, -+ .cs_parse = &evergreen_cs_parse, -+ .copy_blit = NULL, -+ .copy_dma = NULL, -+ .copy = NULL, -+ .get_engine_clock = &radeon_atom_get_engine_clock, -+ .set_engine_clock = &radeon_atom_set_engine_clock, -+ .get_memory_clock = &radeon_atom_get_memory_clock, -+ .set_memory_clock = &radeon_atom_set_memory_clock, -+ .get_pcie_lanes = NULL, -+ .set_pcie_lanes = NULL, -+ .set_clock_gating = NULL, -+ .set_surface_reg = r600_set_surface_reg, -+ .clear_surface_reg = r600_clear_surface_reg, -+ .bandwidth_update = &evergreen_bandwidth_update, -+ .hpd_init = &evergreen_hpd_init, -+ .hpd_fini = &evergreen_hpd_fini, -+ .hpd_sense = &evergreen_hpd_sense, -+ .hpd_set_polarity = &evergreen_hpd_set_polarity, -+ .gui_idle = &r600_gui_idle, -+ .pm_misc = &evergreen_pm_misc, -+ .pm_prepare = &evergreen_pm_prepare, -+ .pm_finish = &evergreen_pm_finish, -+ .pm_init_profile = &r600_pm_init_profile, -+ .pm_get_dynpm_state = &r600_pm_get_dynpm_state, -+ .pre_page_flip = &evergreen_pre_page_flip, -+ .page_flip = &evergreen_page_flip, -+ .post_page_flip = &evergreen_post_page_flip, -+}; -+ - int radeon_asic_init(struct radeon_device *rdev) - { - radeon_register_accessor_init(rdev); -@@ -977,6 +1023,9 @@ int radeon_asic_init(struct radeon_device *rdev) - case CHIP_CAICOS: - rdev->asic = &btc_asic; - break; -+ case CHIP_CAYMAN: -+ rdev->asic = &cayman_asic; -+ break; - default: - /* FIXME: not supported yet */ - return -EINVAL; -diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h -index c59bd98..82c4bc2 100644 ---- a/drivers/gpu/drm/radeon/radeon_asic.h -+++ b/drivers/gpu/drm/radeon/radeon_asic.h -@@ -375,4 +375,15 @@ extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); - extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); - extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); - -+/* -+ * cayman -+ */ -+void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev); -+int cayman_init(struct radeon_device *rdev); -+void cayman_fini(struct radeon_device *rdev); -+int cayman_suspend(struct radeon_device *rdev); -+int cayman_resume(struct radeon_device *rdev); -+bool cayman_gpu_is_lockup(struct radeon_device *rdev); -+int cayman_asic_reset(struct radeon_device *rdev); -+ - #endif -diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c -index 99768d9..f116516 100644 ---- a/drivers/gpu/drm/radeon/radeon_atombios.c -+++ b/drivers/gpu/drm/radeon/radeon_atombios.c -@@ -1599,9 +1599,10 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct - memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0], - fake_edid_record->ucFakeEDIDLength); - -- if (drm_edid_is_valid(edid)) -+ if (drm_edid_is_valid(edid)) { - rdev->mode_info.bios_hardcoded_edid = edid; -- else -+ rdev->mode_info.bios_hardcoded_edid_size = edid_size; -+ } else - kfree(edid); - } - } -@@ -2176,24 +2177,27 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r - } - } - --static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev) -+static void radeon_atombios_get_default_voltages(struct radeon_device *rdev, -+ u16 *vddc, u16 *vddci) - { - struct radeon_mode_info *mode_info = &rdev->mode_info; - int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); - u8 frev, crev; - u16 data_offset; - union firmware_info *firmware_info; -- u16 vddc = 0; -+ -+ *vddc = 0; -+ *vddci = 0; - - if (atom_parse_data_header(mode_info->atom_context, index, NULL, - &frev, &crev, &data_offset)) { - firmware_info = - (union firmware_info *)(mode_info->atom_context->bios + - data_offset); -- vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage); -+ *vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage); -+ if ((frev == 2) && (crev >= 2)) -+ *vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage); - } -- -- return vddc; - } - - static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev, -@@ -2203,7 +2207,9 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde - int j; - u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); - u32 misc2 = le16_to_cpu(non_clock_info->usClassification); -- u16 vddc = radeon_atombios_get_default_vddc(rdev); -+ u16 vddc, vddci; -+ -+ radeon_atombios_get_default_voltages(rdev, &vddc, &vddci); - - rdev->pm.power_state[state_index].misc = misc; - rdev->pm.power_state[state_index].misc2 = misc2; -@@ -2244,6 +2250,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde - rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; - rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; - rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage; -+ rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci; - } else { - /* patch the table values with the default slck/mclk from firmware info */ - for (j = 0; j < mode_index; j++) { -@@ -2286,6 +2293,8 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, - VOLTAGE_SW; - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = - le16_to_cpu(clock_info->evergreen.usVDDC); -+ rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci = -+ le16_to_cpu(clock_info->evergreen.usVDDCI); - } else { - sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); - sclk |= clock_info->r600.ucEngineClockHigh << 16; -@@ -2577,25 +2586,25 @@ union set_voltage { - struct _SET_VOLTAGE_PARAMETERS_V2 v2; - }; - --void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level) -+void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type) - { - union set_voltage args; - int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); -- u8 frev, crev, volt_index = level; -+ u8 frev, crev, volt_index = voltage_level; - - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) - return; - - switch (crev) { - case 1: -- args.v1.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC; -+ args.v1.ucVoltageType = voltage_type; - args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE; - args.v1.ucVoltageIndex = volt_index; - break; - case 2: -- args.v2.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC; -+ args.v2.ucVoltageType = voltage_type; - args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE; -- args.v2.usVoltageLevel = cpu_to_le16(level); -+ args.v2.usVoltageLevel = cpu_to_le16(voltage_level); - break; - default: - DRM_ERROR("Unknown table version %d, %d\n", frev, crev); -diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c -index cf602e2..8caf546 100644 ---- a/drivers/gpu/drm/radeon/radeon_combios.c -+++ b/drivers/gpu/drm/radeon/radeon_combios.c -@@ -2079,6 +2079,19 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) - DRM_MODE_CONNECTOR_DVII, &ddc_i2c, - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, - &hpd); -+ /* TV - TV DAC */ -+ ddc_i2c.valid = false; -+ hpd.hpd = RADEON_HPD_NONE; -+ radeon_add_legacy_encoder(dev, -+ radeon_get_encoder_enum(dev, -+ ATOM_DEVICE_TV1_SUPPORT, -+ 2), -+ ATOM_DEVICE_TV1_SUPPORT); -+ radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, -+ DRM_MODE_CONNECTOR_SVIDEO, -+ &ddc_i2c, -+ CONNECTOR_OBJECT_ID_SVIDEO, -+ &hpd); - break; - default: - DRM_INFO("Connector table: %d (invalid)\n", -diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c -index d83338b..a186673 100644 ---- a/drivers/gpu/drm/radeon/radeon_connectors.c -+++ b/drivers/gpu/drm/radeon/radeon_connectors.c -@@ -998,7 +998,16 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector, - (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || - (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) - return MODE_OK; -- else -+ else if (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_A) { -+ if (ASIC_IS_DCE3(rdev)) { -+ /* HDMI 1.3+ supports max clock of 340 Mhz */ -+ if (mode->clock > 340000) -+ return MODE_CLOCK_HIGH; -+ else -+ return MODE_OK; -+ } else -+ return MODE_CLOCK_HIGH; -+ } else - return MODE_CLOCK_HIGH; - } - return MODE_OK; -diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c -index 4954e2d..207d43f 100644 ---- a/drivers/gpu/drm/radeon/radeon_device.c -+++ b/drivers/gpu/drm/radeon/radeon_device.c -@@ -85,6 +85,7 @@ static const char radeon_family_name[][16] = { - "BARTS", - "TURKS", - "CAICOS", -+ "CAYMAN", - "LAST", - }; - -diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c -index 275b26a..0444911 100644 ---- a/drivers/gpu/drm/radeon/radeon_drv.c -+++ b/drivers/gpu/drm/radeon/radeon_drv.c -@@ -49,9 +49,10 @@ - * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500) - * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs - * 2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK, clock crystal query -+ * 2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query - */ - #define KMS_DRIVER_MAJOR 2 --#define KMS_DRIVER_MINOR 8 -+#define KMS_DRIVER_MINOR 9 - #define KMS_DRIVER_PATCHLEVEL 0 - int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); - int radeon_driver_unload_kms(struct drm_device *dev); -diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h -index 1ca55eb..6f1d9e5 100644 ---- a/drivers/gpu/drm/radeon/radeon_family.h -+++ b/drivers/gpu/drm/radeon/radeon_family.h -@@ -84,6 +84,7 @@ enum radeon_family { - CHIP_BARTS, - CHIP_TURKS, - CHIP_CAICOS, -+ CHIP_CAYMAN, - CHIP_LAST, - }; - -diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c -index 8387d32..d36fe3f 100644 ---- a/drivers/gpu/drm/radeon/radeon_kms.c -+++ b/drivers/gpu/drm/radeon/radeon_kms.c -@@ -169,7 +169,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) - value = rdev->accel_working; - break; - case RADEON_INFO_TILING_CONFIG: -- if (rdev->family >= CHIP_CEDAR) -+ if (rdev->family >= CHIP_CAYMAN) -+ value = rdev->config.cayman.tile_config; -+ else if (rdev->family >= CHIP_CEDAR) - value = rdev->config.evergreen.tile_config; - else if (rdev->family >= CHIP_RV770) - value = rdev->config.rv770.tile_config; -@@ -205,6 +207,36 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) - /* return clock value in KHz */ - value = rdev->clock.spll.reference_freq * 10; - break; -+ case RADEON_INFO_NUM_BACKENDS: -+ if (rdev->family >= CHIP_CAYMAN) -+ value = rdev->config.cayman.max_backends_per_se * -+ rdev->config.cayman.max_shader_engines; -+ else if (rdev->family >= CHIP_CEDAR) -+ value = rdev->config.evergreen.max_backends; -+ else if (rdev->family >= CHIP_RV770) -+ value = rdev->config.rv770.max_backends; -+ else if (rdev->family >= CHIP_R600) -+ value = rdev->config.r600.max_backends; -+ else { -+ return -EINVAL; -+ } -+ break; -+ case RADEON_INFO_NUM_TILE_PIPES: -+ if (rdev->family >= CHIP_CAYMAN) -+ value = rdev->config.cayman.max_tile_pipes; -+ else if (rdev->family >= CHIP_CEDAR) -+ value = rdev->config.evergreen.max_tile_pipes; -+ else if (rdev->family >= CHIP_RV770) -+ value = rdev->config.rv770.max_tile_pipes; -+ else if (rdev->family >= CHIP_R600) -+ value = rdev->config.r600.max_tile_pipes; -+ else { -+ return -EINVAL; -+ } -+ break; -+ case RADEON_INFO_FUSION_GART_WORKING: -+ value = 1; -+ break; - default: - DRM_DEBUG_KMS("Invalid request %d\n", info->request); - return -EINVAL; -diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c -index 2aed03b..320ddc3 100644 ---- a/drivers/gpu/drm/radeon/radeon_pm.c -+++ b/drivers/gpu/drm/radeon/radeon_pm.c -@@ -23,6 +23,7 @@ - #include "drmP.h" - #include "radeon.h" - #include "avivod.h" -+#include "atom.h" - #ifdef CONFIG_ACPI - #include - #endif -@@ -533,7 +534,11 @@ void radeon_pm_resume(struct radeon_device *rdev) - /* set up the default clocks if the MC ucode is loaded */ - if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { - if (rdev->pm.default_vddc) -- radeon_atom_set_voltage(rdev, rdev->pm.default_vddc); -+ radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, -+ SET_VOLTAGE_TYPE_ASIC_VDDC); -+ if (rdev->pm.default_vddci) -+ radeon_atom_set_voltage(rdev, rdev->pm.default_vddci, -+ SET_VOLTAGE_TYPE_ASIC_VDDCI); - if (rdev->pm.default_sclk) - radeon_set_engine_clock(rdev, rdev->pm.default_sclk); - if (rdev->pm.default_mclk) -@@ -546,6 +551,7 @@ void radeon_pm_resume(struct radeon_device *rdev) - rdev->pm.current_sclk = rdev->pm.default_sclk; - rdev->pm.current_mclk = rdev->pm.default_mclk; - rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; -+ rdev->pm.current_vddci = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.vddci; - if (rdev->pm.pm_method == PM_METHOD_DYNPM - && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) { - rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; -@@ -583,7 +589,8 @@ int radeon_pm_init(struct radeon_device *rdev) - /* set up the default clocks if the MC ucode is loaded */ - if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { - if (rdev->pm.default_vddc) -- radeon_atom_set_voltage(rdev, rdev->pm.default_vddc); -+ radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, -+ SET_VOLTAGE_TYPE_ASIC_VDDC); - if (rdev->pm.default_sclk) - radeon_set_engine_clock(rdev, rdev->pm.default_sclk); - if (rdev->pm.default_mclk) -diff --git a/drivers/gpu/drm/radeon/reg_srcs/cayman b/drivers/gpu/drm/radeon/reg_srcs/cayman -new file mode 100644 -index 0000000..6334f8a ---- /dev/null -+++ b/drivers/gpu/drm/radeon/reg_srcs/cayman -@@ -0,0 +1,619 @@ -+cayman 0x9400 -+0x0000802C GRBM_GFX_INDEX -+0x000088B0 VGT_VTX_VECT_EJECT_REG -+0x000088C4 VGT_CACHE_INVALIDATION -+0x000088D4 VGT_GS_VERTEX_REUSE -+0x00008958 VGT_PRIMITIVE_TYPE -+0x0000895C VGT_INDEX_TYPE -+0x00008970 VGT_NUM_INDICES -+0x00008974 VGT_NUM_INSTANCES -+0x00008990 VGT_COMPUTE_DIM_X -+0x00008994 VGT_COMPUTE_DIM_Y -+0x00008998 VGT_COMPUTE_DIM_Z -+0x0000899C VGT_COMPUTE_START_X -+0x000089A0 VGT_COMPUTE_START_Y -+0x000089A4 VGT_COMPUTE_START_Z -+0x000089A8 VGT_COMPUTE_INDEX -+0x000089AC VGT_COMPUTE_THREAD_GOURP_SIZE -+0x000089B0 VGT_HS_OFFCHIP_PARAM -+0x00008A14 PA_CL_ENHANCE -+0x00008A60 PA_SC_LINE_STIPPLE_VALUE -+0x00008B10 PA_SC_LINE_STIPPLE_STATE -+0x00008BF0 PA_SC_ENHANCE -+0x00008D8C SQ_DYN_GPR_CNTL_PS_FLUSH_REQ -+0x00008D94 SQ_DYN_GPR_SIMD_LOCK_EN -+0x00008C00 SQ_CONFIG -+0x00008C04 SQ_GPR_RESOURCE_MGMT_1 -+0x00008C10 SQ_GLOBAL_GPR_RESOURCE_MGMT_1 -+0x00008C14 SQ_GLOBAL_GPR_RESOURCE_MGMT_2 -+0x00008DF8 SQ_CONST_MEM_BASE -+0x00008E20 SQ_STATIC_THREAD_MGMT_1 -+0x00008E24 SQ_STATIC_THREAD_MGMT_2 -+0x00008E28 SQ_STATIC_THREAD_MGMT_3 -+0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS -+0x00009100 SPI_CONFIG_CNTL -+0x0000913C SPI_CONFIG_CNTL_1 -+0x00009830 DB_DEBUG -+0x00009834 DB_DEBUG2 -+0x00009838 DB_DEBUG3 -+0x0000983C DB_DEBUG4 -+0x00009854 DB_WATERMARKS -+0x0000A400 TD_PS_BORDER_COLOR_INDEX -+0x0000A404 TD_PS_BORDER_COLOR_RED -+0x0000A408 TD_PS_BORDER_COLOR_GREEN -+0x0000A40C TD_PS_BORDER_COLOR_BLUE -+0x0000A410 TD_PS_BORDER_COLOR_ALPHA -+0x0000A414 TD_VS_BORDER_COLOR_INDEX -+0x0000A418 TD_VS_BORDER_COLOR_RED -+0x0000A41C TD_VS_BORDER_COLOR_GREEN -+0x0000A420 TD_VS_BORDER_COLOR_BLUE -+0x0000A424 TD_VS_BORDER_COLOR_ALPHA -+0x0000A428 TD_GS_BORDER_COLOR_INDEX -+0x0000A42C TD_GS_BORDER_COLOR_RED -+0x0000A430 TD_GS_BORDER_COLOR_GREEN -+0x0000A434 TD_GS_BORDER_COLOR_BLUE -+0x0000A438 TD_GS_BORDER_COLOR_ALPHA -+0x0000A43C TD_HS_BORDER_COLOR_INDEX -+0x0000A440 TD_HS_BORDER_COLOR_RED -+0x0000A444 TD_HS_BORDER_COLOR_GREEN -+0x0000A448 TD_HS_BORDER_COLOR_BLUE -+0x0000A44C TD_HS_BORDER_COLOR_ALPHA -+0x0000A450 TD_LS_BORDER_COLOR_INDEX -+0x0000A454 TD_LS_BORDER_COLOR_RED -+0x0000A458 TD_LS_BORDER_COLOR_GREEN -+0x0000A45C TD_LS_BORDER_COLOR_BLUE -+0x0000A460 TD_LS_BORDER_COLOR_ALPHA -+0x0000A464 TD_CS_BORDER_COLOR_INDEX -+0x0000A468 TD_CS_BORDER_COLOR_RED -+0x0000A46C TD_CS_BORDER_COLOR_GREEN -+0x0000A470 TD_CS_BORDER_COLOR_BLUE -+0x0000A474 TD_CS_BORDER_COLOR_ALPHA -+0x00028000 DB_RENDER_CONTROL -+0x00028004 DB_COUNT_CONTROL -+0x0002800C DB_RENDER_OVERRIDE -+0x00028010 DB_RENDER_OVERRIDE2 -+0x00028028 DB_STENCIL_CLEAR -+0x0002802C DB_DEPTH_CLEAR -+0x00028030 PA_SC_SCREEN_SCISSOR_TL -+0x00028034 PA_SC_SCREEN_SCISSOR_BR -+0x0002805C DB_DEPTH_SLICE -+0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0 -+0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1 -+0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2 -+0x0002814C SQ_ALU_CONST_BUFFER_SIZE_PS_3 -+0x00028150 SQ_ALU_CONST_BUFFER_SIZE_PS_4 -+0x00028154 SQ_ALU_CONST_BUFFER_SIZE_PS_5 -+0x00028158 SQ_ALU_CONST_BUFFER_SIZE_PS_6 -+0x0002815C SQ_ALU_CONST_BUFFER_SIZE_PS_7 -+0x00028160 SQ_ALU_CONST_BUFFER_SIZE_PS_8 -+0x00028164 SQ_ALU_CONST_BUFFER_SIZE_PS_9 -+0x00028168 SQ_ALU_CONST_BUFFER_SIZE_PS_10 -+0x0002816C SQ_ALU_CONST_BUFFER_SIZE_PS_11 -+0x00028170 SQ_ALU_CONST_BUFFER_SIZE_PS_12 -+0x00028174 SQ_ALU_CONST_BUFFER_SIZE_PS_13 -+0x00028178 SQ_ALU_CONST_BUFFER_SIZE_PS_14 -+0x0002817C SQ_ALU_CONST_BUFFER_SIZE_PS_15 -+0x00028180 SQ_ALU_CONST_BUFFER_SIZE_VS_0 -+0x00028184 SQ_ALU_CONST_BUFFER_SIZE_VS_1 -+0x00028188 SQ_ALU_CONST_BUFFER_SIZE_VS_2 -+0x0002818C SQ_ALU_CONST_BUFFER_SIZE_VS_3 -+0x00028190 SQ_ALU_CONST_BUFFER_SIZE_VS_4 -+0x00028194 SQ_ALU_CONST_BUFFER_SIZE_VS_5 -+0x00028198 SQ_ALU_CONST_BUFFER_SIZE_VS_6 -+0x0002819C SQ_ALU_CONST_BUFFER_SIZE_VS_7 -+0x000281A0 SQ_ALU_CONST_BUFFER_SIZE_VS_8 -+0x000281A4 SQ_ALU_CONST_BUFFER_SIZE_VS_9 -+0x000281A8 SQ_ALU_CONST_BUFFER_SIZE_VS_10 -+0x000281AC SQ_ALU_CONST_BUFFER_SIZE_VS_11 -+0x000281B0 SQ_ALU_CONST_BUFFER_SIZE_VS_12 -+0x000281B4 SQ_ALU_CONST_BUFFER_SIZE_VS_13 -+0x000281B8 SQ_ALU_CONST_BUFFER_SIZE_VS_14 -+0x000281BC SQ_ALU_CONST_BUFFER_SIZE_VS_15 -+0x000281C0 SQ_ALU_CONST_BUFFER_SIZE_GS_0 -+0x000281C4 SQ_ALU_CONST_BUFFER_SIZE_GS_1 -+0x000281C8 SQ_ALU_CONST_BUFFER_SIZE_GS_2 -+0x000281CC SQ_ALU_CONST_BUFFER_SIZE_GS_3 -+0x000281D0 SQ_ALU_CONST_BUFFER_SIZE_GS_4 -+0x000281D4 SQ_ALU_CONST_BUFFER_SIZE_GS_5 -+0x000281D8 SQ_ALU_CONST_BUFFER_SIZE_GS_6 -+0x000281DC SQ_ALU_CONST_BUFFER_SIZE_GS_7 -+0x000281E0 SQ_ALU_CONST_BUFFER_SIZE_GS_8 -+0x000281E4 SQ_ALU_CONST_BUFFER_SIZE_GS_9 -+0x000281E8 SQ_ALU_CONST_BUFFER_SIZE_GS_10 -+0x000281EC SQ_ALU_CONST_BUFFER_SIZE_GS_11 -+0x000281F0 SQ_ALU_CONST_BUFFER_SIZE_GS_12 -+0x000281F4 SQ_ALU_CONST_BUFFER_SIZE_GS_13 -+0x000281F8 SQ_ALU_CONST_BUFFER_SIZE_GS_14 -+0x000281FC SQ_ALU_CONST_BUFFER_SIZE_GS_15 -+0x00028200 PA_SC_WINDOW_OFFSET -+0x00028204 PA_SC_WINDOW_SCISSOR_TL -+0x00028208 PA_SC_WINDOW_SCISSOR_BR -+0x0002820C PA_SC_CLIPRECT_RULE -+0x00028210 PA_SC_CLIPRECT_0_TL -+0x00028214 PA_SC_CLIPRECT_0_BR -+0x00028218 PA_SC_CLIPRECT_1_TL -+0x0002821C PA_SC_CLIPRECT_1_BR -+0x00028220 PA_SC_CLIPRECT_2_TL -+0x00028224 PA_SC_CLIPRECT_2_BR -+0x00028228 PA_SC_CLIPRECT_3_TL -+0x0002822C PA_SC_CLIPRECT_3_BR -+0x00028230 PA_SC_EDGERULE -+0x00028234 PA_SU_HARDWARE_SCREEN_OFFSET -+0x00028240 PA_SC_GENERIC_SCISSOR_TL -+0x00028244 PA_SC_GENERIC_SCISSOR_BR -+0x00028250 PA_SC_VPORT_SCISSOR_0_TL -+0x00028254 PA_SC_VPORT_SCISSOR_0_BR -+0x00028258 PA_SC_VPORT_SCISSOR_1_TL -+0x0002825C PA_SC_VPORT_SCISSOR_1_BR -+0x00028260 PA_SC_VPORT_SCISSOR_2_TL -+0x00028264 PA_SC_VPORT_SCISSOR_2_BR -+0x00028268 PA_SC_VPORT_SCISSOR_3_TL -+0x0002826C PA_SC_VPORT_SCISSOR_3_BR -+0x00028270 PA_SC_VPORT_SCISSOR_4_TL -+0x00028274 PA_SC_VPORT_SCISSOR_4_BR -+0x00028278 PA_SC_VPORT_SCISSOR_5_TL -+0x0002827C PA_SC_VPORT_SCISSOR_5_BR -+0x00028280 PA_SC_VPORT_SCISSOR_6_TL -+0x00028284 PA_SC_VPORT_SCISSOR_6_BR -+0x00028288 PA_SC_VPORT_SCISSOR_7_TL -+0x0002828C PA_SC_VPORT_SCISSOR_7_BR -+0x00028290 PA_SC_VPORT_SCISSOR_8_TL -+0x00028294 PA_SC_VPORT_SCISSOR_8_BR -+0x00028298 PA_SC_VPORT_SCISSOR_9_TL -+0x0002829C PA_SC_VPORT_SCISSOR_9_BR -+0x000282A0 PA_SC_VPORT_SCISSOR_10_TL -+0x000282A4 PA_SC_VPORT_SCISSOR_10_BR -+0x000282A8 PA_SC_VPORT_SCISSOR_11_TL -+0x000282AC PA_SC_VPORT_SCISSOR_11_BR -+0x000282B0 PA_SC_VPORT_SCISSOR_12_TL -+0x000282B4 PA_SC_VPORT_SCISSOR_12_BR -+0x000282B8 PA_SC_VPORT_SCISSOR_13_TL -+0x000282BC PA_SC_VPORT_SCISSOR_13_BR -+0x000282C0 PA_SC_VPORT_SCISSOR_14_TL -+0x000282C4 PA_SC_VPORT_SCISSOR_14_BR -+0x000282C8 PA_SC_VPORT_SCISSOR_15_TL -+0x000282CC PA_SC_VPORT_SCISSOR_15_BR -+0x000282D0 PA_SC_VPORT_ZMIN_0 -+0x000282D4 PA_SC_VPORT_ZMAX_0 -+0x000282D8 PA_SC_VPORT_ZMIN_1 -+0x000282DC PA_SC_VPORT_ZMAX_1 -+0x000282E0 PA_SC_VPORT_ZMIN_2 -+0x000282E4 PA_SC_VPORT_ZMAX_2 -+0x000282E8 PA_SC_VPORT_ZMIN_3 -+0x000282EC PA_SC_VPORT_ZMAX_3 -+0x000282F0 PA_SC_VPORT_ZMIN_4 -+0x000282F4 PA_SC_VPORT_ZMAX_4 -+0x000282F8 PA_SC_VPORT_ZMIN_5 -+0x000282FC PA_SC_VPORT_ZMAX_5 -+0x00028300 PA_SC_VPORT_ZMIN_6 -+0x00028304 PA_SC_VPORT_ZMAX_6 -+0x00028308 PA_SC_VPORT_ZMIN_7 -+0x0002830C PA_SC_VPORT_ZMAX_7 -+0x00028310 PA_SC_VPORT_ZMIN_8 -+0x00028314 PA_SC_VPORT_ZMAX_8 -+0x00028318 PA_SC_VPORT_ZMIN_9 -+0x0002831C PA_SC_VPORT_ZMAX_9 -+0x00028320 PA_SC_VPORT_ZMIN_10 -+0x00028324 PA_SC_VPORT_ZMAX_10 -+0x00028328 PA_SC_VPORT_ZMIN_11 -+0x0002832C PA_SC_VPORT_ZMAX_11 -+0x00028330 PA_SC_VPORT_ZMIN_12 -+0x00028334 PA_SC_VPORT_ZMAX_12 -+0x00028338 PA_SC_VPORT_ZMIN_13 -+0x0002833C PA_SC_VPORT_ZMAX_13 -+0x00028340 PA_SC_VPORT_ZMIN_14 -+0x00028344 PA_SC_VPORT_ZMAX_14 -+0x00028348 PA_SC_VPORT_ZMIN_15 -+0x0002834C PA_SC_VPORT_ZMAX_15 -+0x00028350 SX_MISC -+0x00028354 SX_SURFACE_SYNC -+0x00028380 SQ_VTX_SEMANTIC_0 -+0x00028384 SQ_VTX_SEMANTIC_1 -+0x00028388 SQ_VTX_SEMANTIC_2 -+0x0002838C SQ_VTX_SEMANTIC_3 -+0x00028390 SQ_VTX_SEMANTIC_4 -+0x00028394 SQ_VTX_SEMANTIC_5 -+0x00028398 SQ_VTX_SEMANTIC_6 -+0x0002839C SQ_VTX_SEMANTIC_7 -+0x000283A0 SQ_VTX_SEMANTIC_8 -+0x000283A4 SQ_VTX_SEMANTIC_9 -+0x000283A8 SQ_VTX_SEMANTIC_10 -+0x000283AC SQ_VTX_SEMANTIC_11 -+0x000283B0 SQ_VTX_SEMANTIC_12 -+0x000283B4 SQ_VTX_SEMANTIC_13 -+0x000283B8 SQ_VTX_SEMANTIC_14 -+0x000283BC SQ_VTX_SEMANTIC_15 -+0x000283C0 SQ_VTX_SEMANTIC_16 -+0x000283C4 SQ_VTX_SEMANTIC_17 -+0x000283C8 SQ_VTX_SEMANTIC_18 -+0x000283CC SQ_VTX_SEMANTIC_19 -+0x000283D0 SQ_VTX_SEMANTIC_20 -+0x000283D4 SQ_VTX_SEMANTIC_21 -+0x000283D8 SQ_VTX_SEMANTIC_22 -+0x000283DC SQ_VTX_SEMANTIC_23 -+0x000283E0 SQ_VTX_SEMANTIC_24 -+0x000283E4 SQ_VTX_SEMANTIC_25 -+0x000283E8 SQ_VTX_SEMANTIC_26 -+0x000283EC SQ_VTX_SEMANTIC_27 -+0x000283F0 SQ_VTX_SEMANTIC_28 -+0x000283F4 SQ_VTX_SEMANTIC_29 -+0x000283F8 SQ_VTX_SEMANTIC_30 -+0x000283FC SQ_VTX_SEMANTIC_31 -+0x00028400 VGT_MAX_VTX_INDX -+0x00028404 VGT_MIN_VTX_INDX -+0x00028408 VGT_INDX_OFFSET -+0x0002840C VGT_MULTI_PRIM_IB_RESET_INDX -+0x00028410 SX_ALPHA_TEST_CONTROL -+0x00028414 CB_BLEND_RED -+0x00028418 CB_BLEND_GREEN -+0x0002841C CB_BLEND_BLUE -+0x00028420 CB_BLEND_ALPHA -+0x00028430 DB_STENCILREFMASK -+0x00028434 DB_STENCILREFMASK_BF -+0x00028438 SX_ALPHA_REF -+0x0002843C PA_CL_VPORT_XSCALE_0 -+0x00028440 PA_CL_VPORT_XOFFSET_0 -+0x00028444 PA_CL_VPORT_YSCALE_0 -+0x00028448 PA_CL_VPORT_YOFFSET_0 -+0x0002844C PA_CL_VPORT_ZSCALE_0 -+0x00028450 PA_CL_VPORT_ZOFFSET_0 -+0x00028454 PA_CL_VPORT_XSCALE_1 -+0x00028458 PA_CL_VPORT_XOFFSET_1 -+0x0002845C PA_CL_VPORT_YSCALE_1 -+0x00028460 PA_CL_VPORT_YOFFSET_1 -+0x00028464 PA_CL_VPORT_ZSCALE_1 -+0x00028468 PA_CL_VPORT_ZOFFSET_1 -+0x0002846C PA_CL_VPORT_XSCALE_2 -+0x00028470 PA_CL_VPORT_XOFFSET_2 -+0x00028474 PA_CL_VPORT_YSCALE_2 -+0x00028478 PA_CL_VPORT_YOFFSET_2 -+0x0002847C PA_CL_VPORT_ZSCALE_2 -+0x00028480 PA_CL_VPORT_ZOFFSET_2 -+0x00028484 PA_CL_VPORT_XSCALE_3 -+0x00028488 PA_CL_VPORT_XOFFSET_3 -+0x0002848C PA_CL_VPORT_YSCALE_3 -+0x00028490 PA_CL_VPORT_YOFFSET_3 -+0x00028494 PA_CL_VPORT_ZSCALE_3 -+0x00028498 PA_CL_VPORT_ZOFFSET_3 -+0x0002849C PA_CL_VPORT_XSCALE_4 -+0x000284A0 PA_CL_VPORT_XOFFSET_4 -+0x000284A4 PA_CL_VPORT_YSCALE_4 -+0x000284A8 PA_CL_VPORT_YOFFSET_4 -+0x000284AC PA_CL_VPORT_ZSCALE_4 -+0x000284B0 PA_CL_VPORT_ZOFFSET_4 -+0x000284B4 PA_CL_VPORT_XSCALE_5 -+0x000284B8 PA_CL_VPORT_XOFFSET_5 -+0x000284BC PA_CL_VPORT_YSCALE_5 -+0x000284C0 PA_CL_VPORT_YOFFSET_5 -+0x000284C4 PA_CL_VPORT_ZSCALE_5 -+0x000284C8 PA_CL_VPORT_ZOFFSET_5 -+0x000284CC PA_CL_VPORT_XSCALE_6 -+0x000284D0 PA_CL_VPORT_XOFFSET_6 -+0x000284D4 PA_CL_VPORT_YSCALE_6 -+0x000284D8 PA_CL_VPORT_YOFFSET_6 -+0x000284DC PA_CL_VPORT_ZSCALE_6 -+0x000284E0 PA_CL_VPORT_ZOFFSET_6 -+0x000284E4 PA_CL_VPORT_XSCALE_7 -+0x000284E8 PA_CL_VPORT_XOFFSET_7 -+0x000284EC PA_CL_VPORT_YSCALE_7 -+0x000284F0 PA_CL_VPORT_YOFFSET_7 -+0x000284F4 PA_CL_VPORT_ZSCALE_7 -+0x000284F8 PA_CL_VPORT_ZOFFSET_7 -+0x000284FC PA_CL_VPORT_XSCALE_8 -+0x00028500 PA_CL_VPORT_XOFFSET_8 -+0x00028504 PA_CL_VPORT_YSCALE_8 -+0x00028508 PA_CL_VPORT_YOFFSET_8 -+0x0002850C PA_CL_VPORT_ZSCALE_8 -+0x00028510 PA_CL_VPORT_ZOFFSET_8 -+0x00028514 PA_CL_VPORT_XSCALE_9 -+0x00028518 PA_CL_VPORT_XOFFSET_9 -+0x0002851C PA_CL_VPORT_YSCALE_9 -+0x00028520 PA_CL_VPORT_YOFFSET_9 -+0x00028524 PA_CL_VPORT_ZSCALE_9 -+0x00028528 PA_CL_VPORT_ZOFFSET_9 -+0x0002852C PA_CL_VPORT_XSCALE_10 -+0x00028530 PA_CL_VPORT_XOFFSET_10 -+0x00028534 PA_CL_VPORT_YSCALE_10 -+0x00028538 PA_CL_VPORT_YOFFSET_10 -+0x0002853C PA_CL_VPORT_ZSCALE_10 -+0x00028540 PA_CL_VPORT_ZOFFSET_10 -+0x00028544 PA_CL_VPORT_XSCALE_11 -+0x00028548 PA_CL_VPORT_XOFFSET_11 -+0x0002854C PA_CL_VPORT_YSCALE_11 -+0x00028550 PA_CL_VPORT_YOFFSET_11 -+0x00028554 PA_CL_VPORT_ZSCALE_11 -+0x00028558 PA_CL_VPORT_ZOFFSET_11 -+0x0002855C PA_CL_VPORT_XSCALE_12 -+0x00028560 PA_CL_VPORT_XOFFSET_12 -+0x00028564 PA_CL_VPORT_YSCALE_12 -+0x00028568 PA_CL_VPORT_YOFFSET_12 -+0x0002856C PA_CL_VPORT_ZSCALE_12 -+0x00028570 PA_CL_VPORT_ZOFFSET_12 -+0x00028574 PA_CL_VPORT_XSCALE_13 -+0x00028578 PA_CL_VPORT_XOFFSET_13 -+0x0002857C PA_CL_VPORT_YSCALE_13 -+0x00028580 PA_CL_VPORT_YOFFSET_13 -+0x00028584 PA_CL_VPORT_ZSCALE_13 -+0x00028588 PA_CL_VPORT_ZOFFSET_13 -+0x0002858C PA_CL_VPORT_XSCALE_14 -+0x00028590 PA_CL_VPORT_XOFFSET_14 -+0x00028594 PA_CL_VPORT_YSCALE_14 -+0x00028598 PA_CL_VPORT_YOFFSET_14 -+0x0002859C PA_CL_VPORT_ZSCALE_14 -+0x000285A0 PA_CL_VPORT_ZOFFSET_14 -+0x000285A4 PA_CL_VPORT_XSCALE_15 -+0x000285A8 PA_CL_VPORT_XOFFSET_15 -+0x000285AC PA_CL_VPORT_YSCALE_15 -+0x000285B0 PA_CL_VPORT_YOFFSET_15 -+0x000285B4 PA_CL_VPORT_ZSCALE_15 -+0x000285B8 PA_CL_VPORT_ZOFFSET_15 -+0x000285BC PA_CL_UCP_0_X -+0x000285C0 PA_CL_UCP_0_Y -+0x000285C4 PA_CL_UCP_0_Z -+0x000285C8 PA_CL_UCP_0_W -+0x000285CC PA_CL_UCP_1_X -+0x000285D0 PA_CL_UCP_1_Y -+0x000285D4 PA_CL_UCP_1_Z -+0x000285D8 PA_CL_UCP_1_W -+0x000285DC PA_CL_UCP_2_X -+0x000285E0 PA_CL_UCP_2_Y -+0x000285E4 PA_CL_UCP_2_Z -+0x000285E8 PA_CL_UCP_2_W -+0x000285EC PA_CL_UCP_3_X -+0x000285F0 PA_CL_UCP_3_Y -+0x000285F4 PA_CL_UCP_3_Z -+0x000285F8 PA_CL_UCP_3_W -+0x000285FC PA_CL_UCP_4_X -+0x00028600 PA_CL_UCP_4_Y -+0x00028604 PA_CL_UCP_4_Z -+0x00028608 PA_CL_UCP_4_W -+0x0002860C PA_CL_UCP_5_X -+0x00028610 PA_CL_UCP_5_Y -+0x00028614 PA_CL_UCP_5_Z -+0x00028618 PA_CL_UCP_5_W -+0x0002861C SPI_VS_OUT_ID_0 -+0x00028620 SPI_VS_OUT_ID_1 -+0x00028624 SPI_VS_OUT_ID_2 -+0x00028628 SPI_VS_OUT_ID_3 -+0x0002862C SPI_VS_OUT_ID_4 -+0x00028630 SPI_VS_OUT_ID_5 -+0x00028634 SPI_VS_OUT_ID_6 -+0x00028638 SPI_VS_OUT_ID_7 -+0x0002863C SPI_VS_OUT_ID_8 -+0x00028640 SPI_VS_OUT_ID_9 -+0x00028644 SPI_PS_INPUT_CNTL_0 -+0x00028648 SPI_PS_INPUT_CNTL_1 -+0x0002864C SPI_PS_INPUT_CNTL_2 -+0x00028650 SPI_PS_INPUT_CNTL_3 -+0x00028654 SPI_PS_INPUT_CNTL_4 -+0x00028658 SPI_PS_INPUT_CNTL_5 -+0x0002865C SPI_PS_INPUT_CNTL_6 -+0x00028660 SPI_PS_INPUT_CNTL_7 -+0x00028664 SPI_PS_INPUT_CNTL_8 -+0x00028668 SPI_PS_INPUT_CNTL_9 -+0x0002866C SPI_PS_INPUT_CNTL_10 -+0x00028670 SPI_PS_INPUT_CNTL_11 -+0x00028674 SPI_PS_INPUT_CNTL_12 -+0x00028678 SPI_PS_INPUT_CNTL_13 -+0x0002867C SPI_PS_INPUT_CNTL_14 -+0x00028680 SPI_PS_INPUT_CNTL_15 -+0x00028684 SPI_PS_INPUT_CNTL_16 -+0x00028688 SPI_PS_INPUT_CNTL_17 -+0x0002868C SPI_PS_INPUT_CNTL_18 -+0x00028690 SPI_PS_INPUT_CNTL_19 -+0x00028694 SPI_PS_INPUT_CNTL_20 -+0x00028698 SPI_PS_INPUT_CNTL_21 -+0x0002869C SPI_PS_INPUT_CNTL_22 -+0x000286A0 SPI_PS_INPUT_CNTL_23 -+0x000286A4 SPI_PS_INPUT_CNTL_24 -+0x000286A8 SPI_PS_INPUT_CNTL_25 -+0x000286AC SPI_PS_INPUT_CNTL_26 -+0x000286B0 SPI_PS_INPUT_CNTL_27 -+0x000286B4 SPI_PS_INPUT_CNTL_28 -+0x000286B8 SPI_PS_INPUT_CNTL_29 -+0x000286BC SPI_PS_INPUT_CNTL_30 -+0x000286C0 SPI_PS_INPUT_CNTL_31 -+0x000286C4 SPI_VS_OUT_CONFIG -+0x000286C8 SPI_THREAD_GROUPING -+0x000286CC SPI_PS_IN_CONTROL_0 -+0x000286D0 SPI_PS_IN_CONTROL_1 -+0x000286D4 SPI_INTERP_CONTROL_0 -+0x000286D8 SPI_INPUT_Z -+0x000286DC SPI_FOG_CNTL -+0x000286E0 SPI_BARYC_CNTL -+0x000286E4 SPI_PS_IN_CONTROL_2 -+0x000286E8 SPI_COMPUTE_INPUT_CNTL -+0x000286EC SPI_COMPUTE_NUM_THREAD_X -+0x000286F0 SPI_COMPUTE_NUM_THREAD_Y -+0x000286F4 SPI_COMPUTE_NUM_THREAD_Z -+0x000286F8 SPI_GPR_MGMT -+0x000286FC SPI_LDS_MGMT -+0x00028700 SPI_STACK_MGMT -+0x00028704 SPI_WAVE_MGMT_1 -+0x00028708 SPI_WAVE_MGMT_2 -+0x00028724 GDS_ADDR_SIZE -+0x00028780 CB_BLEND0_CONTROL -+0x00028784 CB_BLEND1_CONTROL -+0x00028788 CB_BLEND2_CONTROL -+0x0002878C CB_BLEND3_CONTROL -+0x00028790 CB_BLEND4_CONTROL -+0x00028794 CB_BLEND5_CONTROL -+0x00028798 CB_BLEND6_CONTROL -+0x0002879C CB_BLEND7_CONTROL -+0x000287CC CS_COPY_STATE -+0x000287D0 GFX_COPY_STATE -+0x000287D4 PA_CL_POINT_X_RAD -+0x000287D8 PA_CL_POINT_Y_RAD -+0x000287DC PA_CL_POINT_SIZE -+0x000287E0 PA_CL_POINT_CULL_RAD -+0x00028808 CB_COLOR_CONTROL -+0x0002880C DB_SHADER_CONTROL -+0x00028810 PA_CL_CLIP_CNTL -+0x00028814 PA_SU_SC_MODE_CNTL -+0x00028818 PA_CL_VTE_CNTL -+0x0002881C PA_CL_VS_OUT_CNTL -+0x00028820 PA_CL_NANINF_CNTL -+0x00028824 PA_SU_LINE_STIPPLE_CNTL -+0x00028828 PA_SU_LINE_STIPPLE_SCALE -+0x0002882C PA_SU_PRIM_FILTER_CNTL -+0x00028844 SQ_PGM_RESOURCES_PS -+0x00028848 SQ_PGM_RESOURCES_2_PS -+0x0002884C SQ_PGM_EXPORTS_PS -+0x00028860 SQ_PGM_RESOURCES_VS -+0x00028864 SQ_PGM_RESOURCES_2_VS -+0x00028878 SQ_PGM_RESOURCES_GS -+0x0002887C SQ_PGM_RESOURCES_2_GS -+0x00028890 SQ_PGM_RESOURCES_ES -+0x00028894 SQ_PGM_RESOURCES_2_ES -+0x000288A8 SQ_PGM_RESOURCES_FS -+0x000288BC SQ_PGM_RESOURCES_HS -+0x000288C0 SQ_PGM_RESOURCES_2_HS -+0x000288D4 SQ_PGM_RESOURCES_LS -+0x000288D8 SQ_PGM_RESOURCES_2_LS -+0x000288E8 SQ_LDS_ALLOC -+0x000288EC SQ_LDS_ALLOC_PS -+0x000288F0 SQ_VTX_SEMANTIC_CLEAR -+0x00028A00 PA_SU_POINT_SIZE -+0x00028A04 PA_SU_POINT_MINMAX -+0x00028A08 PA_SU_LINE_CNTL -+0x00028A0C PA_SC_LINE_STIPPLE -+0x00028A10 VGT_OUTPUT_PATH_CNTL -+0x00028A14 VGT_HOS_CNTL -+0x00028A18 VGT_HOS_MAX_TESS_LEVEL -+0x00028A1C VGT_HOS_MIN_TESS_LEVEL -+0x00028A20 VGT_HOS_REUSE_DEPTH -+0x00028A24 VGT_GROUP_PRIM_TYPE -+0x00028A28 VGT_GROUP_FIRST_DECR -+0x00028A2C VGT_GROUP_DECR -+0x00028A30 VGT_GROUP_VECT_0_CNTL -+0x00028A34 VGT_GROUP_VECT_1_CNTL -+0x00028A38 VGT_GROUP_VECT_0_FMT_CNTL -+0x00028A3C VGT_GROUP_VECT_1_FMT_CNTL -+0x00028A40 VGT_GS_MODE -+0x00028A48 PA_SC_MODE_CNTL_0 -+0x00028A4C PA_SC_MODE_CNTL_1 -+0x00028A50 VGT_ENHANCE -+0x00028A54 VGT_GS_PER_ES -+0x00028A58 VGT_ES_PER_GS -+0x00028A5C VGT_GS_PER_VS -+0x00028A6C VGT_GS_OUT_PRIM_TYPE -+0x00028A70 IA_ENHANCE -+0x00028A84 VGT_PRIMITIVEID_EN -+0x00028A94 VGT_MULTI_PRIM_IB_RESET_EN -+0x00028AA0 VGT_INSTANCE_STEP_RATE_0 -+0x00028AA4 VGT_INSTANCE_STEP_RATE_1 -+0x00028AA8 IA_MULTI_VGT_PARAM -+0x00028AB4 VGT_REUSE_OFF -+0x00028AB8 VGT_VTX_CNT_EN -+0x00028ABC DB_HTILE_SURFACE -+0x00028AC0 DB_SRESULTS_COMPARE_STATE0 -+0x00028AC4 DB_SRESULTS_COMPARE_STATE1 -+0x00028AC8 DB_PRELOAD_CONTROL -+0x00028B38 VGT_GS_MAX_VERT_OUT -+0x00028B54 VGT_SHADER_STAGES_EN -+0x00028B58 VGT_LS_HS_CONFIG -+0x00028B6C VGT_TF_PARAM -+0x00028B70 DB_ALPHA_TO_MASK -+0x00028B74 VGT_DISPATCH_INITIATOR -+0x00028B78 PA_SU_POLY_OFFSET_DB_FMT_CNTL -+0x00028B7C PA_SU_POLY_OFFSET_CLAMP -+0x00028B80 PA_SU_POLY_OFFSET_FRONT_SCALE -+0x00028B84 PA_SU_POLY_OFFSET_FRONT_OFFSET -+0x00028B88 PA_SU_POLY_OFFSET_BACK_SCALE -+0x00028B8C PA_SU_POLY_OFFSET_BACK_OFFSET -+0x00028B74 VGT_GS_INSTANCE_CNT -+0x00028BD4 PA_SC_CENTROID_PRIORITY_0 -+0x00028BD8 PA_SC_CENTROID_PRIORITY_1 -+0x00028BDC PA_SC_LINE_CNTL -+0x00028BE4 PA_SU_VTX_CNTL -+0x00028BE8 PA_CL_GB_VERT_CLIP_ADJ -+0x00028BEC PA_CL_GB_VERT_DISC_ADJ -+0x00028BF0 PA_CL_GB_HORZ_CLIP_ADJ -+0x00028BF4 PA_CL_GB_HORZ_DISC_ADJ -+0x00028BF8 PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y0_0 -+0x00028BFC PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y0_1 -+0x00028C00 PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y0_2 -+0x00028C04 PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y0_3 -+0x00028C08 PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y0_0 -+0x00028C0C PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y0_1 -+0x00028C10 PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y0_2 -+0x00028C14 PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y0_3 -+0x00028C18 PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y1_0 -+0x00028C1C PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y1_1 -+0x00028C20 PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y1_2 -+0x00028C24 PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y1_3 -+0x00028C28 PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y1_0 -+0x00028C2C PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y1_1 -+0x00028C30 PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y1_2 -+0x00028C34 PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y1_3 -+0x00028C38 PA_SC_AA_MASK_X0_Y0_X1_Y0 -+0x00028C3C PA_SC_AA_MASK_X0_Y1_X1_Y1 -+0x00028C8C CB_COLOR0_CLEAR_WORD0 -+0x00028C90 CB_COLOR0_CLEAR_WORD1 -+0x00028C94 CB_COLOR0_CLEAR_WORD2 -+0x00028C98 CB_COLOR0_CLEAR_WORD3 -+0x00028CC8 CB_COLOR1_CLEAR_WORD0 -+0x00028CCC CB_COLOR1_CLEAR_WORD1 -+0x00028CD0 CB_COLOR1_CLEAR_WORD2 -+0x00028CD4 CB_COLOR1_CLEAR_WORD3 -+0x00028D04 CB_COLOR2_CLEAR_WORD0 -+0x00028D08 CB_COLOR2_CLEAR_WORD1 -+0x00028D0C CB_COLOR2_CLEAR_WORD2 -+0x00028D10 CB_COLOR2_CLEAR_WORD3 -+0x00028D40 CB_COLOR3_CLEAR_WORD0 -+0x00028D44 CB_COLOR3_CLEAR_WORD1 -+0x00028D48 CB_COLOR3_CLEAR_WORD2 -+0x00028D4C CB_COLOR3_CLEAR_WORD3 -+0x00028D7C CB_COLOR4_CLEAR_WORD0 -+0x00028D80 CB_COLOR4_CLEAR_WORD1 -+0x00028D84 CB_COLOR4_CLEAR_WORD2 -+0x00028D88 CB_COLOR4_CLEAR_WORD3 -+0x00028DB8 CB_COLOR5_CLEAR_WORD0 -+0x00028DBC CB_COLOR5_CLEAR_WORD1 -+0x00028DC0 CB_COLOR5_CLEAR_WORD2 -+0x00028DC4 CB_COLOR5_CLEAR_WORD3 -+0x00028DF4 CB_COLOR6_CLEAR_WORD0 -+0x00028DF8 CB_COLOR6_CLEAR_WORD1 -+0x00028DFC CB_COLOR6_CLEAR_WORD2 -+0x00028E00 CB_COLOR6_CLEAR_WORD3 -+0x00028E30 CB_COLOR7_CLEAR_WORD0 -+0x00028E34 CB_COLOR7_CLEAR_WORD1 -+0x00028E38 CB_COLOR7_CLEAR_WORD2 -+0x00028E3C CB_COLOR7_CLEAR_WORD3 -+0x00028F80 SQ_ALU_CONST_BUFFER_SIZE_HS_0 -+0x00028F84 SQ_ALU_CONST_BUFFER_SIZE_HS_1 -+0x00028F88 SQ_ALU_CONST_BUFFER_SIZE_HS_2 -+0x00028F8C SQ_ALU_CONST_BUFFER_SIZE_HS_3 -+0x00028F90 SQ_ALU_CONST_BUFFER_SIZE_HS_4 -+0x00028F94 SQ_ALU_CONST_BUFFER_SIZE_HS_5 -+0x00028F98 SQ_ALU_CONST_BUFFER_SIZE_HS_6 -+0x00028F9C SQ_ALU_CONST_BUFFER_SIZE_HS_7 -+0x00028FA0 SQ_ALU_CONST_BUFFER_SIZE_HS_8 -+0x00028FA4 SQ_ALU_CONST_BUFFER_SIZE_HS_9 -+0x00028FA8 SQ_ALU_CONST_BUFFER_SIZE_HS_10 -+0x00028FAC SQ_ALU_CONST_BUFFER_SIZE_HS_11 -+0x00028FB0 SQ_ALU_CONST_BUFFER_SIZE_HS_12 -+0x00028FB4 SQ_ALU_CONST_BUFFER_SIZE_HS_13 -+0x00028FB8 SQ_ALU_CONST_BUFFER_SIZE_HS_14 -+0x00028FBC SQ_ALU_CONST_BUFFER_SIZE_HS_15 -+0x00028FC0 SQ_ALU_CONST_BUFFER_SIZE_LS_0 -+0x00028FC4 SQ_ALU_CONST_BUFFER_SIZE_LS_1 -+0x00028FC8 SQ_ALU_CONST_BUFFER_SIZE_LS_2 -+0x00028FCC SQ_ALU_CONST_BUFFER_SIZE_LS_3 -+0x00028FD0 SQ_ALU_CONST_BUFFER_SIZE_LS_4 -+0x00028FD4 SQ_ALU_CONST_BUFFER_SIZE_LS_5 -+0x00028FD8 SQ_ALU_CONST_BUFFER_SIZE_LS_6 -+0x00028FDC SQ_ALU_CONST_BUFFER_SIZE_LS_7 -+0x00028FE0 SQ_ALU_CONST_BUFFER_SIZE_LS_8 -+0x00028FE4 SQ_ALU_CONST_BUFFER_SIZE_LS_9 -+0x00028FE8 SQ_ALU_CONST_BUFFER_SIZE_LS_10 -+0x00028FEC SQ_ALU_CONST_BUFFER_SIZE_LS_11 -+0x00028FF0 SQ_ALU_CONST_BUFFER_SIZE_LS_12 -+0x00028FF4 SQ_ALU_CONST_BUFFER_SIZE_LS_13 -+0x00028FF8 SQ_ALU_CONST_BUFFER_SIZE_LS_14 -+0x00028FFC SQ_ALU_CONST_BUFFER_SIZE_LS_15 -+0x0003CFF0 SQ_VTX_BASE_VTX_LOC -+0x0003CFF4 SQ_VTX_START_INST_LOC -+0x0003FF00 SQ_TEX_SAMPLER_CLEAR -+0x0003FF04 SQ_TEX_RESOURCE_CLEAR -+0x0003FF08 SQ_LOOP_BOOL_CLEAR -diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen -index 9177f91..7e16371 100644 ---- a/drivers/gpu/drm/radeon/reg_srcs/evergreen -+++ b/drivers/gpu/drm/radeon/reg_srcs/evergreen -@@ -1,4 +1,5 @@ - evergreen 0x9400 -+0x0000802C GRBM_GFX_INDEX - 0x00008040 WAIT_UNTIL - 0x00008044 WAIT_UNTIL_POLL_CNTL - 0x00008048 WAIT_UNTIL_POLL_MASK -@@ -220,6 +221,7 @@ evergreen 0x9400 - 0x00028348 PA_SC_VPORT_ZMIN_15 - 0x0002834C PA_SC_VPORT_ZMAX_15 - 0x00028350 SX_MISC -+0x00028354 SX_SURFACE_SYNC - 0x00028380 SQ_VTX_SEMANTIC_0 - 0x00028384 SQ_VTX_SEMANTIC_1 - 0x00028388 SQ_VTX_SEMANTIC_2 -diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 -index af0da4a..92f1900 100644 ---- a/drivers/gpu/drm/radeon/reg_srcs/r600 -+++ b/drivers/gpu/drm/radeon/reg_srcs/r600 -@@ -708,6 +708,7 @@ r600 0x9400 - 0x00028D0C DB_RENDER_CONTROL - 0x00028D10 DB_RENDER_OVERRIDE - 0x0002880C DB_SHADER_CONTROL -+0x00028D28 DB_SRESULTS_COMPARE_STATE0 - 0x00028D2C DB_SRESULTS_COMPARE_STATE1 - 0x00028430 DB_STENCILREFMASK - 0x00028434 DB_STENCILREFMASK_BF -diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c -index 8af4679..c55cf2a 100644 ---- a/drivers/gpu/drm/radeon/rs600.c -+++ b/drivers/gpu/drm/radeon/rs600.c -@@ -48,17 +48,6 @@ int rs600_mc_wait_for_idle(struct radeon_device *rdev); - - void rs600_pre_page_flip(struct radeon_device *rdev, int crtc) - { -- struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; -- u32 tmp; -- -- /* make sure flip is at vb rather than hb */ -- tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); -- tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN; -- WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); -- -- /* set pageflip to happen anywhere in vblank interval */ -- WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); -- - /* enable the pflip int */ - radeon_irq_kms_pflip_irq_get(rdev, crtc); - } -@@ -125,7 +114,7 @@ void rs600_pm_misc(struct radeon_device *rdev) - udelay(voltage->delay); - } - } else if (voltage->type == VOLTAGE_VDDC) -- radeon_atom_set_voltage(rdev, voltage->vddc_id); -+ radeon_atom_set_voltage(rdev, voltage->vddc_id, SET_VOLTAGE_TYPE_ASIC_VDDC); - - dyn_pwrmgt_sclk_length = RREG32_PLL(DYN_PWRMGT_SCLK_LENGTH); - dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_HILEN(0xf); -diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c -index 714ad45..114e5cc 100644 ---- a/drivers/gpu/drm/radeon/rv770.c -+++ b/drivers/gpu/drm/radeon/rv770.c -@@ -106,7 +106,7 @@ void rv770_pm_misc(struct radeon_device *rdev) - - if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { - if (voltage->voltage != rdev->pm.current_vddc) { -- radeon_atom_set_voltage(rdev, voltage->voltage); -+ radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); - rdev->pm.current_vddc = voltage->voltage; - DRM_DEBUG("Setting: v: %d\n", voltage->voltage); - } -diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h -index e5c607a..32c8e1c 100644 ---- a/include/drm/radeon_drm.h -+++ b/include/drm/radeon_drm.h -@@ -908,6 +908,9 @@ struct drm_radeon_cs { - #define RADEON_INFO_WANT_HYPERZ 0x07 - #define RADEON_INFO_WANT_CMASK 0x08 /* get access to CMASK on r300 */ - #define RADEON_INFO_CLOCK_CRYSTAL_FREQ 0x09 /* clock crystal frequency */ -+#define RADEON_INFO_NUM_BACKENDS 0x0a /* DB/backends for r600+ - need for OQ */ -+#define RADEON_INFO_NUM_TILE_PIPES 0x0b /* tile pipes for r600+ */ -+#define RADEON_INFO_FUSION_GART_WORKING 0x0c /* fusion writes to GTT were broken before this */ - - struct drm_radeon_info { - uint32_t request; -diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h -index 6724bf3..816e30c 100644 ---- a/include/drm/drm_pciids.h -+++ b/include/drm/drm_pciids.h -@@ -141,6 +141,20 @@ - {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6701, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6702, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6703, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6704, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6705, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6706, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6707, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6708, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6709, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6718, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6719, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x671c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x671d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6721, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6722, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_NEW_MEMMAP}, \ --- -1.7.1 - diff --git a/drm-radeon-update2.patch b/drm-radeon-update2.patch deleted file mode 100644 index 1224c0f..0000000 --- a/drm-radeon-update2.patch +++ /dev/null @@ -1,1708 +0,0 @@ -commit 05d1ee2878c955f7cf4254ed7f94bd65758f9208 -Author: Alex Deucher -Date: Wed May 25 01:00:45 2011 -0400 - - drm/radeon/kms/blit: workaround some hw issues on evergreen+ - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit e520c516656b3c361ebf8add4e00428b7c37afd6 -Author: Alex Deucher -Date: Wed May 25 16:39:00 2011 -0400 - - drm/radeon/kms: add blit support for cayman (v2) - - Allows us to use the 3D engine for memory management - and allows us to use vram beyond the BAR aperture. - - v2: fix copy paste typo - Reported-by: Nils Wallménius - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit e1b12b63f9df3a5480972c21f504163b36ceaa88 -Author: Alex Deucher -Date: Wed May 25 18:45:37 2011 -0400 - - drm/radeon/kms: fix thermal sensor reading on juniper - - Uses a different method than other evergreen asics. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 46f21922e84d074158781368eee24727a60f9d32 -Author: Alex Deucher -Date: Wed May 25 17:49:54 2011 -0400 - - drm/radeon/kms: add missing case for cayman thermal sensor - - The rest of the code is already in place. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 8cc42a1f51ada532c76009fd8b3261d5e7e8f02b -Author: Alex Deucher -Date: Fri May 20 12:35:23 2011 -0400 - - drm/radeon/kms: bump kms version number - - - proper bank size for fusion for 2D tiling. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit e0014e347d1d15e12c5beffd6af9d22a8d495969 -Author: Alex Deucher -Date: Fri May 20 12:35:22 2011 -0400 - - drm/radeon/kms: properly set num banks for fusion asics - - Needed by userspace for 2D tiled buffer alignment - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 48c7304eb2af97b6e50a93e22b656c9f3ead5f90 -Author: Alex Deucher -Date: Mon May 23 14:22:26 2011 -0400 - - drm/radeon/kms/cayman: fix typo in register mask - - Noticed by Droste on IRC. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 13e5c224cdd62fc3d454f1ef6d8157181ade07d9 -Author: Dave Airlie -Date: Thu May 19 14:14:41 2011 +1000 - - drm/radeon/kms: fix tile_config value reported to userspace on cayman. - - cayman is reporting the wrong tile config value to userspace, this - causes piglit mipmap generation tests to fail. - - Reviewed-by: Alex Deucher - cc: stable@kernel.org - Signed-off-by: Dave Airlie - -commit a9b83345a9c37d3bdea30be5a7d0cd34a0f28a68 -Author: Dave Airlie -Date: Thu May 19 14:14:40 2011 +1000 - - drm/radeon/kms: fix incorrect comparison in cayman setup code. - - This was leading to a bogus value being programmed to the backend - routing register. - - Reviewed-by: Alex Deucher - cc: stable@kernel.org - Signed-off-by: Dave Airlie - -commit 4f71384abcb866214a927510d7e315ad00692faa -Author: Dave Airlie -Date: Thu May 19 14:14:43 2011 +1000 - - drm/radeon/kms: add wait idle ioctl for eg->cayman - - None of the latest GPUs had this hooked up, this is necessary for - correct operation in a lot of cases, however we should test this on a few - GPUs in these families as we've had problems in this area before. - - Reviewed-by: Alex Deucher - cc: stable@kernel.org - Signed-off-by: Dave Airlie - -commit 0676d9dc1e66566af98e1192a041c9e983a69eaf -Author: Dave Airlie -Date: Thu May 19 14:14:42 2011 +1000 - - drm/radeon/cayman: setup hdp to invalidate and flush when asked - - On cayman we need to set the bit to cause HDP flushes to invalidate the - HDP cache also. - - Reviewed-by: Alex Deucher - cc: stable@kernel.org - Signed-off-by: Dave Airlie - -commit 5e9df070bdc59db0b8718b8e2e6a387e49acda7c -Author: Alex Deucher -Date: Thu May 19 11:07:57 2011 -0400 - - drm/radeon/evergreen/btc/fusion: setup hdp to invalidate and flush when asked - - This needs to be explicitly set on btc. It's set by default - on evergreen/fusion, so it fine to just unconditionally enable it for - all chips. - - Signed-off-by: Alex Deucher - cc: stable@kernel.org - Signed-off-by: Dave Airlie - -commit 97bce584876b2293c0ceeeb1abc33ec568d320ea -Author: Alex Deucher -Date: Thu May 12 21:15:15 2011 -0400 - - drm/radeon/kms: add some evergreen/ni safe regs - - need to programmed from the userspace drivers. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit d3be86b8137152ebf1be2ee2ccf90fea7f9a07a9 -Author: Alex Deucher -Date: Wed May 11 03:15:24 2011 -0400 - - drm/radeon/kms: fix tiling reg on fusion - - The location of MC_ARB_RAMCFG changed on fusion. - I've diffed all the other regs in evergreend.h and this - is the only other reg that changed. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 740da77e0792cd804510d018924df8f149f58fe4 -Author: Alex Deucher -Date: Tue May 10 02:14:52 2011 +0000 - - drm/radeon/kms: fix cayman acceleration - - The TCC disable setup was incorrect. This - prevents the GPU from hanging when draw commands - are issued. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 02b1b583d1c9b2559288ea5f46f04b0c8385f1ef -Author: Dave Airlie -Date: Mon May 9 14:54:33 2011 +1000 - - drm/radeon: fix cayman struct accessors. - - We are accessing totally the wrong struct in this case, and putting - uninitialised values into the GPU, which it doesn't like unsurprisingly. - - Signed-off-by: Dave Airlie - -commit 202ea65cf5d6451baf74feb4becdad19ab53eadc -Author: Ilija Hadzic -Date: Wed May 4 20:15:03 2011 -0400 - - drm/radeon: fix order of doing things in radeon_crtc_cursor_set - - if object pin or object lookup in radeon_cursor_set fail, the function - could leave inconsistent mouse width and hight values in radeon_crtc - fixed by moving cursor width and height assignments after all - checks have passed - - Signed-off-by: Ilija Hadzic - Reviewed-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit a796f1fc096d0032972480657d6d9c4fc5836496 -Author: Alex Deucher -Date: Fri May 6 01:42:49 2011 -0400 - - drm/radeon/kms: ATPX switcheroo fixes - - When we switch the display mux, also switch - the i2c mux. Also use the start and finish - methods to let the sbios know that the switch - is happening. - - Should fix: - https://bugs.freedesktop.org/show_bug.cgi?id=35398 - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 134627db513fffd8ecc90b96d477c18ae76d2d61 -Author: Alex Deucher -Date: Tue May 3 12:44:54 2011 -0400 - - drm/radeon/kms: add support for thermal chips on combios asics - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie -diff --git a/drivers/gpu/drm/radeon/cayman_blit_shaders.c b/drivers/gpu/drm/radeon/cayman_blit_shaders.c -index e148ab0..7b4eeb7 100644 ---- a/drivers/gpu/drm/radeon/cayman_blit_shaders.c -+++ b/drivers/gpu/drm/radeon/cayman_blit_shaders.c -@@ -39,17 +39,335 @@ - - const u32 cayman_default_state[] = - { -- /* XXX fill in additional blit state */ -+ 0xc0066900, -+ 0x00000000, -+ 0x00000060, /* DB_RENDER_CONTROL */ -+ 0x00000000, /* DB_COUNT_CONTROL */ -+ 0x00000000, /* DB_DEPTH_VIEW */ -+ 0x0000002a, /* DB_RENDER_OVERRIDE */ -+ 0x00000000, /* DB_RENDER_OVERRIDE2 */ -+ 0x00000000, /* DB_HTILE_DATA_BASE */ - - 0xc0026900, -- 0x00000316, -- 0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */ -- 0x00000010, /* */ -+ 0x0000000a, -+ 0x00000000, /* DB_STENCIL_CLEAR */ -+ 0x00000000, /* DB_DEPTH_CLEAR */ -+ -+ 0xc0036900, -+ 0x0000000f, -+ 0x00000000, /* DB_DEPTH_INFO */ -+ 0x00000000, /* DB_Z_INFO */ -+ 0x00000000, /* DB_STENCIL_INFO */ -+ -+ 0xc0016900, -+ 0x00000080, -+ 0x00000000, /* PA_SC_WINDOW_OFFSET */ -+ -+ 0xc00d6900, -+ 0x00000083, -+ 0x0000ffff, /* PA_SC_CLIPRECT_RULE */ -+ 0x00000000, /* PA_SC_CLIPRECT_0_TL */ -+ 0x20002000, /* PA_SC_CLIPRECT_0_BR */ -+ 0x00000000, -+ 0x20002000, -+ 0x00000000, -+ 0x20002000, -+ 0x00000000, -+ 0x20002000, -+ 0xaaaaaaaa, /* PA_SC_EDGERULE */ -+ 0x00000000, /* PA_SU_HARDWARE_SCREEN_OFFSET */ -+ 0x0000000f, /* CB_TARGET_MASK */ -+ 0x0000000f, /* CB_SHADER_MASK */ -+ -+ 0xc0226900, -+ 0x00000094, -+ 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ -+ 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ -+ 0x80000000, -+ 0x20002000, -+ 0x80000000, -+ 0x20002000, -+ 0x80000000, -+ 0x20002000, -+ 0x80000000, -+ 0x20002000, -+ 0x80000000, -+ 0x20002000, -+ 0x80000000, -+ 0x20002000, -+ 0x80000000, -+ 0x20002000, -+ 0x80000000, -+ 0x20002000, -+ 0x80000000, -+ 0x20002000, -+ 0x80000000, -+ 0x20002000, -+ 0x80000000, -+ 0x20002000, -+ 0x80000000, -+ 0x20002000, -+ 0x80000000, -+ 0x20002000, -+ 0x80000000, -+ 0x20002000, -+ 0x80000000, -+ 0x20002000, -+ 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ -+ 0x3f800000, /* PA_SC_VPORT_ZMAX_0 */ -+ -+ 0xc0016900, -+ 0x000000d4, -+ 0x00000000, /* SX_MISC */ - - 0xc0026900, - 0x000000d9, - 0x00000000, /* CP_RINGID */ - 0x00000000, /* CP_VMID */ -+ -+ 0xc0096900, -+ 0x00000100, -+ 0x00ffffff, /* VGT_MAX_VTX_INDX */ -+ 0x00000000, /* VGT_MIN_VTX_INDX */ -+ 0x00000000, /* VGT_INDX_OFFSET */ -+ 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ -+ 0x00000000, /* SX_ALPHA_TEST_CONTROL */ -+ 0x00000000, /* CB_BLEND_RED */ -+ 0x00000000, /* CB_BLEND_GREEN */ -+ 0x00000000, /* CB_BLEND_BLUE */ -+ 0x00000000, /* CB_BLEND_ALPHA */ -+ -+ 0xc0016900, -+ 0x00000187, -+ 0x00000100, /* SPI_VS_OUT_ID_0 */ -+ -+ 0xc0026900, -+ 0x00000191, -+ 0x00000100, /* SPI_PS_INPUT_CNTL_0 */ -+ 0x00000101, /* SPI_PS_INPUT_CNTL_1 */ -+ -+ 0xc0016900, -+ 0x000001b1, -+ 0x00000000, /* SPI_VS_OUT_CONFIG */ -+ -+ 0xc0106900, -+ 0x000001b3, -+ 0x20000001, /* SPI_PS_IN_CONTROL_0 */ -+ 0x00000000, /* SPI_PS_IN_CONTROL_1 */ -+ 0x00000000, /* SPI_INTERP_CONTROL_0 */ -+ 0x00000000, /* SPI_INPUT_Z */ -+ 0x00000000, /* SPI_FOG_CNTL */ -+ 0x00100000, /* SPI_BARYC_CNTL */ -+ 0x00000000, /* SPI_PS_IN_CONTROL_2 */ -+ 0x00000000, /* SPI_COMPUTE_INPUT_CNTL */ -+ 0x00000000, /* SPI_COMPUTE_NUM_THREAD_X */ -+ 0x00000000, /* SPI_COMPUTE_NUM_THREAD_Y */ -+ 0x00000000, /* SPI_COMPUTE_NUM_THREAD_Z */ -+ 0x00000000, /* SPI_GPR_MGMT */ -+ 0x00000000, /* SPI_LDS_MGMT */ -+ 0x00000000, /* SPI_STACK_MGMT */ -+ 0x00000000, /* SPI_WAVE_MGMT_1 */ -+ 0x00000000, /* SPI_WAVE_MGMT_2 */ -+ -+ 0xc0016900, -+ 0x000001e0, -+ 0x00000000, /* CB_BLEND0_CONTROL */ -+ -+ 0xc00e6900, -+ 0x00000200, -+ 0x00000000, /* DB_DEPTH_CONTROL */ -+ 0x00000000, /* DB_EQAA */ -+ 0x00cc0010, /* CB_COLOR_CONTROL */ -+ 0x00000210, /* DB_SHADER_CONTROL */ -+ 0x00010000, /* PA_CL_CLIP_CNTL */ -+ 0x00000004, /* PA_SU_SC_MODE_CNTL */ -+ 0x00000100, /* PA_CL_VTE_CNTL */ -+ 0x00000000, /* PA_CL_VS_OUT_CNTL */ -+ 0x00000000, /* PA_CL_NANINF_CNTL */ -+ 0x00000000, /* PA_SU_LINE_STIPPLE_CNTL */ -+ 0x00000000, /* PA_SU_LINE_STIPPLE_SCALE */ -+ 0x00000000, /* PA_SU_PRIM_FILTER_CNTL */ -+ 0x00000000, /* */ -+ 0x00000000, /* */ -+ -+ 0xc0026900, -+ 0x00000229, -+ 0x00000000, /* SQ_PGM_START_FS */ -+ 0x00000000, -+ -+ 0xc0016900, -+ 0x0000023b, -+ 0x00000000, /* SQ_LDS_ALLOC_PS */ -+ -+ 0xc0066900, -+ 0x00000240, -+ 0x00000000, /* SQ_ESGS_RING_ITEMSIZE */ -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ -+ 0xc0046900, -+ 0x00000247, -+ 0x00000000, /* SQ_GS_VERT_ITEMSIZE */ -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ -+ 0xc0116900, -+ 0x00000280, -+ 0x00000000, /* PA_SU_POINT_SIZE */ -+ 0x00000000, /* PA_SU_POINT_MINMAX */ -+ 0x00000008, /* PA_SU_LINE_CNTL */ -+ 0x00000000, /* PA_SC_LINE_STIPPLE */ -+ 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ -+ 0x00000000, /* VGT_HOS_CNTL */ -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, /* VGT_GS_MODE */ -+ -+ 0xc0026900, -+ 0x00000292, -+ 0x00000000, /* PA_SC_MODE_CNTL_0 */ -+ 0x00000000, /* PA_SC_MODE_CNTL_1 */ -+ -+ 0xc0016900, -+ 0x000002a1, -+ 0x00000000, /* VGT_PRIMITIVEID_EN */ -+ -+ 0xc0016900, -+ 0x000002a5, -+ 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_EN */ -+ -+ 0xc0026900, -+ 0x000002a8, -+ 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ -+ 0x00000000, -+ -+ 0xc0026900, -+ 0x000002ad, -+ 0x00000000, /* VGT_REUSE_OFF */ -+ 0x00000000, -+ -+ 0xc0016900, -+ 0x000002d5, -+ 0x00000000, /* VGT_SHADER_STAGES_EN */ -+ -+ 0xc0016900, -+ 0x000002dc, -+ 0x0000aa00, /* DB_ALPHA_TO_MASK */ -+ -+ 0xc0066900, -+ 0x000002de, -+ 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ -+ 0xc0026900, -+ 0x000002e5, -+ 0x00000000, /* VGT_STRMOUT_CONFIG */ -+ 0x00000000, -+ -+ 0xc01b6900, -+ 0x000002f5, -+ 0x76543210, /* PA_SC_CENTROID_PRIORITY_0 */ -+ 0xfedcba98, /* PA_SC_CENTROID_PRIORITY_1 */ -+ 0x00000000, /* PA_SC_LINE_CNTL */ -+ 0x00000000, /* PA_SC_AA_CONFIG */ -+ 0x00000005, /* PA_SU_VTX_CNTL */ -+ 0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */ -+ 0x3f800000, /* PA_CL_GB_VERT_DISC_ADJ */ -+ 0x3f800000, /* PA_CL_GB_HORZ_CLIP_ADJ */ -+ 0x3f800000, /* PA_CL_GB_HORZ_DISC_ADJ */ -+ 0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */ -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0xffffffff, /* PA_SC_AA_MASK_X0Y0_X1Y0 */ -+ 0xffffffff, -+ -+ 0xc0026900, -+ 0x00000316, -+ 0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */ -+ 0x00000010, /* */ -+}; -+ -+const u32 cayman_vs[] = -+{ -+ 0x00000004, -+ 0x80400400, -+ 0x0000a03c, -+ 0x95000688, -+ 0x00004000, -+ 0x15000688, -+ 0x00000000, -+ 0x88000000, -+ 0x04000000, -+ 0x67961001, -+#ifdef __BIG_ENDIAN -+ 0x00020000, -+#else -+ 0x00000000, -+#endif -+ 0x00000000, -+ 0x04000000, -+ 0x67961000, -+#ifdef __BIG_ENDIAN -+ 0x00020008, -+#else -+ 0x00000008, -+#endif -+ 0x00000000, -+}; -+ -+const u32 cayman_ps[] = -+{ -+ 0x00000004, -+ 0xa00c0000, -+ 0x00000008, -+ 0x80400000, -+ 0x00000000, -+ 0x95000688, -+ 0x00000000, -+ 0x88000000, -+ 0x00380400, -+ 0x00146b10, -+ 0x00380000, -+ 0x20146b10, -+ 0x00380400, -+ 0x40146b00, -+ 0x80380000, -+ 0x60146b00, -+ 0x00000010, -+ 0x000d1000, -+ 0xb0800000, -+ 0x00000000, - }; - -+const u32 cayman_ps_size = ARRAY_SIZE(cayman_ps); -+const u32 cayman_vs_size = ARRAY_SIZE(cayman_vs); - const u32 cayman_default_size = ARRAY_SIZE(cayman_default_state); -diff --git a/drivers/gpu/drm/radeon/cayman_blit_shaders.h b/drivers/gpu/drm/radeon/cayman_blit_shaders.h -index 33b75e5..f5d0e9a 100644 ---- a/drivers/gpu/drm/radeon/cayman_blit_shaders.h -+++ b/drivers/gpu/drm/radeon/cayman_blit_shaders.h -@@ -25,8 +25,11 @@ - #ifndef CAYMAN_BLIT_SHADERS_H - #define CAYMAN_BLIT_SHADERS_H - -+extern const u32 cayman_ps[]; -+extern const u32 cayman_vs[]; - extern const u32 cayman_default_state[]; - -+extern const u32 cayman_ps_size, cayman_vs_size; - extern const u32 cayman_default_size; - - #endif -diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c -index f7e0376..1b583f8 100644 ---- a/drivers/gpu/drm/radeon/evergreen.c -+++ b/drivers/gpu/drm/radeon/evergreen.c -@@ -88,21 +88,39 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) - /* get temperature in millidegrees */ - int evergreen_get_temp(struct radeon_device *rdev) - { -- u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> -- ASIC_T_SHIFT; -- u32 actual_temp = 0; -- -- if (temp & 0x400) -- actual_temp = -256; -- else if (temp & 0x200) -- actual_temp = 255; -- else if (temp & 0x100) { -- actual_temp = temp & 0x1ff; -- actual_temp |= ~0x1ff; -- } else -- actual_temp = temp & 0xff; -+ u32 temp, toffset, actual_temp = 0; -+ -+ if (rdev->family == CHIP_JUNIPER) { -+ toffset = (RREG32(CG_THERMAL_CTRL) & TOFFSET_MASK) >> -+ TOFFSET_SHIFT; -+ temp = (RREG32(CG_TS0_STATUS) & TS0_ADC_DOUT_MASK) >> -+ TS0_ADC_DOUT_SHIFT; -+ -+ if (toffset & 0x100) -+ actual_temp = temp / 2 - (0x200 - toffset); -+ else -+ actual_temp = temp / 2 + toffset; -+ -+ actual_temp = actual_temp * 1000; -+ -+ } else { -+ temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> -+ ASIC_T_SHIFT; -+ -+ if (temp & 0x400) -+ actual_temp = -256; -+ else if (temp & 0x200) -+ actual_temp = 255; -+ else if (temp & 0x100) { -+ actual_temp = temp & 0x1ff; -+ actual_temp |= ~0x1ff; -+ } else -+ actual_temp = temp & 0xff; - -- return (actual_temp * 1000) / 2; -+ actual_temp = (actual_temp * 1000) / 2; -+ } -+ -+ return actual_temp; - } - - int sumo_get_temp(struct radeon_device *rdev) -@@ -1578,7 +1596,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) - u32 sq_stack_resource_mgmt_2; - u32 sq_stack_resource_mgmt_3; - u32 vgt_cache_invalidation; -- u32 hdp_host_path_cntl; -+ u32 hdp_host_path_cntl, tmp; - int i, j, num_shader_engines, ps_thread_count; - - switch (rdev->family) { -@@ -1780,7 +1798,10 @@ static void evergreen_gpu_init(struct radeon_device *rdev) - - - mc_shared_chmap = RREG32(MC_SHARED_CHMAP); -- mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); -+ if (rdev->flags & RADEON_IS_IGP) -+ mc_arb_ramcfg = RREG32(FUS_MC_ARB_RAMCFG); -+ else -+ mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); - - switch (rdev->config.evergreen.max_tile_pipes) { - case 1: -@@ -1933,8 +1954,12 @@ static void evergreen_gpu_init(struct radeon_device *rdev) - rdev->config.evergreen.tile_config |= (3 << 0); - break; - } -- rdev->config.evergreen.tile_config |= -- ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; -+ /* num banks is 8 on all fusion asics */ -+ if (rdev->flags & RADEON_IS_IGP) -+ rdev->config.evergreen.tile_config |= 8 << 4; -+ else -+ rdev->config.evergreen.tile_config |= -+ ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; - rdev->config.evergreen.tile_config |= - ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) << 8; - rdev->config.evergreen.tile_config |= -@@ -2138,6 +2163,10 @@ static void evergreen_gpu_init(struct radeon_device *rdev) - for (i = SQ_ALU_CONST_BUFFER_SIZE_HS_0; i < 0x29000; i += 4) - WREG32(i, 0); - -+ tmp = RREG32(HDP_MISC_CNTL); -+ tmp |= HDP_FLUSH_INVALIDATE_CACHE; -+ WREG32(HDP_MISC_CNTL, tmp); -+ - hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); - WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); - -diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c -index 2be698e..9c91468 100644 ---- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c -+++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c -@@ -31,6 +31,7 @@ - - #include "evergreend.h" - #include "evergreen_blit_shaders.h" -+#include "cayman_blit_shaders.h" - - #define DI_PT_RECTLIST 0x11 - #define DI_INDEX_SIZE_16_BIT 0x0 -@@ -199,6 +200,16 @@ static void - set_scissors(struct radeon_device *rdev, int x1, int y1, - int x2, int y2) - { -+ /* workaround some hw bugs */ -+ if (x2 == 0) -+ x1 = 1; -+ if (y2 == 0) -+ y1 = 1; -+ if (rdev->family == CHIP_CAYMAN) { -+ if ((x2 == 1) && (y2 == 1)) -+ x2 = 2; -+ } -+ - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(rdev, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(rdev, (x1 << 0) | (y1 << 16)); -@@ -255,238 +266,240 @@ set_default_state(struct radeon_device *rdev) - u64 gpu_addr; - int dwords; - -- switch (rdev->family) { -- case CHIP_CEDAR: -- default: -- num_ps_gprs = 93; -- num_vs_gprs = 46; -- num_temp_gprs = 4; -- num_gs_gprs = 31; -- num_es_gprs = 31; -- num_hs_gprs = 23; -- num_ls_gprs = 23; -- num_ps_threads = 96; -- num_vs_threads = 16; -- num_gs_threads = 16; -- num_es_threads = 16; -- num_hs_threads = 16; -- num_ls_threads = 16; -- num_ps_stack_entries = 42; -- num_vs_stack_entries = 42; -- num_gs_stack_entries = 42; -- num_es_stack_entries = 42; -- num_hs_stack_entries = 42; -- num_ls_stack_entries = 42; -- break; -- case CHIP_REDWOOD: -- num_ps_gprs = 93; -- num_vs_gprs = 46; -- num_temp_gprs = 4; -- num_gs_gprs = 31; -- num_es_gprs = 31; -- num_hs_gprs = 23; -- num_ls_gprs = 23; -- num_ps_threads = 128; -- num_vs_threads = 20; -- num_gs_threads = 20; -- num_es_threads = 20; -- num_hs_threads = 20; -- num_ls_threads = 20; -- num_ps_stack_entries = 42; -- num_vs_stack_entries = 42; -- num_gs_stack_entries = 42; -- num_es_stack_entries = 42; -- num_hs_stack_entries = 42; -- num_ls_stack_entries = 42; -- break; -- case CHIP_JUNIPER: -- num_ps_gprs = 93; -- num_vs_gprs = 46; -- num_temp_gprs = 4; -- num_gs_gprs = 31; -- num_es_gprs = 31; -- num_hs_gprs = 23; -- num_ls_gprs = 23; -- num_ps_threads = 128; -- num_vs_threads = 20; -- num_gs_threads = 20; -- num_es_threads = 20; -- num_hs_threads = 20; -- num_ls_threads = 20; -- num_ps_stack_entries = 85; -- num_vs_stack_entries = 85; -- num_gs_stack_entries = 85; -- num_es_stack_entries = 85; -- num_hs_stack_entries = 85; -- num_ls_stack_entries = 85; -- break; -- case CHIP_CYPRESS: -- case CHIP_HEMLOCK: -- num_ps_gprs = 93; -- num_vs_gprs = 46; -- num_temp_gprs = 4; -- num_gs_gprs = 31; -- num_es_gprs = 31; -- num_hs_gprs = 23; -- num_ls_gprs = 23; -- num_ps_threads = 128; -- num_vs_threads = 20; -- num_gs_threads = 20; -- num_es_threads = 20; -- num_hs_threads = 20; -- num_ls_threads = 20; -- num_ps_stack_entries = 85; -- num_vs_stack_entries = 85; -- num_gs_stack_entries = 85; -- num_es_stack_entries = 85; -- num_hs_stack_entries = 85; -- num_ls_stack_entries = 85; -- break; -- case CHIP_PALM: -- num_ps_gprs = 93; -- num_vs_gprs = 46; -- num_temp_gprs = 4; -- num_gs_gprs = 31; -- num_es_gprs = 31; -- num_hs_gprs = 23; -- num_ls_gprs = 23; -- num_ps_threads = 96; -- num_vs_threads = 16; -- num_gs_threads = 16; -- num_es_threads = 16; -- num_hs_threads = 16; -- num_ls_threads = 16; -- num_ps_stack_entries = 42; -- num_vs_stack_entries = 42; -- num_gs_stack_entries = 42; -- num_es_stack_entries = 42; -- num_hs_stack_entries = 42; -- num_ls_stack_entries = 42; -- break; -- case CHIP_BARTS: -- num_ps_gprs = 93; -- num_vs_gprs = 46; -- num_temp_gprs = 4; -- num_gs_gprs = 31; -- num_es_gprs = 31; -- num_hs_gprs = 23; -- num_ls_gprs = 23; -- num_ps_threads = 128; -- num_vs_threads = 20; -- num_gs_threads = 20; -- num_es_threads = 20; -- num_hs_threads = 20; -- num_ls_threads = 20; -- num_ps_stack_entries = 85; -- num_vs_stack_entries = 85; -- num_gs_stack_entries = 85; -- num_es_stack_entries = 85; -- num_hs_stack_entries = 85; -- num_ls_stack_entries = 85; -- break; -- case CHIP_TURKS: -- num_ps_gprs = 93; -- num_vs_gprs = 46; -- num_temp_gprs = 4; -- num_gs_gprs = 31; -- num_es_gprs = 31; -- num_hs_gprs = 23; -- num_ls_gprs = 23; -- num_ps_threads = 128; -- num_vs_threads = 20; -- num_gs_threads = 20; -- num_es_threads = 20; -- num_hs_threads = 20; -- num_ls_threads = 20; -- num_ps_stack_entries = 42; -- num_vs_stack_entries = 42; -- num_gs_stack_entries = 42; -- num_es_stack_entries = 42; -- num_hs_stack_entries = 42; -- num_ls_stack_entries = 42; -- break; -- case CHIP_CAICOS: -- num_ps_gprs = 93; -- num_vs_gprs = 46; -- num_temp_gprs = 4; -- num_gs_gprs = 31; -- num_es_gprs = 31; -- num_hs_gprs = 23; -- num_ls_gprs = 23; -- num_ps_threads = 128; -- num_vs_threads = 10; -- num_gs_threads = 10; -- num_es_threads = 10; -- num_hs_threads = 10; -- num_ls_threads = 10; -- num_ps_stack_entries = 42; -- num_vs_stack_entries = 42; -- num_gs_stack_entries = 42; -- num_es_stack_entries = 42; -- num_hs_stack_entries = 42; -- num_ls_stack_entries = 42; -- break; -- } -- -- if ((rdev->family == CHIP_CEDAR) || -- (rdev->family == CHIP_PALM) || -- (rdev->family == CHIP_CAICOS)) -- sq_config = 0; -- else -- sq_config = VC_ENABLE; -- -- sq_config |= (EXPORT_SRC_C | -- CS_PRIO(0) | -- LS_PRIO(0) | -- HS_PRIO(0) | -- PS_PRIO(0) | -- VS_PRIO(1) | -- GS_PRIO(2) | -- ES_PRIO(3)); -- -- sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) | -- NUM_VS_GPRS(num_vs_gprs) | -- NUM_CLAUSE_TEMP_GPRS(num_temp_gprs)); -- sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) | -- NUM_ES_GPRS(num_es_gprs)); -- sq_gpr_resource_mgmt_3 = (NUM_HS_GPRS(num_hs_gprs) | -- NUM_LS_GPRS(num_ls_gprs)); -- sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) | -- NUM_VS_THREADS(num_vs_threads) | -- NUM_GS_THREADS(num_gs_threads) | -- NUM_ES_THREADS(num_es_threads)); -- sq_thread_resource_mgmt_2 = (NUM_HS_THREADS(num_hs_threads) | -- NUM_LS_THREADS(num_ls_threads)); -- sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) | -- NUM_VS_STACK_ENTRIES(num_vs_stack_entries)); -- sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) | -- NUM_ES_STACK_ENTRIES(num_es_stack_entries)); -- sq_stack_resource_mgmt_3 = (NUM_HS_STACK_ENTRIES(num_hs_stack_entries) | -- NUM_LS_STACK_ENTRIES(num_ls_stack_entries)); -- - /* set clear context state */ - radeon_ring_write(rdev, PACKET3(PACKET3_CLEAR_STATE, 0)); - radeon_ring_write(rdev, 0); - -- /* disable dyn gprs */ -- radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); -- radeon_ring_write(rdev, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2); -- radeon_ring_write(rdev, 0); -+ if (rdev->family < CHIP_CAYMAN) { -+ switch (rdev->family) { -+ case CHIP_CEDAR: -+ default: -+ num_ps_gprs = 93; -+ num_vs_gprs = 46; -+ num_temp_gprs = 4; -+ num_gs_gprs = 31; -+ num_es_gprs = 31; -+ num_hs_gprs = 23; -+ num_ls_gprs = 23; -+ num_ps_threads = 96; -+ num_vs_threads = 16; -+ num_gs_threads = 16; -+ num_es_threads = 16; -+ num_hs_threads = 16; -+ num_ls_threads = 16; -+ num_ps_stack_entries = 42; -+ num_vs_stack_entries = 42; -+ num_gs_stack_entries = 42; -+ num_es_stack_entries = 42; -+ num_hs_stack_entries = 42; -+ num_ls_stack_entries = 42; -+ break; -+ case CHIP_REDWOOD: -+ num_ps_gprs = 93; -+ num_vs_gprs = 46; -+ num_temp_gprs = 4; -+ num_gs_gprs = 31; -+ num_es_gprs = 31; -+ num_hs_gprs = 23; -+ num_ls_gprs = 23; -+ num_ps_threads = 128; -+ num_vs_threads = 20; -+ num_gs_threads = 20; -+ num_es_threads = 20; -+ num_hs_threads = 20; -+ num_ls_threads = 20; -+ num_ps_stack_entries = 42; -+ num_vs_stack_entries = 42; -+ num_gs_stack_entries = 42; -+ num_es_stack_entries = 42; -+ num_hs_stack_entries = 42; -+ num_ls_stack_entries = 42; -+ break; -+ case CHIP_JUNIPER: -+ num_ps_gprs = 93; -+ num_vs_gprs = 46; -+ num_temp_gprs = 4; -+ num_gs_gprs = 31; -+ num_es_gprs = 31; -+ num_hs_gprs = 23; -+ num_ls_gprs = 23; -+ num_ps_threads = 128; -+ num_vs_threads = 20; -+ num_gs_threads = 20; -+ num_es_threads = 20; -+ num_hs_threads = 20; -+ num_ls_threads = 20; -+ num_ps_stack_entries = 85; -+ num_vs_stack_entries = 85; -+ num_gs_stack_entries = 85; -+ num_es_stack_entries = 85; -+ num_hs_stack_entries = 85; -+ num_ls_stack_entries = 85; -+ break; -+ case CHIP_CYPRESS: -+ case CHIP_HEMLOCK: -+ num_ps_gprs = 93; -+ num_vs_gprs = 46; -+ num_temp_gprs = 4; -+ num_gs_gprs = 31; -+ num_es_gprs = 31; -+ num_hs_gprs = 23; -+ num_ls_gprs = 23; -+ num_ps_threads = 128; -+ num_vs_threads = 20; -+ num_gs_threads = 20; -+ num_es_threads = 20; -+ num_hs_threads = 20; -+ num_ls_threads = 20; -+ num_ps_stack_entries = 85; -+ num_vs_stack_entries = 85; -+ num_gs_stack_entries = 85; -+ num_es_stack_entries = 85; -+ num_hs_stack_entries = 85; -+ num_ls_stack_entries = 85; -+ break; -+ case CHIP_PALM: -+ num_ps_gprs = 93; -+ num_vs_gprs = 46; -+ num_temp_gprs = 4; -+ num_gs_gprs = 31; -+ num_es_gprs = 31; -+ num_hs_gprs = 23; -+ num_ls_gprs = 23; -+ num_ps_threads = 96; -+ num_vs_threads = 16; -+ num_gs_threads = 16; -+ num_es_threads = 16; -+ num_hs_threads = 16; -+ num_ls_threads = 16; -+ num_ps_stack_entries = 42; -+ num_vs_stack_entries = 42; -+ num_gs_stack_entries = 42; -+ num_es_stack_entries = 42; -+ num_hs_stack_entries = 42; -+ num_ls_stack_entries = 42; -+ break; -+ case CHIP_BARTS: -+ num_ps_gprs = 93; -+ num_vs_gprs = 46; -+ num_temp_gprs = 4; -+ num_gs_gprs = 31; -+ num_es_gprs = 31; -+ num_hs_gprs = 23; -+ num_ls_gprs = 23; -+ num_ps_threads = 128; -+ num_vs_threads = 20; -+ num_gs_threads = 20; -+ num_es_threads = 20; -+ num_hs_threads = 20; -+ num_ls_threads = 20; -+ num_ps_stack_entries = 85; -+ num_vs_stack_entries = 85; -+ num_gs_stack_entries = 85; -+ num_es_stack_entries = 85; -+ num_hs_stack_entries = 85; -+ num_ls_stack_entries = 85; -+ break; -+ case CHIP_TURKS: -+ num_ps_gprs = 93; -+ num_vs_gprs = 46; -+ num_temp_gprs = 4; -+ num_gs_gprs = 31; -+ num_es_gprs = 31; -+ num_hs_gprs = 23; -+ num_ls_gprs = 23; -+ num_ps_threads = 128; -+ num_vs_threads = 20; -+ num_gs_threads = 20; -+ num_es_threads = 20; -+ num_hs_threads = 20; -+ num_ls_threads = 20; -+ num_ps_stack_entries = 42; -+ num_vs_stack_entries = 42; -+ num_gs_stack_entries = 42; -+ num_es_stack_entries = 42; -+ num_hs_stack_entries = 42; -+ num_ls_stack_entries = 42; -+ break; -+ case CHIP_CAICOS: -+ num_ps_gprs = 93; -+ num_vs_gprs = 46; -+ num_temp_gprs = 4; -+ num_gs_gprs = 31; -+ num_es_gprs = 31; -+ num_hs_gprs = 23; -+ num_ls_gprs = 23; -+ num_ps_threads = 128; -+ num_vs_threads = 10; -+ num_gs_threads = 10; -+ num_es_threads = 10; -+ num_hs_threads = 10; -+ num_ls_threads = 10; -+ num_ps_stack_entries = 42; -+ num_vs_stack_entries = 42; -+ num_gs_stack_entries = 42; -+ num_es_stack_entries = 42; -+ num_hs_stack_entries = 42; -+ num_ls_stack_entries = 42; -+ break; -+ } - -- /* SQ config */ -- radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 11)); -- radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2); -- radeon_ring_write(rdev, sq_config); -- radeon_ring_write(rdev, sq_gpr_resource_mgmt_1); -- radeon_ring_write(rdev, sq_gpr_resource_mgmt_2); -- radeon_ring_write(rdev, sq_gpr_resource_mgmt_3); -- radeon_ring_write(rdev, 0); -- radeon_ring_write(rdev, 0); -- radeon_ring_write(rdev, sq_thread_resource_mgmt); -- radeon_ring_write(rdev, sq_thread_resource_mgmt_2); -- radeon_ring_write(rdev, sq_stack_resource_mgmt_1); -- radeon_ring_write(rdev, sq_stack_resource_mgmt_2); -- radeon_ring_write(rdev, sq_stack_resource_mgmt_3); -+ if ((rdev->family == CHIP_CEDAR) || -+ (rdev->family == CHIP_PALM) || -+ (rdev->family == CHIP_CAICOS)) -+ sq_config = 0; -+ else -+ sq_config = VC_ENABLE; -+ -+ sq_config |= (EXPORT_SRC_C | -+ CS_PRIO(0) | -+ LS_PRIO(0) | -+ HS_PRIO(0) | -+ PS_PRIO(0) | -+ VS_PRIO(1) | -+ GS_PRIO(2) | -+ ES_PRIO(3)); -+ -+ sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) | -+ NUM_VS_GPRS(num_vs_gprs) | -+ NUM_CLAUSE_TEMP_GPRS(num_temp_gprs)); -+ sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) | -+ NUM_ES_GPRS(num_es_gprs)); -+ sq_gpr_resource_mgmt_3 = (NUM_HS_GPRS(num_hs_gprs) | -+ NUM_LS_GPRS(num_ls_gprs)); -+ sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) | -+ NUM_VS_THREADS(num_vs_threads) | -+ NUM_GS_THREADS(num_gs_threads) | -+ NUM_ES_THREADS(num_es_threads)); -+ sq_thread_resource_mgmt_2 = (NUM_HS_THREADS(num_hs_threads) | -+ NUM_LS_THREADS(num_ls_threads)); -+ sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) | -+ NUM_VS_STACK_ENTRIES(num_vs_stack_entries)); -+ sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) | -+ NUM_ES_STACK_ENTRIES(num_es_stack_entries)); -+ sq_stack_resource_mgmt_3 = (NUM_HS_STACK_ENTRIES(num_hs_stack_entries) | -+ NUM_LS_STACK_ENTRIES(num_ls_stack_entries)); -+ -+ /* disable dyn gprs */ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); -+ radeon_ring_write(rdev, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2); -+ radeon_ring_write(rdev, 0); -+ -+ /* SQ config */ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 11)); -+ radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2); -+ radeon_ring_write(rdev, sq_config); -+ radeon_ring_write(rdev, sq_gpr_resource_mgmt_1); -+ radeon_ring_write(rdev, sq_gpr_resource_mgmt_2); -+ radeon_ring_write(rdev, sq_gpr_resource_mgmt_3); -+ radeon_ring_write(rdev, 0); -+ radeon_ring_write(rdev, 0); -+ radeon_ring_write(rdev, sq_thread_resource_mgmt); -+ radeon_ring_write(rdev, sq_thread_resource_mgmt_2); -+ radeon_ring_write(rdev, sq_stack_resource_mgmt_1); -+ radeon_ring_write(rdev, sq_stack_resource_mgmt_2); -+ radeon_ring_write(rdev, sq_stack_resource_mgmt_3); -+ } - - /* CONTEXT_CONTROL */ - radeon_ring_write(rdev, 0xc0012800); -@@ -560,7 +573,10 @@ int evergreen_blit_init(struct radeon_device *rdev) - mutex_init(&rdev->r600_blit.mutex); - rdev->r600_blit.state_offset = 0; - -- rdev->r600_blit.state_len = evergreen_default_size; -+ if (rdev->family < CHIP_CAYMAN) -+ rdev->r600_blit.state_len = evergreen_default_size; -+ else -+ rdev->r600_blit.state_len = cayman_default_size; - - dwords = rdev->r600_blit.state_len; - while (dwords & 0xf) { -@@ -572,11 +588,17 @@ int evergreen_blit_init(struct radeon_device *rdev) - obj_size = ALIGN(obj_size, 256); - - rdev->r600_blit.vs_offset = obj_size; -- obj_size += evergreen_vs_size * 4; -+ if (rdev->family < CHIP_CAYMAN) -+ obj_size += evergreen_vs_size * 4; -+ else -+ obj_size += cayman_vs_size * 4; - obj_size = ALIGN(obj_size, 256); - - rdev->r600_blit.ps_offset = obj_size; -- obj_size += evergreen_ps_size * 4; -+ if (rdev->family < CHIP_CAYMAN) -+ obj_size += evergreen_ps_size * 4; -+ else -+ obj_size += cayman_ps_size * 4; - obj_size = ALIGN(obj_size, 256); - - r = radeon_bo_create(rdev, NULL, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, -@@ -599,16 +621,29 @@ int evergreen_blit_init(struct radeon_device *rdev) - return r; - } - -- memcpy_toio(ptr + rdev->r600_blit.state_offset, -- evergreen_default_state, rdev->r600_blit.state_len * 4); -- -- if (num_packet2s) -- memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), -- packet2s, num_packet2s * 4); -- for (i = 0; i < evergreen_vs_size; i++) -- *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(evergreen_vs[i]); -- for (i = 0; i < evergreen_ps_size; i++) -- *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(evergreen_ps[i]); -+ if (rdev->family < CHIP_CAYMAN) { -+ memcpy_toio(ptr + rdev->r600_blit.state_offset, -+ evergreen_default_state, rdev->r600_blit.state_len * 4); -+ -+ if (num_packet2s) -+ memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), -+ packet2s, num_packet2s * 4); -+ for (i = 0; i < evergreen_vs_size; i++) -+ *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(evergreen_vs[i]); -+ for (i = 0; i < evergreen_ps_size; i++) -+ *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(evergreen_ps[i]); -+ } else { -+ memcpy_toio(ptr + rdev->r600_blit.state_offset, -+ cayman_default_state, rdev->r600_blit.state_len * 4); -+ -+ if (num_packet2s) -+ memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), -+ packet2s, num_packet2s * 4); -+ for (i = 0; i < cayman_vs_size; i++) -+ *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(cayman_vs[i]); -+ for (i = 0; i < cayman_ps_size; i++) -+ *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(cayman_ps[i]); -+ } - radeon_bo_kunmap(rdev->r600_blit.shader_obj); - radeon_bo_unreserve(rdev->r600_blit.shader_obj); - -diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h -index 9453384..1636e34 100644 ---- a/drivers/gpu/drm/radeon/evergreend.h -+++ b/drivers/gpu/drm/radeon/evergreend.h -@@ -64,6 +64,8 @@ - #define GB_BACKEND_MAP 0x98FC - #define DMIF_ADDR_CONFIG 0xBD4 - #define HDP_ADDR_CONFIG 0x2F48 -+#define HDP_MISC_CNTL 0x2F4C -+#define HDP_FLUSH_INVALIDATE_CACHE (1 << 0) - - #define CC_SYS_RB_BACKEND_DISABLE 0x3F88 - #define GC_USER_RB_BACKEND_DISABLE 0x9B7C -@@ -166,10 +168,16 @@ - #define SE_DB_BUSY (1 << 30) - #define SE_CB_BUSY (1 << 31) - /* evergreen */ -+#define CG_THERMAL_CTRL 0x72c -+#define TOFFSET_MASK 0x00003FE0 -+#define TOFFSET_SHIFT 5 - #define CG_MULT_THERMAL_STATUS 0x740 - #define ASIC_T(x) ((x) << 16) --#define ASIC_T_MASK 0x7FF0000 -+#define ASIC_T_MASK 0x07FF0000 - #define ASIC_T_SHIFT 16 -+#define CG_TS0_STATUS 0x760 -+#define TS0_ADC_DOUT_MASK 0x000003FF -+#define TS0_ADC_DOUT_SHIFT 0 - /* APU */ - #define CG_THERMAL_STATUS 0x678 - -@@ -200,6 +208,7 @@ - #define BURSTLENGTH_SHIFT 9 - #define BURSTLENGTH_MASK 0x00000200 - #define CHANSIZE_OVERRIDE (1 << 11) -+#define FUS_MC_ARB_RAMCFG 0x2768 - #define MC_VM_AGP_TOP 0x2028 - #define MC_VM_AGP_BOT 0x202C - #define MC_VM_AGP_BASE 0x2030 -diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c -index 8c199c4..b226cca 100644 ---- a/drivers/gpu/drm/radeon/ni.c -+++ b/drivers/gpu/drm/radeon/ni.c -@@ -417,7 +417,7 @@ static u32 cayman_get_tile_pipe_to_backend_map(struct radeon_device *rdev, - num_shader_engines = 1; - if (num_shader_engines > rdev->config.cayman.max_shader_engines) - num_shader_engines = rdev->config.cayman.max_shader_engines; -- if (num_backends_per_asic > num_shader_engines) -+ if (num_backends_per_asic < num_shader_engines) - num_backends_per_asic = num_shader_engines; - if (num_backends_per_asic > (rdev->config.cayman.max_backends_per_se * num_shader_engines)) - num_backends_per_asic = rdev->config.cayman.max_backends_per_se * num_shader_engines; -@@ -674,7 +674,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) - - cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE); - cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG); -- cgts_tcc_disable = RREG32(CGTS_TCC_DISABLE); -+ cgts_tcc_disable = 0xff000000; - gc_user_rb_backend_disable = RREG32(GC_USER_RB_BACKEND_DISABLE); - gc_user_shader_pipe_config = RREG32(GC_USER_SHADER_PIPE_CONFIG); - cgts_user_tcc_disable = RREG32(CGTS_USER_TCC_DISABLE); -@@ -829,7 +829,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) - rdev->config.cayman.tile_config |= - ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; - rdev->config.cayman.tile_config |= -- (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT; -+ ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; - rdev->config.cayman.tile_config |= - ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; - -@@ -871,7 +871,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) - - smx_dc_ctl0 = RREG32(SMX_DC_CTL0); - smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff); -- smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets); -+ smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.cayman.sx_num_of_sets); - WREG32(SMX_DC_CTL0, smx_dc_ctl0); - - WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE); -@@ -887,20 +887,20 @@ static void cayman_gpu_init(struct radeon_device *rdev) - - WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO); - -- WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) | -- POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) | -- SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1))); -+ WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.cayman.sx_max_export_size / 4) - 1) | -+ POSITION_BUFFER_SIZE((rdev->config.cayman.sx_max_export_pos_size / 4) - 1) | -+ SMX_BUFFER_SIZE((rdev->config.cayman.sx_max_export_smx_size / 4) - 1))); - -- WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.evergreen.sc_prim_fifo_size) | -- SC_HIZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_hiz_tile_fifo_size) | -- SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_earlyz_tile_fifo_size))); -+ WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.cayman.sc_prim_fifo_size) | -+ SC_HIZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_hiz_tile_fifo_size) | -+ SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_earlyz_tile_fifo_size))); - - - WREG32(VGT_NUM_INSTANCES, 1); - - WREG32(CP_PERFMON_CNTL, 0); - -- WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.evergreen.sq_num_cf_insts) | -+ WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.cayman.sq_num_cf_insts) | - FETCH_FIFO_HIWATER(0x4) | - DONE_FIFO_HIWATER(0xe0) | - ALU_UPDATE_FIFO_HIWATER(0x8))); -@@ -931,6 +931,10 @@ static void cayman_gpu_init(struct radeon_device *rdev) - WREG32(CB_PERF_CTR3_SEL_0, 0); - WREG32(CB_PERF_CTR3_SEL_1, 0); - -+ tmp = RREG32(HDP_MISC_CNTL); -+ tmp |= HDP_FLUSH_INVALIDATE_CACHE; -+ WREG32(HDP_MISC_CNTL, tmp); -+ - hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); - WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); - -@@ -1383,14 +1387,12 @@ static int cayman_startup(struct radeon_device *rdev) - return r; - cayman_gpu_init(rdev); - --#if 0 -- r = cayman_blit_init(rdev); -+ r = evergreen_blit_init(rdev); - if (r) { -- cayman_blit_fini(rdev); -+ evergreen_blit_fini(rdev); - rdev->asic->copy = NULL; - dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); - } --#endif - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); -@@ -1448,7 +1450,7 @@ int cayman_resume(struct radeon_device *rdev) - - int cayman_suspend(struct radeon_device *rdev) - { -- /* int r; */ -+ int r; - - /* FIXME: we should wait for ring to be empty */ - cayman_cp_enable(rdev, false); -@@ -1457,14 +1459,13 @@ int cayman_suspend(struct radeon_device *rdev) - radeon_wb_disable(rdev); - cayman_pcie_gart_disable(rdev); - --#if 0 - /* unpin shaders bo */ - r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); - if (likely(r == 0)) { - radeon_bo_unpin(rdev->r600_blit.shader_obj); - radeon_bo_unreserve(rdev->r600_blit.shader_obj); - } --#endif -+ - return 0; - } - -@@ -1576,7 +1577,7 @@ int cayman_init(struct radeon_device *rdev) - - void cayman_fini(struct radeon_device *rdev) - { -- /* cayman_blit_fini(rdev); */ -+ evergreen_blit_fini(rdev); - cayman_cp_fini(rdev); - r600_irq_fini(rdev); - radeon_wb_fini(rdev); -diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h -index 0f9a08b..9736746 100644 ---- a/drivers/gpu/drm/radeon/nid.h -+++ b/drivers/gpu/drm/radeon/nid.h -@@ -136,6 +136,8 @@ - #define HDP_NONSURFACE_INFO 0x2C08 - #define HDP_NONSURFACE_SIZE 0x2C0C - #define HDP_ADDR_CONFIG 0x2F48 -+#define HDP_MISC_CNTL 0x2F4C -+#define HDP_FLUSH_INVALIDATE_CACHE (1 << 0) - - #define CC_SYS_RB_BACKEND_DISABLE 0x3F88 - #define GC_USER_SYS_RB_BACKEND_DISABLE 0x3F8C -@@ -351,7 +353,7 @@ - #define MULTI_GPU_TILE_SIZE_MASK 0x03000000 - #define MULTI_GPU_TILE_SIZE_SHIFT 24 - #define ROW_SIZE(x) ((x) << 28) --#define ROW_SIZE_MASK 0x30000007 -+#define ROW_SIZE_MASK 0x30000000 - #define ROW_SIZE_SHIFT 28 - #define NUM_LOWER_PIPES(x) ((x) << 30) - #define NUM_LOWER_PIPES_MASK 0x40000000 -diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c -index ca57619..b9b3c2a 100644 ---- a/drivers/gpu/drm/radeon/radeon_asic.c -+++ b/drivers/gpu/drm/radeon/radeon_asic.c -@@ -782,6 +782,7 @@ static struct radeon_asic evergreen_asic = { - .hpd_fini = &evergreen_hpd_fini, - .hpd_sense = &evergreen_hpd_sense, - .hpd_set_polarity = &evergreen_hpd_set_polarity, -+ .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .pm_misc = &evergreen_pm_misc, - .pm_prepare = &evergreen_pm_prepare, -@@ -828,6 +829,7 @@ static struct radeon_asic sumo_asic = { - .hpd_fini = &evergreen_hpd_fini, - .hpd_sense = &evergreen_hpd_sense, - .hpd_set_polarity = &evergreen_hpd_set_polarity, -+ .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .pm_misc = &evergreen_pm_misc, - .pm_prepare = &evergreen_pm_prepare, -@@ -874,6 +876,7 @@ static struct radeon_asic btc_asic = { - .hpd_fini = &evergreen_hpd_fini, - .hpd_sense = &evergreen_hpd_sense, - .hpd_set_polarity = &evergreen_hpd_set_polarity, -+ .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .pm_misc = &evergreen_pm_misc, - .pm_prepare = &evergreen_pm_prepare, -@@ -903,9 +906,9 @@ static struct radeon_asic cayman_asic = { - .get_vblank_counter = &evergreen_get_vblank_counter, - .fence_ring_emit = &r600_fence_ring_emit, - .cs_parse = &evergreen_cs_parse, -- .copy_blit = NULL, -- .copy_dma = NULL, -- .copy = NULL, -+ .copy_blit = &evergreen_copy_blit, -+ .copy_dma = &evergreen_copy_blit, -+ .copy = &evergreen_copy_blit, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, -@@ -920,6 +923,7 @@ static struct radeon_asic cayman_asic = { - .hpd_fini = &evergreen_hpd_fini, - .hpd_sense = &evergreen_hpd_sense, - .hpd_set_polarity = &evergreen_hpd_set_polarity, -+ .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .pm_misc = &evergreen_pm_misc, - .pm_prepare = &evergreen_pm_prepare, -diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c -index ed5dfe5..9d95792 100644 ---- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c -+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c -@@ -15,6 +15,9 @@ - #define ATPX_VERSION 0 - #define ATPX_GPU_PWR 2 - #define ATPX_MUX_SELECT 3 -+#define ATPX_I2C_MUX_SELECT 4 -+#define ATPX_SWITCH_START 5 -+#define ATPX_SWITCH_END 6 - - #define ATPX_INTEGRATED 0 - #define ATPX_DISCRETE 1 -@@ -149,13 +152,35 @@ static int radeon_atpx_switch_mux(acpi_handle handle, int mux_id) - return radeon_atpx_execute(handle, ATPX_MUX_SELECT, mux_id); - } - -+static int radeon_atpx_switch_i2c_mux(acpi_handle handle, int mux_id) -+{ -+ return radeon_atpx_execute(handle, ATPX_I2C_MUX_SELECT, mux_id); -+} -+ -+static int radeon_atpx_switch_start(acpi_handle handle, int gpu_id) -+{ -+ return radeon_atpx_execute(handle, ATPX_SWITCH_START, gpu_id); -+} -+ -+static int radeon_atpx_switch_end(acpi_handle handle, int gpu_id) -+{ -+ return radeon_atpx_execute(handle, ATPX_SWITCH_END, gpu_id); -+} - - static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) - { -+ int gpu_id; -+ - if (id == VGA_SWITCHEROO_IGD) -- radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 0); -+ gpu_id = ATPX_INTEGRATED; - else -- radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 1); -+ gpu_id = ATPX_DISCRETE; -+ -+ radeon_atpx_switch_start(radeon_atpx_priv.atpx_handle, gpu_id); -+ radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, gpu_id); -+ radeon_atpx_switch_i2c_mux(radeon_atpx_priv.atpx_handle, gpu_id); -+ radeon_atpx_switch_end(radeon_atpx_priv.atpx_handle, gpu_id); -+ - return 0; - } - -diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c -index 8caf546..089ab92 100644 ---- a/drivers/gpu/drm/radeon/radeon_combios.c -+++ b/drivers/gpu/drm/radeon/radeon_combios.c -@@ -2504,6 +2504,12 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) - return true; - } - -+static const char *thermal_controller_names[] = { -+ "NONE", -+ "lm63", -+ "adm1032", -+}; -+ - void radeon_combios_get_power_modes(struct radeon_device *rdev) - { - struct drm_device *dev = rdev->ddev; -@@ -2524,6 +2530,54 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) - return; - } - -+ /* check for a thermal chip */ -+ offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE); -+ if (offset) { -+ u8 thermal_controller = 0, gpio = 0, i2c_addr = 0, clk_bit = 0, data_bit = 0; -+ struct radeon_i2c_bus_rec i2c_bus; -+ -+ rev = RBIOS8(offset); -+ -+ if (rev == 0) { -+ thermal_controller = RBIOS8(offset + 3); -+ gpio = RBIOS8(offset + 4) & 0x3f; -+ i2c_addr = RBIOS8(offset + 5); -+ } else if (rev == 1) { -+ thermal_controller = RBIOS8(offset + 4); -+ gpio = RBIOS8(offset + 5) & 0x3f; -+ i2c_addr = RBIOS8(offset + 6); -+ } else if (rev == 2) { -+ thermal_controller = RBIOS8(offset + 4); -+ gpio = RBIOS8(offset + 5) & 0x3f; -+ i2c_addr = RBIOS8(offset + 6); -+ clk_bit = RBIOS8(offset + 0xa); -+ data_bit = RBIOS8(offset + 0xb); -+ } -+ if ((thermal_controller > 0) && (thermal_controller < 3)) { -+ DRM_INFO("Possible %s thermal controller at 0x%02x\n", -+ thermal_controller_names[thermal_controller], -+ i2c_addr >> 1); -+ if (gpio == DDC_LCD) { -+ /* MM i2c */ -+ i2c_bus.valid = true; -+ i2c_bus.hw_capable = true; -+ i2c_bus.mm_i2c = true; -+ i2c_bus.i2c_id = 0xa0; -+ } else if (gpio == DDC_GPIO) -+ i2c_bus = combios_setup_i2c_bus(rdev, gpio, 1 << clk_bit, 1 << data_bit); -+ else -+ i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0); -+ rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); -+ if (rdev->pm.i2c_bus) { -+ struct i2c_board_info info = { }; -+ const char *name = thermal_controller_names[thermal_controller]; -+ info.addr = i2c_addr >> 1; -+ strlcpy(info.type, name, sizeof(info.type)); -+ i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); -+ } -+ } -+ } -+ - if (rdev->flags & RADEON_IS_MOBILITY) { - offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE); - if (offset) { -diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c -index 017ac54..5df2acd 100644 ---- a/drivers/gpu/drm/radeon/radeon_cursor.c -+++ b/drivers/gpu/drm/radeon/radeon_cursor.c -@@ -167,9 +167,6 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, - return -EINVAL; - } - -- radeon_crtc->cursor_width = width; -- radeon_crtc->cursor_height = height; -- - obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); - if (!obj) { - DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); -@@ -180,6 +177,9 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, - if (ret) - goto fail; - -+ radeon_crtc->cursor_width = width; -+ radeon_crtc->cursor_height = height; -+ - radeon_lock_cursor(crtc, true); - /* XXX only 27 bit offset for legacy cursor */ - radeon_set_cursor(crtc, obj, gpu_addr); -diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c -index 0444911..fc44376 100644 ---- a/drivers/gpu/drm/radeon/radeon_drv.c -+++ b/drivers/gpu/drm/radeon/radeon_drv.c -@@ -50,9 +50,10 @@ - * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs - * 2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK, clock crystal query - * 2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query -+ * 2.10.0 - fusion 2D tiling - */ - #define KMS_DRIVER_MAJOR 2 --#define KMS_DRIVER_MINOR 9 -+#define KMS_DRIVER_MINOR 10 - #define KMS_DRIVER_PATCHLEVEL 0 - int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); - int radeon_driver_unload_kms(struct drm_device *dev); -diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c -index 320ddc3..4fec348 100644 ---- a/drivers/gpu/drm/radeon/radeon_pm.c -+++ b/drivers/gpu/drm/radeon/radeon_pm.c -@@ -485,6 +485,7 @@ static int radeon_hwmon_init(struct radeon_device *rdev) - case THERMAL_TYPE_RV6XX: - case THERMAL_TYPE_RV770: - case THERMAL_TYPE_EVERGREEN: -+ case THERMAL_TYPE_NI: - case THERMAL_TYPE_SUMO: - rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev); - if (IS_ERR(rdev->pm.int_hwmon_dev)) { -diff --git a/drivers/gpu/drm/radeon/reg_srcs/cayman b/drivers/gpu/drm/radeon/reg_srcs/cayman -index 6334f8a..0aa8e85 100644 ---- a/drivers/gpu/drm/radeon/reg_srcs/cayman -+++ b/drivers/gpu/drm/radeon/reg_srcs/cayman -@@ -33,6 +33,7 @@ cayman 0x9400 - 0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS - 0x00009100 SPI_CONFIG_CNTL - 0x0000913C SPI_CONFIG_CNTL_1 -+0x00009508 TA_CNTL_AUX - 0x00009830 DB_DEBUG - 0x00009834 DB_DEBUG2 - 0x00009838 DB_DEBUG3 -diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen -index 7e16371..0e28cae 100644 ---- a/drivers/gpu/drm/radeon/reg_srcs/evergreen -+++ b/drivers/gpu/drm/radeon/reg_srcs/evergreen -@@ -46,6 +46,7 @@ evergreen 0x9400 - 0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS - 0x00009100 SPI_CONFIG_CNTL - 0x0000913C SPI_CONFIG_CNTL_1 -+0x00009508 TA_CNTL_AUX - 0x00009700 VC_CNTL - 0x00009714 VC_ENHANCE - 0x00009830 DB_DEBUG diff --git a/drm-radeon-update3.patch b/drm-radeon-update3.patch deleted file mode 100644 index 626ccdc..0000000 --- a/drm-radeon-update3.patch +++ /dev/null @@ -1,820 +0,0 @@ -commit 3c79cf677a2eca93762d15f69744937d43185573 -Author: Alex Deucher -Date: Thu Jun 23 12:19:32 2011 -0400 - - drm/radeon/kms: handle special cases for vddc - - A voltage value of 0xff01 requires that the driver - look up the max voltage for the board based using the - atom SetVoltage command table. - - Setting the proper voltage should fix stability on - some newer asics. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 63311583922e52b7687233c18e9eebe83207d2e8 -Author: Alex Deucher -Date: Thu Jun 23 00:49:29 2011 -0400 - - drm/radeon/kms: fix num_banks tiling config for fusion - - The field is encoded: - 0 = 4 banks - 1 = 8 banks - 2 = 16 banks - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 1421991c155016ce31777d09ebfdfe3eb04cb78c -Author: Alex Deucher -Date: Mon Jun 20 13:00:31 2011 -0400 - - drm/radeon/kms/r6xx+: voltage fixes - - 0xff01 is not an actual voltage value, but a flag - for the driver. If the power state as that value, - skip setting the voltage. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit a7b65dda144af8ba443f1745875440c87a41b0a3 -Author: Dave Airlie -Date: Sat Jun 18 03:59:51 2011 +0000 - - drm/radeon: avoid warnings from r600/eg irq handlers on powered off card. - - Since we were calling the wptr function before checking if the IH was - even enabled, or the GPU wasn't shutdown, we'd get spam in the logs when - the GPU readback 0xffffffff. This reorders things so we return early - in the no IH and GPU shutdown cases. - - Reported-and-tested-by: ManDay on #radeon - Reviewed-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 3f662051e0acf55bc8c2ea246c9f05e004a2d698 -Author: Alex Deucher -Date: Fri Jun 17 06:11:30 2011 +0000 - - drm/radeon/kms: add missing param for dce3.2 DP transmitter setup - - This is used during phy init to set up the phy for DP. This may - fix DP problems on DCE3.2 cards. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit dc4f34ba0796f4b09501b035825c02c405335063 -Author: Alex Deucher -Date: Fri Jun 17 13:13:52 2011 -0400 - - drm/radeon/kms/atom: fix duallink on some early DCE3.2 cards - - Certain revisions of the vbios on DCE3.2 cards have a bug - in the transmitter control table which prevents duallink from - being enabled properly on some cards. The action switch statement - jumps to the wrong offset for the OUTPUT_ENABLE action. The fix - is to use the ENABLE action rather than the OUTPUT_ENABLE action - on the affected cards. In fixed version of the vbios, both - actions jump to the same offset, so the change should be safe. - - Reported-and-tested-by: Dave Airlie - Signed-off-by: Alex Deucher - Cc: stable@kernel.org - Signed-off-by: Dave Airlie - -commit b5097472f2119480f60657f92b17dd79bcf8e24a -Author: Alex Deucher -Date: Mon Jun 13 17:39:06 2011 -0400 - - drm/radeon/kms: use helper functions for fence read/write - - The existing code assumed scratch registers in a number - of places while in most cases we are be using writeback - and events rather than scratch registers. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 4414ac4ea84407d14e9fde512c1c229f9cfc96c4 -Author: Alex Deucher -Date: Thu Jun 16 18:14:22 2011 +0000 - - drm/radeon/kms: fix num crtcs for Cedar and Caicos - - Only support 4 rather than 6. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit c4eee24a87a71c14f223e85065cccea6bf32321d -Author: Alex Deucher -Date: Mon Jun 13 22:02:51 2011 +0000 - - drm/radeon/kms: clear wb memory by default - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit 12ca85df2db5988ea5c53d0ee53ff1b1cf1257fd -Author: Alex Deucher -Date: Tue Jun 14 19:15:53 2011 +0000 - - drm/radeon/kms: signed fix for evergreen thermal - - temperature is signed. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit dd53acd144d8fa6385e50949f4f635890420ba0b -Author: Alex Deucher -Date: Wed Jun 8 13:01:11 2011 -0400 - - drm/radeon/kms: check modes against max pixel clock - - Filter out modes that are higher than the max pixel - clock. - - Signed-off-by: Alex Deucher - Signed-off-by: Dave Airlie - -commit a812b560d0d041f2318ae4243ead692e26bae429 -Author: Daniel Haid -Date: Wed Jun 8 20:04:45 2011 +1000 - - drm/radeon/kms: fix for radeon on systems >4GB without hardware iommu - - On my x86_64 system with >4GB of ram and swiotlb instead of - a hardware iommu (because I have a VIA chipset), the call - to pci_set_dma_mask (see below) with 40bits returns an error. - - But it seems that the radeon driver is designed to have - need_dma32 = true exactly if pci_set_dma_mask is called - with 32 bits and false if it is called with 40 bits. - - I have read somewhere that the default are 32 bits. So if the - call fails I suppose that need_dma32 should be set to true. - - And indeed the patch fixes the problem I have had before - and which I had described here: - http://choon.net/forum/read.php?21,106131,115940 - - Acked-by: Alex Deucher - cc: stable@kernel.org - Signed-off-by: Dave Airlie - -commit 262016fe924bbc06d50bcfc816c635d465cd503d -Author: Alex Deucher -Date: Fri May 27 10:05:03 2011 -0400 - - drm/radeon/kms: viewport height has to be even - - Otherwise, no vblank interrupts. - Fixes: - https://bugs.freedesktop.org/show_bug.cgi?id=37522 - - Signed-off-by: Alex Deucher - Cc: stable@kernel.org - Signed-off-by: Dave Airlie - -commit 36b3cb168810e68ae8dd2036189c4f2cfc0c6d49 -Author: Marek Olšák -Date: Fri Jun 10 14:41:26 2011 +0000 - - drm/radeon/kms: do bounds checking for 3D_LOAD_VBPNTR and bump array limit - - To my knowledge, the limit is 16 on r300. - (the docs don't say what the limit is) - - The lack of bounds checking can be abused to do all sorts of things - (from bypassing parts of the CS checker to crashing the kernel). - - Bugzilla: - https://bugs.freedesktop.org/show_bug.cgi?id=36745 - - Cc: stable@kernel.org - Signed-off-by: Marek Olšák - Signed-off-by: Dave Airlie -diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c -index 2bab32f..1fce6b7 100644 ---- a/drivers/gpu/drm/radeon/atombios_crtc.c -+++ b/drivers/gpu/drm/radeon/atombios_crtc.c -@@ -1011,7 +1011,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, - uint64_t fb_location; - uint32_t fb_format, fb_pitch_pixels, tiling_flags; - u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); -- u32 tmp; -+ u32 tmp, viewport_w, viewport_h; - int r; - - /* no fb bound */ -@@ -1137,8 +1137,10 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, - y &= ~1; - WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset, - (x << 16) | y); -+ viewport_w = crtc->mode.hdisplay; -+ viewport_h = (crtc->mode.vdisplay + 1) & ~1; - WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, -- (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); -+ (viewport_w << 16) | viewport_h); - - /* pageflip setup */ - /* make sure flip is at vb rather than hb */ -@@ -1179,7 +1181,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, - uint64_t fb_location; - uint32_t fb_format, fb_pitch_pixels, tiling_flags; - u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE; -- u32 tmp; -+ u32 tmp, viewport_w, viewport_h; - int r; - - /* no fb bound */ -@@ -1304,8 +1306,10 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, - y &= ~1; - WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, - (x << 16) | y); -+ viewport_w = crtc->mode.hdisplay; -+ viewport_h = (crtc->mode.vdisplay + 1) & ~1; - WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, -- (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); -+ (viewport_w << 16) | viewport_h); - - /* pageflip setup */ - /* make sure flip is at vb rather than hb */ -diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c -index 1b583f8..81f5211 100644 ---- a/drivers/gpu/drm/radeon/evergreen.c -+++ b/drivers/gpu/drm/radeon/evergreen.c -@@ -88,7 +88,8 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) - /* get temperature in millidegrees */ - int evergreen_get_temp(struct radeon_device *rdev) - { -- u32 temp, toffset, actual_temp = 0; -+ u32 temp, toffset; -+ int actual_temp = 0; - - if (rdev->family == CHIP_JUNIPER) { - toffset = (RREG32(CG_THERMAL_CTRL) & TOFFSET_MASK) >> -@@ -139,11 +140,17 @@ void evergreen_pm_misc(struct radeon_device *rdev) - struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; - - if (voltage->type == VOLTAGE_SW) { -+ /* 0xff01 is a flag rather then an actual voltage */ -+ if (voltage->voltage == 0xff01) -+ return; - if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) { - radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); - rdev->pm.current_vddc = voltage->voltage; - DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage); - } -+ /* 0xff01 is a flag rather then an actual voltage */ -+ if (voltage->vddci == 0xff01) -+ return; - if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) { - radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI); - rdev->pm.current_vddci = voltage->vddci; -@@ -1954,9 +1961,9 @@ static void evergreen_gpu_init(struct radeon_device *rdev) - rdev->config.evergreen.tile_config |= (3 << 0); - break; - } -- /* num banks is 8 on all fusion asics */ -+ /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */ - if (rdev->flags & RADEON_IS_IGP) -- rdev->config.evergreen.tile_config |= 8 << 4; -+ rdev->config.evergreen.tile_config |= 1 << 4; - else - rdev->config.evergreen.tile_config |= - ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; -@@ -2636,28 +2643,25 @@ static inline u32 evergreen_get_ih_wptr(struct radeon_device *rdev) - - int evergreen_irq_process(struct radeon_device *rdev) - { -- u32 wptr = evergreen_get_ih_wptr(rdev); -- u32 rptr = rdev->ih.rptr; -+ u32 wptr; -+ u32 rptr; - u32 src_id, src_data; - u32 ring_index; - unsigned long flags; - bool queue_hotplug = false; - -- DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); -- if (!rdev->ih.enabled) -+ if (!rdev->ih.enabled || rdev->shutdown) - return IRQ_NONE; - -- spin_lock_irqsave(&rdev->ih.lock, flags); -+ wptr = evergreen_get_ih_wptr(rdev); -+ rptr = rdev->ih.rptr; -+ DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); - -+ spin_lock_irqsave(&rdev->ih.lock, flags); - if (rptr == wptr) { - spin_unlock_irqrestore(&rdev->ih.lock, flags); - return IRQ_NONE; - } -- if (rdev->shutdown) { -- spin_unlock_irqrestore(&rdev->ih.lock, flags); -- return IRQ_NONE; -- } -- - restart_ih: - /* display interrupts */ - evergreen_irq_ack(rdev); -diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h -index 2fef9de..686f9dc 100644 ---- a/drivers/gpu/drm/radeon/r100_track.h -+++ b/drivers/gpu/drm/radeon/r100_track.h -@@ -63,7 +63,7 @@ struct r100_cs_track { - unsigned num_arrays; - unsigned max_indx; - unsigned color_channel_mask; -- struct r100_cs_track_array arrays[11]; -+ struct r100_cs_track_array arrays[16]; - struct r100_cs_track_cb cb[R300_MAX_CB]; - struct r100_cs_track_cb zb; - struct r100_cs_track_cb aa; -@@ -146,6 +146,12 @@ static inline int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, - ib = p->ib->ptr; - track = (struct r100_cs_track *)p->track; - c = radeon_get_ib_value(p, idx++) & 0x1F; -+ if (c > 16) { -+ DRM_ERROR("Only 16 vertex buffers are allowed %d\n", -+ pkt->opcode); -+ r100_cs_dump_packet(p, pkt); -+ return -EINVAL; -+ } - track->num_arrays = c; - for (i = 0; i < (c - 1); i+=2, idx+=3) { - r = r100_cs_packet_next_reloc(p, &reloc); -diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c -index 70e9fb0..e7157b7 100644 ---- a/drivers/gpu/drm/radeon/r600.c -+++ b/drivers/gpu/drm/radeon/r600.c -@@ -586,6 +586,9 @@ void r600_pm_misc(struct radeon_device *rdev) - struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; - - if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { -+ /* 0xff01 is a flag rather then an actual voltage */ -+ if (voltage->voltage == 0xff01) -+ return; - if (voltage->voltage != rdev->pm.current_vddc) { - radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); - rdev->pm.current_vddc = voltage->voltage; -@@ -3286,27 +3289,26 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) - - int r600_irq_process(struct radeon_device *rdev) - { -- u32 wptr = r600_get_ih_wptr(rdev); -- u32 rptr = rdev->ih.rptr; -+ u32 wptr; -+ u32 rptr; - u32 src_id, src_data; - u32 ring_index; - unsigned long flags; - bool queue_hotplug = false; - -- DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); -- if (!rdev->ih.enabled) -+ if (!rdev->ih.enabled || rdev->shutdown) - return IRQ_NONE; - -+ wptr = r600_get_ih_wptr(rdev); -+ rptr = rdev->ih.rptr; -+ DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); -+ - spin_lock_irqsave(&rdev->ih.lock, flags); - - if (rptr == wptr) { - spin_unlock_irqrestore(&rdev->ih.lock, flags); - return IRQ_NONE; - } -- if (rdev->shutdown) { -- spin_unlock_irqrestore(&rdev->ih.lock, flags); -- return IRQ_NONE; -- } - - restart_ih: - /* display interrupts */ -diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h -index 27df931..c46552d 100644 ---- a/drivers/gpu/drm/radeon/radeon.h -+++ b/drivers/gpu/drm/radeon/radeon.h -@@ -165,6 +165,7 @@ struct radeon_clock { - uint32_t default_sclk; - uint32_t default_dispclk; - uint32_t dp_extclk; -+ uint32_t max_pixel_clock; - }; - - /* -@@ -178,6 +179,7 @@ void radeon_pm_resume(struct radeon_device *rdev); - void radeon_combios_get_power_modes(struct radeon_device *rdev); - void radeon_atombios_get_power_modes(struct radeon_device *rdev); - void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type); -+int radeon_atom_get_max_vddc(struct radeon_device *rdev, u16 *voltage); - void rs690_pm_info(struct radeon_device *rdev); - extern int rv6xx_get_temp(struct radeon_device *rdev); - extern int rv770_get_temp(struct radeon_device *rdev); -diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c -index b9b3c2a..6f5bd29 100644 ---- a/drivers/gpu/drm/radeon/radeon_asic.c -+++ b/drivers/gpu/drm/radeon/radeon_asic.c -@@ -938,6 +938,13 @@ static struct radeon_asic cayman_asic = { - int radeon_asic_init(struct radeon_device *rdev) - { - radeon_register_accessor_init(rdev); -+ -+ /* set the number of crtcs */ -+ if (rdev->flags & RADEON_SINGLE_CRTC) -+ rdev->num_crtc = 1; -+ else -+ rdev->num_crtc = 2; -+ - switch (rdev->family) { - case CHIP_R100: - case CHIP_RV100: -@@ -1017,6 +1024,11 @@ int radeon_asic_init(struct radeon_device *rdev) - case CHIP_JUNIPER: - case CHIP_CYPRESS: - case CHIP_HEMLOCK: -+ /* set num crtcs */ -+ if (rdev->family == CHIP_CEDAR) -+ rdev->num_crtc = 4; -+ else -+ rdev->num_crtc = 6; - rdev->asic = &evergreen_asic; - break; - case CHIP_PALM: -@@ -1025,10 +1037,17 @@ int radeon_asic_init(struct radeon_device *rdev) - case CHIP_BARTS: - case CHIP_TURKS: - case CHIP_CAICOS: -+ /* set num crtcs */ -+ if (rdev->family == CHIP_CAICOS) -+ rdev->num_crtc = 4; -+ else -+ rdev->num_crtc = 6; - rdev->asic = &btc_asic; - break; - case CHIP_CAYMAN: - rdev->asic = &cayman_asic; -+ /* set num crtcs */ -+ rdev->num_crtc = 6; - break; - default: - /* FIXME: not supported yet */ -@@ -1040,18 +1059,6 @@ int radeon_asic_init(struct radeon_device *rdev) - rdev->asic->set_memory_clock = NULL; - } - -- /* set the number of crtcs */ -- if (rdev->flags & RADEON_SINGLE_CRTC) -- rdev->num_crtc = 1; -- else { -- if (ASIC_IS_DCE41(rdev)) -- rdev->num_crtc = 2; -- else if (ASIC_IS_DCE4(rdev)) -- rdev->num_crtc = 6; -- else -- rdev->num_crtc = 2; -- } -- - return 0; - } - -diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c -index f116516..ce861ff 100644 ---- a/drivers/gpu/drm/radeon/radeon_atombios.c -+++ b/drivers/gpu/drm/radeon/radeon_atombios.c -@@ -1246,6 +1246,10 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) - } - *dcpll = *p1pll; - -+ rdev->clock.max_pixel_clock = le16_to_cpu(firmware_info->info.usMaxPixelClock); -+ if (rdev->clock.max_pixel_clock == 0) -+ rdev->clock.max_pixel_clock = 40000; -+ - return true; - } - -@@ -2308,6 +2312,14 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, - le16_to_cpu(clock_info->r600.usVDDC); - } - -+ /* patch up vddc if necessary */ -+ if (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage == 0xff01) { -+ u16 vddc; -+ -+ if (radeon_atom_get_max_vddc(rdev, &vddc) == 0) -+ rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc; -+ } -+ - if (rdev->flags & RADEON_IS_IGP) { - /* skip invalid modes */ - if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) -@@ -2595,6 +2607,10 @@ void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 v - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) - return; - -+ /* 0xff01 is a flag rather then an actual voltage */ -+ if (voltage_level == 0xff01) -+ return; -+ - switch (crev) { - case 1: - args.v1.ucVoltageType = voltage_type; -@@ -2614,7 +2630,35 @@ void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 v - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - } - -+int radeon_atom_get_max_vddc(struct radeon_device *rdev, -+ u16 *voltage) -+{ -+ union set_voltage args; -+ int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); -+ u8 frev, crev; -+ -+ if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) -+ return -EINVAL; - -+ switch (crev) { -+ case 1: -+ return -EINVAL; -+ case 2: -+ args.v2.ucVoltageType = SET_VOLTAGE_GET_MAX_VOLTAGE; -+ args.v2.ucVoltageMode = 0; -+ args.v2.usVoltageLevel = 0; -+ -+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -+ -+ *voltage = le16_to_cpu(args.v2.usVoltageLevel); -+ break; -+ default: -+ DRM_ERROR("Unknown table version %d, %d\n", frev, crev); -+ return -EINVAL; -+ } -+ -+ return 0; -+} - - void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) - { -diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c -index 5249af8..2d48e7a 100644 ---- a/drivers/gpu/drm/radeon/radeon_clocks.c -+++ b/drivers/gpu/drm/radeon/radeon_clocks.c -@@ -117,7 +117,7 @@ static bool __devinit radeon_read_clocks_OF(struct drm_device *dev) - p1pll->reference_div = RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff; - if (p1pll->reference_div < 2) - p1pll->reference_div = 12; -- p2pll->reference_div = p1pll->reference_div; -+ p2pll->reference_div = p1pll->reference_div; - - /* These aren't in the device-tree */ - if (rdev->family >= CHIP_R420) { -@@ -139,6 +139,8 @@ static bool __devinit radeon_read_clocks_OF(struct drm_device *dev) - p2pll->pll_out_min = 12500; - p2pll->pll_out_max = 35000; - } -+ /* not sure what the max should be in all cases */ -+ rdev->clock.max_pixel_clock = 35000; - - spll->reference_freq = mpll->reference_freq = p1pll->reference_freq; - spll->reference_div = mpll->reference_div = -@@ -151,7 +153,7 @@ static bool __devinit radeon_read_clocks_OF(struct drm_device *dev) - else - rdev->clock.default_sclk = - radeon_legacy_get_engine_clock(rdev); -- -+ - val = of_get_property(dp, "ATY,MCLK", NULL); - if (val && *val) - rdev->clock.default_mclk = (*val) / 10; -@@ -160,7 +162,7 @@ static bool __devinit radeon_read_clocks_OF(struct drm_device *dev) - radeon_legacy_get_memory_clock(rdev); - - DRM_INFO("Using device-tree clock info\n"); -- -+ - return true; - } - #else -diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c -index 089ab92..8a53691 100644 ---- a/drivers/gpu/drm/radeon/radeon_combios.c -+++ b/drivers/gpu/drm/radeon/radeon_combios.c -@@ -833,6 +833,11 @@ bool radeon_combios_get_clock_info(struct drm_device *dev) - rdev->clock.default_sclk = sclk; - rdev->clock.default_mclk = mclk; - -+ if (RBIOS32(pll_info + 0x16)) -+ rdev->clock.max_pixel_clock = RBIOS32(pll_info + 0x16); -+ else -+ rdev->clock.max_pixel_clock = 35000; /* might need something asic specific */ -+ - return true; - } - return false; -diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c -index a186673..33cb72b 100644 ---- a/drivers/gpu/drm/radeon/radeon_connectors.c -+++ b/drivers/gpu/drm/radeon/radeon_connectors.c -@@ -621,8 +621,14 @@ static int radeon_vga_get_modes(struct drm_connector *connector) - static int radeon_vga_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) - { -+ struct drm_device *dev = connector->dev; -+ struct radeon_device *rdev = dev->dev_private; -+ - /* XXX check mode bandwidth */ -- /* XXX verify against max DAC output frequency */ -+ -+ if ((mode->clock / 10) > rdev->clock.max_pixel_clock) -+ return MODE_CLOCK_HIGH; -+ - return MODE_OK; - } - -@@ -1010,6 +1016,11 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector, - } else - return MODE_CLOCK_HIGH; - } -+ -+ /* check against the max pixel clock */ -+ if ((mode->clock / 10) > rdev->clock.max_pixel_clock) -+ return MODE_CLOCK_HIGH; -+ - return MODE_OK; - } - -diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c -index 207d43f..8a64a3b 100644 ---- a/drivers/gpu/drm/radeon/radeon_device.c -+++ b/drivers/gpu/drm/radeon/radeon_device.c -@@ -213,6 +213,8 @@ int radeon_wb_init(struct radeon_device *rdev) - return r; - } - -+ /* clear wb memory */ -+ memset((char *)rdev->wb.wb, 0, RADEON_GPU_PAGE_SIZE); - /* disable event_write fences */ - rdev->wb.use_event = false; - /* disabled via module param */ -@@ -752,6 +754,7 @@ int radeon_device_init(struct radeon_device *rdev, - dma_bits = rdev->need_dma32 ? 32 : 40; - r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(dma_bits)); - if (r) { -+ rdev->need_dma32 = true; - printk(KERN_WARNING "radeon: No suitable DMA available.\n"); - } - -diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c -index b427488..e2a1c7d 100644 ---- a/drivers/gpu/drm/radeon/radeon_encoders.c -+++ b/drivers/gpu/drm/radeon/radeon_encoders.c -@@ -994,9 +994,10 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t - break; - } - -- if (is_dp) -+ if (is_dp) { - args.v2.acConfig.fCoherentMode = 1; -- else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { -+ args.v2.acConfig.fDPConnector = 1; -+ } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { - if (dig->coherent_mode) - args.v2.acConfig.fCoherentMode = 1; - if (radeon_encoder->pixel_clock > 165000) -@@ -1294,7 +1295,11 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) - if (is_dig) { - switch (mode) { - case DRM_MODE_DPMS_ON: -- atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); -+ /* some early dce3.2 boards have a bug in their transmitter control table */ -+ if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730)) -+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); -+ else -+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); - if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { - struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); - -diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c -index 2b0ee62..3285de1 100644 ---- a/drivers/gpu/drm/radeon/radeon_fence.c -+++ b/drivers/gpu/drm/radeon/radeon_fence.c -@@ -40,6 +40,35 @@ - #include "radeon.h" - #include "radeon_trace.h" - -+static void radeon_fence_write(struct radeon_device *rdev, u32 seq) -+{ -+ if (rdev->wb.enabled) { -+ u32 scratch_index; -+ if (rdev->wb.use_event) -+ scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; -+ else -+ scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; -+ rdev->wb.wb[scratch_index/4] = cpu_to_le32(seq);; -+ } else -+ WREG32(rdev->fence_drv.scratch_reg, seq); -+} -+ -+static u32 radeon_fence_read(struct radeon_device *rdev) -+{ -+ u32 seq; -+ -+ if (rdev->wb.enabled) { -+ u32 scratch_index; -+ if (rdev->wb.use_event) -+ scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; -+ else -+ scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; -+ seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]); -+ } else -+ seq = RREG32(rdev->fence_drv.scratch_reg); -+ return seq; -+} -+ - int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) - { - unsigned long irq_flags; -@@ -50,12 +79,12 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) - return 0; - } - fence->seq = atomic_add_return(1, &rdev->fence_drv.seq); -- if (!rdev->cp.ready) { -+ if (!rdev->cp.ready) - /* FIXME: cp is not running assume everythings is done right - * away - */ -- WREG32(rdev->fence_drv.scratch_reg, fence->seq); -- } else -+ radeon_fence_write(rdev, fence->seq); -+ else - radeon_fence_ring_emit(rdev, fence); - - trace_radeon_fence_emit(rdev->ddev, fence->seq); -@@ -74,15 +103,7 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev) - bool wake = false; - unsigned long cjiffies; - -- if (rdev->wb.enabled) { -- u32 scratch_index; -- if (rdev->wb.use_event) -- scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; -- else -- scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; -- seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]); -- } else -- seq = RREG32(rdev->fence_drv.scratch_reg); -+ seq = radeon_fence_read(rdev); - if (seq != rdev->fence_drv.last_seq) { - rdev->fence_drv.last_seq = seq; - rdev->fence_drv.last_jiffies = jiffies; -@@ -253,7 +274,7 @@ retry: - r = radeon_gpu_reset(rdev); - if (r) - return r; -- WREG32(rdev->fence_drv.scratch_reg, fence->seq); -+ radeon_fence_write(rdev, fence->seq); - rdev->gpu_lockup = false; - } - timeout = RADEON_FENCE_JIFFIES_TIMEOUT; -@@ -353,7 +374,7 @@ int radeon_fence_driver_init(struct radeon_device *rdev) - write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); - return r; - } -- WREG32(rdev->fence_drv.scratch_reg, 0); -+ radeon_fence_write(rdev, 0); - atomic_set(&rdev->fence_drv.seq, 0); - INIT_LIST_HEAD(&rdev->fence_drv.created); - INIT_LIST_HEAD(&rdev->fence_drv.emited); -@@ -393,7 +414,7 @@ static int radeon_debugfs_fence_info(struct seq_file *m, void *data) - struct radeon_fence *fence; - - seq_printf(m, "Last signaled fence 0x%08X\n", -- RREG32(rdev->fence_drv.scratch_reg)); -+ radeon_fence_read(rdev)); - if (!list_empty(&rdev->fence_drv.emited)) { - fence = list_entry(rdev->fence_drv.emited.prev, - struct radeon_fence, list); -diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c -index 114e5cc..cd9578b 100644 ---- a/drivers/gpu/drm/radeon/rv770.c -+++ b/drivers/gpu/drm/radeon/rv770.c -@@ -105,6 +105,9 @@ void rv770_pm_misc(struct radeon_device *rdev) - struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; - - if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { -+ /* 0xff01 is a flag rather then an actual voltage */ -+ if (voltage->voltage == 0xff01) -+ return; - if (voltage->voltage != rdev->pm.current_vddc) { - radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); - rdev->pm.current_vddc = voltage->voltage; diff --git a/drm-ttm-move-notify.patch b/drm-ttm-move-notify.patch deleted file mode 100644 index 4d4206f..0000000 --- a/drm-ttm-move-notify.patch +++ /dev/null @@ -1,40 +0,0 @@ -From e40ec45d67d32ce900dd6f2242675979593db18c Mon Sep 17 00:00:00 2001 -From: Ben Skeggs -Date: Tue, 18 Jan 2011 11:04:03 +1000 -Subject: [PATCH] drm/ttm: call driver move_notify() when doing system->tt bo moves - -Nouveau doesn't have enough information at ttm_backend_func.bind() time -to implement things like tiled GART, or to keep a buffer at a constant -address in the GPU virtual address space no matter where in physical -memory it's placed. - -To resolve this, nouveau will handle binding of all buffers to the GPU -itself from the move_notify() hook. This commit ensures it's called -for all buffer moves. - -Signed-off-by: Ben Skeggs ---- - drivers/gpu/drm/ttm/ttm_bo.c | 3 ++- - 1 files changed, 2 insertions(+), 1 deletions(-) - -diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c -index af61fc2..0b6a55a 100644 ---- a/drivers/gpu/drm/ttm/ttm_bo.c -+++ b/drivers/gpu/drm/ttm/ttm_bo.c -@@ -406,11 +406,12 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, - } - - if (bo->mem.mem_type == TTM_PL_SYSTEM) { -+ if (bdev->driver->move_notify) -+ bdev->driver->move_notify(bo, mem); - bo->mem = *mem; - mem->mm_node = NULL; - goto moved; - } -- - } - - if (bdev->driver->move_notify) --- -1.7.4.2 - diff --git a/efifb_update.patch b/efifb_update.patch deleted file mode 100644 index 7058ba6..0000000 --- a/efifb_update.patch +++ /dev/null @@ -1,217 +0,0 @@ -Fix up efifb so it works properly on the 11" Macbook Air. Upstream in .38? - -diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c -index 70477c2..476ffb1 100644 ---- a/drivers/video/efifb.c -+++ b/drivers/video/efifb.c -@@ -53,6 +53,7 @@ enum { - M_MB_7_1, /* MacBook, 7th rev. */ - M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ - M_MBA, /* MacBook Air */ -+ M_MBA_3, /* Macbook Air, 3rd rev */ - M_MBP, /* MacBook Pro */ - M_MBP_2, /* MacBook Pro 2nd gen */ - M_MBP_2_2, /* MacBook Pro 2,2nd gen */ -@@ -67,40 +68,49 @@ enum { - M_UNKNOWN /* placeholder */ - }; - -+#define OVERRIDE_NONE 0x0 -+#define OVERRIDE_BASE 0x1 -+#define OVERRIDE_STRIDE 0x2 -+#define OVERRIDE_HEIGHT 0x4 -+#define OVERRIDE_WIDTH 0x8 -+ - static struct efifb_dmi_info { - char *optname; - unsigned long base; - int stride; - int width; - int height; -+ int flags; - } dmi_list[] __initdata = { -- [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900 }, -- [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 } -+ [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, -+ [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, /* guess */ -+ [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, -+ [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, /* guess */ -+ [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, -+ [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080, OVERRIDE_NONE }, -+ [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440, OVERRIDE_NONE }, -+ [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768, OVERRIDE_NONE }, -+ [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768, OVERRIDE_NONE }, -+ [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, -+ [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, -+ [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, -+ [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, -+ [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, -+ [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, -+ /* 11" Macbook Air 3,1 passes the wrong stride */ -+ [M_MBA_3] = { "mba3", 0, 2048 * 4, 0, 0, OVERRIDE_STRIDE }, -+ [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, -+ [M_MBP_2] = { "mbp2", 0, 0, 0, 0, OVERRIDE_NONE }, /* placeholder */ -+ [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, -+ [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, -+ [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, -+ [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, -+ [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, -+ [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, -+ [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, -+ [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050, OVERRIDE_NONE }, -+ [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, -+ [M_UNKNOWN] = { NULL, 0, 0, 0, 0, OVERRIDE_NONE } - }; - - static int set_system(const struct dmi_system_id *id); -@@ -138,6 +148,7 @@ static const struct dmi_system_id dmi_system_table[] __initconst = { - 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 Inc.", "MacBookAir3,1", M_MBA_3), - 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), -@@ -154,16 +165,22 @@ static const struct dmi_system_id dmi_system_table[] __initconst = { - {}, - }; - -+#define choose_value(dmivalue, fwvalue, field, flags) ({ \ -+ typeof(fwvalue) _ret_ = fwvalue; \ -+ if ((flags) & (field)) \ -+ _ret_ = dmivalue; \ -+ else if ((fwvalue) == 0) \ -+ _ret_ = dmivalue; \ -+ _ret_; \ -+ }) -+ - static int set_system(const struct dmi_system_id *id) - { - struct efifb_dmi_info *info = id->driver_data; -- if (info->base == 0) -- return 0; - -- printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p " -- "(%dx%d, stride %d)\n", id->ident, -- (void *)info->base, info->width, info->height, -- info->stride); -+ if (info->base == 0 && info->height == 0 && info->width == 0 -+ && info->stride == 0) -+ return 0; - - /* Trust the bootloader over the DMI tables */ - if (screen_info.lfb_base == 0) { -@@ -171,40 +188,47 @@ static int set_system(const struct dmi_system_id *id) - struct pci_dev *dev = NULL; - int found_bar = 0; - #endif -- screen_info.lfb_base = info->base; -+ if (info->base) { -+ screen_info.lfb_base = choose_value(info->base, -+ screen_info.lfb_base, OVERRIDE_BASE, -+ info->flags); - - #if defined(CONFIG_PCI) -- /* make sure that the address in the table is actually on a -- * VGA device's PCI BAR */ -- -- for_each_pci_dev(dev) { -- int i; -- if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) -- continue; -- for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { -- resource_size_t start, end; -- -- start = pci_resource_start(dev, i); -- if (start == 0) -- break; -- end = pci_resource_end(dev, i); -- if (screen_info.lfb_base >= start && -- screen_info.lfb_base < end) { -- found_bar = 1; -+ /* make sure that the address in the table is actually -+ * on a VGA device's PCI BAR */ -+ -+ for_each_pci_dev(dev) { -+ int i; -+ if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) -+ continue; -+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { -+ resource_size_t start, end; -+ -+ start = pci_resource_start(dev, i); -+ if (start == 0) -+ break; -+ end = pci_resource_end(dev, i); -+ if (screen_info.lfb_base >= start && -+ screen_info.lfb_base < end) { -+ found_bar = 1; -+ } - } - } -- } -- if (!found_bar) -- screen_info.lfb_base = 0; -+ if (!found_bar) -+ screen_info.lfb_base = 0; - #endif -+ } - } - if (screen_info.lfb_base) { -- if (screen_info.lfb_linelength == 0) -- screen_info.lfb_linelength = info->stride; -- if (screen_info.lfb_width == 0) -- screen_info.lfb_width = info->width; -- if (screen_info.lfb_height == 0) -- screen_info.lfb_height = info->height; -+ screen_info.lfb_linelength = choose_value(info->stride, -+ screen_info.lfb_linelength, OVERRIDE_STRIDE, -+ info->flags); -+ screen_info.lfb_width = choose_value(info->width, -+ screen_info.lfb_width, OVERRIDE_WIDTH, -+ info->flags); -+ screen_info.lfb_height = choose_value(info->height, -+ screen_info.lfb_height, OVERRIDE_HEIGHT, -+ info->flags); - if (screen_info.orig_video_isVGA == 0) - screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; - } else { -@@ -214,6 +238,13 @@ static int set_system(const struct dmi_system_id *id) - screen_info.orig_video_isVGA = 0; - return 0; - } -+ -+ printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p " -+ "(%dx%d, stride %d)\n", id->ident, -+ (void *)screen_info.lfb_base, screen_info.lfb_width, -+ screen_info.lfb_height, screen_info.lfb_linelength); -+ -+ - return 1; - } - diff --git a/git-linus.diff b/git-linus.diff deleted file mode 100644 index e69de29..0000000 --- a/git-linus.diff +++ /dev/null diff --git a/hid-multitouch-add-support-for-elo-touchsystems.patch b/hid-multitouch-add-support-for-elo-touchsystems.patch index 1294f46..789201f 100644 --- a/hid-multitouch-add-support-for-elo-touchsystems.patch +++ b/hid-multitouch-add-support-for-elo-touchsystems.patch @@ -1,30 +1,2205 @@ -From: Benjamin Tissoires -Date: Thu, 19 May 2011 09:37:29 +0000 (+0200) -Subject: HID: hid-multitouch: add support for Elo TouchSystems 2515 IntelliTouch Plus -X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjikos%2Fhid.git;a=commitdiff_plain;h=c04abeeff9d76a703cac1e6d312853b0fc8136f5 +commit 9498f954a4ec389806333041a1018909c6fe0518 +Author: Benjamin Tissoires +Date: Fri Mar 18 14:27:52 2011 +0100 -HID: hid-multitouch: add support for Elo TouchSystems 2515 IntelliTouch Plus + HID: hid-multitouch: Auto detection of maxcontacts + + This patch enables support of autodetection of maxcontacts. + When adding support for a new device, one is now able to let + the device tell how many contacts it supports, or to manually + set the value if the device happens to provide wrong information. + + Signed-off-by: Benjamin Tissoires + Reviewed-by: Stéphane Chatty + Reviewed-by: Henrik Rydberg + Signed-off-by: Jiri Kosina -This patch adds support for Elo TouchSystems 2515 IntelliTouch Plus -that can be found in Lenovo A700 all-in-one. +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index ee01e65..b9f9eec 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -60,8 +60,9 @@ struct mt_device { + __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ + __u8 num_received; /* how many contacts we received */ + __u8 num_expected; /* expected last contact index */ ++ __u8 maxcontacts; + bool curvalid; /* is the current contact valid? */ +- struct mt_slot slots[0]; /* first slot */ ++ struct mt_slot *slots; + }; + + struct mt_class { +@@ -79,6 +80,8 @@ struct mt_class { + #define MT_CLS_CYPRESS 4 + #define MT_CLS_EGALAX 5 + ++#define MT_DEFAULT_MAXCONTACT 10 ++ + /* + * these device-dependent functions determine what slot corresponds + * to a valid contact that was just read. +@@ -95,12 +98,12 @@ static int cypress_compute_slot(struct mt_device *td) + static int find_slot_from_contactid(struct mt_device *td) + { + int i; +- for (i = 0; i < td->mtclass->maxcontacts; ++i) { ++ for (i = 0; i < td->maxcontacts; ++i) { + if (td->slots[i].contactid == td->curdata.contactid && + td->slots[i].touch_state) + return i; + } +- for (i = 0; i < td->mtclass->maxcontacts; ++i) { ++ for (i = 0; i < td->maxcontacts; ++i) { + if (!td->slots[i].seen_in_this_frame && + !td->slots[i].touch_state) + return i; +@@ -113,8 +116,7 @@ static int find_slot_from_contactid(struct mt_device *td) + + struct mt_class mt_classes[] = { + { .name = MT_CLS_DEFAULT, +- .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP, +- .maxcontacts = 10 }, ++ .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, + { .name = MT_CLS_DUAL_INRANGE_CONTACTID, + .quirks = MT_QUIRK_VALID_IS_INRANGE | + MT_QUIRK_SLOT_IS_CONTACTID, +@@ -142,9 +144,19 @@ struct mt_class mt_classes[] = { + static void mt_feature_mapping(struct hid_device *hdev, + struct hid_field *field, struct hid_usage *usage) + { +- if (usage->hid == HID_DG_INPUTMODE) { +- struct mt_device *td = hid_get_drvdata(hdev); ++ struct mt_device *td = hid_get_drvdata(hdev); ++ ++ switch (usage->hid) { ++ case HID_DG_INPUTMODE: + td->inputmode = field->report->id; ++ break; ++ case HID_DG_CONTACTMAX: ++ td->maxcontacts = field->value[0]; ++ if (td->mtclass->maxcontacts) ++ /* check if the maxcontacts is given by the class */ ++ td->maxcontacts = td->mtclass->maxcontacts; ++ ++ break; + } + } + +@@ -208,8 +220,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, + td->last_slot_field = usage->hid; + return 1; + case HID_DG_CONTACTID: +- input_mt_init_slots(hi->input, +- td->mtclass->maxcontacts); ++ input_mt_init_slots(hi->input, td->maxcontacts); + td->last_slot_field = usage->hid; + return 1; + case HID_DG_WIDTH: +@@ -292,7 +303,7 @@ static void mt_complete_slot(struct mt_device *td) + if (td->curvalid) { + int slotnum = mt_compute_slot(td); + +- if (slotnum >= 0 && slotnum < td->mtclass->maxcontacts) ++ if (slotnum >= 0 && slotnum < td->maxcontacts) + td->slots[slotnum] = td->curdata; + } + td->num_received++; +@@ -307,7 +318,7 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input) + { + int i; + +- for (i = 0; i < td->mtclass->maxcontacts; ++i) { ++ for (i = 0; i < td->maxcontacts; ++i) { + struct mt_slot *s = &(td->slots[i]); + if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) && + !s->seen_in_this_frame) { +@@ -341,7 +352,7 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, + struct mt_device *td = hid_get_drvdata(hid); + __s32 quirks = td->mtclass->quirks; + +- if (hid->claimed & HID_CLAIMED_INPUT) { ++ if (hid->claimed & HID_CLAIMED_INPUT && td->slots) { + switch (usage->hid) { + case HID_DG_INRANGE: + if (quirks & MT_QUIRK_VALID_IS_INRANGE) +@@ -442,9 +453,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) + */ + hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; + +- td = kzalloc(sizeof(struct mt_device) + +- mtclass->maxcontacts * sizeof(struct mt_slot), +- GFP_KERNEL); ++ td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); + if (!td) { + dev_err(&hdev->dev, "cannot allocate multitouch data\n"); + return -ENOMEM; +@@ -461,6 +470,18 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) + if (ret) + goto fail; + ++ if (!td->maxcontacts) ++ td->maxcontacts = MT_DEFAULT_MAXCONTACT; ++ ++ td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), ++ GFP_KERNEL); ++ if (!td->slots) { ++ dev_err(&hdev->dev, "cannot allocate multitouch slots\n"); ++ hid_hw_stop(hdev); ++ ret = -ENOMEM; ++ goto fail; ++ } ++ + mt_set_input_mode(hdev); + + return 0; +@@ -482,6 +503,7 @@ static void mt_remove(struct hid_device *hdev) + { + struct mt_device *td = hid_get_drvdata(hdev); + hid_hw_stop(hdev); ++ kfree(td->slots); + kfree(td); + hid_set_drvdata(hdev, NULL); + } +commit 043b403aede4a528ed99ceaf050f567f1283a23e +Author: Benjamin Tissoires +Date: Fri Mar 18 14:27:53 2011 +0100 -Signed-off-by: Benjamin Tissoires -Tested-by: Bastien Nocera -Signed-off-by: Jiri Kosina + HID: hid-multitouch: migrate support for Stantum panels to the unified driver. + + This patch merges hid-stantum to the generic multitouch driver. + + Signed-off-by: Benjamin Tissoires + Reviewed-by: Stéphane Chatty + Reviewed-by: Henrik Rydberg + Signed-off-by: Jiri Kosina +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index b7ec405..3c72f16 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig -@@ -309,6 +309,7 @@ config HID_MULTITOUCH +@@ -327,6 +327,7 @@ config HID_MULTITOUCH + - 'Sensing Win7-TwoFinger' panel by GeneralTouch + - eGalax dual-touch panels, including the + Joojoo and Wetab tablets ++ - Stantum multitouch panels + + If unsure, say N. + +@@ -493,12 +494,6 @@ config HID_SONY + ---help--- + Support for Sony PS3 controller. + +-config HID_STANTUM +- tristate "Stantum multitouch panel" +- depends on USB_HID +- ---help--- +- Support for Stantum multitouch panel. +- + config HID_SUNPLUS + tristate "Sunplus wireless desktop" + depends on USB_HID +diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile +index 06c68ae..a13cb4e 100644 +--- a/drivers/hid/Makefile ++++ b/drivers/hid/Makefile +@@ -66,7 +66,6 @@ obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o + obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o + obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o + obj-$(CONFIG_HID_SONY) += hid-sony.o +-obj-$(CONFIG_HID_STANTUM) += hid-stantum.o + obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o + obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o + obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index b9f9eec..5983e55 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -79,6 +79,7 @@ struct mt_class { + #define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 3 + #define MT_CLS_CYPRESS 4 + #define MT_CLS_EGALAX 5 ++#define MT_CLS_STANTUM 6 + + #define MT_DEFAULT_MAXCONTACT 10 + +@@ -138,6 +139,9 @@ struct mt_class mt_classes[] = { + .sn_move = 4096, + .sn_pressure = 32, + }, ++ { .name = MT_CLS_STANTUM, ++ .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, ++ + { } + }; + +@@ -552,6 +556,17 @@ static const struct hid_device_id mt_devices[] = { + HID_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, + ++ /* Stantum panels */ ++ { .driver_data = MT_CLS_STANTUM, ++ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, ++ USB_DEVICE_ID_MTP)}, ++ { .driver_data = MT_CLS_STANTUM, ++ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, ++ USB_DEVICE_ID_MTP_STM)}, ++ { .driver_data = MT_CLS_STANTUM, ++ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, ++ USB_DEVICE_ID_MTP_SITRONIX)}, ++ + { } + }; + MODULE_DEVICE_TABLE(hid, mt_devices); +diff --git a/drivers/hid/hid-stantum.c b/drivers/hid/hid-stantum.c +deleted file mode 100644 +index b2be1d1..0000000 +--- a/drivers/hid/hid-stantum.c ++++ /dev/null +@@ -1,286 +0,0 @@ +-/* +- * HID driver for Stantum multitouch panels +- * +- * Copyright (c) 2009 Stephane Chatty +- * +- */ +- +-/* +- * 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; either version 2 of the License, or (at your option) +- * any later version. +- */ +- +-#include +-#include +-#include +-#include +- +-MODULE_AUTHOR("Stephane Chatty "); +-MODULE_DESCRIPTION("Stantum HID multitouch panels"); +-MODULE_LICENSE("GPL"); +- +-#include "hid-ids.h" +- +-struct stantum_data { +- __s32 x, y, z, w, h; /* x, y, pressure, width, height */ +- __u16 id; /* touch id */ +- bool valid; /* valid finger data, or just placeholder? */ +- bool first; /* first finger in the HID packet? */ +- bool activity; /* at least one active finger so far? */ +-}; +- +-static int stantum_input_mapping(struct hid_device *hdev, struct hid_input *hi, +- struct hid_field *field, struct hid_usage *usage, +- unsigned long **bit, int *max) +-{ +- switch (usage->hid & HID_USAGE_PAGE) { +- +- case HID_UP_GENDESK: +- switch (usage->hid) { +- case HID_GD_X: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_POSITION_X); +- /* touchscreen emulation */ +- input_set_abs_params(hi->input, ABS_X, +- field->logical_minimum, +- field->logical_maximum, 0, 0); +- return 1; +- case HID_GD_Y: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_POSITION_Y); +- /* touchscreen emulation */ +- input_set_abs_params(hi->input, ABS_Y, +- field->logical_minimum, +- field->logical_maximum, 0, 0); +- return 1; +- } +- return 0; +- +- case HID_UP_DIGITIZER: +- switch (usage->hid) { +- case HID_DG_INRANGE: +- case HID_DG_CONFIDENCE: +- case HID_DG_INPUTMODE: +- case HID_DG_DEVICEINDEX: +- case HID_DG_CONTACTCOUNT: +- case HID_DG_CONTACTMAX: +- return -1; +- +- case HID_DG_TIPSWITCH: +- /* touchscreen emulation */ +- hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); +- return 1; +- +- case HID_DG_WIDTH: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_TOUCH_MAJOR); +- return 1; +- case HID_DG_HEIGHT: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_TOUCH_MINOR); +- input_set_abs_params(hi->input, ABS_MT_ORIENTATION, +- 1, 1, 0, 0); +- return 1; +- case HID_DG_TIPPRESSURE: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_PRESSURE); +- return 1; +- +- case HID_DG_CONTACTID: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_TRACKING_ID); +- return 1; +- +- } +- return 0; +- +- case 0xff000000: +- /* no input-oriented meaning */ +- return -1; +- } +- +- return 0; +-} +- +-static int stantum_input_mapped(struct hid_device *hdev, struct hid_input *hi, +- struct hid_field *field, struct hid_usage *usage, +- unsigned long **bit, int *max) +-{ +- if (usage->type == EV_KEY || usage->type == EV_ABS) +- clear_bit(usage->code, *bit); +- +- return 0; +-} +- +-/* +- * this function is called when a whole finger has been parsed, +- * so that it can decide what to send to the input layer. +- */ +-static void stantum_filter_event(struct stantum_data *sd, +- struct input_dev *input) +-{ +- bool wide; +- +- if (!sd->valid) { +- /* +- * touchscreen emulation: if the first finger is not valid and +- * there previously was finger activity, this is a release +- */ +- if (sd->first && sd->activity) { +- input_event(input, EV_KEY, BTN_TOUCH, 0); +- sd->activity = false; +- } +- return; +- } +- +- input_event(input, EV_ABS, ABS_MT_TRACKING_ID, sd->id); +- input_event(input, EV_ABS, ABS_MT_POSITION_X, sd->x); +- input_event(input, EV_ABS, ABS_MT_POSITION_Y, sd->y); +- +- wide = (sd->w > sd->h); +- input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); +- input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, wide ? sd->w : sd->h); +- input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, wide ? sd->h : sd->w); +- +- input_event(input, EV_ABS, ABS_MT_PRESSURE, sd->z); +- +- input_mt_sync(input); +- sd->valid = false; +- +- /* touchscreen emulation */ +- if (sd->first) { +- if (!sd->activity) { +- input_event(input, EV_KEY, BTN_TOUCH, 1); +- sd->activity = true; +- } +- input_event(input, EV_ABS, ABS_X, sd->x); +- input_event(input, EV_ABS, ABS_Y, sd->y); +- } +- sd->first = false; +-} +- +- +-static int stantum_event(struct hid_device *hid, struct hid_field *field, +- struct hid_usage *usage, __s32 value) +-{ +- struct stantum_data *sd = hid_get_drvdata(hid); +- +- if (hid->claimed & HID_CLAIMED_INPUT) { +- struct input_dev *input = field->hidinput->input; +- +- switch (usage->hid) { +- case HID_DG_INRANGE: +- /* this is the last field in a finger */ +- stantum_filter_event(sd, input); +- break; +- case HID_DG_WIDTH: +- sd->w = value; +- break; +- case HID_DG_HEIGHT: +- sd->h = value; +- break; +- case HID_GD_X: +- sd->x = value; +- break; +- case HID_GD_Y: +- sd->y = value; +- break; +- case HID_DG_TIPPRESSURE: +- sd->z = value; +- break; +- case HID_DG_CONTACTID: +- sd->id = value; +- break; +- case HID_DG_CONFIDENCE: +- sd->valid = !!value; +- break; +- case 0xff000002: +- /* this comes only before the first finger */ +- sd->first = true; +- break; +- +- default: +- /* ignore the others */ +- return 1; +- } +- } +- +- /* we have handled the hidinput part, now remains hiddev */ +- if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) +- hid->hiddev_hid_event(hid, field, usage, value); +- +- return 1; +-} +- +-static int stantum_probe(struct hid_device *hdev, +- const struct hid_device_id *id) +-{ +- int ret; +- struct stantum_data *sd; +- +- sd = kmalloc(sizeof(struct stantum_data), GFP_KERNEL); +- if (!sd) { +- hid_err(hdev, "cannot allocate Stantum data\n"); +- return -ENOMEM; +- } +- sd->valid = false; +- sd->first = false; +- sd->activity = false; +- hid_set_drvdata(hdev, sd); +- +- ret = hid_parse(hdev); +- if (!ret) +- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); +- +- if (ret) +- kfree(sd); +- +- return ret; +-} +- +-static void stantum_remove(struct hid_device *hdev) +-{ +- hid_hw_stop(hdev); +- kfree(hid_get_drvdata(hdev)); +- hid_set_drvdata(hdev, NULL); +-} +- +-static const struct hid_device_id stantum_devices[] = { +- { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) }, +- { } +-}; +-MODULE_DEVICE_TABLE(hid, stantum_devices); +- +-static const struct hid_usage_id stantum_grabbed_usages[] = { +- { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, +- { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} +-}; +- +-static struct hid_driver stantum_driver = { +- .name = "stantum", +- .id_table = stantum_devices, +- .probe = stantum_probe, +- .remove = stantum_remove, +- .input_mapping = stantum_input_mapping, +- .input_mapped = stantum_input_mapped, +- .usage_table = stantum_grabbed_usages, +- .event = stantum_event, +-}; +- +-static int __init stantum_init(void) +-{ +- return hid_register_driver(&stantum_driver); +-} +- +-static void __exit stantum_exit(void) +-{ +- hid_unregister_driver(&stantum_driver); +-} +- +-module_init(stantum_init); +-module_exit(stantum_exit); +- +commit a841b62c5d5f75ce3676fde755696d30cc8de99a +Author: Benjamin Tissoires +Date: Fri Mar 18 14:27:54 2011 +0100 + + HID: hid-multitouch: migrate Cando dual touch panels to hid-multitouch + + This patch merges hid-cando into the unified multitouch driver. + + Signed-off-by: Benjamin Tissoires + Reviewed-by: Stéphane Chatty + Reviewed-by: Henrik Rydberg + Signed-off-by: Jiri Kosina + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 3c72f16..1edb0bd 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -100,12 +100,6 @@ config HID_BELKIN + ---help--- + Support for Belkin Flip KVM and Wireless keyboard. + +-config HID_CANDO +- tristate "Cando dual touch panel" +- depends on USB_HID +- ---help--- +- Support for Cando dual touch panel. +- + config HID_CHERRY + tristate "Cherry Cymotion keyboard" if EXPERT + depends on USB_HID +@@ -320,6 +314,7 @@ config HID_MULTITOUCH + Generic support for HID multitouch panels. Say Y here if you have one of the following devices: ++ - Cando dual touch panel - Cypress TrueTouch panels -+ - Elo TouchSystems IntelliTouch Plus panels - Hanvon dual touch panels + - IrTouch Infrared USB panels +diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile +index a13cb4e..f8b90e4 100644 +--- a/drivers/hid/Makefile ++++ b/drivers/hid/Makefile +@@ -30,7 +30,6 @@ obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o + obj-$(CONFIG_HID_ACRUX) += hid-axff.o + obj-$(CONFIG_HID_APPLE) += hid-apple.o + obj-$(CONFIG_HID_BELKIN) += hid-belkin.o +-obj-$(CONFIG_HID_CANDO) += hid-cando.o + obj-$(CONFIG_HID_CHERRY) += hid-cherry.o + obj-$(CONFIG_HID_CHICONY) += hid-chicony.o + obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o +diff --git a/drivers/hid/hid-cando.c b/drivers/hid/hid-cando.c +deleted file mode 100644 +index 1ea066c..0000000 +--- a/drivers/hid/hid-cando.c ++++ /dev/null +@@ -1,276 +0,0 @@ +-/* +- * HID driver for Cando dual-touch panels +- * +- * Copyright (c) 2010 Stephane Chatty +- * +- */ +- +-/* +- * 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; either version 2 of the License, or (at your option) +- * any later version. +- */ +- +-#include +-#include +-#include +-#include +- +-MODULE_AUTHOR("Stephane Chatty "); +-MODULE_DESCRIPTION("Cando dual-touch panel"); +-MODULE_LICENSE("GPL"); +- +-#include "hid-ids.h" +- +-struct cando_data { +- __u16 x, y; +- __u8 id; +- __s8 oldest; /* id of the oldest finger in previous frame */ +- bool valid; /* valid finger data, or just placeholder? */ +- bool first; /* is this the first finger in this frame? */ +- __s8 firstid; /* id of the first finger in the frame */ +- __u16 firstx, firsty; /* (x, y) of the first finger in the frame */ +-}; +- +-static int cando_input_mapping(struct hid_device *hdev, struct hid_input *hi, +- struct hid_field *field, struct hid_usage *usage, +- unsigned long **bit, int *max) +-{ +- switch (usage->hid & HID_USAGE_PAGE) { +- +- case HID_UP_GENDESK: +- switch (usage->hid) { +- case HID_GD_X: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_POSITION_X); +- /* touchscreen emulation */ +- input_set_abs_params(hi->input, ABS_X, +- field->logical_minimum, +- field->logical_maximum, 0, 0); +- return 1; +- case HID_GD_Y: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_POSITION_Y); +- /* touchscreen emulation */ +- input_set_abs_params(hi->input, ABS_Y, +- field->logical_minimum, +- field->logical_maximum, 0, 0); +- return 1; +- } +- return 0; +- +- case HID_UP_DIGITIZER: +- switch (usage->hid) { +- case HID_DG_TIPSWITCH: +- case HID_DG_CONTACTMAX: +- return -1; +- case HID_DG_INRANGE: +- /* touchscreen emulation */ +- hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); +- return 1; +- case HID_DG_CONTACTID: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_TRACKING_ID); +- return 1; +- } +- return 0; +- } +- +- return 0; +-} +- +-static int cando_input_mapped(struct hid_device *hdev, struct hid_input *hi, +- struct hid_field *field, struct hid_usage *usage, +- unsigned long **bit, int *max) +-{ +- if (usage->type == EV_KEY || usage->type == EV_ABS) +- clear_bit(usage->code, *bit); +- +- return 0; +-} +- +-/* +- * this function is called when a whole finger has been parsed, +- * so that it can decide what to send to the input layer. +- */ +-static void cando_filter_event(struct cando_data *td, struct input_dev *input) +-{ +- td->first = !td->first; /* touchscreen emulation */ +- +- if (!td->valid) { +- /* +- * touchscreen emulation: if this is the second finger and +- * the first was valid, the first was the oldest; if the +- * first was not valid and there was a valid finger in the +- * previous frame, this is a release. +- */ +- if (td->first) { +- td->firstid = -1; +- } else if (td->firstid >= 0) { +- input_event(input, EV_ABS, ABS_X, td->firstx); +- input_event(input, EV_ABS, ABS_Y, td->firsty); +- td->oldest = td->firstid; +- } else if (td->oldest >= 0) { +- input_event(input, EV_KEY, BTN_TOUCH, 0); +- td->oldest = -1; +- } +- +- return; +- } +- +- input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); +- input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x); +- input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y); +- +- input_mt_sync(input); +- +- /* +- * touchscreen emulation: if there was no touching finger previously, +- * emit touch event +- */ +- if (td->oldest < 0) { +- input_event(input, EV_KEY, BTN_TOUCH, 1); +- td->oldest = td->id; +- } +- +- /* +- * touchscreen emulation: if this is the first finger, wait for the +- * second; the oldest is then the second if it was the oldest already +- * or if there was no first, the first otherwise. +- */ +- if (td->first) { +- td->firstx = td->x; +- td->firsty = td->y; +- td->firstid = td->id; +- } else { +- int x, y, oldest; +- if (td->id == td->oldest || td->firstid < 0) { +- x = td->x; +- y = td->y; +- oldest = td->id; +- } else { +- x = td->firstx; +- y = td->firsty; +- oldest = td->firstid; +- } +- input_event(input, EV_ABS, ABS_X, x); +- input_event(input, EV_ABS, ABS_Y, y); +- td->oldest = oldest; +- } +-} +- +- +-static int cando_event(struct hid_device *hid, struct hid_field *field, +- struct hid_usage *usage, __s32 value) +-{ +- struct cando_data *td = hid_get_drvdata(hid); +- +- if (hid->claimed & HID_CLAIMED_INPUT) { +- struct input_dev *input = field->hidinput->input; +- +- switch (usage->hid) { +- case HID_DG_INRANGE: +- td->valid = value; +- break; +- case HID_DG_CONTACTID: +- td->id = value; +- break; +- case HID_GD_X: +- td->x = value; +- break; +- case HID_GD_Y: +- td->y = value; +- cando_filter_event(td, input); +- break; +- case HID_DG_TIPSWITCH: +- /* avoid interference from generic hidinput handling */ +- break; +- +- default: +- /* fallback to the generic hidinput handling */ +- return 0; +- } +- } +- +- /* we have handled the hidinput part, now remains hiddev */ +- if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) +- hid->hiddev_hid_event(hid, field, usage, value); +- +- return 1; +-} +- +-static int cando_probe(struct hid_device *hdev, const struct hid_device_id *id) +-{ +- int ret; +- struct cando_data *td; +- +- td = kmalloc(sizeof(struct cando_data), GFP_KERNEL); +- if (!td) { +- hid_err(hdev, "cannot allocate Cando Touch data\n"); +- return -ENOMEM; +- } +- hid_set_drvdata(hdev, td); +- td->first = false; +- td->oldest = -1; +- td->valid = false; +- +- ret = hid_parse(hdev); +- if (!ret) +- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); +- +- if (ret) +- kfree(td); +- +- return ret; +-} +- +-static void cando_remove(struct hid_device *hdev) +-{ +- hid_hw_stop(hdev); +- kfree(hid_get_drvdata(hdev)); +- hid_set_drvdata(hdev, NULL); +-} +- +-static const struct hid_device_id cando_devices[] = { +- { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, +- USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, +- USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, +- USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, +- USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, +- { } +-}; +-MODULE_DEVICE_TABLE(hid, cando_devices); +- +-static const struct hid_usage_id cando_grabbed_usages[] = { +- { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, +- { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} +-}; +- +-static struct hid_driver cando_driver = { +- .name = "cando-touch", +- .id_table = cando_devices, +- .probe = cando_probe, +- .remove = cando_remove, +- .input_mapping = cando_input_mapping, +- .input_mapped = cando_input_mapped, +- .usage_table = cando_grabbed_usages, +- .event = cando_event, +-}; +- +-static int __init cando_init(void) +-{ +- return hid_register_driver(&cando_driver); +-} +- +-static void __exit cando_exit(void) +-{ +- hid_unregister_driver(&cando_driver); +-} +- +-module_init(cando_init); +-module_exit(cando_exit); +- +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 5983e55..e6e1ea2 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -514,6 +514,20 @@ static void mt_remove(struct hid_device *hdev) + + static const struct hid_device_id mt_devices[] = { + ++ /* Cando panels */ ++ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, ++ HID_USB_DEVICE(USB_VENDOR_ID_CANDO, ++ USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, ++ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, ++ HID_USB_DEVICE(USB_VENDOR_ID_CANDO, ++ USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, ++ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, ++ HID_USB_DEVICE(USB_VENDOR_ID_CANDO, ++ USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, ++ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, ++ HID_USB_DEVICE(USB_VENDOR_ID_CANDO, ++ USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, ++ + /* Cypress panel */ + { .driver_data = MT_CLS_CYPRESS, + HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, +commit 1e648a13720ef5de51f132501acf3e443d1a36d4 +Author: Benjamin Tissoires +Date: Fri Mar 18 14:27:55 2011 +0100 + + HID: hid-multitouch: refactor initialization of ABS_MT_ORIENTATION + + The way the input_set_abs_params was called for the new composite field + ABS_MT_ORIENTATION was not very clear at second reading. We can remove the + non-necessary call to set_abs and use the simple call to input_set_abs_params. + + Signed-off-by: Benjamin Tissoires + Reviewed-by: Stéphane Chatty + Signed-off-by: Jiri Kosina + +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index e6e1ea2..d31301e 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -235,9 +235,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, + case HID_DG_HEIGHT: + hid_map_usage(hi, usage, bit, max, + EV_ABS, ABS_MT_TOUCH_MINOR); +- field->logical_maximum = 1; +- field->logical_minimum = 0; +- set_abs(hi->input, ABS_MT_ORIENTATION, field, 0); ++ input_set_abs_params(hi->input, ++ ABS_MT_ORIENTATION, 0, 1, 0, 0); + td->last_slot_field = usage->hid; + return 1; + case HID_DG_TIPPRESSURE: +commit f786bba4499cf3de20da345ce090457ebcef03b0 +Author: Benjamin Tissoires +Date: Tue Mar 22 17:34:01 2011 +0100 + + HID: hid-multitouch: migrate 3M PCT touch screens to hid-multitouch + + This patch merges the hid-3m-pct driver into hid-multitouch. + To keep devices working the same way they used to with hid-3m-pct, + we need to add two signal/noise ratios for width and height. + We also need to work on width/height to send proper + ABS_MT_ORIENTATION flag. + + Importing 3M into hid-multitouch also solved the bug in which + devices handling width and height in their report descriptors + did not show ABS_MT_TOUCH_MAJOR and ABS_MT_TOUCH_MINOR. + + Signed-off-by: Benjamin Tissoires + Reviewed-by: Stéphane Chatty + Reviewed-and-tested-by: Henrik Rydberg + Signed-off-by: Jiri Kosina + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 1edb0bd..996ae3a 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -55,12 +55,6 @@ source "drivers/hid/usbhid/Kconfig" + menu "Special HID drivers" + depends on HID + +-config HID_3M_PCT +- tristate "3M PCT touchscreen" +- depends on USB_HID +- ---help--- +- Support for 3M PCT touch screens. +- + config HID_A4TECH + tristate "A4 tech mice" if EXPERT + depends on USB_HID +@@ -314,6 +308,7 @@ config HID_MULTITOUCH + Generic support for HID multitouch panels. + + Say Y here if you have one of the following devices: ++ - 3M PCT touch screens + - Cando dual touch panel + - Cypress TrueTouch panels + - Hanvon dual touch panels +diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile +index f8b90e4..11c9f0b 100644 +--- a/drivers/hid/Makefile ++++ b/drivers/hid/Makefile +@@ -25,7 +25,6 @@ ifdef CONFIG_LOGIWII_FF + hid-logitech-y += hid-lg4ff.o + endif + +-obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o + obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o + obj-$(CONFIG_HID_ACRUX) += hid-axff.o + obj-$(CONFIG_HID_APPLE) += hid-apple.o +diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c +deleted file mode 100644 +index 5243ae2..0000000 +--- a/drivers/hid/hid-3m-pct.c ++++ /dev/null +@@ -1,305 +0,0 @@ +-/* +- * HID driver for 3M PCT multitouch panels +- * +- * Copyright (c) 2009-2010 Stephane Chatty +- * Copyright (c) 2010 Henrik Rydberg +- * Copyright (c) 2010 Canonical, Ltd. +- * +- */ +- +-/* +- * 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; either version 2 of the License, or (at your option) +- * any later version. +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-MODULE_AUTHOR("Stephane Chatty "); +-MODULE_DESCRIPTION("3M PCT multitouch panels"); +-MODULE_LICENSE("GPL"); +- +-#include "hid-ids.h" +- +-#define MAX_SLOTS 60 +- +-/* estimated signal-to-noise ratios */ +-#define SN_MOVE 2048 +-#define SN_WIDTH 128 +- +-struct mmm_finger { +- __s32 x, y, w, h; +- bool touch, valid; +-}; +- +-struct mmm_data { +- struct mmm_finger f[MAX_SLOTS]; +- __u8 curid; +- __u8 nexp, nreal; +- bool touch, valid; +-}; +- +-static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi, +- struct hid_field *field, struct hid_usage *usage, +- unsigned long **bit, int *max) +-{ +- int f1 = field->logical_minimum; +- int f2 = field->logical_maximum; +- int df = f2 - f1; +- +- switch (usage->hid & HID_USAGE_PAGE) { +- +- case HID_UP_BUTTON: +- return -1; +- +- case HID_UP_GENDESK: +- switch (usage->hid) { +- case HID_GD_X: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_POSITION_X); +- input_set_abs_params(hi->input, ABS_MT_POSITION_X, +- f1, f2, df / SN_MOVE, 0); +- /* touchscreen emulation */ +- input_set_abs_params(hi->input, ABS_X, +- f1, f2, df / SN_MOVE, 0); +- return 1; +- case HID_GD_Y: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_POSITION_Y); +- input_set_abs_params(hi->input, ABS_MT_POSITION_Y, +- f1, f2, df / SN_MOVE, 0); +- /* touchscreen emulation */ +- input_set_abs_params(hi->input, ABS_Y, +- f1, f2, df / SN_MOVE, 0); +- return 1; +- } +- return 0; +- +- case HID_UP_DIGITIZER: +- switch (usage->hid) { +- /* we do not want to map these: no input-oriented meaning */ +- case 0x14: +- case 0x23: +- case HID_DG_INPUTMODE: +- case HID_DG_DEVICEINDEX: +- case HID_DG_CONTACTCOUNT: +- case HID_DG_CONTACTMAX: +- case HID_DG_INRANGE: +- case HID_DG_CONFIDENCE: +- return -1; +- case HID_DG_TIPSWITCH: +- /* touchscreen emulation */ +- hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); +- input_set_capability(hi->input, EV_KEY, BTN_TOUCH); +- return 1; +- case HID_DG_WIDTH: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_TOUCH_MAJOR); +- input_set_abs_params(hi->input, ABS_MT_TOUCH_MAJOR, +- f1, f2, df / SN_WIDTH, 0); +- return 1; +- case HID_DG_HEIGHT: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_TOUCH_MINOR); +- input_set_abs_params(hi->input, ABS_MT_TOUCH_MINOR, +- f1, f2, df / SN_WIDTH, 0); +- input_set_abs_params(hi->input, ABS_MT_ORIENTATION, +- 0, 1, 0, 0); +- return 1; +- case HID_DG_CONTACTID: +- input_mt_init_slots(hi->input, MAX_SLOTS); +- return 1; +- } +- /* let hid-input decide for the others */ +- return 0; +- +- case 0xff000000: +- /* we do not want to map these: no input-oriented meaning */ +- return -1; +- } +- +- return 0; +-} +- +-static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi, +- struct hid_field *field, struct hid_usage *usage, +- unsigned long **bit, int *max) +-{ +- /* tell hid-input to skip setup of these event types */ +- if (usage->type == EV_KEY || usage->type == EV_ABS) +- set_bit(usage->type, hi->input->evbit); +- return -1; +-} +- +-/* +- * this function is called when a whole packet has been received and processed, +- * so that it can decide what to send to the input layer. +- */ +-static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) +-{ +- int i; +- for (i = 0; i < MAX_SLOTS; ++i) { +- struct mmm_finger *f = &md->f[i]; +- if (!f->valid) { +- /* this finger is just placeholder data, ignore */ +- continue; +- } +- input_mt_slot(input, i); +- input_mt_report_slot_state(input, MT_TOOL_FINGER, f->touch); +- if (f->touch) { +- /* this finger is on the screen */ +- int wide = (f->w > f->h); +- /* divided by two to match visual scale of touch */ +- int major = max(f->w, f->h) >> 1; +- int minor = min(f->w, f->h) >> 1; +- +- input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); +- input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); +- input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); +- input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); +- input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); +- } +- f->valid = 0; +- } +- +- input_mt_report_pointer_emulation(input, true); +- input_sync(input); +-} +- +-/* +- * this function is called upon all reports +- * so that we can accumulate contact point information, +- * and call input_mt_sync after each point. +- */ +-static int mmm_event(struct hid_device *hid, struct hid_field *field, +- struct hid_usage *usage, __s32 value) +-{ +- struct mmm_data *md = hid_get_drvdata(hid); +- /* +- * strangely, this function can be called before +- * field->hidinput is initialized! +- */ +- if (hid->claimed & HID_CLAIMED_INPUT) { +- struct input_dev *input = field->hidinput->input; +- switch (usage->hid) { +- case HID_DG_TIPSWITCH: +- md->touch = value; +- break; +- case HID_DG_CONFIDENCE: +- md->valid = value; +- break; +- case HID_DG_WIDTH: +- if (md->valid) +- md->f[md->curid].w = value; +- break; +- case HID_DG_HEIGHT: +- if (md->valid) +- md->f[md->curid].h = value; +- break; +- case HID_DG_CONTACTID: +- value = clamp_val(value, 0, MAX_SLOTS - 1); +- if (md->valid) { +- md->curid = value; +- md->f[value].touch = md->touch; +- md->f[value].valid = 1; +- md->nreal++; +- } +- break; +- case HID_GD_X: +- if (md->valid) +- md->f[md->curid].x = value; +- break; +- case HID_GD_Y: +- if (md->valid) +- md->f[md->curid].y = value; +- break; +- case HID_DG_CONTACTCOUNT: +- if (value) +- md->nexp = value; +- if (md->nreal >= md->nexp) { +- mmm_filter_event(md, input); +- md->nreal = 0; +- } +- break; +- } +- } +- +- /* we have handled the hidinput part, now remains hiddev */ +- if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) +- hid->hiddev_hid_event(hid, field, usage, value); +- +- return 1; +-} +- +-static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id) +-{ +- int ret; +- struct mmm_data *md; +- +- hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; +- +- md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL); +- if (!md) { +- hid_err(hdev, "cannot allocate 3M data\n"); +- return -ENOMEM; +- } +- hid_set_drvdata(hdev, md); +- +- ret = hid_parse(hdev); +- if (!ret) +- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); +- +- if (ret) +- kfree(md); +- return ret; +-} +- +-static void mmm_remove(struct hid_device *hdev) +-{ +- hid_hw_stop(hdev); +- kfree(hid_get_drvdata(hdev)); +- hid_set_drvdata(hdev, NULL); +-} +- +-static const struct hid_device_id mmm_devices[] = { +- { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, +- { } +-}; +-MODULE_DEVICE_TABLE(hid, mmm_devices); +- +-static const struct hid_usage_id mmm_grabbed_usages[] = { +- { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, +- { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} +-}; +- +-static struct hid_driver mmm_driver = { +- .name = "3m-pct", +- .id_table = mmm_devices, +- .probe = mmm_probe, +- .remove = mmm_remove, +- .input_mapping = mmm_input_mapping, +- .input_mapped = mmm_input_mapped, +- .usage_table = mmm_grabbed_usages, +- .event = mmm_event, +-}; +- +-static int __init mmm_init(void) +-{ +- return hid_register_driver(&mmm_driver); +-} +- +-static void __exit mmm_exit(void) +-{ +- hid_unregister_driver(&mmm_driver); +-} +- +-module_init(mmm_init); +-module_exit(mmm_exit); +- +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index d31301e..0175f85 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -11,6 +11,12 @@ + * Copyright (c) 2010 Henrik Rydberg + * Copyright (c) 2010 Canonical, Ltd. + * ++ * This code is partly based on hid-3m-pct.c: ++ * ++ * Copyright (c) 2009-2010 Stephane Chatty ++ * Copyright (c) 2010 Henrik Rydberg ++ * Copyright (c) 2010 Canonical, Ltd. ++ * + */ + + /* +@@ -69,6 +75,8 @@ struct mt_class { + __s32 name; /* MT_CLS */ + __s32 quirks; + __s32 sn_move; /* Signal/noise ratio for move events */ ++ __s32 sn_width; /* Signal/noise ratio for width events */ ++ __s32 sn_height; /* Signal/noise ratio for height events */ + __s32 sn_pressure; /* Signal/noise ratio for pressure events */ + __u8 maxcontacts; + }; +@@ -80,6 +88,7 @@ struct mt_class { + #define MT_CLS_CYPRESS 4 + #define MT_CLS_EGALAX 5 + #define MT_CLS_STANTUM 6 ++#define MT_CLS_3M 7 + + #define MT_DEFAULT_MAXCONTACT 10 + +@@ -141,6 +150,12 @@ struct mt_class mt_classes[] = { + }, + { .name = MT_CLS_STANTUM, + .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, ++ { .name = MT_CLS_3M, ++ .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | ++ MT_QUIRK_SLOT_IS_CONTACTID, ++ .sn_move = 2048, ++ .sn_width = 128, ++ .sn_height = 128 }, + + { } + }; +@@ -230,11 +245,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, + case HID_DG_WIDTH: + hid_map_usage(hi, usage, bit, max, + EV_ABS, ABS_MT_TOUCH_MAJOR); ++ set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, ++ cls->sn_width); + td->last_slot_field = usage->hid; + return 1; + case HID_DG_HEIGHT: + hid_map_usage(hi, usage, bit, max, + EV_ABS, ABS_MT_TOUCH_MINOR); ++ set_abs(hi->input, ABS_MT_TOUCH_MINOR, field, ++ cls->sn_height); + input_set_abs_params(hi->input, + ABS_MT_ORIENTATION, 0, 1, 0, 0); + td->last_slot_field = usage->hid; +@@ -332,11 +351,18 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input) + input_mt_report_slot_state(input, MT_TOOL_FINGER, + s->touch_state); + if (s->touch_state) { ++ /* this finger is on the screen */ ++ int wide = (s->w > s->h); ++ /* divided by two to match visual scale of touch */ ++ int major = max(s->w, s->h) >> 1; ++ int minor = min(s->w, s->h) >> 1; ++ + input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); + input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); ++ input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); + input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); +- input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, s->w); +- input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, s->h); ++ input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); ++ input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); + } + s->seen_in_this_frame = false; + +@@ -398,6 +424,15 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, + break; + + default: ++ if (td->last_field_index ++ && field->index == td->last_field_index) ++ /* we reach here when the last field in the ++ * report is not related to multitouch. ++ * This is not good. As a temporary solution, ++ * we trigger our mt event completion and ++ * ignore the field. ++ */ ++ break; + /* fallback to the generic hidinput handling */ + return 0; + } +@@ -513,6 +548,14 @@ static void mt_remove(struct hid_device *hdev) + + static const struct hid_device_id mt_devices[] = { + ++ /* 3M panels */ ++ { .driver_data = MT_CLS_3M, ++ HID_USB_DEVICE(USB_VENDOR_ID_3M, ++ USB_DEVICE_ID_3M1968) }, ++ { .driver_data = MT_CLS_3M, ++ HID_USB_DEVICE(USB_VENDOR_ID_3M, ++ USB_DEVICE_ID_3M2256) }, ++ + /* Cando panels */ + { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, + HID_USB_DEVICE(USB_VENDOR_ID_CANDO, +commit 2955caed8b9865c1f04fcde6bd7103d5d5ec9415 +Author: Benjamin Tissoires +Date: Thu Apr 21 14:15:59 2011 +0200 + + HID: hid-multitouch: refactor last_field_index + + the current implementation requires the devices to report + HID_DG_CONTACTCOUNT to set the last_field_index value. + However, devices reporting in serial mode (DWAV and PenMount) + do not send this field. + Other devices (3M) add other fields in the reports descriptor + that are not multitouch related at the end, thus the need to + add a special case in the default case when handling events. + + A first work around has been set up but with PenMount devices, + we have reached the limit. + + The idea is to calculate the last_field_index by relying only on + multitouch fields the device send. This allows us to remove + the handling of non-multitouch events in hid-multitouch, and + guarantee that the function mt_emit_event is always called. + + Signed-off-by: Benjamin Tissoires + Reviewed-and-tested-by: Henrik Rydberg + Signed-off-by: Jiri Kosina + +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 0175f85..6005e78 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -210,6 +210,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, + /* touchscreen emulation */ + set_abs(hi->input, ABS_X, field, cls->sn_move); + td->last_slot_field = usage->hid; ++ td->last_field_index = field->index; + return 1; + case HID_GD_Y: + if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) +@@ -221,6 +222,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, + /* touchscreen emulation */ + set_abs(hi->input, ABS_Y, field, cls->sn_move); + td->last_slot_field = usage->hid; ++ td->last_field_index = field->index; + return 1; + } + return 0; +@@ -229,18 +231,22 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, + switch (usage->hid) { + case HID_DG_INRANGE: + td->last_slot_field = usage->hid; ++ td->last_field_index = field->index; + return 1; + case HID_DG_CONFIDENCE: + td->last_slot_field = usage->hid; ++ td->last_field_index = field->index; + return 1; + case HID_DG_TIPSWITCH: + hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); + input_set_capability(hi->input, EV_KEY, BTN_TOUCH); + td->last_slot_field = usage->hid; ++ td->last_field_index = field->index; + return 1; + case HID_DG_CONTACTID: + input_mt_init_slots(hi->input, td->maxcontacts); + td->last_slot_field = usage->hid; ++ td->last_field_index = field->index; + return 1; + case HID_DG_WIDTH: + hid_map_usage(hi, usage, bit, max, +@@ -248,6 +254,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, + set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, + cls->sn_width); + td->last_slot_field = usage->hid; ++ td->last_field_index = field->index; + return 1; + case HID_DG_HEIGHT: + hid_map_usage(hi, usage, bit, max, +@@ -257,6 +264,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, + input_set_abs_params(hi->input, + ABS_MT_ORIENTATION, 0, 1, 0, 0); + td->last_slot_field = usage->hid; ++ td->last_field_index = field->index; + return 1; + case HID_DG_TIPPRESSURE: + if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) +@@ -269,13 +277,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, + set_abs(hi->input, ABS_PRESSURE, field, + cls->sn_pressure); + td->last_slot_field = usage->hid; ++ td->last_field_index = field->index; + return 1; + case HID_DG_CONTACTCOUNT: +- td->last_field_index = field->report->maxfield - 1; ++ td->last_field_index = field->index; + return 1; + case HID_DG_CONTACTMAX: + /* we don't set td->last_slot_field as contactcount and + * contact max are global to the report */ ++ td->last_field_index = field->index; + return -1; + } + /* let hid-input decide for the others */ +@@ -424,23 +434,12 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, + break; + + default: +- if (td->last_field_index +- && field->index == td->last_field_index) +- /* we reach here when the last field in the +- * report is not related to multitouch. +- * This is not good. As a temporary solution, +- * we trigger our mt event completion and +- * ignore the field. +- */ +- break; + /* fallback to the generic hidinput handling */ + return 0; + } + + if (usage->hid == td->last_slot_field) { + mt_complete_slot(td); +- if (!td->last_field_index) +- mt_emit_event(td, field->hidinput->input); + } + + if (field->index == td->last_field_index +commit 6ab3a9a63fc16b04f7de48eb0190d516dd7574df +Author: John Sung +Date: Thu Apr 21 16:21:52 2011 +0200 + + HID: hid-multitouch: add support for PenMount dual-touch panel + + This patch adds PenMount support to hid-multitouch. A new class + MT_CLS_CONFIDENCE is defined for PenMount, since it uses HID_DG_CONFIDENCE as + the valid flag. + + Signed-off-by: John Sung + [benjamin.tissoires@enac.fr: rebased on top of last_index_field changes] + Signed-off-by: Benjamin Tissoires + Acked-by: Henrik Rydberg + Signed-off-by: Jiri Kosina + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 996ae3a..8058cf1 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -313,6 +313,7 @@ config HID_MULTITOUCH + - Cypress TrueTouch panels + - Hanvon dual touch panels + - IrTouch Infrared USB panels ++ - PenMount dual touch panels + - Pixcir dual touch panels + - 'Sensing Win7-TwoFinger' panel by GeneralTouch + - eGalax dual-touch panels, including the +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index c3d6626..6e31b9f 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1438,6 +1438,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, + { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, + { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index d485894..252aeba 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -484,6 +484,9 @@ + #define USB_VENDOR_ID_PANTHERLORD 0x0810 + #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 + ++#define USB_VENDOR_ID_PENMOUNT 0x14e1 ++#define USB_DEVICE_ID_PENMOUNT_PCI 0x3500 ++ + #define USB_VENDOR_ID_PETALYNX 0x18b1 + #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 + +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 6005e78..51b5d27 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -89,6 +89,7 @@ struct mt_class { + #define MT_CLS_EGALAX 5 + #define MT_CLS_STANTUM 6 + #define MT_CLS_3M 7 ++#define MT_CLS_CONFIDENCE 8 + + #define MT_DEFAULT_MAXCONTACT 10 + +@@ -156,6 +157,8 @@ struct mt_class mt_classes[] = { + .sn_move = 2048, + .sn_width = 128, + .sn_height = 128 }, ++ { .name = MT_CLS_CONFIDENCE, ++ .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, + + { } + }; +@@ -584,6 +587,11 @@ static const struct hid_device_id mt_devices[] = { + HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, + USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, + ++ /* PenMount panels */ ++ { .driver_data = MT_CLS_CONFIDENCE, ++ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, ++ USB_DEVICE_ID_PENMOUNT_PCI) }, ++ + /* PixCir-based panels */ + { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, + HID_USB_DEVICE(USB_VENDOR_ID_HANVON, +commit 4a6ee685fbcba4a440cf86f41557752ba81e2ccf +Author: Benjamin Tissoires +Date: Fri Apr 22 11:51:48 2011 +0200 + + HID: hid-multitouch: merge hid-mosart into hid-multitouch + + This patch include MosArt devices into hid-multitouch. + MosArt devices now support mt-protocol B. + + We also need to introduce a new quirk for mosart devices to support + their contactID. + + Signed-off-by: Benjamin Tissoires + Signed-off-by: Jiri Kosina + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 8058cf1..d2d4e5f 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -288,12 +288,6 @@ config HID_MICROSOFT + ---help--- + Support for Microsoft devices that are not fully compliant with HID standard. + +-config HID_MOSART +- tristate "MosArt dual-touch panels" +- depends on USB_HID +- ---help--- +- Support for MosArt dual-touch panels. +- + config HID_MONTEREY + tristate "Monterey Genius KB29E keyboard" if EXPERT + depends on USB_HID +@@ -313,6 +307,7 @@ config HID_MULTITOUCH + - Cypress TrueTouch panels + - Hanvon dual touch panels + - IrTouch Infrared USB panels ++ - MosArt dual-touch panels + - PenMount dual touch panels - Pixcir dual touch panels - 'Sensing Win7-TwoFinger' panel by GeneralTouch +diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile +index 11c9f0b..f8cc4ea 100644 +--- a/drivers/hid/Makefile ++++ b/drivers/hid/Makefile +@@ -45,7 +45,6 @@ obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o + obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o + obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o + obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o +-obj-$(CONFIG_HID_MOSART) += hid-mosart.o + obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o + obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o + obj-$(CONFIG_HID_ORTEK) += hid-ortek.o +diff --git a/drivers/hid/hid-mosart.c b/drivers/hid/hid-mosart.c +deleted file mode 100644 +index aed7ffe..0000000 +--- a/drivers/hid/hid-mosart.c ++++ /dev/null +@@ -1,296 +0,0 @@ +-/* +- * HID driver for the multitouch panel on the ASUS EeePC T91MT +- * +- * Copyright (c) 2009-2010 Stephane Chatty +- * Copyright (c) 2010 Teemu Tuominen +- * +- */ +- +-/* +- * 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; either version 2 of the License, or (at your option) +- * any later version. +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include "usbhid/usbhid.h" +- +-MODULE_AUTHOR("Stephane Chatty "); +-MODULE_DESCRIPTION("MosArt dual-touch panel"); +-MODULE_LICENSE("GPL"); +- +-#include "hid-ids.h" +- +-struct mosart_data { +- __u16 x, y; +- __u8 id; +- bool valid; /* valid finger data, or just placeholder? */ +- bool first; /* is this the first finger in this frame? */ +- bool activity_now; /* at least one active finger in this frame? */ +- bool activity; /* at least one active finger previously? */ +-}; +- +-static int mosart_input_mapping(struct hid_device *hdev, struct hid_input *hi, +- struct hid_field *field, struct hid_usage *usage, +- unsigned long **bit, int *max) +-{ +- switch (usage->hid & HID_USAGE_PAGE) { +- +- case HID_UP_GENDESK: +- switch (usage->hid) { +- case HID_GD_X: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_POSITION_X); +- /* touchscreen emulation */ +- input_set_abs_params(hi->input, ABS_X, +- field->logical_minimum, +- field->logical_maximum, 0, 0); +- return 1; +- case HID_GD_Y: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_POSITION_Y); +- /* touchscreen emulation */ +- input_set_abs_params(hi->input, ABS_Y, +- field->logical_minimum, +- field->logical_maximum, 0, 0); +- return 1; +- } +- return 0; +- +- case HID_UP_DIGITIZER: +- switch (usage->hid) { +- case HID_DG_CONFIDENCE: +- case HID_DG_TIPSWITCH: +- case HID_DG_INPUTMODE: +- case HID_DG_DEVICEINDEX: +- case HID_DG_CONTACTCOUNT: +- case HID_DG_CONTACTMAX: +- case HID_DG_TIPPRESSURE: +- case HID_DG_WIDTH: +- case HID_DG_HEIGHT: +- return -1; +- case HID_DG_INRANGE: +- /* touchscreen emulation */ +- hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); +- return 1; +- +- case HID_DG_CONTACTID: +- hid_map_usage(hi, usage, bit, max, +- EV_ABS, ABS_MT_TRACKING_ID); +- return 1; +- +- } +- return 0; +- +- case 0xff000000: +- /* ignore HID features */ +- return -1; +- +- case HID_UP_BUTTON: +- /* ignore buttons */ +- return -1; +- } +- +- return 0; +-} +- +-static int mosart_input_mapped(struct hid_device *hdev, struct hid_input *hi, +- struct hid_field *field, struct hid_usage *usage, +- unsigned long **bit, int *max) +-{ +- if (usage->type == EV_KEY || usage->type == EV_ABS) +- clear_bit(usage->code, *bit); +- +- return 0; +-} +- +-/* +- * this function is called when a whole finger has been parsed, +- * so that it can decide what to send to the input layer. +- */ +-static void mosart_filter_event(struct mosart_data *td, struct input_dev *input) +-{ +- td->first = !td->first; /* touchscreen emulation */ +- +- if (!td->valid) { +- /* +- * touchscreen emulation: if no finger in this frame is valid +- * and there previously was finger activity, this is a release +- */ +- if (!td->first && !td->activity_now && td->activity) { +- input_event(input, EV_KEY, BTN_TOUCH, 0); +- td->activity = false; +- } +- return; +- } +- +- input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); +- input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x); +- input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y); +- +- input_mt_sync(input); +- td->valid = false; +- +- /* touchscreen emulation: if first active finger in this frame... */ +- if (!td->activity_now) { +- /* if there was no previous activity, emit touch event */ +- if (!td->activity) { +- input_event(input, EV_KEY, BTN_TOUCH, 1); +- td->activity = true; +- } +- td->activity_now = true; +- /* and in any case this is our preferred finger */ +- input_event(input, EV_ABS, ABS_X, td->x); +- input_event(input, EV_ABS, ABS_Y, td->y); +- } +-} +- +- +-static int mosart_event(struct hid_device *hid, struct hid_field *field, +- struct hid_usage *usage, __s32 value) +-{ +- struct mosart_data *td = hid_get_drvdata(hid); +- +- if (hid->claimed & HID_CLAIMED_INPUT) { +- struct input_dev *input = field->hidinput->input; +- switch (usage->hid) { +- case HID_DG_INRANGE: +- td->valid = !!value; +- break; +- case HID_GD_X: +- td->x = value; +- break; +- case HID_GD_Y: +- td->y = value; +- mosart_filter_event(td, input); +- break; +- case HID_DG_CONTACTID: +- td->id = value; +- break; +- case HID_DG_CONTACTCOUNT: +- /* touch emulation: this is the last field in a frame */ +- td->first = false; +- td->activity_now = false; +- break; +- case HID_DG_CONFIDENCE: +- case HID_DG_TIPSWITCH: +- /* avoid interference from generic hidinput handling */ +- break; +- +- default: +- /* fallback to the generic hidinput handling */ +- return 0; +- } +- } +- +- /* we have handled the hidinput part, now remains hiddev */ +- if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) +- hid->hiddev_hid_event(hid, field, usage, value); +- +- return 1; +-} +- +-static int mosart_probe(struct hid_device *hdev, const struct hid_device_id *id) +-{ +- int ret; +- struct mosart_data *td; +- +- +- td = kmalloc(sizeof(struct mosart_data), GFP_KERNEL); +- if (!td) { +- hid_err(hdev, "cannot allocate MosArt data\n"); +- return -ENOMEM; +- } +- td->valid = false; +- td->activity = false; +- td->activity_now = false; +- td->first = false; +- hid_set_drvdata(hdev, td); +- +- /* currently, it's better to have one evdev device only */ +-#if 0 +- hdev->quirks |= HID_QUIRK_MULTI_INPUT; +-#endif +- +- ret = hid_parse(hdev); +- if (ret == 0) +- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); +- +- if (ret == 0) { +- struct hid_report_enum *re = hdev->report_enum +- + HID_FEATURE_REPORT; +- struct hid_report *r = re->report_id_hash[7]; +- +- r->field[0]->value[0] = 0x02; +- usbhid_submit_report(hdev, r, USB_DIR_OUT); +- } else +- kfree(td); +- +- return ret; +-} +- +-#ifdef CONFIG_PM +-static int mosart_reset_resume(struct hid_device *hdev) +-{ +- struct hid_report_enum *re = hdev->report_enum +- + HID_FEATURE_REPORT; +- struct hid_report *r = re->report_id_hash[7]; +- +- r->field[0]->value[0] = 0x02; +- usbhid_submit_report(hdev, r, USB_DIR_OUT); +- return 0; +-} +-#endif +- +-static void mosart_remove(struct hid_device *hdev) +-{ +- hid_hw_stop(hdev); +- kfree(hid_get_drvdata(hdev)); +- hid_set_drvdata(hdev, NULL); +-} +- +-static const struct hid_device_id mosart_devices[] = { +- { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, +- { } +-}; +-MODULE_DEVICE_TABLE(hid, mosart_devices); +- +-static const struct hid_usage_id mosart_grabbed_usages[] = { +- { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, +- { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} +-}; +- +-static struct hid_driver mosart_driver = { +- .name = "mosart", +- .id_table = mosart_devices, +- .probe = mosart_probe, +- .remove = mosart_remove, +- .input_mapping = mosart_input_mapping, +- .input_mapped = mosart_input_mapped, +- .usage_table = mosart_grabbed_usages, +- .event = mosart_event, +-#ifdef CONFIG_PM +- .reset_resume = mosart_reset_resume, +-#endif +-}; +- +-static int __init mosart_init(void) +-{ +- return hid_register_driver(&mosart_driver); +-} +- +-static void __exit mosart_exit(void) +-{ +- hid_unregister_driver(&mosart_driver); +-} +- +-module_init(mosart_init); +-module_exit(mosart_exit); +- +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 51b5d27..bf46804 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -50,6 +50,7 @@ MODULE_LICENSE("GPL"); + #define MT_QUIRK_VALID_IS_INRANGE (1 << 4) + #define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5) + #define MT_QUIRK_EGALAX_XYZ_FIXUP (1 << 6) ++#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 7) + + struct mt_slot { + __s32 x, y, p, w, h; +@@ -90,6 +91,7 @@ struct mt_class { + #define MT_CLS_STANTUM 6 + #define MT_CLS_3M 7 + #define MT_CLS_CONFIDENCE 8 ++#define MT_CLS_CONFIDENCE_MINUS_ONE 9 + + #define MT_DEFAULT_MAXCONTACT 10 + +@@ -140,7 +142,9 @@ struct mt_class mt_classes[] = { + .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | + MT_QUIRK_CYPRESS, + .maxcontacts = 10 }, +- ++ { .name = MT_CLS_CONFIDENCE_MINUS_ONE, ++ .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | ++ MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE }, + { .name = MT_CLS_EGALAX, + .quirks = MT_QUIRK_SLOT_IS_CONTACTID | + MT_QUIRK_VALID_IS_INRANGE | +@@ -325,6 +329,9 @@ static int mt_compute_slot(struct mt_device *td) + if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER) + return td->num_received; + ++ if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE) ++ return td->curdata.contactid - 1; ++ + return find_slot_from_contactid(td); + } + +@@ -587,6 +594,17 @@ static const struct hid_device_id mt_devices[] = { + HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, + USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, + ++ /* MosArt panels */ ++ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, ++ HID_USB_DEVICE(USB_VENDOR_ID_ASUS, ++ USB_DEVICE_ID_ASUS_T91MT)}, ++ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, ++ HID_USB_DEVICE(USB_VENDOR_ID_ASUS, ++ USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, ++ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, ++ HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, ++ USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, ++ + /* PenMount panels */ + { .driver_data = MT_CLS_CONFIDENCE, + HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, +commit 4e61f0d75aa86c9e59451f6bcffcdceb355b4fc4 +Author: Austin Zhang +Date: Mon May 9 23:54:14 2011 +0800 + + HID: hid-multitouch: add support for Ilitek dual-touch panel + + Added ILITEK hid dual touch panel support into hid-multitouch. + + Signed-off-by: Austin Zhang + Reviewed-by: Benjamin Tissoires + Signed-off-by: Jiri Kosina + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index d2d4e5f..d9635d6 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -306,6 +306,7 @@ config HID_MULTITOUCH + - Cando dual touch panel + - Cypress TrueTouch panels + - Hanvon dual touch panels ++ - Ilitek dual touch panel + - IrTouch Infrared USB panels + - MosArt dual-touch panels + - PenMount dual touch panels +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 6e31b9f..c0ea857 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1377,6 +1377,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, + { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) }, + { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, + { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, + { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 252aeba..0f29b3f 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -330,6 +330,9 @@ + #define USB_DEVICE_ID_UGCI_FLYING 0x0020 + #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 + ++#define USB_VENDOR_ID_ILITEK 0x222a ++#define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 ++ + #define USB_VENDOR_ID_IMATION 0x0718 + #define USB_DEVICE_ID_DISC_STAKKA 0xd000 + +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index bf46804..b21251b 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -589,6 +589,11 @@ static const struct hid_device_id mt_devices[] = { + HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, + USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, + ++ /* Ilitek dual touch panel */ ++ { .driver_data = MT_CLS_DEFAULT, ++ HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, ++ USB_DEVICE_ID_ILITEK_MULTITOUCH) }, ++ + /* IRTOUCH panels */ + { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, + HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, +commit df167c4a0d68a9dbde044a39a77f255ac666f93e +Author: Benjamin Tissoires +Date: Wed May 18 15:27:24 2011 +0200 + + HID: hid-multitouch: Add support for Lumio panels + + This patch enables support for Lumio optical devices. + + Signed-off-by: Benjamin Tissoires + Signed-off-by: Jiri Kosina + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index d9635d6..5a54b13 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -308,6 +308,7 @@ config HID_MULTITOUCH + - Hanvon dual touch panels + - Ilitek dual touch panel + - IrTouch Infrared USB panels ++ - Lumio CrystalTouch panels + - MosArt dual-touch panels + - PenMount dual touch panels + - Pixcir dual touch panels +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index c0ea857..3dad069 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1410,6 +1410,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 0f29b3f..bfbc0d2 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -410,6 +410,9 @@ + #define USB_DEVICE_ID_DINOVO_MINI 0xc71f + #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03 + ++#define USB_VENDOR_ID_LUMIO 0x202e ++#define USB_DEVICE_ID_CRYSTALTOUCH 0x0006 ++ + #define USB_VENDOR_ID_MCC 0x09db + #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 + #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index b21251b..ef33e2d 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -599,6 +599,11 @@ static const struct hid_device_id mt_devices[] = { + HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, + USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, + ++ /* Lumio panels */ ++ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, ++ HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, ++ USB_DEVICE_ID_CRYSTALTOUCH) }, ++ + /* MosArt panels */ + { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, + HID_USB_DEVICE(USB_VENDOR_ID_ASUS, +commit c04abeeff9d76a703cac1e6d312853b0fc8136f5 +Author: Benjamin Tissoires +Date: Thu May 19 11:37:29 2011 +0200 + + HID: hid-multitouch: add support for Elo TouchSystems 2515 IntelliTouch Plus + + This patch adds support for Elo TouchSystems 2515 IntelliTouch Plus + that can be found in Lenovo A700 all-in-one. + + Signed-off-by: Benjamin Tissoires + Tested-by: Bastien Nocera + Signed-off-by: Jiri Kosina + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 5a54b13..1572ff1 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -305,6 +305,7 @@ config HID_MULTITOUCH + - 3M PCT touch screens + - Cando dual touch panel + - Cypress TrueTouch panels ++ - Elo TouchSystems IntelliTouch Plus panels + - Hanvon dual touch panels + - Ilitek dual touch panel + - IrTouch Infrared USB panels +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 3dad069..053fc08 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c -@@ -1335,6 +1335,7 @@ static const struct hid_device_id hid_have_special_driver[] = { +@@ -1366,6 +1366,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, @@ -32,9 +2207,11 @@ Signed-off-by: Jiri Kosina { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index bfbc0d2..6c19d1a 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h -@@ -219,6 +219,7 @@ +@@ -216,6 +216,7 @@ #define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34 #define USB_VENDOR_ID_ELO 0x04E7 @@ -42,29 +2219,30 @@ Signed-off-by: Jiri Kosina #define USB_DEVICE_ID_ELO_TS2700 0x0020 #define USB_VENDOR_ID_EMS 0x2006 +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index ef33e2d..3bc8de6 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c -@@ -69,6 +69,7 @@ struct mt_class { - #define MT_CLS_DUAL1 2 - #define MT_CLS_DUAL2 3 - #define MT_CLS_CYPRESS 4 -+#define MT_CLS_DUAL_NSMU_CONTACTID 5 +@@ -92,6 +92,7 @@ struct mt_class { + #define MT_CLS_3M 7 + #define MT_CLS_CONFIDENCE 8 + #define MT_CLS_CONFIDENCE_MINUS_ONE 9 ++#define MT_CLS_DUAL_NSMU_CONTACTID 10 - /* - * these device-dependent functions determine what slot corresponds -@@ -119,6 +120,11 @@ struct mt_class mt_classes[] = { - MT_QUIRK_CYPRESS, - .maxcontacts = 10 }, + #define MT_DEFAULT_MAXCONTACT 10 +@@ -163,6 +164,10 @@ struct mt_class mt_classes[] = { + .sn_height = 128 }, + { .name = MT_CLS_CONFIDENCE, + .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, + { .name = MT_CLS_DUAL_NSMU_CONTACTID, + .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | + MT_QUIRK_SLOT_IS_CONTACTID, + .maxcontacts = 2 }, -+ + { } }; - -@@ -465,6 +471,11 @@ static const struct hid_device_id mt_devices[] = { +@@ -584,6 +589,11 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, @@ -74,5 +2252,5 @@ Signed-off-by: Jiri Kosina + USB_DEVICE_ID_ELO_TS2515) }, + /* GeneralTouch panel */ - { .driver_data = MT_CLS_DUAL2, + { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, diff --git a/hid-ntrig-deref-unclaimed-input.patch b/hid-ntrig-deref-unclaimed-input.patch deleted file mode 100644 index 8719eae..0000000 --- a/hid-ntrig-deref-unclaimed-input.patch +++ /dev/null @@ -1,46 +0,0 @@ -commit f41a52d3010579949a3b9fd76783120d9643b60b -Author: Rafi Rubin -Date: Tue Mar 8 00:24:29 2011 -0500 - - HID: ntrig don't dereference unclaimed hidinput - - Check before dereferencing field->hidinput to fix a reported invalid - deference bug. - - Signed-off-by: Rafi Rubin - Signed-off-by: Jiri Kosina - -diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c -index beb4034..a93e58c 100644 ---- a/drivers/hid/hid-ntrig.c -+++ b/drivers/hid/hid-ntrig.c -@@ -539,8 +539,19 @@ static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, - static int ntrig_event (struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value) - { -- struct input_dev *input = field->hidinput->input; - struct ntrig_data *nd = hid_get_drvdata(hid); -+ struct input_dev *input; -+ -+ /* Skip processing if not a claimed input */ -+ if (!(hid->claimed & HID_CLAIMED_INPUT)) -+ goto not_claimed_input; -+ -+ /* This function is being called before the structures are fully -+ * initialized */ -+ if(!(field->hidinput && field->hidinput->input)) -+ return -EINVAL; -+ -+ input = field->hidinput->input; - - /* No special handling needed for the pen */ - if (field->application == HID_DG_PEN) -@@ -810,6 +821,8 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, - } - } - -+not_claimed_input: -+ - /* we have handled the hidinput part, now remains hiddev */ - if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_hid_event) - hid->hiddev_hid_event(hid, field, usage, value); diff --git a/input-wacom-add-support-for-lenovo-tablet-id-0xe6.patch b/input-wacom-add-support-for-lenovo-tablet-id-0xe6.patch deleted file mode 100644 index f95908e..0000000 --- a/input-wacom-add-support-for-lenovo-tablet-id-0xe6.patch +++ /dev/null @@ -1,36 +0,0 @@ -From: Manoj Iyer -Date: Fri, 1 Apr 2011 05:39:43 +0000 (-0700) -Subject: Input: wacom - add support for Lenovo tablet ID (0xE6) -X-Git-Tag: v2.6.39-rc2~4^2~1 -X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=26fcd2a7618db6c16be6aa3e56c0f3c25381e5a3 - -Input: wacom - add support for Lenovo tablet ID (0xE6) -[ 2.6.38 backport ] - -Signed-off-by: Manoj Iyer -Acked-by: Ping Cheng -Signed-off-by: Dmitry Torokhov ---- -RHBZ 708307 - -diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c -index c87d94f..08ba5ad 100644 ---- a/drivers/input/tablet/wacom_wac.c -+++ b/drivers/input/tablet/wacom_wac.c -@@ -1439,6 +1439,8 @@ static const struct wacom_features wacom_features_0xE2 = - { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; - static const struct wacom_features wacom_features_0xE3 = - { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; -+static const struct wacom_features wacom_features_0xE6 = -+ { "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255, 0, TABLETPC2FG }; - static const struct wacom_features wacom_features_0x47 = - { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; - static struct wacom_features wacom_features_0xD0 = -@@ -1561,6 +1564,7 @@ const struct usb_device_id wacom_ids[] = { - { USB_DEVICE_WACOM(0x9F) }, - { USB_DEVICE_WACOM(0xE2) }, - { USB_DEVICE_WACOM(0xE3) }, -+ { USB_DEVICE_WACOM(0xE6) }, - { USB_DEVICE_WACOM(0x47) }, - { USB_DEVICE_LENOVO(0x6004) }, - { } diff --git a/intel-iommu-add-domain-check-in-domain_remove_one_dev_info.patch b/intel-iommu-add-domain-check-in-domain_remove_one_dev_info.patch deleted file mode 100644 index ec494f6..0000000 --- a/intel-iommu-add-domain-check-in-domain_remove_one_dev_info.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 8519dc4401ddf8a5399f979870bbeeadbc111186 Mon Sep 17 00:00:00 2001 -From: Mike Habeck -Date: Sat, 28 May 2011 13:15:07 -0500 -Subject: intel-iommu: Add domain check in domain_remove_one_dev_info - -From: Mike Habeck - -commit 8519dc4401ddf8a5399f979870bbeeadbc111186 upstream. - -The comment in domain_remove_one_dev_info() states "No need to compare -PCI domain; it has to be the same". But for the si_domain that isn't -going to be true, as it consists of all the PCI devices that are -identity mapped thus multiple PCI domains can be in si_domain. The -code needs to validate the PCI domain too. - -Signed-off-by: Mike Habeck -Signed-off-by: Mike Travis -Signed-off-by: David Woodhouse -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/pci/intel-iommu.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/pci/intel-iommu.c -+++ b/drivers/pci/intel-iommu.c -@@ -3398,8 +3398,8 @@ static void domain_remove_one_dev_info(s - spin_lock_irqsave(&device_domain_lock, flags); - list_for_each_safe(entry, tmp, &domain->devices) { - info = list_entry(entry, struct device_domain_info, link); -- /* No need to compare PCI domain; it has to be the same */ -- if (info->bus == pdev->bus->number && -+ if (info->segment == pci_domain_nr(pdev->bus) && -+ info->bus == pdev->bus->number && - info->devfn == pdev->devfn) { - list_del(&info->link); - list_del(&info->global); diff --git a/intel-iommu-check-for-identity-mapping-candidate-using.patch b/intel-iommu-check-for-identity-mapping-candidate-using.patch deleted file mode 100644 index 50da533..0000000 --- a/intel-iommu-check-for-identity-mapping-candidate-using.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 8fcc5372fbac085199d84a880503ed67aba3fe49 Mon Sep 17 00:00:00 2001 -From: Chris Wright -Date: Sat, 28 May 2011 13:15:02 -0500 -Subject: intel-iommu: Check for identity mapping candidate using - system dma mask - -From: Chris Wright - -commit 8fcc5372fbac085199d84a880503ed67aba3fe49 upstream. - -The identity mapping code appears to make the assumption that if the -devices dma_mask is greater than 32bits the device can use identity -mapping. But that is not true: take the case where we have a 40bit -device in a 44bit architecture. The device can potentially receive a -physical address that it will truncate and cause incorrect addresses -to be used. - -Instead check to see if the device's dma_mask is large enough -to address the system's dma_mask. - -Signed-off-by: Mike Travis -Reviewed-by: Mike Habeck -Signed-off-by: David Woodhouse -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/pci/intel-iommu.c | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - ---- a/drivers/pci/intel-iommu.c -+++ b/drivers/pci/intel-iommu.c -@@ -2190,8 +2190,19 @@ static int iommu_should_identity_map(str - * Assume that they will -- if they turn out not to be, then we can - * take them out of the 1:1 domain later. - */ -- if (!startup) -- return pdev->dma_mask > DMA_BIT_MASK(32); -+ if (!startup) { -+ /* -+ * If the device's dma_mask is less than the system's memory -+ * size then this is not a candidate for identity mapping. -+ */ -+ u64 dma_mask = pdev->dma_mask; -+ -+ if (pdev->dev.coherent_dma_mask && -+ pdev->dev.coherent_dma_mask < dma_mask) -+ dma_mask = pdev->dev.coherent_dma_mask; -+ -+ return dma_mask >= dma_get_required_mask(&pdev->dev); -+ } - - return 1; - } diff --git a/intel-iommu-dont-cache-iova-above-32bit.patch b/intel-iommu-dont-cache-iova-above-32bit.patch deleted file mode 100644 index 4a2691e..0000000 --- a/intel-iommu-dont-cache-iova-above-32bit.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 1c9fc3d11b84fbd0c4f4aa7855702c2a1f098ebb Mon Sep 17 00:00:00 2001 -From: Chris Wright -Date: Sat, 28 May 2011 13:15:04 -0500 -Subject: intel-iommu: Dont cache iova above 32bit - -From: Chris Wright - -commit 1c9fc3d11b84fbd0c4f4aa7855702c2a1f098ebb upstream. - -Mike Travis and Mike Habeck reported an issue where iova allocation -would return a range that was larger than a device's dma mask. - -https://lkml.org/lkml/2011/3/29/423 - -The dmar initialization code will reserve all PCI MMIO regions and copy -those reservations into a domain specific iova tree. It is possible for -one of those regions to be above the dma mask of a device. It is typical -to allocate iovas with a 32bit mask (despite device's dma mask possibly -being larger) and cache the result until it exhausts the lower 32bit -address space. Freeing the iova range that is >= the last iova in the -lower 32bit range when there is still an iova above the 32bit range will -corrupt the cached iova by pointing it to a region that is above 32bit. -If that region is also larger than the device's dma mask, a subsequent -allocation will return an unusable iova and cause dma failure. - -Simply don't cache an iova that is above the 32bit caching boundary. - -Reported-by: Mike Travis -Reported-by: Mike Habeck -Acked-by: Mike Travis -Tested-by: Mike Habeck -Signed-off-by: Chris Wright -Signed-off-by: David Woodhouse -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/pci/iova.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - ---- a/drivers/pci/iova.c -+++ b/drivers/pci/iova.c -@@ -63,8 +63,16 @@ __cached_rbnode_delete_update(struct iov - curr = iovad->cached32_node; - cached_iova = container_of(curr, struct iova, node); - -- if (free->pfn_lo >= cached_iova->pfn_lo) -- iovad->cached32_node = rb_next(&free->node); -+ if (free->pfn_lo >= cached_iova->pfn_lo) { -+ struct rb_node *node = rb_next(&free->node); -+ struct iova *iova = container_of(node, struct iova, node); -+ -+ /* only cache if it's below 32bit pfn */ -+ if (node && iova->pfn_lo < iovad->dma_32bit_pfn) -+ iovad->cached32_node = node; -+ else -+ iovad->cached32_node = NULL; -+ } - } - - /* Computes the padding size required, to make the diff --git a/intel-iommu-flush-unmaps-at-domain_exit.patch b/intel-iommu-flush-unmaps-at-domain_exit.patch deleted file mode 100644 index d08772a..0000000 --- a/intel-iommu-flush-unmaps-at-domain_exit.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 7b668357810ecb5fdda4418689d50f5d95aea6a8 Mon Sep 17 00:00:00 2001 -From: Alex Williamson -Date: Tue, 24 May 2011 12:02:41 +0100 -Subject: intel-iommu: Flush unmaps at domain_exit - -From: Alex Williamson - -commit 7b668357810ecb5fdda4418689d50f5d95aea6a8 upstream. - -We typically batch unmaps to be lazily flushed out at -regular intervals. When we destroy a domain, we need -to force a flush of these lazy unmaps to be sure none -reference the domain we're about to free. - -Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=35062 -Signed-off-by: Alex Williamson -Signed-off-by: David Woodhouse -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/pci/intel-iommu.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/pci/intel-iommu.c -+++ b/drivers/pci/intel-iommu.c -@@ -1416,6 +1416,10 @@ static void domain_exit(struct dmar_doma - if (!domain) - return; - -+ /* Flush any lazy unmaps that may reference this domain */ -+ if (!intel_iommu_strict) -+ flush_unmaps_timeout(0); -+ - domain_remove_dev_info(domain); - /* destroy iovas */ - put_iova_domain(&domain->iovad); diff --git a/intel-iommu-only-unlink-device-domains-from-iommu.patch b/intel-iommu-only-unlink-device-domains-from-iommu.patch deleted file mode 100644 index 839c564..0000000 --- a/intel-iommu-only-unlink-device-domains-from-iommu.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 9b4554b21ed07e8556405510638171f0c787742a Mon Sep 17 00:00:00 2001 -From: Alex Williamson -Date: Tue, 24 May 2011 12:19:04 -0400 -Subject: intel-iommu: Only unlink device domains from iommu - -From: Alex Williamson - -commit 9b4554b21ed07e8556405510638171f0c787742a upstream. - -Commit a97590e5 added unlinking domains from iommus to reciprocate the -iommu from domains unlinking that was already done. We actually want -to only do this for device domains and never for the static -identity map domain or VM domains. The SI domain is special and -never freed, while VM domain->id lives in their own special address -space, separate from iommu->domain_ids. - -In the current code, a VM can get domain->id zero, then mark that -domain unused when unbound from pci-stub. This leads to DMAR -write faults when the device is re-bound to the host driver. - -Signed-off-by: Alex Williamson -Signed-off-by: David Woodhouse -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/pci/intel-iommu.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - ---- a/drivers/pci/intel-iommu.c -+++ b/drivers/pci/intel-iommu.c -@@ -3422,10 +3422,13 @@ static void domain_remove_one_dev_info(s - domain_update_iommu_cap(domain); - spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); - -- spin_lock_irqsave(&iommu->lock, tmp_flags); -- clear_bit(domain->id, iommu->domain_ids); -- iommu->domains[domain->id] = NULL; -- spin_unlock_irqrestore(&iommu->lock, tmp_flags); -+ if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) && -+ !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY)) { -+ spin_lock_irqsave(&iommu->lock, tmp_flags); -+ clear_bit(domain->id, iommu->domain_ids); -+ iommu->domains[domain->id] = NULL; -+ spin_unlock_irqrestore(&iommu->lock, tmp_flags); -+ } - } - - spin_unlock_irqrestore(&device_domain_lock, flags); diff --git a/intel-iommu-remove-host-bridge-devices-from-identity.patch b/intel-iommu-remove-host-bridge-devices-from-identity.patch deleted file mode 100644 index 66cef4a..0000000 --- a/intel-iommu-remove-host-bridge-devices-from-identity.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 825507d6d059f1cbe2503e0e5a3926225b983aec Mon Sep 17 00:00:00 2001 -From: Mike Travis -Date: Sat, 28 May 2011 13:15:06 -0500 -Subject: intel-iommu: Remove Host Bridge devices from identity - mapping - -From: Mike Travis - -commit 825507d6d059f1cbe2503e0e5a3926225b983aec upstream. - -When using the 1:1 (identity) PCI DMA remapping, PCI Host Bridge devices -that do not use the IOMMU causes a kernel panic. Fix that by not -inserting those devices into the si_domain. - -Signed-off-by: Mike Travis -Reviewed-by: Mike Habeck -Signed-off-by: David Woodhouse -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/pci/intel-iommu.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/pci/intel-iommu.c -+++ b/drivers/pci/intel-iommu.c -@@ -46,6 +46,8 @@ - #define ROOT_SIZE VTD_PAGE_SIZE - #define CONTEXT_SIZE VTD_PAGE_SIZE - -+#define IS_BRIDGE_HOST_DEVICE(pdev) \ -+ ((pdev->class >> 8) == PCI_CLASS_BRIDGE_HOST) - #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) - #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) - #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) -@@ -2217,6 +2219,9 @@ static int __init iommu_prepare_static_i - return -EFAULT; - - for_each_pci_dev(pdev) { -+ /* Skip Host/PCI Bridge devices */ -+ if (IS_BRIDGE_HOST_DEVICE(pdev)) -+ continue; - if (iommu_should_identity_map(pdev, 1)) { - printk(KERN_INFO "IOMMU: %s identity mapping for device %s\n", - hw ? "hardware" : "software", pci_name(pdev)); diff --git a/intel-iommu-speed-up-processing-of-the-identity_mapping.patch b/intel-iommu-speed-up-processing-of-the-identity_mapping.patch deleted file mode 100644 index 9a2fd55..0000000 --- a/intel-iommu-speed-up-processing-of-the-identity_mapping.patch +++ /dev/null @@ -1,43 +0,0 @@ -From cb452a4040bb051d92e85d6e7eb60c11734c1781 Mon Sep 17 00:00:00 2001 -From: Mike Travis -Date: Sat, 28 May 2011 13:15:03 -0500 -Subject: intel-iommu: Speed up processing of the identity_mapping - function - -From: Mike Travis - -commit cb452a4040bb051d92e85d6e7eb60c11734c1781 upstream. - -When there are a large count of PCI devices, and the pass through -option for iommu is set, much time is spent in the identity_mapping -function hunting though the iommu domains to check if a specific -device is "identity mapped". - -Speed up the function by checking the cached info to see if -it's mapped to the static identity domain. - -Signed-off-by: Mike Travis -Reviewed-by: Mike Habeck -Signed-off-by: David Woodhouse -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/pci/intel-iommu.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/pci/intel-iommu.c -+++ b/drivers/pci/intel-iommu.c -@@ -2109,10 +2109,10 @@ static int identity_mapping(struct pci_d - if (likely(!iommu_identity_mapping)) - return 0; - -+ info = pdev->dev.archdata.iommu; -+ if (info && info != DUMMY_DEVICE_DOMAIN_INFO) -+ return (info->domain == si_domain); - -- list_for_each_entry(info, &si_domain->devices, link) -- if (info->dev == pdev) -- return 1; - return 0; - } - diff --git a/intel-iommu-use-coherent-dma-mask-when-requested.patch b/intel-iommu-use-coherent-dma-mask-when-requested.patch deleted file mode 100644 index 01b43db..0000000 --- a/intel-iommu-use-coherent-dma-mask-when-requested.patch +++ /dev/null @@ -1,35 +0,0 @@ -From c681d0ba1252954208220ad32248a3e8e2fc98e4 Mon Sep 17 00:00:00 2001 -From: Mike Travis -Date: Sat, 28 May 2011 13:15:05 -0500 -Subject: intel-iommu: Use coherent DMA mask when requested - -From: Mike Travis - -commit c681d0ba1252954208220ad32248a3e8e2fc98e4 upstream. - -The __intel_map_single function is not honoring the passed in DMA mask. -This results in not using the coherent DMA mask when called from -intel_alloc_coherent(). - -Signed-off-by: Mike Travis -Acked-by: Chris Wright -Reviewed-by: Mike Habeck -Signed-off-by: David Woodhouse -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/pci/intel-iommu.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/pci/intel-iommu.c -+++ b/drivers/pci/intel-iommu.c -@@ -2606,8 +2606,7 @@ static dma_addr_t __intel_map_single(str - iommu = domain_get_iommu(domain); - size = aligned_nrpages(paddr, size); - -- iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), -- pdev->dma_mask); -+ iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), dma_mask); - if (!iova) - goto error; - diff --git a/iwlagn-use-cts-to-self-protection-on-5000-adapters-series.patch b/iwlagn-use-cts-to-self-protection-on-5000-adapters-series.patch deleted file mode 100644 index 6743f90..0000000 --- a/iwlagn-use-cts-to-self-protection-on-5000-adapters-series.patch +++ /dev/null @@ -1,103 +0,0 @@ -From sgruszka@redhat.com Mon Jun 20 10:09:55 2011 -From: Stanislaw Gruszka -To: kernel@lists.fedoraproject.org -Subject: [PATCH 2.6.38] iwlagn: use cts-to-self protection on 5000 adapters series -Date: Mon, 20 Jun 2011 16:11:22 +0200 -Message-Id: <1308579082-19006-2-git-send-email-sgruszka@redhat.com> - -This patch fixes 802.11n stability and performance regression we have -since 2.6.35. It boost performance on my 5GHz N-only network from about -5MB/s to 8MB/s. Similar percentage boost can be observed on 2.4 GHz. - -These are test results of 5x downloading of approximately 700MB iso -image: - -vanilla: 5.27 5.22 4.94 4.47 5.31 ; avr 5.0420 std 0.35110 -patched: 8.07 7.95 8.06 7.99 7.96 ; avr 8.0060 std 0.055946 - -This was achieved with NetworkManager configured to do not perform -periodical scans, by configuring constant BSSID. With periodical scans, -after some time, performance downgrade to unpatched driver level, like -in example below: - -patched: 7.40 7.61 4.28 4.37 4.80 avr 5.6920 std 1.6683 - -However patch still make better here, since similar test on unpatched -driver make link disconnects with below messages after some time: - -wlan1: authenticate with 00:23:69:35:d1:3f (try 1) -wlan1: authenticate with 00:23:69:35:d1:3f (try 2) -wlan1: authenticate with 00:23:69:35:d1:3f (try 3) -wlan1: authentication with 00:23:69:35:d1:3f timed out - -On 2.6.35 kernel patch helps against connection hangs with messages: - -iwlagn 0000:20:00.0: queue 10 stuck 3 time. Fw reload. -iwlagn 0000:20:00.0: On demand firmware reload -iwlagn 0000:20:00.0: Stopping AGG while state not ON or starting - -Signed-off-by: Stanislaw Gruszka ---- - drivers/net/wireless/iwlwifi/iwl-5000.c | 1 - - drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 12 ++---------- - drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 8 ++++++++ - 3 files changed, 10 insertions(+), 11 deletions(-) - -diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c -index 537fb8c..909cc30 100644 ---- a/drivers/net/wireless/iwlwifi/iwl-5000.c -+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c -@@ -517,7 +517,6 @@ static struct iwl_base_params iwl5000_base_params = { - }; - static struct iwl_ht_params iwl5000_ht_params = { - .ht_greenfield_support = true, -- .use_rts_for_aggregation = true, /* use rts/cts protection */ - }; - - #define IWL_DEVICE_5000 \ -diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c -index 366340f..89762a7 100644 ---- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c -+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c -@@ -217,17 +217,9 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv, - __le16 fc, __le32 *tx_flags) - { - if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS || -- info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { -+ info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT || -+ info->flags & IEEE80211_TX_CTL_AMPDU) - *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; -- return; -- } -- -- if (priv->cfg->ht_params && -- priv->cfg->ht_params->use_rts_for_aggregation && -- info->flags & IEEE80211_TX_CTL_AMPDU) { -- *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; -- return; -- } - } - - /* Calc max signal level (dBm) among 3 possible receivers */ -diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c -index ee802fe..b19fb85 100644 ---- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c -+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c -@@ -145,6 +145,14 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) - /* always get timestamp with Rx frame */ - ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; - -+ /* -+ * force CTS-to-self frames protection if RTS-CTS is not preferred -+ * one aggregation protection method -+ */ -+ if (!(priv->cfg->ht_params && -+ priv->cfg->ht_params->use_rts_for_aggregation)) -+ ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; -+ - if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || - !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK)) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; --- -1.7.1 - diff --git a/kernel.spec b/kernel.spec index 5211df6..397f648 100644 --- a/kernel.spec +++ b/kernel.spec @@ -51,19 +51,19 @@ Summary: The Linux kernel # For non-released -rc kernels, this will be prepended with "0.", so # for example a 3 here will become 0.3 # -%global baserelease 34 +%global baserelease 1 %global fedora_build %{baserelease} # base_sublevel is the kernel version we're starting with and patching # on top of -- for example, 2.6.22-rc7-git1 starts with a 2.6.21 base, # which yields a base_sublevel of 21. -%define base_sublevel 38 +%define base_sublevel 39 ## If this is a released kernel ## %if 0%{?released_kernel} # Do we have a -stable update to apply? -%define stable_update 8 +%define stable_update 2 # Is it a -stable RC? %define stable_rc 0 # Set rpm version accordingly @@ -596,8 +596,6 @@ Patch00: patch-2.6.%{base_sublevel}-git%{gitrev}.bz2 ### BRANCH PATCH ### %endif -Patch02: git-linus.diff - # we also need compile fixes for -vanilla Patch04: linux-2.6-compile-fixes.patch @@ -609,10 +607,7 @@ Patch05: linux-2.6-makefile-after_link.patch # revert upstream patches we get via other methods Patch09: linux-2.6-upstream-reverts.patch -# Git trees. -# Standalone patches -Patch20: linux-2.6-hotfixes.patch Patch29: linux-2.6-utrace-revert-make-ptrace-functions-static.patch Patch30: linux-2.6-tracehook.patch @@ -627,17 +622,14 @@ Patch150: linux-2.6.29-sparc-IOC_TYPECHECK.patch Patch160: linux-2.6-32bit-mmap-exec-randomization.patch Patch161: linux-2.6-i386-nx-emulation.patch -Patch200: linux-2.6-debug-sizeof-structs.patch Patch202: linux-2.6-debug-taint-vm.patch Patch203: linux-2.6-debug-vm-would-have-oomkilled.patch -Patch204: linux-2.6-debug-always-inline-kzalloc.patch Patch380: linux-2.6-defaults-pci_no_msi.patch Patch381: linux-2.6-defaults-pci_use_crs.patch # ASPM: enable powersave by default Patch383: linux-2.6-defaults-aspm.patch -Patch384: pci-pcie-links-may-not-get-configured-for-aspm-under-powersave-mode.patch Patch385: pci-enable-aspm-state-clearing-regardless-of-policy.patch Patch389: ima-allow-it-to-be-completely-disabled-and-default-off.patch @@ -650,8 +642,6 @@ Patch394: linux-2.6-acpi-debug-infinite-loop.patch Patch450: linux-2.6-input-kill-stupid-messages.patch Patch452: linux-2.6.30-no-pcspkr-modalias.patch Patch453: revert-hid-magicmouse-ignore-ivalid-report-id-while-switching.patch -Patch454: input-wacom-add-support-for-lenovo-tablet-id-0xe6.patch -Patch455: hid-ntrig-deref-unclaimed-input.patch Patch456: hid-multitouch-add-support-for-elo-touchsystems.patch Patch460: linux-2.6-serial-460800.patch @@ -664,13 +654,9 @@ Patch570: linux-2.6-selinux-mprotect-checks.patch Patch580: linux-2.6-sparc-selinux-mprotect-checks.patch # scsi / block -Patch600: block-queue-refcount.patch -Patch601: block-export-blk_-get-put-_queue.patch -Patch602: block-blkdev_get-should-access-bd_disk-only-after.patch Patch603: cfq-iosched-fix-locking-around-ioc-ioc-data-assignment.patch # libata -Patch620: ahci-add-another-pci-id-for-marvell.patch Patch621: libata-sas-only-set-frozen-flag-if-new-eh-is-supported.patch Patch650: hda_intel-prealloc-4mb-dmabuffer.patch @@ -689,35 +675,18 @@ Patch1555: fix_xen_guest_on_old_EC2.patch # nouveau + drm fixes Patch1809: drm-nouveau-fixes.patch Patch1810: drm-nouveau-updates.patch -Patch1811: drm-ttm-move-notify.patch Patch1819: drm-intel-big-hammer.patch # intel drm is all merged upstream -# fix for 945G corruption will hit stable eventually -Patch1821: drm-i915-fix-pipelined-fencing.patch Patch1824: drm-intel-next.patch # make sure the lvds comes back on lid open Patch1825: drm-intel-make-lvds-work.patch Patch1826: drm-intel-edp-fixes.patch -Patch1828: drm-intel-eeebox-eb1007-quirk.patch -Patch1829: drm-intel-restore-mode.patch Patch1830: drm-i915-snb-irq-stalls-fix.patch Patch1831: drm-i915-apply-hwstam-workaround-for-bsd-ring-on-sandybridge.patch # radeon - new hw + fixes for fusion and t500 regression Patch1839: drm-radeon-fix-regression-on-atom-cards-with-hardcoded-EDID-record.patch -Patch1840: drm-radeon-update.patch -Patch1841: drm-radeon-update2.patch -Patch1842: drm-radeon-pageflip-oops-fix.patch -Patch1843: drm-radeon-update3.patch Patch1900: linux-2.6-intel-iommu-igfx.patch -Patch1901: intel-iommu-flush-unmaps-at-domain_exit.patch -Patch1902: intel-iommu-only-unlink-device-domains-from-iommu.patch -Patch1903: intel-iommu-check-for-identity-mapping-candidate-using.patch -Patch1904: intel-iommu-speed-up-processing-of-the-identity_mapping.patch -Patch1905: intel-iommu-dont-cache-iova-above-32bit.patch -Patch1906: intel-iommu-use-coherent-dma-mask-when-requested.patch -Patch1907: intel-iommu-remove-host-bridge-devices-from-identity.patch -Patch1908: intel-iommu-add-domain-check-in-domain_remove_one_dev_info.patch # linux1394 git patches Patch2200: linux-2.6-firewire-git-update.patch @@ -728,7 +697,6 @@ Patch2201: linux-2.6-firewire-git-pending.patch Patch2802: linux-2.6-silence-acpi-blacklist.patch # media patches -Patch2898: cx88-Fix-HVR4000-IR-keymap.patch Patch2899: linux-2.6-v4l-dvb-fixes.patch Patch2900: linux-2.6-v4l-dvb-update.patch Patch2901: linux-2.6-v4l-dvb-experimental.patch @@ -745,38 +713,21 @@ Patch12016: disable-i8042-check-on-apple-mac.patch Patch12018: neuter_intel_microcode_load.patch -Patch12101: apple_backlight.patch -Patch12102: efifb_update.patch -Patch12200: acpi_reboot.patch - # Runtime power management Patch12203: linux-2.6-usb-pci-autosuspend.patch Patch12204: linux-2.6-enable-more-pci-autosuspend.patch Patch12303: dmar-disable-when-ricoh-multifunction.patch -Patch12305: printk-do-not-mangle-valid-userspace-syslog-prefixes.patch Patch12306: scsi-sd-downgrade-caching-printk-from-error-to-notice.patch -#netconsole fixes -Patch12400: linux-2.6-netconsole-deadlock.patch - -# CVE-2011-1581 -Patch12402: bonding-incorrect-tx-queue-offset.patch - -# Restore reliable stack backtraces, and hopefully fix RHBZ #700718 -Patch12403: x86-dumpstack-correct-stack-dump-info-when-frame-pointer-is-available.patch - # Fix breakage of PCI network adapter names on older Dell systems Patch12404: x86-pci-preserve-existing-pci-bfsort-whitelist-for-dell-systems.patch -Patch12407: scsi_dh_hp_sw-fix-deadlock-in-start_stop_endio.patch - Patch12416: bluetooth-device-ids-for-ath3k-on-pegatron-lucid-tablets.patch Patch12418: ath5k-disable-fast-channel-switching-by-default.patch -Patch12419: iwlagn-use-cts-to-self-protection-on-5000-adapters-series.patch Patch12420: crypto-aesni_intel-merge-with-fpu_ko.patch @@ -1203,8 +1154,6 @@ do done %endif -ApplyOptionalPatch git-linus.diff - ApplyPatch linux-2.6-makefile-after_link.patch # @@ -1217,9 +1166,7 @@ ApplyOptionalPatch linux-2.6-compile-fixes.patch # revert patches from upstream that conflict or that we get via other means ApplyOptionalPatch linux-2.6-upstream-reverts.patch -R -ApplyPatch linux-2.6-hotfixes.patch - -# Roland's utrace ptrace replacement. +# utrace ApplyPatch linux-2.6-utrace-revert-make-ptrace-functions-static.patch ApplyPatch linux-2.6-tracehook.patch ApplyPatch linux-2.6-utrace.patch @@ -1231,22 +1178,6 @@ ApplyPatch ksm-fix-null-pointer-dereference-in-scan-get-next-rmap-item.patch # Architecture patches # x86(-64) -# Restore reliable stack backtraces, and hopefully -# fix RHBZ #700718 -ApplyPatch x86-dumpstack-correct-stack-dump-info-when-frame-pointer-is-available.patch - -# -# Intel IOMMU -# -# from 2.6.39.2 -ApplyPatch intel-iommu-flush-unmaps-at-domain_exit.patch -ApplyPatch intel-iommu-only-unlink-device-domains-from-iommu.patch -ApplyPatch intel-iommu-check-for-identity-mapping-candidate-using.patch -ApplyPatch intel-iommu-speed-up-processing-of-the-identity_mapping.patch -ApplyPatch intel-iommu-dont-cache-iova-above-32bit.patch -ApplyPatch intel-iommu-use-coherent-dma-mask-when-requested.patch -ApplyPatch intel-iommu-remove-host-bridge-devices-from-identity.patch -ApplyPatch intel-iommu-add-domain-check-in-domain_remove_one_dev_info.patch # # PowerPC @@ -1289,10 +1220,8 @@ ApplyPatch acpi-ec-add-delay-before-write.patch ApplyPatch linux-2.6-acpi-debug-infinite-loop.patch # Various low-impact patches to aid debugging. -ApplyPatch linux-2.6-debug-sizeof-structs.patch ApplyPatch linux-2.6-debug-taint-vm.patch ApplyPatch linux-2.6-debug-vm-would-have-oomkilled.patch -ApplyPatch linux-2.6-debug-always-inline-kzalloc.patch # # PCI @@ -1302,8 +1231,6 @@ ApplyPatch linux-2.6-defaults-pci_no_msi.patch ApplyPatch linux-2.6-defaults-pci_use_crs.patch # enable ASPM by default on hardware we expect to work ApplyPatch linux-2.6-defaults-aspm.patch -# fixes for ASPM powersave mode -ApplyPatch pci-pcie-links-may-not-get-configured-for-aspm-under-powersave-mode.patch ApplyPatch pci-enable-aspm-state-clearing-regardless-of-policy.patch # Fix breakage of PCI network adapter names on older Dell systems ApplyPatch x86-pci-preserve-existing-pci-bfsort-whitelist-for-dell-systems.patch @@ -1313,14 +1240,10 @@ ApplyPatch x86-pci-preserve-existing-pci-bfsort-whitelist-for-dell-systems.patch # # SCSI / block Bits. # -ApplyPatch block-queue-refcount.patch -ApplyPatch block-export-blk_-get-put-_queue.patch -ApplyPatch block-blkdev_get-should-access-bd_disk-only-after.patch # rhbz#577968 ApplyPatch cfq-iosched-fix-locking-around-ioc-ioc-data-assignment.patch # libata -ApplyPatch ahci-add-another-pci-id-for-marvell.patch # Fix drive detection failure on mvsas (rhbz#705019) ApplyPatch libata-sas-only-set-frozen-flag-if-new-eh-is-supported.patch @@ -1336,8 +1259,6 @@ ApplyPatch hda_intel-prealloc-4mb-dmabuffer.patch ApplyPatch linux-2.6-input-kill-stupid-messages.patch ApplyPatch linux-2.6.30-no-pcspkr-modalias.patch ApplyPatch revert-hid-magicmouse-ignore-ivalid-report-id-while-switching.patch -ApplyPatch input-wacom-add-support-for-lenovo-tablet-id-0xe6.patch -ApplyPatch hid-ntrig-deref-unclaimed-input.patch ApplyPatch hid-multitouch-add-support-for-elo-touchsystems.patch # stop floppy.ko from autoloading during udev... @@ -1375,7 +1296,6 @@ ApplyPatch fix_xen_guest_on_old_EC2.patch # DRM core # Nouveau DRM -ApplyPatch drm-ttm-move-notify.patch ApplyOptionalPatch drm-nouveau-fixes.patch ApplyOptionalPatch drm-nouveau-updates.patch @@ -1385,18 +1305,11 @@ ApplyPatch drm-intel-big-hammer.patch ApplyPatch drm-intel-make-lvds-work.patch ApplyPatch linux-2.6-intel-iommu-igfx.patch ApplyPatch drm-intel-edp-fixes.patch -ApplyPatch drm-i915-fix-pipelined-fencing.patch -ApplyPatch drm-intel-eeebox-eb1007-quirk.patch -ApplyPatch drm-intel-restore-mode.patch ApplyPatch drm-i915-snb-irq-stalls-fix.patch ApplyPatch drm-i915-apply-hwstam-workaround-for-bsd-ring-on-sandybridge.patch # radeon DRM (add cayman support) ApplyPatch drm-radeon-fix-regression-on-atom-cards-with-hardcoded-EDID-record.patch -R -ApplyPatch drm-radeon-update.patch -ApplyPatch drm-radeon-update2.patch -ApplyPatch drm-radeon-pageflip-oops-fix.patch -ApplyPatch drm-radeon-update3.patch # linux1394 git patches #ApplyPatch linux-2.6-firewire-git-update.patch @@ -1407,7 +1320,6 @@ ApplyPatch linux-2.6-silence-acpi-blacklist.patch # V4L/DVB updates/fixes/experimental drivers # apply if non-empty -ApplyPatch cx88-Fix-HVR4000-IR-keymap.patch -R ApplyOptionalPatch linux-2.6-v4l-dvb-fixes.patch ApplyOptionalPatch linux-2.6-v4l-dvb-update.patch ApplyOptionalPatch linux-2.6-v4l-dvb-experimental.patch @@ -1420,11 +1332,6 @@ ApplyPatch add-appleir-usb-driver.patch ApplyPatch neuter_intel_microcode_load.patch -# various fixes for Apple and EFI -ApplyPatch apple_backlight.patch -ApplyPatch efifb_update.patch -ApplyPatch acpi_reboot.patch - # Runtime PM #ApplyPatch linux-2.6-usb-pci-autosuspend.patch ### Broken by implicit notify support & ACPICA rebase @@ -1433,27 +1340,13 @@ ApplyPatch acpi_reboot.patch # rhbz#605888 ApplyPatch dmar-disable-when-ricoh-multifunction.patch -# rhbz#691888 -ApplyPatch printk-do-not-mangle-valid-userspace-syslog-prefixes.patch - ApplyPatch scsi-sd-downgrade-caching-printk-from-error-to-notice.patch -#rhbz 668231 -ApplyPatch linux-2.6-netconsole-deadlock.patch - -# CVE-2011-1581 -ApplyPatch bonding-incorrect-tx-queue-offset.patch - -ApplyPatch scsi_dh_hp_sw-fix-deadlock-in-start_stop_endio.patch - ApplyPatch bluetooth-device-ids-for-ath3k-on-pegatron-lucid-tablets.patch # rhbz#709122 ApplyPatch ath5k-disable-fast-channel-switching-by-default.patch -# rhbz#648732 -ApplyPatch iwlagn-use-cts-to-self-protection-on-5000-adapters-series.patch - # rhbz#589390 ApplyPatch crypto-aesni_intel-merge-with-fpu_ko.patch @@ -2065,6 +1958,9 @@ fi # and build. %changelog +* Wed Jun 29 2011 Dave Jones +- 2.6.39 + * Mon Jun 27 2011 Dave Jones - Disable CONFIG_CRYPTO_MANAGER_DISABLE_TESTS, as this also disables FIPS (rhbz 716942) diff --git a/linux-2.6-acpi-debug-infinite-loop.patch b/linux-2.6-acpi-debug-infinite-loop.patch index 45cb051..d200252 100644 --- a/linux-2.6-acpi-debug-infinite-loop.patch +++ b/linux-2.6-acpi-debug-infinite-loop.patch @@ -1,16 +1,3 @@ ---- linux-2.6.34.noarch/drivers/acpi/acpica/dsopcode.c~ 2010-07-01 14:40:44.000000000 -0400 -+++ linux-2.6.34.noarch/drivers/acpi/acpica/dsopcode.c 2010-07-01 14:48:56.000000000 -0400 -@@ -1276,6 +1276,10 @@ acpi_ds_exec_end_control_op(struct acpi_ - * loop does not implement a timeout. - */ - control_state->control.loop_count++; -+ if ((control_state->control.loop_count > 1) && (control_state->control.loop_count % 0xffff == 0)) -+ printk("ACPI: While loop taking a really long time. loop_count=0x%x\n", -+ control_state->control.loop_count); -+ - if (control_state->control.loop_count > - ACPI_MAX_LOOP_ITERATIONS) { - status = AE_AML_INFINITE_LOOP; --- linux-2.6.34.noarch/drivers/acpi/acpica/acconfig.h~ 2010-07-01 14:49:03.000000000 -0400 +++ linux-2.6.34.noarch/drivers/acpi/acpica/acconfig.h 2010-07-01 14:49:17.000000000 -0400 @@ -117,7 +117,7 @@ @@ -22,3 +9,17 @@ /* Maximum sleep allowed via Sleep() operator */ +--- a/drivers/acpi/acpica/dscontrol.c ++++ b/drivers/acpi/acpica/dscontrol.c +@@ -212,6 +212,11 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, + * loop does not implement a timeout. + */ + control_state->control.loop_count++; ++ if ((control_state->control.loop_count > 1) && ++ (control_state->control.loop_count % 0xffff == 0)) ++ printk("ACPI: While loop taking a really long time. loop_count=0x%x\n", ++ control_state->control.loop_count); ++ + if (control_state->control.loop_count > + ACPI_MAX_LOOP_ITERATIONS) { + status = AE_AML_INFINITE_LOOP; diff --git a/linux-2.6-crash-driver.patch b/linux-2.6-crash-driver.patch index 0f11aba..5127743 100644 --- a/linux-2.6-crash-driver.patch +++ b/linux-2.6-crash-driver.patch @@ -220,20 +220,18 @@ index 5eb1ba7..3e525d2 100644 /* * Fix up the linear direct mapping of the kernel to avoid cache attribute * conflicts. -diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig -index 3141dd3..153658c 100644 ---- a/drivers/char/Kconfig -+++ b/drivers/char/Kconfig -@@ -471,6 +471,8 @@ config LEGACY_PTYS - security. This option enables these legacy devices; on most - systems, it is safe to say N. +--- linux-2.6.39.noarch/drivers/char/Kconfig~ 2011-06-29 23:41:24.386370545 -0400 ++++ linux-2.6.39.noarch/drivers/char/Kconfig 2011-06-29 23:42:11.984193335 -0400 +@@ -15,6 +15,9 @@ config DEVKMEM + kind of kernel debugging operations. + When in doubt, say "N". +config CRASH -+ tristate "Crash Utility memory driver" - - config LEGACY_PTY_COUNT - int "Maximum number of legacy PTY in use" - ++ tristate "Crash Utility memory driver" ++ + config STALDRV + bool "Stallion multiport serial support" + depends on SERIAL_NONSTANDARD diff --git a/drivers/char/crash.c b/drivers/char/crash.c new file mode 100644 index 0000000..e5437de diff --git a/linux-2.6-debug-always-inline-kzalloc.patch b/linux-2.6-debug-always-inline-kzalloc.patch deleted file mode 100644 index 24f665c..0000000 --- a/linux-2.6-debug-always-inline-kzalloc.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 76ec0e2e6d6edf81abc0331d5e7873ef7b2f6019 Mon Sep 17 00:00:00 2001 -From: Kyle McMartin -Date: Wed, 8 Jul 2009 13:06:01 -0400 -Subject: [PATCH 6/6] fedora: linux-2.6-debug-always-inline-kzalloc.patch - ---- - include/linux/slab.h | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/include/linux/slab.h b/include/linux/slab.h -index 2da8372..d4ef74f 100644 ---- a/include/linux/slab.h -+++ b/include/linux/slab.h -@@ -310,7 +310,7 @@ static inline void *kmem_cache_zalloc(struct kmem_cache *k, gfp_t flags) - * @size: how many bytes of memory are required. - * @flags: the type of memory to allocate (see kmalloc). - */ --static inline void *kzalloc(size_t size, gfp_t flags) -+static __always_inline void *kzalloc(size_t size, gfp_t flags) - { - return kmalloc(size, flags | __GFP_ZERO); - } --- -1.6.2.5 - diff --git a/linux-2.6-debug-sizeof-structs.patch b/linux-2.6-debug-sizeof-structs.patch deleted file mode 100644 index e027d98..0000000 --- a/linux-2.6-debug-sizeof-structs.patch +++ /dev/null @@ -1,33 +0,0 @@ -diff --git a/init/main.c b/init/main.c -index 7449819..98cfaae 100644 ---- a/init/main.c -+++ b/init/main.c -@@ -369,6 +369,11 @@ static void __init setup_nr_cpu_ids(void) - nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask),NR_CPUS) + 1; - } - -+#include <../fs/ext4/ext4.h> -+#include -+#include -+#include -+ - /* Called by boot processor to activate the rest. */ - static void __init smp_init(void) - { -@@ -391,6 +395,16 @@ static void __init smp_init(void) - /* Any cleanup work */ - printk(KERN_INFO "Brought up %ld CPUs\n", (long)num_online_cpus()); - smp_cpus_done(setup_max_cpus); -+ -+ printk(KERN_DEBUG "sizeof(vma)=%u bytes\n", (unsigned int) sizeof(struct vm_area_struct)); -+ printk(KERN_DEBUG "sizeof(page)=%u bytes\n", (unsigned int) sizeof(struct page)); -+ printk(KERN_DEBUG "sizeof(inode)=%u bytes\n", (unsigned int) sizeof(struct inode)); -+ printk(KERN_DEBUG "sizeof(dentry)=%u bytes\n", (unsigned int) sizeof(struct dentry)); -+ printk(KERN_DEBUG "sizeof(ext3inode)=%u bytes\n", (unsigned int) sizeof(struct ext3_inode_info)); -+ printk(KERN_DEBUG "sizeof(ext4inode)=%u bytes\n", (unsigned int) sizeof(struct ext4_inode_info)); -+ printk(KERN_DEBUG "sizeof(buffer_head)=%u bytes\n", (unsigned int) sizeof(struct buffer_head)); -+ printk(KERN_DEBUG "sizeof(skbuff)=%u bytes\n", (unsigned int) sizeof(struct sk_buff)); -+ printk(KERN_DEBUG "sizeof(task_struct)=%u bytes\n", (unsigned int) sizeof(struct task_struct)); - } - - #endif diff --git a/linux-2.6-hotfixes.patch b/linux-2.6-hotfixes.patch deleted file mode 100644 index 4949473..0000000 --- a/linux-2.6-hotfixes.patch +++ /dev/null @@ -1,15 +0,0 @@ -fixes: -implicit declaration of function kzalloc - ---- linux-2.6.34.noarch/drivers/usb/serial/qcserial.c~ 2010-06-08 15:19:41.000000000 -0400 -+++ linux-2.6.34.noarch/drivers/usb/serial/qcserial.c 2010-06-08 15:19:47.000000000 -0400 -@@ -11,6 +11,7 @@ - * - */ - -+#include - #include - #include - #include - - diff --git a/linux-2.6-i386-nx-emulation.patch b/linux-2.6-i386-nx-emulation.patch index da84cc6..3d2c968 100644 --- a/linux-2.6-i386-nx-emulation.patch +++ b/linux-2.6-i386-nx-emulation.patch @@ -46,7 +46,7 @@ #endif /* _ASM_X86_DESC_H */ --- a/arch/x86/include/asm/mmu.h +++ b/arch/x86/include/asm/mmu.h -@@ -7,12 +7,19 @@ +@@ -7,18 +7,25 @@ /* * The x86 doesn't have a mmu context, but * we put the segment information here. @@ -59,10 +59,16 @@ int size; struct mutex lock; void *vdso; + + #ifdef CONFIG_X86_64 + /* True if mm supports a task running in 32 bit compatibility mode. */ + unsigned short ia32_compat; + #endif +#ifdef CONFIG_X86_32 + struct desc_struct user_cs; + unsigned long exec_limit; +#endif + } mm_context_t; #ifdef CONFIG_SMP @@ -132,7 +138,7 @@ .store_gdt = native_store_gdt, --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c -@@ -243,7 +243,10 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, +@@ -243,7 +243,10 @@ int copy_thread(unsigned long clone_flag void start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) { @@ -141,8 +147,8 @@ set_user_gs(regs, 0); + regs->fs = 0; - set_fs(USER_DS); regs->ds = __USER_DS; + regs->es = __USER_DS; @@ -252,6 +255,11 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) regs->cs = __USER_CS; regs->ip = new_ip; @@ -472,8 +478,8 @@ --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -101,6 +101,9 @@ struct bio_list; - struct fs_struct; struct perf_event_context; + struct blk_plug; +extern int disable_nx; +extern int print_fatal_signals; diff --git a/linux-2.6-netconsole-deadlock.patch b/linux-2.6-netconsole-deadlock.patch deleted file mode 100644 index 677ed76..0000000 --- a/linux-2.6-netconsole-deadlock.patch +++ /dev/null @@ -1,56 +0,0 @@ -commit 13f172ff26563995049abe73f6eeba828de3c09d -Author: Neil Horman -Date: Fri Apr 22 08:10:59 2011 +0000 - - netconsole: fix deadlock when removing net driver that netconsole is using (v2) - - A deadlock was reported to me recently that occured when netconsole was being - used in a virtual guest. If the virtio_net driver was removed while netconsole - was setup to use an interface that was driven by that driver, the guest - deadlocked. No backtrace was provided because netconsole was the only console - configured, but it became clear pretty quickly what the problem was. In - netconsole_netdev_event, if we get an unregister event, we call - __netpoll_cleanup with the target_list_lock held and irqs disabled. - __netpoll_cleanup can, if pending netpoll packets are waiting call - cancel_delayed_work_sync, which is a sleeping path. the might_sleep call in - that path gets triggered, causing a console warning to be issued. The - netconsole write handler of course tries to take the target_list_lock again, - which we already hold, causing deadlock. - - The fix is pretty striaghtforward. Simply drop the target_list_lock and - re-enable irqs prior to calling __netpoll_cleanup, the re-acquire the lock, and - restart the loop. Confirmed by myself to fix the problem reported. - - Signed-off-by: Neil Horman - CC: "David S. Miller" - Signed-off-by: David S. Miller - -diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c -index dfb67eb..eb41e44 100644 ---- a/drivers/net/netconsole.c -+++ b/drivers/net/netconsole.c -@@ -671,6 +671,7 @@ static int netconsole_netdev_event(struct notifier_block *this, - goto done; - - spin_lock_irqsave(&target_list_lock, flags); -+restart: - list_for_each_entry(nt, &target_list, list) { - netconsole_target_get(nt); - if (nt->np.dev == dev) { -@@ -683,9 +684,16 @@ static int netconsole_netdev_event(struct notifier_block *this, - * rtnl_lock already held - */ - if (nt->np.dev) { -+ spin_unlock_irqrestore( -+ &target_list_lock, -+ flags); - __netpoll_cleanup(&nt->np); -+ spin_lock_irqsave(&target_list_lock, -+ flags); - dev_put(nt->np.dev); - nt->np.dev = NULL; -+ netconsole_target_put(nt); -+ goto restart; - } - /* Fall through */ - case NETDEV_GOING_DOWN: diff --git a/linux-2.6-upstream-reverts.patch b/linux-2.6-upstream-reverts.patch index 157205f..e69de29 100644 --- a/linux-2.6-upstream-reverts.patch +++ b/linux-2.6-upstream-reverts.patch @@ -1,203 +0,0 @@ -From 97bfd0acd32e9639c9136e03955d574655d5cc2b Mon Sep 17 00:00:00 2001 -From: Dave Airlie -Date: Thu, 19 May 2011 14:14:43 +1000 -Subject: drm/radeon/kms: add wait idle ioctl for eg->cayman - -From: Dave Airlie - -commit 97bfd0acd32e9639c9136e03955d574655d5cc2b upstream. - -None of the latest GPUs had this hooked up, this is necessary for -correct operation in a lot of cases, however we should test this on a few -GPUs in these families as we've had problems in this area before. - -Reviewed-by: Alex Deucher -Signed-off-by: Dave Airlie -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/radeon/radeon_asic.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/gpu/drm/radeon/radeon_asic.c -+++ b/drivers/gpu/drm/radeon/radeon_asic.c -@@ -782,6 +782,7 @@ static struct radeon_asic evergreen_asic - .hpd_fini = &evergreen_hpd_fini, - .hpd_sense = &evergreen_hpd_sense, - .hpd_set_polarity = &evergreen_hpd_set_polarity, -+ .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .pm_misc = &evergreen_pm_misc, - .pm_prepare = &evergreen_pm_prepare, -@@ -828,6 +829,7 @@ static struct radeon_asic sumo_asic = { - .hpd_fini = &evergreen_hpd_fini, - .hpd_sense = &evergreen_hpd_sense, - .hpd_set_polarity = &evergreen_hpd_set_polarity, -+ .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .pm_misc = &evergreen_pm_misc, - .pm_prepare = &evergreen_pm_prepare, -@@ -874,6 +876,8 @@ static struct radeon_asic btc_asic = { - .hpd_fini = &evergreen_hpd_fini, - .hpd_sense = &evergreen_hpd_sense, - .hpd_set_polarity = &evergreen_hpd_set_polarity, -+ .ioctl_wait_idle = r600_ioctl_wait_idle, -+ .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .pm_misc = &evergreen_pm_misc, - .pm_prepare = &evergreen_pm_prepare, -From f25a5c63bfa017498c9adecb24d649ae96ba5c68 Mon Sep 17 00:00:00 2001 -From: Alex Deucher -Date: Thu, 19 May 2011 11:07:57 -0400 -Subject: drm/radeon/evergreen/btc/fusion: setup hdp to invalidate and - flush when asked - -From: Alex Deucher - -commit f25a5c63bfa017498c9adecb24d649ae96ba5c68 upstream. - -This needs to be explicitly set on btc. It's set by default -on evergreen/fusion, so it fine to just unconditionally enable it for -all chips. - -Signed-off-by: Alex Deucher -Signed-off-by: Dave Airlie -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/radeon/evergreen.c | 6 +++++- - drivers/gpu/drm/radeon/evergreend.h | 2 ++ - 2 files changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/radeon/evergreen.c -+++ b/drivers/gpu/drm/radeon/evergreen.c -@@ -1585,7 +1585,7 @@ static void evergreen_gpu_init(struct ra - u32 sq_stack_resource_mgmt_2; - u32 sq_stack_resource_mgmt_3; - u32 vgt_cache_invalidation; -- u32 hdp_host_path_cntl; -+ u32 hdp_host_path_cntl, tmp; - int i, j, num_shader_engines, ps_thread_count; - - switch (rdev->family) { -@@ -2145,6 +2145,10 @@ static void evergreen_gpu_init(struct ra - for (i = SQ_ALU_CONST_BUFFER_SIZE_HS_0; i < 0x29000; i += 4) - WREG32(i, 0); - -+ tmp = RREG32(HDP_MISC_CNTL); -+ tmp |= HDP_FLUSH_INVALIDATE_CACHE; -+ WREG32(HDP_MISC_CNTL, tmp); -+ - hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); - WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); - ---- a/drivers/gpu/drm/radeon/evergreend.h -+++ b/drivers/gpu/drm/radeon/evergreend.h -@@ -64,6 +64,8 @@ - #define GB_BACKEND_MAP 0x98FC - #define DMIF_ADDR_CONFIG 0xBD4 - #define HDP_ADDR_CONFIG 0x2F48 -+#define HDP_MISC_CNTL 0x2F4C -+#define HDP_FLUSH_INVALIDATE_CACHE (1 << 0) - - #define CC_SYS_RB_BACKEND_DISABLE 0x3F88 - #define GC_USER_RB_BACKEND_DISABLE 0x9B7C -From alexdeucher@gmail.com Mon May 9 16:35:34 2011 -From: Alex Deucher -Date: Fri, 6 May 2011 14:29:55 -0400 -Subject: [stable] [PATCH] drm/radeon/kms: fix gart setup on fusion parts (v2) backport -To: stable@kernel.org -Cc: Alex Deucher , airlied@redhat.com, gregkh@suse.de -Message-ID: <1304706595-9781-1-git-send-email-alexdeucher@gmail.com> - -From: Alex Deucher - -Backport of 8aeb96f80232e9a701b5c4715504f4c9173978bd -(drm/radeon/kms: fix gart setup on fusion parts (v2)) -to the stable tree. - -Out of the entire GART/VM subsystem, the hw designers changed -the location of 3 regs. - -v2: airlied: add parameter for userspace to work from. - -Signed-off-by: Alex Deucher -Signed-off-by: Jerome Glisse -Signed-off-by: Dave Airlie -Signed-off-by: Greg Kroah-Hartman ---- - drivers/gpu/drm/radeon/evergreen.c | 17 +++++++++-------- - drivers/gpu/drm/radeon/evergreend.h | 5 +++++ - drivers/gpu/drm/radeon/radeon_kms.c | 3 +++ - include/drm/radeon_drm.h | 1 + - 4 files changed, 18 insertions(+), 8 deletions(-) - ---- a/drivers/gpu/drm/radeon/evergreen.c -+++ b/drivers/gpu/drm/radeon/evergreen.c -@@ -869,9 +869,15 @@ int evergreen_pcie_gart_enable(struct ra - SYSTEM_ACCESS_MODE_NOT_IN_SYS | - SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | - EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); -- WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); -- WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); -- WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); -+ if (rdev->flags & RADEON_IS_IGP) { -+ WREG32(FUS_MC_VM_MD_L1_TLB0_CNTL, tmp); -+ WREG32(FUS_MC_VM_MD_L1_TLB1_CNTL, tmp); -+ WREG32(FUS_MC_VM_MD_L1_TLB2_CNTL, tmp); -+ } else { -+ WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); -+ WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); -+ WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); -+ } - WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); -@@ -2930,11 +2936,6 @@ static int evergreen_startup(struct rade - rdev->asic->copy = NULL; - dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); - } -- /* XXX: ontario has problems blitting to gart at the moment */ -- if (rdev->family == CHIP_PALM) { -- rdev->asic->copy = NULL; -- radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); -- } - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); ---- a/drivers/gpu/drm/radeon/evergreend.h -+++ b/drivers/gpu/drm/radeon/evergreend.h -@@ -221,6 +221,11 @@ - #define MC_VM_MD_L1_TLB0_CNTL 0x2654 - #define MC_VM_MD_L1_TLB1_CNTL 0x2658 - #define MC_VM_MD_L1_TLB2_CNTL 0x265C -+ -+#define FUS_MC_VM_MD_L1_TLB0_CNTL 0x265C -+#define FUS_MC_VM_MD_L1_TLB1_CNTL 0x2660 -+#define FUS_MC_VM_MD_L1_TLB2_CNTL 0x2664 -+ - #define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C - #define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 - #define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 ---- a/drivers/gpu/drm/radeon/radeon_kms.c -+++ b/drivers/gpu/drm/radeon/radeon_kms.c -@@ -205,6 +205,9 @@ int radeon_info_ioctl(struct drm_device - /* return clock value in KHz */ - value = rdev->clock.spll.reference_freq * 10; - break; -+ case RADEON_INFO_FUSION_GART_WORKING: -+ value = 1; -+ break; - default: - DRM_DEBUG_KMS("Invalid request %d\n", info->request); - return -EINVAL; ---- a/include/drm/radeon_drm.h -+++ b/include/drm/radeon_drm.h -@@ -908,6 +908,7 @@ struct drm_radeon_cs { - #define RADEON_INFO_WANT_HYPERZ 0x07 - #define RADEON_INFO_WANT_CMASK 0x08 /* get access to CMASK on r300 */ - #define RADEON_INFO_CLOCK_CRYSTAL_FREQ 0x09 /* clock crystal frequency */ -+#define RADEON_INFO_FUSION_GART_WORKING 0x0c /* fusion writes to GTT were broken before this */ - - struct drm_radeon_info { - uint32_t request; diff --git a/linux-2.6-utrace-ptrace.patch b/linux-2.6-utrace-ptrace.patch index 367deb9..55c6f61 100644 --- a/linux-2.6-utrace-ptrace.patch +++ b/linux-2.6-utrace-ptrace.patch @@ -48,7 +48,7 @@ new file mode 100644 index ...a5bcb9e 100644 --- /dev/null +++ b/kernel/ptrace-utrace.c -@@ -0,0 +1,1187 @@ +@@ -0,0 +1,1186 @@ +/* + * linux/kernel/ptrace.c + * @@ -65,7 +65,6 @@ index ...a5bcb9e 100644 +#include +#include +#include -+#include +#include +#include +#include @@ -1248,7 +1247,333 @@ index e275608..72ea65c 100644 #include #include #include -@@ -24,7 +23,320 @@ +@@ -195,8 +452,6 @@ int ptrace_attach(struct task_struct *ta + + task_lock(task); + retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH); +- if (!retval && exclude_ptrace(task)) +- retval = -EBUSY; + task_unlock(task); + if (retval) + goto unlock_creds; +@@ -220,91 +475,37 @@ unlock_tasklist: + write_unlock_irq(&tasklist_lock); + unlock_creds: + mutex_unlock(&task->signal->cred_guard_mutex); +-out: +- return retval; +-} +- +-/** +- * ptrace_traceme -- helper for PTRACE_TRACEME +- * +- * Performs checks and sets PT_PTRACED. +- * Should be used by all ptrace implementations for PTRACE_TRACEME. +- */ +-int ptrace_traceme(void) +-{ +- int ret = -EPERM; +- +- if (exclude_ptrace(current)) /* XXX locking */ +- return -EBUSY; +- +- write_lock_irq(&tasklist_lock); +- /* Are we already being traced? */ +- if (!current->ptrace) { +- ret = security_ptrace_traceme(current->parent); +- /* +- * Check PF_EXITING to ensure ->real_parent has not passed +- * exit_ptrace(). Otherwise we don't report the error but +- * pretend ->real_parent untraces us right after return. +- */ +- if (!ret && !(current->real_parent->flags & PF_EXITING)) { +- current->ptrace = PT_PTRACED; +- __ptrace_link(current, current->real_parent); +- } +- } +- write_unlock_irq(&tasklist_lock); +- +- return ret; +-} +- +-/* +- * Called with irqs disabled, returns true if childs should reap themselves. +- */ +-static int ignoring_children(struct sighand_struct *sigh) +-{ +- int ret; +- spin_lock(&sigh->siglock); +- ret = (sigh->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) || +- (sigh->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT); +- spin_unlock(&sigh->siglock); +- return ret; +-} +- +-/* +- * Called with tasklist_lock held for writing. +- * Unlink a traced task, and clean it up if it was a traced zombie. +- * Return true if it needs to be reaped with release_task(). +- * (We can't call release_task() here because we already hold tasklist_lock.) +- * +- * If it's a zombie, our attachedness prevented normal parent notification +- * or self-reaping. Do notification now if it would have happened earlier. +- * If it should reap itself, return true. ++out: ++ return retval; ++} ++ ++/** ++ * ptrace_traceme -- helper for PTRACE_TRACEME + * +- * If it's our own child, there is no notification to do. But if our normal +- * children self-reap, then this child was prevented by ptrace and we must +- * reap it now, in that case we must also wake up sub-threads sleeping in +- * do_wait(). ++ * Performs checks and sets PT_PTRACED. ++ * Should be used by all ptrace implementations for PTRACE_TRACEME. + */ +-bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) ++int ptrace_traceme(void) + { +- __ptrace_unlink(p); ++ int ret = -EPERM; + +- if (p->exit_state == EXIT_ZOMBIE) { +- if (!task_detached(p) && thread_group_empty(p)) { +- if (!same_thread_group(p->real_parent, tracer)) +- do_notify_parent(p, p->exit_signal); +- else if (ignoring_children(tracer->sighand)) { +- __wake_up_parent(p, tracer); +- p->exit_signal = -1; +- } +- } +- if (task_detached(p)) { +- /* Mark it as in the process of being reaped. */ +- p->exit_state = EXIT_DEAD; +- return true; ++ write_lock_irq(&tasklist_lock); ++ /* Are we already being traced? */ ++ if (!current->ptrace) { ++ ret = security_ptrace_traceme(current->parent); ++ /* ++ * Check PF_EXITING to ensure ->real_parent has not passed ++ * exit_ptrace(). Otherwise we don't report the error but ++ * pretend ->real_parent untraces us right after return. ++ */ ++ if (!ret && !(current->real_parent->flags & PF_EXITING)) { ++ current->ptrace = PT_PTRACED; ++ __ptrace_link(current, current->real_parent); + } + } ++ write_unlock_irq(&tasklist_lock); + +- return false; ++ return ret; + } + + int ptrace_detach(struct task_struct *child, unsigned int data) +@@ -368,57 +569,7 @@ void exit_ptrace(struct task_struct *tra + write_lock_irq(&tasklist_lock); + } + +-int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len) +-{ +- int copied = 0; +- +- while (len > 0) { +- char buf[128]; +- int this_len, retval; +- +- this_len = (len > sizeof(buf)) ? sizeof(buf) : len; +- retval = access_process_vm(tsk, src, buf, this_len, 0); +- if (!retval) { +- if (copied) +- break; +- return -EIO; +- } +- if (copy_to_user(dst, buf, retval)) +- return -EFAULT; +- copied += retval; +- src += retval; +- dst += retval; +- len -= retval; +- } +- return copied; +-} +- +-int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len) +-{ +- int copied = 0; +- +- while (len > 0) { +- char buf[128]; +- int this_len, retval; +- +- this_len = (len > sizeof(buf)) ? sizeof(buf) : len; +- if (copy_from_user(buf, src, this_len)) +- return -EFAULT; +- retval = access_process_vm(tsk, dst, buf, this_len, 1); +- if (!retval) { +- if (copied) +- break; +- return -EIO; +- } +- copied += retval; +- src += retval; +- dst += retval; +- len -= retval; +- } +- return copied; +-} +- +-static int ptrace_setoptions(struct task_struct *child, unsigned long data) ++static int ptrace_setoptions(struct task_struct *child, long data) + { + child->ptrace &= ~PT_TRACE_MASK; + +@@ -533,47 +683,6 @@ static int ptrace_resume(struct task_str + return 0; + } + +-#ifdef CONFIG_HAVE_ARCH_TRACEHOOK +- +-static const struct user_regset * +-find_regset(const struct user_regset_view *view, unsigned int type) +-{ +- const struct user_regset *regset; +- int n; +- +- for (n = 0; n < view->n; ++n) { +- regset = view->regsets + n; +- if (regset->core_note_type == type) +- return regset; +- } +- +- return NULL; +-} +- +-static int ptrace_regset(struct task_struct *task, int req, unsigned int type, +- struct iovec *kiov) +-{ +- const struct user_regset_view *view = task_user_regset_view(task); +- const struct user_regset *regset = find_regset(view, type); +- int regset_no; +- +- if (!regset || (kiov->iov_len % regset->size) != 0) +- return -EINVAL; +- +- regset_no = regset - view->regsets; +- kiov->iov_len = min(kiov->iov_len, +- (__kernel_size_t) (regset->n * regset->size)); +- +- if (req == PTRACE_GETREGSET) +- return copy_regset_to_user(task, view, regset_no, 0, +- kiov->iov_len, kiov->iov_base); +- else +- return copy_regset_from_user(task, view, regset_no, 0, +- kiov->iov_len, kiov->iov_base); +-} +- +-#endif +- + int ptrace_request(struct task_struct *child, long request, + unsigned long addr, unsigned long data) + { +@@ -689,91 +798,7 @@ int ptrace_request(struct task_struct *c + return ret; + } + +-static struct task_struct *ptrace_get_task_struct(pid_t pid) +-{ +- struct task_struct *child; +- +- rcu_read_lock(); +- child = find_task_by_vpid(pid); +- if (child) +- get_task_struct(child); +- rcu_read_unlock(); +- +- if (!child) +- return ERR_PTR(-ESRCH); +- return child; +-} +- +-#ifndef arch_ptrace_attach +-#define arch_ptrace_attach(child) do { } while (0) +-#endif +- +-SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, +- unsigned long, data) +-{ +- struct task_struct *child; +- long ret; +- +- if (request == PTRACE_TRACEME) { +- ret = ptrace_traceme(); +- if (!ret) +- arch_ptrace_attach(current); +- goto out; +- } +- +- child = ptrace_get_task_struct(pid); +- if (IS_ERR(child)) { +- ret = PTR_ERR(child); +- goto out; +- } +- +- if (request == PTRACE_ATTACH) { +- ret = ptrace_attach(child); +- /* +- * Some architectures need to do book-keeping after +- * a ptrace attach. +- */ +- if (!ret) +- arch_ptrace_attach(child); +- goto out_put_task_struct; +- } +- +- ret = ptrace_check_attach(child, request == PTRACE_KILL); +- if (ret < 0) +- goto out_put_task_struct; +- +- ret = arch_ptrace(child, request, addr, data); +- +- out_put_task_struct: +- put_task_struct(child); +- out: +- return ret; +-} +- +-int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr, +- unsigned long data) +-{ +- unsigned long tmp; +- int copied; +- +- copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0); +- if (copied != sizeof(tmp)) +- return -EIO; +- return put_user(tmp, (unsigned long __user *)data); +-} +- +-int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr, +- unsigned long data) +-{ +- int copied; +- +- copied = access_process_vm(tsk, addr, &data, sizeof(data), 1); +- return (copied == sizeof(data)) ? 0 : -EIO; +-} +- + #if defined CONFIG_COMPAT +-#include +- + int compat_ptrace_request(struct task_struct *child, compat_long_t request, + compat_ulong_t addr, compat_ulong_t data) + { +--- linux-2.6.39.noarch/kernel/ptrace.c~ 2011-06-30 01:26:39.872164118 -0400 ++++ linux-2.6.39.noarch/kernel/ptrace.c 2011-06-30 01:30:09.682400285 -0400 +@@ -24,8 +24,321 @@ #include #include @@ -1298,8 +1623,8 @@ index e275608..72ea65c 100644 + task_unlock(task); + return !err; +} -+ -+/* + + /* + * Called with irqs disabled, returns true if childs should reap themselves. + */ +static int ignoring_children(struct sighand_struct *sigh) @@ -1472,7 +1797,7 @@ index e275608..72ea65c 100644 + arch_ptrace_attach(current); + goto out; + } - ++ + child = ptrace_get_task_struct(pid); + if (IS_ERR(child)) { + ret = PTR_ERR(child); @@ -1544,422 +1869,101 @@ index e275608..72ea65c 100644 + } + + if (request == PTRACE_ATTACH) { -+ ret = ptrace_attach(child); -+ /* -+ * Some architectures need to do book-keeping after -+ * a ptrace attach. -+ */ -+ if (!ret) -+ arch_ptrace_attach(child); -+ goto out_put_task_struct; -+ } -+ -+ ret = ptrace_check_attach(child, request == PTRACE_KILL); -+ if (!ret) -+ ret = compat_arch_ptrace(child, request, addr, data); -+ -+ out_put_task_struct: -+ put_task_struct(child); -+ out: -+ return ret; -+} -+#endif /* CONFIG_COMPAT */ -+ -+#ifndef CONFIG_UTRACE - /* - * ptrace a task: make the debugger its new parent and - * move it to the ptrace list. -@@ -117,61 +429,6 @@ int ptrace_check_attach(struct task_stru - return ret; - } - --int __ptrace_may_access(struct task_struct *task, unsigned int mode) --{ -- const struct cred *cred = current_cred(), *tcred; -- -- /* May we inspect the given task? -- * This check is used both for attaching with ptrace -- * and for allowing access to sensitive information in /proc. -- * -- * ptrace_attach denies several cases that /proc allows -- * because setting up the necessary parent/child relationship -- * or halting the specified task is impossible. -- */ -- int dumpable = 0; -- /* Don't let security modules deny introspection */ -- if (task == current) -- return 0; -- rcu_read_lock(); -- tcred = __task_cred(task); -- if ((cred->uid != tcred->euid || -- cred->uid != tcred->suid || -- cred->uid != tcred->uid || -- cred->gid != tcred->egid || -- cred->gid != tcred->sgid || -- cred->gid != tcred->gid) && -- !capable(CAP_SYS_PTRACE)) { -- rcu_read_unlock(); -- return -EPERM; -- } -- rcu_read_unlock(); -- smp_rmb(); -- if (task->mm) -- dumpable = get_dumpable(task->mm); -- if (!dumpable && !capable(CAP_SYS_PTRACE)) -- return -EPERM; -- -- return security_ptrace_access_check(task, mode); --} -- --bool ptrace_may_access(struct task_struct *task, unsigned int mode) --{ -- int err; -- task_lock(task); -- err = __ptrace_may_access(task, mode); -- task_unlock(task); -- return !err; --} -- --/* -- * For experimental use of utrace, exclude ptrace on the same task. -- */ --static inline bool exclude_ptrace(struct task_struct *task) --{ -- return unlikely(!!task_utrace_flags(task)); --} -- - int ptrace_attach(struct task_struct *task) - { - int retval; -@@ -195,8 +452,6 @@ int ptrace_attach(struct task_struct *ta - - task_lock(task); - retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH); -- if (!retval && exclude_ptrace(task)) -- retval = -EBUSY; - task_unlock(task); - if (retval) - goto unlock_creds; -@@ -220,91 +475,37 @@ unlock_tasklist: - write_unlock_irq(&tasklist_lock); - unlock_creds: - mutex_unlock(&task->signal->cred_guard_mutex); --out: -- return retval; --} -- --/** -- * ptrace_traceme -- helper for PTRACE_TRACEME -- * -- * Performs checks and sets PT_PTRACED. -- * Should be used by all ptrace implementations for PTRACE_TRACEME. -- */ --int ptrace_traceme(void) --{ -- int ret = -EPERM; -- -- if (exclude_ptrace(current)) /* XXX locking */ -- return -EBUSY; -- -- write_lock_irq(&tasklist_lock); -- /* Are we already being traced? */ -- if (!current->ptrace) { -- ret = security_ptrace_traceme(current->parent); -- /* -- * Check PF_EXITING to ensure ->real_parent has not passed -- * exit_ptrace(). Otherwise we don't report the error but -- * pretend ->real_parent untraces us right after return. -- */ -- if (!ret && !(current->real_parent->flags & PF_EXITING)) { -- current->ptrace = PT_PTRACED; -- __ptrace_link(current, current->real_parent); -- } -- } -- write_unlock_irq(&tasklist_lock); -- -- return ret; --} -- --/* -- * Called with irqs disabled, returns true if childs should reap themselves. -- */ --static int ignoring_children(struct sighand_struct *sigh) --{ -- int ret; -- spin_lock(&sigh->siglock); -- ret = (sigh->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) || -- (sigh->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT); -- spin_unlock(&sigh->siglock); -- return ret; --} -- --/* -- * Called with tasklist_lock held for writing. -- * Unlink a traced task, and clean it up if it was a traced zombie. -- * Return true if it needs to be reaped with release_task(). -- * (We can't call release_task() here because we already hold tasklist_lock.) -- * -- * If it's a zombie, our attachedness prevented normal parent notification -- * or self-reaping. Do notification now if it would have happened earlier. -- * If it should reap itself, return true. -+out: -+ return retval; -+} -+ -+/** -+ * ptrace_traceme -- helper for PTRACE_TRACEME - * -- * If it's our own child, there is no notification to do. But if our normal -- * children self-reap, then this child was prevented by ptrace and we must -- * reap it now, in that case we must also wake up sub-threads sleeping in -- * do_wait(). -+ * Performs checks and sets PT_PTRACED. -+ * Should be used by all ptrace implementations for PTRACE_TRACEME. - */ --bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) -+int ptrace_traceme(void) - { -- __ptrace_unlink(p); -+ int ret = -EPERM; - -- if (p->exit_state == EXIT_ZOMBIE) { -- if (!task_detached(p) && thread_group_empty(p)) { -- if (!same_thread_group(p->real_parent, tracer)) -- do_notify_parent(p, p->exit_signal); -- else if (ignoring_children(tracer->sighand)) { -- __wake_up_parent(p, tracer); -- p->exit_signal = -1; -- } -- } -- if (task_detached(p)) { -- /* Mark it as in the process of being reaped. */ -- p->exit_state = EXIT_DEAD; -- return true; -+ write_lock_irq(&tasklist_lock); -+ /* Are we already being traced? */ -+ if (!current->ptrace) { -+ ret = security_ptrace_traceme(current->parent); ++ ret = ptrace_attach(child); + /* -+ * Check PF_EXITING to ensure ->real_parent has not passed -+ * exit_ptrace(). Otherwise we don't report the error but -+ * pretend ->real_parent untraces us right after return. ++ * Some architectures need to do book-keeping after ++ * a ptrace attach. + */ -+ if (!ret && !(current->real_parent->flags & PF_EXITING)) { -+ current->ptrace = PT_PTRACED; -+ __ptrace_link(current, current->real_parent); - } - } -+ write_unlock_irq(&tasklist_lock); - -- return false; ++ if (!ret) ++ arch_ptrace_attach(child); ++ goto out_put_task_struct; ++ } ++ ++ ret = ptrace_check_attach(child, request == PTRACE_KILL); ++ if (!ret) ++ ret = compat_arch_ptrace(child, request, addr, data); ++ ++ out_put_task_struct: ++ put_task_struct(child); ++ out: + return ret; - } - - int ptrace_detach(struct task_struct *child, unsigned int data) -@@ -368,57 +569,7 @@ void exit_ptrace(struct task_struct *tra - write_lock_irq(&tasklist_lock); - } - --int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len) --{ -- int copied = 0; -- -- while (len > 0) { -- char buf[128]; -- int this_len, retval; -- -- this_len = (len > sizeof(buf)) ? sizeof(buf) : len; -- retval = access_process_vm(tsk, src, buf, this_len, 0); -- if (!retval) { -- if (copied) -- break; -- return -EIO; -- } -- if (copy_to_user(dst, buf, retval)) -- return -EFAULT; -- copied += retval; -- src += retval; -- dst += retval; -- len -= retval; -- } -- return copied; --} -- --int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len) --{ -- int copied = 0; -- -- while (len > 0) { -- char buf[128]; -- int this_len, retval; -- -- this_len = (len > sizeof(buf)) ? sizeof(buf) : len; -- if (copy_from_user(buf, src, this_len)) -- return -EFAULT; -- retval = access_process_vm(tsk, dst, buf, this_len, 1); -- if (!retval) { -- if (copied) -- break; -- return -EIO; -- } -- copied += retval; -- src += retval; -- dst += retval; -- len -= retval; -- } -- return copied; --} -- --static int ptrace_setoptions(struct task_struct *child, unsigned long data) -+static int ptrace_setoptions(struct task_struct *child, long data) - { - child->ptrace &= ~PT_TRACE_MASK; - -@@ -533,47 +683,6 @@ static int ptrace_resume(struct task_str - return 0; - } - --#ifdef CONFIG_HAVE_ARCH_TRACEHOOK -- --static const struct user_regset * --find_regset(const struct user_regset_view *view, unsigned int type) --{ -- const struct user_regset *regset; -- int n; -- -- for (n = 0; n < view->n; ++n) { -- regset = view->regsets + n; -- if (regset->core_note_type == type) -- return regset; -- } -- -- return NULL; --} -- --static int ptrace_regset(struct task_struct *task, int req, unsigned int type, -- struct iovec *kiov) --{ -- const struct user_regset_view *view = task_user_regset_view(task); -- const struct user_regset *regset = find_regset(view, type); -- int regset_no; -- -- if (!regset || (kiov->iov_len % regset->size) != 0) -- return -EINVAL; -- -- regset_no = regset - view->regsets; -- kiov->iov_len = min(kiov->iov_len, -- (__kernel_size_t) (regset->n * regset->size)); -- -- if (req == PTRACE_GETREGSET) -- return copy_regset_to_user(task, view, regset_no, 0, -- kiov->iov_len, kiov->iov_base); -- else -- return copy_regset_from_user(task, view, regset_no, 0, -- kiov->iov_len, kiov->iov_base); --} -- --#endif -- - int ptrace_request(struct task_struct *child, long request, - unsigned long addr, unsigned long data) - { -@@ -689,91 +798,7 @@ int ptrace_request(struct task_struct *c ++} ++#endif /* CONFIG_COMPAT */ ++ ++#ifndef CONFIG_UTRACE ++/* + * ptrace a task: make the debugger its new parent and + * move it to the ptrace list. + * +@@ -117,64 +430,6 @@ int ptrace_check_attach(struct task_stru return ret; } --static struct task_struct *ptrace_get_task_struct(pid_t pid) +-int __ptrace_may_access(struct task_struct *task, unsigned int mode) -{ -- struct task_struct *child; +- const struct cred *cred = current_cred(), *tcred; - +- /* May we inspect the given task? +- * This check is used both for attaching with ptrace +- * and for allowing access to sensitive information in /proc. +- * +- * ptrace_attach denies several cases that /proc allows +- * because setting up the necessary parent/child relationship +- * or halting the specified task is impossible. +- */ +- int dumpable = 0; +- /* Don't let security modules deny introspection */ +- if (task == current) +- return 0; - rcu_read_lock(); -- child = find_task_by_vpid(pid); -- if (child) -- get_task_struct(child); +- tcred = __task_cred(task); +- if (cred->user->user_ns == tcred->user->user_ns && +- (cred->uid == tcred->euid && +- cred->uid == tcred->suid && +- cred->uid == tcred->uid && +- cred->gid == tcred->egid && +- cred->gid == tcred->sgid && +- cred->gid == tcred->gid)) +- goto ok; +- if (ns_capable(tcred->user->user_ns, CAP_SYS_PTRACE)) +- goto ok; - rcu_read_unlock(); +- return -EPERM; +-ok: +- rcu_read_unlock(); +- smp_rmb(); +- if (task->mm) +- dumpable = get_dumpable(task->mm); +- if (!dumpable && !task_ns_capable(task, CAP_SYS_PTRACE)) +- return -EPERM; - -- if (!child) -- return ERR_PTR(-ESRCH); -- return child; --} -- --#ifndef arch_ptrace_attach --#define arch_ptrace_attach(child) do { } while (0) --#endif -- --SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, -- unsigned long, data) --{ -- struct task_struct *child; -- long ret; -- -- if (request == PTRACE_TRACEME) { -- ret = ptrace_traceme(); -- if (!ret) -- arch_ptrace_attach(current); -- goto out; -- } -- -- child = ptrace_get_task_struct(pid); -- if (IS_ERR(child)) { -- ret = PTR_ERR(child); -- goto out; -- } -- -- if (request == PTRACE_ATTACH) { -- ret = ptrace_attach(child); -- /* -- * Some architectures need to do book-keeping after -- * a ptrace attach. -- */ -- if (!ret) -- arch_ptrace_attach(child); -- goto out_put_task_struct; -- } -- -- ret = ptrace_check_attach(child, request == PTRACE_KILL); -- if (ret < 0) -- goto out_put_task_struct; -- -- ret = arch_ptrace(child, request, addr, data); -- -- out_put_task_struct: -- put_task_struct(child); -- out: -- return ret; +- return security_ptrace_access_check(task, mode); -} - --int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr, -- unsigned long data) +-bool ptrace_may_access(struct task_struct *task, unsigned int mode) -{ -- unsigned long tmp; -- int copied; -- -- copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0); -- if (copied != sizeof(tmp)) -- return -EIO; -- return put_user(tmp, (unsigned long __user *)data); +- int err; +- task_lock(task); +- err = __ptrace_may_access(task, mode); +- task_unlock(task); +- return !err; -} - --int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr, -- unsigned long data) +-/* +- * For experimental use of utrace, exclude ptrace on the same task. +- */ +-static inline bool exclude_ptrace(struct task_struct *task) -{ -- int copied; -- -- copied = access_process_vm(tsk, addr, &data, sizeof(data), 1); -- return (copied == sizeof(data)) ? 0 : -EIO; +- return unlikely(!!task_utrace_flags(task)); -} - - #if defined CONFIG_COMPAT --#include -- - int compat_ptrace_request(struct task_struct *child, compat_long_t request, - compat_ulong_t addr, compat_ulong_t data) + int ptrace_attach(struct task_struct *task) { -@@ -851,45 +876,8 @@ int compat_ptrace_request(struct task_st - + int retval; +@@ -624,44 +879,8 @@ int compat_ptrace_request(struct task_st return ret; } -- + -asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, - compat_long_t addr, compat_long_t data) -{ @@ -1998,7 +2002,7 @@ index e275608..72ea65c 100644 - return ret; -} #endif /* CONFIG_COMPAT */ -+#endif /* CONFIG_UTRACE */ ++#endif /* CONFIG_UTRACE */ #ifdef CONFIG_HAVE_HW_BREAKPOINT int ptrace_get_breakpoints(struct task_struct *tsk) diff --git a/linux-2.6-v4l-dvb-experimental.patch b/linux-2.6-v4l-dvb-experimental.patch index 308ca63..e69de29 100644 --- a/linux-2.6-v4l-dvb-experimental.patch +++ b/linux-2.6-v4l-dvb-experimental.patch @@ -1,1326 +0,0 @@ -commit 9069f7f1ce7309cba021ac9c3527526d8524bd04 -Author: Jarod Wilson -Date: Mon Apr 25 13:50:50 2011 -0400 - - [media] ite-cir: modular build on ppc requires delay.h include - - Signed-off-by: Jarod Wilson - -commit 50f19c24801caaa6d846c62cef93ee54f6e6914f -Author: Jarod Wilson -Date: Mon Apr 25 13:48:18 2011 -0400 - - [media] mceusb: add Dell transceiver ID - - Add device ID for a Dell-branded, Philips device ID transceiver reported - by an OpenELEC user on their forums. - - http://openelec.tv/forum/27-hardware-support/5622-adding-support-for-an-ir-receiver--dell-branded--#5622 - - Signed-off-by: Jarod Wilson - -commit d9193f3784352638b355c9a24c16f1a2e14b0548 -Author: Jarod Wilson -Date: Thu Apr 21 14:21:47 2011 -0400 - - [media] nuvoton-cir: minor tweaks to rc dev init - - - Set a default timeout (matching mceusb.c) and use - ir_raw_event_store_with_filter, which leads to better behavior when - using lirc userspace decoding with this hardware - - Fill in rx_resolution with the value we're using here (50us) - - Signed-off-by: Jarod Wilson - -commit 02210203eb4df7fdf1156b24fcf2b7e2a20bf29c -Author: Jarod Wilson -Date: Tue Apr 19 15:47:34 2011 -0400 - - [media] mceusb: Formosa e017 device has no tx - - Per hardware provided to me, the Formosa Industrial Computing eHome - Infrared Receiver, 0x147a:0xe017, has no tx capability, it is rx only. - - Thanks go to Paul Rae for the hardware. - - Signed-off-by: Jarod Wilson - -commit 5919687ea8e0d3ee093b6edc4e24e30c1a8a60dc -Author: Jarod Wilson -Date: Tue Apr 19 14:31:40 2011 -0400 - - hid: flesh out support for tivo slide remote - - This patch finishes off adding full support for the TiVo Slide remote, - which is a mostly pure HID device from the perspective of the kernel. - There are a few mappings that use a vendor-specific usage page, and a - few keys in the consumer usage page that I think make sense to remap - slightly, to better fit their key labels' intended use. Doing this in a - stand-alone hid-tivo.c makes the modifications only matter for this - specific device. - - What's actually connected to the computer is a Broadcom-made usb dongle, - which has an embedded hub, bluetooth adapter, mouse and keyboard - devices. You pair with the dongle, then the remote sends data that its - converted into HID on the keyboard interface (the mouse interface - doesn't do anything interesting, so far as I can tell). - - lsusb for this device: - Bus 004 Device 005: ID 0a5c:2190 Broadcom Corp. - Bus 004 Device 004: ID 0a5c:4503 Broadcom Corp. - Bus 004 Device 003: ID 150a:1201 - Bus 004 Device 002: ID 0a5c:4500 Broadcom Corp. BCM2046B1 USB 2.0 Hub (part of BCM2046 Bluetooth) - - Speaking of the keyboard interface, the remote actually does contain a - keyboard as well. The top slides away, revealing a reasonably functional - qwerty keyboard (not unlike many slide cell phones), thus the product - name. - - Applies cleanly to hid master, tested w/a 2.6.38.3-based Fedora kernel - and a 2.6.32-based Red Hat Enterprise Linux 6 kernel. - - CC: Jiri Kosina - Signed-off-by: Jarod Wilson - -commit f5d27c83d8b1d1db7d727d4d33ae3df1357c0f03 -Author: Jarod Wilson -Date: Thu Mar 24 17:08:00 2011 -0400 - - rc: add an Apple remote keymap - - Signed-off-by: Jarod Wilson - -commit 9942d577525ebac939c155aaeb18e97e1282c923 -Author: Jarod Wilson -Date: Tue Apr 12 12:38:27 2011 -0400 - - [media] rc/nuvoton-cir: enable CIR on w83667hg chip variant - - Thanks to some excellent investigative work by Douglas Clowes, it was - uncovered that the older w83667hg Nuvoton chip functions with this - driver after actually enabling the CIR function via its multi-function - chip config register. The CIR and CIR wide-band sensor enable bits are - just in a different place on this hardware, so we only poke register - 0x27 on 677 hardware now, and we poke register 0x2c on the 667 now. - - Reported-by: Douglas Clowes - Signed-off-by: Jarod Wilson - -commit 92e839f5added53445aa2c447d69ea1c399e3113 -Author: Jarod Wilson -Date: Tue Apr 12 13:00:07 2011 -0400 - - [media] rc/nuvoton-cir: only warn about unknown chips - - There are additional chip IDs that report a PNP ID of NTN0530, which we - were refusing to load on. Instead, lets just warn if we encounter an - unknown chip, as there's a chance it will work just fine. - - Also, expand the list of known hardware to include both an earlier and a - later generation chip that this driver should function with. Douglas has - an older w83667hg variant, that with a touch more work, will be - supported by this driver, and Lutz has a newer w83677hg variant that - works without any further modifications to the driver. - - Reported-by: Douglas Clowes - Reported-by: Lutz Sammer - Signed-off-by: Jarod Wilson - -commit 8cc98ca72fe0a5c0a5299057edf24690c6940098 -Author: Jarod Wilson -Date: Tue Apr 5 17:42:30 2011 -0400 - - [media] rc: further key name standardization - - Use the newly introduced KEY_IMAGES where appropriate, and standardize - on KEY_MEDIA for media center/application launcher button (such as the - Windows logo key on the Windows Media Center Ed. remotes). - - Signed-off-by: Jarod Wilson - -commit 29d1ac85998862cc4cb7629461358e932363c358 -Author: Jarod Wilson -Date: Thu Mar 24 15:43:45 2011 -0400 - - lirc_sasem: key debug spew off debug modparam - - Signed-off-by: Jarod Wilson - -commit 9965e8d8e0035e56e11e1ad6c359877e51749b34 -Author: Jarod Wilson -Date: Thu Mar 24 11:56:16 2011 -0400 - - ttusb-budget: driver has a debug param, use it - - Remove DEBUG define, key debug spew off of the module's debug param that - already exists. - - Signed-off-by: Jarod Wilson - -commit 10fabf1f9cf8c1d1b579ab549bf4429ad13e0219 -Author: Jarod Wilson -Date: Thu Mar 24 11:54:41 2011 -0400 - - drx397xD: remove unused DEBUG define - - Signed-off-by: Jarod Wilson - -commit aa17ba00097df21cd0392e8aea41e93460e25007 -Author: Jarod Wilson -Date: Thu Mar 24 11:59:10 2011 -0400 - - mceusb: tivo transceiver should default to tivo keymap - - Signed-off-by: Jarod Wilson - -commit 02a5f7ed83b1da82f78b759a293cd15170afe611 -Author: Jarod Wilson -Date: Thu Mar 24 11:58:48 2011 -0400 - - rc: add tivo/nero liquidtv keymap - - Signed-off-by: Jarod Wilson - -commit db27bf543d740530ca0c1ab9fa7f3386f998e87c -Author: Jarod Wilson -Date: Mon Apr 11 17:33:28 2011 -0400 - - hid: assorted usage updates from hut 1.12 - - I've got a Tivo Slide bluetooth remote/dongle, which uses a fair number - of hid usages that aren't currently mapped in hid-input.c. I'd initially - written additions to hid-input.c with just this device in mind, - including some bits that were specific to the device. This go around, - I'm looking at adding/correcting as many generic HID usages from the HID - Usage Tables, version 1.12, as I can -- which also serves to enable all - but four of the buttons on the Tivo Slide remote[*]. - - Outside of fixing the obviously incorrect mapping of 0xc 0x45 from - KEY_RADIO to KEY_RIGHT, and making use of the new KEY_IMAGES (just added - in 2.6.39-rc4) for AL Image Browser instead of KEY_MEDIA, these are - purely additions, and thus should have no negative impact on any already - functional HID devices. Most of the added mappings seemed to be - perfectly logical to me, but there were a few that were mapped on more - of an "I think this makes the most sense" basis. - - [*] I'll handle the last four tivo buttons via an hid-tivo.c follow-up. - - CC: Dmitry Torokhov - CC: Jiri Kosina - Signed-off-by: Jarod Wilson - -commit 967bc222e57b94cf12cb4ad55383dec885f1755c -Author: Jarod Wilson -Date: Wed Apr 6 09:54:01 2011 -0400 - - input: add KEY_IMAGES specifically for AL Image Browser - - Many media center remotes have buttons intended for jumping straight to - one type of media browser or another -- commonly, images/photos/pictures, - audio/music, television, and movies. At present, remotes with an images - or photos or pictures button use any number of different keycodes which - sort of maybe fit. I've seen at least KEY_MEDIA, KEY_CAMERA, - KEY_GRAPHICSEDITOR and KEY_PRESENTATION. None of those seem quite right. - In my mind, KEY_MEDIA should be something more like a media center - application launcher (and I'd like to standardize on that for things - like the windows media center button on the mce remotes). KEY_CAMERA is - used in a lot of webcams, and typically means "take a picture now". - KEY_GRAPHICSEDITOR implies an editor, not a browser. KEY_PRESENTATION - might be the closest fit here, if you think "photo slide show", but it - may well be more intended for "run application in full-screen - presentation mode" or to launch something like magicpoint, I dunno. - And thus, I'd like to have a KEY_IMAGES, which matches the HID Usage AL - Image Browser, the meaning of which I think is crystal-clear. I believe - AL Audio Browser is already covered by KEY_AUDIO, and AL Movie Browser - by KEY_VIDEO, so I'm also adding appropriate comments next to those - keys. - - Signed-off-by: Jarod Wilson - ---- - drivers/hid/Kconfig | 6 + - drivers/hid/Makefile | 1 + - drivers/hid/hid-ids.h | 3 + - drivers/hid/hid-input.c | 60 ++++++++++-- - drivers/hid/hid-tivo.c | 89 ++++++++++++++++++ - drivers/media/dvb/dvb-usb/dibusb-common.c | 2 +- - drivers/media/dvb/dvb-usb/m920x.c | 16 ++-- - drivers/media/dvb/dvb-usb/nova-t-usb2.c | 2 +- - drivers/media/dvb/frontends/drx397xD.c | 1 - - drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | 60 ++++++------- - drivers/media/rc/keymaps/Makefile | 2 + - drivers/media/rc/keymaps/rc-apple.c | 55 +++++++++++ - drivers/media/rc/keymaps/rc-avermedia-cardbus.c | 2 +- - drivers/media/rc/keymaps/rc-imon-mce.c | 2 +- - drivers/media/rc/keymaps/rc-imon-pad.c | 6 +- - .../media/rc/keymaps/rc-kworld-plus-tv-analog.c | 2 +- - drivers/media/rc/keymaps/rc-rc6-mce.c | 4 +- - drivers/media/rc/keymaps/rc-tivo.c | 98 ++++++++++++++++++++ - drivers/media/rc/mceusb.c | 16 +++- - drivers/media/rc/nuvoton-cir.c | 62 ++++++++++--- - drivers/media/rc/nuvoton-cir.h | 17 +++- - drivers/staging/lirc/lirc_sasem.c | 13 ++- - include/linux/input.h | 5 +- - include/media/rc-map.h | 2 + - 24 files changed, 439 insertions(+), 87 deletions(-) - -diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig -index 2560f01..30a8cfd 100644 ---- a/drivers/hid/Kconfig -+++ b/drivers/hid/Kconfig -@@ -492,6 +492,12 @@ config SMARTJOYPLUS_FF - Say Y here if you have a SmartJoy PLUS PS2/USB adapter and want to - enable force feedback support for it. - -+config HID_TIVO_SLIDE -+ tristate "TiVo Slide Bluetooth remote control support" -+ depends on USB_HID -+ ---help--- -+ Say Y if you have a TiVo Slide Bluetooth remote control. -+ - config HID_TOPSEED - tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support" - depends on USB_HID -diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile -index 6efc2a0..7c1efa3 100644 ---- a/drivers/hid/Makefile -+++ b/drivers/hid/Makefile -@@ -66,6 +66,7 @@ obj-$(CONFIG_HID_STANTUM) += hid-stantum.o - obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o - obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o - obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o -+obj-$(CONFIG_HID_TIVO) += hid-tivo.o - obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o - obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o - obj-$(CONFIG_HID_UCLOGIC) += hid-uclogic.o -diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h -index 92a0d61..8ece9eb 100644 ---- a/drivers/hid/hid-ids.h -+++ b/drivers/hid/hid-ids.h -@@ -533,6 +533,9 @@ - - #define USB_VENDOR_ID_THRUSTMASTER 0x044f - -+#define USB_VENDOR_ID_TIVO 0x150a -+#define USB_DEVICE_ID_TIVO_SLIDE 0x1201 -+ - #define USB_VENDOR_ID_TOPSEED 0x0766 - #define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204 - -diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c -index 7f552bf..88d4703 100644 ---- a/drivers/hid/hid-input.c -+++ b/drivers/hid/hid-input.c -@@ -44,11 +44,11 @@ static const unsigned char hid_keyboard[256] = { - 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190, - 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113, - 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk, -- 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, -+ 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk, - unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, - unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,unk,unk,unk,unk, - unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, -- unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, -+ unk,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,unk,unk,unk,unk, - 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, - 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk - }; -@@ -365,6 +365,18 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel - case 0x1: map_key_clear(KEY_POWER); break; - case 0x2: map_key_clear(KEY_SLEEP); break; - case 0x3: map_key_clear(KEY_WAKEUP); break; -+ case 0x4: map_key_clear(KEY_CONTEXT_MENU); break; -+ case 0x5: map_key_clear(KEY_MENU); break; -+ case 0x6: map_key_clear(KEY_PROG1); break; -+ case 0x7: map_key_clear(KEY_HELP); break; -+ case 0x8: map_key_clear(KEY_EXIT); break; -+ case 0x9: map_key_clear(KEY_SELECT); break; -+ case 0xa: map_key_clear(KEY_RIGHT); break; -+ case 0xb: map_key_clear(KEY_LEFT); break; -+ case 0xc: map_key_clear(KEY_UP); break; -+ case 0xd: map_key_clear(KEY_DOWN); break; -+ case 0xe: map_key_clear(KEY_POWER2); break; -+ case 0xf: map_key_clear(KEY_RESTART); break; - default: goto unknown; - } - break; -@@ -474,16 +486,39 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel - } - break; - -- case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */ -+ case HID_UP_CONSUMER: /* USB HUT v1.12, pages 75-84 */ - switch (usage->hid & HID_USAGE) { - case 0x000: goto ignore; -+ case 0x030: map_key_clear(KEY_POWER); break; -+ case 0x031: map_key_clear(KEY_RESTART); break; -+ case 0x032: map_key_clear(KEY_SLEEP); break; - case 0x034: map_key_clear(KEY_SLEEP); break; -+ case 0x035: map_key_clear(KEY_KBDILLUMTOGGLE); break; - case 0x036: map_key_clear(BTN_MISC); break; - -- case 0x040: map_key_clear(KEY_MENU); break; -- case 0x045: map_key_clear(KEY_RADIO); break; -- -+ case 0x040: map_key_clear(KEY_MENU); break; /* Menu */ -+ case 0x041: map_key_clear(KEY_SELECT); break; /* Menu Pick */ -+ case 0x042: map_key_clear(KEY_UP); break; /* Menu Up */ -+ case 0x043: map_key_clear(KEY_DOWN); break; /* Menu Down */ -+ case 0x044: map_key_clear(KEY_LEFT); break; /* Menu Left */ -+ case 0x045: map_key_clear(KEY_RIGHT); break; /* Menu Right */ -+ case 0x046: map_key_clear(KEY_ESC); break; /* Menu Escape */ -+ case 0x047: map_key_clear(KEY_KPPLUS); break; /* Menu Value Increase */ -+ case 0x048: map_key_clear(KEY_KPMINUS); break; /* Menu Value Decrease */ -+ -+ case 0x060: map_key_clear(KEY_INFO); break; /* Data On Screen */ -+ case 0x061: map_key_clear(KEY_SUBTITLE); break; /* Closed Caption */ -+ case 0x063: map_key_clear(KEY_VCR); break; /* VCR/TV */ -+ case 0x065: map_key_clear(KEY_CAMERA); break; /* Snapshot */ -+ case 0x069: map_key_clear(KEY_RED); break; -+ case 0x06a: map_key_clear(KEY_GREEN); break; -+ case 0x06b: map_key_clear(KEY_BLUE); break; -+ case 0x06c: map_key_clear(KEY_YELLOW); break; -+ case 0x06d: map_key_clear(KEY_ZOOM); break; -+ -+ case 0x082: map_key_clear(KEY_VIDEO_NEXT); break; - case 0x083: map_key_clear(KEY_LAST); break; -+ case 0x084: map_key_clear(KEY_ENTER); break; - case 0x088: map_key_clear(KEY_PC); break; - case 0x089: map_key_clear(KEY_TV); break; - case 0x08a: map_key_clear(KEY_WWW); break; -@@ -517,6 +552,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel - case 0x0b7: map_key_clear(KEY_STOPCD); break; - case 0x0b8: map_key_clear(KEY_EJECTCD); break; - case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT); break; -+ case 0x0b9: map_key_clear(KEY_SHUFFLE); break; -+ case 0x0bf: map_key_clear(KEY_SLOW); break; - - case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; - case 0x0e0: map_abs_clear(ABS_VOLUME); break; -@@ -524,6 +561,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel - case 0x0e5: map_key_clear(KEY_BASSBOOST); break; - case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; - case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; -+ case 0x0f5: map_key_clear(KEY_SLOW); break; - - case 0x182: map_key_clear(KEY_BOOKMARKS); break; - case 0x183: map_key_clear(KEY_CONFIG); break; -@@ -540,6 +578,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel - case 0x18e: map_key_clear(KEY_CALENDAR); break; - case 0x191: map_key_clear(KEY_FINANCE); break; - case 0x192: map_key_clear(KEY_CALC); break; -+ case 0x193: map_key_clear(KEY_PLAYER); break; - case 0x194: map_key_clear(KEY_FILE); break; - case 0x196: map_key_clear(KEY_WWW); break; - case 0x199: map_key_clear(KEY_CHAT); break; -@@ -548,8 +587,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel - case 0x1a6: map_key_clear(KEY_HELP); break; - case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; - case 0x1ab: map_key_clear(KEY_SPELLCHECK); break; -- case 0x1b6: map_key_clear(KEY_MEDIA); break; -- case 0x1b7: map_key_clear(KEY_SOUND); break; -+ case 0x1ae: map_key_clear(KEY_KEYBOARD); break; -+ case 0x1b6: map_key_clear(KEY_IMAGES); break; -+ case 0x1b7: map_key_clear(KEY_AUDIO); break; -+ case 0x1b8: map_key_clear(KEY_VIDEO); break; - case 0x1bc: map_key_clear(KEY_MESSENGER); break; - case 0x1bd: map_key_clear(KEY_INFO); break; - case 0x201: map_key_clear(KEY_NEW); break; -@@ -578,7 +619,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel - case 0x233: map_key_clear(KEY_SCROLLUP); break; - case 0x234: map_key_clear(KEY_SCROLLDOWN); break; - case 0x238: map_rel(REL_HWHEEL); break; -+ case 0x23d: map_key_clear(KEY_EDIT); break; - case 0x25f: map_key_clear(KEY_CANCEL); break; -+ case 0x269: map_key_clear(KEY_INSERT); break; -+ case 0x26a: map_key_clear(KEY_DELETE); break; - case 0x279: map_key_clear(KEY_REDO); break; - - case 0x289: map_key_clear(KEY_REPLY); break; -diff --git a/drivers/hid/hid-tivo.c b/drivers/hid/hid-tivo.c -new file mode 100644 -index 0000000..3d43c06 ---- /dev/null -+++ b/drivers/hid/hid-tivo.c -@@ -0,0 +1,89 @@ -+/* -+ * HID driver for TiVo Slide Bluetooth remote -+ * -+ * Copyright (c) 2011 Jarod Wilson -+ * based on the hid-topseed driver, which is in turn, based on hid-cherry... -+ */ -+ -+/* -+ * 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; either version 2 of the License, or (at your option) -+ * any later version. -+ */ -+ -+#include -+#include -+#include -+ -+#include "hid-ids.h" -+ -+#define HID_UP_TIVOVENDOR 0xffff0000 -+#define tivo_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ -+ EV_KEY, (c)) -+ -+static int tivo_input_mapping(struct hid_device *hdev, struct hid_input *hi, -+ struct hid_field *field, struct hid_usage *usage, -+ unsigned long **bit, int *max) -+{ -+ switch (usage->hid & HID_USAGE_PAGE) { -+ case HID_UP_TIVOVENDOR: -+ switch (usage->hid & HID_USAGE) { -+ /* TiVo button */ -+ case 0x3d: tivo_map_key_clear(KEY_MEDIA); break; -+ /* Live TV */ -+ case 0x3e: tivo_map_key_clear(KEY_TV); break; -+ /* Red thumbs down */ -+ case 0x41: tivo_map_key_clear(KEY_KPMINUS); break; -+ /* Green thumbs up */ -+ case 0x42: tivo_map_key_clear(KEY_KPPLUS); break; -+ default: -+ return 0; -+ } -+ break; -+ case HID_UP_CONSUMER: -+ switch (usage->hid & HID_USAGE) { -+ /* Enter/Last (default mapping: KEY_LAST) */ -+ case 0x083: tivo_map_key_clear(KEY_ENTER); break; -+ /* Info (default mapping: KEY_PROPS) */ -+ case 0x209: tivo_map_key_clear(KEY_INFO); break; -+ default: -+ return 0; -+ } -+ break; -+ default: -+ return 0; -+ } -+ -+ /* This means we found a matching mapping here, else, look in the -+ * standard hid mappings in hid-input.c */ -+ return 1; -+} -+ -+static const struct hid_device_id tivo_devices[] = { -+ /* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */ -+ { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) }, -+ { } -+}; -+MODULE_DEVICE_TABLE(hid, tivo_devices); -+ -+static struct hid_driver tivo_driver = { -+ .name = "tivo_slide", -+ .id_table = tivo_devices, -+ .input_mapping = tivo_input_mapping, -+}; -+ -+static int __init tivo_init(void) -+{ -+ return hid_register_driver(&tivo_driver); -+} -+ -+static void __exit tivo_exit(void) -+{ -+ hid_unregister_driver(&tivo_driver); -+} -+ -+module_init(tivo_init); -+module_exit(tivo_exit); -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jarod Wilson "); -diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c -index 956f7ae..4c2a689 100644 ---- a/drivers/media/dvb/dvb-usb/dibusb-common.c -+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c -@@ -408,7 +408,7 @@ struct rc_map_table rc_map_dibusb_table[] = { - - { 0x8008, KEY_DVD }, - { 0x8009, KEY_AUDIO }, -- { 0x800a, KEY_MEDIA }, /* Pictures */ -+ { 0x800a, KEY_IMAGES }, /* Pictures */ - { 0x800b, KEY_VIDEO }, - - { 0x800c, KEY_BACK }, -diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c -index da9dc91..51bfd42 100644 ---- a/drivers/media/dvb/dvb-usb/m920x.c -+++ b/drivers/media/dvb/dvb-usb/m920x.c -@@ -632,9 +632,9 @@ static struct rc_map_table rc_map_pinnacle310e_table[] = { - { 0x16, KEY_POWER }, - { 0x17, KEY_FAVORITES }, - { 0x0f, KEY_TEXT }, -- { 0x48, KEY_MEDIA }, /* preview */ -+ { 0x48, KEY_PROGRAM }, /* preview */ - { 0x1c, KEY_EPG }, -- { 0x04, KEY_LIST }, /* record list */ -+ { 0x04, KEY_LIST }, /* record list */ - { 0x03, KEY_1 }, - { 0x01, KEY_2 }, - { 0x06, KEY_3 }, -@@ -674,14 +674,14 @@ static struct rc_map_table rc_map_pinnacle310e_table[] = { - { 0x0e, KEY_MUTE }, - /* { 0x49, KEY_LR }, */ /* L/R */ - { 0x07, KEY_SLEEP }, /* Hibernate */ -- { 0x08, KEY_MEDIA }, /* A/V */ -- { 0x0e, KEY_MENU }, /* Recall */ -+ { 0x08, KEY_VIDEO }, /* A/V */ -+ { 0x0e, KEY_MENU }, /* Recall */ - { 0x45, KEY_ZOOMIN }, - { 0x46, KEY_ZOOMOUT }, -- { 0x18, KEY_TV }, /* Red */ -- { 0x53, KEY_VCR }, /* Green */ -- { 0x5e, KEY_SAT }, /* Yellow */ -- { 0x5f, KEY_PLAYER }, /* Blue */ -+ { 0x18, KEY_RED }, /* Red */ -+ { 0x53, KEY_GREEN }, /* Green */ -+ { 0x5e, KEY_YELLOW }, /* Yellow */ -+ { 0x5f, KEY_BLUE }, /* Blue */ - }; - - /* DVB USB Driver stuff */ -diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c -index 9d3cd2d..bc350e9 100644 ---- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c -+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c -@@ -47,7 +47,7 @@ static struct rc_map_table rc_map_haupp_table[] = { - { 0x1e17, KEY_RIGHT }, - { 0x1e18, KEY_VIDEO }, - { 0x1e19, KEY_AUDIO }, -- { 0x1e1a, KEY_MEDIA }, -+ { 0x1e1a, KEY_IMAGES }, - { 0x1e1b, KEY_EPG }, - { 0x1e1c, KEY_TV }, - { 0x1e1e, KEY_NEXT }, -diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c -index a05007c..235ac72 100644 ---- a/drivers/media/dvb/frontends/drx397xD.c -+++ b/drivers/media/dvb/frontends/drx397xD.c -@@ -17,7 +17,6 @@ - * along with this program; If not, see . - */ - --#define DEBUG /* uncomment if you want debugging output */ - #include - #include - #include -diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c -index cbe2f0d..420bb42 100644 ---- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c -+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c -@@ -52,7 +52,7 @@ - my TTUSB, so let it undef'd unless you want to implement another - frontend. never tested. - -- DEBUG: -+ debug: - define it to > 3 for really hardcore debugging. you probably don't want - this unless the device doesn't load at all. > 2 for bandwidth statistics. - */ -@@ -134,20 +134,19 @@ struct ttusb { - /* ugly workaround ... don't know why it's necessary to read */ - /* all result codes. */ - --#define DEBUG 0 - static int ttusb_cmd(struct ttusb *ttusb, - const u8 * data, int len, int needresult) - { - int actual_len; - int err; --#if DEBUG >= 3 - int i; - -- printk(">"); -- for (i = 0; i < len; ++i) -- printk(" %02x", data[i]); -- printk("\n"); --#endif -+ if (debug >= 3) { -+ printk(KERN_DEBUG ">"); -+ for (i = 0; i < len; ++i) -+ printk(KERN_CONT " %02x", data[i]); -+ printk(KERN_CONT "\n"); -+ } - - if (mutex_lock_interruptible(&ttusb->semusb) < 0) - return -EAGAIN; -@@ -176,13 +175,15 @@ static int ttusb_cmd(struct ttusb *ttusb, - mutex_unlock(&ttusb->semusb); - return err; - } --#if DEBUG >= 3 -- actual_len = ttusb->last_result[3] + 4; -- printk("<"); -- for (i = 0; i < actual_len; ++i) -- printk(" %02x", ttusb->last_result[i]); -- printk("\n"); --#endif -+ -+ if (debug >= 3) { -+ actual_len = ttusb->last_result[3] + 4; -+ printk(KERN_DEBUG "<"); -+ for (i = 0; i < actual_len; ++i) -+ printk(KERN_CONT " %02x", ttusb->last_result[i]); -+ printk(KERN_CONT "\n"); -+ } -+ - if (!needresult) - mutex_unlock(&ttusb->semusb); - return 0; -@@ -636,16 +637,13 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len) - ++ttusb->mux_state; - else { - ttusb->mux_state = 0; --#if DEBUG > 3 -- if (ttusb->insync) -- printk("%02x ", data[-1]); --#else - if (ttusb->insync) { -- printk("%s: lost sync.\n", -+ dprintk("%s: %02x\n", -+ __func__, data[-1]); -+ printk(KERN_INFO "%s: lost sync.\n", - __func__); - ttusb->insync = 0; - } --#endif - } - break; - case 3: -@@ -744,6 +742,9 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len) - static void ttusb_iso_irq(struct urb *urb) - { - struct ttusb *ttusb = urb->context; -+ struct usb_iso_packet_descriptor *d; -+ u8 *data; -+ int len, i; - - if (!ttusb->iso_streaming) - return; -@@ -755,21 +756,14 @@ static void ttusb_iso_irq(struct urb *urb) - #endif - - if (!urb->status) { -- int i; - for (i = 0; i < urb->number_of_packets; ++i) { -- struct usb_iso_packet_descriptor *d; -- u8 *data; -- int len; - numpkt++; - if (time_after_eq(jiffies, lastj + HZ)) { --#if DEBUG > 2 -- printk -- ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n", -- numpkt * HZ / (jiffies - lastj), -- numts, numstuff, numsec, numinvalid, -- numts + numstuff + numsec + -- numinvalid); --#endif -+ dprintk("frames/s: %lu (ts: %d, stuff %d, " -+ "sec: %d, invalid: %d, all: %d)\n", -+ numpkt * HZ / (jiffies - lastj), -+ numts, numstuff, numsec, numinvalid, -+ numts + numstuff + numsec + numinvalid); - numts = numstuff = numsec = numinvalid = 0; - lastj = jiffies; - numpkt = 0; -diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile -index 85cac7d..8c0cb70 100644 ---- a/drivers/media/rc/keymaps/Makefile -+++ b/drivers/media/rc/keymaps/Makefile -@@ -2,6 +2,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ - rc-alink-dtu-m.o \ - rc-anysee.o \ - rc-apac-viewcomp.o \ -+ rc-apple.o \ - rc-asus-pc39.o \ - rc-ati-tv-wonder-hd-600.o \ - rc-avermedia-a16d.o \ -@@ -77,6 +78,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ - rc-terratec-cinergy-xs.o \ - rc-terratec-slim.o \ - rc-tevii-nec.o \ -+ rc-tivo.o \ - rc-total-media-in-hand.o \ - rc-trekstor.o \ - rc-tt-1500.o \ -diff --git a/drivers/media/rc/keymaps/rc-apple.c b/drivers/media/rc/keymaps/rc-apple.c -new file mode 100644 -index 0000000..9fff474 ---- /dev/null -+++ b/drivers/media/rc/keymaps/rc-apple.c -@@ -0,0 +1,55 @@ -+/* rc-apple.c - Keytable for Apple remotes -+ * -+ * Copyright (c) 2011 by Jarod Wilson -+ * -+ * 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; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+#include -+ -+/* -+ * The Apple remotes use an NEC-ish protocol, but instead of having a -+ * command/not_command pair, they use a vendor ID of 0x77e1. Another byte -+ * is used for a pairing ID (0-255), to make it possible to have a system -+ * listen for only its specific remote. The last byte is the actual command -+ * byte. This table will only Just Work(tm) with remotes that have their -+ * pairing byte set to 0xc7 at the moment (one of my Apple remotes), but -+ * it can be trivially replaced from userspace with one using a different -+ * pairing byte value. -+ */ -+static struct rc_map_table apple[] = { -+ { 0x77e150c7, KEY_VOLUMEUP }, -+ { 0x77e130c7, KEY_VOLUMEDOWN }, -+ { 0x77e190c7, KEY_REWIND }, -+ { 0x77e160c7, KEY_FASTFORWARD }, -+ { 0x77e1a0c7, KEY_PLAYPAUSE }, -+ { 0x77e1c0c7, KEY_MENU }, -+}; -+ -+static struct rc_map_list apple_map = { -+ .map = { -+ .scan = apple, -+ .size = ARRAY_SIZE(apple), -+ .rc_type = RC_TYPE_NEC, -+ .name = RC_MAP_APPLE, -+ } -+}; -+ -+static int __init init_rc_map_apple(void) -+{ -+ return rc_map_register(&apple_map); -+} -+ -+static void __exit exit_rc_map_apple(void) -+{ -+ rc_map_unregister(&apple_map); -+} -+ -+module_init(init_rc_map_apple) -+module_exit(exit_rc_map_apple) -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jarod Wilson "); -diff --git a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c -index bdf97b7..22f54d4 100644 ---- a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c -+++ b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c -@@ -52,7 +52,7 @@ static struct rc_map_table avermedia_cardbus[] = { - { 0x28, KEY_SELECT }, /* Select */ - { 0x29, KEY_BLUE }, /* Blue/Picture */ - { 0x2a, KEY_BACKSPACE }, /* Back */ -- { 0x2b, KEY_MEDIA }, /* PIP (Picture-in-picture) */ -+ { 0x2b, KEY_VIDEO }, /* PIP (Picture-in-picture) */ - { 0x2c, KEY_DOWN }, - { 0x2e, KEY_DOT }, - { 0x2f, KEY_TV }, /* Live TV */ -diff --git a/drivers/media/rc/keymaps/rc-imon-mce.c b/drivers/media/rc/keymaps/rc-imon-mce.c -index 937a819..0ea2aa1 100644 ---- a/drivers/media/rc/keymaps/rc-imon-mce.c -+++ b/drivers/media/rc/keymaps/rc-imon-mce.c -@@ -111,7 +111,7 @@ static struct rc_map_table imon_mce[] = { - { 0x800ff44d, KEY_TITLE }, - - { 0x800ff40c, KEY_POWER }, -- { 0x800ff40d, KEY_LEFTMETA }, /* Windows MCE button */ -+ { 0x800ff40d, KEY_MEDIA }, /* Windows MCE button */ - - }; - -diff --git a/drivers/media/rc/keymaps/rc-imon-pad.c b/drivers/media/rc/keymaps/rc-imon-pad.c -index 63d42bd..75d3843 100644 ---- a/drivers/media/rc/keymaps/rc-imon-pad.c -+++ b/drivers/media/rc/keymaps/rc-imon-pad.c -@@ -87,7 +87,7 @@ static struct rc_map_table imon_pad[] = { - - { 0x2b8515b7, KEY_VIDEO }, - { 0x299195b7, KEY_AUDIO }, -- { 0x2ba115b7, KEY_CAMERA }, -+ { 0x2ba115b7, KEY_IMAGES }, - { 0x28a515b7, KEY_TV }, - { 0x29a395b7, KEY_DVD }, - { 0x29a295b7, KEY_DVD }, -@@ -97,7 +97,7 @@ static struct rc_map_table imon_pad[] = { - { 0x2ba395b7, KEY_MENU }, - - { 0x288515b7, KEY_BOOKMARKS }, -- { 0x2ab715b7, KEY_MEDIA }, /* Thumbnail */ -+ { 0x2ab715b7, KEY_CAMERA }, /* Thumbnail */ - { 0x298595b7, KEY_SUBTITLE }, - { 0x2b8595b7, KEY_LANGUAGE }, - -@@ -125,7 +125,7 @@ static struct rc_map_table imon_pad[] = { - { 0x2b8195b7, KEY_CONTEXT_MENU }, /* Left Menu*/ - { 0x02000065, KEY_COMPOSE }, /* RightMenu */ - { 0x28b715b7, KEY_COMPOSE }, /* RightMenu */ -- { 0x2ab195b7, KEY_LEFTMETA }, /* Go or MultiMon */ -+ { 0x2ab195b7, KEY_MEDIA }, /* Go or MultiMon */ - { 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */ - }; - -diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c -index 08d1831..7fa17a3 100644 ---- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c -+++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c -@@ -17,7 +17,7 @@ - */ - - static struct rc_map_table kworld_plus_tv_analog[] = { -- { 0x0c, KEY_LEFTMETA }, /* Kworld key */ -+ { 0x0c, KEY_MEDIA }, /* Kworld key */ - { 0x16, KEY_CLOSECD }, /* -> ) */ - { 0x1d, KEY_POWER2 }, - -diff --git a/drivers/media/rc/keymaps/rc-rc6-mce.c b/drivers/media/rc/keymaps/rc-rc6-mce.c -index 8dd519e..01b69bc 100644 ---- a/drivers/media/rc/keymaps/rc-rc6-mce.c -+++ b/drivers/media/rc/keymaps/rc-rc6-mce.c -@@ -30,7 +30,7 @@ static struct rc_map_table rc6_mce[] = { - { 0x800f040a, KEY_DELETE }, - { 0x800f040b, KEY_ENTER }, - { 0x800f040c, KEY_POWER }, /* PC Power */ -- { 0x800f040d, KEY_LEFTMETA }, /* Windows MCE button */ -+ { 0x800f040d, KEY_MEDIA }, /* Windows MCE button */ - { 0x800f040e, KEY_MUTE }, - { 0x800f040f, KEY_INFO }, - -@@ -87,7 +87,7 @@ static struct rc_map_table rc6_mce[] = { - - { 0x800f0465, KEY_POWER2 }, /* TV Power */ - { 0x800f046e, KEY_PLAYPAUSE }, -- { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */ -+ { 0x800f046f, KEY_PLAYER }, /* Start media application (NEW) */ - - { 0x800f0480, KEY_BRIGHTNESSDOWN }, - { 0x800f0481, KEY_PLAYPAUSE }, -diff --git a/drivers/media/rc/keymaps/rc-tivo.c b/drivers/media/rc/keymaps/rc-tivo.c -new file mode 100644 -index 0000000..98ad085 ---- /dev/null -+++ b/drivers/media/rc/keymaps/rc-tivo.c -@@ -0,0 +1,98 @@ -+/* rc-tivo.c - Keytable for TiVo remotes -+ * -+ * Copyright (c) 2011 by Jarod Wilson -+ * -+ * 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; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+#include -+ -+/* -+ * Initial mapping is for the TiVo remote included in the Nero LiquidTV bundle, -+ * which also ships with a TiVo-branded IR transceiver, supported by the mceusb -+ * driver. Note that the remote uses an NEC-ish protocol, but instead of having -+ * a command/not_command pair, it has a vendor ID of 0xa10c, but some keys, the -+ * NEC extended checksums do pass, so the table presently has the intended -+ * values and the checksum-passed versions for those keys. -+ */ -+static struct rc_map_table tivo[] = { -+ { 0xa10c900f, KEY_MEDIA }, /* TiVo Button */ -+ { 0xa10c0807, KEY_POWER2 }, /* TV Power */ -+ { 0xa10c8807, KEY_TV }, /* Live TV/Swap */ -+ { 0xa10c2c03, KEY_VIDEO_NEXT }, /* TV Input */ -+ { 0xa10cc807, KEY_INFO }, -+ { 0xa10cfa05, KEY_CYCLEWINDOWS }, /* Window */ -+ { 0x0085305f, KEY_CYCLEWINDOWS }, -+ { 0xa10c6c03, KEY_EPG }, /* Guide */ -+ -+ { 0xa10c2807, KEY_UP }, -+ { 0xa10c6807, KEY_DOWN }, -+ { 0xa10ce807, KEY_LEFT }, -+ { 0xa10ca807, KEY_RIGHT }, -+ -+ { 0xa10c1807, KEY_SCROLLDOWN }, /* Red Thumbs Down */ -+ { 0xa10c9807, KEY_SELECT }, -+ { 0xa10c5807, KEY_SCROLLUP }, /* Green Thumbs Up */ -+ -+ { 0xa10c3807, KEY_VOLUMEUP }, -+ { 0xa10cb807, KEY_VOLUMEDOWN }, -+ { 0xa10cd807, KEY_MUTE }, -+ { 0xa10c040b, KEY_RECORD }, -+ { 0xa10c7807, KEY_CHANNELUP }, -+ { 0xa10cf807, KEY_CHANNELDOWN }, -+ { 0x0085301f, KEY_CHANNELDOWN }, -+ -+ { 0xa10c840b, KEY_PLAY }, -+ { 0xa10cc40b, KEY_PAUSE }, -+ { 0xa10ca40b, KEY_SLOW }, -+ { 0xa10c440b, KEY_REWIND }, -+ { 0xa10c240b, KEY_FASTFORWARD }, -+ { 0xa10c640b, KEY_PREVIOUS }, -+ { 0xa10ce40b, KEY_NEXT }, /* ->| */ -+ -+ { 0xa10c220d, KEY_ZOOM }, /* Aspect */ -+ { 0xa10c120d, KEY_STOP }, -+ { 0xa10c520d, KEY_DVD }, /* DVD Menu */ -+ -+ { 0xa10c140b, KEY_NUMERIC_1 }, -+ { 0xa10c940b, KEY_NUMERIC_2 }, -+ { 0xa10c540b, KEY_NUMERIC_3 }, -+ { 0xa10cd40b, KEY_NUMERIC_4 }, -+ { 0xa10c340b, KEY_NUMERIC_5 }, -+ { 0xa10cb40b, KEY_NUMERIC_6 }, -+ { 0xa10c740b, KEY_NUMERIC_7 }, -+ { 0xa10cf40b, KEY_NUMERIC_8 }, -+ { 0x0085302f, KEY_NUMERIC_8 }, -+ { 0xa10c0c03, KEY_NUMERIC_9 }, -+ { 0xa10c8c03, KEY_NUMERIC_0 }, -+ { 0xa10ccc03, KEY_ENTER }, -+ { 0xa10c4c03, KEY_CLEAR }, -+}; -+ -+static struct rc_map_list tivo_map = { -+ .map = { -+ .scan = tivo, -+ .size = ARRAY_SIZE(tivo), -+ .rc_type = RC_TYPE_NEC, -+ .name = RC_MAP_TIVO, -+ } -+}; -+ -+static int __init init_rc_map_tivo(void) -+{ -+ return rc_map_register(&tivo_map); -+} -+ -+static void __exit exit_rc_map_tivo(void) -+{ -+ rc_map_unregister(&tivo_map); -+} -+ -+module_init(init_rc_map_tivo) -+module_exit(exit_rc_map_tivo) -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jarod Wilson "); -diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c -index 044fb7a..47a1c5d 100644 ---- a/drivers/media/rc/mceusb.c -+++ b/drivers/media/rc/mceusb.c -@@ -149,6 +149,8 @@ enum mceusb_model_type { - POLARIS_EVK, - CX_HYBRID_TV, - MULTIFUNCTION, -+ TIVO_KIT, -+ MCE_GEN2_NO_TX, - }; - - struct mceusb_model { -@@ -172,6 +174,10 @@ static const struct mceusb_model mceusb_model[] = { - [MCE_GEN2] = { - .mce_gen2 = 1, - }, -+ [MCE_GEN2_NO_TX] = { -+ .mce_gen2 = 1, -+ .no_tx = 1, -+ }, - [MCE_GEN2_TX_INV] = { - .mce_gen2 = 1, - .tx_mask_normal = 1, -@@ -197,6 +203,10 @@ static const struct mceusb_model mceusb_model[] = { - .mce_gen2 = 1, - .ir_intfnum = 2, - }, -+ [TIVO_KIT] = { -+ .mce_gen2 = 1, -+ .rc_map = RC_MAP_TIVO, -+ }, - }; - - static struct usb_device_id mceusb_dev_table[] = { -@@ -230,6 +230,8 @@ static struct usb_device_id mceusb_dev_table[] = { - { USB_DEVICE(VENDOR_PHILIPS, 0x206c) }, - /* Philips/Spinel plus IR transceiver for ASUS */ - { USB_DEVICE(VENDOR_PHILIPS, 0x2088) }, -+ /* Philips IR transceiver (Dell branded) */ -+ { USB_DEVICE(VENDOR_PHILIPS, 0x2093) }, - /* Realtek MCE IR Receiver and card reader */ - { USB_DEVICE(VENDOR_REALTEK, 0x0161), - .driver_info = MULTIFUNCTION }, -@@ -279,7 +289,8 @@ static struct usb_device_id mceusb_dev_table[] = { - /* Formosa21 / eHome Infrared Receiver */ - { USB_DEVICE(VENDOR_FORMOSA, 0xe016) }, - /* Formosa aim / Trust MCE Infrared Receiver */ -- { USB_DEVICE(VENDOR_FORMOSA, 0xe017) }, -+ { USB_DEVICE(VENDOR_FORMOSA, 0xe017), -+ .driver_info = MCE_GEN2_NO_TX }, - /* Formosa Industrial Computing / Beanbag Emulation Device */ - { USB_DEVICE(VENDOR_FORMOSA, 0xe018) }, - /* Formosa21 / eHome Infrared Receiver */ -@@ -308,7 +319,8 @@ static struct usb_device_id mceusb_dev_table[] = { - /* Northstar Systems, Inc. eHome Infrared Transceiver */ - { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) }, - /* TiVo PC IR Receiver */ -- { USB_DEVICE(VENDOR_TIVO, 0x2000) }, -+ { USB_DEVICE(VENDOR_TIVO, 0x2000), -+ .driver_info = TIVO_KIT }, - /* Conexant Hybrid TV "Shelby" Polaris SDK */ - { USB_DEVICE(VENDOR_CONEXANT, 0x58a1), - .driver_info = POLARIS_EVK }, -diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c -index d4d6449..5d93384 100644 ---- a/drivers/media/rc/nuvoton-cir.c -+++ b/drivers/media/rc/nuvoton-cir.c -@@ -37,8 +37,6 @@ - - #include "nuvoton-cir.h" - --static char *chip_id = "w836x7hg"; -- - /* write val to config reg */ - static inline void nvt_cr_write(struct nvt_dev *nvt, u8 val, u8 reg) - { -@@ -233,6 +231,8 @@ static int nvt_hw_detect(struct nvt_dev *nvt) - unsigned long flags; - u8 chip_major, chip_minor; - int ret = 0; -+ char chip_id[12]; -+ bool chip_unknown = false; - - nvt_efm_enable(nvt); - -@@ -246,15 +246,39 @@ static int nvt_hw_detect(struct nvt_dev *nvt) - } - - chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO); -- nvt_dbg("%s: chip id: 0x%02x 0x%02x", chip_id, chip_major, chip_minor); - -- if (chip_major != CHIP_ID_HIGH || -- (chip_minor != CHIP_ID_LOW && chip_minor != CHIP_ID_LOW2)) { -- nvt_pr(KERN_ERR, "%s: unsupported chip, id: 0x%02x 0x%02x", -- chip_id, chip_major, chip_minor); -- ret = -ENODEV; -+ /* these are the known working chip revisions... */ -+ switch (chip_major) { -+ case CHIP_ID_HIGH_667: -+ strcpy(chip_id, "w83667hg\0"); -+ if (chip_minor != CHIP_ID_LOW_667) -+ chip_unknown = true; -+ break; -+ case CHIP_ID_HIGH_677B: -+ strcpy(chip_id, "w83677hg\0"); -+ if (chip_minor != CHIP_ID_LOW_677B2 && -+ chip_minor != CHIP_ID_LOW_677B3) -+ chip_unknown = true; -+ break; -+ case CHIP_ID_HIGH_677C: -+ strcpy(chip_id, "w83677hg-c\0"); -+ if (chip_minor != CHIP_ID_LOW_677C) -+ chip_unknown = true; -+ break; -+ default: -+ strcpy(chip_id, "w836x7hg\0"); -+ chip_unknown = true; -+ break; - } - -+ /* warn, but still let the driver load, if we don't know this chip */ -+ if (chip_unknown) -+ nvt_pr(KERN_WARNING, "%s: unknown chip, id: 0x%02x 0x%02x, " -+ "it may not work...", chip_id, chip_major, chip_minor); -+ else -+ nvt_dbg("%s: chip id: 0x%02x 0x%02x", -+ chip_id, chip_major, chip_minor); -+ - nvt_efm_disable(nvt); - - spin_lock_irqsave(&nvt->nvt_lock, flags); -@@ -267,13 +291,23 @@ static int nvt_hw_detect(struct nvt_dev *nvt) - - static void nvt_cir_ldev_init(struct nvt_dev *nvt) - { -- u8 val; -+ u8 val, psreg, psmask, psval; -+ -+ if (nvt->chip_major == CHIP_ID_HIGH_667) { -+ psreg = CR_MULTIFUNC_PIN_SEL; -+ psmask = MULTIFUNC_PIN_SEL_MASK; -+ psval = MULTIFUNC_ENABLE_CIR | MULTIFUNC_ENABLE_CIRWB; -+ } else { -+ psreg = CR_OUTPUT_PIN_SEL; -+ psmask = OUTPUT_PIN_SEL_MASK; -+ psval = OUTPUT_ENABLE_CIR | OUTPUT_ENABLE_CIRWB; -+ } - -- /* output pin selection (Pin95=CIRRX, Pin96=CIRTX1, WB enabled */ -- val = nvt_cr_read(nvt, CR_OUTPUT_PIN_SEL); -- val &= OUTPUT_PIN_SEL_MASK; -- val |= (OUTPUT_ENABLE_CIR | OUTPUT_ENABLE_CIRWB); -- nvt_cr_write(nvt, val, CR_OUTPUT_PIN_SEL); -+ /* output pin selection: enable CIR, with WB sensor enabled */ -+ val = nvt_cr_read(nvt, psreg); -+ val &= psmask; -+ val |= psval; -+ nvt_cr_write(nvt, val, psreg); - - /* Select CIR logical device and enable */ - nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); -@@ -674,7 +674,7 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) - rawir.pulse ? "pulse" : "space", - rawir.duration); - -- ir_raw_event_store(nvt->rdev, &rawir); -+ ir_raw_event_store_with_filter(nvt->rdev, &rawir); - } - - /* -@@ -1110,12 +1110,12 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) - rdev->input_id.version = nvt->chip_minor; - rdev->driver_name = NVT_DRIVER_NAME; - rdev->map_name = RC_MAP_RC6_MCE; -+ rdev->timeout = US_TO_NS(1000); -+ /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ -+ rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD); - #if 0 - rdev->min_timeout = XYZ; - rdev->max_timeout = XYZ; -- rdev->timeout = XYZ; -- /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ -- rdev->rx_resolution = XYZ; - /* tx bits */ - rdev->tx_resolution = XYZ; - #endif -diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h -index 048135e..379795d 100644 ---- a/drivers/media/rc/nuvoton-cir.h -+++ b/drivers/media/rc/nuvoton-cir.h -@@ -330,9 +330,13 @@ struct nvt_dev { - #define EFER_EFM_DISABLE 0xaa - - /* Chip IDs found in CR_CHIP_ID_{HI,LO} */ --#define CHIP_ID_HIGH 0xb4 --#define CHIP_ID_LOW 0x72 --#define CHIP_ID_LOW2 0x73 -+#define CHIP_ID_HIGH_667 0xa5 -+#define CHIP_ID_HIGH_677B 0xb4 -+#define CHIP_ID_HIGH_677C 0xc3 -+#define CHIP_ID_LOW_667 0x13 -+#define CHIP_ID_LOW_677B2 0x72 -+#define CHIP_ID_LOW_677B3 0x73 -+#define CHIP_ID_LOW_677C 0x33 - - /* Config regs we need to care about */ - #define CR_SOFTWARE_RESET 0x02 -@@ -341,6 +345,7 @@ struct nvt_dev { - #define CR_CHIP_ID_LO 0x21 - #define CR_DEV_POWER_DOWN 0x22 /* bit 2 is CIR power, default power on */ - #define CR_OUTPUT_PIN_SEL 0x27 -+#define CR_MULTIFUNC_PIN_SEL 0x2c - #define CR_LOGICAL_DEV_EN 0x30 /* valid for all logical devices */ - /* next three regs valid for both the CIR and CIR_WAKE logical devices */ - #define CR_CIR_BASE_ADDR_HI 0x60 -@@ -364,10 +369,16 @@ struct nvt_dev { - #define CIR_INTR_MOUSE_IRQ_BIT 0x80 - #define PME_INTR_CIR_PASS_BIT 0x08 - -+/* w83677hg CIR pin config */ - #define OUTPUT_PIN_SEL_MASK 0xbc - #define OUTPUT_ENABLE_CIR 0x01 /* Pin95=CIRRX, Pin96=CIRTX1 */ - #define OUTPUT_ENABLE_CIRWB 0x40 /* enable wide-band sensor */ - -+/* w83667hg CIR pin config */ -+#define MULTIFUNC_PIN_SEL_MASK 0x1f -+#define MULTIFUNC_ENABLE_CIR 0x80 /* Pin75=CIRRX, Pin76=CIRTX1 */ -+#define MULTIFUNC_ENABLE_CIRWB 0x20 /* enable wide-band sensor */ -+ - /* MCE CIR signal length, related on sample period */ - - /* MCE CIR controller signal length: about 43ms -diff --git a/drivers/staging/lirc/lirc_sasem.c b/drivers/staging/lirc/lirc_sasem.c -index 63a438d..7080cde 100644 ---- a/drivers/staging/lirc/lirc_sasem.c -+++ b/drivers/staging/lirc/lirc_sasem.c -@@ -570,6 +570,7 @@ static void incoming_packet(struct sasem_context *context, - unsigned char *buf = urb->transfer_buffer; - long ms; - struct timeval tv; -+ int i; - - if (len != 8) { - printk(KERN_WARNING "%s: invalid incoming packet size (%d)\n", -@@ -577,12 +578,12 @@ static void incoming_packet(struct sasem_context *context, - return; - } - --#ifdef DEBUG -- int i; -- for (i = 0; i < 8; ++i) -- printk(KERN_INFO "%02x ", buf[i]); -- printk(KERN_INFO "\n"); --#endif -+ if (debug) { -+ printk(KERN_INFO "Incoming data: "); -+ for (i = 0; i < 8; ++i) -+ printk(KERN_CONT "%02x ", buf[i]); -+ printk(KERN_CONT "\n"); -+ } - - /* - * Lirc could deal with the repeat code, but we really need to block it -diff --git a/include/linux/input.h b/include/linux/input.h -index e428382..be082e9 100644 ---- a/include/linux/input.h -+++ b/include/linux/input.h -@@ -553,8 +553,8 @@ struct input_keymap_entry { - #define KEY_DVD 0x185 /* Media Select DVD */ - #define KEY_AUX 0x186 - #define KEY_MP3 0x187 --#define KEY_AUDIO 0x188 --#define KEY_VIDEO 0x189 -+#define KEY_AUDIO 0x188 /* AL Audio Browser */ -+#define KEY_VIDEO 0x189 /* AL Movie Browser */ - #define KEY_DIRECTORY 0x18a - #define KEY_LIST 0x18b - #define KEY_MEMO 0x18c /* Media Select Messages */ -@@ -605,6 +605,7 @@ struct input_keymap_entry { - #define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */ - #define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */ - #define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */ -+#define KEY_IMAGES 0x1ba /* AL Image Browser */ - - #define KEY_DEL_EOL 0x1c0 - #define KEY_DEL_EOS 0x1c1 -diff --git a/include/media/rc-map.h b/include/media/rc-map.h -index 9184751..b2bd405 100644 ---- a/include/media/rc-map.h -+++ b/include/media/rc-map.h -@@ -58,6 +58,7 @@ void rc_map_init(void); - #define RC_MAP_ALINK_DTU_M "rc-alink-dtu-m" - #define RC_MAP_ANYSEE "rc-anysee" - #define RC_MAP_APAC_VIEWCOMP "rc-apac-viewcomp" -+#define RC_MAP_APPLE "rc-apple" - #define RC_MAP_ASUS_PC39 "rc-asus-pc39" - #define RC_MAP_ATI_TV_WONDER_HD_600 "rc-ati-tv-wonder-hd-600" - #define RC_MAP_AVERMEDIA_A16D "rc-avermedia-a16d" -@@ -136,6 +137,7 @@ void rc_map_init(void); - #define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs" - #define RC_MAP_TERRATEC_SLIM "rc-terratec-slim" - #define RC_MAP_TEVII_NEC "rc-tevii-nec" -+#define RC_MAP_TIVO "rc-tivo" - #define RC_MAP_TOTAL_MEDIA_IN_HAND "rc-total-media-in-hand" - #define RC_MAP_TREKSTOR "rc-trekstor" - #define RC_MAP_TT_1500 "rc-tt-1500" -diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c -index accaf6c..43908a7 100644 ---- a/drivers/media/rc/ite-cir.c -+++ b/drivers/media/rc/ite-cir.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - #include - #include - #include - diff --git a/linux-2.6-v4l-dvb-update.patch b/linux-2.6-v4l-dvb-update.patch index 0984884..e69de29 100644 --- a/linux-2.6-v4l-dvb-update.patch +++ b/linux-2.6-v4l-dvb-update.patch @@ -1,7725 +0,0 @@ -v4l/dvb/rc media_tree updates from 2.6.39 - -commit f9d088784131609419595b51beb701d0f3aa6afc -Author: Jarod Wilson -Date: Tue Mar 22 17:23:15 2011 -0300 - - [media] rc: interim support for 32-bit NEC-ish scancodes - - The Apple and TiVo remotes I've got use an NEC-ish protocol, but rather - than a command/not_command pair, they have what appear to be vendor ID - bytes. This change makes the NEC decoder warn if the command/not_command - checksum fails, but then passes along a full 32-bit scancode for keymap - lookup. This change should make no difference for existing keymaps, - since they simply won't have 32-bit scancodes, but allows for a 32-bit - keymap. At the moment, that'll have to be uploaded by the user, but I've - got Apple and TiVo remote keymaps forthcoming. - - In the long run (2.6.40, hopefully), we should probably just always use - all 32 bits for all NEC keymaps, but this should get us by for 2.6.39. - - (Note that a few of the TiVo keys actuallly *do* pass the command - checksum, so for now, the keymap for this remote will have to be a mix - of 24-bit and 32-bit scancodes, but so be it). - - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 4568844fff1dc46b8adb7364ac3a844aa34d1e38 -Author: Jarod Wilson -Date: Fri Mar 4 20:20:47 2011 -0300 - - [media] mceusb: topseed 0x0011 needs gen3 init for tx to work - - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 514c3ef0671bdbdb1ae3708c63cce12e6f4b55f0 -Author: Jarod Wilson -Date: Fri Mar 4 19:53:05 2011 -0300 - - [media] lirc_zilog: error out if buffer read bytes != chunk size - - Give it a few tries, then exit. Prevents a possible endless loop - situation. - - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 7f72453889801675b825083d7ebddc341ccbb331 -Author: Jarod Wilson -Date: Fri Mar 4 17:57:24 2011 -0300 - - [media] lirc: silence some compile warnings - - Both lirc_imon and lirc_sasem were causing gcc to complain about the - possible use of uninitialized variables. - - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 37bda6318295a3412e191f1a5cb5a5bea2db59a5 -Author: Jarod Wilson -Date: Fri Mar 4 17:31:11 2011 -0300 - - [media] hdpvr: use same polling interval as other OS - - The hdpvr's IR part, in short, sucks. As observed with a usb traffic - sniffer, the Windows software for it uses a polling interval of 405ms. - Its still not behaving as well as I'd like even with this change, but - this inches us closer and closer to that point... - - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 6ba973db97845b0b7322d1a0cd5348d3024d7387 -Author: Jarod Wilson -Date: Fri Mar 4 17:30:17 2011 -0300 - - [media] ir-kbd-i2c: pass device code w/key in hauppauge case - - The new hauppauge key tables use both device code button code. - - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 246286a63b4820c1c039a836025c52ec79d18a2f -Author: Mauro Carvalho Chehab -Date: Mon Jan 24 22:23:08 2011 -0300 - - [media] rc/keymaps: Remove the obsolete rc-rc5-tv keymap - - This keymap were used for the Hauppauge Black remote controller - only. It also contains some keycodes not found there. As the - Hauppauge Black is now part of the hauppauge keymap, just remove - it. - - Also, remove the modprobe hacks to select between the Gray - and the Black versions of the remote controller as: - - Both are supported by default by the keymap; - - If the user just wants one keyboard supported, - it is just a matter of changing the keymap via - the userspace tool (ir-keytable), removing - the keys that he doesn't desire. As ir-keytable - auto-loads the keys via udev, this is better than - obscure modprobe parameters. - - Signed-off-by: Mauro Carvalho Chehab - Signed-off-by: Jarod Wilson - -commit af2a42cc5eec9659bac301885ac795be81d019c8 -Author: Mauro Carvalho Chehab -Date: Mon Jan 24 12:18:48 2011 -0300 - - [media] remove the old RC_MAP_HAUPPAUGE_NEW RC map - - The rc-hauppauge-new map is a messy thing, as it bundles 3 - - different remote controllers as if they were just one, - discarding the address byte. Also, some key maps are wrong. - - With the conversion to the new rc-core, it is likely that - most of the devices won't be working properly, as the i2c - driver and the raw decoders are now providing 16 bits for - the remote, instead of just 8. - - delete mode 100644 drivers/media/rc/keymaps/rc-hauppauge-new.c - - Signed-off-by: Mauro Carvalho Chehab - Signed-off-by: Jarod Wilson - -commit 1ef571252ec29a8b3674deb746bfaa8ad1b034c3 -Author: Mauro Carvalho Chehab -Date: Mon Jan 24 12:18:47 2011 -0300 - - [media] rc/keymaps: Rename Hauppauge table as rc-hauppauge - - There are two "hauppauge-new" keymaps, one with protocol - unknown, and the other with the protocol marked accordingly. - However, both tables are miss-named. - - Also, the old rc-hauppauge-new is broken, as it mixes - three different controllers as if they were just one. - - This patch solves half of the problem by renaming the - correct keycode table as just rc-hauppauge. This table - contains the codes for the four different types of - remote controllers found on Hauppauge cards, properly - mapped with their different addresses. - - create mode 100644 drivers/media/rc/keymaps/rc-hauppauge.c - delete mode 100644 drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c - [Jarod: fix up RC_MAP_HAUPPAUGE defines] - - Signed-off-by: Mauro Carvalho Chehab - Signed-off-by: Jarod Wilson - -commit 41abb2ee0ac34ecd8769b2ddd84caf67414ca0f7 -Author: Mauro Carvalho Chehab -Date: Mon Jan 24 12:18:45 2011 -0300 - - [media] rc-rc5-hauppauge-new: Fix Hauppauge Grey mapping - - The keys for the old black were messed with the ones for the - hauppauge grey. Fix it. - - Also, fixes some keycodes and order the keys according with - the way they appear inside the remote controller. - - Signed-off-by: Mauro Carvalho Chehab - Signed-off-by: Jarod Wilson - -commit 80daad9d9ece3bbfd0f7cc13dbefc92e3ebb1f6f -Author: Mauro Carvalho Chehab -Date: Mon Jan 24 12:18:44 2011 -0300 - - [media] rc-rc5-hauppauge-new: Add support for the old Black RC - - Hans borrowed me an old Black Hauppauge RC. Thanks to that, we - can fix the RC5 table for Hauppauge. - - Thanks-to: Hans Verkuil - Signed-off-by: Mauro Carvalho Chehab - Signed-off-by: Jarod Wilson - -commit 9ba542ee399a091a56711d5bc1f778f39768a26d -Author: Mauro Carvalho Chehab -Date: Mon Jan 24 12:18:43 2011 -0300 - - [media] rc-rc5-hauppauge-new: Add the old control to the table - - Adds the old grey remote controller to Hauppauge table. - - Hans borrowed me an old gray Hauppauge RC. Thanks to that, we - can fix the RC5 table for Hauppauge. - - Thanks-to: Hans Verkuil - Signed-off-by: Mauro Carvalho Chehab - Signed-off-by: Jarod Wilson - -commit 8d198df40f2d6fe2bfb3b8818dce974b40a614e9 -Author: Mauro Carvalho Chehab -Date: Mon Jan 24 12:18:43 2011 -0300 - - [media] rc-winfast: Fix the keycode tables - - One of the remotes has a picture available at: - http://lirc.sourceforge.net/remotes/leadtek/Y04G0004.jpg - - As there's one variant with a set direction keys plus vol/chann - keys, and the same table is used for both models, change it to - represent all keys, avoiding the usage of weird function keys. - - Signed-off-by: Mauro Carvalho Chehab - Signed-off-by: Jarod Wilson - -commit 434e6519a292096ee29303d74688ced038606842 -Author: Mauro Carvalho Chehab -Date: Mon Jan 24 12:18:42 2011 -0300 - - [media] a800: Fix a few wrong IR key assignments - - Signed-off-by: Mauro Carvalho Chehab - Signed-off-by: Jarod Wilson - -commit 674ff915ca5d7b40d710eb910afcf7f490b76ab0 -Author: Mauro Carvalho Chehab -Date: Mon Jan 24 12:18:41 2011 -0300 - - [media] opera1: Use multimedia keys instead of an app-specific mapping - - This driver uses an app-specific keymap for one of the tables. This - is wrong. Instead, use the standard keycodes. - - Signed-off-by: Mauro Carvalho Chehab - Signed-off-by: Jarod Wilson - -commit d59b1eedf5d5108cc90b9cfaf17f7845bad4f806 -Author: Mauro Carvalho Chehab -Date: Mon Jan 24 12:18:40 2011 -0300 - - [media] dw2102: Use multimedia keys instead of an app-specific mapping - - This driver uses an app-specific keymap for one of the tables. This - is wrong. Instead, use the standard keycodes. - - Signed-off-by: Mauro Carvalho Chehab - Signed-off-by: Jarod Wilson - -commit 651cef86ff15697ad8a5659ecc9bc43f16ca07ba -Author: Mauro Carvalho Chehab -Date: Mon Jan 24 12:18:39 2011 -0300 - - [media] rc/keymaps: Use KEY_LEFTMETA were pertinent - - Using xev and testing the "Windows" key on a normal keyboard, it - is mapped as KEY_LEFTMETA. So, as this is the standard code for - it, use it, instead of a generic, meaningless KEY_PROG1. - - Signed-off-by: Mauro Carvalho Chehab - Signed-off-by: Jarod Wilson - -commit bb8aeecec52791eacc727d8400ced9e1b230ec49 -Author: Mauro Carvalho Chehab -Date: Mon Jan 24 12:18:38 2011 -0300 - - [media] rc/keymaps: Fix most KEY_PROG[n] keycodes - - Those KEY_PROG[n] keys were used on places where the developer - didn't know for sure what key should be used. On several cases, - using KEY_RED, KEY_GREEN, KEY_YELLOW would be enough. On others, - there are specific keys for that already. - - Signed-off-by: Mauro Carvalho Chehab - Signed-off-by: Jarod Wilson - -commit 84c122769cca37480fbcd7de5a102f6221874247 -Author: Mauro Carvalho Chehab -Date: Mon Jan 24 12:18:37 2011 -0300 - - [media] rc/keymaps: Use KEY_VIDEO for Video Source - - Each keyboard map were using a different definition for - the Source/Video Source key. - Behold Columbus were the only one using KEY_PROPS. - - As we want to standardize those keys at X11 and at - userspace applications, we need to use just one code - for it. - - Signed-off-by: Mauro Carvalho Chehab - Signed-off-by: Jarod Wilson - -commit ea35a76538a45e78cee889d2c462df71a9b34e4c -Author: Mauro Carvalho Chehab -Date: Mon Jan 24 12:18:36 2011 -0300 - - [media] rc/keymaps: use KEY_CAMERA for snapshots - - On a few places, KEY_MHP were used for snapshots. However, KEY_CAMERA - is used for it on all the other keyboards that have a snapshot/Picture - button. - - Signed-off-by: Mauro Carvalho Chehab - Signed-off-by: Jarod Wilson - -commit d33d27b1745fc72b042b6431dd29ee484fdabbcc -Author: Andy Walls -Date: Thu Feb 17 21:32:06 2011 -0300 - - [media] lirc_zilog: Update TODO list based on work completed and revised plans - - Update the TODO.lirc_zilog based on what has been completed. Also revised - the development plan for lirc_zilog to not try and split Tx/Rx for one IR - transceiver unit between lirc_zilog and ir-kbd-i2c, since that would be a - ref-counting nightmare. - - Signed-off-by: Andy Walls - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 1a9cb97924e71b33a5d1a59facd58e1a584daa97 -Author: Andy Walls -Date: Thu Feb 17 21:14:13 2011 -0300 - - [media] lirc_zilog: Fix somewhat confusing information messages in ir_probe() - - The total sequence of messages emitted by the ir_porbe() calls - for a transceiver's two i2c_clients was confusing. Clean it up a bit. - - Signed-off-by: Andy Walls - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit cf141c455938cb245b6bf489c832d0c2e3833686 -Author: Andy Walls -Date: Thu Feb 17 20:50:38 2011 -0300 - - [media] lirc_zilog: Add locking of the i2c_clients when in use - - Lock the i2c_client pointers and prevent i2c_client removal when - lirc_zilog is perfoming a series of operations that require valid - i2c_client pointers. - - Signed-off-by: Andy Walls - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 6f4276ac6e98a05833aa7e49e438fec198e537e8 -Author: Andy Walls -Date: Mon Feb 7 22:30:55 2011 -0300 - - [media] lirc_zilog: Add ref counting of struct IR, IR_tx, and IR_rx - - This is a major change to add pointer reference counting for - struct IR, struct IR_tx, and struct IR_rx object instances. - This ref counting gets lirc_zilog closer to gracefully handling - bridge drivers and hot-unplugged USB devices disappearing out from - under lirc_zilog when the /dev/lircN node is still open. (mutexes - to protect the i2c_client pointers in struct IR_tx and struct IR_rx - still need to be added.) - - This reference counting also helps lirc_zilog clean up properly - when the i2c_clients disappear. - - Signed-off-by: Andy Walls - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit f3bc78dbb5942f1827a97329b1c095903329aa8b -Author: Andy Walls -Date: Thu Jan 27 23:02:20 2011 -0300 - - [media] lirc_zilog: Move constants from ir_probe() into the lirc_driver template - - ir_probe() makes a number of constant assignments into the lirc_driver - object after copying in a template. Make better use of the template. - - Signed-off-by: Andy Walls - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 6f61cb53e2b8f6c65cf2c6b3e3710233c643e6ce -Author: Andy Walls -Date: Thu Jan 27 22:32:44 2011 -0300 - - [media] lirc_zilog: Always allocate a Rx lirc_buffer object - - Always allocate a lirc_buffer object, instead of just upon setup of - the Rx i2c_client. If we do not allocate a lirc_buffer object, because - we are not handling the Rx i2c_client, lirc_dev will allocate its own - lirc_buffer anyway and not tell us about its location. - - Signed-off-by: Andy Walls - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 8941d66476b33d339408f66898766e0d8ac2cb0a -Author: Andy Walls -Date: Thu Jan 27 02:34:13 2011 -0300 - - [media] lirc_zilog: Remove unneeded rx->buf_lock - - Remove the rx->buf_lock that protected the rx->buf lirc_buffer. The - underlying operations on the objects within the lirc_buffer are already - protected by spinlocks, or the objects are constant (e.g. chunk_size). - - Signed-off-by: Andy Walls - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit fa2d70732b5699cd3bc9fc0e82c154e1410857e4 -Author: Andy Walls -Date: Thu Jan 27 02:10:42 2011 -0300 - - [media] lirc_zilog: Don't acquire the rx->buf_lock in the poll() function - - There is no need to take the rx->buf_lock in the the poll() function - as all the underling calls made on objects in the rx->buf lirc_buffer object - are protected by spinlocks. - - Corrected a bad error return value in poll(): return POLLERR instead - of -ENODEV. - - Added some comments to poll() for when, in the future, I forget what - poll() and poll_wait() are supposed to do. - - [Jarod: minor debug spew fix] - - Signed-off-by: Andy Walls - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 45a0dd2e9575f72693c94920e8d189ea395d5b5d -Author: Andy Walls -Date: Thu Jan 27 00:04:15 2011 -0300 - - [media] lirc_zilog: Use kernel standard methods for marking device non-seekable - - lirc_zilog had its own llseek stub that returned -ESPIPE. Get rid of - it and use the kernel's no_llseek() and nonseekable_open() functions - instead. - - Signed-off-by: Andy Walls - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit c4c4362e1e1bd1a39f186b96ba5b0df74470f101 -Author: Andy Walls -Date: Wed Jan 26 22:04:24 2011 -0300 - - [media] lirc_zilog: Convert the instance open count to an atomic_t - - The open count is simply used for deciding if the Rx polling thread - needs to poll the IR chip for userspace. Simplify the manipulation - of the open count by using an atomic_t and not requiring a lock - The polling thread errantly didn't try to take the lock anyway. - - Signed-off-by: Andy Walls - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 7f94125db5889c202b95e717ccbe9e35de63c14a -Author: Andy Walls -Date: Wed Jan 26 21:48:32 2011 -0300 - - [media] lirc_zilog: Convert ir_device instance array to a linked list - - Signed-off-by: Andy Walls - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit d2a47dc2e351e6cf33b98f0d3339d6d39fd8ed8b -Author: Andy Walls -Date: Wed Jan 26 21:25:47 2011 -0300 - - [media] lirc_zilog: Remove broken, ineffective reference counting - - The set_use_inc() and set_use_dec() functions tried to lock - the underlying bridge driver device instance in memory by - changing the use count on the device's i2c_clients. This - worked for PCI devices (ivtv, cx18, bttv). It doesn't - work for hot-pluggable usb devices (pvrusb2 and hdpvr). - With usb device instances, the driver may get locked into - memory, but the unplugged hardware is gone. - - The set_use_inc() set_use_dec() functions also tried to have - lirc_zilog change its own module refernce count, which is - racy and not guaranteed to work. The lirc_dev module does - actually perform proper module ref count manipulation on the - lirc_zilog module, so there is need for lirc_zilog to - attempt a buggy module get on itself anyway. - - lirc_zilog also errantly called these functions on itself - in open() and close(), but lirc_dev did that already too. - - So let's just gut the bodies of the set_use_*() functions, - and remove the extra calls to them from within lirc_zilog. - - Proper reference counting of the struct IR, IR_rx, and IR_tx - objects -- to handle the case when the underlying - bttv, ivtv, cx18, hdpvr, or pvrusb2 bridge driver module or - device instance goes away -- will be added in subsequent - patches. - - Signed-off-by: Andy Walls - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 767dd925f017bd0f0363f827509cebfaf0bb2b57 -Author: Andy Walls -Date: Wed Jan 26 21:06:43 2011 -0300 - - [media] lirc_zilog: Restore checks for existence of the IR_tx object - - This reverts commit 8090232a237ab62e22307fc060097da1a283dd66 and - adds an additional check for ir->tx == NULL. - - The user may need us to handle an RX only unit. Apparently - there are TV capture units in existence with Rx only wiring - and/or RX only firmware for the on-board Zilog Z8 IR unit. - - Signed-off-by: Andy Walls - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 91f27e09d7bba99341bd8ce035995ae21ff493f7 -Author: Jarod Wilson -Date: Wed Mar 2 13:23:52 2011 -0300 - - [media] hdpvr: i2c master enhancements - - Make the hdpvr's i2c master implementation more closely mirror that of - the pvrusb2 driver. Currently makes no significant difference in IR - reception behavior with ir-kbd-i2c (i.e., it still sucks). - - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit c1ba04cf3a0626f725795e3a853654928596d522 -Author: Jarod Wilson -Date: Tue Feb 1 16:27:05 2011 -0300 - - [media] imon: add more panel scancode mappings - - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 9cd4f638d57b01c5d901f73c94b08fad4aa0b295 -Author: Jarod Wilson -Date: Mon Jan 24 18:22:12 2011 -0300 - - [media] docs: fix typo in lirc_device_interface.xml - - Reported-by: Daniel Burr - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 97ad124749a060d8c4f5461111911474db3b555f -Author: Mauro Carvalho Chehab -Date: Tue Mar 22 17:17:56 2011 -0300 - - ite-cir: Fix a breakage caused by my cleanup patch - - Signed-off-by: Mauro Carvalho Chehab - -commit a38fc7a384bd679f2550e2a2323ff3e690d4ffd7 -Author: Juan J. Garcia de Soria -Date: Wed Mar 16 17:14:53 2011 -0300 - - [media] lirc: remove staging lirc_it87 and lirc_ite8709 drivers - - Remove older drivers lirc_it87 and lirc_ite8709 from the LIRC staging area, - since they're now superceded by ite-cir. - - Signed-off-by: Juan J. Garcia de Soria - Tested-by: Stephan Raue - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit e1bede3475c792a5c4793ec3cc929efa24aaae64 -Author: Mauro Carvalho Chehab -Date: Tue Mar 22 15:12:40 2011 -0300 - - [media] ite-cir: Fix some CodingStyle issues - - Cc: Juan J. Garcia de Soria - Cc: Stephan Raue - Cc: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - -commit 9e8739744ccc917011a91e489339278d7bb14eac -Author: Juan J. Garcia de Soria -Date: Wed Mar 16 17:14:52 2011 -0300 - - [media] rc: New rc-based ite-cir driver for several ITE CIRs - - This is a second version of an rc-core based driver for the ITE Tech IT8712F - CIR and now for a pair of other variants of the IT8512 CIR too. - - This driver should replace the lirc_it87 and lirc_ite8709 currently living in - the LIRC staging directory. - - The driver should support the ITE8704, ITE8713, ITE8708 and ITE8709 (this last - one yet untested) PNP ID's. - - The code doesn'te reuse code from the pre-existing LIRC drivers, but has been - written from scratch using the nuvoton.cir driver as a skeleton. - - This new driver shouldn't exhibit timing problems when running under load (or - with interrupts disabled for relatively long times). It works OOTB with the - RC6 MCE remote bundled with the ASUS EEEBox. TX support is implemented, but - I'm unable to test it since my hardware lacks TX capability. - - Signed-off-by: Juan J. Garcia de Soria - Tested-by: Stephan Raue - Signed-off-by: Jarod Wilson - Signed-off-by: Mauro Carvalho Chehab - .../DocBook/v4l/lirc_device_interface.xml | 2 +- - drivers/media/dvb/dvb-usb/a800.c | 8 +- - drivers/media/dvb/dvb-usb/digitv.c | 2 +- - drivers/media/dvb/dvb-usb/dw2102.c | 40 +- - drivers/media/dvb/dvb-usb/opera1.c | 33 +- - drivers/media/dvb/siano/sms-cards.c | 2 +- - drivers/media/dvb/ttpci/budget-ci.c | 15 +- - drivers/media/rc/Kconfig | 13 + - drivers/media/rc/Makefile | 1 + - drivers/media/rc/imon.c | 11 +- - drivers/media/rc/ir-nec-decoder.c | 10 +- - drivers/media/rc/ite-cir.c | 1736 ++++++++++++++++++++ - drivers/media/rc/ite-cir.h | 481 ++++++ - drivers/media/rc/keymaps/Makefile | 4 +- - drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c | 6 +- - drivers/media/rc/keymaps/rc-avermedia-dvbt.c | 4 +- - drivers/media/rc/keymaps/rc-avermedia-m135a.c | 2 +- - .../media/rc/keymaps/rc-avermedia-m733a-rm-k6.c | 2 +- - drivers/media/rc/keymaps/rc-avermedia-rm-ks.c | 2 +- - drivers/media/rc/keymaps/rc-behold-columbus.c | 2 +- - drivers/media/rc/keymaps/rc-behold.c | 2 +- - drivers/media/rc/keymaps/rc-budget-ci-old.c | 3 +- - drivers/media/rc/keymaps/rc-cinergy.c | 2 +- - drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c | 2 +- - drivers/media/rc/keymaps/rc-encore-enltv.c | 4 +- - drivers/media/rc/keymaps/rc-encore-enltv2.c | 2 +- - drivers/media/rc/keymaps/rc-flydvb.c | 4 +- - drivers/media/rc/keymaps/rc-hauppauge-new.c | 100 -- - drivers/media/rc/keymaps/rc-hauppauge.c | 241 +++ - drivers/media/rc/keymaps/rc-imon-mce.c | 2 +- - drivers/media/rc/keymaps/rc-imon-pad.c | 2 +- - drivers/media/rc/keymaps/rc-kworld-315u.c | 2 +- - .../media/rc/keymaps/rc-kworld-plus-tv-analog.c | 2 +- - drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c | 2 +- - drivers/media/rc/keymaps/rc-nebula.c | 2 +- - drivers/media/rc/keymaps/rc-norwood.c | 2 +- - drivers/media/rc/keymaps/rc-pctv-sedna.c | 2 +- - drivers/media/rc/keymaps/rc-pixelview-mk12.c | 2 +- - drivers/media/rc/keymaps/rc-pixelview-new.c | 2 +- - drivers/media/rc/keymaps/rc-pixelview.c | 2 +- - drivers/media/rc/keymaps/rc-pv951.c | 4 +- - drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c | 141 -- - drivers/media/rc/keymaps/rc-rc5-tv.c | 81 - - drivers/media/rc/keymaps/rc-rc6-mce.c | 2 +- - .../media/rc/keymaps/rc-real-audio-220-32-keys.c | 2 +- - drivers/media/rc/keymaps/rc-winfast.c | 22 +- - drivers/media/rc/mceusb.c | 4 +- - drivers/media/video/cx18/cx18-i2c.c | 2 +- - drivers/media/video/cx23885/cx23885-input.c | 2 +- - drivers/media/video/cx88/cx88-input.c | 4 +- - drivers/media/video/em28xx/em28xx-cards.c | 10 +- - drivers/media/video/hdpvr/hdpvr-i2c.c | 72 +- - drivers/media/video/ir-kbd-i2c.c | 18 +- - drivers/media/video/ivtv/ivtv-i2c.c | 5 +- - drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 4 +- - drivers/media/video/saa7134/saa7134-input.c | 2 +- - drivers/staging/lirc/Kconfig | 12 - - drivers/staging/lirc/Makefile | 2 - - drivers/staging/lirc/TODO.lirc_zilog | 51 +- - drivers/staging/lirc/lirc_imon.c | 2 +- - drivers/staging/lirc/lirc_it87.c | 1027 ------------ - drivers/staging/lirc/lirc_it87.h | 116 -- - drivers/staging/lirc/lirc_ite8709.c | 542 ------ - drivers/staging/lirc/lirc_sasem.c | 2 +- - drivers/staging/lirc/lirc_zilog.c | 814 ++++++---- - include/media/rc-map.h | 4 +- - include/media/soc_camera.h | 2 + - 67 files changed, 3128 insertions(+), 2513 deletions(-) - ---- -diff --git a/Documentation/DocBook/v4l/lirc_device_interface.xml b/Documentation/DocBook/v4l/lirc_device_interface.xml -index 68134c0..0e0453f 100644 ---- a/Documentation/DocBook/v4l/lirc_device_interface.xml -+++ b/Documentation/DocBook/v4l/lirc_device_interface.xml -@@ -45,7 +45,7 @@ describing an IR signal are read from the chardev. - The data written to the chardev is a pulse/space sequence of integer - values. Pulses and spaces are only marked implicitly by their position. The - data must start and end with a pulse, therefore, the data must always include --an unevent number of samples. The write function must block until the data has -+an uneven number of samples. The write function must block until the data has - been transmitted by the hardware. - - -diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c -index 53b93a4..f8e9bf1 100644 ---- a/drivers/media/dvb/dvb-usb/a800.c -+++ b/drivers/media/dvb/dvb-usb/a800.c -@@ -38,8 +38,8 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr - } - - static struct rc_map_table rc_map_a800_table[] = { -- { 0x0201, KEY_PROG1 }, /* SOURCE */ -- { 0x0200, KEY_POWER }, /* POWER */ -+ { 0x0201, KEY_MODE }, /* SOURCE */ -+ { 0x0200, KEY_POWER2 }, /* POWER */ - { 0x0205, KEY_1 }, /* 1 */ - { 0x0206, KEY_2 }, /* 2 */ - { 0x0207, KEY_3 }, /* 3 */ -@@ -52,8 +52,8 @@ static struct rc_map_table rc_map_a800_table[] = { - { 0x0212, KEY_LEFT }, /* L / DISPLAY */ - { 0x0211, KEY_0 }, /* 0 */ - { 0x0213, KEY_RIGHT }, /* R / CH RTN */ -- { 0x0217, KEY_PROG2 }, /* SNAP SHOT */ -- { 0x0210, KEY_PROG3 }, /* 16-CH PREV */ -+ { 0x0217, KEY_CAMERA }, /* SNAP SHOT */ -+ { 0x0210, KEY_LAST }, /* 16-CH PREV */ - { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */ - { 0x020c, KEY_ZOOM }, /* FULL SCREEN */ - { 0x021f, KEY_VOLUMEUP }, /* VOL UP */ -diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c -index f2dbce7..f6344cd 100644 ---- a/drivers/media/dvb/dvb-usb/digitv.c -+++ b/drivers/media/dvb/dvb-usb/digitv.c -@@ -176,7 +176,7 @@ static struct rc_map_table rc_map_digitv_table[] = { - { 0xaf59, KEY_AUX }, - { 0x5f5a, KEY_DVD }, - { 0x6f5a, KEY_POWER }, -- { 0x9f5a, KEY_MHP }, /* labelled 'Picture' */ -+ { 0x9f5a, KEY_CAMERA }, /* labelled 'Picture' */ - { 0xaf5a, KEY_AUDIO }, - { 0x5f65, KEY_INFO }, - { 0x6f65, KEY_F13 }, /* 16:9 */ -diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c -index 98cf302..f5b9da1 100644 ---- a/drivers/media/dvb/dvb-usb/dw2102.c -+++ b/drivers/media/dvb/dvb-usb/dw2102.c -@@ -1224,8 +1224,8 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) - } - - static struct rc_map_table rc_map_dw210x_table[] = { -- { 0xf80a, KEY_Q }, /*power*/ -- { 0xf80c, KEY_M }, /*mute*/ -+ { 0xf80a, KEY_POWER2 }, /*power*/ -+ { 0xf80c, KEY_MUTE }, /*mute*/ - { 0xf811, KEY_1 }, - { 0xf812, KEY_2 }, - { 0xf813, KEY_3 }, -@@ -1236,25 +1236,25 @@ static struct rc_map_table rc_map_dw210x_table[] = { - { 0xf818, KEY_8 }, - { 0xf819, KEY_9 }, - { 0xf810, KEY_0 }, -- { 0xf81c, KEY_PAGEUP }, /*ch+*/ -- { 0xf80f, KEY_PAGEDOWN }, /*ch-*/ -- { 0xf81a, KEY_O }, /*vol+*/ -- { 0xf80e, KEY_Z }, /*vol-*/ -- { 0xf804, KEY_R }, /*rec*/ -- { 0xf809, KEY_D }, /*fav*/ -- { 0xf808, KEY_BACKSPACE }, /*rewind*/ -- { 0xf807, KEY_A }, /*fast*/ -- { 0xf80b, KEY_P }, /*pause*/ -- { 0xf802, KEY_ESC }, /*cancel*/ -- { 0xf803, KEY_G }, /*tab*/ -+ { 0xf81c, KEY_CHANNELUP }, /*ch+*/ -+ { 0xf80f, KEY_CHANNELDOWN }, /*ch-*/ -+ { 0xf81a, KEY_VOLUMEUP }, /*vol+*/ -+ { 0xf80e, KEY_VOLUMEDOWN }, /*vol-*/ -+ { 0xf804, KEY_RECORD }, /*rec*/ -+ { 0xf809, KEY_FAVORITES }, /*fav*/ -+ { 0xf808, KEY_REWIND }, /*rewind*/ -+ { 0xf807, KEY_FASTFORWARD }, /*fast*/ -+ { 0xf80b, KEY_PAUSE }, /*pause*/ -+ { 0xf802, KEY_ESC }, /*cancel*/ -+ { 0xf803, KEY_TAB }, /*tab*/ - { 0xf800, KEY_UP }, /*up*/ -- { 0xf81f, KEY_ENTER }, /*ok*/ -- { 0xf801, KEY_DOWN }, /*down*/ -- { 0xf805, KEY_C }, /*cap*/ -- { 0xf806, KEY_S }, /*stop*/ -- { 0xf840, KEY_F }, /*full*/ -- { 0xf81e, KEY_W }, /*tvmode*/ -- { 0xf81b, KEY_B }, /*recall*/ -+ { 0xf81f, KEY_OK }, /*ok*/ -+ { 0xf801, KEY_DOWN }, /*down*/ -+ { 0xf805, KEY_CAMERA }, /*cap*/ -+ { 0xf806, KEY_STOP }, /*stop*/ -+ { 0xf840, KEY_ZOOM }, /*full*/ -+ { 0xf81e, KEY_TV }, /*tvmode*/ -+ { 0xf81b, KEY_LAST }, /*recall*/ - }; - - static struct rc_map_table rc_map_tevii_table[] = { -diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c -index 1f1b7d6..7e569f4 100644 ---- a/drivers/media/dvb/dvb-usb/opera1.c -+++ b/drivers/media/dvb/dvb-usb/opera1.c -@@ -342,23 +342,22 @@ static struct rc_map_table rc_map_opera1_table[] = { - {0x49b6, KEY_8}, - {0x05fa, KEY_9}, - {0x45ba, KEY_0}, -- {0x09f6, KEY_UP}, /*chanup */ -- {0x1be5, KEY_DOWN}, /*chandown */ -- {0x5da3, KEY_LEFT}, /*voldown */ -- {0x5fa1, KEY_RIGHT}, /*volup */ -- {0x07f8, KEY_SPACE}, /*tab */ -- {0x1fe1, KEY_ENTER}, /*play ok */ -- {0x1be4, KEY_Z}, /*zoom */ -- {0x59a6, KEY_M}, /*mute */ -- {0x5ba5, KEY_F}, /*tv/f */ -- {0x19e7, KEY_R}, /*rec */ -- {0x01fe, KEY_S}, /*Stop */ -- {0x03fd, KEY_P}, /*pause */ -- {0x03fc, KEY_W}, /*<- -> */ -- {0x07f9, KEY_C}, /*capture */ -- {0x47b9, KEY_Q}, /*exit */ -- {0x43bc, KEY_O}, /*power */ -- -+ {0x09f6, KEY_CHANNELUP}, /*chanup */ -+ {0x1be5, KEY_CHANNELDOWN}, /*chandown */ -+ {0x5da3, KEY_VOLUMEDOWN}, /*voldown */ -+ {0x5fa1, KEY_VOLUMEUP}, /*volup */ -+ {0x07f8, KEY_SPACE}, /*tab */ -+ {0x1fe1, KEY_OK}, /*play ok */ -+ {0x1be4, KEY_ZOOM}, /*zoom */ -+ {0x59a6, KEY_MUTE}, /*mute */ -+ {0x5ba5, KEY_RADIO}, /*tv/f */ -+ {0x19e7, KEY_RECORD}, /*rec */ -+ {0x01fe, KEY_STOP}, /*Stop */ -+ {0x03fd, KEY_PAUSE}, /*pause */ -+ {0x03fc, KEY_SCREEN}, /*<- -> */ -+ {0x07f9, KEY_CAMERA}, /*capture */ -+ {0x47b9, KEY_ESC}, /*exit */ -+ {0x43bc, KEY_POWER2}, /*power */ - }; - - static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state) -diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c -index 25b43e5..af121db 100644 ---- a/drivers/media/dvb/siano/sms-cards.c -+++ b/drivers/media/dvb/siano/sms-cards.c -@@ -64,7 +64,7 @@ static struct sms_board sms_boards[] = { - .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw", - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", -- .rc_codes = RC_MAP_RC5_HAUPPAUGE_NEW, -+ .rc_codes = RC_MAP_HAUPPAUGE, - .board_cfg.leds_power = 26, - .board_cfg.led0 = 27, - .board_cfg.led1 = 28, -diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c -index b82756d..1d79ada 100644 ---- a/drivers/media/dvb/ttpci/budget-ci.c -+++ b/drivers/media/dvb/ttpci/budget-ci.c -@@ -26,7 +26,7 @@ - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * -- * the project's page is at http://www.linuxtv.org/ -+ * the project's page is at http://www.linuxtv.org/ - */ - - #include -@@ -102,6 +102,7 @@ struct budget_ci_ir { - int rc5_device; - u32 ir_key; - bool have_command; -+ bool full_rc5; /* Outputs a full RC5 code */ - }; - - struct budget_ci { -@@ -154,11 +155,18 @@ static void msp430_ir_interrupt(unsigned long data) - return; - budget_ci->ir.have_command = false; - -- /* FIXME: We should generate complete scancodes with device info */ - if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && - budget_ci->ir.rc5_device != (command & 0x1f)) - return; - -+ if (budget_ci->ir.full_rc5) { -+ rc_keydown(dev, -+ budget_ci->ir.rc5_device <<8 | budget_ci->ir.ir_key, -+ (command & 0x20) ? 1 : 0); -+ return; -+ } -+ -+ /* FIXME: We should generate complete scancodes for all devices */ - rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0); - } - -@@ -206,7 +214,8 @@ static int msp430_ir_init(struct budget_ci *budget_ci) - case 0x1011: - case 0x1012: - /* The hauppauge keymap is a superset of these remotes */ -- dev->map_name = RC_MAP_HAUPPAUGE_NEW; -+ dev->map_name = RC_MAP_HAUPPAUGE; -+ budget_ci->ir.full_rc5 = true; - - if (rc5_device < 0) - budget_ci->ir.rc5_device = 0x1f; -diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig -index 1143845..7f03142 100644 ---- a/drivers/media/rc/Kconfig -+++ b/drivers/media/rc/Kconfig -@@ -135,6 +135,19 @@ config IR_MCEUSB - To compile this driver as a module, choose M here: the - module will be called mceusb. - -+config IR_ITE_CIR -+ tristate "ITE Tech Inc. IT8712/IT8512 Consumer Infrared Transceiver" -+ depends on PNP -+ depends on RC_CORE -+ ---help--- -+ Say Y here to enable support for integrated infrared receivers -+ /transceivers made by ITE Tech Inc. These are found in -+ several ASUS devices, like the ASUS Digimatrix or the ASUS -+ EEEBox 1501U. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called ite-cir. -+ - config IR_NUVOTON - tristate "Nuvoton w836x7hg Consumer Infrared Transceiver" - depends on PNP -diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile -index 67b4f7f..c6cfe70 100644 ---- a/drivers/media/rc/Makefile -+++ b/drivers/media/rc/Makefile -@@ -14,6 +14,7 @@ obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o - - # stand-alone IR receivers/transmitters - obj-$(CONFIG_IR_IMON) += imon.o -+obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o - obj-$(CONFIG_IR_MCEUSB) += mceusb.o - obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o - obj-$(CONFIG_IR_ENE) += ene_ir.o -diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c -index e7dc6b4..f714e1a 100644 ---- a/drivers/media/rc/imon.c -+++ b/drivers/media/rc/imon.c -@@ -277,12 +277,21 @@ static const struct { - u64 hw_code; - u32 keycode; - } imon_panel_key_table[] = { -- { 0x000000000f00ffeell, KEY_PROG1 }, /* Go */ -+ { 0x000000000f00ffeell, KEY_MEDIA }, /* Go */ -+ { 0x000000001200ffeell, KEY_UP }, -+ { 0x000000001300ffeell, KEY_DOWN }, -+ { 0x000000001400ffeell, KEY_LEFT }, -+ { 0x000000001500ffeell, KEY_RIGHT }, -+ { 0x000000001600ffeell, KEY_ENTER }, -+ { 0x000000001700ffeell, KEY_ESC }, - { 0x000000001f00ffeell, KEY_AUDIO }, - { 0x000000002000ffeell, KEY_VIDEO }, - { 0x000000002100ffeell, KEY_CAMERA }, - { 0x000000002700ffeell, KEY_DVD }, - { 0x000000002300ffeell, KEY_TV }, -+ { 0x000000002b00ffeell, KEY_EXIT }, -+ { 0x000000002c00ffeell, KEY_SELECT }, -+ { 0x000000002d00ffeell, KEY_MENU }, - { 0x000000000500ffeell, KEY_PREVIOUS }, - { 0x000000000700ffeell, KEY_REWIND }, - { 0x000000000400ffeell, KEY_STOP }, -diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c -index 7b58b4a..63ee722 100644 ---- a/drivers/media/rc/ir-nec-decoder.c -+++ b/drivers/media/rc/ir-nec-decoder.c -@@ -49,6 +49,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) - struct nec_dec *data = &dev->raw->nec; - u32 scancode; - u8 address, not_address, command, not_command; -+ bool send_32bits = false; - - if (!(dev->raw->enabled_protocols & RC_TYPE_NEC)) - return 0; -@@ -164,10 +165,15 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) - if ((command ^ not_command) != 0xff) { - IR_dprintk(1, "NEC checksum error: received 0x%08x\n", - data->bits); -- break; -+ send_32bits = true; - } - -- if ((address ^ not_address) != 0xff) { -+ if (send_32bits) { -+ /* NEC transport, but modified protocol, used by at -+ * least Apple and TiVo remotes */ -+ scancode = data->bits; -+ IR_dprintk(1, "NEC (modified) scancode 0x%08x\n", scancode); -+ } else if ((address ^ not_address) != 0xff) { - /* Extended NEC */ - scancode = address << 16 | - not_address << 8 | -diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c -new file mode 100644 -index 0000000..9be6a83 ---- /dev/null -+++ b/drivers/media/rc/ite-cir.c -@@ -0,0 +1,1736 @@ -+/* -+ * Driver for ITE Tech Inc. IT8712F/IT8512 CIR -+ * -+ * Copyright (C) 2010 Juan Jesús García de Soria -+ * -+ * 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; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -+ * USA. -+ * -+ * Inspired by the original lirc_it87 and lirc_ite8709 drivers, on top of the -+ * skeleton provided by the nuvoton-cir driver. -+ * -+ * The lirc_it87 driver was originally written by Hans-Gunter Lutke Uphues -+ * in 2001, with enhancements by Christoph Bartelmus -+ * , Andrew Calkin and James Edwards -+ * . -+ * -+ * The lirc_ite8709 driver was written by Grégory Lardière -+ * in 2008. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "ite-cir.h" -+ -+/* module parameters */ -+ -+/* debug level */ -+static int debug; -+module_param(debug, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(debug, "Enable debugging output"); -+ -+/* low limit for RX carrier freq, Hz, 0 for no RX demodulation */ -+static int rx_low_carrier_freq; -+module_param(rx_low_carrier_freq, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(rx_low_carrier_freq, "Override low RX carrier frequency, Hz, " -+ "0 for no RX demodulation"); -+ -+/* high limit for RX carrier freq, Hz, 0 for no RX demodulation */ -+static int rx_high_carrier_freq; -+module_param(rx_high_carrier_freq, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(rx_high_carrier_freq, "Override high RX carrier frequency, " -+ "Hz, 0 for no RX demodulation"); -+ -+/* override tx carrier frequency */ -+static int tx_carrier_freq; -+module_param(tx_carrier_freq, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(tx_carrier_freq, "Override TX carrier frequency, Hz"); -+ -+/* override tx duty cycle */ -+static int tx_duty_cycle; -+module_param(tx_duty_cycle, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(tx_duty_cycle, "Override TX duty cycle, 1-100"); -+ -+/* override default sample period */ -+static long sample_period; -+module_param(sample_period, long, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(sample_period, "Override carrier sample period, us"); -+ -+/* override detected model id */ -+static int model_number = -1; -+module_param(model_number, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(model_number, "Use this model number, don't autodetect"); -+ -+ -+/* HW-independent code functions */ -+ -+/* check whether carrier frequency is high frequency */ -+static inline bool ite_is_high_carrier_freq(unsigned int freq) -+{ -+ return freq >= ITE_HCF_MIN_CARRIER_FREQ; -+} -+ -+/* get the bits required to program the carrier frequency in CFQ bits, -+ * unshifted */ -+static u8 ite_get_carrier_freq_bits(unsigned int freq) -+{ -+ if (ite_is_high_carrier_freq(freq)) { -+ if (freq < 425000) -+ return ITE_CFQ_400; -+ -+ else if (freq < 465000) -+ return ITE_CFQ_450; -+ -+ else if (freq < 490000) -+ return ITE_CFQ_480; -+ -+ else -+ return ITE_CFQ_500; -+ } else { -+ /* trim to limits */ -+ if (freq < ITE_LCF_MIN_CARRIER_FREQ) -+ freq = ITE_LCF_MIN_CARRIER_FREQ; -+ if (freq > ITE_LCF_MAX_CARRIER_FREQ) -+ freq = ITE_LCF_MAX_CARRIER_FREQ; -+ -+ /* convert to kHz and subtract the base freq */ -+ freq = -+ DIV_ROUND_CLOSEST(freq - ITE_LCF_MIN_CARRIER_FREQ, -+ 1000); -+ -+ return (u8) freq; -+ } -+} -+ -+/* get the bits required to program the pulse with in TXMPW */ -+static u8 ite_get_pulse_width_bits(unsigned int freq, int duty_cycle) -+{ -+ unsigned long period_ns, on_ns; -+ -+ /* sanitize freq into range */ -+ if (freq < ITE_LCF_MIN_CARRIER_FREQ) -+ freq = ITE_LCF_MIN_CARRIER_FREQ; -+ if (freq > ITE_HCF_MAX_CARRIER_FREQ) -+ freq = ITE_HCF_MAX_CARRIER_FREQ; -+ -+ period_ns = 1000000000UL / freq; -+ on_ns = period_ns * duty_cycle / 100; -+ -+ if (ite_is_high_carrier_freq(freq)) { -+ if (on_ns < 750) -+ return ITE_TXMPW_A; -+ -+ else if (on_ns < 850) -+ return ITE_TXMPW_B; -+ -+ else if (on_ns < 950) -+ return ITE_TXMPW_C; -+ -+ else if (on_ns < 1080) -+ return ITE_TXMPW_D; -+ -+ else -+ return ITE_TXMPW_E; -+ } else { -+ if (on_ns < 6500) -+ return ITE_TXMPW_A; -+ -+ else if (on_ns < 7850) -+ return ITE_TXMPW_B; -+ -+ else if (on_ns < 9650) -+ return ITE_TXMPW_C; -+ -+ else if (on_ns < 11950) -+ return ITE_TXMPW_D; -+ -+ else -+ return ITE_TXMPW_E; -+ } -+} -+ -+/* decode raw bytes as received by the hardware, and push them to the ir-core -+ * layer */ -+static void ite_decode_bytes(struct ite_dev *dev, const u8 * data, int -+ length) -+{ -+ u32 sample_period; -+ unsigned long *ldata; -+ unsigned int next_one, next_zero, size; -+ DEFINE_IR_RAW_EVENT(ev); -+ -+ if (length == 0) -+ return; -+ -+ sample_period = dev->params.sample_period; -+ ldata = (unsigned long *)data; -+ size = length << 3; -+ next_one = generic_find_next_le_bit(ldata, size, 0); -+ if (next_one > 0) { -+ ev.pulse = true; -+ ev.duration = -+ ITE_BITS_TO_NS(next_one, sample_period); -+ ir_raw_event_store_with_filter(dev->rdev, &ev); -+ } -+ -+ while (next_one < size) { -+ next_zero = generic_find_next_zero_le_bit(ldata, size, next_one + 1); -+ ev.pulse = false; -+ ev.duration = ITE_BITS_TO_NS(next_zero - next_one, sample_period); -+ ir_raw_event_store_with_filter(dev->rdev, &ev); -+ -+ if (next_zero < size) { -+ next_one = -+ generic_find_next_le_bit(ldata, -+ size, -+ next_zero + 1); -+ ev.pulse = true; -+ ev.duration = -+ ITE_BITS_TO_NS(next_one - next_zero, -+ sample_period); -+ ir_raw_event_store_with_filter -+ (dev->rdev, &ev); -+ } else -+ next_one = size; -+ } -+ -+ ir_raw_event_handle(dev->rdev); -+ -+ ite_dbg_verbose("decoded %d bytes.", length); -+} -+ -+/* set all the rx/tx carrier parameters; this must be called with the device -+ * spinlock held */ -+static void ite_set_carrier_params(struct ite_dev *dev) -+{ -+ unsigned int freq, low_freq, high_freq; -+ int allowance; -+ bool use_demodulator; -+ bool for_tx = dev->transmitting; -+ -+ ite_dbg("%s called", __func__); -+ -+ if (for_tx) { -+ /* we don't need no stinking calculations */ -+ freq = dev->params.tx_carrier_freq; -+ allowance = ITE_RXDCR_DEFAULT; -+ use_demodulator = false; -+ } else { -+ low_freq = dev->params.rx_low_carrier_freq; -+ high_freq = dev->params.rx_high_carrier_freq; -+ -+ if (low_freq == 0) { -+ /* don't demodulate */ -+ freq = -+ ITE_DEFAULT_CARRIER_FREQ; -+ allowance = ITE_RXDCR_DEFAULT; -+ use_demodulator = false; -+ } else { -+ /* calculate the middle freq */ -+ freq = (low_freq + high_freq) / 2; -+ -+ /* calculate the allowance */ -+ allowance = -+ DIV_ROUND_CLOSEST(10000 * (high_freq - low_freq), -+ ITE_RXDCR_PER_10000_STEP -+ * (high_freq + low_freq)); -+ -+ if (allowance < 1) -+ allowance = 1; -+ -+ if (allowance > ITE_RXDCR_MAX) -+ allowance = ITE_RXDCR_MAX; -+ } -+ } -+ -+ /* set the carrier parameters in a device-dependent way */ -+ dev->params.set_carrier_params(dev, ite_is_high_carrier_freq(freq), -+ use_demodulator, ite_get_carrier_freq_bits(freq), allowance, -+ ite_get_pulse_width_bits(freq, dev->params.tx_duty_cycle)); -+} -+ -+/* interrupt service routine for incoming and outgoing CIR data */ -+static irqreturn_t ite_cir_isr(int irq, void *data) -+{ -+ struct ite_dev *dev = data; -+ unsigned long flags; -+ irqreturn_t ret = IRQ_RETVAL(IRQ_NONE); -+ u8 rx_buf[ITE_RX_FIFO_LEN]; -+ int rx_bytes; -+ int iflags; -+ -+ ite_dbg_verbose("%s firing", __func__); -+ -+ /* grab the spinlock */ -+ spin_lock_irqsave(&dev->lock, flags); -+ -+ /* read the interrupt flags */ -+ iflags = dev->params.get_irq_causes(dev); -+ -+ /* check for the receive interrupt */ -+ if (iflags & (ITE_IRQ_RX_FIFO | ITE_IRQ_RX_FIFO_OVERRUN)) { -+ /* read the FIFO bytes */ -+ rx_bytes = -+ dev->params.get_rx_bytes(dev, rx_buf, -+ ITE_RX_FIFO_LEN); -+ -+ if (rx_bytes > 0) { -+ /* drop the spinlock, since the ir-core layer -+ * may call us back again through -+ * ite_s_idle() */ -+ spin_unlock_irqrestore(&dev-> -+ lock, -+ flags); -+ -+ /* decode the data we've just received */ -+ ite_decode_bytes(dev, rx_buf, -+ rx_bytes); -+ -+ /* reacquire the spinlock */ -+ spin_lock_irqsave(&dev->lock, -+ flags); -+ -+ /* mark the interrupt as serviced */ -+ ret = IRQ_RETVAL(IRQ_HANDLED); -+ } -+ } else if (iflags & ITE_IRQ_TX_FIFO) { -+ /* FIFO space available interrupt */ -+ ite_dbg_verbose("got interrupt for TX FIFO"); -+ -+ /* wake any sleeping transmitter */ -+ wake_up_interruptible(&dev->tx_queue); -+ -+ /* mark the interrupt as serviced */ -+ ret = IRQ_RETVAL(IRQ_HANDLED); -+ } -+ -+ /* drop the spinlock */ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ ite_dbg_verbose("%s done returning %d", __func__, (int)ret); -+ -+ return ret; -+} -+ -+/* set the rx carrier freq range, guess it's in Hz... */ -+static int ite_set_rx_carrier_range(struct rc_dev *rcdev, u32 carrier_low, u32 -+ carrier_high) -+{ -+ unsigned long flags; -+ struct ite_dev *dev = rcdev->priv; -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ dev->params.rx_low_carrier_freq = carrier_low; -+ dev->params.rx_high_carrier_freq = carrier_high; -+ ite_set_carrier_params(dev); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ return 0; -+} -+ -+/* set the tx carrier freq, guess it's in Hz... */ -+static int ite_set_tx_carrier(struct rc_dev *rcdev, u32 carrier) -+{ -+ unsigned long flags; -+ struct ite_dev *dev = rcdev->priv; -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ dev->params.tx_carrier_freq = carrier; -+ ite_set_carrier_params(dev); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ return 0; -+} -+ -+/* set the tx duty cycle by controlling the pulse width */ -+static int ite_set_tx_duty_cycle(struct rc_dev *rcdev, u32 duty_cycle) -+{ -+ unsigned long flags; -+ struct ite_dev *dev = rcdev->priv; -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ dev->params.tx_duty_cycle = duty_cycle; -+ ite_set_carrier_params(dev); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ return 0; -+} -+ -+/* transmit out IR pulses; what you get here is a batch of alternating -+ * pulse/space/pulse/space lengths that we should write out completely through -+ * the FIFO, blocking on a full FIFO */ -+static int ite_tx_ir(struct rc_dev *rcdev, int *txbuf, u32 n) -+{ -+ unsigned long flags; -+ struct ite_dev *dev = rcdev->priv; -+ bool is_pulse = false; -+ int remaining_us, fifo_avail, fifo_remaining, last_idx = 0; -+ int max_rle_us, next_rle_us; -+ int ret = n; -+ u8 last_sent[ITE_TX_FIFO_LEN]; -+ u8 val; -+ -+ ite_dbg("%s called", __func__); -+ -+ /* clear the array just in case */ -+ memset(last_sent, 0, ARRAY_SIZE(last_sent)); -+ -+ /* n comes in bytes; convert to ints */ -+ n /= sizeof(int); -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ -+ /* let everybody know we're now transmitting */ -+ dev->transmitting = true; -+ -+ /* and set the carrier values for transmission */ -+ ite_set_carrier_params(dev); -+ -+ /* calculate how much time we can send in one byte */ -+ max_rle_us = -+ (ITE_BAUDRATE_DIVISOR * dev->params.sample_period * -+ ITE_TX_MAX_RLE) / 1000; -+ -+ /* disable the receiver */ -+ dev->params.disable_rx(dev); -+ -+ /* this is where we'll begin filling in the FIFO, until it's full. -+ * then we'll just activate the interrupt, wait for it to wake us up -+ * again, disable it, continue filling the FIFO... until everything -+ * has been pushed out */ -+ fifo_avail = -+ ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev); -+ -+ while (n > 0 && dev->in_use) { -+ /* transmit the next sample */ -+ is_pulse = !is_pulse; -+ remaining_us = *(txbuf++); -+ n--; -+ -+ ite_dbg("%s: %ld", -+ ((is_pulse) ? "pulse" : "space"), -+ (long int) -+ remaining_us); -+ -+ /* repeat while the pulse is non-zero length */ -+ while (remaining_us > 0 && dev->in_use) { -+ if (remaining_us > max_rle_us) -+ next_rle_us = max_rle_us; -+ -+ else -+ next_rle_us = remaining_us; -+ -+ remaining_us -= next_rle_us; -+ -+ /* check what's the length we have to pump out */ -+ val = (ITE_TX_MAX_RLE * next_rle_us) / max_rle_us; -+ -+ /* put it into the sent buffer */ -+ last_sent[last_idx++] = val; -+ last_idx &= (ITE_TX_FIFO_LEN); -+ -+ /* encode it for 7 bits */ -+ val = (val - 1) & ITE_TX_RLE_MASK; -+ -+ /* take into account pulse/space prefix */ -+ if (is_pulse) -+ val |= ITE_TX_PULSE; -+ -+ else -+ val |= ITE_TX_SPACE; -+ -+ /* -+ * if we get to 0 available, read again, just in case -+ * some other slot got freed -+ */ -+ if (fifo_avail <= 0) -+ fifo_avail = ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev); -+ -+ /* if it's still full */ -+ if (fifo_avail <= 0) { -+ /* enable the tx interrupt */ -+ dev->params. -+ enable_tx_interrupt(dev); -+ -+ /* drop the spinlock */ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ /* wait for the FIFO to empty enough */ -+ wait_event_interruptible(dev->tx_queue, (fifo_avail = ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev)) >= 8); -+ -+ /* get the spinlock again */ -+ spin_lock_irqsave(&dev->lock, flags); -+ -+ /* disable the tx interrupt again. */ -+ dev->params. -+ disable_tx_interrupt(dev); -+ } -+ -+ /* now send the byte through the FIFO */ -+ dev->params.put_tx_byte(dev, val); -+ fifo_avail--; -+ } -+ } -+ -+ /* wait and don't return until the whole FIFO has been sent out; -+ * otherwise we could configure the RX carrier params instead of the -+ * TX ones while the transmission is still being performed! */ -+ fifo_remaining = dev->params.get_tx_used_slots(dev); -+ remaining_us = 0; -+ while (fifo_remaining > 0) { -+ fifo_remaining--; -+ last_idx--; -+ last_idx &= (ITE_TX_FIFO_LEN - 1); -+ remaining_us += last_sent[last_idx]; -+ } -+ remaining_us = (remaining_us * max_rle_us) / (ITE_TX_MAX_RLE); -+ -+ /* drop the spinlock while we sleep */ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ /* sleep remaining_us microseconds */ -+ mdelay(DIV_ROUND_UP(remaining_us, 1000)); -+ -+ /* reacquire the spinlock */ -+ spin_lock_irqsave(&dev->lock, flags); -+ -+ /* now we're not transmitting anymore */ -+ dev->transmitting = false; -+ -+ /* and set the carrier values for reception */ -+ ite_set_carrier_params(dev); -+ -+ /* reenable the receiver */ -+ if (dev->in_use) -+ dev->params.enable_rx(dev); -+ -+ /* notify transmission end */ -+ wake_up_interruptible(&dev->tx_ended); -+ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ return ret; -+} -+ -+/* idle the receiver if needed */ -+static void ite_s_idle(struct rc_dev *rcdev, bool enable) -+{ -+ unsigned long flags; -+ struct ite_dev *dev = rcdev->priv; -+ -+ ite_dbg("%s called", __func__); -+ -+ if (enable) { -+ spin_lock_irqsave(&dev->lock, flags); -+ dev->params.idle_rx(dev); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ } -+} -+ -+ -+/* IT8712F HW-specific functions */ -+ -+/* retrieve a bitmask of the current causes for a pending interrupt; this may -+ * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN -+ * */ -+static int it87_get_irq_causes(struct ite_dev *dev) -+{ -+ u8 iflags; -+ int ret = 0; -+ -+ ite_dbg("%s called", __func__); -+ -+ /* read the interrupt flags */ -+ iflags = inb(dev->cir_addr + IT87_IIR) & IT87_II; -+ -+ switch (iflags) { -+ case IT87_II_RXDS: -+ ret = ITE_IRQ_RX_FIFO; -+ break; -+ case IT87_II_RXFO: -+ ret = ITE_IRQ_RX_FIFO_OVERRUN; -+ break; -+ case IT87_II_TXLDL: -+ ret = ITE_IRQ_TX_FIFO; -+ break; -+ } -+ -+ return ret; -+} -+ -+/* set the carrier parameters; to be called with the spinlock held */ -+static void it87_set_carrier_params(struct ite_dev *dev, bool high_freq, -+ bool use_demodulator, -+ u8 carrier_freq_bits, u8 allowance_bits, -+ u8 pulse_width_bits) -+{ -+ u8 val; -+ -+ ite_dbg("%s called", __func__); -+ -+ /* program the RCR register */ -+ val = inb(dev->cir_addr + IT87_RCR) -+ & ~(IT87_HCFS | IT87_RXEND | IT87_RXDCR); -+ -+ if (high_freq) -+ val |= IT87_HCFS; -+ -+ if (use_demodulator) -+ val |= IT87_RXEND; -+ -+ val |= allowance_bits; -+ -+ outb(val, dev->cir_addr + IT87_RCR); -+ -+ /* program the TCR2 register */ -+ outb((carrier_freq_bits << IT87_CFQ_SHIFT) | pulse_width_bits, -+ dev->cir_addr + IT87_TCR2); -+} -+ -+/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock -+ * held */ -+static int it87_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size) -+{ -+ int fifo, read = 0; -+ -+ ite_dbg("%s called", __func__); -+ -+ /* read how many bytes are still in the FIFO */ -+ fifo = inb(dev->cir_addr + IT87_RSR) & IT87_RXFBC; -+ -+ while (fifo > 0 && buf_size > 0) { -+ *(buf++) = inb(dev->cir_addr + IT87_DR); -+ fifo--; -+ read++; -+ buf_size--; -+ } -+ -+ return read; -+} -+ -+/* return how many bytes are still in the FIFO; this will be called -+ * with the device spinlock NOT HELD while waiting for the TX FIFO to get -+ * empty; let's expect this won't be a problem */ -+static int it87_get_tx_used_slots(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ return inb(dev->cir_addr + IT87_TSR) & IT87_TXFBC; -+} -+ -+/* put a byte to the TX fifo; this should be called with the spinlock held */ -+static void it87_put_tx_byte(struct ite_dev *dev, u8 value) -+{ -+ outb(value, dev->cir_addr + IT87_DR); -+} -+ -+/* idle the receiver so that we won't receive samples until another -+ pulse is detected; this must be called with the device spinlock held */ -+static void it87_idle_rx(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* disable streaming by clearing RXACT writing it as 1 */ -+ outb(inb(dev->cir_addr + IT87_RCR) | IT87_RXACT, -+ dev->cir_addr + IT87_RCR); -+ -+ /* clear the FIFO */ -+ outb(inb(dev->cir_addr + IT87_TCR1) | IT87_FIFOCLR, -+ dev->cir_addr + IT87_TCR1); -+} -+ -+/* disable the receiver; this must be called with the device spinlock held */ -+static void it87_disable_rx(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* disable the receiver interrupts */ -+ outb(inb(dev->cir_addr + IT87_IER) & ~(IT87_RDAIE | IT87_RFOIE), -+ dev->cir_addr + IT87_IER); -+ -+ /* disable the receiver */ -+ outb(inb(dev->cir_addr + IT87_RCR) & ~IT87_RXEN, -+ dev->cir_addr + IT87_RCR); -+ -+ /* clear the FIFO and RXACT (actually RXACT should have been cleared -+ * in the previous outb() call) */ -+ it87_idle_rx(dev); -+} -+ -+/* enable the receiver; this must be called with the device spinlock held */ -+static void it87_enable_rx(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* enable the receiver by setting RXEN */ -+ outb(inb(dev->cir_addr + IT87_RCR) | IT87_RXEN, -+ dev->cir_addr + IT87_RCR); -+ -+ /* just prepare it to idle for the next reception */ -+ it87_idle_rx(dev); -+ -+ /* enable the receiver interrupts and master enable flag */ -+ outb(inb(dev->cir_addr + IT87_IER) | IT87_RDAIE | IT87_RFOIE | IT87_IEC, -+ dev->cir_addr + IT87_IER); -+} -+ -+/* disable the transmitter interrupt; this must be called with the device -+ * spinlock held */ -+static void it87_disable_tx_interrupt(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* disable the transmitter interrupts */ -+ outb(inb(dev->cir_addr + IT87_IER) & ~IT87_TLDLIE, -+ dev->cir_addr + IT87_IER); -+} -+ -+/* enable the transmitter interrupt; this must be called with the device -+ * spinlock held */ -+static void it87_enable_tx_interrupt(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* enable the transmitter interrupts and master enable flag */ -+ outb(inb(dev->cir_addr + IT87_IER) | IT87_TLDLIE | IT87_IEC, -+ dev->cir_addr + IT87_IER); -+} -+ -+/* disable the device; this must be called with the device spinlock held */ -+static void it87_disable(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* clear out all interrupt enable flags */ -+ outb(inb(dev->cir_addr + IT87_IER) & -+ ~(IT87_IEC | IT87_RFOIE | IT87_RDAIE | IT87_TLDLIE), -+ dev->cir_addr + IT87_IER); -+ -+ /* disable the receiver */ -+ it87_disable_rx(dev); -+ -+ /* erase the FIFO */ -+ outb(IT87_FIFOCLR | inb(dev->cir_addr + IT87_TCR1), -+ dev->cir_addr + IT87_TCR1); -+} -+ -+/* initialize the hardware */ -+static void it87_init_hardware(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* enable just the baud rate divisor register, -+ disabling all the interrupts at the same time */ -+ outb((inb(dev->cir_addr + IT87_IER) & -+ ~(IT87_IEC | IT87_RFOIE | IT87_RDAIE | IT87_TLDLIE)) | IT87_BR, -+ dev->cir_addr + IT87_IER); -+ -+ /* write out the baud rate divisor */ -+ outb(ITE_BAUDRATE_DIVISOR & 0xff, dev->cir_addr + IT87_BDLR); -+ outb((ITE_BAUDRATE_DIVISOR >> 8) & 0xff, dev->cir_addr + IT87_BDHR); -+ -+ /* disable the baud rate divisor register again */ -+ outb(inb(dev->cir_addr + IT87_IER) & ~IT87_BR, -+ dev->cir_addr + IT87_IER); -+ -+ /* program the RCR register defaults */ -+ outb(ITE_RXDCR_DEFAULT, dev->cir_addr + IT87_RCR); -+ -+ /* program the TCR1 register */ -+ outb(IT87_TXMPM_DEFAULT | IT87_TXENDF | IT87_TXRLE -+ | IT87_FIFOTL_DEFAULT | IT87_FIFOCLR, -+ dev->cir_addr + IT87_TCR1); -+ -+ /* program the carrier parameters */ -+ ite_set_carrier_params(dev); -+} -+ -+/* IT8512F on ITE8708 HW-specific functions */ -+ -+/* retrieve a bitmask of the current causes for a pending interrupt; this may -+ * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN -+ * */ -+static int it8708_get_irq_causes(struct ite_dev *dev) -+{ -+ u8 iflags; -+ int ret = 0; -+ -+ ite_dbg("%s called", __func__); -+ -+ /* read the interrupt flags */ -+ iflags = inb(dev->cir_addr + IT8708_C0IIR); -+ -+ if (iflags & IT85_TLDLI) -+ ret |= ITE_IRQ_TX_FIFO; -+ if (iflags & IT85_RDAI) -+ ret |= ITE_IRQ_RX_FIFO; -+ if (iflags & IT85_RFOI) -+ ret |= ITE_IRQ_RX_FIFO_OVERRUN; -+ -+ return ret; -+} -+ -+/* set the carrier parameters; to be called with the spinlock held */ -+static void it8708_set_carrier_params(struct ite_dev *dev, bool high_freq, -+ bool use_demodulator, -+ u8 carrier_freq_bits, u8 allowance_bits, -+ u8 pulse_width_bits) -+{ -+ u8 val; -+ -+ ite_dbg("%s called", __func__); -+ -+ /* program the C0CFR register, with HRAE=1 */ -+ outb(inb(dev->cir_addr + IT8708_BANKSEL) | IT8708_HRAE, -+ dev->cir_addr + IT8708_BANKSEL); -+ -+ val = (inb(dev->cir_addr + IT8708_C0CFR) -+ & ~(IT85_HCFS | IT85_CFQ)) | carrier_freq_bits; -+ -+ if (high_freq) -+ val |= IT85_HCFS; -+ -+ outb(val, dev->cir_addr + IT8708_C0CFR); -+ -+ outb(inb(dev->cir_addr + IT8708_BANKSEL) & ~IT8708_HRAE, -+ dev->cir_addr + IT8708_BANKSEL); -+ -+ /* program the C0RCR register */ -+ val = inb(dev->cir_addr + IT8708_C0RCR) -+ & ~(IT85_RXEND | IT85_RXDCR); -+ -+ if (use_demodulator) -+ val |= IT85_RXEND; -+ -+ val |= allowance_bits; -+ -+ outb(val, dev->cir_addr + IT8708_C0RCR); -+ -+ /* program the C0TCR register */ -+ val = inb(dev->cir_addr + IT8708_C0TCR) & ~IT85_TXMPW; -+ val |= pulse_width_bits; -+ outb(val, dev->cir_addr + IT8708_C0TCR); -+} -+ -+/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock -+ * held */ -+static int it8708_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size) -+{ -+ int fifo, read = 0; -+ -+ ite_dbg("%s called", __func__); -+ -+ /* read how many bytes are still in the FIFO */ -+ fifo = inb(dev->cir_addr + IT8708_C0RFSR) & IT85_RXFBC; -+ -+ while (fifo > 0 && buf_size > 0) { -+ *(buf++) = inb(dev->cir_addr + IT8708_C0DR); -+ fifo--; -+ read++; -+ buf_size--; -+ } -+ -+ return read; -+} -+ -+/* return how many bytes are still in the FIFO; this will be called -+ * with the device spinlock NOT HELD while waiting for the TX FIFO to get -+ * empty; let's expect this won't be a problem */ -+static int it8708_get_tx_used_slots(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ return inb(dev->cir_addr + IT8708_C0TFSR) & IT85_TXFBC; -+} -+ -+/* put a byte to the TX fifo; this should be called with the spinlock held */ -+static void it8708_put_tx_byte(struct ite_dev *dev, u8 value) -+{ -+ outb(value, dev->cir_addr + IT8708_C0DR); -+} -+ -+/* idle the receiver so that we won't receive samples until another -+ pulse is detected; this must be called with the device spinlock held */ -+static void it8708_idle_rx(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* disable streaming by clearing RXACT writing it as 1 */ -+ outb(inb(dev->cir_addr + IT8708_C0RCR) | IT85_RXACT, -+ dev->cir_addr + IT8708_C0RCR); -+ -+ /* clear the FIFO */ -+ outb(inb(dev->cir_addr + IT8708_C0MSTCR) | IT85_FIFOCLR, -+ dev->cir_addr + IT8708_C0MSTCR); -+} -+ -+/* disable the receiver; this must be called with the device spinlock held */ -+static void it8708_disable_rx(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* disable the receiver interrupts */ -+ outb(inb(dev->cir_addr + IT8708_C0IER) & -+ ~(IT85_RDAIE | IT85_RFOIE), -+ dev->cir_addr + IT8708_C0IER); -+ -+ /* disable the receiver */ -+ outb(inb(dev->cir_addr + IT8708_C0RCR) & ~IT85_RXEN, -+ dev->cir_addr + IT8708_C0RCR); -+ -+ /* clear the FIFO and RXACT (actually RXACT should have been cleared -+ * in the previous outb() call) */ -+ it8708_idle_rx(dev); -+} -+ -+/* enable the receiver; this must be called with the device spinlock held */ -+static void it8708_enable_rx(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* enable the receiver by setting RXEN */ -+ outb(inb(dev->cir_addr + IT8708_C0RCR) | IT85_RXEN, -+ dev->cir_addr + IT8708_C0RCR); -+ -+ /* just prepare it to idle for the next reception */ -+ it8708_idle_rx(dev); -+ -+ /* enable the receiver interrupts and master enable flag */ -+ outb(inb(dev->cir_addr + IT8708_C0IER) -+ |IT85_RDAIE | IT85_RFOIE | IT85_IEC, -+ dev->cir_addr + IT8708_C0IER); -+} -+ -+/* disable the transmitter interrupt; this must be called with the device -+ * spinlock held */ -+static void it8708_disable_tx_interrupt(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* disable the transmitter interrupts */ -+ outb(inb(dev->cir_addr + IT8708_C0IER) & ~IT85_TLDLIE, -+ dev->cir_addr + IT8708_C0IER); -+} -+ -+/* enable the transmitter interrupt; this must be called with the device -+ * spinlock held */ -+static void it8708_enable_tx_interrupt(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* enable the transmitter interrupts and master enable flag */ -+ outb(inb(dev->cir_addr + IT8708_C0IER) -+ |IT85_TLDLIE | IT85_IEC, -+ dev->cir_addr + IT8708_C0IER); -+} -+ -+/* disable the device; this must be called with the device spinlock held */ -+static void it8708_disable(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* clear out all interrupt enable flags */ -+ outb(inb(dev->cir_addr + IT8708_C0IER) & -+ ~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE), -+ dev->cir_addr + IT8708_C0IER); -+ -+ /* disable the receiver */ -+ it8708_disable_rx(dev); -+ -+ /* erase the FIFO */ -+ outb(IT85_FIFOCLR | inb(dev->cir_addr + IT8708_C0MSTCR), -+ dev->cir_addr + IT8708_C0MSTCR); -+} -+ -+/* initialize the hardware */ -+static void it8708_init_hardware(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* disable all the interrupts */ -+ outb(inb(dev->cir_addr + IT8708_C0IER) & -+ ~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE), -+ dev->cir_addr + IT8708_C0IER); -+ -+ /* program the baud rate divisor */ -+ outb(inb(dev->cir_addr + IT8708_BANKSEL) | IT8708_HRAE, -+ dev->cir_addr + IT8708_BANKSEL); -+ -+ outb(ITE_BAUDRATE_DIVISOR & 0xff, dev->cir_addr + IT8708_C0BDLR); -+ outb((ITE_BAUDRATE_DIVISOR >> 8) & 0xff, -+ dev->cir_addr + IT8708_C0BDHR); -+ -+ outb(inb(dev->cir_addr + IT8708_BANKSEL) & ~IT8708_HRAE, -+ dev->cir_addr + IT8708_BANKSEL); -+ -+ /* program the C0MSTCR register defaults */ -+ outb((inb(dev->cir_addr + IT8708_C0MSTCR) & -+ ~(IT85_ILSEL | IT85_ILE | IT85_FIFOTL | -+ IT85_FIFOCLR | IT85_RESET)) | -+ IT85_FIFOTL_DEFAULT, -+ dev->cir_addr + IT8708_C0MSTCR); -+ -+ /* program the C0RCR register defaults */ -+ outb((inb(dev->cir_addr + IT8708_C0RCR) & -+ ~(IT85_RXEN | IT85_RDWOS | IT85_RXEND | -+ IT85_RXACT | IT85_RXDCR)) | -+ ITE_RXDCR_DEFAULT, -+ dev->cir_addr + IT8708_C0RCR); -+ -+ /* program the C0TCR register defaults */ -+ outb((inb(dev->cir_addr + IT8708_C0TCR) & -+ ~(IT85_TXMPM | IT85_TXMPW)) -+ |IT85_TXRLE | IT85_TXENDF | -+ IT85_TXMPM_DEFAULT | IT85_TXMPW_DEFAULT, -+ dev->cir_addr + IT8708_C0TCR); -+ -+ /* program the carrier parameters */ -+ ite_set_carrier_params(dev); -+} -+ -+/* IT8512F on ITE8709 HW-specific functions */ -+ -+/* read a byte from the SRAM module */ -+static inline u8 it8709_rm(struct ite_dev *dev, int index) -+{ -+ outb(index, dev->cir_addr + IT8709_RAM_IDX); -+ return inb(dev->cir_addr + IT8709_RAM_VAL); -+} -+ -+/* write a byte to the SRAM module */ -+static inline void it8709_wm(struct ite_dev *dev, u8 val, int index) -+{ -+ outb(index, dev->cir_addr + IT8709_RAM_IDX); -+ outb(val, dev->cir_addr + IT8709_RAM_VAL); -+} -+ -+static void it8709_wait(struct ite_dev *dev) -+{ -+ int i = 0; -+ /* -+ * loop until device tells it's ready to continue -+ * iterations count is usually ~750 but can sometimes achieve 13000 -+ */ -+ for (i = 0; i < 15000; i++) { -+ udelay(2); -+ if (it8709_rm(dev, IT8709_MODE) == IT8709_IDLE) -+ break; -+ } -+} -+ -+/* read the value of a CIR register */ -+static u8 it8709_rr(struct ite_dev *dev, int index) -+{ -+ /* just wait in case the previous access was a write */ -+ it8709_wait(dev); -+ it8709_wm(dev, index, IT8709_REG_IDX); -+ it8709_wm(dev, IT8709_READ, IT8709_MODE); -+ -+ /* wait for the read data to be available */ -+ it8709_wait(dev); -+ -+ /* return the read value */ -+ return it8709_rm(dev, IT8709_REG_VAL); -+} -+ -+/* write the value of a CIR register */ -+static void it8709_wr(struct ite_dev *dev, u8 val, int index) -+{ -+ /* we wait before writing, and not afterwards, since this allows us to -+ * pipeline the host CPU with the microcontroller */ -+ it8709_wait(dev); -+ it8709_wm(dev, val, IT8709_REG_VAL); -+ it8709_wm(dev, index, IT8709_REG_IDX); -+ it8709_wm(dev, IT8709_WRITE, IT8709_MODE); -+} -+ -+/* retrieve a bitmask of the current causes for a pending interrupt; this may -+ * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN -+ * */ -+static int it8709_get_irq_causes(struct ite_dev *dev) -+{ -+ u8 iflags; -+ int ret = 0; -+ -+ ite_dbg("%s called", __func__); -+ -+ /* read the interrupt flags */ -+ iflags = it8709_rm(dev, IT8709_IIR); -+ -+ if (iflags & IT85_TLDLI) -+ ret |= ITE_IRQ_TX_FIFO; -+ if (iflags & IT85_RDAI) -+ ret |= ITE_IRQ_RX_FIFO; -+ if (iflags & IT85_RFOI) -+ ret |= ITE_IRQ_RX_FIFO_OVERRUN; -+ -+ return ret; -+} -+ -+/* set the carrier parameters; to be called with the spinlock held */ -+static void it8709_set_carrier_params(struct ite_dev *dev, bool high_freq, -+ bool use_demodulator, -+ u8 carrier_freq_bits, u8 allowance_bits, -+ u8 pulse_width_bits) -+{ -+ u8 val; -+ -+ ite_dbg("%s called", __func__); -+ -+ val = (it8709_rr(dev, IT85_C0CFR) -+ &~(IT85_HCFS | IT85_CFQ)) | -+ carrier_freq_bits; -+ -+ if (high_freq) -+ val |= IT85_HCFS; -+ -+ it8709_wr(dev, val, IT85_C0CFR); -+ -+ /* program the C0RCR register */ -+ val = it8709_rr(dev, IT85_C0RCR) -+ & ~(IT85_RXEND | IT85_RXDCR); -+ -+ if (use_demodulator) -+ val |= IT85_RXEND; -+ -+ val |= allowance_bits; -+ -+ it8709_wr(dev, val, IT85_C0RCR); -+ -+ /* program the C0TCR register */ -+ val = it8709_rr(dev, IT85_C0TCR) & ~IT85_TXMPW; -+ val |= pulse_width_bits; -+ it8709_wr(dev, val, IT85_C0TCR); -+} -+ -+/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock -+ * held */ -+static int it8709_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size) -+{ -+ int fifo, read = 0; -+ -+ ite_dbg("%s called", __func__); -+ -+ /* read how many bytes are still in the FIFO */ -+ fifo = it8709_rm(dev, IT8709_RFSR) & IT85_RXFBC; -+ -+ while (fifo > 0 && buf_size > 0) { -+ *(buf++) = it8709_rm(dev, IT8709_FIFO + read); -+ fifo--; -+ read++; -+ buf_size--; -+ } -+ -+ /* 'clear' the FIFO by setting the writing index to 0; this is -+ * completely bound to be racy, but we can't help it, since it's a -+ * limitation of the protocol */ -+ it8709_wm(dev, 0, IT8709_RFSR); -+ -+ return read; -+} -+ -+/* return how many bytes are still in the FIFO; this will be called -+ * with the device spinlock NOT HELD while waiting for the TX FIFO to get -+ * empty; let's expect this won't be a problem */ -+static int it8709_get_tx_used_slots(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ return it8709_rr(dev, IT85_C0TFSR) & IT85_TXFBC; -+} -+ -+/* put a byte to the TX fifo; this should be called with the spinlock held */ -+static void it8709_put_tx_byte(struct ite_dev *dev, u8 value) -+{ -+ it8709_wr(dev, value, IT85_C0DR); -+} -+ -+/* idle the receiver so that we won't receive samples until another -+ pulse is detected; this must be called with the device spinlock held */ -+static void it8709_idle_rx(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* disable streaming by clearing RXACT writing it as 1 */ -+ it8709_wr(dev, it8709_rr(dev, IT85_C0RCR) | IT85_RXACT, -+ IT85_C0RCR); -+ -+ /* clear the FIFO */ -+ it8709_wr(dev, it8709_rr(dev, IT85_C0MSTCR) | IT85_FIFOCLR, -+ IT85_C0MSTCR); -+} -+ -+/* disable the receiver; this must be called with the device spinlock held */ -+static void it8709_disable_rx(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* disable the receiver interrupts */ -+ it8709_wr(dev, it8709_rr(dev, IT85_C0IER) & -+ ~(IT85_RDAIE | IT85_RFOIE), -+ IT85_C0IER); -+ -+ /* disable the receiver */ -+ it8709_wr(dev, it8709_rr(dev, IT85_C0RCR) & ~IT85_RXEN, -+ IT85_C0RCR); -+ -+ /* clear the FIFO and RXACT (actually RXACT should have been cleared -+ * in the previous it8709_wr(dev, ) call) */ -+ it8709_idle_rx(dev); -+} -+ -+/* enable the receiver; this must be called with the device spinlock held */ -+static void it8709_enable_rx(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* enable the receiver by setting RXEN */ -+ it8709_wr(dev, it8709_rr(dev, IT85_C0RCR) | IT85_RXEN, -+ IT85_C0RCR); -+ -+ /* just prepare it to idle for the next reception */ -+ it8709_idle_rx(dev); -+ -+ /* enable the receiver interrupts and master enable flag */ -+ it8709_wr(dev, it8709_rr(dev, IT85_C0IER) -+ |IT85_RDAIE | IT85_RFOIE | IT85_IEC, -+ IT85_C0IER); -+} -+ -+/* disable the transmitter interrupt; this must be called with the device -+ * spinlock held */ -+static void it8709_disable_tx_interrupt(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* disable the transmitter interrupts */ -+ it8709_wr(dev, it8709_rr(dev, IT85_C0IER) & ~IT85_TLDLIE, -+ IT85_C0IER); -+} -+ -+/* enable the transmitter interrupt; this must be called with the device -+ * spinlock held */ -+static void it8709_enable_tx_interrupt(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* enable the transmitter interrupts and master enable flag */ -+ it8709_wr(dev, it8709_rr(dev, IT85_C0IER) -+ |IT85_TLDLIE | IT85_IEC, -+ IT85_C0IER); -+} -+ -+/* disable the device; this must be called with the device spinlock held */ -+static void it8709_disable(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* clear out all interrupt enable flags */ -+ it8709_wr(dev, -+ it8709_rr(dev, -+ IT85_C0IER) & ~(IT85_IEC | IT85_RFOIE | -+ IT85_RDAIE | -+ IT85_TLDLIE), IT85_C0IER); -+ -+ /* disable the receiver */ -+ it8709_disable_rx(dev); -+ -+ /* erase the FIFO */ -+ it8709_wr(dev, IT85_FIFOCLR | it8709_rr(dev, IT85_C0MSTCR), -+ IT85_C0MSTCR); -+} -+ -+/* initialize the hardware */ -+static void it8709_init_hardware(struct ite_dev *dev) -+{ -+ ite_dbg("%s called", __func__); -+ -+ /* disable all the interrupts */ -+ it8709_wr(dev, -+ it8709_rr(dev, -+ IT85_C0IER) & ~(IT85_IEC | IT85_RFOIE | -+ IT85_RDAIE | -+ IT85_TLDLIE), IT85_C0IER); -+ -+ /* program the baud rate divisor */ -+ it8709_wr(dev, ITE_BAUDRATE_DIVISOR & 0xff, IT85_C0BDLR); -+ it8709_wr(dev, (ITE_BAUDRATE_DIVISOR >> 8) & 0xff, -+ IT85_C0BDHR); -+ -+ /* program the C0MSTCR register defaults */ -+ it8709_wr(dev, (it8709_rr(dev, IT85_C0MSTCR) & ~(IT85_ILSEL | -+ IT85_ILE -+ | IT85_FIFOTL -+ | -+ IT85_FIFOCLR -+ | -+ IT85_RESET)) -+ | IT85_FIFOTL_DEFAULT, IT85_C0MSTCR); -+ -+ /* program the C0RCR register defaults */ -+ it8709_wr(dev, -+ (it8709_rr(dev, IT85_C0RCR) & -+ ~(IT85_RXEN | IT85_RDWOS | IT85_RXEND -+ | IT85_RXACT | IT85_RXDCR)) | -+ ITE_RXDCR_DEFAULT, IT85_C0RCR); -+ -+ /* program the C0TCR register defaults */ -+ it8709_wr(dev, (it8709_rr(dev, IT85_C0TCR) -+ &~(IT85_TXMPM | IT85_TXMPW)) -+ |IT85_TXRLE | IT85_TXENDF | -+ IT85_TXMPM_DEFAULT | -+ IT85_TXMPW_DEFAULT, IT85_C0TCR); -+ -+ /* program the carrier parameters */ -+ ite_set_carrier_params(dev); -+} -+ -+ -+/* generic hardware setup/teardown code */ -+ -+/* activate the device for use */ -+static int ite_open(struct rc_dev *rcdev) -+{ -+ struct ite_dev *dev = rcdev->priv; -+ unsigned long flags; -+ -+ ite_dbg("%s called", __func__); -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ dev->in_use = true; -+ -+ /* enable the receiver */ -+ dev->params.enable_rx(dev); -+ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ return 0; -+} -+ -+/* deactivate the device for use */ -+static void ite_close(struct rc_dev *rcdev) -+{ -+ struct ite_dev *dev = rcdev->priv; -+ unsigned long flags; -+ -+ ite_dbg("%s called", __func__); -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ dev->in_use = false; -+ -+ /* wait for any transmission to end */ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ wait_event_interruptible(dev->tx_ended, !dev->transmitting); -+ spin_lock_irqsave(&dev->lock, flags); -+ -+ dev->params.disable(dev); -+ -+ spin_unlock_irqrestore(&dev->lock, flags); -+} -+ -+/* supported models and their parameters */ -+static const struct ite_dev_params ite_dev_descs[] = { -+ { /* 0: ITE8704 */ -+ .model = "ITE8704 CIR transceiver", -+ .io_region_size = IT87_IOREG_LENGTH, -+ .hw_tx_capable = true, -+ .sample_period = (u32) (1000000000ULL / 115200), -+ .tx_carrier_freq = 38000, -+ .tx_duty_cycle = 33, -+ .rx_low_carrier_freq = 0, -+ .rx_high_carrier_freq = 0, -+ -+ /* operations */ -+ .get_irq_causes = it87_get_irq_causes, -+ .enable_rx = it87_enable_rx, -+ .idle_rx = it87_idle_rx, -+ .disable_rx = it87_idle_rx, -+ .get_rx_bytes = it87_get_rx_bytes, -+ .enable_tx_interrupt = it87_enable_tx_interrupt, -+ .disable_tx_interrupt = it87_disable_tx_interrupt, -+ .get_tx_used_slots = it87_get_tx_used_slots, -+ .put_tx_byte = it87_put_tx_byte, -+ .disable = it87_disable, -+ .init_hardware = it87_init_hardware, -+ .set_carrier_params = it87_set_carrier_params, -+ }, -+ { /* 1: ITE8713 */ -+ .model = "ITE8713 CIR transceiver", -+ .io_region_size = IT87_IOREG_LENGTH, -+ .hw_tx_capable = true, -+ .sample_period = (u32) (1000000000ULL / 115200), -+ .tx_carrier_freq = 38000, -+ .tx_duty_cycle = 33, -+ .rx_low_carrier_freq = 0, -+ .rx_high_carrier_freq = 0, -+ -+ /* operations */ -+ .get_irq_causes = it87_get_irq_causes, -+ .enable_rx = it87_enable_rx, -+ .idle_rx = it87_idle_rx, -+ .disable_rx = it87_idle_rx, -+ .get_rx_bytes = it87_get_rx_bytes, -+ .enable_tx_interrupt = it87_enable_tx_interrupt, -+ .disable_tx_interrupt = it87_disable_tx_interrupt, -+ .get_tx_used_slots = it87_get_tx_used_slots, -+ .put_tx_byte = it87_put_tx_byte, -+ .disable = it87_disable, -+ .init_hardware = it87_init_hardware, -+ .set_carrier_params = it87_set_carrier_params, -+ }, -+ { /* 2: ITE8708 */ -+ .model = "ITE8708 CIR transceiver", -+ .io_region_size = IT8708_IOREG_LENGTH, -+ .hw_tx_capable = true, -+ .sample_period = (u32) (1000000000ULL / 115200), -+ .tx_carrier_freq = 38000, -+ .tx_duty_cycle = 33, -+ .rx_low_carrier_freq = 0, -+ .rx_high_carrier_freq = 0, -+ -+ /* operations */ -+ .get_irq_causes = it8708_get_irq_causes, -+ .enable_rx = it8708_enable_rx, -+ .idle_rx = it8708_idle_rx, -+ .disable_rx = it8708_idle_rx, -+ .get_rx_bytes = it8708_get_rx_bytes, -+ .enable_tx_interrupt = it8708_enable_tx_interrupt, -+ .disable_tx_interrupt = -+ it8708_disable_tx_interrupt, -+ .get_tx_used_slots = it8708_get_tx_used_slots, -+ .put_tx_byte = it8708_put_tx_byte, -+ .disable = it8708_disable, -+ .init_hardware = it8708_init_hardware, -+ .set_carrier_params = it8708_set_carrier_params, -+ }, -+ { /* 3: ITE8709 */ -+ .model = "ITE8709 CIR transceiver", -+ .io_region_size = IT8709_IOREG_LENGTH, -+ .hw_tx_capable = true, -+ .sample_period = (u32) (1000000000ULL / 115200), -+ .tx_carrier_freq = 38000, -+ .tx_duty_cycle = 33, -+ .rx_low_carrier_freq = 0, -+ .rx_high_carrier_freq = 0, -+ -+ /* operations */ -+ .get_irq_causes = it8709_get_irq_causes, -+ .enable_rx = it8709_enable_rx, -+ .idle_rx = it8709_idle_rx, -+ .disable_rx = it8709_idle_rx, -+ .get_rx_bytes = it8709_get_rx_bytes, -+ .enable_tx_interrupt = it8709_enable_tx_interrupt, -+ .disable_tx_interrupt = -+ it8709_disable_tx_interrupt, -+ .get_tx_used_slots = it8709_get_tx_used_slots, -+ .put_tx_byte = it8709_put_tx_byte, -+ .disable = it8709_disable, -+ .init_hardware = it8709_init_hardware, -+ .set_carrier_params = it8709_set_carrier_params, -+ }, -+}; -+ -+static const struct pnp_device_id ite_ids[] = { -+ {"ITE8704", 0}, /* Default model */ -+ {"ITE8713", 1}, /* CIR found in EEEBox 1501U */ -+ {"ITE8708", 2}, /* Bridged IT8512 */ -+ {"ITE8709", 3}, /* SRAM-Bridged IT8512 */ -+ {"", 0}, -+}; -+ -+/* allocate memory, probe hardware, and initialize everything */ -+static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id -+ *dev_id) -+{ -+ const struct ite_dev_params *dev_desc = NULL; -+ struct ite_dev *itdev = NULL; -+ struct rc_dev *rdev = NULL; -+ int ret = -ENOMEM; -+ int model_no; -+ -+ ite_dbg("%s called", __func__); -+ -+ itdev = kzalloc(sizeof(struct ite_dev), GFP_KERNEL); -+ if (!itdev) -+ return ret; -+ -+ /* input device for IR remote (and tx) */ -+ rdev = rc_allocate_device(); -+ if (!rdev) -+ goto failure; -+ -+ ret = -ENODEV; -+ -+ /* get the model number */ -+ model_no = (int)dev_id->driver_data; -+ ite_pr(KERN_NOTICE, "Auto-detected model: %s\n", -+ ite_dev_descs[model_no].model); -+ -+ if (model_number >= 0 && model_number < ARRAY_SIZE(ite_dev_descs)) { -+ model_no = model_number; -+ ite_pr(KERN_NOTICE, "The model has been fixed by a module " -+ "parameter."); -+ } -+ -+ ite_pr(KERN_NOTICE, "Using model: %s\n", ite_dev_descs[model_no].model); -+ -+ /* get the description for the device */ -+ dev_desc = &ite_dev_descs[model_no]; -+ -+ /* validate pnp resources */ -+ if (!pnp_port_valid(pdev, 0) || -+ pnp_port_len(pdev, 0) != dev_desc->io_region_size) { -+ dev_err(&pdev->dev, "IR PNP Port not valid!\n"); -+ goto failure; -+ } -+ -+ if (!pnp_irq_valid(pdev, 0)) { -+ dev_err(&pdev->dev, "PNP IRQ not valid!\n"); -+ goto failure; -+ } -+ -+ /* store resource values */ -+ itdev->cir_addr = pnp_port_start(pdev, 0); -+ itdev->cir_irq = pnp_irq(pdev, 0); -+ -+ /* initialize spinlocks */ -+ spin_lock_init(&itdev->lock); -+ -+ /* initialize raw event */ -+ init_ir_raw_event(&itdev->rawir); -+ -+ ret = -EBUSY; -+ /* now claim resources */ -+ if (!request_region(itdev->cir_addr, -+ dev_desc->io_region_size, ITE_DRIVER_NAME)) -+ goto failure; -+ -+ if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED, -+ ITE_DRIVER_NAME, (void *)itdev)) -+ goto failure; -+ -+ /* set driver data into the pnp device */ -+ pnp_set_drvdata(pdev, itdev); -+ itdev->pdev = pdev; -+ -+ /* initialize waitqueues for transmission */ -+ init_waitqueue_head(&itdev->tx_queue); -+ init_waitqueue_head(&itdev->tx_ended); -+ -+ /* copy model-specific parameters */ -+ itdev->params = *dev_desc; -+ -+ /* apply any overrides */ -+ if (sample_period > 0) -+ itdev->params.sample_period = sample_period; -+ -+ if (tx_carrier_freq > 0) -+ itdev->params.tx_carrier_freq = tx_carrier_freq; -+ -+ if (tx_duty_cycle > 0 && tx_duty_cycle <= 100) -+ itdev->params.tx_duty_cycle = tx_duty_cycle; -+ -+ if (rx_low_carrier_freq > 0) -+ itdev->params.rx_low_carrier_freq = rx_low_carrier_freq; -+ -+ if (rx_high_carrier_freq > 0) -+ itdev->params.rx_high_carrier_freq = rx_high_carrier_freq; -+ -+ /* print out parameters */ -+ ite_pr(KERN_NOTICE, "TX-capable: %d\n", (int) -+ itdev->params.hw_tx_capable); -+ ite_pr(KERN_NOTICE, "Sample period (ns): %ld\n", (long) -+ itdev->params.sample_period); -+ ite_pr(KERN_NOTICE, "TX carrier frequency (Hz): %d\n", (int) -+ itdev->params.tx_carrier_freq); -+ ite_pr(KERN_NOTICE, "TX duty cycle (%%): %d\n", (int) -+ itdev->params.tx_duty_cycle); -+ ite_pr(KERN_NOTICE, "RX low carrier frequency (Hz): %d\n", (int) -+ itdev->params.rx_low_carrier_freq); -+ ite_pr(KERN_NOTICE, "RX high carrier frequency (Hz): %d\n", (int) -+ itdev->params.rx_high_carrier_freq); -+ -+ /* set up hardware initial state */ -+ itdev->params.init_hardware(itdev); -+ -+ /* set up ir-core props */ -+ rdev->priv = itdev; -+ rdev->driver_type = RC_DRIVER_IR_RAW; -+ rdev->allowed_protos = RC_TYPE_ALL; -+ rdev->open = ite_open; -+ rdev->close = ite_close; -+ rdev->s_idle = ite_s_idle; -+ rdev->s_rx_carrier_range = ite_set_rx_carrier_range; -+ rdev->min_timeout = ITE_MIN_IDLE_TIMEOUT; -+ rdev->max_timeout = ITE_MAX_IDLE_TIMEOUT; -+ rdev->timeout = ITE_IDLE_TIMEOUT; -+ rdev->rx_resolution = ITE_BAUDRATE_DIVISOR * -+ itdev->params.sample_period; -+ rdev->tx_resolution = ITE_BAUDRATE_DIVISOR * -+ itdev->params.sample_period; -+ -+ /* set up transmitter related values if needed */ -+ if (itdev->params.hw_tx_capable) { -+ rdev->tx_ir = ite_tx_ir; -+ rdev->s_tx_carrier = ite_set_tx_carrier; -+ rdev->s_tx_duty_cycle = ite_set_tx_duty_cycle; -+ } -+ -+ rdev->input_name = dev_desc->model; -+ rdev->input_id.bustype = BUS_HOST; -+ rdev->input_id.vendor = PCI_VENDOR_ID_ITE; -+ rdev->input_id.product = 0; -+ rdev->input_id.version = 0; -+ rdev->driver_name = ITE_DRIVER_NAME; -+ rdev->map_name = RC_MAP_RC6_MCE; -+ -+ ret = rc_register_device(rdev); -+ if (ret) -+ goto failure; -+ -+ itdev->rdev = rdev; -+ ite_pr(KERN_NOTICE, "driver has been successfully loaded\n"); -+ -+ return 0; -+ -+failure: -+ if (itdev->cir_irq) -+ free_irq(itdev->cir_irq, itdev); -+ -+ if (itdev->cir_addr) -+ release_region(itdev->cir_addr, itdev->params.io_region_size); -+ -+ rc_free_device(rdev); -+ kfree(itdev); -+ -+ return ret; -+} -+ -+static void __devexit ite_remove(struct pnp_dev *pdev) -+{ -+ struct ite_dev *dev = pnp_get_drvdata(pdev); -+ unsigned long flags; -+ -+ ite_dbg("%s called", __func__); -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ -+ /* disable hardware */ -+ dev->params.disable(dev); -+ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ /* free resources */ -+ free_irq(dev->cir_irq, dev); -+ release_region(dev->cir_addr, dev->params.io_region_size); -+ -+ rc_unregister_device(dev->rdev); -+ -+ kfree(dev); -+} -+ -+static int ite_suspend(struct pnp_dev *pdev, pm_message_t state) -+{ -+ struct ite_dev *dev = pnp_get_drvdata(pdev); -+ unsigned long flags; -+ -+ ite_dbg("%s called", __func__); -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ -+ /* disable all interrupts */ -+ dev->params.disable(dev); -+ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ return 0; -+} -+ -+static int ite_resume(struct pnp_dev *pdev) -+{ -+ int ret = 0; -+ struct ite_dev *dev = pnp_get_drvdata(pdev); -+ unsigned long flags; -+ -+ ite_dbg("%s called", __func__); -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ -+ if (dev->transmitting) { -+ /* wake up the transmitter */ -+ wake_up_interruptible(&dev->tx_queue); -+ } else { -+ /* enable the receiver */ -+ dev->params.enable_rx(dev); -+ } -+ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ return ret; -+} -+ -+static void ite_shutdown(struct pnp_dev *pdev) -+{ -+ struct ite_dev *dev = pnp_get_drvdata(pdev); -+ unsigned long flags; -+ -+ ite_dbg("%s called", __func__); -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ -+ /* disable all interrupts */ -+ dev->params.disable(dev); -+ -+ spin_unlock_irqrestore(&dev->lock, flags); -+} -+ -+static struct pnp_driver ite_driver = { -+ .name = ITE_DRIVER_NAME, -+ .id_table = ite_ids, -+ .probe = ite_probe, -+ .remove = __devexit_p(ite_remove), -+ .suspend = ite_suspend, -+ .resume = ite_resume, -+ .shutdown = ite_shutdown, -+}; -+ -+int ite_init(void) -+{ -+ return pnp_register_driver(&ite_driver); -+} -+ -+void ite_exit(void) -+{ -+ pnp_unregister_driver(&ite_driver); -+} -+ -+MODULE_DEVICE_TABLE(pnp, ite_ids); -+MODULE_DESCRIPTION("ITE Tech Inc. IT8712F/ITE8512F CIR driver"); -+ -+MODULE_AUTHOR("Juan J. Garcia de Soria "); -+MODULE_LICENSE("GPL"); -+ -+module_init(ite_init); -+module_exit(ite_exit); -diff --git a/drivers/media/rc/ite-cir.h b/drivers/media/rc/ite-cir.h -new file mode 100644 -index 0000000..16a19f5 ---- /dev/null -+++ b/drivers/media/rc/ite-cir.h -@@ -0,0 +1,481 @@ -+/* -+ * Driver for ITE Tech Inc. IT8712F/IT8512F CIR -+ * -+ * Copyright (C) 2010 Juan Jesús García de Soria -+ * -+ * 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; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -+ * USA. -+ */ -+ -+/* platform driver name to register */ -+#define ITE_DRIVER_NAME "ite-cir" -+ -+/* logging macros */ -+#define ite_pr(level, text, ...) \ -+ printk(level KBUILD_MODNAME ": " text, ## __VA_ARGS__) -+#define ite_dbg(text, ...) do { \ -+ if (debug) \ -+ printk(KERN_DEBUG \ -+ KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__); \ -+} while (0) -+ -+#define ite_dbg_verbose(text, ...) do {\ -+ if (debug > 1) \ -+ printk(KERN_DEBUG \ -+ KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__); \ -+} while (0) -+ -+/* FIFO sizes */ -+#define ITE_TX_FIFO_LEN 32 -+#define ITE_RX_FIFO_LEN 32 -+ -+/* interrupt types */ -+#define ITE_IRQ_TX_FIFO 1 -+#define ITE_IRQ_RX_FIFO 2 -+#define ITE_IRQ_RX_FIFO_OVERRUN 4 -+ -+/* forward declaration */ -+struct ite_dev; -+ -+/* struct for storing the parameters of different recognized devices */ -+struct ite_dev_params { -+ /* model of the device */ -+ const char *model; -+ -+ /* size of the I/O region */ -+ int io_region_size; -+ -+ /* true if the hardware supports transmission */ -+ bool hw_tx_capable; -+ -+ /* base sampling period, in ns */ -+ u32 sample_period; -+ -+ /* rx low carrier frequency, in Hz, 0 means no demodulation */ -+ unsigned int rx_low_carrier_freq; -+ -+ /* tx high carrier frequency, in Hz, 0 means no demodulation */ -+ unsigned int rx_high_carrier_freq; -+ -+ /* tx carrier frequency, in Hz */ -+ unsigned int tx_carrier_freq; -+ -+ /* duty cycle, 0-100 */ -+ int tx_duty_cycle; -+ -+ /* hw-specific operation function pointers; most of these must be -+ * called while holding the spin lock, except for the TX FIFO length -+ * one */ -+ /* get pending interrupt causes */ -+ int (*get_irq_causes) (struct ite_dev *dev); -+ -+ /* enable rx */ -+ void (*enable_rx) (struct ite_dev *dev); -+ -+ /* make rx enter the idle state; keep listening for a pulse, but stop -+ * streaming space bytes */ -+ void (*idle_rx) (struct ite_dev *dev); -+ -+ /* disable rx completely */ -+ void (*disable_rx) (struct ite_dev *dev); -+ -+ /* read bytes from RX FIFO; return read count */ -+ int (*get_rx_bytes) (struct ite_dev *dev, u8 *buf, int buf_size); -+ -+ /* enable tx FIFO space available interrupt */ -+ void (*enable_tx_interrupt) (struct ite_dev *dev); -+ -+ /* disable tx FIFO space available interrupt */ -+ void (*disable_tx_interrupt) (struct ite_dev *dev); -+ -+ /* get number of full TX FIFO slots */ -+ int (*get_tx_used_slots) (struct ite_dev *dev); -+ -+ /* put a byte to the TX FIFO */ -+ void (*put_tx_byte) (struct ite_dev *dev, u8 value); -+ -+ /* disable hardware completely */ -+ void (*disable) (struct ite_dev *dev); -+ -+ /* initialize the hardware */ -+ void (*init_hardware) (struct ite_dev *dev); -+ -+ /* set the carrier parameters */ -+ void (*set_carrier_params) (struct ite_dev *dev, bool high_freq, -+ bool use_demodulator, u8 carrier_freq_bits, -+ u8 allowance_bits, u8 pulse_width_bits); -+}; -+ -+/* ITE CIR device structure */ -+struct ite_dev { -+ struct pnp_dev *pdev; -+ struct rc_dev *rdev; -+ struct ir_raw_event rawir; -+ -+ /* sync data */ -+ spinlock_t lock; -+ bool in_use, transmitting; -+ -+ /* transmit support */ -+ int tx_fifo_allowance; -+ wait_queue_head_t tx_queue, tx_ended; -+ -+ /* hardware I/O settings */ -+ unsigned long cir_addr; -+ int cir_irq; -+ -+ /* overridable copy of model parameters */ -+ struct ite_dev_params params; -+}; -+ -+/* common values for all kinds of hardware */ -+ -+/* baud rate divisor default */ -+#define ITE_BAUDRATE_DIVISOR 1 -+ -+/* low-speed carrier frequency limits (Hz) */ -+#define ITE_LCF_MIN_CARRIER_FREQ 27000 -+#define ITE_LCF_MAX_CARRIER_FREQ 58000 -+ -+/* high-speed carrier frequency limits (Hz) */ -+#define ITE_HCF_MIN_CARRIER_FREQ 400000 -+#define ITE_HCF_MAX_CARRIER_FREQ 500000 -+ -+/* default carrier freq for when demodulator is off (Hz) */ -+#define ITE_DEFAULT_CARRIER_FREQ 38000 -+ -+/* default idling timeout in ns (0.2 seconds) */ -+#define ITE_IDLE_TIMEOUT 200000000UL -+ -+/* limit timeout values */ -+#define ITE_MIN_IDLE_TIMEOUT 100000000UL -+#define ITE_MAX_IDLE_TIMEOUT 1000000000UL -+ -+/* convert bits to us */ -+#define ITE_BITS_TO_NS(bits, sample_period) \ -+((u32) ((bits) * ITE_BAUDRATE_DIVISOR * sample_period)) -+ -+/* -+ * n in RDCR produces a tolerance of +/- n * 6.25% around the center -+ * carrier frequency... -+ * -+ * From two limit frequencies, L (low) and H (high), we can get both the -+ * center frequency F = (L + H) / 2 and the variation from the center -+ * frequency A = (H - L) / (H + L). We can use this in order to honor the -+ * s_rx_carrier_range() call in ir-core. We'll suppose that any request -+ * setting L=0 means we must shut down the demodulator. -+ */ -+#define ITE_RXDCR_PER_10000_STEP 625 -+ -+/* high speed carrier freq values */ -+#define ITE_CFQ_400 0x03 -+#define ITE_CFQ_450 0x08 -+#define ITE_CFQ_480 0x0b -+#define ITE_CFQ_500 0x0d -+ -+/* values for pulse widths */ -+#define ITE_TXMPW_A 0x02 -+#define ITE_TXMPW_B 0x03 -+#define ITE_TXMPW_C 0x04 -+#define ITE_TXMPW_D 0x05 -+#define ITE_TXMPW_E 0x06 -+ -+/* values for demodulator carrier range allowance */ -+#define ITE_RXDCR_DEFAULT 0x01 /* default carrier range */ -+#define ITE_RXDCR_MAX 0x07 /* default carrier range */ -+ -+/* DR TX bits */ -+#define ITE_TX_PULSE 0x00 -+#define ITE_TX_SPACE 0x80 -+#define ITE_TX_MAX_RLE 0x80 -+#define ITE_TX_RLE_MASK 0x7f -+ -+/* -+ * IT8712F -+ * -+ * hardware data obtained from: -+ * -+ * IT8712F -+ * Environment Control – Low Pin Count Input / Output -+ * (EC - LPC I/O) -+ * Preliminary Specification V0. 81 -+ */ -+ -+/* register offsets */ -+#define IT87_DR 0x00 /* data register */ -+#define IT87_IER 0x01 /* interrupt enable register */ -+#define IT87_RCR 0x02 /* receiver control register */ -+#define IT87_TCR1 0x03 /* transmitter control register 1 */ -+#define IT87_TCR2 0x04 /* transmitter control register 2 */ -+#define IT87_TSR 0x05 /* transmitter status register */ -+#define IT87_RSR 0x06 /* receiver status register */ -+#define IT87_BDLR 0x05 /* baud rate divisor low byte register */ -+#define IT87_BDHR 0x06 /* baud rate divisor high byte register */ -+#define IT87_IIR 0x07 /* interrupt identification register */ -+ -+#define IT87_IOREG_LENGTH 0x08 /* length of register file */ -+ -+/* IER bits */ -+#define IT87_TLDLIE 0x01 /* transmitter low data interrupt enable */ -+#define IT87_RDAIE 0x02 /* receiver data available interrupt enable */ -+#define IT87_RFOIE 0x04 /* receiver FIFO overrun interrupt enable */ -+#define IT87_IEC 0x08 /* interrupt enable control */ -+#define IT87_BR 0x10 /* baud rate register enable */ -+#define IT87_RESET 0x20 /* reset */ -+ -+/* RCR bits */ -+#define IT87_RXDCR 0x07 /* receiver demodulation carrier range mask */ -+#define IT87_RXACT 0x08 /* receiver active */ -+#define IT87_RXEND 0x10 /* receiver demodulation enable */ -+#define IT87_RXEN 0x20 /* receiver enable */ -+#define IT87_HCFS 0x40 /* high-speed carrier frequency select */ -+#define IT87_RDWOS 0x80 /* receiver data without sync */ -+ -+/* TCR1 bits */ -+#define IT87_TXMPM 0x03 /* transmitter modulation pulse mode mask */ -+#define IT87_TXMPM_DEFAULT 0x00 /* modulation pulse mode default */ -+#define IT87_TXENDF 0x04 /* transmitter deferral */ -+#define IT87_TXRLE 0x08 /* transmitter run length enable */ -+#define IT87_FIFOTL 0x30 /* FIFO level threshold mask */ -+#define IT87_FIFOTL_DEFAULT 0x20 /* FIFO level threshold default -+ * 0x00 -> 1, 0x10 -> 7, 0x20 -> 17, -+ * 0x30 -> 25 */ -+#define IT87_ILE 0x40 /* internal loopback enable */ -+#define IT87_FIFOCLR 0x80 /* FIFO clear bit */ -+ -+/* TCR2 bits */ -+#define IT87_TXMPW 0x07 /* transmitter modulation pulse width mask */ -+#define IT87_TXMPW_DEFAULT 0x04 /* default modulation pulse width */ -+#define IT87_CFQ 0xf8 /* carrier frequency mask */ -+#define IT87_CFQ_SHIFT 3 /* carrier frequency bit shift */ -+ -+/* TSR bits */ -+#define IT87_TXFBC 0x3f /* transmitter FIFO byte count mask */ -+ -+/* RSR bits */ -+#define IT87_RXFBC 0x3f /* receiver FIFO byte count mask */ -+#define IT87_RXFTO 0x80 /* receiver FIFO time-out */ -+ -+/* IIR bits */ -+#define IT87_IP 0x01 /* interrupt pending */ -+#define IT87_II 0x06 /* interrupt identification mask */ -+#define IT87_II_NOINT 0x00 /* no interrupt */ -+#define IT87_II_TXLDL 0x02 /* transmitter low data level */ -+#define IT87_II_RXDS 0x04 /* receiver data stored */ -+#define IT87_II_RXFO 0x06 /* receiver FIFO overrun */ -+ -+/* -+ * IT8512E/F -+ * -+ * Hardware data obtained from: -+ * -+ * IT8512E/F -+ * Embedded Controller -+ * Preliminary Specification V0.4.1 -+ * -+ * Note that the CIR registers are not directly available to the host, because -+ * they only are accessible to the integrated microcontroller. Thus, in order -+ * use it, some kind of bridging is required. As the bridging may depend on -+ * the controller firmware in use, we are going to use the PNP ID in order to -+ * determine the strategy and ports available. See after these generic -+ * IT8512E/F register definitions for register definitions for those -+ * strategies. -+ */ -+ -+/* register offsets */ -+#define IT85_C0DR 0x00 /* data register */ -+#define IT85_C0MSTCR 0x01 /* master control register */ -+#define IT85_C0IER 0x02 /* interrupt enable register */ -+#define IT85_C0IIR 0x03 /* interrupt identification register */ -+#define IT85_C0CFR 0x04 /* carrier frequency register */ -+#define IT85_C0RCR 0x05 /* receiver control register */ -+#define IT85_C0TCR 0x06 /* transmitter control register */ -+#define IT85_C0SCK 0x07 /* slow clock control register */ -+#define IT85_C0BDLR 0x08 /* baud rate divisor low byte register */ -+#define IT85_C0BDHR 0x09 /* baud rate divisor high byte register */ -+#define IT85_C0TFSR 0x0a /* transmitter FIFO status register */ -+#define IT85_C0RFSR 0x0b /* receiver FIFO status register */ -+#define IT85_C0WCL 0x0d /* wakeup code length register */ -+#define IT85_C0WCR 0x0e /* wakeup code read/write register */ -+#define IT85_C0WPS 0x0f /* wakeup power control/status register */ -+ -+#define IT85_IOREG_LENGTH 0x10 /* length of register file */ -+ -+/* C0MSTCR bits */ -+#define IT85_RESET 0x01 /* reset */ -+#define IT85_FIFOCLR 0x02 /* FIFO clear bit */ -+#define IT85_FIFOTL 0x0c /* FIFO level threshold mask */ -+#define IT85_FIFOTL_DEFAULT 0x08 /* FIFO level threshold default -+ * 0x00 -> 1, 0x04 -> 7, 0x08 -> 17, -+ * 0x0c -> 25 */ -+#define IT85_ILE 0x10 /* internal loopback enable */ -+#define IT85_ILSEL 0x20 /* internal loopback select */ -+ -+/* C0IER bits */ -+#define IT85_TLDLIE 0x01 /* TX low data level interrupt enable */ -+#define IT85_RDAIE 0x02 /* RX data available interrupt enable */ -+#define IT85_RFOIE 0x04 /* RX FIFO overrun interrupt enable */ -+#define IT85_IEC 0x80 /* interrupt enable function control */ -+ -+/* C0IIR bits */ -+#define IT85_TLDLI 0x01 /* transmitter low data level interrupt */ -+#define IT85_RDAI 0x02 /* receiver data available interrupt */ -+#define IT85_RFOI 0x04 /* receiver FIFO overrun interrupt */ -+#define IT85_NIP 0x80 /* no interrupt pending */ -+ -+/* C0CFR bits */ -+#define IT85_CFQ 0x1f /* carrier frequency mask */ -+#define IT85_HCFS 0x20 /* high speed carrier frequency select */ -+ -+/* C0RCR bits */ -+#define IT85_RXDCR 0x07 /* receiver demodulation carrier range mask */ -+#define IT85_RXACT 0x08 /* receiver active */ -+#define IT85_RXEND 0x10 /* receiver demodulation enable */ -+#define IT85_RDWOS 0x20 /* receiver data without sync */ -+#define IT85_RXEN 0x80 /* receiver enable */ -+ -+/* C0TCR bits */ -+#define IT85_TXMPW 0x07 /* transmitter modulation pulse width mask */ -+#define IT85_TXMPW_DEFAULT 0x04 /* default modulation pulse width */ -+#define IT85_TXMPM 0x18 /* transmitter modulation pulse mode mask */ -+#define IT85_TXMPM_DEFAULT 0x00 /* modulation pulse mode default */ -+#define IT85_TXENDF 0x20 /* transmitter deferral */ -+#define IT85_TXRLE 0x40 /* transmitter run length enable */ -+ -+/* C0SCK bits */ -+#define IT85_SCKS 0x01 /* slow clock select */ -+#define IT85_TXDCKG 0x02 /* TXD clock gating */ -+#define IT85_DLL1P8E 0x04 /* DLL 1.8432M enable */ -+#define IT85_DLLTE 0x08 /* DLL test enable */ -+#define IT85_BRCM 0x70 /* baud rate count mode */ -+#define IT85_DLLOCK 0x80 /* DLL lock */ -+ -+/* C0TFSR bits */ -+#define IT85_TXFBC 0x3f /* transmitter FIFO count mask */ -+ -+/* C0RFSR bits */ -+#define IT85_RXFBC 0x3f /* receiver FIFO count mask */ -+#define IT85_RXFTO 0x80 /* receiver FIFO time-out */ -+ -+/* C0WCL bits */ -+#define IT85_WCL 0x3f /* wakeup code length mask */ -+ -+/* C0WPS bits */ -+#define IT85_CIRPOSIE 0x01 /* power on/off status interrupt enable */ -+#define IT85_CIRPOIS 0x02 /* power on/off interrupt status */ -+#define IT85_CIRPOII 0x04 /* power on/off interrupt identification */ -+#define IT85_RCRST 0x10 /* wakeup code reading counter reset bit */ -+#define IT85_WCRST 0x20 /* wakeup code writing counter reset bit */ -+ -+/* -+ * ITE8708 -+ * -+ * Hardware data obtained from hacked driver for IT8512 in this forum post: -+ * -+ * http://ubuntuforums.org/showthread.php?t=1028640 -+ * -+ * Although there's no official documentation for that driver, analysis would -+ * suggest that it maps the 16 registers of IT8512 onto two 8-register banks, -+ * selectable by a single bank-select bit that's mapped onto both banks. The -+ * IT8512 registers are mapped in a different order, so that the first bank -+ * maps the ones that are used more often, and two registers that share a -+ * reserved high-order bit are placed at the same offset in both banks in -+ * order to reuse the reserved bit as the bank select bit. -+ */ -+ -+/* register offsets */ -+ -+/* mapped onto both banks */ -+#define IT8708_BANKSEL 0x07 /* bank select register */ -+#define IT8708_HRAE 0x80 /* high registers access enable */ -+ -+/* mapped onto the low bank */ -+#define IT8708_C0DR 0x00 /* data register */ -+#define IT8708_C0MSTCR 0x01 /* master control register */ -+#define IT8708_C0IER 0x02 /* interrupt enable register */ -+#define IT8708_C0IIR 0x03 /* interrupt identification register */ -+#define IT8708_C0RFSR 0x04 /* receiver FIFO status register */ -+#define IT8708_C0RCR 0x05 /* receiver control register */ -+#define IT8708_C0TFSR 0x06 /* transmitter FIFO status register */ -+#define IT8708_C0TCR 0x07 /* transmitter control register */ -+ -+/* mapped onto the high bank */ -+#define IT8708_C0BDLR 0x01 /* baud rate divisor low byte register */ -+#define IT8708_C0BDHR 0x02 /* baud rate divisor high byte register */ -+#define IT8708_C0CFR 0x04 /* carrier frequency register */ -+ -+/* registers whose bank mapping we don't know, since they weren't being used -+ * in the hacked driver... most probably they belong to the high bank too, -+ * since they fit in the holes the other registers leave */ -+#define IT8708_C0SCK 0x03 /* slow clock control register */ -+#define IT8708_C0WCL 0x05 /* wakeup code length register */ -+#define IT8708_C0WCR 0x06 /* wakeup code read/write register */ -+#define IT8708_C0WPS 0x07 /* wakeup power control/status register */ -+ -+#define IT8708_IOREG_LENGTH 0x08 /* length of register file */ -+ -+/* two more registers that are defined in the hacked driver, but can't be -+ * found in the data sheets; no idea what they are or how they are accessed, -+ * since the hacked driver doesn't seem to use them */ -+#define IT8708_CSCRR 0x00 -+#define IT8708_CGPINTR 0x01 -+ -+/* CSCRR bits */ -+#define IT8708_CSCRR_SCRB 0x3f -+#define IT8708_CSCRR_PM 0x80 -+ -+/* CGPINTR bits */ -+#define IT8708_CGPINT 0x01 -+ -+/* -+ * ITE8709 -+ * -+ * Hardware interfacing data obtained from the original lirc_ite8709 driver. -+ * Verbatim from its sources: -+ * -+ * The ITE8709 device seems to be the combination of IT8512 superIO chip and -+ * a specific firmware running on the IT8512's embedded micro-controller. -+ * In addition of the embedded micro-controller, the IT8512 chip contains a -+ * CIR module and several other modules. A few modules are directly accessible -+ * by the host CPU, but most of them are only accessible by the -+ * micro-controller. The CIR module is only accessible by the -+ * micro-controller. -+ * -+ * The battery-backed SRAM module is accessible by the host CPU and the -+ * micro-controller. So one of the MC's firmware role is to act as a bridge -+ * between the host CPU and the CIR module. The firmware implements a kind of -+ * communication protocol using the SRAM module as a shared memory. The IT8512 -+ * specification is publicly available on ITE's web site, but the -+ * communication protocol is not, so it was reverse-engineered. -+ */ -+ -+/* register offsets */ -+#define IT8709_RAM_IDX 0x00 /* index into the SRAM module bytes */ -+#define IT8709_RAM_VAL 0x01 /* read/write data to the indexed byte */ -+ -+#define IT8709_IOREG_LENGTH 0x02 /* length of register file */ -+ -+/* register offsets inside the SRAM module */ -+#define IT8709_MODE 0x1a /* request/ack byte */ -+#define IT8709_REG_IDX 0x1b /* index of the CIR register to access */ -+#define IT8709_REG_VAL 0x1c /* value read/to be written */ -+#define IT8709_IIR 0x1e /* interrupt identification register */ -+#define IT8709_RFSR 0x1f /* receiver FIFO status register */ -+#define IT8709_FIFO 0x20 /* start of in RAM RX FIFO copy */ -+ -+/* MODE values */ -+#define IT8709_IDLE 0x00 -+#define IT8709_WRITE 0x01 -+#define IT8709_READ 0x02 -diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile -index cb72121..85cac7d 100644 ---- a/drivers/media/rc/keymaps/Makefile -+++ b/drivers/media/rc/keymaps/Makefile -@@ -37,7 +37,6 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ - rc-gadmei-rm008z.o \ - rc-genius-tvgo-a11mce.o \ - rc-gotview7135.o \ -- rc-hauppauge-new.o \ - rc-imon-mce.o \ - rc-imon-pad.o \ - rc-iodata-bctv7e.o \ -@@ -68,8 +67,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ - rc-proteus-2309.o \ - rc-purpletv.o \ - rc-pv951.o \ -- rc-rc5-hauppauge-new.o \ -- rc-rc5-tv.o \ -+ rc-hauppauge.o \ - rc-rc6-mce.o \ - rc-real-audio-220-32-keys.o \ - rc-streamzap.o \ -diff --git a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c -index 136d395..9a8752f 100644 ---- a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c -+++ b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c -@@ -50,9 +50,9 @@ static struct rc_map_table adstech_dvb_t_pci[] = { - { 0x13, KEY_TUNER }, /* Live */ - { 0x0a, KEY_A }, - { 0x12, KEY_B }, -- { 0x03, KEY_PROG1 }, /* 1 */ -- { 0x01, KEY_PROG2 }, /* 2 */ -- { 0x00, KEY_PROG3 }, /* 3 */ -+ { 0x03, KEY_RED }, /* 1 */ -+ { 0x01, KEY_GREEN }, /* 2 */ -+ { 0x00, KEY_YELLOW }, /* 3 */ - { 0x06, KEY_DVD }, - { 0x48, KEY_AUX }, /* Photo */ - { 0x40, KEY_VIDEO }, -diff --git a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c -index 3ddb41b..c25809d 100644 ---- a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c -+++ b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c -@@ -26,12 +26,12 @@ static struct rc_map_table avermedia_dvbt[] = { - { 0x16, KEY_8 }, /* '8' / 'down arrow' */ - { 0x36, KEY_9 }, /* '9' */ - -- { 0x20, KEY_LIST }, /* 'source' */ -+ { 0x20, KEY_VIDEO }, /* 'source' */ - { 0x10, KEY_TEXT }, /* 'teletext' */ - { 0x00, KEY_POWER }, /* 'power' */ - { 0x04, KEY_AUDIO }, /* 'audio' */ - { 0x06, KEY_ZOOM }, /* 'full screen' */ -- { 0x18, KEY_VIDEO }, /* 'display' */ -+ { 0x18, KEY_SWITCHVIDEOMODE }, /* 'display' */ - { 0x38, KEY_SEARCH }, /* 'loop' */ - { 0x08, KEY_INFO }, /* 'preview' */ - { 0x2a, KEY_REWIND }, /* 'backward <<' */ -diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c -index 357fea5..3d2cbe4 100644 ---- a/drivers/media/rc/keymaps/rc-avermedia-m135a.c -+++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c -@@ -108,7 +108,7 @@ static struct rc_map_table avermedia_m135a[] = { - { 0x0414, KEY_TEXT }, - { 0x0415, KEY_EPG }, - { 0x041a, KEY_TV2 }, /* PIP */ -- { 0x041b, KEY_MHP }, /* Snapshot */ -+ { 0x041b, KEY_CAMERA }, /* Snapshot */ - - { 0x0417, KEY_RECORD }, - { 0x0416, KEY_PLAYPAUSE }, -diff --git a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c -index e694e6e..8cd7f28 100644 ---- a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c -+++ b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c -@@ -56,7 +56,7 @@ static struct rc_map_table avermedia_m733a_rm_k6[] = { - { 0x0414, KEY_TEXT }, - { 0x0415, KEY_EPG }, - { 0x041a, KEY_TV2 }, /* PIP */ -- { 0x041b, KEY_MHP }, /* Snapshot */ -+ { 0x041b, KEY_CAMERA }, /* Snapshot */ - - { 0x0417, KEY_RECORD }, - { 0x0416, KEY_PLAYPAUSE }, -diff --git a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c -index f4ca1ff..9d68af2 100644 ---- a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c -+++ b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c -@@ -31,7 +31,7 @@ static struct rc_map_table avermedia_rm_ks[] = { - { 0x0505, KEY_VOLUMEDOWN }, - { 0x0506, KEY_MUTE }, - { 0x0507, KEY_RIGHT }, -- { 0x0508, KEY_PROG1 }, -+ { 0x0508, KEY_RED }, - { 0x0509, KEY_1 }, - { 0x050a, KEY_2 }, - { 0x050b, KEY_3 }, -diff --git a/drivers/media/rc/keymaps/rc-behold-columbus.c b/drivers/media/rc/keymaps/rc-behold-columbus.c -index 4b787fa..8bf058f 100644 ---- a/drivers/media/rc/keymaps/rc-behold-columbus.c -+++ b/drivers/media/rc/keymaps/rc-behold-columbus.c -@@ -28,7 +28,7 @@ static struct rc_map_table behold_columbus[] = { - * */ - - { 0x13, KEY_MUTE }, -- { 0x11, KEY_PROPS }, -+ { 0x11, KEY_VIDEO }, - { 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */ - { 0x12, KEY_POWER }, - -diff --git a/drivers/media/rc/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c -index 0ee1f14..c909a23 100644 ---- a/drivers/media/rc/keymaps/rc-behold.c -+++ b/drivers/media/rc/keymaps/rc-behold.c -@@ -97,7 +97,7 @@ static struct rc_map_table behold[] = { - { 0x6b861a, KEY_STOP }, - { 0x6b860e, KEY_TEXT }, - { 0x6b861f, KEY_RED }, /*XXX KEY_AUDIO */ -- { 0x6b861e, KEY_YELLOW }, /*XXX KEY_SOURCE */ -+ { 0x6b861e, KEY_VIDEO }, - - /* 0x1d 0x13 0x19 * - * SLEEP PREVIEW DVB * -diff --git a/drivers/media/rc/keymaps/rc-budget-ci-old.c b/drivers/media/rc/keymaps/rc-budget-ci-old.c -index 97fc386..2f66e43 100644 ---- a/drivers/media/rc/keymaps/rc-budget-ci-old.c -+++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c -@@ -12,7 +12,8 @@ - - #include - --/* From reading the following remotes: -+/* -+ * From reading the following remotes: - * Zenith Universal 7 / TV Mode 807 / VCR Mode 837 - * Hauppauge (from NOVA-CI-s box product) - * This is a "middle of the road" approach, differences are noted -diff --git a/drivers/media/rc/keymaps/rc-cinergy.c b/drivers/media/rc/keymaps/rc-cinergy.c -index 99520ff..cf3a6bf 100644 ---- a/drivers/media/rc/keymaps/rc-cinergy.c -+++ b/drivers/media/rc/keymaps/rc-cinergy.c -@@ -25,7 +25,7 @@ static struct rc_map_table cinergy[] = { - { 0x09, KEY_9 }, - - { 0x0a, KEY_POWER }, -- { 0x0b, KEY_PROG1 }, /* app */ -+ { 0x0b, KEY_MEDIA }, /* app */ - { 0x0c, KEY_ZOOM }, /* zoom/fullscreen */ - { 0x0d, KEY_CHANNELUP }, /* channel */ - { 0x0e, KEY_CHANNELDOWN }, /* channel- */ -diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c -index 43912bd..82c0200 100644 ---- a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c -+++ b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c -@@ -32,7 +32,7 @@ static struct rc_map_table dntv_live_dvb_t[] = { - { 0x0c, KEY_SEARCH }, /* scan */ - { 0x0d, KEY_STOP }, - { 0x0e, KEY_PAUSE }, -- { 0x0f, KEY_LIST }, /* source */ -+ { 0x0f, KEY_VIDEO }, /* source */ - - { 0x10, KEY_MUTE }, - { 0x11, KEY_REWIND }, /* backward << */ -diff --git a/drivers/media/rc/keymaps/rc-encore-enltv.c b/drivers/media/rc/keymaps/rc-encore-enltv.c -index afa4e92..e56ac6e 100644 ---- a/drivers/media/rc/keymaps/rc-encore-enltv.c -+++ b/drivers/media/rc/keymaps/rc-encore-enltv.c -@@ -24,7 +24,7 @@ static struct rc_map_table encore_enltv[] = { - { 0x1e, KEY_TV }, - { 0x00, KEY_VIDEO }, - { 0x01, KEY_AUDIO }, /* music */ -- { 0x02, KEY_MHP }, /* picture */ -+ { 0x02, KEY_CAMERA }, /* picture */ - - { 0x1f, KEY_1 }, - { 0x03, KEY_2 }, -@@ -77,7 +77,7 @@ static struct rc_map_table encore_enltv[] = { - { 0x50, KEY_SLEEP }, /* shutdown */ - { 0x51, KEY_MODE }, /* stereo > main */ - { 0x52, KEY_SELECT }, /* stereo > sap */ -- { 0x53, KEY_PROG1 }, /* teletext */ -+ { 0x53, KEY_TEXT }, /* teletext */ - - - { 0x59, KEY_RED }, /* AP1 */ -diff --git a/drivers/media/rc/keymaps/rc-encore-enltv2.c b/drivers/media/rc/keymaps/rc-encore-enltv2.c -index 7d5b00e..b6264f1 100644 ---- a/drivers/media/rc/keymaps/rc-encore-enltv2.c -+++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c -@@ -32,7 +32,7 @@ static struct rc_map_table encore_enltv2[] = { - { 0x64, KEY_LAST }, /* +100 */ - { 0x4e, KEY_AGAIN }, /* Recall */ - -- { 0x6c, KEY_SWITCHVIDEOMODE }, /* Video Source */ -+ { 0x6c, KEY_VIDEO }, /* Video Source */ - { 0x5e, KEY_MENU }, - { 0x56, KEY_SCREEN }, - { 0x7a, KEY_SETUP }, -diff --git a/drivers/media/rc/keymaps/rc-flydvb.c b/drivers/media/rc/keymaps/rc-flydvb.c -index aea2f4a..a8b0f66 100644 ---- a/drivers/media/rc/keymaps/rc-flydvb.c -+++ b/drivers/media/rc/keymaps/rc-flydvb.c -@@ -37,8 +37,8 @@ static struct rc_map_table flydvb[] = { - { 0x13, KEY_CHANNELDOWN }, /* CH- */ - { 0x1d, KEY_ENTER }, /* Enter */ - -- { 0x1a, KEY_MODE }, /* PIP */ -- { 0x18, KEY_TUNER }, /* Source */ -+ { 0x1a, KEY_TV2 }, /* PIP */ -+ { 0x18, KEY_VIDEO }, /* Source */ - - { 0x1e, KEY_RECORD }, /* Record/Pause */ - { 0x15, KEY_ANGLE }, /* Swap (no label on key) */ -diff --git a/drivers/media/rc/keymaps/rc-hauppauge-new.c b/drivers/media/rc/keymaps/rc-hauppauge-new.c -deleted file mode 100644 -index bd11da4..0000000 ---- a/drivers/media/rc/keymaps/rc-hauppauge-new.c -+++ /dev/null -@@ -1,100 +0,0 @@ --/* hauppauge-new.h - Keytable for hauppauge_new Remote Controller -- * -- * keymap imported from ir-keymaps.c -- * -- * Copyright (c) 2010 by Mauro Carvalho Chehab -- * -- * 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; either version 2 of the License, or -- * (at your option) any later version. -- */ -- --#include -- --/* Hauppauge: the newer, gray remotes (seems there are multiple -- * slightly different versions), shipped with cx88+ivtv cards. -- * almost rc5 coding, but some non-standard keys */ -- --static struct rc_map_table hauppauge_new[] = { -- /* Keys 0 to 9 */ -- { 0x00, KEY_0 }, -- { 0x01, KEY_1 }, -- { 0x02, KEY_2 }, -- { 0x03, KEY_3 }, -- { 0x04, KEY_4 }, -- { 0x05, KEY_5 }, -- { 0x06, KEY_6 }, -- { 0x07, KEY_7 }, -- { 0x08, KEY_8 }, -- { 0x09, KEY_9 }, -- -- { 0x0a, KEY_TEXT }, /* keypad asterisk as well */ -- { 0x0b, KEY_RED }, /* red button */ -- { 0x0c, KEY_RADIO }, -- { 0x0d, KEY_MENU }, -- { 0x0e, KEY_SUBTITLE }, /* also the # key */ -- { 0x0f, KEY_MUTE }, -- { 0x10, KEY_VOLUMEUP }, -- { 0x11, KEY_VOLUMEDOWN }, -- { 0x12, KEY_PREVIOUS }, /* previous channel */ -- { 0x14, KEY_UP }, -- { 0x15, KEY_DOWN }, -- { 0x16, KEY_LEFT }, -- { 0x17, KEY_RIGHT }, -- { 0x18, KEY_VIDEO }, /* Videos */ -- { 0x19, KEY_AUDIO }, /* Music */ -- /* 0x1a: Pictures - presume this means -- "Multimedia Home Platform" - -- no "PICTURES" key in input.h -- */ -- { 0x1a, KEY_MHP }, -- -- { 0x1b, KEY_EPG }, /* Guide */ -- { 0x1c, KEY_TV }, -- { 0x1e, KEY_NEXTSONG }, /* skip >| */ -- { 0x1f, KEY_EXIT }, /* back/exit */ -- { 0x20, KEY_CHANNELUP }, /* channel / program + */ -- { 0x21, KEY_CHANNELDOWN }, /* channel / program - */ -- { 0x22, KEY_CHANNEL }, /* source (old black remote) */ -- { 0x24, KEY_PREVIOUSSONG }, /* replay |< */ -- { 0x25, KEY_ENTER }, /* OK */ -- { 0x26, KEY_SLEEP }, /* minimize (old black remote) */ -- { 0x29, KEY_BLUE }, /* blue key */ -- { 0x2e, KEY_GREEN }, /* green button */ -- { 0x30, KEY_PAUSE }, /* pause */ -- { 0x32, KEY_REWIND }, /* backward << */ -- { 0x34, KEY_FASTFORWARD }, /* forward >> */ -- { 0x35, KEY_PLAY }, -- { 0x36, KEY_STOP }, -- { 0x37, KEY_RECORD }, /* recording */ -- { 0x38, KEY_YELLOW }, /* yellow key */ -- { 0x3b, KEY_SELECT }, /* top right button */ -- { 0x3c, KEY_ZOOM }, /* full */ -- { 0x3d, KEY_POWER }, /* system power (green button) */ --}; -- --static struct rc_map_list hauppauge_new_map = { -- .map = { -- .scan = hauppauge_new, -- .size = ARRAY_SIZE(hauppauge_new), -- .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ -- .name = RC_MAP_HAUPPAUGE_NEW, -- } --}; -- --static int __init init_rc_map_hauppauge_new(void) --{ -- return rc_map_register(&hauppauge_new_map); --} -- --static void __exit exit_rc_map_hauppauge_new(void) --{ -- rc_map_unregister(&hauppauge_new_map); --} -- --module_init(init_rc_map_hauppauge_new) --module_exit(exit_rc_map_hauppauge_new) -- --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Mauro Carvalho Chehab "); -diff --git a/drivers/media/rc/keymaps/rc-hauppauge.c b/drivers/media/rc/keymaps/rc-hauppauge.c -new file mode 100644 -index 0000000..cd3db77 ---- /dev/null -+++ b/drivers/media/rc/keymaps/rc-hauppauge.c -@@ -0,0 +1,241 @@ -+/* rc-hauppauge.c - Keytable for Hauppauge Remote Controllers -+ * -+ * keymap imported from ir-keymaps.c -+ * -+ * This map currently contains the code for four different RCs: -+ * - New Hauppauge Gray; -+ * - Old Hauppauge Gray (with a golden screen for media keys); -+ * - Hauppauge Black; -+ * - DSR-0112 remote bundled with Haupauge MiniStick. -+ * -+ * Copyright (c) 2010-2011 by Mauro Carvalho Chehab -+ * -+ * 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; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+#include -+ -+/* -+ * Hauppauge:the newer, gray remotes (seems there are multiple -+ * slightly different versions), shipped with cx88+ivtv cards. -+ * -+ * This table contains the complete RC5 code, instead of just the data part -+ */ -+ -+static struct rc_map_table rc5_hauppauge_new[] = { -+ /* -+ * Remote Controller Hauppauge Gray found on modern devices -+ * Keycodes start with address = 0x1e -+ */ -+ -+ { 0x1e3b, KEY_SELECT }, /* GO / house symbol */ -+ { 0x1e3d, KEY_POWER2 }, /* system power (green button) */ -+ -+ { 0x1e1c, KEY_TV }, -+ { 0x1e18, KEY_VIDEO }, /* Videos */ -+ { 0x1e19, KEY_AUDIO }, /* Music */ -+ { 0x1e1a, KEY_CAMERA }, /* Pictures */ -+ -+ { 0x1e1b, KEY_EPG }, /* Guide */ -+ { 0x1e0c, KEY_RADIO }, -+ -+ { 0x1e14, KEY_UP }, -+ { 0x1e15, KEY_DOWN }, -+ { 0x1e16, KEY_LEFT }, -+ { 0x1e17, KEY_RIGHT }, -+ { 0x1e25, KEY_OK }, /* OK */ -+ -+ { 0x1e1f, KEY_EXIT }, /* back/exit */ -+ { 0x1e0d, KEY_MENU }, -+ -+ { 0x1e10, KEY_VOLUMEUP }, -+ { 0x1e11, KEY_VOLUMEDOWN }, -+ -+ { 0x1e12, KEY_PREVIOUS }, /* previous channel */ -+ { 0x1e0f, KEY_MUTE }, -+ -+ { 0x1e20, KEY_CHANNELUP }, /* channel / program + */ -+ { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */ -+ -+ { 0x1e37, KEY_RECORD }, /* recording */ -+ { 0x1e36, KEY_STOP }, -+ -+ { 0x1e32, KEY_REWIND }, /* backward << */ -+ { 0x1e35, KEY_PLAY }, -+ { 0x1e34, KEY_FASTFORWARD }, /* forward >> */ -+ -+ { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */ -+ { 0x1e30, KEY_PAUSE }, /* pause */ -+ { 0x1e1e, KEY_NEXTSONG }, /* skip >| */ -+ -+ { 0x1e01, KEY_1 }, -+ { 0x1e02, KEY_2 }, -+ { 0x1e03, KEY_3 }, -+ -+ { 0x1e04, KEY_4 }, -+ { 0x1e05, KEY_5 }, -+ { 0x1e06, KEY_6 }, -+ -+ { 0x1e07, KEY_7 }, -+ { 0x1e08, KEY_8 }, -+ { 0x1e09, KEY_9 }, -+ -+ { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */ -+ { 0x1e00, KEY_0 }, -+ { 0x1e0e, KEY_SUBTITLE }, /* also the Pound key (#) */ -+ -+ { 0x1e0b, KEY_RED }, /* red button */ -+ { 0x1e2e, KEY_GREEN }, /* green button */ -+ { 0x1e38, KEY_YELLOW }, /* yellow key */ -+ { 0x1e29, KEY_BLUE }, /* blue key */ -+ -+ /* -+ * Old Remote Controller Hauppauge Gray with a golden screen -+ * Keycodes start with address = 0x1f -+ */ -+ { 0x1f3d, KEY_POWER2 }, /* system power (green button) */ -+ { 0x1f3b, KEY_SELECT }, /* GO */ -+ -+ /* Keys 0 to 9 */ -+ { 0x1f00, KEY_0 }, -+ { 0x1f01, KEY_1 }, -+ { 0x1f02, KEY_2 }, -+ { 0x1f03, KEY_3 }, -+ { 0x1f04, KEY_4 }, -+ { 0x1f05, KEY_5 }, -+ { 0x1f06, KEY_6 }, -+ { 0x1f07, KEY_7 }, -+ { 0x1f08, KEY_8 }, -+ { 0x1f09, KEY_9 }, -+ -+ { 0x1f1f, KEY_EXIT }, /* back/exit */ -+ { 0x1f0d, KEY_MENU }, -+ -+ { 0x1f10, KEY_VOLUMEUP }, -+ { 0x1f11, KEY_VOLUMEDOWN }, -+ { 0x1f20, KEY_CHANNELUP }, /* channel / program + */ -+ { 0x1f21, KEY_CHANNELDOWN }, /* channel / program - */ -+ { 0x1f25, KEY_ENTER }, /* OK */ -+ -+ { 0x1f0b, KEY_RED }, /* red button */ -+ { 0x1f2e, KEY_GREEN }, /* green button */ -+ { 0x1f38, KEY_YELLOW }, /* yellow key */ -+ { 0x1f29, KEY_BLUE }, /* blue key */ -+ -+ { 0x1f0f, KEY_MUTE }, -+ { 0x1f0c, KEY_RADIO }, /* There's no indicator on this key */ -+ { 0x1f3c, KEY_ZOOM }, /* full */ -+ -+ { 0x1f32, KEY_REWIND }, /* backward << */ -+ { 0x1f35, KEY_PLAY }, -+ { 0x1f34, KEY_FASTFORWARD }, /* forward >> */ -+ -+ { 0x1f37, KEY_RECORD }, /* recording */ -+ { 0x1f36, KEY_STOP }, -+ { 0x1f30, KEY_PAUSE }, /* pause */ -+ -+ { 0x1f24, KEY_PREVIOUSSONG }, /* replay |< */ -+ { 0x1f1e, KEY_NEXTSONG }, /* skip >| */ -+ -+ /* -+ * Keycodes for DSR-0112 remote bundled with Haupauge MiniStick -+ * Keycodes start with address = 0x1d -+ */ -+ { 0x1d00, KEY_0 }, -+ { 0x1d01, KEY_1 }, -+ { 0x1d02, KEY_2 }, -+ { 0x1d03, KEY_3 }, -+ { 0x1d04, KEY_4 }, -+ { 0x1d05, KEY_5 }, -+ { 0x1d06, KEY_6 }, -+ { 0x1d07, KEY_7 }, -+ { 0x1d08, KEY_8 }, -+ { 0x1d09, KEY_9 }, -+ { 0x1d0a, KEY_TEXT }, -+ { 0x1d0d, KEY_MENU }, -+ { 0x1d0f, KEY_MUTE }, -+ { 0x1d10, KEY_VOLUMEUP }, -+ { 0x1d11, KEY_VOLUMEDOWN }, -+ { 0x1d12, KEY_PREVIOUS }, /* Prev.Ch .. ??? */ -+ { 0x1d14, KEY_UP }, -+ { 0x1d15, KEY_DOWN }, -+ { 0x1d16, KEY_LEFT }, -+ { 0x1d17, KEY_RIGHT }, -+ { 0x1d1c, KEY_TV }, -+ { 0x1d1e, KEY_NEXT }, /* >| */ -+ { 0x1d1f, KEY_EXIT }, -+ { 0x1d20, KEY_CHANNELUP }, -+ { 0x1d21, KEY_CHANNELDOWN }, -+ { 0x1d24, KEY_LAST }, /* <| */ -+ { 0x1d25, KEY_OK }, -+ { 0x1d30, KEY_PAUSE }, -+ { 0x1d32, KEY_REWIND }, -+ { 0x1d34, KEY_FASTFORWARD }, -+ { 0x1d35, KEY_PLAY }, -+ { 0x1d36, KEY_STOP }, -+ { 0x1d37, KEY_RECORD }, -+ { 0x1d3b, KEY_GOTO }, -+ { 0x1d3d, KEY_POWER }, -+ { 0x1d3f, KEY_HOME }, -+ -+ /* -+ * Keycodes for the old Black Remote Controller -+ * This one also uses RC-5 protocol -+ * Keycodes start with address = 0x00 -+ */ -+ { 0x001f, KEY_TV }, -+ { 0x0020, KEY_CHANNELUP }, -+ { 0x000c, KEY_RADIO }, -+ -+ { 0x0011, KEY_VOLUMEDOWN }, -+ { 0x002e, KEY_ZOOM }, /* full screen */ -+ { 0x0010, KEY_VOLUMEUP }, -+ -+ { 0x000d, KEY_MUTE }, -+ { 0x0021, KEY_CHANNELDOWN }, -+ { 0x0022, KEY_VIDEO }, /* source */ -+ -+ { 0x0001, KEY_1 }, -+ { 0x0002, KEY_2 }, -+ { 0x0003, KEY_3 }, -+ -+ { 0x0004, KEY_4 }, -+ { 0x0005, KEY_5 }, -+ { 0x0006, KEY_6 }, -+ -+ { 0x0007, KEY_7 }, -+ { 0x0008, KEY_8 }, -+ { 0x0009, KEY_9 }, -+ -+ { 0x001e, KEY_RED }, /* Reserved */ -+ { 0x0000, KEY_0 }, -+ { 0x0026, KEY_SLEEP }, /* Minimize */ -+}; -+ -+static struct rc_map_list rc5_hauppauge_new_map = { -+ .map = { -+ .scan = rc5_hauppauge_new, -+ .size = ARRAY_SIZE(rc5_hauppauge_new), -+ .rc_type = RC_TYPE_RC5, -+ .name = RC_MAP_HAUPPAUGE, -+ } -+}; -+ -+static int __init init_rc_map_rc5_hauppauge_new(void) -+{ -+ return rc_map_register(&rc5_hauppauge_new_map); -+} -+ -+static void __exit exit_rc_map_rc5_hauppauge_new(void) -+{ -+ rc_map_unregister(&rc5_hauppauge_new_map); -+} -+ -+module_init(init_rc_map_rc5_hauppauge_new) -+module_exit(exit_rc_map_rc5_hauppauge_new) -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Mauro Carvalho Chehab "); -diff --git a/drivers/media/rc/keymaps/rc-imon-mce.c b/drivers/media/rc/keymaps/rc-imon-mce.c -index cb67184..937a819 100644 ---- a/drivers/media/rc/keymaps/rc-imon-mce.c -+++ b/drivers/media/rc/keymaps/rc-imon-mce.c -@@ -111,7 +111,7 @@ static struct rc_map_table imon_mce[] = { - { 0x800ff44d, KEY_TITLE }, - - { 0x800ff40c, KEY_POWER }, -- { 0x800ff40d, KEY_PROG1 }, /* Windows MCE button */ -+ { 0x800ff40d, KEY_LEFTMETA }, /* Windows MCE button */ - - }; - -diff --git a/drivers/media/rc/keymaps/rc-imon-pad.c b/drivers/media/rc/keymaps/rc-imon-pad.c -index eef46b7..63d42bd 100644 ---- a/drivers/media/rc/keymaps/rc-imon-pad.c -+++ b/drivers/media/rc/keymaps/rc-imon-pad.c -@@ -125,7 +125,7 @@ static struct rc_map_table imon_pad[] = { - { 0x2b8195b7, KEY_CONTEXT_MENU }, /* Left Menu*/ - { 0x02000065, KEY_COMPOSE }, /* RightMenu */ - { 0x28b715b7, KEY_COMPOSE }, /* RightMenu */ -- { 0x2ab195b7, KEY_PROG1 }, /* Go or MultiMon */ -+ { 0x2ab195b7, KEY_LEFTMETA }, /* Go or MultiMon */ - { 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */ - }; - -diff --git a/drivers/media/rc/keymaps/rc-kworld-315u.c b/drivers/media/rc/keymaps/rc-kworld-315u.c -index 3ce6ef7..7f33edb 100644 ---- a/drivers/media/rc/keymaps/rc-kworld-315u.c -+++ b/drivers/media/rc/keymaps/rc-kworld-315u.c -@@ -17,7 +17,7 @@ - - static struct rc_map_table kworld_315u[] = { - { 0x6143, KEY_POWER }, -- { 0x6101, KEY_TUNER }, /* source */ -+ { 0x6101, KEY_VIDEO }, /* source */ - { 0x610b, KEY_ZOOM }, - { 0x6103, KEY_POWER2 }, /* shutdown */ - -diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c -index e45f0b8..08d1831 100644 ---- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c -+++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c -@@ -17,7 +17,7 @@ - */ - - static struct rc_map_table kworld_plus_tv_analog[] = { -- { 0x0c, KEY_PROG1 }, /* Kworld key */ -+ { 0x0c, KEY_LEFTMETA }, /* Kworld key */ - { 0x16, KEY_CLOSECD }, /* -> ) */ - { 0x1d, KEY_POWER2 }, - -diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c -index fa8fd0a..8e9969d 100644 ---- a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c -+++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c -@@ -62,7 +62,7 @@ static struct rc_map_table msi_tvanywhere_plus[] = { - { 0x13, KEY_AGAIN }, /* Recall */ - - { 0x1e, KEY_POWER }, /* Power */ -- { 0x07, KEY_TUNER }, /* Source */ -+ { 0x07, KEY_VIDEO }, /* Source */ - { 0x1c, KEY_SEARCH }, /* Scan */ - { 0x18, KEY_MUTE }, /* Mute */ - -diff --git a/drivers/media/rc/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c -index 3e6f077..ddae20e 100644 ---- a/drivers/media/rc/keymaps/rc-nebula.c -+++ b/drivers/media/rc/keymaps/rc-nebula.c -@@ -27,7 +27,7 @@ static struct rc_map_table nebula[] = { - { 0x0b, KEY_AUX }, - { 0x0c, KEY_DVD }, - { 0x0d, KEY_POWER }, -- { 0x0e, KEY_MHP }, /* labelled 'Picture' */ -+ { 0x0e, KEY_CAMERA }, /* labelled 'Picture' */ - { 0x0f, KEY_AUDIO }, - { 0x10, KEY_INFO }, - { 0x11, KEY_F13 }, /* 16:9 */ -diff --git a/drivers/media/rc/keymaps/rc-norwood.c b/drivers/media/rc/keymaps/rc-norwood.c -index 629ee9d..f1c1281 100644 ---- a/drivers/media/rc/keymaps/rc-norwood.c -+++ b/drivers/media/rc/keymaps/rc-norwood.c -@@ -29,7 +29,7 @@ static struct rc_map_table norwood[] = { - { 0x28, KEY_8 }, - { 0x29, KEY_9 }, - -- { 0x78, KEY_TUNER }, /* Video Source */ -+ { 0x78, KEY_VIDEO }, /* Video Source */ - { 0x2c, KEY_EXIT }, /* Open/Close software */ - { 0x2a, KEY_SELECT }, /* 2 Digit Select */ - { 0x69, KEY_AGAIN }, /* Recall */ -diff --git a/drivers/media/rc/keymaps/rc-pctv-sedna.c b/drivers/media/rc/keymaps/rc-pctv-sedna.c -index fa5ae59..7cdef6e 100644 ---- a/drivers/media/rc/keymaps/rc-pctv-sedna.c -+++ b/drivers/media/rc/keymaps/rc-pctv-sedna.c -@@ -36,7 +36,7 @@ static struct rc_map_table pctv_sedna[] = { - { 0x0e, KEY_STOP }, - { 0x0f, KEY_PREVIOUSSONG }, - { 0x10, KEY_ZOOM }, -- { 0x11, KEY_TUNER }, /* Source */ -+ { 0x11, KEY_VIDEO }, /* Source */ - { 0x12, KEY_POWER }, - { 0x13, KEY_MUTE }, - { 0x15, KEY_CHANNELDOWN }, -diff --git a/drivers/media/rc/keymaps/rc-pixelview-mk12.c b/drivers/media/rc/keymaps/rc-pixelview-mk12.c -index 8d9f664..125fc39 100644 ---- a/drivers/media/rc/keymaps/rc-pixelview-mk12.c -+++ b/drivers/media/rc/keymaps/rc-pixelview-mk12.c -@@ -34,7 +34,7 @@ static struct rc_map_table pixelview_mk12[] = { - { 0x866b13, KEY_AGAIN }, /* loop */ - { 0x866b10, KEY_DIGITS }, /* +100 */ - -- { 0x866b00, KEY_MEDIA }, /* source */ -+ { 0x866b00, KEY_VIDEO }, /* source */ - { 0x866b18, KEY_MUTE }, /* mute */ - { 0x866b19, KEY_CAMERA }, /* snapshot */ - { 0x866b1a, KEY_SEARCH }, /* scan */ -diff --git a/drivers/media/rc/keymaps/rc-pixelview-new.c b/drivers/media/rc/keymaps/rc-pixelview-new.c -index 777a700..bd78d6a 100644 ---- a/drivers/media/rc/keymaps/rc-pixelview-new.c -+++ b/drivers/media/rc/keymaps/rc-pixelview-new.c -@@ -33,7 +33,7 @@ static struct rc_map_table pixelview_new[] = { - { 0x3e, KEY_0 }, - - { 0x1c, KEY_AGAIN }, /* LOOP */ -- { 0x3f, KEY_MEDIA }, /* Source */ -+ { 0x3f, KEY_VIDEO }, /* Source */ - { 0x1f, KEY_LAST }, /* +100 */ - { 0x1b, KEY_MUTE }, - -diff --git a/drivers/media/rc/keymaps/rc-pixelview.c b/drivers/media/rc/keymaps/rc-pixelview.c -index 0ec5988..06187e7 100644 ---- a/drivers/media/rc/keymaps/rc-pixelview.c -+++ b/drivers/media/rc/keymaps/rc-pixelview.c -@@ -15,7 +15,7 @@ - static struct rc_map_table pixelview[] = { - - { 0x1e, KEY_POWER }, /* power */ -- { 0x07, KEY_MEDIA }, /* source */ -+ { 0x07, KEY_VIDEO }, /* source */ - { 0x1c, KEY_SEARCH }, /* scan */ - - -diff --git a/drivers/media/rc/keymaps/rc-pv951.c b/drivers/media/rc/keymaps/rc-pv951.c -index 83a418d..5e8beee 100644 ---- a/drivers/media/rc/keymaps/rc-pv951.c -+++ b/drivers/media/rc/keymaps/rc-pv951.c -@@ -46,10 +46,10 @@ static struct rc_map_table pv951[] = { - { 0x0c, KEY_SEARCH }, /* AUTOSCAN */ - - /* Not sure what to do with these ones! */ -- { 0x0f, KEY_SELECT }, /* SOURCE */ -+ { 0x0f, KEY_VIDEO }, /* SOURCE */ - { 0x0a, KEY_KPPLUS }, /* +100 */ - { 0x14, KEY_EQUAL }, /* SYNC */ -- { 0x1c, KEY_MEDIA }, /* PC/TV */ -+ { 0x1c, KEY_TV }, /* PC/TV */ - }; - - static struct rc_map_list pv951_map = { -diff --git a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c -deleted file mode 100644 -index dfc9b15..0000000 ---- a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c -+++ /dev/null -@@ -1,141 +0,0 @@ --/* rc5-hauppauge-new.h - Keytable for rc5_hauppauge_new Remote Controller -- * -- * keymap imported from ir-keymaps.c -- * -- * Copyright (c) 2010 by Mauro Carvalho Chehab -- * -- * 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; either version 2 of the License, or -- * (at your option) any later version. -- */ -- --#include -- --/* -- * Hauppauge:the newer, gray remotes (seems there are multiple -- * slightly different versions), shipped with cx88+ivtv cards. -- * -- * This table contains the complete RC5 code, instead of just the data part -- */ -- --static struct rc_map_table rc5_hauppauge_new[] = { -- /* Keys 0 to 9 */ -- { 0x1e00, KEY_0 }, -- { 0x1e01, KEY_1 }, -- { 0x1e02, KEY_2 }, -- { 0x1e03, KEY_3 }, -- { 0x1e04, KEY_4 }, -- { 0x1e05, KEY_5 }, -- { 0x1e06, KEY_6 }, -- { 0x1e07, KEY_7 }, -- { 0x1e08, KEY_8 }, -- { 0x1e09, KEY_9 }, -- -- { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */ -- { 0x1e0b, KEY_RED }, /* red button */ -- { 0x1e0c, KEY_RADIO }, -- { 0x1e0d, KEY_MENU }, -- { 0x1e0e, KEY_SUBTITLE }, /* also the # key */ -- { 0x1e0f, KEY_MUTE }, -- { 0x1e10, KEY_VOLUMEUP }, -- { 0x1e11, KEY_VOLUMEDOWN }, -- { 0x1e12, KEY_PREVIOUS }, /* previous channel */ -- { 0x1e14, KEY_UP }, -- { 0x1e15, KEY_DOWN }, -- { 0x1e16, KEY_LEFT }, -- { 0x1e17, KEY_RIGHT }, -- { 0x1e18, KEY_VIDEO }, /* Videos */ -- { 0x1e19, KEY_AUDIO }, /* Music */ -- /* 0x1e1a: Pictures - presume this means -- "Multimedia Home Platform" - -- no "PICTURES" key in input.h -- */ -- { 0x1e1a, KEY_MHP }, -- -- { 0x1e1b, KEY_EPG }, /* Guide */ -- { 0x1e1c, KEY_TV }, -- { 0x1e1e, KEY_NEXTSONG }, /* skip >| */ -- { 0x1e1f, KEY_EXIT }, /* back/exit */ -- { 0x1e20, KEY_CHANNELUP }, /* channel / program + */ -- { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */ -- { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */ -- { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */ -- { 0x1e25, KEY_ENTER }, /* OK */ -- { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */ -- { 0x1e29, KEY_BLUE }, /* blue key */ -- { 0x1e2e, KEY_GREEN }, /* green button */ -- { 0x1e30, KEY_PAUSE }, /* pause */ -- { 0x1e32, KEY_REWIND }, /* backward << */ -- { 0x1e34, KEY_FASTFORWARD }, /* forward >> */ -- { 0x1e35, KEY_PLAY }, -- { 0x1e36, KEY_STOP }, -- { 0x1e37, KEY_RECORD }, /* recording */ -- { 0x1e38, KEY_YELLOW }, /* yellow key */ -- { 0x1e3b, KEY_SELECT }, /* top right button */ -- { 0x1e3c, KEY_ZOOM }, /* full */ -- { 0x1e3d, KEY_POWER }, /* system power (green button) */ -- -- /* Keycodes for DSR-0112 remote bundled with Haupauge MiniStick */ -- { 0x1d00, KEY_0 }, -- { 0x1d01, KEY_1 }, -- { 0x1d02, KEY_2 }, -- { 0x1d03, KEY_3 }, -- { 0x1d04, KEY_4 }, -- { 0x1d05, KEY_5 }, -- { 0x1d06, KEY_6 }, -- { 0x1d07, KEY_7 }, -- { 0x1d08, KEY_8 }, -- { 0x1d09, KEY_9 }, -- { 0x1d0a, KEY_TEXT }, -- { 0x1d0d, KEY_MENU }, -- { 0x1d0f, KEY_MUTE }, -- { 0x1d10, KEY_VOLUMEUP }, -- { 0x1d11, KEY_VOLUMEDOWN }, -- { 0x1d12, KEY_PREVIOUS }, /* Prev.Ch .. ??? */ -- { 0x1d14, KEY_UP }, -- { 0x1d15, KEY_DOWN }, -- { 0x1d16, KEY_LEFT }, -- { 0x1d17, KEY_RIGHT }, -- { 0x1d1c, KEY_TV }, -- { 0x1d1e, KEY_NEXT }, /* >| */ -- { 0x1d1f, KEY_EXIT }, -- { 0x1d20, KEY_CHANNELUP }, -- { 0x1d21, KEY_CHANNELDOWN }, -- { 0x1d24, KEY_LAST }, /* <| */ -- { 0x1d25, KEY_OK }, -- { 0x1d30, KEY_PAUSE }, -- { 0x1d32, KEY_REWIND }, -- { 0x1d34, KEY_FASTFORWARD }, -- { 0x1d35, KEY_PLAY }, -- { 0x1d36, KEY_STOP }, -- { 0x1d37, KEY_RECORD }, -- { 0x1d3b, KEY_GOTO }, -- { 0x1d3d, KEY_POWER }, -- { 0x1d3f, KEY_HOME }, --}; -- --static struct rc_map_list rc5_hauppauge_new_map = { -- .map = { -- .scan = rc5_hauppauge_new, -- .size = ARRAY_SIZE(rc5_hauppauge_new), -- .rc_type = RC_TYPE_RC5, -- .name = RC_MAP_RC5_HAUPPAUGE_NEW, -- } --}; -- --static int __init init_rc_map_rc5_hauppauge_new(void) --{ -- return rc_map_register(&rc5_hauppauge_new_map); --} -- --static void __exit exit_rc_map_rc5_hauppauge_new(void) --{ -- rc_map_unregister(&rc5_hauppauge_new_map); --} -- --module_init(init_rc_map_rc5_hauppauge_new) --module_exit(exit_rc_map_rc5_hauppauge_new) -- --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Mauro Carvalho Chehab "); -diff --git a/drivers/media/rc/keymaps/rc-rc5-tv.c b/drivers/media/rc/keymaps/rc-rc5-tv.c -deleted file mode 100644 -index 4fcef9f..0000000 ---- a/drivers/media/rc/keymaps/rc-rc5-tv.c -+++ /dev/null -@@ -1,81 +0,0 @@ --/* rc5-tv.h - Keytable for rc5_tv Remote Controller -- * -- * keymap imported from ir-keymaps.c -- * -- * Copyright (c) 2010 by Mauro Carvalho Chehab -- * -- * 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; either version 2 of the License, or -- * (at your option) any later version. -- */ -- --#include -- --/* generic RC5 keytable */ --/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */ --/* used by old (black) Hauppauge remotes */ -- --static struct rc_map_table rc5_tv[] = { -- /* Keys 0 to 9 */ -- { 0x00, KEY_0 }, -- { 0x01, KEY_1 }, -- { 0x02, KEY_2 }, -- { 0x03, KEY_3 }, -- { 0x04, KEY_4 }, -- { 0x05, KEY_5 }, -- { 0x06, KEY_6 }, -- { 0x07, KEY_7 }, -- { 0x08, KEY_8 }, -- { 0x09, KEY_9 }, -- -- { 0x0b, KEY_CHANNEL }, /* channel / program (japan: 11) */ -- { 0x0c, KEY_POWER }, /* standby */ -- { 0x0d, KEY_MUTE }, /* mute / demute */ -- { 0x0f, KEY_TV }, /* display */ -- { 0x10, KEY_VOLUMEUP }, -- { 0x11, KEY_VOLUMEDOWN }, -- { 0x12, KEY_BRIGHTNESSUP }, -- { 0x13, KEY_BRIGHTNESSDOWN }, -- { 0x1e, KEY_SEARCH }, /* search + */ -- { 0x20, KEY_CHANNELUP }, /* channel / program + */ -- { 0x21, KEY_CHANNELDOWN }, /* channel / program - */ -- { 0x22, KEY_CHANNEL }, /* alt / channel */ -- { 0x23, KEY_LANGUAGE }, /* 1st / 2nd language */ -- { 0x26, KEY_SLEEP }, /* sleeptimer */ -- { 0x2e, KEY_MENU }, /* 2nd controls (USA: menu) */ -- { 0x30, KEY_PAUSE }, -- { 0x32, KEY_REWIND }, -- { 0x33, KEY_GOTO }, -- { 0x35, KEY_PLAY }, -- { 0x36, KEY_STOP }, -- { 0x37, KEY_RECORD }, /* recording */ -- { 0x3c, KEY_TEXT }, /* teletext submode (Japan: 12) */ -- { 0x3d, KEY_SUSPEND }, /* system standby */ -- --}; -- --static struct rc_map_list rc5_tv_map = { -- .map = { -- .scan = rc5_tv, -- .size = ARRAY_SIZE(rc5_tv), -- .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ -- .name = RC_MAP_RC5_TV, -- } --}; -- --static int __init init_rc_map_rc5_tv(void) --{ -- return rc_map_register(&rc5_tv_map); --} -- --static void __exit exit_rc_map_rc5_tv(void) --{ -- rc_map_unregister(&rc5_tv_map); --} -- --module_init(init_rc_map_rc5_tv) --module_exit(exit_rc_map_rc5_tv) -- --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Mauro Carvalho Chehab "); -diff --git a/drivers/media/rc/keymaps/rc-rc6-mce.c b/drivers/media/rc/keymaps/rc-rc6-mce.c -index 2f5dc06..8dd519e 100644 ---- a/drivers/media/rc/keymaps/rc-rc6-mce.c -+++ b/drivers/media/rc/keymaps/rc-rc6-mce.c -@@ -30,7 +30,7 @@ static struct rc_map_table rc6_mce[] = { - { 0x800f040a, KEY_DELETE }, - { 0x800f040b, KEY_ENTER }, - { 0x800f040c, KEY_POWER }, /* PC Power */ -- { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */ -+ { 0x800f040d, KEY_LEFTMETA }, /* Windows MCE button */ - { 0x800f040e, KEY_MUTE }, - { 0x800f040f, KEY_INFO }, - -diff --git a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c -index 2d14598..6813d11 100644 ---- a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c -+++ b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c -@@ -35,7 +35,7 @@ static struct rc_map_table real_audio_220_32_keys[] = { - { 0x15, KEY_CHANNELDOWN}, - { 0x16, KEY_ENTER}, - -- { 0x11, KEY_LIST}, /* Source */ -+ { 0x11, KEY_VIDEO}, /* Source */ - { 0x0d, KEY_AUDIO}, /* stereo */ - - { 0x0f, KEY_PREVIOUS}, /* Prev */ -diff --git a/drivers/media/rc/keymaps/rc-winfast.c b/drivers/media/rc/keymaps/rc-winfast.c -index 2747db4..0062ca2 100644 ---- a/drivers/media/rc/keymaps/rc-winfast.c -+++ b/drivers/media/rc/keymaps/rc-winfast.c -@@ -27,15 +27,15 @@ static struct rc_map_table winfast[] = { - { 0x0e, KEY_8 }, - { 0x0f, KEY_9 }, - -- { 0x00, KEY_POWER }, -+ { 0x00, KEY_POWER2 }, - { 0x1b, KEY_AUDIO }, /* Audio Source */ - { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */ - { 0x1e, KEY_VIDEO }, /* Video Source */ - { 0x16, KEY_INFO }, /* Display information */ -- { 0x04, KEY_VOLUMEUP }, -- { 0x08, KEY_VOLUMEDOWN }, -- { 0x0c, KEY_CHANNELUP }, -- { 0x10, KEY_CHANNELDOWN }, -+ { 0x04, KEY_LEFT }, -+ { 0x08, KEY_RIGHT }, -+ { 0x0c, KEY_UP }, -+ { 0x10, KEY_DOWN }, - { 0x03, KEY_ZOOM }, /* fullscreen */ - { 0x1f, KEY_TEXT }, /* closed caption/teletext */ - { 0x20, KEY_SLEEP }, -@@ -47,7 +47,7 @@ static struct rc_map_table winfast[] = { - { 0x2e, KEY_BLUE }, - { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */ - { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */ -- { 0x2a, KEY_MEDIA }, /* PIP (Picture in picture */ -+ { 0x2a, KEY_TV2 }, /* PIP (Picture in picture */ - { 0x21, KEY_DOT }, - { 0x13, KEY_ENTER }, - { 0x11, KEY_LAST }, /* Recall (last channel */ -@@ -57,7 +57,7 @@ static struct rc_map_table winfast[] = { - { 0x25, KEY_TIME }, /* Time Shifting */ - { 0x26, KEY_STOP }, - { 0x27, KEY_RECORD }, -- { 0x28, KEY_SAVE }, /* Screenshot */ -+ { 0x28, KEY_CAMERA }, /* Screenshot */ - { 0x2f, KEY_MENU }, - { 0x30, KEY_CANCEL }, - { 0x31, KEY_CHANNEL }, /* Channel Surf */ -@@ -70,10 +70,10 @@ static struct rc_map_table winfast[] = { - { 0x38, KEY_DVD }, - - { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */ -- { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */ -- { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */ -- { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */ -- { 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */ -+ { 0x3e, KEY_VOLUMEUP }, /* MCE +VOL, on Y04G0033 */ -+ { 0x3a, KEY_VOLUMEDOWN }, /* MCE -VOL, on Y04G0033 */ -+ { 0x3b, KEY_CHANNELUP }, /* MCE +CH, on Y04G0033 */ -+ { 0x3f, KEY_CHANNELDOWN } /* MCE -CH, on Y04G0033 */ - }; - - static struct rc_map_list winfast_map = { -diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c -index e4f8eac..044fb7a 100644 ---- a/drivers/media/rc/mceusb.c -+++ b/drivers/media/rc/mceusb.c -@@ -186,7 +186,7 @@ static const struct mceusb_model mceusb_model[] = { - * remotes, but we should have something handy, - * to allow testing it - */ -- .rc_map = RC_MAP_RC5_HAUPPAUGE_NEW, -+ .rc_map = RC_MAP_HAUPPAUGE, - .name = "Conexant Hybrid TV (cx231xx) MCE IR", - }, - [CX_HYBRID_TV] = { -@@ -261,7 +261,7 @@ static struct usb_device_id mceusb_dev_table[] = { - .driver_info = MCE_GEN2_TX_INV }, - /* Topseed eHome Infrared Transceiver */ - { USB_DEVICE(VENDOR_TOPSEED, 0x0011), -- .driver_info = MCE_GEN2_TX_INV }, -+ .driver_info = MCE_GEN3 }, - /* Ricavision internal Infrared Transceiver */ - { USB_DEVICE(VENDOR_RICAVISION, 0x0010) }, - /* Itron ione Libra Q-11 */ -diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c -index c330fb9..040aaa8 100644 ---- a/drivers/media/video/cx18/cx18-i2c.c -+++ b/drivers/media/video/cx18/cx18-i2c.c -@@ -96,7 +96,7 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw, - /* Our default information for ir-kbd-i2c.c to use */ - switch (hw) { - case CX18_HW_Z8F0811_IR_RX_HAUP: -- init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; -+ init_data->ir_codes = RC_MAP_HAUPPAUGE; - init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; - init_data->type = RC_TYPE_RC5; - init_data->name = cx->card_name; -diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c -index 199b996..e97cafd 100644 ---- a/drivers/media/video/cx23885/cx23885-input.c -+++ b/drivers/media/video/cx23885/cx23885-input.c -@@ -264,7 +264,7 @@ int cx23885_input_init(struct cx23885_dev *dev) - driver_type = RC_DRIVER_IR_RAW; - allowed_protos = RC_TYPE_ALL; - /* The grey Hauppauge RC-5 remote */ -- rc_map = RC_MAP_RC5_HAUPPAUGE_NEW; -+ rc_map = RC_MAP_HAUPPAUGE; - break; - case CX23885_BOARD_TEVII_S470: - /* Integrated CX23885 IR controller */ -diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c -index fbfbba5..c820e2f 100644 ---- a/drivers/media/video/cx88/cx88-input.c -+++ b/drivers/media/video/cx88/cx88-input.c -@@ -283,7 +283,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) - case CX88_BOARD_PCHDTV_HD3000: - case CX88_BOARD_PCHDTV_HD5500: - case CX88_BOARD_HAUPPAUGE_IRONLY: -- ir_codes = RC_MAP_HAUPPAUGE_NEW; -+ ir_codes = RC_MAP_HAUPPAUGE; - ir->sampling = 1; - break; - case CX88_BOARD_WINFAST_DTV2000H: -@@ -604,7 +604,7 @@ void cx88_i2c_init_ir(struct cx88_core *core) - if (*addrp == 0x71) { - /* Hauppauge XVR */ - core->init_data.name = "cx88 Hauppauge XVR remote"; -- core->init_data.ir_codes = RC_MAP_HAUPPAUGE_NEW; -+ core->init_data.ir_codes = RC_MAP_HAUPPAUGE; - core->init_data.type = RC_TYPE_RC5; - core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; - -diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c -index 87f77a3..69fcea8 100644 ---- a/drivers/media/video/em28xx/em28xx-cards.c -+++ b/drivers/media/video/em28xx/em28xx-cards.c -@@ -834,7 +834,7 @@ struct em28xx_board em28xx_boards[] = { - .mts_firmware = 1, - .has_dvb = 1, - .dvb_gpio = hauppauge_wintv_hvr_900_digital, -- .ir_codes = RC_MAP_HAUPPAUGE_NEW, -+ .ir_codes = RC_MAP_HAUPPAUGE, - .decoder = EM28XX_TVP5150, - .input = { { - .type = EM28XX_VMUX_TELEVISION, -@@ -859,7 +859,7 @@ struct em28xx_board em28xx_boards[] = { - .tuner_type = TUNER_XC2028, - .tuner_gpio = default_tuner_gpio, - .mts_firmware = 1, -- .ir_codes = RC_MAP_HAUPPAUGE_NEW, -+ .ir_codes = RC_MAP_HAUPPAUGE, - .decoder = EM28XX_TVP5150, - .input = { { - .type = EM28XX_VMUX_TELEVISION, -@@ -885,7 +885,7 @@ struct em28xx_board em28xx_boards[] = { - .mts_firmware = 1, - .has_dvb = 1, - .dvb_gpio = hauppauge_wintv_hvr_900_digital, -- .ir_codes = RC_MAP_HAUPPAUGE_NEW, -+ .ir_codes = RC_MAP_HAUPPAUGE, - .decoder = EM28XX_TVP5150, - .input = { { - .type = EM28XX_VMUX_TELEVISION, -@@ -911,7 +911,7 @@ struct em28xx_board em28xx_boards[] = { - .mts_firmware = 1, - .has_dvb = 1, - .dvb_gpio = hauppauge_wintv_hvr_900_digital, -- .ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW, -+ .ir_codes = RC_MAP_HAUPPAUGE, - .decoder = EM28XX_TVP5150, - .input = { { - .type = EM28XX_VMUX_TELEVISION, -@@ -2430,7 +2430,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev) - dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)"; - break; - case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: -- dev->init_data.ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW; -+ dev->init_data.ir_codes = RC_MAP_HAUPPAUGE; - dev->init_data.get_key = em28xx_get_key_em_haup; - dev->init_data.name = "i2c IR (EM2840 Hauppauge)"; - break; -diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c -index e53fa55..2a1ac28 100644 ---- a/drivers/media/video/hdpvr/hdpvr-i2c.c -+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c -@@ -52,25 +52,36 @@ struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev) - }; - - /* Our default information for ir-kbd-i2c.c to use */ -- init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; -+ init_data->ir_codes = RC_MAP_HAUPPAUGE; - init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; - init_data->type = RC_TYPE_RC5; - init_data->name = "HD-PVR"; -+ init_data->polling_interval = 405; /* ms, duplicated from Windows */ - hdpvr_ir_rx_i2c_board_info.platform_data = init_data; - - return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_rx_i2c_board_info); - } - - static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus, -- unsigned char addr, char *data, int len) -+ unsigned char addr, char *wdata, int wlen, -+ char *data, int len) - { - int ret; - -- if (len > sizeof(dev->i2c_buf)) -+ if ((len > sizeof(dev->i2c_buf)) || (wlen > sizeof(dev->i2c_buf))) - return -EINVAL; - -- ret = usb_control_msg(dev->udev, -- usb_rcvctrlpipe(dev->udev, 0), -+ if (wlen) { -+ memcpy(&dev->i2c_buf, wdata, wlen); -+ ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), -+ REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST, -+ (bus << 8) | addr, 0, &dev->i2c_buf, -+ wlen, 1000); -+ if (ret < 0) -+ return ret; -+ } -+ -+ ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), - REQTYPE_I2C_READ, CTRL_READ_REQUEST, - (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000); - -@@ -92,16 +103,14 @@ static int hdpvr_i2c_write(struct hdpvr_device *dev, int bus, - return -EINVAL; - - memcpy(&dev->i2c_buf, data, len); -- ret = usb_control_msg(dev->udev, -- usb_sndctrlpipe(dev->udev, 0), -+ ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), - REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST, - (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000); - - if (ret < 0) - return ret; - -- ret = usb_control_msg(dev->udev, -- usb_rcvctrlpipe(dev->udev, 0), -+ ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), - REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST, - 0, 0, &dev->i2c_buf, 2, 1000); - -@@ -117,24 +126,49 @@ static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs, - int num) - { - struct hdpvr_device *dev = i2c_get_adapdata(i2c_adapter); -- int retval = 0, i, addr; -+ int retval = 0, addr; - - if (num <= 0) - return 0; - - mutex_lock(&dev->i2c_mutex); - -- for (i = 0; i < num && !retval; i++) { -- addr = msgs[i].addr << 1; -+ addr = msgs[0].addr << 1; - -- if (msgs[i].flags & I2C_M_RD) -- retval = hdpvr_i2c_read(dev, 1, addr, msgs[i].buf, -- msgs[i].len); -+ if (num == 1) { -+ if (msgs[0].flags & I2C_M_RD) -+ retval = hdpvr_i2c_read(dev, 1, addr, NULL, 0, -+ msgs[0].buf, msgs[0].len); - else -- retval = hdpvr_i2c_write(dev, 1, addr, msgs[i].buf, -- msgs[i].len); -+ retval = hdpvr_i2c_write(dev, 1, addr, msgs[0].buf, -+ msgs[0].len); -+ } else if (num == 2) { -+ if (msgs[0].addr != msgs[1].addr) { -+ v4l2_warn(&dev->v4l2_dev, "refusing 2-phase i2c xfer " -+ "with conflicting target addresses\n"); -+ retval = -EINVAL; -+ goto out; -+ } -+ -+ if ((msgs[0].flags & I2C_M_RD) || !(msgs[1].flags & I2C_M_RD)) { -+ v4l2_warn(&dev->v4l2_dev, "refusing complex xfer with " -+ "r0=%d, r1=%d\n", msgs[0].flags & I2C_M_RD, -+ msgs[1].flags & I2C_M_RD); -+ retval = -EINVAL; -+ goto out; -+ } -+ -+ /* -+ * Write followed by atomic read is the only complex xfer that -+ * we actually support here. -+ */ -+ retval = hdpvr_i2c_read(dev, 1, addr, msgs[0].buf, msgs[0].len, -+ msgs[1].buf, msgs[1].len); -+ } else { -+ v4l2_warn(&dev->v4l2_dev, "refusing %d-phase i2c xfer\n", num); - } - -+out: - mutex_unlock(&dev->i2c_mutex); - - return retval ? retval : num; -@@ -158,11 +192,11 @@ static struct i2c_adapter hdpvr_i2c_adapter_template = { - - static int hdpvr_activate_ir(struct hdpvr_device *dev) - { -- char buffer[8]; -+ char buffer[2]; - - mutex_lock(&dev->i2c_mutex); - -- hdpvr_i2c_read(dev, 0, 0x54, buffer, 1); -+ hdpvr_i2c_read(dev, 0, 0x54, NULL, 0, buffer, 1); - - buffer[0] = 0; - buffer[1] = 0x8; -diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c -index a221ad6..3ab875d 100644 ---- a/drivers/media/video/ir-kbd-i2c.c -+++ b/drivers/media/video/ir-kbd-i2c.c -@@ -55,10 +55,6 @@ - static int debug; - module_param(debug, int, 0644); /* debug level (0,1,2) */ - --static int hauppauge; --module_param(hauppauge, int, 0644); /* Choose Hauppauge remote */ --MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults to 0)"); -- - - #define MODULE_NAME "ir-kbd-i2c" - #define dprintk(level, fmt, arg...) if (debug >= level) \ -@@ -105,10 +101,6 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, - /* invalid key press */ - return 0; - -- if (dev!=0x1e && dev!=0x1f) -- /* not a hauppauge remote */ -- return 0; -- - if (!range) - code += 64; - -@@ -116,7 +108,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, - start, range, toggle, dev, code); - - /* return key */ -- *ir_key = code; -+ *ir_key = (dev << 8) | code; - *ir_raw = ircode; - return 1; - } -@@ -312,11 +304,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) - name = "Hauppauge"; - ir->get_key = get_key_haup; - rc_type = RC_TYPE_RC5; -- if (hauppauge == 1) { -- ir_codes = RC_MAP_HAUPPAUGE_NEW; -- } else { -- ir_codes = RC_MAP_RC5_TV; -- } -+ ir_codes = RC_MAP_HAUPPAUGE; - break; - case 0x30: - name = "KNC One"; -@@ -340,7 +328,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) - name = "Hauppauge/Zilog Z8"; - ir->get_key = get_key_haup_xvr; - rc_type = RC_TYPE_RC5; -- ir_codes = hauppauge ? RC_MAP_HAUPPAUGE_NEW : RC_MAP_RC5_TV; -+ ir_codes = RC_MAP_HAUPPAUGE; - break; - } - -diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c -index 9fb86a0..d47f41a 100644 ---- a/drivers/media/video/ivtv/ivtv-i2c.c -+++ b/drivers/media/video/ivtv/ivtv-i2c.c -@@ -205,15 +205,14 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) - break; - case IVTV_HW_I2C_IR_RX_HAUP_EXT: - case IVTV_HW_I2C_IR_RX_HAUP_INT: -- /* Default to old black remote */ -- init_data->ir_codes = RC_MAP_RC5_TV; -+ init_data->ir_codes = RC_MAP_HAUPPAUGE; - init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; - init_data->type = RC_TYPE_RC5; - init_data->name = itv->card_name; - break; - case IVTV_HW_Z8F0811_IR_RX_HAUP: - /* Default to grey remote */ -- init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; -+ init_data->ir_codes = RC_MAP_HAUPPAUGE; - init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; - init_data->type = RC_TYPE_RC5; - init_data->name = itv->card_name; -diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c -index 451ecd4..e72d510 100644 ---- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c -+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c -@@ -578,7 +578,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw) - switch (hdw->ir_scheme_active) { - case PVR2_IR_SCHEME_24XXX: /* FX2-controlled IR */ - case PVR2_IR_SCHEME_29XXX: /* Original 29xxx device */ -- init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; -+ init_data->ir_codes = RC_MAP_HAUPPAUGE; - init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; - init_data->type = RC_TYPE_RC5; - init_data->name = hdw->hdw_desc->description; -@@ -593,7 +593,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw) - break; - case PVR2_IR_SCHEME_ZILOG: /* HVR-1950 style */ - case PVR2_IR_SCHEME_24XXX_MCE: /* 24xxx MCE device */ -- init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; -+ init_data->ir_codes = RC_MAP_HAUPPAUGE; - init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; - init_data->type = RC_TYPE_RC5; - init_data->name = hdw->hdw_desc->description; -diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c -index 790d667..be1c2a2 100644 ---- a/drivers/media/video/saa7134/saa7134-input.c -+++ b/drivers/media/video/saa7134/saa7134-input.c -@@ -893,7 +893,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) - case SAA7134_BOARD_HAUPPAUGE_HVR1110: - dev->init_data.name = "HVR 1110"; - dev->init_data.get_key = get_key_hvr1110; -- dev->init_data.ir_codes = RC_MAP_HAUPPAUGE_NEW; -+ dev->init_data.ir_codes = RC_MAP_HAUPPAUGE; - info.addr = 0x71; - break; - case SAA7134_BOARD_BEHOLD_607FM_MK3: -diff --git a/drivers/staging/lirc/Kconfig b/drivers/staging/lirc/Kconfig -index cdaff59..526ec0f 100644 ---- a/drivers/staging/lirc/Kconfig -+++ b/drivers/staging/lirc/Kconfig -@@ -32,18 +32,6 @@ config LIRC_IMON - - Current generation iMON devices use the input layer imon driver. - --config LIRC_IT87 -- tristate "ITE IT87XX CIR Port Receiver" -- depends on LIRC && PNP -- help -- Driver for the ITE IT87xx IR Receiver -- --config LIRC_ITE8709 -- tristate "ITE8709 CIR Port Receiver" -- depends on LIRC && PNP -- help -- Driver for the ITE8709 IR Receiver -- - config LIRC_PARALLEL - tristate "Homebrew Parallel Port Receiver" - depends on LIRC && PARPORT -diff --git a/drivers/staging/lirc/Makefile b/drivers/staging/lirc/Makefile -index 94af218..d76b0fa 100644 ---- a/drivers/staging/lirc/Makefile -+++ b/drivers/staging/lirc/Makefile -@@ -6,8 +6,6 @@ - obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o - obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o - obj-$(CONFIG_LIRC_IMON) += lirc_imon.o --obj-$(CONFIG_LIRC_IT87) += lirc_it87.o --obj-$(CONFIG_LIRC_ITE8709) += lirc_ite8709.o - obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o - obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o - obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o -diff --git a/drivers/staging/lirc/TODO.lirc_zilog b/drivers/staging/lirc/TODO.lirc_zilog -index 2d0263f..a97800a 100644 ---- a/drivers/staging/lirc/TODO.lirc_zilog -+++ b/drivers/staging/lirc/TODO.lirc_zilog -@@ -1,34 +1,33 @@ --1. Both ir-kbd-i2c and lirc_zilog provide support for RX events. --The 'tx_only' lirc_zilog module parameter will allow ir-kbd-i2c --and lirc_zilog to coexist in the kernel, if the user requires such a set-up. --However the IR unit will not work well without coordination between the --two modules. A shared mutex, for transceiver access locking, needs to be --supplied by bridge drivers, in struct IR_i2_init_data, to both ir-kbd-i2c --and lirc_zilog, before they will coexist usefully. This should be fixed --before moving out of staging. -- --2. References and locking need careful examination. For cx18 and ivtv PCI --cards, which are not easily "hot unplugged", the imperfect state of reference --counting and locking is acceptable if not correct. For USB connected units --like HD PVR, PVR USB2, HVR-1900, and HVR1950, the likelyhood of an Ooops on --unplug is probably great. Proper reference counting and locking needs to be --implemented before this module is moved out of staging. -- --3. The binding between hdpvr and lirc_zilog is currently disabled, --due to an OOPS reported a few years ago when both the hdpvr and cx18 --drivers were loaded in his system. More details can be seen at: -- http://www.mail-archive.com/linux-media@vger.kernel.org/msg09163.html --More tests need to be done, in order to fix the reported issue. -- --4. In addition to providing a shared mutex for transceiver access --locking, bridge drivers, if able, should provide a chip reset() callback -+1. Both ir-kbd-i2c and lirc_zilog provide support for RX events for -+the chips supported by lirc_zilog. Before moving lirc_zilog out of staging: -+ -+a. ir-kbd-i2c needs a module parameter added to allow the user to tell -+ ir-kbd-i2c to ignore Z8 IR units. -+ -+b. lirc_zilog should provide Rx key presses to the rc core like ir-kbd-i2c -+ does. -+ -+ -+2. lirc_zilog module ref-counting need examination. It has not been -+verified that cdev and lirc_dev will take the proper module references on -+lirc_zilog to prevent removal of lirc_zilog when the /dev/lircN device node -+is open. -+ -+(The good news is ref-counting of lirc_zilog internal structures appears to be -+complete. Testing has shown the cx18 module can be unloaded out from under -+irw + lircd + lirc_dev, with the /dev/lirc0 device node open, with no adverse -+effects. The cx18 module could then be reloaded and irw properly began -+receiving button presses again and ir_send worked without error.) -+ -+ -+3. Bridge drivers, if able, should provide a chip reset() callback - to lirc_zilog via struct IR_i2c_init_data. cx18 and ivtv already have routines --to perform Z8 chip resets via GPIO manipulations. This will allow lirc_zilog -+to perform Z8 chip resets via GPIO manipulations. This would allow lirc_zilog - to bring the chip back to normal when it hangs, in the same places the - original lirc_pvr150 driver code does. This is not strictly needed, so it - is not required to move lirc_zilog out of staging. - --5. Both lirc_zilog and ir-kbd-i2c support the Zilog Z8 for IR, as programmed -+Note: Both lirc_zilog and ir-kbd-i2c support the Zilog Z8 for IR, as programmed - and installed on Hauppauge products. When working on either module, developers - must consider at least the following bridge drivers which mention an IR Rx unit - at address 0x71 (indicative of a Z8): -diff --git a/drivers/staging/lirc/lirc_imon.c b/drivers/staging/lirc/lirc_imon.c -index 235cab0..4039eda 100644 ---- a/drivers/staging/lirc/lirc_imon.c -+++ b/drivers/staging/lirc/lirc_imon.c -@@ -379,7 +379,7 @@ static ssize_t vfd_write(struct file *file, const char *buf, - struct imon_context *context; - const unsigned char vfd_packet6[] = { - 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF }; -- int *data_buf; -+ int *data_buf = NULL; - - context = file->private_data; - if (!context) { -diff --git a/drivers/staging/lirc/lirc_it87.c b/drivers/staging/lirc/lirc_it87.c -deleted file mode 100644 -index 5938616..0000000 ---- a/drivers/staging/lirc/lirc_it87.c -+++ /dev/null -@@ -1,1027 +0,0 @@ --/* -- * LIRC driver for ITE IT8712/IT8705 CIR port -- * -- * Copyright (C) 2001 Hans-Gunter Lutke Uphues -- * -- * 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; either version 2 of the -- * License, or (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, but -- * WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * General Public License for more details. -- -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -- * USA -- * -- * ITE IT8705 and IT8712(not tested) and IT8720 CIR-port support for lirc based -- * via cut and paste from lirc_sir.c (C) 2000 Milan Pikula -- * -- * Attention: Sendmode only tested with debugging logs -- * -- * 2001/02/27 Christoph Bartelmus : -- * reimplemented read function -- * 2005/06/05 Andrew Calkin implemented support for Asus Digimatrix, -- * based on work of the following member of the Outertrack Digimatrix -- * Forum: Art103 -- * 2009/12/24 James Edwards implemeted support -- * for ITE8704/ITE8718, on my machine, the DSDT reports 8704, but the -- * chip identifies as 18. -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include --#include -- --#include --#include -- --#include "lirc_it87.h" -- --#ifdef LIRC_IT87_DIGIMATRIX --static int digimatrix = 1; --static int it87_freq = 36; /* kHz */ --static int irq = 9; --#else --static int digimatrix; --static int it87_freq = 38; /* kHz */ --static int irq = IT87_CIR_DEFAULT_IRQ; --#endif -- --static unsigned long it87_bits_in_byte_out; --static unsigned long it87_send_counter; --static unsigned char it87_RXEN_mask = IT87_CIR_RCR_RXEN; -- --#define RBUF_LEN 1024 -- --#define LIRC_DRIVER_NAME "lirc_it87" -- --/* timeout for sequences in jiffies (=5/100s) */ --/* must be longer than TIME_CONST */ --#define IT87_TIMEOUT (HZ*5/100) -- --/* module parameters */ --static int debug; --#define dprintk(fmt, args...) \ -- do { \ -- if (debug) \ -- printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ -- fmt, ## args); \ -- } while (0) -- --static int io = IT87_CIR_DEFAULT_IOBASE; --/* receiver demodulator default: off */ --static int it87_enable_demodulator; -- --static int timer_enabled; --static DEFINE_SPINLOCK(timer_lock); --static struct timer_list timerlist; --/* time of last signal change detected */ --static struct timeval last_tv = {0, 0}; --/* time of last UART data ready interrupt */ --static struct timeval last_intr_tv = {0, 0}; --static int last_value; -- --static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue); -- --static DEFINE_SPINLOCK(hardware_lock); --static DEFINE_SPINLOCK(dev_lock); --static bool device_open; -- --static int rx_buf[RBUF_LEN]; --unsigned int rx_tail, rx_head; -- --static struct pnp_driver it87_pnp_driver; -- --/* SECTION: Prototypes */ -- --/* Communication with user-space */ --static int lirc_open(struct inode *inode, struct file *file); --static int lirc_close(struct inode *inode, struct file *file); --static unsigned int lirc_poll(struct file *file, poll_table *wait); --static ssize_t lirc_read(struct file *file, char *buf, -- size_t count, loff_t *ppos); --static ssize_t lirc_write(struct file *file, const char *buf, -- size_t n, loff_t *pos); --static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); --static void add_read_queue(int flag, unsigned long val); --static int init_chrdev(void); --static void drop_chrdev(void); --/* Hardware */ --static irqreturn_t it87_interrupt(int irq, void *dev_id); --static void send_space(unsigned long len); --static void send_pulse(unsigned long len); --static void init_send(void); --static void terminate_send(unsigned long len); --static int init_hardware(void); --static void drop_hardware(void); --/* Initialisation */ --static int init_port(void); --static void drop_port(void); -- -- --/* SECTION: Communication with user-space */ -- --static int lirc_open(struct inode *inode, struct file *file) --{ -- spin_lock(&dev_lock); -- if (device_open) { -- spin_unlock(&dev_lock); -- return -EBUSY; -- } -- device_open = true; -- spin_unlock(&dev_lock); -- return 0; --} -- -- --static int lirc_close(struct inode *inode, struct file *file) --{ -- spin_lock(&dev_lock); -- device_open = false; -- spin_unlock(&dev_lock); -- return 0; --} -- -- --static unsigned int lirc_poll(struct file *file, poll_table *wait) --{ -- poll_wait(file, &lirc_read_queue, wait); -- if (rx_head != rx_tail) -- return POLLIN | POLLRDNORM; -- return 0; --} -- -- --static ssize_t lirc_read(struct file *file, char *buf, -- size_t count, loff_t *ppos) --{ -- int n = 0; -- int retval = 0; -- -- while (n < count) { -- if (file->f_flags & O_NONBLOCK && rx_head == rx_tail) { -- retval = -EAGAIN; -- break; -- } -- retval = wait_event_interruptible(lirc_read_queue, -- rx_head != rx_tail); -- if (retval) -- break; -- -- if (copy_to_user((void *) buf + n, (void *) (rx_buf + rx_head), -- sizeof(int))) { -- retval = -EFAULT; -- break; -- } -- rx_head = (rx_head + 1) & (RBUF_LEN - 1); -- n += sizeof(int); -- } -- if (n) -- return n; -- return retval; --} -- -- --static ssize_t lirc_write(struct file *file, const char *buf, -- size_t n, loff_t *pos) --{ -- int i = 0; -- int *tx_buf; -- -- if (n % sizeof(int)) -- return -EINVAL; -- tx_buf = memdup_user(buf, n); -- if (IS_ERR(tx_buf)) -- return PTR_ERR(tx_buf); -- n /= sizeof(int); -- init_send(); -- while (1) { -- if (i >= n) -- break; -- if (tx_buf[i]) -- send_pulse(tx_buf[i]); -- i++; -- if (i >= n) -- break; -- if (tx_buf[i]) -- send_space(tx_buf[i]); -- i++; -- } -- terminate_send(tx_buf[i - 1]); -- kfree(tx_buf); -- return n; --} -- -- --static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) --{ -- int retval = 0; -- __u32 value = 0; -- unsigned long hw_flags; -- -- if (cmd == LIRC_GET_FEATURES) -- value = LIRC_CAN_SEND_PULSE | -- LIRC_CAN_SET_SEND_CARRIER | -- LIRC_CAN_REC_MODE2; -- else if (cmd == LIRC_GET_SEND_MODE) -- value = LIRC_MODE_PULSE; -- else if (cmd == LIRC_GET_REC_MODE) -- value = LIRC_MODE_MODE2; -- -- switch (cmd) { -- case LIRC_GET_FEATURES: -- case LIRC_GET_SEND_MODE: -- case LIRC_GET_REC_MODE: -- retval = put_user(value, (__u32 *) arg); -- break; -- -- case LIRC_SET_SEND_MODE: -- case LIRC_SET_REC_MODE: -- retval = get_user(value, (__u32 *) arg); -- break; -- -- case LIRC_SET_SEND_CARRIER: -- retval = get_user(value, (__u32 *) arg); -- if (retval) -- return retval; -- value /= 1000; -- if (value > IT87_CIR_FREQ_MAX || -- value < IT87_CIR_FREQ_MIN) -- return -EINVAL; -- -- it87_freq = value; -- -- spin_lock_irqsave(&hardware_lock, hw_flags); -- outb(((inb(io + IT87_CIR_TCR2) & IT87_CIR_TCR2_TXMPW) | -- (it87_freq - IT87_CIR_FREQ_MIN) << 3), -- io + IT87_CIR_TCR2); -- spin_unlock_irqrestore(&hardware_lock, hw_flags); -- dprintk("demodulation frequency: %d kHz\n", it87_freq); -- -- break; -- -- default: -- retval = -EINVAL; -- } -- -- if (retval) -- return retval; -- -- if (cmd == LIRC_SET_REC_MODE) { -- if (value != LIRC_MODE_MODE2) -- retval = -ENOSYS; -- } else if (cmd == LIRC_SET_SEND_MODE) { -- if (value != LIRC_MODE_PULSE) -- retval = -ENOSYS; -- } -- return retval; --} -- --static void add_read_queue(int flag, unsigned long val) --{ -- unsigned int new_rx_tail; -- int newval; -- -- dprintk("add flag %d with val %lu\n", flag, val); -- -- newval = val & PULSE_MASK; -- -- /* -- * statistically, pulses are ~TIME_CONST/2 too long. we could -- * maybe make this more exact, but this is good enough -- */ -- if (flag) { -- /* pulse */ -- if (newval > TIME_CONST / 2) -- newval -= TIME_CONST / 2; -- else /* should not ever happen */ -- newval = 1; -- newval |= PULSE_BIT; -- } else -- newval += TIME_CONST / 2; -- new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1); -- if (new_rx_tail == rx_head) { -- dprintk("Buffer overrun.\n"); -- return; -- } -- rx_buf[rx_tail] = newval; -- rx_tail = new_rx_tail; -- wake_up_interruptible(&lirc_read_queue); --} -- -- --static const struct file_operations lirc_fops = { -- .owner = THIS_MODULE, -- .read = lirc_read, -- .write = lirc_write, -- .poll = lirc_poll, -- .unlocked_ioctl = lirc_ioctl, --#ifdef CONFIG_COMPAT -- .compat_ioctl = lirc_ioctl, --#endif -- .open = lirc_open, -- .release = lirc_close, -- .llseek = noop_llseek, --}; -- --static int set_use_inc(void *data) --{ -- return 0; --} -- --static void set_use_dec(void *data) --{ --} -- --static struct lirc_driver driver = { -- .name = LIRC_DRIVER_NAME, -- .minor = -1, -- .code_length = 1, -- .sample_rate = 0, -- .data = NULL, -- .add_to_buf = NULL, -- .set_use_inc = set_use_inc, -- .set_use_dec = set_use_dec, -- .fops = &lirc_fops, -- .dev = NULL, -- .owner = THIS_MODULE, --}; -- -- --static int init_chrdev(void) --{ -- driver.minor = lirc_register_driver(&driver); -- -- if (driver.minor < 0) { -- printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n"); -- return -EIO; -- } -- return 0; --} -- -- --static void drop_chrdev(void) --{ -- lirc_unregister_driver(driver.minor); --} -- -- --/* SECTION: Hardware */ --static long delta(struct timeval *tv1, struct timeval *tv2) --{ -- unsigned long deltv; -- -- deltv = tv2->tv_sec - tv1->tv_sec; -- if (deltv > 15) -- deltv = 0xFFFFFF; -- else -- deltv = deltv*1000000 + tv2->tv_usec - tv1->tv_usec; -- return deltv; --} -- --static void it87_timeout(unsigned long data) --{ -- unsigned long flags; -- -- /* avoid interference with interrupt */ -- spin_lock_irqsave(&timer_lock, flags); -- -- if (digimatrix) { -- /* We have timed out. Disable the RX mechanism. */ -- -- outb((inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN) | -- IT87_CIR_RCR_RXACT, io + IT87_CIR_RCR); -- if (it87_RXEN_mask) -- outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN, -- io + IT87_CIR_RCR); -- dprintk(" TIMEOUT\n"); -- timer_enabled = 0; -- -- /* fifo clear */ -- outb(inb(io + IT87_CIR_TCR1) | IT87_CIR_TCR1_FIFOCLR, -- io+IT87_CIR_TCR1); -- -- } else { -- /* -- * if last received signal was a pulse, but receiving stopped -- * within the 9 bit frame, we need to finish this pulse and -- * simulate a signal change to from pulse to space. Otherwise -- * upper layers will receive two sequences next time. -- */ -- -- if (last_value) { -- unsigned long pulse_end; -- -- /* determine 'virtual' pulse end: */ -- pulse_end = delta(&last_tv, &last_intr_tv); -- dprintk("timeout add %d for %lu usec\n", -- last_value, pulse_end); -- add_read_queue(last_value, pulse_end); -- last_value = 0; -- last_tv = last_intr_tv; -- } -- } -- spin_unlock_irqrestore(&timer_lock, flags); --} -- --static irqreturn_t it87_interrupt(int irq, void *dev_id) --{ -- unsigned char data; -- struct timeval curr_tv; -- static unsigned long deltv; -- unsigned long deltintrtv; -- unsigned long flags, hw_flags; -- int iir, lsr; -- int fifo = 0; -- static char lastbit; -- char bit; -- -- /* Bit duration in microseconds */ -- const unsigned long bit_duration = 1000000ul / -- (115200 / IT87_CIR_BAUDRATE_DIVISOR); -- -- -- iir = inb(io + IT87_CIR_IIR); -- -- switch (iir & IT87_CIR_IIR_IID) { -- case 0x4: -- case 0x6: -- lsr = inb(io + IT87_CIR_RSR) & (IT87_CIR_RSR_RXFTO | -- IT87_CIR_RSR_RXFBC); -- fifo = lsr & IT87_CIR_RSR_RXFBC; -- dprintk("iir: 0x%x fifo: 0x%x\n", iir, lsr); -- -- /* avoid interference with timer */ -- spin_lock_irqsave(&timer_lock, flags); -- spin_lock_irqsave(&hardware_lock, hw_flags); -- if (digimatrix) { -- static unsigned long acc_pulse; -- static unsigned long acc_space; -- -- do { -- data = inb(io + IT87_CIR_DR); -- data = ~data; -- fifo--; -- if (data != 0x00) { -- if (timer_enabled) -- del_timer(&timerlist); -- /* -- * start timer for end of -- * sequence detection -- */ -- timerlist.expires = jiffies + -- IT87_TIMEOUT; -- add_timer(&timerlist); -- timer_enabled = 1; -- } -- /* Loop through */ -- for (bit = 0; bit < 8; ++bit) { -- if ((data >> bit) & 1) { -- ++acc_pulse; -- if (lastbit == 0) { -- add_read_queue(0, -- acc_space * -- bit_duration); -- acc_space = 0; -- } -- } else { -- ++acc_space; -- if (lastbit == 1) { -- add_read_queue(1, -- acc_pulse * -- bit_duration); -- acc_pulse = 0; -- } -- } -- lastbit = (data >> bit) & 1; -- } -- -- } while (fifo != 0); -- } else { /* Normal Operation */ -- do { -- del_timer(&timerlist); -- data = inb(io + IT87_CIR_DR); -- -- dprintk("data=%02x\n", data); -- do_gettimeofday(&curr_tv); -- deltv = delta(&last_tv, &curr_tv); -- deltintrtv = delta(&last_intr_tv, &curr_tv); -- -- dprintk("t %lu , d %d\n", -- deltintrtv, (int)data); -- -- /* -- * if nothing came in last 2 cycles, -- * it was gap -- */ -- if (deltintrtv > TIME_CONST * 2) { -- if (last_value) { -- dprintk("GAP\n"); -- -- /* simulate signal change */ -- add_read_queue(last_value, -- deltv - -- deltintrtv); -- last_value = 0; -- last_tv.tv_sec = -- last_intr_tv.tv_sec; -- last_tv.tv_usec = -- last_intr_tv.tv_usec; -- deltv = deltintrtv; -- } -- } -- data = 1; -- if (data ^ last_value) { -- /* -- * deltintrtv > 2*TIME_CONST, -- * remember ? the other case is -- * timeout -- */ -- add_read_queue(last_value, -- deltv-TIME_CONST); -- last_value = data; -- last_tv = curr_tv; -- if (last_tv.tv_usec >= TIME_CONST) -- last_tv.tv_usec -= TIME_CONST; -- else { -- last_tv.tv_sec--; -- last_tv.tv_usec += 1000000 - -- TIME_CONST; -- } -- } -- last_intr_tv = curr_tv; -- if (data) { -- /* -- * start timer for end of -- * sequence detection -- */ -- timerlist.expires = -- jiffies + IT87_TIMEOUT; -- add_timer(&timerlist); -- } -- outb((inb(io + IT87_CIR_RCR) & -- ~IT87_CIR_RCR_RXEN) | -- IT87_CIR_RCR_RXACT, -- io + IT87_CIR_RCR); -- if (it87_RXEN_mask) -- outb(inb(io + IT87_CIR_RCR) | -- IT87_CIR_RCR_RXEN, -- io + IT87_CIR_RCR); -- fifo--; -- } while (fifo != 0); -- } -- spin_unlock_irqrestore(&hardware_lock, hw_flags); -- spin_unlock_irqrestore(&timer_lock, flags); -- -- return IRQ_RETVAL(IRQ_HANDLED); -- -- default: -- /* not our irq */ -- dprintk("unknown IRQ (shouldn't happen) !!\n"); -- return IRQ_RETVAL(IRQ_NONE); -- } --} -- -- --static void send_it87(unsigned long len, unsigned long stime, -- unsigned char send_byte, unsigned int count_bits) --{ -- long count = len / stime; -- long time_left = 0; -- static unsigned char byte_out; -- unsigned long hw_flags; -- -- dprintk("%s: len=%ld, sb=%d\n", __func__, len, send_byte); -- -- time_left = (long)len - (long)count * (long)stime; -- count += ((2 * time_left) / stime); -- while (count) { -- long i = 0; -- for (i = 0; i < count_bits; i++) { -- byte_out = (byte_out << 1) | (send_byte & 1); -- it87_bits_in_byte_out++; -- } -- if (it87_bits_in_byte_out == 8) { -- dprintk("out=0x%x, tsr_txfbc: 0x%x\n", -- byte_out, -- inb(io + IT87_CIR_TSR) & -- IT87_CIR_TSR_TXFBC); -- -- while ((inb(io + IT87_CIR_TSR) & -- IT87_CIR_TSR_TXFBC) >= IT87_CIR_FIFO_SIZE) -- ; -- -- spin_lock_irqsave(&hardware_lock, hw_flags); -- outb(byte_out, io + IT87_CIR_DR); -- spin_unlock_irqrestore(&hardware_lock, hw_flags); -- -- it87_bits_in_byte_out = 0; -- it87_send_counter++; -- byte_out = 0; -- } -- count--; -- } --} -- -- --/*TODO: maybe exchange space and pulse because it8705 only modulates 0-bits */ -- --static void send_space(unsigned long len) --{ -- send_it87(len, TIME_CONST, IT87_CIR_SPACE, IT87_CIR_BAUDRATE_DIVISOR); --} -- --static void send_pulse(unsigned long len) --{ -- send_it87(len, TIME_CONST, IT87_CIR_PULSE, IT87_CIR_BAUDRATE_DIVISOR); --} -- -- --static void init_send() --{ -- unsigned long flags; -- -- spin_lock_irqsave(&hardware_lock, flags); -- /* RXEN=0: receiver disable */ -- it87_RXEN_mask = 0; -- outb(inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN, -- io + IT87_CIR_RCR); -- spin_unlock_irqrestore(&hardware_lock, flags); -- it87_bits_in_byte_out = 0; -- it87_send_counter = 0; --} -- -- --static void terminate_send(unsigned long len) --{ -- unsigned long flags; -- unsigned long last = 0; -- -- last = it87_send_counter; -- /* make sure all necessary data has been sent */ -- while (last == it87_send_counter) -- send_space(len); -- /* wait until all data sent */ -- while ((inb(io + IT87_CIR_TSR) & IT87_CIR_TSR_TXFBC) != 0) -- ; -- /* then re-enable receiver */ -- spin_lock_irqsave(&hardware_lock, flags); -- it87_RXEN_mask = IT87_CIR_RCR_RXEN; -- outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN, -- io + IT87_CIR_RCR); -- spin_unlock_irqrestore(&hardware_lock, flags); --} -- -- --static int init_hardware(void) --{ -- unsigned long flags; -- unsigned char it87_rcr = 0; -- -- spin_lock_irqsave(&hardware_lock, flags); -- /* init cir-port */ -- /* enable r/w-access to Baudrate-Register */ -- outb(IT87_CIR_IER_BR, io + IT87_CIR_IER); -- outb(IT87_CIR_BAUDRATE_DIVISOR % 0x100, io+IT87_CIR_BDLR); -- outb(IT87_CIR_BAUDRATE_DIVISOR / 0x100, io+IT87_CIR_BDHR); -- /* Baudrate Register off, define IRQs: Input only */ -- if (digimatrix) { -- outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RFOIE, io + IT87_CIR_IER); -- /* RX: HCFS=0, RXDCR = 001b (33,75..38,25 kHz), RXEN=1 */ -- } else { -- outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RDAIE, io + IT87_CIR_IER); -- /* RX: HCFS=0, RXDCR = 001b (35,6..40,3 kHz), RXEN=1 */ -- } -- it87_rcr = (IT87_CIR_RCR_RXEN & it87_RXEN_mask) | 0x1; -- if (it87_enable_demodulator) -- it87_rcr |= IT87_CIR_RCR_RXEND; -- outb(it87_rcr, io + IT87_CIR_RCR); -- if (digimatrix) { -- /* Set FIFO depth to 1 byte, and disable TX */ -- outb(inb(io + IT87_CIR_TCR1) | 0x00, -- io + IT87_CIR_TCR1); -- -- /* -- * TX: it87_freq (36kHz), 'reserved' sensitivity -- * setting (0x00) -- */ -- outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x00, -- io + IT87_CIR_TCR2); -- } else { -- /* TX: 38kHz, 13,3us (pulse-width) */ -- outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x06, -- io + IT87_CIR_TCR2); -- } -- spin_unlock_irqrestore(&hardware_lock, flags); -- return 0; --} -- -- --static void drop_hardware(void) --{ -- unsigned long flags; -- -- spin_lock_irqsave(&hardware_lock, flags); -- disable_irq(irq); -- /* receiver disable */ -- it87_RXEN_mask = 0; -- outb(0x1, io + IT87_CIR_RCR); -- /* turn off irqs */ -- outb(0, io + IT87_CIR_IER); -- /* fifo clear */ -- outb(IT87_CIR_TCR1_FIFOCLR, io+IT87_CIR_TCR1); -- /* reset */ -- outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER); -- enable_irq(irq); -- spin_unlock_irqrestore(&hardware_lock, flags); --} -- -- --static unsigned char it87_read(unsigned char port) --{ -- outb(port, IT87_ADRPORT); -- return inb(IT87_DATAPORT); --} -- -- --static void it87_write(unsigned char port, unsigned char data) --{ -- outb(port, IT87_ADRPORT); -- outb(data, IT87_DATAPORT); --} -- -- --/* SECTION: Initialisation */ -- --static int init_port(void) --{ -- unsigned long hw_flags; -- int retval = 0; -- -- unsigned char init_bytes[4] = IT87_INIT; -- unsigned char it87_chipid = 0; -- unsigned char ldn = 0; -- unsigned int it87_io = 0; -- unsigned int it87_irq = 0; -- -- /* Enter MB PnP Mode */ -- outb(init_bytes[0], IT87_ADRPORT); -- outb(init_bytes[1], IT87_ADRPORT); -- outb(init_bytes[2], IT87_ADRPORT); -- outb(init_bytes[3], IT87_ADRPORT); -- -- /* 8712 or 8705 ? */ -- it87_chipid = it87_read(IT87_CHIP_ID1); -- if (it87_chipid != 0x87) { -- retval = -ENXIO; -- return retval; -- } -- it87_chipid = it87_read(IT87_CHIP_ID2); -- if ((it87_chipid != 0x05) && -- (it87_chipid != 0x12) && -- (it87_chipid != 0x18) && -- (it87_chipid != 0x20)) { -- printk(KERN_INFO LIRC_DRIVER_NAME -- ": no IT8704/05/12/18/20 found (claimed IT87%02x), " -- "exiting..\n", it87_chipid); -- retval = -ENXIO; -- return retval; -- } -- printk(KERN_INFO LIRC_DRIVER_NAME -- ": found IT87%02x.\n", -- it87_chipid); -- -- /* get I/O-Port and IRQ */ -- if (it87_chipid == 0x12 || it87_chipid == 0x18) -- ldn = IT8712_CIR_LDN; -- else -- ldn = IT8705_CIR_LDN; -- it87_write(IT87_LDN, ldn); -- -- it87_io = it87_read(IT87_CIR_BASE_MSB) * 256 + -- it87_read(IT87_CIR_BASE_LSB); -- if (it87_io == 0) { -- if (io == 0) -- io = IT87_CIR_DEFAULT_IOBASE; -- printk(KERN_INFO LIRC_DRIVER_NAME -- ": set default io 0x%x\n", -- io); -- it87_write(IT87_CIR_BASE_MSB, io / 0x100); -- it87_write(IT87_CIR_BASE_LSB, io % 0x100); -- } else -- io = it87_io; -- -- it87_irq = it87_read(IT87_CIR_IRQ); -- if (digimatrix || it87_irq == 0) { -- if (irq == 0) -- irq = IT87_CIR_DEFAULT_IRQ; -- printk(KERN_INFO LIRC_DRIVER_NAME -- ": set default irq 0x%x\n", -- irq); -- it87_write(IT87_CIR_IRQ, irq); -- } else -- irq = it87_irq; -- -- spin_lock_irqsave(&hardware_lock, hw_flags); -- /* reset */ -- outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER); -- /* fifo clear */ -- outb(IT87_CIR_TCR1_FIFOCLR | -- /* IT87_CIR_TCR1_ILE | */ -- IT87_CIR_TCR1_TXRLE | -- IT87_CIR_TCR1_TXENDF, io+IT87_CIR_TCR1); -- spin_unlock_irqrestore(&hardware_lock, hw_flags); -- -- /* get I/O port access and IRQ line */ -- if (request_region(io, 8, LIRC_DRIVER_NAME) == NULL) { -- printk(KERN_ERR LIRC_DRIVER_NAME -- ": i/o port 0x%.4x already in use.\n", io); -- /* Leaving MB PnP Mode */ -- it87_write(IT87_CFGCTRL, 0x2); -- return -EBUSY; -- } -- -- /* activate CIR-Device */ -- it87_write(IT87_CIR_ACT, 0x1); -- -- /* Leaving MB PnP Mode */ -- it87_write(IT87_CFGCTRL, 0x2); -- -- retval = request_irq(irq, it87_interrupt, 0 /*IRQF_DISABLED*/, -- LIRC_DRIVER_NAME, NULL); -- if (retval < 0) { -- printk(KERN_ERR LIRC_DRIVER_NAME -- ": IRQ %d already in use.\n", -- irq); -- release_region(io, 8); -- return retval; -- } -- -- printk(KERN_INFO LIRC_DRIVER_NAME -- ": I/O port 0x%.4x, IRQ %d.\n", io, irq); -- -- init_timer(&timerlist); -- timerlist.function = it87_timeout; -- timerlist.data = 0xabadcafe; -- -- return 0; --} -- -- --static void drop_port(void) --{ --#if 0 -- unsigned char init_bytes[4] = IT87_INIT; -- -- /* Enter MB PnP Mode */ -- outb(init_bytes[0], IT87_ADRPORT); -- outb(init_bytes[1], IT87_ADRPORT); -- outb(init_bytes[2], IT87_ADRPORT); -- outb(init_bytes[3], IT87_ADRPORT); -- -- /* deactivate CIR-Device */ -- it87_write(IT87_CIR_ACT, 0x0); -- -- /* Leaving MB PnP Mode */ -- it87_write(IT87_CFGCTRL, 0x2); --#endif -- -- del_timer_sync(&timerlist); -- free_irq(irq, NULL); -- release_region(io, 8); --} -- -- --static int init_lirc_it87(void) --{ -- int retval; -- -- init_waitqueue_head(&lirc_read_queue); -- retval = init_port(); -- if (retval < 0) -- return retval; -- init_hardware(); -- printk(KERN_INFO LIRC_DRIVER_NAME ": Installed.\n"); -- return 0; --} -- --static int it87_probe(struct pnp_dev *pnp_dev, -- const struct pnp_device_id *dev_id) --{ -- int retval; -- -- driver.dev = &pnp_dev->dev; -- -- retval = init_chrdev(); -- if (retval < 0) -- return retval; -- -- retval = init_lirc_it87(); -- if (retval) -- goto init_lirc_it87_failed; -- -- return 0; -- --init_lirc_it87_failed: -- drop_chrdev(); -- -- return retval; --} -- --static int __init lirc_it87_init(void) --{ -- return pnp_register_driver(&it87_pnp_driver); --} -- -- --static void __exit lirc_it87_exit(void) --{ -- drop_hardware(); -- drop_chrdev(); -- drop_port(); -- pnp_unregister_driver(&it87_pnp_driver); -- printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n"); --} -- --/* SECTION: PNP for ITE8704/13/18 */ -- --static const struct pnp_device_id pnp_dev_table[] = { -- {"ITE8704", 0}, -- {"ITE8713", 0}, -- {} --}; -- --MODULE_DEVICE_TABLE(pnp, pnp_dev_table); -- --static struct pnp_driver it87_pnp_driver = { -- .name = LIRC_DRIVER_NAME, -- .id_table = pnp_dev_table, -- .probe = it87_probe, --}; -- --module_init(lirc_it87_init); --module_exit(lirc_it87_exit); -- --MODULE_DESCRIPTION("LIRC driver for ITE IT8704/05/12/18/20 CIR port"); --MODULE_AUTHOR("Hans-Gunter Lutke Uphues"); --MODULE_LICENSE("GPL"); -- --module_param(io, int, S_IRUGO); --MODULE_PARM_DESC(io, "I/O base address (default: 0x310)"); -- --module_param(irq, int, S_IRUGO); --#ifdef LIRC_IT87_DIGIMATRIX --MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 9)"); --#else --MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 7)"); --#endif -- --module_param(it87_enable_demodulator, bool, S_IRUGO); --MODULE_PARM_DESC(it87_enable_demodulator, -- "Receiver demodulator enable/disable (1/0), default: 0"); -- --module_param(debug, bool, S_IRUGO | S_IWUSR); --MODULE_PARM_DESC(debug, "Enable debugging messages"); -- --module_param(digimatrix, bool, S_IRUGO | S_IWUSR); --#ifdef LIRC_IT87_DIGIMATRIX --MODULE_PARM_DESC(digimatrix, -- "Asus Digimatrix it87 compat. enable/disable (1/0), default: 1"); --#else --MODULE_PARM_DESC(digimatrix, -- "Asus Digimatrix it87 compat. enable/disable (1/0), default: 0"); --#endif -- -- --module_param(it87_freq, int, S_IRUGO); --#ifdef LIRC_IT87_DIGIMATRIX --MODULE_PARM_DESC(it87_freq, -- "Carrier demodulator frequency (kHz), (default: 36)"); --#else --MODULE_PARM_DESC(it87_freq, -- "Carrier demodulator frequency (kHz), (default: 38)"); --#endif -diff --git a/drivers/staging/lirc/lirc_it87.h b/drivers/staging/lirc/lirc_it87.h -deleted file mode 100644 -index cf021c8..0000000 ---- a/drivers/staging/lirc/lirc_it87.h -+++ /dev/null -@@ -1,116 +0,0 @@ --/* lirc_it87.h */ --/* SECTION: Definitions */ -- --/********************************* ITE IT87xx ************************/ -- --/* based on the following documentation from ITE: -- a) IT8712F Preliminary CIR Programming Guide V0.1 -- b) IT8705F Simple LPC I/O Preliminary Specification V0.3 -- c) IT8712F EC-LPC I/O Preliminary Specification V0.5 --*/ -- --/* IT8712/05 Ports: */ --#define IT87_ADRPORT 0x2e --#define IT87_DATAPORT 0x2f --#define IT87_INIT {0x87, 0x01, 0x55, 0x55} -- --/* alternate Ports: */ --/* --#define IT87_ADRPORT 0x4e --#define IT87_DATAPORT 0x4f --#define IT87_INIT {0x87, 0x01, 0x55, 0xaa} -- */ -- --/* IT8712/05 Registers */ --#define IT87_CFGCTRL 0x2 --#define IT87_LDN 0x7 --#define IT87_CHIP_ID1 0x20 --#define IT87_CHIP_ID2 0x21 --#define IT87_CFG_VERSION 0x22 --#define IT87_SWSUSPEND 0x23 -- --#define IT8712_CIR_LDN 0xa --#define IT8705_CIR_LDN 0x7 -- --/* CIR Configuration Registers: */ --#define IT87_CIR_ACT 0x30 --#define IT87_CIR_BASE_MSB 0x60 --#define IT87_CIR_BASE_LSB 0x61 --#define IT87_CIR_IRQ 0x70 --#define IT87_CIR_CONFIG 0xf0 -- --/* List of IT87_CIR registers: offset to BaseAddr */ --#define IT87_CIR_DR 0 --#define IT87_CIR_IER 1 --#define IT87_CIR_RCR 2 --#define IT87_CIR_TCR1 3 --#define IT87_CIR_TCR2 4 --#define IT87_CIR_TSR 5 --#define IT87_CIR_RSR 6 --#define IT87_CIR_BDLR 5 --#define IT87_CIR_BDHR 6 --#define IT87_CIR_IIR 7 -- --/* Bit Definition */ --/* IER: */ --#define IT87_CIR_IER_TM_EN 0x80 --#define IT87_CIR_IER_RESEVED 0x40 --#define IT87_CIR_IER_RESET 0x20 --#define IT87_CIR_IER_BR 0x10 --#define IT87_CIR_IER_IEC 0x8 --#define IT87_CIR_IER_RFOIE 0x4 --#define IT87_CIR_IER_RDAIE 0x2 --#define IT87_CIR_IER_TLDLIE 0x1 -- --/* RCR: */ --#define IT87_CIR_RCR_RDWOS 0x80 --#define IT87_CIR_RCR_HCFS 0x40 --#define IT87_CIR_RCR_RXEN 0x20 --#define IT87_CIR_RCR_RXEND 0x10 --#define IT87_CIR_RCR_RXACT 0x8 --#define IT87_CIR_RCR_RXDCR 0x7 -- --/* TCR1: */ --#define IT87_CIR_TCR1_FIFOCLR 0x80 --#define IT87_CIR_TCR1_ILE 0x40 --#define IT87_CIR_TCR1_FIFOTL 0x30 --#define IT87_CIR_TCR1_TXRLE 0x8 --#define IT87_CIR_TCR1_TXENDF 0x4 --#define IT87_CIR_TCR1_TXMPM 0x3 -- --/* TCR2: */ --#define IT87_CIR_TCR2_CFQ 0xf8 --#define IT87_CIR_TCR2_TXMPW 0x7 -- --/* TSR: */ --#define IT87_CIR_TSR_RESERVED 0xc0 --#define IT87_CIR_TSR_TXFBC 0x3f -- --/* RSR: */ --#define IT87_CIR_RSR_RXFTO 0x80 --#define IT87_CIR_RSR_RESERVED 0x40 --#define IT87_CIR_RSR_RXFBC 0x3f -- --/* IIR: */ --#define IT87_CIR_IIR_RESERVED 0xf8 --#define IT87_CIR_IIR_IID 0x6 --#define IT87_CIR_IIR_IIP 0x1 -- --/* TM: */ --#define IT87_CIR_TM_IL_SEL 0x80 --#define IT87_CIR_TM_RESERVED 0x40 --#define IT87_CIR_TM_TM_REG 0x3f -- --#define IT87_CIR_FIFO_SIZE 32 -- --/* Baudratedivisor for IT87: power of 2: only 1,2,4 or 8) */ --#define IT87_CIR_BAUDRATE_DIVISOR 0x1 --#define IT87_CIR_DEFAULT_IOBASE 0x310 --#define IT87_CIR_DEFAULT_IRQ 0x7 --#define IT87_CIR_SPACE 0x00 --#define IT87_CIR_PULSE 0xff --#define IT87_CIR_FREQ_MIN 27 --#define IT87_CIR_FREQ_MAX 58 --#define TIME_CONST (IT87_CIR_BAUDRATE_DIVISOR * 8000000ul / 115200ul) -- --/********************************* ITE IT87xx ************************/ -diff --git a/drivers/staging/lirc/lirc_ite8709.c b/drivers/staging/lirc/lirc_ite8709.c -deleted file mode 100644 -index cb20cfd..0000000 ---- a/drivers/staging/lirc/lirc_ite8709.c -+++ /dev/null -@@ -1,542 +0,0 @@ --/* -- * LIRC driver for ITE8709 CIR port -- * -- * Copyright (C) 2008 Grégory Lardière -- * -- * 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; either version 2 of the -- * License, or (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, but -- * WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -- * USA -- */ -- --#include --#include --#include --#include --#include --#include -- --#include --#include -- --#define LIRC_DRIVER_NAME "lirc_ite8709" -- --#define BUF_CHUNK_SIZE sizeof(int) --#define BUF_SIZE (128*BUF_CHUNK_SIZE) -- --/* -- * The ITE8709 device seems to be the combination of IT8512 superIO chip and -- * a specific firmware running on the IT8512's embedded micro-controller. -- * In addition of the embedded micro-controller, the IT8512 chip contains a -- * CIR module and several other modules. A few modules are directly accessible -- * by the host CPU, but most of them are only accessible by the -- * micro-controller. The CIR module is only accessible by the micro-controller. -- * The battery-backed SRAM module is accessible by the host CPU and the -- * micro-controller. So one of the MC's firmware role is to act as a bridge -- * between the host CPU and the CIR module. The firmware implements a kind of -- * communication protocol using the SRAM module as a shared memory. The IT8512 -- * specification is publicly available on ITE's web site, but the communication -- * protocol is not, so it was reverse-engineered. -- */ -- --/* ITE8709 Registers addresses and values (reverse-engineered) */ --#define ITE8709_MODE 0x1a --#define ITE8709_REG_ADR 0x1b --#define ITE8709_REG_VAL 0x1c --#define ITE8709_IIR 0x1e /* Interrupt identification register */ --#define ITE8709_RFSR 0x1f /* Receiver FIFO status register */ --#define ITE8709_FIFO_START 0x20 -- --#define ITE8709_MODE_READY 0X00 --#define ITE8709_MODE_WRITE 0X01 --#define ITE8709_MODE_READ 0X02 --#define ITE8709_IIR_RDAI 0x02 /* Receiver data available interrupt */ --#define ITE8709_IIR_RFOI 0x04 /* Receiver FIFO overrun interrupt */ --#define ITE8709_RFSR_MASK 0x3f /* FIFO byte count mask */ -- --/* -- * IT8512 CIR-module registers addresses and values -- * (from IT8512 E/F specification v0.4.1) -- */ --#define IT8512_REG_MSTCR 0x01 /* Master control register */ --#define IT8512_REG_IER 0x02 /* Interrupt enable register */ --#define IT8512_REG_CFR 0x04 /* Carrier frequency register */ --#define IT8512_REG_RCR 0x05 /* Receive control register */ --#define IT8512_REG_BDLR 0x08 /* Baud rate divisor low byte register */ --#define IT8512_REG_BDHR 0x09 /* Baud rate divisor high byte register */ -- --#define IT8512_MSTCR_RESET 0x01 /* Reset registers to default value */ --#define IT8512_MSTCR_FIFOCLR 0x02 /* Clear FIFO */ --#define IT8512_MSTCR_FIFOTL_7 0x04 /* FIFO threshold level : 7 */ --#define IT8512_MSTCR_FIFOTL_25 0x0c /* FIFO threshold level : 25 */ --#define IT8512_IER_RDAIE 0x02 /* Enable data interrupt request */ --#define IT8512_IER_RFOIE 0x04 /* Enable FIFO overrun interrupt req */ --#define IT8512_IER_IEC 0x80 /* Enable interrupt request */ --#define IT8512_CFR_CF_36KHZ 0x09 /* Carrier freq : low speed, 36kHz */ --#define IT8512_RCR_RXDCR_1 0x01 /* Demodulation carrier range : 1 */ --#define IT8512_RCR_RXACT 0x08 /* Receiver active */ --#define IT8512_RCR_RXEN 0x80 /* Receiver enable */ --#define IT8512_BDR_6 6 /* Baud rate divisor : 6 */ -- --/* Actual values used by this driver */ --#define CFG_FIFOTL IT8512_MSTCR_FIFOTL_25 --#define CFG_CR_FREQ IT8512_CFR_CF_36KHZ --#define CFG_DCR IT8512_RCR_RXDCR_1 --#define CFG_BDR IT8512_BDR_6 --#define CFG_TIMEOUT 100000 /* Rearm interrupt when a space is > 100 ms */ -- --static int debug; -- --struct ite8709_device { -- int use_count; -- int io; -- int irq; -- spinlock_t hardware_lock; -- __u64 acc_pulse; -- __u64 acc_space; -- char lastbit; -- struct timeval last_tv; -- struct lirc_driver driver; -- struct tasklet_struct tasklet; -- char force_rearm; -- char rearmed; -- char device_busy; --}; -- --#define dprintk(fmt, args...) \ -- do { \ -- if (debug) \ -- printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ -- fmt, ## args); \ -- } while (0) -- -- --static unsigned char ite8709_read(struct ite8709_device *dev, -- unsigned char port) --{ -- outb(port, dev->io); -- return inb(dev->io+1); --} -- --static void ite8709_write(struct ite8709_device *dev, unsigned char port, -- unsigned char data) --{ -- outb(port, dev->io); -- outb(data, dev->io+1); --} -- --static void ite8709_wait_device(struct ite8709_device *dev) --{ -- int i = 0; -- /* -- * loop until device tells it's ready to continue -- * iterations count is usually ~750 but can sometimes achieve 13000 -- */ -- for (i = 0; i < 15000; i++) { -- udelay(2); -- if (ite8709_read(dev, ITE8709_MODE) == ITE8709_MODE_READY) -- break; -- } --} -- --static void ite8709_write_register(struct ite8709_device *dev, -- unsigned char reg_adr, unsigned char reg_value) --{ -- ite8709_wait_device(dev); -- -- ite8709_write(dev, ITE8709_REG_VAL, reg_value); -- ite8709_write(dev, ITE8709_REG_ADR, reg_adr); -- ite8709_write(dev, ITE8709_MODE, ITE8709_MODE_WRITE); --} -- --static void ite8709_init_hardware(struct ite8709_device *dev) --{ -- spin_lock_irq(&dev->hardware_lock); -- dev->device_busy = 1; -- spin_unlock_irq(&dev->hardware_lock); -- -- ite8709_write_register(dev, IT8512_REG_BDHR, (CFG_BDR >> 8) & 0xff); -- ite8709_write_register(dev, IT8512_REG_BDLR, CFG_BDR & 0xff); -- ite8709_write_register(dev, IT8512_REG_CFR, CFG_CR_FREQ); -- ite8709_write_register(dev, IT8512_REG_IER, -- IT8512_IER_IEC | IT8512_IER_RFOIE | IT8512_IER_RDAIE); -- ite8709_write_register(dev, IT8512_REG_RCR, CFG_DCR); -- ite8709_write_register(dev, IT8512_REG_MSTCR, -- CFG_FIFOTL | IT8512_MSTCR_FIFOCLR); -- ite8709_write_register(dev, IT8512_REG_RCR, -- IT8512_RCR_RXEN | IT8512_RCR_RXACT | CFG_DCR); -- -- spin_lock_irq(&dev->hardware_lock); -- dev->device_busy = 0; -- spin_unlock_irq(&dev->hardware_lock); -- -- tasklet_enable(&dev->tasklet); --} -- --static void ite8709_drop_hardware(struct ite8709_device *dev) --{ -- tasklet_disable(&dev->tasklet); -- -- spin_lock_irq(&dev->hardware_lock); -- dev->device_busy = 1; -- spin_unlock_irq(&dev->hardware_lock); -- -- ite8709_write_register(dev, IT8512_REG_RCR, 0); -- ite8709_write_register(dev, IT8512_REG_MSTCR, -- IT8512_MSTCR_RESET | IT8512_MSTCR_FIFOCLR); -- -- spin_lock_irq(&dev->hardware_lock); -- dev->device_busy = 0; -- spin_unlock_irq(&dev->hardware_lock); --} -- --static int ite8709_set_use_inc(void *data) --{ -- struct ite8709_device *dev; -- dev = data; -- if (dev->use_count == 0) -- ite8709_init_hardware(dev); -- dev->use_count++; -- return 0; --} -- --static void ite8709_set_use_dec(void *data) --{ -- struct ite8709_device *dev; -- dev = data; -- dev->use_count--; -- if (dev->use_count == 0) -- ite8709_drop_hardware(dev); --} -- --static void ite8709_add_read_queue(struct ite8709_device *dev, int flag, -- __u64 val) --{ -- int value; -- -- dprintk("add a %llu usec %s\n", val, flag ? "pulse" : "space"); -- -- value = (val > PULSE_MASK) ? PULSE_MASK : val; -- if (flag) -- value |= PULSE_BIT; -- -- if (!lirc_buffer_full(dev->driver.rbuf)) { -- lirc_buffer_write(dev->driver.rbuf, (void *) &value); -- wake_up(&dev->driver.rbuf->wait_poll); -- } --} -- --static irqreturn_t ite8709_interrupt(int irq, void *dev_id) --{ -- unsigned char data; -- int iir, rfsr, i; -- int fifo = 0; -- char bit; -- struct timeval curr_tv; -- -- /* Bit duration in microseconds */ -- const unsigned long bit_duration = 1000000ul / (115200 / CFG_BDR); -- -- struct ite8709_device *dev; -- dev = dev_id; -- -- /* -- * If device is busy, we simply discard data because we are in one of -- * these two cases : shutting down or rearming the device, so this -- * doesn't really matter and this avoids waiting too long in IRQ ctx -- */ -- spin_lock(&dev->hardware_lock); -- if (dev->device_busy) { -- spin_unlock(&dev->hardware_lock); -- return IRQ_RETVAL(IRQ_HANDLED); -- } -- -- iir = ite8709_read(dev, ITE8709_IIR); -- -- switch (iir) { -- case ITE8709_IIR_RFOI: -- dprintk("fifo overrun, scheduling forced rearm just in case\n"); -- dev->force_rearm = 1; -- tasklet_schedule(&dev->tasklet); -- spin_unlock(&dev->hardware_lock); -- return IRQ_RETVAL(IRQ_HANDLED); -- -- case ITE8709_IIR_RDAI: -- rfsr = ite8709_read(dev, ITE8709_RFSR); -- fifo = rfsr & ITE8709_RFSR_MASK; -- if (fifo > 32) -- fifo = 32; -- dprintk("iir: 0x%x rfsr: 0x%x fifo: %d\n", iir, rfsr, fifo); -- -- if (dev->rearmed) { -- do_gettimeofday(&curr_tv); -- dev->acc_space += 1000000ull -- * (curr_tv.tv_sec - dev->last_tv.tv_sec) -- + (curr_tv.tv_usec - dev->last_tv.tv_usec); -- dev->rearmed = 0; -- } -- for (i = 0; i < fifo; i++) { -- data = ite8709_read(dev, i+ITE8709_FIFO_START); -- data = ~data; -- /* Loop through */ -- for (bit = 0; bit < 8; ++bit) { -- if ((data >> bit) & 1) { -- dev->acc_pulse += bit_duration; -- if (dev->lastbit == 0) { -- ite8709_add_read_queue(dev, 0, -- dev->acc_space); -- dev->acc_space = 0; -- } -- } else { -- dev->acc_space += bit_duration; -- if (dev->lastbit == 1) { -- ite8709_add_read_queue(dev, 1, -- dev->acc_pulse); -- dev->acc_pulse = 0; -- } -- } -- dev->lastbit = (data >> bit) & 1; -- } -- } -- ite8709_write(dev, ITE8709_RFSR, 0); -- -- if (dev->acc_space > CFG_TIMEOUT) { -- dprintk("scheduling rearm IRQ\n"); -- do_gettimeofday(&dev->last_tv); -- dev->force_rearm = 0; -- tasklet_schedule(&dev->tasklet); -- } -- -- spin_unlock(&dev->hardware_lock); -- return IRQ_RETVAL(IRQ_HANDLED); -- -- default: -- /* not our irq */ -- dprintk("unknown IRQ (shouldn't happen) !!\n"); -- spin_unlock(&dev->hardware_lock); -- return IRQ_RETVAL(IRQ_NONE); -- } --} -- --static void ite8709_rearm_irq(unsigned long data) --{ -- struct ite8709_device *dev; -- unsigned long flags; -- dev = (struct ite8709_device *) data; -- -- spin_lock_irqsave(&dev->hardware_lock, flags); -- dev->device_busy = 1; -- spin_unlock_irqrestore(&dev->hardware_lock, flags); -- -- if (dev->force_rearm || dev->acc_space > CFG_TIMEOUT) { -- dprintk("rearming IRQ\n"); -- ite8709_write_register(dev, IT8512_REG_RCR, -- IT8512_RCR_RXACT | CFG_DCR); -- ite8709_write_register(dev, IT8512_REG_MSTCR, -- CFG_FIFOTL | IT8512_MSTCR_FIFOCLR); -- ite8709_write_register(dev, IT8512_REG_RCR, -- IT8512_RCR_RXEN | IT8512_RCR_RXACT | CFG_DCR); -- if (!dev->force_rearm) -- dev->rearmed = 1; -- dev->force_rearm = 0; -- } -- -- spin_lock_irqsave(&dev->hardware_lock, flags); -- dev->device_busy = 0; -- spin_unlock_irqrestore(&dev->hardware_lock, flags); --} -- --static int ite8709_cleanup(struct ite8709_device *dev, int stage, int errno, -- char *msg) --{ -- if (msg != NULL) -- printk(KERN_ERR LIRC_DRIVER_NAME ": %s\n", msg); -- -- switch (stage) { -- case 6: -- if (dev->use_count > 0) -- ite8709_drop_hardware(dev); -- case 5: -- free_irq(dev->irq, dev); -- case 4: -- release_region(dev->io, 2); -- case 3: -- lirc_unregister_driver(dev->driver.minor); -- case 2: -- lirc_buffer_free(dev->driver.rbuf); -- kfree(dev->driver.rbuf); -- case 1: -- kfree(dev); -- case 0: -- ; -- } -- -- return errno; --} -- --static int __devinit ite8709_pnp_probe(struct pnp_dev *dev, -- const struct pnp_device_id *dev_id) --{ -- struct lirc_driver *driver; -- struct ite8709_device *ite8709_dev; -- int ret; -- -- /* Check resources validity */ -- if (!pnp_irq_valid(dev, 0)) -- return ite8709_cleanup(NULL, 0, -ENODEV, "invalid IRQ"); -- if (!pnp_port_valid(dev, 2)) -- return ite8709_cleanup(NULL, 0, -ENODEV, "invalid IO port"); -- -- /* Allocate memory for device struct */ -- ite8709_dev = kzalloc(sizeof(struct ite8709_device), GFP_KERNEL); -- if (ite8709_dev == NULL) -- return ite8709_cleanup(NULL, 0, -ENOMEM, "kzalloc failed"); -- pnp_set_drvdata(dev, ite8709_dev); -- -- /* Initialize device struct */ -- ite8709_dev->use_count = 0; -- ite8709_dev->irq = pnp_irq(dev, 0); -- ite8709_dev->io = pnp_port_start(dev, 2); -- ite8709_dev->hardware_lock = -- __SPIN_LOCK_UNLOCKED(ite8709_dev->hardware_lock); -- ite8709_dev->acc_pulse = 0; -- ite8709_dev->acc_space = 0; -- ite8709_dev->lastbit = 0; -- do_gettimeofday(&ite8709_dev->last_tv); -- tasklet_init(&ite8709_dev->tasklet, ite8709_rearm_irq, -- (long) ite8709_dev); -- ite8709_dev->force_rearm = 0; -- ite8709_dev->rearmed = 0; -- ite8709_dev->device_busy = 0; -- -- /* Initialize driver struct */ -- driver = &ite8709_dev->driver; -- strcpy(driver->name, LIRC_DRIVER_NAME); -- driver->minor = -1; -- driver->code_length = sizeof(int) * 8; -- driver->sample_rate = 0; -- driver->features = LIRC_CAN_REC_MODE2; -- driver->data = ite8709_dev; -- driver->add_to_buf = NULL; -- driver->set_use_inc = ite8709_set_use_inc; -- driver->set_use_dec = ite8709_set_use_dec; -- driver->dev = &dev->dev; -- driver->owner = THIS_MODULE; -- -- /* Initialize LIRC buffer */ -- driver->rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); -- if (!driver->rbuf) -- return ite8709_cleanup(ite8709_dev, 1, -ENOMEM, -- "can't allocate lirc_buffer"); -- if (lirc_buffer_init(driver->rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) -- return ite8709_cleanup(ite8709_dev, 1, -ENOMEM, -- "lirc_buffer_init() failed"); -- -- /* Register LIRC driver */ -- ret = lirc_register_driver(driver); -- if (ret < 0) -- return ite8709_cleanup(ite8709_dev, 2, ret, -- "lirc_register_driver() failed"); -- -- /* Reserve I/O port access */ -- if (!request_region(ite8709_dev->io, 2, LIRC_DRIVER_NAME)) -- return ite8709_cleanup(ite8709_dev, 3, -EBUSY, -- "i/o port already in use"); -- -- /* Reserve IRQ line */ -- ret = request_irq(ite8709_dev->irq, ite8709_interrupt, 0, -- LIRC_DRIVER_NAME, ite8709_dev); -- if (ret < 0) -- return ite8709_cleanup(ite8709_dev, 4, ret, -- "IRQ already in use"); -- -- /* Initialize hardware */ -- ite8709_drop_hardware(ite8709_dev); /* Shutdown hw until first use */ -- -- printk(KERN_INFO LIRC_DRIVER_NAME ": device found : irq=%d io=0x%x\n", -- ite8709_dev->irq, ite8709_dev->io); -- -- return 0; --} -- --static void __devexit ite8709_pnp_remove(struct pnp_dev *dev) --{ -- struct ite8709_device *ite8709_dev; -- ite8709_dev = pnp_get_drvdata(dev); -- -- ite8709_cleanup(ite8709_dev, 6, 0, NULL); -- -- printk(KERN_INFO LIRC_DRIVER_NAME ": device removed\n"); --} -- --#ifdef CONFIG_PM --static int ite8709_pnp_suspend(struct pnp_dev *dev, pm_message_t state) --{ -- struct ite8709_device *ite8709_dev; -- ite8709_dev = pnp_get_drvdata(dev); -- -- if (ite8709_dev->use_count > 0) -- ite8709_drop_hardware(ite8709_dev); -- -- return 0; --} -- --static int ite8709_pnp_resume(struct pnp_dev *dev) --{ -- struct ite8709_device *ite8709_dev; -- ite8709_dev = pnp_get_drvdata(dev); -- -- if (ite8709_dev->use_count > 0) -- ite8709_init_hardware(ite8709_dev); -- -- return 0; --} --#else --#define ite8709_pnp_suspend NULL --#define ite8709_pnp_resume NULL --#endif -- --static const struct pnp_device_id pnp_dev_table[] = { -- {"ITE8709", 0}, -- {} --}; -- --MODULE_DEVICE_TABLE(pnp, pnp_dev_table); -- --static struct pnp_driver ite8709_pnp_driver = { -- .name = LIRC_DRIVER_NAME, -- .probe = ite8709_pnp_probe, -- .remove = __devexit_p(ite8709_pnp_remove), -- .suspend = ite8709_pnp_suspend, -- .resume = ite8709_pnp_resume, -- .id_table = pnp_dev_table, --}; -- --static int __init ite8709_init_module(void) --{ -- return pnp_register_driver(&ite8709_pnp_driver); --} --module_init(ite8709_init_module); -- --static void __exit ite8709_cleanup_module(void) --{ -- pnp_unregister_driver(&ite8709_pnp_driver); --} --module_exit(ite8709_cleanup_module); -- --MODULE_DESCRIPTION("LIRC driver for ITE8709 CIR port"); --MODULE_AUTHOR("Grégory Lardière"); --MODULE_LICENSE("GPL"); -- --module_param(debug, bool, S_IRUGO | S_IWUSR); --MODULE_PARM_DESC(debug, "Enable debugging messages"); -diff --git a/drivers/staging/lirc/lirc_sasem.c b/drivers/staging/lirc/lirc_sasem.c -index 925eabe..63a438d 100644 ---- a/drivers/staging/lirc/lirc_sasem.c -+++ b/drivers/staging/lirc/lirc_sasem.c -@@ -364,7 +364,7 @@ static ssize_t vfd_write(struct file *file, const char *buf, - int i; - int retval = 0; - struct sasem_context *context; -- int *data_buf; -+ int *data_buf = NULL; - - context = (struct sasem_context *) file->private_data; - if (!context) { -diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c -index 0aad0d7..dd6a57c 100644 ---- a/drivers/staging/lirc/lirc_zilog.c -+++ b/drivers/staging/lirc/lirc_zilog.c -@@ -63,14 +63,16 @@ - #include - #include - -+struct IR; -+ - struct IR_rx { -+ struct kref ref; -+ struct IR *ir; -+ - /* RX device */ -+ struct mutex client_lock; - struct i2c_client *c; - -- /* RX device buffer & lock */ -- struct lirc_buffer buf; -- struct mutex buf_lock; -- - /* RX polling thread data */ - struct task_struct *task; - -@@ -80,7 +82,11 @@ struct IR_rx { - }; - - struct IR_tx { -+ struct kref ref; -+ struct IR *ir; -+ - /* TX device */ -+ struct mutex client_lock; - struct i2c_client *c; - - /* TX additional actions needed */ -@@ -89,19 +95,34 @@ struct IR_tx { - }; - - struct IR { -+ struct kref ref; -+ struct list_head list; -+ -+ /* FIXME spinlock access to l.features */ - struct lirc_driver l; -+ struct lirc_buffer rbuf; - - struct mutex ir_lock; -- int open; -+ atomic_t open_count; - - struct i2c_adapter *adapter; -+ -+ spinlock_t rx_ref_lock; /* struct IR_rx kref get()/put() */ - struct IR_rx *rx; -+ -+ spinlock_t tx_ref_lock; /* struct IR_tx kref get()/put() */ - struct IR_tx *tx; - }; - --/* Minor -> data mapping */ --static struct mutex ir_devices_lock; --static struct IR *ir_devices[MAX_IRCTL_DEVICES]; -+/* IR transceiver instance object list */ -+/* -+ * This lock is used for the following: -+ * a. ir_devices_list access, insertions, deletions -+ * b. struct IR kref get()s and put()s -+ * c. serialization of ir_probe() for the two i2c_clients for a Z8 -+ */ -+static DEFINE_MUTEX(ir_devices_lock); -+static LIST_HEAD(ir_devices_list); - - /* Block size for IR transmitter */ - #define TX_BLOCK_SIZE 99 -@@ -147,6 +168,157 @@ static int minor = -1; /* minor number */ - ## args); \ - } while (0) - -+ -+/* struct IR reference counting */ -+static struct IR *get_ir_device(struct IR *ir, bool ir_devices_lock_held) -+{ -+ if (ir_devices_lock_held) { -+ kref_get(&ir->ref); -+ } else { -+ mutex_lock(&ir_devices_lock); -+ kref_get(&ir->ref); -+ mutex_unlock(&ir_devices_lock); -+ } -+ return ir; -+} -+ -+static void release_ir_device(struct kref *ref) -+{ -+ struct IR *ir = container_of(ref, struct IR, ref); -+ -+ /* -+ * Things should be in this state by now: -+ * ir->rx set to NULL and deallocated - happens before ir->rx->ir put() -+ * ir->rx->task kthread stopped - happens before ir->rx->ir put() -+ * ir->tx set to NULL and deallocated - happens before ir->tx->ir put() -+ * ir->open_count == 0 - happens on final close() -+ * ir_lock, tx_ref_lock, rx_ref_lock, all released -+ */ -+ if (ir->l.minor >= 0 && ir->l.minor < MAX_IRCTL_DEVICES) { -+ lirc_unregister_driver(ir->l.minor); -+ ir->l.minor = MAX_IRCTL_DEVICES; -+ } -+ if (ir->rbuf.fifo_initialized) -+ lirc_buffer_free(&ir->rbuf); -+ list_del(&ir->list); -+ kfree(ir); -+} -+ -+static int put_ir_device(struct IR *ir, bool ir_devices_lock_held) -+{ -+ int released; -+ -+ if (ir_devices_lock_held) -+ return kref_put(&ir->ref, release_ir_device); -+ -+ mutex_lock(&ir_devices_lock); -+ released = kref_put(&ir->ref, release_ir_device); -+ mutex_unlock(&ir_devices_lock); -+ -+ return released; -+} -+ -+/* struct IR_rx reference counting */ -+static struct IR_rx *get_ir_rx(struct IR *ir) -+{ -+ struct IR_rx *rx; -+ -+ spin_lock(&ir->rx_ref_lock); -+ rx = ir->rx; -+ if (rx != NULL) -+ kref_get(&rx->ref); -+ spin_unlock(&ir->rx_ref_lock); -+ return rx; -+} -+ -+static void destroy_rx_kthread(struct IR_rx *rx, bool ir_devices_lock_held) -+{ -+ /* end up polling thread */ -+ if (!IS_ERR_OR_NULL(rx->task)) { -+ kthread_stop(rx->task); -+ rx->task = NULL; -+ /* Put the ir ptr that ir_probe() gave to the rx poll thread */ -+ put_ir_device(rx->ir, ir_devices_lock_held); -+ } -+} -+ -+static void release_ir_rx(struct kref *ref) -+{ -+ struct IR_rx *rx = container_of(ref, struct IR_rx, ref); -+ struct IR *ir = rx->ir; -+ -+ /* -+ * This release function can't do all the work, as we want -+ * to keep the rx_ref_lock a spinlock, and killing the poll thread -+ * and releasing the ir reference can cause a sleep. That work is -+ * performed by put_ir_rx() -+ */ -+ ir->l.features &= ~LIRC_CAN_REC_LIRCCODE; -+ /* Don't put_ir_device(rx->ir) here; lock can't be freed yet */ -+ ir->rx = NULL; -+ /* Don't do the kfree(rx) here; we still need to kill the poll thread */ -+ return; -+} -+ -+static int put_ir_rx(struct IR_rx *rx, bool ir_devices_lock_held) -+{ -+ int released; -+ struct IR *ir = rx->ir; -+ -+ spin_lock(&ir->rx_ref_lock); -+ released = kref_put(&rx->ref, release_ir_rx); -+ spin_unlock(&ir->rx_ref_lock); -+ /* Destroy the rx kthread while not holding the spinlock */ -+ if (released) { -+ destroy_rx_kthread(rx, ir_devices_lock_held); -+ kfree(rx); -+ /* Make sure we're not still in a poll_table somewhere */ -+ wake_up_interruptible(&ir->rbuf.wait_poll); -+ } -+ /* Do a reference put() for the rx->ir reference, if we released rx */ -+ if (released) -+ put_ir_device(ir, ir_devices_lock_held); -+ return released; -+} -+ -+/* struct IR_tx reference counting */ -+static struct IR_tx *get_ir_tx(struct IR *ir) -+{ -+ struct IR_tx *tx; -+ -+ spin_lock(&ir->tx_ref_lock); -+ tx = ir->tx; -+ if (tx != NULL) -+ kref_get(&tx->ref); -+ spin_unlock(&ir->tx_ref_lock); -+ return tx; -+} -+ -+static void release_ir_tx(struct kref *ref) -+{ -+ struct IR_tx *tx = container_of(ref, struct IR_tx, ref); -+ struct IR *ir = tx->ir; -+ -+ ir->l.features &= ~LIRC_CAN_SEND_PULSE; -+ /* Don't put_ir_device(tx->ir) here, so our lock doesn't get freed */ -+ ir->tx = NULL; -+ kfree(tx); -+} -+ -+static int put_ir_tx(struct IR_tx *tx, bool ir_devices_lock_held) -+{ -+ int released; -+ struct IR *ir = tx->ir; -+ -+ spin_lock(&ir->tx_ref_lock); -+ released = kref_put(&tx->ref, release_ir_tx); -+ spin_unlock(&ir->tx_ref_lock); -+ /* Do a reference put() for the tx->ir reference, if we released tx */ -+ if (released) -+ put_ir_device(ir, ir_devices_lock_held); -+ return released; -+} -+ - static int add_to_buf(struct IR *ir) - { - __u16 code; -@@ -156,23 +328,38 @@ static int add_to_buf(struct IR *ir) - int ret; - int failures = 0; - unsigned char sendbuf[1] = { 0 }; -- struct IR_rx *rx = ir->rx; -+ struct lirc_buffer *rbuf = ir->l.rbuf; -+ struct IR_rx *rx; -+ struct IR_tx *tx; - -+ if (lirc_buffer_full(rbuf)) { -+ dprintk("buffer overflow\n"); -+ return -EOVERFLOW; -+ } -+ -+ rx = get_ir_rx(ir); - if (rx == NULL) - return -ENXIO; - -- if (lirc_buffer_full(&rx->buf)) { -- dprintk("buffer overflow\n"); -- return -EOVERFLOW; -+ /* Ensure our rx->c i2c_client remains valid for the duration */ -+ mutex_lock(&rx->client_lock); -+ if (rx->c == NULL) { -+ mutex_unlock(&rx->client_lock); -+ put_ir_rx(rx, false); -+ return -ENXIO; - } - -+ tx = get_ir_tx(ir); -+ - /* - * service the device as long as it is returning - * data and we have space - */ - do { -- if (kthread_should_stop()) -- return -ENODATA; -+ if (kthread_should_stop()) { -+ ret = -ENODATA; -+ break; -+ } - - /* - * Lock i2c bus for the duration. RX/TX chips interfere so -@@ -182,7 +369,8 @@ static int add_to_buf(struct IR *ir) - - if (kthread_should_stop()) { - mutex_unlock(&ir->ir_lock); -- return -ENODATA; -+ ret = -ENODATA; -+ break; - } - - /* -@@ -196,7 +384,7 @@ static int add_to_buf(struct IR *ir) - mutex_unlock(&ir->ir_lock); - zilog_error("unable to read from the IR chip " - "after 3 resets, giving up\n"); -- return ret; -+ break; - } - - /* Looks like the chip crashed, reset it */ -@@ -206,19 +394,23 @@ static int add_to_buf(struct IR *ir) - set_current_state(TASK_UNINTERRUPTIBLE); - if (kthread_should_stop()) { - mutex_unlock(&ir->ir_lock); -- return -ENODATA; -+ ret = -ENODATA; -+ break; - } - schedule_timeout((100 * HZ + 999) / 1000); -- ir->tx->need_boot = 1; -+ if (tx != NULL) -+ tx->need_boot = 1; - - ++failures; - mutex_unlock(&ir->ir_lock); -+ ret = 0; - continue; - } - - if (kthread_should_stop()) { - mutex_unlock(&ir->ir_lock); -- return -ENODATA; -+ ret = -ENODATA; -+ break; - } - ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf)); - mutex_unlock(&ir->ir_lock); -@@ -234,12 +426,17 @@ static int add_to_buf(struct IR *ir) - - /* key pressed ? */ - if (rx->hdpvr_data_fmt) { -- if (got_data && (keybuf[0] == 0x80)) -- return 0; -- else if (got_data && (keybuf[0] == 0x00)) -- return -ENODATA; -- } else if ((rx->b[0] & 0x80) == 0) -- return got_data ? 0 : -ENODATA; -+ if (got_data && (keybuf[0] == 0x80)) { -+ ret = 0; -+ break; -+ } else if (got_data && (keybuf[0] == 0x00)) { -+ ret = -ENODATA; -+ break; -+ } -+ } else if ((rx->b[0] & 0x80) == 0) { -+ ret = got_data ? 0 : -ENODATA; -+ break; -+ } - - /* look what we have */ - code = (((__u16)rx->b[0] & 0x7f) << 6) | (rx->b[1] >> 2); -@@ -248,11 +445,16 @@ static int add_to_buf(struct IR *ir) - codes[1] = code & 0xff; - - /* return it */ -- lirc_buffer_write(&rx->buf, codes); -+ lirc_buffer_write(rbuf, codes); - ++got_data; -- } while (!lirc_buffer_full(&rx->buf)); -+ ret = 0; -+ } while (!lirc_buffer_full(rbuf)); - -- return 0; -+ mutex_unlock(&rx->client_lock); -+ if (tx != NULL) -+ put_ir_tx(tx, false); -+ put_ir_rx(rx, false); -+ return ret; - } - - /* -@@ -268,19 +470,19 @@ static int add_to_buf(struct IR *ir) - static int lirc_thread(void *arg) - { - struct IR *ir = arg; -- struct IR_rx *rx = ir->rx; -+ struct lirc_buffer *rbuf = ir->l.rbuf; - - dprintk("poll thread started\n"); - - while (!kthread_should_stop()) { -- set_current_state(TASK_INTERRUPTIBLE); -- - /* if device not opened, we can sleep half a second */ -- if (!ir->open) { -+ if (atomic_read(&ir->open_count) == 0) { - schedule_timeout(HZ/2); - continue; - } - -+ set_current_state(TASK_INTERRUPTIBLE); -+ - /* - * This is ~113*2 + 24 + jitter (2*repeat gap + code length). - * We use this interval as the chip resets every time you poll -@@ -295,7 +497,7 @@ static int lirc_thread(void *arg) - if (kthread_should_stop()) - break; - if (!add_to_buf(ir)) -- wake_up_interruptible(&rx->buf.wait_poll); -+ wake_up_interruptible(&rbuf->wait_poll); - } - - dprintk("poll thread ended\n"); -@@ -304,34 +506,12 @@ static int lirc_thread(void *arg) - - static int set_use_inc(void *data) - { -- struct IR *ir = data; -- -- if (ir->l.owner == NULL || try_module_get(ir->l.owner) == 0) -- return -ENODEV; -- -- /* lock bttv in memory while /dev/lirc is in use */ -- /* -- * this is completely broken code. lirc_unregister_driver() -- * must be possible even when the device is open -- */ -- if (ir->rx != NULL) -- i2c_use_client(ir->rx->c); -- if (ir->tx != NULL) -- i2c_use_client(ir->tx->c); -- - return 0; - } - - static void set_use_dec(void *data) - { -- struct IR *ir = data; -- -- if (ir->rx) -- i2c_release_client(ir->rx->c); -- if (ir->tx) -- i2c_release_client(ir->tx->c); -- if (ir->l.owner != NULL) -- module_put(ir->l.owner); -+ return; - } - - /* safe read of a uint32 (always network byte order) */ -@@ -585,7 +765,7 @@ static int fw_load(struct IR_tx *tx) - } - - /* Request codeset data file */ -- ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", &tx->c->dev); -+ ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", tx->ir->l.dev); - if (ret != 0) { - zilog_error("firmware haup-ir-blaster.bin not available " - "(%d)\n", ret); -@@ -711,59 +891,32 @@ out: - return ret; - } - --/* initialise the IR TX device */ --static int tx_init(struct IR_tx *tx) --{ -- int ret; -- -- /* Load 'firmware' */ -- ret = fw_load(tx); -- if (ret != 0) -- return ret; -- -- /* Send boot block */ -- ret = send_boot_data(tx); -- if (ret != 0) -- return ret; -- tx->need_boot = 0; -- -- /* Looks good */ -- return 0; --} -- --/* do nothing stub to make LIRC happy */ --static loff_t lseek(struct file *filep, loff_t offset, int orig) --{ -- return -ESPIPE; --} -- - /* copied from lirc_dev */ - static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) - { - struct IR *ir = filep->private_data; -- struct IR_rx *rx = ir->rx; -- int ret = 0, written = 0; -+ struct IR_rx *rx; -+ struct lirc_buffer *rbuf = ir->l.rbuf; -+ int ret = 0, written = 0, retries = 0; -+ unsigned int m; - DECLARE_WAITQUEUE(wait, current); - - dprintk("read called\n"); -- if (rx == NULL) -- return -ENODEV; -- -- if (mutex_lock_interruptible(&rx->buf_lock)) -- return -ERESTARTSYS; -- -- if (n % rx->buf.chunk_size) { -+ if (n % rbuf->chunk_size) { - dprintk("read result = -EINVAL\n"); -- mutex_unlock(&rx->buf_lock); - return -EINVAL; - } - -+ rx = get_ir_rx(ir); -+ if (rx == NULL) -+ return -ENXIO; -+ - /* - * we add ourselves to the task queue before buffer check - * to avoid losing scan code (in case when queue is awaken somewhere - * between while condition checking and scheduling) - */ -- add_wait_queue(&rx->buf.wait_poll, &wait); -+ add_wait_queue(&rbuf->wait_poll, &wait); - set_current_state(TASK_INTERRUPTIBLE); - - /* -@@ -771,7 +924,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) - * mode and 'copy_to_user' is happy, wait for data. - */ - while (written < n && ret == 0) { -- if (lirc_buffer_empty(&rx->buf)) { -+ if (lirc_buffer_empty(rbuf)) { - /* - * According to the read(2) man page, 'written' can be - * returned as less than 'n', instead of blocking -@@ -791,20 +944,27 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) - schedule(); - set_current_state(TASK_INTERRUPTIBLE); - } else { -- unsigned char buf[rx->buf.chunk_size]; -- lirc_buffer_read(&rx->buf, buf); -- ret = copy_to_user((void *)outbuf+written, buf, -- rx->buf.chunk_size); -- written += rx->buf.chunk_size; -+ unsigned char buf[rbuf->chunk_size]; -+ m = lirc_buffer_read(rbuf, buf); -+ if (m == rbuf->chunk_size) { -+ ret = copy_to_user((void *)outbuf+written, buf, -+ rbuf->chunk_size); -+ written += rbuf->chunk_size; -+ } else { -+ retries++; -+ } -+ if (retries >= 5) { -+ zilog_error("Buffer read failed!\n"); -+ ret = -EIO; -+ } - } - } - -- remove_wait_queue(&rx->buf.wait_poll, &wait); -+ remove_wait_queue(&rbuf->wait_poll, &wait); -+ put_ir_rx(rx, false); - set_current_state(TASK_RUNNING); -- mutex_unlock(&rx->buf_lock); - -- dprintk("read result = %s (%d)\n", -- ret ? "-EFAULT" : "OK", ret); -+ dprintk("read result = %d (%s)\n", ret, ret ? "Error" : "OK"); - - return ret ? ret : written; - } -@@ -931,17 +1091,27 @@ static ssize_t write(struct file *filep, const char *buf, size_t n, - loff_t *ppos) - { - struct IR *ir = filep->private_data; -- struct IR_tx *tx = ir->tx; -+ struct IR_tx *tx; - size_t i; - int failures = 0; - -- if (tx == NULL) -- return -ENODEV; -- - /* Validate user parameters */ - if (n % sizeof(int)) - return -EINVAL; - -+ /* Get a struct IR_tx reference */ -+ tx = get_ir_tx(ir); -+ if (tx == NULL) -+ return -ENXIO; -+ -+ /* Ensure our tx->c i2c_client remains valid for the duration */ -+ mutex_lock(&tx->client_lock); -+ if (tx->c == NULL) { -+ mutex_unlock(&tx->client_lock); -+ put_ir_tx(tx, false); -+ return -ENXIO; -+ } -+ - /* Lock i2c bus for the duration */ - mutex_lock(&ir->ir_lock); - -@@ -952,11 +1122,24 @@ static ssize_t write(struct file *filep, const char *buf, size_t n, - - if (copy_from_user(&command, buf + i, sizeof(command))) { - mutex_unlock(&ir->ir_lock); -+ mutex_unlock(&tx->client_lock); -+ put_ir_tx(tx, false); - return -EFAULT; - } - - /* Send boot data first if required */ - if (tx->need_boot == 1) { -+ /* Make sure we have the 'firmware' loaded, first */ -+ ret = fw_load(tx); -+ if (ret != 0) { -+ mutex_unlock(&ir->ir_lock); -+ mutex_unlock(&tx->client_lock); -+ put_ir_tx(tx, false); -+ if (ret != -ENOMEM) -+ ret = -EIO; -+ return ret; -+ } -+ /* Prep the chip for transmitting codes */ - ret = send_boot_data(tx); - if (ret == 0) - tx->need_boot = 0; -@@ -968,6 +1151,8 @@ static ssize_t write(struct file *filep, const char *buf, size_t n, - (unsigned)command & 0xFFFF); - if (ret == -EPROTO) { - mutex_unlock(&ir->ir_lock); -+ mutex_unlock(&tx->client_lock); -+ put_ir_tx(tx, false); - return ret; - } - } -@@ -985,6 +1170,8 @@ static ssize_t write(struct file *filep, const char *buf, size_t n, - zilog_error("unable to send to the IR chip " - "after 3 resets, giving up\n"); - mutex_unlock(&ir->ir_lock); -+ mutex_unlock(&tx->client_lock); -+ put_ir_tx(tx, false); - return ret; - } - set_current_state(TASK_UNINTERRUPTIBLE); -@@ -998,6 +1185,11 @@ static ssize_t write(struct file *filep, const char *buf, size_t n, - /* Release i2c bus */ - mutex_unlock(&ir->ir_lock); - -+ mutex_unlock(&tx->client_lock); -+ -+ /* Give back our struct IR_tx reference */ -+ put_ir_tx(tx, false); -+ - /* All looks good */ - return n; - } -@@ -1006,23 +1198,32 @@ static ssize_t write(struct file *filep, const char *buf, size_t n, - static unsigned int poll(struct file *filep, poll_table *wait) - { - struct IR *ir = filep->private_data; -- struct IR_rx *rx = ir->rx; -+ struct IR_rx *rx; -+ struct lirc_buffer *rbuf = ir->l.rbuf; - unsigned int ret; - - dprintk("poll called\n"); -- if (rx == NULL) -- return -ENODEV; -- -- mutex_lock(&rx->buf_lock); - -- poll_wait(filep, &rx->buf.wait_poll, wait); -+ rx = get_ir_rx(ir); -+ if (rx == NULL) { -+ /* -+ * Revisit this, if our poll function ever reports writeable -+ * status for Tx -+ */ -+ dprintk("poll result = POLLERR\n"); -+ return POLLERR; -+ } - -- dprintk("poll result = %s\n", -- lirc_buffer_empty(&rx->buf) ? "0" : "POLLIN|POLLRDNORM"); -+ /* -+ * Add our lirc_buffer's wait_queue to the poll_table. A wake up on -+ * that buffer's wait queue indicates we may have a new poll status. -+ */ -+ poll_wait(filep, &rbuf->wait_poll, wait); - -- ret = lirc_buffer_empty(&rx->buf) ? 0 : (POLLIN|POLLRDNORM); -+ /* Indicate what ops could happen immediately without blocking */ -+ ret = lirc_buffer_empty(rbuf) ? 0 : (POLLIN|POLLRDNORM); - -- mutex_unlock(&rx->buf_lock); -+ dprintk("poll result = %s\n", ret ? "POLLIN|POLLRDNORM" : "none"); - return ret; - } - -@@ -1030,11 +1231,9 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg) - { - struct IR *ir = filep->private_data; - int result; -- unsigned long mode, features = 0; -+ unsigned long mode, features; - -- features |= LIRC_CAN_SEND_PULSE; -- if (ir->rx != NULL) -- features |= LIRC_CAN_REC_LIRCCODE; -+ features = ir->l.features; - - switch (cmd) { - case LIRC_GET_LENGTH: -@@ -1061,9 +1260,15 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg) - result = -EINVAL; - break; - case LIRC_GET_SEND_MODE: -+ if (!(features&LIRC_CAN_SEND_MASK)) -+ return -ENOSYS; -+ - result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg); - break; - case LIRC_SET_SEND_MODE: -+ if (!(features&LIRC_CAN_SEND_MASK)) -+ return -ENOSYS; -+ - result = get_user(mode, (unsigned long *) arg); - if (!result && mode != LIRC_MODE_PULSE) - return -EINVAL; -@@ -1074,13 +1279,24 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg) - return result; - } - --/* ir_devices_lock must be held */ --static struct IR *find_ir_device_by_minor(unsigned int minor) -+static struct IR *get_ir_device_by_minor(unsigned int minor) - { -- if (minor >= MAX_IRCTL_DEVICES) -- return NULL; -+ struct IR *ir; -+ struct IR *ret = NULL; -+ -+ mutex_lock(&ir_devices_lock); -+ -+ if (!list_empty(&ir_devices_list)) { -+ list_for_each_entry(ir, &ir_devices_list, list) { -+ if (ir->l.minor == minor) { -+ ret = get_ir_device(ir, true); -+ break; -+ } -+ } -+ } - -- return ir_devices[minor]; -+ mutex_unlock(&ir_devices_lock); -+ return ret; - } - - /* -@@ -1090,31 +1306,20 @@ static struct IR *find_ir_device_by_minor(unsigned int minor) - static int open(struct inode *node, struct file *filep) - { - struct IR *ir; -- int ret; - unsigned int minor = MINOR(node->i_rdev); - - /* find our IR struct */ -- mutex_lock(&ir_devices_lock); -- ir = find_ir_device_by_minor(minor); -- mutex_unlock(&ir_devices_lock); -+ ir = get_ir_device_by_minor(minor); - - if (ir == NULL) - return -ENODEV; - -- /* increment in use count */ -- mutex_lock(&ir->ir_lock); -- ++ir->open; -- ret = set_use_inc(ir); -- if (ret != 0) { -- --ir->open; -- mutex_unlock(&ir->ir_lock); -- return ret; -- } -- mutex_unlock(&ir->ir_lock); -+ atomic_inc(&ir->open_count); - - /* stash our IR struct */ - filep->private_data = ir; - -+ nonseekable_open(node, filep); - return 0; - } - -@@ -1128,22 +1333,12 @@ static int close(struct inode *node, struct file *filep) - return -ENODEV; - } - -- /* decrement in use count */ -- mutex_lock(&ir->ir_lock); -- --ir->open; -- set_use_dec(ir); -- mutex_unlock(&ir->ir_lock); -+ atomic_dec(&ir->open_count); - -+ put_ir_device(ir, false); - return 0; - } - --static struct lirc_driver lirc_template = { -- .name = "lirc_zilog", -- .set_use_inc = set_use_inc, -- .set_use_dec = set_use_dec, -- .owner = THIS_MODULE --}; -- - static int ir_remove(struct i2c_client *client); - static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id); - -@@ -1170,7 +1365,7 @@ static struct i2c_driver driver = { - - static const struct file_operations lirc_fops = { - .owner = THIS_MODULE, -- .llseek = lseek, -+ .llseek = no_llseek, - .read = read, - .write = write, - .poll = poll, -@@ -1182,97 +1377,64 @@ static const struct file_operations lirc_fops = { - .release = close - }; - --static void destroy_rx_kthread(struct IR_rx *rx) --{ -- /* end up polling thread */ -- if (rx != NULL && !IS_ERR_OR_NULL(rx->task)) { -- kthread_stop(rx->task); -- rx->task = NULL; -- } --} -+static struct lirc_driver lirc_template = { -+ .name = "lirc_zilog", -+ .minor = -1, -+ .code_length = 13, -+ .buffer_size = BUFLEN / 2, -+ .sample_rate = 0, /* tell lirc_dev to not start its own kthread */ -+ .chunk_size = 2, -+ .set_use_inc = set_use_inc, -+ .set_use_dec = set_use_dec, -+ .fops = &lirc_fops, -+ .owner = THIS_MODULE, -+}; - --/* ir_devices_lock must be held */ --static int add_ir_device(struct IR *ir) -+static int ir_remove(struct i2c_client *client) - { -- int i; -- -- for (i = 0; i < MAX_IRCTL_DEVICES; i++) -- if (ir_devices[i] == NULL) { -- ir_devices[i] = ir; -- break; -+ if (strncmp("ir_tx_z8", client->name, 8) == 0) { -+ struct IR_tx *tx = i2c_get_clientdata(client); -+ if (tx != NULL) { -+ mutex_lock(&tx->client_lock); -+ tx->c = NULL; -+ mutex_unlock(&tx->client_lock); -+ put_ir_tx(tx, false); - } -- -- return i == MAX_IRCTL_DEVICES ? -ENOMEM : i; --} -- --/* ir_devices_lock must be held */ --static void del_ir_device(struct IR *ir) --{ -- int i; -- -- for (i = 0; i < MAX_IRCTL_DEVICES; i++) -- if (ir_devices[i] == ir) { -- ir_devices[i] = NULL; -- break; -+ } else if (strncmp("ir_rx_z8", client->name, 8) == 0) { -+ struct IR_rx *rx = i2c_get_clientdata(client); -+ if (rx != NULL) { -+ mutex_lock(&rx->client_lock); -+ rx->c = NULL; -+ mutex_unlock(&rx->client_lock); -+ put_ir_rx(rx, false); - } --} -- --static int ir_remove(struct i2c_client *client) --{ -- struct IR *ir = i2c_get_clientdata(client); -- -- mutex_lock(&ir_devices_lock); -- -- if (ir == NULL) { -- /* We destroyed everything when the first client came through */ -- mutex_unlock(&ir_devices_lock); -- return 0; - } -- -- /* Good-bye LIRC */ -- lirc_unregister_driver(ir->l.minor); -- -- /* Good-bye Rx */ -- destroy_rx_kthread(ir->rx); -- if (ir->rx != NULL) { -- if (ir->rx->buf.fifo_initialized) -- lirc_buffer_free(&ir->rx->buf); -- i2c_set_clientdata(ir->rx->c, NULL); -- kfree(ir->rx); -- } -- -- /* Good-bye Tx */ -- i2c_set_clientdata(ir->tx->c, NULL); -- kfree(ir->tx); -- -- /* Good-bye IR */ -- del_ir_device(ir); -- kfree(ir); -- -- mutex_unlock(&ir_devices_lock); - return 0; - } - - - /* ir_devices_lock must be held */ --static struct IR *find_ir_device_by_adapter(struct i2c_adapter *adapter) -+static struct IR *get_ir_device_by_adapter(struct i2c_adapter *adapter) - { -- int i; -- struct IR *ir = NULL; -+ struct IR *ir; - -- for (i = 0; i < MAX_IRCTL_DEVICES; i++) -- if (ir_devices[i] != NULL && -- ir_devices[i]->adapter == adapter) { -- ir = ir_devices[i]; -- break; -+ if (list_empty(&ir_devices_list)) -+ return NULL; -+ -+ list_for_each_entry(ir, &ir_devices_list, list) -+ if (ir->adapter == adapter) { -+ get_ir_device(ir, true); -+ return ir; - } - -- return ir; -+ return NULL; - } - - static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) - { - struct IR *ir; -+ struct IR_tx *tx; -+ struct IR_rx *rx; - struct i2c_adapter *adap = client->adapter; - int ret; - bool tx_probe = false; -@@ -1296,133 +1458,170 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) - mutex_lock(&ir_devices_lock); - - /* Use a single struct IR instance for both the Rx and Tx functions */ -- ir = find_ir_device_by_adapter(adap); -+ ir = get_ir_device_by_adapter(adap); - if (ir == NULL) { - ir = kzalloc(sizeof(struct IR), GFP_KERNEL); - if (ir == NULL) { - ret = -ENOMEM; - goto out_no_ir; - } -+ kref_init(&ir->ref); -+ - /* store for use in ir_probe() again, and open() later on */ -- ret = add_ir_device(ir); -- if (ret) -- goto out_free_ir; -+ INIT_LIST_HEAD(&ir->list); -+ list_add_tail(&ir->list, &ir_devices_list); - - ir->adapter = adap; - mutex_init(&ir->ir_lock); -+ atomic_set(&ir->open_count, 0); -+ spin_lock_init(&ir->tx_ref_lock); -+ spin_lock_init(&ir->rx_ref_lock); - - /* set lirc_dev stuff */ - memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver)); -- ir->l.minor = minor; /* module option */ -- ir->l.code_length = 13; -- ir->l.rbuf = NULL; -- ir->l.fops = &lirc_fops; -- ir->l.data = ir; -- ir->l.dev = &adap->dev; -- ir->l.sample_rate = 0; -+ /* -+ * FIXME this is a pointer reference to us, but no refcount. -+ * -+ * This OK for now, since lirc_dev currently won't touch this -+ * buffer as we provide our own lirc_fops. -+ * -+ * Currently our own lirc_fops rely on this ir->l.rbuf pointer -+ */ -+ ir->l.rbuf = &ir->rbuf; -+ ir->l.dev = &adap->dev; -+ ret = lirc_buffer_init(ir->l.rbuf, -+ ir->l.chunk_size, ir->l.buffer_size); -+ if (ret) -+ goto out_put_ir; - } - - if (tx_probe) { -+ /* Get the IR_rx instance for later, if already allocated */ -+ rx = get_ir_rx(ir); -+ - /* Set up a struct IR_tx instance */ -- ir->tx = kzalloc(sizeof(struct IR_tx), GFP_KERNEL); -- if (ir->tx == NULL) { -+ tx = kzalloc(sizeof(struct IR_tx), GFP_KERNEL); -+ if (tx == NULL) { - ret = -ENOMEM; -- goto out_free_xx; -+ goto out_put_xx; - } -- -- ir->tx->c = client; -- ir->tx->need_boot = 1; -- ir->tx->post_tx_ready_poll = -+ kref_init(&tx->ref); -+ ir->tx = tx; -+ -+ ir->l.features |= LIRC_CAN_SEND_PULSE; -+ mutex_init(&tx->client_lock); -+ tx->c = client; -+ tx->need_boot = 1; -+ tx->post_tx_ready_poll = - (id->driver_data & ID_FLAG_HDPVR) ? false : true; -+ -+ /* An ir ref goes to the struct IR_tx instance */ -+ tx->ir = get_ir_device(ir, true); -+ -+ /* A tx ref goes to the i2c_client */ -+ i2c_set_clientdata(client, get_ir_tx(ir)); -+ -+ /* -+ * Load the 'firmware'. We do this before registering with -+ * lirc_dev, so the first firmware load attempt does not happen -+ * after a open() or write() call on the device. -+ * -+ * Failure here is not deemed catastrophic, so the receiver will -+ * still be usable. Firmware load will be retried in write(), -+ * if it is needed. -+ */ -+ fw_load(tx); -+ -+ /* Proceed only if the Rx client is also ready or not needed */ -+ if (rx == NULL && !tx_only) { -+ zilog_info("probe of IR Tx on %s (i2c-%d) done. Waiting" -+ " on IR Rx.\n", adap->name, adap->nr); -+ goto out_ok; -+ } - } else { -+ /* Get the IR_tx instance for later, if already allocated */ -+ tx = get_ir_tx(ir); -+ - /* Set up a struct IR_rx instance */ -- ir->rx = kzalloc(sizeof(struct IR_rx), GFP_KERNEL); -- if (ir->rx == NULL) { -+ rx = kzalloc(sizeof(struct IR_rx), GFP_KERNEL); -+ if (rx == NULL) { - ret = -ENOMEM; -- goto out_free_xx; -+ goto out_put_xx; - } -+ kref_init(&rx->ref); -+ ir->rx = rx; - -- ret = lirc_buffer_init(&ir->rx->buf, 2, BUFLEN / 2); -- if (ret) -- goto out_free_xx; -- -- mutex_init(&ir->rx->buf_lock); -- ir->rx->c = client; -- ir->rx->hdpvr_data_fmt = -+ ir->l.features |= LIRC_CAN_REC_LIRCCODE; -+ mutex_init(&rx->client_lock); -+ rx->c = client; -+ rx->hdpvr_data_fmt = - (id->driver_data & ID_FLAG_HDPVR) ? true : false; - -- /* set lirc_dev stuff */ -- ir->l.rbuf = &ir->rx->buf; -- } -- -- i2c_set_clientdata(client, ir); -+ /* An ir ref goes to the struct IR_rx instance */ -+ rx->ir = get_ir_device(ir, true); - -- /* Proceed only if we have the required Tx and Rx clients ready to go */ -- if (ir->tx == NULL || -- (ir->rx == NULL && !tx_only)) { -- zilog_info("probe of IR %s on %s (i2c-%d) done. Waiting on " -- "IR %s.\n", tx_probe ? "Tx" : "Rx", adap->name, -- adap->nr, tx_probe ? "Rx" : "Tx"); -- goto out_ok; -- } -+ /* An rx ref goes to the i2c_client */ -+ i2c_set_clientdata(client, get_ir_rx(ir)); - -- /* initialise RX device */ -- if (ir->rx != NULL) { -- /* try to fire up polling thread */ -- ir->rx->task = kthread_run(lirc_thread, ir, -- "zilog-rx-i2c-%d", adap->nr); -- if (IS_ERR(ir->rx->task)) { -- ret = PTR_ERR(ir->rx->task); -+ /* -+ * Start the polling thread. -+ * It will only perform an empty loop around schedule_timeout() -+ * until we register with lirc_dev and the first user open() -+ */ -+ /* An ir ref goes to the new rx polling kthread */ -+ rx->task = kthread_run(lirc_thread, get_ir_device(ir, true), -+ "zilog-rx-i2c-%d", adap->nr); -+ if (IS_ERR(rx->task)) { -+ ret = PTR_ERR(rx->task); - zilog_error("%s: could not start IR Rx polling thread" - "\n", __func__); -- goto out_free_xx; -+ /* Failed kthread, so put back the ir ref */ -+ put_ir_device(ir, true); -+ /* Failure exit, so put back rx ref from i2c_client */ -+ i2c_set_clientdata(client, NULL); -+ put_ir_rx(rx, true); -+ ir->l.features &= ~LIRC_CAN_REC_LIRCCODE; -+ goto out_put_xx; -+ } -+ -+ /* Proceed only if the Tx client is also ready */ -+ if (tx == NULL) { -+ zilog_info("probe of IR Rx on %s (i2c-%d) done. Waiting" -+ " on IR Tx.\n", adap->name, adap->nr); -+ goto out_ok; - } - } - - /* register with lirc */ -+ ir->l.minor = minor; /* module option: user requested minor number */ - ir->l.minor = lirc_register_driver(&ir->l); - if (ir->l.minor < 0 || ir->l.minor >= MAX_IRCTL_DEVICES) { - zilog_error("%s: \"minor\" must be between 0 and %d (%d)!\n", - __func__, MAX_IRCTL_DEVICES-1, ir->l.minor); - ret = -EBADRQC; -- goto out_free_thread; -+ goto out_put_xx; - } -+ zilog_info("IR unit on %s (i2c-%d) registered as lirc%d and ready\n", -+ adap->name, adap->nr, ir->l.minor); - -- /* -- * if we have the tx device, load the 'firmware'. We do this -- * after registering with lirc as otherwise hotplug seems to take -- * 10s to create the lirc device. -- */ -- ret = tx_init(ir->tx); -- if (ret != 0) -- goto out_unregister; -- -- zilog_info("probe of IR %s on %s (i2c-%d) done. IR unit ready.\n", -- tx_probe ? "Tx" : "Rx", adap->name, adap->nr); - out_ok: -+ if (rx != NULL) -+ put_ir_rx(rx, true); -+ if (tx != NULL) -+ put_ir_tx(tx, true); -+ put_ir_device(ir, true); -+ zilog_info("probe of IR %s on %s (i2c-%d) done\n", -+ tx_probe ? "Tx" : "Rx", adap->name, adap->nr); - mutex_unlock(&ir_devices_lock); - return 0; - --out_unregister: -- lirc_unregister_driver(ir->l.minor); --out_free_thread: -- destroy_rx_kthread(ir->rx); --out_free_xx: -- if (ir->rx != NULL) { -- if (ir->rx->buf.fifo_initialized) -- lirc_buffer_free(&ir->rx->buf); -- if (ir->rx->c != NULL) -- i2c_set_clientdata(ir->rx->c, NULL); -- kfree(ir->rx); -- } -- if (ir->tx != NULL) { -- if (ir->tx->c != NULL) -- i2c_set_clientdata(ir->tx->c, NULL); -- kfree(ir->tx); -- } --out_free_ir: -- del_ir_device(ir); -- kfree(ir); -+out_put_xx: -+ if (rx != NULL) -+ put_ir_rx(rx, true); -+ if (tx != NULL) -+ put_ir_tx(tx, true); -+out_put_ir: -+ put_ir_device(ir, true); - out_no_ir: - zilog_error("%s: probing IR %s on %s (i2c-%d) failed with %d\n", - __func__, tx_probe ? "Tx" : "Rx", adap->name, adap->nr, -@@ -1438,7 +1637,6 @@ static int __init zilog_init(void) - zilog_notify("Zilog/Hauppauge IR driver initializing\n"); - - mutex_init(&tx_data_lock); -- mutex_init(&ir_devices_lock); - - request_module("firmware_class"); - -diff --git a/include/media/rc-map.h b/include/media/rc-map.h -index d843afc..9184751 100644 ---- a/include/media/rc-map.h -+++ b/include/media/rc-map.h -@@ -94,7 +94,7 @@ void rc_map_init(void); - #define RC_MAP_GADMEI_RM008Z "rc-gadmei-rm008z" - #define RC_MAP_GENIUS_TVGO_A11MCE "rc-genius-tvgo-a11mce" - #define RC_MAP_GOTVIEW7135 "rc-gotview7135" --#define RC_MAP_HAUPPAUGE_NEW "rc-hauppauge-new" -+#define RC_MAP_HAUPPAUGE_NEW "rc-hauppauge" - #define RC_MAP_IMON_MCE "rc-imon-mce" - #define RC_MAP_IMON_PAD "rc-imon-pad" - #define RC_MAP_IODATA_BCTV7E "rc-iodata-bctv7e" -@@ -125,7 +125,7 @@ void rc_map_init(void); - #define RC_MAP_PROTEUS_2309 "rc-proteus-2309" - #define RC_MAP_PURPLETV "rc-purpletv" - #define RC_MAP_PV951 "rc-pv951" --#define RC_MAP_RC5_HAUPPAUGE_NEW "rc-rc5-hauppauge-new" -+#define RC_MAP_HAUPPAUGE "rc-hauppauge" - #define RC_MAP_RC5_TV "rc-rc5-tv" - #define RC_MAP_RC6_MCE "rc-rc6-mce" - #define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys" -diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h -index 6e96b26..f80b537 100644 ---- a/include/media/soc_camera.h -+++ b/include/media/soc_camera.h -@@ -30,6 +30,8 @@ struct soc_camera_device { - struct device *pdev; /* Platform device */ - s32 user_width; - s32 user_height; -+ u32 bytesperline; /* for padding, zero if unused */ -+ u32 sizeimage; - enum v4l2_colorspace colorspace; - unsigned char iface; /* Host number */ - unsigned char devnum; /* Device number per host */ diff --git a/pci-pcie-links-may-not-get-configured-for-aspm-under-powersave-mode.patch b/pci-pcie-links-may-not-get-configured-for-aspm-under-powersave-mode.patch deleted file mode 100644 index 0c7f592..0000000 --- a/pci-pcie-links-may-not-get-configured-for-aspm-under-powersave-mode.patch +++ /dev/null @@ -1,112 +0,0 @@ -From: Naga Chumbalkar -Date: Mon, 21 Mar 2011 03:29:08 +0000 (+0000) -Subject: PCI: PCIe links may not get configured for ASPM under POWERSAVE mode -X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=1a680b7c325882188865f05b9a88d32f75f26495 - -PCI: PCIe links may not get configured for ASPM under POWERSAVE mode - -v3 -> v2: Moved ASPM enabling logic to pci_set_power_state() -v2 -> v1: Preserved the logic in pci_raw_set_power_state() - : Added ASPM enabling logic after scanning Root Bridge - : http://marc.info/?l=linux-pci&m=130046996216391&w=2 -v1 : http://marc.info/?l=linux-pci&m=130013164703283&w=2 - -The assumption made in commit 41cd766b065970ff6f6c89dd1cf55fa706c84a3d -(PCI: Don't enable aspm before drivers have had a chance to veto it) that -pci_enable_device() will result in re-configuring ASPM when aspm_policy is -POWERSAVE is no longer valid. This is due to commit -97c145f7c87453cec90e91238fba5fe2c1561b32 (PCI: read current power state -at enable time) which resets dev->current_state to D0. Due to this the -call to pcie_aspm_pm_state_change() is never made. Note the equality check -(below) that returns early: -./drivers/pci/pci.c: pci_raw_set_pci_power_state() -546 /* Check if we're already there */ -547 if (dev->current_state == state) -548 return 0; - -Therefore OSPM never configures the PCIe links for ASPM to turn them "on". - -Fix it by configuring ASPM from the pci_enable_device() code path. This -also allows a driver such as the e1000e networking driver a chance to -disable ASPM (L0s, L1), if need be, prior to enabling the device. A -driver may perform this action if the device is known to mis-behave -wrt ASPM. - -Signed-off-by: Naga Chumbalkar -Acked-by: Rafael J. Wysocki -Cc: Matthew Garrett -Signed-off-by: Jesse Barnes ---- - -diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c -index b714d78..2472e71 100644 ---- a/drivers/pci/pci.c -+++ b/drivers/pci/pci.c -@@ -740,6 +740,12 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) - - if (!__pci_complete_power_transition(dev, state)) - error = 0; -+ /* -+ * When aspm_policy is "powersave" this call ensures -+ * that ASPM is configured. -+ */ -+ if (!error && dev->bus->self) -+ pcie_aspm_powersave_config_link(dev->bus->self); - - return error; - } -diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c -index bbdb4fd..e61b82e 100644 ---- a/drivers/pci/pcie/aspm.c -+++ b/drivers/pci/pcie/aspm.c -@@ -708,6 +708,28 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev) - up_read(&pci_bus_sem); - } - -+void pcie_aspm_powersave_config_link(struct pci_dev *pdev) -+{ -+ struct pcie_link_state *link = pdev->link_state; -+ -+ if (aspm_disabled || !pci_is_pcie(pdev) || !link) -+ return; -+ -+ if (aspm_policy != POLICY_POWERSAVE) -+ return; -+ -+ if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && -+ (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) -+ return; -+ -+ down_read(&pci_bus_sem); -+ mutex_lock(&aspm_lock); -+ pcie_config_aspm_path(link); -+ pcie_set_clkpm(link, policy_to_clkpm_state(link)); -+ mutex_unlock(&aspm_lock); -+ up_read(&pci_bus_sem); -+} -+ - /* - * pci_disable_link_state - disable pci device's link state, so the link will - * never enter specific states -diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h -index ce68105..67cb3ae 100644 ---- a/include/linux/pci-aspm.h -+++ b/include/linux/pci-aspm.h -@@ -26,6 +26,7 @@ - extern void pcie_aspm_init_link_state(struct pci_dev *pdev); - extern void pcie_aspm_exit_link_state(struct pci_dev *pdev); - extern void pcie_aspm_pm_state_change(struct pci_dev *pdev); -+extern void pcie_aspm_powersave_config_link(struct pci_dev *pdev); - extern void pci_disable_link_state(struct pci_dev *pdev, int state); - extern void pcie_clear_aspm(void); - extern void pcie_no_aspm(void); -@@ -39,6 +40,9 @@ static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) - static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) - { - } -+static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) -+{ -+} - static inline void pci_disable_link_state(struct pci_dev *pdev, int state) - { - } diff --git a/printk-do-not-mangle-valid-userspace-syslog-prefixes.patch b/printk-do-not-mangle-valid-userspace-syslog-prefixes.patch deleted file mode 100644 index 73885ae..0000000 --- a/printk-do-not-mangle-valid-userspace-syslog-prefixes.patch +++ /dev/null @@ -1,214 +0,0 @@ -From: Kay Sievers -Date: Sun, 13 Mar 2011 02:19:51 +0000 (+0100) -Subject: printk: do not mangle valid userspace syslog prefixes -X-Git-Tag: v2.6.39-rc1~471^2 -X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9d90c8d9cde929cbc575098e825d7c29d9f45054 - -printk: do not mangle valid userspace syslog prefixes - -printk: do not mangle valid userspace syslog prefixes with /dev/kmsg - -Log messages passed to the kernel log by using /dev/kmsg or /dev/ttyprintk -might contain a syslog prefix including the syslog facility value. - -This makes printk to recognize these headers properly, extract the real log -level from it to use, and add the prefix as a proper prefix to the -log buffer, instead of wrongly printing it as the log message text. - -Before: - $ echo '<14>text' > /dev/kmsg - $ dmesg -r - <4>[135159.594810] <14>text - -After: - $ echo '<14>text' > /dev/kmsg - $ dmesg -r - <14>[ 50.750654] text - -Cc: Lennart Poettering -Signed-off-by: Kay Sievers -Signed-off-by: Greg Kroah-Hartman ---- - -diff --git a/kernel/printk.c b/kernel/printk.c -index 2ddbdc7..5e3d042 100644 ---- a/kernel/printk.c -+++ b/kernel/printk.c -@@ -499,6 +499,71 @@ static void _call_console_drivers(unsigned start, - } - - /* -+ * Parse the syslog header <[0-9]*>. The decimal value represents 32bit, the -+ * lower 3 bit are the log level, the rest are the log facility. In case -+ * userspace passes usual userspace syslog messages to /dev/kmsg or -+ * /dev/ttyprintk, the log prefix might contain the facility. Printk needs -+ * to extract the correct log level for in-kernel processing, and not mangle -+ * the original value. -+ * -+ * If a prefix is found, the length of the prefix is returned. If 'level' is -+ * passed, it will be filled in with the log level without a possible facility -+ * value. If 'special' is passed, the special printk prefix chars are accepted -+ * and returned. If no valid header is found, 0 is returned and the passed -+ * variables are not touched. -+ */ -+static size_t log_prefix(const char *p, unsigned int *level, char *special) -+{ -+ unsigned int lev = 0; -+ char sp = '\0'; -+ size_t len; -+ -+ if (p[0] != '<' || !p[1]) -+ return 0; -+ if (p[2] == '>') { -+ /* usual single digit level number or special char */ -+ switch (p[1]) { -+ case '0' ... '7': -+ lev = p[1] - '0'; -+ break; -+ case 'c': /* KERN_CONT */ -+ case 'd': /* KERN_DEFAULT */ -+ sp = p[1]; -+ break; -+ default: -+ return 0; -+ } -+ len = 3; -+ } else { -+ /* multi digit including the level and facility number */ -+ char *endp = NULL; -+ -+ if (p[1] < '0' && p[1] > '9') -+ return 0; -+ -+ lev = (simple_strtoul(&p[1], &endp, 10) & 7); -+ if (endp == NULL || endp[0] != '>') -+ return 0; -+ len = (endp + 1) - p; -+ } -+ -+ /* do not accept special char if not asked for */ -+ if (sp && !special) -+ return 0; -+ -+ if (special) { -+ *special = sp; -+ /* return special char, do not touch level */ -+ if (sp) -+ return len; -+ } -+ -+ if (level) -+ *level = lev; -+ return len; -+} -+ -+/* - * Call the console drivers, asking them to write out - * log_buf[start] to log_buf[end - 1]. - * The console_lock must be held. -@@ -513,13 +578,9 @@ static void call_console_drivers(unsigned start, unsigned end) - cur_index = start; - start_print = start; - while (cur_index != end) { -- if (msg_level < 0 && ((end - cur_index) > 2) && -- LOG_BUF(cur_index + 0) == '<' && -- LOG_BUF(cur_index + 1) >= '0' && -- LOG_BUF(cur_index + 1) <= '7' && -- LOG_BUF(cur_index + 2) == '>') { -- msg_level = LOG_BUF(cur_index + 1) - '0'; -- cur_index += 3; -+ if (msg_level < 0 && ((end - cur_index) > 2)) { -+ /* strip log prefix */ -+ cur_index += log_prefix(&LOG_BUF(cur_index), &msg_level, NULL); - start_print = cur_index; - } - while (cur_index != end) { -@@ -717,6 +778,8 @@ asmlinkage int vprintk(const char *fmt, va_list args) - unsigned long flags; - int this_cpu; - char *p; -+ size_t plen; -+ char special; - - boot_delay_msec(); - printk_delay(); -@@ -757,45 +820,52 @@ asmlinkage int vprintk(const char *fmt, va_list args) - printed_len += vscnprintf(printk_buf + printed_len, - sizeof(printk_buf) - printed_len, fmt, args); - -- - p = printk_buf; - -- /* Do we have a loglevel in the string? */ -- if (p[0] == '<') { -- unsigned char c = p[1]; -- if (c && p[2] == '>') { -- switch (c) { -- case '0' ... '7': /* loglevel */ -- current_log_level = c - '0'; -- /* Fallthrough - make sure we're on a new line */ -- case 'd': /* KERN_DEFAULT */ -- if (!new_text_line) { -- emit_log_char('\n'); -- new_text_line = 1; -- } -- /* Fallthrough - skip the loglevel */ -- case 'c': /* KERN_CONT */ -- p += 3; -- break; -+ /* Read log level and handle special printk prefix */ -+ plen = log_prefix(p, ¤t_log_level, &special); -+ if (plen) { -+ p += plen; -+ -+ switch (special) { -+ case 'c': /* Strip KERN_CONT, continue line */ -+ plen = 0; -+ break; -+ case 'd': /* Strip KERN_DEFAULT, start new line */ -+ plen = 0; -+ default: -+ if (!new_text_line) { -+ emit_log_char('\n'); -+ new_text_line = 1; - } - } - } - - /* -- * Copy the output into log_buf. If the caller didn't provide -- * appropriate log level tags, we insert them here -+ * Copy the output into log_buf. If the caller didn't provide -+ * the appropriate log prefix, we insert them here - */ -- for ( ; *p; p++) { -+ for (; *p; p++) { - if (new_text_line) { -- /* Always output the token */ -- emit_log_char('<'); -- emit_log_char(current_log_level + '0'); -- emit_log_char('>'); -- printed_len += 3; - new_text_line = 0; - -+ if (plen) { -+ /* Copy original log prefix */ -+ int i; -+ -+ for (i = 0; i < plen; i++) -+ emit_log_char(printk_buf[i]); -+ printed_len += plen; -+ } else { -+ /* Add log prefix */ -+ emit_log_char('<'); -+ emit_log_char(current_log_level + '0'); -+ emit_log_char('>'); -+ printed_len += 3; -+ } -+ - if (printk_time) { -- /* Follow the token with the time */ -+ /* Add the current time stamp */ - char tbuf[50], *tp; - unsigned tlen; - unsigned long long t; diff --git a/scsi_dh_hp_sw-fix-deadlock-in-start_stop_endio.patch b/scsi_dh_hp_sw-fix-deadlock-in-start_stop_endio.patch deleted file mode 100644 index faded33..0000000 --- a/scsi_dh_hp_sw-fix-deadlock-in-start_stop_endio.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 7a1e9d829f8bd821466c5ea834ad6f378740d2be Mon Sep 17 00:00:00 2001 -From: Mike Snitzer -Date: Tue, 25 Jan 2011 11:52:17 -0500 -Subject: [SCSI] scsi_dh_hp_sw: fix deadlock in start_stop_endio - -The use of blk_execute_rq_nowait() implies __blk_put_request() is needed -in start_stop_endio() rather than blk_put_request() -- -blk_finish_request() is called with queue lock already held. - -Signed-off-by: Mike Snitzer -Signed-off-by: James Bottomley ---- - drivers/scsi/device_handler/scsi_dh_hp_sw.c | 3 ++- - 1 files changed, 2 insertions(+), 1 deletions(-) - -diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c -index e391664..d0363c8 100644 ---- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c -+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c -@@ -225,7 +225,8 @@ static void start_stop_endio(struct request *req, int error) - } - } - done: -- blk_put_request(req); -+ req->end_io_data = NULL; -+ __blk_put_request(req->q, req); - if (h->callback_fn) { - h->callback_fn(h->callback_data, err); - h->callback_fn = h->callback_data = NULL; --- -1.7.5.1 - diff --git a/sources b/sources index b519133..c8ff5a0 100644 --- a/sources +++ b/sources @@ -1,2 +1 @@ -7d471477bfa67546f902da62227fa976 linux-2.6.38.tar.bz2 -c0f416f6a2e916633f697287cc7cb914 patch-2.6.38.8.bz2 +1aab7a741abe08d42e8eccf20de61e05 linux-2.6.39.tar.bz2 diff --git a/x86-dumpstack-correct-stack-dump-info-when-frame-pointer-is-available.patch b/x86-dumpstack-correct-stack-dump-info-when-frame-pointer-is-available.patch deleted file mode 100644 index 36eae4b..0000000 --- a/x86-dumpstack-correct-stack-dump-info-when-frame-pointer-is-available.patch +++ /dev/null @@ -1,352 +0,0 @@ -From: Namhyung Kim -Date: Fri, 18 Mar 2011 02:40:06 +0000 (+0900) -Subject: x86, dumpstack: Correct stack dump info when frame pointer is available -X-Git-Tag: v2.6.39-rc1~64^2~7 -X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=e8e999cf3cc733482e390b02ff25a64cecdc0b64 - -x86, dumpstack: Correct stack dump info when frame pointer is available - -Current stack dump code scans entire stack and check each entry -contains a pointer to kernel code. If CONFIG_FRAME_POINTER=y it -could mark whether the pointer is valid or not based on value of -the frame pointer. Invalid entries could be preceded by '?' sign. - -However this was not going to happen because scan start point -was always higher than the frame pointer so that they could not -meet. - -Commit 9c0729dc8062 ("x86: Eliminate bp argument from the stack -tracing routines") delayed bp acquisition point, so the bp was -read in lower frame, thus all of the entries were marked -invalid. - -This patch fixes this by reverting above commit while retaining -stack_frame() helper as suggested by Frederic Weisbecker. - -End result looks like below: - -before: - - [ 3.508329] Call Trace: - [ 3.508551] [] ? panic+0x91/0x199 - [ 3.508662] [] ? printk+0x68/0x6a - [ 3.508770] [] ? mount_block_root+0x257/0x26e - [ 3.508876] [] ? mount_root+0x56/0x5a - [ 3.508975] [] ? prepare_namespace+0x170/0x1a9 - [ 3.509216] [] ? kernel_init+0x1d2/0x1e2 - [ 3.509335] [] ? kernel_thread_helper+0x4/0x10 - [ 3.509442] [] ? restore_args+0x0/0x30 - [ 3.509542] [] ? kernel_init+0x0/0x1e2 - [ 3.509641] [] ? kernel_thread_helper+0x0/0x10 - -after: - - [ 3.522991] Call Trace: - [ 3.523351] [] panic+0x91/0x199 - [ 3.523468] [] ? printk+0x68/0x6a - [ 3.523576] [] mount_block_root+0x257/0x26e - [ 3.523681] [] mount_root+0x56/0x5a - [ 3.523780] [] prepare_namespace+0x170/0x1a9 - [ 3.523885] [] kernel_init+0x1d2/0x1e2 - [ 3.523987] [] kernel_thread_helper+0x4/0x10 - [ 3.524228] [] ? restore_args+0x0/0x30 - [ 3.524345] [] ? kernel_init+0x0/0x1e2 - [ 3.524445] [] ? kernel_thread_helper+0x0/0x10 - - -v5: - * fix build breakage with oprofile - - -v4: - * use 0 instead of regs->bp - * separate out printk changes - - -v3: - * apply comment from Frederic - * add a couple of printk fixes - -Signed-off-by: Namhyung Kim -Acked-by: Peter Zijlstra -Acked-by: Frederic Weisbecker -Cc: Soren Sandmann -Cc: Paul Mackerras -Cc: Arnaldo Carvalho de Melo -Cc: Robert Richter -LKML-Reference: <1300416006-3163-1-git-send-email-namhyung@gmail.com> -Signed-off-by: Ingo Molnar ---- - -diff --git a/arch/x86/include/asm/kdebug.h b/arch/x86/include/asm/kdebug.h -index 518bbbb..fe2cc6e 100644 ---- a/arch/x86/include/asm/kdebug.h -+++ b/arch/x86/include/asm/kdebug.h -@@ -26,7 +26,7 @@ extern void die(const char *, struct pt_regs *,long); - extern int __must_check __die(const char *, struct pt_regs *, long); - extern void show_registers(struct pt_regs *regs); - extern void show_trace(struct task_struct *t, struct pt_regs *regs, -- unsigned long *sp); -+ unsigned long *sp, unsigned long bp); - extern void __show_regs(struct pt_regs *regs, int all); - extern void show_regs(struct pt_regs *regs); - extern unsigned long oops_begin(void); -diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h -index 52b5c7e..d7e89c8 100644 ---- a/arch/x86/include/asm/stacktrace.h -+++ b/arch/x86/include/asm/stacktrace.h -@@ -47,7 +47,7 @@ struct stacktrace_ops { - }; - - void dump_trace(struct task_struct *tsk, struct pt_regs *regs, -- unsigned long *stack, -+ unsigned long *stack, unsigned long bp, - const struct stacktrace_ops *ops, void *data); - - #ifdef CONFIG_X86_32 -@@ -86,11 +86,11 @@ stack_frame(struct task_struct *task, struct pt_regs *regs) - - extern void - show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, -- unsigned long *stack, char *log_lvl); -+ unsigned long *stack, unsigned long bp, char *log_lvl); - - extern void - show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, -- unsigned long *sp, char *log_lvl); -+ unsigned long *sp, unsigned long bp, char *log_lvl); - - extern unsigned int code_bytes; - -diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c -index 279bc9d..3061276 100644 ---- a/arch/x86/kernel/cpu/perf_event.c -+++ b/arch/x86/kernel/cpu/perf_event.c -@@ -1792,7 +1792,7 @@ perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) - - perf_callchain_store(entry, regs->ip); - -- dump_trace(NULL, regs, NULL, &backtrace_ops, entry); -+ dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry); - } - - #ifdef CONFIG_COMPAT -diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c -index 220a1c1..999e279 100644 ---- a/arch/x86/kernel/dumpstack.c -+++ b/arch/x86/kernel/dumpstack.c -@@ -175,21 +175,21 @@ static const struct stacktrace_ops print_trace_ops = { - - void - show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, -- unsigned long *stack, char *log_lvl) -+ unsigned long *stack, unsigned long bp, char *log_lvl) - { - printk("%sCall Trace:\n", log_lvl); -- dump_trace(task, regs, stack, &print_trace_ops, log_lvl); -+ dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl); - } - - void show_trace(struct task_struct *task, struct pt_regs *regs, -- unsigned long *stack) -+ unsigned long *stack, unsigned long bp) - { -- show_trace_log_lvl(task, regs, stack, ""); -+ show_trace_log_lvl(task, regs, stack, bp, ""); - } - - void show_stack(struct task_struct *task, unsigned long *sp) - { -- show_stack_log_lvl(task, NULL, sp, ""); -+ show_stack_log_lvl(task, NULL, sp, 0, ""); - } - - /* -@@ -197,14 +197,16 @@ void show_stack(struct task_struct *task, unsigned long *sp) - */ - void dump_stack(void) - { -+ unsigned long bp; - unsigned long stack; - -+ bp = stack_frame(current, NULL); - printk("Pid: %d, comm: %.20s %s %s %.*s\n", - current->pid, current->comm, print_tainted(), - init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); -- show_trace(NULL, NULL, &stack); -+ show_trace(NULL, NULL, &stack, bp); - } - EXPORT_SYMBOL(dump_stack); - -diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c -index 74cc1ed..3b97a80 100644 ---- a/arch/x86/kernel/dumpstack_32.c -+++ b/arch/x86/kernel/dumpstack_32.c -@@ -17,12 +17,11 @@ - #include - - --void dump_trace(struct task_struct *task, -- struct pt_regs *regs, unsigned long *stack, -+void dump_trace(struct task_struct *task, struct pt_regs *regs, -+ unsigned long *stack, unsigned long bp, - const struct stacktrace_ops *ops, void *data) - { - int graph = 0; -- unsigned long bp; - - if (!task) - task = current; -@@ -35,7 +34,9 @@ void dump_trace(struct task_struct *task, - stack = (unsigned long *)task->thread.sp; - } - -- bp = stack_frame(task, regs); -+ if (!bp) -+ bp = stack_frame(task, regs); -+ - for (;;) { - struct thread_info *context; - -@@ -55,7 +56,7 @@ EXPORT_SYMBOL(dump_trace); - - void - show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, -- unsigned long *sp, char *log_lvl) -+ unsigned long *sp, unsigned long bp, char *log_lvl) - { - unsigned long *stack; - int i; -@@ -77,7 +78,7 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, - touch_nmi_watchdog(); - } - printk(KERN_CONT "\n"); -- show_trace_log_lvl(task, regs, sp, log_lvl); -+ show_trace_log_lvl(task, regs, sp, bp, log_lvl); - } - - -@@ -102,7 +103,7 @@ void show_registers(struct pt_regs *regs) - u8 *ip; - - printk(KERN_EMERG "Stack:\n"); -- show_stack_log_lvl(NULL, regs, ®s->sp, KERN_EMERG); -+ show_stack_log_lvl(NULL, regs, ®s->sp, 0, KERN_EMERG); - - printk(KERN_EMERG "Code: "); - -diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c -index a6b6fcf..e71c98d 100644 ---- a/arch/x86/kernel/dumpstack_64.c -+++ b/arch/x86/kernel/dumpstack_64.c -@@ -139,8 +139,8 @@ fixup_bp_irq_link(unsigned long bp, unsigned long *stack, - * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack - */ - --void dump_trace(struct task_struct *task, -- struct pt_regs *regs, unsigned long *stack, -+void dump_trace(struct task_struct *task, struct pt_regs *regs, -+ unsigned long *stack, unsigned long bp, - const struct stacktrace_ops *ops, void *data) - { - const unsigned cpu = get_cpu(); -@@ -150,7 +150,6 @@ void dump_trace(struct task_struct *task, - struct thread_info *tinfo; - int graph = 0; - unsigned long dummy; -- unsigned long bp; - - if (!task) - task = current; -@@ -161,7 +160,8 @@ void dump_trace(struct task_struct *task, - stack = (unsigned long *)task->thread.sp; - } - -- bp = stack_frame(task, regs); -+ if (!bp) -+ bp = stack_frame(task, regs); - /* - * Print function call entries in all stacks, starting at the - * current stack address. If the stacks consist of nested -@@ -225,7 +225,7 @@ EXPORT_SYMBOL(dump_trace); - - void - show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, -- unsigned long *sp, char *log_lvl) -+ unsigned long *sp, unsigned long bp, char *log_lvl) - { - unsigned long *irq_stack_end; - unsigned long *irq_stack; -@@ -269,7 +269,7 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, - preempt_enable(); - - printk(KERN_CONT "\n"); -- show_trace_log_lvl(task, regs, sp, log_lvl); -+ show_trace_log_lvl(task, regs, sp, bp, log_lvl); - } - - void show_registers(struct pt_regs *regs) -@@ -298,7 +298,7 @@ void show_registers(struct pt_regs *regs) - - printk(KERN_EMERG "Stack:\n"); - show_stack_log_lvl(NULL, regs, (unsigned long *)sp, -- KERN_EMERG); -+ 0, KERN_EMERG); - - printk(KERN_EMERG "Code: "); - -diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c -index 99fa3ad..d46cbe4 100644 ---- a/arch/x86/kernel/process.c -+++ b/arch/x86/kernel/process.c -@@ -87,7 +87,7 @@ void exit_thread(void) - void show_regs(struct pt_regs *regs) - { - show_registers(regs); -- show_trace(NULL, regs, (unsigned long *)kernel_stack_pointer(regs)); -+ show_trace(NULL, regs, (unsigned long *)kernel_stack_pointer(regs), 0); - } - - void show_regs_common(void) -diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c -index 938c8e1..6515733 100644 ---- a/arch/x86/kernel/stacktrace.c -+++ b/arch/x86/kernel/stacktrace.c -@@ -73,7 +73,7 @@ static const struct stacktrace_ops save_stack_ops_nosched = { - */ - void save_stack_trace(struct stack_trace *trace) - { -- dump_trace(current, NULL, NULL, &save_stack_ops, trace); -+ dump_trace(current, NULL, NULL, 0, &save_stack_ops, trace); - if (trace->nr_entries < trace->max_entries) - trace->entries[trace->nr_entries++] = ULONG_MAX; - } -@@ -81,14 +81,14 @@ EXPORT_SYMBOL_GPL(save_stack_trace); - - void save_stack_trace_regs(struct stack_trace *trace, struct pt_regs *regs) - { -- dump_trace(current, regs, NULL, &save_stack_ops, trace); -+ dump_trace(current, regs, NULL, 0, &save_stack_ops, trace); - if (trace->nr_entries < trace->max_entries) - trace->entries[trace->nr_entries++] = ULONG_MAX; - } - - void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) - { -- dump_trace(tsk, NULL, NULL, &save_stack_ops_nosched, trace); -+ dump_trace(tsk, NULL, NULL, 0, &save_stack_ops_nosched, trace); - if (trace->nr_entries < trace->max_entries) - trace->entries[trace->nr_entries++] = ULONG_MAX; - } -diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c -index 72cbec1..2d49d4e 100644 ---- a/arch/x86/oprofile/backtrace.c -+++ b/arch/x86/oprofile/backtrace.c -@@ -126,7 +126,7 @@ x86_backtrace(struct pt_regs * const regs, unsigned int depth) - if (!user_mode_vm(regs)) { - unsigned long stack = kernel_stack_pointer(regs); - if (depth) -- dump_trace(NULL, regs, (unsigned long *)stack, -+ dump_trace(NULL, regs, (unsigned long *)stack, 0, - &backtrace_ops, &depth); - return; - }