]> Git Repo - linux.git/blob - drivers/gpu/drm/omapdrm/omap_drv.c
Merge tag 'gfs2-4.13.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2...
[linux.git] / drivers / gpu / drm / omapdrm / omap_drv.c
1 /*
2  * drivers/gpu/drm/omapdrm/omap_drv.c
3  *
4  * Copyright (C) 2011 Texas Instruments
5  * Author: Rob Clark <[email protected]>
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License version 2 as published by
9  * the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <linux/wait.h>
21
22 #include <drm/drm_atomic.h>
23 #include <drm/drm_atomic_helper.h>
24 #include <drm/drm_crtc_helper.h>
25 #include <drm/drm_fb_helper.h>
26
27 #include "omap_dmm_tiler.h"
28 #include "omap_drv.h"
29
30 #define DRIVER_NAME             MODULE_NAME
31 #define DRIVER_DESC             "OMAP DRM"
32 #define DRIVER_DATE             "20110917"
33 #define DRIVER_MAJOR            1
34 #define DRIVER_MINOR            0
35 #define DRIVER_PATCHLEVEL       0
36
37 /*
38  * mode config funcs
39  */
40
41 /* Notes about mapping DSS and DRM entities:
42  *    CRTC:        overlay
43  *    encoder:     manager.. with some extension to allow one primary CRTC
44  *                 and zero or more video CRTC's to be mapped to one encoder?
45  *    connector:   dssdev.. manager can be attached/detached from different
46  *                 devices
47  */
48
49 static void omap_fb_output_poll_changed(struct drm_device *dev)
50 {
51         struct omap_drm_private *priv = dev->dev_private;
52         DBG("dev=%p", dev);
53         if (priv->fbdev)
54                 drm_fb_helper_hotplug_event(priv->fbdev);
55 }
56
57 struct omap_atomic_state_commit {
58         struct work_struct work;
59         struct drm_device *dev;
60         struct drm_atomic_state *state;
61         u32 crtcs;
62 };
63
64 static void omap_atomic_wait_for_completion(struct drm_device *dev,
65                                             struct drm_atomic_state *old_state)
66 {
67         struct drm_crtc_state *old_crtc_state;
68         struct drm_crtc *crtc;
69         unsigned int i;
70         int ret;
71
72         for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
73                 if (!crtc->state->enable)
74                         continue;
75
76                 ret = omap_crtc_wait_pending(crtc);
77
78                 if (!ret)
79                         dev_warn(dev->dev,
80                                  "atomic complete timeout (pipe %u)!\n", i);
81         }
82 }
83
84 static void omap_atomic_complete(struct omap_atomic_state_commit *commit)
85 {
86         struct drm_device *dev = commit->dev;
87         struct omap_drm_private *priv = dev->dev_private;
88         struct drm_atomic_state *old_state = commit->state;
89
90         /* Apply the atomic update. */
91         priv->dispc_ops->runtime_get();
92
93         drm_atomic_helper_commit_modeset_disables(dev, old_state);
94
95         /* With the current dss dispc implementation we have to enable
96          * the new modeset before we can commit planes. The dispc ovl
97          * configuration relies on the video mode configuration been
98          * written into the HW when the ovl configuration is
99          * calculated.
100          *
101          * This approach is not ideal because after a mode change the
102          * plane update is executed only after the first vblank
103          * interrupt. The dispc implementation should be fixed so that
104          * it is able use uncommitted drm state information.
105          */
106         drm_atomic_helper_commit_modeset_enables(dev, old_state);
107         omap_atomic_wait_for_completion(dev, old_state);
108
109         drm_atomic_helper_commit_planes(dev, old_state, 0);
110
111         omap_atomic_wait_for_completion(dev, old_state);
112
113         drm_atomic_helper_cleanup_planes(dev, old_state);
114
115         priv->dispc_ops->runtime_put();
116
117         drm_atomic_state_put(old_state);
118
119         /* Complete the commit, wake up any waiter. */
120         spin_lock(&priv->commit.lock);
121         priv->commit.pending &= ~commit->crtcs;
122         spin_unlock(&priv->commit.lock);
123
124         wake_up_all(&priv->commit.wait);
125
126         kfree(commit);
127 }
128
129 static void omap_atomic_work(struct work_struct *work)
130 {
131         struct omap_atomic_state_commit *commit =
132                 container_of(work, struct omap_atomic_state_commit, work);
133
134         omap_atomic_complete(commit);
135 }
136
137 static bool omap_atomic_is_pending(struct omap_drm_private *priv,
138                                    struct omap_atomic_state_commit *commit)
139 {
140         bool pending;
141
142         spin_lock(&priv->commit.lock);
143         pending = priv->commit.pending & commit->crtcs;
144         spin_unlock(&priv->commit.lock);
145
146         return pending;
147 }
148
149 static int omap_atomic_commit(struct drm_device *dev,
150                               struct drm_atomic_state *state, bool nonblock)
151 {
152         struct omap_drm_private *priv = dev->dev_private;
153         struct omap_atomic_state_commit *commit;
154         struct drm_crtc *crtc;
155         struct drm_crtc_state *crtc_state;
156         int i, ret;
157
158         ret = drm_atomic_helper_prepare_planes(dev, state);
159         if (ret)
160                 return ret;
161
162         /* Allocate the commit object. */
163         commit = kzalloc(sizeof(*commit), GFP_KERNEL);
164         if (commit == NULL) {
165                 ret = -ENOMEM;
166                 goto error;
167         }
168
169         INIT_WORK(&commit->work, omap_atomic_work);
170         commit->dev = dev;
171         commit->state = state;
172
173         /* Wait until all affected CRTCs have completed previous commits and
174          * mark them as pending.
175          */
176         for_each_crtc_in_state(state, crtc, crtc_state, i)
177                 commit->crtcs |= drm_crtc_mask(crtc);
178
179         wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit));
180
181         spin_lock(&priv->commit.lock);
182         priv->commit.pending |= commit->crtcs;
183         spin_unlock(&priv->commit.lock);
184
185         /* Swap the state, this is the point of no return. */
186         drm_atomic_helper_swap_state(state, true);
187
188         drm_atomic_state_get(state);
189         if (nonblock)
190                 schedule_work(&commit->work);
191         else
192                 omap_atomic_complete(commit);
193
194         return 0;
195
196 error:
197         drm_atomic_helper_cleanup_planes(dev, state);
198         return ret;
199 }
200
201 static const struct drm_mode_config_funcs omap_mode_config_funcs = {
202         .fb_create = omap_framebuffer_create,
203         .output_poll_changed = omap_fb_output_poll_changed,
204         .atomic_check = drm_atomic_helper_check,
205         .atomic_commit = omap_atomic_commit,
206 };
207
208 static int get_connector_type(struct omap_dss_device *dssdev)
209 {
210         switch (dssdev->type) {
211         case OMAP_DISPLAY_TYPE_HDMI:
212                 return DRM_MODE_CONNECTOR_HDMIA;
213         case OMAP_DISPLAY_TYPE_DVI:
214                 return DRM_MODE_CONNECTOR_DVID;
215         case OMAP_DISPLAY_TYPE_DSI:
216                 return DRM_MODE_CONNECTOR_DSI;
217         default:
218                 return DRM_MODE_CONNECTOR_Unknown;
219         }
220 }
221
222 static void omap_disconnect_dssdevs(void)
223 {
224         struct omap_dss_device *dssdev = NULL;
225
226         for_each_dss_dev(dssdev)
227                 dssdev->driver->disconnect(dssdev);
228 }
229
230 static int omap_connect_dssdevs(void)
231 {
232         int r;
233         struct omap_dss_device *dssdev = NULL;
234
235         if (!omapdss_stack_is_ready())
236                 return -EPROBE_DEFER;
237
238         for_each_dss_dev(dssdev) {
239                 r = dssdev->driver->connect(dssdev);
240                 if (r == -EPROBE_DEFER) {
241                         omap_dss_put_device(dssdev);
242                         goto cleanup;
243                 } else if (r) {
244                         dev_warn(dssdev->dev, "could not connect display: %s\n",
245                                 dssdev->name);
246                 }
247         }
248
249         return 0;
250
251 cleanup:
252         /*
253          * if we are deferring probe, we disconnect the devices we previously
254          * connected
255          */
256         omap_disconnect_dssdevs();
257
258         return r;
259 }
260
261 static int omap_modeset_init_properties(struct drm_device *dev)
262 {
263         struct omap_drm_private *priv = dev->dev_private;
264
265         priv->zorder_prop = drm_property_create_range(dev, 0, "zorder", 0, 3);
266         if (!priv->zorder_prop)
267                 return -ENOMEM;
268
269         return 0;
270 }
271
272 static int omap_modeset_init(struct drm_device *dev)
273 {
274         struct omap_drm_private *priv = dev->dev_private;
275         struct omap_dss_device *dssdev = NULL;
276         int num_ovls = priv->dispc_ops->get_num_ovls();
277         int num_mgrs = priv->dispc_ops->get_num_mgrs();
278         int num_crtcs, crtc_idx, plane_idx;
279         int ret;
280         u32 plane_crtc_mask;
281
282         drm_mode_config_init(dev);
283
284         ret = omap_modeset_init_properties(dev);
285         if (ret < 0)
286                 return ret;
287
288         /*
289          * This function creates exactly one connector, encoder, crtc,
290          * and primary plane per each connected dss-device. Each
291          * connector->encoder->crtc chain is expected to be separate
292          * and each crtc is connect to a single dss-channel. If the
293          * configuration does not match the expectations or exceeds
294          * the available resources, the configuration is rejected.
295          */
296         num_crtcs = 0;
297         for_each_dss_dev(dssdev)
298                 if (omapdss_device_is_connected(dssdev))
299                         num_crtcs++;
300
301         if (num_crtcs > num_mgrs || num_crtcs > num_ovls ||
302             num_crtcs > ARRAY_SIZE(priv->crtcs) ||
303             num_crtcs > ARRAY_SIZE(priv->planes) ||
304             num_crtcs > ARRAY_SIZE(priv->encoders) ||
305             num_crtcs > ARRAY_SIZE(priv->connectors)) {
306                 dev_err(dev->dev, "%s(): Too many connected displays\n",
307                         __func__);
308                 return -EINVAL;
309         }
310
311         /* All planes can be put to any CRTC */
312         plane_crtc_mask = (1 << num_crtcs) - 1;
313
314         dssdev = NULL;
315
316         crtc_idx = 0;
317         plane_idx = 0;
318         for_each_dss_dev(dssdev) {
319                 struct drm_connector *connector;
320                 struct drm_encoder *encoder;
321                 struct drm_plane *plane;
322                 struct drm_crtc *crtc;
323
324                 if (!omapdss_device_is_connected(dssdev))
325                         continue;
326
327                 encoder = omap_encoder_init(dev, dssdev);
328                 if (!encoder)
329                         return -ENOMEM;
330
331                 connector = omap_connector_init(dev,
332                                 get_connector_type(dssdev), dssdev, encoder);
333                 if (!connector)
334                         return -ENOMEM;
335
336                 plane = omap_plane_init(dev, plane_idx, DRM_PLANE_TYPE_PRIMARY,
337                                         plane_crtc_mask);
338                 if (IS_ERR(plane))
339                         return PTR_ERR(plane);
340
341                 crtc = omap_crtc_init(dev, plane, dssdev);
342                 if (IS_ERR(crtc))
343                         return PTR_ERR(crtc);
344
345                 drm_mode_connector_attach_encoder(connector, encoder);
346                 encoder->possible_crtcs = (1 << crtc_idx);
347
348                 priv->crtcs[priv->num_crtcs++] = crtc;
349                 priv->planes[priv->num_planes++] = plane;
350                 priv->encoders[priv->num_encoders++] = encoder;
351                 priv->connectors[priv->num_connectors++] = connector;
352
353                 plane_idx++;
354                 crtc_idx++;
355         }
356
357         /*
358          * Create normal planes for the remaining overlays:
359          */
360         for (; plane_idx < num_ovls; plane_idx++) {
361                 struct drm_plane *plane;
362
363                 if (WARN_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)))
364                         return -EINVAL;
365
366                 plane = omap_plane_init(dev, plane_idx, DRM_PLANE_TYPE_OVERLAY,
367                         plane_crtc_mask);
368                 if (IS_ERR(plane))
369                         return PTR_ERR(plane);
370
371                 priv->planes[priv->num_planes++] = plane;
372         }
373
374         DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n",
375                 priv->num_planes, priv->num_crtcs, priv->num_encoders,
376                 priv->num_connectors);
377
378         dev->mode_config.min_width = 8;
379         dev->mode_config.min_height = 2;
380
381         /* note: eventually will need some cpu_is_omapXYZ() type stuff here
382          * to fill in these limits properly on different OMAP generations..
383          */
384         dev->mode_config.max_width = 2048;
385         dev->mode_config.max_height = 2048;
386
387         dev->mode_config.funcs = &omap_mode_config_funcs;
388
389         drm_mode_config_reset(dev);
390
391         omap_drm_irq_install(dev);
392
393         return 0;
394 }
395
396 /*
397  * drm ioctl funcs
398  */
399
400
401 static int ioctl_get_param(struct drm_device *dev, void *data,
402                 struct drm_file *file_priv)
403 {
404         struct omap_drm_private *priv = dev->dev_private;
405         struct drm_omap_param *args = data;
406
407         DBG("%p: param=%llu", dev, args->param);
408
409         switch (args->param) {
410         case OMAP_PARAM_CHIPSET_ID:
411                 args->value = priv->omaprev;
412                 break;
413         default:
414                 DBG("unknown parameter %lld", args->param);
415                 return -EINVAL;
416         }
417
418         return 0;
419 }
420
421 static int ioctl_set_param(struct drm_device *dev, void *data,
422                 struct drm_file *file_priv)
423 {
424         struct drm_omap_param *args = data;
425
426         switch (args->param) {
427         default:
428                 DBG("unknown parameter %lld", args->param);
429                 return -EINVAL;
430         }
431
432         return 0;
433 }
434
435 #define OMAP_BO_USER_MASK       0x00ffffff      /* flags settable by userspace */
436
437 static int ioctl_gem_new(struct drm_device *dev, void *data,
438                 struct drm_file *file_priv)
439 {
440         struct drm_omap_gem_new *args = data;
441         u32 flags = args->flags & OMAP_BO_USER_MASK;
442
443         VERB("%p:%p: size=0x%08x, flags=%08x", dev, file_priv,
444              args->size.bytes, flags);
445
446         return omap_gem_new_handle(dev, file_priv, args->size, flags,
447                                    &args->handle);
448 }
449
450 static int ioctl_gem_cpu_prep(struct drm_device *dev, void *data,
451                 struct drm_file *file_priv)
452 {
453         struct drm_omap_gem_cpu_prep *args = data;
454         struct drm_gem_object *obj;
455         int ret;
456
457         VERB("%p:%p: handle=%d, op=%x", dev, file_priv, args->handle, args->op);
458
459         obj = drm_gem_object_lookup(file_priv, args->handle);
460         if (!obj)
461                 return -ENOENT;
462
463         ret = omap_gem_op_sync(obj, args->op);
464
465         if (!ret)
466                 ret = omap_gem_op_start(obj, args->op);
467
468         drm_gem_object_unreference_unlocked(obj);
469
470         return ret;
471 }
472
473 static int ioctl_gem_cpu_fini(struct drm_device *dev, void *data,
474                 struct drm_file *file_priv)
475 {
476         struct drm_omap_gem_cpu_fini *args = data;
477         struct drm_gem_object *obj;
478         int ret;
479
480         VERB("%p:%p: handle=%d", dev, file_priv, args->handle);
481
482         obj = drm_gem_object_lookup(file_priv, args->handle);
483         if (!obj)
484                 return -ENOENT;
485
486         /* XXX flushy, flushy */
487         ret = 0;
488
489         if (!ret)
490                 ret = omap_gem_op_finish(obj, args->op);
491
492         drm_gem_object_unreference_unlocked(obj);
493
494         return ret;
495 }
496
497 static int ioctl_gem_info(struct drm_device *dev, void *data,
498                 struct drm_file *file_priv)
499 {
500         struct drm_omap_gem_info *args = data;
501         struct drm_gem_object *obj;
502         int ret = 0;
503
504         VERB("%p:%p: handle=%d", dev, file_priv, args->handle);
505
506         obj = drm_gem_object_lookup(file_priv, args->handle);
507         if (!obj)
508                 return -ENOENT;
509
510         args->size = omap_gem_mmap_size(obj);
511         args->offset = omap_gem_mmap_offset(obj);
512
513         drm_gem_object_unreference_unlocked(obj);
514
515         return ret;
516 }
517
518 static const struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = {
519         DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param,
520                           DRM_AUTH | DRM_RENDER_ALLOW),
521         DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, ioctl_set_param,
522                           DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
523         DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new,
524                           DRM_AUTH | DRM_RENDER_ALLOW),
525         DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_PREP, ioctl_gem_cpu_prep,
526                           DRM_AUTH | DRM_RENDER_ALLOW),
527         DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_FINI, ioctl_gem_cpu_fini,
528                           DRM_AUTH | DRM_RENDER_ALLOW),
529         DRM_IOCTL_DEF_DRV(OMAP_GEM_INFO, ioctl_gem_info,
530                           DRM_AUTH | DRM_RENDER_ALLOW),
531 };
532
533 /*
534  * drm driver funcs
535  */
536
537 static int dev_open(struct drm_device *dev, struct drm_file *file)
538 {
539         file->driver_priv = NULL;
540
541         DBG("open: dev=%p, file=%p", dev, file);
542
543         return 0;
544 }
545
546 /**
547  * lastclose - clean up after all DRM clients have exited
548  * @dev: DRM device
549  *
550  * Take care of cleaning up after all DRM clients have exited.  In the
551  * mode setting case, we want to restore the kernel's initial mode (just
552  * in case the last client left us in a bad state).
553  */
554 static void dev_lastclose(struct drm_device *dev)
555 {
556         int i;
557
558         /* we don't support vga_switcheroo.. so just make sure the fbdev
559          * mode is active
560          */
561         struct omap_drm_private *priv = dev->dev_private;
562         int ret;
563
564         DBG("lastclose: dev=%p", dev);
565
566         /* need to restore default rotation state.. not sure
567          * if there is a cleaner way to restore properties to
568          * default state?  Maybe a flag that properties should
569          * automatically be restored to default state on
570          * lastclose?
571          */
572         for (i = 0; i < priv->num_crtcs; i++) {
573                 struct drm_crtc *crtc = priv->crtcs[i];
574
575                 if (!crtc->primary->rotation_property)
576                         continue;
577
578                 drm_object_property_set_value(&crtc->base,
579                                               crtc->primary->rotation_property,
580                                               DRM_ROTATE_0);
581         }
582
583         for (i = 0; i < priv->num_planes; i++) {
584                 struct drm_plane *plane = priv->planes[i];
585
586                 if (!plane->rotation_property)
587                         continue;
588
589                 drm_object_property_set_value(&plane->base,
590                                               plane->rotation_property,
591                                               DRM_ROTATE_0);
592         }
593
594         if (priv->fbdev) {
595                 ret = drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev);
596                 if (ret)
597                         DBG("failed to restore crtc mode");
598         }
599 }
600
601 static const struct vm_operations_struct omap_gem_vm_ops = {
602         .fault = omap_gem_fault,
603         .open = drm_gem_vm_open,
604         .close = drm_gem_vm_close,
605 };
606
607 static const struct file_operations omapdriver_fops = {
608         .owner = THIS_MODULE,
609         .open = drm_open,
610         .unlocked_ioctl = drm_ioctl,
611         .release = drm_release,
612         .mmap = omap_gem_mmap,
613         .poll = drm_poll,
614         .read = drm_read,
615         .llseek = noop_llseek,
616 };
617
618 static struct drm_driver omap_drm_driver = {
619         .driver_features = DRIVER_MODESET | DRIVER_GEM  | DRIVER_PRIME |
620                 DRIVER_ATOMIC | DRIVER_RENDER,
621         .open = dev_open,
622         .lastclose = dev_lastclose,
623 #ifdef CONFIG_DEBUG_FS
624         .debugfs_init = omap_debugfs_init,
625 #endif
626         .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
627         .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
628         .gem_prime_export = omap_gem_prime_export,
629         .gem_prime_import = omap_gem_prime_import,
630         .gem_free_object = omap_gem_free_object,
631         .gem_vm_ops = &omap_gem_vm_ops,
632         .dumb_create = omap_gem_dumb_create,
633         .dumb_map_offset = omap_gem_dumb_map_offset,
634         .dumb_destroy = drm_gem_dumb_destroy,
635         .ioctls = ioctls,
636         .num_ioctls = DRM_OMAP_NUM_IOCTLS,
637         .fops = &omapdriver_fops,
638         .name = DRIVER_NAME,
639         .desc = DRIVER_DESC,
640         .date = DRIVER_DATE,
641         .major = DRIVER_MAJOR,
642         .minor = DRIVER_MINOR,
643         .patchlevel = DRIVER_PATCHLEVEL,
644 };
645
646 static int pdev_probe(struct platform_device *pdev)
647 {
648         struct omap_drm_platform_data *pdata = pdev->dev.platform_data;
649         struct omap_drm_private *priv;
650         struct drm_device *ddev;
651         unsigned int i;
652         int ret;
653
654         DBG("%s", pdev->name);
655
656         if (omapdss_is_initialized() == false)
657                 return -EPROBE_DEFER;
658
659         omap_crtc_pre_init();
660
661         ret = omap_connect_dssdevs();
662         if (ret)
663                 goto err_crtc_uninit;
664
665         /* Allocate and initialize the driver private structure. */
666         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
667         if (!priv) {
668                 ret = -ENOMEM;
669                 goto err_disconnect_dssdevs;
670         }
671
672         priv->dispc_ops = dispc_get_ops();
673
674         priv->omaprev = pdata->omaprev;
675         priv->wq = alloc_ordered_workqueue("omapdrm", 0);
676
677         init_waitqueue_head(&priv->commit.wait);
678         spin_lock_init(&priv->commit.lock);
679         spin_lock_init(&priv->list_lock);
680         INIT_LIST_HEAD(&priv->obj_list);
681
682         /* Allocate and initialize the DRM device. */
683         ddev = drm_dev_alloc(&omap_drm_driver, &pdev->dev);
684         if (IS_ERR(ddev)) {
685                 ret = PTR_ERR(ddev);
686                 goto err_free_priv;
687         }
688
689         ddev->dev_private = priv;
690         platform_set_drvdata(pdev, ddev);
691
692         omap_gem_init(ddev);
693
694         ret = omap_modeset_init(ddev);
695         if (ret) {
696                 dev_err(&pdev->dev, "omap_modeset_init failed: ret=%d\n", ret);
697                 goto err_free_drm_dev;
698         }
699
700         /* Initialize vblank handling, start with all CRTCs disabled. */
701         ret = drm_vblank_init(ddev, priv->num_crtcs);
702         if (ret) {
703                 dev_err(&pdev->dev, "could not init vblank\n");
704                 goto err_cleanup_modeset;
705         }
706
707         for (i = 0; i < priv->num_crtcs; i++)
708                 drm_crtc_vblank_off(priv->crtcs[i]);
709
710         priv->fbdev = omap_fbdev_init(ddev);
711
712         drm_kms_helper_poll_init(ddev);
713
714         /*
715          * Register the DRM device with the core and the connectors with
716          * sysfs.
717          */
718         ret = drm_dev_register(ddev, 0);
719         if (ret)
720                 goto err_cleanup_helpers;
721
722         return 0;
723
724 err_cleanup_helpers:
725         drm_kms_helper_poll_fini(ddev);
726         if (priv->fbdev)
727                 omap_fbdev_free(ddev);
728 err_cleanup_modeset:
729         drm_mode_config_cleanup(ddev);
730         omap_drm_irq_uninstall(ddev);
731 err_free_drm_dev:
732         omap_gem_deinit(ddev);
733         drm_dev_unref(ddev);
734 err_free_priv:
735         destroy_workqueue(priv->wq);
736         kfree(priv);
737 err_disconnect_dssdevs:
738         omap_disconnect_dssdevs();
739 err_crtc_uninit:
740         omap_crtc_pre_uninit();
741         return ret;
742 }
743
744 static int pdev_remove(struct platform_device *pdev)
745 {
746         struct drm_device *ddev = platform_get_drvdata(pdev);
747         struct omap_drm_private *priv = ddev->dev_private;
748
749         DBG("");
750
751         drm_dev_unregister(ddev);
752
753         drm_kms_helper_poll_fini(ddev);
754
755         if (priv->fbdev)
756                 omap_fbdev_free(ddev);
757
758         drm_atomic_helper_shutdown(ddev);
759
760         drm_mode_config_cleanup(ddev);
761
762         omap_drm_irq_uninstall(ddev);
763         omap_gem_deinit(ddev);
764
765         drm_dev_unref(ddev);
766
767         destroy_workqueue(priv->wq);
768         kfree(priv);
769
770         omap_disconnect_dssdevs();
771         omap_crtc_pre_uninit();
772
773         return 0;
774 }
775
776 #ifdef CONFIG_PM_SLEEP
777 static int omap_drm_suspend_all_displays(void)
778 {
779         struct omap_dss_device *dssdev = NULL;
780
781         for_each_dss_dev(dssdev) {
782                 if (!dssdev->driver)
783                         continue;
784
785                 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
786                         dssdev->driver->disable(dssdev);
787                         dssdev->activate_after_resume = true;
788                 } else {
789                         dssdev->activate_after_resume = false;
790                 }
791         }
792
793         return 0;
794 }
795
796 static int omap_drm_resume_all_displays(void)
797 {
798         struct omap_dss_device *dssdev = NULL;
799
800         for_each_dss_dev(dssdev) {
801                 if (!dssdev->driver)
802                         continue;
803
804                 if (dssdev->activate_after_resume) {
805                         dssdev->driver->enable(dssdev);
806                         dssdev->activate_after_resume = false;
807                 }
808         }
809
810         return 0;
811 }
812
813 static int omap_drm_suspend(struct device *dev)
814 {
815         struct drm_device *drm_dev = dev_get_drvdata(dev);
816
817         drm_kms_helper_poll_disable(drm_dev);
818
819         drm_modeset_lock_all(drm_dev);
820         omap_drm_suspend_all_displays();
821         drm_modeset_unlock_all(drm_dev);
822
823         return 0;
824 }
825
826 static int omap_drm_resume(struct device *dev)
827 {
828         struct drm_device *drm_dev = dev_get_drvdata(dev);
829
830         drm_modeset_lock_all(drm_dev);
831         omap_drm_resume_all_displays();
832         drm_modeset_unlock_all(drm_dev);
833
834         drm_kms_helper_poll_enable(drm_dev);
835
836         return omap_gem_resume(dev);
837 }
838 #endif
839
840 static SIMPLE_DEV_PM_OPS(omapdrm_pm_ops, omap_drm_suspend, omap_drm_resume);
841
842 static struct platform_driver pdev = {
843         .driver = {
844                 .name = DRIVER_NAME,
845                 .pm = &omapdrm_pm_ops,
846         },
847         .probe = pdev_probe,
848         .remove = pdev_remove,
849 };
850
851 static struct platform_driver * const drivers[] = {
852         &omap_dmm_driver,
853         &pdev,
854 };
855
856 static int __init omap_drm_init(void)
857 {
858         DBG("init");
859
860         return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
861 }
862
863 static void __exit omap_drm_fini(void)
864 {
865         DBG("fini");
866
867         platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
868 }
869
870 /* need late_initcall() so we load after dss_driver's are loaded */
871 late_initcall(omap_drm_init);
872 module_exit(omap_drm_fini);
873
874 MODULE_AUTHOR("Rob Clark <[email protected]>");
875 MODULE_DESCRIPTION("OMAP DRM Display Driver");
876 MODULE_ALIAS("platform:" DRIVER_NAME);
877 MODULE_LICENSE("GPL v2");
This page took 0.082533 seconds and 4 git commands to generate.