Commit 8f6e1e22 authored by Maarten Lankhorst's avatar Maarten Lankhorst

drm/atomic: Add support for custom scaling mode properties, v2

Some connectors may not allow all scaling mode properties, this function will allow
creating the scaling mode property with only the supported subset. It also wires up
this state for atomic.

This will make it possible to convert i915 connectors to atomic.

Changes since v1:
 - Add DRM_MODE_PROP_ENUM flag to drm_property_create
 - Use the correct index in drm_property_add_enum.
 - Add DocBook for function (Sean Paul).
 - Warn if less than 2 valid scaling modes are passed.
 - Remove level of indent. (Sean Paul)
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170501133804.8116-3-maarten.lankhorst@linux.intel.com
[mlankhorst: Rename function, fix docbook issues]
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 0e9f25d0
...@@ -1190,6 +1190,8 @@ int drm_atomic_connector_set_property(struct drm_connector *connector, ...@@ -1190,6 +1190,8 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
state->link_status = val; state->link_status = val;
} else if (property == config->aspect_ratio_property) { } else if (property == config->aspect_ratio_property) {
state->picture_aspect_ratio = val; state->picture_aspect_ratio = val;
} else if (property == connector->scaling_mode_property) {
state->scaling_mode = val;
} else if (connector->funcs->atomic_set_property) { } else if (connector->funcs->atomic_set_property) {
return connector->funcs->atomic_set_property(connector, return connector->funcs->atomic_set_property(connector,
state, property, val); state, property, val);
...@@ -1268,6 +1270,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector, ...@@ -1268,6 +1270,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
*val = state->link_status; *val = state->link_status;
} else if (property == config->aspect_ratio_property) { } else if (property == config->aspect_ratio_property) {
*val = state->picture_aspect_ratio; *val = state->picture_aspect_ratio;
} else if (property == connector->scaling_mode_property) {
*val = state->scaling_mode;
} else if (connector->funcs->atomic_get_property) { } else if (connector->funcs->atomic_get_property) {
return connector->funcs->atomic_get_property(connector, return connector->funcs->atomic_get_property(connector,
state, property, val); state, property, val);
......
...@@ -941,6 +941,10 @@ EXPORT_SYMBOL(drm_mode_create_tv_properties); ...@@ -941,6 +941,10 @@ EXPORT_SYMBOL(drm_mode_create_tv_properties);
* *
* Called by a driver the first time it's needed, must be attached to desired * Called by a driver the first time it's needed, must be attached to desired
* connectors. * connectors.
*
* Atomic drivers should use drm_connector_attach_scaling_mode_property()
* instead to correctly assign &drm_connector_state.picture_aspect_ratio
* in the atomic state.
*/ */
int drm_mode_create_scaling_mode_property(struct drm_device *dev) int drm_mode_create_scaling_mode_property(struct drm_device *dev)
{ {
...@@ -960,6 +964,66 @@ int drm_mode_create_scaling_mode_property(struct drm_device *dev) ...@@ -960,6 +964,66 @@ int drm_mode_create_scaling_mode_property(struct drm_device *dev)
} }
EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
/**
* drm_connector_attach_scaling_mode_property - attach atomic scaling mode property
* @connector: connector to attach scaling mode property on.
* @scaling_mode_mask: or'ed mask of BIT(%DRM_MODE_SCALE_\*).
*
* This is used to add support for scaling mode to atomic drivers.
* The scaling mode will be set to &drm_connector_state.picture_aspect_ratio
* and can be used from &drm_connector_helper_funcs->atomic_check for validation.
*
* This is the atomic version of drm_mode_create_scaling_mode_property().
*
* Returns:
* Zero on success, negative errno on failure.
*/
int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
u32 scaling_mode_mask)
{
struct drm_device *dev = connector->dev;
struct drm_property *scaling_mode_property;
int i, j = 0;
const unsigned valid_scaling_mode_mask =
(1U << ARRAY_SIZE(drm_scaling_mode_enum_list)) - 1;
if (WARN_ON(hweight32(scaling_mode_mask) < 2 ||
scaling_mode_mask & ~valid_scaling_mode_mask))
return -EINVAL;
scaling_mode_property =
drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode",
hweight32(scaling_mode_mask));
if (!scaling_mode_property)
return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++) {
int ret;
if (!(BIT(i) & scaling_mode_mask))
continue;
ret = drm_property_add_enum(scaling_mode_property, j++,
drm_scaling_mode_enum_list[i].type,
drm_scaling_mode_enum_list[i].name);
if (ret) {
drm_property_destroy(dev, scaling_mode_property);
return ret;
}
}
drm_object_attach_property(&connector->base,
scaling_mode_property, 0);
connector->scaling_mode_property = scaling_mode_property;
return 0;
}
EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property);
/** /**
* drm_mode_create_aspect_ratio_property - create aspect ratio property * drm_mode_create_aspect_ratio_property - create aspect ratio property
* @dev: DRM device * @dev: DRM device
......
...@@ -332,10 +332,16 @@ struct drm_connector_state { ...@@ -332,10 +332,16 @@ struct drm_connector_state {
* @picture_aspect_ratio: Connector property to control the * @picture_aspect_ratio: Connector property to control the
* HDMI infoframe aspect ratio setting. * HDMI infoframe aspect ratio setting.
* *
* The DRM_MODE_PICTURE_ASPECT_\* values much match the * The %DRM_MODE_PICTURE_ASPECT_\* values much match the
* values for &enum hdmi_picture_aspect * values for &enum hdmi_picture_aspect
*/ */
enum hdmi_picture_aspect picture_aspect_ratio; enum hdmi_picture_aspect picture_aspect_ratio;
/**
* @scaling_mode: Connector property to control the
* upscaling, mostly used for built-in panels.
*/
unsigned int scaling_mode;
}; };
/** /**
...@@ -685,6 +691,7 @@ struct drm_cmdline_mode { ...@@ -685,6 +691,7 @@ struct drm_cmdline_mode {
* @tile_v_loc: vertical location of this tile * @tile_v_loc: vertical location of this tile
* @tile_h_size: horizontal size of this tile. * @tile_h_size: horizontal size of this tile.
* @tile_v_size: vertical size of this tile. * @tile_v_size: vertical size of this tile.
* @scaling_mode_property: Optional atomic property to control the upscaling.
* *
* Each connector may be connected to one or more CRTCs, or may be clonable by * Each connector may be connected to one or more CRTCs, or may be clonable by
* another connector if they can share a CRTC. Each connector also has a specific * another connector if they can share a CRTC. Each connector also has a specific
...@@ -764,6 +771,8 @@ struct drm_connector { ...@@ -764,6 +771,8 @@ struct drm_connector {
struct drm_property_blob *edid_blob_ptr; struct drm_property_blob *edid_blob_ptr;
struct drm_object_properties properties; struct drm_object_properties properties;
struct drm_property *scaling_mode_property;
/** /**
* @path_blob_ptr: * @path_blob_ptr:
* *
...@@ -963,6 +972,8 @@ int drm_mode_create_tv_properties(struct drm_device *dev, ...@@ -963,6 +972,8 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
unsigned int num_modes, unsigned int num_modes,
const char * const modes[]); const char * const modes[]);
int drm_mode_create_scaling_mode_property(struct drm_device *dev); int drm_mode_create_scaling_mode_property(struct drm_device *dev);
int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
u32 scaling_mode_mask);
int drm_mode_create_aspect_ratio_property(struct drm_device *dev); int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
int drm_mode_create_suggested_offset_properties(struct drm_device *dev); int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment