diff options
author | Jesse Keating <jkeating@redhat.com> | 2010-07-29 17:18:45 -0700 |
---|---|---|
committer | Jesse Keating <jkeating@redhat.com> | 2010-07-29 17:18:45 -0700 |
commit | 2f82dda4a9bf41e64e864889bf06564bdf826e25 (patch) | |
tree | 118a7b483ae5de4dbf83d20001302f1404866ef0 /linux-2.6-upstream-reverts.patch | |
parent | 64ba2e5ffde5f2418eb26c700cb0ab62b04e5013 (diff) | |
download | dom0-kernel-2f82dda4a9bf41e64e864889bf06564bdf826e25.tar.gz dom0-kernel-2f82dda4a9bf41e64e864889bf06564bdf826e25.tar.xz dom0-kernel-2f82dda4a9bf41e64e864889bf06564bdf826e25.zip |
initial srpm import
Diffstat (limited to 'linux-2.6-upstream-reverts.patch')
-rw-r--r-- | linux-2.6-upstream-reverts.patch | 1936 |
1 files changed, 1936 insertions, 0 deletions
diff --git a/linux-2.6-upstream-reverts.patch b/linux-2.6-upstream-reverts.patch new file mode 100644 index 0000000..1984356 --- /dev/null +++ b/linux-2.6-upstream-reverts.patch @@ -0,0 +1,1936 @@ +From 0725e95ea56698774e893edb7e7276b1d6890954 Mon Sep 17 00:00:00 2001 +From: Bernhard Rosenkraenzer <br@blankpage.ch> +Date: Wed, 10 Mar 2010 12:36:43 +0100 +Subject: USB: qcserial: add new device ids + +From: Bernhard Rosenkraenzer <br@blankpage.ch> + +commit 0725e95ea56698774e893edb7e7276b1d6890954 upstream. + +This patch adds various USB device IDs for Gobi 2000 devices, as found in the +drivers available at https://www.codeaurora.org/wiki/GOBI_Releases + +Signed-off-by: Bernhard Rosenkraenzer <bero@arklinux.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/qcserial.c | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +--- a/drivers/usb/serial/qcserial.c ++++ b/drivers/usb/serial/qcserial.c +@@ -47,6 +47,35 @@ static struct usb_device_id id_table[] = + {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ + {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ + {USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ ++ {USB_DEVICE(0x413c, 0x8185)}, /* Dell Gobi 2000 QDL device (N0218, VU936) */ ++ {USB_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ ++ {USB_DEVICE(0x05c6, 0x9224)}, /* Sony Gobi 2000 QDL device (N0279, VU730) */ ++ {USB_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ ++ {USB_DEVICE(0x05c6, 0x9244)}, /* Samsung Gobi 2000 QDL device (VL176) */ ++ {USB_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ ++ {USB_DEVICE(0x03f0, 0x241d)}, /* HP Gobi 2000 QDL device (VP412) */ ++ {USB_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ ++ {USB_DEVICE(0x05c6, 0x9214)}, /* Acer Gobi 2000 QDL device (VP413) */ ++ {USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ ++ {USB_DEVICE(0x05c6, 0x9264)}, /* Asus Gobi 2000 QDL device (VR305) */ ++ {USB_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ ++ {USB_DEVICE(0x05c6, 0x9234)}, /* Top Global Gobi 2000 QDL device (VR306) */ ++ {USB_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ ++ {USB_DEVICE(0x05c6, 0x9274)}, /* iRex Technologies Gobi 2000 QDL device (VR307) */ ++ {USB_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ ++ {USB_DEVICE(0x1199, 0x9000)}, /* Sierra Wireless Gobi 2000 QDL device (VT773) */ ++ {USB_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ ++ {USB_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ ++ {USB_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ ++ {USB_DEVICE(0x1199, 0x9004)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ ++ {USB_DEVICE(0x1199, 0x9005)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ ++ {USB_DEVICE(0x1199, 0x9006)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ ++ {USB_DEVICE(0x1199, 0x9007)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ ++ {USB_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ ++ {USB_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ ++ {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ ++ {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */ ++ {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, id_table); +From 9cf00977da092096c7a983276dad8b3002d23a99 Mon Sep 17 00:00:00 2001 +From: Adam Jackson <ajax@redhat.com> +Date: Thu, 3 Dec 2009 17:44:36 -0500 +Subject: drm/edid: Unify detailed block parsing between base and extension blocks + +From: Adam Jackson <ajax@redhat.com> + +commit 9cf00977da092096c7a983276dad8b3002d23a99 upstream. + +Also fix an embarassing bug in standard timing subblock parsing that +would result in an infinite loop. + +Signed-off-by: Adam Jackson <ajax@redhat.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +Cc: maximilian attems <max@stro.at> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/drm_edid.c | 163 ++++++++++++++++----------------------------- + 1 file changed, 61 insertions(+), 102 deletions(-) + +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -834,8 +834,57 @@ static int add_standard_modes(struct drm + return modes; + } + ++static int add_detailed_modes(struct drm_connector *connector, ++ struct detailed_timing *timing, ++ struct edid *edid, u32 quirks, int preferred) ++{ ++ int i, modes = 0; ++ struct detailed_non_pixel *data = &timing->data.other_data; ++ int timing_level = standard_timing_level(edid); ++ struct drm_display_mode *newmode; ++ struct drm_device *dev = connector->dev; ++ ++ if (timing->pixel_clock) { ++ newmode = drm_mode_detailed(dev, edid, timing, quirks); ++ if (!newmode) ++ return 0; ++ ++ if (preferred) ++ newmode->type |= DRM_MODE_TYPE_PREFERRED; ++ ++ drm_mode_probed_add(connector, newmode); ++ return 1; ++ } ++ ++ /* other timing types */ ++ switch (data->type) { ++ case EDID_DETAIL_MONITOR_RANGE: ++ /* Get monitor range data */ ++ break; ++ case EDID_DETAIL_STD_MODES: ++ /* Six modes per detailed section */ ++ for (i = 0; i < 6; i++) { ++ struct std_timing *std; ++ struct drm_display_mode *newmode; ++ ++ std = &data->data.timings[i]; ++ newmode = drm_mode_std(dev, std, edid->revision, ++ timing_level); ++ if (newmode) { ++ drm_mode_probed_add(connector, newmode); ++ modes++; ++ } ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return modes; ++} ++ + /** +- * add_detailed_modes - get detailed mode info from EDID data ++ * add_detailed_info - get detailed mode info from EDID data + * @connector: attached connector + * @edid: EDID block to scan + * @quirks: quirks to apply +@@ -846,67 +895,24 @@ static int add_standard_modes(struct drm + static int add_detailed_info(struct drm_connector *connector, + struct edid *edid, u32 quirks) + { +- struct drm_device *dev = connector->dev; +- int i, j, modes = 0; +- int timing_level; +- +- timing_level = standard_timing_level(edid); ++ int i, modes = 0; + + for (i = 0; i < EDID_DETAILED_TIMINGS; i++) { + struct detailed_timing *timing = &edid->detailed_timings[i]; +- struct detailed_non_pixel *data = &timing->data.other_data; +- struct drm_display_mode *newmode; ++ int preferred = (i == 0) && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING); + +- /* X server check is version 1.1 or higher */ +- if (edid->version == 1 && edid->revision >= 1 && +- !timing->pixel_clock) { +- /* Other timing or info */ +- switch (data->type) { +- case EDID_DETAIL_MONITOR_SERIAL: +- break; +- case EDID_DETAIL_MONITOR_STRING: +- break; +- case EDID_DETAIL_MONITOR_RANGE: +- /* Get monitor range data */ +- break; +- case EDID_DETAIL_MONITOR_NAME: +- break; +- case EDID_DETAIL_MONITOR_CPDATA: +- break; +- case EDID_DETAIL_STD_MODES: +- for (j = 0; j < 6; i++) { +- struct std_timing *std; +- struct drm_display_mode *newmode; +- +- std = &data->data.timings[j]; +- newmode = drm_mode_std(dev, std, +- edid->revision, +- timing_level); +- if (newmode) { +- drm_mode_probed_add(connector, newmode); +- modes++; +- } +- } +- break; +- default: +- break; +- } +- } else { +- newmode = drm_mode_detailed(dev, edid, timing, quirks); +- if (!newmode) +- continue; +- +- /* First detailed mode is preferred */ +- if (i == 0 && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING)) +- newmode->type |= DRM_MODE_TYPE_PREFERRED; +- drm_mode_probed_add(connector, newmode); ++ /* In 1.0, only timings are allowed */ ++ if (!timing->pixel_clock && edid->version == 1 && ++ edid->revision == 0) ++ continue; + +- modes++; +- } ++ modes += add_detailed_modes(connector, timing, edid, quirks, ++ preferred); + } + + return modes; + } ++ + /** + * add_detailed_mode_eedid - get detailed mode info from addtional timing + * EDID block +@@ -920,12 +926,9 @@ static int add_detailed_info(struct drm_ + static int add_detailed_info_eedid(struct drm_connector *connector, + struct edid *edid, u32 quirks) + { +- struct drm_device *dev = connector->dev; +- int i, j, modes = 0; ++ int i, modes = 0; + char *edid_ext = NULL; + struct detailed_timing *timing; +- struct detailed_non_pixel *data; +- struct drm_display_mode *newmode; + int edid_ext_num; + int start_offset, end_offset; + int timing_level; +@@ -976,51 +979,7 @@ static int add_detailed_info_eedid(struc + for (i = start_offset; i < end_offset; + i += sizeof(struct detailed_timing)) { + timing = (struct detailed_timing *)(edid_ext + i); +- data = &timing->data.other_data; +- /* Detailed mode timing */ +- if (timing->pixel_clock) { +- newmode = drm_mode_detailed(dev, edid, timing, quirks); +- if (!newmode) +- continue; +- +- drm_mode_probed_add(connector, newmode); +- +- modes++; +- continue; +- } +- +- /* Other timing or info */ +- switch (data->type) { +- case EDID_DETAIL_MONITOR_SERIAL: +- break; +- case EDID_DETAIL_MONITOR_STRING: +- break; +- case EDID_DETAIL_MONITOR_RANGE: +- /* Get monitor range data */ +- break; +- case EDID_DETAIL_MONITOR_NAME: +- break; +- case EDID_DETAIL_MONITOR_CPDATA: +- break; +- case EDID_DETAIL_STD_MODES: +- /* Five modes per detailed section */ +- for (j = 0; j < 5; i++) { +- struct std_timing *std; +- struct drm_display_mode *newmode; +- +- std = &data->data.timings[j]; +- newmode = drm_mode_std(dev, std, +- edid->revision, +- timing_level); +- if (newmode) { +- drm_mode_probed_add(connector, newmode); +- modes++; +- } +- } +- break; +- default: +- break; +- } ++ modes += add_detailed_modes(connector, timing, edid, quirks, 0); + } + + return modes; +From 29874f44fbcbc24b231b42c9956f8f9de9407231 Mon Sep 17 00:00:00 2001 +From: Shaohua Li <shaohua.li@intel.com> +Date: Wed, 18 Nov 2009 15:15:02 +0800 +Subject: drm/i915: fix gpio register detection logic for BIOS without VBT + +From: Shaohua Li <shaohua.li@intel.com> + +commit 29874f44fbcbc24b231b42c9956f8f9de9407231 upstream. + +if no VBT is present, crt_ddc_bus will be left at 0, and cause us +to use that for the GPIO register offset. That's never a valid register +offset, so let the "undefined" value be 0 instead of -1. + +Signed-off-by: Shaohua Li <shaohua.li@intel.com> +Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> +Signed-off-by: Eric Anholt <eric@anholt.net> +[anholt: clarified the commit message a bit] +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/i915_drv.h | 2 +- + drivers/gpu/drm/i915/intel_bios.c | 4 ---- + drivers/gpu/drm/i915/intel_crt.c | 2 +- + 3 files changed, 2 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -258,7 +258,7 @@ typedef struct drm_i915_private { + + struct notifier_block lid_notifier; + +- int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */ ++ int crt_ddc_bus; /* 0 = unknown, else GPIO to use for CRT DDC */ + struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ + int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ + int num_fence_regs; /* 8 on pre-965, 16 otherwise */ +--- a/drivers/gpu/drm/i915/intel_bios.c ++++ b/drivers/gpu/drm/i915/intel_bios.c +@@ -241,10 +241,6 @@ parse_general_definitions(struct drm_i91 + GPIOF, + }; + +- /* Set sensible defaults in case we can't find the general block +- or it is the wrong chipset */ +- dev_priv->crt_ddc_bus = -1; +- + general = find_section(bdb, BDB_GENERAL_DEFINITIONS); + if (general) { + u16 block_size = get_blocksize(general); +--- a/drivers/gpu/drm/i915/intel_crt.c ++++ b/drivers/gpu/drm/i915/intel_crt.c +@@ -557,7 +557,7 @@ void intel_crt_init(struct drm_device *d + else { + i2c_reg = GPIOA; + /* Use VBT information for CRT DDC if available */ +- if (dev_priv->crt_ddc_bus != -1) ++ if (dev_priv->crt_ddc_bus != 0) + i2c_reg = dev_priv->crt_ddc_bus; + } + intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); +From 290e55056ec3d25c72088628245d8cae037b30db Mon Sep 17 00:00:00 2001 +From: Maarten Maathuis <madman2003@gmail.com> +Date: Sat, 20 Feb 2010 03:22:21 +0100 +Subject: drm/ttm: handle OOM in ttm_tt_swapout + +From: Maarten Maathuis <madman2003@gmail.com> + +commit 290e55056ec3d25c72088628245d8cae037b30db upstream. + +- Without this change I get a general protection fault. +- Also use PTR_ERR where applicable. + +Signed-off-by: Maarten Maathuis <madman2003@gmail.com> +Reviewed-by: Dave Airlie <airlied@redhat.com> +Acked-by: Thomas Hellstrom <thellstrom@vmware.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/ttm/ttm_tt.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +--- a/drivers/gpu/drm/ttm/ttm_tt.c ++++ b/drivers/gpu/drm/ttm/ttm_tt.c +@@ -466,7 +466,7 @@ static int ttm_tt_swapin(struct ttm_tt * + void *from_virtual; + void *to_virtual; + int i; +- int ret; ++ int ret = -ENOMEM; + + if (ttm->page_flags & TTM_PAGE_FLAG_USER) { + ret = ttm_tt_set_user(ttm, ttm->tsk, ttm->start, +@@ -485,8 +485,10 @@ static int ttm_tt_swapin(struct ttm_tt * + + for (i = 0; i < ttm->num_pages; ++i) { + from_page = read_mapping_page(swap_space, i, NULL); +- if (IS_ERR(from_page)) ++ if (IS_ERR(from_page)) { ++ ret = PTR_ERR(from_page); + goto out_err; ++ } + to_page = __ttm_tt_get_page(ttm, i); + if (unlikely(to_page == NULL)) + goto out_err; +@@ -509,7 +511,7 @@ static int ttm_tt_swapin(struct ttm_tt * + return 0; + out_err: + ttm_tt_free_alloced_pages(ttm); +- return -ENOMEM; ++ return ret; + } + + int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) +@@ -521,6 +523,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, s + void *from_virtual; + void *to_virtual; + int i; ++ int ret = -ENOMEM; + + BUG_ON(ttm->state != tt_unbound && ttm->state != tt_unpopulated); + BUG_ON(ttm->caching_state != tt_cached); +@@ -543,7 +546,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, s + 0); + if (unlikely(IS_ERR(swap_storage))) { + printk(KERN_ERR "Failed allocating swap storage.\n"); +- return -ENOMEM; ++ return PTR_ERR(swap_storage); + } + } else + swap_storage = persistant_swap_storage; +@@ -555,9 +558,10 @@ int ttm_tt_swapout(struct ttm_tt *ttm, s + if (unlikely(from_page == NULL)) + continue; + to_page = read_mapping_page(swap_space, i, NULL); +- if (unlikely(to_page == NULL)) ++ if (unlikely(IS_ERR(to_page))) { ++ ret = PTR_ERR(to_page); + goto out_err; +- ++ } + preempt_disable(); + from_virtual = kmap_atomic(from_page, KM_USER0); + to_virtual = kmap_atomic(to_page, KM_USER1); +@@ -581,5 +585,5 @@ out_err: + if (!persistant_swap_storage) + fput(swap_storage); + +- return -ENOMEM; ++ return ret; + } +From 70136081fc67ea77d849f86fa323e5773c8e40ea Mon Sep 17 00:00:00 2001 +From: Theodore Kilgore <kilgota@auburn.edu> +Date: Fri, 25 Dec 2009 05:15:10 -0300 +Subject: V4L/DVB (13991): gspca_mr973010a: Fix cif type 1 cameras not streaming on UHCI controllers + +From: Theodore Kilgore <kilgota@auburn.edu> + +commit 70136081fc67ea77d849f86fa323e5773c8e40ea upstream. + +If you read the mail to Oliver Neukum on the linux-usb list, then you know +that I found a cure for the mysterious problem that the MR97310a CIF "type +1" cameras have been freezing up and refusing to stream if hooked up to a +machine with a UHCI controller. + +Namely, the cure is that if the camera is an mr97310a CIF type 1 camera, you +have to send it 0xa0, 0x00. Somehow, this is a timing reset command, or +such. It un-blocks whatever was previously stopping the CIF type 1 cameras +from working on the UHCI-based machines. + +Signed-off-by: Theodore Kilgore <kilgota@auburn.edu> +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/media/video/gspca/mr97310a.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/media/video/gspca/mr97310a.c ++++ b/drivers/media/video/gspca/mr97310a.c +@@ -530,6 +530,12 @@ static int start_cif_cam(struct gspca_de + {0x13, 0x00, {0x01}, 1}, + {0, 0, {0}, 0} + }; ++ /* Without this command the cam won't work with USB-UHCI */ ++ gspca_dev->usb_buf[0] = 0x0a; ++ gspca_dev->usb_buf[1] = 0x00; ++ err_code = mr_write(gspca_dev, 2); ++ if (err_code < 0) ++ return err_code; + err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, + ARRAY_SIZE(cif_sensor1_init_data)); + } +From 8fcc501831aa5b37a4a5a8cd9dc965be3cacc599 Mon Sep 17 00:00:00 2001 +From: Zhenyu Wang <zhenyuw@linux.intel.com> +Date: Mon, 28 Dec 2009 13:15:20 +0800 +Subject: drm/i915: disable TV hotplug status check + +From: Zhenyu Wang <zhenyuw@linux.intel.com> + +commit 8fcc501831aa5b37a4a5a8cd9dc965be3cacc599 upstream. + +As we removed TV hotplug, don't check its status ever. + +Reviewed-by: Adam Jackson <ajax@redhat.com> +Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/intel_tv.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_tv.c ++++ b/drivers/gpu/drm/i915/intel_tv.c +@@ -1801,8 +1801,6 @@ intel_tv_init(struct drm_device *dev) + drm_connector_attach_property(connector, + dev->mode_config.tv_bottom_margin_property, + tv_priv->margin[TV_MARGIN_BOTTOM]); +- +- dev_priv->hotplug_supported_mask |= TV_HOTPLUG_INT_STATUS; + out: + drm_sysfs_connector_add(connector); + } +From 43bcd61fae05fc6062b4f117c5adb1a72c9f8c57 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter <daniel.vetter@ffwll.ch> +Date: Tue, 3 Nov 2009 09:03:34 +0000 +Subject: drm/i915: fix get_core_clock_speed for G33 class desktop chips + +From: Daniel Vetter <daniel.vetter@ffwll.ch> + +commit 43bcd61fae05fc6062b4f117c5adb1a72c9f8c57 upstream. + +Somehow the case for G33 got dropped while porting from ums code. +This made a 400MHz chip into a 133MHz one which resulted in the +unnecessary enabling of double wide pipe mode which in turn +screwed up the overlay code. + +Nothing else (than the overlay code) seems to be affected. + +This fixes fdo.org bug #24835 + +Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/intel_display.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4322,7 +4322,7 @@ static void intel_init_display(struct dr + } + + /* Returns the core display clock speed */ +- if (IS_I945G(dev)) ++ if (IS_I945G(dev) || (IS_G33(dev) && ! IS_IGDGM(dev))) + dev_priv->display.get_display_clock_speed = + i945_get_display_clock_speed; + else if (IS_I915G(dev)) +From ceb0297d3da7ecf44bccec2c4520c8710612c238 Mon Sep 17 00:00:00 2001 +From: Jerome Glisse <jglisse@redhat.com> +Date: Sun, 14 Feb 2010 19:33:18 +0000 +Subject: drm/radeon: r6xx/r7xx possible security issue, system ram access + +From: Jerome Glisse <jglisse@redhat.com> + +commit c8c15ff1e90bfc4a2db1ba77a01b3b2783e723fc upstream + +This patch workaround a possible security issue which can allow +user to abuse drm on r6xx/r7xx hw to access any system ram memory. +This patch doesn't break userspace, it detect "valid" old use of +CB_COLOR[0-7]_FRAG & CB_COLOR[0-7]_TILE registers and overwritte +the address these registers are pointing to with the one of the +last color buffer. This workaround will work for old mesa & +xf86-video-ati and any old user which did use similar register +programming pattern as those (we expect that there is no others +user of those ioctl except possibly a malicious one). This patch +add a warning if it detects such usage, warning encourage people +to update their mesa & xf86-video-ati. New userspace will submit +proper relocation. + +Fix for xf86-video-ati / mesa (this kernel patch is enough to +prevent abuse, fix for userspace are to set proper cs stream and +avoid kernel warning) : +http://cgit.freedesktop.org/xorg/driver/xf86-video-ati/commit/?id=95d63e408cc88b6934bec84a0b1ef94dfe8bee7b +http://cgit.freedesktop.org/mesa/mesa/commit/?id=46dc6fd3ed5ef96cda53641a97bc68c3bc104a9f + +Abusing this register to perform system ram memory is not easy, +here is outline on how it could be achieve. First attacker must +have access to the drm device and be able to submit command stream +throught cs ioctl. Then attacker must build a proper command stream +for r6xx/r7xx hw which will abuse the FRAG or TILE buffer to +overwrite the GPU GART which is in VRAM. To achieve so attacker +as to setup CB_COLOR[0-7]_FRAG or CB_COLOR[0-7]_TILE to point +to the GPU GART, then it has to find a way to write predictable +value into those buffer (with little cleverness i believe this +can be done but this is an hard task). Once attacker have such +program it can overwritte GPU GART to program GPU gart to point +anywhere in system memory. It then can reusse same method as he +used to reprogram GART to overwritte the system ram through the +GART mapping. In the process the attacker has to be carefull to +not overwritte any sensitive area of the GART table, like ring +or IB gart entry as it will more then likely lead to GPU lockup. +Bottom line is that i think it's very hard to use this flaw +to get system ram access but in theory one can achieve so. + +Side note: I am not aware of anyone ever using the GPU as an +attack vector, nevertheless we take great care in the opensource +driver to try to detect and forbid malicious use of GPU. I don't +think the closed source driver are as cautious as we are. + +[bwh: Adjusted context for 2.6.32] +Signed-off-by: Jerome Glisse <jglisse@redhat.com> +Signed-off-by: Dave Airlie <airlied@linux.ie> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/radeon/r600_cs.c | 83 +++++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/radeon/r600d.h | 26 +++++++++++ + drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_cs.c | 1 + 4 files changed, 111 insertions(+) + +--- a/drivers/gpu/drm/radeon/r600_cs.c ++++ b/drivers/gpu/drm/radeon/r600_cs.c +@@ -36,6 +36,10 @@ static int r600_cs_packet_next_reloc_nom + typedef int (*next_reloc_t)(struct radeon_cs_parser*, struct radeon_cs_reloc**); + static next_reloc_t r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_mm; + ++struct r600_cs_track { ++ u32 cb_color0_base_last; ++}; ++ + /** + * r600_cs_packet_parse() - parse cp packet and point ib index to next packet + * @parser: parser structure holding parsing context. +@@ -177,6 +181,28 @@ static int r600_cs_packet_next_reloc_nom + } + + /** ++ * r600_cs_packet_next_is_pkt3_nop() - test if next packet is packet3 nop for reloc ++ * @parser: parser structure holding parsing context. ++ * ++ * Check next packet is relocation packet3, do bo validation and compute ++ * GPU offset using the provided start. ++ **/ ++static inline int r600_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p) ++{ ++ struct radeon_cs_packet p3reloc; ++ int r; ++ ++ r = r600_cs_packet_parse(p, &p3reloc, p->idx); ++ if (r) { ++ return 0; ++ } ++ if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { ++ return 0; ++ } ++ return 1; ++} ++ ++/** + * r600_cs_packet_next_vline() - parse userspace VLINE packet + * @parser: parser structure holding parsing context. + * +@@ -337,6 +363,7 @@ static int r600_packet3_check(struct rad + struct radeon_cs_packet *pkt) + { + struct radeon_cs_reloc *reloc; ++ struct r600_cs_track *track; + volatile u32 *ib; + unsigned idx; + unsigned i; +@@ -344,6 +371,7 @@ static int r600_packet3_check(struct rad + int r; + u32 idx_value; + ++ track = (struct r600_cs_track *)p->track; + ib = p->ib->ptr; + idx = pkt->idx + 1; + idx_value = radeon_get_ib_value(p, idx); +@@ -503,9 +531,60 @@ static int r600_packet3_check(struct rad + for (i = 0; i < pkt->count; i++) { + reg = start_reg + (4 * i); + switch (reg) { ++ /* This register were added late, there is userspace ++ * which does provide relocation for those but set ++ * 0 offset. In order to avoid breaking old userspace ++ * we detect this and set address to point to last ++ * CB_COLOR0_BASE, note that if userspace doesn't set ++ * CB_COLOR0_BASE before this register we will report ++ * error. Old userspace always set CB_COLOR0_BASE ++ * before any of this. ++ */ ++ case R_0280E0_CB_COLOR0_FRAG: ++ case R_0280E4_CB_COLOR1_FRAG: ++ case R_0280E8_CB_COLOR2_FRAG: ++ case R_0280EC_CB_COLOR3_FRAG: ++ case R_0280F0_CB_COLOR4_FRAG: ++ case R_0280F4_CB_COLOR5_FRAG: ++ case R_0280F8_CB_COLOR6_FRAG: ++ case R_0280FC_CB_COLOR7_FRAG: ++ case R_0280C0_CB_COLOR0_TILE: ++ case R_0280C4_CB_COLOR1_TILE: ++ case R_0280C8_CB_COLOR2_TILE: ++ case R_0280CC_CB_COLOR3_TILE: ++ case R_0280D0_CB_COLOR4_TILE: ++ case R_0280D4_CB_COLOR5_TILE: ++ case R_0280D8_CB_COLOR6_TILE: ++ case R_0280DC_CB_COLOR7_TILE: ++ if (!r600_cs_packet_next_is_pkt3_nop(p)) { ++ if (!track->cb_color0_base_last) { ++ dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); ++ return -EINVAL; ++ } ++ ib[idx+1+i] = track->cb_color0_base_last; ++ printk_once(KERN_WARNING "You have old & broken userspace " ++ "please consider updating mesa & xf86-video-ati\n"); ++ } else { ++ r = r600_cs_packet_next_reloc(p, &reloc); ++ if (r) { ++ dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); ++ return -EINVAL; ++ } ++ ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); ++ } ++ break; + case DB_DEPTH_BASE: + case DB_HTILE_DATA_BASE: + case CB_COLOR0_BASE: ++ r = r600_cs_packet_next_reloc(p, &reloc); ++ if (r) { ++ DRM_ERROR("bad SET_CONTEXT_REG " ++ "0x%04X\n", reg); ++ return -EINVAL; ++ } ++ ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); ++ track->cb_color0_base_last = ib[idx+1+i]; ++ break; + case CB_COLOR1_BASE: + case CB_COLOR2_BASE: + case CB_COLOR3_BASE: +@@ -678,8 +757,11 @@ static int r600_packet3_check(struct rad + int r600_cs_parse(struct radeon_cs_parser *p) + { + struct radeon_cs_packet pkt; ++ struct r600_cs_track *track; + int r; + ++ track = kzalloc(sizeof(*track), GFP_KERNEL); ++ p->track = track; + do { + r = r600_cs_packet_parse(p, &pkt, p->idx); + if (r) { +@@ -757,6 +839,7 @@ int r600_cs_legacy(struct drm_device *de + /* initialize parser */ + memset(&parser, 0, sizeof(struct radeon_cs_parser)); + parser.filp = filp; ++ parser.dev = &dev->pdev->dev; + parser.rdev = NULL; + parser.family = family; + parser.ib = &fake_ib; +--- a/drivers/gpu/drm/radeon/r600d.h ++++ b/drivers/gpu/drm/radeon/r600d.h +@@ -674,4 +674,30 @@ + #define S_000E60_SOFT_RESET_TSC(x) (((x) & 1) << 16) + #define S_000E60_SOFT_RESET_VMC(x) (((x) & 1) << 17) + ++#define R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 ++ ++#define R_0280E0_CB_COLOR0_FRAG 0x0280E0 ++#define S_0280E0_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0) ++#define G_0280E0_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF) ++#define C_0280E0_BASE_256B 0x00000000 ++#define R_0280E4_CB_COLOR1_FRAG 0x0280E4 ++#define R_0280E8_CB_COLOR2_FRAG 0x0280E8 ++#define R_0280EC_CB_COLOR3_FRAG 0x0280EC ++#define R_0280F0_CB_COLOR4_FRAG 0x0280F0 ++#define R_0280F4_CB_COLOR5_FRAG 0x0280F4 ++#define R_0280F8_CB_COLOR6_FRAG 0x0280F8 ++#define R_0280FC_CB_COLOR7_FRAG 0x0280FC ++#define R_0280C0_CB_COLOR0_TILE 0x0280C0 ++#define S_0280C0_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0) ++#define G_0280C0_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF) ++#define C_0280C0_BASE_256B 0x00000000 ++#define R_0280C4_CB_COLOR1_TILE 0x0280C4 ++#define R_0280C8_CB_COLOR2_TILE 0x0280C8 ++#define R_0280CC_CB_COLOR3_TILE 0x0280CC ++#define R_0280D0_CB_COLOR4_TILE 0x0280D0 ++#define R_0280D4_CB_COLOR5_TILE 0x0280D4 ++#define R_0280D8_CB_COLOR6_TILE 0x0280D8 ++#define R_0280DC_CB_COLOR7_TILE 0x0280DC ++ ++ + #endif +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -448,6 +448,7 @@ struct radeon_cs_chunk { + }; + + struct radeon_cs_parser { ++ struct device *dev; + struct radeon_device *rdev; + struct drm_file *filp; + /* chunks */ +--- a/drivers/gpu/drm/radeon/radeon_cs.c ++++ b/drivers/gpu/drm/radeon/radeon_cs.c +@@ -230,6 +230,7 @@ int radeon_cs_ioctl(struct drm_device *d + memset(&parser, 0, sizeof(struct radeon_cs_parser)); + parser.filp = filp; + parser.rdev = rdev; ++ parser.dev = rdev->dev; + r = radeon_cs_parser_init(&parser, data); + if (r) { + DRM_ERROR("Failed to initialize parser !\n"); +From e3dae5087754984ed7e6daf4fbb742ff026aadd5 Mon Sep 17 00:00:00 2001 +From: Jerome Glisse <jglisse@redhat.com> +Date: Sun, 14 Feb 2010 19:31:58 +0000 +Subject: drm/radeon/kms: r600/r700 don't test ib if ib initialization fails + +From: Jerome Glisse <jglisse@redhat.com> + +commit db96380ea26fcc31ab37189aedeabd12894b1431 upstream + +If ib initialization failed don't try to test ib as it will result +in an oops (accessing NULL ib buffer ptr). + +[bwh: Adjusted context for 2.6.32] +Signed-off-by: Jerome Glisse <jglisse@redhat.com> +Signed-off-by: Dave Airlie <airlied@linux.ie> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/radeon/r600.c | 13 +++++++------ + drivers/gpu/drm/radeon/rv770.c | 13 +++++++------ + 2 files changed, 14 insertions(+), 12 deletions(-) + +--- a/drivers/gpu/drm/radeon/r600.c ++++ b/drivers/gpu/drm/radeon/r600.c +@@ -1686,13 +1686,14 @@ int r600_init(struct radeon_device *rdev + if (rdev->accel_working) { + r = radeon_ib_pool_init(rdev); + if (r) { +- DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); +- rdev->accel_working = false; +- } +- r = r600_ib_test(rdev); +- if (r) { +- DRM_ERROR("radeon: failled testing IB (%d).\n", r); ++ dev_err(rdev->dev, "IB initialization failed (%d).\n", r); + rdev->accel_working = false; ++ } else { ++ r = r600_ib_test(rdev); ++ if (r) { ++ dev_err(rdev->dev, "IB test failed (%d).\n", r); ++ rdev->accel_working = false; ++ } + } + } + return 0; +--- a/drivers/gpu/drm/radeon/rv770.c ++++ b/drivers/gpu/drm/radeon/rv770.c +@@ -1034,13 +1034,14 @@ int rv770_init(struct radeon_device *rde + if (rdev->accel_working) { + r = radeon_ib_pool_init(rdev); + if (r) { +- DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); +- rdev->accel_working = false; +- } +- r = r600_ib_test(rdev); +- if (r) { +- DRM_ERROR("radeon: failled testing IB (%d).\n", r); ++ dev_err(rdev->dev, "IB initialization failed (%d).\n", r); + rdev->accel_working = false; ++ } else { ++ r = r600_ib_test(rdev); ++ if (r) { ++ dev_err(rdev->dev, "IB test failed (%d).\n", r); ++ rdev->accel_working = false; ++ } + } + } + return 0; +From 7e71c9e2e7704ebf044d4a964e02fbd2098a173f Mon Sep 17 00:00:00 2001 +From: Jerome Glisse <jglisse@redhat.com> +Date: Sun, 17 Jan 2010 21:21:41 +0100 +Subject: drm/radeon/kms: Forbid creation of framebuffer with no valid GEM object + +From: Jerome Glisse <jglisse@redhat.com> + +commit 7e71c9e2e7704ebf044d4a964e02fbd2098a173f upstream. + +This will avoid oops if at later point the fb is use. Trying to create +a framebuffer with no valid GEM object is bogus and should be forbidden +as this patch does. + +Signed-off-by: Jerome Glisse <jglisse@redhat.com> +Signed-off-by: Dave Airlie <airlied@linux.ie> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/radeon/radeon_display.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/radeon/radeon_display.c ++++ b/drivers/gpu/drm/radeon/radeon_display.c +@@ -599,7 +599,11 @@ radeon_user_framebuffer_create(struct dr + struct drm_gem_object *obj; + + obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); +- ++ if (obj == NULL) { ++ dev_err(&dev->pdev->dev, "No GEM object associated to handle 0x%08X, " ++ "can't create framebuffer\n", mode_cmd->handle); ++ return NULL; ++ } + return radeon_framebuffer_create(dev, mode_cmd, obj); + } + +From 1379d2fef0ec07c7027a5e89036025ce761470c8 Mon Sep 17 00:00:00 2001 +From: Zhang Rui <rui.zhang@intel.com> +Date: Tue, 16 Feb 2010 04:16:55 -0500 +Subject: ACPI, i915: blacklist Clevo M5x0N bad_lid state + +From: Zhang Rui <rui.zhang@intel.com> + +commit 1379d2fef0ec07c7027a5e89036025ce761470c8 upstream. + +Wrong Lid state reported. +Need to blacklist this machine for LVDS detection. + +Signed-off-by: Zhang Rui <rui.zhang@intel.com> +Signed-off-by: Len Brown <len.brown@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/intel_lvds.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -629,6 +629,13 @@ static const struct dmi_system_id bad_li + DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"), + }, + }, ++ { ++ .ident = "Clevo M5x0N", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."), ++ DMI_MATCH(DMI_BOARD_NAME, "M5x0N"), ++ }, ++ }, + { } + }; + +From 01d4503968f471f876fb44335800d2cf8dc5a2ce Mon Sep 17 00:00:00 2001 +From: Dave Airlie <airlied@redhat.com> +Date: Sun, 31 Jan 2010 07:07:14 +1000 +Subject: drm/radeon/kms: use udelay for short delays + +From: Dave Airlie <airlied@redhat.com> + +commit 01d4503968f471f876fb44335800d2cf8dc5a2ce upstream. + +For usec delays use udelay instead of scheduling, this should +allow reclocking to happen faster. This also was the cause +of reported 33s delays at bootup on certain systems. + +fixes: freedesktop.org bug 25506 + +Signed-off-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/radeon/atom.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/radeon/atom.c ++++ b/drivers/gpu/drm/radeon/atom.c +@@ -607,7 +607,7 @@ static void atom_op_delay(atom_exec_cont + uint8_t count = U8((*ptr)++); + SDEBUG(" count: %d\n", count); + if (arg == ATOM_UNIT_MICROSEC) +- schedule_timeout_uninterruptible(usecs_to_jiffies(count)); ++ udelay(count); + else + schedule_timeout_uninterruptible(msecs_to_jiffies(count)); + } +From b9241ea31fae4887104e5d1b3b18f4009c25a0c4 Mon Sep 17 00:00:00 2001 +From: Zhenyu Wang <zhenyuw@linux.intel.com> +Date: Wed, 25 Nov 2009 13:09:39 +0800 +Subject: drm/i915: Don't wait interruptible for possible plane buffer flush + +From: Zhenyu Wang <zhenyuw@linux.intel.com> + +commit b9241ea31fae4887104e5d1b3b18f4009c25a0c4 upstream. + +When we setup buffer for display plane, we'll check any pending +required GPU flush and possible make interruptible wait for flush +complete. But that wait would be most possibly to fail in case of +signals received for X process, which will then fail modeset process +and put display engine in unconsistent state. The result could be +blank screen or CPU hang, and DDX driver would always turn on outputs +DPMS after whatever modeset fails or not. + +So this one creates new helper for setup display plane buffer, and +when needing flush using uninterruptible wait for that. + +This one should fix bug like https://bugs.freedesktop.org/show_bug.cgi?id=24009. +Also fixing mode switch stress test on Ironlake. + +Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 51 +++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/i915/intel_display.c | 2 - + 3 files changed, 53 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -829,6 +829,7 @@ int i915_lp_ring_sync(struct drm_device + int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); + int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, + int write); ++int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj); + int i915_gem_attach_phys_object(struct drm_device *dev, + struct drm_gem_object *obj, int id); + void i915_gem_detach_phys_object(struct drm_device *dev, +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2825,6 +2825,57 @@ i915_gem_object_set_to_gtt_domain(struct + return 0; + } + ++/* ++ * Prepare buffer for display plane. Use uninterruptible for possible flush ++ * wait, as in modesetting process we're not supposed to be interrupted. ++ */ ++int ++i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) ++{ ++ struct drm_device *dev = obj->dev; ++ struct drm_i915_gem_object *obj_priv = obj->driver_private; ++ uint32_t old_write_domain, old_read_domains; ++ int ret; ++ ++ /* Not valid to be called on unbound objects. */ ++ if (obj_priv->gtt_space == NULL) ++ return -EINVAL; ++ ++ i915_gem_object_flush_gpu_write_domain(obj); ++ ++ /* Wait on any GPU rendering and flushing to occur. */ ++ if (obj_priv->active) { ++#if WATCH_BUF ++ DRM_INFO("%s: object %p wait for seqno %08x\n", ++ __func__, obj, obj_priv->last_rendering_seqno); ++#endif ++ ret = i915_do_wait_request(dev, obj_priv->last_rendering_seqno, 0); ++ if (ret != 0) ++ return ret; ++ } ++ ++ old_write_domain = obj->write_domain; ++ old_read_domains = obj->read_domains; ++ ++ obj->read_domains &= I915_GEM_DOMAIN_GTT; ++ ++ i915_gem_object_flush_cpu_write_domain(obj); ++ ++ /* It should now be out of any other write domains, and we can update ++ * the domain values for our changes. ++ */ ++ BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0); ++ obj->read_domains |= I915_GEM_DOMAIN_GTT; ++ obj->write_domain = I915_GEM_DOMAIN_GTT; ++ obj_priv->dirty = 1; ++ ++ trace_i915_gem_object_change_domain(obj, ++ old_read_domains, ++ old_write_domain); ++ ++ return 0; ++} ++ + /** + * Moves a single object to the CPU read, and possibly write domain. + * +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1253,7 +1253,7 @@ intel_pipe_set_base(struct drm_crtc *crt + return ret; + } + +- ret = i915_gem_object_set_to_gtt_domain(obj, 1); ++ ret = i915_gem_object_set_to_display_plane(obj); + if (ret != 0) { + i915_gem_object_unpin(obj); + mutex_unlock(&dev->struct_mutex); +From 48764bf43f746113fc77877d7e80f2df23ca4cbb Mon Sep 17 00:00:00 2001 +From: Daniel Vetter <daniel.vetter@ffwll.ch> +Date: Tue, 15 Sep 2009 22:57:32 +0200 +Subject: drm/i915: add i915_lp_ring_sync helper + +From: Daniel Vetter <daniel.vetter@ffwll.ch> + +commit 48764bf43f746113fc77877d7e80f2df23ca4cbb upstream. + +This just waits until the hw passed the current ring position with +cmd execution. This slightly changes the existing i915_wait_request +function to make uninterruptible waiting possible - no point in +returning to userspace while mucking around with the overlay, that +piece of hw is just too fragile. + +Also replace a magic 0 with the symbolic constant (and kill the then +superflous comment) while I was looking at the code. + +Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 49 +++++++++++++++++++++++++++++++--------- + include/drm/drm_os_linux.h | 2 - + 3 files changed, 41 insertions(+), 11 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -825,6 +825,7 @@ void i915_gem_cleanup_ringbuffer(struct + int i915_gem_do_init(struct drm_device *dev, unsigned long start, + unsigned long end); + int i915_gem_idle(struct drm_device *dev); ++int i915_lp_ring_sync(struct drm_device *dev); + int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); + int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, + int write); +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -1809,12 +1809,8 @@ i915_gem_retire_work_handler(struct work + mutex_unlock(&dev->struct_mutex); + } + +-/** +- * Waits for a sequence number to be signaled, and cleans up the +- * request and object lists appropriately for that event. +- */ + static int +-i915_wait_request(struct drm_device *dev, uint32_t seqno) ++i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) + { + drm_i915_private_t *dev_priv = dev->dev_private; + u32 ier; +@@ -1841,10 +1837,15 @@ i915_wait_request(struct drm_device *dev + + dev_priv->mm.waiting_gem_seqno = seqno; + i915_user_irq_get(dev); +- ret = wait_event_interruptible(dev_priv->irq_queue, +- i915_seqno_passed(i915_get_gem_seqno(dev), +- seqno) || +- atomic_read(&dev_priv->mm.wedged)); ++ if (interruptible) ++ ret = wait_event_interruptible(dev_priv->irq_queue, ++ i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || ++ atomic_read(&dev_priv->mm.wedged)); ++ else ++ wait_event(dev_priv->irq_queue, ++ i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || ++ atomic_read(&dev_priv->mm.wedged)); ++ + i915_user_irq_put(dev); + dev_priv->mm.waiting_gem_seqno = 0; + +@@ -1868,6 +1869,34 @@ i915_wait_request(struct drm_device *dev + return ret; + } + ++/** ++ * Waits for a sequence number to be signaled, and cleans up the ++ * request and object lists appropriately for that event. ++ */ ++static int ++i915_wait_request(struct drm_device *dev, uint32_t seqno) ++{ ++ return i915_do_wait_request(dev, seqno, 1); ++} ++ ++/** ++ * Waits for the ring to finish up to the latest request. Usefull for waiting ++ * for flip events, e.g for the overlay support. */ ++int i915_lp_ring_sync(struct drm_device *dev) ++{ ++ uint32_t seqno; ++ int ret; ++ ++ seqno = i915_add_request(dev, NULL, 0); ++ ++ if (seqno == 0) ++ return -ENOMEM; ++ ++ ret = i915_do_wait_request(dev, seqno, 0); ++ BUG_ON(ret == -ERESTARTSYS); ++ return ret; ++} ++ + static void + i915_gem_flush(struct drm_device *dev, + uint32_t invalidate_domains, +@@ -1936,7 +1965,7 @@ i915_gem_flush(struct drm_device *dev, + #endif + BEGIN_LP_RING(2); + OUT_RING(cmd); +- OUT_RING(0); /* noop */ ++ OUT_RING(MI_NOOP); + ADVANCE_LP_RING(); + } + } +--- a/include/drm/drm_os_linux.h ++++ b/include/drm/drm_os_linux.h +@@ -123,5 +123,5 @@ do { \ + remove_wait_queue(&(queue), &entry); \ + } while (0) + +-#define DRM_WAKEUP( queue ) wake_up_interruptible( queue ) ++#define DRM_WAKEUP( queue ) wake_up( queue ) + #define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue ) +From 823f68fd646da6a39a9c0d3eb4c60d69dab5aa13 Mon Sep 17 00:00:00 2001 +From: Zhenyu Wang <zhenyuw@linux.intel.com> +Date: Mon, 28 Dec 2009 13:23:36 +0800 +Subject: drm/i915: remove full registers dump debug + +From: Zhenyu Wang <zhenyuw@linux.intel.com> + +commit 823f68fd646da6a39a9c0d3eb4c60d69dab5aa13 upstream. + +This one reverts 9e3a6d155ed0a7636b926a798dd7221ea107b274. +As reported by http://bugzilla.kernel.org/show_bug.cgi?id=14485, +this dump will cause hang problem on some machine. If something +really needs this kind of full registers dump, that could be done +within intel-gpu-tools. + +Cc: Ben Gamari <bgamari.foss@gmail.com> +Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + + +--- + drivers/gpu/drm/i915/i915_debugfs.c | 30 ------------------------------ + 1 file changed, 30 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -384,37 +384,7 @@ out: + return 0; + } + +-static int i915_registers_info(struct seq_file *m, void *data) { +- struct drm_info_node *node = (struct drm_info_node *) m->private; +- struct drm_device *dev = node->minor->dev; +- drm_i915_private_t *dev_priv = dev->dev_private; +- uint32_t reg; +- +-#define DUMP_RANGE(start, end) \ +- for (reg=start; reg < end; reg += 4) \ +- seq_printf(m, "%08x\t%08x\n", reg, I915_READ(reg)); +- +- DUMP_RANGE(0x00000, 0x00fff); /* VGA registers */ +- DUMP_RANGE(0x02000, 0x02fff); /* instruction, memory, interrupt control registers */ +- DUMP_RANGE(0x03000, 0x031ff); /* FENCE and PPGTT control registers */ +- DUMP_RANGE(0x03200, 0x03fff); /* frame buffer compression registers */ +- DUMP_RANGE(0x05000, 0x05fff); /* I/O control registers */ +- DUMP_RANGE(0x06000, 0x06fff); /* clock control registers */ +- DUMP_RANGE(0x07000, 0x07fff); /* 3D internal debug registers */ +- DUMP_RANGE(0x07400, 0x088ff); /* GPE debug registers */ +- DUMP_RANGE(0x0a000, 0x0afff); /* display palette registers */ +- DUMP_RANGE(0x10000, 0x13fff); /* MMIO MCHBAR */ +- DUMP_RANGE(0x30000, 0x3ffff); /* overlay registers */ +- DUMP_RANGE(0x60000, 0x6ffff); /* display engine pipeline registers */ +- DUMP_RANGE(0x70000, 0x72fff); /* display and cursor registers */ +- DUMP_RANGE(0x73000, 0x73fff); /* performance counters */ +- +- return 0; +-} +- +- + static struct drm_info_list i915_debugfs_list[] = { +- {"i915_regs", i915_registers_info, 0}, + {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, + {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, + {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, +From 99fcb766a3a50466fe31d743260a3400c1aee855 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter <daniel.vetter@ffwll.ch> +Date: Sun, 7 Feb 2010 16:20:18 +0100 +Subject: drm/i915: Update write_domains on active list after flush. + +From: Daniel Vetter <daniel.vetter@ffwll.ch> + +commit 99fcb766a3a50466fe31d743260a3400c1aee855 upstream. + +Before changing the status of a buffer with a pending write we will await +upon a new flush for that buffer. So we can take advantage of any flushes +posted whilst the buffer is active and pending processing by the GPU, by +clearing its write_domain and updating its last_rendering_seqno -- thus +saving a potential flush in deep queues and improves flushing behaviour +upon eviction for both GTT space and fences. + +In order to reduce the time spent searching the active list for matching +write_domains, we move those to a separate list whose elements are +the buffers belong to the active/flushing list with pending writes. + +Orignal patch by Chris Wilson <chris@chris-wilson.co.uk>, forward-ported +by me. + +In addition to better performance, this also fixes a real bug. Before +this changes, i915_gem_evict_everything didn't work as advertised. When +the gpu was actually busy and processing request, the flush and subsequent +wait would not move active and dirty buffers to the inactive list, but +just to the flushing list. Which triggered the BUG_ON at the end of this +function. With the more tight dirty buffer tracking, all currently busy and +dirty buffers get moved to the inactive list by one i915_gem_flush operation. + +I've left the BUG_ON I've used to prove this in there. + +References: + Bug 25911 - 2.10.0 causes kernel oops and system hangs + http://bugs.freedesktop.org/show_bug.cgi?id=25911 + + Bug 26101 - [i915] xf86-video-intel 2.10.0 (and git) triggers kernel oops + within seconds after login + http://bugs.freedesktop.org/show_bug.cgi?id=26101 + +Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> +Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> +Tested-by: Adam Lantos <hege@playma.org> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/i915_drv.h | 11 +++++++++++ + drivers/gpu/drm/i915/i915_gem.c | 23 +++++++++++++++++++---- + 2 files changed, 30 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -467,6 +467,15 @@ typedef struct drm_i915_private { + struct list_head flushing_list; + + /** ++ * List of objects currently pending a GPU write flush. ++ * ++ * All elements on this list will belong to either the ++ * active_list or flushing_list, last_rendering_seqno can ++ * be used to differentiate between the two elements. ++ */ ++ struct list_head gpu_write_list; ++ ++ /** + * LRU list of objects which are not in the ringbuffer and + * are ready to unbind, but are still in the GTT. + * +@@ -558,6 +567,8 @@ struct drm_i915_gem_object { + + /** This object's place on the active/flushing/inactive lists */ + struct list_head list; ++ /** This object's place on GPU write list */ ++ struct list_head gpu_write_list; + + /** This object's place on the fenced object LRU */ + struct list_head fence_list; +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -1552,6 +1552,8 @@ i915_gem_object_move_to_inactive(struct + else + list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); + ++ BUG_ON(!list_empty(&obj_priv->gpu_write_list)); ++ + obj_priv->last_rendering_seqno = 0; + if (obj_priv->active) { + obj_priv->active = 0; +@@ -1622,7 +1624,8 @@ i915_add_request(struct drm_device *dev, + struct drm_i915_gem_object *obj_priv, *next; + + list_for_each_entry_safe(obj_priv, next, +- &dev_priv->mm.flushing_list, list) { ++ &dev_priv->mm.gpu_write_list, ++ gpu_write_list) { + struct drm_gem_object *obj = obj_priv->obj; + + if ((obj->write_domain & flush_domains) == +@@ -1630,6 +1633,7 @@ i915_add_request(struct drm_device *dev, + uint32_t old_write_domain = obj->write_domain; + + obj->write_domain = 0; ++ list_del_init(&obj_priv->gpu_write_list); + i915_gem_object_move_to_active(obj, seqno); + + trace_i915_gem_object_change_domain(obj, +@@ -2073,8 +2077,8 @@ static int + i915_gem_evict_everything(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; +- uint32_t seqno; + int ret; ++ uint32_t seqno; + bool lists_empty; + + spin_lock(&dev_priv->mm.active_list_lock); +@@ -2096,6 +2100,8 @@ i915_gem_evict_everything(struct drm_dev + if (ret) + return ret; + ++ BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); ++ + ret = i915_gem_evict_from_inactive_list(dev); + if (ret) + return ret; +@@ -2690,7 +2696,7 @@ i915_gem_object_flush_gpu_write_domain(s + old_write_domain = obj->write_domain; + i915_gem_flush(dev, 0, obj->write_domain); + seqno = i915_add_request(dev, NULL, obj->write_domain); +- obj->write_domain = 0; ++ BUG_ON(obj->write_domain); + i915_gem_object_move_to_active(obj, seqno); + + trace_i915_gem_object_change_domain(obj, +@@ -3710,16 +3716,23 @@ i915_gem_execbuffer(struct drm_device *d + i915_gem_flush(dev, + dev->invalidate_domains, + dev->flush_domains); +- if (dev->flush_domains) ++ if (dev->flush_domains & I915_GEM_GPU_DOMAINS) + (void)i915_add_request(dev, file_priv, + dev->flush_domains); + } + + for (i = 0; i < args->buffer_count; i++) { + struct drm_gem_object *obj = object_list[i]; ++ struct drm_i915_gem_object *obj_priv = obj->driver_private; + uint32_t old_write_domain = obj->write_domain; + + obj->write_domain = obj->pending_write_domain; ++ if (obj->write_domain) ++ list_move_tail(&obj_priv->gpu_write_list, ++ &dev_priv->mm.gpu_write_list); ++ else ++ list_del_init(&obj_priv->gpu_write_list); ++ + trace_i915_gem_object_change_domain(obj, + obj->read_domains, + old_write_domain); +@@ -4112,6 +4125,7 @@ int i915_gem_init_object(struct drm_gem_ + obj_priv->obj = obj; + obj_priv->fence_reg = I915_FENCE_REG_NONE; + INIT_LIST_HEAD(&obj_priv->list); ++ INIT_LIST_HEAD(&obj_priv->gpu_write_list); + INIT_LIST_HEAD(&obj_priv->fence_list); + obj_priv->madv = I915_MADV_WILLNEED; + +@@ -4563,6 +4577,7 @@ i915_gem_load(struct drm_device *dev) + spin_lock_init(&dev_priv->mm.active_list_lock); + INIT_LIST_HEAD(&dev_priv->mm.active_list); + INIT_LIST_HEAD(&dev_priv->mm.flushing_list); ++ INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list); + INIT_LIST_HEAD(&dev_priv->mm.inactive_list); + INIT_LIST_HEAD(&dev_priv->mm.request_list); + INIT_LIST_HEAD(&dev_priv->mm.fence_list); +From fd2e8ea597222b8f38ae8948776a61ea7958232e Mon Sep 17 00:00:00 2001 +From: Chris Wilson <chris@chris-wilson.co.uk> +Date: Tue, 9 Feb 2010 14:14:36 +0000 +Subject: drm/i915: Increase fb alignment to 64k + +From: Chris Wilson <chris@chris-wilson.co.uk> + +commit fd2e8ea597222b8f38ae8948776a61ea7958232e upstream. + +An untiled framebuffer must be aligned to 64k. This is normally handled +by intel_pin_and_fence_fb_obj(), but the intelfb_create() likes to be +different and do the pinning itself. However, it aligns the buffer +object incorrectly for pre-i965 chipsets causing a PGTBL_ERR when it is +installed onto the output. + +Fixes: + KMS error message while initializing modesetting - + render error detected: EIR: 0x10 [i915] + http://bugs.freedesktop.org/show_bug.cgi?id=22936 + +Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/intel_fb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/intel_fb.c ++++ b/drivers/gpu/drm/i915/intel_fb.c +@@ -148,7 +148,7 @@ static int intelfb_create(struct drm_dev + + mutex_lock(&dev->struct_mutex); + +- ret = i915_gem_object_pin(fbo, PAGE_SIZE); ++ ret = i915_gem_object_pin(fbo, 64*1024); + if (ret) { + DRM_ERROR("failed to pin fb: %d\n", ret); + goto out_unref; +From ee25df2bc379728c45d81e04cf87984db1425edf Mon Sep 17 00:00:00 2001 +From: Jesse Barnes <jbarnes@virtuousgeek.org> +Date: Sat, 6 Feb 2010 10:41:53 -0800 +Subject: drm/i915: handle FBC and self-refresh better + +From: Jesse Barnes <jbarnes@virtuousgeek.org> + +commit ee25df2bc379728c45d81e04cf87984db1425edf upstream. + +On 945, we need to avoid entering self-refresh if the compressor is +busy, or we may cause display FIFO underruns leading to ugly flicker. + +Fixes fdo bug #24314, kernel bug #15043. + +Tested-by: Alexander Lam <lambchop468@gmail.com> +Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> +Tested-by: Julien Cristau <jcristau@debian.org> (fd.o #25371) +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/i915_reg.h | 1 + + drivers/gpu/drm/i915/intel_display.c | 2 ++ + 2 files changed, 3 insertions(+) + +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -329,6 +329,7 @@ + #define FBC_CTL_PERIODIC (1<<30) + #define FBC_CTL_INTERVAL_SHIFT (16) + #define FBC_CTL_UNCOMPRESSIBLE (1<<14) ++#define FBC_C3_IDLE (1<<13) + #define FBC_CTL_STRIDE_SHIFT (5) + #define FBC_CTL_FENCENO (1<<0) + #define FBC_COMMAND 0x0320c +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -988,6 +988,8 @@ static void i8xx_enable_fbc(struct drm_c + + /* enable it... */ + fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC; ++ if (IS_I945GM(dev)) ++ fbc_ctl |= FBC_C3_IDLE; /* 945 needs special SR handling */ + fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; + fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; + if (obj_priv->tiling_mode != I915_TILING_NONE) +From a3cb5195f6db58dbebd8a31b877ddce082c9b63d Mon Sep 17 00:00:00 2001 +From: Zhao Yakui <yakui.zhao@intel.com> +Date: Fri, 11 Dec 2009 09:26:10 +0800 +Subject: drm/i915: Add MALATA PC-81005 to ACPI LID quirk list + +From: Zhao Yakui <yakui.zhao@intel.com> + +commit a3cb5195f6db58dbebd8a31b877ddce082c9b63d upstream. + +The MALATA PC-81005 laptop always reports that the LID status is closed and we +can't use it reliabily for LVDS detection. So add this box into the quirk list. + +https://bugs.freedesktop.org/show_bug.cgi?id=25523 + +Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> +Review-by: Jesse Barnes <jbarnes@virtuousgeek.org> +Tested-by: Hector <hector1987@gmail.com> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/intel_lvds.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -622,6 +622,13 @@ static const struct dmi_system_id bad_li + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire one"), + }, + }, ++ { ++ .ident = "PC-81005", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "MALATA"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"), ++ }, ++ }, + { } + }; + +From f034b12dbb5749b11e9390e15e93ffa87ece8038 Mon Sep 17 00:00:00 2001 +From: Zhao Yakui <yakui.zhao@intel.com> +Date: Thu, 21 Jan 2010 15:20:18 +0800 +Subject: drm/i915: Fix the incorrect DMI string for Samsung SX20S laptop + +From: Zhao Yakui <yakui.zhao@intel.com> + +commit f034b12dbb5749b11e9390e15e93ffa87ece8038 upstream. + +Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> +Reported-by: Philipp Kohlbecher <xt28@gmx.de> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/intel_lvds.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -611,7 +611,7 @@ static const struct dmi_system_id bad_li + { + .ident = "Samsung SX20S", + .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Phoenix Technologies LTD"), ++ DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"), + DMI_MATCH(DMI_BOARD_NAME, "SX20S"), + }, + }, +From 40f33a92100f4d9b6e85ad642100cfe42d7ff57d Mon Sep 17 00:00:00 2001 +From: Zhao Yakui <yakui.zhao@intel.com> +Date: Wed, 6 Jan 2010 13:30:36 +0800 +Subject: drm/i915: Add HP nx9020/SamsungSX20S to ACPI LID quirk list + +From: Zhao Yakui <yakui.zhao@intel.com> + +commit 40f33a92100f4d9b6e85ad642100cfe42d7ff57d upstream. + +The HP comaq nx9020/Samsung SX20S laptop always report that the LID status is +closed and we can't use it reliabily for LVDS detection. So add the two boxes +into the quirk list. + +http://bugzilla.kernel.org/show_bug.cgi?id=14957 +http://bugzilla.kernel.org/show_bug.cgi?id=14554 + +Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/intel_lvds.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -602,6 +602,20 @@ static void intel_lvds_mode_set(struct d + /* Some lid devices report incorrect lid status, assume they're connected */ + static const struct dmi_system_id bad_lid_status[] = { + { ++ .ident = "Compaq nx9020", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_BOARD_NAME, "3084"), ++ }, ++ }, ++ { ++ .ident = "Samsung SX20S", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Phoenix Technologies LTD"), ++ DMI_MATCH(DMI_BOARD_NAME, "SX20S"), ++ }, ++ }, ++ { + .ident = "Aspire One", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +From f0217c42c9ab3d772e543f635ce628b9478f70b6 Mon Sep 17 00:00:00 2001 +From: Eric Anholt <eric@anholt.net> +Date: Tue, 1 Dec 2009 11:56:30 -0800 +Subject: drm/i915: Fix DDC on some systems by clearing BIOS GMBUS setup. + +From: Eric Anholt <eric@anholt.net> + +commit f0217c42c9ab3d772e543f635ce628b9478f70b6 upstream. + +This is a sync of a fix I made in the old UMS code. If the BIOS uses +the GMBUS and doesn't clear that setup, then our bit-banging I2C can +fail, leading to monitors not being detected. + +Signed-off-by: Eric Anholt <eric@anholt.net> +Cc: maximilian attems <max@stro.at> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/i915_reg.h | 14 ++++++++++++++ + drivers/gpu/drm/i915/i915_suspend.c | 5 ++++- + drivers/gpu/drm/i915/intel_drv.h | 2 ++ + drivers/gpu/drm/i915/intel_i2c.c | 19 +++++++++++++++++++ + 4 files changed, 39 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -405,6 +405,13 @@ + # define GPIO_DATA_VAL_IN (1 << 12) + # define GPIO_DATA_PULLUP_DISABLE (1 << 13) + ++#define GMBUS0 0x5100 ++#define GMBUS1 0x5104 ++#define GMBUS2 0x5108 ++#define GMBUS3 0x510c ++#define GMBUS4 0x5110 ++#define GMBUS5 0x5120 ++ + /* + * Clock control & power management + */ +@@ -2153,6 +2160,13 @@ + #define PCH_GPIOE 0xc5020 + #define PCH_GPIOF 0xc5024 + ++#define PCH_GMBUS0 0xc5100 ++#define PCH_GMBUS1 0xc5104 ++#define PCH_GMBUS2 0xc5108 ++#define PCH_GMBUS3 0xc510c ++#define PCH_GMBUS4 0xc5110 ++#define PCH_GMBUS5 0xc5120 ++ + #define PCH_DPLL_A 0xc6014 + #define PCH_DPLL_B 0xc6018 + +--- a/drivers/gpu/drm/i915/i915_suspend.c ++++ b/drivers/gpu/drm/i915/i915_suspend.c +@@ -27,7 +27,7 @@ + #include "drmP.h" + #include "drm.h" + #include "i915_drm.h" +-#include "i915_drv.h" ++#include "intel_drv.h" + + static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) + { +@@ -846,6 +846,9 @@ int i915_restore_state(struct drm_device + for (i = 0; i < 3; i++) + I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); + ++ /* I2C state */ ++ intel_i2c_reset_gmbus(dev); ++ + return 0; + } + +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -134,6 +134,8 @@ void intel_i2c_destroy(struct i2c_adapte + int intel_ddc_get_modes(struct intel_output *intel_output); + extern bool intel_ddc_probe(struct intel_output *intel_output); + void intel_i2c_quirk_set(struct drm_device *dev, bool enable); ++void intel_i2c_reset_gmbus(struct drm_device *dev); ++ + extern void intel_crt_init(struct drm_device *dev); + extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); + extern bool intel_sdvo_init(struct drm_device *dev, int output_device); +--- a/drivers/gpu/drm/i915/intel_i2c.c ++++ b/drivers/gpu/drm/i915/intel_i2c.c +@@ -118,6 +118,23 @@ static void set_data(void *data, int sta + udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ + } + ++/* Clears the GMBUS setup. Our driver doesn't make use of the GMBUS I2C ++ * engine, but if the BIOS leaves it enabled, then that can break our use ++ * of the bit-banging I2C interfaces. This is notably the case with the ++ * Mac Mini in EFI mode. ++ */ ++void ++intel_i2c_reset_gmbus(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (IS_IGDNG(dev)) { ++ I915_WRITE(PCH_GMBUS0, 0); ++ } else { ++ I915_WRITE(GMBUS0, 0); ++ } ++} ++ + /** + * intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg + * @dev: DRM device +@@ -168,6 +185,8 @@ struct i2c_adapter *intel_i2c_create(str + if(i2c_bit_add_bus(&chan->adapter)) + goto out_free; + ++ intel_i2c_reset_gmbus(dev); ++ + /* JJJ: raise SCL and SDA? */ + intel_i2c_quirk_set(dev, true); + set_data(chan, 1); +From 33c5fd121eabbccc9103daf6cda36941eb3c349f Mon Sep 17 00:00:00 2001 +From: David John <davidjon@xenontk.org> +Date: Wed, 27 Jan 2010 15:19:08 +0530 +Subject: drm/i915: Disable SR when more than one pipe is enabled + +From: David John <davidjon@xenontk.org> + +commit 33c5fd121eabbccc9103daf6cda36941eb3c349f upstream. + +Self Refresh should be disabled on dual plane configs. Otherwise, as +the SR watermark is not calculated for such configs, switching to non +VGA mode causes FIFO underrun and display flicker. + +This fixes Korg Bug #14897. + +Signed-off-by: David John <davidjon@xenontk.org> +Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/intel_display.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2538,6 +2538,10 @@ static void g4x_update_wm(struct drm_dev + sr_entries = roundup(sr_entries / cacheline_size, 1); + DRM_DEBUG("self-refresh entries: %d\n", sr_entries); + I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); ++ } else { ++ /* Turn off self refresh if both pipes are enabled */ ++ I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) ++ & ~FW_BLC_SELF_EN); + } + + DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n", +@@ -2581,6 +2585,10 @@ static void i965_update_wm(struct drm_de + srwm = 1; + srwm &= 0x3f; + I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); ++ } else { ++ /* Turn off self refresh if both pipes are enabled */ ++ I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) ++ & ~FW_BLC_SELF_EN); + } + + DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", +@@ -2649,6 +2657,10 @@ static void i9xx_update_wm(struct drm_de + if (srwm < 0) + srwm = 1; + I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f)); ++ } else { ++ /* Turn off self refresh if both pipes are enabled */ ++ I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) ++ & ~FW_BLC_SELF_EN); + } + + DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", +From 1dc7546d1a73664e5d117715b214bea9cae5951c Mon Sep 17 00:00:00 2001 +From: Jesse Barnes <jbarnes@jbarnes-x200.(none)> +Date: Mon, 19 Oct 2009 10:08:17 +0900 +Subject: drm/i915: enable self-refresh on 965 + +From: Jesse Barnes <jbarnes@jbarnes-x200.(none)> + +commit 1dc7546d1a73664e5d117715b214bea9cae5951c upstream. + +Need to calculate the SR watermark and enable it. + +Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/intel_display.c | 32 ++++++++++++++++++++++++++++---- + 1 file changed, 28 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2556,15 +2556,39 @@ static void g4x_update_wm(struct drm_dev + (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); + } + +-static void i965_update_wm(struct drm_device *dev, int unused, int unused2, +- int unused3, int unused4) ++static void i965_update_wm(struct drm_device *dev, int planea_clock, ++ int planeb_clock, int sr_hdisplay, int pixel_size) + { + struct drm_i915_private *dev_priv = dev->dev_private; ++ unsigned long line_time_us; ++ int sr_clock, sr_entries, srwm = 1; + +- DRM_DEBUG("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR 8\n"); ++ /* Calc sr entries for one plane configs */ ++ if (sr_hdisplay && (!planea_clock || !planeb_clock)) { ++ /* self-refresh has much higher latency */ ++ const static int sr_latency_ns = 12000; ++ ++ sr_clock = planea_clock ? planea_clock : planeb_clock; ++ line_time_us = ((sr_hdisplay * 1000) / sr_clock); ++ ++ /* Use ns/us then divide to preserve precision */ ++ sr_entries = (((sr_latency_ns / line_time_us) + 1) * ++ pixel_size * sr_hdisplay) / 1000; ++ sr_entries = roundup(sr_entries / I915_FIFO_LINE_SIZE, 1); ++ DRM_DEBUG("self-refresh entries: %d\n", sr_entries); ++ srwm = I945_FIFO_SIZE - sr_entries; ++ if (srwm < 0) ++ srwm = 1; ++ srwm &= 0x3f; ++ I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); ++ } ++ ++ DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", ++ srwm); + + /* 965 has limitations... */ +- I915_WRITE(DSPFW1, (8 << 16) | (8 << 8) | (8 << 0)); ++ I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | (8 << 16) | (8 << 8) | ++ (8 << 0)); + I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); + } + +From eceb784cec4dc0fcc2993d9ee4a7c0d111ada80a Mon Sep 17 00:00:00 2001 +From: Zhenyu Wang <zhenyuw@linux.intel.com> +Date: Mon, 25 Jan 2010 10:35:16 +0800 +Subject: drm/i915: disable hotplug detect before Ironlake CRT detect + +From: Zhenyu Wang <zhenyuw@linux.intel.com> + +commit eceb784cec4dc0fcc2993d9ee4a7c0d111ada80a upstream. + +This tries to fix CRT detect loop hang seen on some Ironlake form +factor, to clear up hotplug detect state before taking CRT detect +to make sure next hotplug detect cycle is consistent. + +Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/intel_crt.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/gpu/drm/i915/intel_crt.c ++++ b/drivers/gpu/drm/i915/intel_crt.c +@@ -185,6 +185,9 @@ static bool intel_igdng_crt_detect_hotpl + adpa = I915_READ(PCH_ADPA); + + adpa &= ~ADPA_CRT_HOTPLUG_MASK; ++ /* disable HPD first */ ++ I915_WRITE(PCH_ADPA, adpa); ++ (void)I915_READ(PCH_ADPA); + + adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | + ADPA_CRT_HOTPLUG_WARMUP_10MS | |