diff options
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_crtc.c | 29 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_encoder.c | 54 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_encoder.h | 1 |
3 files changed, 73 insertions, 11 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 9337e5e2dbb6..b1d6526340bb 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c | |||
| @@ -85,7 +85,8 @@ static void exynos_drm_crtc_apply(struct drm_crtc *crtc) | |||
| 85 | 85 | ||
| 86 | exynos_drm_fn_encoder(crtc, overlay, | 86 | exynos_drm_fn_encoder(crtc, overlay, |
| 87 | exynos_drm_encoder_crtc_mode_set); | 87 | exynos_drm_encoder_crtc_mode_set); |
| 88 | exynos_drm_fn_encoder(crtc, NULL, exynos_drm_encoder_crtc_commit); | 88 | exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe, |
| 89 | exynos_drm_encoder_crtc_commit); | ||
| 89 | } | 90 | } |
| 90 | 91 | ||
| 91 | static int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay, | 92 | static int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay, |
| @@ -171,9 +172,26 @@ static int exynos_drm_crtc_update(struct drm_crtc *crtc) | |||
| 171 | 172 | ||
| 172 | static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) | 173 | static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) |
| 173 | { | 174 | { |
| 174 | DRM_DEBUG_KMS("%s\n", __FILE__); | 175 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); |
| 175 | 176 | ||
| 176 | /* TODO */ | 177 | DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode); |
| 178 | |||
| 179 | switch (mode) { | ||
| 180 | case DRM_MODE_DPMS_ON: | ||
| 181 | exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe, | ||
| 182 | exynos_drm_encoder_crtc_commit); | ||
| 183 | break; | ||
| 184 | case DRM_MODE_DPMS_STANDBY: | ||
| 185 | case DRM_MODE_DPMS_SUSPEND: | ||
| 186 | case DRM_MODE_DPMS_OFF: | ||
| 187 | /* TODO */ | ||
| 188 | exynos_drm_fn_encoder(crtc, NULL, | ||
| 189 | exynos_drm_encoder_crtc_disable); | ||
| 190 | break; | ||
| 191 | default: | ||
| 192 | DRM_DEBUG_KMS("unspecified mode %d\n", mode); | ||
| 193 | break; | ||
| 194 | } | ||
| 177 | } | 195 | } |
| 178 | 196 | ||
| 179 | static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) | 197 | static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) |
| @@ -185,9 +203,12 @@ static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) | |||
| 185 | 203 | ||
| 186 | static void exynos_drm_crtc_commit(struct drm_crtc *crtc) | 204 | static void exynos_drm_crtc_commit(struct drm_crtc *crtc) |
| 187 | { | 205 | { |
| 206 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); | ||
| 207 | |||
| 188 | DRM_DEBUG_KMS("%s\n", __FILE__); | 208 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 189 | 209 | ||
| 190 | /* drm framework doesn't check NULL. */ | 210 | exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe, |
| 211 | exynos_drm_encoder_crtc_commit); | ||
| 191 | } | 212 | } |
| 192 | 213 | ||
| 193 | static bool | 214 | static bool |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 0034fa7a58db..f15da9581a1e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c | |||
| @@ -61,6 +61,8 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 61 | struct exynos_drm_display_ops *display_ops = | 61 | struct exynos_drm_display_ops *display_ops = |
| 62 | manager->display_ops; | 62 | manager->display_ops; |
| 63 | 63 | ||
| 64 | DRM_DEBUG_KMS("connector[%d] dpms[%d]\n", | ||
| 65 | connector->base.id, mode); | ||
| 64 | if (display_ops && display_ops->power_on) | 66 | if (display_ops && display_ops->power_on) |
| 65 | display_ops->power_on(manager->dev, mode); | 67 | display_ops->power_on(manager->dev, mode); |
| 66 | } | 68 | } |
| @@ -117,15 +119,11 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder) | |||
| 117 | { | 119 | { |
| 118 | struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); | 120 | struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); |
| 119 | struct exynos_drm_manager_ops *manager_ops = manager->ops; | 121 | struct exynos_drm_manager_ops *manager_ops = manager->ops; |
| 120 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; | ||
| 121 | 122 | ||
| 122 | DRM_DEBUG_KMS("%s\n", __FILE__); | 123 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 123 | 124 | ||
| 124 | if (manager_ops && manager_ops->commit) | 125 | if (manager_ops && manager_ops->commit) |
| 125 | manager_ops->commit(manager->dev); | 126 | manager_ops->commit(manager->dev); |
| 126 | |||
| 127 | if (overlay_ops && overlay_ops->commit) | ||
| 128 | overlay_ops->commit(manager->dev); | ||
| 129 | } | 127 | } |
| 130 | 128 | ||
| 131 | static struct drm_crtc * | 129 | static struct drm_crtc * |
| @@ -209,10 +207,23 @@ void exynos_drm_fn_encoder(struct drm_crtc *crtc, void *data, | |||
| 209 | { | 207 | { |
| 210 | struct drm_device *dev = crtc->dev; | 208 | struct drm_device *dev = crtc->dev; |
| 211 | struct drm_encoder *encoder; | 209 | struct drm_encoder *encoder; |
| 210 | struct exynos_drm_private *private = dev->dev_private; | ||
| 211 | struct exynos_drm_manager *manager; | ||
| 212 | 212 | ||
| 213 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 213 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
| 214 | if (encoder->crtc != crtc) | 214 | /* |
| 215 | continue; | 215 | * if crtc is detached from encoder, check pipe, |
| 216 | * otherwise check crtc attached to encoder | ||
| 217 | */ | ||
| 218 | if (!encoder->crtc) { | ||
| 219 | manager = to_exynos_encoder(encoder)->manager; | ||
| 220 | if (manager->pipe < 0 || | ||
| 221 | private->crtc[manager->pipe] != crtc) | ||
| 222 | continue; | ||
| 223 | } else { | ||
| 224 | if (encoder->crtc != crtc) | ||
| 225 | continue; | ||
| 226 | } | ||
| 216 | 227 | ||
| 217 | fn(encoder, data); | 228 | fn(encoder, data); |
| 218 | } | 229 | } |
| @@ -251,8 +262,18 @@ void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data) | |||
| 251 | struct exynos_drm_manager *manager = | 262 | struct exynos_drm_manager *manager = |
| 252 | to_exynos_encoder(encoder)->manager; | 263 | to_exynos_encoder(encoder)->manager; |
| 253 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; | 264 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; |
| 265 | int crtc = *(int *)data; | ||
| 266 | |||
| 267 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
| 254 | 268 | ||
| 255 | overlay_ops->commit(manager->dev); | 269 | /* |
| 270 | * when crtc is detached from encoder, this pipe is used | ||
| 271 | * to select manager operation | ||
| 272 | */ | ||
| 273 | manager->pipe = crtc; | ||
| 274 | |||
| 275 | if (overlay_ops && overlay_ops->commit) | ||
| 276 | overlay_ops->commit(manager->dev); | ||
| 256 | } | 277 | } |
| 257 | 278 | ||
| 258 | void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data) | 279 | void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data) |
| @@ -265,6 +286,25 @@ void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data) | |||
| 265 | overlay_ops->mode_set(manager->dev, overlay); | 286 | overlay_ops->mode_set(manager->dev, overlay); |
| 266 | } | 287 | } |
| 267 | 288 | ||
| 289 | void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data) | ||
| 290 | { | ||
| 291 | struct exynos_drm_manager *manager = | ||
| 292 | to_exynos_encoder(encoder)->manager; | ||
| 293 | struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; | ||
| 294 | |||
| 295 | DRM_DEBUG_KMS("\n"); | ||
| 296 | |||
| 297 | overlay_ops->disable(manager->dev); | ||
| 298 | |||
| 299 | /* | ||
| 300 | * crtc is already detached from encoder and last | ||
| 301 | * function for detaching is properly done, so | ||
| 302 | * clear pipe from manager to prevent repeated call | ||
| 303 | */ | ||
| 304 | if (!encoder->crtc) | ||
| 305 | manager->pipe = -1; | ||
| 306 | } | ||
| 307 | |||
| 268 | MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); | 308 | MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); |
| 269 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | 309 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); |
| 270 | MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>"); | 310 | MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>"); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h index 5ecd645d06a9..a22acfbf0e4e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.h | |||
| @@ -41,5 +41,6 @@ void exynos_drm_enable_vblank(struct drm_encoder *encoder, void *data); | |||
| 41 | void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data); | 41 | void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data); |
| 42 | void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data); | 42 | void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data); |
| 43 | void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data); | 43 | void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data); |
| 44 | void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data); | ||
| 44 | 45 | ||
| 45 | #endif | 46 | #endif |
