Subversion Repositories Kolibri OS

Rev

Rev 3764 | Rev 4104 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2006-2008 Intel Corporation
  3.  * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
  4.  * Copyright (c) 2008 Red Hat Inc.
  5.  *
  6.  * DRM core CRTC related functions
  7.  *
  8.  * Permission to use, copy, modify, distribute, and sell this software and its
  9.  * documentation for any purpose is hereby granted without fee, provided that
  10.  * the above copyright notice appear in all copies and that both that copyright
  11.  * notice and this permission notice appear in supporting documentation, and
  12.  * that the name of the copyright holders not be used in advertising or
  13.  * publicity pertaining to distribution of the software without specific,
  14.  * written prior permission.  The copyright holders make no representations
  15.  * about the suitability of this software for any purpose.  It is provided "as
  16.  * is" without express or implied warranty.
  17.  *
  18.  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  19.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  20.  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  21.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  22.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  23.  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  24.  * OF THIS SOFTWARE.
  25.  *
  26.  * Authors:
  27.  *      Keith Packard
  28.  *      Eric Anholt <eric@anholt.net>
  29.  *      Dave Airlie <airlied@linux.ie>
  30.  *      Jesse Barnes <jesse.barnes@intel.com>
  31.  */
  32. #include <linux/ctype.h>
  33. #include <linux/list.h>
  34. #include <linux/slab.h>
  35. #include <linux/export.h>
  36. #include <drm/drmP.h>
  37. #include <drm/drm_crtc.h>
  38. #include <drm/drm_edid.h>
  39. #include <drm/drm_fourcc.h>
  40.  
  41. /**
  42.  * drm_modeset_lock_all - take all modeset locks
  43.  * @dev: drm device
  44.  *
  45.  * This function takes all modeset locks, suitable where a more fine-grained
  46.  * scheme isn't (yet) implemented.
  47.  */
  48. void drm_modeset_lock_all(struct drm_device *dev)
  49. {
  50.         struct drm_crtc *crtc;
  51.  
  52.         mutex_lock(&dev->mode_config.mutex);
  53.  
  54.         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
  55.                 mutex_lock_nest_lock(&crtc->mutex, &dev->mode_config.mutex);
  56. }
  57. EXPORT_SYMBOL(drm_modeset_lock_all);
  58.  
  59. /**
  60.  * drm_modeset_unlock_all - drop all modeset locks
  61.  * @dev: device
  62.  */
  63. void drm_modeset_unlock_all(struct drm_device *dev)
  64. {
  65.         struct drm_crtc *crtc;
  66.  
  67.         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
  68.                 mutex_unlock(&crtc->mutex);
  69.  
  70.         mutex_unlock(&dev->mode_config.mutex);
  71. }
  72. EXPORT_SYMBOL(drm_modeset_unlock_all);
  73.  
  74. /**
  75.  * drm_warn_on_modeset_not_all_locked - check that all modeset locks are locked
  76.  * @dev: device
  77.  */
  78. void drm_warn_on_modeset_not_all_locked(struct drm_device *dev)
  79. {
  80.         struct drm_crtc *crtc;
  81.  
  82.         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
  83.                 WARN_ON(!mutex_is_locked(&crtc->mutex));
  84.  
  85.         WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
  86. }
  87. EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked);
  88.  
  89. /* Avoid boilerplate.  I'm tired of typing. */
  90. #define DRM_ENUM_NAME_FN(fnname, list)                          \
  91.         const char *fnname(int val)                             \
  92.         {                                                       \
  93.                 int i;                                          \
  94.                 for (i = 0; i < ARRAY_SIZE(list); i++) {        \
  95.                         if (list[i].type == val)                \
  96.                                 return list[i].name;            \
  97.                 }                                               \
  98.                 return "(unknown)";                             \
  99.         }
  100.  
  101. /*
  102.  * Global properties
  103.  */
  104. static const struct drm_prop_enum_list drm_dpms_enum_list[] =
  105. {       { DRM_MODE_DPMS_ON, "On" },
  106.         { DRM_MODE_DPMS_STANDBY, "Standby" },
  107.         { DRM_MODE_DPMS_SUSPEND, "Suspend" },
  108.         { DRM_MODE_DPMS_OFF, "Off" }
  109. };
  110.  
  111. DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
  112.  
  113. /*
  114.  * Optional properties
  115.  */
  116. static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
  117. {
  118.         { DRM_MODE_SCALE_NONE, "None" },
  119.         { DRM_MODE_SCALE_FULLSCREEN, "Full" },
  120.         { DRM_MODE_SCALE_CENTER, "Center" },
  121.         { DRM_MODE_SCALE_ASPECT, "Full aspect" },
  122. };
  123.  
  124. static const struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
  125. {
  126.         { DRM_MODE_DITHERING_OFF, "Off" },
  127.         { DRM_MODE_DITHERING_ON, "On" },
  128.         { DRM_MODE_DITHERING_AUTO, "Automatic" },
  129. };
  130.  
  131. /*
  132.  * Non-global properties, but "required" for certain connectors.
  133.  */
  134. static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] =
  135. {
  136.         { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
  137.         { DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
  138.         { DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
  139. };
  140.  
  141. DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
  142.  
  143. static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] =
  144. {
  145.         { DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
  146.         { DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
  147.         { DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
  148. };
  149.  
  150. DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
  151.                  drm_dvi_i_subconnector_enum_list)
  152.  
  153. static const struct drm_prop_enum_list drm_tv_select_enum_list[] =
  154. {
  155.         { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
  156.         { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
  157.         { DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
  158.         { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
  159.         { DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
  160. };
  161.  
  162. DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
  163.  
  164. static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
  165. {
  166.         { DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
  167.         { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
  168.         { DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
  169.         { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
  170.         { DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
  171. };
  172.  
  173. DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
  174.                  drm_tv_subconnector_enum_list)
  175.  
  176. static const struct drm_prop_enum_list drm_dirty_info_enum_list[] = {
  177.         { DRM_MODE_DIRTY_OFF,      "Off"      },
  178.         { DRM_MODE_DIRTY_ON,       "On"       },
  179.         { DRM_MODE_DIRTY_ANNOTATE, "Annotate" },
  180. };
  181.  
  182. struct drm_conn_prop_enum_list {
  183.         int type;
  184.         const char *name;
  185.         int count;
  186. };
  187.  
  188. /*
  189.  * Connector and encoder types.
  190.  */
  191. static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
  192. {       { DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 },
  193.         { DRM_MODE_CONNECTOR_VGA, "VGA", 0 },
  194.         { DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 },
  195.         { DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 },
  196.         { DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 },
  197.         { DRM_MODE_CONNECTOR_Composite, "Composite", 0 },
  198.         { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
  199.         { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
  200.         { DRM_MODE_CONNECTOR_Component, "Component", 0 },
  201.         { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 },
  202.         { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 },
  203.         { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 },
  204.         { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 },
  205.         { DRM_MODE_CONNECTOR_TV, "TV", 0 },
  206.         { DRM_MODE_CONNECTOR_eDP, "eDP", 0 },
  207.         { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0},
  208. };
  209.  
  210. static const struct drm_prop_enum_list drm_encoder_enum_list[] =
  211. {       { DRM_MODE_ENCODER_NONE, "None" },
  212.         { DRM_MODE_ENCODER_DAC, "DAC" },
  213.         { DRM_MODE_ENCODER_TMDS, "TMDS" },
  214.         { DRM_MODE_ENCODER_LVDS, "LVDS" },
  215.         { DRM_MODE_ENCODER_TVDAC, "TV" },
  216.         { DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
  217. };
  218.  
  219. const char *drm_get_encoder_name(const struct drm_encoder *encoder)
  220. {
  221.         static char buf[32];
  222.  
  223.         snprintf(buf, 32, "%s-%d",
  224.                  drm_encoder_enum_list[encoder->encoder_type].name,
  225.                  encoder->base.id);
  226.         return buf;
  227. }
  228. EXPORT_SYMBOL(drm_get_encoder_name);
  229.  
  230. const char *drm_get_connector_name(const struct drm_connector *connector)
  231. {
  232.         static char buf[32];
  233.  
  234.         snprintf(buf, 32, "%s-%d",
  235.                  drm_connector_enum_list[connector->connector_type].name,
  236.                  connector->connector_type_id);
  237.         return buf;
  238. }
  239. EXPORT_SYMBOL(drm_get_connector_name);
  240.  
  241. const char *drm_get_connector_status_name(enum drm_connector_status status)
  242. {
  243.         if (status == connector_status_connected)
  244.                 return "connected";
  245.         else if (status == connector_status_disconnected)
  246.                 return "disconnected";
  247.         else
  248.                 return "unknown";
  249. }
  250. EXPORT_SYMBOL(drm_get_connector_status_name);
  251.  
  252. static char printable_char(int c)
  253. {
  254.         return isascii(c) && isprint(c) ? c : '?';
  255. }
  256.  
  257. const char *drm_get_format_name(uint32_t format)
  258. {
  259.         static char buf[32];
  260.  
  261.         snprintf(buf, sizeof(buf),
  262.                  "%c%c%c%c %s-endian (0x%08x)",
  263.                  printable_char(format & 0xff),
  264.                  printable_char((format >> 8) & 0xff),
  265.                  printable_char((format >> 16) & 0xff),
  266.                  printable_char((format >> 24) & 0x7f),
  267.                  format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little",
  268.                  format);
  269.  
  270.         return buf;
  271. }
  272. EXPORT_SYMBOL(drm_get_format_name);
  273.  
  274. /**
  275.  * drm_mode_object_get - allocate a new modeset identifier
  276.  * @dev: DRM device
  277.  * @obj: object pointer, used to generate unique ID
  278.  * @obj_type: object type
  279.  *
  280.  * Create a unique identifier based on @ptr in @dev's identifier space.  Used
  281.  * for tracking modes, CRTCs and connectors.
  282.  *
  283.  * RETURNS:
  284.  * New unique (relative to other objects in @dev) integer identifier for the
  285.  * object.
  286.  */
  287. static int drm_mode_object_get(struct drm_device *dev,
  288.                                struct drm_mode_object *obj, uint32_t obj_type)
  289. {
  290.         int ret;
  291.  
  292.         mutex_lock(&dev->mode_config.idr_mutex);
  293.         ret = idr_alloc(&dev->mode_config.crtc_idr, obj, 1, 0, GFP_KERNEL);
  294.         if (ret >= 0) {
  295.                 /*
  296.                  * Set up the object linking under the protection of the idr
  297.                  * lock so that other users can't see inconsistent state.
  298.                  */
  299.                 obj->id = ret;
  300.                 obj->type = obj_type;
  301.         }
  302.         mutex_unlock(&dev->mode_config.idr_mutex);
  303.  
  304.         return ret < 0 ? ret : 0;
  305. }
  306.  
  307. /**
  308.  * drm_mode_object_put - free a modeset identifer
  309.  * @dev: DRM device
  310.  * @object: object to free
  311.  *
  312.  * Free @id from @dev's unique identifier pool.
  313.  */
  314. static void drm_mode_object_put(struct drm_device *dev,
  315.                                 struct drm_mode_object *object)
  316. {
  317.         mutex_lock(&dev->mode_config.idr_mutex);
  318.         idr_remove(&dev->mode_config.crtc_idr, object->id);
  319.         mutex_unlock(&dev->mode_config.idr_mutex);
  320. }
  321.  
  322. /**
  323.  * drm_mode_object_find - look up a drm object with static lifetime
  324.  * @dev: drm device
  325.  * @id: id of the mode object
  326.  * @type: type of the mode object
  327.  *
  328.  * Note that framebuffers cannot be looked up with this functions - since those
  329.  * are reference counted, they need special treatment.
  330.  */
  331. struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
  332.                 uint32_t id, uint32_t type)
  333. {
  334.         struct drm_mode_object *obj = NULL;
  335.  
  336.         /* Framebuffers are reference counted and need their own lookup
  337.          * function.*/
  338.         WARN_ON(type == DRM_MODE_OBJECT_FB);
  339.  
  340.         mutex_lock(&dev->mode_config.idr_mutex);
  341.         obj = idr_find(&dev->mode_config.crtc_idr, id);
  342.         if (!obj || (obj->type != type) || (obj->id != id))
  343.                 obj = NULL;
  344.         mutex_unlock(&dev->mode_config.idr_mutex);
  345.  
  346.         return obj;
  347. }
  348. EXPORT_SYMBOL(drm_mode_object_find);
  349.  
  350. /**
  351.  * drm_framebuffer_init - initialize a framebuffer
  352.  * @dev: DRM device
  353.  * @fb: framebuffer to be initialized
  354.  * @funcs: ... with these functions
  355.  *
  356.  * Allocates an ID for the framebuffer's parent mode object, sets its mode
  357.  * functions & device file and adds it to the master fd list.
  358.  *
  359.  * IMPORTANT:
  360.  * This functions publishes the fb and makes it available for concurrent access
  361.  * by other users. Which means by this point the fb _must_ be fully set up -
  362.  * since all the fb attributes are invariant over its lifetime, no further
  363.  * locking but only correct reference counting is required.
  364.  *
  365.  * RETURNS:
  366.  * Zero on success, error code on failure.
  367.  */
  368. int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
  369.                          const struct drm_framebuffer_funcs *funcs)
  370. {
  371.         int ret;
  372.  
  373.         mutex_lock(&dev->mode_config.fb_lock);
  374.         kref_init(&fb->refcount);
  375.         INIT_LIST_HEAD(&fb->filp_head);
  376.         fb->dev = dev;
  377.         fb->funcs = funcs;
  378.  
  379.         ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
  380.         if (ret)
  381.                 goto out;
  382.  
  383.         /* Grab the idr reference. */
  384.         drm_framebuffer_reference(fb);
  385.  
  386.         dev->mode_config.num_fb++;
  387.         list_add(&fb->head, &dev->mode_config.fb_list);
  388. out:
  389.         mutex_unlock(&dev->mode_config.fb_lock);
  390.  
  391.         return 0;
  392. }
  393. EXPORT_SYMBOL(drm_framebuffer_init);
  394.  
  395. static void drm_framebuffer_free(struct kref *kref)
  396. {
  397.         struct drm_framebuffer *fb =
  398.                         container_of(kref, struct drm_framebuffer, refcount);
  399.         fb->funcs->destroy(fb);
  400. }
  401.  
  402. static struct drm_framebuffer *__drm_framebuffer_lookup(struct drm_device *dev,
  403.                                                         uint32_t id)
  404. {
  405.         struct drm_mode_object *obj = NULL;
  406.         struct drm_framebuffer *fb;
  407.  
  408.         mutex_lock(&dev->mode_config.idr_mutex);
  409.         obj = idr_find(&dev->mode_config.crtc_idr, id);
  410.         if (!obj || (obj->type != DRM_MODE_OBJECT_FB) || (obj->id != id))
  411.                 fb = NULL;
  412.         else
  413.                 fb = obj_to_fb(obj);
  414.         mutex_unlock(&dev->mode_config.idr_mutex);
  415.  
  416.         return fb;
  417. }
  418.  
  419. /**
  420.  * drm_framebuffer_lookup - look up a drm framebuffer and grab a reference
  421.  * @dev: drm device
  422.  * @id: id of the fb object
  423.  *
  424.  * If successful, this grabs an additional reference to the framebuffer -
  425.  * callers need to make sure to eventually unreference the returned framebuffer
  426.  * again.
  427.  */
  428. struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
  429.                                                uint32_t id)
  430. {
  431.         struct drm_framebuffer *fb;
  432.  
  433.         mutex_lock(&dev->mode_config.fb_lock);
  434.         fb = __drm_framebuffer_lookup(dev, id);
  435.         if (fb)
  436.                 drm_framebuffer_reference(fb);
  437.         mutex_unlock(&dev->mode_config.fb_lock);
  438.  
  439.         return fb;
  440. }
  441. EXPORT_SYMBOL(drm_framebuffer_lookup);
  442.  
  443. /**
  444.  * drm_framebuffer_unreference - unref a framebuffer
  445.  * @fb: framebuffer to unref
  446.  *
  447.  * This functions decrements the fb's refcount and frees it if it drops to zero.
  448.  */
  449. void drm_framebuffer_unreference(struct drm_framebuffer *fb)
  450. {
  451.         DRM_DEBUG("FB ID: %d\n", fb->base.id);
  452.         kref_put(&fb->refcount, drm_framebuffer_free);
  453. }
  454. EXPORT_SYMBOL(drm_framebuffer_unreference);
  455.  
  456. /**
  457.  * drm_framebuffer_reference - incr the fb refcnt
  458.  * @fb: framebuffer
  459.  */
  460. void drm_framebuffer_reference(struct drm_framebuffer *fb)
  461. {
  462.         DRM_DEBUG("FB ID: %d\n", fb->base.id);
  463.         kref_get(&fb->refcount);
  464. }
  465. EXPORT_SYMBOL(drm_framebuffer_reference);
  466.  
  467. static void drm_framebuffer_free_bug(struct kref *kref)
  468. {
  469.         BUG();
  470. }
  471.  
  472. static void __drm_framebuffer_unreference(struct drm_framebuffer *fb)
  473. {
  474.         DRM_DEBUG("FB ID: %d\n", fb->base.id);
  475.         kref_put(&fb->refcount, drm_framebuffer_free_bug);
  476. }
  477.  
  478. /* dev->mode_config.fb_lock must be held! */
  479. static void __drm_framebuffer_unregister(struct drm_device *dev,
  480.                                          struct drm_framebuffer *fb)
  481. {
  482.         mutex_lock(&dev->mode_config.idr_mutex);
  483.         idr_remove(&dev->mode_config.crtc_idr, fb->base.id);
  484.         mutex_unlock(&dev->mode_config.idr_mutex);
  485.  
  486.         fb->base.id = 0;
  487.  
  488.         __drm_framebuffer_unreference(fb);
  489. }
  490.  
  491. /**
  492.  * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
  493.  * @fb: fb to unregister
  494.  *
  495.  * Drivers need to call this when cleaning up driver-private framebuffers, e.g.
  496.  * those used for fbdev. Note that the caller must hold a reference of it's own,
  497.  * i.e. the object may not be destroyed through this call (since it'll lead to a
  498.  * locking inversion).
  499.  */
  500. void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
  501. {
  502.         struct drm_device *dev = fb->dev;
  503.  
  504.         mutex_lock(&dev->mode_config.fb_lock);
  505.         /* Mark fb as reaped and drop idr ref. */
  506.         __drm_framebuffer_unregister(dev, fb);
  507.         mutex_unlock(&dev->mode_config.fb_lock);
  508. }
  509. EXPORT_SYMBOL(drm_framebuffer_unregister_private);
  510.  
  511. /**
  512.  * drm_framebuffer_cleanup - remove a framebuffer object
  513.  * @fb: framebuffer to remove
  514.  *
  515.  * Cleanup references to a user-created framebuffer. This function is intended
  516.  * to be used from the drivers ->destroy callback.
  517.  *
  518.  * Note that this function does not remove the fb from active usuage - if it is
  519.  * still used anywhere, hilarity can ensue since userspace could call getfb on
  520.  * the id and get back -EINVAL. Obviously no concern at driver unload time.
  521.  *
  522.  * Also, the framebuffer will not be removed from the lookup idr - for
  523.  * user-created framebuffers this will happen in in the rmfb ioctl. For
  524.  * driver-private objects (e.g. for fbdev) drivers need to explicitly call
  525.  * drm_framebuffer_unregister_private.
  526.  */
  527. void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
  528. {
  529.         struct drm_device *dev = fb->dev;
  530.  
  531.         mutex_lock(&dev->mode_config.fb_lock);
  532.         list_del(&fb->head);
  533.         dev->mode_config.num_fb--;
  534.         mutex_unlock(&dev->mode_config.fb_lock);
  535. }
  536. EXPORT_SYMBOL(drm_framebuffer_cleanup);
  537.  
  538. /**
  539.  * drm_framebuffer_remove - remove and unreference a framebuffer object
  540.  * @fb: framebuffer to remove
  541.  *
  542.  * Scans all the CRTCs and planes in @dev's mode_config.  If they're
  543.  * using @fb, removes it, setting it to NULL. Then drops the reference to the
  544.  * passed-in framebuffer. Might take the modeset locks.
  545.  *
  546.  * Note that this function optimizes the cleanup away if the caller holds the
  547.  * last reference to the framebuffer. It is also guaranteed to not take the
  548.  * modeset locks in this case.
  549.  */
  550. void drm_framebuffer_remove(struct drm_framebuffer *fb)
  551. {
  552.         struct drm_device *dev = fb->dev;
  553.         struct drm_crtc *crtc;
  554.         struct drm_plane *plane;
  555.         struct drm_mode_set set;
  556.         int ret;
  557.  
  558.         WARN_ON(!list_empty(&fb->filp_head));
  559.  
  560.         /*
  561.          * drm ABI mandates that we remove any deleted framebuffers from active
  562.          * useage. But since most sane clients only remove framebuffers they no
  563.          * longer need, try to optimize this away.
  564.          *
  565.          * Since we're holding a reference ourselves, observing a refcount of 1
  566.          * means that we're the last holder and can skip it. Also, the refcount
  567.          * can never increase from 1 again, so we don't need any barriers or
  568.          * locks.
  569.          *
  570.          * Note that userspace could try to race with use and instate a new
  571.          * usage _after_ we've cleared all current ones. End result will be an
  572.          * in-use fb with fb-id == 0. Userspace is allowed to shoot its own foot
  573.          * in this manner.
  574.          */
  575.         if (atomic_read(&fb->refcount.refcount) > 1) {
  576.                 drm_modeset_lock_all(dev);
  577.                 /* remove from any CRTC */
  578.                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
  579.                         if (crtc->fb == fb) {
  580.                                 /* should turn off the crtc */
  581.                                 memset(&set, 0, sizeof(struct drm_mode_set));
  582.                                 set.crtc = crtc;
  583.                                 set.fb = NULL;
  584.                                 ret = drm_mode_set_config_internal(&set);
  585.                                 if (ret)
  586.                                         DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
  587.                         }
  588.                 }
  589.  
  590.                 list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
  591.                         if (plane->fb == fb)
  592.                                 drm_plane_force_disable(plane);
  593.                 }
  594.                 drm_modeset_unlock_all(dev);
  595.         }
  596.  
  597.         drm_framebuffer_unreference(fb);
  598. }
  599. EXPORT_SYMBOL(drm_framebuffer_remove);
  600.  
  601. /**
  602.  * drm_crtc_init - Initialise a new CRTC object
  603.  * @dev: DRM device
  604.  * @crtc: CRTC object to init
  605.  * @funcs: callbacks for the new CRTC
  606.  *
  607.  * Inits a new object created as base part of a driver crtc object.
  608.  *
  609.  * RETURNS:
  610.  * Zero on success, error code on failure.
  611.  */
  612. int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
  613.                    const struct drm_crtc_funcs *funcs)
  614. {
  615.         int ret;
  616.  
  617.         crtc->dev = dev;
  618.         crtc->funcs = funcs;
  619.         crtc->invert_dimensions = false;
  620.  
  621.         drm_modeset_lock_all(dev);
  622.         mutex_init(&crtc->mutex);
  623.         mutex_lock_nest_lock(&crtc->mutex, &dev->mode_config.mutex);
  624.  
  625.         ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
  626.         if (ret)
  627.                 goto out;
  628.  
  629.         crtc->base.properties = &crtc->properties;
  630.  
  631.         list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
  632.         dev->mode_config.num_crtc++;
  633.  
  634.  out:
  635.         drm_modeset_unlock_all(dev);
  636.  
  637.         return ret;
  638. }
  639. EXPORT_SYMBOL(drm_crtc_init);
  640.  
  641. /**
  642.  * drm_crtc_cleanup - Clean up the core crtc usage
  643.  * @crtc: CRTC to cleanup
  644.  *
  645.  * This function cleans up @crtc and removes it from the DRM mode setting
  646.  * core. Note that the function does *not* free the crtc structure itself,
  647.  * this is the responsibility of the caller.
  648.  */
  649. void drm_crtc_cleanup(struct drm_crtc *crtc)
  650. {
  651.         struct drm_device *dev = crtc->dev;
  652.  
  653.                 kfree(crtc->gamma_store);
  654.                 crtc->gamma_store = NULL;
  655.  
  656.         drm_mode_object_put(dev, &crtc->base);
  657.         list_del(&crtc->head);
  658.         dev->mode_config.num_crtc--;
  659. }
  660. EXPORT_SYMBOL(drm_crtc_cleanup);
  661.  
  662. /**
  663.  * drm_mode_probed_add - add a mode to a connector's probed mode list
  664.  * @connector: connector the new mode
  665.  * @mode: mode data
  666.  *
  667.  * Add @mode to @connector's mode list for later use.
  668.  */
  669. void drm_mode_probed_add(struct drm_connector *connector,
  670.                          struct drm_display_mode *mode)
  671. {
  672.         list_add_tail(&mode->head, &connector->probed_modes);
  673. }
  674. EXPORT_SYMBOL(drm_mode_probed_add);
  675.  
  676. /**
  677.  * drm_mode_remove - remove and free a mode
  678.  * @connector: connector list to modify
  679.  * @mode: mode to remove
  680.  *
  681.  * Remove @mode from @connector's mode list, then free it.
  682.  */
  683. void drm_mode_remove(struct drm_connector *connector,
  684.                      struct drm_display_mode *mode)
  685. {
  686.         list_del(&mode->head);
  687.         drm_mode_destroy(connector->dev, mode);
  688. }
  689. EXPORT_SYMBOL(drm_mode_remove);
  690.  
  691. /**
  692.  * drm_connector_init - Init a preallocated connector
  693.  * @dev: DRM device
  694.  * @connector: the connector to init
  695.  * @funcs: callbacks for this connector
  696.  * @connector_type: user visible type of the connector
  697.  *
  698.  * Initialises a preallocated connector. Connectors should be
  699.  * subclassed as part of driver connector objects.
  700.  *
  701.  * RETURNS:
  702.  * Zero on success, error code on failure.
  703.  */
  704. int drm_connector_init(struct drm_device *dev,
  705.                      struct drm_connector *connector,
  706.                      const struct drm_connector_funcs *funcs,
  707.                      int connector_type)
  708. {
  709.         int ret;
  710.  
  711.         drm_modeset_lock_all(dev);
  712.  
  713.         ret = drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
  714.         if (ret)
  715.                 goto out;
  716.  
  717.         connector->base.properties = &connector->properties;
  718.         connector->dev = dev;
  719.         connector->funcs = funcs;
  720.         connector->connector_type = connector_type;
  721.         connector->connector_type_id =
  722.                 ++drm_connector_enum_list[connector_type].count; /* TODO */
  723.         INIT_LIST_HEAD(&connector->probed_modes);
  724.         INIT_LIST_HEAD(&connector->modes);
  725.         connector->edid_blob_ptr = NULL;
  726.         connector->status = connector_status_unknown;
  727.  
  728.         list_add_tail(&connector->head, &dev->mode_config.connector_list);
  729.         dev->mode_config.num_connector++;
  730.  
  731.         if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
  732.                 drm_object_attach_property(&connector->base,
  733.                                               dev->mode_config.edid_property,
  734.                                               0);
  735.  
  736.         drm_object_attach_property(&connector->base,
  737.                                       dev->mode_config.dpms_property, 0);
  738.  
  739.  out:
  740.         drm_modeset_unlock_all(dev);
  741.  
  742.         return ret;
  743. }
  744. EXPORT_SYMBOL(drm_connector_init);
  745.  
  746. /**
  747.  * drm_connector_cleanup - cleans up an initialised connector
  748.  * @connector: connector to cleanup
  749.  *
  750.  * Cleans up the connector but doesn't free the object.
  751.  */
  752. void drm_connector_cleanup(struct drm_connector *connector)
  753. {
  754.         struct drm_device *dev = connector->dev;
  755.         struct drm_display_mode *mode, *t;
  756.  
  757.         list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
  758.                 drm_mode_remove(connector, mode);
  759.  
  760.         list_for_each_entry_safe(mode, t, &connector->modes, head)
  761.                 drm_mode_remove(connector, mode);
  762.  
  763.         drm_mode_object_put(dev, &connector->base);
  764.         list_del(&connector->head);
  765.         dev->mode_config.num_connector--;
  766. }
  767. EXPORT_SYMBOL(drm_connector_cleanup);
  768.  
  769. void drm_connector_unplug_all(struct drm_device *dev)
  770. {
  771.         struct drm_connector *connector;
  772.  
  773.         /* taking the mode config mutex ends up in a clash with sysfs */
  774. //   list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  775. //       drm_sysfs_connector_remove(connector);
  776.  
  777. }
  778. EXPORT_SYMBOL(drm_connector_unplug_all);
  779.  
  780. int drm_encoder_init(struct drm_device *dev,
  781.                       struct drm_encoder *encoder,
  782.                       const struct drm_encoder_funcs *funcs,
  783.                       int encoder_type)
  784. {
  785.         int ret;
  786.  
  787.         drm_modeset_lock_all(dev);
  788.  
  789.         ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
  790.         if (ret)
  791.                 goto out;
  792.  
  793.         encoder->dev = dev;
  794.         encoder->encoder_type = encoder_type;
  795.         encoder->funcs = funcs;
  796.  
  797.         list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
  798.         dev->mode_config.num_encoder++;
  799.  
  800.  out:
  801.         drm_modeset_unlock_all(dev);
  802.  
  803.         return ret;
  804. }
  805. EXPORT_SYMBOL(drm_encoder_init);
  806.  
  807. void drm_encoder_cleanup(struct drm_encoder *encoder)
  808. {
  809.         struct drm_device *dev = encoder->dev;
  810.         drm_modeset_lock_all(dev);
  811.         drm_mode_object_put(dev, &encoder->base);
  812.         list_del(&encoder->head);
  813.         dev->mode_config.num_encoder--;
  814.         drm_modeset_unlock_all(dev);
  815. }
  816. EXPORT_SYMBOL(drm_encoder_cleanup);
  817.  
  818. /**
  819.  * drm_plane_init - Initialise a new plane object
  820.  * @dev: DRM device
  821.  * @plane: plane object to init
  822.  * @possible_crtcs: bitmask of possible CRTCs
  823.  * @funcs: callbacks for the new plane
  824.  * @formats: array of supported formats (%DRM_FORMAT_*)
  825.  * @format_count: number of elements in @formats
  826.  * @priv: plane is private (hidden from userspace)?
  827.  *
  828.  * Inits a new object created as base part of a driver plane object.
  829.  *
  830.  * RETURNS:
  831.  * Zero on success, error code on failure.
  832.  */
  833. int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
  834.                    unsigned long possible_crtcs,
  835.                    const struct drm_plane_funcs *funcs,
  836.                    const uint32_t *formats, uint32_t format_count,
  837.                    bool priv)
  838. {
  839.         int ret;
  840.  
  841.         drm_modeset_lock_all(dev);
  842.  
  843.         ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
  844.         if (ret)
  845.                 goto out;
  846.  
  847.         plane->base.properties = &plane->properties;
  848.         plane->dev = dev;
  849.         plane->funcs = funcs;
  850.         plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
  851.                                       GFP_KERNEL);
  852.         if (!plane->format_types) {
  853.                 DRM_DEBUG_KMS("out of memory when allocating plane\n");
  854.                 drm_mode_object_put(dev, &plane->base);
  855.                 ret = -ENOMEM;
  856.                 goto out;
  857.         }
  858.  
  859.         memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
  860.         plane->format_count = format_count;
  861.         plane->possible_crtcs = possible_crtcs;
  862.  
  863.         /* private planes are not exposed to userspace, but depending on
  864.          * display hardware, might be convenient to allow sharing programming
  865.          * for the scanout engine with the crtc implementation.
  866.          */
  867.         if (!priv) {
  868.                 list_add_tail(&plane->head, &dev->mode_config.plane_list);
  869.                 dev->mode_config.num_plane++;
  870.         } else {
  871.                 INIT_LIST_HEAD(&plane->head);
  872.         }
  873.  
  874.  out:
  875.         drm_modeset_unlock_all(dev);
  876.  
  877.         return ret;
  878. }
  879. EXPORT_SYMBOL(drm_plane_init);
  880.  
  881. /**
  882.  * drm_plane_cleanup - Clean up the core plane usage
  883.  * @plane: plane to cleanup
  884.  *
  885.  * This function cleans up @plane and removes it from the DRM mode setting
  886.  * core. Note that the function does *not* free the plane structure itself,
  887.  * this is the responsibility of the caller.
  888.  */
  889. void drm_plane_cleanup(struct drm_plane *plane)
  890. {
  891.         struct drm_device *dev = plane->dev;
  892.  
  893.         drm_modeset_lock_all(dev);
  894.         kfree(plane->format_types);
  895.         drm_mode_object_put(dev, &plane->base);
  896.         /* if not added to a list, it must be a private plane */
  897.         if (!list_empty(&plane->head)) {
  898.                 list_del(&plane->head);
  899.                 dev->mode_config.num_plane--;
  900.         }
  901.         drm_modeset_unlock_all(dev);
  902. }
  903. EXPORT_SYMBOL(drm_plane_cleanup);
  904.  
  905. /**
  906.  * drm_plane_force_disable - Forcibly disable a plane
  907.  * @plane: plane to disable
  908.  *
  909.  * Forces the plane to be disabled.
  910.  *
  911.  * Used when the plane's current framebuffer is destroyed,
  912.  * and when restoring fbdev mode.
  913.  */
  914. void drm_plane_force_disable(struct drm_plane *plane)
  915. {
  916.         int ret;
  917.  
  918.         if (!plane->fb)
  919.                 return;
  920.  
  921.         ret = plane->funcs->disable_plane(plane);
  922.         if (ret)
  923.                 DRM_ERROR("failed to disable plane with busy fb\n");
  924.         /* disconnect the plane from the fb and crtc: */
  925.         __drm_framebuffer_unreference(plane->fb);
  926.         plane->fb = NULL;
  927.         plane->crtc = NULL;
  928. }
  929. EXPORT_SYMBOL(drm_plane_force_disable);
  930.  
  931. /**
  932.  * drm_mode_create - create a new display mode
  933.  * @dev: DRM device
  934.  *
  935.  * Create a new drm_display_mode, give it an ID, and return it.
  936.  *
  937.  * RETURNS:
  938.  * Pointer to new mode on success, NULL on error.
  939.  */
  940. struct drm_display_mode *drm_mode_create(struct drm_device *dev)
  941. {
  942.         struct drm_display_mode *nmode;
  943.  
  944.         nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
  945.         if (!nmode)
  946.                 return NULL;
  947.  
  948.         if (drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE)) {
  949.                 kfree(nmode);
  950.                 return NULL;
  951.         }
  952.  
  953.         return nmode;
  954. }
  955. EXPORT_SYMBOL(drm_mode_create);
  956.  
  957. /**
  958.  * drm_mode_destroy - remove a mode
  959.  * @dev: DRM device
  960.  * @mode: mode to remove
  961.  *
  962.  * Free @mode's unique identifier, then free it.
  963.  */
  964. void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
  965. {
  966.         if (!mode)
  967.                 return;
  968.  
  969.         drm_mode_object_put(dev, &mode->base);
  970.  
  971.         kfree(mode);
  972. }
  973. EXPORT_SYMBOL(drm_mode_destroy);
  974.  
  975. static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
  976. {
  977.         struct drm_property *edid;
  978.         struct drm_property *dpms;
  979.  
  980.         /*
  981.          * Standard properties (apply to all connectors)
  982.          */
  983.         edid = drm_property_create(dev, DRM_MODE_PROP_BLOB |
  984.                                    DRM_MODE_PROP_IMMUTABLE,
  985.                                    "EDID", 0);
  986.         dev->mode_config.edid_property = edid;
  987.  
  988.         dpms = drm_property_create_enum(dev, 0,
  989.                                    "DPMS", drm_dpms_enum_list,
  990.                                    ARRAY_SIZE(drm_dpms_enum_list));
  991.         dev->mode_config.dpms_property = dpms;
  992.  
  993.         return 0;
  994. }
  995.  
  996. /**
  997.  * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
  998.  * @dev: DRM device
  999.  *
  1000.  * Called by a driver the first time a DVI-I connector is made.
  1001.  */
  1002. int drm_mode_create_dvi_i_properties(struct drm_device *dev)
  1003. {
  1004.         struct drm_property *dvi_i_selector;
  1005.         struct drm_property *dvi_i_subconnector;
  1006.  
  1007.         if (dev->mode_config.dvi_i_select_subconnector_property)
  1008.                 return 0;
  1009.  
  1010.         dvi_i_selector =
  1011.                 drm_property_create_enum(dev, 0,
  1012.                                     "select subconnector",
  1013.                                     drm_dvi_i_select_enum_list,
  1014.                                     ARRAY_SIZE(drm_dvi_i_select_enum_list));
  1015.         dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
  1016.  
  1017.         dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
  1018.                                     "subconnector",
  1019.                                     drm_dvi_i_subconnector_enum_list,
  1020.                                     ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
  1021.         dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
  1022.  
  1023.         return 0;
  1024. }
  1025. EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
  1026.  
  1027. /**
  1028.  * drm_create_tv_properties - create TV specific connector properties
  1029.  * @dev: DRM device
  1030.  * @num_modes: number of different TV formats (modes) supported
  1031.  * @modes: array of pointers to strings containing name of each format
  1032.  *
  1033.  * Called by a driver's TV initialization routine, this function creates
  1034.  * the TV specific connector properties for a given device.  Caller is
  1035.  * responsible for allocating a list of format names and passing them to
  1036.  * this routine.
  1037.  */
  1038. int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
  1039.                                   char *modes[])
  1040. {
  1041.         struct drm_property *tv_selector;
  1042.         struct drm_property *tv_subconnector;
  1043.         int i;
  1044.  
  1045.         if (dev->mode_config.tv_select_subconnector_property)
  1046.                 return 0;
  1047.  
  1048.         /*
  1049.          * Basic connector properties
  1050.          */
  1051.         tv_selector = drm_property_create_enum(dev, 0,
  1052.                                           "select subconnector",
  1053.                                           drm_tv_select_enum_list,
  1054.                                           ARRAY_SIZE(drm_tv_select_enum_list));
  1055.         dev->mode_config.tv_select_subconnector_property = tv_selector;
  1056.  
  1057.         tv_subconnector =
  1058.                 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
  1059.                                     "subconnector",
  1060.                                     drm_tv_subconnector_enum_list,
  1061.                                     ARRAY_SIZE(drm_tv_subconnector_enum_list));
  1062.         dev->mode_config.tv_subconnector_property = tv_subconnector;
  1063.  
  1064.         /*
  1065.          * Other, TV specific properties: margins & TV modes.
  1066.          */
  1067.         dev->mode_config.tv_left_margin_property =
  1068.                 drm_property_create_range(dev, 0, "left margin", 0, 100);
  1069.  
  1070.         dev->mode_config.tv_right_margin_property =
  1071.                 drm_property_create_range(dev, 0, "right margin", 0, 100);
  1072.  
  1073.         dev->mode_config.tv_top_margin_property =
  1074.                 drm_property_create_range(dev, 0, "top margin", 0, 100);
  1075.  
  1076.         dev->mode_config.tv_bottom_margin_property =
  1077.                 drm_property_create_range(dev, 0, "bottom margin", 0, 100);
  1078.  
  1079.         dev->mode_config.tv_mode_property =
  1080.                 drm_property_create(dev, DRM_MODE_PROP_ENUM,
  1081.                                     "mode", num_modes);
  1082.         for (i = 0; i < num_modes; i++)
  1083.                 drm_property_add_enum(dev->mode_config.tv_mode_property, i,
  1084.                                       i, modes[i]);
  1085.  
  1086.         dev->mode_config.tv_brightness_property =
  1087.                 drm_property_create_range(dev, 0, "brightness", 0, 100);
  1088.  
  1089.         dev->mode_config.tv_contrast_property =
  1090.                 drm_property_create_range(dev, 0, "contrast", 0, 100);
  1091.  
  1092.         dev->mode_config.tv_flicker_reduction_property =
  1093.                 drm_property_create_range(dev, 0, "flicker reduction", 0, 100);
  1094.  
  1095.         dev->mode_config.tv_overscan_property =
  1096.                 drm_property_create_range(dev, 0, "overscan", 0, 100);
  1097.  
  1098.         dev->mode_config.tv_saturation_property =
  1099.                 drm_property_create_range(dev, 0, "saturation", 0, 100);
  1100.  
  1101.         dev->mode_config.tv_hue_property =
  1102.                 drm_property_create_range(dev, 0, "hue", 0, 100);
  1103.  
  1104.         return 0;
  1105. }
  1106. EXPORT_SYMBOL(drm_mode_create_tv_properties);
  1107.  
  1108. /**
  1109.  * drm_mode_create_scaling_mode_property - create scaling mode property
  1110.  * @dev: DRM device
  1111.  *
  1112.  * Called by a driver the first time it's needed, must be attached to desired
  1113.  * connectors.
  1114.  */
  1115. int drm_mode_create_scaling_mode_property(struct drm_device *dev)
  1116. {
  1117.         struct drm_property *scaling_mode;
  1118.  
  1119.         if (dev->mode_config.scaling_mode_property)
  1120.                 return 0;
  1121.  
  1122.         scaling_mode =
  1123.                 drm_property_create_enum(dev, 0, "scaling mode",
  1124.                                 drm_scaling_mode_enum_list,
  1125.                                     ARRAY_SIZE(drm_scaling_mode_enum_list));
  1126.  
  1127.         dev->mode_config.scaling_mode_property = scaling_mode;
  1128.  
  1129.         return 0;
  1130. }
  1131. EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
  1132.  
  1133. /**
  1134.  * drm_mode_create_dithering_property - create dithering property
  1135.  * @dev: DRM device
  1136.  *
  1137.  * Called by a driver the first time it's needed, must be attached to desired
  1138.  * connectors.
  1139.  */
  1140. int drm_mode_create_dithering_property(struct drm_device *dev)
  1141. {
  1142.         struct drm_property *dithering_mode;
  1143.  
  1144.         if (dev->mode_config.dithering_mode_property)
  1145.                 return 0;
  1146.  
  1147.         dithering_mode =
  1148.                 drm_property_create_enum(dev, 0, "dithering",
  1149.                                 drm_dithering_mode_enum_list,
  1150.                                     ARRAY_SIZE(drm_dithering_mode_enum_list));
  1151.         dev->mode_config.dithering_mode_property = dithering_mode;
  1152.  
  1153.         return 0;
  1154. }
  1155. EXPORT_SYMBOL(drm_mode_create_dithering_property);
  1156.  
  1157. /**
  1158.  * drm_mode_create_dirty_property - create dirty property
  1159.  * @dev: DRM device
  1160.  *
  1161.  * Called by a driver the first time it's needed, must be attached to desired
  1162.  * connectors.
  1163.  */
  1164. int drm_mode_create_dirty_info_property(struct drm_device *dev)
  1165. {
  1166.         struct drm_property *dirty_info;
  1167.  
  1168.         if (dev->mode_config.dirty_info_property)
  1169.                 return 0;
  1170.  
  1171.         dirty_info =
  1172.                 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
  1173.                                     "dirty",
  1174.                                     drm_dirty_info_enum_list,
  1175.                                     ARRAY_SIZE(drm_dirty_info_enum_list));
  1176.         dev->mode_config.dirty_info_property = dirty_info;
  1177.  
  1178.         return 0;
  1179. }
  1180. EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
  1181.  
  1182. static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
  1183. {
  1184.         uint32_t total_objects = 0;
  1185.  
  1186.         total_objects += dev->mode_config.num_crtc;
  1187.         total_objects += dev->mode_config.num_connector;
  1188.         total_objects += dev->mode_config.num_encoder;
  1189.  
  1190.         group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
  1191.         if (!group->id_list)
  1192.                 return -ENOMEM;
  1193.  
  1194.         group->num_crtcs = 0;
  1195.         group->num_connectors = 0;
  1196.         group->num_encoders = 0;
  1197.         return 0;
  1198. }
  1199.  
  1200. int drm_mode_group_init_legacy_group(struct drm_device *dev,
  1201.                                      struct drm_mode_group *group)
  1202. {
  1203.         struct drm_crtc *crtc;
  1204.         struct drm_encoder *encoder;
  1205.         struct drm_connector *connector;
  1206.         int ret;
  1207.  
  1208.         if ((ret = drm_mode_group_init(dev, group)))
  1209.                 return ret;
  1210.  
  1211.         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
  1212.                 group->id_list[group->num_crtcs++] = crtc->base.id;
  1213.  
  1214.         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
  1215.                 group->id_list[group->num_crtcs + group->num_encoders++] =
  1216.                 encoder->base.id;
  1217.  
  1218.         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  1219.                 group->id_list[group->num_crtcs + group->num_encoders +
  1220.                                group->num_connectors++] = connector->base.id;
  1221.  
  1222.         return 0;
  1223. }
  1224. EXPORT_SYMBOL(drm_mode_group_init_legacy_group);
  1225.  
  1226. /**
  1227.  * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
  1228.  * @out: drm_mode_modeinfo struct to return to the user
  1229.  * @in: drm_display_mode to use
  1230.  *
  1231.  * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
  1232.  * the user.
  1233.  */
  1234. static void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
  1235.                                       const struct drm_display_mode *in)
  1236. {
  1237.         WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX ||
  1238.              in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX ||
  1239.              in->hskew > USHRT_MAX || in->vdisplay > USHRT_MAX ||
  1240.              in->vsync_start > USHRT_MAX || in->vsync_end > USHRT_MAX ||
  1241.              in->vtotal > USHRT_MAX || in->vscan > USHRT_MAX,
  1242.              "timing values too large for mode info\n");
  1243.  
  1244.         out->clock = in->clock;
  1245.         out->hdisplay = in->hdisplay;
  1246.         out->hsync_start = in->hsync_start;
  1247.         out->hsync_end = in->hsync_end;
  1248.         out->htotal = in->htotal;
  1249.         out->hskew = in->hskew;
  1250.         out->vdisplay = in->vdisplay;
  1251.         out->vsync_start = in->vsync_start;
  1252.         out->vsync_end = in->vsync_end;
  1253.         out->vtotal = in->vtotal;
  1254.         out->vscan = in->vscan;
  1255.         out->vrefresh = in->vrefresh;
  1256.         out->flags = in->flags;
  1257.         out->type = in->type;
  1258.         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
  1259.         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
  1260. }
  1261.  
  1262. /**
  1263.  * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
  1264.  * @out: drm_display_mode to return to the user
  1265.  * @in: drm_mode_modeinfo to use
  1266.  *
  1267.  * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
  1268.  * the caller.
  1269.  *
  1270.  * RETURNS:
  1271.  * Zero on success, errno on failure.
  1272.  */
  1273. static int drm_crtc_convert_umode(struct drm_display_mode *out,
  1274.                                   const struct drm_mode_modeinfo *in)
  1275. {
  1276.         if (in->clock > INT_MAX || in->vrefresh > INT_MAX)
  1277.                 return -ERANGE;
  1278.  
  1279.         out->clock = in->clock;
  1280.         out->hdisplay = in->hdisplay;
  1281.         out->hsync_start = in->hsync_start;
  1282.         out->hsync_end = in->hsync_end;
  1283.         out->htotal = in->htotal;
  1284.         out->hskew = in->hskew;
  1285.         out->vdisplay = in->vdisplay;
  1286.         out->vsync_start = in->vsync_start;
  1287.         out->vsync_end = in->vsync_end;
  1288.         out->vtotal = in->vtotal;
  1289.         out->vscan = in->vscan;
  1290.         out->vrefresh = in->vrefresh;
  1291.         out->flags = in->flags;
  1292.         out->type = in->type;
  1293.         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
  1294.         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
  1295.  
  1296.         return 0;
  1297. }
  1298.  
  1299.  
  1300. #if 0
  1301. /**
  1302.  * drm_mode_getresources - get graphics configuration
  1303.  * @dev: drm device for the ioctl
  1304.  * @data: data pointer for the ioctl
  1305.  * @file_priv: drm file for the ioctl call
  1306.  *
  1307.  * Construct a set of configuration description structures and return
  1308.  * them to the user, including CRTC, connector and framebuffer configuration.
  1309.  *
  1310.  * Called by the user via ioctl.
  1311.  *
  1312.  * RETURNS:
  1313.  * Zero on success, errno on failure.
  1314.  */
  1315. int drm_mode_getresources(struct drm_device *dev, void *data,
  1316.                           struct drm_file *file_priv)
  1317. {
  1318.         struct drm_mode_card_res *card_res = data;
  1319.         struct list_head *lh;
  1320.         struct drm_framebuffer *fb;
  1321.         struct drm_connector *connector;
  1322.         struct drm_crtc *crtc;
  1323.         struct drm_encoder *encoder;
  1324.         int ret = 0;
  1325.         int connector_count = 0;
  1326.         int crtc_count = 0;
  1327.         int fb_count = 0;
  1328.         int encoder_count = 0;
  1329.         int copied = 0, i;
  1330.         uint32_t __user *fb_id;
  1331.         uint32_t __user *crtc_id;
  1332.         uint32_t __user *connector_id;
  1333.         uint32_t __user *encoder_id;
  1334.         struct drm_mode_group *mode_group;
  1335.  
  1336.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1337.                 return -EINVAL;
  1338.  
  1339.  
  1340.         mutex_lock(&file_priv->fbs_lock);
  1341.         /*
  1342.          * For the non-control nodes we need to limit the list of resources
  1343.          * by IDs in the group list for this node
  1344.          */
  1345.         list_for_each(lh, &file_priv->fbs)
  1346.                 fb_count++;
  1347.  
  1348.         /* handle this in 4 parts */
  1349.         /* FBs */
  1350.         if (card_res->count_fbs >= fb_count) {
  1351.                 copied = 0;
  1352.                 fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
  1353.                 list_for_each_entry(fb, &file_priv->fbs, filp_head) {
  1354.                         if (put_user(fb->base.id, fb_id + copied)) {
  1355.                                 mutex_unlock(&file_priv->fbs_lock);
  1356.                                 return -EFAULT;
  1357.                         }
  1358.                         copied++;
  1359.                 }
  1360.         }
  1361.         card_res->count_fbs = fb_count;
  1362.         mutex_unlock(&file_priv->fbs_lock);
  1363.  
  1364.         drm_modeset_lock_all(dev);
  1365.         mode_group = &file_priv->master->minor->mode_group;
  1366.         if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
  1367.  
  1368.                 list_for_each(lh, &dev->mode_config.crtc_list)
  1369.                         crtc_count++;
  1370.  
  1371.                 list_for_each(lh, &dev->mode_config.connector_list)
  1372.                         connector_count++;
  1373.  
  1374.                 list_for_each(lh, &dev->mode_config.encoder_list)
  1375.                         encoder_count++;
  1376.         } else {
  1377.  
  1378.                 crtc_count = mode_group->num_crtcs;
  1379.                 connector_count = mode_group->num_connectors;
  1380.                 encoder_count = mode_group->num_encoders;
  1381.         }
  1382.  
  1383.         card_res->max_height = dev->mode_config.max_height;
  1384.         card_res->min_height = dev->mode_config.min_height;
  1385.         card_res->max_width = dev->mode_config.max_width;
  1386.         card_res->min_width = dev->mode_config.min_width;
  1387.  
  1388.         /* CRTCs */
  1389.         if (card_res->count_crtcs >= crtc_count) {
  1390.                 copied = 0;
  1391.                 crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
  1392.                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
  1393.                         list_for_each_entry(crtc, &dev->mode_config.crtc_list,
  1394.                                             head) {
  1395.                                 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
  1396.                                 if (put_user(crtc->base.id, crtc_id + copied)) {
  1397.                                         ret = -EFAULT;
  1398.                                         goto out;
  1399.                                 }
  1400.                                 copied++;
  1401.                         }
  1402.                 } else {
  1403.                         for (i = 0; i < mode_group->num_crtcs; i++) {
  1404.                                 if (put_user(mode_group->id_list[i],
  1405.                                              crtc_id + copied)) {
  1406.                                         ret = -EFAULT;
  1407.                                         goto out;
  1408.                                 }
  1409.                                 copied++;
  1410.                         }
  1411.                 }
  1412.         }
  1413.         card_res->count_crtcs = crtc_count;
  1414.  
  1415.         /* Encoders */
  1416.         if (card_res->count_encoders >= encoder_count) {
  1417.                 copied = 0;
  1418.                 encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
  1419.                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
  1420.                         list_for_each_entry(encoder,
  1421.                                             &dev->mode_config.encoder_list,
  1422.                                             head) {
  1423.                                 DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", encoder->base.id,
  1424.                                                 drm_get_encoder_name(encoder));
  1425.                                 if (put_user(encoder->base.id, encoder_id +
  1426.                                              copied)) {
  1427.                                         ret = -EFAULT;
  1428.                                         goto out;
  1429.                                 }
  1430.                                 copied++;
  1431.                         }
  1432.                 } else {
  1433.                         for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) {
  1434.                                 if (put_user(mode_group->id_list[i],
  1435.                                              encoder_id + copied)) {
  1436.                                         ret = -EFAULT;
  1437.                                         goto out;
  1438.                                 }
  1439.                                 copied++;
  1440.                         }
  1441.  
  1442.                 }
  1443.         }
  1444.         card_res->count_encoders = encoder_count;
  1445.  
  1446.         /* Connectors */
  1447.         if (card_res->count_connectors >= connector_count) {
  1448.                 copied = 0;
  1449.                 connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
  1450.                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
  1451.                         list_for_each_entry(connector,
  1452.                                             &dev->mode_config.connector_list,
  1453.                                             head) {
  1454.                                 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
  1455.                                         connector->base.id,
  1456.                                         drm_get_connector_name(connector));
  1457.                                 if (put_user(connector->base.id,
  1458.                                              connector_id + copied)) {
  1459.                                         ret = -EFAULT;
  1460.                                         goto out;
  1461.                                 }
  1462.                                 copied++;
  1463.                         }
  1464.                 } else {
  1465.                         int start = mode_group->num_crtcs +
  1466.                                 mode_group->num_encoders;
  1467.                         for (i = start; i < start + mode_group->num_connectors; i++) {
  1468.                                 if (put_user(mode_group->id_list[i],
  1469.                                              connector_id + copied)) {
  1470.                                         ret = -EFAULT;
  1471.                                         goto out;
  1472.                                 }
  1473.                                 copied++;
  1474.                         }
  1475.                 }
  1476.         }
  1477.         card_res->count_connectors = connector_count;
  1478.  
  1479.         DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs,
  1480.                   card_res->count_connectors, card_res->count_encoders);
  1481.  
  1482. out:
  1483.         drm_modeset_unlock_all(dev);
  1484.         return ret;
  1485. }
  1486.  
  1487. /**
  1488.  * drm_mode_getcrtc - get CRTC configuration
  1489.  * @dev: drm device for the ioctl
  1490.  * @data: data pointer for the ioctl
  1491.  * @file_priv: drm file for the ioctl call
  1492.  *
  1493.  * Construct a CRTC configuration structure to return to the user.
  1494.  *
  1495.  * Called by the user via ioctl.
  1496.  *
  1497.  * RETURNS:
  1498.  * Zero on success, errno on failure.
  1499.  */
  1500. int drm_mode_getcrtc(struct drm_device *dev,
  1501.                      void *data, struct drm_file *file_priv)
  1502. {
  1503.         struct drm_mode_crtc *crtc_resp = data;
  1504.         struct drm_crtc *crtc;
  1505.         struct drm_mode_object *obj;
  1506.         int ret = 0;
  1507.  
  1508.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1509.                 return -EINVAL;
  1510.  
  1511.         drm_modeset_lock_all(dev);
  1512.  
  1513.         obj = drm_mode_object_find(dev, crtc_resp->crtc_id,
  1514.                                    DRM_MODE_OBJECT_CRTC);
  1515.         if (!obj) {
  1516.                 ret = -EINVAL;
  1517.                 goto out;
  1518.         }
  1519.         crtc = obj_to_crtc(obj);
  1520.  
  1521.         crtc_resp->x = crtc->x;
  1522.         crtc_resp->y = crtc->y;
  1523.         crtc_resp->gamma_size = crtc->gamma_size;
  1524.         if (crtc->fb)
  1525.                 crtc_resp->fb_id = crtc->fb->base.id;
  1526.         else
  1527.                 crtc_resp->fb_id = 0;
  1528.  
  1529.         if (crtc->enabled) {
  1530.  
  1531.                 drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode);
  1532.                 crtc_resp->mode_valid = 1;
  1533.  
  1534.         } else {
  1535.                 crtc_resp->mode_valid = 0;
  1536.         }
  1537.  
  1538. out:
  1539.         drm_modeset_unlock_all(dev);
  1540.         return ret;
  1541. }
  1542.  
  1543. /**
  1544.  * drm_mode_getconnector - get connector configuration
  1545.  * @dev: drm device for the ioctl
  1546.  * @data: data pointer for the ioctl
  1547.  * @file_priv: drm file for the ioctl call
  1548.  *
  1549.  * Construct a connector configuration structure to return to the user.
  1550.  *
  1551.  * Called by the user via ioctl.
  1552.  *
  1553.  * RETURNS:
  1554.  * Zero on success, errno on failure.
  1555.  */
  1556. int drm_mode_getconnector(struct drm_device *dev, void *data,
  1557.                           struct drm_file *file_priv)
  1558. {
  1559.         struct drm_mode_get_connector *out_resp = data;
  1560.         struct drm_mode_object *obj;
  1561.         struct drm_connector *connector;
  1562.         struct drm_display_mode *mode;
  1563.         int mode_count = 0;
  1564.         int props_count = 0;
  1565.         int encoders_count = 0;
  1566.         int ret = 0;
  1567.         int copied = 0;
  1568.         int i;
  1569.         struct drm_mode_modeinfo u_mode;
  1570.         struct drm_mode_modeinfo __user *mode_ptr;
  1571.         uint32_t __user *prop_ptr;
  1572.         uint64_t __user *prop_values;
  1573.         uint32_t __user *encoder_ptr;
  1574.  
  1575.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1576.                 return -EINVAL;
  1577.  
  1578.         memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
  1579.  
  1580.         DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
  1581.  
  1582.         mutex_lock(&dev->mode_config.mutex);
  1583.  
  1584.         obj = drm_mode_object_find(dev, out_resp->connector_id,
  1585.                                    DRM_MODE_OBJECT_CONNECTOR);
  1586.         if (!obj) {
  1587.                 ret = -EINVAL;
  1588.                 goto out;
  1589.         }
  1590.         connector = obj_to_connector(obj);
  1591.  
  1592.         props_count = connector->properties.count;
  1593.  
  1594.         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
  1595.                 if (connector->encoder_ids[i] != 0) {
  1596.                         encoders_count++;
  1597.                 }
  1598.         }
  1599.  
  1600.         if (out_resp->count_modes == 0) {
  1601.                 connector->funcs->fill_modes(connector,
  1602.                                              dev->mode_config.max_width,
  1603.                                              dev->mode_config.max_height);
  1604.         }
  1605.  
  1606.         /* delayed so we get modes regardless of pre-fill_modes state */
  1607.         list_for_each_entry(mode, &connector->modes, head)
  1608.                 mode_count++;
  1609.  
  1610.         out_resp->connector_id = connector->base.id;
  1611.         out_resp->connector_type = connector->connector_type;
  1612.         out_resp->connector_type_id = connector->connector_type_id;
  1613.         out_resp->mm_width = connector->display_info.width_mm;
  1614.         out_resp->mm_height = connector->display_info.height_mm;
  1615.         out_resp->subpixel = connector->display_info.subpixel_order;
  1616.         out_resp->connection = connector->status;
  1617.         if (connector->encoder)
  1618.                 out_resp->encoder_id = connector->encoder->base.id;
  1619.         else
  1620.                 out_resp->encoder_id = 0;
  1621.  
  1622.         /*
  1623.          * This ioctl is called twice, once to determine how much space is
  1624.          * needed, and the 2nd time to fill it.
  1625.          */
  1626.         if ((out_resp->count_modes >= mode_count) && mode_count) {
  1627.                 copied = 0;
  1628.                 mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr;
  1629.                 list_for_each_entry(mode, &connector->modes, head) {
  1630.                         drm_crtc_convert_to_umode(&u_mode, mode);
  1631.                         if (copy_to_user(mode_ptr + copied,
  1632.                                          &u_mode, sizeof(u_mode))) {
  1633.                                 ret = -EFAULT;
  1634.                                 goto out;
  1635.                         }
  1636.                         copied++;
  1637.                 }
  1638.         }
  1639.         out_resp->count_modes = mode_count;
  1640.  
  1641.         if ((out_resp->count_props >= props_count) && props_count) {
  1642.                 copied = 0;
  1643.                 prop_ptr = (uint32_t __user *)(unsigned long)(out_resp->props_ptr);
  1644.                 prop_values = (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr);
  1645.                 for (i = 0; i < connector->properties.count; i++) {
  1646.                         if (put_user(connector->properties.ids[i],
  1647.                                              prop_ptr + copied)) {
  1648.                                         ret = -EFAULT;
  1649.                                         goto out;
  1650.                                 }
  1651.  
  1652.                         if (put_user(connector->properties.values[i],
  1653.                                              prop_values + copied)) {
  1654.                                         ret = -EFAULT;
  1655.                                         goto out;
  1656.                                 }
  1657.                                 copied++;
  1658.                         }
  1659.                 }
  1660.         out_resp->count_props = props_count;
  1661.  
  1662.         if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
  1663.                 copied = 0;
  1664.                 encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
  1665.                 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
  1666.                         if (connector->encoder_ids[i] != 0) {
  1667.                                 if (put_user(connector->encoder_ids[i],
  1668.                                              encoder_ptr + copied)) {
  1669.                                         ret = -EFAULT;
  1670.                                         goto out;
  1671.                                 }
  1672.                                 copied++;
  1673.                         }
  1674.                 }
  1675.         }
  1676.         out_resp->count_encoders = encoders_count;
  1677.  
  1678. out:
  1679.         mutex_unlock(&dev->mode_config.mutex);
  1680.  
  1681.         return ret;
  1682. }
  1683.  
  1684. int drm_mode_getencoder(struct drm_device *dev, void *data,
  1685.                         struct drm_file *file_priv)
  1686. {
  1687.         struct drm_mode_get_encoder *enc_resp = data;
  1688.         struct drm_mode_object *obj;
  1689.         struct drm_encoder *encoder;
  1690.         int ret = 0;
  1691.  
  1692.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1693.                 return -EINVAL;
  1694.  
  1695.         drm_modeset_lock_all(dev);
  1696.         obj = drm_mode_object_find(dev, enc_resp->encoder_id,
  1697.                                    DRM_MODE_OBJECT_ENCODER);
  1698.         if (!obj) {
  1699.                 ret = -EINVAL;
  1700.                 goto out;
  1701.         }
  1702.         encoder = obj_to_encoder(obj);
  1703.  
  1704.         if (encoder->crtc)
  1705.                 enc_resp->crtc_id = encoder->crtc->base.id;
  1706.         else
  1707.                 enc_resp->crtc_id = 0;
  1708.         enc_resp->encoder_type = encoder->encoder_type;
  1709.         enc_resp->encoder_id = encoder->base.id;
  1710.         enc_resp->possible_crtcs = encoder->possible_crtcs;
  1711.         enc_resp->possible_clones = encoder->possible_clones;
  1712.  
  1713. out:
  1714.         drm_modeset_unlock_all(dev);
  1715.         return ret;
  1716. }
  1717.  
  1718. /**
  1719.  * drm_mode_getplane_res - get plane info
  1720.  * @dev: DRM device
  1721.  * @data: ioctl data
  1722.  * @file_priv: DRM file info
  1723.  *
  1724.  * Return an plane count and set of IDs.
  1725.  */
  1726. int drm_mode_getplane_res(struct drm_device *dev, void *data,
  1727.                             struct drm_file *file_priv)
  1728. {
  1729.         struct drm_mode_get_plane_res *plane_resp = data;
  1730.         struct drm_mode_config *config;
  1731.         struct drm_plane *plane;
  1732.         uint32_t __user *plane_ptr;
  1733.         int copied = 0, ret = 0;
  1734.  
  1735.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1736.                 return -EINVAL;
  1737.  
  1738.         drm_modeset_lock_all(dev);
  1739.         config = &dev->mode_config;
  1740.  
  1741.         /*
  1742.          * This ioctl is called twice, once to determine how much space is
  1743.          * needed, and the 2nd time to fill it.
  1744.          */
  1745.         if (config->num_plane &&
  1746.             (plane_resp->count_planes >= config->num_plane)) {
  1747.                 plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;
  1748.  
  1749.                 list_for_each_entry(plane, &config->plane_list, head) {
  1750.                         if (put_user(plane->base.id, plane_ptr + copied)) {
  1751.                                 ret = -EFAULT;
  1752.                                 goto out;
  1753.                         }
  1754.                         copied++;
  1755.                 }
  1756.         }
  1757.         plane_resp->count_planes = config->num_plane;
  1758.  
  1759. out:
  1760.         drm_modeset_unlock_all(dev);
  1761.         return ret;
  1762. }
  1763.  
  1764. /**
  1765.  * drm_mode_getplane - get plane info
  1766.  * @dev: DRM device
  1767.  * @data: ioctl data
  1768.  * @file_priv: DRM file info
  1769.  *
  1770.  * Return plane info, including formats supported, gamma size, any
  1771.  * current fb, etc.
  1772.  */
  1773. int drm_mode_getplane(struct drm_device *dev, void *data,
  1774.                         struct drm_file *file_priv)
  1775. {
  1776.         struct drm_mode_get_plane *plane_resp = data;
  1777.         struct drm_mode_object *obj;
  1778.         struct drm_plane *plane;
  1779.         uint32_t __user *format_ptr;
  1780.         int ret = 0;
  1781.  
  1782.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1783.                 return -EINVAL;
  1784.  
  1785.         drm_modeset_lock_all(dev);
  1786.         obj = drm_mode_object_find(dev, plane_resp->plane_id,
  1787.                                    DRM_MODE_OBJECT_PLANE);
  1788.         if (!obj) {
  1789.                 ret = -ENOENT;
  1790.                 goto out;
  1791.         }
  1792.         plane = obj_to_plane(obj);
  1793.  
  1794.         if (plane->crtc)
  1795.                 plane_resp->crtc_id = plane->crtc->base.id;
  1796.         else
  1797.                 plane_resp->crtc_id = 0;
  1798.  
  1799.         if (plane->fb)
  1800.                 plane_resp->fb_id = plane->fb->base.id;
  1801.         else
  1802.                 plane_resp->fb_id = 0;
  1803.  
  1804.         plane_resp->plane_id = plane->base.id;
  1805.         plane_resp->possible_crtcs = plane->possible_crtcs;
  1806.         plane_resp->gamma_size = 0;
  1807.  
  1808.         /*
  1809.          * This ioctl is called twice, once to determine how much space is
  1810.          * needed, and the 2nd time to fill it.
  1811.          */
  1812.         if (plane->format_count &&
  1813.             (plane_resp->count_format_types >= plane->format_count)) {
  1814.                 format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr;
  1815.                 if (copy_to_user(format_ptr,
  1816.                                  plane->format_types,
  1817.                                  sizeof(uint32_t) * plane->format_count)) {
  1818.                         ret = -EFAULT;
  1819.                         goto out;
  1820.                 }
  1821.         }
  1822.         plane_resp->count_format_types = plane->format_count;
  1823.  
  1824. out:
  1825.         drm_modeset_unlock_all(dev);
  1826.         return ret;
  1827. }
  1828.  
  1829. /**
  1830.  * drm_mode_setplane - set up or tear down an plane
  1831.  * @dev: DRM device
  1832.  * @data: ioctl data*
  1833.  * @file_priv: DRM file info
  1834.  *
  1835.  * Set plane info, including placement, fb, scaling, and other factors.
  1836.  * Or pass a NULL fb to disable.
  1837.  */
  1838. int drm_mode_setplane(struct drm_device *dev, void *data,
  1839.                         struct drm_file *file_priv)
  1840. {
  1841.         struct drm_mode_set_plane *plane_req = data;
  1842.         struct drm_mode_object *obj;
  1843.         struct drm_plane *plane;
  1844.         struct drm_crtc *crtc;
  1845.         struct drm_framebuffer *fb = NULL, *old_fb = NULL;
  1846.         int ret = 0;
  1847.         unsigned int fb_width, fb_height;
  1848.         int i;
  1849.  
  1850.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1851.                 return -EINVAL;
  1852.  
  1853.         /*
  1854.          * First, find the plane, crtc, and fb objects.  If not available,
  1855.          * we don't bother to call the driver.
  1856.          */
  1857.         obj = drm_mode_object_find(dev, plane_req->plane_id,
  1858.                                    DRM_MODE_OBJECT_PLANE);
  1859.         if (!obj) {
  1860.                 DRM_DEBUG_KMS("Unknown plane ID %d\n",
  1861.                               plane_req->plane_id);
  1862.                 return -ENOENT;
  1863.         }
  1864.         plane = obj_to_plane(obj);
  1865.  
  1866.         /* No fb means shut it down */
  1867.         if (!plane_req->fb_id) {
  1868.                 drm_modeset_lock_all(dev);
  1869.                 old_fb = plane->fb;
  1870.                 plane->funcs->disable_plane(plane);
  1871.                 plane->crtc = NULL;
  1872.                 plane->fb = NULL;
  1873.                 drm_modeset_unlock_all(dev);
  1874.                 goto out;
  1875.         }
  1876.  
  1877.         obj = drm_mode_object_find(dev, plane_req->crtc_id,
  1878.                                    DRM_MODE_OBJECT_CRTC);
  1879.         if (!obj) {
  1880.                 DRM_DEBUG_KMS("Unknown crtc ID %d\n",
  1881.                               plane_req->crtc_id);
  1882.                 ret = -ENOENT;
  1883.                 goto out;
  1884.         }
  1885.         crtc = obj_to_crtc(obj);
  1886.  
  1887.         fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
  1888.         if (!fb) {
  1889.                 DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
  1890.                               plane_req->fb_id);
  1891.                 ret = -ENOENT;
  1892.                 goto out;
  1893.         }
  1894.  
  1895.         /* Check whether this plane supports the fb pixel format. */
  1896.         for (i = 0; i < plane->format_count; i++)
  1897.                 if (fb->pixel_format == plane->format_types[i])
  1898.                         break;
  1899.         if (i == plane->format_count) {
  1900.                 DRM_DEBUG_KMS("Invalid pixel format %s\n",
  1901.                               drm_get_format_name(fb->pixel_format));
  1902.                 ret = -EINVAL;
  1903.                 goto out;
  1904.         }
  1905.  
  1906.         fb_width = fb->width << 16;
  1907.         fb_height = fb->height << 16;
  1908.  
  1909.         /* Make sure source coordinates are inside the fb. */
  1910.         if (plane_req->src_w > fb_width ||
  1911.             plane_req->src_x > fb_width - plane_req->src_w ||
  1912.             plane_req->src_h > fb_height ||
  1913.             plane_req->src_y > fb_height - plane_req->src_h) {
  1914.                 DRM_DEBUG_KMS("Invalid source coordinates "
  1915.                               "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
  1916.                               plane_req->src_w >> 16,
  1917.                               ((plane_req->src_w & 0xffff) * 15625) >> 10,
  1918.                               plane_req->src_h >> 16,
  1919.                               ((plane_req->src_h & 0xffff) * 15625) >> 10,
  1920.                               plane_req->src_x >> 16,
  1921.                               ((plane_req->src_x & 0xffff) * 15625) >> 10,
  1922.                               plane_req->src_y >> 16,
  1923.                               ((plane_req->src_y & 0xffff) * 15625) >> 10);
  1924.                 ret = -ENOSPC;
  1925.                 goto out;
  1926.         }
  1927.  
  1928.         /* Give drivers some help against integer overflows */
  1929.         if (plane_req->crtc_w > INT_MAX ||
  1930.             plane_req->crtc_x > INT_MAX - (int32_t) plane_req->crtc_w ||
  1931.             plane_req->crtc_h > INT_MAX ||
  1932.             plane_req->crtc_y > INT_MAX - (int32_t) plane_req->crtc_h) {
  1933.                 DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
  1934.                               plane_req->crtc_w, plane_req->crtc_h,
  1935.                               plane_req->crtc_x, plane_req->crtc_y);
  1936.                 ret = -ERANGE;
  1937.                 goto out;
  1938.         }
  1939.  
  1940.         drm_modeset_lock_all(dev);
  1941.         ret = plane->funcs->update_plane(plane, crtc, fb,
  1942.                                          plane_req->crtc_x, plane_req->crtc_y,
  1943.                                          plane_req->crtc_w, plane_req->crtc_h,
  1944.                                          plane_req->src_x, plane_req->src_y,
  1945.                                          plane_req->src_w, plane_req->src_h);
  1946.         if (!ret) {
  1947.                 old_fb = plane->fb;
  1948.                 plane->crtc = crtc;
  1949.                 plane->fb = fb;
  1950.                 fb = NULL;
  1951.         }
  1952.         drm_modeset_unlock_all(dev);
  1953.  
  1954. out:
  1955.         if (fb)
  1956.                 drm_framebuffer_unreference(fb);
  1957.         if (old_fb)
  1958.                 drm_framebuffer_unreference(old_fb);
  1959.  
  1960.         return ret;
  1961. }
  1962. #endif
  1963.  
  1964. /**
  1965.  * drm_mode_set_config_internal - helper to call ->set_config
  1966.  * @set: modeset config to set
  1967.  *
  1968.  * This is a little helper to wrap internal calls to the ->set_config driver
  1969.  * interface. The only thing it adds is correct refcounting dance.
  1970.  */
  1971. int drm_mode_set_config_internal(struct drm_mode_set *set)
  1972. {
  1973.         struct drm_crtc *crtc = set->crtc;
  1974.         struct drm_framebuffer *fb;
  1975.         struct drm_crtc *tmp;
  1976.         int ret;
  1977.  
  1978.         /*
  1979.          * NOTE: ->set_config can also disable other crtcs (if we steal all
  1980.          * connectors from it), hence we need to refcount the fbs across all
  1981.          * crtcs. Atomic modeset will have saner semantics ...
  1982.          */
  1983.         list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head)
  1984.                 tmp->old_fb = tmp->fb;
  1985.  
  1986.         fb = set->fb;
  1987.  
  1988.         ret = crtc->funcs->set_config(set);
  1989.         if (ret == 0) {
  1990.                 /* crtc->fb must be updated by ->set_config, enforces this. */
  1991.                 WARN_ON(fb != crtc->fb);
  1992.         }
  1993.  
  1994.         list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) {
  1995.                 if (tmp->fb)
  1996.                         drm_framebuffer_reference(tmp->fb);
  1997. //              if (tmp->old_fb)
  1998. //                      drm_framebuffer_unreference(tmp->old_fb);
  1999.         }
  2000.  
  2001.         return ret;
  2002. }
  2003. EXPORT_SYMBOL(drm_mode_set_config_internal);
  2004.  
  2005. #if 0
  2006. /**
  2007.  * drm_mode_setcrtc - set CRTC configuration
  2008.  * @dev: drm device for the ioctl
  2009.  * @data: data pointer for the ioctl
  2010.  * @file_priv: drm file for the ioctl call
  2011.  *
  2012.  * Build a new CRTC configuration based on user request.
  2013.  *
  2014.  * Called by the user via ioctl.
  2015.  *
  2016.  * RETURNS:
  2017.  * Zero on success, errno on failure.
  2018.  */
  2019. int drm_mode_setcrtc(struct drm_device *dev, void *data,
  2020.                      struct drm_file *file_priv)
  2021. {
  2022.         struct drm_mode_config *config = &dev->mode_config;
  2023.         struct drm_mode_crtc *crtc_req = data;
  2024.         struct drm_mode_object *obj;
  2025.         struct drm_crtc *crtc;
  2026.         struct drm_connector **connector_set = NULL, *connector;
  2027.         struct drm_framebuffer *fb = NULL;
  2028.         struct drm_display_mode *mode = NULL;
  2029.         struct drm_mode_set set;
  2030.         uint32_t __user *set_connectors_ptr;
  2031.         int ret;
  2032.         int i;
  2033.  
  2034.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  2035.                 return -EINVAL;
  2036.  
  2037.         /* For some reason crtc x/y offsets are signed internally. */
  2038.         if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX)
  2039.                 return -ERANGE;
  2040.  
  2041.         drm_modeset_lock_all(dev);
  2042.         obj = drm_mode_object_find(dev, crtc_req->crtc_id,
  2043.                                    DRM_MODE_OBJECT_CRTC);
  2044.         if (!obj) {
  2045.                 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
  2046.                 ret = -EINVAL;
  2047.                 goto out;
  2048.         }
  2049.         crtc = obj_to_crtc(obj);
  2050.         DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
  2051.  
  2052.         if (crtc_req->mode_valid) {
  2053.                 int hdisplay, vdisplay;
  2054.                 /* If we have a mode we need a framebuffer. */
  2055.                 /* If we pass -1, set the mode with the currently bound fb */
  2056.                 if (crtc_req->fb_id == -1) {
  2057.                         if (!crtc->fb) {
  2058.                                 DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
  2059.                                 ret = -EINVAL;
  2060.                                 goto out;
  2061.                         }
  2062.                                         fb = crtc->fb;
  2063.                         /* Make refcounting symmetric with the lookup path. */
  2064.                         drm_framebuffer_reference(fb);
  2065.                 } else {
  2066.                         fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
  2067.                         if (!fb) {
  2068.                                 DRM_DEBUG_KMS("Unknown FB ID%d\n",
  2069.                                                 crtc_req->fb_id);
  2070.                                 ret = -EINVAL;
  2071.                                 goto out;
  2072.                         }
  2073.                 }
  2074.  
  2075.                 mode = drm_mode_create(dev);
  2076.                 if (!mode) {
  2077.                         ret = -ENOMEM;
  2078.                         goto out;
  2079.                 }
  2080.  
  2081.                 ret = drm_crtc_convert_umode(mode, &crtc_req->mode);
  2082.                 if (ret) {
  2083.                         DRM_DEBUG_KMS("Invalid mode\n");
  2084.                         goto out;
  2085.                 }
  2086.  
  2087.                 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
  2088.  
  2089.                 hdisplay = mode->hdisplay;
  2090.                 vdisplay = mode->vdisplay;
  2091.  
  2092.                 if (crtc->invert_dimensions)
  2093.                         swap(hdisplay, vdisplay);
  2094.  
  2095.                 if (hdisplay > fb->width ||
  2096.                     vdisplay > fb->height ||
  2097.                     crtc_req->x > fb->width - hdisplay ||
  2098.                     crtc_req->y > fb->height - vdisplay) {
  2099.                         DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
  2100.                                       fb->width, fb->height,
  2101.                                       hdisplay, vdisplay, crtc_req->x, crtc_req->y,
  2102.                                       crtc->invert_dimensions ? " (inverted)" : "");
  2103.                         ret = -ENOSPC;
  2104.                         goto out;
  2105.                 }
  2106.         }
  2107.  
  2108.         if (crtc_req->count_connectors == 0 && mode) {
  2109.                 DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
  2110.                 ret = -EINVAL;
  2111.                 goto out;
  2112.         }
  2113.  
  2114.         if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
  2115.                 DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
  2116.                           crtc_req->count_connectors);
  2117.                 ret = -EINVAL;
  2118.                 goto out;
  2119.         }
  2120.  
  2121.         if (crtc_req->count_connectors > 0) {
  2122.                 u32 out_id;
  2123.  
  2124.                 /* Avoid unbounded kernel memory allocation */
  2125.                 if (crtc_req->count_connectors > config->num_connector) {
  2126.                         ret = -EINVAL;
  2127.                         goto out;
  2128.                 }
  2129.  
  2130.                 connector_set = kmalloc(crtc_req->count_connectors *
  2131.                                         sizeof(struct drm_connector *),
  2132.                                         GFP_KERNEL);
  2133.                 if (!connector_set) {
  2134.                         ret = -ENOMEM;
  2135.                         goto out;
  2136.                 }
  2137.  
  2138.                 for (i = 0; i < crtc_req->count_connectors; i++) {
  2139.                         set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
  2140.                         if (get_user(out_id, &set_connectors_ptr[i])) {
  2141.                                 ret = -EFAULT;
  2142.                                 goto out;
  2143.                         }
  2144.  
  2145.                         obj = drm_mode_object_find(dev, out_id,
  2146.                                                    DRM_MODE_OBJECT_CONNECTOR);
  2147.                         if (!obj) {
  2148.                                 DRM_DEBUG_KMS("Connector id %d unknown\n",
  2149.                                                 out_id);
  2150.                                 ret = -EINVAL;
  2151.                                 goto out;
  2152.                         }
  2153.                         connector = obj_to_connector(obj);
  2154.                         DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
  2155.                                         connector->base.id,
  2156.                                         drm_get_connector_name(connector));
  2157.  
  2158.                         connector_set[i] = connector;
  2159.                 }
  2160.         }
  2161.  
  2162.         set.crtc = crtc;
  2163.         set.x = crtc_req->x;
  2164.         set.y = crtc_req->y;
  2165.         set.mode = mode;
  2166.         set.connectors = connector_set;
  2167.         set.num_connectors = crtc_req->count_connectors;
  2168.         set.fb = fb;
  2169.         ret = drm_mode_set_config_internal(&set);
  2170.  
  2171. out:
  2172.         if (fb)
  2173.                 drm_framebuffer_unreference(fb);
  2174.  
  2175.         kfree(connector_set);
  2176.         drm_mode_destroy(dev, mode);
  2177.         drm_modeset_unlock_all(dev);
  2178.         return ret;
  2179. }
  2180.  
  2181. static int drm_mode_cursor_common(struct drm_device *dev,
  2182.                                   struct drm_mode_cursor2 *req,
  2183.                                   struct drm_file *file_priv)
  2184. {
  2185.         struct drm_mode_object *obj;
  2186.         struct drm_crtc *crtc;
  2187.         int ret = 0;
  2188.  
  2189.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  2190.                 return -EINVAL;
  2191.  
  2192.         if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
  2193.                 return -EINVAL;
  2194.  
  2195.         obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
  2196.         if (!obj) {
  2197.                 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
  2198.                 return -EINVAL;
  2199.         }
  2200.         crtc = obj_to_crtc(obj);
  2201.  
  2202.         mutex_lock(&crtc->mutex);
  2203.         if (req->flags & DRM_MODE_CURSOR_BO) {
  2204.                 if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) {
  2205.                         ret = -ENXIO;
  2206.                         goto out;
  2207.                 }
  2208.                 /* Turns off the cursor if handle is 0 */
  2209.                 if (crtc->funcs->cursor_set2)
  2210.                         ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle,
  2211.                                                       req->width, req->height, req->hot_x, req->hot_y);
  2212.                 else
  2213.                 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
  2214.                                               req->width, req->height);
  2215.         }
  2216.  
  2217.         if (req->flags & DRM_MODE_CURSOR_MOVE) {
  2218.                 if (crtc->funcs->cursor_move) {
  2219.                         ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
  2220.                 } else {
  2221.                         ret = -EFAULT;
  2222.                         goto out;
  2223.                 }
  2224.         }
  2225. out:
  2226.         mutex_unlock(&crtc->mutex);
  2227.  
  2228.         return ret;
  2229.  
  2230. }
  2231. int drm_mode_cursor_ioctl(struct drm_device *dev,
  2232.                         void *data, struct drm_file *file_priv)
  2233. {
  2234.         struct drm_mode_cursor *req = data;
  2235.         struct drm_mode_cursor2 new_req;
  2236.  
  2237.         memcpy(&new_req, req, sizeof(struct drm_mode_cursor));
  2238.         new_req.hot_x = new_req.hot_y = 0;
  2239.  
  2240.         return drm_mode_cursor_common(dev, &new_req, file_priv);
  2241. }
  2242.  
  2243. int drm_mode_cursor2_ioctl(struct drm_device *dev,
  2244.                            void *data, struct drm_file *file_priv)
  2245. {
  2246.         struct drm_mode_cursor2 *req = data;
  2247.         return drm_mode_cursor_common(dev, req, file_priv);
  2248. }
  2249. #endif
  2250. /* Original addfb only supported RGB formats, so figure out which one */
  2251. uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
  2252. {
  2253.         uint32_t fmt;
  2254.  
  2255.         switch (bpp) {
  2256.         case 8:
  2257.                 fmt = DRM_FORMAT_C8;
  2258.                 break;
  2259.         case 16:
  2260.                 if (depth == 15)
  2261.                         fmt = DRM_FORMAT_XRGB1555;
  2262.                 else
  2263.                         fmt = DRM_FORMAT_RGB565;
  2264.                 break;
  2265.         case 24:
  2266.                 fmt = DRM_FORMAT_RGB888;
  2267.                 break;
  2268.         case 32:
  2269.                 if (depth == 24)
  2270.                         fmt = DRM_FORMAT_XRGB8888;
  2271.                 else if (depth == 30)
  2272.                         fmt = DRM_FORMAT_XRGB2101010;
  2273.                 else
  2274.                         fmt = DRM_FORMAT_ARGB8888;
  2275.                 break;
  2276.         default:
  2277.                 DRM_ERROR("bad bpp, assuming x8r8g8b8 pixel format\n");
  2278.                 fmt = DRM_FORMAT_XRGB8888;
  2279.                 break;
  2280.         }
  2281.  
  2282.         return fmt;
  2283. }
  2284. EXPORT_SYMBOL(drm_mode_legacy_fb_format);
  2285. #if 0
  2286. /**
  2287.  * drm_mode_addfb - add an FB to the graphics configuration
  2288.  * @dev: drm device for the ioctl
  2289.  * @data: data pointer for the ioctl
  2290.  * @file_priv: drm file for the ioctl call
  2291.  *
  2292.  * Add a new FB to the specified CRTC, given a user request.
  2293.  *
  2294.  * Called by the user via ioctl.
  2295.  *
  2296.  * RETURNS:
  2297.  * Zero on success, errno on failure.
  2298.  */
  2299. int drm_mode_addfb(struct drm_device *dev,
  2300.                    void *data, struct drm_file *file_priv)
  2301. {
  2302.         struct drm_mode_fb_cmd *or = data;
  2303.         struct drm_mode_fb_cmd2 r = {};
  2304.         struct drm_mode_config *config = &dev->mode_config;
  2305.         struct drm_framebuffer *fb;
  2306.         int ret = 0;
  2307.  
  2308.         /* Use new struct with format internally */
  2309.         r.fb_id = or->fb_id;
  2310.         r.width = or->width;
  2311.         r.height = or->height;
  2312.         r.pitches[0] = or->pitch;
  2313.         r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
  2314.         r.handles[0] = or->handle;
  2315.  
  2316.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  2317.                 return -EINVAL;
  2318.  
  2319.         if ((config->min_width > r.width) || (r.width > config->max_width))
  2320.                 return -EINVAL;
  2321.  
  2322.         if ((config->min_height > r.height) || (r.height > config->max_height))
  2323.                 return -EINVAL;
  2324.  
  2325.         fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
  2326.         if (IS_ERR(fb)) {
  2327.                 DRM_DEBUG_KMS("could not create framebuffer\n");
  2328.                 return PTR_ERR(fb);
  2329.         }
  2330.  
  2331.         mutex_lock(&file_priv->fbs_lock);
  2332.         or->fb_id = fb->base.id;
  2333.         list_add(&fb->filp_head, &file_priv->fbs);
  2334.         DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
  2335.         mutex_unlock(&file_priv->fbs_lock);
  2336.  
  2337.         return ret;
  2338. }
  2339.  
  2340. static int format_check(const struct drm_mode_fb_cmd2 *r)
  2341. {
  2342.         uint32_t format = r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN;
  2343.  
  2344.         switch (format) {
  2345.         case DRM_FORMAT_C8:
  2346.         case DRM_FORMAT_RGB332:
  2347.         case DRM_FORMAT_BGR233:
  2348.         case DRM_FORMAT_XRGB4444:
  2349.         case DRM_FORMAT_XBGR4444:
  2350.         case DRM_FORMAT_RGBX4444:
  2351.         case DRM_FORMAT_BGRX4444:
  2352.         case DRM_FORMAT_ARGB4444:
  2353.         case DRM_FORMAT_ABGR4444:
  2354.         case DRM_FORMAT_RGBA4444:
  2355.         case DRM_FORMAT_BGRA4444:
  2356.         case DRM_FORMAT_XRGB1555:
  2357.         case DRM_FORMAT_XBGR1555:
  2358.         case DRM_FORMAT_RGBX5551:
  2359.         case DRM_FORMAT_BGRX5551:
  2360.         case DRM_FORMAT_ARGB1555:
  2361.         case DRM_FORMAT_ABGR1555:
  2362.         case DRM_FORMAT_RGBA5551:
  2363.         case DRM_FORMAT_BGRA5551:
  2364.         case DRM_FORMAT_RGB565:
  2365.         case DRM_FORMAT_BGR565:
  2366.         case DRM_FORMAT_RGB888:
  2367.         case DRM_FORMAT_BGR888:
  2368.         case DRM_FORMAT_XRGB8888:
  2369.         case DRM_FORMAT_XBGR8888:
  2370.         case DRM_FORMAT_RGBX8888:
  2371.         case DRM_FORMAT_BGRX8888:
  2372.         case DRM_FORMAT_ARGB8888:
  2373.         case DRM_FORMAT_ABGR8888:
  2374.         case DRM_FORMAT_RGBA8888:
  2375.         case DRM_FORMAT_BGRA8888:
  2376.         case DRM_FORMAT_XRGB2101010:
  2377.         case DRM_FORMAT_XBGR2101010:
  2378.         case DRM_FORMAT_RGBX1010102:
  2379.         case DRM_FORMAT_BGRX1010102:
  2380.         case DRM_FORMAT_ARGB2101010:
  2381.         case DRM_FORMAT_ABGR2101010:
  2382.         case DRM_FORMAT_RGBA1010102:
  2383.         case DRM_FORMAT_BGRA1010102:
  2384.         case DRM_FORMAT_YUYV:
  2385.         case DRM_FORMAT_YVYU:
  2386.         case DRM_FORMAT_UYVY:
  2387.         case DRM_FORMAT_VYUY:
  2388.         case DRM_FORMAT_AYUV:
  2389.         case DRM_FORMAT_NV12:
  2390.         case DRM_FORMAT_NV21:
  2391.         case DRM_FORMAT_NV16:
  2392.         case DRM_FORMAT_NV61:
  2393.         case DRM_FORMAT_NV24:
  2394.         case DRM_FORMAT_NV42:
  2395.         case DRM_FORMAT_YUV410:
  2396.         case DRM_FORMAT_YVU410:
  2397.         case DRM_FORMAT_YUV411:
  2398.         case DRM_FORMAT_YVU411:
  2399.         case DRM_FORMAT_YUV420:
  2400.         case DRM_FORMAT_YVU420:
  2401.         case DRM_FORMAT_YUV422:
  2402.         case DRM_FORMAT_YVU422:
  2403.         case DRM_FORMAT_YUV444:
  2404.         case DRM_FORMAT_YVU444:
  2405.                 return 0;
  2406.         default:
  2407.                 return -EINVAL;
  2408.         }
  2409. }
  2410.  
  2411. static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
  2412. {
  2413.         int ret, hsub, vsub, num_planes, i;
  2414.  
  2415.         ret = format_check(r);
  2416.         if (ret) {
  2417.                 DRM_DEBUG_KMS("bad framebuffer format %s\n",
  2418.                               drm_get_format_name(r->pixel_format));
  2419.                 return ret;
  2420.         }
  2421.  
  2422.         hsub = drm_format_horz_chroma_subsampling(r->pixel_format);
  2423.         vsub = drm_format_vert_chroma_subsampling(r->pixel_format);
  2424.         num_planes = drm_format_num_planes(r->pixel_format);
  2425.  
  2426.         if (r->width == 0 || r->width % hsub) {
  2427.                 DRM_DEBUG_KMS("bad framebuffer width %u\n", r->height);
  2428.                 return -EINVAL;
  2429.         }
  2430.  
  2431.         if (r->height == 0 || r->height % vsub) {
  2432.                 DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height);
  2433.                 return -EINVAL;
  2434.         }
  2435.  
  2436.         for (i = 0; i < num_planes; i++) {
  2437.                 unsigned int width = r->width / (i != 0 ? hsub : 1);
  2438.                 unsigned int height = r->height / (i != 0 ? vsub : 1);
  2439.                 unsigned int cpp = drm_format_plane_cpp(r->pixel_format, i);
  2440.  
  2441.                 if (!r->handles[i]) {
  2442.                         DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
  2443.                         return -EINVAL;
  2444.                 }
  2445.  
  2446.                 if ((uint64_t) width * cpp > UINT_MAX)
  2447.                         return -ERANGE;
  2448.  
  2449.                 if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
  2450.                         return -ERANGE;
  2451.  
  2452.                 if (r->pitches[i] < width * cpp) {
  2453.                         DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
  2454.                         return -EINVAL;
  2455.                 }
  2456.         }
  2457.  
  2458.         return 0;
  2459. }
  2460.  
  2461. /**
  2462.  * drm_mode_addfb2 - add an FB to the graphics configuration
  2463.  * @dev: drm device for the ioctl
  2464.  * @data: data pointer for the ioctl
  2465.  * @file_priv: drm file for the ioctl call
  2466.  *
  2467.  * Add a new FB to the specified CRTC, given a user request with format.
  2468.  *
  2469.  * Called by the user via ioctl.
  2470.  *
  2471.  * RETURNS:
  2472.  * Zero on success, errno on failure.
  2473.  */
  2474. int drm_mode_addfb2(struct drm_device *dev,
  2475.                     void *data, struct drm_file *file_priv)
  2476. {
  2477.         struct drm_mode_fb_cmd2 *r = data;
  2478.         struct drm_mode_config *config = &dev->mode_config;
  2479.         struct drm_framebuffer *fb;
  2480.         int ret;
  2481.  
  2482.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  2483.                 return -EINVAL;
  2484.  
  2485.         if (r->flags & ~DRM_MODE_FB_INTERLACED) {
  2486.                 DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags);
  2487.                 return -EINVAL;
  2488.         }
  2489.  
  2490.         if ((config->min_width > r->width) || (r->width > config->max_width)) {
  2491.                 DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n",
  2492.                           r->width, config->min_width, config->max_width);
  2493.                 return -EINVAL;
  2494.         }
  2495.         if ((config->min_height > r->height) || (r->height > config->max_height)) {
  2496.                 DRM_DEBUG_KMS("bad framebuffer height %d, should be >= %d && <= %d\n",
  2497.                           r->height, config->min_height, config->max_height);
  2498.                 return -EINVAL;
  2499.         }
  2500.  
  2501.         ret = framebuffer_check(r);
  2502.         if (ret)
  2503.                 return ret;
  2504.  
  2505.         fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
  2506.         if (IS_ERR(fb)) {
  2507.                 DRM_DEBUG_KMS("could not create framebuffer\n");
  2508.                 return PTR_ERR(fb);
  2509.         }
  2510.  
  2511.         mutex_lock(&file_priv->fbs_lock);
  2512.         r->fb_id = fb->base.id;
  2513.         list_add(&fb->filp_head, &file_priv->fbs);
  2514.         DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
  2515.         mutex_unlock(&file_priv->fbs_lock);
  2516.  
  2517.  
  2518.         return ret;
  2519. }
  2520.  
  2521. /**
  2522.  * drm_mode_rmfb - remove an FB from the configuration
  2523.  * @dev: drm device for the ioctl
  2524.  * @data: data pointer for the ioctl
  2525.  * @file_priv: drm file for the ioctl call
  2526.  *
  2527.  * Remove the FB specified by the user.
  2528.  *
  2529.  * Called by the user via ioctl.
  2530.  *
  2531.  * RETURNS:
  2532.  * Zero on success, errno on failure.
  2533.  */
  2534. int drm_mode_rmfb(struct drm_device *dev,
  2535.                    void *data, struct drm_file *file_priv)
  2536. {
  2537.         struct drm_framebuffer *fb = NULL;
  2538.         struct drm_framebuffer *fbl = NULL;
  2539.         uint32_t *id = data;
  2540.         int found = 0;
  2541.  
  2542.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  2543.                 return -EINVAL;
  2544.  
  2545.         mutex_lock(&file_priv->fbs_lock);
  2546.         mutex_lock(&dev->mode_config.fb_lock);
  2547.         fb = __drm_framebuffer_lookup(dev, *id);
  2548.         if (!fb)
  2549.                 goto fail_lookup;
  2550.  
  2551.         list_for_each_entry(fbl, &file_priv->fbs, filp_head)
  2552.                 if (fb == fbl)
  2553.                         found = 1;
  2554.         if (!found)
  2555.                 goto fail_lookup;
  2556.  
  2557.         /* Mark fb as reaped, we still have a ref from fpriv->fbs. */
  2558.         __drm_framebuffer_unregister(dev, fb);
  2559.  
  2560.         list_del_init(&fb->filp_head);
  2561.         mutex_unlock(&dev->mode_config.fb_lock);
  2562.         mutex_unlock(&file_priv->fbs_lock);
  2563.  
  2564.         drm_framebuffer_remove(fb);
  2565.  
  2566.         return 0;
  2567.  
  2568. fail_lookup:
  2569.         mutex_unlock(&dev->mode_config.fb_lock);
  2570.         mutex_unlock(&file_priv->fbs_lock);
  2571.  
  2572.         return -EINVAL;
  2573. }
  2574.  
  2575. /**
  2576.  * drm_mode_getfb - get FB info
  2577.  * @dev: drm device for the ioctl
  2578.  * @data: data pointer for the ioctl
  2579.  * @file_priv: drm file for the ioctl call
  2580.  *
  2581.  * Lookup the FB given its ID and return info about it.
  2582.  *
  2583.  * Called by the user via ioctl.
  2584.  *
  2585.  * RETURNS:
  2586.  * Zero on success, errno on failure.
  2587.  */
  2588. int drm_mode_getfb(struct drm_device *dev,
  2589.                    void *data, struct drm_file *file_priv)
  2590. {
  2591.         struct drm_mode_fb_cmd *r = data;
  2592.         struct drm_framebuffer *fb;
  2593.         int ret;
  2594.  
  2595.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  2596.                 return -EINVAL;
  2597.  
  2598.         fb = drm_framebuffer_lookup(dev, r->fb_id);
  2599.         if (!fb)
  2600.                 return -EINVAL;
  2601.  
  2602.         r->height = fb->height;
  2603.         r->width = fb->width;
  2604.         r->depth = fb->depth;
  2605.         r->bpp = fb->bits_per_pixel;
  2606.         r->pitch = fb->pitches[0];
  2607.         if (fb->funcs->create_handle)
  2608.                 ret = fb->funcs->create_handle(fb, file_priv, &r->handle);
  2609.         else
  2610.                 ret = -ENODEV;
  2611.  
  2612.         drm_framebuffer_unreference(fb);
  2613.  
  2614.         return ret;
  2615. }
  2616.  
  2617. int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
  2618.                            void *data, struct drm_file *file_priv)
  2619. {
  2620.         struct drm_clip_rect __user *clips_ptr;
  2621.         struct drm_clip_rect *clips = NULL;
  2622.         struct drm_mode_fb_dirty_cmd *r = data;
  2623.         struct drm_framebuffer *fb;
  2624.         unsigned flags;
  2625.         int num_clips;
  2626.         int ret;
  2627.  
  2628.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  2629.                 return -EINVAL;
  2630.  
  2631.         fb = drm_framebuffer_lookup(dev, r->fb_id);
  2632.         if (!fb)
  2633.                 return -EINVAL;
  2634.  
  2635.         num_clips = r->num_clips;
  2636.         clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr;
  2637.  
  2638.         if (!num_clips != !clips_ptr) {
  2639.                 ret = -EINVAL;
  2640.                 goto out_err1;
  2641.         }
  2642.  
  2643.         flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags;
  2644.  
  2645.         /* If userspace annotates copy, clips must come in pairs */
  2646.         if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) {
  2647.                 ret = -EINVAL;
  2648.                 goto out_err1;
  2649.         }
  2650.  
  2651.         if (num_clips && clips_ptr) {
  2652.                 if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) {
  2653.                         ret = -EINVAL;
  2654.                         goto out_err1;
  2655.                 }
  2656.                 clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
  2657.                 if (!clips) {
  2658.                         ret = -ENOMEM;
  2659.                         goto out_err1;
  2660.                 }
  2661.  
  2662.                 ret = copy_from_user(clips, clips_ptr,
  2663.                                      num_clips * sizeof(*clips));
  2664.                 if (ret) {
  2665.                         ret = -EFAULT;
  2666.                         goto out_err2;
  2667.         }
  2668.         }
  2669.  
  2670.         if (fb->funcs->dirty) {
  2671.                 drm_modeset_lock_all(dev);
  2672.                 ret = fb->funcs->dirty(fb, file_priv, flags, r->color,
  2673.                                        clips, num_clips);
  2674.                 drm_modeset_unlock_all(dev);
  2675.         } else {
  2676.                 ret = -ENOSYS;
  2677.         }
  2678.  
  2679. out_err2:
  2680.         kfree(clips);
  2681. out_err1:
  2682.         drm_framebuffer_unreference(fb);
  2683.  
  2684.         return ret;
  2685. }
  2686.  
  2687.  
  2688. /**
  2689.  * drm_fb_release - remove and free the FBs on this file
  2690.  * @priv: drm file for the ioctl
  2691.  *
  2692.  * Destroy all the FBs associated with @filp.
  2693.  *
  2694.  * Called by the user via ioctl.
  2695.  *
  2696.  * RETURNS:
  2697.  * Zero on success, errno on failure.
  2698.  */
  2699. void drm_fb_release(struct drm_file *priv)
  2700. {
  2701.         struct drm_device *dev = priv->minor->dev;
  2702.         struct drm_framebuffer *fb, *tfb;
  2703.  
  2704.         mutex_lock(&priv->fbs_lock);
  2705.         list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
  2706.  
  2707.                 mutex_lock(&dev->mode_config.fb_lock);
  2708.                 /* Mark fb as reaped, we still have a ref from fpriv->fbs. */
  2709.                 __drm_framebuffer_unregister(dev, fb);
  2710.                 mutex_unlock(&dev->mode_config.fb_lock);
  2711.  
  2712.                 list_del_init(&fb->filp_head);
  2713.  
  2714.                 /* This will also drop the fpriv->fbs reference. */
  2715.                 drm_framebuffer_remove(fb);
  2716.         }
  2717.         mutex_unlock(&priv->fbs_lock);
  2718. }
  2719. #endif
  2720.  
  2721.  
  2722. struct drm_property *drm_property_create(struct drm_device *dev, int flags,
  2723.                                          const char *name, int num_values)
  2724. {
  2725.         struct drm_property *property = NULL;
  2726.         int ret;
  2727.  
  2728.         property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
  2729.         if (!property)
  2730.                 return NULL;
  2731.  
  2732.         if (num_values) {
  2733.                 property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
  2734.                 if (!property->values)
  2735.                         goto fail;
  2736.         }
  2737.  
  2738.         ret = drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
  2739.         if (ret)
  2740.                 goto fail;
  2741.  
  2742.         property->flags = flags;
  2743.         property->num_values = num_values;
  2744.         INIT_LIST_HEAD(&property->enum_blob_list);
  2745.  
  2746.         if (name) {
  2747.                 strncpy(property->name, name, DRM_PROP_NAME_LEN);
  2748.                 property->name[DRM_PROP_NAME_LEN-1] = '\0';
  2749.         }
  2750.  
  2751.         list_add_tail(&property->head, &dev->mode_config.property_list);
  2752.         return property;
  2753. fail:
  2754.         kfree(property->values);
  2755.         kfree(property);
  2756.         return NULL;
  2757. }
  2758. EXPORT_SYMBOL(drm_property_create);
  2759.  
  2760. struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
  2761.                                          const char *name,
  2762.                                          const struct drm_prop_enum_list *props,
  2763.                                          int num_values)
  2764. {
  2765.         struct drm_property *property;
  2766.         int i, ret;
  2767.  
  2768.         flags |= DRM_MODE_PROP_ENUM;
  2769.  
  2770.         property = drm_property_create(dev, flags, name, num_values);
  2771.         if (!property)
  2772.                 return NULL;
  2773.  
  2774.         for (i = 0; i < num_values; i++) {
  2775.                 ret = drm_property_add_enum(property, i,
  2776.                                       props[i].type,
  2777.                                       props[i].name);
  2778.                 if (ret) {
  2779.                         drm_property_destroy(dev, property);
  2780.                         return NULL;
  2781.                 }
  2782.         }
  2783.  
  2784.         return property;
  2785. }
  2786. EXPORT_SYMBOL(drm_property_create_enum);
  2787.  
  2788. struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
  2789.                                          int flags, const char *name,
  2790.                                          const struct drm_prop_enum_list *props,
  2791.                                          int num_values)
  2792. {
  2793.         struct drm_property *property;
  2794.         int i, ret;
  2795.  
  2796.         flags |= DRM_MODE_PROP_BITMASK;
  2797.  
  2798.         property = drm_property_create(dev, flags, name, num_values);
  2799.         if (!property)
  2800.                 return NULL;
  2801.  
  2802.         for (i = 0; i < num_values; i++) {
  2803.                 ret = drm_property_add_enum(property, i,
  2804.                                       props[i].type,
  2805.                                       props[i].name);
  2806.                 if (ret) {
  2807.                         drm_property_destroy(dev, property);
  2808.                         return NULL;
  2809.                 }
  2810.         }
  2811.  
  2812.         return property;
  2813. }
  2814. EXPORT_SYMBOL(drm_property_create_bitmask);
  2815.  
  2816. struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
  2817.                                          const char *name,
  2818.                                          uint64_t min, uint64_t max)
  2819. {
  2820.         struct drm_property *property;
  2821.  
  2822.         flags |= DRM_MODE_PROP_RANGE;
  2823.  
  2824.         property = drm_property_create(dev, flags, name, 2);
  2825.         if (!property)
  2826.                 return NULL;
  2827.  
  2828.         property->values[0] = min;
  2829.         property->values[1] = max;
  2830.  
  2831.         return property;
  2832. }
  2833. EXPORT_SYMBOL(drm_property_create_range);
  2834.  
  2835. int drm_property_add_enum(struct drm_property *property, int index,
  2836.                           uint64_t value, const char *name)
  2837. {
  2838.         struct drm_property_enum *prop_enum;
  2839.  
  2840.         if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)))
  2841.                 return -EINVAL;
  2842.  
  2843.         /*
  2844.          * Bitmask enum properties have the additional constraint of values
  2845.          * from 0 to 63
  2846.          */
  2847.         if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63))
  2848.                 return -EINVAL;
  2849.  
  2850.         if (!list_empty(&property->enum_blob_list)) {
  2851.                 list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
  2852.                         if (prop_enum->value == value) {
  2853.                                 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
  2854.                                 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
  2855.                                 return 0;
  2856.                         }
  2857.                 }
  2858.         }
  2859.  
  2860.         prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
  2861.         if (!prop_enum)
  2862.                 return -ENOMEM;
  2863.  
  2864.         strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
  2865.         prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
  2866.         prop_enum->value = value;
  2867.  
  2868.         property->values[index] = value;
  2869.         list_add_tail(&prop_enum->head, &property->enum_blob_list);
  2870.         return 0;
  2871. }
  2872. EXPORT_SYMBOL(drm_property_add_enum);
  2873.  
  2874. void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
  2875. {
  2876.         struct drm_property_enum *prop_enum, *pt;
  2877.  
  2878.         list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) {
  2879.                 list_del(&prop_enum->head);
  2880.                 kfree(prop_enum);
  2881.         }
  2882.  
  2883.         if (property->num_values)
  2884.                 kfree(property->values);
  2885.         drm_mode_object_put(dev, &property->base);
  2886.         list_del(&property->head);
  2887.         kfree(property);
  2888. }
  2889. EXPORT_SYMBOL(drm_property_destroy);
  2890.  
  2891. void drm_object_attach_property(struct drm_mode_object *obj,
  2892.                                 struct drm_property *property,
  2893.                                 uint64_t init_val)
  2894. {
  2895.         int count = obj->properties->count;
  2896.  
  2897.         if (count == DRM_OBJECT_MAX_PROPERTY) {
  2898.                 WARN(1, "Failed to attach object property (type: 0x%x). Please "
  2899.                         "increase DRM_OBJECT_MAX_PROPERTY by 1 for each time "
  2900.                         "you see this message on the same object type.\n",
  2901.                         obj->type);
  2902.                 return;
  2903.         }
  2904.  
  2905.         obj->properties->ids[count] = property->base.id;
  2906.         obj->properties->values[count] = init_val;
  2907.         obj->properties->count++;
  2908. }
  2909. EXPORT_SYMBOL(drm_object_attach_property);
  2910.  
  2911. int drm_object_property_set_value(struct drm_mode_object *obj,
  2912.                                   struct drm_property *property, uint64_t val)
  2913. {
  2914.         int i;
  2915.  
  2916.         for (i = 0; i < obj->properties->count; i++) {
  2917.                 if (obj->properties->ids[i] == property->base.id) {
  2918.                         obj->properties->values[i] = val;
  2919.                         return 0;
  2920.                 }
  2921.         }
  2922.  
  2923.                 return -EINVAL;
  2924. }
  2925. EXPORT_SYMBOL(drm_object_property_set_value);
  2926.  
  2927. int drm_object_property_get_value(struct drm_mode_object *obj,
  2928.                                   struct drm_property *property, uint64_t *val)
  2929. {
  2930.         int i;
  2931.  
  2932.         for (i = 0; i < obj->properties->count; i++) {
  2933.                 if (obj->properties->ids[i] == property->base.id) {
  2934.                         *val = obj->properties->values[i];
  2935.                         return 0;
  2936.                 }
  2937.         }
  2938.  
  2939.                 return -EINVAL;
  2940. }
  2941. EXPORT_SYMBOL(drm_object_property_get_value);
  2942.  
  2943. #if 0
  2944. int drm_mode_getproperty_ioctl(struct drm_device *dev,
  2945.                                void *data, struct drm_file *file_priv)
  2946. {
  2947.         struct drm_mode_object *obj;
  2948.         struct drm_mode_get_property *out_resp = data;
  2949.         struct drm_property *property;
  2950.         int enum_count = 0;
  2951.         int blob_count = 0;
  2952.         int value_count = 0;
  2953.         int ret = 0, i;
  2954.         int copied;
  2955.         struct drm_property_enum *prop_enum;
  2956.         struct drm_mode_property_enum __user *enum_ptr;
  2957.         struct drm_property_blob *prop_blob;
  2958.         uint32_t __user *blob_id_ptr;
  2959.         uint64_t __user *values_ptr;
  2960.         uint32_t __user *blob_length_ptr;
  2961.  
  2962.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  2963.                 return -EINVAL;
  2964.  
  2965.         drm_modeset_lock_all(dev);
  2966.         obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
  2967.         if (!obj) {
  2968.                 ret = -EINVAL;
  2969.                 goto done;
  2970.         }
  2971.         property = obj_to_property(obj);
  2972.  
  2973.         if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
  2974.                 list_for_each_entry(prop_enum, &property->enum_blob_list, head)
  2975.                         enum_count++;
  2976.         } else if (property->flags & DRM_MODE_PROP_BLOB) {
  2977.                 list_for_each_entry(prop_blob, &property->enum_blob_list, head)
  2978.                         blob_count++;
  2979.         }
  2980.  
  2981.         value_count = property->num_values;
  2982.  
  2983.         strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
  2984.         out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
  2985.         out_resp->flags = property->flags;
  2986.  
  2987.         if ((out_resp->count_values >= value_count) && value_count) {
  2988.                 values_ptr = (uint64_t __user *)(unsigned long)out_resp->values_ptr;
  2989.                 for (i = 0; i < value_count; i++) {
  2990.                         if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
  2991.                                 ret = -EFAULT;
  2992.                                 goto done;
  2993.                         }
  2994.                 }
  2995.         }
  2996.         out_resp->count_values = value_count;
  2997.  
  2998.         if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
  2999.                 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
  3000.                         copied = 0;
  3001.                         enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;
  3002.                         list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
  3003.  
  3004.                                 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
  3005.                                         ret = -EFAULT;
  3006.                                         goto done;
  3007.                                 }
  3008.  
  3009.                                 if (copy_to_user(&enum_ptr[copied].name,
  3010.                                                  &prop_enum->name, DRM_PROP_NAME_LEN)) {
  3011.                                         ret = -EFAULT;
  3012.                                         goto done;
  3013.                                 }
  3014.                                 copied++;
  3015.                         }
  3016.                 }
  3017.                 out_resp->count_enum_blobs = enum_count;
  3018.         }
  3019.  
  3020.         if (property->flags & DRM_MODE_PROP_BLOB) {
  3021.                 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
  3022.                         copied = 0;
  3023.                         blob_id_ptr = (uint32_t __user *)(unsigned long)out_resp->enum_blob_ptr;
  3024.                         blob_length_ptr = (uint32_t __user *)(unsigned long)out_resp->values_ptr;
  3025.  
  3026.                         list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
  3027.                                 if (put_user(prop_blob->base.id, blob_id_ptr + copied)) {
  3028.                                         ret = -EFAULT;
  3029.                                         goto done;
  3030.                                 }
  3031.  
  3032.                                 if (put_user(prop_blob->length, blob_length_ptr + copied)) {
  3033.                                         ret = -EFAULT;
  3034.                                         goto done;
  3035.                                 }
  3036.  
  3037.                                 copied++;
  3038.                         }
  3039.                 }
  3040.                 out_resp->count_enum_blobs = blob_count;
  3041.         }
  3042. done:
  3043.         drm_modeset_unlock_all(dev);
  3044.         return ret;
  3045. }
  3046. #endif
  3047.  
  3048. static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,
  3049.                                                           void *data)
  3050. {
  3051.         struct drm_property_blob *blob;
  3052.         int ret;
  3053.  
  3054.         if (!length || !data)
  3055.                 return NULL;
  3056.  
  3057.         blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
  3058.         if (!blob)
  3059.                 return NULL;
  3060.  
  3061.         ret = drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
  3062.         if (ret) {
  3063.                 kfree(blob);
  3064.                 return NULL;
  3065.         }
  3066.  
  3067.         blob->length = length;
  3068.  
  3069.         memcpy(blob->data, data, length);
  3070.  
  3071.         list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
  3072.         return blob;
  3073. }
  3074.  
  3075. static void drm_property_destroy_blob(struct drm_device *dev,
  3076.                                struct drm_property_blob *blob)
  3077. {
  3078.         drm_mode_object_put(dev, &blob->base);
  3079.         list_del(&blob->head);
  3080.         kfree(blob);
  3081. }
  3082.  
  3083. #if 0
  3084. int drm_mode_getblob_ioctl(struct drm_device *dev,
  3085.                            void *data, struct drm_file *file_priv)
  3086. {
  3087.         struct drm_mode_object *obj;
  3088.         struct drm_mode_get_blob *out_resp = data;
  3089.         struct drm_property_blob *blob;
  3090.         int ret = 0;
  3091.         void __user *blob_ptr;
  3092.  
  3093.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  3094.                 return -EINVAL;
  3095.  
  3096.         drm_modeset_lock_all(dev);
  3097.         obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB);
  3098.         if (!obj) {
  3099.                 ret = -EINVAL;
  3100.                 goto done;
  3101.         }
  3102.         blob = obj_to_blob(obj);
  3103.  
  3104.         if (out_resp->length == blob->length) {
  3105.                 blob_ptr = (void __user *)(unsigned long)out_resp->data;
  3106.                 if (copy_to_user(blob_ptr, blob->data, blob->length)){
  3107.                         ret = -EFAULT;
  3108.                         goto done;
  3109.                 }
  3110.         }
  3111.         out_resp->length = blob->length;
  3112.  
  3113. done:
  3114.         drm_modeset_unlock_all(dev);
  3115.         return ret;
  3116. }
  3117. #endif
  3118.  
  3119. int drm_mode_connector_update_edid_property(struct drm_connector *connector,
  3120.                                             struct edid *edid)
  3121. {
  3122.         struct drm_device *dev = connector->dev;
  3123.         int ret, size;
  3124.  
  3125.         if (connector->edid_blob_ptr)
  3126.                 drm_property_destroy_blob(dev, connector->edid_blob_ptr);
  3127.  
  3128.         /* Delete edid, when there is none. */
  3129.         if (!edid) {
  3130.                 connector->edid_blob_ptr = NULL;
  3131.                 ret = drm_object_property_set_value(&connector->base, dev->mode_config.edid_property, 0);
  3132.                 return ret;
  3133.         }
  3134.  
  3135.         size = EDID_LENGTH * (1 + edid->extensions);
  3136.         connector->edid_blob_ptr = drm_property_create_blob(connector->dev,
  3137.                                                             size, edid);
  3138.         if (!connector->edid_blob_ptr)
  3139.                 return -EINVAL;
  3140.  
  3141.         ret = drm_object_property_set_value(&connector->base,
  3142.                                                dev->mode_config.edid_property,
  3143.                                                connector->edid_blob_ptr->base.id);
  3144.  
  3145.         return ret;
  3146. }
  3147. EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
  3148.  
  3149. #if 0
  3150.  
  3151. static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
  3152.                                            struct drm_property *property,
  3153.                                            uint64_t value)
  3154. {
  3155.         int ret = -EINVAL;
  3156.         struct drm_connector *connector = obj_to_connector(obj);
  3157.  
  3158.         /* Do DPMS ourselves */
  3159.         if (property == connector->dev->mode_config.dpms_property) {
  3160.                 if (connector->funcs->dpms)
  3161.                         (*connector->funcs->dpms)(connector, (int)value);
  3162.                 ret = 0;
  3163.         } else if (connector->funcs->set_property)
  3164.                 ret = connector->funcs->set_property(connector, property, value);
  3165.  
  3166.         /* store the property value if successful */
  3167.         if (!ret)
  3168.                 drm_object_property_set_value(&connector->base, property, value);
  3169.         return ret;
  3170. }
  3171.  
  3172. static int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
  3173.                                       struct drm_property *property,
  3174.                                       uint64_t value)
  3175. {
  3176.         int ret = -EINVAL;
  3177.         struct drm_crtc *crtc = obj_to_crtc(obj);
  3178.  
  3179.         if (crtc->funcs->set_property)
  3180.                 ret = crtc->funcs->set_property(crtc, property, value);
  3181.         if (!ret)
  3182.                 drm_object_property_set_value(obj, property, value);
  3183.  
  3184.         return ret;
  3185. }
  3186.  
  3187. static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj,
  3188.                                       struct drm_property *property,
  3189.                                       uint64_t value)
  3190. {
  3191.         int ret = -EINVAL;
  3192.         struct drm_plane *plane = obj_to_plane(obj);
  3193.  
  3194.         if (plane->funcs->set_property)
  3195.                 ret = plane->funcs->set_property(plane, property, value);
  3196.         if (!ret)
  3197.                 drm_object_property_set_value(obj, property, value);
  3198.  
  3199.         return ret;
  3200. }
  3201.  
  3202. int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
  3203.                                       struct drm_file *file_priv)
  3204. {
  3205.         struct drm_mode_obj_get_properties *arg = data;
  3206.         struct drm_mode_object *obj;
  3207.         int ret = 0;
  3208.         int i;
  3209.         int copied = 0;
  3210.         int props_count = 0;
  3211.         uint32_t __user *props_ptr;
  3212.         uint64_t __user *prop_values_ptr;
  3213.  
  3214.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  3215.                 return -EINVAL;
  3216.  
  3217.         drm_modeset_lock_all(dev);
  3218.  
  3219.         obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
  3220.         if (!obj) {
  3221.                 ret = -EINVAL;
  3222.                 goto out;
  3223.         }
  3224.         if (!obj->properties) {
  3225.                 ret = -EINVAL;
  3226.                 goto out;
  3227.         }
  3228.  
  3229.         props_count = obj->properties->count;
  3230.  
  3231.         /* This ioctl is called twice, once to determine how much space is
  3232.          * needed, and the 2nd time to fill it. */
  3233.         if ((arg->count_props >= props_count) && props_count) {
  3234.                 copied = 0;
  3235.                 props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
  3236.                 prop_values_ptr = (uint64_t __user *)(unsigned long)
  3237.                                   (arg->prop_values_ptr);
  3238.                 for (i = 0; i < props_count; i++) {
  3239.                         if (put_user(obj->properties->ids[i],
  3240.                                      props_ptr + copied)) {
  3241.                                 ret = -EFAULT;
  3242.                                 goto out;
  3243.         }
  3244.                         if (put_user(obj->properties->values[i],
  3245.                                      prop_values_ptr + copied)) {
  3246.                                 ret = -EFAULT;
  3247.                 goto out;
  3248.         }
  3249.                         copied++;
  3250.                 }
  3251.         }
  3252.         arg->count_props = props_count;
  3253. out:
  3254.         drm_modeset_unlock_all(dev);
  3255.         return ret;
  3256. }
  3257.  
  3258. int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
  3259.                                     struct drm_file *file_priv)
  3260. {
  3261.         struct drm_mode_obj_set_property *arg = data;
  3262.         struct drm_mode_object *arg_obj;
  3263.         struct drm_mode_object *prop_obj;
  3264.         struct drm_property *property;
  3265.         int ret = -EINVAL;
  3266.         int i;
  3267.  
  3268.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  3269.                 return -EINVAL;
  3270.  
  3271.         drm_modeset_lock_all(dev);
  3272.  
  3273.         arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
  3274.         if (!arg_obj)
  3275.                 goto out;
  3276.         if (!arg_obj->properties)
  3277.                 goto out;
  3278.  
  3279.         for (i = 0; i < arg_obj->properties->count; i++)
  3280.                 if (arg_obj->properties->ids[i] == arg->prop_id)
  3281.                         break;
  3282.  
  3283.         if (i == arg_obj->properties->count)
  3284.                 goto out;
  3285.  
  3286.         prop_obj = drm_mode_object_find(dev, arg->prop_id,
  3287.                                         DRM_MODE_OBJECT_PROPERTY);
  3288.         if (!prop_obj)
  3289.                         goto out;
  3290.         property = obj_to_property(prop_obj);
  3291.  
  3292.         if (!drm_property_change_is_valid(property, arg->value))
  3293.                         goto out;
  3294.  
  3295.         switch (arg_obj->type) {
  3296.         case DRM_MODE_OBJECT_CONNECTOR:
  3297.                 ret = drm_mode_connector_set_obj_prop(arg_obj, property,
  3298.                                                       arg->value);
  3299.                 break;
  3300.         case DRM_MODE_OBJECT_CRTC:
  3301.                 ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
  3302.                 break;
  3303.         case DRM_MODE_OBJECT_PLANE:
  3304.                 ret = drm_mode_plane_set_obj_prop(arg_obj, property, arg->value);
  3305.                                 break;
  3306.                         }
  3307.  
  3308. out:
  3309.         drm_modeset_unlock_all(dev);
  3310.         return ret;
  3311. }
  3312. #endif
  3313.  
  3314. int drm_mode_connector_attach_encoder(struct drm_connector *connector,
  3315.                                       struct drm_encoder *encoder)
  3316. {
  3317.         int i;
  3318.  
  3319.         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
  3320.                 if (connector->encoder_ids[i] == 0) {
  3321.                         connector->encoder_ids[i] = encoder->base.id;
  3322.                         return 0;
  3323.                 }
  3324.         }
  3325.         return -ENOMEM;
  3326. }
  3327. EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
  3328.  
  3329. void drm_mode_connector_detach_encoder(struct drm_connector *connector,
  3330.                                     struct drm_encoder *encoder)
  3331. {
  3332.         int i;
  3333.         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
  3334.                 if (connector->encoder_ids[i] == encoder->base.id) {
  3335.                         connector->encoder_ids[i] = 0;
  3336.                         if (connector->encoder == encoder)
  3337.                                 connector->encoder = NULL;
  3338.                         break;
  3339.                 }
  3340.         }
  3341. }
  3342. EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
  3343.  
  3344. int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
  3345.                                   int gamma_size)
  3346. {
  3347.         crtc->gamma_size = gamma_size;
  3348.  
  3349.         crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
  3350.         if (!crtc->gamma_store) {
  3351.                 crtc->gamma_size = 0;
  3352.                 return -ENOMEM;
  3353.         }
  3354.  
  3355.         return 0;
  3356. }
  3357. EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
  3358.  
  3359. #if 0
  3360. int drm_mode_gamma_set_ioctl(struct drm_device *dev,
  3361.                              void *data, struct drm_file *file_priv)
  3362. {
  3363.         struct drm_mode_crtc_lut *crtc_lut = data;
  3364.         struct drm_mode_object *obj;
  3365.         struct drm_crtc *crtc;
  3366.         void *r_base, *g_base, *b_base;
  3367.         int size;
  3368.         int ret = 0;
  3369.  
  3370.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  3371.                 return -EINVAL;
  3372.  
  3373.         drm_modeset_lock_all(dev);
  3374.         obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
  3375.         if (!obj) {
  3376.                 ret = -EINVAL;
  3377.                 goto out;
  3378.         }
  3379.         crtc = obj_to_crtc(obj);
  3380.  
  3381.         if (crtc->funcs->gamma_set == NULL) {
  3382.                 ret = -ENOSYS;
  3383.                 goto out;
  3384.         }
  3385.  
  3386.         /* memcpy into gamma store */
  3387.         if (crtc_lut->gamma_size != crtc->gamma_size) {
  3388.                 ret = -EINVAL;
  3389.                 goto out;
  3390.         }
  3391.  
  3392.         size = crtc_lut->gamma_size * (sizeof(uint16_t));
  3393.         r_base = crtc->gamma_store;
  3394.         if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) {
  3395.                 ret = -EFAULT;
  3396.                 goto out;
  3397.         }
  3398.  
  3399.         g_base = r_base + size;
  3400.         if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) {
  3401.                 ret = -EFAULT;
  3402.                 goto out;
  3403.         }
  3404.  
  3405.         b_base = g_base + size;
  3406.         if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) {
  3407.                 ret = -EFAULT;
  3408.                 goto out;
  3409.         }
  3410.  
  3411.         crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size);
  3412.  
  3413. out:
  3414.         drm_modeset_unlock_all(dev);
  3415.         return ret;
  3416.  
  3417. }
  3418.  
  3419. int drm_mode_gamma_get_ioctl(struct drm_device *dev,
  3420.                              void *data, struct drm_file *file_priv)
  3421. {
  3422.         struct drm_mode_crtc_lut *crtc_lut = data;
  3423.         struct drm_mode_object *obj;
  3424.         struct drm_crtc *crtc;
  3425.         void *r_base, *g_base, *b_base;
  3426.         int size;
  3427.         int ret = 0;
  3428.  
  3429.         if (!drm_core_check_feature(dev, DRIVER_MODESET))
  3430.                 return -EINVAL;
  3431.  
  3432.         drm_modeset_lock_all(dev);
  3433.         obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
  3434.         if (!obj) {
  3435.                 ret = -EINVAL;
  3436.                 goto out;
  3437.         }
  3438.         crtc = obj_to_crtc(obj);
  3439.  
  3440.         /* memcpy into gamma store */
  3441.         if (crtc_lut->gamma_size != crtc->gamma_size) {
  3442.                 ret = -EINVAL;
  3443.                 goto out;
  3444.         }
  3445.  
  3446.         size = crtc_lut->gamma_size * (sizeof(uint16_t));
  3447.         r_base = crtc->gamma_store;
  3448.         if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) {
  3449.                 ret = -EFAULT;
  3450.                 goto out;
  3451.         }
  3452.  
  3453.         g_base = r_base + size;
  3454.         if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) {
  3455.                 ret = -EFAULT;
  3456.                 goto out;
  3457.         }
  3458.  
  3459.         b_base = g_base + size;
  3460.         if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) {
  3461.                 ret = -EFAULT;
  3462.                 goto out;
  3463.         }
  3464. out:
  3465.         drm_modeset_unlock_all(dev);
  3466.         return ret;
  3467. }
  3468.  
  3469. #endif
  3470.  
  3471.  
  3472. void drm_mode_config_reset(struct drm_device *dev)
  3473. {
  3474.         struct drm_crtc *crtc;
  3475.         struct drm_encoder *encoder;
  3476.         struct drm_connector *connector;
  3477.  
  3478.         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
  3479.                 if (crtc->funcs->reset)
  3480.                         crtc->funcs->reset(crtc);
  3481.  
  3482.         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
  3483.                 if (encoder->funcs->reset)
  3484.                         encoder->funcs->reset(encoder);
  3485.  
  3486.         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
  3487.                 connector->status = connector_status_unknown;
  3488.  
  3489.                 if (connector->funcs->reset)
  3490.                         connector->funcs->reset(connector);
  3491.         }
  3492. }
  3493. EXPORT_SYMBOL(drm_mode_config_reset);
  3494. /*
  3495.  * Just need to support RGB formats here for compat with code that doesn't
  3496.  * use pixel formats directly yet.
  3497.  */
  3498. void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
  3499.                           int *bpp)
  3500. {
  3501.         switch (format) {
  3502.         case DRM_FORMAT_C8:
  3503.         case DRM_FORMAT_RGB332:
  3504.         case DRM_FORMAT_BGR233:
  3505.                 *depth = 8;
  3506.                 *bpp = 8;
  3507.                 break;
  3508.         case DRM_FORMAT_XRGB1555:
  3509.         case DRM_FORMAT_XBGR1555:
  3510.         case DRM_FORMAT_RGBX5551:
  3511.         case DRM_FORMAT_BGRX5551:
  3512.         case DRM_FORMAT_ARGB1555:
  3513.         case DRM_FORMAT_ABGR1555:
  3514.         case DRM_FORMAT_RGBA5551:
  3515.         case DRM_FORMAT_BGRA5551:
  3516.                 *depth = 15;
  3517.                 *bpp = 16;
  3518.                 break;
  3519.         case DRM_FORMAT_RGB565:
  3520.         case DRM_FORMAT_BGR565:
  3521.                 *depth = 16;
  3522.                 *bpp = 16;
  3523.                 break;
  3524.         case DRM_FORMAT_RGB888:
  3525.         case DRM_FORMAT_BGR888:
  3526.                 *depth = 24;
  3527.                 *bpp = 24;
  3528.                 break;
  3529.         case DRM_FORMAT_XRGB8888:
  3530.         case DRM_FORMAT_XBGR8888:
  3531.         case DRM_FORMAT_RGBX8888:
  3532.         case DRM_FORMAT_BGRX8888:
  3533.                 *depth = 24;
  3534.                 *bpp = 32;
  3535.                 break;
  3536.         case DRM_FORMAT_XRGB2101010:
  3537.         case DRM_FORMAT_XBGR2101010:
  3538.         case DRM_FORMAT_RGBX1010102:
  3539.         case DRM_FORMAT_BGRX1010102:
  3540.         case DRM_FORMAT_ARGB2101010:
  3541.         case DRM_FORMAT_ABGR2101010:
  3542.         case DRM_FORMAT_RGBA1010102:
  3543.         case DRM_FORMAT_BGRA1010102:
  3544.                 *depth = 30;
  3545.                 *bpp = 32;
  3546.                 break;
  3547.         case DRM_FORMAT_ARGB8888:
  3548.         case DRM_FORMAT_ABGR8888:
  3549.         case DRM_FORMAT_RGBA8888:
  3550.         case DRM_FORMAT_BGRA8888:
  3551.                 *depth = 32;
  3552.                 *bpp = 32;
  3553.                 break;
  3554.         default:
  3555.                 DRM_DEBUG_KMS("unsupported pixel format\n");
  3556.                 *depth = 0;
  3557.                 *bpp = 0;
  3558.                 break;
  3559.         }
  3560. }
  3561. EXPORT_SYMBOL(drm_fb_get_bpp_depth);
  3562.  
  3563. /**
  3564.  * drm_format_num_planes - get the number of planes for format
  3565.  * @format: pixel format (DRM_FORMAT_*)
  3566.  *
  3567.  * RETURNS:
  3568.  * The number of planes used by the specified pixel format.
  3569.  */
  3570. int drm_format_num_planes(uint32_t format)
  3571. {
  3572.         switch (format) {
  3573.         case DRM_FORMAT_YUV410:
  3574.         case DRM_FORMAT_YVU410:
  3575.         case DRM_FORMAT_YUV411:
  3576.         case DRM_FORMAT_YVU411:
  3577.         case DRM_FORMAT_YUV420:
  3578.         case DRM_FORMAT_YVU420:
  3579.         case DRM_FORMAT_YUV422:
  3580.         case DRM_FORMAT_YVU422:
  3581.         case DRM_FORMAT_YUV444:
  3582.         case DRM_FORMAT_YVU444:
  3583.                 return 3;
  3584.         case DRM_FORMAT_NV12:
  3585.         case DRM_FORMAT_NV21:
  3586.         case DRM_FORMAT_NV16:
  3587.         case DRM_FORMAT_NV61:
  3588.         case DRM_FORMAT_NV24:
  3589.         case DRM_FORMAT_NV42:
  3590.                 return 2;
  3591.         default:
  3592.                 return 1;
  3593.         }
  3594. }
  3595. EXPORT_SYMBOL(drm_format_num_planes);
  3596.  
  3597. /**
  3598.  * drm_format_plane_cpp - determine the bytes per pixel value
  3599.  * @format: pixel format (DRM_FORMAT_*)
  3600.  * @plane: plane index
  3601.  *
  3602.  * RETURNS:
  3603.  * The bytes per pixel value for the specified plane.
  3604.  */
  3605. int drm_format_plane_cpp(uint32_t format, int plane)
  3606. {
  3607.         unsigned int depth;
  3608.         int bpp;
  3609.  
  3610.         if (plane >= drm_format_num_planes(format))
  3611.                 return 0;
  3612.  
  3613.         switch (format) {
  3614.         case DRM_FORMAT_YUYV:
  3615.         case DRM_FORMAT_YVYU:
  3616.         case DRM_FORMAT_UYVY:
  3617.         case DRM_FORMAT_VYUY:
  3618.                 return 2;
  3619.         case DRM_FORMAT_NV12:
  3620.         case DRM_FORMAT_NV21:
  3621.         case DRM_FORMAT_NV16:
  3622.         case DRM_FORMAT_NV61:
  3623.         case DRM_FORMAT_NV24:
  3624.         case DRM_FORMAT_NV42:
  3625.                 return plane ? 2 : 1;
  3626.         case DRM_FORMAT_YUV410:
  3627.         case DRM_FORMAT_YVU410:
  3628.         case DRM_FORMAT_YUV411:
  3629.         case DRM_FORMAT_YVU411:
  3630.         case DRM_FORMAT_YUV420:
  3631.         case DRM_FORMAT_YVU420:
  3632.         case DRM_FORMAT_YUV422:
  3633.         case DRM_FORMAT_YVU422:
  3634.         case DRM_FORMAT_YUV444:
  3635.         case DRM_FORMAT_YVU444:
  3636.                 return 1;
  3637.         default:
  3638.                 drm_fb_get_bpp_depth(format, &depth, &bpp);
  3639.                 return bpp >> 3;
  3640.         }
  3641. }
  3642. EXPORT_SYMBOL(drm_format_plane_cpp);
  3643.  
  3644. /**
  3645.  * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor
  3646.  * @format: pixel format (DRM_FORMAT_*)
  3647.  *
  3648.  * RETURNS:
  3649.  * The horizontal chroma subsampling factor for the
  3650.  * specified pixel format.
  3651.  */
  3652. int drm_format_horz_chroma_subsampling(uint32_t format)
  3653. {
  3654.         switch (format) {
  3655.         case DRM_FORMAT_YUV411:
  3656.         case DRM_FORMAT_YVU411:
  3657.         case DRM_FORMAT_YUV410:
  3658.         case DRM_FORMAT_YVU410:
  3659.                 return 4;
  3660.         case DRM_FORMAT_YUYV:
  3661.         case DRM_FORMAT_YVYU:
  3662.         case DRM_FORMAT_UYVY:
  3663.         case DRM_FORMAT_VYUY:
  3664.         case DRM_FORMAT_NV12:
  3665.         case DRM_FORMAT_NV21:
  3666.         case DRM_FORMAT_NV16:
  3667.         case DRM_FORMAT_NV61:
  3668.         case DRM_FORMAT_YUV422:
  3669.         case DRM_FORMAT_YVU422:
  3670.         case DRM_FORMAT_YUV420:
  3671.         case DRM_FORMAT_YVU420:
  3672.                 return 2;
  3673.         default:
  3674.                 return 1;
  3675.         }
  3676. }
  3677. EXPORT_SYMBOL(drm_format_horz_chroma_subsampling);
  3678.  
  3679. /**
  3680.  * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor
  3681.  * @format: pixel format (DRM_FORMAT_*)
  3682.  *
  3683.  * RETURNS:
  3684.  * The vertical chroma subsampling factor for the
  3685.  * specified pixel format.
  3686.  */
  3687. int drm_format_vert_chroma_subsampling(uint32_t format)
  3688. {
  3689.         switch (format) {
  3690.         case DRM_FORMAT_YUV410:
  3691.         case DRM_FORMAT_YVU410:
  3692.                 return 4;
  3693.         case DRM_FORMAT_YUV420:
  3694.         case DRM_FORMAT_YVU420:
  3695.         case DRM_FORMAT_NV12:
  3696.         case DRM_FORMAT_NV21:
  3697.                 return 2;
  3698.         default:
  3699.                 return 1;
  3700.         }
  3701. }
  3702. EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
  3703.  
  3704. /**
  3705.  * drm_mode_config_init - initialize DRM mode_configuration structure
  3706.  * @dev: DRM device
  3707.  *
  3708.  * Initialize @dev's mode_config structure, used for tracking the graphics
  3709.  * configuration of @dev.
  3710.  *
  3711.  * Since this initializes the modeset locks, no locking is possible. Which is no
  3712.  * problem, since this should happen single threaded at init time. It is the
  3713.  * driver's problem to ensure this guarantee.
  3714.  *
  3715.  */
  3716. void drm_mode_config_init(struct drm_device *dev)
  3717. {
  3718.         mutex_init(&dev->mode_config.mutex);
  3719.         mutex_init(&dev->mode_config.idr_mutex);
  3720.         mutex_init(&dev->mode_config.fb_lock);
  3721.         INIT_LIST_HEAD(&dev->mode_config.fb_list);
  3722.         INIT_LIST_HEAD(&dev->mode_config.crtc_list);
  3723.         INIT_LIST_HEAD(&dev->mode_config.connector_list);
  3724.         INIT_LIST_HEAD(&dev->mode_config.encoder_list);
  3725.         INIT_LIST_HEAD(&dev->mode_config.property_list);
  3726.         INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
  3727.         INIT_LIST_HEAD(&dev->mode_config.plane_list);
  3728.         idr_init(&dev->mode_config.crtc_idr);
  3729.  
  3730.         drm_modeset_lock_all(dev);
  3731.         drm_mode_create_standard_connector_properties(dev);
  3732.         drm_modeset_unlock_all(dev);
  3733.  
  3734.         /* Just to be sure */
  3735.         dev->mode_config.num_fb = 0;
  3736.         dev->mode_config.num_connector = 0;
  3737.         dev->mode_config.num_crtc = 0;
  3738.         dev->mode_config.num_encoder = 0;
  3739. }
  3740. EXPORT_SYMBOL(drm_mode_config_init);
  3741.  
  3742.