aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2015-01-22 12:53:05 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-01-27 04:02:29 -0500
commitb486e0e6d599b9ca8667fb9a7d49b7383ee963c7 (patch)
tree1a207940466624b213d89e7a9902b1985036c6ba
parenteab3bbeffd152125ae0f90863b8e9bc8eef49423 (diff)
drm/atomic-helper: add connector->dpms() implementation
This builds on top of the crtc->active infrastructure to implement legacy DPMS. My choice of semantics is somewhat arbitrary, but the entire pipe is enabled as along as one output is still enabled. Of course it also clamps everything that's not ON to OFF. v2: Fix spelling in one comment. v3: Don't do an async commit (Thierry) v4: Dan Carpenter noticed missing error case handling. Cc: Thierry Reding <thierry.reding@gmail.com> Reviewed-by: Thierry Reding <treding@nvidia.com> Tested-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c77
-rw-r--r--include/drm/drm_atomic_helper.h2
2 files changed, 79 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 3f17933b1d2c..6112ec261c3b 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1887,6 +1887,83 @@ backoff:
1887EXPORT_SYMBOL(drm_atomic_helper_page_flip); 1887EXPORT_SYMBOL(drm_atomic_helper_page_flip);
1888 1888
1889/** 1889/**
1890 * drm_atomic_helper_connector_dpms() - connector dpms helper implementation
1891 * @connector: affected connector
1892 * @mode: DPMS mode
1893 *
1894 * This is the main helper function provided by the atomic helper framework for
1895 * implementing the legacy DPMS connector interface. It computes the new desired
1896 * ->active state for the corresponding CRTC (if the connector is enabled) and
1897 * updates it.
1898 */
1899void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
1900 int mode)
1901{
1902 struct drm_mode_config *config = &connector->dev->mode_config;
1903 struct drm_atomic_state *state;
1904 struct drm_crtc_state *crtc_state;
1905 struct drm_crtc *crtc;
1906 struct drm_connector *tmp_connector;
1907 int ret;
1908 bool active = false;
1909
1910 if (mode != DRM_MODE_DPMS_ON)
1911 mode = DRM_MODE_DPMS_OFF;
1912
1913 connector->dpms = mode;
1914 crtc = connector->state->crtc;
1915
1916 if (!crtc)
1917 return;
1918
1919 /* FIXME: ->dpms has no return value so can't forward the -ENOMEM. */
1920 state = drm_atomic_state_alloc(connector->dev);
1921 if (!state)
1922 return;
1923
1924 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
1925retry:
1926 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1927 if (IS_ERR(crtc_state))
1928 return;
1929
1930 WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
1931
1932 list_for_each_entry(tmp_connector, &config->connector_list, head) {
1933 if (connector->state->crtc != crtc)
1934 continue;
1935
1936 if (connector->dpms == DRM_MODE_DPMS_ON) {
1937 active = true;
1938 break;
1939 }
1940 }
1941 crtc_state->active = active;
1942
1943 ret = drm_atomic_commit(state);
1944 if (ret != 0)
1945 goto fail;
1946
1947 /* Driver takes ownership of state on successful async commit. */
1948 return;
1949fail:
1950 if (ret == -EDEADLK)
1951 goto backoff;
1952
1953 drm_atomic_state_free(state);
1954
1955 WARN(1, "Driver bug: Changing ->active failed with ret=%i\n", ret);
1956
1957 return;
1958backoff:
1959 drm_atomic_state_clear(state);
1960 drm_atomic_legacy_backoff(state);
1961
1962 goto retry;
1963}
1964EXPORT_SYMBOL(drm_atomic_helper_connector_dpms);
1965
1966/**
1890 * DOC: atomic state reset and initialization 1967 * DOC: atomic state reset and initialization
1891 * 1968 *
1892 * Both the drm core and the atomic helpers assume that there is always the full 1969 * Both the drm core and the atomic helpers assume that there is always the full
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 2095917ff8c7..cf501df9e513 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -82,6 +82,8 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
82 struct drm_framebuffer *fb, 82 struct drm_framebuffer *fb,
83 struct drm_pending_vblank_event *event, 83 struct drm_pending_vblank_event *event,
84 uint32_t flags); 84 uint32_t flags);
85void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
86 int mode);
85 87
86/* default implementations for state handling */ 88/* default implementations for state handling */
87void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc); 89void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc);