Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  3.  * All Rights Reserved.
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the
  7.  * "Software"), to deal in the Software without restriction, including
  8.  * without limitation the rights to use, copy, modify, merge, publish,
  9.  * distribute, sub license, and/or sell copies of the Software, and to
  10.  * permit persons to whom the Software is furnished to do so, subject to
  11.  * the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the
  14.  * next paragraph) shall be included in all copies or substantial portions
  15.  * of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  20.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  21.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  22.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  23.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24.  *
  25.  *
  26.  * Author: Alan Hourihane <alanh@tungstengraphics.com>
  27.  * Author: Jakob Bornecrantz <wallbraker@gmail.com>
  28.  *
  29.  */
  30.  
  31. #include "xorg-server.h"
  32. #include <xf86.h>
  33. #include <xf86i2c.h>
  34. #include <xf86Crtc.h>
  35. #include <xf86DDC.h>
  36. #include <errno.h>
  37. #include <fcntl.h>
  38. #include <unistd.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <stdint.h>
  42. #include <string.h>
  43. #include <sys/stat.h>
  44. #include <sys/types.h>
  45.  
  46. #ifdef HAVE_XEXTPROTO_71
  47. #include <X11/extensions/dpmsconst.h>
  48. #else
  49. #define DPMS_SERVER
  50. #include <X11/extensions/dpms.h>
  51. #endif
  52.  
  53. #include "xorg_tracker.h"
  54.  
  55. struct output_private
  56. {
  57.     drmModeConnectorPtr drm_connector;
  58.     drmModePropertyBlobPtr edid_blob;
  59.     int fd;
  60.     int c;
  61. };
  62.  
  63. static char *output_enum_list[] = {
  64.     "Unknown",
  65.     "VGA",
  66.     "DVI",
  67.     "DVI",
  68.     "DVI",
  69.     "Composite",
  70.     "SVIDEO",
  71.     "LVDS",
  72.     "CTV",
  73.     "DIN",
  74.     "DP",
  75.     "HDMI",
  76.     "HDMI",
  77. };
  78.  
  79. static void
  80. output_create_resources(xf86OutputPtr output)
  81. {
  82. #ifdef RANDR_12_INTERFACE
  83. #endif /* RANDR_12_INTERFACE */
  84. }
  85.  
  86. static void
  87. output_dpms(xf86OutputPtr output, int mode)
  88. {
  89. }
  90.  
  91. static xf86OutputStatus
  92. output_detect(xf86OutputPtr output)
  93. {
  94.     modesettingPtr ms = modesettingPTR(output->scrn);
  95.     struct output_private *priv = output->driver_private;
  96.     drmModeConnectorPtr drm_connector;
  97.     xf86OutputStatus status;
  98.  
  99.     drm_connector = drmModeGetConnector(ms->fd, priv->drm_connector->connector_id);
  100.     if (drm_connector) {
  101.         drmModeFreeConnector(priv->drm_connector);
  102.         priv->drm_connector = drm_connector;
  103.     } else {
  104.         drm_connector = priv->drm_connector;
  105.     }
  106.  
  107.     switch (drm_connector->connection) {
  108.     case DRM_MODE_CONNECTED:
  109.         status = XF86OutputStatusConnected;
  110.         break;
  111.     case DRM_MODE_DISCONNECTED:
  112.         status = XF86OutputStatusDisconnected;
  113.         break;
  114.     default:
  115.         status = XF86OutputStatusUnknown;
  116.     }
  117.  
  118.     return status;
  119. }
  120.  
  121. static DisplayModePtr
  122. output_get_modes(xf86OutputPtr output)
  123. {
  124.     struct output_private *priv = output->driver_private;
  125.     drmModeConnectorPtr drm_connector = priv->drm_connector;
  126.     drmModeModeInfoPtr drm_mode = NULL;
  127.     drmModePropertyPtr props = NULL;
  128.     xf86MonPtr ddc_mon = NULL;
  129.     DisplayModePtr modes = NULL, mode = NULL;
  130.     int i;
  131.  
  132.         for (i = 0; i < drm_connector->count_props; i++) {
  133.                 props = drmModeGetProperty(priv->fd, drm_connector->props[i]);
  134.                 if (!props)
  135.                         continue;
  136.  
  137.                 if (!(props->flags & DRM_MODE_PROP_BLOB))
  138.                         goto out_free;
  139.  
  140.                 if (!strcmp(props->name, "EDID")) {
  141.                         if (priv->edid_blob)
  142.                                 drmModeFreePropertyBlob(priv->edid_blob);
  143.                         priv->edid_blob = drmModeGetPropertyBlob(priv->fd,
  144.                                                           drm_connector->prop_values[i]);
  145.                 }
  146.  
  147.                 out_free:
  148.                 drmModeFreeProperty(props);
  149.         }
  150.  
  151.         if (priv->edid_blob) {
  152.                 ddc_mon = xf86InterpretEDID(output->scrn->scrnIndex,
  153.                                                                         priv->edid_blob->data);
  154.  
  155.                 if (ddc_mon && priv->edid_blob->length > 128)
  156.                         ddc_mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
  157.         }
  158.         xf86OutputSetEDID(output, ddc_mon);
  159.  
  160.     for (i = 0; i < drm_connector->count_modes; i++) {
  161.         drm_mode = &drm_connector->modes[i];
  162.         if (drm_mode) {
  163.             mode = calloc(1, sizeof(DisplayModeRec));
  164.             if (!mode)
  165.                 continue;
  166.             mode->Clock = drm_mode->clock;
  167.             mode->HDisplay = drm_mode->hdisplay;
  168.             mode->HSyncStart = drm_mode->hsync_start;
  169.             mode->HSyncEnd = drm_mode->hsync_end;
  170.             mode->HTotal = drm_mode->htotal;
  171.             mode->VDisplay = drm_mode->vdisplay;
  172.             mode->VSyncStart = drm_mode->vsync_start;
  173.             mode->VSyncEnd = drm_mode->vsync_end;
  174.             mode->VTotal = drm_mode->vtotal;
  175.             mode->Flags = drm_mode->flags;
  176.             mode->HSkew = drm_mode->hskew;
  177.             mode->VScan = drm_mode->vscan;
  178.             mode->VRefresh = xf86ModeVRefresh(mode);
  179.             mode->Private = (void *)drm_mode;
  180.             mode->type = 0;
  181.             if (drm_mode->type & DRM_MODE_TYPE_PREFERRED)
  182.                 mode->type |= M_T_PREFERRED;
  183.             if (drm_mode->type & DRM_MODE_TYPE_DRIVER)
  184.                 mode->type |= M_T_DRIVER;
  185.             xf86SetModeDefaultName(mode);
  186.             modes = xf86ModesAdd(modes, mode);
  187.             xf86PrintModeline(0, mode);
  188.         }
  189.     }
  190.  
  191.     return modes;
  192. }
  193.  
  194. static int
  195. output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
  196. {
  197.     modesettingPtr ms = modesettingPTR(output->scrn);
  198.     CustomizerPtr cust = ms->cust;
  199.  
  200.     if (cust && cust->winsys_check_fb_size &&
  201.         !cust->winsys_check_fb_size(cust, pMode->HDisplay *
  202.                                     output->scrn->bitsPerPixel / 8,
  203.                                     pMode->VDisplay))
  204.         return MODE_BAD;
  205.  
  206.     return MODE_OK;
  207. }
  208.  
  209. #ifdef RANDR_12_INTERFACE
  210. static Bool
  211. output_set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value)
  212. {
  213.     return TRUE;
  214. }
  215. #endif /* RANDR_12_INTERFACE */
  216.  
  217. #ifdef RANDR_13_INTERFACE
  218. static Bool
  219. output_get_property(xf86OutputPtr output, Atom property)
  220. {
  221.     return TRUE;
  222. }
  223. #endif /* RANDR_13_INTERFACE */
  224.  
  225. static void
  226. output_destroy(xf86OutputPtr output)
  227. {
  228.     struct output_private *priv = output->driver_private;
  229.     if (priv->edid_blob)
  230.                 drmModeFreePropertyBlob(priv->edid_blob);
  231.     drmModeFreeConnector(priv->drm_connector);
  232.     free(priv);
  233.     output->driver_private = NULL;
  234. }
  235.  
  236. static const xf86OutputFuncsRec output_funcs = {
  237.     .create_resources = output_create_resources,
  238. #ifdef RANDR_12_INTERFACE
  239.     .set_property = output_set_property,
  240. #endif
  241. #ifdef RANDR_13_INTERFACE
  242.     .get_property = output_get_property,
  243. #endif
  244.     .dpms = output_dpms,
  245.     .detect = output_detect,
  246.  
  247.     .get_modes = output_get_modes,
  248.     .mode_valid = output_mode_valid,
  249.     .destroy = output_destroy,
  250. };
  251.  
  252. void
  253. xorg_output_init(ScrnInfoPtr pScrn)
  254. {
  255.     modesettingPtr ms = modesettingPTR(pScrn);
  256.     xf86OutputPtr output;
  257.     drmModeResPtr res;
  258.     drmModeConnectorPtr drm_connector = NULL;
  259.     drmModeEncoderPtr drm_encoder = NULL;
  260.     struct output_private *priv;
  261.     char name[32];
  262.     int c, v, p;
  263.  
  264.     res = drmModeGetResources(ms->fd);
  265.     if (res == 0) {
  266.         DRV_ERROR("Failed drmModeGetResources\n");
  267.         return;
  268.     }
  269.  
  270.     for (c = 0; c < res->count_connectors; c++) {
  271.         drm_connector = drmModeGetConnector(ms->fd, res->connectors[c]);
  272.         if (!drm_connector)
  273.             goto out;
  274.  
  275. #if 0
  276.         for (p = 0; p < drm_connector->count_props; p++) {
  277.             drmModePropertyPtr prop;
  278.  
  279.             prop = drmModeGetProperty(ms->fd, drm_connector->props[p]);
  280.  
  281.             name = NULL;
  282.             if (prop) {
  283.                 ErrorF("VALUES %d\n", prop->count_values);
  284.  
  285.                 for (v = 0; v < prop->count_values; v++)
  286.                     ErrorF("%s %lld\n", prop->name, prop->values[v]);
  287.             }
  288.         }
  289. #else
  290.         (void)p;
  291.         (void)v;
  292. #endif
  293.  
  294.         snprintf(name, 32, "%s%d",
  295.                  output_enum_list[drm_connector->connector_type],
  296.                  drm_connector->connector_type_id);
  297.  
  298.  
  299.         priv = calloc(sizeof(*priv), 1);
  300.         if (!priv) {
  301.             continue;
  302.         }
  303.  
  304.         output = xf86OutputCreate(pScrn, &output_funcs, name);
  305.         if (!output) {
  306.             free(priv);
  307.             continue;
  308.         }
  309.  
  310.         drm_encoder = drmModeGetEncoder(ms->fd, drm_connector->encoders[0]);
  311.         if (drm_encoder) {
  312.             output->possible_crtcs = drm_encoder->possible_crtcs;
  313.             output->possible_clones = drm_encoder->possible_clones;
  314.         } else {
  315.             output->possible_crtcs = 0;
  316.             output->possible_clones = 0;
  317.         }
  318.         priv->c = c;
  319.         priv->drm_connector = drm_connector;
  320.         priv->fd = ms->fd;
  321.         output->driver_private = priv;
  322.         output->subpixel_order = SubPixelHorizontalRGB;
  323.         output->interlaceAllowed = FALSE;
  324.         output->doubleScanAllowed = FALSE;
  325.     }
  326.  
  327.   out:
  328.     drmModeFreeResources(res);
  329. }
  330.  
  331. unsigned
  332. xorg_output_get_id(xf86OutputPtr output)
  333. {
  334.     struct output_private *priv = output->driver_private;
  335.     return priv->drm_connector->connector_id;
  336. }
  337.  
  338. /* vim: set sw=4 ts=8 sts=4: */
  339.