diff options
author | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2015-06-01 11:04:48 -0400 |
---|---|---|
committer | Inki Dae <daeinki@gmail.com> | 2015-06-19 11:32:49 -0400 |
commit | 9d5ab6a0ff7bb9565e8e1bcce5648964b6434470 (patch) | |
tree | 181628385329a710653c190cc5a2986016db9f9f /drivers/gpu/drm/exynos | |
parent | 47a7deff3606c4455f0abf0cdb1a9c89ba722a6b (diff) |
drm/exynos: atomic phase 3: convert page flips
PageFlips now use the atomic helper to work through the atomic modesetting
API. Async page flips are not supported yet.
v2: Add .atomic_begin() step to handle the vblank part we removed from
exynos page_flip code.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Reviewed-by: Joonyoung Shim <jy0922.shim@samsung.com>
Tested-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu/drm/exynos')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_crtc.c | 79 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fb.c | 9 |
2 files changed, 25 insertions, 63 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index dd1ee7f383cd..a13779915cde 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c | |||
@@ -101,75 +101,30 @@ static void exynos_drm_crtc_disable(struct drm_crtc *crtc) | |||
101 | } | 101 | } |
102 | } | 102 | } |
103 | 103 | ||
104 | static void exynos_crtc_atomic_begin(struct drm_crtc *crtc) | ||
105 | { | ||
106 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); | ||
107 | |||
108 | if (crtc->state->event) { | ||
109 | WARN_ON(drm_crtc_vblank_get(crtc) != 0); | ||
110 | exynos_crtc->event = crtc->state->event; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | static void exynos_crtc_atomic_flush(struct drm_crtc *crtc) | ||
115 | { | ||
116 | } | ||
117 | |||
104 | static struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { | 118 | static struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { |
105 | .dpms = exynos_drm_crtc_dpms, | 119 | .dpms = exynos_drm_crtc_dpms, |
106 | .commit = exynos_drm_crtc_commit, | 120 | .commit = exynos_drm_crtc_commit, |
107 | .mode_fixup = exynos_drm_crtc_mode_fixup, | 121 | .mode_fixup = exynos_drm_crtc_mode_fixup, |
108 | .mode_set_nofb = exynos_drm_crtc_mode_set_nofb, | 122 | .mode_set_nofb = exynos_drm_crtc_mode_set_nofb, |
109 | .disable = exynos_drm_crtc_disable, | 123 | .disable = exynos_drm_crtc_disable, |
124 | .atomic_begin = exynos_crtc_atomic_begin, | ||
125 | .atomic_flush = exynos_crtc_atomic_flush, | ||
110 | }; | 126 | }; |
111 | 127 | ||
112 | static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, | ||
113 | struct drm_framebuffer *fb, | ||
114 | struct drm_pending_vblank_event *event, | ||
115 | uint32_t page_flip_flags) | ||
116 | { | ||
117 | struct drm_device *dev = crtc->dev; | ||
118 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); | ||
119 | unsigned int crtc_w, crtc_h; | ||
120 | int ret; | ||
121 | |||
122 | /* when the page flip is requested, crtc's dpms should be on */ | ||
123 | if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) { | ||
124 | DRM_ERROR("failed page flip request.\n"); | ||
125 | return -EINVAL; | ||
126 | } | ||
127 | |||
128 | if (!event) | ||
129 | return -EINVAL; | ||
130 | |||
131 | spin_lock_irq(&dev->event_lock); | ||
132 | if (exynos_crtc->event) { | ||
133 | ret = -EBUSY; | ||
134 | goto out; | ||
135 | } | ||
136 | |||
137 | ret = exynos_check_plane(crtc->primary, fb); | ||
138 | if (ret) | ||
139 | goto out; | ||
140 | |||
141 | ret = drm_vblank_get(dev, exynos_crtc->pipe); | ||
142 | if (ret) { | ||
143 | DRM_DEBUG("failed to acquire vblank counter\n"); | ||
144 | goto out; | ||
145 | } | ||
146 | |||
147 | exynos_crtc->event = event; | ||
148 | spin_unlock_irq(&dev->event_lock); | ||
149 | |||
150 | /* | ||
151 | * the pipe from user always is 0 so we can set pipe number | ||
152 | * of current owner to event. | ||
153 | */ | ||
154 | event->pipe = exynos_crtc->pipe; | ||
155 | |||
156 | crtc->primary->fb = fb; | ||
157 | crtc_w = fb->width - crtc->x; | ||
158 | crtc_h = fb->height - crtc->y; | ||
159 | exynos_update_plane(crtc->primary, crtc, fb, 0, 0, | ||
160 | crtc_w, crtc_h, crtc->x << 16, crtc->y << 16, | ||
161 | crtc_w << 16, crtc_h << 16); | ||
162 | |||
163 | if (crtc->primary->state) | ||
164 | drm_atomic_set_fb_for_plane(crtc->primary->state, fb); | ||
165 | |||
166 | return 0; | ||
167 | |||
168 | out: | ||
169 | spin_unlock_irq(&dev->event_lock); | ||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) | 128 | static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) |
174 | { | 129 | { |
175 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); | 130 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); |
@@ -183,7 +138,7 @@ static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) | |||
183 | 138 | ||
184 | static struct drm_crtc_funcs exynos_crtc_funcs = { | 139 | static struct drm_crtc_funcs exynos_crtc_funcs = { |
185 | .set_config = drm_atomic_helper_set_config, | 140 | .set_config = drm_atomic_helper_set_config, |
186 | .page_flip = exynos_drm_crtc_page_flip, | 141 | .page_flip = drm_atomic_helper_page_flip, |
187 | .destroy = exynos_drm_crtc_destroy, | 142 | .destroy = exynos_drm_crtc_destroy, |
188 | .reset = drm_atomic_helper_crtc_reset, | 143 | .reset = drm_atomic_helper_crtc_reset, |
189 | .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, | 144 | .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 19c06429fc45..05d229c1629a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c | |||
@@ -266,11 +266,18 @@ static void exynos_drm_output_poll_changed(struct drm_device *dev) | |||
266 | exynos_drm_fbdev_init(dev); | 266 | exynos_drm_fbdev_init(dev); |
267 | } | 267 | } |
268 | 268 | ||
269 | static int exynos_atomic_commit(struct drm_device *dev, | ||
270 | struct drm_atomic_state *state, | ||
271 | bool async) | ||
272 | { | ||
273 | return drm_atomic_helper_commit(dev, state, false); | ||
274 | } | ||
275 | |||
269 | static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { | 276 | static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { |
270 | .fb_create = exynos_user_fb_create, | 277 | .fb_create = exynos_user_fb_create, |
271 | .output_poll_changed = exynos_drm_output_poll_changed, | 278 | .output_poll_changed = exynos_drm_output_poll_changed, |
272 | .atomic_check = drm_atomic_helper_check, | 279 | .atomic_check = drm_atomic_helper_check, |
273 | .atomic_commit = drm_atomic_helper_commit, | 280 | .atomic_commit = exynos_atomic_commit, |
274 | }; | 281 | }; |
275 | 282 | ||
276 | void exynos_drm_mode_config_init(struct drm_device *dev) | 283 | void exynos_drm_mode_config_init(struct drm_device *dev) |