Skip to content
Commits on Source (6)
  • Pekka Paalanen's avatar
    backend-drm: move *_add_prop() debug earlier · dbce396c
    Pekka Paalanen authored and Daniel Stone's avatar Daniel Stone committed
    
    
    Move the debug printing before the bail-out if the property does not
    exist. This means that trying to set a missing property will be logged,
    and it can be identified by the property id being 0.
    
    We are starting to program more KMS properties, and if KMS state
    building fails, this gives better chances to figure out what happened.
    For example, if we accidentally assume that some property always exists
    when it doesn't.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    dbce396c
  • Pekka Paalanen's avatar
    backend-drm: reset CRTC_GAMMA_LUT · debfeb30
    Pekka Paalanen authored and Daniel Stone's avatar Daniel Stone committed
    
    
    We are assuming that CRTC_GAMMA_LUT is pass-through, so better ensure it
    really is pass-through rather than whatever the previous KMS client left
    there.
    
    Unfortunately, we have old drm_output_set_gamma() API that cms-static
    and cms-colord plugins are using. To avoid trampling over them, do not
    touch gamma after they did. Those plugins are deprecated, so there is no
    reason to make set_gamma work through atomic.
    
    drm_output_set_gamma() is called from weston_compositor_add_output()
    through the output_created_signal. This is after drm_output_enable() and
    before any KMS modeset or atomic commit on the CRTC. Therefore it is not
    possible that there would be any KMS action in flight when
    drm_output_set_gamma() is called, and so setting deprecated_gamma_is_set
    should be non-racy - like setting CRTC_GAMMA_LUT itself.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    debfeb30
  • Pekka Paalanen's avatar
    backend-drm: reset gamma on legacy KMS · 1acf69ac
    Pekka Paalanen authored and Daniel Stone's avatar Daniel Stone committed
    
    
    We are assuming that gamma LUT is pass-through, so better ensure it
    really is pass-through rather than whatever the previous KMS client left
    there.
    
    Unfortunately the legacy ioctl does not offer any way to reset the LUT
    without actually crafting an identity LUT.
    
    If the legacy gamma libdrm function indicates the feature is not
    supported, do not try to use it again. This avoids hammering the legacy
    gamma every frame when deprecated drm_output_set_gamma() is not used.
    
    drm_output_set_gamma() is not updated to check/set this flag in order to
    maintain its old behavior.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    1acf69ac
  • Pekka Paalanen's avatar
    backend-drm: reset CRTC_DEGAMMA_LUT · d1ca5f71
    Pekka Paalanen authored and Daniel Stone's avatar Daniel Stone committed
    
    
    We are assuming that CRTC_DEGAMMA_LUT is pass-through, so better ensure
    it really is pass-through rather than whatever the previous KMS client
    left there.
    
    This too falls under deprecated_gamma_is_set check, because the legacy
    gamma could use either GAMMA or DEGAMMA.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    d1ca5f71
  • Pekka Paalanen's avatar
    backend-drm: reset CRTC_CTM · e0d267fb
    Pekka Paalanen authored and Daniel Stone's avatar Daniel Stone committed
    
    
    We are assuming that CRTC_CTM is pass-through, so better ensure it
    really is pass-through rather than whatever the previous KMS client left
    there.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    e0d267fb
  • Pekka Paalanen's avatar
    backend-drm: reset CRTC_VRR_ENABLED · 40999363
    Pekka Paalanen authored and Daniel Stone's avatar Daniel Stone committed
    
    
    Libweston has no support for VRR yet, so make sure it cannot be on by
    accident.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    40999363
......@@ -236,6 +236,12 @@ enum wdrm_content_type {
enum wdrm_crtc_property {
WDRM_CRTC_MODE_ID = 0,
WDRM_CRTC_ACTIVE,
WDRM_CRTC_CTM,
WDRM_CRTC_DEGAMMA_LUT,
WDRM_CRTC_DEGAMMA_LUT_SIZE,
WDRM_CRTC_GAMMA_LUT,
WDRM_CRTC_GAMMA_LUT_SIZE,
WDRM_CRTC_VRR_ENABLED,
WDRM_CRTC__COUNT
};
......@@ -573,6 +579,9 @@ struct drm_output {
unsigned max_bpc;
bool deprecated_gamma_is_set;
bool legacy_gamma_not_supported;
/* Plane being displayed directly on the CRTC */
struct drm_plane *scanout_plane;
......
......@@ -165,6 +165,12 @@ const struct drm_property_info connector_props[] = {
const struct drm_property_info crtc_props[] = {
[WDRM_CRTC_MODE_ID] = { .name = "MODE_ID", },
[WDRM_CRTC_ACTIVE] = { .name = "ACTIVE", },
[WDRM_CRTC_CTM] = { .name = "CTM", },
[WDRM_CRTC_DEGAMMA_LUT] = { .name = "DEGAMMA_LUT", },
[WDRM_CRTC_DEGAMMA_LUT_SIZE] = { .name = "DEGAMMA_LUT_SIZE", },
[WDRM_CRTC_GAMMA_LUT] = { .name = "GAMMA_LUT", },
[WDRM_CRTC_GAMMA_LUT_SIZE] = { .name = "GAMMA_LUT_SIZE", },
[WDRM_CRTC_VRR_ENABLED] = { .name = "VRR_ENABLED", },
};
......@@ -507,6 +513,7 @@ drm_output_set_gamma(struct weston_output *output_base,
if (output_base->gamma_size != size)
return;
output->deprecated_gamma_is_set = true;
rc = drmModeCrtcSetGamma(device->drm.fd,
output->crtc->crtc_id,
size, r, g, b);
......@@ -633,6 +640,41 @@ err:
drmModeSetCursor(device->drm.fd, crtc->crtc_id, 0, 0, 0);
}
static void
drm_output_reset_legacy_gamma(struct drm_output *output)
{
uint32_t len = output->base.gamma_size;
uint16_t *lut;
uint32_t i;
int ret;
if (len == 0)
return;
if (output->legacy_gamma_not_supported)
return;
lut = calloc(len, sizeof(uint16_t));
if (!lut)
return;
/* Identity curve */
for (i = 0; i < len; i++)
lut[i] = 0xffff * i / (len - 1);
ret = drmModeCrtcSetGamma(output->device->drm.fd,
output->crtc->crtc_id,
len, lut, lut, lut);
if (ret == -EOPNOTSUPP || ret == -ENOSYS)
output->legacy_gamma_not_supported = true;
else if (ret < 0) {
weston_log("%s failed for %s: %s\n", __func__,
output->base.name, strerror(-ret));
}
free(lut);
}
static int
drm_output_apply_state_legacy(struct drm_output_state *state)
{
......@@ -725,6 +767,9 @@ drm_output_apply_state_legacy(struct drm_output_state *state)
weston_log("set mode failed: %s\n", strerror(errno));
goto err;
}
if (!output->deprecated_gamma_is_set)
drm_output_reset_legacy_gamma(output);
}
pinfo = scanout_state->fb->format;
......@@ -783,18 +828,49 @@ crtc_add_prop(drmModeAtomicReq *req, struct drm_crtc *crtc,
struct drm_property_info *info = &crtc->props_crtc[prop];
int ret;
drm_debug(b, "\t\t\t[CRTC:%lu] %lu (%s) -> %llu (0x%llx)\n",
(unsigned long) crtc->crtc_id,
(unsigned long) info->prop_id, info->name,
(unsigned long long) val, (unsigned long long) val);
if (info->prop_id == 0)
return -1;
ret = drmModeAtomicAddProperty(req, crtc->crtc_id, info->prop_id,
val);
drm_debug(b, "\t\t\t[CRTC:%lu] %lu (%s) -> %llu (0x%llx)\n",
(unsigned long) crtc->crtc_id,
(unsigned long) info->prop_id, info->name,
(unsigned long long) val, (unsigned long long) val);
return (ret <= 0) ? -1 : 0;
}
/** Set a CRTC property, allowing zero value for non-existing property
*
* \param req The atomic KMS request to append to.
* \param crtc The CRTC whose property to set.
* \param prop Which CRTC property to set.
* \param val The value, cast to u64, to set to the CRTC property.
* \return 0 on succcess, -1 on failure.
*
* If the property does not exist, attempting to set it to value
* zero is ok, because the property with value zero has the same
* KMS effect as the property not existing.
*
* However, trying to set a non-existing property to a non-zero value
* must fail, because that would not achieve the desired KMS effect.
*
* It is up to the caller to understand which KMS properties work
* like this and which do not.
*/
static int
crtc_add_prop_zero_ok(drmModeAtomicReq *req, struct drm_crtc *crtc,
enum wdrm_crtc_property prop, uint64_t val)
{
struct drm_property_info *info = &crtc->props_crtc[prop];
if (info->prop_id == 0 && val == 0)
return 0;
return crtc_add_prop(req, crtc, prop, val);
}
static int
connector_add_prop(drmModeAtomicReq *req, struct drm_connector *connector,
enum wdrm_connector_property prop, uint64_t val)
......@@ -805,14 +881,15 @@ connector_add_prop(drmModeAtomicReq *req, struct drm_connector *connector,
uint32_t connector_id = connector->connector_id;
int ret;
if (info->prop_id == 0)
return -1;
ret = drmModeAtomicAddProperty(req, connector_id, info->prop_id, val);
drm_debug(b, "\t\t\t[CONN:%lu] %lu (%s) -> %llu (0x%llx)\n",
(unsigned long) connector_id,
(unsigned long) info->prop_id, info->name,
(unsigned long long) val, (unsigned long long) val);
if (info->prop_id == 0)
return -1;
ret = drmModeAtomicAddProperty(req, connector_id, info->prop_id, val);
return (ret <= 0) ? -1 : 0;
}
......@@ -825,15 +902,16 @@ plane_add_prop(drmModeAtomicReq *req, struct drm_plane *plane,
struct drm_property_info *info = &plane->props[prop];
int ret;
drm_debug(b, "\t\t\t[PLANE:%lu] %lu (%s) -> %llu (0x%llx)\n",
(unsigned long) plane->plane_id,
(unsigned long) info->prop_id, info->name,
(unsigned long long) val, (unsigned long long) val);
if (info->prop_id == 0)
return -1;
ret = drmModeAtomicAddProperty(req, plane->plane_id, info->prop_id,
val);
drm_debug(b, "\t\t\t[PLANE:%lu] %lu (%s) -> %llu (0x%llx)\n",
(unsigned long) plane->plane_id,
(unsigned long) info->prop_id, info->name,
(unsigned long long) val, (unsigned long long) val);
return (ret <= 0) ? -1 : 0;
}
......@@ -1002,6 +1080,15 @@ drm_output_apply_state_atomic(struct drm_output_state *state,
current_mode->blob_id);
ret |= crtc_add_prop(req, crtc, WDRM_CRTC_ACTIVE, 1);
if (!output->deprecated_gamma_is_set) {
ret |= crtc_add_prop_zero_ok(req, crtc,
WDRM_CRTC_GAMMA_LUT, 0);
ret |= crtc_add_prop_zero_ok(req, crtc,
WDRM_CRTC_DEGAMMA_LUT, 0);
}
ret |= crtc_add_prop_zero_ok(req, crtc, WDRM_CRTC_CTM, 0);
ret |= crtc_add_prop_zero_ok(req, crtc, WDRM_CRTC_VRR_ENABLED, 0);
/* No need for the DPMS property, since it is implicit in
* routing and CRTC activity. */
wl_list_for_each(head, &output->base.head_list, base.output_link) {
......