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; }
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; }
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; }
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); } }
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; }
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; }
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; }
/** * 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)); }
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; }
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; }
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; }
/** * 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]; }
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); }
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; }
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); }
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); }
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"); } } }
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; }
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; }
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); } }
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; }
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"); }
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; }
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; }
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; }