Beispiel #1
0
static void printProperty(int fd, drmModePropertyRes* prop, uint64_t value) {
    fprintf(stdout, "          Property: %i\n", prop->prop_id);
    fprintf(stdout, "            Name: %s\n", prop->name);
    fprintf(stdout, "            Flags: 0x%08x\n", prop->flags);
    fprintf(stdout, "            Values: %d: %s\n", prop->count_values, getList64(prop->values, prop->count_values));

    if (prop->flags & DRM_MODE_PROP_BLOB) {
		drmModePropertyBlobRes* blob;

		fprintf(stdout, "            BLOB: ");

		blob = drmModeGetPropertyBlob(fd, value);
		if (!blob) {
		   fprintf(stdout, "error getting blob %lu\n", value);
		} else {
		   fprintf(stdout, "%d bytes, %08X...\n", blob->length, *(uint32_t *)blob->data);
		   drmModeFreePropertyBlob(blob);
		}
    } else {
    	int i;

        fprintf(stdout, "            Enum: %lu\n", value);
		for (i = 0; i < prop->count_enums; i++) {
			fprintf(stdout, "              %1s %4lld = %s\n",
					prop->enums[i].value == value ? "*" : "",
					prop->enums[i].value, prop->enums[i].name);
		}
    }

    fprintf(stdout, "\n");
}
static GBytes *
read_output_edid (MetaMonitorManagerKms *manager_kms,
                  MetaOutput            *output)
{
  MetaOutputKms *output_kms = output->driver_private;
  drmModePropertyBlobPtr edid_blob = NULL;

  if (output_kms->edid_blob_id == 0)
    return NULL;

  edid_blob = drmModeGetPropertyBlob (manager_kms->fd, output_kms->edid_blob_id);
  if (!edid_blob)
    {
      meta_warning ("Failed to read EDID of output %s: %s\n", output->name, strerror(errno));
      return NULL;
    }

  if (edid_blob->length > 0)
    return g_bytes_new_with_free_func (edid_blob->data, edid_blob->length,
                                       (GDestroyNotify)drmModeFreePropertyBlob, edid_blob);
  else
    {
      drmModeFreePropertyBlob (edid_blob);
      return NULL;
    }
}
Beispiel #3
0
static void
output_destroy(xf86OutputPtr output)
{
    struct output_private *priv = output->driver_private;
    if (priv->edid_blob)
		drmModeFreePropertyBlob(priv->edid_blob);
    drmModeFreeConnector(priv->drm_connector);
    free(priv);
    output->driver_private = NULL;
}
static uint32_t blob_duplicate(int fd, uint32_t id_orig)
{
	drmModePropertyBlobPtr orig = drmModeGetPropertyBlob(fd, id_orig);
	uint32_t id_new;

	igt_assert(orig);
	do_or_die(drmModeCreatePropertyBlob(fd, orig->data, orig->length,
					    &id_new));
	drmModeFreePropertyBlob(orig);

	return id_new;
}
static gboolean
output_get_tile_info (MetaMonitorManagerKms *manager_kms,
                      MetaOutput            *output)
{
  MetaOutputKms *output_kms = output->driver_private;
  drmModePropertyBlobPtr tile_blob = NULL;
  int ret;

  if (output_kms->tile_blob_id == 0)
    return FALSE;

  tile_blob = drmModeGetPropertyBlob (manager_kms->fd, output_kms->tile_blob_id);
  if (!tile_blob)
    {
      meta_warning ("Failed to read TILE of output %s: %s\n", output->name, strerror(errno));
      return FALSE;
    }

  if (tile_blob->length > 0)
    {
      ret = sscanf ((char *)tile_blob->data, "%d:%d:%d:%d:%d:%d:%d:%d",
                    &output->tile_info.group_id,
                    &output->tile_info.flags,
                    &output->tile_info.max_h_tiles,
                    &output->tile_info.max_v_tiles,
                    &output->tile_info.loc_h_tile,
                    &output->tile_info.loc_v_tile,
                    &output->tile_info.tile_w,
                    &output->tile_info.tile_h);

      if (ret != 8)
        return FALSE;
      return TRUE;
    }
  else
    {
      drmModeFreePropertyBlob (tile_blob);
      return FALSE;
    }
}
Beispiel #6
0
const std::string Property::to_str(uint64_t val) const
{
	drmModePropertyPtr p = m_priv->drm_prop;
	string ret;

	if (p->flags & DRM_MODE_PROP_ENUM) {
		for (int i = 0; i < p->count_enums; i++) {
			if (p->enums[i].value == val) {
				ret += string("\"") + p->enums[i].name + "\"";
				break;
			}
		}
		ret += " (enum: " + to_string(val) + ")";
	} else if (p->flags & DRM_MODE_PROP_RANGE) {
		ret += to_string(val);
		if (p->count_values == 2)
			ret += " [" + to_string(p->values[0]) + "-" +
				to_string(p->values[1]) + "]";
		else
			ret += " <broken range>";
	} else if (p->flags & DRM_MODE_PROP_BLOB) {
		ret += "Blob id: " + to_string(val);

		auto blob = drmModeGetPropertyBlob(card().fd(), (uint32_t) val);
		if (blob) {
			ret += " length: " + to_string(blob->length);
			drmModeFreePropertyBlob(blob);
		}
	} else {
		ret += to_string(val);
	}

	if (p->flags & DRM_MODE_PROP_PENDING)
		ret += " (pendig)";
	if (p->flags & DRM_MODE_PROP_IMMUTABLE)
		ret += " (immutable)";

	return ret;
}
static void
drmmode_output_destroy(xf86OutputPtr output)
{
	drmmode_output_private_ptr drmmode_output = output->driver_private;
	int i;

	if (drmmode_output->edid_blob)
		drmModeFreePropertyBlob(drmmode_output->edid_blob);
	for (i = 0; i < drmmode_output->num_props; i++) {
	    drmModeFreeProperty(drmmode_output->props[i].mode_prop);
	    free(drmmode_output->props[i].atoms);
	}
	free(drmmode_output->props);
	drmModeFreeConnector(drmmode_output->mode_output);
	if (drmmode_output->private_data) {
		free(drmmode_output->private_data);
		drmmode_output->private_data = NULL;
	}
	if (drmmode_output->backlight_iface)
		drmmode_backlight_set(output, drmmode_output->backlight_active_level);
	free(drmmode_output);
	output->driver_private = NULL;
}
Beispiel #8
0
/**
 * Get the extended display identification data for the monitor connected to a connector
 * 
 * @param   connection       The identifier for the connection to the card
 * @param   connector_index  The index of the connector
 * @param   edid             Storage location for the EDID, it should be 128 bytes,
 *                           or 256 bytes if you are counting on the depricated EDID 2.0,
 *                           If hexadecimal, twice that + zero termiation.
 * @param   size             The size allocated to `edid` excluding your zero termination
 * @param   hexadecimal      Whether to convert to hexadecimal representation, this is preferable
 * @return                   The length of the found value, 0 if none, as if hex is false
 */
long blueshift_drm_get_edid(int connection, int connector_index, char* edid, long size, int hexadecimal)
{
  card_connection* card = card_connections + connection;
  drmModeConnector* connector = *(card->connectors + connector_index);
  int fd = card->fd;
  long rc = 0;
  int prop_n = connector->count_props;
  int prop_i;
  
  for (prop_i = 0; prop_i < prop_n; prop_i++)
    {
      drmModePropertyRes* prop = drmModeGetProperty(fd, connector->props[prop_i]);
      if (!strcmp("EDID", prop->name))
	{
	  drmModePropertyBlobRes* blob = drmModeGetPropertyBlob(fd, (uint32_t)(connector->prop_values[prop_i]));
	  if (hexadecimal)
	    {
	      uint32_t n = (uint32_t)size / 2;
	      uint32_t i;
	      rc += blob->length;
	      if (n > blob->length)
		n = blob->length;
	      for (i = 0; i < n ; i++)
		{
		  *(edid + i * 2 + 0) = "0123456789abcdef"[(*((char*)(blob->data) + i) >> 4) & 15];
		  *(edid + i * 2 + 1) = "0123456789abcdef"[(*((char*)(blob->data) + i) >> 0) & 15];
		}
	    }
	  else
	    {
	      uint32_t len = blob->length < size ? blob->length : (uint32_t)size;
	      memcpy(edid, blob->data, (size_t)len * sizeof(char));
	    }
	  drmModeFreePropertyBlob(blob);
	  prop_i = prop_n; /* stop the for-loop */
	}
Beispiel #9
0
/* dump_blob and dump_prop shamelessly copied from ../modetest/modetest.c */
static void
dump_blob(uint32_t blob_id)
{
	uint32_t i;
	unsigned char *blob_data;
	drmModePropertyBlobPtr blob;

	blob = drmModeGetPropertyBlob(fd, blob_id);
	if (!blob) {
		printf("\n");
		return;
	}

	blob_data = blob->data;

	for (i = 0; i < blob->length; i++) {
		if (i % 16 == 0)
			printf("\n\t\t\t");
		printf("%.2hhx", blob_data[i]);
	}
	printf("\n");

	drmModeFreePropertyBlob(blob);
}
Beispiel #10
0
static DisplayModePtr
output_get_modes(xf86OutputPtr output)
{
    struct output_private *priv = output->driver_private;
    drmModeConnectorPtr drm_connector = priv->drm_connector;
    drmModeModeInfoPtr drm_mode = NULL;
    drmModePropertyPtr props = NULL;
    xf86MonPtr ddc_mon = NULL;
    DisplayModePtr modes = NULL, mode = NULL;
    int i;

	for (i = 0; i < drm_connector->count_props; i++) {
		props = drmModeGetProperty(priv->fd, drm_connector->props[i]);
		if (!props)
			continue;

		if (!(props->flags & DRM_MODE_PROP_BLOB))
			goto out_free;

		if (!strcmp(props->name, "EDID")) {
			if (priv->edid_blob)
				drmModeFreePropertyBlob(priv->edid_blob);
			priv->edid_blob = drmModeGetPropertyBlob(priv->fd,
							  drm_connector->prop_values[i]);
		}

		out_free:
		drmModeFreeProperty(props);
	}

	if (priv->edid_blob) {
		ddc_mon = xf86InterpretEDID(output->scrn->scrnIndex,
									priv->edid_blob->data);

		if (ddc_mon && priv->edid_blob->length > 128)
			ddc_mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
	}
	xf86OutputSetEDID(output, ddc_mon);

    for (i = 0; i < drm_connector->count_modes; i++) {
	drm_mode = &drm_connector->modes[i];
	if (drm_mode) {
	    mode = calloc(1, sizeof(DisplayModeRec));
	    if (!mode)
		continue;
	    mode->Clock = drm_mode->clock;
	    mode->HDisplay = drm_mode->hdisplay;
	    mode->HSyncStart = drm_mode->hsync_start;
	    mode->HSyncEnd = drm_mode->hsync_end;
	    mode->HTotal = drm_mode->htotal;
	    mode->VDisplay = drm_mode->vdisplay;
	    mode->VSyncStart = drm_mode->vsync_start;
	    mode->VSyncEnd = drm_mode->vsync_end;
	    mode->VTotal = drm_mode->vtotal;
	    mode->Flags = drm_mode->flags;
	    mode->HSkew = drm_mode->hskew;
	    mode->VScan = drm_mode->vscan;
	    mode->VRefresh = xf86ModeVRefresh(mode);
	    mode->Private = (void *)drm_mode;
	    mode->type = 0;
	    if (drm_mode->type & DRM_MODE_TYPE_PREFERRED)
		mode->type |= M_T_PREFERRED;
	    if (drm_mode->type & DRM_MODE_TYPE_DRIVER)
		mode->type |= M_T_DRIVER;
	    xf86SetModeDefaultName(mode);
	    modes = xf86ModesAdd(modes, mode);
	    xf86PrintModeline(0, mode);
	}
    }

    return modes;
}
static DisplayModePtr
drmmode_output_get_modes(xf86OutputPtr output)
{
	drmmode_output_private_ptr drmmode_output = output->driver_private;
	drmModeConnectorPtr koutput = drmmode_output->mode_output;
	drmmode_ptr drmmode = drmmode_output->drmmode;
	int i;
	DisplayModePtr Modes = NULL, Mode;
	drmModePropertyPtr props;
	struct fixed_panel_lvds *p_lvds;
	drmModeModeInfo *mode_ptr;

	/* look for an EDID property */
	for (i = 0; i < koutput->count_props; i++) {
		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
		if (!props)
			continue;
		if (!(props->flags & DRM_MODE_PROP_BLOB)) {
			drmModeFreeProperty(props);
			continue;
		}

		if (!strcmp(props->name, "EDID")) {
			drmModeFreePropertyBlob(drmmode_output->edid_blob);
			drmmode_output->edid_blob =
				drmModeGetPropertyBlob(drmmode->fd,
						       koutput->prop_values[i]);
		}
		drmModeFreeProperty(props);
	}

	if (drmmode_output->edid_blob)
		xf86OutputSetEDID(output,
				  xf86InterpretEDID(output->scrn->scrnIndex,
						    drmmode_output->edid_blob->data));
	else
		xf86OutputSetEDID(output,
				  xf86InterpretEDID(output->scrn->scrnIndex,
						    NULL));

	/* modes should already be available */
	for (i = 0; i < koutput->count_modes; i++) {
		Mode = xnfalloc(sizeof(DisplayModeRec));

		drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i],
					 Mode);
		Modes = xf86ModesAdd(Modes, Mode);

	}
	p_lvds = drmmode_output->private_data;
	/*
	 * If the connector type is LVDS, we will traverse the kernel mode to
	 * get the panel limit.
	 * If it is incorrect, please fix me.
	 */
	if ((koutput->connector_type ==  DRM_MODE_CONNECTOR_LVDS) && p_lvds) {
		p_lvds->hdisplay = 0;
		p_lvds->vdisplay = 0;
		for (i = 0; i < koutput->count_modes; i++) {
			mode_ptr = &koutput->modes[i];
			if ((mode_ptr->hdisplay >= p_lvds->hdisplay) &&
				(mode_ptr->vdisplay >= p_lvds->vdisplay)) {
				p_lvds->hdisplay = mode_ptr->hdisplay;
				p_lvds->vdisplay = mode_ptr->vdisplay;
			}
		}
		if (!p_lvds->hdisplay || !p_lvds->vdisplay)
			xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
				"Incorrect KMS mode.\n");
		drmmode_output_lvds_edid(output, p_lvds);
	}
	return Modes;
}