Subversion Repositories Kolibri OS

Rev

Rev 1126 | Rev 1221 | 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.         mutex_lock(&dev->mode_config.mutex);
  486.         drm_mode_object_put(dev, &connector->base);
  487.         list_del(&connector->head);
  488.         mutex_unlock(&dev->mode_config.mutex);
  489. }
  490. EXPORT_SYMBOL(drm_connector_cleanup);
  491.  
  492. void drm_encoder_init(struct drm_device *dev,
  493.                       struct drm_encoder *encoder,
  494.                       const struct drm_encoder_funcs *funcs,
  495.                       int encoder_type)
  496. {
  497.         mutex_lock(&dev->mode_config.mutex);
  498.  
  499.         encoder->dev = dev;
  500.  
  501.         drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
  502.         encoder->encoder_type = encoder_type;
  503.         encoder->funcs = funcs;
  504.  
  505.         list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
  506.         dev->mode_config.num_encoder++;
  507.  
  508.         mutex_unlock(&dev->mode_config.mutex);
  509. }
  510. EXPORT_SYMBOL(drm_encoder_init);
  511.  
  512. void drm_encoder_cleanup(struct drm_encoder *encoder)
  513. {
  514.         struct drm_device *dev = encoder->dev;
  515.         mutex_lock(&dev->mode_config.mutex);
  516.         drm_mode_object_put(dev, &encoder->base);
  517.         list_del(&encoder->head);
  518.         mutex_unlock(&dev->mode_config.mutex);
  519. }
  520. EXPORT_SYMBOL(drm_encoder_cleanup);
  521.  
  522. /**
  523.  * drm_mode_create - create a new display mode
  524.  * @dev: DRM device
  525.  *
  526.  * LOCKING:
  527.  * Caller must hold DRM mode_config lock.
  528.  *
  529.  * Create a new drm_display_mode, give it an ID, and return it.
  530.  *
  531.  * RETURNS:
  532.  * Pointer to new mode on success, NULL on error.
  533.  */
  534. struct drm_display_mode *drm_mode_create(struct drm_device *dev)
  535. {
  536.         struct drm_display_mode *nmode;
  537.  
  538.         nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
  539.         if (!nmode)
  540.                 return NULL;
  541.  
  542.         drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE);
  543.         return nmode;
  544. }
  545. EXPORT_SYMBOL(drm_mode_create);
  546.  
  547. /**
  548.  * drm_mode_destroy - remove a mode
  549.  * @dev: DRM device
  550.  * @mode: mode to remove
  551.  *
  552.  * LOCKING:
  553.  * Caller must hold mode config lock.
  554.  *
  555.  * Free @mode's unique identifier, then free it.
  556.  */
  557. void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
  558. {
  559.         drm_mode_object_put(dev, &mode->base);
  560.  
  561.         kfree(mode);
  562. }
  563. EXPORT_SYMBOL(drm_mode_destroy);
  564.  
  565. static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
  566. {
  567.         struct drm_property *edid;
  568.         struct drm_property *dpms;
  569.         int i;
  570.  
  571.         /*
  572.          * Standard properties (apply to all connectors)
  573.          */
  574.         edid = drm_property_create(dev, DRM_MODE_PROP_BLOB |
  575.                                    DRM_MODE_PROP_IMMUTABLE,
  576.                                    "EDID", 0);
  577.         dev->mode_config.edid_property = edid;
  578.  
  579.         dpms = drm_property_create(dev, DRM_MODE_PROP_ENUM,
  580.                                    "DPMS", ARRAY_SIZE(drm_dpms_enum_list));
  581.         for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++)
  582.                 drm_property_add_enum(dpms, i, drm_dpms_enum_list[i].type,
  583.                                       drm_dpms_enum_list[i].name);
  584.         dev->mode_config.dpms_property = dpms;
  585.  
  586.         return 0;
  587. }
  588.  
  589. /**
  590.  * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
  591.  * @dev: DRM device
  592.  *
  593.  * Called by a driver the first time a DVI-I connector is made.
  594.  */
  595. int drm_mode_create_dvi_i_properties(struct drm_device *dev)
  596. {
  597.         struct drm_property *dvi_i_selector;
  598.         struct drm_property *dvi_i_subconnector;
  599.         int i;
  600.  
  601.         if (dev->mode_config.dvi_i_select_subconnector_property)
  602.                 return 0;
  603.  
  604.         dvi_i_selector =
  605.                 drm_property_create(dev, DRM_MODE_PROP_ENUM,
  606.                                     "select subconnector",
  607.                                     ARRAY_SIZE(drm_dvi_i_select_enum_list));
  608.         for (i = 0; i < ARRAY_SIZE(drm_dvi_i_select_enum_list); i++)
  609.                 drm_property_add_enum(dvi_i_selector, i,
  610.                                       drm_dvi_i_select_enum_list[i].type,
  611.                                       drm_dvi_i_select_enum_list[i].name);
  612.         dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
  613.  
  614.         dvi_i_subconnector =
  615.                 drm_property_create(dev, DRM_MODE_PROP_ENUM |
  616.                                     DRM_MODE_PROP_IMMUTABLE,
  617.                                     "subconnector",
  618.                                     ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
  619.         for (i = 0; i < ARRAY_SIZE(drm_dvi_i_subconnector_enum_list); i++)
  620.                 drm_property_add_enum(dvi_i_subconnector, i,
  621.                                       drm_dvi_i_subconnector_enum_list[i].type,
  622.                                       drm_dvi_i_subconnector_enum_list[i].name);
  623.         dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
  624.  
  625.         return 0;
  626. }
  627. EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
  628.  
  629. /**
  630.  * drm_create_tv_properties - create TV specific connector properties
  631.  * @dev: DRM device
  632.  * @num_modes: number of different TV formats (modes) supported
  633.  * @modes: array of pointers to strings containing name of each format
  634.  *
  635.  * Called by a driver's TV initialization routine, this function creates
  636.  * the TV specific connector properties for a given device.  Caller is
  637.  * responsible for allocating a list of format names and passing them to
  638.  * this routine.
  639.  */
  640. int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
  641.                                   char *modes[])
  642. {
  643.         struct drm_property *tv_selector;
  644.         struct drm_property *tv_subconnector;
  645.         int i;
  646.  
  647.         if (dev->mode_config.tv_select_subconnector_property)
  648.                 return 0;
  649.  
  650.         /*
  651.          * Basic connector properties
  652.          */
  653.         tv_selector = drm_property_create(dev, DRM_MODE_PROP_ENUM,
  654.                                           "select subconnector",
  655.                                           ARRAY_SIZE(drm_tv_select_enum_list));
  656.         for (i = 0; i < ARRAY_SIZE(drm_tv_select_enum_list); i++)
  657.                 drm_property_add_enum(tv_selector, i,
  658.                                       drm_tv_select_enum_list[i].type,
  659.                                       drm_tv_select_enum_list[i].name);
  660.         dev->mode_config.tv_select_subconnector_property = tv_selector;
  661.  
  662.         tv_subconnector =
  663.                 drm_property_create(dev, DRM_MODE_PROP_ENUM |
  664.                                     DRM_MODE_PROP_IMMUTABLE, "subconnector",
  665.                                     ARRAY_SIZE(drm_tv_subconnector_enum_list));
  666.         for (i = 0; i < ARRAY_SIZE(drm_tv_subconnector_enum_list); i++)
  667.                 drm_property_add_enum(tv_subconnector, i,
  668.                                       drm_tv_subconnector_enum_list[i].type,
  669.                                       drm_tv_subconnector_enum_list[i].name);
  670.         dev->mode_config.tv_subconnector_property = tv_subconnector;
  671.  
  672.         /*
  673.          * Other, TV specific properties: margins & TV modes.
  674.          */
  675.         dev->mode_config.tv_left_margin_property =
  676.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  677.                                     "left margin", 2);
  678.         dev->mode_config.tv_left_margin_property->values[0] = 0;
  679.         dev->mode_config.tv_left_margin_property->values[1] = 100;
  680.  
  681.         dev->mode_config.tv_right_margin_property =
  682.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  683.                                     "right margin", 2);
  684.         dev->mode_config.tv_right_margin_property->values[0] = 0;
  685.         dev->mode_config.tv_right_margin_property->values[1] = 100;
  686.  
  687.         dev->mode_config.tv_top_margin_property =
  688.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  689.                                     "top margin", 2);
  690.         dev->mode_config.tv_top_margin_property->values[0] = 0;
  691.         dev->mode_config.tv_top_margin_property->values[1] = 100;
  692.  
  693.         dev->mode_config.tv_bottom_margin_property =
  694.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  695.                                     "bottom margin", 2);
  696.         dev->mode_config.tv_bottom_margin_property->values[0] = 0;
  697.         dev->mode_config.tv_bottom_margin_property->values[1] = 100;
  698.  
  699.         dev->mode_config.tv_mode_property =
  700.                 drm_property_create(dev, DRM_MODE_PROP_ENUM,
  701.                                     "mode", num_modes);
  702.         for (i = 0; i < num_modes; i++)
  703.                 drm_property_add_enum(dev->mode_config.tv_mode_property, i,
  704.                                       i, modes[i]);
  705.  
  706.         dev->mode_config.tv_brightness_property =
  707.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  708.                                     "brightness", 2);
  709.         dev->mode_config.tv_brightness_property->values[0] = 0;
  710.         dev->mode_config.tv_brightness_property->values[1] = 100;
  711.  
  712.         dev->mode_config.tv_contrast_property =
  713.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  714.                                     "contrast", 2);
  715.         dev->mode_config.tv_contrast_property->values[0] = 0;
  716.         dev->mode_config.tv_contrast_property->values[1] = 100;
  717.  
  718.         dev->mode_config.tv_flicker_reduction_property =
  719.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  720.                                     "flicker reduction", 2);
  721.         dev->mode_config.tv_flicker_reduction_property->values[0] = 0;
  722.         dev->mode_config.tv_flicker_reduction_property->values[1] = 100;
  723.  
  724.         dev->mode_config.tv_overscan_property =
  725.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  726.                                     "overscan", 2);
  727.         dev->mode_config.tv_overscan_property->values[0] = 0;
  728.         dev->mode_config.tv_overscan_property->values[1] = 100;
  729.  
  730.         dev->mode_config.tv_saturation_property =
  731.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  732.                                     "saturation", 2);
  733.         dev->mode_config.tv_saturation_property->values[0] = 0;
  734.         dev->mode_config.tv_saturation_property->values[1] = 100;
  735.  
  736.         dev->mode_config.tv_hue_property =
  737.                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
  738.                                     "hue", 2);
  739.         dev->mode_config.tv_hue_property->values[0] = 0;
  740.         dev->mode_config.tv_hue_property->values[1] = 100;
  741.  
  742.         return 0;
  743. }
  744. EXPORT_SYMBOL(drm_mode_create_tv_properties);
  745.  
  746. /**
  747.  * drm_mode_create_scaling_mode_property - create scaling mode property
  748.  * @dev: DRM device
  749.  *
  750.  * Called by a driver the first time it's needed, must be attached to desired
  751.  * connectors.
  752.  */
  753. int drm_mode_create_scaling_mode_property(struct drm_device *dev)
  754. {
  755.         struct drm_property *scaling_mode;
  756.         int i;
  757.  
  758.         if (dev->mode_config.scaling_mode_property)
  759.                 return 0;
  760.  
  761.         scaling_mode =
  762.                 drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode",
  763.                                     ARRAY_SIZE(drm_scaling_mode_enum_list));
  764.         for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++)
  765.                 drm_property_add_enum(scaling_mode, i,
  766.                                       drm_scaling_mode_enum_list[i].type,
  767.                                       drm_scaling_mode_enum_list[i].name);
  768.  
  769.         dev->mode_config.scaling_mode_property = scaling_mode;
  770.  
  771.         return 0;
  772. }
  773. EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
  774.  
  775. /**
  776.  * drm_mode_create_dithering_property - create dithering property
  777.  * @dev: DRM device
  778.  *
  779.  * Called by a driver the first time it's needed, must be attached to desired
  780.  * connectors.
  781.  */
  782. int drm_mode_create_dithering_property(struct drm_device *dev)
  783. {
  784.         struct drm_property *dithering_mode;
  785.         int i;
  786.  
  787.         if (dev->mode_config.dithering_mode_property)
  788.                 return 0;
  789.  
  790.         dithering_mode =
  791.                 drm_property_create(dev, DRM_MODE_PROP_ENUM, "dithering",
  792.                                     ARRAY_SIZE(drm_dithering_mode_enum_list));
  793.         for (i = 0; i < ARRAY_SIZE(drm_dithering_mode_enum_list); i++)
  794.                 drm_property_add_enum(dithering_mode, i,
  795.                                       drm_dithering_mode_enum_list[i].type,
  796.                                       drm_dithering_mode_enum_list[i].name);
  797.         dev->mode_config.dithering_mode_property = dithering_mode;
  798.  
  799.         return 0;
  800. }
  801. EXPORT_SYMBOL(drm_mode_create_dithering_property);
  802.  
  803. /**
  804.  * drm_mode_config_init - initialize DRM mode_configuration structure
  805.  * @dev: DRM device
  806.  *
  807.  * LOCKING:
  808.  * None, should happen single threaded at init time.
  809.  *
  810.  * Initialize @dev's mode_config structure, used for tracking the graphics
  811.  * configuration of @dev.
  812.  */
  813. void drm_mode_config_init(struct drm_device *dev)
  814. {
  815. //   mutex_init(&dev->mode_config.mutex);
  816. //   mutex_init(&dev->mode_config.idr_mutex);
  817.         INIT_LIST_HEAD(&dev->mode_config.fb_list);
  818.         INIT_LIST_HEAD(&dev->mode_config.fb_kernel_list);
  819.         INIT_LIST_HEAD(&dev->mode_config.crtc_list);
  820.         INIT_LIST_HEAD(&dev->mode_config.connector_list);
  821.         INIT_LIST_HEAD(&dev->mode_config.encoder_list);
  822.         INIT_LIST_HEAD(&dev->mode_config.property_list);
  823.         INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
  824.         idr_init(&dev->mode_config.crtc_idr);
  825.  
  826.         mutex_lock(&dev->mode_config.mutex);
  827.         drm_mode_create_standard_connector_properties(dev);
  828.         mutex_unlock(&dev->mode_config.mutex);
  829.  
  830.         /* Just to be sure */
  831.         dev->mode_config.num_fb = 0;
  832.         dev->mode_config.num_connector = 0;
  833.         dev->mode_config.num_crtc = 0;
  834.         dev->mode_config.num_encoder = 0;
  835. }
  836. EXPORT_SYMBOL(drm_mode_config_init);
  837.  
  838. int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
  839. {
  840.         uint32_t total_objects = 0;
  841.  
  842.         total_objects += dev->mode_config.num_crtc;
  843.         total_objects += dev->mode_config.num_connector;
  844.         total_objects += dev->mode_config.num_encoder;
  845.  
  846.         if (total_objects == 0)
  847.                 return -EINVAL;
  848.  
  849.         group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
  850.         if (!group->id_list)
  851.                 return -ENOMEM;
  852.  
  853.         group->num_crtcs = 0;
  854.         group->num_connectors = 0;
  855.         group->num_encoders = 0;
  856.         return 0;
  857. }
  858.  
  859. int drm_mode_group_init_legacy_group(struct drm_device *dev,
  860.                                      struct drm_mode_group *group)
  861. {
  862.         struct drm_crtc *crtc;
  863.         struct drm_encoder *encoder;
  864.         struct drm_connector *connector;
  865.         int ret;
  866.  
  867.         if ((ret = drm_mode_group_init(dev, group)))
  868.                 return ret;
  869.  
  870.         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
  871.                 group->id_list[group->num_crtcs++] = crtc->base.id;
  872.  
  873.         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
  874.                 group->id_list[group->num_crtcs + group->num_encoders++] =
  875.                 encoder->base.id;
  876.  
  877.         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  878.                 group->id_list[group->num_crtcs + group->num_encoders +
  879.                                group->num_connectors++] = connector->base.id;
  880.  
  881.         return 0;
  882. }
  883.  
  884. /**
  885.  * drm_mode_config_cleanup - free up DRM mode_config info
  886.  * @dev: DRM device
  887.  *
  888.  * LOCKING:
  889.  * Caller must hold mode config lock.
  890.  *
  891.  * Free up all the connectors and CRTCs associated with this DRM device, then
  892.  * free up the framebuffers and associated buffer objects.
  893.  *
  894.  * FIXME: cleanup any dangling user buffer objects too
  895.  */
  896. void drm_mode_config_cleanup(struct drm_device *dev)
  897. {
  898.         struct drm_connector *connector, *ot;
  899.         struct drm_crtc *crtc, *ct;
  900.         struct drm_encoder *encoder, *enct;
  901.         struct drm_framebuffer *fb, *fbt;
  902.         struct drm_property *property, *pt;
  903.  
  904.         list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
  905.                                  head) {
  906.                 encoder->funcs->destroy(encoder);
  907.         }
  908.  
  909.         list_for_each_entry_safe(connector, ot,
  910.                                  &dev->mode_config.connector_list, head) {
  911.                 connector->funcs->destroy(connector);
  912.         }
  913.  
  914.         list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
  915.                                  head) {
  916.                 drm_property_destroy(dev, property);
  917.         }
  918.  
  919.         list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
  920.                 fb->funcs->destroy(fb);
  921.         }
  922.  
  923.         list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
  924.                 crtc->funcs->destroy(crtc);
  925.         }
  926.  
  927. }
  928. EXPORT_SYMBOL(drm_mode_config_cleanup);
  929.  
  930. /**
  931.  * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
  932.  * @out: drm_mode_modeinfo struct to return to the user
  933.  * @in: drm_display_mode to use
  934.  *
  935.  * LOCKING:
  936.  * None.
  937.  *
  938.  * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
  939.  * the user.
  940.  */
  941. void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
  942.                                struct drm_display_mode *in)
  943. {
  944.         out->clock = in->clock;
  945.         out->hdisplay = in->hdisplay;
  946.         out->hsync_start = in->hsync_start;
  947.         out->hsync_end = in->hsync_end;
  948.         out->htotal = in->htotal;
  949.         out->hskew = in->hskew;
  950.         out->vdisplay = in->vdisplay;
  951.         out->vsync_start = in->vsync_start;
  952.         out->vsync_end = in->vsync_end;
  953.         out->vtotal = in->vtotal;
  954.         out->vscan = in->vscan;
  955.         out->vrefresh = in->vrefresh;
  956.         out->flags = in->flags;
  957.         out->type = in->type;
  958.         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
  959.         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
  960. }
  961.  
  962. /**
  963.  * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
  964.  * @out: drm_display_mode to return to the user
  965.  * @in: drm_mode_modeinfo to use
  966.  *
  967.  * LOCKING:
  968.  * None.
  969.  *
  970.  * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
  971.  * the caller.
  972.  */
  973. void drm_crtc_convert_umode(struct drm_display_mode *out,
  974.                             struct drm_mode_modeinfo *in)
  975. {
  976.         out->clock = in->clock;
  977.         out->hdisplay = in->hdisplay;
  978.         out->hsync_start = in->hsync_start;
  979.         out->hsync_end = in->hsync_end;
  980.         out->htotal = in->htotal;
  981.         out->hskew = in->hskew;
  982.         out->vdisplay = in->vdisplay;
  983.         out->vsync_start = in->vsync_start;
  984.         out->vsync_end = in->vsync_end;
  985.         out->vtotal = in->vtotal;
  986.         out->vscan = in->vscan;
  987.         out->vrefresh = in->vrefresh;
  988.         out->flags = in->flags;
  989.         out->type = in->type;
  990.         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
  991.         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
  992. }
  993.  
  994.  
  995. #if 0
  996. /**
  997.  * drm_mode_getresources - get graphics configuration
  998.  * @inode: inode from the ioctl
  999.  * @filp: file * from the ioctl
  1000.  * @cmd: cmd from ioctl
  1001.  * @arg: arg from ioctl
  1002.  *
  1003.  * LOCKING:
  1004.  * Takes mode config lock.
  1005.  *
  1006.  * Construct a set of configuration description structures and return
  1007.  * them to the user, including CRTC, connector and framebuffer configuration.
  1008.  *
  1009.  * Called by the user via ioctl.
  1010.  *
  1011.  * RETURNS:
  1012.  * Zero on success, errno on failure.
  1013.  */
  1014. int drm_mode_getresources(struct drm_device *dev, void *data,
  1015.                           struct drm_file *file_priv)
  1016. {
  1017.         struct drm_mode_card_res *card_res = data;
  1018.         struct list_head *lh;
  1019.         struct drm_framebuffer *fb;
  1020.         struct drm_connector *connector;
  1021.         struct drm_crtc *crtc;
  1022.         struct drm_encoder *encoder;
  1023.         int ret = 0;
  1024.         int connector_count = 0;
  1025.         int crtc_count = 0;
  1026.         int fb_count = 0;
  1027.         int encoder_count = 0;
  1028.         int copied = 0, i;
  1029.         uint32_t __user *fb_id;
  1030.         uint32_t __user *crtc_id;
  1031.         uint32_t __user *connector_id;
  1032.         uint32_t __user *encoder_id;
  1033.         struct drm_mode_group *mode_group;
  1034.  
  1035.         mutex_lock(&dev->mode_config.mutex);
  1036.  
  1037.         /*
  1038.          * For the non-control nodes we need to limit the list of resources
  1039.          * by IDs in the group list for this node
  1040.          */
  1041.         list_for_each(lh, &file_priv->fbs)
  1042.                 fb_count++;
  1043.  
  1044.         mode_group = &file_priv->master->minor->mode_group;
  1045.         if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
  1046.  
  1047.                 list_for_each(lh, &dev->mode_config.crtc_list)
  1048.                         crtc_count++;
  1049.  
  1050.                 list_for_each(lh, &dev->mode_config.connector_list)
  1051.                         connector_count++;
  1052.  
  1053.                 list_for_each(lh, &dev->mode_config.encoder_list)
  1054.                         encoder_count++;
  1055.         } else {
  1056.  
  1057.                 crtc_count = mode_group->num_crtcs;
  1058.                 connector_count = mode_group->num_connectors;
  1059.                 encoder_count = mode_group->num_encoders;
  1060.         }
  1061.  
  1062.         card_res->max_height = dev->mode_config.max_height;
  1063.         card_res->min_height = dev->mode_config.min_height;
  1064.         card_res->max_width = dev->mode_config.max_width;
  1065.         card_res->min_width = dev->mode_config.min_width;
  1066.  
  1067.         /* handle this in 4 parts */
  1068.         /* FBs */
  1069.         if (card_res->count_fbs >= fb_count) {
  1070.                 copied = 0;
  1071.                 fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
  1072.                 list_for_each_entry(fb, &file_priv->fbs, head) {
  1073.                         if (put_user(fb->base.id, fb_id + copied)) {
  1074.                                 ret = -EFAULT;
  1075.                                 goto out;
  1076.                         }
  1077.                         copied++;
  1078.                 }
  1079.         }
  1080.         card_res->count_fbs = fb_count;
  1081.  
  1082.         /* CRTCs */
  1083.         if (card_res->count_crtcs >= crtc_count) {
  1084.                 copied = 0;
  1085.                 crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
  1086.                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
  1087.                         list_for_each_entry(crtc, &dev->mode_config.crtc_list,
  1088.                                             head) {
  1089.                                 DRM_DEBUG_KMS("CRTC ID is %d\n", crtc->base.id);
  1090.                                 if (put_user(crtc->base.id, crtc_id + copied)) {
  1091.                                         ret = -EFAULT;
  1092.                                         goto out;
  1093.                                 }
  1094.                                 copied++;
  1095.                         }
  1096.                 } else {
  1097.                         for (i = 0; i < mode_group->num_crtcs; i++) {
  1098.                                 if (put_user(mode_group->id_list[i],
  1099.                                              crtc_id + copied)) {
  1100.                                         ret = -EFAULT;
  1101.                                         goto out;
  1102.                                 }
  1103.                                 copied++;
  1104.                         }
  1105.                 }
  1106.         }
  1107.         card_res->count_crtcs = crtc_count;
  1108.  
  1109.         /* Encoders */
  1110.         if (card_res->count_encoders >= encoder_count) {
  1111.                 copied = 0;
  1112.                 encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
  1113.                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
  1114.                         list_for_each_entry(encoder,
  1115.                                             &dev->mode_config.encoder_list,
  1116.                                             head) {
  1117.                                 DRM_DEBUG_KMS("ENCODER ID is %d\n",
  1118.                                           encoder->base.id);
  1119.                                 if (put_user(encoder->base.id, encoder_id +
  1120.                                              copied)) {
  1121.                                         ret = -EFAULT;
  1122.                                         goto out;
  1123.                                 }
  1124.                                 copied++;
  1125.                         }
  1126.                 } else {
  1127.                         for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) {
  1128.                                 if (put_user(mode_group->id_list[i],
  1129.                                              encoder_id + copied)) {
  1130.                                         ret = -EFAULT;
  1131.                                         goto out;
  1132.                                 }
  1133.                                 copied++;
  1134.                         }
  1135.  
  1136.                 }
  1137.         }
  1138.         card_res->count_encoders = encoder_count;
  1139.  
  1140.         /* Connectors */
  1141.         if (card_res->count_connectors >= connector_count) {
  1142.                 copied = 0;
  1143.                 connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
  1144.                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
  1145.                         list_for_each_entry(connector,
  1146.                                             &dev->mode_config.connector_list,
  1147.                                             head) {
  1148.                                 DRM_DEBUG_KMS("CONNECTOR ID is %d\n",
  1149.                                           connector->base.id);
  1150.                                 if (put_user(connector->base.id,
  1151.                                              connector_id + copied)) {
  1152.                                         ret = -EFAULT;
  1153.                                         goto out;
  1154.                                 }
  1155.                                 copied++;
  1156.                         }
  1157.                 } else {
  1158.                         int start = mode_group->num_crtcs +
  1159.                                 mode_group->num_encoders;
  1160.                         for (i = start; i < start + mode_group->num_connectors; i++) {
  1161.                                 if (put_user(mode_group->id_list[i],
  1162.                                              connector_id + copied)) {
  1163.                                         ret = -EFAULT;
  1164.                                         goto out;
  1165.                                 }
  1166.                                 copied++;
  1167.                         }
  1168.                 }
  1169.         }
  1170.         card_res->count_connectors = connector_count;
  1171.  
  1172.         DRM_DEBUG_KMS("Counted %d %d %d\n", card_res->count_crtcs,
  1173.                   card_res->count_connectors, card_res->count_encoders);
  1174.  
  1175. out:
  1176.         mutex_unlock(&dev->mode_config.mutex);
  1177.         return ret;
  1178. }
  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.         DRM_DEBUG_KMS("\n");
  1562.  
  1563.         if (!req->flags) {
  1564.                 DRM_ERROR("no operation set\n");
  1565.                 return -EINVAL;
  1566.         }
  1567.  
  1568.         mutex_lock(&dev->mode_config.mutex);
  1569.         obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
  1570.         if (!obj) {
  1571.                 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
  1572.                 ret = -EINVAL;
  1573.                 goto out;
  1574.         }
  1575.         crtc = obj_to_crtc(obj);
  1576.  
  1577.         if (req->flags & DRM_MODE_CURSOR_BO) {
  1578.                 if (!crtc->funcs->cursor_set) {
  1579.                         DRM_ERROR("crtc does not support cursor\n");
  1580.                         ret = -ENXIO;
  1581.                         goto out;
  1582.                 }
  1583.                 /* Turns off the cursor if handle is 0 */
  1584.                 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
  1585.                                               req->width, req->height);
  1586.         }
  1587.  
  1588.         if (req->flags & DRM_MODE_CURSOR_MOVE) {
  1589.                 if (crtc->funcs->cursor_move) {
  1590.                         ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
  1591.                 } else {
  1592.                         DRM_ERROR("crtc does not support cursor\n");
  1593.                         ret = -EFAULT;
  1594.                         goto out;
  1595.                 }
  1596.         }
  1597. out:
  1598.         mutex_unlock(&dev->mode_config.mutex);
  1599.         return ret;
  1600. }
  1601.  
  1602. /**
  1603.  * drm_mode_addfb - add an FB to the graphics configuration
  1604.  * @inode: inode from the ioctl
  1605.  * @filp: file * from the ioctl
  1606.  * @cmd: cmd from ioctl
  1607.  * @arg: arg from ioctl
  1608.  *
  1609.  * LOCKING:
  1610.  * Takes mode config lock.
  1611.  *
  1612.  * Add a new FB to the specified CRTC, given a user request.
  1613.  *
  1614.  * Called by the user via ioctl.
  1615.  *
  1616.  * RETURNS:
  1617.  * Zero on success, errno on failure.
  1618.  */
  1619. int drm_mode_addfb(struct drm_device *dev,
  1620.                    void *data, struct drm_file *file_priv)
  1621. {
  1622.         struct drm_mode_fb_cmd *r = data;
  1623.         struct drm_mode_config *config = &dev->mode_config;
  1624.         struct drm_framebuffer *fb;
  1625.         int ret = 0;
  1626.  
  1627.         if ((config->min_width > r->width) || (r->width > config->max_width)) {
  1628.                 DRM_ERROR("mode new framebuffer width not within limits\n");
  1629.                 return -EINVAL;
  1630.         }
  1631.         if ((config->min_height > r->height) || (r->height > config->max_height)) {
  1632.                 DRM_ERROR("mode new framebuffer height not within limits\n");
  1633.                 return -EINVAL;
  1634.         }
  1635.  
  1636.         mutex_lock(&dev->mode_config.mutex);
  1637.  
  1638.         /* TODO check buffer is sufficently large */
  1639.         /* TODO setup destructor callback */
  1640.  
  1641.         fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
  1642.         if (!fb) {
  1643.                 DRM_ERROR("could not create framebuffer\n");
  1644.                 ret = -EINVAL;
  1645.                 goto out;
  1646.         }
  1647.  
  1648.         r->fb_id = fb->base.id;
  1649.         list_add(&fb->filp_head, &file_priv->fbs);
  1650.  
  1651. out:
  1652.         mutex_unlock(&dev->mode_config.mutex);
  1653.         return ret;
  1654. }
  1655.  
  1656. /**
  1657.  * drm_mode_rmfb - remove an FB from the configuration
  1658.  * @inode: inode from the ioctl
  1659.  * @filp: file * from the ioctl
  1660.  * @cmd: cmd from ioctl
  1661.  * @arg: arg from ioctl
  1662.  *
  1663.  * LOCKING:
  1664.  * Takes mode config lock.
  1665.  *
  1666.  * Remove the FB specified by the user.
  1667.  *
  1668.  * Called by the user via ioctl.
  1669.  *
  1670.  * RETURNS:
  1671.  * Zero on success, errno on failure.
  1672.  */
  1673. int drm_mode_rmfb(struct drm_device *dev,
  1674.                    void *data, struct drm_file *file_priv)
  1675. {
  1676.         struct drm_mode_object *obj;
  1677.         struct drm_framebuffer *fb = NULL;
  1678.         struct drm_framebuffer *fbl = NULL;
  1679.         uint32_t *id = data;
  1680.         int ret = 0;
  1681.         int found = 0;
  1682.  
  1683.         mutex_lock(&dev->mode_config.mutex);
  1684.         obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB);
  1685.         /* TODO check that we realy get a framebuffer back. */
  1686.         if (!obj) {
  1687.                 DRM_ERROR("mode invalid framebuffer id\n");
  1688.                 ret = -EINVAL;
  1689.                 goto out;
  1690.         }
  1691.         fb = obj_to_fb(obj);
  1692.  
  1693.         list_for_each_entry(fbl, &file_priv->fbs, filp_head)
  1694.                 if (fb == fbl)
  1695.                         found = 1;
  1696.  
  1697.         if (!found) {
  1698.                 DRM_ERROR("tried to remove a fb that we didn't own\n");
  1699.                 ret = -EINVAL;
  1700.                 goto out;
  1701.         }
  1702.  
  1703.         /* TODO release all crtc connected to the framebuffer */
  1704.         /* TODO unhock the destructor from the buffer object */
  1705.  
  1706.         list_del(&fb->filp_head);
  1707.         fb->funcs->destroy(fb);
  1708.  
  1709. out:
  1710.         mutex_unlock(&dev->mode_config.mutex);
  1711.         return ret;
  1712. }
  1713.  
  1714. /**
  1715.  * drm_mode_getfb - get FB info
  1716.  * @inode: inode from the ioctl
  1717.  * @filp: file * from the ioctl
  1718.  * @cmd: cmd from ioctl
  1719.  * @arg: arg from ioctl
  1720.  *
  1721.  * LOCKING:
  1722.  * Caller? (FIXME)
  1723.  *
  1724.  * Lookup the FB given its ID and return info about it.
  1725.  *
  1726.  * Called by the user via ioctl.
  1727.  *
  1728.  * RETURNS:
  1729.  * Zero on success, errno on failure.
  1730.  */
  1731. int drm_mode_getfb(struct drm_device *dev,
  1732.                    void *data, struct drm_file *file_priv)
  1733. {
  1734.         struct drm_mode_fb_cmd *r = data;
  1735.         struct drm_mode_object *obj;
  1736.         struct drm_framebuffer *fb;
  1737.         int ret = 0;
  1738.  
  1739.         mutex_lock(&dev->mode_config.mutex);
  1740.         obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
  1741.         if (!obj) {
  1742.                 DRM_ERROR("invalid framebuffer id\n");
  1743.                 ret = -EINVAL;
  1744.                 goto out;
  1745.         }
  1746.         fb = obj_to_fb(obj);
  1747.  
  1748.         r->height = fb->height;
  1749.         r->width = fb->width;
  1750.         r->depth = fb->depth;
  1751.         r->bpp = fb->bits_per_pixel;
  1752.         r->pitch = fb->pitch;
  1753.         fb->funcs->create_handle(fb, file_priv, &r->handle);
  1754.  
  1755. out:
  1756.         mutex_unlock(&dev->mode_config.mutex);
  1757.         return ret;
  1758. }
  1759.  
  1760. /**
  1761.  * drm_fb_release - remove and free the FBs on this file
  1762.  * @filp: file * from the ioctl
  1763.  *
  1764.  * LOCKING:
  1765.  * Takes mode config lock.
  1766.  *
  1767.  * Destroy all the FBs associated with @filp.
  1768.  *
  1769.  * Called by the user via ioctl.
  1770.  *
  1771.  * RETURNS:
  1772.  * Zero on success, errno on failure.
  1773.  */
  1774. void drm_fb_release(struct drm_file *priv)
  1775. {
  1776.         struct drm_device *dev = priv->minor->dev;
  1777.         struct drm_framebuffer *fb, *tfb;
  1778.  
  1779.         mutex_lock(&dev->mode_config.mutex);
  1780.         list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
  1781.                 list_del(&fb->filp_head);
  1782.                 fb->funcs->destroy(fb);
  1783.         }
  1784.         mutex_unlock(&dev->mode_config.mutex);
  1785. }
  1786. #endif
  1787.  
  1788. /**
  1789.  * drm_mode_attachmode - add a mode to the user mode list
  1790.  * @dev: DRM device
  1791.  * @connector: connector to add the mode to
  1792.  * @mode: mode to add
  1793.  *
  1794.  * Add @mode to @connector's user mode list.
  1795.  */
  1796. static int drm_mode_attachmode(struct drm_device *dev,
  1797.                                struct drm_connector *connector,
  1798.                                struct drm_display_mode *mode)
  1799. {
  1800.         int ret = 0;
  1801.  
  1802.         list_add_tail(&mode->head, &connector->user_modes);
  1803.         return ret;
  1804. }
  1805.  
  1806. int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
  1807.                              struct drm_display_mode *mode)
  1808. {
  1809.         struct drm_connector *connector;
  1810.         int ret = 0;
  1811.         struct drm_display_mode *dup_mode;
  1812.         int need_dup = 0;
  1813.         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
  1814.                 if (!connector->encoder)
  1815.                         break;
  1816.                 if (connector->encoder->crtc == crtc) {
  1817.                         if (need_dup)
  1818.                                 dup_mode = drm_mode_duplicate(dev, mode);
  1819.                         else
  1820.                                 dup_mode = mode;
  1821.                         ret = drm_mode_attachmode(dev, connector, dup_mode);
  1822.                         if (ret)
  1823.                                 return ret;
  1824.                         need_dup = 1;
  1825.                 }
  1826.         }
  1827.         return 0;
  1828. }
  1829. EXPORT_SYMBOL(drm_mode_attachmode_crtc);
  1830.  
  1831. static int drm_mode_detachmode(struct drm_device *dev,
  1832.                                struct drm_connector *connector,
  1833.                                struct drm_display_mode *mode)
  1834. {
  1835.         int found = 0;
  1836.         int ret = 0;
  1837.         struct drm_display_mode *match_mode, *t;
  1838.  
  1839.         list_for_each_entry_safe(match_mode, t, &connector->user_modes, head) {
  1840.                 if (drm_mode_equal(match_mode, mode)) {
  1841.                         list_del(&match_mode->head);
  1842.                         drm_mode_destroy(dev, match_mode);
  1843.                         found = 1;
  1844.                         break;
  1845.                 }
  1846.         }
  1847.  
  1848.         if (!found)
  1849.                 ret = -EINVAL;
  1850.  
  1851.         return ret;
  1852. }
  1853.  
  1854. int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode)
  1855. {
  1856.         struct drm_connector *connector;
  1857.  
  1858.         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
  1859.                 drm_mode_detachmode(dev, connector, mode);
  1860.         }
  1861.         return 0;
  1862. }
  1863. EXPORT_SYMBOL(drm_mode_detachmode_crtc);
  1864.  
  1865. #if 0
  1866.  
  1867. /**
  1868.  * drm_fb_attachmode - Attach a user mode to an connector
  1869.  * @inode: inode from the ioctl
  1870.  * @filp: file * from the ioctl
  1871.  * @cmd: cmd from ioctl
  1872.  * @arg: arg from ioctl
  1873.  *
  1874.  * This attaches a user specified mode to an connector.
  1875.  * Called by the user via ioctl.
  1876.  *
  1877.  * RETURNS:
  1878.  * Zero on success, errno on failure.
  1879.  */
  1880. int drm_mode_attachmode_ioctl(struct drm_device *dev,
  1881.                               void *data, struct drm_file *file_priv)
  1882. {
  1883.         struct drm_mode_mode_cmd *mode_cmd = data;
  1884.         struct drm_connector *connector;
  1885.         struct drm_display_mode *mode;
  1886.         struct drm_mode_object *obj;
  1887.         struct drm_mode_modeinfo *umode = &mode_cmd->mode;
  1888.         int ret = 0;
  1889.  
  1890.         mutex_lock(&dev->mode_config.mutex);
  1891.  
  1892.         obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
  1893.         if (!obj) {
  1894.                 ret = -EINVAL;
  1895.                 goto out;
  1896.         }
  1897.         connector = obj_to_connector(obj);
  1898.  
  1899.         mode = drm_mode_create(dev);
  1900.         if (!mode) {
  1901.                 ret = -ENOMEM;
  1902.                 goto out;
  1903.         }
  1904.  
  1905.         drm_crtc_convert_umode(mode, umode);
  1906.  
  1907.         ret = drm_mode_attachmode(dev, connector, mode);
  1908. out:
  1909.         mutex_unlock(&dev->mode_config.mutex);
  1910.         return ret;
  1911. }
  1912.  
  1913.  
  1914. /**
  1915.  * drm_fb_detachmode - Detach a user specified mode from an connector
  1916.  * @inode: inode from the ioctl
  1917.  * @filp: file * from the ioctl
  1918.  * @cmd: cmd from ioctl
  1919.  * @arg: arg from ioctl
  1920.  *
  1921.  * Called by the user via ioctl.
  1922.  *
  1923.  * RETURNS:
  1924.  * Zero on success, errno on failure.
  1925.  */
  1926. int drm_mode_detachmode_ioctl(struct drm_device *dev,
  1927.                               void *data, struct drm_file *file_priv)
  1928. {
  1929.         struct drm_mode_object *obj;
  1930.         struct drm_mode_mode_cmd *mode_cmd = data;
  1931.         struct drm_connector *connector;
  1932.         struct drm_display_mode mode;
  1933.         struct drm_mode_modeinfo *umode = &mode_cmd->mode;
  1934.         int ret = 0;
  1935.  
  1936.         mutex_lock(&dev->mode_config.mutex);
  1937.  
  1938.         obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
  1939.         if (!obj) {
  1940.                 ret = -EINVAL;
  1941.                 goto out;
  1942.         }
  1943.         connector = obj_to_connector(obj);
  1944.  
  1945.         drm_crtc_convert_umode(&mode, umode);
  1946.         ret = drm_mode_detachmode(dev, connector, &mode);
  1947. out:
  1948.         mutex_unlock(&dev->mode_config.mutex);
  1949.         return ret;
  1950. }
  1951. #endif
  1952.  
  1953. struct drm_property *drm_property_create(struct drm_device *dev, int flags,
  1954.                                          const char *name, int num_values)
  1955. {
  1956.         struct drm_property *property = NULL;
  1957.  
  1958.         property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
  1959.         if (!property)
  1960.                 return NULL;
  1961.  
  1962.         if (num_values) {
  1963.                 property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
  1964.                 if (!property->values)
  1965.                         goto fail;
  1966.         }
  1967.  
  1968.         drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
  1969.         property->flags = flags;
  1970.         property->num_values = num_values;
  1971.         INIT_LIST_HEAD(&property->enum_blob_list);
  1972.  
  1973.         if (name)
  1974.                 strncpy(property->name, name, DRM_PROP_NAME_LEN);
  1975.  
  1976.         list_add_tail(&property->head, &dev->mode_config.property_list);
  1977.  
  1978.     dbgprintf("%s %x name %s\n", __FUNCTION__, property, name);
  1979.  
  1980.         return property;
  1981. fail:
  1982.         kfree(property);
  1983.         return NULL;
  1984. }
  1985. EXPORT_SYMBOL(drm_property_create);
  1986.  
  1987. int drm_property_add_enum(struct drm_property *property, int index,
  1988.                           uint64_t value, const char *name)
  1989. {
  1990.         struct drm_property_enum *prop_enum;
  1991.  
  1992.         if (!(property->flags & DRM_MODE_PROP_ENUM))
  1993.                 return -EINVAL;
  1994.  
  1995.         if (!list_empty(&property->enum_blob_list)) {
  1996.                 list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
  1997.                         if (prop_enum->value == value) {
  1998.                                 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
  1999.                                 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
  2000.                                 return 0;
  2001.                         }
  2002.                 }
  2003.         }
  2004.  
  2005.         prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
  2006.         if (!prop_enum)
  2007.                 return -ENOMEM;
  2008.  
  2009.         strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
  2010.         prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
  2011.         prop_enum->value = value;
  2012.  
  2013.         property->values[index] = value;
  2014.         list_add_tail(&prop_enum->head, &property->enum_blob_list);
  2015.         return 0;
  2016. }
  2017. EXPORT_SYMBOL(drm_property_add_enum);
  2018.  
  2019. void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
  2020. {
  2021.         struct drm_property_enum *prop_enum, *pt;
  2022.  
  2023.         list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) {
  2024.                 list_del(&prop_enum->head);
  2025.                 kfree(prop_enum);
  2026.         }
  2027.  
  2028.         if (property->num_values)
  2029.                 kfree(property->values);
  2030.         drm_mode_object_put(dev, &property->base);
  2031.         list_del(&property->head);
  2032.         kfree(property);
  2033. }
  2034. EXPORT_SYMBOL(drm_property_destroy);
  2035.  
  2036. int drm_connector_attach_property(struct drm_connector *connector,
  2037.                                struct drm_property *property, uint64_t init_val)
  2038. {
  2039.         int i;
  2040.  
  2041.         for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
  2042.                 if (connector->property_ids[i] == 0) {
  2043.                         connector->property_ids[i] = property->base.id;
  2044.                         connector->property_values[i] = init_val;
  2045.                         break;
  2046.                 }
  2047.         }
  2048.  
  2049.         if (i == DRM_CONNECTOR_MAX_PROPERTY)
  2050.                 return -EINVAL;
  2051.         return 0;
  2052. }
  2053. EXPORT_SYMBOL(drm_connector_attach_property);
  2054.  
  2055. int drm_connector_property_set_value(struct drm_connector *connector,
  2056.                                   struct drm_property *property, uint64_t value)
  2057. {
  2058.         int i;
  2059.  
  2060.         for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
  2061.                 if (connector->property_ids[i] == property->base.id) {
  2062.                         connector->property_values[i] = value;
  2063.                         break;
  2064.                 }
  2065.         }
  2066.  
  2067.         if (i == DRM_CONNECTOR_MAX_PROPERTY)
  2068.                 return -EINVAL;
  2069.         return 0;
  2070. }
  2071. EXPORT_SYMBOL(drm_connector_property_set_value);
  2072.  
  2073. int drm_connector_property_get_value(struct drm_connector *connector,
  2074.                                   struct drm_property *property, uint64_t *val)
  2075. {
  2076.         int i;
  2077.  
  2078.         for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
  2079.                 if (connector->property_ids[i] == property->base.id) {
  2080.                         *val = connector->property_values[i];
  2081.                         break;
  2082.                 }
  2083.         }
  2084.  
  2085.         if (i == DRM_CONNECTOR_MAX_PROPERTY)
  2086.                 return -EINVAL;
  2087.         return 0;
  2088. }
  2089. EXPORT_SYMBOL(drm_connector_property_get_value);
  2090.  
  2091. #if 0
  2092. int drm_mode_getproperty_ioctl(struct drm_device *dev,
  2093.                                void *data, struct drm_file *file_priv)
  2094. {
  2095.         struct drm_mode_object *obj;
  2096.         struct drm_mode_get_property *out_resp = data;
  2097.         struct drm_property *property;
  2098.         int enum_count = 0;
  2099.         int blob_count = 0;
  2100.         int value_count = 0;
  2101.         int ret = 0, i;
  2102.         int copied;
  2103.         struct drm_property_enum *prop_enum;
  2104.         struct drm_mode_property_enum __user *enum_ptr;
  2105.         struct drm_property_blob *prop_blob;
  2106.         uint32_t *blob_id_ptr;
  2107.         uint64_t __user *values_ptr;
  2108.         uint32_t __user *blob_length_ptr;
  2109.  
  2110.         mutex_lock(&dev->mode_config.mutex);
  2111.         obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
  2112.         if (!obj) {
  2113.                 ret = -EINVAL;
  2114.                 goto done;
  2115.         }
  2116.         property = obj_to_property(obj);
  2117.  
  2118.         if (property->flags & DRM_MODE_PROP_ENUM) {
  2119.                 list_for_each_entry(prop_enum, &property->enum_blob_list, head)
  2120.                         enum_count++;
  2121.         } else if (property->flags & DRM_MODE_PROP_BLOB) {
  2122.                 list_for_each_entry(prop_blob, &property->enum_blob_list, head)
  2123.                         blob_count++;
  2124.         }
  2125.  
  2126.         value_count = property->num_values;
  2127.  
  2128.         strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
  2129.         out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
  2130.         out_resp->flags = property->flags;
  2131.  
  2132.         if ((out_resp->count_values >= value_count) && value_count) {
  2133.                 values_ptr = (uint64_t *)(unsigned long)out_resp->values_ptr;
  2134.                 for (i = 0; i < value_count; i++) {
  2135.                         if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
  2136.                                 ret = -EFAULT;
  2137.                                 goto done;
  2138.                         }
  2139.                 }
  2140.         }
  2141.         out_resp->count_values = value_count;
  2142.  
  2143.         if (property->flags & DRM_MODE_PROP_ENUM) {
  2144.                 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
  2145.                         copied = 0;
  2146.                         enum_ptr = (struct drm_mode_property_enum *)(unsigned long)out_resp->enum_blob_ptr;
  2147.                         list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
  2148.  
  2149.                                 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
  2150.                                         ret = -EFAULT;
  2151.                                         goto done;
  2152.                                 }
  2153.  
  2154.                                 if (copy_to_user(&enum_ptr[copied].name,
  2155.                                                  &prop_enum->name, DRM_PROP_NAME_LEN)) {
  2156.                                         ret = -EFAULT;
  2157.                                         goto done;
  2158.                                 }
  2159.                                 copied++;
  2160.                         }
  2161.                 }
  2162.                 out_resp->count_enum_blobs = enum_count;
  2163.         }
  2164.  
  2165.         if (property->flags & DRM_MODE_PROP_BLOB) {
  2166.                 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
  2167.                         copied = 0;
  2168.                         blob_id_ptr = (uint32_t *)(unsigned long)out_resp->enum_blob_ptr;
  2169.                         blob_length_ptr = (uint32_t *)(unsigned long)out_resp->values_ptr;
  2170.  
  2171.                         list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
  2172.                                 if (put_user(prop_blob->base.id, blob_id_ptr + copied)) {
  2173.                                         ret = -EFAULT;
  2174.                                         goto done;
  2175.                                 }
  2176.  
  2177.                                 if (put_user(prop_blob->length, blob_length_ptr + copied)) {
  2178.                                         ret = -EFAULT;
  2179.                                         goto done;
  2180.                                 }
  2181.  
  2182.                                 copied++;
  2183.                         }
  2184.                 }
  2185.                 out_resp->count_enum_blobs = blob_count;
  2186.         }
  2187. done:
  2188.         mutex_unlock(&dev->mode_config.mutex);
  2189.         return ret;
  2190. }
  2191. #endif
  2192.  
  2193. static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,
  2194.                                                           void *data)
  2195. {
  2196.         struct drm_property_blob *blob;
  2197.  
  2198.         if (!length || !data)
  2199.                 return NULL;
  2200.  
  2201.         blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
  2202.         if (!blob)
  2203.                 return NULL;
  2204.  
  2205.         blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob));
  2206.         blob->length = length;
  2207.  
  2208.         memcpy(blob->data, data, length);
  2209.  
  2210.         drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
  2211.  
  2212.         list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
  2213.         return blob;
  2214. }
  2215.  
  2216. static void drm_property_destroy_blob(struct drm_device *dev,
  2217.                                struct drm_property_blob *blob)
  2218. {
  2219.         drm_mode_object_put(dev, &blob->base);
  2220.         list_del(&blob->head);
  2221.         kfree(blob);
  2222. }
  2223.  
  2224. #if 0
  2225. int drm_mode_getblob_ioctl(struct drm_device *dev,
  2226.                            void *data, struct drm_file *file_priv)
  2227. {
  2228.         struct drm_mode_object *obj;
  2229.         struct drm_mode_get_blob *out_resp = data;
  2230.         struct drm_property_blob *blob;
  2231.         int ret = 0;
  2232.         void *blob_ptr;
  2233.  
  2234.         mutex_lock(&dev->mode_config.mutex);
  2235.         obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB);
  2236.         if (!obj) {
  2237.                 ret = -EINVAL;
  2238.                 goto done;
  2239.         }
  2240.         blob = obj_to_blob(obj);
  2241.  
  2242.         if (out_resp->length == blob->length) {
  2243.                 blob_ptr = (void *)(unsigned long)out_resp->data;
  2244.                 if (copy_to_user(blob_ptr, blob->data, blob->length)){
  2245.                         ret = -EFAULT;
  2246.                         goto done;
  2247.                 }
  2248.         }
  2249.         out_resp->length = blob->length;
  2250.  
  2251. done:
  2252.         mutex_unlock(&dev->mode_config.mutex);
  2253.         return ret;
  2254. }
  2255. #endif
  2256.  
  2257. int drm_mode_connector_update_edid_property(struct drm_connector *connector,
  2258.                                             struct edid *edid)
  2259. {
  2260.         struct drm_device *dev = connector->dev;
  2261.         int ret = 0;
  2262.  
  2263.         if (connector->edid_blob_ptr)
  2264.                 drm_property_destroy_blob(dev, connector->edid_blob_ptr);
  2265.  
  2266.         /* Delete edid, when there is none. */
  2267.         if (!edid) {
  2268.                 connector->edid_blob_ptr = NULL;
  2269.                 ret = drm_connector_property_set_value(connector, dev->mode_config.edid_property, 0);
  2270.                 return ret;
  2271.         }
  2272.  
  2273.         connector->edid_blob_ptr = drm_property_create_blob(connector->dev, 128, edid);
  2274.  
  2275.         ret = drm_connector_property_set_value(connector,
  2276.                                                dev->mode_config.edid_property,
  2277.                                                connector->edid_blob_ptr->base.id);
  2278.  
  2279.         return ret;
  2280. }
  2281. EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
  2282.  
  2283. #if 0
  2284. int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
  2285.                                        void *data, struct drm_file *file_priv)
  2286. {
  2287.         struct drm_mode_connector_set_property *out_resp = data;
  2288.         struct drm_mode_object *obj;
  2289.         struct drm_property *property;
  2290.         struct drm_connector *connector;
  2291.         int ret = -EINVAL;
  2292.         int i;
  2293.  
  2294.         mutex_lock(&dev->mode_config.mutex);
  2295.  
  2296.         obj = drm_mode_object_find(dev, out_resp->connector_id, DRM_MODE_OBJECT_CONNECTOR);
  2297.         if (!obj) {
  2298.                 goto out;
  2299.         }
  2300.         connector = obj_to_connector(obj);
  2301.  
  2302.         for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
  2303.                 if (connector->property_ids[i] == out_resp->prop_id)
  2304.                         break;
  2305.         }
  2306.  
  2307.         if (i == DRM_CONNECTOR_MAX_PROPERTY) {
  2308.                 goto out;
  2309.         }
  2310.  
  2311.         obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
  2312.         if (!obj) {
  2313.                 goto out;
  2314.         }
  2315.         property = obj_to_property(obj);
  2316.  
  2317.         if (property->flags & DRM_MODE_PROP_IMMUTABLE)
  2318.                 goto out;
  2319.  
  2320.         if (property->flags & DRM_MODE_PROP_RANGE) {
  2321.                 if (out_resp->value < property->values[0])
  2322.                         goto out;
  2323.  
  2324.                 if (out_resp->value > property->values[1])
  2325.                         goto out;
  2326.         } else {
  2327.                 int found = 0;
  2328.                 for (i = 0; i < property->num_values; i++) {
  2329.                         if (property->values[i] == out_resp->value) {
  2330.                                 found = 1;
  2331.                                 break;
  2332.                         }
  2333.                 }
  2334.                 if (!found) {
  2335.                         goto out;
  2336.                 }
  2337.         }
  2338.  
  2339.         /* Do DPMS ourselves */
  2340.         if (property == connector->dev->mode_config.dpms_property) {
  2341.                 if (connector->funcs->dpms)
  2342.                         (*connector->funcs->dpms)(connector, (int) out_resp->value);
  2343.                 ret = 0;
  2344.         } else if (connector->funcs->set_property)
  2345.                 ret = connector->funcs->set_property(connector, property, out_resp->value);
  2346.  
  2347.         /* store the property value if succesful */
  2348.         if (!ret)
  2349.                 drm_connector_property_set_value(connector, property, out_resp->value);
  2350. out:
  2351.         mutex_unlock(&dev->mode_config.mutex);
  2352.         return ret;
  2353. }
  2354. #endif
  2355.  
  2356. int drm_mode_connector_attach_encoder(struct drm_connector *connector,
  2357.                                       struct drm_encoder *encoder)
  2358. {
  2359.         int i;
  2360.  
  2361.         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
  2362.                 if (connector->encoder_ids[i] == 0) {
  2363.                         connector->encoder_ids[i] = encoder->base.id;
  2364.                         return 0;
  2365.                 }
  2366.         }
  2367.         return -ENOMEM;
  2368. }
  2369. EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
  2370.  
  2371. void drm_mode_connector_detach_encoder(struct drm_connector *connector,
  2372.                                     struct drm_encoder *encoder)
  2373. {
  2374.         int i;
  2375.         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
  2376.                 if (connector->encoder_ids[i] == encoder->base.id) {
  2377.                         connector->encoder_ids[i] = 0;
  2378.                         if (connector->encoder == encoder)
  2379.                                 connector->encoder = NULL;
  2380.                         break;
  2381.                 }
  2382.         }
  2383. }
  2384. EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
  2385.  
  2386. bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
  2387.                                   int gamma_size)
  2388. {
  2389.         crtc->gamma_size = gamma_size;
  2390.  
  2391.         crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
  2392.         if (!crtc->gamma_store) {
  2393.                 crtc->gamma_size = 0;
  2394.                 return false;
  2395.         }
  2396.  
  2397.         return true;
  2398. }
  2399. EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
  2400.  
  2401. #if 0
  2402. int drm_mode_gamma_set_ioctl(struct drm_device *dev,
  2403.                              void *data, struct drm_file *file_priv)
  2404. {
  2405.         struct drm_mode_crtc_lut *crtc_lut = data;
  2406.         struct drm_mode_object *obj;
  2407.         struct drm_crtc *crtc;
  2408.         void *r_base, *g_base, *b_base;
  2409.         int size;
  2410.         int ret = 0;
  2411.  
  2412.         mutex_lock(&dev->mode_config.mutex);
  2413.         obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
  2414.         if (!obj) {
  2415.                 ret = -EINVAL;
  2416.                 goto out;
  2417.         }
  2418.         crtc = obj_to_crtc(obj);
  2419.  
  2420.         /* memcpy into gamma store */
  2421.         if (crtc_lut->gamma_size != crtc->gamma_size) {
  2422.                 ret = -EINVAL;
  2423.                 goto out;
  2424.         }
  2425.  
  2426.         size = crtc_lut->gamma_size * (sizeof(uint16_t));
  2427.         r_base = crtc->gamma_store;
  2428.         if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) {
  2429.                 ret = -EFAULT;
  2430.                 goto out;
  2431.         }
  2432.  
  2433.         g_base = r_base + size;
  2434.         if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) {
  2435.                 ret = -EFAULT;
  2436.                 goto out;
  2437.         }
  2438.  
  2439.         b_base = g_base + size;
  2440.         if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) {
  2441.                 ret = -EFAULT;
  2442.                 goto out;
  2443.         }
  2444.  
  2445.         crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, crtc->gamma_size);
  2446.  
  2447. out:
  2448.         mutex_unlock(&dev->mode_config.mutex);
  2449.         return ret;
  2450.  
  2451. }
  2452.  
  2453. int drm_mode_gamma_get_ioctl(struct drm_device *dev,
  2454.                              void *data, struct drm_file *file_priv)
  2455. {
  2456.         struct drm_mode_crtc_lut *crtc_lut = data;
  2457.         struct drm_mode_object *obj;
  2458.         struct drm_crtc *crtc;
  2459.         void *r_base, *g_base, *b_base;
  2460.         int size;
  2461.         int ret = 0;
  2462.  
  2463.         mutex_lock(&dev->mode_config.mutex);
  2464.         obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
  2465.         if (!obj) {
  2466.                 ret = -EINVAL;
  2467.                 goto out;
  2468.         }
  2469.         crtc = obj_to_crtc(obj);
  2470.  
  2471.         /* memcpy into gamma store */
  2472.         if (crtc_lut->gamma_size != crtc->gamma_size) {
  2473.                 ret = -EINVAL;
  2474.                 goto out;
  2475.         }
  2476.  
  2477.         size = crtc_lut->gamma_size * (sizeof(uint16_t));
  2478.         r_base = crtc->gamma_store;
  2479.         if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) {
  2480.                 ret = -EFAULT;
  2481.                 goto out;
  2482.         }
  2483.  
  2484.         g_base = r_base + size;
  2485.         if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) {
  2486.                 ret = -EFAULT;
  2487.                 goto out;
  2488.         }
  2489.  
  2490.         b_base = g_base + size;
  2491.         if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) {
  2492.                 ret = -EFAULT;
  2493.                 goto out;
  2494.         }
  2495. out:
  2496.         mutex_unlock(&dev->mode_config.mutex);
  2497.         return ret;
  2498. }
  2499.  
  2500. #endif
  2501.  
  2502.  
  2503.