diff options
author | Dave Airlie <airlied@redhat.com> | 2011-11-28 09:17:09 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-11-28 09:17:09 -0500 |
commit | b7b996da27e6f8b518a7c7753fa5b6dff2df6899 (patch) | |
tree | 26fcabc7cbfd2ec81c13bec2649f1999b13a8eaa /drivers/gpu/drm/exynos/exynos_drm_encoder.c | |
parent | caca6a03d365883564885f2c1da3e88dcf65d139 (diff) | |
parent | ca22e3cc25f180859561f36d51bf21278db5ae11 (diff) |
Merge branch 'exynos-drm' of git://git.infradead.org/users/kmpark/linux-samsung into drm-fixes
* 'exynos-drm' of git://git.infradead.org/users/kmpark/linux-samsung:
drm/exynos: fixed wrong err ptr usage and destroy call in exeception
drm/exynos: Add disable of manager
drm/exynos: include linux/module.h
drm/exynos: fix vblank bug.
drm/exynos: changed buffer structure.
drm/exynos: removed unnecessary variable.
drm/exynos: use gem create function generically
drm/exynos: checked for null pointer
drm/exynos: added crtc dpms for disable crtc
drm/exynos: removed meaningless parameter from fbdev update
drm/exynos: restored kernel_fb_list when reiniting fb_helper
drm/exynos: changed exynos_drm_display to exynos_drm_display_ops
drm/exynos: added manager object to connector
drm/exynos: fixed converting between display mode and timing
drm/exynos: fixed connector flag with hpd and interlace scan for hdmi
drm/exynos: added kms poll for handling hpd event
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_encoder.c')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_encoder.c | 83 |
1 files changed, 72 insertions, 11 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 7cf6fa86a67e..153061415baf 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c | |||
@@ -53,15 +53,36 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
53 | struct drm_device *dev = encoder->dev; | 53 | struct drm_device *dev = encoder->dev; |
54 | struct drm_connector *connector; | 54 | struct drm_connector *connector; |
55 | struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); | 55 | struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); |
56 | struct exynos_drm_manager_ops *manager_ops = manager->ops; | ||
56 | 57 | ||
57 | DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode); | 58 | DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode); |
58 | 59 | ||
60 | switch (mode) { | ||
61 | case DRM_MODE_DPMS_ON: | ||
62 | if (manager_ops && manager_ops->commit) | ||
63 | manager_ops->commit(manager->dev); | ||
64 | break; | ||
65 | case DRM_MODE_DPMS_STANDBY: | ||
66 | case DRM_MODE_DPMS_SUSPEND: | ||
67 | case DRM_MODE_DPMS_OFF: | ||
68 | /* TODO */ | ||
69 | if (manager_ops && manager_ops->disable) | ||
70 | manager_ops->disable(manager->dev); | ||
71 | break; | ||
72 | default: | ||
73 | DRM_ERROR("unspecified mode %d\n", mode); | ||
74 | break; | ||
75 | } | ||
76 | |||
59 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 77 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
60 | if (connector->encoder == encoder) { | 78 | if (connector->encoder == encoder) { |
61 | struct exynos_drm_display *display = manager->display; | 79 | struct exynos_drm_display_ops *display_ops = |
80 | manager->display_ops; | ||
62 | 81 | ||
63 | if (display && display->power_on) | 82 | DRM_DEBUG_KMS("connector[%d] dpms[%d]\n", |
64 | display->power_on(manager->dev, mode); | 83 | connector->base.id, mode); |
84 | if (display_ops && display_ops->power_on) | ||
85 | display_ops->power_on(manager->dev, mode); | ||
65 | } | 86 | } |
66 | } | 87 | } |
67 | } | 88 | } |
@@ -116,15 +137,11 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder) | |||
116 | { | 137 | { |
117 | struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); | 138 | struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); |
118 | struct exynos_drm_manager_ops *manager_ops = manager->ops; | 139 | struct exynos_drm_manager_ops *manager_ops = manager->ops; |
119 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; | ||
120 | 140 | ||
121 | DRM_DEBUG_KMS("%s\n", __FILE__); | 141 | DRM_DEBUG_KMS("%s\n", __FILE__); |
122 | 142 | ||
123 | if (manager_ops && manager_ops->commit) | 143 | if (manager_ops && manager_ops->commit) |
124 | manager_ops->commit(manager->dev); | 144 | manager_ops->commit(manager->dev); |
125 | |||
126 | if (overlay_ops && overlay_ops->commit) | ||
127 | overlay_ops->commit(manager->dev); | ||
128 | } | 145 | } |
129 | 146 | ||
130 | static struct drm_crtc * | 147 | static struct drm_crtc * |
@@ -208,10 +225,23 @@ void exynos_drm_fn_encoder(struct drm_crtc *crtc, void *data, | |||
208 | { | 225 | { |
209 | struct drm_device *dev = crtc->dev; | 226 | struct drm_device *dev = crtc->dev; |
210 | struct drm_encoder *encoder; | 227 | struct drm_encoder *encoder; |
228 | struct exynos_drm_private *private = dev->dev_private; | ||
229 | struct exynos_drm_manager *manager; | ||
211 | 230 | ||
212 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 231 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
213 | if (encoder->crtc != crtc) | 232 | /* |
214 | continue; | 233 | * if crtc is detached from encoder, check pipe, |
234 | * otherwise check crtc attached to encoder | ||
235 | */ | ||
236 | if (!encoder->crtc) { | ||
237 | manager = to_exynos_encoder(encoder)->manager; | ||
238 | if (manager->pipe < 0 || | ||
239 | private->crtc[manager->pipe] != crtc) | ||
240 | continue; | ||
241 | } else { | ||
242 | if (encoder->crtc != crtc) | ||
243 | continue; | ||
244 | } | ||
215 | 245 | ||
216 | fn(encoder, data); | 246 | fn(encoder, data); |
217 | } | 247 | } |
@@ -250,8 +280,18 @@ void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data) | |||
250 | struct exynos_drm_manager *manager = | 280 | struct exynos_drm_manager *manager = |
251 | to_exynos_encoder(encoder)->manager; | 281 | to_exynos_encoder(encoder)->manager; |
252 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; | 282 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; |
283 | int crtc = *(int *)data; | ||
284 | |||
285 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
286 | |||
287 | /* | ||
288 | * when crtc is detached from encoder, this pipe is used | ||
289 | * to select manager operation | ||
290 | */ | ||
291 | manager->pipe = crtc; | ||
253 | 292 | ||
254 | overlay_ops->commit(manager->dev); | 293 | if (overlay_ops && overlay_ops->commit) |
294 | overlay_ops->commit(manager->dev); | ||
255 | } | 295 | } |
256 | 296 | ||
257 | void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data) | 297 | void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data) |
@@ -261,7 +301,28 @@ void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data) | |||
261 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; | 301 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; |
262 | struct exynos_drm_overlay *overlay = data; | 302 | struct exynos_drm_overlay *overlay = data; |
263 | 303 | ||
264 | overlay_ops->mode_set(manager->dev, overlay); | 304 | if (overlay_ops && overlay_ops->mode_set) |
305 | overlay_ops->mode_set(manager->dev, overlay); | ||
306 | } | ||
307 | |||
308 | void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data) | ||
309 | { | ||
310 | struct exynos_drm_manager *manager = | ||
311 | to_exynos_encoder(encoder)->manager; | ||
312 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; | ||
313 | |||
314 | DRM_DEBUG_KMS("\n"); | ||
315 | |||
316 | if (overlay_ops && overlay_ops->disable) | ||
317 | overlay_ops->disable(manager->dev); | ||
318 | |||
319 | /* | ||
320 | * crtc is already detached from encoder and last | ||
321 | * function for detaching is properly done, so | ||
322 | * clear pipe from manager to prevent repeated call | ||
323 | */ | ||
324 | if (!encoder->crtc) | ||
325 | manager->pipe = -1; | ||
265 | } | 326 | } |
266 | 327 | ||
267 | MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); | 328 | MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); |