diff options
| author | Clarence Ip <cip@codeaurora.org> | 2016-07-26 13:39:59 -0400 |
|---|---|---|
| committer | Dhaval Patel <pdhaval@codeaurora.org> | 2016-08-01 12:35:46 -0700 |
| commit | bf3eccabfa91d219fa0347bfb2d6c5a60d28bf28 (patch) | |
| tree | 26d06471543e793ea78f4193bfc247e9301dff4b /drivers | |
| parent | bc79a7ccd350e433c5f47542b4b98cd9e154aff7 (diff) | |
drm/msm/sde: add retire fence support
Add a property to the sde connector to support Android's retire
fence semantics.
Change-Id: Ibd557cc7a881859fd410aae8529addeedfa347c1
Signed-off-by: Clarence Ip <cip@codeaurora.org>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_connector.c | 52 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_connector.h | 15 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_kms.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_kms.h | 1 |
4 files changed, 71 insertions, 5 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c index 28e8cbc2b049..d95068b13948 100644 --- a/drivers/gpu/drm/msm/sde/sde_connector.c +++ b/drivers/gpu/drm/msm/sde/sde_connector.c @@ -32,6 +32,7 @@ static void sde_connector_destroy(struct drm_connector *connector) msm_property_destroy(&c_conn->property_info); drm_connector_unregister(connector); + sde_fence_deinit(&c_conn->retire_fence); drm_connector_cleanup(connector); kfree(c_conn); } @@ -258,10 +259,12 @@ 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); - - /* get cached property value */ - rc = msm_property_atomic_get(&c_conn->property_info, - c_state->property_values, 0, property, val); + if (idx == CONNECTOR_PROP_RETIRE_FENCE) + rc = sde_fence_create(&c_conn->retire_fence, val); + 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) @@ -273,6 +276,27 @@ static int sde_connector_atomic_get_property(struct drm_connector *connector, return rc; } +void sde_connector_prepare_fence(struct drm_connector *connector) +{ + if (!connector) { + SDE_ERROR("invalid connector\n"); + return; + } + + sde_fence_prepare(&to_sde_connector(connector)->retire_fence); +} + +void sde_connector_complete_commit(struct drm_connector *connector) +{ + if (!connector) { + SDE_ERROR("invalid connector\n"); + return; + } + + /* signal connector's retire fence */ + sde_fence_signal(&to_sde_connector(connector)->retire_fence, 0); +} + static enum drm_connector_status sde_connector_detect(struct drm_connector *connector, bool force) { @@ -429,10 +453,23 @@ struct drm_connector *sde_connector_init(struct drm_device *dev, "conn%u", c_conn->base.base.id); + /* + * Initialize retire fence support. Set fence offset to 0 for virtual + * connectors so that the fence signals at the end of the current commit + * and 1 for others so that the fence signals after one additional + * commit. + */ + rc = sde_fence_init(dev, &c_conn->retire_fence, c_conn->name, + connector_type == DRM_MODE_CONNECTOR_VIRTUAL ? 0 : 1); + if (rc) { + SDE_ERROR("failed to init fence, %d\n", rc); + goto error_cleanup_conn; + } + rc = drm_connector_register(&c_conn->base); if (rc) { SDE_ERROR("failed to register drm connector, %d\n", rc); - goto error_cleanup_conn; + goto error_cleanup_fence; } rc = drm_mode_connector_attach_encoder(&c_conn->base, encoder); @@ -476,6 +513,9 @@ struct drm_connector *sde_connector_init(struct drm_device *dev, kfree(info); } + msm_property_install_range(&c_conn->property_info, "RETIRE_FENCE", + 0, ~0, ~0, CONNECTOR_PROP_RETIRE_FENCE); + rc = msm_property_install_get_status(&c_conn->property_info); if (rc) { SDE_ERROR("failed to create one or more properties\n"); @@ -492,6 +532,8 @@ error_destroy_property: msm_property_destroy(&c_conn->property_info); error_unregister_conn: drm_connector_unregister(&c_conn->base); +error_cleanup_fence: + sde_fence_deinit(&c_conn->retire_fence); error_cleanup_conn: drm_connector_cleanup(&c_conn->base); error_free_conn: diff --git a/drivers/gpu/drm/msm/sde/sde_connector.h b/drivers/gpu/drm/msm/sde/sde_connector.h index a4dbc2e4a2df..3a848a5b190b 100644 --- a/drivers/gpu/drm/msm/sde/sde_connector.h +++ b/drivers/gpu/drm/msm/sde/sde_connector.h @@ -19,6 +19,7 @@ #include "msm_prop.h" #include "sde_kms.h" +#include "sde_fence.h" #define SDE_CONNECTOR_NAME_SIZE 16 @@ -112,6 +113,7 @@ struct sde_connector_ops { * @display: Pointer to private display data structure * @mmu_id: MMU is for buffer mapping * @name: ASCII name of connector + * @retire_fence: Retire fence reference * @ops: Local callback function pointer table * @property_info: Private structure for generic property handling * @property_data: Array of private data for generic property handling @@ -130,6 +132,7 @@ struct sde_connector { char name[SDE_CONNECTOR_NAME_SIZE]; + struct sde_fence retire_fence; struct sde_connector_ops ops; struct msm_property_info property_info; @@ -236,5 +239,17 @@ struct drm_connector *sde_connector_init(struct drm_device *dev, int connector_poll, int connector_type); +/** + * sde_connector_prepare_fence - prepare fence support for current commit + * @connector: Pointer to drm connector object + */ +void sde_connector_prepare_fence(struct drm_connector *connector); + +/** + * sde_connector_complete_commit - signal completion of current commit + * @connector: Pointer to drm connector object + */ +void sde_connector_complete_commit(struct drm_connector *connector); + #endif /* _SDE_CONNECTOR_H_ */ diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index 76af87a7d1f0..fc20d8ea8b76 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -192,10 +192,14 @@ static void sde_complete_commit(struct msm_kms *kms, struct sde_kms *sde_kms = to_sde_kms(kms); struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; + struct drm_connector *connector; + struct drm_connector_state *conn_state; int i; for_each_crtc_in_state(state, crtc, crtc_state, i) sde_crtc_complete_commit(crtc); + for_each_connector_in_state(state, connector, conn_state, i) + sde_connector_complete_commit(connector); sde_disable(sde_kms); MSM_EVT(sde_kms->dev, 0, 0); @@ -212,10 +216,14 @@ static void sde_kms_prepare_fence(struct msm_kms *kms, { struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; + struct drm_connector *connector; + struct drm_connector_state *conn_state; int i; for_each_crtc_in_state(state, crtc, crtc_state, i) sde_crtc_prepare_fence(crtc); + for_each_connector_in_state(state, connector, conn_state, i) + sde_connector_prepare_fence(connector); } static int modeset_init(struct sde_kms *sde_kms) diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h index 154edf3468b5..1b63d18bdbe2 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.h +++ b/drivers/gpu/drm/msm/sde/sde_kms.h @@ -20,6 +20,7 @@ #include "sde_hw_ctl.h" #include "sde_hw_lm.h" #include "sde_hw_interrupts.h" +#include "sde_connector.h" /** * SDE_DEBUG - macro for kms/plane/crtc/encoder/connector logs |
