drm/msm/sde: reject commits that only update crtc roi
Add check to reject commits that update the CRTC ROI but do not
update the Connector ROI as well.
Change-Id: I1f9ac169cf899424f7375e361b1f5710c6566207
Signed-off-by: Lloyd Atkinson <latkinso@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/msm_prop.c b/drivers/gpu/drm/msm/msm_prop.c
index ce84b7a..8e85c81 100644
--- a/drivers/gpu/drm/msm/msm_prop.c
+++ b/drivers/gpu/drm/msm/msm_prop.c
@@ -128,6 +128,20 @@
&property_state->dirty_list);
}
+bool msm_property_is_dirty(
+ struct msm_property_info *info,
+ struct msm_property_state *property_state,
+ uint32_t property_idx)
+{
+ if (!info || !property_state || !property_state->values ||
+ property_idx >= info->property_count) {
+ DRM_ERROR("invalid argument(s), idx %u\n", property_idx);
+ return false;
+ }
+
+ return !list_empty(&property_state->values[property_idx].dirty_node);
+}
+
/**
* _msm_property_install_integer - install standard drm range property
* @info: Pointer to property info container struct
diff --git a/drivers/gpu/drm/msm/msm_prop.h b/drivers/gpu/drm/msm/msm_prop.h
index d257a8c..ecc1d0b 100644
--- a/drivers/gpu/drm/msm/msm_prop.h
+++ b/drivers/gpu/drm/msm/msm_prop.h
@@ -316,6 +316,19 @@
int property_idx);
/**
+ * msm_property_is_dirty - check whether a property is dirty
+ * Note: Intended for use during atomic_check before pop_dirty usage
+ * @info: Pointer to property info container struct
+ * @property_state: Pointer to property state container struct
+ * @property_idx: Property index
+ * Returns: true if dirty, false otherwise
+ */
+bool msm_property_is_dirty(
+ struct msm_property_info *info,
+ struct msm_property_state *property_state,
+ uint32_t property_idx);
+
+/**
* msm_property_atomic_set - helper function for atomic property set callback
* @info: Pointer to property info container struct
* @property_state: Pointer to local state structure
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 2aeec3f..9d138cc 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -789,6 +789,21 @@
*crtc_roi = &crtc_state->crtc_roi;
}
+bool sde_crtc_is_crtc_roi_dirty(struct drm_crtc_state *state)
+{
+ struct sde_crtc_state *cstate;
+ struct sde_crtc *sde_crtc;
+
+ if (!state || !state->crtc)
+ return false;
+
+ sde_crtc = to_sde_crtc(state->crtc);
+ cstate = to_sde_crtc_state(state);
+
+ return msm_property_is_dirty(&sde_crtc->property_info,
+ &cstate->property_state, CRTC_PROP_ROI_V1);
+}
+
static int _sde_crtc_set_roi_v1(struct drm_crtc_state *state,
void __user *usr_ptr)
{
@@ -877,6 +892,8 @@
struct sde_crtc_state *crtc_state;
struct sde_rect *crtc_roi;
int i, num_attached_conns = 0;
+ bool is_crtc_roi_dirty;
+ bool is_any_conn_roi_dirty;
if (!crtc || !state)
return -EINVAL;
@@ -885,7 +902,11 @@
crtc_state = to_sde_crtc_state(state);
crtc_roi = &crtc_state->crtc_roi;
+ is_crtc_roi_dirty = sde_crtc_is_crtc_roi_dirty(state);
+ is_any_conn_roi_dirty = false;
+
for_each_connector_in_state(state->state, conn, conn_state, i) {
+ struct sde_connector *sde_conn;
struct sde_connector_state *sde_conn_state;
struct sde_rect conn_roi;
@@ -900,8 +921,15 @@
}
++num_attached_conns;
+ sde_conn = to_sde_connector(conn_state->connector);
sde_conn_state = to_sde_connector_state(conn_state);
+ is_any_conn_roi_dirty = is_any_conn_roi_dirty ||
+ msm_property_is_dirty(
+ &sde_conn->property_info,
+ &sde_conn_state->property_state,
+ CONNECTOR_PROP_ROI_V1);
+
/*
* current driver only supports same connector and crtc size,
* but if support for different sizes is added, driver needs
@@ -921,6 +949,16 @@
conn_roi.w, conn_roi.h);
}
+ /*
+ * Check against CRTC ROI and Connector ROI not being updated together.
+ * This restriction should be relaxed when Connector ROI scaling is
+ * supported.
+ */
+ if (is_any_conn_roi_dirty != is_crtc_roi_dirty) {
+ SDE_ERROR("connector/crtc rois not updated together\n");
+ return -EINVAL;
+ }
+
sde_kms_rect_merge_rectangles(&crtc_state->user_roi_list, crtc_roi);
SDE_DEBUG("%s: crtc roi (%d,%d,%d,%d)\n", sde_crtc->name,
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h
index c6b4afa..9501d0f 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.h
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.h
@@ -684,6 +684,14 @@
void sde_crtc_get_crtc_roi(struct drm_crtc_state *state,
const struct sde_rect **crtc_roi);
+/**
+ * sde_crtc_is_crtc_roi_dirty - retrieve whether crtc_roi was updated this frame
+ * Note: Only use during atomic_check since dirty properties may be popped
+ * @crtc_state: Pointer to crtc state
+ * Return: true if roi is dirty, false otherwise
+ */
+bool sde_crtc_is_crtc_roi_dirty(struct drm_crtc_state *state);
+
/** sde_crt_get_secure_level - retrieve the secure level from the give state
* object, this is used to determine the secure state of the crtc
* @crtc : Pointer to drm crtc structure