aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-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