Merge "drm/msm/sde: set correct timeline at fence create"

This commit is contained in:
Linux Build Service Account 2019-02-13 09:31:36 -08:00 committed by Gerrit - the friendly Code Review server
commit e2a34f151c
2 changed files with 126 additions and 48 deletions

View file

@ -428,6 +428,7 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
struct sde_connector *c_conn;
struct sde_connector_state *c_state;
int idx, rc;
uint64_t fence_fd = 0;
if (!connector || !state || !property) {
SDE_ERROR("invalid argument(s), conn %pK, state %pK, prp %pK\n",
@ -472,6 +473,29 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
SDE_ERROR("prep fb failed, %d\n", rc);
}
break;
case CONNECTOR_PROP_RETIRE_FENCE:
if (!val)
goto end;
/*
* update the the offset to a timeline for commit completion
*/
rc = sde_fence_create(&c_conn->retire_fence, &fence_fd, 1);
if (rc) {
SDE_ERROR("fence create failed rc:%d\n", rc);
goto end;
}
rc = copy_to_user((uint64_t __user *)val, &fence_fd,
sizeof(uint64_t));
if (rc) {
SDE_ERROR("copy to user failed rc:%d\n", rc);
/* fence will be released with timeline update */
put_unused_fd(fence_fd);
rc = -EFAULT;
goto end;
}
break;
case CONNECTOR_PROP_TOPOLOGY_CONTROL:
rc = sde_rm_check_property_topctl(val);
if (rc)
@ -544,12 +568,14 @@ static int sde_connector_atomic_get_property(struct drm_connector *connector,
c_state = to_sde_connector_state(state);
idx = msm_property_index(&c_conn->property_info, property);
if (idx == CONNECTOR_PROP_RETIRE_FENCE)
rc = sde_fence_create(&c_conn->retire_fence, val, 0);
else
if (idx == CONNECTOR_PROP_RETIRE_FENCE) {
*val = ~0;
rc = 0;
} else {
/* get cached property value */
rc = msm_property_atomic_get(&c_conn->property_info,
c_state->property_values, 0, property, val);
}
/* allow for custom override */
if (c_conn->ops.get_property)
@ -931,8 +957,8 @@ struct drm_connector *sde_connector_init(struct drm_device *dev,
"hdr_control", 0x0, 0, ~0, 0,
CONNECTOR_PROP_HDR_CONTROL);
msm_property_install_range(&c_conn->property_info, "RETIRE_FENCE",
0x0, 0, INR_OPEN_MAX, 0, CONNECTOR_PROP_RETIRE_FENCE);
msm_property_install_volatile_range(&c_conn->property_info,
"RETIRE_FENCE", 0x0, 0, ~0, 0, CONNECTOR_PROP_RETIRE_FENCE);
msm_property_install_volatile_signed_range(&c_conn->property_info,
"PLL_DELTA", 0x0, INT_MIN, INT_MAX, 0,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
* Copyright (c) 2014-2019 The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@ -1642,8 +1642,8 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
"input_fence_timeout", 0x0, 0, SDE_CRTC_MAX_INPUT_FENCE_TIMEOUT,
SDE_CRTC_INPUT_FENCE_TIMEOUT, CRTC_PROP_INPUT_FENCE_TIMEOUT);
msm_property_install_range(&sde_crtc->property_info, "output_fence",
0x0, 0, INR_OPEN_MAX, 0x0, CRTC_PROP_OUTPUT_FENCE);
msm_property_install_volatile_range(&sde_crtc->property_info,
"output_fence", 0x0, 0, ~0, 0, CRTC_PROP_OUTPUT_FENCE);
msm_property_install_range(&sde_crtc->property_info,
"output_fence_offset", 0x0, 0, 1, 0,
@ -1708,6 +1708,28 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
kfree(info);
}
static int _sde_crtc_get_output_fence(struct drm_crtc *crtc,
const struct drm_crtc_state *state, uint64_t *val)
{
struct sde_crtc *sde_crtc;
struct sde_crtc_state *cstate;
uint32_t offset;
sde_crtc = to_sde_crtc(crtc);
cstate = to_sde_crtc_state(state);
offset = sde_crtc_get_property(cstate, CRTC_PROP_OUTPUT_FENCE_OFFSET);
/*
* Hwcomposer now queries the fences using the commit list in atomic
* commit ioctl. The offset should be set to next timeline
* which will be incremented during the prepare commit phase
*/
offset++;
return sde_fence_create(&sde_crtc->output_fence, val, offset);
}
/**
* sde_crtc_atomic_set_property - atomically set a crtc drm property
* @crtc: Pointer to drm crtc structure
@ -1724,28 +1746,61 @@ static int sde_crtc_atomic_set_property(struct drm_crtc *crtc,
struct sde_crtc *sde_crtc;
struct sde_crtc_state *cstate;
int idx, ret = -EINVAL;
uint64_t fence_fd = 0;
if (!crtc || !state || !property) {
SDE_ERROR("invalid argument(s)\n");
} else {
sde_crtc = to_sde_crtc(crtc);
cstate = to_sde_crtc_state(state);
ret = msm_property_atomic_set(&sde_crtc->property_info,
cstate->property_values, cstate->property_blobs,
property, val);
if (!ret) {
idx = msm_property_index(&sde_crtc->property_info,
property);
if (idx == CRTC_PROP_INPUT_FENCE_TIMEOUT)
_sde_crtc_set_input_fence_timeout(cstate);
} else {
ret = sde_cp_crtc_set_property(crtc,
property, val);
}
if (ret)
DRM_ERROR("failed to set the property\n");
return -EINVAL;
}
sde_crtc = to_sde_crtc(crtc);
cstate = to_sde_crtc_state(state);
ret = msm_property_atomic_set(&sde_crtc->property_info,
cstate->property_values, cstate->property_blobs,
property, val);
if (!ret) {
idx = msm_property_index(&sde_crtc->property_info,
property);
switch (idx) {
case CRTC_PROP_INPUT_FENCE_TIMEOUT:
_sde_crtc_set_input_fence_timeout(cstate);
break;
case CRTC_PROP_OUTPUT_FENCE:
if (!val)
goto exit;
ret = _sde_crtc_get_output_fence(crtc,
state, &fence_fd);
if (ret) {
SDE_ERROR("fence create failed rc:%d\n", ret);
goto exit;
}
ret = copy_to_user((uint64_t __user *)val, &fence_fd,
sizeof(uint64_t));
if (ret) {
SDE_ERROR("copy to user failed rc:%d\n", ret);
put_unused_fd(fence_fd);
ret = -EFAULT;
goto exit;
}
break;
default:
/* nothing to do */
break;
}
} else {
ret = sde_cp_crtc_set_property(crtc,
property, val);
}
exit:
if (ret)
DRM_ERROR("failed to set the property\n");
return ret;
}
@ -1783,30 +1838,27 @@ static int sde_crtc_atomic_get_property(struct drm_crtc *crtc,
if (!crtc || !state) {
SDE_ERROR("invalid argument(s)\n");
} else {
sde_crtc = to_sde_crtc(crtc);
cstate = to_sde_crtc_state(state);
i = msm_property_index(&sde_crtc->property_info, property);
if (i == CRTC_PROP_OUTPUT_FENCE) {
int offset = sde_crtc_get_property(cstate,
CRTC_PROP_OUTPUT_FENCE_OFFSET);
ret = sde_fence_create(&sde_crtc->output_fence, val,
offset);
if (ret)
SDE_ERROR("fence create failed\n");
} else {
ret = msm_property_atomic_get(&sde_crtc->property_info,
cstate->property_values,
cstate->property_blobs, property, val);
if (ret)
ret = sde_cp_crtc_get_property(crtc,
property, val);
}
if (ret)
DRM_ERROR("get property failed\n");
return -EINVAL;
}
sde_crtc = to_sde_crtc(crtc);
cstate = to_sde_crtc_state(state);
i = msm_property_index(&sde_crtc->property_info, property);
if (i == CRTC_PROP_OUTPUT_FENCE) {
*val = ~0;
ret = 0;
} else {
ret = msm_property_atomic_get(&sde_crtc->property_info,
cstate->property_values,
cstate->property_blobs, property, val);
if (ret)
ret = sde_cp_crtc_get_property(crtc,
property, val);
}
if (ret)
DRM_ERROR("get property failed\n");
return ret;
}