static int set_property_legacy(struct drm_mode_object *obj,
			       struct drm_property *prop,
			       uint64_t prop_value)
{
	struct drm_device *dev = prop->dev;
	struct drm_mode_object *ref;
	int ret = -EINVAL;

	if (!drm_property_change_valid_get(prop, prop_value, &ref))
		return -EINVAL;

	drm_modeset_lock_all(dev);
	switch (obj->type) {
	case DRM_MODE_OBJECT_CONNECTOR:
		ret = drm_mode_connector_set_obj_prop(obj, prop,
						      prop_value);
		break;
	case DRM_MODE_OBJECT_CRTC:
		ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value);
		break;
	case DRM_MODE_OBJECT_PLANE:
		ret = drm_mode_plane_set_obj_prop(obj_to_plane(obj),
						  prop, prop_value);
		break;
	}
	drm_property_change_valid_put(prop, ref);
	drm_modeset_unlock_all(dev);

	return ret;
}
/**
 * drm_mode_obj_get_properties_ioctl - get the current value of a object's property
 * @dev: DRM device
 * @data: ioctl data
 * @file_priv: DRM file info
 *
 * This function retrieves the current value for an object's property. Compared
 * to the connector specific ioctl this one is extended to also work on crtc and
 * plane objects.
 *
 * Called by the user via ioctl.
 *
 * Returns:
 * Zero on success, negative errno on failure.
 */
int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
				      struct drm_file *file_priv)
{
	struct drm_mode_obj_get_properties *arg = data;
	struct drm_mode_object *obj;
	int ret = 0;

	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return -EINVAL;

	drm_modeset_lock_all(dev);

	obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
	if (!obj) {
		ret = -ENOENT;
		goto out;
	}
	if (!obj->properties) {
		ret = -EINVAL;
		goto out_unref;
	}

	ret = drm_mode_object_get_properties(obj, file_priv->atomic,
			(uint32_t __user *)(unsigned long)(arg->props_ptr),
			(uint64_t __user *)(unsigned long)(arg->prop_values_ptr),
			&arg->count_props);

out_unref:
	drm_mode_object_put(obj);
out:
	drm_modeset_unlock_all(dev);
	return ret;
}
Exemple #3
0
int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
			      struct drm_file *file_priv)
{
	struct drm_intel_sprite_colorkey *set = data;
	struct drm_mode_object *obj;
	struct drm_plane *plane;
	struct intel_plane *intel_plane;
	int ret = 0;

	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return -ENODEV;

	/* Make sure we don't try to enable both src & dest simultaneously */
	if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
		return -EINVAL;

	drm_modeset_lock_all(dev);

	obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
	if (!obj) {
		ret = -EINVAL;
		goto out_unlock;
	}

	plane = obj_to_plane(obj);
	intel_plane = to_intel_plane(plane);
	ret = intel_plane->update_colorkey(plane, set);

out_unlock:
	drm_modeset_unlock_all(dev);
	return ret;
}
Exemple #4
0
void
radeondrm_doswitch(void *v)
{
	struct rasops_info *ri = v;
	struct radeon_device *rdev = ri->ri_hw;
	struct radeon_crtc *radeon_crtc;
	int i, crtc;

	rasops_show_screen(ri, rdev->switchcookie, 0, NULL, NULL);
	for (crtc = 0; crtc < rdev->num_crtc; crtc++) {
		for (i = 0; i < 256; i++) {
			radeon_crtc = rdev->mode_info.crtcs[crtc];
			radeon_crtc->lut_r[i] = rasops_cmap[3 * i] << 2;
			radeon_crtc->lut_g[i] = rasops_cmap[(3 * i) + 1] << 2;
			radeon_crtc->lut_b[i] = rasops_cmap[(3 * i) + 2] << 2;
		}
	}
#ifdef __sparc64__
	fbwscons_setcolormap(&rdev->sf, radeondrm_setcolor);
#endif
	drm_modeset_lock_all(rdev->ddev);
	drm_fb_helper_restore_fbdev_mode((void *)rdev->mode_info.rfbdev);
	drm_modeset_unlock_all(rdev->ddev);

	if (rdev->switchcb)
		(rdev->switchcb)(rdev->switchcbarg, 0, 0);
}
Exemple #5
0
int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
			      struct drm_file *file_priv)
{
	struct drm_intel_sprite_colorkey *get = data;
	struct drm_mode_object *obj;
	struct drm_plane *plane;
	struct intel_plane *intel_plane;
	int ret = 0;

	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return -ENODEV;

	drm_modeset_lock_all(dev);

	obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
	if (!obj) {
		ret = -EINVAL;
		goto out_unlock;
	}

	plane = obj_to_plane(obj);
	intel_plane = to_intel_plane(plane);
	intel_plane->get_colorkey(plane, get);

out_unlock:
	drm_modeset_unlock_all(dev);
	return ret;
}
Exemple #6
0
static int
drmfb_genfb_ioctl(void *v, void *vs, unsigned long cmd, void *data, int flag,
    struct lwp *l)
{
	struct genfb_softc *const genfb = v;
	struct drmfb_softc *const sc = container_of(genfb, struct drmfb_softc,
	    sc_genfb);
	int error;

	if (sc->sc_da.da_params->dp_ioctl) {
		error = (*sc->sc_da.da_params->dp_ioctl)(sc, cmd, data, flag,
		    l);
		if (error != EPASSTHROUGH)
			return error;
	}

	switch (cmd) {
	/*
	 * Screen blanking ioctls.  Not to be confused with backlight
	 * (can be disabled while stuff is still drawn on the screen),
	 * brightness, or contrast (which we don't support).  Backlight
	 * and brightness are done through WSDISPLAYIO_{GET,SET}PARAM.
	 * This toggles between DPMS ON and DPMS OFF; backlight toggles
	 * between DPMS ON and DPMS SUSPEND.
	 */
	case WSDISPLAYIO_GVIDEO: {
		int *onp = (int *)data;

		/* XXX Can't really determine a single answer here.  */
		*onp = 1;
		return 0;
	}
	case WSDISPLAYIO_SVIDEO: {
		const int on = *(const int *)data;
		const int dpms_mode = on? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF;
		struct drm_fb_helper *const fb_helper = sc->sc_da.da_fb_helper;
		struct drm_device *const dev = fb_helper->dev;
		unsigned i;

		drm_modeset_lock_all(dev);
		for (i = 0; i < fb_helper->connector_count; i++) {
			struct drm_connector *const connector =
			    fb_helper->connector_info[i]->connector;
			(*connector->funcs->dpms)(connector, dpms_mode);
			drm_object_property_set_value(&connector->base,
			    dev->mode_config.dpms_property, dpms_mode);
		}
		drm_modeset_unlock_all(dev);

		return 0;
	}
	default:
		return EPASSTHROUGH;
	}
}
Exemple #7
0
static void intel_dp_register_mst_connector(struct drm_connector *connector)
{
	struct intel_connector *intel_connector = to_intel_connector(connector);
	struct drm_device *dev = connector->dev;

	drm_modeset_lock_all(dev);
	intel_connector_add_to_fbdev(intel_connector);
	drm_modeset_unlock_all(dev);

	drm_connector_register(&intel_connector->base);
}
static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
{
	struct drm_device *dev = dev_priv->dev;
	struct intel_encoder *encoder;

	drm_modeset_lock_all(dev);
	for_each_intel_encoder(dev, encoder)
		if (encoder->suspend)
			encoder->suspend(encoder);
	drm_modeset_unlock_all(dev);
}
Exemple #9
0
static int shmob_drm_pm_resume(struct device *dev)
{
	struct shmob_drm_device *sdev = dev_get_drvdata(dev);

	drm_modeset_lock_all(sdev->ddev);
	shmob_drm_crtc_resume(&sdev->crtc);
	drm_modeset_unlock_all(sdev->ddev);

	drm_kms_helper_poll_enable(sdev->ddev);
	return 0;
}
Exemple #10
0
static int omap_drm_resume(struct device *dev)
{
	struct drm_device *drm_dev = dev_get_drvdata(dev);

	drm_modeset_lock_all(drm_dev);
	omap_drm_resume_all_displays();
	drm_modeset_unlock_all(drm_dev);

	drm_kms_helper_poll_enable(drm_dev);

	return omap_gem_resume(drm_dev);
}
Exemple #11
0
static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv,
				     enum pipe pipe,
				     enum intel_pipe_crc_source *source)
{
	struct drm_device *dev = &dev_priv->drm;
	struct intel_encoder *encoder;
	struct intel_crtc *crtc;
	struct intel_digital_port *dig_port;
	int ret = 0;

	*source = INTEL_PIPE_CRC_SOURCE_PIPE;

	drm_modeset_lock_all(dev);
	for_each_intel_encoder(dev, encoder) {
		if (!encoder->base.crtc)
			continue;

		crtc = to_intel_crtc(encoder->base.crtc);

		if (crtc->pipe != pipe)
			continue;

		switch (encoder->type) {
		case INTEL_OUTPUT_TVOUT:
			*source = INTEL_PIPE_CRC_SOURCE_TV;
			break;
		case INTEL_OUTPUT_DP:
		case INTEL_OUTPUT_EDP:
			dig_port = enc_to_dig_port(&encoder->base);
			switch (dig_port->port) {
			case PORT_B:
				*source = INTEL_PIPE_CRC_SOURCE_DP_B;
				break;
			case PORT_C:
				*source = INTEL_PIPE_CRC_SOURCE_DP_C;
				break;
			case PORT_D:
				*source = INTEL_PIPE_CRC_SOURCE_DP_D;
				break;
			default:
				WARN(1, "nonexisting DP port %c\n",
				     port_name(dig_port->port));
				break;
			}
			break;
		default:
			break;
		}
	}
	drm_modeset_unlock_all(dev);

	return ret;
}
Exemple #12
0
static int omap_drm_suspend(struct device *dev)
{
	struct drm_device *drm_dev = dev_get_drvdata(dev);

	drm_kms_helper_poll_disable(drm_dev);

	drm_modeset_lock_all(drm_dev);
	omap_drm_suspend_all_displays();
	drm_modeset_unlock_all(drm_dev);

	return 0;
}
Exemple #13
0
int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
				    struct drm_file *file_priv)
{
	struct drm_mode_obj_set_property *arg = data;
	struct drm_mode_object *arg_obj;
	struct drm_property *property;
	int ret = -EINVAL;
	struct drm_mode_object *ref;

	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return -EINVAL;

	drm_modeset_lock_all(dev);

	arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
	if (!arg_obj) {
		ret = -ENOENT;
		goto out;
	}

	if (!arg_obj->properties)
		goto out_unref;

	property = drm_mode_obj_find_prop_id(arg_obj, arg->prop_id);
	if (!property)
		goto out_unref;

	if (!drm_property_change_valid_get(property, arg->value, &ref))
		goto out_unref;

	switch (arg_obj->type) {
	case DRM_MODE_OBJECT_CONNECTOR:
		ret = drm_mode_connector_set_obj_prop(arg_obj, property,
						      arg->value);
		break;
	case DRM_MODE_OBJECT_CRTC:
		ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
		break;
	case DRM_MODE_OBJECT_PLANE:
		ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj),
						  property, arg->value);
		break;
	}

	drm_property_change_valid_put(property, ref);

out_unref:
	drm_mode_object_unreference(arg_obj);
out:
	drm_modeset_unlock_all(dev);
	return ret;
}
Exemple #14
0
/**
 * radeon_driver_firstopen_kms - drm callback for last close
 *
 * @dev: drm dev pointer
 *
 * Switch vga switcheroo state after last close (all asics).
 */
void radeon_driver_lastclose_kms(struct drm_device *dev)
{
	struct radeon_device *rdev = dev->dev_private;

#ifdef __sparc64__
	fbwscons_setcolormap(&rdev->sf, radeondrm_setcolor);
#endif
	drm_modeset_lock_all(dev);
	drm_fb_helper_restore_fbdev_mode((void *)rdev->mode_info.rfbdev);
	drm_modeset_unlock_all(dev);
#ifdef notyet
	vga_switcheroo_process_delayed_switch();
#endif
}
static int evdi_user_framebuffer_dirty(struct drm_framebuffer *fb,
				       __always_unused struct drm_file *file,
				       __always_unused unsigned int flags,
				       __always_unused unsigned int color,
				       struct drm_clip_rect *clips,
				       unsigned int num_clips)
{
	struct evdi_framebuffer *ufb = to_evdi_fb(fb);
	struct drm_device *dev = ufb->base.dev;
	struct evdi_device *evdi = dev->dev_private;
	int i;
	int ret = 0;

	EVDI_CHECKPT();
	drm_modeset_lock_all(fb->dev);

	if (!ufb->active)
		goto unlock;

	if (ufb->obj->base.import_attach) {
		ret =
			dma_buf_begin_cpu_access(
					ufb->obj->base.import_attach->dmabuf,
#if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE
					0, ufb->obj->base.size,
#endif
					DMA_FROM_DEVICE);
		if (ret)
			goto unlock;
	}

	for (i = 0; i < num_clips; i++) {
		ret = evdi_handle_damage(ufb, clips[i].x1, clips[i].y1,
					 clips[i].x2 - clips[i].x1,
					 clips[i].y2 - clips[i].y1);
		if (ret)
			goto unlock;
	}

	if (ufb->obj->base.import_attach)
		dma_buf_end_cpu_access(ufb->obj->base.import_attach->dmabuf,
#if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE
				       0, ufb->obj->base.size,
#endif
				       DMA_FROM_DEVICE);
	atomic_add(1, &evdi->frame_count);
 unlock:
	drm_modeset_unlock_all(fb->dev);
	return ret;
}
static int atmel_hlcdc_dc_drm_resume(struct device *dev)
{
	struct drm_device *drm_dev = dev_get_drvdata(dev);
	struct drm_crtc *crtc;

	if (pm_runtime_suspended(dev))
		return 0;

	drm_modeset_lock_all(drm_dev);
	list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head)
		atmel_hlcdc_crtc_resume(crtc);
	drm_modeset_unlock_all(drm_dev);
	return 0;
}
Exemple #17
0
static int i915_drm_freeze(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_crtc *crtc;

	intel_runtime_pm_get(dev_priv);

	/* ignore lid events during suspend */
	mutex_lock(&dev_priv->modeset_restore_lock);
	dev_priv->modeset_restore = MODESET_SUSPENDED;
	mutex_unlock(&dev_priv->modeset_restore_lock);

	/* We do a lot of poking in a lot of registers, make sure they work
	 * properly. */
	intel_display_set_init_power(dev_priv, true);

	drm_kms_helper_poll_disable(dev);

	pci_save_state(dev->pdev);

	/* If KMS is active, we do the leavevt stuff here */
	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
		int error;

		error = i915_gem_suspend(dev);
		if (error) {
			dev_err(&dev->pdev->dev,
				"GEM idle failed, resume might fail\n");
			return error;
		}

		intel_disable_gt_powersave(dev);

		/*
		 * Disable CRTCs directly since we want to preserve sw state
		 * for _thaw.
		 */
		drm_modeset_lock_all(dev);
		for_each_crtc(dev, crtc) {
			dev_priv->display.crtc_disable(crtc);
		}
		drm_modeset_unlock_all(dev);

		intel_dp_mst_suspend(dev);
		drm_irq_uninstall(dev);

		intel_modeset_suspend_hw(dev);
	}
static int ast_drm_thaw(struct drm_device *dev)
{
	int error = 0;

	ast_post_gpu(dev);

	drm_mode_config_reset(dev);
	drm_modeset_lock_all(dev);
	drm_helper_resume_force_mode(dev);
	drm_modeset_unlock_all(dev);

	console_lock();
	ast_fbdev_set_suspend(dev, 0);
	console_unlock();
	return error;
}
void intel_fbdev_restore_mode(struct drm_device *dev)
{
	int ret;
	struct drm_i915_private *dev_priv = dev->dev_private;

	if (INTEL_INFO(dev)->num_pipes == 0)
		return;

	drm_modeset_lock_all(dev);

	ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
	if (ret)
		DRM_DEBUG("failed to restore crtc mode\n");

	drm_modeset_unlock_all(dev);
}
Exemple #20
0
/**
 * drm_crtc_force_disable_all - Forcibly turn off all enabled CRTCs
 * @dev: DRM device whose CRTCs to turn off
 *
 * Drivers may want to call this on unload to ensure that all displays are
 * unlit and the GPU is in a consistent, low power state. Takes modeset locks.
 *
 * Note: This should only be used by non-atomic legacy drivers. For an atomic
 * version look at drm_atomic_helper_shutdown().
 *
 * Returns:
 * Zero on success, error code on failure.
 */
int drm_crtc_force_disable_all(struct drm_device *dev)
{
	struct drm_crtc *crtc;
	int ret = 0;

	drm_modeset_lock_all(dev);
	drm_for_each_crtc(crtc, dev)
		if (crtc->enabled) {
			ret = drm_crtc_force_disable(crtc);
			if (ret)
				goto out;
		}
out:
	drm_modeset_unlock_all(dev);
	return ret;
}
Exemple #21
0
static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
					   struct drm_connector *connector)
{
	struct intel_connector *intel_connector = to_intel_connector(connector);
	struct drm_device *dev = connector->dev;

	drm_connector_unregister(connector);

	/* need to nuke the connector */
	drm_modeset_lock_all(dev);
	intel_connector_remove_from_fbdev(intel_connector);
	intel_connector->mst_port = NULL;
	drm_modeset_unlock_all(dev);

	drm_connector_unreference(&intel_connector->base);
	DRM_DEBUG_KMS("\n");
}
Exemple #22
0
static int evdi_user_framebuffer_dirty(struct drm_framebuffer *fb,
                                       struct drm_file *file,
                                       unsigned flags,
                                       unsigned color,
                                       struct drm_clip_rect *clips,
                                       unsigned num_clips)
{
  struct evdi_framebuffer *ufb = to_evdi_fb(fb);
  struct drm_device *dev = ufb->base.dev;
  struct evdi_device *evdi = dev->dev_private;
  int i;
  int ret = 0;

  EVDI_CHECKPT();
  drm_modeset_lock_all(fb->dev);

  if (ufb->obj->base.import_attach) {
    ret = dma_buf_begin_cpu_access(ufb->obj->base.import_attach->dmabuf,
                                   0, ufb->obj->base.size,
                                   DMA_FROM_DEVICE);
    if (ret) {
      goto unlock;
    }
  }

  for (i = 0; i < num_clips; i++) {
    ret = evdi_handle_damage(ufb, clips[i].x1, clips[i].y1,
                             clips[i].x2 - clips[i].x1,
                             clips[i].y2 - clips[i].y1);
    if (ret) {
      goto unlock;
    }
  }

  if (ufb->obj->base.import_attach) {
    dma_buf_end_cpu_access(ufb->obj->base.import_attach->dmabuf,
                           0,
                           ufb->obj->base.size,
                           DMA_FROM_DEVICE);
  }
  atomic_add(1, &evdi->frame_count);
unlock:
  drm_modeset_unlock_all(fb->dev);
  return ret;
}
Exemple #23
0
/**
 * drm_encoder_cleanup - cleans up an initialised encoder
 * @encoder: encoder to cleanup
 *
 * Cleans up the encoder but doesn't free the object.
 */
void drm_encoder_cleanup(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;

	/* Note that the encoder_list is considered to be static; should we
	 * remove the drm_encoder at runtime we would have to decrement all
	 * the indices on the drm_encoder after us in the encoder_list.
	 */

	drm_modeset_lock_all(dev);
	drm_mode_object_unregister(dev, &encoder->base);
	kfree(encoder->name);
	list_del(&encoder->head);
	dev->mode_config.num_encoder--;
	drm_modeset_unlock_all(dev);

	memset(encoder, 0, sizeof(*encoder));
}
static int omap_framebuffer_dirty(struct drm_framebuffer *fb,
		struct drm_file *file_priv, unsigned flags, unsigned color,
		struct drm_clip_rect *clips, unsigned num_clips)
{
	int i;

	drm_modeset_lock_all(fb->dev);

	for (i = 0; i < num_clips; i++) {
		omap_framebuffer_flush(fb, clips[i].x1, clips[i].y1,
					clips[i].x2 - clips[i].x1,
					clips[i].y2 - clips[i].y1);
	}

	drm_modeset_unlock_all(fb->dev);

	return 0;
}
/**
 * lastclose - clean up after all DRM clients have exited
 * @dev: DRM device
 *
 * Take care of cleaning up after all DRM clients have exited.  In the
 * mode setting case, we want to restore the kernel's initial mode (just
 * in case the last client left us in a bad state).
 */
static void dev_lastclose(struct drm_device *dev)
{
	int i;

	/* we don't support vga-switcheroo.. so just make sure the fbdev
	 * mode is active
	 */
	struct omap_drm_private *priv = dev->dev_private;
	int ret;

	DBG("lastclose: dev=%p", dev);

	if (priv->rotation_prop) {
		/* need to restore default rotation state.. not sure
		 * if there is a cleaner way to restore properties to
		 * default state?  Maybe a flag that properties should
		 * automatically be restored to default state on
		 * lastclose?
		 */
		for (i = 0; i < priv->num_crtcs; i++) {
			drm_object_property_set_value(&priv->crtcs[i]->base,
					priv->rotation_prop, 0);
		}

		for (i = 0; i < priv->num_planes; i++) {
			drm_object_property_set_value(&priv->planes[i]->base,
					priv->rotation_prop, 0);
		}
	}

	if (priv->fbdev) {
		drm_modeset_lock_all(dev);
		ret = drm_fb_helper_restore_fbdev_mode(priv->fbdev);
		drm_modeset_unlock_all(dev);
		if (ret)
			DBG("failed to restore crtc mode");
		/*
		 * Flush crtcs to finish any pending work.
		 * This makes sure the fbdev mode has been restored.
		 */
		for (i = 0; i < priv->num_crtcs; i++)
			omap_crtc_flush(priv->crtcs[i]);
	}
}
Exemple #26
0
/**
 * drm_encoder_init - Init a preallocated encoder
 * @dev: drm device
 * @encoder: the encoder to init
 * @funcs: callbacks for this encoder
 * @encoder_type: user visible type of the encoder
 * @name: printf style format string for the encoder name, or NULL for default name
 *
 * Initialises a preallocated encoder. Encoder should be subclassed as part of
 * driver encoder objects. At driver unload time drm_encoder_cleanup() should be
 * called from the driver's destroy hook in &drm_encoder_funcs.
 *
 * Returns:
 * Zero on success, error code on failure.
 */
int drm_encoder_init(struct drm_device *dev,
		     struct drm_encoder *encoder,
		     const struct drm_encoder_funcs *funcs,
		     int encoder_type, const char *name, ...)
{
	int ret;

	drm_modeset_lock_all(dev);

	ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
	if (ret)
		goto out_unlock;

	encoder->dev = dev;
	encoder->encoder_type = encoder_type;
	encoder->funcs = funcs;
	if (name) {
		va_list ap;

		va_start(ap, name);
		encoder->name = kvasprintf(GFP_KERNEL, name, ap);
		va_end(ap);
	} else {
		encoder->name = kasprintf(GFP_KERNEL, "%s-%d",
					  drm_encoder_enum_list[encoder_type].name,
					  encoder->base.id);
	}
	if (!encoder->name) {
		ret = -ENOMEM;
		goto out_put;
	}

	list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
	encoder->index = dev->mode_config.num_encoder++;

out_put:
	if (ret)
		drm_mode_object_unregister(dev, &encoder->base);

out_unlock:
	drm_modeset_unlock_all(dev);

	return ret;
}
Exemple #27
0
static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb,
				      struct drm_file *file,
				      unsigned flags, unsigned color,
				      struct drm_clip_rect *clips,
				      unsigned num_clips)
{
	struct udl_framebuffer *ufb = to_udl_fb(fb);
	int i;
	int ret = 0;

	drm_modeset_lock_all(fb->dev);

	if (!ufb->active_16)
		goto unlock;

	if (ufb->obj->base.import_attach) {
		ret = dma_buf_begin_cpu_access(ufb->obj->base.import_attach->dmabuf,
					       DMA_FROM_DEVICE);
		if (ret)
			goto unlock;
	}

	for (i = 0; i < num_clips; i++) {
		ret = udl_handle_damage(ufb, clips[i].x1, clips[i].y1,
				  clips[i].x2 - clips[i].x1,
				  clips[i].y2 - clips[i].y1);
		if (ret)
			break;
	}

	if (ufb->obj->base.import_attach) {
		ret = dma_buf_end_cpu_access(ufb->obj->base.import_attach->dmabuf,
					     DMA_FROM_DEVICE);
	}

 unlock:
	drm_modeset_unlock_all(fb->dev);

	return ret;
}
static int qxl_framebuffer_surface_dirty(struct drm_framebuffer *fb,
					 struct drm_file *file_priv,
					 unsigned flags, unsigned color,
					 struct drm_clip_rect *clips,
					 unsigned num_clips)
{
	/* TODO: vmwgfx where this was cribbed from had locking. Why? */
	struct qxl_framebuffer *qxl_fb = to_qxl_framebuffer(fb);
	struct qxl_device *qdev = qxl_fb->base.dev->dev_private;
	struct drm_clip_rect norect;
	struct qxl_bo *qobj;
	int inc = 1;

	drm_modeset_lock_all(fb->dev);

	qobj = gem_to_qxl_bo(qxl_fb->obj);
	/* if we aren't primary surface ignore this */
	if (!qobj->is_primary) {
		drm_modeset_unlock_all(fb->dev);
		return 0;
	}

	if (!num_clips) {
		num_clips = 1;
		clips = &norect;
		norect.x1 = norect.y1 = 0;
		norect.x2 = fb->width;
		norect.y2 = fb->height;
	} else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) {
		num_clips /= 2;
		inc = 2; /* skip source rects */
	}

	qxl_draw_dirty_fb(qdev, qxl_fb, qobj, flags, color,
			  clips, num_clips, inc);

	drm_modeset_unlock_all(fb->dev);

	return 0;
}
Exemple #29
0
static void hsw_trans_edp_pipe_A_crc_wa(struct drm_i915_private *dev_priv,
					bool enable)
{
	struct drm_device *dev = &dev_priv->drm;
	struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_A);
	struct intel_crtc_state *pipe_config;
	struct drm_atomic_state *state;
	int ret = 0;

	drm_modeset_lock_all(dev);
	state = drm_atomic_state_alloc(dev);
	if (!state) {
		ret = -ENOMEM;
		goto unlock;
	}

	state->acquire_ctx = drm_modeset_legacy_acquire_ctx(&crtc->base);
	pipe_config = intel_atomic_get_crtc_state(state, crtc);
	if (IS_ERR(pipe_config)) {
		ret = PTR_ERR(pipe_config);
		goto put_state;
	}

	pipe_config->pch_pfit.force_thru = enable;
	if (pipe_config->cpu_transcoder == TRANSCODER_EDP &&
	    pipe_config->pch_pfit.enabled != enable)
		pipe_config->base.connectors_changed = true;

	ret = drm_atomic_commit(state);

put_state:
	drm_atomic_state_put(state);
unlock:
	WARN(ret, "Toggling workaround to %i returns %i\n", enable, ret);
	drm_modeset_unlock_all(dev);
}
Exemple #30
0
int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
			       struct drm_file *file_priv)
{
	struct vmw_private *dev_priv = vmw_priv(dev);
	struct drm_vmw_present_readback_arg *arg =
		(struct drm_vmw_present_readback_arg *)data;
	struct drm_vmw_fence_rep __user *user_fence_rep =
		(struct drm_vmw_fence_rep __user *)
		(unsigned long)arg->fence_rep;
	struct vmw_master *vmaster = vmw_master(file_priv->master);
	struct drm_vmw_rect __user *clips_ptr;
	struct drm_vmw_rect *clips = NULL;
	struct drm_framebuffer *fb;
	struct vmw_framebuffer *vfb;
	uint32_t num_clips;
	int ret;

	num_clips = arg->num_clips;
	clips_ptr = (struct drm_vmw_rect *)(unsigned long)arg->clips_ptr;

	if (unlikely(num_clips == 0))
		return 0;

	if (clips_ptr == NULL) {
		DRM_ERROR("Argument clips_ptr must be specified.\n");
		ret = -EINVAL;
		goto out_clips;
	}

	clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL);
	if (clips == NULL) {
		DRM_ERROR("Failed to allocate clip rect list.\n");
		ret = -ENOMEM;
		goto out_clips;
	}

	ret = copy_from_user(clips, clips_ptr, num_clips * sizeof(*clips));
	if (ret) {
		DRM_ERROR("Failed to copy clip rects from userspace.\n");
		ret = -EFAULT;
		goto out_no_copy;
	}

	drm_modeset_lock_all(dev);

	fb = drm_framebuffer_lookup(dev, arg->fb_id);
	if (!fb) {
		DRM_ERROR("Invalid framebuffer id.\n");
		ret = -ENOENT;
		goto out_no_fb;
	}

	vfb = vmw_framebuffer_to_vfb(fb);
	if (!vfb->dmabuf) {
		DRM_ERROR("Framebuffer not dmabuf backed.\n");
		ret = -EINVAL;
		goto out_no_ttm_lock;
	}

	ret = ttm_read_lock(&vmaster->lock, true);
	if (unlikely(ret != 0))
		goto out_no_ttm_lock;

	ret = vmw_kms_readback(dev_priv, file_priv,
			       vfb, user_fence_rep,
			       clips, num_clips);

	ttm_read_unlock(&vmaster->lock);
out_no_ttm_lock:
	drm_framebuffer_unreference(fb);
out_no_fb:
	drm_modeset_unlock_all(dev);
out_no_copy:
	kfree(clips);
out_clips:
	return ret;
}