f2a8acbfe3
2.6.32.16 update. (#620955) - Revert upstream DRM stable fix we already have: drm-i915-give-up-on-8xx-lid-status.patch
2437 lines
82 KiB
Diff
2437 lines
82 KiB
Diff
From 7b9c5abee98c54f85bcc04bd4d7ec8d5094c73f4 Mon Sep 17 00:00:00 2001
|
|
From: Jesse Barnes <jbarnes@virtuousgeek.org>
|
|
Date: Fri, 12 Feb 2010 09:30:00 -0800
|
|
Subject: drm/i915: give up on 8xx lid status
|
|
|
|
From: Jesse Barnes <jbarnes@virtuousgeek.org>
|
|
|
|
commit 7b9c5abee98c54f85bcc04bd4d7ec8d5094c73f4 upstream.
|
|
|
|
These old machines more often than not lie about their lid state. So
|
|
don't use it to detect LVDS presence, but leave the event handler to
|
|
deal with lid open/close, when we might need to reset the mode.
|
|
|
|
Fixes kernel bug #15248
|
|
|
|
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
|
|
Signed-off-by: Eric Anholt <eric@anholt.net>
|
|
Cc: Ben Hutchings <ben@decadent.org.uk>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
|
|
|
---
|
|
drivers/gpu/drm/i915/intel_lvds.c | 4 ++++
|
|
1 file changed, 4 insertions(+)
|
|
|
|
--- a/drivers/gpu/drm/i915/intel_lvds.c
|
|
+++ b/drivers/gpu/drm/i915/intel_lvds.c
|
|
@@ -648,8 +648,12 @@ static const struct dmi_system_id bad_li
|
|
*/
|
|
static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector)
|
|
{
|
|
+ struct drm_device *dev = connector->dev;
|
|
enum drm_connector_status status = connector_status_connected;
|
|
|
|
+ if (IS_I8XX(dev))
|
|
+ return connector_status_connected;
|
|
+
|
|
if (!acpi_lid_open() && !dmi_check_system(bad_lid_status))
|
|
status = connector_status_disconnected;
|
|
|
|
From 6363ee6f496eb7e3b3f78dc105e522c7b496089b Mon Sep 17 00:00:00 2001
|
|
From: Zhao Yakui <yakui.zhao@intel.com>
|
|
Date: Tue, 24 Nov 2009 09:48:44 +0800
|
|
Subject: drm/i915: parse child device from VBT
|
|
|
|
From: Zhao Yakui <yakui.zhao@intel.com>
|
|
|
|
commit 6363ee6f496eb7e3b3f78dc105e522c7b496089b upstream.
|
|
|
|
On some laptops there is no HDMI/DP. But the xrandr still reports
|
|
several disconnected HDMI/display ports. In such case the user will be
|
|
confused.
|
|
>DVI1 disconnected (normal left inverted right x axis y axis)
|
|
>DP1 disconnected (normal left inverted right x axis y axis)
|
|
>DVI2 disconnected (normal left inverted right x axis y axis)
|
|
>DP2 disconnected (normal left inverted right x axis y axis)
|
|
>DP3 disconnected (normal left inverted right x axis y axis)
|
|
|
|
This patch set is to use the child device parsed in VBT to decide whether
|
|
the HDMI/DP/LVDS/TV should be initialized.
|
|
|
|
Parse the child device from VBT.
|
|
|
|
The device class type is also added for LFP, TV, HDMI, DP output.
|
|
|
|
https://bugs.freedesktop.org/show_bug.cgi?id=22785
|
|
|
|
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
|
|
Reviewed-by: Adam Jackson <ajax@redhat.com>
|
|
Signed-off-by: Eric Anholt <eric@anholt.net>
|
|
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
|
|
|
---
|
|
drivers/gpu/drm/i915/i915_dma.c | 9 +++++
|
|
drivers/gpu/drm/i915/i915_drv.h | 2 +
|
|
drivers/gpu/drm/i915/intel_bios.c | 65 ++++++++++++++++++++++++++++++++++++++
|
|
drivers/gpu/drm/i915/intel_bios.h | 17 +++++++++
|
|
4 files changed, 93 insertions(+)
|
|
|
|
--- a/drivers/gpu/drm/i915/i915_dma.c
|
|
+++ b/drivers/gpu/drm/i915/i915_dma.c
|
|
@@ -1526,6 +1526,15 @@ int i915_driver_unload(struct drm_device
|
|
}
|
|
|
|
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
|
+ /*
|
|
+ * free the memory space allocated for the child device
|
|
+ * config parsed from VBT
|
|
+ */
|
|
+ if (dev_priv->child_dev && dev_priv->child_dev_num) {
|
|
+ kfree(dev_priv->child_dev);
|
|
+ dev_priv->child_dev = NULL;
|
|
+ dev_priv->child_dev_num = 0;
|
|
+ }
|
|
drm_irq_uninstall(dev);
|
|
vga_client_register(dev->pdev, NULL, NULL, NULL);
|
|
}
|
|
--- a/drivers/gpu/drm/i915/i915_drv.h
|
|
+++ b/drivers/gpu/drm/i915/i915_drv.h
|
|
@@ -555,6 +555,8 @@ typedef struct drm_i915_private {
|
|
struct timer_list idle_timer;
|
|
bool busy;
|
|
u16 orig_clock;
|
|
+ int child_dev_num;
|
|
+ struct child_device_config *child_dev;
|
|
struct drm_connector *int_lvds_connector;
|
|
} drm_i915_private_t;
|
|
|
|
--- a/drivers/gpu/drm/i915/intel_bios.c
|
|
+++ b/drivers/gpu/drm/i915/intel_bios.c
|
|
@@ -362,6 +362,70 @@ parse_driver_features(struct drm_i915_pr
|
|
dev_priv->render_reclock_avail = true;
|
|
}
|
|
|
|
+static void
|
|
+parse_device_mapping(struct drm_i915_private *dev_priv,
|
|
+ struct bdb_header *bdb)
|
|
+{
|
|
+ struct bdb_general_definitions *p_defs;
|
|
+ struct child_device_config *p_child, *child_dev_ptr;
|
|
+ int i, child_device_num, count;
|
|
+ u16 block_size;
|
|
+
|
|
+ p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
|
|
+ if (!p_defs) {
|
|
+ DRM_DEBUG_KMS("No general definition block is found\n");
|
|
+ return;
|
|
+ }
|
|
+ /* judge whether the size of child device meets the requirements.
|
|
+ * If the child device size obtained from general definition block
|
|
+ * is different with sizeof(struct child_device_config), skip the
|
|
+ * parsing of sdvo device info
|
|
+ */
|
|
+ if (p_defs->child_dev_size != sizeof(*p_child)) {
|
|
+ /* different child dev size . Ignore it */
|
|
+ DRM_DEBUG_KMS("different child size is found. Invalid.\n");
|
|
+ return;
|
|
+ }
|
|
+ /* get the block size of general definitions */
|
|
+ block_size = get_blocksize(p_defs);
|
|
+ /* get the number of child device */
|
|
+ child_device_num = (block_size - sizeof(*p_defs)) /
|
|
+ sizeof(*p_child);
|
|
+ count = 0;
|
|
+ /* get the number of child device that is present */
|
|
+ for (i = 0; i < child_device_num; i++) {
|
|
+ p_child = &(p_defs->devices[i]);
|
|
+ if (!p_child->device_type) {
|
|
+ /* skip the device block if device type is invalid */
|
|
+ continue;
|
|
+ }
|
|
+ count++;
|
|
+ }
|
|
+ if (!count) {
|
|
+ DRM_DEBUG_KMS("no child dev is parsed from VBT \n");
|
|
+ return;
|
|
+ }
|
|
+ dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL);
|
|
+ if (!dev_priv->child_dev) {
|
|
+ DRM_DEBUG_KMS("No memory space for child device\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ dev_priv->child_dev_num = count;
|
|
+ count = 0;
|
|
+ for (i = 0; i < child_device_num; i++) {
|
|
+ p_child = &(p_defs->devices[i]);
|
|
+ if (!p_child->device_type) {
|
|
+ /* skip the device block if device type is invalid */
|
|
+ continue;
|
|
+ }
|
|
+ child_dev_ptr = dev_priv->child_dev + count;
|
|
+ count++;
|
|
+ memcpy((void *)child_dev_ptr, (void *)p_child,
|
|
+ sizeof(*p_child));
|
|
+ }
|
|
+ return;
|
|
+}
|
|
/**
|
|
* intel_init_bios - initialize VBIOS settings & find VBT
|
|
* @dev: DRM device
|
|
@@ -413,6 +477,7 @@ intel_init_bios(struct drm_device *dev)
|
|
parse_lfp_panel_data(dev_priv, bdb);
|
|
parse_sdvo_panel_data(dev_priv, bdb);
|
|
parse_sdvo_device_mapping(dev_priv, bdb);
|
|
+ parse_device_mapping(dev_priv, bdb);
|
|
parse_driver_features(dev_priv, bdb);
|
|
|
|
pci_unmap_rom(pdev, bios);
|
|
--- a/drivers/gpu/drm/i915/intel_bios.h
|
|
+++ b/drivers/gpu/drm/i915/intel_bios.h
|
|
@@ -549,4 +549,21 @@ bool intel_init_bios(struct drm_device *
|
|
#define SWF14_APM_STANDBY 0x1
|
|
#define SWF14_APM_RESTORE 0x0
|
|
|
|
+/* Add the device class for LFP, TV, HDMI */
|
|
+#define DEVICE_TYPE_INT_LFP 0x1022
|
|
+#define DEVICE_TYPE_INT_TV 0x1009
|
|
+#define DEVICE_TYPE_HDMI 0x60D2
|
|
+#define DEVICE_TYPE_DP 0x68C6
|
|
+#define DEVICE_TYPE_eDP 0x78C6
|
|
+
|
|
+/* define the DVO port for HDMI output type */
|
|
+#define DVO_B 1
|
|
+#define DVO_C 2
|
|
+#define DVO_D 3
|
|
+
|
|
+/* define the PORT for DP output type */
|
|
+#define PORT_IDPB 7
|
|
+#define PORT_IDPC 8
|
|
+#define PORT_IDPD 9
|
|
+
|
|
#endif /* _I830_BIOS_H_ */
|
|
From 38b3037ee47fbd65a36bc7c39f60a900fbbe3b8e Mon Sep 17 00:00:00 2001
|
|
From: Adam Jackson <ajax@redhat.com>
|
|
Date: Tue, 24 Nov 2009 10:07:00 -0500
|
|
Subject: drm/i915: Fix LVDS presence check
|
|
|
|
Combined patches from 2.6.33 for fixing LVDS detection.
|
|
7cf4f69d3f4511f443473954456cb91d5514756d
|
|
drm/i915: Don't set up the LVDS if it isn't in the BIOS device table.
|
|
38b3037ee47fbd65a36bc7c39f60a900fbbe3b8e
|
|
drm/i915: Fix LVDS presence check
|
|
6e36595a2131e7ed5ee2674be54b2713ba7f0490
|
|
drm/i915: Declare the new VBT parsing functions as static
|
|
11ba159288f1bfc1a475c994e598f5fe423fde9d
|
|
drm/i915: Don't check for lid presence when detecting LVDS
|
|
|
|
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Cc: Matthew Garrett <mjg@redhat.com>
|
|
Cc: Adam Jackson <ajax@redhat.com>
|
|
Cc: Eric Anholt <eric@anholt.net>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
|
|
|
---
|
|
drivers/gpu/drm/i915/intel_lvds.c | 90 +++++++++++++-------------------------
|
|
1 file changed, 33 insertions(+), 57 deletions(-)
|
|
|
|
--- a/drivers/gpu/drm/i915/intel_lvds.c
|
|
+++ b/drivers/gpu/drm/i915/intel_lvds.c
|
|
@@ -901,64 +901,45 @@ static const struct dmi_system_id intel_
|
|
{ } /* terminating entry */
|
|
};
|
|
|
|
-#ifdef CONFIG_ACPI
|
|
/*
|
|
- * check_lid_device -- check whether @handle is an ACPI LID device.
|
|
- * @handle: ACPI device handle
|
|
- * @level : depth in the ACPI namespace tree
|
|
- * @context: the number of LID device when we find the device
|
|
- * @rv: a return value to fill if desired (Not use)
|
|
+ * Enumerate the child dev array parsed from VBT to check whether
|
|
+ * the LVDS is present.
|
|
+ * If it is present, return 1.
|
|
+ * If it is not present, return false.
|
|
+ * If no child dev is parsed from VBT, it assumes that the LVDS is present.
|
|
+ * Note: The addin_offset should also be checked for LVDS panel.
|
|
+ * Only when it is non-zero, it is assumed that it is present.
|
|
*/
|
|
-static acpi_status
|
|
-check_lid_device(acpi_handle handle, u32 level, void *context,
|
|
- void **return_value)
|
|
+static int lvds_is_present_in_vbt(struct drm_device *dev)
|
|
{
|
|
- struct acpi_device *acpi_dev;
|
|
- int *lid_present = context;
|
|
-
|
|
- acpi_dev = NULL;
|
|
- /* Get the acpi device for device handle */
|
|
- if (acpi_bus_get_device(handle, &acpi_dev) || !acpi_dev) {
|
|
- /* If there is no ACPI device for handle, return */
|
|
- return AE_OK;
|
|
- }
|
|
-
|
|
- if (!strncmp(acpi_device_hid(acpi_dev), "PNP0C0D", 7))
|
|
- *lid_present = 1;
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
+ struct child_device_config *p_child;
|
|
+ int i, ret;
|
|
|
|
- return AE_OK;
|
|
-}
|
|
+ if (!dev_priv->child_dev_num)
|
|
+ return 1;
|
|
|
|
-/**
|
|
- * check whether there exists the ACPI LID device by enumerating the ACPI
|
|
- * device tree.
|
|
- */
|
|
-static int intel_lid_present(void)
|
|
-{
|
|
- int lid_present = 0;
|
|
+ ret = 0;
|
|
+ for (i = 0; i < dev_priv->child_dev_num; i++) {
|
|
+ p_child = dev_priv->child_dev + i;
|
|
+ /*
|
|
+ * If the device type is not LFP, continue.
|
|
+ * If the device type is 0x22, it is also regarded as LFP.
|
|
+ */
|
|
+ if (p_child->device_type != DEVICE_TYPE_INT_LFP &&
|
|
+ p_child->device_type != DEVICE_TYPE_LFP)
|
|
+ continue;
|
|
|
|
- if (acpi_disabled) {
|
|
- /* If ACPI is disabled, there is no ACPI device tree to
|
|
- * check, so assume the LID device would have been present.
|
|
+ /* The addin_offset should be checked. Only when it is
|
|
+ * non-zero, it is regarded as present.
|
|
*/
|
|
- return 1;
|
|
+ if (p_child->addin_offset) {
|
|
+ ret = 1;
|
|
+ break;
|
|
+ }
|
|
}
|
|
-
|
|
- acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
|
|
- ACPI_UINT32_MAX,
|
|
- check_lid_device, &lid_present, NULL);
|
|
-
|
|
- return lid_present;
|
|
-}
|
|
-#else
|
|
-static int intel_lid_present(void)
|
|
-{
|
|
- /* In the absence of ACPI built in, assume that the LID device would
|
|
- * have been present.
|
|
- */
|
|
- return 1;
|
|
+ return ret;
|
|
}
|
|
-#endif
|
|
|
|
/**
|
|
* intel_lvds_init - setup LVDS connectors on this device
|
|
@@ -983,15 +964,10 @@ void intel_lvds_init(struct drm_device *
|
|
if (dmi_check_system(intel_no_lvds))
|
|
return;
|
|
|
|
- /* Assume that any device without an ACPI LID device also doesn't
|
|
- * have an integrated LVDS. We would be better off parsing the BIOS
|
|
- * to get a reliable indicator, but that code isn't written yet.
|
|
- *
|
|
- * In the case of all-in-one desktops using LVDS that we've seen,
|
|
- * they're using SDVO LVDS.
|
|
- */
|
|
- if (!intel_lid_present())
|
|
+ if (!lvds_is_present_in_vbt(dev)) {
|
|
+ DRM_DEBUG_KMS("LVDS is not present in VBT\n");
|
|
return;
|
|
+ }
|
|
|
|
if (IS_IGDNG(dev)) {
|
|
if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
|
|
From 944001201ca0196bcdb088129e5866a9f379d08c Mon Sep 17 00:00:00 2001
|
|
From: Dave Airlie <airlied@redhat.com>
|
|
Date: Tue, 20 Jul 2010 13:15:31 +1000
|
|
Subject: drm/i915: enable low power render writes on GEN3 hardware.
|
|
|
|
From: Dave Airlie <airlied@redhat.com>
|
|
|
|
commit 944001201ca0196bcdb088129e5866a9f379d08c upstream.
|
|
|
|
A lot of 945GMs have had stability issues for a long time, this manifested as X hangs, blitter engine hangs, and lots of crashes.
|
|
|
|
one such report is at:
|
|
https://bugs.freedesktop.org/show_bug.cgi?id=20560
|
|
|
|
along with numerous distro bugzillas.
|
|
|
|
This only took a week of digging and hair ripping to figure out.
|
|
|
|
Tracked down and tested on a 945GM Lenovo T60,
|
|
previously running
|
|
x11perf -copypixwin500
|
|
or
|
|
x11perf -copywinpix500
|
|
repeatedly would cause the GPU to wedge within 4 or 5 tries, with random busy bits set.
|
|
|
|
After this patch no hangs were observed.
|
|
|
|
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
|
|
|
---
|
|
drivers/gpu/drm/i915/i915_gem.c | 10 ++++++++++
|
|
1 file changed, 10 insertions(+)
|
|
|
|
--- a/drivers/gpu/drm/i915/i915_gem.c
|
|
+++ b/drivers/gpu/drm/i915/i915_gem.c
|
|
@@ -4697,6 +4697,16 @@ i915_gem_load(struct drm_device *dev)
|
|
list_add(&dev_priv->mm.shrink_list, &shrink_list);
|
|
spin_unlock(&shrink_list_lock);
|
|
|
|
+ /* On GEN3 we really need to make sure the ARB C3 LP bit is set */
|
|
+ if (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
|
|
+ u32 tmp = I915_READ(MI_ARB_STATE);
|
|
+ if (!(tmp & MI_ARB_C3_LP_WRITE_ENABLE)) {
|
|
+ /* arb state is a masked write, so set bit + bit in mask */
|
|
+ tmp = MI_ARB_C3_LP_WRITE_ENABLE | (MI_ARB_C3_LP_WRITE_ENABLE << MI_ARB_MASK_SHIFT);
|
|
+ I915_WRITE(MI_ARB_STATE, tmp);
|
|
+ }
|
|
+ }
|
|
+
|
|
/* Old X drivers will take 0-2 for front, back, depth buffers */
|
|
dev_priv->fence_reg_start = 3;
|
|
|
|
From 45503ded966c98e604c9667c0b458d40666b9ef3 Mon Sep 17 00:00:00 2001
|
|
From: Keith Packard <keithp@keithp.com>
|
|
Date: Mon, 19 Jul 2010 21:12:35 -0700
|
|
Subject: drm/i915: Define MI_ARB_STATE bits
|
|
|
|
From: Keith Packard <keithp@keithp.com>
|
|
|
|
commit 45503ded966c98e604c9667c0b458d40666b9ef3 upstream.
|
|
|
|
The i915 memory arbiter has a register full of configuration
|
|
bits which are currently not defined in the driver header file.
|
|
|
|
Signed-off-by: Keith Packard <keithp@keithp.com>
|
|
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
|
|
|
---
|
|
drivers/gpu/drm/i915/i915_reg.h | 64 ++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 64 insertions(+)
|
|
|
|
--- a/drivers/gpu/drm/i915/i915_reg.h
|
|
+++ b/drivers/gpu/drm/i915/i915_reg.h
|
|
@@ -307,6 +307,70 @@
|
|
#define LM_BURST_LENGTH 0x00000700
|
|
#define LM_FIFO_WATERMARK 0x0000001F
|
|
#define MI_ARB_STATE 0x020e4 /* 915+ only */
|
|
+#define MI_ARB_MASK_SHIFT 16 /* shift for enable bits */
|
|
+
|
|
+/* Make render/texture TLB fetches lower priorty than associated data
|
|
+ * fetches. This is not turned on by default
|
|
+ */
|
|
+#define MI_ARB_RENDER_TLB_LOW_PRIORITY (1 << 15)
|
|
+
|
|
+/* Isoch request wait on GTT enable (Display A/B/C streams).
|
|
+ * Make isoch requests stall on the TLB update. May cause
|
|
+ * display underruns (test mode only)
|
|
+ */
|
|
+#define MI_ARB_ISOCH_WAIT_GTT (1 << 14)
|
|
+
|
|
+/* Block grant count for isoch requests when block count is
|
|
+ * set to a finite value.
|
|
+ */
|
|
+#define MI_ARB_BLOCK_GRANT_MASK (3 << 12)
|
|
+#define MI_ARB_BLOCK_GRANT_8 (0 << 12) /* for 3 display planes */
|
|
+#define MI_ARB_BLOCK_GRANT_4 (1 << 12) /* for 2 display planes */
|
|
+#define MI_ARB_BLOCK_GRANT_2 (2 << 12) /* for 1 display plane */
|
|
+#define MI_ARB_BLOCK_GRANT_0 (3 << 12) /* don't use */
|
|
+
|
|
+/* Enable render writes to complete in C2/C3/C4 power states.
|
|
+ * If this isn't enabled, render writes are prevented in low
|
|
+ * power states. That seems bad to me.
|
|
+ */
|
|
+#define MI_ARB_C3_LP_WRITE_ENABLE (1 << 11)
|
|
+
|
|
+/* This acknowledges an async flip immediately instead
|
|
+ * of waiting for 2TLB fetches.
|
|
+ */
|
|
+#define MI_ARB_ASYNC_FLIP_ACK_IMMEDIATE (1 << 10)
|
|
+
|
|
+/* Enables non-sequential data reads through arbiter
|
|
+ */
|
|
+#define MI_ARB_DUAL_DATA_PHASE_DISABLE (1 << 9)
|
|
+
|
|
+/* Disable FSB snooping of cacheable write cycles from binner/render
|
|
+ * command stream
|
|
+ */
|
|
+#define MI_ARB_CACHE_SNOOP_DISABLE (1 << 8)
|
|
+
|
|
+/* Arbiter time slice for non-isoch streams */
|
|
+#define MI_ARB_TIME_SLICE_MASK (7 << 5)
|
|
+#define MI_ARB_TIME_SLICE_1 (0 << 5)
|
|
+#define MI_ARB_TIME_SLICE_2 (1 << 5)
|
|
+#define MI_ARB_TIME_SLICE_4 (2 << 5)
|
|
+#define MI_ARB_TIME_SLICE_6 (3 << 5)
|
|
+#define MI_ARB_TIME_SLICE_8 (4 << 5)
|
|
+#define MI_ARB_TIME_SLICE_10 (5 << 5)
|
|
+#define MI_ARB_TIME_SLICE_14 (6 << 5)
|
|
+#define MI_ARB_TIME_SLICE_16 (7 << 5)
|
|
+
|
|
+/* Low priority grace period page size */
|
|
+#define MI_ARB_LOW_PRIORITY_GRACE_4KB (0 << 4) /* default */
|
|
+#define MI_ARB_LOW_PRIORITY_GRACE_8KB (1 << 4)
|
|
+
|
|
+/* Disable display A/B trickle feed */
|
|
+#define MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE (1 << 2)
|
|
+
|
|
+/* Set display plane priority */
|
|
+#define MI_ARB_DISPLAY_PRIORITY_A_B (0 << 0) /* display A > display B */
|
|
+#define MI_ARB_DISPLAY_PRIORITY_B_A (1 << 0) /* display B > display A */
|
|
+
|
|
#define CACHE_MODE_0 0x02120 /* 915+ only */
|
|
#define CM0_MASK_SHIFT 16
|
|
#define CM0_IZ_OPT_DISABLE (1<<6)
|
|
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 |
|