drm: Add a rotation parameter to connectors.

Some connectors, particularly writeback, can implement flip
or transpose operations as writing back to memory.

Add a connector rotation property to control this.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
This commit is contained in:
Dave Stevenson
2024-10-22 17:22:40 +01:00
committed by Dom Cobley
parent 97026bb399
commit 9af84eeaf1
4 changed files with 60 additions and 10 deletions

View File

@@ -793,6 +793,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
state->privacy_screen_sw_state = val; state->privacy_screen_sw_state = val;
} else if (property == connector->broadcast_rgb_property) { } else if (property == connector->broadcast_rgb_property) {
state->hdmi.broadcast_rgb = val; state->hdmi.broadcast_rgb = val;
} else if (property == connector->rotation_property) {
state->rotation = 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);
@@ -884,6 +886,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
*val = state->privacy_screen_sw_state; *val = state->privacy_screen_sw_state;
} else if (property == connector->broadcast_rgb_property) { } else if (property == connector->broadcast_rgb_property) {
*val = state->hdmi.broadcast_rgb; *val = state->hdmi.broadcast_rgb;
} else if (property == connector->rotation_property) {
*val = state->rotation;
} 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);

View File

@@ -241,6 +241,16 @@ int drm_plane_create_alpha_property(struct drm_plane *plane)
} }
EXPORT_SYMBOL(drm_plane_create_alpha_property); EXPORT_SYMBOL(drm_plane_create_alpha_property);
static const struct drm_prop_enum_list drm_rotate_props[] = {
{ __builtin_ffs(DRM_MODE_ROTATE_0) - 1, "rotate-0" },
{ __builtin_ffs(DRM_MODE_ROTATE_90) - 1, "rotate-90" },
{ __builtin_ffs(DRM_MODE_ROTATE_180) - 1, "rotate-180" },
{ __builtin_ffs(DRM_MODE_ROTATE_270) - 1, "rotate-270" },
{ __builtin_ffs(DRM_MODE_REFLECT_X) - 1, "reflect-x" },
{ __builtin_ffs(DRM_MODE_REFLECT_Y) - 1, "reflect-y" },
{ __builtin_ffs(DRM_MODE_TRANSPOSE) - 1, "transpose" },
};
/** /**
* drm_plane_create_rotation_property - create a new rotation property * drm_plane_create_rotation_property - create a new rotation property
* @plane: drm plane * @plane: drm plane
@@ -281,15 +291,6 @@ int drm_plane_create_rotation_property(struct drm_plane *plane,
unsigned int rotation, unsigned int rotation,
unsigned int supported_rotations) unsigned int supported_rotations)
{ {
static const struct drm_prop_enum_list props[] = {
{ __builtin_ffs(DRM_MODE_ROTATE_0) - 1, "rotate-0" },
{ __builtin_ffs(DRM_MODE_ROTATE_90) - 1, "rotate-90" },
{ __builtin_ffs(DRM_MODE_ROTATE_180) - 1, "rotate-180" },
{ __builtin_ffs(DRM_MODE_ROTATE_270) - 1, "rotate-270" },
{ __builtin_ffs(DRM_MODE_REFLECT_X) - 1, "reflect-x" },
{ __builtin_ffs(DRM_MODE_REFLECT_Y) - 1, "reflect-y" },
{ __builtin_ffs(DRM_MODE_TRANSPOSE) - 1, "transpose" },
};
struct drm_property *prop; struct drm_property *prop;
WARN_ON((supported_rotations & DRM_MODE_ROTATE_MASK) == 0); WARN_ON((supported_rotations & DRM_MODE_ROTATE_MASK) == 0);
@@ -297,7 +298,8 @@ int drm_plane_create_rotation_property(struct drm_plane *plane,
WARN_ON(rotation & ~supported_rotations); WARN_ON(rotation & ~supported_rotations);
prop = drm_property_create_bitmask(plane->dev, 0, "rotation", prop = drm_property_create_bitmask(plane->dev, 0, "rotation",
props, ARRAY_SIZE(props), drm_rotate_props,
ARRAY_SIZE(drm_rotate_props),
supported_rotations); supported_rotations);
if (!prop) if (!prop)
return -ENOMEM; return -ENOMEM;
@@ -313,6 +315,34 @@ int drm_plane_create_rotation_property(struct drm_plane *plane,
} }
EXPORT_SYMBOL(drm_plane_create_rotation_property); EXPORT_SYMBOL(drm_plane_create_rotation_property);
int drm_connector_create_rotation_property(struct drm_connector *conn,
unsigned int rotation,
unsigned int supported_rotations)
{
struct drm_property *prop;
WARN_ON((supported_rotations & DRM_MODE_ROTATE_MASK) == 0);
WARN_ON(!is_power_of_2(rotation & DRM_MODE_ROTATE_MASK));
WARN_ON(rotation & ~supported_rotations);
prop = drm_property_create_bitmask(conn->dev, 0, "rotation",
drm_rotate_props,
ARRAY_SIZE(drm_rotate_props),
supported_rotations);
if (!prop)
return -ENOMEM;
drm_object_attach_property(&conn->base, prop, rotation);
if (conn->state)
conn->state->rotation = rotation;
conn->rotation_property = prop;
return 0;
}
EXPORT_SYMBOL(drm_connector_create_rotation_property);
/** /**
* drm_rotation_simplify() - Try to simplify the rotation * drm_rotation_simplify() - Try to simplify the rotation
* @rotation: Rotation to be simplified * @rotation: Rotation to be simplified

View File

@@ -34,6 +34,7 @@
struct drm_device; struct drm_device;
struct drm_atomic_state; struct drm_atomic_state;
struct drm_plane; struct drm_plane;
struct drm_connector;
static inline bool drm_rotation_90_or_270(unsigned int rotation) static inline bool drm_rotation_90_or_270(unsigned int rotation)
{ {
@@ -58,4 +59,8 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
struct drm_atomic_state *state); struct drm_atomic_state *state);
int drm_plane_create_blend_mode_property(struct drm_plane *plane, int drm_plane_create_blend_mode_property(struct drm_plane *plane,
unsigned int supported_modes); unsigned int supported_modes);
int drm_connector_create_rotation_property(struct drm_connector *conn,
unsigned int rotation,
unsigned int supported_rotations);
#endif #endif

View File

@@ -1149,6 +1149,11 @@ struct drm_connector_state {
* @drm_atomic_helper_connector_hdmi_check(). * @drm_atomic_helper_connector_hdmi_check().
*/ */
struct drm_connector_hdmi_state hdmi; struct drm_connector_hdmi_state hdmi;
/**
* @rotation: Connector property to rotate the maximum output image.
*/
u32 rotation;
}; };
struct drm_connector_hdmi_audio_funcs { struct drm_connector_hdmi_audio_funcs {
@@ -2103,6 +2108,12 @@ struct drm_connector {
*/ */
struct drm_property *broadcast_rgb_property; struct drm_property *broadcast_rgb_property;
/**
* @rotation_property: Optional DRM property controlling rotation of the
* output.
*/
struct drm_property *rotation_property;
#define DRM_CONNECTOR_POLL_HPD (1 << 0) #define DRM_CONNECTOR_POLL_HPD (1 << 0)
#define DRM_CONNECTOR_POLL_CONNECT (1 << 1) #define DRM_CONNECTOR_POLL_CONNECT (1 << 1)
#define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2) #define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2)