Merge tag 'mmc-fixes-for-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
[cascardo/linux.git] / drivers / gpu / drm / exynos / exynos_drm_encoder.c
1 /* exynos_drm_encoder.c
2  *
3  * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4  * Authors:
5  *      Inki Dae <inki.dae@samsung.com>
6  *      Joonyoung Shim <jy0922.shim@samsung.com>
7  *      Seung-Woo Kim <sw0312.kim@samsung.com>
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the "Software"),
11  * to deal in the Software without restriction, including without limitation
12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  * and/or sell copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice (including the next
17  * paragraph) shall be included in all copies or substantial portions of the
18  * Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26  * OTHER DEALINGS IN THE SOFTWARE.
27  */
28
29 #include <drm/drmP.h>
30 #include <drm/drm_crtc_helper.h>
31
32 #include "exynos_drm_drv.h"
33 #include "exynos_drm_encoder.h"
34 #include "exynos_drm_connector.h"
35
36 #define to_exynos_encoder(x)    container_of(x, struct exynos_drm_encoder,\
37                                 drm_encoder)
38
39 /*
40  * exynos specific encoder structure.
41  *
42  * @drm_encoder: encoder object.
43  * @manager: specific encoder has its own manager to control a hardware
44  *      appropriately and we can access a hardware drawing on this manager.
45  * @dpms: store the encoder dpms value.
46  * @updated: indicate whether overlay data updating is needed or not.
47  */
48 struct exynos_drm_encoder {
49         struct drm_crtc                 *old_crtc;
50         struct drm_encoder              drm_encoder;
51         struct exynos_drm_manager       *manager;
52         int                             dpms;
53         bool                            updated;
54 };
55
56 static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode)
57 {
58         struct drm_device *dev = encoder->dev;
59         struct drm_connector *connector;
60
61         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
62                 if (exynos_drm_best_encoder(connector) == encoder) {
63                         DRM_DEBUG_KMS("connector[%d] dpms[%d]\n",
64                                         connector->base.id, mode);
65
66                         exynos_drm_display_power(connector, mode);
67                 }
68         }
69 }
70
71 static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
72 {
73         struct drm_device *dev = encoder->dev;
74         struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
75         struct exynos_drm_manager_ops *manager_ops = manager->ops;
76         struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
77
78         DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode);
79
80         if (exynos_encoder->dpms == mode) {
81                 DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n");
82                 return;
83         }
84
85         mutex_lock(&dev->struct_mutex);
86
87         switch (mode) {
88         case DRM_MODE_DPMS_ON:
89                 if (manager_ops && manager_ops->apply)
90                         if (!exynos_encoder->updated)
91                                 manager_ops->apply(manager->dev);
92
93                 exynos_drm_connector_power(encoder, mode);
94                 exynos_encoder->dpms = mode;
95                 break;
96         case DRM_MODE_DPMS_STANDBY:
97         case DRM_MODE_DPMS_SUSPEND:
98         case DRM_MODE_DPMS_OFF:
99                 exynos_drm_connector_power(encoder, mode);
100                 exynos_encoder->dpms = mode;
101                 exynos_encoder->updated = false;
102                 break;
103         default:
104                 DRM_ERROR("unspecified mode %d\n", mode);
105                 break;
106         }
107
108         mutex_unlock(&dev->struct_mutex);
109 }
110
111 static bool
112 exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
113                                const struct drm_display_mode *mode,
114                                struct drm_display_mode *adjusted_mode)
115 {
116         struct drm_device *dev = encoder->dev;
117         struct drm_connector *connector;
118         struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
119         struct exynos_drm_manager_ops *manager_ops = manager->ops;
120
121         DRM_DEBUG_KMS("%s\n", __FILE__);
122
123         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
124                 if (connector->encoder == encoder)
125                         if (manager_ops && manager_ops->mode_fixup)
126                                 manager_ops->mode_fixup(manager->dev, connector,
127                                                         mode, adjusted_mode);
128         }
129
130         return true;
131 }
132
133 static void disable_plane_to_crtc(struct drm_device *dev,
134                                                 struct drm_crtc *old_crtc,
135                                                 struct drm_crtc *new_crtc)
136 {
137         struct drm_plane *plane;
138
139         /*
140          * if old_crtc isn't same as encoder->crtc then it means that
141          * user changed crtc id to another one so the plane to old_crtc
142          * should be disabled and plane->crtc should be set to new_crtc
143          * (encoder->crtc)
144          */
145         list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
146                 if (plane->crtc == old_crtc) {
147                         /*
148                          * do not change below call order.
149                          *
150                          * plane->funcs->disable_plane call checks
151                          * if encoder->crtc is same as plane->crtc and if same
152                          * then overlay_ops->disable callback will be called
153                          * to diasble current hw overlay so plane->crtc should
154                          * have new_crtc because new_crtc was set to
155                          * encoder->crtc in advance.
156                          */
157                         plane->crtc = new_crtc;
158                         plane->funcs->disable_plane(plane);
159                 }
160         }
161 }
162
163 static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
164                                          struct drm_display_mode *mode,
165                                          struct drm_display_mode *adjusted_mode)
166 {
167         struct drm_device *dev = encoder->dev;
168         struct drm_connector *connector;
169         struct exynos_drm_manager *manager;
170         struct exynos_drm_manager_ops *manager_ops;
171
172         DRM_DEBUG_KMS("%s\n", __FILE__);
173
174         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
175                 if (connector->encoder == encoder) {
176                         struct exynos_drm_encoder *exynos_encoder;
177
178                         exynos_encoder = to_exynos_encoder(encoder);
179
180                         if (exynos_encoder->old_crtc != encoder->crtc &&
181                                         exynos_encoder->old_crtc) {
182
183                                 /*
184                                  * disable a plane to old crtc and change
185                                  * crtc of the plane to new one.
186                                  */
187                                 disable_plane_to_crtc(dev,
188                                                 exynos_encoder->old_crtc,
189                                                 encoder->crtc);
190                         }
191
192                         manager = exynos_drm_get_manager(encoder);
193                         manager_ops = manager->ops;
194
195                         if (manager_ops && manager_ops->mode_set)
196                                 manager_ops->mode_set(manager->dev,
197                                                         adjusted_mode);
198
199                         exynos_encoder->old_crtc = encoder->crtc;
200                 }
201         }
202 }
203
204 static void exynos_drm_encoder_prepare(struct drm_encoder *encoder)
205 {
206         DRM_DEBUG_KMS("%s\n", __FILE__);
207
208         /* drm framework doesn't check NULL. */
209 }
210
211 static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
212 {
213         struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
214         struct exynos_drm_manager *manager = exynos_encoder->manager;
215         struct exynos_drm_manager_ops *manager_ops = manager->ops;
216
217         DRM_DEBUG_KMS("%s\n", __FILE__);
218
219         if (manager_ops && manager_ops->commit)
220                 manager_ops->commit(manager->dev);
221
222         /*
223          * this will avoid one issue that overlay data is updated to
224          * real hardware two times.
225          * And this variable will be used to check if the data was
226          * already updated or not by exynos_drm_encoder_dpms function.
227          */
228         exynos_encoder->updated = true;
229
230         /*
231          * In case of setcrtc, there is no way to update encoder's dpms
232          * so update it here.
233          */
234         exynos_encoder->dpms = DRM_MODE_DPMS_ON;
235 }
236
237 static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
238 {
239         struct drm_plane *plane;
240         struct drm_device *dev = encoder->dev;
241
242         exynos_drm_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
243
244         /* all planes connected to this encoder should be also disabled. */
245         list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
246                 if (plane->crtc == encoder->crtc)
247                         plane->funcs->disable_plane(plane);
248         }
249 }
250
251 static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = {
252         .dpms           = exynos_drm_encoder_dpms,
253         .mode_fixup     = exynos_drm_encoder_mode_fixup,
254         .mode_set       = exynos_drm_encoder_mode_set,
255         .prepare        = exynos_drm_encoder_prepare,
256         .commit         = exynos_drm_encoder_commit,
257         .disable        = exynos_drm_encoder_disable,
258 };
259
260 static void exynos_drm_encoder_destroy(struct drm_encoder *encoder)
261 {
262         struct exynos_drm_encoder *exynos_encoder =
263                 to_exynos_encoder(encoder);
264
265         DRM_DEBUG_KMS("%s\n", __FILE__);
266
267         exynos_encoder->manager->pipe = -1;
268
269         drm_encoder_cleanup(encoder);
270         kfree(exynos_encoder);
271 }
272
273 static struct drm_encoder_funcs exynos_encoder_funcs = {
274         .destroy = exynos_drm_encoder_destroy,
275 };
276
277 static unsigned int exynos_drm_encoder_clones(struct drm_encoder *encoder)
278 {
279         struct drm_encoder *clone;
280         struct drm_device *dev = encoder->dev;
281         struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
282         struct exynos_drm_display_ops *display_ops =
283                                 exynos_encoder->manager->display_ops;
284         unsigned int clone_mask = 0;
285         int cnt = 0;
286
287         list_for_each_entry(clone, &dev->mode_config.encoder_list, head) {
288                 switch (display_ops->type) {
289                 case EXYNOS_DISPLAY_TYPE_LCD:
290                 case EXYNOS_DISPLAY_TYPE_HDMI:
291                 case EXYNOS_DISPLAY_TYPE_VIDI:
292                         clone_mask |= (1 << (cnt++));
293                         break;
294                 default:
295                         continue;
296                 }
297         }
298
299         return clone_mask;
300 }
301
302 void exynos_drm_encoder_setup(struct drm_device *dev)
303 {
304         struct drm_encoder *encoder;
305
306         DRM_DEBUG_KMS("%s\n", __FILE__);
307
308         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
309                 encoder->possible_clones = exynos_drm_encoder_clones(encoder);
310 }
311
312 struct drm_encoder *
313 exynos_drm_encoder_create(struct drm_device *dev,
314                            struct exynos_drm_manager *manager,
315                            unsigned int possible_crtcs)
316 {
317         struct drm_encoder *encoder;
318         struct exynos_drm_encoder *exynos_encoder;
319
320         DRM_DEBUG_KMS("%s\n", __FILE__);
321
322         if (!manager || !possible_crtcs)
323                 return NULL;
324
325         if (!manager->dev)
326                 return NULL;
327
328         exynos_encoder = kzalloc(sizeof(*exynos_encoder), GFP_KERNEL);
329         if (!exynos_encoder) {
330                 DRM_ERROR("failed to allocate encoder\n");
331                 return NULL;
332         }
333
334         exynos_encoder->dpms = DRM_MODE_DPMS_OFF;
335         exynos_encoder->manager = manager;
336         encoder = &exynos_encoder->drm_encoder;
337         encoder->possible_crtcs = possible_crtcs;
338
339         DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
340
341         drm_encoder_init(dev, encoder, &exynos_encoder_funcs,
342                         DRM_MODE_ENCODER_TMDS);
343
344         drm_encoder_helper_add(encoder, &exynos_encoder_helper_funcs);
345
346         DRM_DEBUG_KMS("encoder has been created\n");
347
348         return encoder;
349 }
350
351 struct exynos_drm_manager *exynos_drm_get_manager(struct drm_encoder *encoder)
352 {
353         return to_exynos_encoder(encoder)->manager;
354 }
355
356 void exynos_drm_fn_encoder(struct drm_crtc *crtc, void *data,
357                             void (*fn)(struct drm_encoder *, void *))
358 {
359         struct drm_device *dev = crtc->dev;
360         struct drm_encoder *encoder;
361         struct exynos_drm_private *private = dev->dev_private;
362         struct exynos_drm_manager *manager;
363
364         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
365                 /*
366                  * if crtc is detached from encoder, check pipe,
367                  * otherwise check crtc attached to encoder
368                  */
369                 if (!encoder->crtc) {
370                         manager = to_exynos_encoder(encoder)->manager;
371                         if (manager->pipe < 0 ||
372                                         private->crtc[manager->pipe] != crtc)
373                                 continue;
374                 } else {
375                         if (encoder->crtc != crtc)
376                                 continue;
377                 }
378
379                 fn(encoder, data);
380         }
381 }
382
383 void exynos_drm_enable_vblank(struct drm_encoder *encoder, void *data)
384 {
385         struct exynos_drm_manager *manager =
386                 to_exynos_encoder(encoder)->manager;
387         struct exynos_drm_manager_ops *manager_ops = manager->ops;
388         int crtc = *(int *)data;
389
390         if (manager->pipe != crtc)
391                 return;
392
393         if (manager_ops->enable_vblank)
394                 manager_ops->enable_vblank(manager->dev);
395 }
396
397 void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data)
398 {
399         struct exynos_drm_manager *manager =
400                 to_exynos_encoder(encoder)->manager;
401         struct exynos_drm_manager_ops *manager_ops = manager->ops;
402         int crtc = *(int *)data;
403
404         if (manager->pipe != crtc)
405                 return;
406
407         if (manager_ops->disable_vblank)
408                 manager_ops->disable_vblank(manager->dev);
409 }
410
411 void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data)
412 {
413         struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
414         struct exynos_drm_manager *manager = exynos_encoder->manager;
415         struct exynos_drm_manager_ops *manager_ops = manager->ops;
416         int mode = *(int *)data;
417
418         DRM_DEBUG_KMS("%s\n", __FILE__);
419
420         if (manager_ops && manager_ops->dpms)
421                 manager_ops->dpms(manager->dev, mode);
422
423         /*
424          * if this condition is ok then it means that the crtc is already
425          * detached from encoder and last function for detaching is properly
426          * done, so clear pipe from manager to prevent repeated call.
427          */
428         if (mode > DRM_MODE_DPMS_ON) {
429                 if (!encoder->crtc)
430                         manager->pipe = -1;
431         }
432 }
433
434 void exynos_drm_encoder_crtc_pipe(struct drm_encoder *encoder, void *data)
435 {
436         struct exynos_drm_manager *manager =
437                 to_exynos_encoder(encoder)->manager;
438         int pipe = *(int *)data;
439
440         DRM_DEBUG_KMS("%s\n", __FILE__);
441
442         /*
443          * when crtc is detached from encoder, this pipe is used
444          * to select manager operation
445          */
446         manager->pipe = pipe;
447 }
448
449 void exynos_drm_encoder_plane_mode_set(struct drm_encoder *encoder, void *data)
450 {
451         struct exynos_drm_manager *manager =
452                 to_exynos_encoder(encoder)->manager;
453         struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
454         struct exynos_drm_overlay *overlay = data;
455
456         DRM_DEBUG_KMS("%s\n", __FILE__);
457
458         if (overlay_ops && overlay_ops->mode_set)
459                 overlay_ops->mode_set(manager->dev, overlay);
460 }
461
462 void exynos_drm_encoder_plane_commit(struct drm_encoder *encoder, void *data)
463 {
464         struct exynos_drm_manager *manager =
465                 to_exynos_encoder(encoder)->manager;
466         struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
467         int zpos = DEFAULT_ZPOS;
468
469         DRM_DEBUG_KMS("%s\n", __FILE__);
470
471         if (data)
472                 zpos = *(int *)data;
473
474         if (overlay_ops && overlay_ops->commit)
475                 overlay_ops->commit(manager->dev, zpos);
476 }
477
478 void exynos_drm_encoder_plane_enable(struct drm_encoder *encoder, void *data)
479 {
480         struct exynos_drm_manager *manager =
481                 to_exynos_encoder(encoder)->manager;
482         struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
483         int zpos = DEFAULT_ZPOS;
484
485         DRM_DEBUG_KMS("%s\n", __FILE__);
486
487         if (data)
488                 zpos = *(int *)data;
489
490         if (overlay_ops && overlay_ops->enable)
491                 overlay_ops->enable(manager->dev, zpos);
492 }
493
494 void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data)
495 {
496         struct exynos_drm_manager *manager =
497                 to_exynos_encoder(encoder)->manager;
498         struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
499         int zpos = DEFAULT_ZPOS;
500
501         DRM_DEBUG_KMS("%s\n", __FILE__);
502
503         if (data)
504                 zpos = *(int *)data;
505
506         if (overlay_ops && overlay_ops->disable)
507                 overlay_ops->disable(manager->dev, zpos);
508
509         /*
510          * wait for vblank interrupt
511          * - this makes sure that hardware overlay is disabled to avoid
512          * for the dma accesses to memory after gem buffer was released
513          * because the setting for disabling the overlay will be updated
514          * at vsync.
515          */
516         if (overlay_ops && overlay_ops->wait_for_vblank)
517                 overlay_ops->wait_for_vblank(manager->dev);
518 }