]> Git Repo - linux.git/blob - drivers/gpu/drm/omapdrm/omap_drv.c
Merge tag 'cxl-for-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl
[linux.git] / drivers / gpu / drm / omapdrm / omap_drv.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
4  * Author: Rob Clark <[email protected]>
5  */
6
7 #include <linux/dma-mapping.h>
8 #include <linux/platform_device.h>
9 #include <linux/of.h>
10 #include <linux/sort.h>
11 #include <linux/sys_soc.h>
12
13 #include <drm/drm_atomic.h>
14 #include <drm/drm_atomic_helper.h>
15 #include <drm/drm_bridge.h>
16 #include <drm/drm_bridge_connector.h>
17 #include <drm/drm_drv.h>
18 #include <drm/drm_file.h>
19 #include <drm/drm_ioctl.h>
20 #include <drm/drm_panel.h>
21 #include <drm/drm_prime.h>
22 #include <drm/drm_probe_helper.h>
23 #include <drm/drm_vblank.h>
24
25 #include "omap_dmm_tiler.h"
26 #include "omap_drv.h"
27 #include "omap_fbdev.h"
28
29 #define DRIVER_NAME             MODULE_NAME
30 #define DRIVER_DESC             "OMAP DRM"
31 #define DRIVER_DATE             "20110917"
32 #define DRIVER_MAJOR            1
33 #define DRIVER_MINOR            0
34 #define DRIVER_PATCHLEVEL       0
35
36 /*
37  * mode config funcs
38  */
39
40 /* Notes about mapping DSS and DRM entities:
41  *    CRTC:        overlay
42  *    encoder:     manager.. with some extension to allow one primary CRTC
43  *                 and zero or more video CRTC's to be mapped to one encoder?
44  *    connector:   dssdev.. manager can be attached/detached from different
45  *                 devices
46  */
47
48 static void omap_atomic_wait_for_completion(struct drm_device *dev,
49                                             struct drm_atomic_state *old_state)
50 {
51         struct drm_crtc_state *new_crtc_state;
52         struct drm_crtc *crtc;
53         unsigned int i;
54         int ret;
55
56         for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
57                 if (!new_crtc_state->active)
58                         continue;
59
60                 ret = omap_crtc_wait_pending(crtc);
61
62                 if (!ret)
63                         dev_warn(dev->dev,
64                                  "atomic complete timeout (pipe %u)!\n", i);
65         }
66 }
67
68 static void omap_atomic_commit_tail(struct drm_atomic_state *old_state)
69 {
70         struct drm_device *dev = old_state->dev;
71         struct omap_drm_private *priv = dev->dev_private;
72
73         dispc_runtime_get(priv->dispc);
74
75         /* Apply the atomic update. */
76         drm_atomic_helper_commit_modeset_disables(dev, old_state);
77
78         if (priv->omaprev != 0x3430) {
79                 /* With the current dss dispc implementation we have to enable
80                  * the new modeset before we can commit planes. The dispc ovl
81                  * configuration relies on the video mode configuration been
82                  * written into the HW when the ovl configuration is
83                  * calculated.
84                  *
85                  * This approach is not ideal because after a mode change the
86                  * plane update is executed only after the first vblank
87                  * interrupt. The dispc implementation should be fixed so that
88                  * it is able use uncommitted drm state information.
89                  */
90                 drm_atomic_helper_commit_modeset_enables(dev, old_state);
91                 omap_atomic_wait_for_completion(dev, old_state);
92
93                 drm_atomic_helper_commit_planes(dev, old_state, 0);
94
95                 drm_atomic_helper_commit_hw_done(old_state);
96         } else {
97                 /*
98                  * OMAP3 DSS seems to have issues with the work-around above,
99                  * resulting in endless sync losts if a crtc is enabled without
100                  * a plane. For now, skip the WA for OMAP3.
101                  */
102                 drm_atomic_helper_commit_planes(dev, old_state, 0);
103
104                 drm_atomic_helper_commit_modeset_enables(dev, old_state);
105
106                 drm_atomic_helper_commit_hw_done(old_state);
107         }
108
109         /*
110          * Wait for completion of the page flips to ensure that old buffers
111          * can't be touched by the hardware anymore before cleaning up planes.
112          */
113         omap_atomic_wait_for_completion(dev, old_state);
114
115         drm_atomic_helper_cleanup_planes(dev, old_state);
116
117         dispc_runtime_put(priv->dispc);
118 }
119
120 static int drm_atomic_state_normalized_zpos_cmp(const void *a, const void *b)
121 {
122         const struct drm_plane_state *sa = *(struct drm_plane_state **)a;
123         const struct drm_plane_state *sb = *(struct drm_plane_state **)b;
124
125         if (sa->normalized_zpos != sb->normalized_zpos)
126                 return sa->normalized_zpos - sb->normalized_zpos;
127         else
128                 return sa->plane->base.id - sb->plane->base.id;
129 }
130
131 /*
132  * This replaces the drm_atomic_normalize_zpos to handle the dual overlay case.
133  *
134  * Since both halves need to be 'appear' side by side the zpos is
135  * recalculated when dealing with dual overlay cases so that the other
136  * planes zpos is consistent.
137  */
138 static int omap_atomic_update_normalize_zpos(struct drm_device *dev,
139                                              struct drm_atomic_state *state)
140 {
141         struct drm_crtc *crtc;
142         struct drm_crtc_state *old_state, *new_state;
143         struct drm_plane *plane;
144         int c, i, n, inc;
145         int total_planes = dev->mode_config.num_total_plane;
146         struct drm_plane_state **states;
147         int ret = 0;
148
149         states = kmalloc_array(total_planes, sizeof(*states), GFP_KERNEL);
150         if (!states)
151                 return -ENOMEM;
152
153         for_each_oldnew_crtc_in_state(state, crtc, old_state, new_state, c) {
154                 if (old_state->plane_mask == new_state->plane_mask &&
155                     !new_state->zpos_changed)
156                         continue;
157
158                 /* Reset plane increment and index value for every crtc */
159                 n = 0;
160
161                 /*
162                  * Normalization process might create new states for planes
163                  * which normalized_zpos has to be recalculated.
164                  */
165                 drm_for_each_plane_mask(plane, dev, new_state->plane_mask) {
166                         struct drm_plane_state *plane_state =
167                                 drm_atomic_get_plane_state(new_state->state,
168                                                            plane);
169                         if (IS_ERR(plane_state)) {
170                                 ret = PTR_ERR(plane_state);
171                                 goto done;
172                         }
173                         states[n++] = plane_state;
174                 }
175
176                 sort(states, n, sizeof(*states),
177                      drm_atomic_state_normalized_zpos_cmp, NULL);
178
179                 for (i = 0, inc = 0; i < n; i++) {
180                         plane = states[i]->plane;
181
182                         states[i]->normalized_zpos = i + inc;
183                         DRM_DEBUG_ATOMIC("[PLANE:%d:%s] updated normalized zpos value %d\n",
184                                          plane->base.id, plane->name,
185                                          states[i]->normalized_zpos);
186
187                         if (is_omap_plane_dual_overlay(states[i]))
188                                 inc++;
189                 }
190                 new_state->zpos_changed = true;
191         }
192
193 done:
194         kfree(states);
195         return ret;
196 }
197
198 static int omap_atomic_check(struct drm_device *dev,
199                              struct drm_atomic_state *state)
200 {
201         int ret;
202
203         ret = drm_atomic_helper_check(dev, state);
204         if (ret)
205                 return ret;
206
207         if (dev->mode_config.normalize_zpos) {
208                 ret = omap_atomic_update_normalize_zpos(dev, state);
209                 if (ret)
210                         return ret;
211         }
212
213         return 0;
214 }
215
216 static const struct drm_mode_config_helper_funcs omap_mode_config_helper_funcs = {
217         .atomic_commit_tail = omap_atomic_commit_tail,
218 };
219
220 static const struct drm_mode_config_funcs omap_mode_config_funcs = {
221         .fb_create = omap_framebuffer_create,
222         .atomic_check = omap_atomic_check,
223         .atomic_commit = drm_atomic_helper_commit,
224 };
225
226 /* Global/shared object state funcs */
227
228 /*
229  * This is a helper that returns the private state currently in operation.
230  * Note that this would return the "old_state" if called in the atomic check
231  * path, and the "new_state" after the atomic swap has been done.
232  */
233 struct omap_global_state *
234 omap_get_existing_global_state(struct omap_drm_private *priv)
235 {
236         return to_omap_global_state(priv->glob_obj.state);
237 }
238
239 /*
240  * This acquires the modeset lock set aside for global state, creates
241  * a new duplicated private object state.
242  */
243 struct omap_global_state *__must_check
244 omap_get_global_state(struct drm_atomic_state *s)
245 {
246         struct omap_drm_private *priv = s->dev->dev_private;
247         struct drm_private_state *priv_state;
248
249         priv_state = drm_atomic_get_private_obj_state(s, &priv->glob_obj);
250         if (IS_ERR(priv_state))
251                 return ERR_CAST(priv_state);
252
253         return to_omap_global_state(priv_state);
254 }
255
256 static struct drm_private_state *
257 omap_global_duplicate_state(struct drm_private_obj *obj)
258 {
259         struct omap_global_state *state;
260
261         state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
262         if (!state)
263                 return NULL;
264
265         __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
266
267         return &state->base;
268 }
269
270 static void omap_global_destroy_state(struct drm_private_obj *obj,
271                                       struct drm_private_state *state)
272 {
273         struct omap_global_state *omap_state = to_omap_global_state(state);
274
275         kfree(omap_state);
276 }
277
278 static const struct drm_private_state_funcs omap_global_state_funcs = {
279         .atomic_duplicate_state = omap_global_duplicate_state,
280         .atomic_destroy_state = omap_global_destroy_state,
281 };
282
283 static int omap_global_obj_init(struct drm_device *dev)
284 {
285         struct omap_drm_private *priv = dev->dev_private;
286         struct omap_global_state *state;
287
288         state = kzalloc(sizeof(*state), GFP_KERNEL);
289         if (!state)
290                 return -ENOMEM;
291
292         drm_atomic_private_obj_init(dev, &priv->glob_obj, &state->base,
293                                     &omap_global_state_funcs);
294         return 0;
295 }
296
297 static void omap_global_obj_fini(struct omap_drm_private *priv)
298 {
299         drm_atomic_private_obj_fini(&priv->glob_obj);
300 }
301
302 static void omap_disconnect_pipelines(struct drm_device *ddev)
303 {
304         struct omap_drm_private *priv = ddev->dev_private;
305         unsigned int i;
306
307         for (i = 0; i < priv->num_pipes; i++) {
308                 struct omap_drm_pipeline *pipe = &priv->pipes[i];
309
310                 omapdss_device_disconnect(NULL, pipe->output);
311
312                 omapdss_device_put(pipe->output);
313                 pipe->output = NULL;
314         }
315
316         memset(&priv->channels, 0, sizeof(priv->channels));
317
318         priv->num_pipes = 0;
319 }
320
321 static int omap_connect_pipelines(struct drm_device *ddev)
322 {
323         struct omap_drm_private *priv = ddev->dev_private;
324         struct omap_dss_device *output = NULL;
325         int r;
326
327         for_each_dss_output(output) {
328                 r = omapdss_device_connect(priv->dss, NULL, output);
329                 if (r == -EPROBE_DEFER) {
330                         omapdss_device_put(output);
331                         return r;
332                 } else if (r) {
333                         dev_warn(output->dev, "could not connect output %s\n",
334                                  output->name);
335                 } else {
336                         struct omap_drm_pipeline *pipe;
337
338                         pipe = &priv->pipes[priv->num_pipes++];
339                         pipe->output = omapdss_device_get(output);
340
341                         if (priv->num_pipes == ARRAY_SIZE(priv->pipes)) {
342                                 /* To balance the 'for_each_dss_output' loop */
343                                 omapdss_device_put(output);
344                                 break;
345                         }
346                 }
347         }
348
349         return 0;
350 }
351
352 static int omap_compare_pipelines(const void *a, const void *b)
353 {
354         const struct omap_drm_pipeline *pipe1 = a;
355         const struct omap_drm_pipeline *pipe2 = b;
356
357         if (pipe1->alias_id > pipe2->alias_id)
358                 return 1;
359         else if (pipe1->alias_id < pipe2->alias_id)
360                 return -1;
361         return 0;
362 }
363
364 static int omap_modeset_init_properties(struct drm_device *dev)
365 {
366         struct omap_drm_private *priv = dev->dev_private;
367         unsigned int num_planes = dispc_get_num_ovls(priv->dispc);
368
369         priv->zorder_prop = drm_property_create_range(dev, 0, "zorder", 0,
370                                                       num_planes - 1);
371         if (!priv->zorder_prop)
372                 return -ENOMEM;
373
374         return 0;
375 }
376
377 static int omap_display_id(struct omap_dss_device *output)
378 {
379         struct device_node *node = NULL;
380
381         if (output->bridge) {
382                 struct drm_bridge *bridge = output->bridge;
383
384                 while (drm_bridge_get_next_bridge(bridge))
385                         bridge = drm_bridge_get_next_bridge(bridge);
386
387                 node = bridge->of_node;
388         }
389
390         return node ? of_alias_get_id(node, "display") : -ENODEV;
391 }
392
393 static int omap_modeset_init(struct drm_device *dev)
394 {
395         struct omap_drm_private *priv = dev->dev_private;
396         int num_ovls = dispc_get_num_ovls(priv->dispc);
397         int num_mgrs = dispc_get_num_mgrs(priv->dispc);
398         unsigned int i;
399         int ret;
400         u32 plane_crtc_mask;
401
402         if (!omapdss_stack_is_ready())
403                 return -EPROBE_DEFER;
404
405         ret = omap_modeset_init_properties(dev);
406         if (ret < 0)
407                 return ret;
408
409         /*
410          * This function creates exactly one connector, encoder, crtc,
411          * and primary plane per each connected dss-device. Each
412          * connector->encoder->crtc chain is expected to be separate
413          * and each crtc is connect to a single dss-channel. If the
414          * configuration does not match the expectations or exceeds
415          * the available resources, the configuration is rejected.
416          */
417         ret = omap_connect_pipelines(dev);
418         if (ret < 0)
419                 return ret;
420
421         if (priv->num_pipes > num_mgrs || priv->num_pipes > num_ovls) {
422                 dev_err(dev->dev, "%s(): Too many connected displays\n",
423                         __func__);
424                 return -EINVAL;
425         }
426
427         /* Create all planes first. They can all be put to any CRTC. */
428         plane_crtc_mask = (1 << priv->num_pipes) - 1;
429
430         for (i = 0; i < num_ovls; i++) {
431                 enum drm_plane_type type = i < priv->num_pipes
432                                          ? DRM_PLANE_TYPE_PRIMARY
433                                          : DRM_PLANE_TYPE_OVERLAY;
434                 struct drm_plane *plane;
435
436                 if (WARN_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)))
437                         return -EINVAL;
438
439                 plane = omap_plane_init(dev, i, type, plane_crtc_mask);
440                 if (IS_ERR(plane))
441                         return PTR_ERR(plane);
442
443                 priv->planes[priv->num_planes++] = plane;
444         }
445
446         /*
447          * Create the encoders, attach the bridges and get the pipeline alias
448          * IDs.
449          */
450         for (i = 0; i < priv->num_pipes; i++) {
451                 struct omap_drm_pipeline *pipe = &priv->pipes[i];
452                 int id;
453
454                 pipe->encoder = omap_encoder_init(dev, pipe->output);
455                 if (!pipe->encoder)
456                         return -ENOMEM;
457
458                 if (pipe->output->bridge) {
459                         ret = drm_bridge_attach(pipe->encoder,
460                                                 pipe->output->bridge, NULL,
461                                                 DRM_BRIDGE_ATTACH_NO_CONNECTOR);
462                         if (ret < 0)
463                                 return ret;
464                 }
465
466                 id = omap_display_id(pipe->output);
467                 pipe->alias_id = id >= 0 ? id : i;
468         }
469
470         /* Sort the pipelines by DT aliases. */
471         sort(priv->pipes, priv->num_pipes, sizeof(priv->pipes[0]),
472              omap_compare_pipelines, NULL);
473
474         /*
475          * Populate the pipeline lookup table by DISPC channel. Only one display
476          * is allowed per channel.
477          */
478         for (i = 0; i < priv->num_pipes; ++i) {
479                 struct omap_drm_pipeline *pipe = &priv->pipes[i];
480                 enum omap_channel channel = pipe->output->dispc_channel;
481
482                 if (WARN_ON(priv->channels[channel] != NULL))
483                         return -EINVAL;
484
485                 priv->channels[channel] = pipe;
486         }
487
488         /* Create the connectors and CRTCs. */
489         for (i = 0; i < priv->num_pipes; i++) {
490                 struct omap_drm_pipeline *pipe = &priv->pipes[i];
491                 struct drm_encoder *encoder = pipe->encoder;
492                 struct drm_crtc *crtc;
493
494                 pipe->connector = drm_bridge_connector_init(dev, encoder);
495                 if (IS_ERR(pipe->connector)) {
496                         dev_err(priv->dev,
497                                 "unable to create bridge connector for %s\n",
498                                 pipe->output->name);
499                         return PTR_ERR(pipe->connector);
500                 }
501
502                 drm_connector_attach_encoder(pipe->connector, encoder);
503
504                 crtc = omap_crtc_init(dev, pipe, priv->planes[i]);
505                 if (IS_ERR(crtc))
506                         return PTR_ERR(crtc);
507
508                 encoder->possible_crtcs = 1 << i;
509                 pipe->crtc = crtc;
510         }
511
512         DBG("registered %u planes, %u crtcs/encoders/connectors\n",
513             priv->num_planes, priv->num_pipes);
514
515         dev->mode_config.min_width = 8;
516         dev->mode_config.min_height = 2;
517
518         /*
519          * Note: these values are used for multiple independent things:
520          * connector mode filtering, buffer sizes, crtc sizes...
521          * Use big enough values here to cover all use cases, and do more
522          * specific checking in the respective code paths.
523          */
524         dev->mode_config.max_width = 8192;
525         dev->mode_config.max_height = 8192;
526
527         /* We want the zpos to be normalized */
528         dev->mode_config.normalize_zpos = true;
529
530         dev->mode_config.funcs = &omap_mode_config_funcs;
531         dev->mode_config.helper_private = &omap_mode_config_helper_funcs;
532
533         drm_mode_config_reset(dev);
534
535         omap_drm_irq_install(dev);
536
537         return 0;
538 }
539
540 static void omap_modeset_fini(struct drm_device *ddev)
541 {
542         omap_drm_irq_uninstall(ddev);
543
544         drm_mode_config_cleanup(ddev);
545 }
546
547 /*
548  * drm ioctl funcs
549  */
550
551
552 static int ioctl_get_param(struct drm_device *dev, void *data,
553                 struct drm_file *file_priv)
554 {
555         struct omap_drm_private *priv = dev->dev_private;
556         struct drm_omap_param *args = data;
557
558         DBG("%p: param=%llu", dev, args->param);
559
560         switch (args->param) {
561         case OMAP_PARAM_CHIPSET_ID:
562                 args->value = priv->omaprev;
563                 break;
564         default:
565                 DBG("unknown parameter %lld", args->param);
566                 return -EINVAL;
567         }
568
569         return 0;
570 }
571
572 #define OMAP_BO_USER_MASK       0x00ffffff      /* flags settable by userspace */
573
574 static int ioctl_gem_new(struct drm_device *dev, void *data,
575                 struct drm_file *file_priv)
576 {
577         struct drm_omap_gem_new *args = data;
578         u32 flags = args->flags & OMAP_BO_USER_MASK;
579
580         VERB("%p:%p: size=0x%08x, flags=%08x", dev, file_priv,
581              args->size.bytes, flags);
582
583         return omap_gem_new_handle(dev, file_priv, args->size, flags,
584                                    &args->handle);
585 }
586
587 static int ioctl_gem_info(struct drm_device *dev, void *data,
588                 struct drm_file *file_priv)
589 {
590         struct drm_omap_gem_info *args = data;
591         struct drm_gem_object *obj;
592         int ret = 0;
593
594         VERB("%p:%p: handle=%d", dev, file_priv, args->handle);
595
596         obj = drm_gem_object_lookup(file_priv, args->handle);
597         if (!obj)
598                 return -ENOENT;
599
600         args->size = omap_gem_mmap_size(obj);
601         args->offset = omap_gem_mmap_offset(obj);
602
603         drm_gem_object_put(obj);
604
605         return ret;
606 }
607
608 static const struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = {
609         DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param,
610                           DRM_RENDER_ALLOW),
611         DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, drm_invalid_op,
612                           DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
613         DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new,
614                           DRM_RENDER_ALLOW),
615         /* Deprecated, to be removed. */
616         DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_PREP, drm_noop,
617                           DRM_RENDER_ALLOW),
618         /* Deprecated, to be removed. */
619         DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_FINI, drm_noop,
620                           DRM_RENDER_ALLOW),
621         DRM_IOCTL_DEF_DRV(OMAP_GEM_INFO, ioctl_gem_info,
622                           DRM_RENDER_ALLOW),
623 };
624
625 /*
626  * drm driver funcs
627  */
628
629 static int dev_open(struct drm_device *dev, struct drm_file *file)
630 {
631         file->driver_priv = NULL;
632
633         DBG("open: dev=%p, file=%p", dev, file);
634
635         return 0;
636 }
637
638 DEFINE_DRM_GEM_FOPS(omapdriver_fops);
639
640 static const struct drm_driver omap_drm_driver = {
641         .driver_features = DRIVER_MODESET | DRIVER_GEM  |
642                 DRIVER_ATOMIC | DRIVER_RENDER,
643         .open = dev_open,
644 #ifdef CONFIG_DEBUG_FS
645         .debugfs_init = omap_debugfs_init,
646 #endif
647         .gem_prime_import = omap_gem_prime_import,
648         .dumb_create = omap_gem_dumb_create,
649         .dumb_map_offset = omap_gem_dumb_map_offset,
650         .ioctls = ioctls,
651         .num_ioctls = DRM_OMAP_NUM_IOCTLS,
652         .fops = &omapdriver_fops,
653         .name = DRIVER_NAME,
654         .desc = DRIVER_DESC,
655         .date = DRIVER_DATE,
656         .major = DRIVER_MAJOR,
657         .minor = DRIVER_MINOR,
658         .patchlevel = DRIVER_PATCHLEVEL,
659 };
660
661 static const struct soc_device_attribute omapdrm_soc_devices[] = {
662         { .family = "OMAP3", .data = (void *)0x3430 },
663         { .family = "OMAP4", .data = (void *)0x4430 },
664         { .family = "OMAP5", .data = (void *)0x5430 },
665         { .family = "DRA7",  .data = (void *)0x0752 },
666         { /* sentinel */ }
667 };
668
669 static int omapdrm_init(struct omap_drm_private *priv, struct device *dev)
670 {
671         const struct soc_device_attribute *soc;
672         struct dss_pdata *pdata = dev->platform_data;
673         struct drm_device *ddev;
674         int ret;
675
676         DBG("%s", dev_name(dev));
677
678         if (drm_firmware_drivers_only())
679                 return -ENODEV;
680
681         /* Allocate and initialize the DRM device. */
682         ddev = drm_dev_alloc(&omap_drm_driver, dev);
683         if (IS_ERR(ddev))
684                 return PTR_ERR(ddev);
685
686         priv->ddev = ddev;
687         ddev->dev_private = priv;
688
689         priv->dev = dev;
690         priv->dss = pdata->dss;
691         priv->dispc = dispc_get_dispc(priv->dss);
692
693         priv->dss->mgr_ops_priv = priv;
694
695         soc = soc_device_match(omapdrm_soc_devices);
696         priv->omaprev = soc ? (uintptr_t)soc->data : 0;
697         priv->wq = alloc_ordered_workqueue("omapdrm", 0);
698
699         mutex_init(&priv->list_lock);
700         INIT_LIST_HEAD(&priv->obj_list);
701
702         /* Get memory bandwidth limits */
703         priv->max_bandwidth = dispc_get_memory_bandwidth_limit(priv->dispc);
704
705         omap_gem_init(ddev);
706
707         drm_mode_config_init(ddev);
708
709         ret = omap_global_obj_init(ddev);
710         if (ret)
711                 goto err_gem_deinit;
712
713         ret = omap_hwoverlays_init(priv);
714         if (ret)
715                 goto err_free_priv_obj;
716
717         ret = omap_modeset_init(ddev);
718         if (ret) {
719                 dev_err(priv->dev, "omap_modeset_init failed: ret=%d\n", ret);
720                 goto err_free_overlays;
721         }
722
723         /* Initialize vblank handling, start with all CRTCs disabled. */
724         ret = drm_vblank_init(ddev, priv->num_pipes);
725         if (ret) {
726                 dev_err(priv->dev, "could not init vblank\n");
727                 goto err_cleanup_modeset;
728         }
729
730         drm_kms_helper_poll_init(ddev);
731
732         /*
733          * Register the DRM device with the core and the connectors with
734          * sysfs.
735          */
736         ret = drm_dev_register(ddev, 0);
737         if (ret)
738                 goto err_cleanup_helpers;
739
740         omap_fbdev_setup(ddev);
741
742         return 0;
743
744 err_cleanup_helpers:
745         drm_kms_helper_poll_fini(ddev);
746 err_cleanup_modeset:
747         omap_modeset_fini(ddev);
748 err_free_overlays:
749         omap_hwoverlays_destroy(priv);
750 err_free_priv_obj:
751         omap_global_obj_fini(priv);
752 err_gem_deinit:
753         drm_mode_config_cleanup(ddev);
754         omap_gem_deinit(ddev);
755         destroy_workqueue(priv->wq);
756         omap_disconnect_pipelines(ddev);
757         drm_dev_put(ddev);
758         return ret;
759 }
760
761 static void omapdrm_cleanup(struct omap_drm_private *priv)
762 {
763         struct drm_device *ddev = priv->ddev;
764
765         DBG("");
766
767         drm_dev_unregister(ddev);
768
769         drm_kms_helper_poll_fini(ddev);
770
771         drm_atomic_helper_shutdown(ddev);
772
773         omap_modeset_fini(ddev);
774         omap_hwoverlays_destroy(priv);
775         omap_global_obj_fini(priv);
776         drm_mode_config_cleanup(ddev);
777         omap_gem_deinit(ddev);
778
779         destroy_workqueue(priv->wq);
780
781         omap_disconnect_pipelines(ddev);
782
783         drm_dev_put(ddev);
784 }
785
786 static int pdev_probe(struct platform_device *pdev)
787 {
788         struct omap_drm_private *priv;
789         int ret;
790
791         ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
792         if (ret) {
793                 dev_err(&pdev->dev, "Failed to set the DMA mask\n");
794                 return ret;
795         }
796
797         /* Allocate and initialize the driver private structure. */
798         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
799         if (!priv)
800                 return -ENOMEM;
801
802         platform_set_drvdata(pdev, priv);
803
804         ret = omapdrm_init(priv, &pdev->dev);
805         if (ret < 0)
806                 kfree(priv);
807
808         return ret;
809 }
810
811 static void pdev_remove(struct platform_device *pdev)
812 {
813         struct omap_drm_private *priv = platform_get_drvdata(pdev);
814
815         omapdrm_cleanup(priv);
816         kfree(priv);
817 }
818
819 static void pdev_shutdown(struct platform_device *pdev)
820 {
821         struct omap_drm_private *priv = platform_get_drvdata(pdev);
822
823         drm_atomic_helper_shutdown(priv->ddev);
824 }
825
826 #ifdef CONFIG_PM_SLEEP
827 static int omap_drm_suspend(struct device *dev)
828 {
829         struct omap_drm_private *priv = dev_get_drvdata(dev);
830         struct drm_device *drm_dev = priv->ddev;
831
832         return drm_mode_config_helper_suspend(drm_dev);
833 }
834
835 static int omap_drm_resume(struct device *dev)
836 {
837         struct omap_drm_private *priv = dev_get_drvdata(dev);
838         struct drm_device *drm_dev = priv->ddev;
839
840         drm_mode_config_helper_resume(drm_dev);
841
842         return omap_gem_resume(drm_dev);
843 }
844 #endif
845
846 static SIMPLE_DEV_PM_OPS(omapdrm_pm_ops, omap_drm_suspend, omap_drm_resume);
847
848 static struct platform_driver pdev = {
849         .driver = {
850                 .name = "omapdrm",
851                 .pm = &omapdrm_pm_ops,
852         },
853         .probe = pdev_probe,
854         .remove_new = pdev_remove,
855         .shutdown = pdev_shutdown,
856 };
857
858 static struct platform_driver * const drivers[] = {
859         &omap_dmm_driver,
860         &pdev,
861 };
862
863 static int __init omap_drm_init(void)
864 {
865         int r;
866
867         DBG("init");
868
869         r = omap_dss_init();
870         if (r)
871                 return r;
872
873         r = platform_register_drivers(drivers, ARRAY_SIZE(drivers));
874         if (r) {
875                 omap_dss_exit();
876                 return r;
877         }
878
879         return 0;
880 }
881
882 static void __exit omap_drm_fini(void)
883 {
884         DBG("fini");
885
886         platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
887
888         omap_dss_exit();
889 }
890
891 module_init(omap_drm_init);
892 module_exit(omap_drm_fini);
893
894 MODULE_AUTHOR("Rob Clark <[email protected]>");
895 MODULE_AUTHOR("Tomi Valkeinen <[email protected]>");
896 MODULE_DESCRIPTION("OMAP DRM Display Driver");
897 MODULE_ALIAS("platform:" DRIVER_NAME);
898 MODULE_LICENSE("GPL v2");
This page took 0.087715 seconds and 4 git commands to generate.