GNU Linux-libre 4.9.337-gnu1
[releases.git] / drivers / gpu / drm / imx / imx-drm-core.c
1 /*
2  * Freescale i.MX drm driver
3  *
4  * Copyright (C) 2011 Sascha Hauer, Pengutronix
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16 #include <linux/component.h>
17 #include <linux/device.h>
18 #include <linux/dma-buf.h>
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <linux/reservation.h>
22 #include <drm/drmP.h>
23 #include <drm/drm_atomic.h>
24 #include <drm/drm_atomic_helper.h>
25 #include <drm/drm_fb_helper.h>
26 #include <drm/drm_crtc_helper.h>
27 #include <drm/drm_gem_cma_helper.h>
28 #include <drm/drm_fb_cma_helper.h>
29 #include <drm/drm_plane_helper.h>
30 #include <drm/drm_of.h>
31 #include <video/imx-ipu-v3.h>
32
33 #include "imx-drm.h"
34
35 #define MAX_CRTC        4
36
37 struct imx_drm_component {
38         struct device_node *of_node;
39         struct list_head list;
40 };
41
42 struct imx_drm_device {
43         struct drm_device                       *drm;
44         struct imx_drm_crtc                     *crtc[MAX_CRTC];
45         unsigned int                            pipes;
46         struct drm_fbdev_cma                    *fbhelper;
47         struct drm_atomic_state                 *state;
48 };
49
50 struct imx_drm_crtc {
51         struct drm_crtc                         *crtc;
52         struct imx_drm_crtc_helper_funcs        imx_drm_helper_funcs;
53 };
54
55 #if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
56 static int legacyfb_depth = 16;
57 module_param(legacyfb_depth, int, 0444);
58 #endif
59
60 static void imx_drm_driver_lastclose(struct drm_device *drm)
61 {
62         struct imx_drm_device *imxdrm = drm->dev_private;
63
64         drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
65 }
66
67 static int imx_drm_enable_vblank(struct drm_device *drm, unsigned int pipe)
68 {
69         struct imx_drm_device *imxdrm = drm->dev_private;
70         struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[pipe];
71         int ret;
72
73         if (!imx_drm_crtc)
74                 return -EINVAL;
75
76         if (!imx_drm_crtc->imx_drm_helper_funcs.enable_vblank)
77                 return -ENOSYS;
78
79         ret = imx_drm_crtc->imx_drm_helper_funcs.enable_vblank(
80                         imx_drm_crtc->crtc);
81
82         return ret;
83 }
84
85 static void imx_drm_disable_vblank(struct drm_device *drm, unsigned int pipe)
86 {
87         struct imx_drm_device *imxdrm = drm->dev_private;
88         struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[pipe];
89
90         if (!imx_drm_crtc)
91                 return;
92
93         if (!imx_drm_crtc->imx_drm_helper_funcs.disable_vblank)
94                 return;
95
96         imx_drm_crtc->imx_drm_helper_funcs.disable_vblank(imx_drm_crtc->crtc);
97 }
98
99 static const struct file_operations imx_drm_driver_fops = {
100         .owner = THIS_MODULE,
101         .open = drm_open,
102         .release = drm_release,
103         .unlocked_ioctl = drm_ioctl,
104         .mmap = drm_gem_cma_mmap,
105         .poll = drm_poll,
106         .read = drm_read,
107         .llseek = noop_llseek,
108 };
109
110 void imx_drm_connector_destroy(struct drm_connector *connector)
111 {
112         drm_connector_unregister(connector);
113         drm_connector_cleanup(connector);
114 }
115 EXPORT_SYMBOL_GPL(imx_drm_connector_destroy);
116
117 void imx_drm_encoder_destroy(struct drm_encoder *encoder)
118 {
119         drm_encoder_cleanup(encoder);
120 }
121 EXPORT_SYMBOL_GPL(imx_drm_encoder_destroy);
122
123 static void imx_drm_output_poll_changed(struct drm_device *drm)
124 {
125         struct imx_drm_device *imxdrm = drm->dev_private;
126
127         drm_fbdev_cma_hotplug_event(imxdrm->fbhelper);
128 }
129
130 static int imx_drm_atomic_check(struct drm_device *dev,
131                                 struct drm_atomic_state *state)
132 {
133         int ret;
134
135         ret = drm_atomic_helper_check_modeset(dev, state);
136         if (ret)
137                 return ret;
138
139         ret = drm_atomic_helper_check_planes(dev, state);
140         if (ret)
141                 return ret;
142
143         /*
144          * Check modeset again in case crtc_state->mode_changed is
145          * updated in plane's ->atomic_check callback.
146          */
147         ret = drm_atomic_helper_check_modeset(dev, state);
148         if (ret)
149                 return ret;
150
151         return ret;
152 }
153
154 static int imx_drm_atomic_commit(struct drm_device *dev,
155                                  struct drm_atomic_state *state,
156                                  bool nonblock)
157 {
158         struct drm_plane_state *plane_state;
159         struct drm_plane *plane;
160         struct dma_buf *dma_buf;
161         int i;
162
163         /*
164          * If the plane fb has an dma-buf attached, fish out the exclusive
165          * fence for the atomic helper to wait on.
166          */
167         for_each_plane_in_state(state, plane, plane_state, i) {
168                 if ((plane->state->fb != plane_state->fb) && plane_state->fb) {
169                         dma_buf = drm_fb_cma_get_gem_obj(plane_state->fb,
170                                                          0)->base.dma_buf;
171                         if (!dma_buf)
172                                 continue;
173                         plane_state->fence =
174                                 reservation_object_get_excl_rcu(dma_buf->resv);
175                 }
176         }
177
178         return drm_atomic_helper_commit(dev, state, nonblock);
179 }
180
181 static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
182         .fb_create = drm_fb_cma_create,
183         .output_poll_changed = imx_drm_output_poll_changed,
184         .atomic_check = imx_drm_atomic_check,
185         .atomic_commit = imx_drm_atomic_commit,
186 };
187
188 static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state)
189 {
190         struct drm_device *dev = state->dev;
191
192         drm_atomic_helper_commit_modeset_disables(dev, state);
193
194         drm_atomic_helper_commit_planes(dev, state,
195                                 DRM_PLANE_COMMIT_ACTIVE_ONLY |
196                                 DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET);
197
198         drm_atomic_helper_commit_modeset_enables(dev, state);
199
200         drm_atomic_helper_commit_hw_done(state);
201
202         drm_atomic_helper_wait_for_vblanks(dev, state);
203
204         drm_atomic_helper_cleanup_planes(dev, state);
205 }
206
207 static struct drm_mode_config_helper_funcs imx_drm_mode_config_helpers = {
208         .atomic_commit_tail = imx_drm_atomic_commit_tail,
209 };
210
211 /*
212  * imx_drm_add_crtc - add a new crtc
213  */
214 int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
215                 struct imx_drm_crtc **new_crtc, struct drm_plane *primary_plane,
216                 const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs,
217                 struct device_node *port)
218 {
219         struct imx_drm_device *imxdrm = drm->dev_private;
220         struct imx_drm_crtc *imx_drm_crtc;
221
222         /*
223          * The vblank arrays are dimensioned by MAX_CRTC - we can't
224          * pass IDs greater than this to those functions.
225          */
226         if (imxdrm->pipes >= MAX_CRTC)
227                 return -EINVAL;
228
229         if (imxdrm->drm->open_count)
230                 return -EBUSY;
231
232         imx_drm_crtc = kzalloc(sizeof(*imx_drm_crtc), GFP_KERNEL);
233         if (!imx_drm_crtc)
234                 return -ENOMEM;
235
236         imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs;
237         imx_drm_crtc->crtc = crtc;
238
239         crtc->port = port;
240
241         imxdrm->crtc[imxdrm->pipes++] = imx_drm_crtc;
242
243         *new_crtc = imx_drm_crtc;
244
245         drm_crtc_helper_add(crtc,
246                         imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs);
247
248         drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
249                         imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs, NULL);
250
251         return 0;
252 }
253 EXPORT_SYMBOL_GPL(imx_drm_add_crtc);
254
255 /*
256  * imx_drm_remove_crtc - remove a crtc
257  */
258 int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc)
259 {
260         struct imx_drm_device *imxdrm = imx_drm_crtc->crtc->dev->dev_private;
261         unsigned int pipe = drm_crtc_index(imx_drm_crtc->crtc);
262
263         drm_crtc_cleanup(imx_drm_crtc->crtc);
264
265         imxdrm->crtc[pipe] = NULL;
266
267         kfree(imx_drm_crtc);
268
269         return 0;
270 }
271 EXPORT_SYMBOL_GPL(imx_drm_remove_crtc);
272
273 int imx_drm_encoder_parse_of(struct drm_device *drm,
274         struct drm_encoder *encoder, struct device_node *np)
275 {
276         uint32_t crtc_mask = drm_of_find_possible_crtcs(drm, np);
277
278         /*
279          * If we failed to find the CRTC(s) which this encoder is
280          * supposed to be connected to, it's because the CRTC has
281          * not been registered yet.  Defer probing, and hope that
282          * the required CRTC is added later.
283          */
284         if (crtc_mask == 0)
285                 return -EPROBE_DEFER;
286
287         encoder->possible_crtcs = crtc_mask;
288
289         /* FIXME: this is the mask of outputs which can clone this output. */
290         encoder->possible_clones = ~0;
291
292         return 0;
293 }
294 EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of);
295
296 static const struct drm_ioctl_desc imx_drm_ioctls[] = {
297         /* none so far */
298 };
299
300 static struct drm_driver imx_drm_driver = {
301         .driver_features        = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
302                                   DRIVER_ATOMIC,
303         .lastclose              = imx_drm_driver_lastclose,
304         .gem_free_object_unlocked = drm_gem_cma_free_object,
305         .gem_vm_ops             = &drm_gem_cma_vm_ops,
306         .dumb_create            = drm_gem_cma_dumb_create,
307         .dumb_map_offset        = drm_gem_cma_dumb_map_offset,
308         .dumb_destroy           = drm_gem_dumb_destroy,
309
310         .prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
311         .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
312         .gem_prime_import       = drm_gem_prime_import,
313         .gem_prime_export       = drm_gem_prime_export,
314         .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
315         .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
316         .gem_prime_vmap         = drm_gem_cma_prime_vmap,
317         .gem_prime_vunmap       = drm_gem_cma_prime_vunmap,
318         .gem_prime_mmap         = drm_gem_cma_prime_mmap,
319         .get_vblank_counter     = drm_vblank_no_hw_counter,
320         .enable_vblank          = imx_drm_enable_vblank,
321         .disable_vblank         = imx_drm_disable_vblank,
322         .ioctls                 = imx_drm_ioctls,
323         .num_ioctls             = ARRAY_SIZE(imx_drm_ioctls),
324         .fops                   = &imx_drm_driver_fops,
325         .name                   = "imx-drm",
326         .desc                   = "i.MX DRM graphics",
327         .date                   = "20120507",
328         .major                  = 1,
329         .minor                  = 0,
330         .patchlevel             = 0,
331 };
332
333 static int compare_of(struct device *dev, void *data)
334 {
335         struct device_node *np = data;
336
337         /* Special case for DI, dev->of_node may not be set yet */
338         if (strcmp(dev->driver->name, "imx-ipuv3-crtc") == 0) {
339                 struct ipu_client_platformdata *pdata = dev->platform_data;
340
341                 return pdata->of_node == np;
342         }
343
344         /* Special case for LDB, one device for two channels */
345         if (of_node_cmp(np->name, "lvds-channel") == 0) {
346                 np = of_get_parent(np);
347                 of_node_put(np);
348         }
349
350         return dev->of_node == np;
351 }
352
353 static int imx_drm_bind(struct device *dev)
354 {
355         struct drm_device *drm;
356         struct imx_drm_device *imxdrm;
357         int ret;
358
359         drm = drm_dev_alloc(&imx_drm_driver, dev);
360         if (IS_ERR(drm))
361                 return PTR_ERR(drm);
362
363         imxdrm = devm_kzalloc(dev, sizeof(*imxdrm), GFP_KERNEL);
364         if (!imxdrm) {
365                 ret = -ENOMEM;
366                 goto err_unref;
367         }
368
369         imxdrm->drm = drm;
370         drm->dev_private = imxdrm;
371
372         /*
373          * enable drm irq mode.
374          * - with irq_enabled = true, we can use the vblank feature.
375          *
376          * P.S. note that we wouldn't use drm irq handler but
377          *      just specific driver own one instead because
378          *      drm framework supports only one irq handler and
379          *      drivers can well take care of their interrupts
380          */
381         drm->irq_enabled = true;
382
383         /*
384          * set max width and height as default value(4096x4096).
385          * this value would be used to check framebuffer size limitation
386          * at drm_mode_addfb().
387          */
388         drm->mode_config.min_width = 64;
389         drm->mode_config.min_height = 64;
390         drm->mode_config.max_width = 4096;
391         drm->mode_config.max_height = 4096;
392         drm->mode_config.funcs = &imx_drm_mode_config_funcs;
393         drm->mode_config.helper_private = &imx_drm_mode_config_helpers;
394
395         drm_mode_config_init(drm);
396
397         ret = drm_vblank_init(drm, MAX_CRTC);
398         if (ret)
399                 goto err_kms;
400
401         dev_set_drvdata(dev, drm);
402
403         /* Now try and bind all our sub-components */
404         ret = component_bind_all(dev, drm);
405         if (ret)
406                 goto err_vblank;
407
408         drm_mode_config_reset(drm);
409
410         /*
411          * All components are now initialised, so setup the fb helper.
412          * The fb helper takes copies of key hardware information, so the
413          * crtcs/connectors/encoders must not change after this point.
414          */
415 #if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
416         if (legacyfb_depth != 16 && legacyfb_depth != 32) {
417                 dev_warn(dev, "Invalid legacyfb_depth.  Defaulting to 16bpp\n");
418                 legacyfb_depth = 16;
419         }
420         imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
421                                 drm->mode_config.num_crtc, MAX_CRTC);
422         if (IS_ERR(imxdrm->fbhelper)) {
423                 ret = PTR_ERR(imxdrm->fbhelper);
424                 imxdrm->fbhelper = NULL;
425                 goto err_unbind;
426         }
427 #endif
428
429         drm_kms_helper_poll_init(drm);
430
431         ret = drm_dev_register(drm, 0);
432         if (ret)
433                 goto err_fbhelper;
434
435         return 0;
436
437 err_fbhelper:
438         drm_kms_helper_poll_fini(drm);
439 #if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
440         if (imxdrm->fbhelper)
441                 drm_fbdev_cma_fini(imxdrm->fbhelper);
442 err_unbind:
443 #endif
444         component_unbind_all(drm->dev, drm);
445 err_vblank:
446         drm_vblank_cleanup(drm);
447 err_kms:
448         drm_mode_config_cleanup(drm);
449 err_unref:
450         drm_dev_unref(drm);
451
452         return ret;
453 }
454
455 static void imx_drm_unbind(struct device *dev)
456 {
457         struct drm_device *drm = dev_get_drvdata(dev);
458         struct imx_drm_device *imxdrm = drm->dev_private;
459
460         drm_dev_unregister(drm);
461
462         drm_kms_helper_poll_fini(drm);
463
464         if (imxdrm->fbhelper)
465                 drm_fbdev_cma_fini(imxdrm->fbhelper);
466
467         drm_mode_config_cleanup(drm);
468
469         component_unbind_all(drm->dev, drm);
470         dev_set_drvdata(dev, NULL);
471
472         drm_dev_unref(drm);
473 }
474
475 static const struct component_master_ops imx_drm_ops = {
476         .bind = imx_drm_bind,
477         .unbind = imx_drm_unbind,
478 };
479
480 static int imx_drm_platform_probe(struct platform_device *pdev)
481 {
482         int ret = drm_of_component_probe(&pdev->dev, compare_of, &imx_drm_ops);
483
484         if (!ret)
485                 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
486
487         return ret;
488 }
489
490 static int imx_drm_platform_remove(struct platform_device *pdev)
491 {
492         component_master_del(&pdev->dev, &imx_drm_ops);
493         return 0;
494 }
495
496 #ifdef CONFIG_PM_SLEEP
497 static int imx_drm_suspend(struct device *dev)
498 {
499         struct drm_device *drm_dev = dev_get_drvdata(dev);
500         struct imx_drm_device *imxdrm;
501
502         /* The drm_dev is NULL before .load hook is called */
503         if (drm_dev == NULL)
504                 return 0;
505
506         drm_kms_helper_poll_disable(drm_dev);
507
508         imxdrm = drm_dev->dev_private;
509         imxdrm->state = drm_atomic_helper_suspend(drm_dev);
510         if (IS_ERR(imxdrm->state)) {
511                 drm_kms_helper_poll_enable(drm_dev);
512                 return PTR_ERR(imxdrm->state);
513         }
514
515         return 0;
516 }
517
518 static int imx_drm_resume(struct device *dev)
519 {
520         struct drm_device *drm_dev = dev_get_drvdata(dev);
521         struct imx_drm_device *imx_drm;
522
523         if (drm_dev == NULL)
524                 return 0;
525
526         imx_drm = drm_dev->dev_private;
527         drm_atomic_helper_resume(drm_dev, imx_drm->state);
528         drm_kms_helper_poll_enable(drm_dev);
529
530         return 0;
531 }
532 #endif
533
534 static SIMPLE_DEV_PM_OPS(imx_drm_pm_ops, imx_drm_suspend, imx_drm_resume);
535
536 static const struct of_device_id imx_drm_dt_ids[] = {
537         { .compatible = "fsl,imx-display-subsystem", },
538         { /* sentinel */ },
539 };
540 MODULE_DEVICE_TABLE(of, imx_drm_dt_ids);
541
542 static struct platform_driver imx_drm_pdrv = {
543         .probe          = imx_drm_platform_probe,
544         .remove         = imx_drm_platform_remove,
545         .driver         = {
546                 .name   = "imx-drm",
547                 .pm     = &imx_drm_pm_ops,
548                 .of_match_table = imx_drm_dt_ids,
549         },
550 };
551 module_platform_driver(imx_drm_pdrv);
552
553 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
554 MODULE_DESCRIPTION("i.MX drm driver core");
555 MODULE_LICENSE("GPL");