aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoonyoung Shim <jy0922.shim@samsung.com>2011-11-04 04:04:45 -0400
committerInki Dae <inki.dae@samsung.com>2011-11-15 00:58:46 -0500
commitd2716c896d305fb5d3d0d7f58394c17841ed2967 (patch)
treeac26c995dc9b4166413c3c3f9e283434c7d9177e
parentaa6b2b6cd43e4a23c2a220382a8b385b087d8bca (diff)
drm/exynos: added crtc dpms for disable crtc
crtc dpms is called as destroying attached fb so dpms off sould be processed. crtc dpms also can be called after crtc is detached from encoder so pipe value of manager is used to find display controller for this case Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c29
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.c54
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.h1
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
91static int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay, 92static 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
172static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) 173static 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
179static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) 197static 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
186static void exynos_drm_crtc_commit(struct drm_crtc *crtc) 204static 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
193static bool 214static 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
131static struct drm_crtc * 129static 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
258void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data) 279void 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
289void 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
268MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); 308MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
269MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); 309MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
270MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>"); 310MODULE_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);
41void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data); 41void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data);
42void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data); 42void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data);
43void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data); 43void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data);
44void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data);
44 45
45#endif 46#endif