예제 #1
0
bool drm_get_connector(int fd)
{
   unsigned i;
   unsigned monitor_index = 0;
   settings_t *settings   = config_get_ptr();
   unsigned monitor       = MAX(settings->video.monitor_index, 1);

   /* Enumerate all connectors. */

   RARCH_LOG("[DRM]: Found %d connectors.\n", g_drm_resources->count_connectors);

   for (i = 0; (int)i < g_drm_resources->count_connectors; i++)
   {
      drmModeConnectorPtr conn = drmModeGetConnector(
            fd, g_drm_resources->connectors[i]);

      if (conn)
      {
         bool connected = conn->connection == DRM_MODE_CONNECTED;
         RARCH_LOG("[DRM]: Connector %d connected: %s\n", i, connected ? "yes" : "no");
         RARCH_LOG("[DRM]: Connector %d has %d modes.\n", i, conn->count_modes);
         if (connected && conn->count_modes > 0)
         {
            monitor_index++;
            RARCH_LOG("[DRM]: Connector %d assigned to monitor index: #%u.\n", i, monitor_index);
         }
         drmModeFreeConnector(conn);
      }
   }

   monitor_index = 0;

   for (i = 0; (int)i < g_drm_resources->count_connectors; i++)
   {
      g_drm_connector = drmModeGetConnector(fd,
            g_drm_resources->connectors[i]);

      if (!g_drm_connector)
         continue;
      if (g_drm_connector->connection == DRM_MODE_CONNECTED
            && g_drm_connector->count_modes > 0)
      {
         monitor_index++;
         if (monitor_index == monitor)
            break;
      }

      drmModeFreeConnector(g_drm_connector);
      g_drm_connector = NULL;
   }

   if (!g_drm_connector)
   {
      RARCH_WARN("[DRM]: Couldn't get device connector.\n");
      return false;
   }
   return true;
}
예제 #2
0
static xf86OutputStatus
output_detect(xf86OutputPtr output)
{
    modesettingPtr ms = modesettingPTR(output->scrn);
    struct output_private *priv = output->driver_private;
    drmModeConnectorPtr drm_connector;
    xf86OutputStatus status;

    drm_connector = drmModeGetConnector(ms->fd, priv->drm_connector->connector_id);
    if (drm_connector) {
	drmModeFreeConnector(priv->drm_connector);
	priv->drm_connector = drm_connector;
    } else {
	drm_connector = priv->drm_connector;
    }

    switch (drm_connector->connection) {
    case DRM_MODE_CONNECTED:
	status = XF86OutputStatusConnected;
	break;
    case DRM_MODE_DISCONNECTED:
	status = XF86OutputStatusDisconnected;
	break;
    default:
	status = XF86OutputStatusUnknown;
    }

    return status;
}
int DrmConnector::UpdateModes() {
  int fd = drm_->fd();

  drmModeConnectorPtr c = drmModeGetConnector(fd, id_);
  if (!c) {
    ALOGE("Failed to get connector %d", id_);
    return -ENODEV;
  }

  std::vector<DrmMode> new_modes;
  for (int i = 0; i < c->count_modes; ++i) {
    bool exists = false;
    for (std::vector<DrmMode>::iterator iter = modes_.begin();
         iter != modes_.end(); ++iter) {
      if (*iter == c->modes[i]) {
        new_modes.push_back(*iter);
        exists = true;
        break;
      }
    }
    if (exists)
      continue;

    DrmMode m(&c->modes[i]);
    m.set_id(drm_->next_mode_id());
    new_modes.push_back(m);
  }
  modes_.swap(new_modes);
  return 0;
}
예제 #4
0
static xf86OutputStatus
drmmode_output_detect(xf86OutputPtr output)
{
	/* go to the hw and retrieve a new output struct */
	drmmode_output_private_ptr drmmode_output = output->driver_private;
	drmmode_ptr drmmode = drmmode_output->drmmode;
	xf86OutputStatus status;
	drmModeFreeConnector(drmmode_output->mode_output);

	drmmode_output->mode_output =
		drmModeGetConnector(drmmode->fd, drmmode_output->output_id);

	switch (drmmode_output->mode_output->connection) {
	case DRM_MODE_CONNECTED:
		status = XF86OutputStatusConnected;
		break;
	case DRM_MODE_DISCONNECTED:
		status = XF86OutputStatusDisconnected;
		break;
	default:
	case DRM_MODE_UNKNOWNCONNECTION:
		status = XF86OutputStatusUnknown;
		break;
	}
	return status;
}
예제 #5
0
static void printConnectors(int fd, uint32_t* ids, uint32_t count) {
	drmModeConnector *conn;
	int i;

	for (i = 0; i < count; i++) {
		conn = drmModeGetConnector(fd, ids[i]);
		if (!conn) {
			fprintf(stdout, "      Connector %u: cannot retrieve (%d): %m\n\n", ids[i], errno);
			continue;
		}

		fprintf(stdout, "      Connector %u:\n", conn->connector_id);
		fprintf(stdout, "        Type: %s\n", getConnectorType(conn->connector_type));
		fprintf(stdout, "        Dimensions: %umm x %umm\n", conn->mmWidth, conn->mmHeight);
		fprintf(stdout, "        SubPixel: %s\n", getConnectorSubPixel(conn->subpixel));
		fprintf(stdout, "        Connection: %s\n", getConnectorConnection(conn->connection));
		fprintf(stdout, "        Encoders: %d: %s\n", conn->count_encoders, getList32(conn->encoders, conn->count_encoders));
		fprintf(stdout, "        Properties: %d:\n", conn->count_props);
		printProperties(fd, conn->props, conn->prop_values, conn->count_props);
		fprintf(stdout, "        Modes: %d:\n", conn->count_modes);
		printModes(conn->modes, conn->count_modes);

		fprintf(stdout, "\n");

		drmModeFreeConnector(conn);
	}
}
예제 #6
0
파일: DRMUtils.cpp 프로젝트: Arcko/xbmc
bool CDRMUtils::GetConnector()
{
  for(auto i = 0; i < m_drm_resources->count_connectors; i++)
  {
    m_connector->connector = drmModeGetConnector(m_fd,
                                                      m_drm_resources->connectors[i]);
    if(m_connector->connector->connection == DRM_MODE_CONNECTED)
    {
      CLog::Log(LOGDEBUG, "CDRMUtils::%s - found connector: %d", __FUNCTION__,
                                                                 m_connector->connector->connector_id);
      break;
    }
    drmModeFreeConnector(m_connector->connector);
    m_connector->connector = nullptr;
  }

  if(!m_connector->connector)
  {
    CLog::Log(LOGERROR, "CDRMUtils::%s - could not get connector: %s", __FUNCTION__, strerror(errno));
    return false;
  }

  if (!GetProperties(m_fd, m_connector->connector->connector_id, DRM_MODE_OBJECT_CONNECTOR, m_connector))
  {
    CLog::Log(LOGERROR, "CDRMUtils::%s - could not get connector %u properties: %s", __FUNCTION__, m_connector->connector->connector_id, strerror(errno));
    return false;
  }

  return true;
}
예제 #7
0
static drmModeConnector* getConnector(int fd, uint32_t connector_type)
{
    LOGV("Entering %s, %d", __func__, connector_type);
    drmModeRes *resources = drmModeGetResources(fd);
    drmModeConnector *connector = NULL;
    int i;

    if (resources == NULL || resources->connectors == NULL) {
        LOGE("%s: drmModeGetResources failed.", __func__);
        return NULL;
    }
    for (i = 0; i < resources->count_connectors; i++) {
        connector = drmModeGetConnector(fd, resources->connectors[i]);
        if (connector == NULL)
            continue;
        if (connector->connector_type == connector_type)
            break;

        drmModeFreeConnector(connector);
        connector = NULL;
    }
    drmModeFreeResources(resources);
    if (connector == NULL) {
        LOGE("%s: Failed to get conector", __func__);
    }
    LOGV("Leaving %s, %d", __func__, connector_type);
    return connector;
}
예제 #8
0
static drmModeConnector *
get_connector(int fd, drmModeRes *res,
              const struct gbm_options *options)
{
        drmModeConnector *conn;
        int i;

        for (i = 0; i < res->count_connectors; i++) {
                conn = drmModeGetConnector(fd, res->connectors[i]);

                if (conn == NULL) {
                        fprintf(stderr,
                                "cannot retrieve DRM connector "
                                "%u:%u (%d): %m\n",
                                i, res->connectors[i], errno);
                        return NULL;
                }

                if (options->connector == -1 ||
                    conn->connector_id == options->connector)
                        return conn;
                drmModeFreeConnector(conn);
        }

        fprintf(stderr,
                "couldn't find connector with id %i\n",
                options->connector);

        return NULL;
}
예제 #9
0
/**
 * Acquire information about a connector
 * 
 * @param  connection       The identifier for the connection to the card
 * @param  connector_index  The index of the connector
 */
void blueshift_drm_open_connector(int connection, int connector_index)
{
  card_connection* card = card_connections + connection;
  
  if (card->connectors == NULL)
    card->connectors = malloc((size_t)(card->res->count_connectors) * sizeof(drmModeConnector*));
  *(card->connectors + connector_index) = drmModeGetConnector(card->fd, *(card->res->connectors + connector_index));
}
예제 #10
0
파일: drm.c 프로젝트: ibab/swc
bool swc_drm_create_screens(struct wl_list * screens)
{
    drmModeRes * resources;
    drmModeConnector * connector;
    uint32_t index;
    struct swc_output * output;
    uint32_t taken_crtcs = 0;

    if (!(resources = drmModeGetResources(swc.drm->fd)))
    {
        ERROR("Could not get DRM resources\n");
        return false;
    }

    for (index = 0; index < resources->count_connectors;
         ++index, drmModeFreeConnector(connector))
    {
        connector = drmModeGetConnector(swc.drm->fd,
                                        resources->connectors[index]);

        if (connector->connection == DRM_MODE_CONNECTED)
        {
            uint32_t crtc_index;
            uint32_t id;

            if (!find_available_crtc(resources, connector, taken_crtcs,
                                     &crtc_index))
            {
                WARNING("Could not find CRTC for connector %u\n", index);
                continue;
            }

            if (!find_available_id(&id))
            {
                WARNING("No more available output IDs\n");
                drmModeFreeConnector(connector);
                break;
            }

            if (!(output = swc_output_new(connector)))
                continue;

            output->screen = screen_new(resources->crtcs[crtc_index], output);
            output->screen->id = id;

            taken_crtcs |= 1 << crtc_index;
            drm.taken_ids |= 1 << id;

            wl_list_insert(screens, &output->screen->link);
        }
    }

    drmModeFreeResources(resources);

    return true;
}
drmModeConnectorPtr
IntelHWComposerDrm::getConnector(int disp)
{
    if (mDrmFd < 0) {
        ALOGE("%s: invalid drm FD\n", __func__);
        return NULL;
    }
    uint32_t req_connector_type = 0;
    uint32_t req_connector_type_id = 1;

    switch (disp) {
        case OUTPUT_MIPI0:
        case OUTPUT_MIPI1:
            req_connector_type = DRM_MODE_CONNECTOR_MIPI;
            req_connector_type_id = disp ? 2 : 1;
            break;
        case OUTPUT_HDMI:
            req_connector_type = DRM_MODE_CONNECTOR_DVID;
            break;
        default:
            ALOGW("%s: invalid device number: %d\n", __func__, disp);
            return NULL;
    }

    drmModeResPtr resources = drmModeGetResources(mDrmFd);
    if (!resources || !resources->connectors) {
        ALOGE("%s: fail to get drm resources. %s\n", __func__, strerror(errno));
        return NULL;
    }

    drmModeConnectorPtr connector = NULL;
    // get requested connector type and id
    // search connector
    for (int i = 0; i < resources->count_connectors; i++) {
        connector = drmModeGetConnector(mDrmFd, resources->connectors[i]);
        if (!connector) {
            ALOGW("%s: fail to get drm connector\n", __func__);
            continue;
        }

        if (connector->connector_type == req_connector_type &&
            connector->connector_type_id == req_connector_type_id)
            break;

        drmModeFreeConnector(connector);
        connector = NULL;
    }

    drmModeFreeResources(resources);

    if (connector == NULL)
        ALOGW("%s: fail to get required connector\n", __func__);

    return connector;
}
예제 #12
0
static int modeset_prepare(int fd)
{
	drmModeRes *res;
	drmModeConnector *conn;
	unsigned int i;
	struct modeset_dev *dev;
	int ret;

	/* retrieve resources */
	res = drmModeGetResources(fd);
	if (!res) {
		fprintf(stderr, "cannot retrieve DRM resources (%d): %m\n",
			errno);
		return -errno;
	}

	/* iterate all connectors */
	for (i = 0; i < res->count_connectors; ++i) {
		/* get information for each connector */
		conn = drmModeGetConnector(fd, res->connectors[i]);
		if (!conn) {
			fprintf(stderr, "cannot retrieve DRM connector %u:%u (%d): %m\n",
				i, res->connectors[i], errno);
			continue;
		}

		/* create a device structure */
		dev = malloc(sizeof(*dev));
		memset(dev, 0, sizeof(*dev));
		dev->conn = conn->connector_id;

		/* call helper function to prepare this connector */
		ret = modeset_setup_dev(fd, res, conn, dev);
		if (ret) {
			if (ret != -ENOENT) {
				errno = -ret;
				fprintf(stderr, "cannot setup device for connector %u:%u (%d): %m\n",
					i, res->connectors[i], errno);
			}
			free(dev);
			drmModeFreeConnector(conn);
			continue;
		}

		/* free connector data and link device into global list */
		drmModeFreeConnector(conn);
		dev->next = modeset_list;
		modeset_list = dev;
	}

	/* free resources again */
	drmModeFreeResources(res);
	return 0;
}
예제 #13
0
파일: device.c 프로젝트: magcius/drmdemo
static gboolean
device_find_crtc (Device *device)
{
  gboolean ret = FALSE;
  drmModeRes *resources;
  drmModeConnector *connector;
  drmModeEncoder *encoder;
  drmModeCrtc *crtc;
  int i;

  resources = drmModeGetResources (device->fd);
  if (resources == NULL)
    {
      g_warning ("Unable to get DRI device resources fd=%d: %m", device->fd);
      goto out;
    }

  /* Find the first active connector to display on. */
  for (i = 0; i < resources->count_connectors; i++)
    {
      connector = drmModeGetConnector (device->fd,
                                       resources->connectors[i]);
      if (connector == NULL)
        continue;

      if (connector->connection == DRM_MODE_CONNECTED &&
          connector->count_modes > 0)
        break;

      drmModeFreeConnector(connector);
    }

  if (i == resources->count_connectors)
    {
      g_warning ("Could not find an active connector");
      goto out;
    }

  /* Find an associated encoder for that connector. */
  encoder = drmModeGetEncoder (device->fd, connector->encoder_id);

  /* Now grab the CRTC for that encoder. */
  crtc = drmModeGetCrtc (device->fd, encoder->crtc_id);

  device->resources = resources;
  device->connector = connector;
  device->crtc = crtc;

  ret = TRUE;

 out:
  return ret;
}
예제 #14
0
파일: modeset.c 프로젝트: nikai3d/mesa
/**
 * Choose a CRTC that supports all given connectors.
 */
static uint32_t
drm_display_choose_crtc(struct native_display *ndpy,
                        uint32_t *connectors, int num_connectors)
{
   struct drm_display *drmdpy = drm_display(ndpy);
   int idx;

   for (idx = 0; idx < drmdpy->resources->count_crtcs; idx++) {
      boolean found_crtc = TRUE;
      int i, j;

      for (i = 0; i < num_connectors; i++) {
         drmModeConnectorPtr connector;
         int encoder_idx = -1;

         connector = drmModeGetConnector(drmdpy->fd, connectors[i]);
         if (!connector) {
            found_crtc = FALSE;
            break;
         }

         /* find an encoder the CRTC supports */
         for (j = 0; j < connector->count_encoders; j++) {
            drmModeEncoderPtr encoder =
               drmModeGetEncoder(drmdpy->fd, connector->encoders[j]);
            if (encoder->possible_crtcs & (1 << idx)) {
               encoder_idx = j;
               break;
            }
            drmModeFreeEncoder(encoder);
         }

         drmModeFreeConnector(connector);
         if (encoder_idx < 0) {
            found_crtc = FALSE;
            break;
         }
      }

      if (found_crtc)
         break;
   }

   if (idx >= drmdpy->resources->count_crtcs) {
      _eglLog(_EGL_WARNING,
            "failed to find a CRTC that supports the given %d connectors",
            num_connectors);
      return 0;
   }

   return drmdpy->resources->crtcs[idx];
}
예제 #15
0
void QKmsScreen::initializeScreenMode()
{
    //Determine optimal mode for screen
    drmModeRes *resources = drmModeGetResources(m_device->fd());
    if (!resources)
        qFatal("drmModeGetResources failed");

    drmModeConnector *connector = drmModeGetConnector(m_device->fd(), m_connectorId);
    drmModeModeInfo *mode = 0;
    for (int i = 0; i < connector->count_modes; ++i) {
        if (connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) {
            mode = &connector->modes[i];
            break;
        }
    }
    if (!mode)
        mode = &builtin_1024x768;

    drmModeEncoder *encoder = drmModeGetEncoder(m_device->fd(), connector->encoders[0]);
    if (encoder == 0)
        qFatal("No encoder for connector.");

    int i;
    for (i = 0; i < resources->count_crtcs; i++) {
        if (encoder->possible_crtcs & (1 << i))
            break;
    }
    if (i == resources->count_crtcs)
        qFatal("No usable crtc for encoder.");

    m_oldCrtc = drmModeGetCrtc(m_device->fd(), encoder->crtc_id);

    m_crtcId = resources->crtcs[i];
    m_mode = *mode;
    m_geometry = QRect(0, 0, m_mode.hdisplay, m_mode.vdisplay);
    qDebug() << "kms initialized with geometry" << m_geometry;
    m_depth = 32;
    m_format = QImage::Format_RGB32;
    m_physicalSize = QSizeF(connector->mmWidth, connector->mmHeight);

    m_gbmSurface = gbm_surface_create(m_device->gbmDevice(),
                                      m_mode.hdisplay, m_mode.vdisplay,
                                      GBM_BO_FORMAT_XRGB8888,
                                      GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);

    qDebug() << "created gbm surface" << m_gbmSurface << m_mode.hdisplay << m_mode.vdisplay;
    //Cleanup
    drmModeFreeEncoder(encoder);
    drmModeFreeConnector(connector);
    drmModeFreeResources(resources);
}
예제 #16
0
static EGLBoolean
setup_kms(int fd, struct kms *kms)
{
   drmModeRes *resources;
   drmModeConnector *connector;
   drmModeEncoder *encoder;
   int i;

   resources = drmModeGetResources(fd);
   if (!resources) {
      fprintf(stderr, "drmModeGetResources failed\n");
      return EGL_FALSE;
   }

   for (i = 0; i < resources->count_connectors; i++) {
      connector = drmModeGetConnector(fd, resources->connectors[i]);
      if (connector == NULL)
	 continue;

      if (connector->connection == DRM_MODE_CONNECTED &&
	  connector->count_modes > 0)
	 break;

      drmModeFreeConnector(connector);
   }

   if (i == resources->count_connectors) {
      fprintf(stderr, "No currently active connector found.\n");
      return EGL_FALSE;
   }

   for (i = 0; i < resources->count_encoders; i++) {
      encoder = drmModeGetEncoder(fd, resources->encoders[i]);

      if (encoder == NULL)
	 continue;

      if (encoder->encoder_id == connector->encoder_id)
	 break;

      drmModeFreeEncoder(encoder);
   }

   kms->connector = connector;
   kms->encoder = encoder;
   kms->mode = connector->modes[0];

   return EGL_TRUE;
}
예제 #17
0
void QKmsScreen::initializeScreenMode()
{
    //Determine optimal mode for screen
    drmModeRes *resources = drmModeGetResources(m_device->fd());
    if (!resources)
        qFatal("drmModeGetResources failed");

    drmModeConnector *connector = drmModeGetConnector(m_device->fd(), m_connectorId);
    drmModeModeInfo *mode = 0;
    if (connector->count_modes > 0)
        mode = &connector->modes[0];
    else
        mode = &builtin_1024x768;

    drmModeEncoder *encoder = drmModeGetEncoder(m_device->fd(), connector->encoders[0]);
    if (encoder == 0)
        qFatal("No encoder for connector.");

    int i;
    for (i = 0; i < resources->count_crtcs; i++) {
        if (encoder->possible_crtcs & (1 << i))
            break;
    }
    if (i == resources->count_crtcs)
        qFatal("No usable crtc for encoder.");

    m_crtcId = resources->crtcs[i];
    m_mode = *mode;
    m_geometry = QRect(0, 0, m_mode.hdisplay, m_mode.vdisplay);
    m_depth = 32;
    m_format = QImage::Format_RGB32;
    m_physicalSize = QSizeF(connector->mmWidth, connector->mmHeight);

    //Setup three buffers for current mode
    m_bufferManager.setupBuffersForMode(m_mode, 3);

    //Set the Mode of the screen.
    int ret = drmModeSetCrtc(m_device->fd(), m_crtcId, m_bufferManager.displayFramebufferId(),
                             0, 0, &m_connectorId, 1, &m_mode);
    if (ret)
        qFatal("failed to set mode");

    //Cleanup
    drmModeFreeEncoder(encoder);
    drmModeFreeConnector(connector);
    drmModeFreeResources(resources);
}
예제 #18
0
static void setup_drm(void)
{
	int i;

	drm.fd = drm_open_driver_master(DRIVER_INTEL);

	drm.res = drmModeGetResources(drm.fd);
	igt_assert(drm.res->count_connectors <= MAX_CONNECTORS);

	for (i = 0; i < drm.res->count_connectors; i++)
		drm.connectors[i] = drmModeGetConnector(drm.fd,
						drm.res->connectors[i]);

	drm.bufmgr = drm_intel_bufmgr_gem_init(drm.fd, 4096);
	igt_assert(drm.bufmgr);
	drm_intel_bufmgr_gem_enable_reuse(drm.bufmgr);
}
예제 #19
0
파일: main.c 프로젝트: tdaede/drm10bit
int main(int argc, char * argv[])
{
  int control_minor = 64;
  int c = drmOpenControl(control_minor);
  if (!c) {
    printf("DRM open device %d failed\n", control_minor);
    abort();
  }
  int render_minor = 128;
  int r = drmOpenRender(render_minor);
  if (!r) {
    printf("DRM open render node %d failed\n", render_minor);
  }
  drmVersionPtr v = drmGetVersion(r);
  if (!v) {
    printf("Couldn't get DRM version\n");
    abort();
  }
  printf("%s %s %s\n", v->name, v->date, v->desc);
  drmModeResPtr moderes = drmModeGetResources(c);
  if (!moderes) {
    printf("Couldn't get DRM modesetting resources\n");
    abort();
  }
  printf("fbs: %d crtcs: %d connectors: %d encoders: %d\n",
   moderes->count_fbs, moderes->count_crtcs, moderes->count_connectors, moderes->count_encoders);
  for (int i = 0; i < moderes->count_connectors; i++) {
    printf("Connector %d\n", moderes->connectors[i]);
    drmModeConnectorPtr connector = drmModeGetConnector(c, moderes->connectors[i]);
    if (connector->connection == DRM_MODE_CONNECTED) {
      printf("\tConnected\n");
      printf("\tSize: %d x %d mm\n", connector->mmWidth, connector->mmHeight);
      printf("\tModes:\n");
      for (int j = 0; j < connector->count_modes; j++) {
        printf("\t\t%s\n", connector->modes[j].name);
      }
      printf("\tProperties:\n");
      for (int j = 0; j < connector->count_props; j++) {
        drmModePropertyPtr property = drmModeGetProperty(c, connector->props[j]);
        printf("\t\t%s\n", property->name);
      }
    } else {
      printf("\tDisconnected\n");
    }
  }
}
예제 #20
0
static uint32_t
get_drm_connector_type(struct udev_device *drm_device, uint32_t connector_id)
{
	const char *filename;
	int fd, i, connector_type;
	drmModeResPtr res;
	drmModeConnectorPtr connector;

	filename = udev_device_get_devnode(drm_device);
	fd = open(filename, O_RDWR | O_CLOEXEC);
	if (fd < 0) {
		printf("couldn't open drm_device\n");
		return -1;
	}

	res = drmModeGetResources(fd);
	if (res == 0) {
		printf("Failed to get resources from card\n");
		close(fd);
		return -1;
	}

	for (i = 0; i < res->count_connectors; i++) {
		connector = drmModeGetConnector(fd, res->connectors[i]);
		if (!connector)
			continue;

		if ((connector->connection == DRM_MODE_DISCONNECTED) ||
		    (connector->connector_id != connector_id)) {
			drmModeFreeConnector(connector);
			continue;
		}

		connector_type = connector->connector_type;
		drmModeFreeConnector(connector);
		drmModeFreeResources(res);

		close(fd);
		return connector_type;
	}

	close(fd);
	drmModeFreeResources(res);
	return -1;
}
예제 #21
0
static drmModeConnector *
find_first_used_connector (int fd, drmModeRes * res)
{
  int i;
  drmModeConnector *conn;

  conn = NULL;
  for (i = 0; i < res->count_connectors; i++) {
    conn = drmModeGetConnector (fd, res->connectors[i]);
    if (conn) {
      if (connector_is_used (fd, res, conn))
        return conn;
      drmModeFreeConnector (conn);
    }
  }

  return NULL;
}
/*
 * Initialize KMS.
 */
int gralloc_drm_init_kms(struct gralloc_drm_t *drm)
{
	int i;

	if (drm->resources)
		return 0;

	drm->resources = drmModeGetResources(drm->fd);
	if (!drm->resources) {
		LOGE("failed to get modeset resources");
		return -EINVAL;
	}

	/* find the crtc/connector/mode to use */
	for (i = 0; i < drm->resources->count_connectors; i++) {
		drmModeConnectorPtr connector;

		connector = drmModeGetConnector(drm->fd,
				drm->resources->connectors[i]);
		if (connector) {
			if (connector->connection == DRM_MODE_CONNECTED) {
				if (!drm_kms_init_with_connector(drm,
							connector))
					break;
			}

			drmModeFreeConnector(connector);
		}
	}
	if (i == drm->resources->count_connectors) {
		LOGE("failed to find a valid crtc/connector/mode combination");
		drmModeFreeResources(drm->resources);
		drm->resources = NULL;

		return -EINVAL;
	}

	drm_kms_init_features(drm);
	drm->first_post = 1;

	return 0;
}
예제 #23
0
static void listConnectorProperties(void)
{
	int i;
	drmModeConnectorPtr c;

	for (i = 0; i < res->count_connectors; i++) {
		c = drmModeGetConnector(fd, res->connectors[i]);

		if (!c) {
			fprintf(stderr, "Could not get connector %u: %s\n",
				res->connectors[i], strerror(errno));
			continue;
		}

		printf("Connector %u (%s-%u)\n", c->connector_id,
		       util_lookup_connector_type_name(c->connector_type),
		       c->connector_type_id);

		listObjectProperties(c->connector_id,
				     DRM_MODE_OBJECT_CONNECTOR);

		drmModeFreeConnector(c);
	}
}
예제 #24
0
static drmModeConnector *
find_connector (int fd,
                drmModeRes *resources,
                int *excluded_connectors,
                int n_excluded_connectors)
{
  int i;

  for (i = 0; i < resources->count_connectors; i++)
    {
      drmModeConnector *connector =
        drmModeGetConnector (fd, resources->connectors[i]);

      if (connector &&
          connector->connection == DRM_MODE_CONNECTED &&
          connector->count_modes > 0 &&
          !is_connector_excluded (connector->connector_id,
                                  excluded_connectors,
                                  n_excluded_connectors))
        return connector;
      drmModeFreeConnector(connector);
    }
  return NULL;
}
static drmModeConnector *
find_main_monitor (int fd, drmModeRes * res)
{
  /* Find the LVDS and eDP connectors: those are the main screens. */
  static const int priority[] = { DRM_MODE_CONNECTOR_LVDS,
    DRM_MODE_CONNECTOR_eDP
  };
  int i;
  drmModeConnector *conn;

  conn = NULL;
  for (i = 0; !conn && i < G_N_ELEMENTS (priority); i++)
    conn = find_used_connector_by_type (fd, res, priority[i]);

  /* if we didn't find a connector, grab the first one in use */
  if (!conn)
    conn = find_first_used_connector (fd, res);

  /* if no connector is used, grab the first one */
  if (!conn)
    conn = drmModeGetConnector (fd, res->connectors[0]);

  return conn;
}
예제 #26
0
static void dump_connectors(int gfx_fd, drmModeRes *resources)
{
	int i, j;

	printf("Connectors:\n");
	printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\n");
	for (i = 0; i < resources->count_connectors; i++) {
		drmModeConnector *connector;

		connector = drmModeGetConnector(gfx_fd, resources->connectors[i]);
		if (!connector) {
			printf("could not get connector %i: %s\n",
					resources->connectors[i], strerror(errno));
			continue;
		}

		printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\n",
			connector->connector_id,
			connector->encoder_id,
			kmstest_connector_status_str(connector->connection),
			kmstest_connector_type_str(connector->connector_type),
			connector->mmWidth, connector->mmHeight,
			connector->count_modes);

		if (!connector->count_modes)
			continue;

		printf("  modes:\n");
		printf("  name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot flags type clock\n");
		for (j = 0; j < connector->count_modes; j++)
			dump_mode(&connector->modes[j]);

		drmModeFreeConnector(connector);
	}
	printf("\n");
}
예제 #27
0
파일: drm.c 프로젝트: wuyuehang/yuehan9
int main(int argc, char **argv)
{
	int drmfd;
	int vtfd;
	unsigned int i, j;
	drmModeRes *res = NULL;
	drmModeEncoder *enc = NULL;
	drmModeConnector *conn = NULL;
	uint32_t fb_id, conn_id, crtc_id;
	long int vt_args;
	struct drm_mode_create_dumb fbo_create_args = {0};
	struct drm_mode_map_dumb fbo_map_args = {0};
	struct drm_mode_destroy_dumb fbo_close_args = {0};
	uint32_t gem_handle;
	uint8_t *fb_virt = NULL; /* start address of dumb fb */
	uint32_t fb_pitch;
	uint32_t fb_size;
	drmModeModeInfo curr_mode; /* store current mode infomation */

	vtfd = open("/dev/tty1", O_RDWR | O_CLOEXEC);

	/* trigger a vt switch to /dev/tty1 and wait for available */
	ioctl(vtfd, VT_ACTIVATE, 1);
	ioctl(vtfd, VT_WAITACTIVE, 1);

	ioctl(vtfd, KDGETMODE, &vt_args);
	printf("switch to %s mode on tty1\n", vt_args == KD_TEXT ? "TEXT" : "GFX");

	/* from now on, we can do pixel dance on dumb fb */
	drmfd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);

	res = drmModeGetResources(drmfd);

	for (i = 0; i < res->count_connectors; i++) {

		conn = drmModeGetConnector(drmfd, res->connectors[i]);
		conn_id = conn->connector_id;

		if (conn->connection != DRM_MODE_CONNECTED) {
			printf("conn:[%d] is offline\n", conn->connector_id);
			drmModeFreeConnector(conn);
			continue;
		}

		/* we choose max valid mode */
		memcpy(&curr_mode, &conn->modes[0], sizeof(curr_mode));
		printf("conn:[%d] is online %dx%d@%dHZ\n", conn->connector_id, curr_mode.hdisplay, curr_mode.vdisplay, curr_mode.vrefresh);

		enc = drmModeGetEncoder(drmfd, conn->encoder_id);

		crtc_id = enc->crtc_id;
		drmModeFreeEncoder(enc);

		/* create dumb fb and retrieve aperture */
		fbo_create_args.width = curr_mode.hdisplay;
		fbo_create_args.height = curr_mode.vdisplay;
		fbo_create_args.bpp = 32;

		drmIoctl(drmfd, DRM_IOCTL_MODE_CREATE_DUMB, &fbo_create_args);

		gem_handle = fbo_create_args.handle;
		fb_size = fbo_create_args.size;
		fb_pitch = fbo_create_args.pitch;

		drmModeAddFB(drmfd, curr_mode.hdisplay, curr_mode.vdisplay, 24, 32, fb_pitch, gem_handle, &fb_id);

		fbo_map_args.handle = gem_handle;
		drmIoctl(drmfd, DRM_IOCTL_MODE_MAP_DUMB, &fbo_map_args);

		fb_virt = mmap(0, fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, drmfd, fbo_map_args.offset);

		drmModeFreeConnector(conn);
	}

	drmModeFreeResources(res);

	drmModeSetCrtc(drmfd, crtc_id, fb_id, 0, 0, &conn_id, 1, &curr_mode);

	for (i = 0; i < curr_mode.vdisplay; i++) {
		for (j = 0; j < curr_mode.hdisplay; j++) {
			//*((uint32_t *)(fb_virt + fb_pitch * i + j * 4)) = i * j;
			*((uint32_t *)(fb_virt + fb_pitch * i + j * 4)) = 0xFFFFFF;
		}
	}

	/* say hello */
	draw_8x8_char(10, 10, fb_virt, fb_pitch, 'h');
	draw_8x8_char(18, 10, fb_virt, fb_pitch, 'e');
	draw_8x8_char(26, 10, fb_virt, fb_pitch, 'l');
	draw_8x8_char(34, 10, fb_virt, fb_pitch, 'l');
	draw_8x8_char(42, 10, fb_virt, fb_pitch, 'o');

	draw_8x8_char(50, 10, fb_virt, fb_pitch, ' ');
	draw_8x8_char(58, 10, fb_virt, fb_pitch, 'r');
	draw_8x8_char(66, 10, fb_virt, fb_pitch, 'e');
	draw_8x8_char(74, 10, fb_virt, fb_pitch, 'd');
	draw_8x8_char(82, 10, fb_virt, fb_pitch, 'h');
	draw_8x8_char(90, 10, fb_virt, fb_pitch, 'a');
	draw_8x8_char(98, 10, fb_virt, fb_pitch, 't');
	draw_8x8_char(106, 10, fb_virt, fb_pitch, '!');

	draw_8x16_char(110, 100, fb_virt, fb_pitch, 'h');
	draw_8x16_char(118, 100, fb_virt, fb_pitch, 'e');
	draw_8x16_char(126, 100, fb_virt, fb_pitch, 'l');
	draw_8x16_char(134, 100, fb_virt, fb_pitch, 'l');
	draw_8x16_char(142, 100, fb_virt, fb_pitch, 'o');

	draw_8x16_char(150, 100, fb_virt, fb_pitch, ' ');
	draw_8x16_char(158, 100, fb_virt, fb_pitch, 'r');
	draw_8x16_char(166, 100, fb_virt, fb_pitch, 'e');
	draw_8x16_char(174, 100, fb_virt, fb_pitch, 'd');
	draw_8x16_char(182, 100, fb_virt, fb_pitch, 'h');
	draw_8x16_char(190, 100, fb_virt, fb_pitch, 'a');
	draw_8x16_char(198, 100, fb_virt, fb_pitch, 't');
	draw_8x16_char(206, 100, fb_virt, fb_pitch, '!');

	usleep(5000000);

	/* unwind anything we done */
	munmap(fb_virt, fb_size);

	drmModeRmFB(drmfd, fb_id);

	fbo_close_args.handle = gem_handle;
	drmIoctl(drmfd, DRM_IOCTL_MODE_DESTROY_DUMB, &fbo_close_args);

	close(drmfd);

	/* switch back to /dev/tty7 for convinience */
	ioctl(vtfd, VT_ACTIVATE, 7);
	ioctl(vtfd, VT_WAITACTIVE, 7);

	close(vtfd);
	return 0;
}
bool IntelHWComposerDrm::detectDrmModeInfo()
{
    ALOGD_IF(ALLOW_MONITOR_PRINT, "%s: detecting drm mode info...\n", __func__);

    if (mDrmFd < 0) {
        ALOGE("%s: invalid drm FD\n", __func__);
        return false;
    }

    /*try to get drm resources*/
    drmModeResPtr resources = drmModeGetResources(mDrmFd);
    if (!resources || !resources->connectors) {
        ALOGE("%s: fail to get drm resources. %s\n", __func__, strerror(errno));
        return false;
    }

    /*get mipi0 info*/
    drmModeConnectorPtr connector = NULL;
    drmModeEncoderPtr encoder = NULL;
    drmModeCrtcPtr crtc = NULL;
    drmModeConnectorPtr connectors[OUTPUT_MAX];
    drmModeModeInfoPtr mode = NULL;
    drmModeFBPtr fbInfo = NULL;

    for (int i = 0; i < resources->count_connectors; i++) {
        connector = drmModeGetConnector(mDrmFd, resources->connectors[i]);
        if (!connector) {
            ALOGW("%s: fail to get drm connector\n", __func__);
            continue;
        }

        int outputIndex = -1;
        if (connector->connector_type == DRM_MODE_CONNECTOR_MIPI ||
            connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
            ALOGD_IF(ALLOW_MONITOR_PRINT, "%s: got MIPI/LVDS connector\n", __func__);
            if (connector->connector_type_id == 1)
                outputIndex = OUTPUT_MIPI0;
            else if (connector->connector_type_id == 2)
                outputIndex = OUTPUT_MIPI1;
            else {
                ALOGW("%s: unknown connector type\n", __func__);
                outputIndex = OUTPUT_MIPI0;
            }
        } else if (connector->connector_type == DRM_MODE_CONNECTOR_DVID) {
            ALOGD_IF(ALLOW_MONITOR_PRINT, "%s: got HDMI connector\n", __func__);
            outputIndex = OUTPUT_HDMI;
        }

        /*update connection status*/
        setOutputConnection(outputIndex, connector->connection);

        /*get related encoder*/
        encoder = drmModeGetEncoder(mDrmFd, connector->encoder_id);
        if (!encoder) {
            ALOGD_IF(ALLOW_MONITOR_PRINT, "%s: fail to get drm encoder\n", __func__);
            drmModeFreeConnector(connector);
            setOutputConnection(outputIndex, DRM_MODE_DISCONNECTED);
            continue;
        }

        /*get related crtc*/
        crtc = drmModeGetCrtc(mDrmFd, encoder->crtc_id);
        if (!crtc) {
            ALOGD_IF(ALLOW_MONITOR_PRINT, "%s: fail to get drm crtc\n", __func__);
            drmModeFreeEncoder(encoder);
            drmModeFreeConnector(connector);
            setOutputConnection(outputIndex, DRM_MODE_DISCONNECTED);
            continue;
        }
        /*set crtc mode*/
        setOutputMode(outputIndex, &crtc->mode, crtc->mode_valid);

        // get fb info
        fbInfo = drmModeGetFB(mDrmFd, crtc->buffer_id);
        if (!fbInfo) {
            ALOGD("%s: fail to get fb info\n", __func__);
            drmModeFreeCrtc(crtc);
            drmModeFreeEncoder(encoder);
            drmModeFreeConnector(connector);
            setOutputConnection(outputIndex, DRM_MODE_DISCONNECTED);
            continue;
        }

        setOutputFBInfo(outputIndex, fbInfo);

        /*free all crtc/connector/encoder*/
        drmModeFreeFB(fbInfo);
        drmModeFreeCrtc(crtc);
        drmModeFreeEncoder(encoder);
        drmModeFreeConnector(connector);
    }

    drmModeFreeResources(resources);

    drmModeConnection mipi0 = getOutputConnection(OUTPUT_MIPI0);
    drmModeConnection mipi1 = getOutputConnection(OUTPUT_MIPI1);
    drmModeConnection hdmi = getOutputConnection(OUTPUT_HDMI);

    detectMDSModeChange();

    ALOGD_IF(ALLOW_MONITOR_PRINT,
           "%s: mipi/lvds %s, mipi1 %s, hdmi %s, displayMode %d\n",
        __func__,
        ((mipi0 == DRM_MODE_CONNECTED) ? "connected" : "disconnected"),
        ((mipi1 == DRM_MODE_CONNECTED) ? "connected" : "disconnected"),
        ((hdmi == DRM_MODE_CONNECTED) ? "connected" : "disconnected"),
        getDisplayMode());

    return true;
}
예제 #29
0
EGLBoolean
drm_initialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor)
{
	struct drm_device *dev;
	struct drm_screen *screen = NULL;
	drmModeConnectorPtr connector = NULL;
	drmModeResPtr res = NULL;
	unsigned count_connectors = 0;
	int num_screens = 0;
	EGLint i;
	int fd;
	_EGLConfig *config;

	dev = (struct drm_device *) calloc(1, sizeof(struct drm_device));
	if (!dev)
		return EGL_FALSE;
	dev->api = drm_api_create();

	/* try the first node */
	fd = drm_open_minor(0);
	if (fd < 0)
		goto err_fd;

	dev->drmFD = fd;
	drm_get_device_id(dev);

	dev->screen = dev->api->create_screen(dev->api, dev->drmFD, NULL);
	if (!dev->screen)
		goto err_screen;
	dev->winsys = dev->screen->winsys;

	driInitExtensions(NULL, NULL, GL_FALSE);

	drm_update_res(dev);
	res = dev->res;
	if (res)
		count_connectors = res->count_connectors;
	else
		_eglLog(_EGL_WARNING, "Could not retrive kms information\n");

	for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) {
		connector = drmModeGetConnector(fd, res->connectors[i]);

		if (!connector)
			continue;

		if (connector->connection != DRM_MODE_CONNECTED) {
			drmModeFreeConnector(connector);
			continue;
		}

		screen = malloc(sizeof(struct drm_screen));
		memset(screen, 0, sizeof(*screen));
		screen->connector = connector;
		screen->connectorID = connector->connector_id;
		_eglInitScreen(&screen->base);
		_eglAddScreen(disp, &screen->base);
		drm_add_modes_from_connector(&screen->base, connector);
		drm_find_dpms(dev, screen);
		dev->screens[num_screens++] = screen;
	}
	dev->count_screens = num_screens;

	disp->DriverData = dev;

	/* for now we only have one config */
	config = calloc(1, sizeof(*config));
	memset(config, 1, sizeof(*config));
	_eglInitConfig(config, 1);
	_eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
	_eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8);
	_eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8);
	_eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8);
	_eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32);
	_eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24);
	_eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8);
	_eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
	_eglAddConfig(disp, config);

	disp->ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
	/* enable supported extensions */
	disp->Extensions.MESA_screen_surface = EGL_TRUE;
	disp->Extensions.MESA_copy_context = EGL_TRUE;

	*major = 1;
	*minor = 4;

	return EGL_TRUE;

err_screen:
	drmClose(fd);
err_fd:
	free(dev);
	return EGL_FALSE;
}
예제 #30
0
static CoglOutputKMS *
find_output (int _index,
             int fd,
             drmModeRes *resources,
             int *excluded_connectors,
             int n_excluded_connectors,
             CoglError **error)
{
  char *connector_env_name = g_strdup_printf ("COGL_KMS_CONNECTOR%d", _index);
  char *mode_env_name;
  drmModeConnector *connector;
  drmModeEncoder *encoder;
  CoglOutputKMS *output;
  drmModeModeInfo *modes;
  int n_modes;

  if (getenv (connector_env_name))
    {
      unsigned long id = strtoul (getenv (connector_env_name), NULL, 10);
      connector = drmModeGetConnector (fd, id);
    }
  else
    connector = NULL;
  g_free (connector_env_name);

  if (connector == NULL)
    connector = find_connector (fd, resources,
                                excluded_connectors, n_excluded_connectors);
  if (connector == NULL)
    {
      _cogl_set_error (error, COGL_WINSYS_ERROR,
                   COGL_WINSYS_ERROR_INIT,
                   "No currently active connector found");
      return NULL;
    }

  /* XXX: At this point it seems connector->encoder_id may be an invalid id of 0
   * even though the connector is marked as connected. Referencing ->encoders[0]
   * seems more reliable. */
  encoder = drmModeGetEncoder (fd, connector->encoders[0]);

  output = g_slice_new0 (CoglOutputKMS);
  output->connector = connector;
  output->encoder = encoder;
  output->saved_crtc = drmModeGetCrtc (fd, encoder->crtc_id);

  if (is_panel (connector->connector_type))
    {
      n_modes = connector->count_modes + 1;
      modes = g_new (drmModeModeInfo, n_modes);
      memcpy (modes, connector->modes,
              sizeof (drmModeModeInfo) * connector->count_modes);
      /* TODO: parse EDID */
      modes[n_modes - 1] = builtin_1024x768;
    }
  else
    {
      n_modes = connector->count_modes;
      modes = g_new (drmModeModeInfo, n_modes);
      memcpy (modes, connector->modes,
              sizeof (drmModeModeInfo) * n_modes);
    }

  mode_env_name = g_strdup_printf ("COGL_KMS_CONNECTOR%d_MODE", _index);
  if (getenv (mode_env_name))
    {
      const char *name = getenv (mode_env_name);
      int i;
      CoglBool found = FALSE;
      drmModeModeInfo mode;

      for (i = 0; i < n_modes; i++)
        {
          if (strcmp (modes[i].name, name) == 0)
            {
              found = TRUE;
              break;
            }
        }
      if (!found)
        {
          g_free (mode_env_name);
          _cogl_set_error (error, COGL_WINSYS_ERROR,
                       COGL_WINSYS_ERROR_INIT,
                       "COGL_KMS_CONNECTOR%d_MODE of %s could not be found",
                       _index, name);
          return NULL;
        }
      n_modes = 1;
      mode = modes[i];
      g_free (modes);
      modes = g_new (drmModeModeInfo, 1);
      modes[0] = mode;
    }
  g_free (mode_env_name);

  output->modes = modes;
  output->n_modes = n_modes;

  return output;
}