Просмотр исходного кода

Merge tag 'topic/drm-misc-2016-09-08' of git://anongit.freedesktop.org/drm-intel into drm-next

* tag 'topic/drm-misc-2016-09-08' of git://anongit.freedesktop.org/drm-intel:
  drm: Fix error path in drm_mode_page_flip_ioctl()
  Revert "drm: Unify handling of blob and object properties"
  drm/udl: implement usb_driver suspend/resume.
  drm: fix signed integer overflow
  drm/atomic: Reject properties not part of the object.
  drm/doc: Add a few words on validation with IGT
Dave Airlie 9 лет назад
Родитель
Сommit
1f8ee720ce

+ 37 - 0
Documentation/gpu/drm-uapi.rst

@@ -156,6 +156,43 @@ other hand, a driver requires shared state between clients which is
 visible to user-space and accessible beyond open-file boundaries, they
 cannot support render nodes.
 
+Validating changes with IGT
+===========================
+
+There's a collection of tests that aims to cover the whole functionality of
+DRM drivers and that can be used to check that changes to DRM drivers or the
+core don't regress existing functionality. This test suite is called IGT and
+its code can be found in https://cgit.freedesktop.org/drm/igt-gpu-tools/.
+
+To build IGT, start by installing its build dependencies. In Debian-based
+systems::
+
+	# apt-get build-dep intel-gpu-tools
+
+And in Fedora-based systems::
+
+	# dnf builddep intel-gpu-tools
+
+Then clone the repository::
+
+	$ git clone git://anongit.freedesktop.org/drm/igt-gpu-tools
+
+Configure the build system and start the build::
+
+	$ cd igt-gpu-tools && ./autogen.sh && make -j6
+
+Download the piglit dependency::
+
+	$ ./scripts/run-tests.sh -d
+
+And run the tests::
+
+	$ ./scripts/run-tests.sh -t kms -t core -s
+
+run-tests.sh is a wrapper around piglit that will execute the tests matching
+the -t options. A report in HTML format will be available in
+./results/html/index.html. Results can be compared with piglit.
+
 VBlank event handling
 =====================
 

+ 10 - 1
drivers/gpu/drm/drm_atomic.c

@@ -1609,7 +1609,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
 	struct drm_crtc_state *crtc_state;
 	unsigned plane_mask;
 	int ret = 0;
-	unsigned int i, j;
+	unsigned int i, j, k;
 
 	/* disallow for drivers not supporting atomic: */
 	if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
@@ -1691,6 +1691,15 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
 				goto out;
 			}
 
+			for (k = 0; k < obj->properties->count; k++)
+				if (obj->properties->properties[k]->base.id == prop_id)
+					break;
+
+			if (k == obj->properties->count) {
+				ret = -EINVAL;
+				goto out;
+			}
+
 			prop = drm_property_find(dev, prop_id);
 			if (!prop) {
 				drm_mode_object_unreference(obj);

+ 1 - 1
drivers/gpu/drm/drm_crtc.c

@@ -2044,7 +2044,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
 	}
 
 out:
-	if (ret)
+	if (ret && crtc->funcs->page_flip_target)
 		drm_crtc_vblank_put(crtc);
 	if (fb)
 		drm_framebuffer_unreference(fb);

+ 1 - 1
drivers/gpu/drm/drm_hashtab.c

@@ -142,7 +142,7 @@ int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *it
 			      unsigned long add)
 {
 	int ret;
-	unsigned long mask = (1 << bits) - 1;
+	unsigned long mask = (1UL << bits) - 1;
 	unsigned long first, unshifted_key;
 
 	unshifted_key = hash_long(seed, bits);

+ 18 - 5
drivers/gpu/drm/drm_property.c

@@ -870,8 +870,20 @@ bool drm_property_change_valid_get(struct drm_property *property,
 		for (i = 0; i < property->num_values; i++)
 			valid_mask |= (1ULL << property->values[i]);
 		return !(value & ~valid_mask);
-	} else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB) ||
-		   drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
+	} else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
+		struct drm_property_blob *blob;
+
+		if (value == 0)
+			return true;
+
+		blob = drm_property_lookup_blob(property->dev, value);
+		if (blob) {
+			*ref = &blob->base;
+			return true;
+		} else {
+			return false;
+		}
+	} else if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
 		/* a zero value for an object property translates to null: */
 		if (value == 0)
 			return true;
@@ -888,12 +900,13 @@ bool drm_property_change_valid_get(struct drm_property *property,
 }
 
 void drm_property_change_valid_put(struct drm_property *property,
-				   struct drm_mode_object *ref)
+		struct drm_mode_object *ref)
 {
 	if (!ref)
 		return;
 
-	if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT) ||
-	    drm_property_type_is(property, DRM_MODE_PROP_BLOB))
+	if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
 		drm_mode_object_unreference(ref);
+	} else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB))
+		drm_property_unreference_blob(obj_to_blob(ref));
 }

+ 16 - 0
drivers/gpu/drm/udl/udl_drv.c

@@ -16,6 +16,20 @@ static int udl_driver_set_busid(struct drm_device *d, struct drm_master *m)
 	return 0;
 }
 
+static int udl_usb_suspend(struct usb_interface *interface,
+			   pm_message_t message)
+{
+	return 0;
+}
+
+static int udl_usb_resume(struct usb_interface *interface)
+{
+	struct drm_device *dev = usb_get_intfdata(interface);
+
+	udl_modeset_restore(dev);
+	return 0;
+}
+
 static const struct vm_operations_struct udl_gem_vm_ops = {
 	.fault = udl_gem_fault,
 	.open = drm_gem_vm_open,
@@ -122,6 +136,8 @@ static struct usb_driver udl_driver = {
 	.name = "udl",
 	.probe = udl_usb_probe,
 	.disconnect = udl_usb_disconnect,
+	.suspend = udl_usb_suspend,
+	.resume = udl_usb_resume,
 	.id_table = id_table,
 };
 module_usb_driver(udl_driver);

+ 2 - 0
drivers/gpu/drm/udl/udl_drv.h

@@ -52,6 +52,7 @@ struct udl_device {
 	struct device *dev;
 	struct drm_device *ddev;
 	struct usb_device *udev;
+	struct drm_crtc *crtc;
 
 	int sku_pixel_limit;
 
@@ -87,6 +88,7 @@ struct udl_framebuffer {
 
 /* modeset */
 int udl_modeset_init(struct drm_device *dev);
+void udl_modeset_restore(struct drm_device *dev);
 void udl_modeset_cleanup(struct drm_device *dev);
 int udl_connector_init(struct drm_device *dev, struct drm_encoder *encoder);
 

+ 14 - 0
drivers/gpu/drm/udl/udl_modeset.c

@@ -309,6 +309,8 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc,
 	char *wrptr;
 	int color_depth = 0;
 
+	udl->crtc = crtc;
+
 	buf = (char *)udl->mode_buf;
 
 	/* for now we just clip 24 -> 16 - if we fix that fix this */
@@ -450,6 +452,18 @@ int udl_modeset_init(struct drm_device *dev)
 	return 0;
 }
 
+void udl_modeset_restore(struct drm_device *dev)
+{
+	struct udl_device *udl = dev->dev_private;
+	struct udl_framebuffer *ufb;
+
+	if (!udl->crtc || !udl->crtc->primary->fb)
+		return;
+	udl_crtc_commit(udl->crtc);
+	ufb = to_udl_fb(udl->crtc->primary->fb);
+	udl_handle_damage(ufb, 0, 0, ufb->base.width, ufb->base.height);
+}
+
 void udl_modeset_cleanup(struct drm_device *dev)
 {
 	drm_mode_config_cleanup(dev);