0001
0002
0003
0004
0005
0006
0007 #include <linux/dma-mapping.h>
0008 #include <linux/platform_device.h>
0009 #include <linux/sort.h>
0010 #include <linux/sys_soc.h>
0011
0012 #include <drm/drm_atomic.h>
0013 #include <drm/drm_atomic_helper.h>
0014 #include <drm/drm_bridge.h>
0015 #include <drm/drm_bridge_connector.h>
0016 #include <drm/drm_drv.h>
0017 #include <drm/drm_fb_helper.h>
0018 #include <drm/drm_file.h>
0019 #include <drm/drm_ioctl.h>
0020 #include <drm/drm_panel.h>
0021 #include <drm/drm_prime.h>
0022 #include <drm/drm_probe_helper.h>
0023 #include <drm/drm_vblank.h>
0024
0025 #include "omap_dmm_tiler.h"
0026 #include "omap_drv.h"
0027
0028 #define DRIVER_NAME MODULE_NAME
0029 #define DRIVER_DESC "OMAP DRM"
0030 #define DRIVER_DATE "20110917"
0031 #define DRIVER_MAJOR 1
0032 #define DRIVER_MINOR 0
0033 #define DRIVER_PATCHLEVEL 0
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 static void omap_atomic_wait_for_completion(struct drm_device *dev,
0048 struct drm_atomic_state *old_state)
0049 {
0050 struct drm_crtc_state *new_crtc_state;
0051 struct drm_crtc *crtc;
0052 unsigned int i;
0053 int ret;
0054
0055 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
0056 if (!new_crtc_state->active)
0057 continue;
0058
0059 ret = omap_crtc_wait_pending(crtc);
0060
0061 if (!ret)
0062 dev_warn(dev->dev,
0063 "atomic complete timeout (pipe %u)!\n", i);
0064 }
0065 }
0066
0067 static void omap_atomic_commit_tail(struct drm_atomic_state *old_state)
0068 {
0069 struct drm_device *dev = old_state->dev;
0070 struct omap_drm_private *priv = dev->dev_private;
0071 bool fence_cookie = dma_fence_begin_signalling();
0072
0073 dispc_runtime_get(priv->dispc);
0074
0075
0076 drm_atomic_helper_commit_modeset_disables(dev, old_state);
0077
0078 if (priv->omaprev != 0x3430) {
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 drm_atomic_helper_commit_modeset_enables(dev, old_state);
0091 omap_atomic_wait_for_completion(dev, old_state);
0092
0093 drm_atomic_helper_commit_planes(dev, old_state, 0);
0094 } else {
0095
0096
0097
0098
0099
0100 drm_atomic_helper_commit_planes(dev, old_state, 0);
0101
0102 drm_atomic_helper_commit_modeset_enables(dev, old_state);
0103 }
0104
0105 drm_atomic_helper_commit_hw_done(old_state);
0106
0107 dma_fence_end_signalling(fence_cookie);
0108
0109
0110
0111
0112
0113 omap_atomic_wait_for_completion(dev, old_state);
0114
0115 drm_atomic_helper_cleanup_planes(dev, old_state);
0116
0117 dispc_runtime_put(priv->dispc);
0118 }
0119
0120 static int drm_atomic_state_normalized_zpos_cmp(const void *a, const void *b)
0121 {
0122 const struct drm_plane_state *sa = *(struct drm_plane_state **)a;
0123 const struct drm_plane_state *sb = *(struct drm_plane_state **)b;
0124
0125 if (sa->normalized_zpos != sb->normalized_zpos)
0126 return sa->normalized_zpos - sb->normalized_zpos;
0127 else
0128 return sa->plane->base.id - sb->plane->base.id;
0129 }
0130
0131
0132
0133
0134
0135
0136
0137
0138 static int omap_atomic_update_normalize_zpos(struct drm_device *dev,
0139 struct drm_atomic_state *state)
0140 {
0141 struct drm_crtc *crtc;
0142 struct drm_crtc_state *old_state, *new_state;
0143 struct drm_plane *plane;
0144 int c, i, n, inc;
0145 int total_planes = dev->mode_config.num_total_plane;
0146 struct drm_plane_state **states;
0147 int ret = 0;
0148
0149 states = kmalloc_array(total_planes, sizeof(*states), GFP_KERNEL);
0150 if (!states)
0151 return -ENOMEM;
0152
0153 for_each_oldnew_crtc_in_state(state, crtc, old_state, new_state, c) {
0154 if (old_state->plane_mask == new_state->plane_mask &&
0155 !new_state->zpos_changed)
0156 continue;
0157
0158
0159 n = 0;
0160
0161
0162
0163
0164
0165 drm_for_each_plane_mask(plane, dev, new_state->plane_mask) {
0166 struct drm_plane_state *plane_state =
0167 drm_atomic_get_plane_state(new_state->state,
0168 plane);
0169 if (IS_ERR(plane_state)) {
0170 ret = PTR_ERR(plane_state);
0171 goto done;
0172 }
0173 states[n++] = plane_state;
0174 }
0175
0176 sort(states, n, sizeof(*states),
0177 drm_atomic_state_normalized_zpos_cmp, NULL);
0178
0179 for (i = 0, inc = 0; i < n; i++) {
0180 plane = states[i]->plane;
0181
0182 states[i]->normalized_zpos = i + inc;
0183 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] updated normalized zpos value %d\n",
0184 plane->base.id, plane->name,
0185 states[i]->normalized_zpos);
0186
0187 if (is_omap_plane_dual_overlay(states[i]))
0188 inc++;
0189 }
0190 new_state->zpos_changed = true;
0191 }
0192
0193 done:
0194 kfree(states);
0195 return ret;
0196 }
0197
0198 static int omap_atomic_check(struct drm_device *dev,
0199 struct drm_atomic_state *state)
0200 {
0201 int ret;
0202
0203 ret = drm_atomic_helper_check(dev, state);
0204 if (ret)
0205 return ret;
0206
0207 if (dev->mode_config.normalize_zpos) {
0208 ret = omap_atomic_update_normalize_zpos(dev, state);
0209 if (ret)
0210 return ret;
0211 }
0212
0213 return 0;
0214 }
0215
0216 static const struct drm_mode_config_helper_funcs omap_mode_config_helper_funcs = {
0217 .atomic_commit_tail = omap_atomic_commit_tail,
0218 };
0219
0220 static const struct drm_mode_config_funcs omap_mode_config_funcs = {
0221 .fb_create = omap_framebuffer_create,
0222 .output_poll_changed = drm_fb_helper_output_poll_changed,
0223 .atomic_check = omap_atomic_check,
0224 .atomic_commit = drm_atomic_helper_commit,
0225 };
0226
0227
0228
0229
0230
0231
0232
0233
0234 struct omap_global_state *
0235 omap_get_existing_global_state(struct omap_drm_private *priv)
0236 {
0237 return to_omap_global_state(priv->glob_obj.state);
0238 }
0239
0240
0241
0242
0243
0244 struct omap_global_state *__must_check
0245 omap_get_global_state(struct drm_atomic_state *s)
0246 {
0247 struct omap_drm_private *priv = s->dev->dev_private;
0248 struct drm_private_state *priv_state;
0249
0250 priv_state = drm_atomic_get_private_obj_state(s, &priv->glob_obj);
0251 if (IS_ERR(priv_state))
0252 return ERR_CAST(priv_state);
0253
0254 return to_omap_global_state(priv_state);
0255 }
0256
0257 static struct drm_private_state *
0258 omap_global_duplicate_state(struct drm_private_obj *obj)
0259 {
0260 struct omap_global_state *state;
0261
0262 state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
0263 if (!state)
0264 return NULL;
0265
0266 __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
0267
0268 return &state->base;
0269 }
0270
0271 static void omap_global_destroy_state(struct drm_private_obj *obj,
0272 struct drm_private_state *state)
0273 {
0274 struct omap_global_state *omap_state = to_omap_global_state(state);
0275
0276 kfree(omap_state);
0277 }
0278
0279 static const struct drm_private_state_funcs omap_global_state_funcs = {
0280 .atomic_duplicate_state = omap_global_duplicate_state,
0281 .atomic_destroy_state = omap_global_destroy_state,
0282 };
0283
0284 static int omap_global_obj_init(struct drm_device *dev)
0285 {
0286 struct omap_drm_private *priv = dev->dev_private;
0287 struct omap_global_state *state;
0288
0289 state = kzalloc(sizeof(*state), GFP_KERNEL);
0290 if (!state)
0291 return -ENOMEM;
0292
0293 drm_atomic_private_obj_init(dev, &priv->glob_obj, &state->base,
0294 &omap_global_state_funcs);
0295 return 0;
0296 }
0297
0298 static void omap_global_obj_fini(struct omap_drm_private *priv)
0299 {
0300 drm_atomic_private_obj_fini(&priv->glob_obj);
0301 }
0302
0303 static void omap_disconnect_pipelines(struct drm_device *ddev)
0304 {
0305 struct omap_drm_private *priv = ddev->dev_private;
0306 unsigned int i;
0307
0308 for (i = 0; i < priv->num_pipes; i++) {
0309 struct omap_drm_pipeline *pipe = &priv->pipes[i];
0310
0311 omapdss_device_disconnect(NULL, pipe->output);
0312
0313 omapdss_device_put(pipe->output);
0314 pipe->output = NULL;
0315 }
0316
0317 memset(&priv->channels, 0, sizeof(priv->channels));
0318
0319 priv->num_pipes = 0;
0320 }
0321
0322 static int omap_connect_pipelines(struct drm_device *ddev)
0323 {
0324 struct omap_drm_private *priv = ddev->dev_private;
0325 struct omap_dss_device *output = NULL;
0326 int r;
0327
0328 for_each_dss_output(output) {
0329 r = omapdss_device_connect(priv->dss, NULL, output);
0330 if (r == -EPROBE_DEFER) {
0331 omapdss_device_put(output);
0332 return r;
0333 } else if (r) {
0334 dev_warn(output->dev, "could not connect output %s\n",
0335 output->name);
0336 } else {
0337 struct omap_drm_pipeline *pipe;
0338
0339 pipe = &priv->pipes[priv->num_pipes++];
0340 pipe->output = omapdss_device_get(output);
0341
0342 if (priv->num_pipes == ARRAY_SIZE(priv->pipes)) {
0343
0344 omapdss_device_put(output);
0345 break;
0346 }
0347 }
0348 }
0349
0350 return 0;
0351 }
0352
0353 static int omap_compare_pipelines(const void *a, const void *b)
0354 {
0355 const struct omap_drm_pipeline *pipe1 = a;
0356 const struct omap_drm_pipeline *pipe2 = b;
0357
0358 if (pipe1->alias_id > pipe2->alias_id)
0359 return 1;
0360 else if (pipe1->alias_id < pipe2->alias_id)
0361 return -1;
0362 return 0;
0363 }
0364
0365 static int omap_modeset_init_properties(struct drm_device *dev)
0366 {
0367 struct omap_drm_private *priv = dev->dev_private;
0368 unsigned int num_planes = dispc_get_num_ovls(priv->dispc);
0369
0370 priv->zorder_prop = drm_property_create_range(dev, 0, "zorder", 0,
0371 num_planes - 1);
0372 if (!priv->zorder_prop)
0373 return -ENOMEM;
0374
0375 return 0;
0376 }
0377
0378 static int omap_display_id(struct omap_dss_device *output)
0379 {
0380 struct device_node *node = NULL;
0381
0382 if (output->bridge) {
0383 struct drm_bridge *bridge = output->bridge;
0384
0385 while (drm_bridge_get_next_bridge(bridge))
0386 bridge = drm_bridge_get_next_bridge(bridge);
0387
0388 node = bridge->of_node;
0389 }
0390
0391 return node ? of_alias_get_id(node, "display") : -ENODEV;
0392 }
0393
0394 static int omap_modeset_init(struct drm_device *dev)
0395 {
0396 struct omap_drm_private *priv = dev->dev_private;
0397 int num_ovls = dispc_get_num_ovls(priv->dispc);
0398 int num_mgrs = dispc_get_num_mgrs(priv->dispc);
0399 unsigned int i;
0400 int ret;
0401 u32 plane_crtc_mask;
0402
0403 if (!omapdss_stack_is_ready())
0404 return -EPROBE_DEFER;
0405
0406 ret = omap_modeset_init_properties(dev);
0407 if (ret < 0)
0408 return ret;
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418 ret = omap_connect_pipelines(dev);
0419 if (ret < 0)
0420 return ret;
0421
0422 if (priv->num_pipes > num_mgrs || priv->num_pipes > num_ovls) {
0423 dev_err(dev->dev, "%s(): Too many connected displays\n",
0424 __func__);
0425 return -EINVAL;
0426 }
0427
0428
0429 plane_crtc_mask = (1 << priv->num_pipes) - 1;
0430
0431 for (i = 0; i < num_ovls; i++) {
0432 enum drm_plane_type type = i < priv->num_pipes
0433 ? DRM_PLANE_TYPE_PRIMARY
0434 : DRM_PLANE_TYPE_OVERLAY;
0435 struct drm_plane *plane;
0436
0437 if (WARN_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)))
0438 return -EINVAL;
0439
0440 plane = omap_plane_init(dev, i, type, plane_crtc_mask);
0441 if (IS_ERR(plane))
0442 return PTR_ERR(plane);
0443
0444 priv->planes[priv->num_planes++] = plane;
0445 }
0446
0447
0448
0449
0450
0451 for (i = 0; i < priv->num_pipes; i++) {
0452 struct omap_drm_pipeline *pipe = &priv->pipes[i];
0453 int id;
0454
0455 pipe->encoder = omap_encoder_init(dev, pipe->output);
0456 if (!pipe->encoder)
0457 return -ENOMEM;
0458
0459 if (pipe->output->bridge) {
0460 ret = drm_bridge_attach(pipe->encoder,
0461 pipe->output->bridge, NULL,
0462 DRM_BRIDGE_ATTACH_NO_CONNECTOR);
0463 if (ret < 0)
0464 return ret;
0465 }
0466
0467 id = omap_display_id(pipe->output);
0468 pipe->alias_id = id >= 0 ? id : i;
0469 }
0470
0471
0472 sort(priv->pipes, priv->num_pipes, sizeof(priv->pipes[0]),
0473 omap_compare_pipelines, NULL);
0474
0475
0476
0477
0478
0479 for (i = 0; i < priv->num_pipes; ++i) {
0480 struct omap_drm_pipeline *pipe = &priv->pipes[i];
0481 enum omap_channel channel = pipe->output->dispc_channel;
0482
0483 if (WARN_ON(priv->channels[channel] != NULL))
0484 return -EINVAL;
0485
0486 priv->channels[channel] = pipe;
0487 }
0488
0489
0490 for (i = 0; i < priv->num_pipes; i++) {
0491 struct omap_drm_pipeline *pipe = &priv->pipes[i];
0492 struct drm_encoder *encoder = pipe->encoder;
0493 struct drm_crtc *crtc;
0494
0495 pipe->connector = drm_bridge_connector_init(dev, encoder);
0496 if (IS_ERR(pipe->connector)) {
0497 dev_err(priv->dev,
0498 "unable to create bridge connector for %s\n",
0499 pipe->output->name);
0500 return PTR_ERR(pipe->connector);
0501 }
0502
0503 drm_connector_attach_encoder(pipe->connector, encoder);
0504
0505 crtc = omap_crtc_init(dev, pipe, priv->planes[i]);
0506 if (IS_ERR(crtc))
0507 return PTR_ERR(crtc);
0508
0509 encoder->possible_crtcs = 1 << i;
0510 pipe->crtc = crtc;
0511 }
0512
0513 DBG("registered %u planes, %u crtcs/encoders/connectors\n",
0514 priv->num_planes, priv->num_pipes);
0515
0516 dev->mode_config.min_width = 8;
0517 dev->mode_config.min_height = 2;
0518
0519
0520
0521
0522
0523
0524
0525 dev->mode_config.max_width = 8192;
0526 dev->mode_config.max_height = 8192;
0527
0528
0529 dev->mode_config.normalize_zpos = true;
0530
0531 dev->mode_config.funcs = &omap_mode_config_funcs;
0532 dev->mode_config.helper_private = &omap_mode_config_helper_funcs;
0533
0534 drm_mode_config_reset(dev);
0535
0536 omap_drm_irq_install(dev);
0537
0538 return 0;
0539 }
0540
0541 static void omap_modeset_fini(struct drm_device *ddev)
0542 {
0543 omap_drm_irq_uninstall(ddev);
0544
0545 drm_mode_config_cleanup(ddev);
0546 }
0547
0548
0549
0550
0551 static void omap_modeset_enable_external_hpd(struct drm_device *ddev)
0552 {
0553 struct omap_drm_private *priv = ddev->dev_private;
0554 unsigned int i;
0555
0556 for (i = 0; i < priv->num_pipes; i++) {
0557 struct drm_connector *connector = priv->pipes[i].connector;
0558
0559 if (!connector)
0560 continue;
0561
0562 if (priv->pipes[i].output->bridge)
0563 drm_bridge_connector_enable_hpd(connector);
0564 }
0565 }
0566
0567
0568
0569
0570 static void omap_modeset_disable_external_hpd(struct drm_device *ddev)
0571 {
0572 struct omap_drm_private *priv = ddev->dev_private;
0573 unsigned int i;
0574
0575 for (i = 0; i < priv->num_pipes; i++) {
0576 struct drm_connector *connector = priv->pipes[i].connector;
0577
0578 if (!connector)
0579 continue;
0580
0581 if (priv->pipes[i].output->bridge)
0582 drm_bridge_connector_disable_hpd(connector);
0583 }
0584 }
0585
0586
0587
0588
0589
0590
0591 static int ioctl_get_param(struct drm_device *dev, void *data,
0592 struct drm_file *file_priv)
0593 {
0594 struct omap_drm_private *priv = dev->dev_private;
0595 struct drm_omap_param *args = data;
0596
0597 DBG("%p: param=%llu", dev, args->param);
0598
0599 switch (args->param) {
0600 case OMAP_PARAM_CHIPSET_ID:
0601 args->value = priv->omaprev;
0602 break;
0603 default:
0604 DBG("unknown parameter %lld", args->param);
0605 return -EINVAL;
0606 }
0607
0608 return 0;
0609 }
0610
0611 #define OMAP_BO_USER_MASK 0x00ffffff
0612
0613 static int ioctl_gem_new(struct drm_device *dev, void *data,
0614 struct drm_file *file_priv)
0615 {
0616 struct drm_omap_gem_new *args = data;
0617 u32 flags = args->flags & OMAP_BO_USER_MASK;
0618
0619 VERB("%p:%p: size=0x%08x, flags=%08x", dev, file_priv,
0620 args->size.bytes, flags);
0621
0622 return omap_gem_new_handle(dev, file_priv, args->size, flags,
0623 &args->handle);
0624 }
0625
0626 static int ioctl_gem_info(struct drm_device *dev, void *data,
0627 struct drm_file *file_priv)
0628 {
0629 struct drm_omap_gem_info *args = data;
0630 struct drm_gem_object *obj;
0631 int ret = 0;
0632
0633 VERB("%p:%p: handle=%d", dev, file_priv, args->handle);
0634
0635 obj = drm_gem_object_lookup(file_priv, args->handle);
0636 if (!obj)
0637 return -ENOENT;
0638
0639 args->size = omap_gem_mmap_size(obj);
0640 args->offset = omap_gem_mmap_offset(obj);
0641
0642 drm_gem_object_put(obj);
0643
0644 return ret;
0645 }
0646
0647 static const struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = {
0648 DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param,
0649 DRM_RENDER_ALLOW),
0650 DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, drm_invalid_op,
0651 DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
0652 DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new,
0653 DRM_RENDER_ALLOW),
0654
0655 DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_PREP, drm_noop,
0656 DRM_RENDER_ALLOW),
0657
0658 DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_FINI, drm_noop,
0659 DRM_RENDER_ALLOW),
0660 DRM_IOCTL_DEF_DRV(OMAP_GEM_INFO, ioctl_gem_info,
0661 DRM_RENDER_ALLOW),
0662 };
0663
0664
0665
0666
0667
0668 static int dev_open(struct drm_device *dev, struct drm_file *file)
0669 {
0670 file->driver_priv = NULL;
0671
0672 DBG("open: dev=%p, file=%p", dev, file);
0673
0674 return 0;
0675 }
0676
0677 static const struct file_operations omapdriver_fops = {
0678 .owner = THIS_MODULE,
0679 .open = drm_open,
0680 .unlocked_ioctl = drm_ioctl,
0681 .compat_ioctl = drm_compat_ioctl,
0682 .release = drm_release,
0683 .mmap = omap_gem_mmap,
0684 .poll = drm_poll,
0685 .read = drm_read,
0686 .llseek = noop_llseek,
0687 };
0688
0689 static const struct drm_driver omap_drm_driver = {
0690 .driver_features = DRIVER_MODESET | DRIVER_GEM |
0691 DRIVER_ATOMIC | DRIVER_RENDER,
0692 .open = dev_open,
0693 .lastclose = drm_fb_helper_lastclose,
0694 #ifdef CONFIG_DEBUG_FS
0695 .debugfs_init = omap_debugfs_init,
0696 #endif
0697 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
0698 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
0699 .gem_prime_import = omap_gem_prime_import,
0700 .dumb_create = omap_gem_dumb_create,
0701 .dumb_map_offset = omap_gem_dumb_map_offset,
0702 .ioctls = ioctls,
0703 .num_ioctls = DRM_OMAP_NUM_IOCTLS,
0704 .fops = &omapdriver_fops,
0705 .name = DRIVER_NAME,
0706 .desc = DRIVER_DESC,
0707 .date = DRIVER_DATE,
0708 .major = DRIVER_MAJOR,
0709 .minor = DRIVER_MINOR,
0710 .patchlevel = DRIVER_PATCHLEVEL,
0711 };
0712
0713 static const struct soc_device_attribute omapdrm_soc_devices[] = {
0714 { .family = "OMAP3", .data = (void *)0x3430 },
0715 { .family = "OMAP4", .data = (void *)0x4430 },
0716 { .family = "OMAP5", .data = (void *)0x5430 },
0717 { .family = "DRA7", .data = (void *)0x0752 },
0718 { }
0719 };
0720
0721 static int omapdrm_init(struct omap_drm_private *priv, struct device *dev)
0722 {
0723 const struct soc_device_attribute *soc;
0724 struct dss_pdata *pdata = dev->platform_data;
0725 struct drm_device *ddev;
0726 int ret;
0727
0728 DBG("%s", dev_name(dev));
0729
0730 if (drm_firmware_drivers_only())
0731 return -ENODEV;
0732
0733
0734 ddev = drm_dev_alloc(&omap_drm_driver, dev);
0735 if (IS_ERR(ddev))
0736 return PTR_ERR(ddev);
0737
0738 priv->ddev = ddev;
0739 ddev->dev_private = priv;
0740
0741 priv->dev = dev;
0742 priv->dss = pdata->dss;
0743 priv->dispc = dispc_get_dispc(priv->dss);
0744
0745 priv->dss->mgr_ops_priv = priv;
0746
0747 soc = soc_device_match(omapdrm_soc_devices);
0748 priv->omaprev = soc ? (uintptr_t)soc->data : 0;
0749 priv->wq = alloc_ordered_workqueue("omapdrm", 0);
0750
0751 mutex_init(&priv->list_lock);
0752 INIT_LIST_HEAD(&priv->obj_list);
0753
0754
0755 priv->max_bandwidth = dispc_get_memory_bandwidth_limit(priv->dispc);
0756
0757 omap_gem_init(ddev);
0758
0759 drm_mode_config_init(ddev);
0760
0761 ret = omap_global_obj_init(ddev);
0762 if (ret)
0763 goto err_gem_deinit;
0764
0765 ret = omap_hwoverlays_init(priv);
0766 if (ret)
0767 goto err_free_priv_obj;
0768
0769 ret = omap_modeset_init(ddev);
0770 if (ret) {
0771 dev_err(priv->dev, "omap_modeset_init failed: ret=%d\n", ret);
0772 goto err_free_overlays;
0773 }
0774
0775
0776 ret = drm_vblank_init(ddev, priv->num_pipes);
0777 if (ret) {
0778 dev_err(priv->dev, "could not init vblank\n");
0779 goto err_cleanup_modeset;
0780 }
0781
0782 omap_fbdev_init(ddev);
0783
0784 drm_kms_helper_poll_init(ddev);
0785 omap_modeset_enable_external_hpd(ddev);
0786
0787
0788
0789
0790
0791 ret = drm_dev_register(ddev, 0);
0792 if (ret)
0793 goto err_cleanup_helpers;
0794
0795 return 0;
0796
0797 err_cleanup_helpers:
0798 omap_modeset_disable_external_hpd(ddev);
0799 drm_kms_helper_poll_fini(ddev);
0800
0801 omap_fbdev_fini(ddev);
0802 err_cleanup_modeset:
0803 omap_modeset_fini(ddev);
0804 err_free_overlays:
0805 omap_hwoverlays_destroy(priv);
0806 err_free_priv_obj:
0807 omap_global_obj_fini(priv);
0808 err_gem_deinit:
0809 drm_mode_config_cleanup(ddev);
0810 omap_gem_deinit(ddev);
0811 destroy_workqueue(priv->wq);
0812 omap_disconnect_pipelines(ddev);
0813 drm_dev_put(ddev);
0814 return ret;
0815 }
0816
0817 static void omapdrm_cleanup(struct omap_drm_private *priv)
0818 {
0819 struct drm_device *ddev = priv->ddev;
0820
0821 DBG("");
0822
0823 drm_dev_unregister(ddev);
0824
0825 omap_modeset_disable_external_hpd(ddev);
0826 drm_kms_helper_poll_fini(ddev);
0827
0828 omap_fbdev_fini(ddev);
0829
0830 drm_atomic_helper_shutdown(ddev);
0831
0832 omap_modeset_fini(ddev);
0833 omap_hwoverlays_destroy(priv);
0834 omap_global_obj_fini(priv);
0835 drm_mode_config_cleanup(ddev);
0836 omap_gem_deinit(ddev);
0837
0838 destroy_workqueue(priv->wq);
0839
0840 omap_disconnect_pipelines(ddev);
0841
0842 drm_dev_put(ddev);
0843 }
0844
0845 static int pdev_probe(struct platform_device *pdev)
0846 {
0847 struct omap_drm_private *priv;
0848 int ret;
0849
0850 ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
0851 if (ret) {
0852 dev_err(&pdev->dev, "Failed to set the DMA mask\n");
0853 return ret;
0854 }
0855
0856
0857 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
0858 if (!priv)
0859 return -ENOMEM;
0860
0861 platform_set_drvdata(pdev, priv);
0862
0863 ret = omapdrm_init(priv, &pdev->dev);
0864 if (ret < 0)
0865 kfree(priv);
0866
0867 return ret;
0868 }
0869
0870 static int pdev_remove(struct platform_device *pdev)
0871 {
0872 struct omap_drm_private *priv = platform_get_drvdata(pdev);
0873
0874 omapdrm_cleanup(priv);
0875 kfree(priv);
0876
0877 return 0;
0878 }
0879
0880 #ifdef CONFIG_PM_SLEEP
0881 static int omap_drm_suspend(struct device *dev)
0882 {
0883 struct omap_drm_private *priv = dev_get_drvdata(dev);
0884 struct drm_device *drm_dev = priv->ddev;
0885
0886 return drm_mode_config_helper_suspend(drm_dev);
0887 }
0888
0889 static int omap_drm_resume(struct device *dev)
0890 {
0891 struct omap_drm_private *priv = dev_get_drvdata(dev);
0892 struct drm_device *drm_dev = priv->ddev;
0893
0894 drm_mode_config_helper_resume(drm_dev);
0895
0896 return omap_gem_resume(drm_dev);
0897 }
0898 #endif
0899
0900 static SIMPLE_DEV_PM_OPS(omapdrm_pm_ops, omap_drm_suspend, omap_drm_resume);
0901
0902 static struct platform_driver pdev = {
0903 .driver = {
0904 .name = "omapdrm",
0905 .pm = &omapdrm_pm_ops,
0906 },
0907 .probe = pdev_probe,
0908 .remove = pdev_remove,
0909 };
0910
0911 static struct platform_driver * const drivers[] = {
0912 &omap_dmm_driver,
0913 &pdev,
0914 };
0915
0916 static int __init omap_drm_init(void)
0917 {
0918 int r;
0919
0920 DBG("init");
0921
0922 r = omap_dss_init();
0923 if (r)
0924 return r;
0925
0926 r = platform_register_drivers(drivers, ARRAY_SIZE(drivers));
0927 if (r) {
0928 omap_dss_exit();
0929 return r;
0930 }
0931
0932 return 0;
0933 }
0934
0935 static void __exit omap_drm_fini(void)
0936 {
0937 DBG("fini");
0938
0939 platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
0940
0941 omap_dss_exit();
0942 }
0943
0944 module_init(omap_drm_init);
0945 module_exit(omap_drm_fini);
0946
0947 MODULE_AUTHOR("Rob Clark <rob@ti.com>");
0948 MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
0949 MODULE_DESCRIPTION("OMAP DRM Display Driver");
0950 MODULE_ALIAS("platform:" DRIVER_NAME);
0951 MODULE_LICENSE("GPL v2");