Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
0004  * Author: Rob Clark <rob@ti.com>
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  * mode config funcs
0037  */
0038 
0039 /* Notes about mapping DSS and DRM entities:
0040  *    CRTC:        overlay
0041  *    encoder:     manager.. with some extension to allow one primary CRTC
0042  *                 and zero or more video CRTC's to be mapped to one encoder?
0043  *    connector:   dssdev.. manager can be attached/detached from different
0044  *                 devices
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     /* Apply the atomic update. */
0076     drm_atomic_helper_commit_modeset_disables(dev, old_state);
0077 
0078     if (priv->omaprev != 0x3430) {
0079         /* With the current dss dispc implementation we have to enable
0080          * the new modeset before we can commit planes. The dispc ovl
0081          * configuration relies on the video mode configuration been
0082          * written into the HW when the ovl configuration is
0083          * calculated.
0084          *
0085          * This approach is not ideal because after a mode change the
0086          * plane update is executed only after the first vblank
0087          * interrupt. The dispc implementation should be fixed so that
0088          * it is able use uncommitted drm state information.
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          * OMAP3 DSS seems to have issues with the work-around above,
0097          * resulting in endless sync losts if a crtc is enabled without
0098          * a plane. For now, skip the WA for OMAP3.
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      * Wait for completion of the page flips to ensure that old buffers
0111      * can't be touched by the hardware anymore before cleaning up planes.
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  * This replaces the drm_atomic_normalize_zpos to handle the dual overlay case.
0133  *
0134  * Since both halves need to be 'appear' side by side the zpos is
0135  * recalculated when dealing with dual overlay cases so that the other
0136  * planes zpos is consistent.
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         /* Reset plane increment and index value for every crtc */
0159         n = 0;
0160 
0161         /*
0162          * Normalization process might create new states for planes
0163          * which normalized_zpos has to be recalculated.
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 /* Global/shared object state funcs */
0228 
0229 /*
0230  * This is a helper that returns the private state currently in operation.
0231  * Note that this would return the "old_state" if called in the atomic check
0232  * path, and the "new_state" after the atomic swap has been done.
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  * This acquires the modeset lock set aside for global state, creates
0242  * a new duplicated private object state.
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                 /* To balance the 'for_each_dss_output' loop */
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      * This function creates exactly one connector, encoder, crtc,
0412      * and primary plane per each connected dss-device. Each
0413      * connector->encoder->crtc chain is expected to be separate
0414      * and each crtc is connect to a single dss-channel. If the
0415      * configuration does not match the expectations or exceeds
0416      * the available resources, the configuration is rejected.
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     /* Create all planes first. They can all be put to any CRTC. */
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      * Create the encoders, attach the bridges and get the pipeline alias
0449      * IDs.
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     /* Sort the pipelines by DT aliases. */
0472     sort(priv->pipes, priv->num_pipes, sizeof(priv->pipes[0]),
0473          omap_compare_pipelines, NULL);
0474 
0475     /*
0476      * Populate the pipeline lookup table by DISPC channel. Only one display
0477      * is allowed per channel.
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     /* Create the connectors and CRTCs. */
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      * Note: these values are used for multiple independent things:
0521      * connector mode filtering, buffer sizes, crtc sizes...
0522      * Use big enough values here to cover all use cases, and do more
0523      * specific checking in the respective code paths.
0524      */
0525     dev->mode_config.max_width = 8192;
0526     dev->mode_config.max_height = 8192;
0527 
0528     /* We want the zpos to be normalized */
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  * Enable the HPD in external components if supported
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  * Disable the HPD in external components if supported
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  * drm ioctl funcs
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  /* flags settable by userspace */
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     /* Deprecated, to be removed. */
0655     DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_PREP, drm_noop,
0656               DRM_RENDER_ALLOW),
0657     /* Deprecated, to be removed. */
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  * drm driver funcs
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     { /* sentinel */ }
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     /* Allocate and initialize the DRM device. */
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     /* Get memory bandwidth limits */
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     /* Initialize vblank handling, start with all CRTCs disabled. */
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      * Register the DRM device with the core and the connectors with
0789      * sysfs.
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     /* Allocate and initialize the driver private structure. */
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");