summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Boyer <jwboyer@fedoraproject.org>2013-11-09 09:30:06 -0500
committerJosh Boyer <jwboyer@fedoraproject.org>2013-11-09 09:33:45 -0500
commite3ff8fb7104de151b4b090e094d547a579114550 (patch)
treecefd55ba8919b18d82af461357db91c70e5e97f3
parent0a346ea31151e4f114eb0cdb3aa25a55f300bae5 (diff)
downloadkernel-e3ff8fb7104de151b4b090e094d547a579114550.tar.gz
kernel-e3ff8fb7104de151b4b090e094d547a579114550.tar.xz
kernel-e3ff8fb7104de151b4b090e094d547a579114550.zip
Add qxl backport fixes from Dave Airlie
-rw-r--r--drm-qxl-backport-fixes-for-Fedora.patch226
-rw-r--r--kernel.spec7
2 files changed, 233 insertions, 0 deletions
diff --git a/drm-qxl-backport-fixes-for-Fedora.patch b/drm-qxl-backport-fixes-for-Fedora.patch
new file mode 100644
index 000000000..c46060d64
--- /dev/null
+++ b/drm-qxl-backport-fixes-for-Fedora.patch
@@ -0,0 +1,226 @@
+Bugzilla: N/A
+Upstream-status: Queued for 3.13
+
+From db8edc33193879f39c1b52521e20f4d6eb4e9858 Mon Sep 17 00:00:00 2001
+From: Dave Airlie <airlied@redhat.com>
+Date: Fri, 08 Nov 2013 06:36:45 +0000
+Subject: drm/qxl: backport fixes for Fedora
+
+This pulls these changes from drm-next back into Fedora.
+
+drm/qxl: prefer the monitor config resolution (b080742393e2c1)
+drm/qxl: remove unnecessary check (a40a60d912a101e8dfb08ee1)
+drm/qxl: fix disabling extra monitors from client (5cab51cb3381157)
+qxl: avoid an oops in the deferred io code. (cc87509d87696d7cd39)
+drm/qxl: support 64bit surface bar (35541782dcc1e502)
+qxl: add a connector property to denote hotplug should rescan modes. (4695b03970df37)
+
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+---
+diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
+index 835caba..1d975eb 100644
+--- a/drivers/gpu/drm/qxl/qxl_display.c
++++ b/drivers/gpu/drm/qxl/qxl_display.c
+@@ -110,7 +110,9 @@ void qxl_display_read_client_monitors_config(struct qxl_device *qdev)
+ drm_helper_hpd_irq_event(qdev->ddev);
+ }
+
+-static int qxl_add_monitors_config_modes(struct drm_connector *connector)
++static int qxl_add_monitors_config_modes(struct drm_connector *connector,
++ unsigned *pwidth,
++ unsigned *pheight)
+ {
+ struct drm_device *dev = connector->dev;
+ struct qxl_device *qdev = dev->dev_private;
+@@ -126,11 +128,15 @@ static int qxl_add_monitors_config_modes(struct drm_connector *connector)
+ mode = drm_cvt_mode(dev, head->width, head->height, 60, false, false,
+ false);
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
++ *pwidth = head->width;
++ *pheight = head->height;
+ drm_mode_probed_add(connector, mode);
+ return 1;
+ }
+
+-static int qxl_add_common_modes(struct drm_connector *connector)
++static int qxl_add_common_modes(struct drm_connector *connector,
++ unsigned pwidth,
++ unsigned pheight)
+ {
+ struct drm_device *dev = connector->dev;
+ struct drm_display_mode *mode = NULL;
+@@ -159,12 +165,9 @@ static int qxl_add_common_modes(struct drm_connector *connector)
+ };
+
+ for (i = 0; i < ARRAY_SIZE(common_modes); i++) {
+- if (common_modes[i].w < 320 || common_modes[i].h < 200)
+- continue;
+-
+ mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h,
+ 60, false, false, false);
+- if (common_modes[i].w == 1024 && common_modes[i].h == 768)
++ if (common_modes[i].w == pwidth && common_modes[i].h == pheight)
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+ drm_mode_probed_add(connector, mode);
+ }
+@@ -720,16 +723,18 @@ static int qxl_conn_get_modes(struct drm_connector *connector)
+ {
+ int ret = 0;
+ struct qxl_device *qdev = connector->dev->dev_private;
++ unsigned pwidth = 1024;
++ unsigned pheight = 768;
+
+ DRM_DEBUG_KMS("monitors_config=%p\n", qdev->monitors_config);
+ /* TODO: what should we do here? only show the configured modes for the
+ * device, or allow the full list, or both? */
+ if (qdev->monitors_config && qdev->monitors_config->count) {
+- ret = qxl_add_monitors_config_modes(connector);
++ ret = qxl_add_monitors_config_modes(connector, &pwidth, &pheight);
+ if (ret < 0)
+ return ret;
+ }
+- ret += qxl_add_common_modes(connector);
++ ret += qxl_add_common_modes(connector, pwidth, pheight);
+ return ret;
+ }
+
+@@ -793,7 +798,10 @@ static enum drm_connector_status qxl_conn_detect(
+ qdev->client_monitors_config->count > output->index &&
+ qxl_head_enabled(&qdev->client_monitors_config->heads[output->index]));
+
+- DRM_DEBUG("\n");
++ DRM_DEBUG("#%d connected: %d\n", output->index, connected);
++ if (!connected)
++ qxl_monitors_config_set(qdev, output->index, 0, 0, 0, 0, 0);
++
+ return connected ? connector_status_connected
+ : connector_status_disconnected;
+ }
+@@ -835,8 +843,21 @@ static const struct drm_encoder_funcs qxl_enc_funcs = {
+ .destroy = qxl_enc_destroy,
+ };
+
++static int qxl_mode_create_hotplug_mode_update_property(struct qxl_device *qdev)
++{
++ if (qdev->hotplug_mode_update_property)
++ return 0;
++
++ qdev->hotplug_mode_update_property =
++ drm_property_create_range(qdev->ddev, DRM_MODE_PROP_IMMUTABLE,
++ "hotplug_mode_update", 0, 1);
++
++ return 0;
++}
++
+ static int qdev_output_init(struct drm_device *dev, int num_output)
+ {
++ struct qxl_device *qdev = dev->dev_private;
+ struct qxl_output *qxl_output;
+ struct drm_connector *connector;
+ struct drm_encoder *encoder;
+@@ -863,6 +884,8 @@ static int qdev_output_init(struct drm_device *dev, int num_output)
+ drm_encoder_helper_add(encoder, &qxl_enc_helper_funcs);
+ drm_connector_helper_add(connector, &qxl_connector_helper_funcs);
+
++ drm_object_attach_property(&connector->base,
++ qdev->hotplug_mode_update_property, 0);
+ drm_sysfs_connector_add(connector);
+ return 0;
+ }
+@@ -975,6 +998,9 @@ int qxl_modeset_init(struct qxl_device *qdev)
+ qdev->ddev->mode_config.max_height = 8192;
+
+ qdev->ddev->mode_config.fb_base = qdev->vram_base;
++
++ qxl_mode_create_hotplug_mode_update_property(qdev);
++
+ for (i = 0 ; i < qxl_num_crtc; ++i) {
+ qdev_crtc_init(qdev->ddev, i);
+ qdev_output_init(qdev->ddev, i);
+diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
+index 7e96f4f..18c599d 100644
+--- a/drivers/gpu/drm/qxl/qxl_drv.h
++++ b/drivers/gpu/drm/qxl/qxl_drv.h
+@@ -323,6 +323,8 @@ struct qxl_device {
+ struct work_struct gc_work;
+
+ struct work_struct fb_work;
++
++ struct drm_property *hotplug_mode_update_property;
+ };
+
+ /* forward declaration for QXL_INFO_IO */
+diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c
+index 88722f2..f437b30 100644
+--- a/drivers/gpu/drm/qxl/qxl_fb.c
++++ b/drivers/gpu/drm/qxl/qxl_fb.c
+@@ -108,7 +108,7 @@ static void qxl_fb_dirty_flush(struct fb_info *info)
+ u32 x1, x2, y1, y2;
+
+ /* TODO: hard coding 32 bpp */
+- int stride = qfbdev->qfb.base.pitches[0] * 4;
++ int stride = qfbdev->qfb.base.pitches[0];
+
+ x1 = qfbdev->dirty.x1;
+ x2 = qfbdev->dirty.x2;
+diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c
+index 9e8da9e..e0ddd5b 100644
+--- a/drivers/gpu/drm/qxl/qxl_kms.c
++++ b/drivers/gpu/drm/qxl/qxl_kms.c
+@@ -120,7 +120,7 @@ int qxl_device_init(struct qxl_device *qdev,
+ struct pci_dev *pdev,
+ unsigned long flags)
+ {
+- int r;
++ int r, sb;
+
+ qdev->dev = &pdev->dev;
+ qdev->ddev = ddev;
+@@ -136,21 +136,39 @@ int qxl_device_init(struct qxl_device *qdev,
+ qdev->rom_base = pci_resource_start(pdev, 2);
+ qdev->rom_size = pci_resource_len(pdev, 2);
+ qdev->vram_base = pci_resource_start(pdev, 0);
+- qdev->surfaceram_base = pci_resource_start(pdev, 1);
+- qdev->surfaceram_size = pci_resource_len(pdev, 1);
+ qdev->io_base = pci_resource_start(pdev, 3);
+
+ qdev->vram_mapping = io_mapping_create_wc(qdev->vram_base, pci_resource_len(pdev, 0));
+- qdev->surface_mapping = io_mapping_create_wc(qdev->surfaceram_base, qdev->surfaceram_size);
+- DRM_DEBUG_KMS("qxl: vram %llx-%llx(%dM %dk), surface %llx-%llx(%dM %dk)\n",
++
++ if (pci_resource_len(pdev, 4) > 0) {
++ /* 64bit surface bar present */
++ sb = 4;
++ qdev->surfaceram_base = pci_resource_start(pdev, sb);
++ qdev->surfaceram_size = pci_resource_len(pdev, sb);
++ qdev->surface_mapping =
++ io_mapping_create_wc(qdev->surfaceram_base,
++ qdev->surfaceram_size);
++ }
++ if (qdev->surface_mapping == NULL) {
++ /* 64bit surface bar not present (or mapping failed) */
++ sb = 1;
++ qdev->surfaceram_base = pci_resource_start(pdev, sb);
++ qdev->surfaceram_size = pci_resource_len(pdev, sb);
++ qdev->surface_mapping =
++ io_mapping_create_wc(qdev->surfaceram_base,
++ qdev->surfaceram_size);
++ }
++
++ DRM_DEBUG_KMS("qxl: vram %llx-%llx(%dM %dk), surface %llx-%llx(%dM %dk, %s)\n",
+ (unsigned long long)qdev->vram_base,
+ (unsigned long long)pci_resource_end(pdev, 0),
+ (int)pci_resource_len(pdev, 0) / 1024 / 1024,
+ (int)pci_resource_len(pdev, 0) / 1024,
+ (unsigned long long)qdev->surfaceram_base,
+- (unsigned long long)pci_resource_end(pdev, 1),
++ (unsigned long long)pci_resource_end(pdev, sb),
+ (int)qdev->surfaceram_size / 1024 / 1024,
+- (int)qdev->surfaceram_size / 1024);
++ (int)qdev->surfaceram_size / 1024,
++ (sb == 4) ? "64bit" : "32bit");
+
+ qdev->rom = ioremap(qdev->rom_base, qdev->rom_size);
+ if (!qdev->rom) {
+--
+cgit v0.9.0.2-2-gbebe
diff --git a/kernel.spec b/kernel.spec
index 75645c0ec..1ae399616 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -738,6 +738,8 @@ Patch25132: rt2800usb-slow-down-TX-status-polling.patch
#CVE-2013-4348 rhbz 1007939 1025647
Patch25139: net-flow_dissector-fail-on-evil-iph-ihl.patch
+Patch25140: drm-qxl-backport-fixes-for-Fedora.patch
+
# END OF PATCH DEFINITIONS
%endif
@@ -1444,6 +1446,8 @@ ApplyPatch rt2800usb-slow-down-TX-status-polling.patch
#CVE-2013-4348 rhbz 1007939 1025647
ApplyPatch net-flow_dissector-fail-on-evil-iph-ihl.patch
+ApplyPatch drm-qxl-backport-fixes-for-Fedora.patch
+
# END OF PATCH APPLICATIONS
%endif
@@ -2247,6 +2251,9 @@ fi
# ||----w |
# || ||
%changelog
+* Sat Nov 09 2013 Josh Boyer <jwboyer@fedoraproject.org>
+- Add qxl backport fixes from Dave Airlie
+
* Tue Nov 05 2013 Kyle McMartin <kyle@fedoraproject.org>
- Enable crash on {arm,aarch64,ppc64,s390x}