Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2a34f15 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

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

parents cc11fdf3 c021cd0f
Loading
Loading
Loading
Loading
+31 −5
Original line number Diff line number Diff line
@@ -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,
+90 −38
Original line number Diff line number Diff line
/*
 * 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,27 +1746,60 @@ 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 {
		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);
			if (idx == CRTC_PROP_INPUT_FENCE_TIMEOUT)
		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,19 +1838,16 @@ static int sde_crtc_atomic_get_property(struct drm_crtc *crtc,

	if (!crtc || !state) {
		SDE_ERROR("invalid argument(s)\n");
	} else {
		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) {
			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");
		*val = ~0;
		ret = 0;
	} else {
		ret = msm_property_atomic_get(&sde_crtc->property_info,
				cstate->property_values,
@@ -1806,7 +1858,7 @@ static int sde_crtc_atomic_get_property(struct drm_crtc *crtc,
	}
	if (ret)
		DRM_ERROR("get property failed\n");
	}

	return ret;
}