Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ff5f4b05 authored by Daniel Vetter's avatar Daniel Vetter
Browse files

Merge remote-tracking branch 'airlied/drm-next' into for-airlied



Manually resolve the conflict between the new enum drm property
helpers in drm-next and the new "force-dvi" option that the "audio" output
property gained in drm-intel-next.

While resolving this conflict, switch the new drm_prop_enum_list to
use the newly introduced enum defines instead of magic values.

Conflicts:
	drivers/gpu/drm/i915/intel_modes.c

Signed-Off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parents de67cba6 019d96cb
Loading
Loading
Loading
Loading
+97 −104
Original line number Diff line number Diff line
@@ -38,11 +38,6 @@
#include "drm_edid.h"
#include "drm_fourcc.h"

struct drm_prop_enum_list {
	int type;
	char *name;
};

/* Avoid boilerplate.  I'm tired of typing. */
#define DRM_ENUM_NAME_FN(fnname, list)				\
	char *fnname(int val)					\
@@ -442,7 +437,7 @@ void drm_mode_remove(struct drm_connector *connector,
		     struct drm_display_mode *mode)
{
	list_del(&mode->head);
	kfree(mode);
	drm_mode_destroy(connector->dev, mode);
}
EXPORT_SYMBOL(drm_mode_remove);

@@ -454,7 +449,7 @@ EXPORT_SYMBOL(drm_mode_remove);
 * @name: user visible name of the connector
 *
 * LOCKING:
 * Caller must hold @dev's mode_config lock.
 * Takes mode config lock.
 *
 * Initialises a preallocated connector. Connectors should be
 * subclassed as part of driver connector objects.
@@ -497,7 +492,7 @@ EXPORT_SYMBOL(drm_connector_init);
 * @connector: connector to cleanup
 *
 * LOCKING:
 * Caller must hold @dev's mode_config lock.
 * Takes mode config lock.
 *
 * Cleans up the connector but doesn't free the object.
 */
@@ -658,7 +653,6 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
{
	struct drm_property *edid;
	struct drm_property *dpms;
	int i;

	/*
	 * Standard properties (apply to all connectors)
@@ -668,11 +662,9 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
				   "EDID", 0);
	dev->mode_config.edid_property = edid;

	dpms = drm_property_create(dev, DRM_MODE_PROP_ENUM,
				   "DPMS", ARRAY_SIZE(drm_dpms_enum_list));
	for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++)
		drm_property_add_enum(dpms, i, drm_dpms_enum_list[i].type,
				      drm_dpms_enum_list[i].name);
	dpms = drm_property_create_enum(dev, 0,
				   "DPMS", drm_dpms_enum_list,
				   ARRAY_SIZE(drm_dpms_enum_list));
	dev->mode_config.dpms_property = dpms;

	return 0;
@@ -688,30 +680,21 @@ int drm_mode_create_dvi_i_properties(struct drm_device *dev)
{
	struct drm_property *dvi_i_selector;
	struct drm_property *dvi_i_subconnector;
	int i;

	if (dev->mode_config.dvi_i_select_subconnector_property)
		return 0;

	dvi_i_selector =
		drm_property_create(dev, DRM_MODE_PROP_ENUM,
		drm_property_create_enum(dev, 0,
				    "select subconnector",
				    drm_dvi_i_select_enum_list,
				    ARRAY_SIZE(drm_dvi_i_select_enum_list));
	for (i = 0; i < ARRAY_SIZE(drm_dvi_i_select_enum_list); i++)
		drm_property_add_enum(dvi_i_selector, i,
				      drm_dvi_i_select_enum_list[i].type,
				      drm_dvi_i_select_enum_list[i].name);
	dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;

	dvi_i_subconnector =
		drm_property_create(dev, DRM_MODE_PROP_ENUM |
				    DRM_MODE_PROP_IMMUTABLE,
	dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
				    "subconnector",
				    drm_dvi_i_subconnector_enum_list,
				    ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
	for (i = 0; i < ARRAY_SIZE(drm_dvi_i_subconnector_enum_list); i++)
		drm_property_add_enum(dvi_i_subconnector, i,
				      drm_dvi_i_subconnector_enum_list[i].type,
				      drm_dvi_i_subconnector_enum_list[i].name);
	dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;

	return 0;
@@ -742,51 +725,33 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
	/*
	 * Basic connector properties
	 */
	tv_selector = drm_property_create(dev, DRM_MODE_PROP_ENUM,
	tv_selector = drm_property_create_enum(dev, 0,
					  "select subconnector",
					  drm_tv_select_enum_list,
					  ARRAY_SIZE(drm_tv_select_enum_list));
	for (i = 0; i < ARRAY_SIZE(drm_tv_select_enum_list); i++)
		drm_property_add_enum(tv_selector, i,
				      drm_tv_select_enum_list[i].type,
				      drm_tv_select_enum_list[i].name);
	dev->mode_config.tv_select_subconnector_property = tv_selector;

	tv_subconnector =
		drm_property_create(dev, DRM_MODE_PROP_ENUM |
				    DRM_MODE_PROP_IMMUTABLE, "subconnector",
		drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
				    "subconnector",
				    drm_tv_subconnector_enum_list,
				    ARRAY_SIZE(drm_tv_subconnector_enum_list));
	for (i = 0; i < ARRAY_SIZE(drm_tv_subconnector_enum_list); i++)
		drm_property_add_enum(tv_subconnector, i,
				      drm_tv_subconnector_enum_list[i].type,
				      drm_tv_subconnector_enum_list[i].name);
	dev->mode_config.tv_subconnector_property = tv_subconnector;

	/*
	 * Other, TV specific properties: margins & TV modes.
	 */
	dev->mode_config.tv_left_margin_property =
		drm_property_create(dev, DRM_MODE_PROP_RANGE,
				    "left margin", 2);
	dev->mode_config.tv_left_margin_property->values[0] = 0;
	dev->mode_config.tv_left_margin_property->values[1] = 100;
		drm_property_create_range(dev, 0, "left margin", 0, 100);

	dev->mode_config.tv_right_margin_property =
		drm_property_create(dev, DRM_MODE_PROP_RANGE,
				    "right margin", 2);
	dev->mode_config.tv_right_margin_property->values[0] = 0;
	dev->mode_config.tv_right_margin_property->values[1] = 100;
		drm_property_create_range(dev, 0, "right margin", 0, 100);

	dev->mode_config.tv_top_margin_property =
		drm_property_create(dev, DRM_MODE_PROP_RANGE,
				    "top margin", 2);
	dev->mode_config.tv_top_margin_property->values[0] = 0;
	dev->mode_config.tv_top_margin_property->values[1] = 100;
		drm_property_create_range(dev, 0, "top margin", 0, 100);

	dev->mode_config.tv_bottom_margin_property =
		drm_property_create(dev, DRM_MODE_PROP_RANGE,
				    "bottom margin", 2);
	dev->mode_config.tv_bottom_margin_property->values[0] = 0;
	dev->mode_config.tv_bottom_margin_property->values[1] = 100;
		drm_property_create_range(dev, 0, "bottom margin", 0, 100);

	dev->mode_config.tv_mode_property =
		drm_property_create(dev, DRM_MODE_PROP_ENUM,
@@ -796,40 +761,22 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
				      i, modes[i]);

	dev->mode_config.tv_brightness_property =
		drm_property_create(dev, DRM_MODE_PROP_RANGE,
				    "brightness", 2);
	dev->mode_config.tv_brightness_property->values[0] = 0;
	dev->mode_config.tv_brightness_property->values[1] = 100;
		drm_property_create_range(dev, 0, "brightness", 0, 100);

	dev->mode_config.tv_contrast_property =
		drm_property_create(dev, DRM_MODE_PROP_RANGE,
				    "contrast", 2);
	dev->mode_config.tv_contrast_property->values[0] = 0;
	dev->mode_config.tv_contrast_property->values[1] = 100;
		drm_property_create_range(dev, 0, "contrast", 0, 100);

	dev->mode_config.tv_flicker_reduction_property =
		drm_property_create(dev, DRM_MODE_PROP_RANGE,
				    "flicker reduction", 2);
	dev->mode_config.tv_flicker_reduction_property->values[0] = 0;
	dev->mode_config.tv_flicker_reduction_property->values[1] = 100;
		drm_property_create_range(dev, 0, "flicker reduction", 0, 100);

	dev->mode_config.tv_overscan_property =
		drm_property_create(dev, DRM_MODE_PROP_RANGE,
				    "overscan", 2);
	dev->mode_config.tv_overscan_property->values[0] = 0;
	dev->mode_config.tv_overscan_property->values[1] = 100;
		drm_property_create_range(dev, 0, "overscan", 0, 100);

	dev->mode_config.tv_saturation_property =
		drm_property_create(dev, DRM_MODE_PROP_RANGE,
				    "saturation", 2);
	dev->mode_config.tv_saturation_property->values[0] = 0;
	dev->mode_config.tv_saturation_property->values[1] = 100;
		drm_property_create_range(dev, 0, "saturation", 0, 100);

	dev->mode_config.tv_hue_property =
		drm_property_create(dev, DRM_MODE_PROP_RANGE,
				    "hue", 2);
	dev->mode_config.tv_hue_property->values[0] = 0;
	dev->mode_config.tv_hue_property->values[1] = 100;
		drm_property_create_range(dev, 0, "hue", 0, 100);

	return 0;
}
@@ -845,18 +792,14 @@ EXPORT_SYMBOL(drm_mode_create_tv_properties);
int drm_mode_create_scaling_mode_property(struct drm_device *dev)
{
	struct drm_property *scaling_mode;
	int i;

	if (dev->mode_config.scaling_mode_property)
		return 0;

	scaling_mode =
		drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode",
		drm_property_create_enum(dev, 0, "scaling mode",
				drm_scaling_mode_enum_list,
				    ARRAY_SIZE(drm_scaling_mode_enum_list));
	for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++)
		drm_property_add_enum(scaling_mode, i,
				      drm_scaling_mode_enum_list[i].type,
				      drm_scaling_mode_enum_list[i].name);

	dev->mode_config.scaling_mode_property = scaling_mode;

@@ -874,18 +817,14 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
int drm_mode_create_dithering_property(struct drm_device *dev)
{
	struct drm_property *dithering_mode;
	int i;

	if (dev->mode_config.dithering_mode_property)
		return 0;

	dithering_mode =
		drm_property_create(dev, DRM_MODE_PROP_ENUM, "dithering",
		drm_property_create_enum(dev, 0, "dithering",
				drm_dithering_mode_enum_list,
				    ARRAY_SIZE(drm_dithering_mode_enum_list));
	for (i = 0; i < ARRAY_SIZE(drm_dithering_mode_enum_list); i++)
		drm_property_add_enum(dithering_mode, i,
				      drm_dithering_mode_enum_list[i].type,
				      drm_dithering_mode_enum_list[i].name);
	dev->mode_config.dithering_mode_property = dithering_mode;

	return 0;
@@ -902,20 +841,15 @@ EXPORT_SYMBOL(drm_mode_create_dithering_property);
int drm_mode_create_dirty_info_property(struct drm_device *dev)
{
	struct drm_property *dirty_info;
	int i;

	if (dev->mode_config.dirty_info_property)
		return 0;

	dirty_info =
		drm_property_create(dev, DRM_MODE_PROP_ENUM |
				    DRM_MODE_PROP_IMMUTABLE,
		drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
				    "dirty",
				    drm_dirty_info_enum_list,
				    ARRAY_SIZE(drm_dirty_info_enum_list));
	for (i = 0; i < ARRAY_SIZE(drm_dirty_info_enum_list); i++)
		drm_property_add_enum(dirty_info, i,
				      drm_dirty_info_enum_list[i].type,
				      drm_dirty_info_enum_list[i].name);
	dev->mode_config.dirty_info_property = dirty_info;

	return 0;
@@ -1048,6 +982,9 @@ void drm_mode_config_cleanup(struct drm_device *dev)
				 head) {
		plane->funcs->destroy(plane);
	}

	idr_remove_all(&dev->mode_config.crtc_idr);
	idr_destroy(&dev->mode_config.crtc_idr);
}
EXPORT_SYMBOL(drm_mode_config_cleanup);

@@ -1311,7 +1248,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
 * @arg: arg from ioctl
 *
 * LOCKING:
 * Caller? (FIXME)
 * Takes mode config lock.
 *
 * Construct a CRTC configuration structure to return to the user.
 *
@@ -1371,7 +1308,7 @@ int drm_mode_getcrtc(struct drm_device *dev,
 * @arg: arg from ioctl
 *
 * LOCKING:
 * Caller? (FIXME)
 * Takes mode config lock.
 *
 * Construct a connector configuration structure to return to the user.
 *
@@ -1553,6 +1490,9 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
 * @data: ioctl data
 * @file_priv: DRM file info
 *
 * LOCKING:
 * Takes mode config lock.
 *
 * Return an plane count and set of IDs.
 */
int drm_mode_getplane_res(struct drm_device *dev, void *data,
@@ -1599,6 +1539,9 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
 * @data: ioctl data
 * @file_priv: DRM file info
 *
 * LOCKING:
 * Takes mode config lock.
 *
 * Return plane info, including formats supported, gamma size, any
 * current fb, etc.
 */
@@ -1664,6 +1607,9 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
 * @data: ioctl data*
 * @file_prive: DRM file info
 *
 * LOCKING:
 * Takes mode config lock.
 *
 * Set plane info, including placement, fb, scaling, and other factors.
 * Or pass a NULL fb to disable.
 */
@@ -1794,7 +1740,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
 * @arg: arg from ioctl
 *
 * LOCKING:
 * Caller? (FIXME)
 * Takes mode config lock.
 *
 * Build a new CRTC configuration based on user request.
 *
@@ -2275,7 +2221,7 @@ int drm_mode_rmfb(struct drm_device *dev,
 * @arg: arg from ioctl
 *
 * LOCKING:
 * Caller? (FIXME)
 * Takes mode config lock.
 *
 * Lookup the FB given its ID and return info about it.
 *
@@ -2617,6 +2563,53 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
}
EXPORT_SYMBOL(drm_property_create);

struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
					 const char *name,
					 const struct drm_prop_enum_list *props,
					 int num_values)
{
	struct drm_property *property;
	int i, ret;

	flags |= DRM_MODE_PROP_ENUM;

	property = drm_property_create(dev, flags, name, num_values);
	if (!property)
		return NULL;

	for (i = 0; i < num_values; i++) {
		ret = drm_property_add_enum(property, i,
				      props[i].type,
				      props[i].name);
		if (ret) {
			drm_property_destroy(dev, property);
			return NULL;
		}
	}

	return property;
}
EXPORT_SYMBOL(drm_property_create_enum);

struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
					 const char *name,
					 uint64_t min, uint64_t max)
{
	struct drm_property *property;

	flags |= DRM_MODE_PROP_RANGE;

	property = drm_property_create(dev, flags, name, 2);
	if (!property)
		return NULL;

	property->values[0] = min;
	property->values[1] = max;

	return property;
}
EXPORT_SYMBOL(drm_property_create_range);

int drm_property_add_enum(struct drm_property *property, int index,
			  uint64_t value, const char *name)
{
@@ -3021,7 +3014,7 @@ void drm_mode_connector_detach_encoder(struct drm_connector *connector,
}
EXPORT_SYMBOL(drm_mode_connector_detach_encoder);

bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
				  int gamma_size)
{
	crtc->gamma_size = gamma_size;
@@ -3029,10 +3022,10 @@ bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
	crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
	if (!crtc->gamma_store) {
		crtc->gamma_size = 0;
		return false;
		return -ENOMEM;
	}

	return true;
	return 0;
}
EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);

+6 −6
Original line number Diff line number Diff line
@@ -44,12 +44,12 @@ module_param_named(poll, drm_kms_helper_poll, bool, 0600);
static void drm_mode_validate_flag(struct drm_connector *connector,
				   int flags)
{
	struct drm_display_mode *mode, *t;
	struct drm_display_mode *mode;

	if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
		return;

	list_for_each_entry_safe(mode, t, &connector->modes, head) {
	list_for_each_entry(mode, &connector->modes, head) {
		if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
				!(flags & DRM_MODE_FLAG_INTERLACE))
			mode->status = MODE_NO_INTERLACE;
@@ -87,7 +87,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
					    uint32_t maxX, uint32_t maxY)
{
	struct drm_device *dev = connector->dev;
	struct drm_display_mode *mode, *t;
	struct drm_display_mode *mode;
	struct drm_connector_helper_funcs *connector_funcs =
		connector->helper_private;
	int count = 0;
@@ -96,7 +96,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
			drm_get_connector_name(connector));
	/* set all modes to the unverified state */
	list_for_each_entry_safe(mode, t, &connector->modes, head)
	list_for_each_entry(mode, &connector->modes, head)
		mode->status = MODE_UNVERIFIED;

	if (connector->force) {
@@ -136,7 +136,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
		mode_flags |= DRM_MODE_FLAG_DBLSCAN;
	drm_mode_validate_flag(connector, mode_flags);

	list_for_each_entry_safe(mode, t, &connector->modes, head) {
	list_for_each_entry(mode, &connector->modes, head) {
		if (mode->status == MODE_OK)
			mode->status = connector_funcs->mode_valid(connector,
								   mode);
@@ -152,7 +152,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,

	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
			drm_get_connector_name(connector));
	list_for_each_entry_safe(mode, t, &connector->modes, head) {
	list_for_each_entry(mode, &connector->modes, head) {
		mode->vrefresh = drm_mode_vrefresh(mode);

		drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+6 −6
Original line number Diff line number Diff line
@@ -135,23 +135,23 @@ static struct drm_ioctl_desc drm_ioctls[] = {
	DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),

	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
	DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+6 −1
Original line number Diff line number Diff line
@@ -266,6 +266,11 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
			}
		};
		ret = i2c_transfer(adapter, msgs, 2);
		if (ret == -ENXIO) {
			DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n",
					adapter->name);
			break;
		}
	} while (ret != 2 && --retries);

	return ret == 2 ? 0 : -1;
@@ -745,7 +750,7 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid,
		 */
		mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
		if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) {
			kfree(mode);
			drm_mode_destroy(dev, mode);
			mode = drm_gtf_mode_complex(dev, hsize, vsize,
						    vrefresh_rate, 0, 0,
						    drm_gtf2_m(edid),
+15 −73
Original line number Diff line number Diff line
@@ -306,91 +306,31 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
#endif

static void drm_fb_helper_on(struct fb_info *info)
static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
{
	struct drm_fb_helper *fb_helper = info->par;
	struct drm_device *dev = fb_helper->dev;
	struct drm_crtc *crtc;
	struct drm_crtc_helper_funcs *crtc_funcs;
	struct drm_connector *connector;
	struct drm_encoder *encoder;
	int i, j;

	/*
	 * For each CRTC in this fb, turn the crtc on then,
	 * find all associated encoders and turn them on.
	 */
	mutex_lock(&dev->mode_config.mutex);
	for (i = 0; i < fb_helper->crtc_count; i++) {
		crtc = fb_helper->crtc_info[i].mode_set.crtc;
		crtc_funcs = crtc->helper_private;

		if (!crtc->enabled)
			continue;

		crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);

		/* Walk the connectors & encoders on this fb turning them on */
		for (j = 0; j < fb_helper->connector_count; j++) {
			connector = fb_helper->connector_info[j]->connector;
			connector->dpms = DRM_MODE_DPMS_ON;
			drm_connector_property_set_value(connector,
							 dev->mode_config.dpms_property,
							 DRM_MODE_DPMS_ON);
		}
		/* Found a CRTC on this fb, now find encoders */
		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
			if (encoder->crtc == crtc) {
				struct drm_encoder_helper_funcs *encoder_funcs;

				encoder_funcs = encoder->helper_private;
				encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
			}
		}
	}
	mutex_unlock(&dev->mode_config.mutex);
}

static void drm_fb_helper_off(struct fb_info *info, int dpms_mode)
{
	struct drm_fb_helper *fb_helper = info->par;
	struct drm_device *dev = fb_helper->dev;
	struct drm_crtc *crtc;
	struct drm_crtc_helper_funcs *crtc_funcs;
	struct drm_connector *connector;
	struct drm_encoder *encoder;
	int i, j;

	/*
	 * For each CRTC in this fb, find all associated encoders
	 * and turn them off, then turn off the CRTC.
	 * For each CRTC in this fb, turn the connectors on/off.
	 */
	mutex_lock(&dev->mode_config.mutex);
	for (i = 0; i < fb_helper->crtc_count; i++) {
		crtc = fb_helper->crtc_info[i].mode_set.crtc;
		crtc_funcs = crtc->helper_private;

		if (!crtc->enabled)
			continue;

		/* Walk the connectors on this fb and mark them off */
		/* Walk the connectors & encoders on this fb turning them on/off */
		for (j = 0; j < fb_helper->connector_count; j++) {
			connector = fb_helper->connector_info[j]->connector;
			connector->dpms = dpms_mode;
			drm_helper_connector_dpms(connector, dpms_mode);
			drm_connector_property_set_value(connector,
							 dev->mode_config.dpms_property,
							 dpms_mode);
		}
		/* Found a CRTC on this fb, now find encoders */
		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
			if (encoder->crtc == crtc) {
				struct drm_encoder_helper_funcs *encoder_funcs;

				encoder_funcs = encoder->helper_private;
				encoder_funcs->dpms(encoder, dpms_mode);
			}
				dev->mode_config.dpms_property, dpms_mode);
		}
		crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
	}
	mutex_unlock(&dev->mode_config.mutex);
}
@@ -400,23 +340,23 @@ int drm_fb_helper_blank(int blank, struct fb_info *info)
	switch (blank) {
	/* Display: On; HSync: On, VSync: On */
	case FB_BLANK_UNBLANK:
		drm_fb_helper_on(info);
		drm_fb_helper_dpms(info, DRM_MODE_DPMS_ON);
		break;
	/* Display: Off; HSync: On, VSync: On */
	case FB_BLANK_NORMAL:
		drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
		drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY);
		break;
	/* Display: Off; HSync: Off, VSync: On */
	case FB_BLANK_HSYNC_SUSPEND:
		drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
		drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY);
		break;
	/* Display: Off; HSync: On, VSync: Off */
	case FB_BLANK_VSYNC_SUSPEND:
		drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND);
		drm_fb_helper_dpms(info, DRM_MODE_DPMS_SUSPEND);
		break;
	/* Display: Off; HSync: Off, VSync: Off */
	case FB_BLANK_POWERDOWN:
		drm_fb_helper_off(info, DRM_MODE_DPMS_OFF);
		drm_fb_helper_dpms(info, DRM_MODE_DPMS_OFF);
		break;
	}
	return 0;
@@ -430,8 +370,11 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
	for (i = 0; i < helper->connector_count; i++)
		kfree(helper->connector_info[i]);
	kfree(helper->connector_info);
	for (i = 0; i < helper->crtc_count; i++)
	for (i = 0; i < helper->crtc_count; i++) {
		kfree(helper->crtc_info[i].mode_set.connectors);
		if (helper->crtc_info[i].mode_set.mode)
			drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode);
	}
	kfree(helper->crtc_info);
}

@@ -474,11 +417,10 @@ int drm_fb_helper_init(struct drm_device *dev,

	i = 0;
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
		fb_helper->crtc_info[i].crtc_id = crtc->base.id;
		fb_helper->crtc_info[i].mode_set.crtc = crtc;
		i++;
	}
	fb_helper->conn_limit = max_conn_count;

	return 0;
out_free:
	drm_fb_helper_crtc_free(fb_helper);
Loading