Subversion Repositories Kolibri OS

Rev

Rev 1179 | Rev 1404 | 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/list.h>
  33. #include "drm.h"
  34. #include "drmP.h"
  35. #include "drm_crtc.h"
  36.  
  37. struct drm_prop_enum_list {
  38.         int type;
  39.         char *name;
  40. };
  41.  
  42. /* Avoid boilerplate.  I'm tired of typing. */
  43. #define DRM_ENUM_NAME_FN(fnname, list)                          \
  44.         char *fnname(int val)                                   \
  45.         {                                                       \
  46.                 int i;                                          \
  47.                 for (i = 0; i < ARRAY_SIZE(list); i++) {        \
  48.                         if (list[i].type == val)                \
  49.                                 return list[i].name;            \
  50.                 }                                               \
  51.                 return "(unknown)";                             \
  52.         }
  53.  
  54. /*
  55.  * Global properties
  56.  */
  57. static struct drm_prop_enum_list drm_dpms_enum_list[] =
  58. {       { DRM_MODE_DPMS_ON, "On" },
  59.         { DRM_MODE_DPMS_STANDBY, "Standby" },
  60.         { DRM_MODE_DPMS_SUSPEND, "Suspend" },
  61.         { DRM_MODE_DPMS_OFF, "Off" }
  62. };
  63.  
  64. DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
  65.  
  66. /*
  67.  * Optional properties
  68.  */
  69. static struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
  70. {
  71.         { DRM_MODE_SCALE_NONE, "None" },
  72.         { DRM_MODE_SCALE_FULLSCREEN, "Full" },
  73.         { DRM_MODE_SCALE_CENTER, "Center" },
  74.         { DRM_MODE_SCALE_ASPECT, "Full aspect" },
  75. };
  76.  
  77. static struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
  78. {
  79.         { DRM_MODE_DITHERING_OFF, "Off" },
  80.         { DRM_MODE_DITHERING_ON, "On" },
  81. };
  82.  
  83. /*
  84.  * Non-global properties, but "required" for certain connectors.
  85.  */
  86. static struct drm_prop_enum_list drm_dvi_i_select_enum_list[] =
  87. {
  88.         { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
  89.         { DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
  90.         { DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
  91. };
  92.  
  93. DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
  94.  
  95. static struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] =
  96. {
  97.         { DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
  98.         { DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
  99.         { DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
  100. };
  101.  
  102. DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
  103.                  drm_dvi_i_subconnector_enum_list)
  104.  
  105. static struct drm_prop_enum_list drm_tv_select_enum_list[] =
  106. {
  107.         { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
  108.         { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
  109.         { DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
  110.         { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
  111.         { DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
  112. };
  113.  
  114. DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
  115.  
  116. static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
  117. {
  118.         { DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
  119.         { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
  120.         { DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
  121.         { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
  122.         { DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
  123. };
  124.  
  125. DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
  126.                  drm_tv_subconnector_enum_list)
  127.  
  128. struct drm_conn_prop_enum_list {
  129.         int type;
  130.         char *name;
  131.         int count;
  132. };
  133.  
  134. /*
  135.  * Connector and encoder types.
  136.  */
  137. static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
  138. {       { DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 },
  139.         { DRM_MODE_CONNECTOR_VGA, "VGA", 0 },
  140.         { DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 },
  141.         { DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 },
  142.         { DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 },
  143.         { DRM_MODE_CONNECTOR_Composite, "Composite", 0 },
  144.         { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
  145.         { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
  146.         { DRM_MODE_CONNECTOR_Component, "Component", 0 },
  147.         { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 },
  148.         { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 },
  149.         { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
  150.         { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
  151.         { DRM_MODE_CONNECTOR_TV, "TV", 0 },
  152. };
  153.  
  154. static struct drm_prop_enum_list drm_encoder_enum_list[] =
  155. {       { DRM_MODE_ENCODER_NONE, "None" },
  156.         { DRM_MODE_ENCODER_DAC, "DAC" },
  157.         { DRM_MODE_ENCODER_TMDS, "TMDS" },
  158.         { DRM_MODE_ENCODER_LVDS, "LVDS" },
  159.         { DRM_MODE_ENCODER_TVDAC, "TV" },
  160. };
  161.  
  162. char *drm_get_encoder_name(struct drm_encoder *encoder)
  163. {
  164.         static char buf[32];
  165.  
  166.         snprintf(buf, 32, "%s-%d",
  167.                  drm_encoder_enum_list[encoder->encoder_type].name,
  168.                  encoder->base.id);
  169.         return buf;
  170. }
  171. EXPORT_SYMBOL(drm_get_encoder_name);
  172.  
  173. char *drm_get_connector_name(struct drm_connector *connector)
  174. {
  175.         static char buf[32];
  176.  
  177.         snprintf(buf, 32, "%s-%d",
  178.                  drm_connector_enum_list[connector->connector_type].name,
  179.                  connector->connector_type_id);
  180.         return buf;
  181. }
  182. EXPORT_SYMBOL(drm_get_connector_name);
  183.  
  184. char *drm_get_connector_status_name(enum drm_connector_status status)
  185. {
  186.         if (status == connector_status_connected)
  187.                 return "connected";
  188.         else if (status == connector_status_disconnected)
  189.                 return "disconnected";
  190.         else
  191.                 return "unknown";
  192. }
  193.  
  194. /**
  195.  * drm_mode_object_get - allocate a new identifier
  196.  * @dev: DRM device
  197.  * @ptr: object pointer, used to generate unique ID
  198.  * @type: object type
  199.  *
  200.  * LOCKING:
  201.  *
  202.  * Create a unique identifier based on @ptr in @dev's identifier space.  Used
  203.  * for tracking modes, CRTCs and connectors.
  204.  *
  205.  * RETURNS:
  206.  * New unique (relative to other objects in @dev) integer identifier for the
  207.  * object.
  208.  */
  209. static int drm_mode_object_get(struct drm_device *dev,
  210.                                struct drm_mode_object *obj, uint32_t obj_type)
  211. {
  212.         int new_id = 0;
  213.         int ret;
  214.  
  215. again:
  216.         if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
  217.                 DRM_ERROR("Ran out memory getting a mode number\n");
  218.                 return -EINVAL;
  219.         }
  220.  
  221.         mutex_lock(&dev->mode_config.idr_mutex);
  222.         ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id);
  223.         mutex_unlock(&dev->mode_config.idr_mutex);
  224.         if (ret == -EAGAIN)
  225.         goto again;
  226.  
  227.         obj->id = new_id;
  228.         obj->type = obj_type;
  229.     return 0;
  230. }
  231.  
  232. /**
  233.  * drm_mode_object_put - free an identifer
  234.  * @dev: DRM device
  235.  * @id: ID to free
  236.  *
  237.  * LOCKING:
  238.  * Caller must hold DRM mode_config lock.
  239.  *
  240.  * Free @id from @dev's unique identifier pool.
  241.  */
  242. static void drm_mode_object_put(struct drm_device *dev,
  243.                                 struct drm_mode_object *object)
  244. {
  245.         mutex_lock(&dev->mode_config.idr_mutex);
  246.         idr_remove(&dev->mode_config.crtc_idr, object->id);
  247.         mutex_unlock(&dev->mode_config.idr_mutex);
  248. }
  249.  
  250. void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
  251. {
  252.         struct drm_mode_object *obj = NULL;
  253.  
  254.         mutex_lock(&dev->mode_config.idr_mutex);
  255.         obj = idr_find(&dev->mode_config.crtc_idr, id);
  256.         if (!obj || (obj->type != type) || (obj->id != id))
  257.                 obj = NULL;
  258.         mutex_unlock(&dev->mode_config.idr_mutex);
  259.  
  260.         return obj;
  261. }
  262. EXPORT_SYMBOL(drm_mode_object_find);
  263.  
  264. /**
  265.  * drm_framebuffer_init - initialize a framebuffer
  266.  * @dev: DRM device
  267.  *
  268.  * LOCKING:
  269.  * Caller must hold mode config lock.
  270.  *
  271.  * Allocates an ID for the framebuffer's parent mode object, sets its mode
  272.  * functions & device file and adds it to the master fd list.
  273.  *
  274.  * RETURNS:
  275.  * Zero on success, error code on falure.
  276.  */
  277. int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
  278.                          const struct drm_framebuffer_funcs *funcs)
  279. {
  280.         int ret;
  281.  
  282.         ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
  283.         if (ret) {
  284.                 return ret;
  285.         }
  286.  
  287.         fb->dev = dev;
  288.         fb->funcs = funcs;
  289.         dev->mode_config.num_fb++;
  290.         list_add(&fb->head, &dev->mode_config.fb_list);
  291.  
  292.         return 0;
  293. }
  294. EXPORT_SYMBOL(drm_framebuffer_init);
  295.  
  296. /**
  297.  * drm_framebuffer_cleanup - remove a framebuffer object
  298.  * @fb: framebuffer to remove
  299.  *
  300.  * LOCKING:
  301.  * Caller must hold mode config lock.
  302.  *
  303.  * Scans all the CRTCs in @dev's mode_config.  If they're using @fb, removes
  304.  * it, setting it to NULL.
  305.  */
  306. void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
  307. {
  308.         struct drm_device *dev = fb->dev;
  309.         struct drm_crtc *crtc;
  310.         struct drm_mode_set set;
  311.         int ret;
  312.  
  313.         /* remove from any CRTC */
  314.         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
  315.                 if (crtc->fb == fb) {
  316.                         /* should turn off the crtc */
  317.                         memset(&set, 0, sizeof(struct drm_mode_set));
  318.                         set.crtc = crtc;
  319.                         set.fb = NULL;
  320.                         ret = crtc->funcs->set_config(&set);
  321.                         if (ret)
  322.                                 DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
  323.            }
  324.         }
  325.  
  326.         drm_mode_object_put(dev, &fb->base);
  327.         list_del(&fb->head);
  328.         dev->mode_config.num_fb--;
  329. }
  330. EXPORT_SYMBOL(drm_framebuffer_cleanup);
  331.  
  332. /**
  333.  * drm_crtc_init - Initialise a new CRTC object
  334.  * @dev: DRM device
  335.  * @crtc: CRTC object to init
  336.  * @funcs: callbacks for the new CRTC
  337.  *
  338.  * LOCKING:
  339.  * Caller must hold mode config lock.
  340.  *
  341.  * Inits a new object created as base part of an driver crtc object.
  342.  */
  343. void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
  344.                    const struct drm_crtc_funcs *funcs)
  345. {
  346.         crtc->dev = dev;
  347.         crtc->funcs = funcs;
  348.  
  349.         mutex_lock(&dev->mode_config.mutex);
  350.         drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
  351.  
  352.         list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
  353.         dev->mode_config.num_crtc++;
  354.         mutex_unlock(&dev->mode_config.mutex);
  355. }
  356. EXPORT_SYMBOL(drm_crtc_init);
  357.  
  358. /**
  359.  * drm_crtc_cleanup - Cleans up the core crtc usage.
  360.  * @crtc: CRTC to cleanup
  361.  *
  362.  * LOCKING:
  363.  * Caller must hold mode config lock.
  364.  *
  365.  * Cleanup @crtc. Removes from drm modesetting space
  366.  * does NOT free object, caller does that.
  367.  */
  368. void drm_crtc_cleanup(struct drm_crtc *crtc)
  369. {
  370.         struct drm_device *dev = crtc->dev;
  371.  
  372.         if (crtc->gamma_store) {
  373.                 kfree(crtc->gamma_store);
  374.                 crtc->gamma_store = NULL;
  375.         }
  376.  
  377.         drm_mode_object_put(dev, &crtc->base);
  378.         list_del(&crtc->head);
  379.         dev->mode_config.num_crtc--;
  380. }
  381. EXPORT_SYMBOL(drm_crtc_cleanup);
  382.  
  383. /**
  384.  * drm_mode_probed_add - add a mode to a connector's probed mode list
  385.  * @connector: connector the new mode
  386.  * @mode: mode data
  387.  *
  388.  * LOCKING:
  389.  * Caller must hold mode config lock.
  390.  *
  391.  * Add @mode to @connector's mode list for later use.
  392.  */
  393. void drm_mode_probed_add(struct drm_connector *connector,
  394.                          struct drm_display_mode *mode)
  395. {
  396.         list_add(&mode->head, &connector->probed_modes);
  397. }
  398. EXPORT_SYMBOL(drm_mode_probed_add);
  399.  
  400. /**
  401.  * drm_mode_remove - remove and free a mode
  402.  * @connector: connector list to modify
  403.  * @mode: mode to remove
  404.  *
  405.  * LOCKING:
  406.  * Caller must hold mode config lock.
  407.  *
  408.  * Remove @mode from @connector's mode list, then free it.
  409.  */
  410. void drm_mode_remove(struct drm_connector *connector,
  411.                      struct drm_display_mode *mode)
  412. {
  413.         list_del(&mode->head);
  414.         kfree(mode);
  415. }
  416. EXPORT_SYMBOL(drm_mode_remove);
  417.  
  418. /**
  419.  * drm_connector_init - Init a preallocated connector
  420.  * @dev: DRM device
  421.  * @connector: the connector to init
  422.  * @funcs: callbacks for this connector
  423.  * @name: user visible name of the connector
  424.  *
  425.  * LOCKING:
  426.  * Caller must hold @dev's mode_config lock.
  427.  *
  428.  * Initialises a preallocated connector. Connectors should be
  429.  * subclassed as part of driver connector objects.
  430.  */
  431. void drm_connector_init(struct drm_device *dev,
  432.                      struct drm_connector *connector,
  433.                      const struct drm_connector_funcs *funcs,
  434.                      int connector_type)
  435. {
  436.         mutex_lock(&dev->mode_config.mutex);
  437.  
  438.         connector->dev = dev;
  439.         connector->funcs = funcs;
  440.         drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
  441.         connector->connector_type = connector_type;
  442.         connector->connector_type_id =
  443.                 ++drm_connector_enum_list[connector_type].count; /* TODO */
  444.         INIT_LIST_HEAD(&connector->user_modes);
  445.         INIT_LIST_HEAD(&connector->probed_modes);
  446.         INIT_LIST_HEAD(&connector->modes);
  447.         connector->edid_blob_ptr = NULL;
  448.  
  449.         list_add_tail(&connector->head, &dev->mode_config.connector_list);
  450.         dev->mode_config.num_connector++;
  451.  
  452.         drm_connector_attach_property(connector,
  453.                                       dev->mode_config.edid_property, 0);
  454.  
  455.         drm_connector_attach_property(connector,
  456.                                       dev->mode_config.dpms_property, 0);
  457.  
  458.         mutex_unlock(&dev->mode_config.mutex);
  459. }
  460. EXPORT_SYMBOL(drm_connector_init);
  461.  
  462. /**
  463.  * drm_connector_cleanup - cleans up an initialised connector
  464.  * @connector: connector to cleanup
  465.  *
  466.  * LOCKING:
  467.  * Caller must hold @dev's mode_config lock.
  468.  *
  469.  * Cleans up the connector but doesn't free the object.
  470.  */
  471. void drm_connector_cleanup(struct drm_connector *connector)
  472. {
  473.         struct drm_device *dev = connector->dev;
  474.         struct drm_display_mode *mode, *t;
  475.  
  476.         list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
  477.                 drm_mode_remove(connector, mode);
  478.  
  479.         list_for_each_entry_safe(mode, t, &connector->modes, head)
  480.                 drm_mode_remove(connector, mode);
  481.  
  482.         list_for_each_entry_safe(mode, t, &connector->user_modes, head)
  483.                 drm_mode_remove(connector, mode);
  484.  
  485.         kfree(connector->fb_helper_private);
  486.         mutex_lock(&dev->mode_config.mutex);
  487.         drm_mode_object_put(dev, &connector->base);
  488.         list_del(&connector->head);
  489.         mutex_unlock(&dev->mode_config.mutex);
  490. }
  491. EXPORT_SYMBOL(drm_connector_cleanup);
  492.  
  493. void drm_encoder_init(struct drm_device *dev,
  494.                       struct drm_encoder *encoder,
  495.                       const struct drm_encoder_funcs *funcs,
  496.                       int encoder_type)
  497. {
  498.         mutex_lock(&dev->mode_config.mutex);
  499.  
  500.         encoder->dev = dev;
  501.  
  502.         drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
  503.         encoder->encoder_type = encoder_type;
  504.         encoder->funcs = funcs;
  505.  
  506.         list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
  507.         dev->mode_config.num_encoder++;
  508.  
  509.         mutex_unlock(&dev->mode_config.mutex);
  510. }
  511. EXPORT_SYMBOL(drm_encoder_init);
  512.  
  513. void drm_encoder_cleanup(struct drm_encoder *encoder)
  514. {
  515.         struct drm_device *dev = encoder->dev;
  516.         mutex_lock(&dev->mode_config.mutex);
  517.         drm_mode_object_put(dev, &encoder->base);
  518.         list_del(&encoder->head);
  519.         mutex_unlock(&dev->mode_config.mutex);
  520. }
  521. EXPORT_SYMBOL(drm_encoder_cleanup);
  522.  
  523. /**
  524.  * drm_mode_create - create a new display mode
  525.  * @dev: DRM device
  526.  *
  527.  * LOCKING:
  528.  * Caller must hold DRM mode_config lock.
  529.  *
  530.  * Create a new drm_display_mode, give it an ID, and return it.
  531.  *
  532.  * RETURNS:
  533.  * Pointer to new mode on success, NULL on error.
  534.  */
  535. struct drm_display_mode *drm_mode_create(struct drm_device *dev)
  536. {
  537.         struct drm_display_mode *nmode;
  538.  
  539.         nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
  540.         if (!nmode)
  541.                 return NULL;
  542.  
  543.         drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE);
  544.         return nmode;
  545. }
  546. EXPORT_SYMBOL(drm_mode_create);
  547.  
  548. /**
  549.  * drm_mode_destroy - remove a mode
  550.  * @dev: DRM device
  551.  * @mode: mode to remove
  552.  *
  553.  * LOCKING:
  554.  * Caller must hold mode config lock.
  555.  *
  556.  * Free @mode's unique identifier, then free it.
  557.  */
  558. void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
  559. {
  560.         drm_mode_object_put(dev, &mode->base);
  561.  
  562.         kfree(mode);
  563. }
  564. EXPORT_SYMBOL(drm_mode_destroy);
  565.  
  566. static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
  567. {
  568.         struct drm_property *edid;
  569.         struct drm_property *dpms;
  570.         int i;
  571.  
  572.         /*
  573.          * Standard properties (apply to all connectors)
  574.          */
  575.         edid = drm_property_create(dev, DRM_MODE_PROP_BLOB |
  576.                                    DRM_MODE_PROP_IMMUTABLE,
  577.                                    "EDID", 0);
  578.         dev->mode_config.edid_property = edid;
  579.  
  580.         dpms = drm_property_create(dev, DRM_MODE_PROP_ENUM,
  581.                                    "DPMS", ARRAY_SIZE(drm_dpms_enum_list));
  582.         for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++)
  583.                 drm_property_add_enum(dpms, i, drm_dpms_enum_list[i].type,
  584.                                       drm_dpms_enum_list[i].name);
  585.         dev->mode_config.dpms_property = dpms;
  586.  
  587.         return 0;
  588. }
  589.  
  590. /**
  591.  * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
  592.  * @dev: DRM device
  593.  *
  594.  * Called by a driver the first time a DVI-I connector is made.
  595.  */
  596. int drm_mode_create_dvi_i_properties(struct drm_device *dev)
  597. {
  598.         struct drm_property *dvi_i_selector;
  599.         struct drm_property *dvi_i_subconnector;
  600.         int i;
  601.  
  602.         if (dev->mode_config.dvi_i_select_subconnector_property)
  603.                 return 0;
  604.  
  605.         dvi_i_selector =
  606.                 drm_property_create(dev, DRM_MODE_PROP_ENUM,
  607.                                     "select subconnector",
  608.                                     ARRAY_SIZE(drm_dvi_i_select_enum_list));
  609.         for (i = 0; i < ARRAY_SIZE(drm_dvi_i_select_enum_list); i++)
  610.                 drm_property_add_enum(dvi_i_selector, i,
  611.                                       drm_dvi_i_select_enum_list[i].type,
  612.                                       drm_dvi_i_select_enum_list[i].name);
  613.         dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
  614.  
  615.         dvi_i_subconnector =
  616.                 drm_property_create(dev, DRM_MODE_PROP_ENUM |
  617.                                     DRM_MODE_PROP_IMMUTABLE,
  618.                                     "subconnector",
  619.                                     ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
  620.         for (i = 0; i < ARRAY_SIZE(drm_dvi_i_subconnector_enum_list); i++)
  621.                 drm_property_add_enum(dvi_i_subconnector, i,
  622.                                       drm_dvi_i_subconnector_enum_list[i].type,
  623.                                       drm_dvi_i_subconnector_enum_list[i].name);
  624.         dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
  625.  
  626.         return 0;
  627. }
  628. EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
  629.  
  630. /**
  631.  * drm_create_tv_properties - create TV specific connector properties
  632.  * @dev: DRM device
  633.  * @num_modes: number of different TV formats (modes) supported
  634.  * @modes: array of pointers to strings containing name of each format
  635.  *
  636.  * Called by a driver's TV initialization routine, this function creates
  637.  * the TV specific connector properties for a given device.  Caller is
  638.  * responsible for allocating a list of format names and passing them to
  639.  * this routine.
  640.  */
  641. int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
  642.                                   char *modes[])
  643. {
  644.         struct drm_property *tv_selector;
  645.         struct drm_property *tv_subconnector;
  646.         int i;
  647.  
  648.         if (dev->mode_config.tv_select_subconnector_property)
  649.                 return 0;
  650.  
  651.         /*
  652.          * Basic connector properties
  653.          */
  654.         tv_selector = drm_property_create(dev, DRM_MODE_PROP_ENUM,
  655.                                           "select subconnector",
  656.                                           ARRAY_SIZE(drm_tv_select_enum_list));
  657.         for (i = 0; i < ARRAY_SIZE(drm_tv_select_enum_list); i++)
  658.                 drm_property_add_enum(tv_selector, i,
  659.                                       drm_tv_select_enum_list[i].type,
  660.                                       drm_tv_select_enum_list[i].name);
  661.         dev->mode_config.tv_select_subconnector_property = tv_selector;
  662.  
  663.         tv_subconnector =
  664.                 drm_property_create(dev, DRM_MODE_PROP_ENUM |
  665.                                     DRM_MODE_PROP_IMMUTABLE, "subconnector",
  666.                                     ARRAY_SIZE(drm_tv_subconnector_enum_list));
  667.         for (i = 0; i < ARRAY_SIZE(drm_tv_subconnector_enum_list); i++)
  668.                 drm_property_add_enum(tv_subconnector, i,
  669.                                       drm_tv_subconnector_enum_list[i].type,
  670.                                       drm_tv_subconnector_enum_list[i].name);
  671.         dev->mode_config.tv_subconnector_property = tv_subconnector;
  672.  
  673.         /*
  674.          * Other, TV specific properties: margins & TV modes.
  675.          */
  676.         dev->mode_config.tv_left_margin_property =
  677.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  678.                                     "left margin", 2);
  679.         dev->mode_config.tv_left_margin_property->values[0] = 0;
  680.         dev->mode_config.tv_left_margin_property->values[1] = 100;
  681.  
  682.         dev->mode_config.tv_right_margin_property =
  683.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  684.                                     "right margin", 2);
  685.         dev->mode_config.tv_right_margin_property->values[0] = 0;
  686.         dev->mode_config.tv_right_margin_property->values[1] = 100;
  687.  
  688.         dev->mode_config.tv_top_margin_property =
  689.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  690.                                     "top margin", 2);
  691.         dev->mode_config.tv_top_margin_property->values[0] = 0;
  692.         dev->mode_config.tv_top_margin_property->values[1] = 100;
  693.  
  694.         dev->mode_config.tv_bottom_margin_property =
  695.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  696.                                     "bottom margin", 2);
  697.         dev->mode_config.tv_bottom_margin_property->values[0] = 0;
  698.         dev->mode_config.tv_bottom_margin_property->values[1] = 100;
  699.  
  700.         dev->mode_config.tv_mode_property =
  701.                 drm_property_create(dev, DRM_MODE_PROP_ENUM,
  702.                                     "mode", num_modes);
  703.         for (i = 0; i < num_modes; i++)
  704.                 drm_property_add_enum(dev->mode_config.tv_mode_property, i,
  705.                                       i, modes[i]);
  706.  
  707.         dev->mode_config.tv_brightness_property =
  708.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  709.                                     "brightness", 2);
  710.         dev->mode_config.tv_brightness_property->values[0] = 0;
  711.         dev->mode_config.tv_brightness_property->values[1] = 100;
  712.  
  713.         dev->mode_config.tv_contrast_property =
  714.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  715.                                     "contrast", 2);
  716.         dev->mode_config.tv_contrast_property->values[0] = 0;
  717.         dev->mode_config.tv_contrast_property->values[1] = 100;
  718.  
  719.         dev->mode_config.tv_flicker_reduction_property =
  720.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  721.                                     "flicker reduction", 2);
  722.         dev->mode_config.tv_flicker_reduction_property->values[0] = 0;
  723.         dev->mode_config.tv_flicker_reduction_property->values[1] = 100;
  724.  
  725.         dev->mode_config.tv_overscan_property =
  726.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  727.                                     "overscan", 2);
  728.         dev->mode_config.tv_overscan_property->values[0] = 0;
  729.         dev->mode_config.tv_overscan_property->values[1] = 100;
  730.  
  731.         dev->mode_config.tv_saturation_property =
  732.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  733.                                     "saturation", 2);
  734.         dev->mode_config.tv_saturation_property->values[0] = 0;
  735.         dev->mode_config.tv_saturation_property->values[1] = 100;
  736.  
  737.         dev->mode_config.tv_hue_property =
  738.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  739.                                     "hue", 2);
  740.         dev->mode_config.tv_hue_property->values[0] = 0;
  741.         dev->mode_config.tv_hue_property->values[1] = 100;
  742.  
  743.         return 0;
  744. }
  745. EXPORT_SYMBOL(drm_mode_create_tv_properties);
  746.  
  747. /**
  748.  * drm_mode_create_scaling_mode_property - create scaling mode property
  749.  * @dev: DRM device
  750.  *
  751.  * Called by a driver the first time it's needed, must be attached to desired
  752.  * connectors.
  753.  */
  754. int drm_mode_create_scaling_mode_property(struct drm_device *dev)
  755. {
  756.         struct drm_property *scaling_mode;
  757.         int i;
  758.  
  759.         if (dev->mode_config.scaling_mode_property)
  760.                 return 0;
  761.  
  762.         scaling_mode =
  763.                 drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode",
  764.                                     ARRAY_SIZE(drm_scaling_mode_enum_list));
  765.         for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++)
  766.                 drm_property_add_enum(scaling_mode, i,
  767.                                       drm_scaling_mode_enum_list[i].type,
  768.                                       drm_scaling_mode_enum_list[i].name);
  769.  
  770.         dev->mode_config.scaling_mode_property = scaling_mode;
  771.  
  772.         return 0;
  773. }
  774. EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
  775.  
  776. /**
  777.  * drm_mode_create_dithering_property - create dithering property
  778.  * @dev: DRM device
  779.  *
  780.  * Called by a driver the first time it's needed, must be attached to desired
  781.  * connectors.
  782.  */
  783. int drm_mode_create_dithering_property(struct drm_device *dev)
  784. {
  785.         struct drm_property *dithering_mode;
  786.         int i;
  787.  
  788.         if (dev->mode_config.dithering_mode_property)
  789.                 return 0;
  790.  
  791.         dithering_mode =
  792.                 drm_property_create(dev, DRM_MODE_PROP_ENUM, "dithering",
  793.                                     ARRAY_SIZE(drm_dithering_mode_enum_list));
  794.         for (i = 0; i < ARRAY_SIZE(drm_dithering_mode_enum_list); i++)
  795.                 drm_property_add_enum(dithering_mode, i,
  796.                                       drm_dithering_mode_enum_list[i].type,
  797.                                       drm_dithering_mode_enum_list[i].name);
  798.         dev->mode_config.dithering_mode_property = dithering_mode;
  799.  
  800.         return 0;
  801. }
  802. EXPORT_SYMBOL(drm_mode_create_dithering_property);
  803.  
  804. /**
  805.  * drm_mode_config_init - initialize DRM mode_configuration structure
  806.  * @dev: DRM device
  807.  *
  808.  * LOCKING:
  809.  * None, should happen single threaded at init time.
  810.  *
  811.  * Initialize @dev's mode_config structure, used for tracking the graphics
  812.  * configuration of @dev.
  813.  */
  814. void drm_mode_config_init(struct drm_device *dev)
  815. {
  816. //   mutex_init(&dev->mode_config.mutex);
  817. //   mutex_init(&dev->mode_config.idr_mutex);
  818.         INIT_LIST_HEAD(&dev->mode_config.fb_list);
  819.         INIT_LIST_HEAD(&dev->mode_config.fb_kernel_list);
  820.         INIT_LIST_HEAD(&dev->mode_config.crtc_list);
  821.         INIT_LIST_HEAD(&dev->mode_config.connector_list);
  822.         INIT_LIST_HEAD(&dev->mode_config.encoder_list);
  823.         INIT_LIST_HEAD(&dev->mode_config.property_list);
  824.         INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
  825.         idr_init(&dev->mode_config.crtc_idr);
  826.  
  827.         mutex_lock(&dev->mode_config.mutex);
  828.         drm_mode_create_standard_connector_properties(dev);
  829.         mutex_unlock(&dev->mode_config.mutex);
  830.  
  831.         /* Just to be sure */
  832.         dev->mode_config.num_fb = 0;
  833.         dev->mode_config.num_connector = 0;
  834.         dev->mode_config.num_crtc = 0;
  835.         dev->mode_config.num_encoder = 0;
  836. }
  837. EXPORT_SYMBOL(drm_mode_config_init);
  838.  
  839. int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
  840. {
  841.         uint32_t total_objects = 0;
  842.  
  843.         total_objects += dev->mode_config.num_crtc;
  844.         total_objects += dev->mode_config.num_connector;
  845.         total_objects += dev->mode_config.num_encoder;
  846.  
  847.         if (total_objects == 0)
  848.                 return -EINVAL;
  849.  
  850.         group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
  851.         if (!group->id_list)
  852.                 return -ENOMEM;
  853.  
  854.         group->num_crtcs = 0;
  855.         group->num_connectors = 0;
  856.         group->num_encoders = 0;
  857.         return 0;
  858. }
  859.  
  860. int drm_mode_group_init_legacy_group(struct drm_device *dev,
  861.                                      struct drm_mode_group *group)
  862. {
  863.         struct drm_crtc *crtc;
  864.         struct drm_encoder *encoder;
  865.         struct drm_connector *connector;
  866.         int ret;
  867.  
  868.         if ((ret = drm_mode_group_init(dev, group)))
  869.                 return ret;
  870.  
  871.         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
  872.                 group->id_list[group->num_crtcs++] = crtc->base.id;
  873.  
  874.         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
  875.                 group->id_list[group->num_crtcs + group->num_encoders++] =
  876.                 encoder->base.id;
  877.  
  878.         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  879.                 group->id_list[group->num_crtcs + group->num_encoders +
  880.                                group->num_connectors++] = connector->base.id;
  881.  
  882.         return 0;
  883. }
  884.  
  885. /**
  886.  * drm_mode_config_cleanup - free up DRM mode_config info
  887.  * @dev: DRM device
  888.  *
  889.  * LOCKING:
  890.  * Caller must hold mode config lock.
  891.  *
  892.  * Free up all the connectors and CRTCs associated with this DRM device, then
  893.  * free up the framebuffers and associated buffer objects.
  894.  *
  895.  * FIXME: cleanup any dangling user buffer objects too
  896.  */
  897. void drm_mode_config_cleanup(struct drm_device *dev)
  898. {
  899.         struct drm_connector *connector, *ot;
  900.         struct drm_crtc *crtc, *ct;
  901.         struct drm_encoder *encoder, *enct;
  902.         struct drm_framebuffer *fb, *fbt;
  903.         struct drm_property *property, *pt;
  904.  
  905.         list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
  906.                                  head) {
  907.                 encoder->funcs->destroy(encoder);
  908.         }
  909.  
  910.         list_for_each_entry_safe(connector, ot,
  911.                                  &dev->mode_config.connector_list, head) {
  912.                 connector->funcs->destroy(connector);
  913.         }
  914.  
  915.         list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
  916.                                  head) {
  917.                 drm_property_destroy(dev, property);
  918.         }
  919.  
  920.         list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
  921.                 fb->funcs->destroy(fb);
  922.         }
  923.  
  924.         list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
  925.                 crtc->funcs->destroy(crtc);
  926.         }
  927.  
  928. }
  929. EXPORT_SYMBOL(drm_mode_config_cleanup);
  930.  
  931. /**
  932.  * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
  933.  * @out: drm_mode_modeinfo struct to return to the user
  934.  * @in: drm_display_mode to use
  935.  *
  936.  * LOCKING:
  937.  * None.
  938.  *
  939.  * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
  940.  * the user.
  941.  */
  942. void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
  943.                                struct drm_display_mode *in)
  944. {
  945.         out->clock = in->clock;
  946.         out->hdisplay = in->hdisplay;
  947.         out->hsync_start = in->hsync_start;
  948.         out->hsync_end = in->hsync_end;
  949.         out->htotal = in->htotal;
  950.         out->hskew = in->hskew;
  951.         out->vdisplay = in->vdisplay;
  952.         out->vsync_start = in->vsync_start;
  953.         out->vsync_end = in->vsync_end;
  954.         out->vtotal = in->vtotal;
  955.         out->vscan = in->vscan;
  956.         out->vrefresh = in->vrefresh;
  957.         out->flags = in->flags;
  958.         out->type = in->type;
  959.         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
  960.         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
  961. }
  962.  
  963. /**
  964.  * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
  965.  * @out: drm_display_mode to return to the user
  966.  * @in: drm_mode_modeinfo to use
  967.  *
  968.  * LOCKING:
  969.  * None.
  970.  *
  971.  * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
  972.  * the caller.
  973.  */
  974. void drm_crtc_convert_umode(struct drm_display_mode *out,
  975.                             struct drm_mode_modeinfo *in)
  976. {
  977.         out->clock = in->clock;
  978.         out->hdisplay = in->hdisplay;
  979.         out->hsync_start = in->hsync_start;
  980.         out->hsync_end = in->hsync_end;
  981.         out->htotal = in->htotal;
  982.         out->hskew = in->hskew;
  983.         out->vdisplay = in->vdisplay;
  984.         out->vsync_start = in->vsync_start;
  985.         out->vsync_end = in->vsync_end;
  986.         out->vtotal = in->vtotal;
  987.         out->vscan = in->vscan;
  988.         out->vrefresh = in->vrefresh;
  989.         out->flags = in->flags;
  990.         out->type = in->type;
  991.         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
  992.         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
  993. }
  994.  
  995.  
  996. #if 0
  997. /**
  998.  * drm_mode_getresources - get graphics configuration
  999.  * @inode: inode from the ioctl
  1000.  * @filp: file * from the ioctl
  1001.  * @cmd: cmd from ioctl
  1002.  * @arg: arg from ioctl
  1003.  *
  1004.  * LOCKING:
  1005.  * Takes mode config lock.
  1006.  *
  1007.  * Construct a set of configuration description structures and return
  1008.  * them to the user, including CRTC, connector and framebuffer configuration.
  1009.  *
  1010.  * Called by the user via ioctl.
  1011.  *
  1012.  * RETURNS:
  1013.  * Zero on success, errno on failure.
  1014.  */
  1015. int drm_mode_getresources(struct drm_device *dev, void *data,
  1016.                           struct drm_file *file_priv)
  1017. {
  1018.         struct drm_mode_card_res *card_res = data;
  1019.         struct list_head *lh;
  1020.         struct drm_framebuffer *fb;
  1021.         struct drm_connector *connector;
  1022.         struct drm_crtc *crtc;
  1023.         struct drm_encoder *encoder;
  1024.         int ret = 0;
  1025.         int connector_count = 0;
  1026.         int crtc_count = 0;
  1027.         int fb_count = 0;
  1028.         int encoder_count = 0;
  1029.         int copied = 0, i;
  1030.         uint32_t __user *fb_id;
  1031.         uint32_t __user *crtc_id;
  1032.         uint32_t __user *connector_id;
  1033.         uint32_t __user *encoder_id;
  1034.         struct drm_mode_group *mode_group;
  1035.  
  1036.         mutex_lock(&dev->mode_config.mutex);
  1037.  
  1038.         /*
  1039.          * For the non-control nodes we need to limit the list of resources
  1040.          * by IDs in the group list for this node
  1041.          */
  1042.         list_for_each(lh, &file_priv->fbs)
  1043.                 fb_count++;
  1044.  
  1045.         mode_group = &file_priv->master->minor->mode_group;
  1046.         if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
  1047.  
  1048.                 list_for_each(lh, &dev->mode_config.crtc_list)
  1049.                         crtc_count++;
  1050.  
  1051.                 list_for_each(lh, &dev->mode_config.connector_list)
  1052.                         connector_count++;
  1053.  
  1054.                 list_for_each(lh, &dev->mode_config.encoder_list)
  1055.                         encoder_count++;
  1056.         } else {
  1057.  
  1058.                 crtc_count = mode_group->num_crtcs;
  1059.                 connector_count = mode_group->num_connectors;
  1060.                 encoder_count = mode_group->num_encoders;
  1061.         }
  1062.  
  1063.         card_res->max_height = dev->mode_config.max_height;
  1064.         card_res->min_height = dev->mode_config.min_height;
  1065.         card_res->max_width = dev->mode_config.max_width;
  1066.         card_res->min_width = dev->mode_config.min_width;
  1067.  
  1068.         /* handle this in 4 parts */
  1069.         /* FBs */
  1070.         if (card_res->count_fbs >= fb_count) {
  1071.                 copied = 0;
  1072.                 fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
  1073.                 list_for_each_entry(fb, &file_priv->fbs, head) {
  1074.                         if (put_user(fb->base.id, fb_id + copied)) {
  1075.                                 ret = -EFAULT;
  1076.                                 goto out;
  1077.                         }
  1078.                         copied++;
  1079.                 }
  1080.         }
  1081.         card_res->count_fbs = fb_count;
  1082.  
  1083.         /* CRTCs */
  1084.         if (card_res->count_crtcs >= crtc_count) {
  1085.                 copied = 0;
  1086.                 crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
  1087.                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
  1088.                         list_for_each_entry(crtc, &dev->mode_config.crtc_list,
  1089.                                             head) {
  1090.                                 DRM_DEBUG_KMS("CRTC ID is %d\n", crtc->base.id);
  1091.                                 if (put_user(crtc->base.id, crtc_id + copied)) {
  1092.                                         ret = -EFAULT;
  1093.                                         goto out;
  1094.                                 }
  1095.                                 copied++;
  1096.                         }
  1097.                 } else {
  1098.                         for (i = 0; i < mode_group->num_crtcs; i++) {
  1099.                                 if (put_user(mode_group->id_list[i],
  1100.                                              crtc_id + copied)) {
  1101.                                         ret = -EFAULT;
  1102.                                         goto out;
  1103.                                 }
  1104.                                 copied++;
  1105.                         }
  1106.                 }
  1107.         }
  1108.         card_res->count_crtcs = crtc_count;
  1109.  
  1110.         /* Encoders */
  1111.         if (card_res->count_encoders >= encoder_count) {
  1112.                 copied = 0;
  1113.                 encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
  1114.                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
  1115.                         list_for_each_entry(encoder,
  1116.                                             &dev->mode_config.encoder_list,
  1117.                                             head) {
  1118.                                 DRM_DEBUG_KMS("ENCODER ID is %d\n",
  1119.                                           encoder->base.id);
  1120.                                 if (put_user(encoder->base.id, encoder_id +
  1121.                                              copied)) {
  1122.                                         ret = -EFAULT;
  1123.                                         goto out;
  1124.                                 }
  1125.                                 copied++;
  1126.                         }
  1127.                 } else {
  1128.                         for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) {
  1129.                                 if (put_user(mode_group->id_list[i],
  1130.                                              encoder_id + copied)) {
  1131.                                         ret = -EFAULT;
  1132.                                         goto out;
  1133.                                 }
  1134.                                 copied++;
  1135.                         }
  1136.  
  1137.                 }
  1138.         }
  1139.         card_res->count_encoders = encoder_count;
  1140.  
  1141.         /* Connectors */
  1142.         if (card_res->count_connectors >= connector_count) {
  1143.                 copied = 0;
  1144.                 connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
  1145.                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
  1146.                         list_for_each_entry(connector,
  1147.                                             &dev->mode_config.connector_list,
  1148.                                             head) {
  1149.                                 DRM_DEBUG_KMS("CONNECTOR ID is %d\n",
  1150.                                           connector->base.id);
  1151.                                 if (put_user(connector->base.id,
  1152.                                              connector_id + copied)) {
  1153.                                         ret = -EFAULT;
  1154.                                         goto out;
  1155.                                 }
  1156.                                 copied++;
  1157.                         }
  1158.                 } else {
  1159.                         int start = mode_group->num_crtcs +
  1160.                                 mode_group->num_encoders;
  1161.                         for (i = start; i < start + mode_group->num_connectors; i++) {
  1162.                                 if (put_user(mode_group->id_list[i],
  1163.                                              connector_id + copied)) {
  1164.                                         ret = -EFAULT;
  1165.                                         goto out;
  1166.                                 }
  1167.                                 copied++;
  1168.                         }
  1169.                 }
  1170.         }
  1171.         card_res->count_connectors = connector_count;
  1172.  
  1173.         DRM_DEBUG_KMS("Counted %d %d %d\n", card_res->count_crtcs,
  1174.                   card_res->count_connectors, card_res->count_encoders);
  1175.  
  1176. out:
  1177.         mutex_unlock(&dev->mode_config.mutex);
  1178.         return ret;
  1179. }
  1180.  
  1181. /**
  1182.  * drm_mode_getcrtc - get CRTC configuration
  1183.  * @inode: inode from the ioctl
  1184.  * @filp: file * from the ioctl
  1185.  * @cmd: cmd from ioctl
  1186.  * @arg: arg from ioctl
  1187.  *
  1188.  * LOCKING:
  1189.  * Caller? (FIXME)
  1190.  *
  1191.  * Construct a CRTC configuration structure to return to the user.
  1192.  *
  1193.  * Called by the user via ioctl.
  1194.  *
  1195.  * RETURNS:
  1196.  * Zero on success, errno on failure.
  1197.  */
  1198. int drm_mode_getcrtc(struct drm_device *dev,
  1199.                      void *data, struct drm_file *file_priv)
  1200. {
  1201.         struct drm_mode_crtc *crtc_resp = data;
  1202.         struct drm_crtc *crtc;
  1203.         struct drm_mode_object *obj;
  1204.         int ret = 0;
  1205.  
  1206.         mutex_lock(&dev->mode_config.mutex);
  1207.  
  1208.         obj = drm_mode_object_find(dev, crtc_resp->crtc_id,
  1209.                                    DRM_MODE_OBJECT_CRTC);
  1210.         if (!obj) {
  1211.                 ret = -EINVAL;
  1212.                 goto out;
  1213.         }
  1214.         crtc = obj_to_crtc(obj);
  1215.  
  1216.         crtc_resp->x = crtc->x;
  1217.         crtc_resp->y = crtc->y;
  1218.         crtc_resp->gamma_size = crtc->gamma_size;
  1219.         if (crtc->fb)
  1220.                 crtc_resp->fb_id = crtc->fb->base.id;
  1221.         else
  1222.                 crtc_resp->fb_id = 0;
  1223.  
  1224.         if (crtc->enabled) {
  1225.  
  1226.                 drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode);
  1227.                 crtc_resp->mode_valid = 1;
  1228.  
  1229.         } else {
  1230.                 crtc_resp->mode_valid = 0;
  1231.         }
  1232.  
  1233. out:
  1234.         mutex_unlock(&dev->mode_config.mutex);
  1235.         return ret;
  1236. }
  1237.  
  1238. /**
  1239.  * drm_mode_getconnector - get connector configuration
  1240.  * @inode: inode from the ioctl
  1241.  * @filp: file * from the ioctl
  1242.  * @cmd: cmd from ioctl
  1243.  * @arg: arg from ioctl
  1244.  *
  1245.  * LOCKING:
  1246.  * Caller? (FIXME)
  1247.  *
  1248.  * Construct a connector configuration structure to return to the user.
  1249.  *
  1250.  * Called by the user via ioctl.
  1251.  *
  1252.  * RETURNS:
  1253.  * Zero on success, errno on failure.
  1254.  */
  1255. int drm_mode_getconnector(struct drm_device *dev, void *data,
  1256.                           struct drm_file *file_priv)
  1257. {
  1258.         struct drm_mode_get_connector *out_resp = data;
  1259.         struct drm_mode_object *obj;
  1260.         struct drm_connector *connector;
  1261.         struct drm_display_mode *mode;
  1262.         int mode_count = 0;
  1263.         int props_count = 0;
  1264.         int encoders_count = 0;
  1265.         int ret = 0;
  1266.         int copied = 0;
  1267.         int i;
  1268.         struct drm_mode_modeinfo u_mode;
  1269.         struct drm_mode_modeinfo __user *mode_ptr;
  1270.         uint32_t __user *prop_ptr;
  1271.         uint64_t __user *prop_values;
  1272.         uint32_t __user *encoder_ptr;
  1273.  
  1274.         memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
  1275.  
  1276.         DRM_DEBUG_KMS("connector id %d:\n", out_resp->connector_id);
  1277.  
  1278.         mutex_lock(&dev->mode_config.mutex);
  1279.  
  1280.         obj = drm_mode_object_find(dev, out_resp->connector_id,
  1281.                                    DRM_MODE_OBJECT_CONNECTOR);
  1282.         if (!obj) {
  1283.                 ret = -EINVAL;
  1284.                 goto out;
  1285.         }
  1286.         connector = obj_to_connector(obj);
  1287.  
  1288.         for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
  1289.                 if (connector->property_ids[i] != 0) {
  1290.                         props_count++;
  1291.                 }
  1292.         }
  1293.  
  1294.         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
  1295.                 if (connector->encoder_ids[i] != 0) {
  1296.                         encoders_count++;
  1297.                 }
  1298.         }
  1299.  
  1300.         if (out_resp->count_modes == 0) {
  1301.                 connector->funcs->fill_modes(connector,
  1302.                                              dev->mode_config.max_width,
  1303.                                              dev->mode_config.max_height);
  1304.         }
  1305.  
  1306.         /* delayed so we get modes regardless of pre-fill_modes state */
  1307.         list_for_each_entry(mode, &connector->modes, head)
  1308.                 mode_count++;
  1309.  
  1310.         out_resp->connector_id = connector->base.id;
  1311.         out_resp->connector_type = connector->connector_type;
  1312.         out_resp->connector_type_id = connector->connector_type_id;
  1313.         out_resp->mm_width = connector->display_info.width_mm;
  1314.         out_resp->mm_height = connector->display_info.height_mm;
  1315.         out_resp->subpixel = connector->display_info.subpixel_order;
  1316.         out_resp->connection = connector->status;
  1317.         if (connector->encoder)
  1318.                 out_resp->encoder_id = connector->encoder->base.id;
  1319.         else
  1320.                 out_resp->encoder_id = 0;
  1321.  
  1322.         /*
  1323.          * This ioctl is called twice, once to determine how much space is
  1324.          * needed, and the 2nd time to fill it.
  1325.          */
  1326.         if ((out_resp->count_modes >= mode_count) && mode_count) {
  1327.                 copied = 0;
  1328.                 mode_ptr = (struct drm_mode_modeinfo *)(unsigned long)out_resp->modes_ptr;
  1329.                 list_for_each_entry(mode, &connector->modes, head) {
  1330.                         drm_crtc_convert_to_umode(&u_mode, mode);
  1331.                         if (copy_to_user(mode_ptr + copied,
  1332.                                          &u_mode, sizeof(u_mode))) {
  1333.                                 ret = -EFAULT;
  1334.                                 goto out;
  1335.                         }
  1336.                         copied++;
  1337.                 }
  1338.         }
  1339.         out_resp->count_modes = mode_count;
  1340.  
  1341.         if ((out_resp->count_props >= props_count) && props_count) {
  1342.                 copied = 0;
  1343.                 prop_ptr = (uint32_t *)(unsigned long)(out_resp->props_ptr);
  1344.                 prop_values = (uint64_t *)(unsigned long)(out_resp->prop_values_ptr);
  1345.                 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
  1346.                         if (connector->property_ids[i] != 0) {
  1347.                                 if (put_user(connector->property_ids[i],
  1348.                                              prop_ptr + copied)) {
  1349.                                         ret = -EFAULT;
  1350.                                         goto out;
  1351.                                 }
  1352.  
  1353.                                 if (put_user(connector->property_values[i],
  1354.                                              prop_values + copied)) {
  1355.                                         ret = -EFAULT;
  1356.                                         goto out;
  1357.                                 }
  1358.                                 copied++;
  1359.                         }
  1360.                 }
  1361.         }
  1362.         out_resp->count_props = props_count;
  1363.  
  1364.         if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
  1365.                 copied = 0;
  1366.                 encoder_ptr = (uint32_t *)(unsigned long)(out_resp->encoders_ptr);
  1367.                 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
  1368.                         if (connector->encoder_ids[i] != 0) {
  1369.                                 if (put_user(connector->encoder_ids[i],
  1370.                                              encoder_ptr + copied)) {
  1371.                                         ret = -EFAULT;
  1372.                                         goto out;
  1373.                                 }
  1374.                                 copied++;
  1375.                         }
  1376.                 }
  1377.         }
  1378.         out_resp->count_encoders = encoders_count;
  1379.  
  1380. out:
  1381.         mutex_unlock(&dev->mode_config.mutex);
  1382.         return ret;
  1383. }
  1384.  
  1385. int drm_mode_getencoder(struct drm_device *dev, void *data,
  1386.                         struct drm_file *file_priv)
  1387. {
  1388.         struct drm_mode_get_encoder *enc_resp = data;
  1389.         struct drm_mode_object *obj;
  1390.         struct drm_encoder *encoder;
  1391.         int ret = 0;
  1392.  
  1393.         mutex_lock(&dev->mode_config.mutex);
  1394.         obj = drm_mode_object_find(dev, enc_resp->encoder_id,
  1395.                                    DRM_MODE_OBJECT_ENCODER);
  1396.         if (!obj) {
  1397.                 ret = -EINVAL;
  1398.                 goto out;
  1399.         }
  1400.         encoder = obj_to_encoder(obj);
  1401.  
  1402.         if (encoder->crtc)
  1403.                 enc_resp->crtc_id = encoder->crtc->base.id;
  1404.         else
  1405.                 enc_resp->crtc_id = 0;
  1406.         enc_resp->encoder_type = encoder->encoder_type;
  1407.         enc_resp->encoder_id = encoder->base.id;
  1408.         enc_resp->possible_crtcs = encoder->possible_crtcs;
  1409.         enc_resp->possible_clones = encoder->possible_clones;
  1410.  
  1411. out:
  1412.         mutex_unlock(&dev->mode_config.mutex);
  1413.         return ret;
  1414. }
  1415.  
  1416. /**
  1417.  * drm_mode_setcrtc - set CRTC configuration
  1418.  * @inode: inode from the ioctl
  1419.  * @filp: file * from the ioctl
  1420.  * @cmd: cmd from ioctl
  1421.  * @arg: arg from ioctl
  1422.  *
  1423.  * LOCKING:
  1424.  * Caller? (FIXME)
  1425.  *
  1426.  * Build a new CRTC configuration based on user request.
  1427.  *
  1428.  * Called by the user via ioctl.
  1429.  *
  1430.  * RETURNS:
  1431.  * Zero on success, errno on failure.
  1432.  */
  1433. int drm_mode_setcrtc(struct drm_device *dev, void *data,
  1434.                      struct drm_file *file_priv)
  1435. {
  1436.         struct drm_mode_config *config = &dev->mode_config;
  1437.         struct drm_mode_crtc *crtc_req = data;
  1438.         struct drm_mode_object *obj;
  1439.         struct drm_crtc *crtc, *crtcfb;
  1440.         struct drm_connector **connector_set = NULL, *connector;
  1441.         struct drm_framebuffer *fb = NULL;
  1442.         struct drm_display_mode *mode = NULL;
  1443.         struct drm_mode_set set;
  1444.         uint32_t __user *set_connectors_ptr;
  1445.         int ret = 0;
  1446.         int i;
  1447.  
  1448.         mutex_lock(&dev->mode_config.mutex);
  1449.         obj = drm_mode_object_find(dev, crtc_req->crtc_id,
  1450.                                    DRM_MODE_OBJECT_CRTC);
  1451.         if (!obj) {
  1452.                 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
  1453.                 ret = -EINVAL;
  1454.                 goto out;
  1455.         }
  1456.         crtc = obj_to_crtc(obj);
  1457.  
  1458.         if (crtc_req->mode_valid) {
  1459.                 /* If we have a mode we need a framebuffer. */
  1460.                 /* If we pass -1, set the mode with the currently bound fb */
  1461.                 if (crtc_req->fb_id == -1) {
  1462.                         list_for_each_entry(crtcfb,
  1463.                                             &dev->mode_config.crtc_list, head) {
  1464.                                 if (crtcfb == crtc) {
  1465.                                         DRM_DEBUG_KMS("Using current fb for "
  1466.                                                         "setmode\n");
  1467.                                         fb = crtc->fb;
  1468.                                 }
  1469.                         }
  1470.                 } else {
  1471.                         obj = drm_mode_object_find(dev, crtc_req->fb_id,
  1472.                                                    DRM_MODE_OBJECT_FB);
  1473.                         if (!obj) {
  1474.                                 DRM_DEBUG_KMS("Unknown FB ID%d\n",
  1475.                                                 crtc_req->fb_id);
  1476.                                 ret = -EINVAL;
  1477.                                 goto out;
  1478.                         }
  1479.                         fb = obj_to_fb(obj);
  1480.                 }
  1481.  
  1482.                 mode = drm_mode_create(dev);
  1483.                 drm_crtc_convert_umode(mode, &crtc_req->mode);
  1484.                 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
  1485.         }
  1486.  
  1487.         if (crtc_req->count_connectors == 0 && mode) {
  1488.                 DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
  1489.                 ret = -EINVAL;
  1490.                 goto out;
  1491.         }
  1492.  
  1493.         if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
  1494.                 DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
  1495.                           crtc_req->count_connectors);
  1496.                 ret = -EINVAL;
  1497.                 goto out;
  1498.         }
  1499.  
  1500.         if (crtc_req->count_connectors > 0) {
  1501.                 u32 out_id;
  1502.  
  1503.                 /* Avoid unbounded kernel memory allocation */
  1504.                 if (crtc_req->count_connectors > config->num_connector) {
  1505.                         ret = -EINVAL;
  1506.                         goto out;
  1507.                 }
  1508.  
  1509.                 connector_set = kmalloc(crtc_req->count_connectors *
  1510.                                         sizeof(struct drm_connector *),
  1511.                                         GFP_KERNEL);
  1512.                 if (!connector_set) {
  1513.                         ret = -ENOMEM;
  1514.                         goto out;
  1515.                 }
  1516.  
  1517.                 for (i = 0; i < crtc_req->count_connectors; i++) {
  1518.                         set_connectors_ptr = (uint32_t *)(unsigned long)crtc_req->set_connectors_ptr;
  1519.                         if (get_user(out_id, &set_connectors_ptr[i])) {
  1520.                                 ret = -EFAULT;
  1521.                                 goto out;
  1522.                         }
  1523.  
  1524.                         obj = drm_mode_object_find(dev, out_id,
  1525.                                                    DRM_MODE_OBJECT_CONNECTOR);
  1526.                         if (!obj) {
  1527.                                 DRM_DEBUG_KMS("Connector id %d unknown\n",
  1528.                                                 out_id);
  1529.                                 ret = -EINVAL;
  1530.                                 goto out;
  1531.                         }
  1532.                         connector = obj_to_connector(obj);
  1533.  
  1534.                         connector_set[i] = connector;
  1535.                 }
  1536.         }
  1537.  
  1538.         set.crtc = crtc;
  1539.         set.x = crtc_req->x;
  1540.         set.y = crtc_req->y;
  1541.         set.mode = mode;
  1542.         set.connectors = connector_set;
  1543.         set.num_connectors = crtc_req->count_connectors;
  1544.         set.fb = fb;
  1545.         ret = crtc->funcs->set_config(&set);
  1546.  
  1547. out:
  1548.         kfree(connector_set);
  1549.         mutex_unlock(&dev->mode_config.mutex);
  1550.         return ret;
  1551. }
  1552.  
  1553. int drm_mode_cursor_ioctl(struct drm_device *dev,
  1554.                         void *data, struct drm_file *file_priv)
  1555. {
  1556.         struct drm_mode_cursor *req = data;
  1557.         struct drm_mode_object *obj;
  1558.         struct drm_crtc *crtc;
  1559.         int ret = 0;
  1560.  
  1561.         if (!req->flags) {
  1562.                 DRM_ERROR("no operation set\n");
  1563.                 return -EINVAL;
  1564.         }
  1565.  
  1566.         mutex_lock(&dev->mode_config.mutex);
  1567.         obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
  1568.         if (!obj) {
  1569.                 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
  1570.                 ret = -EINVAL;
  1571.                 goto out;
  1572.         }
  1573.         crtc = obj_to_crtc(obj);
  1574.  
  1575.         if (req->flags & DRM_MODE_CURSOR_BO) {
  1576.                 if (!crtc->funcs->cursor_set) {
  1577.                         DRM_ERROR("crtc does not support cursor\n");
  1578.                         ret = -ENXIO;
  1579.                         goto out;
  1580.                 }
  1581.                 /* Turns off the cursor if handle is 0 */
  1582.                 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
  1583.                                               req->width, req->height);
  1584.         }
  1585.  
  1586.         if (req->flags & DRM_MODE_CURSOR_MOVE) {
  1587.                 if (crtc->funcs->cursor_move) {
  1588.                         ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
  1589.                 } else {
  1590.                         DRM_ERROR("crtc does not support cursor\n");
  1591.                         ret = -EFAULT;
  1592.                         goto out;
  1593.                 }
  1594.         }
  1595. out:
  1596.         mutex_unlock(&dev->mode_config.mutex);
  1597.         return ret;
  1598. }
  1599.  
  1600. /**
  1601.  * drm_mode_addfb - add an FB to the graphics configuration
  1602.  * @inode: inode from the ioctl
  1603.  * @filp: file * from the ioctl
  1604.  * @cmd: cmd from ioctl
  1605.  * @arg: arg from ioctl
  1606.  *
  1607.  * LOCKING:
  1608.  * Takes mode config lock.
  1609.  *
  1610.  * Add a new FB to the specified CRTC, given a user request.
  1611.  *
  1612.  * Called by the user via ioctl.
  1613.  *
  1614.  * RETURNS:
  1615.  * Zero on success, errno on failure.
  1616.  */
  1617. int drm_mode_addfb(struct drm_device *dev,
  1618.                    void *data, struct drm_file *file_priv)
  1619. {
  1620.         struct drm_mode_fb_cmd *r = data;
  1621.         struct drm_mode_config *config = &dev->mode_config;
  1622.         struct drm_framebuffer *fb;
  1623.         int ret = 0;
  1624.  
  1625.         if ((config->min_width > r->width) || (r->width > config->max_width)) {
  1626.                 DRM_ERROR("mode new framebuffer width not within limits\n");
  1627.                 return -EINVAL;
  1628.         }
  1629.         if ((config->min_height > r->height) || (r->height > config->max_height)) {
  1630.                 DRM_ERROR("mode new framebuffer height not within limits\n");
  1631.                 return -EINVAL;
  1632.         }
  1633.  
  1634.         mutex_lock(&dev->mode_config.mutex);
  1635.  
  1636.         /* TODO check buffer is sufficently large */
  1637.         /* TODO setup destructor callback */
  1638.  
  1639.         fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
  1640.         if (!fb) {
  1641.                 DRM_ERROR("could not create framebuffer\n");
  1642.                 ret = -EINVAL;
  1643.                 goto out;
  1644.         }
  1645.  
  1646.         r->fb_id = fb->base.id;
  1647.         list_add(&fb->filp_head, &file_priv->fbs);
  1648.  
  1649. out:
  1650.         mutex_unlock(&dev->mode_config.mutex);
  1651.         return ret;
  1652. }
  1653.  
  1654. /**
  1655.  * drm_mode_rmfb - remove an FB from the configuration
  1656.  * @inode: inode from the ioctl
  1657.  * @filp: file * from the ioctl
  1658.  * @cmd: cmd from ioctl
  1659.  * @arg: arg from ioctl
  1660.  *
  1661.  * LOCKING:
  1662.  * Takes mode config lock.
  1663.  *
  1664.  * Remove the FB specified by the user.
  1665.  *
  1666.  * Called by the user via ioctl.
  1667.  *
  1668.  * RETURNS:
  1669.  * Zero on success, errno on failure.
  1670.  */
  1671. int drm_mode_rmfb(struct drm_device *dev,
  1672.                    void *data, struct drm_file *file_priv)
  1673. {
  1674.         struct drm_mode_object *obj;
  1675.         struct drm_framebuffer *fb = NULL;
  1676.         struct drm_framebuffer *fbl = NULL;
  1677.         uint32_t *id = data;
  1678.         int ret = 0;
  1679.         int found = 0;
  1680.  
  1681.         mutex_lock(&dev->mode_config.mutex);
  1682.         obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB);
  1683.         /* TODO check that we realy get a framebuffer back. */
  1684.         if (!obj) {
  1685.                 DRM_ERROR("mode invalid framebuffer id\n");
  1686.                 ret = -EINVAL;
  1687.                 goto out;
  1688.         }
  1689.         fb = obj_to_fb(obj);
  1690.  
  1691.         list_for_each_entry(fbl, &file_priv->fbs, filp_head)
  1692.                 if (fb == fbl)
  1693.                         found = 1;
  1694.  
  1695.         if (!found) {
  1696.                 DRM_ERROR("tried to remove a fb that we didn't own\n");
  1697.                 ret = -EINVAL;
  1698.                 goto out;
  1699.         }
  1700.  
  1701.         /* TODO release all crtc connected to the framebuffer */
  1702.         /* TODO unhock the destructor from the buffer object */
  1703.  
  1704.         list_del(&fb->filp_head);
  1705.         fb->funcs->destroy(fb);
  1706.  
  1707. out:
  1708.         mutex_unlock(&dev->mode_config.mutex);
  1709.         return ret;
  1710. }
  1711.  
  1712. /**
  1713.  * drm_mode_getfb - get FB info
  1714.  * @inode: inode from the ioctl
  1715.  * @filp: file * from the ioctl
  1716.  * @cmd: cmd from ioctl
  1717.  * @arg: arg from ioctl
  1718.  *
  1719.  * LOCKING:
  1720.  * Caller? (FIXME)
  1721.  *
  1722.  * Lookup the FB given its ID and return info about it.
  1723.  *
  1724.  * Called by the user via ioctl.
  1725.  *
  1726.  * RETURNS:
  1727.  * Zero on success, errno on failure.
  1728.  */
  1729. int drm_mode_getfb(struct drm_device *dev,
  1730.                    void *data, struct drm_file *file_priv)
  1731. {
  1732.         struct drm_mode_fb_cmd *r = data;
  1733.         struct drm_mode_object *obj;
  1734.         struct drm_framebuffer *fb;
  1735.         int ret = 0;
  1736.  
  1737.         mutex_lock(&dev->mode_config.mutex);
  1738.         obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
  1739.         if (!obj) {
  1740.                 DRM_ERROR("invalid framebuffer id\n");
  1741.                 ret = -EINVAL;
  1742.                 goto out;
  1743.         }
  1744.         fb = obj_to_fb(obj);
  1745.  
  1746.         r->height = fb->height;
  1747.         r->width = fb->width;
  1748.         r->depth = fb->depth;
  1749.         r->bpp = fb->bits_per_pixel;
  1750.         r->pitch = fb->pitch;
  1751.         fb->funcs->create_handle(fb, file_priv, &r->handle);
  1752.  
  1753. out:
  1754.         mutex_unlock(&dev->mode_config.mutex);
  1755.         return ret;
  1756. }
  1757.  
  1758. /**
  1759.  * drm_fb_release - remove and free the FBs on this file
  1760.  * @filp: file * from the ioctl
  1761.  *
  1762.  * LOCKING:
  1763.  * Takes mode config lock.
  1764.  *
  1765.  * Destroy all the FBs associated with @filp.
  1766.  *
  1767.  * Called by the user via ioctl.
  1768.  *
  1769.  * RETURNS:
  1770.  * Zero on success, errno on failure.
  1771.  */
  1772. void drm_fb_release(struct drm_file *priv)
  1773. {
  1774.         struct drm_device *dev = priv->minor->dev;
  1775.         struct drm_framebuffer *fb, *tfb;
  1776.  
  1777.         mutex_lock(&dev->mode_config.mutex);
  1778.         list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
  1779.                 list_del(&fb->filp_head);
  1780.                 fb->funcs->destroy(fb);
  1781.         }
  1782.         mutex_unlock(&dev->mode_config.mutex);
  1783. }
  1784. #endif
  1785.  
  1786. /**
  1787.  * drm_mode_attachmode - add a mode to the user mode list
  1788.  * @dev: DRM device
  1789.  * @connector: connector to add the mode to
  1790.  * @mode: mode to add
  1791.  *
  1792.  * Add @mode to @connector's user mode list.
  1793.  */
  1794. static int drm_mode_attachmode(struct drm_device *dev,
  1795.                                struct drm_connector *connector,
  1796.                                struct drm_display_mode *mode)
  1797. {
  1798.         int ret = 0;
  1799.  
  1800.         list_add_tail(&mode->head, &connector->user_modes);
  1801.         return ret;
  1802. }
  1803.  
  1804. int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
  1805.                              struct drm_display_mode *mode)
  1806. {
  1807.         struct drm_connector *connector;
  1808.         int ret = 0;
  1809.         struct drm_display_mode *dup_mode;
  1810.         int need_dup = 0;
  1811.         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
  1812.                 if (!connector->encoder)
  1813.                         break;
  1814.                 if (connector->encoder->crtc == crtc) {
  1815.                         if (need_dup)
  1816.                                 dup_mode = drm_mode_duplicate(dev, mode);
  1817.                         else
  1818.                                 dup_mode = mode;
  1819.                         ret = drm_mode_attachmode(dev, connector, dup_mode);
  1820.                         if (ret)
  1821.                                 return ret;
  1822.                         need_dup = 1;
  1823.                 }
  1824.         }
  1825.         return 0;
  1826. }
  1827. EXPORT_SYMBOL(drm_mode_attachmode_crtc);
  1828.  
  1829. static int drm_mode_detachmode(struct drm_device *dev,
  1830.                                struct drm_connector *connector,
  1831.                                struct drm_display_mode *mode)
  1832. {
  1833.         int found = 0;
  1834.         int ret = 0;
  1835.         struct drm_display_mode *match_mode, *t;
  1836.  
  1837.         list_for_each_entry_safe(match_mode, t, &connector->user_modes, head) {
  1838.                 if (drm_mode_equal(match_mode, mode)) {
  1839.                         list_del(&match_mode->head);
  1840.                         drm_mode_destroy(dev, match_mode);
  1841.                         found = 1;
  1842.                         break;
  1843.                 }
  1844.         }
  1845.  
  1846.         if (!found)
  1847.                 ret = -EINVAL;
  1848.  
  1849.         return ret;
  1850. }
  1851.  
  1852. int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode)
  1853. {
  1854.         struct drm_connector *connector;
  1855.  
  1856.         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
  1857.                 drm_mode_detachmode(dev, connector, mode);
  1858.         }
  1859.         return 0;
  1860. }
  1861. EXPORT_SYMBOL(drm_mode_detachmode_crtc);
  1862.  
  1863. #if 0
  1864.  
  1865. /**
  1866.  * drm_fb_attachmode - Attach a user mode to an connector
  1867.  * @inode: inode from the ioctl
  1868.  * @filp: file * from the ioctl
  1869.  * @cmd: cmd from ioctl
  1870.  * @arg: arg from ioctl
  1871.  *
  1872.  * This attaches a user specified mode to an connector.
  1873.  * Called by the user via ioctl.
  1874.  *
  1875.  * RETURNS:
  1876.  * Zero on success, errno on failure.
  1877.  */
  1878. int drm_mode_attachmode_ioctl(struct drm_device *dev,
  1879.                               void *data, struct drm_file *file_priv)
  1880. {
  1881.         struct drm_mode_mode_cmd *mode_cmd = data;
  1882.         struct drm_connector *connector;
  1883.         struct drm_display_mode *mode;
  1884.         struct drm_mode_object *obj;
  1885.         struct drm_mode_modeinfo *umode = &mode_cmd->mode;
  1886.         int ret = 0;
  1887.  
  1888.         mutex_lock(&dev->mode_config.mutex);
  1889.  
  1890.         obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
  1891.         if (!obj) {
  1892.                 ret = -EINVAL;
  1893.                 goto out;
  1894.         }
  1895.         connector = obj_to_connector(obj);
  1896.  
  1897.         mode = drm_mode_create(dev);
  1898.         if (!mode) {
  1899.                 ret = -ENOMEM;
  1900.                 goto out;
  1901.         }
  1902.  
  1903.         drm_crtc_convert_umode(mode, umode);
  1904.  
  1905.         ret = drm_mode_attachmode(dev, connector, mode);
  1906. out:
  1907.         mutex_unlock(&dev->mode_config.mutex);
  1908.         return ret;
  1909. }
  1910.  
  1911.  
  1912. /**
  1913.  * drm_fb_detachmode - Detach a user specified mode from an connector
  1914.  * @inode: inode from the ioctl
  1915.  * @filp: file * from the ioctl
  1916.  * @cmd: cmd from ioctl
  1917.  * @arg: arg from ioctl
  1918.  *
  1919.  * Called by the user via ioctl.
  1920.  *
  1921.  * RETURNS:
  1922.  * Zero on success, errno on failure.
  1923.  */
  1924. int drm_mode_detachmode_ioctl(struct drm_device *dev,
  1925.                               void *data, struct drm_file *file_priv)
  1926. {
  1927.         struct drm_mode_object *obj;
  1928.         struct drm_mode_mode_cmd *mode_cmd = data;
  1929.         struct drm_connector *connector;
  1930.         struct drm_display_mode mode;
  1931.         struct drm_mode_modeinfo *umode = &mode_cmd->mode;
  1932.         int ret = 0;
  1933.  
  1934.         mutex_lock(&dev->mode_config.mutex);
  1935.  
  1936.         obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
  1937.         if (!obj) {
  1938.                 ret = -EINVAL;
  1939.                 goto out;
  1940.         }
  1941.         connector = obj_to_connector(obj);
  1942.  
  1943.         drm_crtc_convert_umode(&mode, umode);
  1944.         ret = drm_mode_detachmode(dev, connector, &mode);
  1945. out:
  1946.         mutex_unlock(&dev->mode_config.mutex);
  1947.         return ret;
  1948. }
  1949. #endif
  1950.  
  1951. struct drm_property *drm_property_create(struct drm_device *dev, int flags,
  1952.                                          const char *name, int num_values)
  1953. {
  1954.         struct drm_property *property = NULL;
  1955.  
  1956.         property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
  1957.         if (!property)
  1958.                 return NULL;
  1959.  
  1960.         if (num_values) {
  1961.                 property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
  1962.                 if (!property->values)
  1963.                         goto fail;
  1964.         }
  1965.  
  1966.         drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
  1967.         property->flags = flags;
  1968.         property->num_values = num_values;
  1969.         INIT_LIST_HEAD(&property->enum_blob_list);
  1970.  
  1971.         if (name)
  1972.                 strncpy(property->name, name, DRM_PROP_NAME_LEN);
  1973.  
  1974.         list_add_tail(&property->head, &dev->mode_config.property_list);
  1975.         return property;
  1976. fail:
  1977.         kfree(property);
  1978.         return NULL;
  1979. }
  1980. EXPORT_SYMBOL(drm_property_create);
  1981.  
  1982. int drm_property_add_enum(struct drm_property *property, int index,
  1983.                           uint64_t value, const char *name)
  1984. {
  1985.         struct drm_property_enum *prop_enum;
  1986.  
  1987.         if (!(property->flags & DRM_MODE_PROP_ENUM))
  1988.                 return -EINVAL;
  1989.  
  1990.         if (!list_empty(&property->enum_blob_list)) {
  1991.                 list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
  1992.                         if (prop_enum->value == value) {
  1993.                                 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
  1994.                                 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
  1995.                                 return 0;
  1996.                         }
  1997.                 }
  1998.         }
  1999.  
  2000.         prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
  2001.         if (!prop_enum)
  2002.                 return -ENOMEM;
  2003.  
  2004.         strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
  2005.         prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
  2006.         prop_enum->value = value;
  2007.  
  2008.         property->values[index] = value;
  2009.         list_add_tail(&prop_enum->head, &property->enum_blob_list);
  2010.         return 0;
  2011. }
  2012. EXPORT_SYMBOL(drm_property_add_enum);
  2013.  
  2014. void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
  2015. {
  2016.         struct drm_property_enum *prop_enum, *pt;
  2017.  
  2018.         list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) {
  2019.                 list_del(&prop_enum->head);
  2020.                 kfree(prop_enum);
  2021.         }
  2022.  
  2023.         if (property->num_values)
  2024.                 kfree(property->values);
  2025.         drm_mode_object_put(dev, &property->base);
  2026.         list_del(&property->head);
  2027.         kfree(property);
  2028. }
  2029. EXPORT_SYMBOL(drm_property_destroy);
  2030.  
  2031. int drm_connector_attach_property(struct drm_connector *connector,
  2032.                                struct drm_property *property, uint64_t init_val)
  2033. {
  2034.         int i;
  2035.  
  2036.         for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
  2037.                 if (connector->property_ids[i] == 0) {
  2038.                         connector->property_ids[i] = property->base.id;
  2039.                         connector->property_values[i] = init_val;
  2040.                         break;
  2041.                 }
  2042.         }
  2043.  
  2044.         if (i == DRM_CONNECTOR_MAX_PROPERTY)
  2045.                 return -EINVAL;
  2046.         return 0;
  2047. }
  2048. EXPORT_SYMBOL(drm_connector_attach_property);
  2049.  
  2050. int drm_connector_property_set_value(struct drm_connector *connector,
  2051.                                   struct drm_property *property, uint64_t value)
  2052. {
  2053.         int i;
  2054.  
  2055.         for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
  2056.                 if (connector->property_ids[i] == property->base.id) {
  2057.                         connector->property_values[i] = value;
  2058.                         break;
  2059.                 }
  2060.         }
  2061.  
  2062.         if (i == DRM_CONNECTOR_MAX_PROPERTY)
  2063.                 return -EINVAL;
  2064.         return 0;
  2065. }
  2066. EXPORT_SYMBOL(drm_connector_property_set_value);
  2067.  
  2068. int drm_connector_property_get_value(struct drm_connector *connector,
  2069.                                   struct drm_property *property, uint64_t *val)
  2070. {
  2071.         int i;
  2072.  
  2073.         for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
  2074.                 if (connector->property_ids[i] == property->base.id) {
  2075.                         *val = connector->property_values[i];
  2076.                         break;
  2077.                 }
  2078.         }
  2079.  
  2080.         if (i == DRM_CONNECTOR_MAX_PROPERTY)
  2081.                 return -EINVAL;
  2082.         return 0;
  2083. }
  2084. EXPORT_SYMBOL(drm_connector_property_get_value);
  2085.  
  2086. #if 0
  2087. int drm_mode_getproperty_ioctl(struct drm_device *dev,
  2088.                                void *data, struct drm_file *file_priv)
  2089. {
  2090.         struct drm_mode_object *obj;
  2091.         struct drm_mode_get_property *out_resp = data;
  2092.         struct drm_property *property;
  2093.         int enum_count = 0;
  2094.         int blob_count = 0;
  2095.         int value_count = 0;
  2096.         int ret = 0, i;
  2097.         int copied;
  2098.         struct drm_property_enum *prop_enum;
  2099.         struct drm_mode_property_enum __user *enum_ptr;
  2100.         struct drm_property_blob *prop_blob;
  2101.         uint32_t *blob_id_ptr;
  2102.         uint64_t __user *values_ptr;
  2103.         uint32_t __user *blob_length_ptr;
  2104.  
  2105.         mutex_lock(&dev->mode_config.mutex);
  2106.         obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
  2107.         if (!obj) {
  2108.                 ret = -EINVAL;
  2109.                 goto done;
  2110.         }
  2111.         property = obj_to_property(obj);
  2112.  
  2113.         if (property->flags & DRM_MODE_PROP_ENUM) {
  2114.                 list_for_each_entry(prop_enum, &property->enum_blob_list, head)
  2115.                         enum_count++;
  2116.         } else if (property->flags & DRM_MODE_PROP_BLOB) {
  2117.                 list_for_each_entry(prop_blob, &property->enum_blob_list, head)
  2118.                         blob_count++;
  2119.         }
  2120.  
  2121.         value_count = property->num_values;
  2122.  
  2123.         strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
  2124.         out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
  2125.         out_resp->flags = property->flags;
  2126.  
  2127.         if ((out_resp->count_values >= value_count) && value_count) {
  2128.                 values_ptr = (uint64_t *)(unsigned long)out_resp->values_ptr;
  2129.                 for (i = 0; i < value_count; i++) {
  2130.                         if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
  2131.                                 ret = -EFAULT;
  2132.                                 goto done;
  2133.                         }
  2134.                 }
  2135.         }
  2136.         out_resp->count_values = value_count;
  2137.  
  2138.         if (property->flags & DRM_MODE_PROP_ENUM) {
  2139.                 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
  2140.                         copied = 0;
  2141.                         enum_ptr = (struct drm_mode_property_enum *)(unsigned long)out_resp->enum_blob_ptr;
  2142.                         list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
  2143.  
  2144.                                 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
  2145.                                         ret = -EFAULT;
  2146.                                         goto done;
  2147.                                 }
  2148.  
  2149.                                 if (copy_to_user(&enum_ptr[copied].name,
  2150.                                                  &prop_enum->name, DRM_PROP_NAME_LEN)) {
  2151.                                         ret = -EFAULT;
  2152.                                         goto done;
  2153.                                 }
  2154.                                 copied++;
  2155.                         }
  2156.                 }
  2157.                 out_resp->count_enum_blobs = enum_count;
  2158.         }
  2159.  
  2160.         if (property->flags & DRM_MODE_PROP_BLOB) {
  2161.                 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
  2162.                         copied = 0;
  2163.                         blob_id_ptr = (uint32_t *)(unsigned long)out_resp->enum_blob_ptr;
  2164.                         blob_length_ptr = (uint32_t *)(unsigned long)out_resp->values_ptr;
  2165.  
  2166.                         list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
  2167.                                 if (put_user(prop_blob->base.id, blob_id_ptr + copied)) {
  2168.                                         ret = -EFAULT;
  2169.                                         goto done;
  2170.                                 }
  2171.  
  2172.                                 if (put_user(prop_blob->length, blob_length_ptr + copied)) {
  2173.                                         ret = -EFAULT;
  2174.                                         goto done;
  2175.                                 }
  2176.  
  2177.                                 copied++;
  2178.                         }
  2179.                 }
  2180.                 out_resp->count_enum_blobs = blob_count;
  2181.         }
  2182. done:
  2183.         mutex_unlock(&dev->mode_config.mutex);
  2184.         return ret;
  2185. }
  2186. #endif
  2187.  
  2188. static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,
  2189.                                                           void *data)
  2190. {
  2191.         struct drm_property_blob *blob;
  2192.  
  2193.         if (!length || !data)
  2194.                 return NULL;
  2195.  
  2196.         blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
  2197.         if (!blob)
  2198.                 return NULL;
  2199.  
  2200.         blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob));
  2201.         blob->length = length;
  2202.  
  2203.         memcpy(blob->data, data, length);
  2204.  
  2205.         drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
  2206.  
  2207.         list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
  2208.         return blob;
  2209. }
  2210.  
  2211. static void drm_property_destroy_blob(struct drm_device *dev,
  2212.                                struct drm_property_blob *blob)
  2213. {
  2214.         drm_mode_object_put(dev, &blob->base);
  2215.         list_del(&blob->head);
  2216.         kfree(blob);
  2217. }
  2218.  
  2219. #if 0
  2220. int drm_mode_getblob_ioctl(struct drm_device *dev,
  2221.                            void *data, struct drm_file *file_priv)
  2222. {
  2223.         struct drm_mode_object *obj;
  2224.         struct drm_mode_get_blob *out_resp = data;
  2225.         struct drm_property_blob *blob;
  2226.         int ret = 0;
  2227.         void *blob_ptr;
  2228.  
  2229.         mutex_lock(&dev->mode_config.mutex);
  2230.         obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB);
  2231.         if (!obj) {
  2232.                 ret = -EINVAL;
  2233.                 goto done;
  2234.         }
  2235.         blob = obj_to_blob(obj);
  2236.  
  2237.         if (out_resp->length == blob->length) {
  2238.                 blob_ptr = (void *)(unsigned long)out_resp->data;
  2239.                 if (copy_to_user(blob_ptr, blob->data, blob->length)){
  2240.                         ret = -EFAULT;
  2241.                         goto done;
  2242.                 }
  2243.         }
  2244.         out_resp->length = blob->length;
  2245.  
  2246. done:
  2247.         mutex_unlock(&dev->mode_config.mutex);
  2248.         return ret;
  2249. }
  2250. #endif
  2251.  
  2252. int drm_mode_connector_update_edid_property(struct drm_connector *connector,
  2253.                                             struct edid *edid)
  2254. {
  2255.         struct drm_device *dev = connector->dev;
  2256.         int ret = 0;
  2257.  
  2258.         if (connector->edid_blob_ptr)
  2259.                 drm_property_destroy_blob(dev, connector->edid_blob_ptr);
  2260.  
  2261.         /* Delete edid, when there is none. */
  2262.         if (!edid) {
  2263.                 connector->edid_blob_ptr = NULL;
  2264.                 ret = drm_connector_property_set_value(connector, dev->mode_config.edid_property, 0);
  2265.                 return ret;
  2266.         }
  2267.  
  2268.         connector->edid_blob_ptr = drm_property_create_blob(connector->dev, 128, edid);
  2269.  
  2270.         ret = drm_connector_property_set_value(connector,
  2271.                                                dev->mode_config.edid_property,
  2272.                                                connector->edid_blob_ptr->base.id);
  2273.  
  2274.         return ret;
  2275. }
  2276. EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
  2277.  
  2278. #if 0
  2279. int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
  2280.                                        void *data, struct drm_file *file_priv)
  2281. {
  2282.         struct drm_mode_connector_set_property *out_resp = data;
  2283.         struct drm_mode_object *obj;
  2284.         struct drm_property *property;
  2285.         struct drm_connector *connector;
  2286.         int ret = -EINVAL;
  2287.         int i;
  2288.  
  2289.         mutex_lock(&dev->mode_config.mutex);
  2290.  
  2291.         obj = drm_mode_object_find(dev, out_resp->connector_id, DRM_MODE_OBJECT_CONNECTOR);
  2292.         if (!obj) {
  2293.                 goto out;
  2294.         }
  2295.         connector = obj_to_connector(obj);
  2296.  
  2297.         for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
  2298.                 if (connector->property_ids[i] == out_resp->prop_id)
  2299.                         break;
  2300.         }
  2301.  
  2302.         if (i == DRM_CONNECTOR_MAX_PROPERTY) {
  2303.                 goto out;
  2304.         }
  2305.  
  2306.         obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
  2307.         if (!obj) {
  2308.                 goto out;
  2309.         }
  2310.         property = obj_to_property(obj);
  2311.  
  2312.         if (property->flags & DRM_MODE_PROP_IMMUTABLE)
  2313.                 goto out;
  2314.  
  2315.         if (property->flags & DRM_MODE_PROP_RANGE) {
  2316.                 if (out_resp->value < property->values[0])
  2317.                         goto out;
  2318.  
  2319.                 if (out_resp->value > property->values[1])
  2320.                         goto out;
  2321.         } else {
  2322.                 int found = 0;
  2323.                 for (i = 0; i < property->num_values; i++) {
  2324.                         if (property->values[i] == out_resp->value) {
  2325.                                 found = 1;
  2326.                                 break;
  2327.                         }
  2328.                 }
  2329.                 if (!found) {
  2330.                         goto out;
  2331.                 }
  2332.         }
  2333.  
  2334.         /* Do DPMS ourselves */
  2335.         if (property == connector->dev->mode_config.dpms_property) {
  2336.                 if (connector->funcs->dpms)
  2337.                         (*connector->funcs->dpms)(connector, (int) out_resp->value);
  2338.                 ret = 0;
  2339.         } else if (connector->funcs->set_property)
  2340.                 ret = connector->funcs->set_property(connector, property, out_resp->value);
  2341.  
  2342.         /* store the property value if succesful */
  2343.         if (!ret)
  2344.                 drm_connector_property_set_value(connector, property, out_resp->value);
  2345. out:
  2346.         mutex_unlock(&dev->mode_config.mutex);
  2347.         return ret;
  2348. }
  2349. #endif
  2350.  
  2351. int drm_mode_connector_attach_encoder(struct drm_connector *connector,
  2352.                                       struct drm_encoder *encoder)
  2353. {
  2354.         int i;
  2355.  
  2356.         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
  2357.                 if (connector->encoder_ids[i] == 0) {
  2358.                         connector->encoder_ids[i] = encoder->base.id;
  2359.                         return 0;
  2360.                 }
  2361.         }
  2362.         return -ENOMEM;
  2363. }
  2364. EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
  2365.  
  2366. void drm_mode_connector_detach_encoder(struct drm_connector *connector,
  2367.                                     struct drm_encoder *encoder)
  2368. {
  2369.         int i;
  2370.         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
  2371.                 if (connector->encoder_ids[i] == encoder->base.id) {
  2372.                         connector->encoder_ids[i] = 0;
  2373.                         if (connector->encoder == encoder)
  2374.                                 connector->encoder = NULL;
  2375.                         break;
  2376.                 }
  2377.         }
  2378. }
  2379. EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
  2380.  
  2381. bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
  2382.                                   int gamma_size)
  2383. {
  2384.         crtc->gamma_size = gamma_size;
  2385.  
  2386.         crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
  2387.         if (!crtc->gamma_store) {
  2388.                 crtc->gamma_size = 0;
  2389.                 return false;
  2390.         }
  2391.  
  2392.         return true;
  2393. }
  2394. EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
  2395.  
  2396. #if 0
  2397. int drm_mode_gamma_set_ioctl(struct drm_device *dev,
  2398.                              void *data, struct drm_file *file_priv)
  2399. {
  2400.         struct drm_mode_crtc_lut *crtc_lut = data;
  2401.         struct drm_mode_object *obj;
  2402.         struct drm_crtc *crtc;
  2403.         void *r_base, *g_base, *b_base;
  2404.         int size;
  2405.         int ret = 0;
  2406.  
  2407.         mutex_lock(&dev->mode_config.mutex);
  2408.         obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
  2409.         if (!obj) {
  2410.                 ret = -EINVAL;
  2411.                 goto out;
  2412.         }
  2413.         crtc = obj_to_crtc(obj);
  2414.  
  2415.         /* memcpy into gamma store */
  2416.         if (crtc_lut->gamma_size != crtc->gamma_size) {
  2417.                 ret = -EINVAL;
  2418.                 goto out;
  2419.         }
  2420.  
  2421.         size = crtc_lut->gamma_size * (sizeof(uint16_t));
  2422.         r_base = crtc->gamma_store;
  2423.         if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) {
  2424.                 ret = -EFAULT;
  2425.                 goto out;
  2426.         }
  2427.  
  2428.         g_base = r_base + size;
  2429.         if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) {
  2430.                 ret = -EFAULT;
  2431.                 goto out;
  2432.         }
  2433.  
  2434.         b_base = g_base + size;
  2435.         if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) {
  2436.                 ret = -EFAULT;
  2437.                 goto out;
  2438.         }
  2439.  
  2440.         crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, crtc->gamma_size);
  2441.  
  2442. out:
  2443.         mutex_unlock(&dev->mode_config.mutex);
  2444.         return ret;
  2445.  
  2446. }
  2447.  
  2448. int drm_mode_gamma_get_ioctl(struct drm_device *dev,
  2449.                              void *data, struct drm_file *file_priv)
  2450. {
  2451.         struct drm_mode_crtc_lut *crtc_lut = data;
  2452.         struct drm_mode_object *obj;
  2453.         struct drm_crtc *crtc;
  2454.         void *r_base, *g_base, *b_base;
  2455.         int size;
  2456.         int ret = 0;
  2457.  
  2458.         mutex_lock(&dev->mode_config.mutex);
  2459.         obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
  2460.         if (!obj) {
  2461.                 ret = -EINVAL;
  2462.                 goto out;
  2463.         }
  2464.         crtc = obj_to_crtc(obj);
  2465.  
  2466.         /* memcpy into gamma store */
  2467.         if (crtc_lut->gamma_size != crtc->gamma_size) {
  2468.                 ret = -EINVAL;
  2469.                 goto out;
  2470.         }
  2471.  
  2472.         size = crtc_lut->gamma_size * (sizeof(uint16_t));
  2473.         r_base = crtc->gamma_store;
  2474.         if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) {
  2475.                 ret = -EFAULT;
  2476.                 goto out;
  2477.         }
  2478.  
  2479.         g_base = r_base + size;
  2480.         if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) {
  2481.                 ret = -EFAULT;
  2482.                 goto out;
  2483.         }
  2484.  
  2485.         b_base = g_base + size;
  2486.         if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) {
  2487.                 ret = -EFAULT;
  2488.                 goto out;
  2489.         }
  2490. out:
  2491.         mutex_unlock(&dev->mode_config.mutex);
  2492.         return ret;
  2493. }
  2494.  
  2495. #endif
  2496.  
  2497.  
  2498.