Skip to content

Commit 5463430

Browse files
Lawstorant1Naim
authored andcommitted
drm: Add ALLM properties to connector
Adds HDMI Auto Low Latency Mode optional connector properties allm_mode and allm_mode_capable. ALLM automatically puts TVs into low latency modes (gaming modes) and it's part of the HDMI Gaming Features introduced in HDMI 2.1. allm_mode_capable indicates whether connector (sink) supports ALLM allm_mode tells the driver which triggering mode to use. Off, dynamic and always on. Dynamic mode should consider the content type and the state of the crtc to discern whether ALLM should be activated. Recommendation is Content Type Hint == Game || VRR_ENABLED based on testing behaviors on other operating systems and multiple GPU vendors + how TVs behave. Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>
1 parent 05773e6 commit 5463430

3 files changed

Lines changed: 156 additions & 0 deletions

File tree

drivers/gpu/drm/drm_atomic_uapi.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
905905
state->content_type = val;
906906
} else if (property == connector->scaling_mode_property) {
907907
state->scaling_mode = val;
908+
} else if (property == connector->allm_mode_property) {
909+
state->allm_mode = val;
908910
} else if (property == config->content_protection_property) {
909911
if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
910912
drm_dbg_kms(dev, "only drivers can set CP Enabled\n");
@@ -1002,6 +1004,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
10021004
*val = state->colorspace;
10031005
} else if (property == connector->scaling_mode_property) {
10041006
*val = state->scaling_mode;
1007+
} else if (property == connector->allm_mode_property) {
1008+
*val = state->allm_mode;
10051009
} else if (property == config->hdr_output_metadata_property) {
10061010
*val = state->hdr_output_metadata ?
10071011
state->hdr_output_metadata->base.id : 0;

drivers/gpu/drm/drm_connector.c

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,12 @@ static const struct drm_prop_enum_list drm_content_type_enum_list[] = {
12321232
{ DRM_MODE_CONTENT_TYPE_GAME, "Game" },
12331233
};
12341234

1235+
static const struct drm_prop_enum_list drm_allm_mode_enum_list[] = {
1236+
{ DRM_ALLM_MODE_DISABLED, "Disabled" },
1237+
{ DRM_ALLM_MODE_ENABLED_DYNAMIC, "Dynamic" },
1238+
{ DRM_ALLM_MODE_ENABLED_FORCED, "Always On" },
1239+
};
1240+
12351241
static const struct drm_prop_enum_list drm_panel_orientation_enum_list[] = {
12361242
{ DRM_MODE_PANEL_ORIENTATION_NORMAL, "Normal" },
12371243
{ DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP, "Upside Down" },
@@ -2455,6 +2461,94 @@ int drm_connector_attach_passive_vrr_capable_property(
24552461
}
24562462
EXPORT_SYMBOL(drm_connector_attach_passive_vrr_capable_property);
24572463

2464+
/**
2465+
* DOC: Auto Low Latency Mode properties
2466+
*
2467+
* Auto Low Latency capable HDMI displays (be it PC monitors or TVs)
2468+
* can automatically enter a "low latency" mode, usually named "Game Mode" by
2469+
* receiving specific data in HDMI Forum vendor-specific info frame.
2470+
*
2471+
* This usually is the best mode for PC usage but disables as much processing as
2472+
* possible which might not be desireable on lower end devices casing them to
2473+
* produce an image that's unsatisfactory to some users.
2474+
*
2475+
* "allm_capable":
2476+
* Optional &drm_connector boolean property that drivers should attach
2477+
* with drm_connector_attach_allm_capable_property() on connectors that
2478+
* could support Auto Low Latency Mode. Drivers should update the
2479+
* property value by calling drm_connector_set_allm_capable_property().
2480+
*
2481+
* Absence of the property should indicate absence of support.
2482+
*
2483+
* "ALLM_MODE":
2484+
* Optional &drm_connector enum property enables compositors to control and
2485+
* expose ALLM triggering behavior modes to the end user where:
2486+
*
2487+
* - ALLM_MODE_DISABLED: completely disabled ALLM signalling.
2488+
* - ALLM_MODE_ENABLED_DYNAMIC: triggers ALLM based on current needs.
2489+
* preferrably display content type hint being set to Game by compositor
2490+
* or VRR being enabled and active.
2491+
* - ALLM_MODE_ENABLED_FORCED: always-on ALLM triggering.
2492+
*
2493+
* ALLM_MODE_ENABLED_DYNAMIC should behave like gaming devices such as
2494+
* consoles where ALLM is only triggered when needed. It's main purpose is
2495+
* gaming (part of so-called HDMI gaming features).
2496+
*
2497+
* If compositors wish to control ALLM completely on their own, they can
2498+
* switch between disabled and enabled_forced modes.
2499+
*/
2500+
2501+
/**
2502+
* drm_connector_attach_allm_capable_property - creates the
2503+
* allm_capable property
2504+
* @connector: connector to create the allm_capable property on.
2505+
*
2506+
* This is used by atomic drivers to add support for querying
2507+
* Auto Low Latency Mode capability for a connector.
2508+
*
2509+
* Returns:
2510+
* Zero on success, negative errno on failure.
2511+
*/
2512+
int drm_connector_attach_allm_capable_property(struct drm_connector *connector)
2513+
{
2514+
struct drm_device *dev = connector->dev;
2515+
struct drm_property *prop;
2516+
2517+
if (!connector->allm_capable_property) {
2518+
prop = drm_property_create_bool(dev, DRM_MODE_PROP_IMMUTABLE,
2519+
"allm_capable");
2520+
if (!prop)
2521+
return -ENOMEM;
2522+
2523+
connector->allm_capable_property = prop;
2524+
drm_object_attach_property(&connector->base, prop, 0);
2525+
}
2526+
2527+
return 0;
2528+
}
2529+
EXPORT_SYMBOL(drm_connector_attach_allm_capable_property);
2530+
2531+
int drm_connector_attach_allm_mode_property(struct drm_connector *connector)
2532+
{
2533+
struct drm_property *prop;
2534+
2535+
if (connector->allm_mode_property)
2536+
return 0;
2537+
2538+
prop = drm_property_create_enum(connector->dev, 0, "allm_mode",
2539+
drm_allm_mode_enum_list,
2540+
ARRAY_SIZE(drm_allm_mode_enum_list));
2541+
if (!prop)
2542+
return -ENOMEM;
2543+
2544+
connector->allm_mode_property = prop;
2545+
drm_object_attach_property(&connector->base, prop,
2546+
DRM_ALLM_MODE_DISABLED);
2547+
2548+
return 0;
2549+
}
2550+
EXPORT_SYMBOL(drm_connector_attach_allm_mode_property);
2551+
24582552
/**
24592553
* drm_connector_attach_scaling_mode_property - attach atomic scaling mode property
24602554
* @connector: connector to attach scaling mode property on.
@@ -3047,6 +3141,27 @@ void drm_connector_set_passive_vrr_capable_property(
30473141
}
30483142
EXPORT_SYMBOL(drm_connector_set_passive_vrr_capable_property);
30493143

3144+
/**
3145+
* drm_connector_set_allm_capable_property - sets Auto Low Latency Mode
3146+
* capable property for a connector
3147+
* @connector: drm connector
3148+
* @capable: True if the connector is ALLM capable
3149+
*
3150+
* Should be used by atomic drivers to update the indicated support for
3151+
* Auto Low Latency Mode over a connector.
3152+
*/
3153+
void drm_connector_set_allm_capable_property(
3154+
struct drm_connector *connector, bool capable)
3155+
{
3156+
if (!connector->allm_capable_property)
3157+
return;
3158+
3159+
drm_object_property_set_value(&connector->base,
3160+
connector->allm_capable_property,
3161+
capable);
3162+
}
3163+
EXPORT_SYMBOL(drm_connector_set_allm_capable_property);
3164+
30503165
/**
30513166
* drm_connector_set_panel_orientation - sets the connector's panel_orientation
30523167
* @connector: connector for which to set the panel-orientation property.

include/drm/drm_connector.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ enum drm_connector_force {
5858
DRM_FORCE_ON_DIGITAL, /* for DVI-I use digital connector */
5959
};
6060

61+
enum drm_allm_mode {
62+
DRM_ALLM_MODE_DISABLED,
63+
DRM_ALLM_MODE_ENABLED_DYNAMIC,
64+
DRM_ALLM_MODE_ENABLED_FORCED,
65+
};
66+
6167
/**
6268
* enum drm_connector_status - status for a &drm_connector
6369
*
@@ -1147,6 +1153,13 @@ struct drm_connector_state {
11471153
*/
11481154
unsigned int content_protection;
11491155

1156+
/**
1157+
* @allm_mode: Connector property to control the
1158+
* HDMI Auto Low Latency Mode trigger setting.
1159+
* The %DRM_ALLM_MODE_\* values must match the values.
1160+
*/
1161+
enum drm_allm_mode allm_mode;
1162+
11501163
/**
11511164
* @colorspace: State variable for Connector property to request
11521165
* colorspace change on Sink. This is most commonly used to switch
@@ -2157,6 +2170,26 @@ struct drm_connector {
21572170
*/
21582171
struct drm_property *passive_vrr_capable_property;
21592172

2173+
/**
2174+
* @allm_capable_property: Optional property to help userspace
2175+
* query hardware support for HDMI Auto Low Latency Mode on a connector.
2176+
* Drivers can add the property to a connector by calling
2177+
* drm_connector_attach_allm_capable_property().
2178+
*
2179+
* This should be updated only by calling
2180+
* drm_connector_set_allm_capable_property().
2181+
*/
2182+
struct drm_property *allm_capable_property;
2183+
2184+
/**
2185+
* @allm_mode_property:
2186+
*
2187+
* Indicates HDMI Auto Low Latency Mode triggering mode for connector.
2188+
* Support for the requested state will depend on driver and hardware
2189+
* capabiltiy - lacking support is not treated as failure.
2190+
*/
2191+
struct drm_property *allm_mode_property;
2192+
21602193
/**
21612194
* @colorspace_property: Connector property to set the suitable
21622195
* colorspace supported by the sink.
@@ -2553,6 +2586,8 @@ int drm_connector_attach_vrr_capable_property(
25532586
struct drm_connector *connector);
25542587
int drm_connector_attach_passive_vrr_capable_property(
25552588
struct drm_connector *connector);
2589+
int drm_connector_attach_allm_capable_property(struct drm_connector *connector);
2590+
int drm_connector_attach_allm_mode_property(struct drm_connector *connector);
25562591
int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector);
25572592
int drm_connector_attach_colorspace_property(struct drm_connector *connector);
25582593
int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector);
@@ -2577,6 +2612,8 @@ void drm_connector_set_vrr_capable_property(
25772612
struct drm_connector *connector, bool capable);
25782613
void drm_connector_set_passive_vrr_capable_property(
25792614
struct drm_connector *connector, bool capable);
2615+
void drm_connector_set_allm_capable_property(
2616+
struct drm_connector *connector, bool capable);
25802617
int drm_connector_set_panel_orientation(
25812618
struct drm_connector *connector,
25822619
enum drm_panel_orientation panel_orientation);

0 commit comments

Comments
 (0)