Пример #1
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);

	/* 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);
	}

	ret = drm_fb_helper_restore_fbdev_mode(priv->fbdev);
	if (ret)
		DBG("failed to restore crtc mode");
}
Пример #2
0
/**
 * xilinx_drm_plane_restore - Restore the plane states
 * @manager: the plane manager
 *
 * Restore the plane states to the default ones. Any state that needs to be
 * restored should be here. This improves consistency as applications see
 * the same default values, and removes mismatch between software and hardware
 * values as software values are updated as hardware values are reset.
 */
void xilinx_drm_plane_restore(struct xilinx_drm_plane_manager *manager)
{
	struct xilinx_drm_plane *plane;
	unsigned int i;

	/*
	 * Reinitialize property default values as they get reset by DPMS OFF
	 * operation. User will read the correct default values later, and
	 * planes will be initialized with default values.
	 */
	for (i = 0; i < manager->num_planes; i++) {
		plane = manager->planes[i];

		plane->prio = plane->zpos = plane->id;
		if (manager->zpos_prop)
			drm_object_property_set_value(&plane->base.base,
						      manager->zpos_prop,
						      plane->prio);

		plane->alpha = manager->default_alpha;
		if (manager->alpha_prop)
			drm_object_property_set_value(&plane->base.base,
						      manager->alpha_prop,
						      plane->alpha);

		plane->alpha_enable = true;
		if (manager->alpha_enable_prop)
			drm_object_property_set_value(&plane->base.base,
					manager->alpha_enable_prop, true);
	}
}
Пример #3
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]);
	}
}
Пример #4
0
static int
intel_hdmi_set_property(struct drm_connector *connector,
			struct drm_property *property,
			uint64_t val)
{
	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
	struct intel_digital_port *intel_dig_port =
		hdmi_to_dig_port(intel_hdmi);
	struct drm_i915_private *dev_priv = connector->dev->dev_private;
	int ret;

	ret = drm_object_property_set_value(&connector->base, property, val);
	if (ret)
		return ret;

	if (property == dev_priv->force_audio_property) {
		enum hdmi_force_audio i = val;
		bool has_audio;

		if (i == intel_hdmi->force_audio)
			return 0;

		intel_hdmi->force_audio = i;

		if (i == HDMI_AUDIO_AUTO)
			has_audio = intel_hdmi_detect_audio(connector);
		else
			has_audio = (i == HDMI_AUDIO_ON);

		if (i == HDMI_AUDIO_OFF_DVI)
			intel_hdmi->has_hdmi_sink = 0;

		intel_hdmi->has_audio = has_audio;
		goto done;
	}

	if (property == dev_priv->broadcast_rgb_property) {
		if (val == !!intel_hdmi->color_range)
			return 0;

		intel_hdmi->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0;
		goto done;
	}

	return -EINVAL;

done:
	if (intel_dig_port->base.base.crtc) {
		struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
		intel_set_mode(crtc, &crtc->mode,
			       crtc->x, crtc->y, crtc->fb);
	}

	return 0;
}
Пример #5
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;
	}
}
Пример #6
0
static int cdv_hdmi_set_property(struct drm_connector *connector,
				       struct drm_property *property,
				       uint64_t value)
{
	struct drm_encoder *encoder = connector->encoder;

	if (!strcmp(property->name, "scaling mode") && encoder) {
		struct gma_crtc *crtc = to_gma_crtc(encoder->crtc);
		bool centre;
		uint64_t curValue;

		if (!crtc)
			return -1;

		switch (value) {
		case DRM_MODE_SCALE_FULLSCREEN:
			break;
		case DRM_MODE_SCALE_NO_SCALE:
			break;
		case DRM_MODE_SCALE_ASPECT:
			break;
		default:
			return -1;
		}

		if (drm_object_property_get_value(&connector->base,
							property, &curValue))
			return -1;

		if (curValue == value)
			return 0;

		if (drm_object_property_set_value(&connector->base,
							property, value))
			return -1;

		centre = (curValue == DRM_MODE_SCALE_NO_SCALE) ||
			(value == DRM_MODE_SCALE_NO_SCALE);

		if (crtc->saved_mode.hdisplay != 0 &&
		    crtc->saved_mode.vdisplay != 0) {
			if (centre) {
				if (!drm_crtc_helper_set_mode(encoder->crtc, &crtc->saved_mode,
					    encoder->crtc->x, encoder->crtc->y, encoder->crtc->primary->fb))
					return -1;
			} else {
				const struct drm_encoder_helper_funcs *helpers
						    = encoder->helper_private;
				helpers->mode_set(encoder, &crtc->saved_mode,
					     &crtc->saved_adjusted_mode);
			}
		}
	}
	return 0;
}
Пример #7
0
static void xylon_drm_crtc_properties_initial_value(struct drm_crtc *base_crtc)
{
	struct drm_mode_object *obj = &base_crtc->base;
	struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
	struct xylon_drm_crtc_properties *props = &crtc->properties;
	bool *val;

	val = &props->layer_update_initval;
	*val = xylon_cvc_get_info(crtc->cvc, LOGICVC_INFO_LAYER_UPDATE, 0);
	drm_object_property_set_value(obj, props->layer_update, *val);

	val = &props->pixel_data_polarity_initval;
	*val = xylon_cvc_get_info(crtc->cvc, LOGICVC_INFO_PIXEL_DATA_INVERT, 0);
	drm_object_property_set_value(obj, props->pixel_data_polarity, *val);

	val = &props->pixel_data_trigger_initval;
	*val = xylon_cvc_get_info(crtc->cvc,
				  LOGICVC_INFO_PIXEL_DATA_TRIGGER_INVERT, 0);
	drm_object_property_set_value(obj, props->pixel_data_trigger, *val);
}
Пример #8
0
void xylon_drm_crtc_properties_restore(struct drm_crtc *base_crtc)
{
	struct drm_mode_object *obj = &base_crtc->base;
	struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
	struct xylon_drm_crtc_properties *props = &crtc->properties;

	xylon_drm_crtc_set_property(base_crtc, props->layer_update,
				    props->layer_update_initval);
	drm_object_property_set_value(obj, props->layer_update,
				      props->layer_update_initval);
	xylon_drm_crtc_set_property(base_crtc, props->pixel_data_polarity,
				    props->pixel_data_polarity_initval);
	drm_object_property_set_value(obj, props->pixel_data_polarity,
				      props->pixel_data_polarity_initval);
	xylon_drm_crtc_set_property(base_crtc, props->pixel_data_trigger,
				    props->pixel_data_trigger_initval);
	drm_object_property_set_value(obj, props->pixel_data_trigger,
				      props->pixel_data_trigger_initval);

	xylon_drm_plane_properties_restore(crtc->manager);
}
static int intel_dsi_set_property(struct drm_connector *connector,
		struct drm_property *property,
		uint64_t val)
{
	struct intel_dsi *intel_dsi = intel_attached_dsi(connector);
	struct drm_i915_private *dev_priv = connector->dev->dev_private;
	struct intel_connector *intel_connector = to_intel_connector(connector);
	struct intel_encoder *encoder = intel_connector->encoder;
	struct intel_crtc *intel_crtc = encoder->new_crtc;
	int ret;

	ret = drm_object_property_set_value(&connector->base, property, val);
	if (ret)
		return ret;

	if (property == dev_priv->force_pfit_property) {

		if (intel_connector->panel.fitting_mode == val)
			return 0;

		intel_connector->panel.fitting_mode = val;

		if (IS_VALLEYVIEW(dev_priv->dev)) {

			/* In case of BYT_CR platform with the panasonic panel of
			 * resolution 19x10, panel fitter needs to be enabled always
			 * becoz we simulate the 12x8 mode due to memory limitation
			 */
			if ((dev_priv->scaling_reqd) ||
			(BYT_CR_CONFIG && (i915_mipi_panel_id ==
				MIPI_DSI_PANASONIC_VXX09F006A00_PANEL_ID))) {
				if (intel_connector->panel.fitting_mode == PFIT_OFF)
					return 0;
			}

			intel_gmch_panel_fitting(intel_crtc, &intel_crtc->config,
				intel_connector->panel.fitting_mode);
			DRM_DEBUG_DRIVER("panel fitting mode = %x", intel_connector->panel.fitting_mode);
			return 0;
		} else
			goto done;
	}

	if (property == dev_priv->scaling_src_size_property) {
		intel_crtc->scaling_src_size = val;
		DRM_DEBUG_DRIVER("src size = %x", intel_crtc->scaling_src_size);
		return 0;
	}
done:
	if (intel_dsi->base.base.crtc)
		intel_crtc_restore_mode(intel_dsi->base.base.crtc);
	return 0;
}
Пример #10
0
int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu,
				struct rcar_du_encoder *renc,
				/* TODO const */ struct device_node *np)
{
	struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc);
	struct rcar_du_lvds_connector *lvdscon;
	struct drm_connector *connector;
	struct display_timing timing;
	int ret;

	lvdscon = devm_kzalloc(rcdu->dev, sizeof(*lvdscon), GFP_KERNEL);
	if (lvdscon == NULL)
		return -ENOMEM;

	ret = of_get_display_timing(np, "panel-timing", &timing);
	if (ret < 0)
		return ret;

	videomode_from_timing(&timing, &lvdscon->panel.mode);

	of_property_read_u32(np, "width-mm", &lvdscon->panel.width_mm);
	of_property_read_u32(np, "height-mm", &lvdscon->panel.height_mm);

	connector = &lvdscon->connector.connector;
	connector->display_info.width_mm = lvdscon->panel.width_mm;
	connector->display_info.height_mm = lvdscon->panel.height_mm;

	ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs,
				 DRM_MODE_CONNECTOR_LVDS);
	if (ret < 0)
		return ret;

	drm_connector_helper_add(connector, &connector_helper_funcs);
	ret = drm_connector_register(connector);
	if (ret < 0)
		return ret;

	drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
	drm_object_property_set_value(&connector->base,
		rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);

	ret = drm_mode_connector_attach_encoder(connector, encoder);
	if (ret < 0)
		return ret;

	connector->encoder = encoder;
	lvdscon->connector.encoder = renc;

	return 0;
}
Пример #11
0
/**
 * drm_mode_plane_set_obj_prop - set the value of a property
 * @plane: drm plane object to set property value for
 * @property: property to set
 * @value: value the property should be set to
 *
 * This functions sets a given property on a given plane object. This function
 * calls the driver's ->set_property callback and changes the software state of
 * the property if the callback succeeds.
 *
 * Returns:
 * Zero on success, error code on failure.
 */
int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
				struct drm_property *property,
				uint64_t value)
{
	int ret = -EINVAL;
	struct drm_mode_object *obj = &plane->base;

	if (plane->funcs->set_property)
		ret = plane->funcs->set_property(plane, property, value);
	if (!ret)
		drm_object_property_set_value(obj, property, value);

	return ret;
}
Пример #12
0
/**
 * xilinx_drm_crtc_restore - Restore the crtc states
 * @base_crtc: base crtc object
 *
 * Restore the crtc states to the default ones. The request is propagated
 * to the plane driver.
 */
void xilinx_drm_crtc_restore(struct drm_crtc *base_crtc)
{
	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);

	/*
	 * Reinitialize the property values, so correct values are read
	 * for these properties.
	 */
	if (crtc->zpos_prop) {
		xilinx_drm_plane_set_zpos(crtc->priv_plane, crtc->default_zpos);
		drm_object_property_set_value(&base_crtc->base, crtc->zpos_prop,
					      crtc->default_zpos);
	}

	if (crtc->alpha_prop) {
		xilinx_drm_plane_set_alpha(crtc->priv_plane,
					   crtc->default_alpha);
		drm_object_property_set_value(&base_crtc->base,
					      crtc->alpha_prop,
					      crtc->default_alpha);
	}

	xilinx_drm_plane_restore(crtc->plane_manager);
}
Пример #13
0
/* set property of a plane */
static int xilinx_drm_crtc_set_property(struct drm_crtc *base_crtc,
					struct drm_property *property,
					uint64_t val)
{
	struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);

	if (property == crtc->zpos_prop)
		xilinx_drm_plane_set_zpos(crtc->priv_plane, val);
	else if (property == crtc->alpha_prop)
		xilinx_drm_plane_set_alpha(crtc->priv_plane, val);
	else
		return -EINVAL;

	drm_object_property_set_value(&base_crtc->base, property, val);

	return 0;
}
Пример #14
0
/* set property of a plane */
static int xilinx_drm_plane_set_property(struct drm_plane *base_plane,
					 struct drm_property *property,
					 uint64_t val)
{
	struct xilinx_drm_plane *plane = to_xilinx_plane(base_plane);
	struct xilinx_drm_plane_manager *manager = plane->manager;

	if (property == manager->zpos_prop)
		xilinx_drm_plane_set_zpos(base_plane, val);
	else if (property == manager->alpha_prop)
		xilinx_drm_plane_set_alpha(base_plane, val);
	else
		return -EINVAL;

	drm_object_property_set_value(&base_plane->base, property, val);

	return 0;
}
Пример #15
0
int shmob_drm_connector_create(struct shmob_drm_device *sdev,
			       struct drm_encoder *encoder)
{
	struct drm_connector *connector = &sdev->connector.connector;
	int ret;

	sdev->connector.encoder = encoder;

	connector->display_info.width_mm = sdev->pdata->panel.width_mm;
	connector->display_info.height_mm = sdev->pdata->panel.height_mm;

	ret = drm_connector_init(sdev->ddev, connector, &connector_funcs,
				 DRM_MODE_CONNECTOR_LVDS);
	if (ret < 0)
		return ret;

	drm_connector_helper_add(connector, &connector_helper_funcs);
	ret = drm_connector_register(connector);
	if (ret < 0)
		goto err_cleanup;

	ret = shmob_drm_backlight_init(&sdev->connector);
	if (ret < 0)
		goto err_sysfs;

	ret = drm_mode_connector_attach_encoder(connector, encoder);
	if (ret < 0)
		goto err_backlight;

	drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
	drm_object_property_set_value(&connector->base,
		sdev->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);

	return 0;

err_backlight:
	shmob_drm_backlight_exit(&sdev->connector);
err_sysfs:
	drm_connector_unregister(connector);
err_cleanup:
	drm_connector_cleanup(connector);
	return ret;
}
Пример #16
0
static int fsl_dcu_attach_panel(struct fsl_dcu_drm_device *fsl_dev,
				 struct drm_panel *panel)
{
	struct drm_encoder *encoder = &fsl_dev->encoder;
	struct drm_connector *connector = &fsl_dev->connector.base;
	struct drm_mode_config *mode_config = &fsl_dev->drm->mode_config;
	int ret;

	fsl_dev->connector.encoder = encoder;

	ret = drm_connector_init(fsl_dev->drm, connector,
				 &fsl_dcu_drm_connector_funcs,
				 DRM_MODE_CONNECTOR_LVDS);
	if (ret < 0)
		return ret;

	drm_connector_helper_add(connector, &connector_helper_funcs);
	ret = drm_connector_register(connector);
	if (ret < 0)
		goto err_cleanup;

	ret = drm_mode_connector_attach_encoder(connector, encoder);
	if (ret < 0)
		goto err_sysfs;

	drm_object_property_set_value(&connector->base,
				      mode_config->dpms_property,
				      DRM_MODE_DPMS_OFF);

	ret = drm_panel_attach(panel, connector);
	if (ret) {
		dev_err(fsl_dev->dev, "failed to attach panel\n");
		goto err_sysfs;
	}

	return 0;

err_sysfs:
	drm_connector_unregister(connector);
err_cleanup:
	drm_connector_cleanup(connector);
	return ret;
}
static int intel_dsi_set_property(struct drm_connector *connector,
		struct drm_property *property,
		uint64_t val)
{
	struct intel_dsi *intel_dsi = intel_attached_dsi(connector);
	struct drm_i915_private *dev_priv = connector->dev->dev_private;
	struct intel_connector *intel_connector = to_intel_connector(connector);
	struct intel_encoder *encoder = intel_connector->encoder;
	struct intel_crtc *intel_crtc = encoder->new_crtc;
	int ret;

	ret = drm_object_property_set_value(&connector->base, property, val);
	if (ret)
		return ret;

	if (property == dev_priv->force_pfit_property) {

		if (intel_connector->panel.fitting_mode == val)
			return 0;

		intel_connector->panel.fitting_mode = val;

		if (IS_VALLEYVIEW(dev_priv->dev)) {
			intel_gmch_panel_fitting(intel_crtc, &intel_crtc->config,
				intel_connector->panel.fitting_mode);
			DRM_DEBUG_DRIVER("panel fitting mode = %x", intel_connector->panel.fitting_mode);
			return 0;
		} else
			goto done;
	}

	if (property == dev_priv->scaling_src_size_property) {
		intel_crtc->scaling_src_size = val;
		DRM_DEBUG_DRIVER("src size = %x", intel_crtc->scaling_src_size);
		return 0;
	}
done:
	if (intel_dsi->base.base.crtc)
		intel_crtc_restore_mode(intel_dsi->base.base.crtc);
	return 0;
}
Пример #18
0
int rcar_du_hdmi_connector_init(struct rcar_du_device *rcdu,
				struct rcar_du_encoder *renc)
{
	struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc);
	struct rcar_du_connector *rcon;
	struct drm_connector *connector;
	int ret;

	rcon = devm_kzalloc(rcdu->dev, sizeof(*rcon), GFP_KERNEL);
	if (rcon == NULL)
		return -ENOMEM;

	connector = &rcon->connector;
	connector->display_info.width_mm = 0;
	connector->display_info.height_mm = 0;
	connector->interlace_allowed = true;
	connector->polled = DRM_CONNECTOR_POLL_HPD;

	ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs,
				 DRM_MODE_CONNECTOR_HDMIA);
	if (ret < 0)
		return ret;

	drm_connector_helper_add(connector, &connector_helper_funcs);
	ret = drm_connector_register(connector);
	if (ret < 0)
		return ret;

	connector->dpms = DRM_MODE_DPMS_OFF;
	drm_object_property_set_value(&connector->base,
		rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);

	ret = drm_mode_connector_attach_encoder(connector, encoder);
	if (ret < 0)
		return ret;

	rcon->encoder = renc;

	return 0;
}
Пример #19
0
int rcar_du_hdmi_connector_init(struct rcar_du_device *rcdu,
			       struct rcar_du_encoder *renc)
{
	struct rcar_du_connector *rcon;
	struct drm_connector *connector;
	int ret;

	rcon = devm_kzalloc(rcdu->dev, sizeof(*rcon), GFP_KERNEL);
	if (rcon == NULL)
		return -ENOMEM;

	connector = &rcon->connector;
	connector->polled = DRM_CONNECTOR_POLL_CONNECT |
				DRM_CONNECTOR_POLL_DISCONNECT;
	connector->interlace_allowed = true;

	ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs,
				 DRM_MODE_CONNECTOR_HDMIA);

	if (ret < 0)
		return ret;

	drm_connector_helper_add(connector, &connector_helper_funcs);
	ret = drm_sysfs_connector_add(connector);
	if (ret < 0)
		return ret;

	drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
	drm_object_property_set_value(&connector->base,
		rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);

	ret = drm_mode_connector_attach_encoder(connector, renc->encoder);
	if (ret < 0)
		return ret;

	connector->encoder = renc->encoder;
	rcon->encoder = renc;

	return 0;
}
Пример #20
0
int rcar_du_vga_connector_init(struct rcar_du_device *rcdu,
			       struct rcar_du_encoder *renc)
{
	struct rcar_du_connector *rcon;
	struct drm_connector *connector;
	int ret;

	rcon = devm_kzalloc(rcdu->dev, sizeof(*rcon), GFP_KERNEL);
	if (rcon == NULL)
		return -ENOMEM;

	connector = &rcon->connector;
	connector->display_info.width_mm = 0;
	connector->display_info.height_mm = 0;

	ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs,
				 DRM_MODE_CONNECTOR_VGA);
	if (ret < 0)
		return ret;

	drm_connector_helper_add(connector, &connector_helper_funcs);
	ret = drm_connector_register(connector);
	if (ret < 0)
		return ret;

	drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
	drm_object_property_set_value(&connector->base,
		rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);

	ret = drm_mode_connector_attach_encoder(connector, &renc->encoder);
	if (ret < 0)
		return ret;

	connector->encoder = &renc->encoder;
	rcon->encoder = renc;

	return 0;
}
Пример #21
0
static int
intel_hdmi_set_property(struct drm_connector *connector,
			struct drm_property *property,
			uint64_t val)
{
	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
	struct intel_digital_port *intel_dig_port =
		hdmi_to_dig_port(intel_hdmi);
	struct drm_i915_private *dev_priv = connector->dev->dev_private;
	int ret;

	ret = drm_object_property_set_value(&connector->base, property, val);
	if (ret)
		return ret;

	if (property == dev_priv->force_audio_property) {
		enum hdmi_force_audio i = val;
		bool has_audio;

		if (i == intel_hdmi->force_audio)
			return 0;

		intel_hdmi->force_audio = i;

		if (i == HDMI_AUDIO_AUTO)
			has_audio = intel_hdmi_detect_audio(connector);
		else
			has_audio = (i == HDMI_AUDIO_ON);

		if (i == HDMI_AUDIO_OFF_DVI)
			intel_hdmi->has_hdmi_sink = 0;

		intel_hdmi->has_audio = has_audio;
		goto done;
	}

	if (property == dev_priv->broadcast_rgb_property) {
		bool old_auto = intel_hdmi->color_range_auto;
		uint32_t old_range = intel_hdmi->color_range;

		switch (val) {
		case INTEL_BROADCAST_RGB_AUTO:
			intel_hdmi->color_range_auto = true;
			break;
		case INTEL_BROADCAST_RGB_FULL:
			intel_hdmi->color_range_auto = false;
			intel_hdmi->color_range = 0;
			break;
		case INTEL_BROADCAST_RGB_LIMITED:
			intel_hdmi->color_range_auto = false;
			intel_hdmi->color_range = HDMI_COLOR_RANGE_16_235;
			break;
		default:
			return -EINVAL;
		}

		if (old_auto == intel_hdmi->color_range_auto &&
		    old_range == intel_hdmi->color_range)
			return 0;

		goto done;
	}

	return -EINVAL;

done:
	if (intel_dig_port->base.base.crtc)
		intel_crtc_restore_mode(intel_dig_port->base.base.crtc);

	return 0;
}