301485215a70d782aa28e182633ca0f1b1592afc
[platform/adaptation/renesas_rcar/renesas_kernel.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 void exynos_drm_encoder_complete_scanout(struct drm_framebuffer *fb)
238 {
239         struct exynos_drm_encoder *exynos_encoder;
240         struct exynos_drm_manager_ops *ops;
241         struct drm_device *dev = fb->dev;
242         struct drm_encoder *encoder;
243
244         /*
245          * make sure that overlay data are updated to real hardware
246          * for all encoders.
247          */
248         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
249                 exynos_encoder = to_exynos_encoder(encoder);
250                 ops = exynos_encoder->manager->ops;
251
252                 /*
253                  * wait for vblank interrupt
254                  * - this makes sure that overlay data are updated to
255                  *      real hardware.
256                  */
257                 if (ops->wait_for_vblank)
258                         ops->wait_for_vblank(exynos_encoder->manager->dev);
259         }
260 }
261
262
263 static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
264 {
265         struct drm_plane *plane;
266         struct drm_device *dev = encoder->dev;
267
268         exynos_drm_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
269
270         /* all planes connected to this encoder should be also disabled. */
271         list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
272                 if (plane->crtc == encoder->crtc)
273                         plane->funcs->disable_plane(plane);
274         }
275 }
276
277 static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = {
278         .dpms           = exynos_drm_encoder_dpms,
279         .mode_fixup     = exynos_drm_encoder_mode_fixup,
280         .mode_set       = exynos_drm_encoder_mode_set,
281         .prepare        = exynos_drm_encoder_prepare,
282         .commit         = exynos_drm_encoder_commit,
283         .disable        = exynos_drm_encoder_disable,
284 };
285
286 static void exynos_drm_encoder_destroy(struct drm_encoder *encoder)
287 {
288         struct exynos_drm_encoder *exynos_encoder =
289                 to_exynos_encoder(encoder);
290
291         DRM_DEBUG_KMS("%s\n", __FILE__);
292
293         exynos_encoder->manager->pipe = -1;
294
295         drm_encoder_cleanup(encoder);
296         kfree(exynos_encoder);
297 }
298
299 static struct drm_encoder_funcs exynos_encoder_funcs = {
300         .destroy = exynos_drm_encoder_destroy,
301 };
302
303 static unsigned int exynos_drm_encoder_clones(struct drm_encoder *encoder)
304 {
305         struct drm_encoder *clone;
306         struct drm_device *dev = encoder->dev;
307         struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
308         struct exynos_drm_display_ops *display_ops =
309                                 exynos_encoder->manager->display_ops;
310         unsigned int clone_mask = 0;
311         int cnt = 0;
312
313         list_for_each_entry(clone, &dev->mode_config.encoder_list, head) {
314                 switch (display_ops->type) {
315                 case EXYNOS_DISPLAY_TYPE_LCD:
316                 case EXYNOS_DISPLAY_TYPE_HDMI:
317                 case EXYNOS_DISPLAY_TYPE_VIDI:
318                         clone_mask |= (1 << (cnt++));
319                         break;
320                 default:
321                         continue;
322                 }
323         }
324
325         return clone_mask;
326 }
327
328 void exynos_drm_encoder_setup(struct drm_device *dev)
329 {
330         struct drm_encoder *encoder;
331
332         DRM_DEBUG_KMS("%s\n", __FILE__);
333
334         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
335                 encoder->possible_clones = exynos_drm_encoder_clones(encoder);
336 }
337
338 struct drm_encoder *
339 exynos_drm_encoder_create(struct drm_device *dev,
340                            struct exynos_drm_manager *manager,
341                            unsigned int possible_crtcs)
342 {
343         struct drm_encoder *encoder;
344         struct exynos_drm_encoder *exynos_encoder;
345
346         DRM_DEBUG_KMS("%s\n", __FILE__);
347
348         if (!manager || !possible_crtcs)
349                 return NULL;
350
351         if (!manager->dev)
352                 return NULL;
353
354         exynos_encoder = kzalloc(sizeof(*exynos_encoder), GFP_KERNEL);
355         if (!exynos_encoder) {
356                 DRM_ERROR("failed to allocate encoder\n");
357                 return NULL;
358         }
359
360         exynos_encoder->dpms = DRM_MODE_DPMS_OFF;
361         exynos_encoder->manager = manager;
362         encoder = &exynos_encoder->drm_encoder;
363         encoder->possible_crtcs = possible_crtcs;
364
365         DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
366
367         drm_encoder_init(dev, encoder, &exynos_encoder_funcs,
368                         DRM_MODE_ENCODER_TMDS);
369
370         drm_encoder_helper_add(encoder, &exynos_encoder_helper_funcs);
371
372         DRM_DEBUG_KMS("encoder has been created\n");
373
374         return encoder;
375 }
376
377 struct exynos_drm_manager *exynos_drm_get_manager(struct drm_encoder *encoder)
378 {
379         return to_exynos_encoder(encoder)->manager;
380 }
381
382 void exynos_drm_fn_encoder(struct drm_crtc *crtc, void *data,
383                             void (*fn)(struct drm_encoder *, void *))
384 {
385         struct drm_device *dev = crtc->dev;
386         struct drm_encoder *encoder;
387         struct exynos_drm_private *private = dev->dev_private;
388         struct exynos_drm_manager *manager;
389
390         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
391                 /*
392                  * if crtc is detached from encoder, check pipe,
393                  * otherwise check crtc attached to encoder
394                  */
395                 if (!encoder->crtc) {
396                         manager = to_exynos_encoder(encoder)->manager;
397                         if (manager->pipe < 0 ||
398                                         private->crtc[manager->pipe] != crtc)
399                                 continue;
400                 } else {
401                         if (encoder->crtc != crtc)
402                                 continue;
403                 }
404
405                 fn(encoder, data);
406         }
407 }
408
409 void exynos_drm_enable_vblank(struct drm_encoder *encoder, void *data)
410 {
411         struct exynos_drm_manager *manager =
412                 to_exynos_encoder(encoder)->manager;
413         struct exynos_drm_manager_ops *manager_ops = manager->ops;
414         int crtc = *(int *)data;
415
416         if (manager->pipe != crtc)
417                 return;
418
419         if (manager_ops->enable_vblank)
420                 manager_ops->enable_vblank(manager->dev);
421 }
422
423 void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data)
424 {
425         struct exynos_drm_manager *manager =
426                 to_exynos_encoder(encoder)->manager;
427         struct exynos_drm_manager_ops *manager_ops = manager->ops;
428         int crtc = *(int *)data;
429
430         if (manager->pipe != crtc)
431                 return;
432
433         if (manager_ops->disable_vblank)
434                 manager_ops->disable_vblank(manager->dev);
435 }
436
437 void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data)
438 {
439         struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
440         struct exynos_drm_manager *manager = exynos_encoder->manager;
441         struct exynos_drm_manager_ops *manager_ops = manager->ops;
442         int mode = *(int *)data;
443
444         DRM_DEBUG_KMS("%s\n", __FILE__);
445
446         if (manager_ops && manager_ops->dpms)
447                 manager_ops->dpms(manager->dev, mode);
448
449         /*
450          * if this condition is ok then it means that the crtc is already
451          * detached from encoder and last function for detaching is properly
452          * done, so clear pipe from manager to prevent repeated call.
453          */
454         if (mode > DRM_MODE_DPMS_ON) {
455                 if (!encoder->crtc)
456                         manager->pipe = -1;
457         }
458 }
459
460 void exynos_drm_encoder_crtc_pipe(struct drm_encoder *encoder, void *data)
461 {
462         struct exynos_drm_manager *manager =
463                 to_exynos_encoder(encoder)->manager;
464         int pipe = *(int *)data;
465
466         DRM_DEBUG_KMS("%s\n", __FILE__);
467
468         /*
469          * when crtc is detached from encoder, this pipe is used
470          * to select manager operation
471          */
472         manager->pipe = pipe;
473 }
474
475 void exynos_drm_encoder_plane_mode_set(struct drm_encoder *encoder, void *data)
476 {
477         struct exynos_drm_manager *manager =
478                 to_exynos_encoder(encoder)->manager;
479         struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
480         struct exynos_drm_overlay *overlay = data;
481
482         DRM_DEBUG_KMS("%s\n", __FILE__);
483
484         if (overlay_ops && overlay_ops->mode_set)
485                 overlay_ops->mode_set(manager->dev, overlay);
486 }
487
488 void exynos_drm_encoder_plane_commit(struct drm_encoder *encoder, void *data)
489 {
490         struct exynos_drm_manager *manager =
491                 to_exynos_encoder(encoder)->manager;
492         struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
493         int zpos = DEFAULT_ZPOS;
494
495         DRM_DEBUG_KMS("%s\n", __FILE__);
496
497         if (data)
498                 zpos = *(int *)data;
499
500         if (overlay_ops && overlay_ops->commit)
501                 overlay_ops->commit(manager->dev, zpos);
502 }
503
504 void exynos_drm_encoder_plane_enable(struct drm_encoder *encoder, void *data)
505 {
506         struct exynos_drm_manager *manager =
507                 to_exynos_encoder(encoder)->manager;
508         struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
509         int zpos = DEFAULT_ZPOS;
510
511         DRM_DEBUG_KMS("%s\n", __FILE__);
512
513         if (data)
514                 zpos = *(int *)data;
515
516         if (overlay_ops && overlay_ops->enable)
517                 overlay_ops->enable(manager->dev, zpos);
518 }
519
520 void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data)
521 {
522         struct exynos_drm_manager *manager =
523                 to_exynos_encoder(encoder)->manager;
524         struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
525         int zpos = DEFAULT_ZPOS;
526
527         DRM_DEBUG_KMS("%s\n", __FILE__);
528
529         if (data)
530                 zpos = *(int *)data;
531
532         if (overlay_ops && overlay_ops->disable)
533                 overlay_ops->disable(manager->dev, zpos);
534 }