int util_open(const char *device, const char *module) { int fd; if (module) { fd = drmOpen(module, device); if (fd < 0) { fprintf(stderr, "failed to open device '%s': %s\n", module, strerror(errno)); return -errno; } } else { unsigned int i; for (i = 0; i < ARRAY_SIZE(modules); i++) { printf("trying to open device '%s'...", modules[i]); fd = drmOpen(modules[i], device); if (fd < 0) { printf("failed\n"); } else { printf("done\n"); break; } } if (fd < 0) { fprintf(stderr, "no device found\n"); return -ENODEV; } } return fd; }
bool CDRMUtils::OpenDrm() { std::vector<const char*>modules = { "i915", "amdgpu", "radeon", "nouveau", "vmwgfx", "msm", "imx-drm", "rockchip", "vc4", "virtio_gpu", "sun4i-drm", }; for(int i = 0; i < 10; ++i) { std::string device = "/dev/dri/card"; device.append(std::to_string(i)); for (auto module : modules) { m_fd = drmOpen(module, device.c_str()); if (m_fd >= 0) { if(!GetResources()) { continue; } if(!GetConnector()) { continue; } drmModeFreeResources(m_drm_resources); m_drm_resources = nullptr; drmModeFreeConnector(m_connector->connector); m_connector->connector = nullptr; drmModeFreeObjectProperties(m_connector->props); m_connector->props = nullptr; drmModeFreeProperty(*m_connector->props_info); *m_connector->props_info = nullptr; CLog::Log(LOGDEBUG, "CDRMUtils::%s - opened device: %s using module: %s", __FUNCTION__, device.c_str(), module); return true; } drmClose(m_fd); m_fd = -1; } } return false; }
int main(int argc, char** argv) { struct kms_driver *kms; int ret, fd, i; for (i = 0, fd = -1; fd < 0 && drivers[i]; i++) fd = drmOpen(drivers[i], NULL); CHECK_RET_RETURN(fd, "Could not open device"); ret = kms_create(fd, &kms); CHECK_RET_RETURN(ret, "Failed to create kms driver"); ret = test_bo(kms); if (ret) goto err; printf("%s: All ok!\n", __func__); kms_destroy(&kms); return 0; err: kms_destroy(&kms); return ret; }
static void init(void) { int fd = drmOpen("kgsl", NULL); drmSetMaster(fd); dev = fd_device_new(fd); pipe = fd_pipe_new(dev, FD_PIPE_2D); context_bos[0] = fd_bo_new(dev, 0x1000, DRM_FREEDRENO_GEM_TYPE_KMEM); context_bos[1] = fd_bo_new(dev, 0x9000, DRM_FREEDRENO_GEM_TYPE_KMEM); context_bos[2] = fd_bo_new(dev, 0x81000, DRM_FREEDRENO_GEM_TYPE_KMEM); next_ring(); ring_pre(ring); BEGIN_RING(8); OUT_RING (ring, REGM(VGV1_DIRTYBASE, 3)); OUT_RELOC (ring, context_bos[0]); /* VGV1_DIRTYBASE */ OUT_RELOC (ring, context_bos[1]); /* VGV1_CBASE1 */ OUT_RELOC (ring, context_bos[2]); /* VGV1_UBASE2 */ OUT_RING (ring, 0x11000000); OUT_RING (ring, 0x10fff000); OUT_RING (ring, 0x10ffffff); OUT_RING (ring, 0x0d000404); END_RING (); }
bool QEglFSKmsEglDevice::open() { Q_ASSERT(fd() == -1); int fd = drmOpen(devicePath().toLocal8Bit().constData(), Q_NULLPTR); if (Q_UNLIKELY(fd < 0)) qFatal("Could not open DRM (NV) device"); setFd(fd); return true; }
static bool load_driver (ply_renderer_backend_t *backend) { char *driver_name; int device_fd; driver_name = find_driver_for_device (backend->device_name); ply_trace ("Attempting to load driver '%s'", driver_name); device_fd = drmOpen (driver_name, NULL); if (device_fd < 0) { ply_trace ("drmOpen failed"); free (driver_name); return false; } if (strcmp (driver_name, "i915") == 0) { backend->driver_interface = ply_renderer_i915_driver_get_interface (); backend->driver_supports_mapping_console = true; } else if (strcmp (driver_name, "radeon") == 0) { backend->driver_interface = ply_renderer_radeon_driver_get_interface (); backend->driver_supports_mapping_console = false; } else if (strcmp (driver_name, "nouveau") == 0) { backend->driver_interface = ply_renderer_nouveau_driver_get_interface (); backend->driver_supports_mapping_console = false; } free (driver_name); if (backend->driver_interface == NULL) { close (device_fd); return false; } backend->driver = backend->driver_interface->create_driver (device_fd); if (backend->driver == NULL) { close (device_fd); return false; } backend->device_fd = device_fd; return true; }
// main function int main(void) { struct csc_bo* input_bo; struct csc_bo* output_bo; int ret, fd; // open DRM device if ((fd = drmOpen("imx-drm", "platform:imx-drm:00")) < 0) { printf("drmOpen failed.\n"); return -1; } // create buffer for csc input input_bo = csc_bo_create(fd, WIDTH, HEIGHT, 32); if (!input_bo) { printf("Couldn't create input gem bo\n"); return -1; } // map the input buffer if (csc_bo_map(fd, input_bo)) { printf("Couldn't map input bo\n"); return -1; } // create buffer for csc output output_bo = csc_bo_create(fd, WIDTH, HEIGHT, 32); if (!output_bo) { printf("Couldn't create output gem bo\n"); return -1; } // create ipu csc request struct drm_imx_ipu_queue req = { .task = IPU_TASK_CSC, .input = { .phys = input_bo->phys, .pix = { .pixelformat = V4L2_PIX_FMT_UYVY, .bytesperline = 2 * WIDTH, .width = WIDTH, .height = HEIGHT, }, .rect = { .width = WIDTH, .height = HEIGHT, }, }, .output = {
static Bool has_kernel_mode_setting(const struct pci_device *dev) { char id[20]; int ret, fd; snprintf(id, sizeof(id), "pci:%04x:%02x:%02x.%d", dev->domain, dev->bus, dev->dev, dev->func); ret = drmCheckModesettingSupported(id); if (ret) { if (xf86LoadKernelModule("i915")) ret = drmCheckModesettingSupported(id); if (ret) return FALSE; /* Be nice to the user and load fbcon too */ (void)xf86LoadKernelModule("fbcon"); } /* Confirm that this is a i915.ko device with GEM/KMS enabled */ ret = FALSE; fd = drmOpen(NULL, id); if (fd != -1) { drmVersionPtr version = drmGetVersion(fd); if (version) { ret = strcmp ("i915", version->name) == 0; drmFreeVersion(version); } if (ret) { struct drm_i915_getparam gp; gp.param = I915_PARAM_HAS_GEM; gp.value = &ret; if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp)) ret = FALSE; } if (ret) { struct drm_mode_card_res res; memset(&res, 0, sizeof(res)); if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) ret = FALSE; } close(fd); } return ret; }
static int kms_open (gchar ** driver) { static const char *drivers[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos", "amdgpu", "imx-drm", "rockchip", "atmel-hlcdc" }; int i, fd = -1; for (i = 0; i < G_N_ELEMENTS (drivers); i++) { fd = drmOpen (drivers[i], NULL); if (fd >= 0) { if (driver) *driver = g_strdup (drivers[i]); break; } } return fd; }
int main(int argc, char *argv[]) { const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "msm", "rockchip" }; unsigned int i, ret = 0; for (i = 0; i < ARRAY_SIZE(modules); i++){ fd = drmOpen(modules[i], NULL); if (fd >= 0) { printf("Module %s loaded.\n", modules[i]); break; } } if (i == ARRAY_SIZE(modules)) { fprintf(stderr, "Failed to load drm modules.\n"); return 1; } res = drmModeGetResources(fd); if (!res) { fprintf(stderr, "Failed to get resources: %s\n", strerror(errno)); ret = 1; goto done; } if (argc < 2) { listAllProperties(); } else if (argc == 5) { ret = setProperty(argv); } else { printUsage(); ret = 1; } drmModeFreeResources(res); done: drmClose(fd); return ret; }
Rk30MaliDRI2 *Rk30MaliDRI2_Init(ScreenPtr pScreen) { int drm_fd; DRI2InfoRec info; if (!xf86LoadSubModule(xf86Screens[pScreen->myNum], "dri2")) return FALSE; if ((drm_fd = drmOpen("mali_drm", NULL)) < 0) { ErrorF("Rk30MaliDRI2_Init: drmOpen failed!\n"); return FALSE; } if (ump_open() != UMP_OK) { drmClose(drm_fd); ErrorF("Rk30MaliDRI2_Init: ump_open() != UMP_OK\n"); return FALSE; } info.version = 3; info.driverName = "rk30-mali"; info.deviceName = "/dev/dri/card0"; info.fd = drm_fd; info.CreateBuffer = MaliDRI2CreateBuffer; info.DestroyBuffer = MaliDRI2DestroyBuffer; info.CopyRegion = MaliDRI2CopyRegion; if (!DRI2ScreenInit(pScreen, &info)) { drmClose(drm_fd); return NULL; } else { Rk30MaliDRI2 *private = calloc(1, sizeof(Rk30MaliDRI2)); private->drm_fd = drm_fd; return private; }
int mggh::DRMHelper::open_drm_device() { static const char *drivers[] = { "i915", "radeon", "nouveau", 0 }; int tmp_fd = -1; const char** driver{drivers}; while (tmp_fd < 0 && *driver) { tmp_fd = drmOpen(*driver, NULL); ++driver; } if (tmp_fd < 0) { BOOST_THROW_EXCEPTION( boost::enable_error_info( std::runtime_error("Problem opening DRM device")) << boost::errinfo_errno(-tmp_fd)); } return tmp_fd; }
int init_drm(void) { static const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", "msm" }; drmModeRes *resources; drmModeConnector *connector = NULL; drmModeEncoder *encoder = NULL; int i, area; for (i = 0; i < ARRAY_SIZE(modules); i++) { printf("trying to load module %s...", modules[i]); drm.fd = drmOpen(modules[i], NULL); if (drm.fd < 0) { printf("failed.\n"); } else { printf("success.\n"); break; } } if (drm.fd < 0) { printf("could not open drm device\n"); return -1; } resources = drmModeGetResources(drm.fd); if (!resources) { printf("drmModeGetResources failed: %s\n", strerror(errno)); return -1; } /* find a connected connector: */ for (i = 0; i < resources->count_connectors; i++) { connector = drmModeGetConnector(drm.fd, resources->connectors[i]); if (connector->connection == DRM_MODE_CONNECTED) { /* it's connected, let's use this! */ break; } drmModeFreeConnector(connector); connector = NULL; } if (!connector) { /* we could be fancy and listen for hotplug events and wait for * a connector.. */ printf("no connected connector!\n"); return -1; } /* find highest resolution mode: */ for (i = 0, area = 0; i < connector->count_modes; i++) { drmModeModeInfo *current_mode = &connector->modes[i]; int current_area = current_mode->hdisplay * current_mode->vdisplay; if (current_area > area) { drm.mode = current_mode; area = current_area; } } if (!drm.mode) { printf("could not find mode!\n"); return -1; } /* find encoder: */ for (i = 0; i < resources->count_encoders; i++) { encoder = drmModeGetEncoder(drm.fd, resources->encoders[i]); if (encoder->encoder_id == connector->encoder_id) break; drmModeFreeEncoder(encoder); encoder = NULL; } if (!encoder) { printf("no encoder!\n"); return -1; } drm.crtc_id = encoder->crtc_id; drm.connector_id = connector->connector_id; return 0; }
static bool gfx_ctx_init(void) { if (g_inited) return false; static const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", NULL }; for (int i = 0; modules[i]; i++) { RARCH_LOG("[KMS/EGL]: Trying to load module %s ...\n", modules[i]); g_drm_fd = drmOpen(modules[i], NULL); if (g_drm_fd >= 0) { RARCH_LOG("[KMS/EGL]: Found module %s.\n", modules[i]); break; } } if (g_drm_fd < 0) { RARCH_ERR("[KMS/EGL]: Couldn't open DRM device.\n"); goto error; } g_resources = drmModeGetResources(g_drm_fd); if (!g_resources) { RARCH_ERR("[KMS/EGL]: Couldn't get device resources.\n"); goto error; } for (int i = 0; i < g_resources->count_connectors; i++) { g_connector = drmModeGetConnector(g_drm_fd, g_resources->connectors[i]); if (g_connector->connection == DRM_MODE_CONNECTED) break; drmModeFreeConnector(g_connector); g_connector = NULL; } // TODO: Figure out what index for crtcs to use ... g_orig_crtc = drmModeGetCrtc(g_drm_fd, g_resources->crtcs[0]); if (!g_orig_crtc) RARCH_WARN("[KMS/EGL]: Cannot find original CRTC.\n"); if (!g_connector) { RARCH_ERR("[KMS/EGL]: Couldn't get device connector.\n"); goto error; } for (int i = 0, area = 0; i < g_connector->count_modes; i++) { drmModeModeInfo *current_mode = &g_connector->modes[i]; int current_area = current_mode->hdisplay * current_mode->vdisplay; if (current_area > area) { g_drm_mode = current_mode; area = current_area; } } if (!g_drm_mode) { RARCH_ERR("[KMS/EGL]: Couldn't find DRM mode.\n"); goto error; } for (int i = 0; i < g_resources->count_encoders; i++) { g_encoder = drmModeGetEncoder(g_drm_fd, g_resources->encoders[i]); if (g_encoder->encoder_id == g_connector->encoder_id) break; drmModeFreeEncoder(g_encoder); g_encoder = NULL; } if (!g_encoder) { RARCH_ERR("[KMS/EGL]: Couldn't find DRM encoder.\n"); goto error; } g_crtc_id = g_encoder->crtc_id; g_connector_id = g_connector->connector_id; g_fb_width = g_drm_mode->hdisplay; g_fb_height = g_drm_mode->vdisplay; g_gbm_dev = gbm_create_device(g_drm_fd); g_gbm_surface = gbm_surface_create(g_gbm_dev, g_fb_width, g_fb_height, GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); if (!g_gbm_surface) { RARCH_ERR("[KMS/EGL]: Couldn't create GBM surface.\n"); goto error; } return true; error: gfx_ctx_destroy(); return false; }
int main(int argc, char **argv) { struct exynos_device *dev; struct exynos_bo *bo, *src; struct connector con; unsigned int fb_id; uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; drmModeRes *resources; int ret, fd, c; memset(&con, 0, sizeof(struct connector)); if (argc != 3) { usage(argv[0]); return -EINVAL; } while ((c = getopt(argc, argv, optstr)) != -1) { switch (c) { case 's': con.crtc = -1; if (sscanf(optarg, "%d:0x%64s", &con.id, con.mode_str) != 2 && sscanf(optarg, "%d@%d:%64s", &con.id, &con.crtc, con.mode_str) != 3) usage(argv[0]); break; default: usage(argv[0]); return -EINVAL; } } fd = drmOpen(DRM_MODULE_NAME, NULL); if (fd < 0) { fprintf(stderr, "failed to open.\n"); return fd; } dev = exynos_device_create(fd); if (!dev) { drmClose(dev->fd); return -EFAULT; } resources = drmModeGetResources(dev->fd); if (!resources) { fprintf(stderr, "drmModeGetResources failed: %s\n", strerror(errno)); ret = -EFAULT; goto err_drm_close; } connector_find_mode(dev->fd, &con, resources); drmModeFreeResources(resources); if (!con.mode) { fprintf(stderr, "failed to find usable connector\n"); ret = -EFAULT; goto err_drm_close; } screen_width = con.mode->hdisplay; screen_height = con.mode->vdisplay; if (screen_width == 0 || screen_height == 0) { fprintf(stderr, "failed to find sane resolution on connector\n"); ret = -EFAULT; goto err_drm_close; } printf("screen width = %d, screen height = %d\n", screen_width, screen_height); bo = exynos_create_buffer(dev, screen_width * screen_height * 4, 0); if (!bo) { ret = -EFAULT; goto err_drm_close; } handles[0] = bo->handle; pitches[0] = screen_width * 4; offsets[0] = 0; ret = drmModeAddFB2(dev->fd, screen_width, screen_height, DRM_FORMAT_RGBA8888, handles, pitches, offsets, &fb_id, 0); if (ret < 0) goto err_destroy_buffer; con.plane_zpos = -1; memset(bo->vaddr, 0xff, screen_width * screen_height * 4); ret = drm_set_crtc(dev, &con, fb_id); if (ret < 0) goto err_rm_fb; ret = test_case.solid_fill(dev, bo); if (ret < 0) { fprintf(stderr, "failed to solid fill operation.\n"); goto err_rm_fb; } wait_for_user_input(0); src = exynos_create_buffer(dev, screen_width * screen_height * 4, 0); if (!src) { ret = -EFAULT; goto err_rm_fb; } ret = test_case.copy(dev, src, bo, G2D_IMGBUF_GEM); if (ret < 0) { fprintf(stderr, "failed to test copy operation.\n"); goto err_free_src; } wait_for_user_input(0); ret = test_case.copy_with_scale(dev, src, bo, G2D_IMGBUF_GEM); if (ret < 0) { fprintf(stderr, "failed to test copy and scale operation.\n"); goto err_free_src; } wait_for_user_input(0); ret = test_case.checkerboard(dev, src, bo, G2D_IMGBUF_GEM); if (ret < 0) { fprintf(stderr, "failed to issue checkerboard test.\n"); goto err_free_src; } wait_for_user_input(1); /* * The blend test uses the userptr functionality of exynos-drm, which * is currently not safe to use. If the kernel hasn't been build with * exynos-iommu support, then the blend test is going to produce (kernel) * memory corruption, eventually leading to a system crash. * * Disable the test for now, until the kernel code has been sanitized. */ #if 0 ret = test_case.blend(dev, src, bo, G2D_IMGBUF_USERPTR); if (ret < 0) fprintf(stderr, "failed to test blend operation.\n"); getchar(); #endif err_free_src: if (src) exynos_destroy_buffer(src); err_rm_fb: drmModeRmFB(dev->fd, fb_id); err_destroy_buffer: exynos_destroy_buffer(bo); err_drm_close: drmClose(dev->fd); exynos_device_destroy(dev); return 0; }
/* * checks if a modesetting capable driver has attached to the pci id * returns 0 if modesetting supported. * -EINVAL or invalid bus id * -ENOSYS if no modesetting support */ int drmCheckModesettingSupported(const char *busid) { #if defined (__linux__) char pci_dev_dir[1024]; int domain, bus, dev, func; DIR *sysdir; struct dirent *dent; int found = 0, ret; ret = sscanf(busid, "pci:%04x:%02x:%02x.%d", &domain, &bus, &dev, &func); if (ret != 4) return -EINVAL; sprintf(pci_dev_dir, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/drm", domain, bus, dev, func); sysdir = opendir(pci_dev_dir); if (sysdir) { dent = readdir(sysdir); while (dent) { if (!strncmp(dent->d_name, "controlD", 8)) { found = 1; break; } dent = readdir(sysdir); } closedir(sysdir); if (found) return 0; } sprintf(pci_dev_dir, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/", domain, bus, dev, func); sysdir = opendir(pci_dev_dir); if (!sysdir) return -EINVAL; dent = readdir(sysdir); while (dent) { if (!strncmp(dent->d_name, "drm:controlD", 12)) { found = 1; break; } dent = readdir(sysdir); } closedir(sysdir); if (found) return 0; #elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) char kbusid[1024], sbusid[1024]; char oid[128]; int domain, bus, dev, func; int i, modesetting, ret; size_t len; ret = sscanf(busid, "pci:%04x:%02x:%02x.%d", &domain, &bus, &dev, &func); if (ret != 4) return -EINVAL; snprintf(kbusid, sizeof(kbusid), "pci:%04x:%02x:%02x.%d", domain, bus, dev, func); /* How many GPUs do we expect in the machine ? */ for (i = 0; i < 16; i++) { snprintf(oid, sizeof(oid), "hw.dri.%d.busid", i); len = sizeof(sbusid); ret = sysctlbyname(oid, sbusid, &len, NULL, 0); if (ret == -1) { if (errno == ENOENT) continue; return -EINVAL; } if (strcmp(sbusid, kbusid) != 0) continue; snprintf(oid, sizeof(oid), "hw.dri.%d.modesetting", i); len = sizeof(modesetting); ret = sysctlbyname(oid, &modesetting, &len, NULL, 0); if (ret == -1 || len != sizeof(modesetting)) return -EINVAL; return (modesetting ? 0 : -ENOSYS); } #elif defined(__DragonFly__) return 0; #else int fd; static const struct drm_mode_card_res zero_res; struct drm_mode_card_res res = zero_res; int ret; fd = drmOpen(NULL, busid); if (fd == -1) return -EINVAL; ret = drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res); drmClose(fd); if (ret == 0) return 0; #endif #ifdef __OpenBSD__ int fd; struct drm_mode_card_res res; drmModeResPtr r = 0; if ((fd = drmOpen(NULL, busid)) < 0) return -EINVAL; memset(&res, 0, sizeof(struct drm_mode_card_res)); if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) { drmClose(fd); return -errno; } drmClose(fd); return 0; #endif return -ENOSYS; }
int main(int argc, char **argv) { int c; int r = 0; int fd = -1; drm_handle_t handle; void *address; char *pt; unsigned long count; unsigned long offset; unsigned long size; drm_context_t context; int loops; char buf[1024]; int i; drmBufInfoPtr info; drmBufMapPtr bufs; drmLockPtr lock; int secs; while ((c = getopt(argc, argv, "lc:vo:O:f:s:w:W:b:r:R:P:L:C:XS:B:F:")) != EOF) switch (c) { case 'F': count = strtoul(optarg, NULL, 0); if (!fork()) { dup(fd); sleep(count); } close(fd); break; case 'v': getversion(fd); break; case 'X': if ((r = drmCreateContext(fd, &context))) { drmError(r, argv[0]); return 1; } printf( "Got %d\n", context); break; case 'S': process_sigio(optarg); break; case 'C': if ((r = drmSwitchToContext(fd, strtoul(optarg, NULL, 0)))) { drmError(r, argv[0]); return 1; } break; case 'c': if ((r = drmSetBusid(fd,optarg))) { drmError(r, argv[0]); return 1; } break; case 'o': if ((fd = drmOpen(optarg, NULL)) < 0) { drmError(fd, argv[0]); return 1; } break; case 'O': if ((fd = drmOpen(NULL, optarg)) < 0) { drmError(fd, argv[0]); return 1; } break; case 'B': /* Test buffer allocation */ count = strtoul(optarg, &pt, 0); size = strtoul(pt+1, &pt, 0); secs = strtoul(pt+1, NULL, 0); { drmDMAReq dma; int *indices, *sizes; indices = alloca(sizeof(*indices) * count); sizes = alloca(sizeof(*sizes) * count); dma.context = context; dma.send_count = 0; dma.request_count = count; dma.request_size = size; dma.request_list = indices; dma.request_sizes = sizes; dma.flags = DRM_DMA_WAIT; if ((r = drmDMA(fd, &dma))) { drmError(r, argv[0]); return 1; } for (i = 0; i < dma.granted_count; i++) { printf("%5d: index = %d, size = %d\n", i, dma.request_list[i], dma.request_sizes[i]); } sleep(secs); drmFreeBufs(fd, dma.granted_count, indices); } break; case 'b': count = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); if ((r = drmAddBufs(fd, count, size, 0, 65536)) < 0) { drmError(r, argv[0]); return 1; } if (!(info = drmGetBufInfo(fd))) { drmError(0, argv[0]); return 1; } for (i = 0; i < info->count; i++) { printf("%5d buffers of size %6d (low = %d, high = %d)\n", info->list[i].count, info->list[i].size, info->list[i].low_mark, info->list[i].high_mark); } if ((r = drmMarkBufs(fd, 0.50, 0.80))) { drmError(r, argv[0]); return 1; } if (!(info = drmGetBufInfo(fd))) { drmError(0, argv[0]); return 1; } for (i = 0; i < info->count; i++) { printf("%5d buffers of size %6d (low = %d, high = %d)\n", info->list[i].count, info->list[i].size, info->list[i].low_mark, info->list[i].high_mark); } printf("===== /proc/dri/0/mem =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem"); system(buf); #if 1 if (!(bufs = drmMapBufs(fd))) { drmError(0, argv[0]); return 1; } printf("===============================\n"); printf( "%d bufs\n", bufs->count); for (i = 0; i < bufs->count; i++) { printf( " %4d: %8d bytes at %p\n", i, bufs->list[i].total, bufs->list[i].address); } printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); #endif break; case 'f': offset = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); handle = 0; if ((r = drmAddMap(fd, offset, size, DRM_FRAME_BUFFER, 0, &handle))) { drmError(r, argv[0]); return 1; } printf("0x%08lx:0x%04lx added\n", offset, size); printf("===== /proc/dri/0/mem =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem"); system(buf); break; case 'r': case 'R': offset = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); handle = 0; if ((r = drmAddMap(fd, offset, size, DRM_REGISTERS, c == 'R' ? DRM_READ_ONLY : 0, &handle))) { drmError(r, argv[0]); return 1; } printf("0x%08lx:0x%04lx added\n", offset, size); printf("===== /proc/dri/0/mem =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem"); system(buf); break; case 's': size = strtoul(optarg, &pt, 0); handle = 0; if ((r = drmAddMap(fd, 0, size, DRM_SHM, DRM_CONTAINS_LOCK, &handle))) { drmError(r, argv[0]); return 1; } printf("0x%04lx byte shm added at 0x%08lx\n", size, handle); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vm"); system(buf); break; case 'P': offset = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); address = NULL; if ((r = drmMap(fd, offset, size, &address))) { drmError(r, argv[0]); return 1; } printf("0x%08lx:0x%04lx mapped at %p for pid %d\n", offset, size, address, getpid()); printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); mprotect((void *)offset, size, PROT_READ); printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); break; case 'w': case 'W': offset = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); address = NULL; if ((r = drmMap(fd, offset, size, &address))) { drmError(r, argv[0]); return 1; } printf("0x%08lx:0x%04lx mapped at %p for pid %d\n", offset, size, address, getpid()); printf("===== /proc/%d/maps =====\n", getpid()); snprintf(buf, sizeof(buf), "cat /proc/%d/maps", getpid()); system(buf); printf("===== /proc/dri/0/mem =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem"); system(buf); printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); printf("===== READING =====\n"); for (i = 0; i < 0x10; i++) printf("%02x ", (unsigned int)((unsigned char *)address)[i]); printf("\n"); if (c == 'w') { printf("===== WRITING =====\n"); for (i = 0; i < size; i+=2) { ((char *)address)[i] = i & 0xff; ((char *)address)[i+1] = i & 0xff; } } printf("===== READING =====\n"); for (i = 0; i < 0x10; i++) printf("%02x ", (unsigned int)((unsigned char *)address)[i]); printf("\n"); printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); break; case 'L': context = strtoul(optarg, &pt, 0); offset = strtoul(pt+1, &pt, 0); size = strtoul(pt+1, &pt, 0); loops = strtoul(pt+1, NULL, 0); address = NULL; if ((r = drmMap(fd, offset, size, &address))) { drmError(r, argv[0]); return 1; } lock = address; #if 1 { int counter = 0; struct timeval loop_start, loop_end; struct timeval lock_start, lock_end; double wt; #define HISTOSIZE 9 int histo[HISTOSIZE]; int output = 0; int fast = 0; if (loops < 0) { loops = -loops; ++output; } for (i = 0; i < HISTOSIZE; i++) histo[i] = 0; gettimeofday(&loop_start, NULL); for (i = 0; i < loops; i++) { gettimeofday(&lock_start, NULL); DRM_LIGHT_LOCK_COUNT(fd,lock,context,fast); gettimeofday(&lock_end, NULL); DRM_UNLOCK(fd,lock,context); ++counter; wt = usec(&lock_end, &lock_start); if (wt <= 2.5) ++histo[8]; if (wt < 5.0) ++histo[0]; else if (wt < 50.0) ++histo[1]; else if (wt < 500.0) ++histo[2]; else if (wt < 5000.0) ++histo[3]; else if (wt < 50000.0) ++histo[4]; else if (wt < 500000.0) ++histo[5]; else if (wt < 5000000.0) ++histo[6]; else ++histo[7]; if (output) printf( "%.2f uSec, %d fast\n", wt, fast); } gettimeofday(&loop_end, NULL); printf( "Average wait time = %.2f usec, %d fast\n", usec(&loop_end, &loop_start) / counter, fast); printf( "%9d <= 2.5 uS\n", histo[8]); printf( "%9d < 5 uS\n", histo[0]); printf( "%9d < 50 uS\n", histo[1]); printf( "%9d < 500 uS\n", histo[2]); printf( "%9d < 5000 uS\n", histo[3]); printf( "%9d < 50000 uS\n", histo[4]); printf( "%9d < 500000 uS\n", histo[5]); printf( "%9d < 5000000 uS\n", histo[6]); printf( "%9d >= 5000000 uS\n", histo[7]); } #else printf( "before lock: 0x%08x\n", lock->lock); printf( "lock: 0x%08x\n", lock->lock); sleep(5); printf( "unlock: 0x%08x\n", lock->lock); #endif break; default: fprintf( stderr, "Usage: drmstat [options]\n" ); return 1; } return r; }
int main(int argc, char **argv) { int fd, newlyopened; drmVersionPtr retval; char *busid; //drmDevicePtr dev; //* fd = drmOpen(NULL, "pci:0000:01:00.0"); assert(fd >= 0); retval = drmGetVersion(fd); printf("name=%s\n", retval->name); drmFreeVersion(retval); busid = drmGetBusid(fd); printf("busid=%s\n", busid); drmFreeBusid(busid); /* assert(!drmGetDevice(fd, &dev)); printf("pci:%04x:%02x:%02x.%d\n", dev->businfo.pci->domain, dev->businfo.pci->bus, dev->businfo.pci->dev, dev->businfo.pci->func); */ drmClose(fd); //*/ fd = drmOpenOnceWithType("pci:0000:01:00.0", &newlyopened, DRM_NODE_PRIMARY); //fd = open("/dev/dri/card0", O_RDWR); assert(fd >= 0); retval = drmGetVersion(fd); printf("name=%s\n", retval->name); drmFreeVersion(retval); busid = drmGetBusid(fd); printf("busid=%s\n", busid); drmFreeBusid(busid); /* assert(!drmGetDevice(fd, &dev)); printf("pci:%04x:%02x:%02x.%d\n", dev->businfo.pci->domain, dev->businfo.pci->bus, dev->businfo.pci->dev, dev->businfo.pci->func); */ drmClose(fd); /* drmDevicePtr devs[16]; int num = drmGetDevices(devs, 16); assert(num >= 0); int i; for (i = 0; i < num; i++) { printf("pci:%04x:%02x:%02x.%d\n", devs[i]->businfo.pci->domain, devs[i]->businfo.pci->bus, devs[i]->businfo.pci->dev, devs[i]->businfo.pci->func); } */ /* struct dirent *dent; struct stat sbuf; DIR *sysdir; sysdir = opendir("/dev/dri"); assert(sysdir); while ((dent = readdir(sysdir))) { char node[1024]; snprintf(node, 1024, "/dev/dri/%s", dent->d_name); if (stat(node, &sbuf)) continue; printf("path=%s, dev=%x rdev=%x maj=%d min=%d\n", node, sbuf.st_dev, sbuf.st_rdev, major(sbuf.st_rdev), minor(sbuf.st_rdev)); } */ fd = open("/dev/dri/card0", O_RDWR); assert(fd >= 0); char *path = drmGetDeviceNameFromFd(fd); assert(path != NULL); printf("get path = %s\n", path); return 0; }
static void ricochet(int tiled, int sprite_w, int sprite_h, int out_w, int out_h, int dump_info) { int ret; int gfx_fd; int keep_moving; const int num_surfaces = 3; uint32_t sprite_handles[num_surfaces]; uint32_t sprite_fb_id[num_surfaces]; int *sprite_x = NULL; int *sprite_y = NULL; uint32_t sprite_stride; uint32_t sprite_size; uint32_t handles[4], pitches[4], offsets[4]; /* we only use [0] */ uint32_t prim_width, prim_height, prim_handle, prim_stride, prim_size, prim_fb_id; struct drm_intel_sprite_colorkey set; struct connector curr_connector; drmModeRes *gfx_resources; struct termios orig_term, curr_term; int c_index; int sprite_index; unsigned int *sprite_plane_id = NULL; uint32_t plane_flags = 0; int *delta_x = NULL, *delta_y = NULL; struct timeval stTimeVal; long long currTime, prevFlipTime, prevMoveTime, deltaFlipTime, deltaMoveTime, SleepTime; char key; int sprite_plane_count = 0; int i; // Open up I915 graphics device gfx_fd = drmOpen("i915", NULL); if (gfx_fd < 0) { printf("Failed to load i915 driver: %s\n", strerror(errno)); return; } // Obtain pointer to struct containing graphics resources gfx_resources = drmModeGetResources(gfx_fd); if (!gfx_resources) { printf("drmModeGetResources failed: %s\n", strerror(errno)); return; } if (dump_info != 0) { dump_connectors(gfx_fd, gfx_resources); dump_crtcs(gfx_fd, gfx_resources); dump_planes(gfx_fd, gfx_resources); } // Save previous terminal settings if (tcgetattr( 0, &orig_term) != 0) { printf("tcgetattr failure: %s\n", strerror(errno)); return; } // Set up input to return characters immediately curr_term = orig_term; curr_term.c_lflag &= ~(ICANON | ECHO | ECHONL); curr_term.c_cc[VMIN] = 0; // No minimum number of characters curr_term.c_cc[VTIME] = 0 ; // Return immediately, even if // nothing has been entered. if (tcsetattr( 0, TCSANOW, &curr_term) != 0) { printf("tcgetattr failure: %s\n", strerror(errno)); return; } // Cycle through all connectors and display the flying sprite // where there are displays attached and the hardware will support it. for (c_index = 0; c_index < gfx_resources->count_connectors; c_index++) { curr_connector.id = gfx_resources->connectors[c_index]; // Find the native (preferred) display mode connector_find_preferred_mode(gfx_fd, gfx_resources, &curr_connector); if (curr_connector.mode_valid == 0) { printf("No valid preferred mode detected\n"); goto out; } // Determine if sprite hardware is available on pipe // associated with this connector. sprite_plane_count = connector_find_plane(gfx_fd, &curr_connector, &sprite_plane_id); if (!sprite_plane_count) { printf("Failed to find sprite plane on crtc\n"); goto out; } // Width and height of preferred mode prim_width = curr_connector.mode.hdisplay; prim_height = curr_connector.mode.vdisplay; // Allocate and fill memory for primary surface ret = prepare_primary_surface( gfx_fd, prim_width, prim_height, &prim_handle, &prim_stride, &prim_size, tiled); if (ret != 0) { printf("Failed to add primary fb (%dx%d): %s\n", prim_width, prim_height, strerror(errno)); goto out; } // Add the primary surface framebuffer ret = drmModeAddFB(gfx_fd, prim_width, prim_height, 24, 32, prim_stride, prim_handle, &prim_fb_id); gem_close(gfx_fd, prim_handle); if (ret != 0) { printf("Failed to add primary fb (%dx%d): %s\n", prim_width, prim_height, strerror(errno)); goto out; } // Allocate and fill sprite surfaces ret = prepare_sprite_surfaces(gfx_fd, sprite_w, sprite_h, num_surfaces, &sprite_handles[0], &sprite_stride, &sprite_size, tiled); if (ret != 0) { printf("Preparation of sprite surfaces failed %dx%d\n", sprite_w, sprite_h); goto out; } // Add the sprite framebuffers for (sprite_index = 0; sprite_index < num_surfaces; sprite_index++) { handles[0] = sprite_handles[sprite_index]; handles[1] = handles[0]; handles[2] = handles[0]; handles[3] = handles[0]; pitches[0] = sprite_stride; pitches[1] = sprite_stride; pitches[2] = sprite_stride; pitches[3] = sprite_stride; memset(offsets, 0, sizeof(offsets)); ret = drmModeAddFB2(gfx_fd, sprite_w, sprite_h, DRM_FORMAT_XRGB8888, handles, pitches, offsets, &sprite_fb_id[sprite_index], plane_flags); gem_close(gfx_fd, sprite_handles[sprite_index]); if (ret) { printf("Failed to add sprite fb (%dx%d): %s\n", sprite_w, sprite_h, strerror(errno)); sprite_index--; while (sprite_index >= 0) { drmModeRmFB(gfx_fd, sprite_fb_id[sprite_index]); sprite_index--; } goto out; } } if (dump_info != 0) { printf("Displayed Mode Connector struct:\n" " .id = %d\n" " .mode_valid = %d\n" " .crtc = %d\n" " .pipe = %d\n" " drmModeModeInfo ...\n" " .name = %s\n" " .type = %d\n" " .flags = %08x\n" " drmModeEncoder ...\n" " .encoder_id = %d\n" " .encoder_type = %d (%s)\n" " .crtc_id = %d\n" " .possible_crtcs = %d\n" " .possible_clones = %d\n" " drmModeConnector ...\n" " .connector_id = %d\n" " .encoder_id = %d\n" " .connector_type = %d (%s)\n" " .connector_type_id = %d\n\n", curr_connector.id, curr_connector.mode_valid, curr_connector.crtc, curr_connector.pipe, curr_connector.mode.name, curr_connector.mode.type, curr_connector.mode.flags, curr_connector.encoder->encoder_id, curr_connector.encoder->encoder_type, kmstest_encoder_type_str(curr_connector.encoder->encoder_type), curr_connector.encoder->crtc_id, curr_connector.encoder->possible_crtcs, curr_connector.encoder->possible_clones, curr_connector.connector->connector_id, curr_connector.connector->encoder_id, curr_connector.connector->connector_type, kmstest_connector_type_str(curr_connector.connector->connector_type), curr_connector.connector->connector_type_id); printf("Sprite surface dimensions = %dx%d\n" "Sprite output dimensions = %dx%d\n" "Press any key to continue >\n", sprite_w, sprite_h, out_w, out_h); // Wait for a key-press while( read(0, &key, 1) == 0); // Purge unread characters tcflush(0, TCIFLUSH); } // Set up the primary display mode ret = drmModeSetCrtc(gfx_fd, curr_connector.crtc, prim_fb_id, 0, 0, &curr_connector.id, 1, &curr_connector.mode); if (ret != 0) { printf("Failed to set mode (%dx%d@%dHz): %s\n", prim_width, prim_height, curr_connector.mode.vrefresh, strerror(errno)); continue; } // Set the sprite colorkey state for(i = 0; i < sprite_plane_count; i++) { set.plane_id = sprite_plane_id[i]; set.min_value = 0; set.max_value = 0; set.flags = I915_SET_COLORKEY_NONE; ret = drmCommandWrite(gfx_fd, DRM_I915_SET_SPRITE_COLORKEY, &set, sizeof(set)); assert(ret == 0); } // Set up sprite output dimensions, initial position, etc. if (out_w > prim_width / 2) out_w = prim_width / 2; if (out_h > prim_height / 2) out_h = prim_height / 2; delta_x = (int *) malloc(sprite_plane_count * sizeof(int)); delta_y = (int *) malloc(sprite_plane_count * sizeof(int)); sprite_x = (int *) malloc(sprite_plane_count * sizeof(int)); sprite_y = (int *) malloc(sprite_plane_count * sizeof(int)); /* Initializing the coordinates (x,y) of the available sprites on the * connector, equally spaced along the diagonal of the rectangle * {(0,0),(prim_width/2, prim_height/2)}. */ for(i = 0; i < sprite_plane_count; i++) { delta_x[i] = 3; delta_y[i] = 4; sprite_x[i] = i * (prim_width / (2 * sprite_plane_count)); sprite_y[i] = i * (prim_height / (2 * sprite_plane_count)); } currTime = 0; prevFlipTime = 0; // Will force immediate sprite flip prevMoveTime = 0; // Will force immediate sprite move deltaFlipTime = 500000; // Flip sprite surface every 1/2 second deltaMoveTime = 100000; // Move sprite every 100 ms sprite_index = num_surfaces - 1; keep_moving = 1; // Bounce sprite off the walls while (keep_moving) { // Obtain system time in usec. if (gettimeofday( &stTimeVal, NULL ) != 0) printf("gettimeofday error: %s\n", strerror(errno)); else currTime = ((long long)stTimeVal.tv_sec * 1000000) + stTimeVal.tv_usec; // Check if it's time to flip the sprite surface if (currTime - prevFlipTime > deltaFlipTime) { sprite_index = (sprite_index + 1) % num_surfaces; prevFlipTime = currTime; } // Move the sprite on the screen and flip // the surface if the index has changed // NB: sprite_w and sprite_h must be 16.16 fixed point, herego << 16 for(i = 0; i < sprite_plane_count; i++) { if (drmModeSetPlane(gfx_fd, sprite_plane_id[i], curr_connector.crtc, sprite_fb_id[sprite_index], plane_flags, sprite_x[i], sprite_y[i], out_w, out_h, 0, 0, sprite_w << 16, sprite_h << 16)) printf("Failed to enable sprite plane: %s\n", strerror(errno)); } // Check if it's time to move the sprite surface if (currTime - prevMoveTime > deltaMoveTime) { // Compute the next position for sprite for(i = 0; i < sprite_plane_count; i++) { sprite_x[i] += delta_x[i]; sprite_y[i] += delta_y[i]; if (sprite_x[i] < 0) { sprite_x[i] = 0; delta_x[i] = -delta_x[i]; } else if (sprite_x[i] > prim_width - out_w) { sprite_x[i] = prim_width - out_w; delta_x[i] = -delta_x[i]; } if (sprite_y[i] < 0) { sprite_y[i] = 0; delta_y[i] = -delta_y[i]; } else if (sprite_y[i] > prim_height - out_h) { sprite_y[i] = prim_height - out_h; delta_y[i] = -delta_y[i]; } } prevMoveTime = currTime; } // Fetch a key from input (non-blocking) if (read(0, &key, 1) == 1) { switch (key) { case 'q': // Kill the program case 'Q': goto out; break; case 's': // Slow down sprite movement; deltaMoveTime = (deltaMoveTime * 100) / 90; if (deltaMoveTime > 800000) { deltaMoveTime = 800000; } break; case 'S': // Speed up sprite movement; deltaMoveTime = (deltaMoveTime * 100) / 110; if (deltaMoveTime < 2000) { deltaMoveTime = 2000; } break; case 'f': // Slow down sprite flipping; deltaFlipTime = (deltaFlipTime * 100) / 90; if (deltaFlipTime > 1000000) deltaFlipTime = 1000000; break; case 'F': // Speed up sprite flipping; deltaFlipTime = (deltaFlipTime * 100) / 110; if (deltaFlipTime < 20000) deltaFlipTime = 20000; break; case 'n': // Next connector case 'N': keep_moving = 0; break; default: break; } // Purge unread characters tcflush(0, TCIFLUSH); } // Wait for min of flip or move deltas SleepTime = (deltaFlipTime < deltaMoveTime) ? deltaFlipTime : deltaMoveTime; usleep(SleepTime); } free(sprite_plane_id); free(sprite_x); free(sprite_y); free(delta_x); free(delta_y); sprite_plane_id = NULL; sprite_plane_count = 0; sprite_x = sprite_y = delta_x = delta_y = NULL; } out: // Purge unread characters tcflush(0, TCIFLUSH); // Restore previous terminal settings if (tcsetattr( 0, TCSANOW, &orig_term) != 0) { printf("tcgetattr failure: %s\n", strerror(errno)); return; } drmModeFreeResources(gfx_resources); }
/* Initialize the screen-specific data structures for the DRI and the Rage 128. This is the main entry point to the device-specific initialization code. It calls device-independent DRI functions to create the DRI data structures and initialize the DRI state. */ static GLboolean R128DRIScreenInit(DRIDriverContext *ctx) { R128InfoPtr info = ctx->driverPrivate; R128DRIPtr pR128DRI; int err, major, minor, patch; drmVersionPtr version; drm_r128_sarea_t *pSAREAPriv; switch (ctx->bpp) { case 8: /* These modes are not supported (yet). */ case 15: case 24: fprintf(stderr, "[dri] R128DRIScreenInit failed (depth %d not supported). " "[dri] Disabling DRI.\n", ctx->bpp); return GL_FALSE; /* Only 16 and 32 color depths are supports currently. */ case 16: case 32: break; } r128_drm_page_size = getpagesize(); info->registerSize = ctx->MMIOSize; ctx->shared.SAREASize = SAREA_MAX; /* Note that drmOpen will try to load the kernel module, if needed. */ ctx->drmFD = drmOpen("r128", NULL ); if (ctx->drmFD < 0) { fprintf(stderr, "[drm] drmOpen failed\n"); return 0; } /* Check the r128 DRM version */ version = drmGetVersion(ctx->drmFD); if (version) { if (version->version_major != 2 || version->version_minor < 2) { /* incompatible drm version */ fprintf(stderr, "[dri] R128DRIScreenInit failed because of a version mismatch.\n" "[dri] r128.o kernel module version is %d.%d.%d but version 2.2 or greater is needed.\n" "[dri] Disabling the DRI.\n", version->version_major, version->version_minor, version->version_patchlevel); drmFreeVersion(version); return GL_FALSE; } info->drmMinor = version->version_minor; drmFreeVersion(version); } if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", ctx->drmFD, ctx->pciBusID, strerror(-err)); return 0; } if (drmAddMap( ctx->drmFD, 0, ctx->shared.SAREASize, DRM_SHM, DRM_CONTAINS_LOCK, &ctx->shared.hSAREA) < 0) { fprintf(stderr, "[drm] drmAddMap failed\n"); return 0; } fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", ctx->shared.SAREASize, ctx->shared.hSAREA); if (drmMap( ctx->drmFD, ctx->shared.hSAREA, ctx->shared.SAREASize, (drmAddressPtr)(&ctx->pSAREA)) < 0) { fprintf(stderr, "[drm] drmMap failed\n"); return 0; } memset(ctx->pSAREA, 0, ctx->shared.SAREASize); fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); /* Need to AddMap the framebuffer and mmio regions here: */ if (drmAddMap( ctx->drmFD, (drm_handle_t)ctx->FBStart, ctx->FBSize, DRM_FRAME_BUFFER, 0, &ctx->shared.hFrameBuffer) < 0) { fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); return 0; } fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", ctx->shared.hFrameBuffer); if (!R128MemoryInit(ctx)) return GL_FALSE; /* Initialize AGP */ if (!info->IsPCI && !R128DRIAgpInit(ctx)) { info->IsPCI = GL_TRUE; fprintf(stderr, "[agp] AGP failed to initialize -- falling back to PCI mode.\n"); fprintf(stderr, "[agp] Make sure you have the agpgart kernel module loaded.\n"); } /* Initialize PCIGART */ if (info->IsPCI && !R128DRIPciInit(ctx)) { return GL_FALSE; } /* DRIScreenInit doesn't add all the common mappings. Add additional mappings here. */ if (!R128DRIMapInit(ctx)) { return GL_FALSE; } /* Create a 'server' context so we can grab the lock for * initialization ioctls. */ if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); return 0; } DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); /* Initialize the kernel data structures */ if (!R128DRIKernelInit(ctx)) { return GL_FALSE; } /* Initialize the vertex buffers list */ if (!R128DRIBufInit(ctx)) { return GL_FALSE; } /* Initialize IRQ */ R128DRIIrqInit(ctx); /* Initialize and start the CCE if required */ R128DRICCEInit(ctx); /* Quick hack to clear the front & back buffers. Could also use * the clear ioctl to do this, but would need to setup hw state * first. */ drimemsetio((char *)ctx->FBAddress + info->frontOffset, 0, info->frontPitch * ctx->cpp * ctx->shared.virtualHeight ); drimemsetio((char *)ctx->FBAddress + info->backOffset, 0, info->backPitch * ctx->cpp * ctx->shared.virtualHeight ); pSAREAPriv = (drm_r128_sarea_t *)(((char*)ctx->pSAREA) + sizeof(drm_sarea_t)); memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); /* This is the struct passed to radeon_dri.so for its initialization */ ctx->driverClientMsg = malloc(sizeof(R128DRIRec)); ctx->driverClientMsgSize = sizeof(R128DRIRec); pR128DRI = (R128DRIPtr)ctx->driverClientMsg; pR128DRI->deviceID = info->Chipset; pR128DRI->width = ctx->shared.virtualWidth; pR128DRI->height = ctx->shared.virtualHeight; pR128DRI->depth = ctx->bpp; pR128DRI->bpp = ctx->bpp; pR128DRI->IsPCI = info->IsPCI; pR128DRI->AGPMode = info->agpMode; pR128DRI->frontOffset = info->frontOffset; pR128DRI->frontPitch = info->frontPitch; pR128DRI->backOffset = info->backOffset; pR128DRI->backPitch = info->backPitch; pR128DRI->depthOffset = info->depthOffset; pR128DRI->depthPitch = info->depthPitch; pR128DRI->spanOffset = info->spanOffset; pR128DRI->textureOffset = info->textureOffset; pR128DRI->textureSize = info->textureSize; pR128DRI->log2TexGran = info->log2TexGran; pR128DRI->registerHandle = info->registerHandle; pR128DRI->registerSize = info->registerSize; pR128DRI->agpTexHandle = info->agpTexHandle; pR128DRI->agpTexMapSize = info->agpTexMapSize; pR128DRI->log2AGPTexGran = info->log2AGPTexGran; pR128DRI->agpTexOffset = info->agpTexStart; pR128DRI->sarea_priv_offset = sizeof(drm_sarea_t); return GL_TRUE; }
static struct pipe_screen * radeon_hardpipe_screen_create(void) { Display *dpy; Window rootWin; XWindowAttributes winAttr; int isCapable; int screen; char *driverName; char *curBusID; unsigned magic; int ddxDriverMajor; int ddxDriverMinor; int ddxDriverPatch; drm_handle_t sAreaOffset; int ret; int drmFD; drm_context_t hHWContext; XID id; dpy = XOpenDisplay(":0"); if (!dpy) { fprintf(stderr, "Open Display Failed\n"); return NULL; } screen = DefaultScreen(dpy); rootWin = RootWindow(dpy, screen); XGetWindowAttributes(dpy, rootWin, &winAttr); ret = uniDRIQueryDirectRenderingCapable(dpy, screen, &isCapable); if (!ret || !isCapable) { fprintf(stderr, "No DRI on this display:sceen\n"); goto error; } if (!uniDRIOpenConnection(dpy, screen, &sAreaOffset, &curBusID)) { fprintf(stderr, "Could not open DRI connection.\n"); goto error; } if (!uniDRIGetClientDriverName(dpy, screen, &ddxDriverMajor, &ddxDriverMinor, &ddxDriverPatch, &driverName)) { fprintf(stderr, "Could not get DRI driver name.\n"); goto error; } if ((drmFD = drmOpen(NULL, curBusID)) < 0) { perror("DRM Device could not be opened"); goto error; } drmGetMagic(drmFD, &magic); if (!uniDRIAuthConnection(dpy, screen, magic)) { fprintf(stderr, "Could not get X server to authenticate us.\n"); goto error; } if (!uniDRICreateContext(dpy, screen, winAttr.visual, &id, &hHWContext)) { fprintf(stderr, "Could not create DRI context.\n"); goto error; } /* FIXME: create a radeon pipe_screen from drmFD and hHWContext */ return NULL; error: return NULL; }
int main() { int fd, fd2; int result; int ret; int i; fd = drmOpen("pscnv", 0); fd2 = drmOpen("pscnv", 0); if (fd == -1 || fd2 == -1) return 1; uint32_t size = 0x2000; uint32_t handle; uint64_t map_handle; ret = pscnv_gem_new(fd, 0xf1f0c0de, PSCNV_GEM_VRAM_SMALL, 0, size, 0, &handle, &map_handle); if (ret) { printf("new: failed ret = %d\n", ret); return 1; } printf("new: handle %d map %llx\n", handle, map_handle); uint32_t *pb_map = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map_handle); printf ("Mapped at %p\n", pb_map); uint32_t vid; ret = pscnv_vspace_new(fd, &vid); if (ret) { printf("vnew: failed ret = %d\n", ret); return 1; } printf ("VID %d\n", vid); uint32_t cid; uint64_t ch_map_handle; ret = pscnv_chan_new(fd, vid, &cid, &ch_map_handle); if (ret) { printf("cnew: failed ret = %d\n", ret); return 1; } printf ("CID %d %llx\n", cid, ch_map_handle); uint64_t offset; ret = pscnv_vspace_map(fd, vid, handle, 0x4001000, 1ull << 32, 0, 0, &offset); if (ret) { printf("vmap: failed ret = %d\n", ret); return 1; } printf ("vmap at %llx\n", offset); ret = pscnv_fifo_init_ib(fd, cid, 0xbeef, 0, 1, offset, 3); if (ret) { printf("fifo_init: failed ret = %d\n", ret); return 1; } volatile uint32_t *chmap = mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, ch_map_handle); if ((void *)chmap == MAP_FAILED) { perror("mmap"); return 1; } printf ("Mapped at %p\n", chmap); pb_map[0] = offset+0x100; pb_map[1] = 0x0800; pb_map[0x40] = 0x20010014; pb_map[0x41] = 0xdeadbeef; chmap[0x8c/4] = 1; while (chmap[0x48/4] != 0xdeadbeef); for (i = 0x40; i < 0x90; i+= 4) { printf ("%03x: %08x\n", i, chmap[i/4]); } close (fd); close (fd2); return 0; }
static Bool PreInit(ScrnInfoPtr pScrn, int flags) { modesettingPtr ms; rgb defaultWeight = { 0, 0, 0 }; EntityInfoPtr pEnt; EntPtr msEnt = NULL; char *BusID = NULL; const char *devicename; Bool prefer_shadow = TRUE; uint64_t value = 0; int ret; int bppflags; int defaultdepth, defaultbpp; if (pScrn->numEntities != 1) return FALSE; pEnt = xf86GetEntityInfo(pScrn->entityList[0]); if (flags & PROBE_DETECT) { return FALSE; } /* Allocate driverPrivate */ if (!GetRec(pScrn)) return FALSE; ms = modesettingPTR(pScrn); ms->SaveGeneration = -1; ms->pEnt = pEnt; pScrn->displayWidth = 640; /* default it */ /* Allocate an entity private if necessary */ if (xf86IsEntityShared(pScrn->entityList[0])) { msEnt = xf86GetEntityPrivate(pScrn->entityList[0], modesettingEntityIndex)->ptr; ms->entityPrivate = msEnt; } else ms->entityPrivate = NULL; if (xf86IsEntityShared(pScrn->entityList[0])) { if (xf86IsPrimInitDone(pScrn->entityList[0])) { /* do something */ } else { xf86SetPrimInitDone(pScrn->entityList[0]); } } pScrn->monitor = pScrn->confScreen->monitor; pScrn->progClock = TRUE; pScrn->rgbBits = 8; #if XSERVER_PLATFORM_BUS if (pEnt->location.type == BUS_PLATFORM) { #ifdef XF86_PDEV_SERVER_FD if (pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD) ms->fd = xf86_get_platform_device_int_attrib(pEnt->location.id.plat, ODEV_ATTRIB_FD, -1); else #endif { char *path = xf86_get_platform_device_attrib(pEnt->location.id.plat, ODEV_ATTRIB_PATH); ms->fd = open_hw(path); } } else #endif if (pEnt->location.type == BUS_PCI) { ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index); if (ms->PciInfo) { BusID = malloc(64); sprintf(BusID, "PCI:%d:%d:%d", #if XSERVER_LIBPCIACCESS ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), ms->PciInfo->dev, ms->PciInfo->func #else ((pciConfigPtr) ms->PciInfo->thisCard)->busnum, ((pciConfigPtr) ms->PciInfo->thisCard)->devnum, ((pciConfigPtr) ms->PciInfo->thisCard)->funcnum #endif ); } ms->fd = drmOpen(NULL, BusID); } else { devicename = xf86FindOptionValue(ms->pEnt->device->options, "kmsdev"); ms->fd = open_hw(devicename); } if (ms->fd < 0) return FALSE; ms->drmmode.fd = ms->fd; #ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT pScrn->capabilities = 0; #ifdef DRM_CAP_PRIME ret = drmGetCap(ms->fd, DRM_CAP_PRIME, &value); if (ret == 0) { if (value & DRM_PRIME_CAP_IMPORT) pScrn->capabilities |= RR_Capability_SinkOutput; } #endif #endif drmmode_get_default_bpp(pScrn, &ms->drmmode, &defaultdepth, &defaultbpp); if (defaultdepth == 24 && defaultbpp == 24) bppflags = SupportConvert32to24 | Support24bppFb; else bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb; if (!xf86SetDepthBpp (pScrn, defaultdepth, defaultdepth, defaultbpp, bppflags)) return FALSE; switch (pScrn->depth) { case 15: case 16: case 24: break; default: xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given depth (%d) is not supported by the driver\n", pScrn->depth); return FALSE; } xf86PrintDepthBpp(pScrn); /* Process the options */ xf86CollectOptions(pScrn, NULL); if (!(ms->Options = malloc(sizeof(Options)))) return FALSE; memcpy(ms->Options, Options, sizeof(Options)); xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options); if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) return FALSE; if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) { ms->drmmode.sw_cursor = TRUE; } ret = drmGetCap(ms->fd, DRM_CAP_DUMB_PREFER_SHADOW, &value); if (!ret) { prefer_shadow = !!value; } ms->cursor_width = 64; ms->cursor_height = 64; ret = drmGetCap(ms->fd, DRM_CAP_CURSOR_WIDTH, &value); if (!ret) { ms->cursor_width = value; } ret = drmGetCap(ms->fd, DRM_CAP_CURSOR_HEIGHT, &value); if (!ret) { ms->cursor_height = value; } ms->drmmode.shadow_enable = xf86ReturnOptValBool(ms->Options, OPTION_SHADOW_FB, prefer_shadow); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ShadowFB: preferred %s, enabled %s\n", prefer_shadow ? "YES" : "NO", ms->drmmode.shadow_enable ? "YES" : "NO"); if (drmmode_pre_init(pScrn, &ms->drmmode, pScrn->bitsPerPixel / 8) == FALSE) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS setup failed\n"); goto fail; } /* * If the driver can do gamma correction, it should call xf86SetGamma() here. */ { Gamma zeros = { 0.0, 0.0, 0.0 }; if (!xf86SetGamma(pScrn, zeros)) { return FALSE; } } if (pScrn->modes == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); return FALSE; } pScrn->currentMode = pScrn->modes; /* Set display resolution */ xf86SetDpi(pScrn, 0, 0); /* Load the required sub modules */ if (!xf86LoadSubModule(pScrn, "fb")) { return FALSE; } if (ms->drmmode.shadow_enable) { if (!xf86LoadSubModule(pScrn, "shadow")) { return FALSE; } } return TRUE; fail: return FALSE; }
static int init_drm(void) { static const char *modules[] = { "omapdrm", "i915", "radeon", "nouveau", "vmwgfx", "exynos" }; drmModeRes *resources; drmModeConnector *connector = NULL; drmModeEncoder *encoder = NULL; int i, j; uint32_t maxRes, curRes; for (i = 0; i < ARRAY_SIZE(modules); i++) { printf("trying to load module %s...", modules[i]); drm.fd = drmOpen(modules[i], NULL); if (drm.fd < 0) { printf("failed.\n"); } else { printf("success.\n"); break; } } if (drm.fd < 0) { printf("could not open drm device\n"); return -1; } resources = drmModeGetResources(drm.fd); if (!resources) { printf("drmModeGetResources failed: %s\n", strerror(errno)); return -1; } drm.resource_id = (uint32_t) resources; /* find a connected connector: */ for (i = 0; i < resources->count_connectors; i++) { connector = drmModeGetConnector(drm.fd, resources->connectors[i]); if (connector->connection == DRM_MODE_CONNECTED) { /* choose the first supported mode */ drm.mode[drm.ndisp] = &connector->modes[0]; drm.connector_id[drm.ndisp] = connector->connector_id; for (j=0; j<resources->count_encoders; j++) { encoder = drmModeGetEncoder(drm.fd, resources->encoders[j]); if (encoder->encoder_id == connector->encoder_id) break; drmModeFreeEncoder(encoder); encoder = NULL; } if (!encoder) { printf("no encoder!\n"); return -1; } drm.encoder[drm.ndisp] = (uint32_t) encoder; drm.crtc_id[drm.ndisp] = encoder->crtc_id; drm.connectors[drm.ndisp] = connector; printf("### Display [%d]: CRTC = %d, Connector = %d\n", drm.ndisp, drm.crtc_id[drm.ndisp], drm.connector_id[drm.ndisp]); printf("\tMode chosen [%s] : Clock => %d, Vertical refresh => %d, Type => %d\n", drm.mode[drm.ndisp]->name, drm.mode[drm.ndisp]->clock, drm.mode[drm.ndisp]->vrefresh, drm.mode[drm.ndisp]->type); printf("\tHorizontal => %d, %d, %d, %d, %d\n", drm.mode[drm.ndisp]->hdisplay, drm.mode[drm.ndisp]->hsync_start, drm.mode[drm.ndisp]->hsync_end, drm.mode[drm.ndisp]->htotal, drm.mode[drm.ndisp]->hskew); printf("\tVertical => %d, %d, %d, %d, %d\n", drm.mode[drm.ndisp]->vdisplay, drm.mode[drm.ndisp]->vsync_start, drm.mode[drm.ndisp]->vsync_end, drm.mode[drm.ndisp]->vtotal, drm.mode[drm.ndisp]->vscan); /* If a connector_id is specified, use the corresponding display */ if ((connector_id != -1) && (connector_id == (int)drm.connector_id[drm.ndisp])) DISP_ID = drm.ndisp; /* If all displays are enabled, choose the connector with maximum * resolution as the primary display */ if (all_display) { maxRes = drm.mode[DISP_ID]->vdisplay * drm.mode[DISP_ID]->hdisplay; curRes = drm.mode[drm.ndisp]->vdisplay * drm.mode[drm.ndisp]->hdisplay; if (curRes > maxRes) DISP_ID = drm.ndisp; } drm.ndisp++; } else { drmModeFreeConnector(connector); } } if (drm.ndisp == 0) { /* we could be fancy and listen for hotplug events and wait for * a connector.. */ printf("no connected connector!\n"); return -1; } return 0; }
static gboolean gst_kms_sink_start (GstBaseSink * bsink) { GstKMSSink *self; drmModeRes *res; drmModeConnector *conn; drmModeCrtc *crtc; drmModePlaneRes *pres; drmModePlane *plane; gboolean universal_planes; gboolean ret; self = GST_KMS_SINK (bsink); universal_planes = FALSE; ret = FALSE; res = NULL; conn = NULL; crtc = NULL; pres = NULL; plane = NULL; if (self->devname) self->fd = drmOpen (self->devname, NULL); else self->fd = kms_open (&self->devname); if (self->fd < 0) goto open_failed; log_drm_version (self); if (!get_drm_caps (self)) goto bail; res = drmModeGetResources (self->fd); if (!res) goto resources_failed; if (self->conn_id == -1) conn = find_main_monitor (self->fd, res); else conn = drmModeGetConnector (self->fd, self->conn_id); if (!conn) goto connector_failed; crtc = find_crtc_for_connector (self->fd, res, conn, &self->pipe); if (!crtc) goto crtc_failed; retry_find_plane: if (universal_planes && drmSetClientCap (self->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) goto set_cap_failed; pres = drmModeGetPlaneResources (self->fd); if (!pres) goto plane_resources_failed; if (self->plane_id == -1) plane = find_plane_for_crtc (self->fd, res, pres, crtc->crtc_id); else plane = drmModeGetPlane (self->fd, self->plane_id); if (!plane) goto plane_failed; /* let's get the available color formats in plane */ if (!ensure_allowed_caps (self, plane, res)) goto bail; self->conn_id = conn->connector_id; self->crtc_id = crtc->crtc_id; self->plane_id = plane->plane_id; GST_INFO_OBJECT (self, "connector id = %d / crtc id = %d / plane id = %d", self->conn_id, self->crtc_id, self->plane_id); self->hdisplay = crtc->mode.hdisplay; self->vdisplay = crtc->mode.vdisplay; self->buffer_id = crtc->buffer_id; self->mm_width = conn->mmWidth; self->mm_height = conn->mmHeight; GST_INFO_OBJECT (self, "display size: pixels = %dx%d / millimeters = %dx%d", self->hdisplay, self->vdisplay, self->mm_width, self->mm_height); self->pollfd.fd = self->fd; gst_poll_add_fd (self->poll, &self->pollfd); gst_poll_fd_ctl_read (self->poll, &self->pollfd, TRUE); ret = TRUE; bail: if (plane) drmModeFreePlane (plane); if (pres) drmModeFreePlaneResources (pres); if (crtc) drmModeFreeCrtc (crtc); if (conn) drmModeFreeConnector (conn); if (res) drmModeFreeResources (res); if (!ret && self->fd >= 0) { drmClose (self->fd); self->fd = -1; } return ret; /* ERRORS */ open_failed: { GST_ERROR_OBJECT (self, "Could not open DRM module %s: %s", GST_STR_NULL (self->devname), strerror (errno)); return FALSE; } resources_failed: { GST_ERROR_OBJECT (self, "drmModeGetResources failed: %s (%d)", strerror (errno), errno); goto bail; } connector_failed: { GST_ERROR_OBJECT (self, "Could not find a valid monitor connector"); goto bail; } crtc_failed: { GST_ERROR_OBJECT (self, "Could not find a crtc for connector"); goto bail; } set_cap_failed: { GST_ERROR_OBJECT (self, "Could not set universal planes capability bit"); goto bail; } plane_resources_failed: { GST_ERROR_OBJECT (self, "drmModeGetPlaneResources failed: %s (%d)", strerror (errno), errno); goto bail; } plane_failed: { if (universal_planes) { GST_ERROR_OBJECT (self, "Could not find a plane for crtc"); goto bail; } else { universal_planes = TRUE; goto retry_find_plane; } } }
int main(int argc, char **argv) { unsigned i; int c, fd, ret; const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos", "omapdrm", "tilcdc", "msm", "tegra", "imx-drm", "rockchip", "mediatek" }; drmVBlank vbl; drmEventContext evctx; struct vbl_info handler_info; opterr = 0; while ((c = getopt(argc, argv, optstr)) != -1) { switch (c) { case 's': secondary = 1; break; default: usage(argv[0]); break; } } for (i = 0; i < ARRAY_SIZE(modules); i++) { printf("trying to load module %s...", modules[i]); fd = drmOpen(modules[i], NULL); if (fd < 0) { printf("failed.\n"); } else { printf("success.\n"); break; } } if (i == ARRAY_SIZE(modules)) { fprintf(stderr, "failed to load any modules, aborting.\n"); return -1; } /* Get current count first */ vbl.request.type = DRM_VBLANK_RELATIVE; if (secondary) vbl.request.type |= DRM_VBLANK_SECONDARY; vbl.request.sequence = 0; ret = drmWaitVBlank(fd, &vbl); if (ret != 0) { printf("drmWaitVBlank (relative) failed ret: %i\n", ret); return -1; } printf("starting count: %d\n", vbl.request.sequence); handler_info.vbl_count = 0; gettimeofday(&handler_info.start, NULL); /* Queue an event for frame + 1 */ vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT; if (secondary) vbl.request.type |= DRM_VBLANK_SECONDARY; vbl.request.sequence = 1; vbl.request.signal = (unsigned long)&handler_info; ret = drmWaitVBlank(fd, &vbl); if (ret != 0) { printf("drmWaitVBlank (relative, event) failed ret: %i\n", ret); return -1; } /* Set up our event handler */ memset(&evctx, 0, sizeof evctx); evctx.version = DRM_EVENT_CONTEXT_VERSION; evctx.vblank_handler = vblank_handler; evctx.page_flip_handler = NULL; /* Poll for events */ while (1) { struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 }; fd_set fds; int ret; FD_ZERO(&fds); FD_SET(0, &fds); FD_SET(fd, &fds); ret = select(fd + 1, &fds, NULL, NULL, &timeout); if (ret <= 0) { fprintf(stderr, "select timed out or error (ret %d)\n", ret); continue; } else if (FD_ISSET(0, &fds)) { break; } ret = drmHandleEvent(fd, &evctx); if (ret != 0) { printf("drmHandleEvent failed: %i\n", ret); return -1; } } return 0; }
static int callCompute_Linux() { Mx_Compute *compute = NULL; int drmFd = 0; struct omap_device *dev = NULL; struct omap_bo *compute_bo = NULL; struct omap_bo *inBuf_bo = NULL; struct omap_bo *outBuf_bo = NULL; uint32_t * inBufPtr = NULL; uint32_t * outBufPtr = NULL; int status = 0; int size; uint32_t val; int i; int32_t ret; /* On Linux, use omapdrm driver to get a Tiler buffer for shared memory */ drmFd = drmOpen("omapdrm", NULL); if (drmFd < 0) { fprintf(stderr, "could not open omapdrm device: %d: %s\n", errno, strerror(errno)); return 1; } dev = omap_device_new(drmFd); if (!dev) { fprintf(stderr, "could not get device from fd\n"); goto leave; } /* allocate a compute structure in shared memory and get a pointer */ compute_bo = omap_bo_new(dev, sizeof(Mx_Compute), OMAP_BO_CACHED); if (compute_bo) { compute = (Mx_Compute *)omap_bo_map(compute_bo); } else { fprintf(stderr, "failed to allocate omap_bo\n"); } if (compute == NULL) { fprintf(stderr, "failed to map omap_bo to user space\n"); goto leave; } /* initialize compute structure */ compute->coef = 0x80400000; compute->key = 0xABA0; compute->size = 0x1000; compute->inBuf = NULL; compute->outBuf = NULL; /* allocate an input buffer in shared memory */ size = compute->size * sizeof(uint32_t); inBuf_bo = omap_bo_new(dev, size, OMAP_BO_CACHED); if (inBuf_bo) { inBufPtr = (uint32_t *)omap_bo_map(inBuf_bo); } else { fprintf(stderr, "failed to allocate inBuf_bo\n"); } if (inBufPtr == NULL) { printf("mmrpc_test: Error: inBufPtr == NULL\n"); status = -1; goto leave; } /* fill input buffer with seed value */ for (i = 0; i < compute->size; i++) { inBufPtr[i] = 0x2010; } /* allocate an output buffer in shared memory */ outBuf_bo = omap_bo_new(dev, size, OMAP_BO_CACHED); if (outBuf_bo) { outBufPtr = (uint32_t *)omap_bo_map(outBuf_bo); } else { fprintf(stderr, "failed to allocate outBuf_bo handle\n"); } if (outBufPtr == NULL) { printf("mmrpc_test: Error: outBufPtr == NULL\n"); status = -1; goto leave; } /* clear output buffer */ for (i = 0; i < compute->size; i++) { outBufPtr[i] = 0; } compute->inBuf = (uint32_t *)inBufPtr; compute->outBuf = (uint32_t *)outBufPtr; /* print some debug info */ printf("mmrpc_test: calling Mx_compute(0x%x)\n", (unsigned int)compute); printf("mmrpc_test: compute->coef=0x%x\n", compute->coef); printf("mmrpc_test: compute->key=0x%x\n", compute->key); printf("mmrpc_test: compute->size=0x%x\n", compute->size); printf("mmrpc_test: compute->inBuf=0x%x\n", (unsigned int)compute->inBuf); printf("mmrpc_test: compute->outBuf=0x%x\n", (unsigned int)compute->outBuf); /* process the buffer */ ret = Mx_compute_Linux(compute, omap_bo_dmabuf(compute_bo), omap_bo_dmabuf(inBuf_bo), omap_bo_dmabuf(outBuf_bo)); if (ret < 0) { status = -1; printf("mmrpc_test: Error: Mx_Compute() failed\n"); goto leave; } printf("mmrpc_test: after Mx_compute(0x%x)\n", (unsigned int)compute); printf("mmrpc_test: compute->coef=0x%x\n", compute->coef); printf("mmrpc_test: compute->key=0x%x\n", compute->key); printf("mmrpc_test: compute->size=0x%x\n", compute->size); printf("mmrpc_test: compute->inBuf=0x%x\n", (unsigned int)compute->inBuf); printf("mmrpc_test: compute->outBuf=0x%x\n", (unsigned int)compute->outBuf); printf("mmrpc_test: compute->inBuf[0]=0x%x\n", (unsigned int)compute->inBuf[0]); printf("mmrpc_test: compute->outBuf[0]=0x%x\n", (unsigned int)compute->outBuf[0]); /* check the output buffer */ for (i = 0; i < compute->size; i++) { val = outBufPtr[i] | compute->coef; if (outBufPtr[i] != val) { status = -1; printf("mmrpc_test: Error: incorrect outBuf\n"); break; } } leave: if (outBuf_bo) { omap_bo_del(outBuf_bo); } if (inBuf_bo) { omap_bo_del(inBuf_bo); } if (compute_bo) { omap_bo_del(compute_bo); } if (dev) { omap_device_del(dev); } if (drmFd) { close(drmFd); } return (status); }
int main(int argc, char *argv[]) { int ret; struct setup s; ret = parse_args(argc, argv, &s); BYE_ON(ret, "failed to parse arguments\n"); BYE_ON(s.module[0] == 0, "DRM module is missing\n"); BYE_ON(s.video[0] == 0, "video node is missing\n"); int drmfd = drmOpen(s.module, NULL); BYE_ON(drmfd < 0, "drmOpen(%s) failed: %s\n", s.module, ERRSTR); int v4lfd = open(s.video, O_RDWR); BYE_ON(v4lfd < 0, "failed to open %s: %s\n", s.video, ERRSTR); struct v4l2_capability caps; memset(&caps, 0, sizeof caps); ret = ioctl(v4lfd, VIDIOC_QUERYCAP, &caps); BYE_ON(ret, "VIDIOC_QUERYCAP failed: %s\n", ERRSTR); /* TODO: add single plane support */ BYE_ON(~caps.capabilities & V4L2_CAP_VIDEO_CAPTURE, "video: singleplanar capture is not supported\n"); struct v4l2_format fmt; memset(&fmt, 0, sizeof fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(v4lfd, VIDIOC_G_FMT, &fmt); BYE_ON(ret < 0, "VIDIOC_G_FMT failed: %s\n", ERRSTR); printf("G_FMT(start): width = %u, height = %u, 4cc = %.4s\n", fmt.fmt.pix.width, fmt.fmt.pix.height, (char*)&fmt.fmt.pix.pixelformat); if (s.use_wh) { fmt.fmt.pix.width = s.w; fmt.fmt.pix.height = s.h; } if (s.in_fourcc) fmt.fmt.pix.pixelformat = s.in_fourcc; ret = ioctl(v4lfd, VIDIOC_S_FMT, &fmt); BYE_ON(ret < 0, "VIDIOC_S_FMT failed: %s\n", ERRSTR); ret = ioctl(v4lfd, VIDIOC_G_FMT, &fmt); BYE_ON(ret < 0, "VIDIOC_G_FMT failed: %s\n", ERRSTR); printf("G_FMT(final): width = %u, height = %u, 4cc = %.4s\n", fmt.fmt.pix.width, fmt.fmt.pix.height, (char*)&fmt.fmt.pix.pixelformat); struct v4l2_requestbuffers rqbufs; memset(&rqbufs, 0, sizeof(rqbufs)); rqbufs.count = s.buffer_count; rqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; rqbufs.memory = V4L2_MEMORY_DMABUF; ret = ioctl(v4lfd, VIDIOC_REQBUFS, &rqbufs); BYE_ON(ret < 0, "VIDIOC_REQBUFS failed: %s\n", ERRSTR); BYE_ON(rqbufs.count < s.buffer_count, "video node allocated only " "%u of %u buffers\n", rqbufs.count, s.buffer_count); s.in_fourcc = fmt.fmt.pix.pixelformat; s.w = fmt.fmt.pix.width; s.h = fmt.fmt.pix.height; /* TODO: add support for multiplanar formats */ struct buffer buffer[s.buffer_count]; uint32_t size = fmt.fmt.pix.sizeimage; uint32_t pitch = fmt.fmt.pix.bytesperline; printf("size = %u pitch = %u\n", size, pitch); for (unsigned int i = 0; i < s.buffer_count; ++i) { ret = buffer_create(&buffer[i], drmfd, &s, size, pitch); BYE_ON(ret, "failed to create buffer%d\n", i); } printf("buffers ready\n"); /*drmModeModeInfo drmmode; uint32_t con; ret = find_mode(&drmmode, drmfd, &s, &con); BYE_ON(ret, "failed to find valid mode\n"); ret = find_plane(drmfd, &s); BYE_ON(ret, "failed to find compatible plane\n");*/ for (unsigned int i = 0; i < s.buffer_count; ++i) { struct v4l2_buffer buf; memset(&buf, 0, sizeof buf); buf.index = i; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_DMABUF; buf.m.fd = buffer[i].dbuf_fd; ret = ioctl(v4lfd, VIDIOC_QBUF, &buf); BYE_ON(ret < 0, "VIDIOC_QBUF for buffer %d failed: %s (fd %u)\n", buf.index, ERRSTR, buffer[i].dbuf_fd); } int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(v4lfd, VIDIOC_STREAMON, &type); BYE_ON(ret < 0, "STREAMON failed: %s\n", ERRSTR); struct pollfd fds[] = { { .fd = v4lfd, .events = POLLIN }, { .fd = drmfd, .events = POLLIN },
unsigned int init_pci(unsigned char bus, const unsigned char forcemem) { int ret = pci_system_init(); if (ret) die(_("Failed to init pciaccess")); struct pci_id_match match; match.vendor_id = 0x1002; match.device_id = PCI_MATCH_ANY; match.subvendor_id = PCI_MATCH_ANY; match.subdevice_id = PCI_MATCH_ANY; match.device_class = 0; match.device_class_mask = 0; match.match_data = 0; struct pci_device_iterator *iter = pci_id_match_iterator_create(&match); struct pci_device *dev = NULL; char busid[32]; while ((dev = pci_device_next(iter))) { pci_device_probe(dev); if ((dev->device_class & 0x00ffff00) != 0x00030000 && (dev->device_class & 0x00ffff00) != 0x00038000) continue; snprintf(busid, sizeof(busid), "pci:%04x:%02x:%02x.%u", dev->domain, dev->bus, dev->dev, dev->func); if (!bus || bus == dev->bus) break; } pci_iterator_destroy(iter); if (!dev) die(_("Can't find Radeon cards")); const unsigned int device_id = dev->device_id; int reg = 2; if (getfamily(device_id) >= BONAIRE) reg = 5; if (!dev->regions[reg].size) die(_("Can't get the register area size")); // printf("Found area %p, size %lu\n", area, dev->regions[reg].size); // DRM support for VRAM drm_fd = drmOpen(NULL, busid); if (drm_fd >= 0) { drmVersionPtr ver = drmGetVersion(drm_fd); if (strcmp(ver->name, "radeon") != 0 && strcmp(ver->name, "amdgpu") != 0) { close(drm_fd); drm_fd = -1; } strcpy(drm_name, ver->name); drmFreeVersion(ver); } if (drm_fd < 0 && access("/dev/ati/card0", F_OK) == 0) // fglrx path drm_fd = open("/dev/ati/card0", O_RDWR); use_ioctl = 0; if (drm_fd >= 0) { authenticate_drm(drm_fd); uint32_t rreg = 0x8010; use_ioctl = get_drm_value(drm_fd, RADEON_INFO_READ_REG, &rreg); } if (forcemem) { printf(_("Forcing the /dev/mem path.\n")); use_ioctl = 0; } if (!use_ioctl) { int mem = open("/dev/mem", O_RDONLY); if (mem < 0) die(_("Cannot access GPU registers, are you root?")); area = mmap(NULL, MMAP_SIZE, PROT_READ, MAP_PRIVATE, mem, dev->regions[reg].base_addr + 0x8000); if (area == MAP_FAILED) die(_("mmap failed")); } bits.vram = 0; if (drm_fd < 0) { printf(_("Failed to open DRM node, no VRAM support.\n")); } else { drmDropMaster(drm_fd); drmVersionPtr ver = drmGetVersion(drm_fd); /* printf("Version %u.%u.%u, name %s\n", ver->version_major, ver->version_minor, ver->version_patchlevel, ver->name);*/ if (ver->version_major < 2 || (ver->version_major == 2 && ver->version_minor < 36)) { printf(_("Kernel too old for VRAM reporting.\n")); drmFreeVersion(ver); goto out; } drmFreeVersion(ver); // No version indicator, so we need to test once // We use different codepaths for radeon and amdgpu // We store vram_size and check below if the ret value is sane if (strcmp(drm_name, "radeon") == 0) { struct drm_radeon_gem_info gem; ret = drmCommandWriteRead(drm_fd, DRM_RADEON_GEM_INFO, &gem, sizeof(gem)); vramsize = gem.vram_size; } else if (strcmp(drm_name, "amdgpu") == 0) { #ifdef ENABLE_AMDGPU struct drm_amdgpu_info_vram_gtt vram_gtt = {}; struct drm_amdgpu_info request; memset(&request, 0, sizeof(request)); request.return_pointer = (unsigned long) &vram_gtt; request.return_size = sizeof(vram_gtt); request.query = AMDGPU_INFO_VRAM_GTT; ret = drmCommandWrite(drm_fd, DRM_AMDGPU_INFO, &request, sizeof(request)); vramsize = vram_gtt.vram_size; #else printf(_("amdgpu DRM driver is used, but amdgpu VRAM size reporting is not enabled\n")); #endif } if (ret) { printf(_("Failed to get VRAM size, error %d\n"), ret); goto out; } ret = getvram(); if (ret == 0) { if (strcmp(drm_name, "amdgpu") == 0) { #ifndef ENABLE_AMDGPU printf(_("amdgpu DRM driver is used, but amdgpu VRAM usage reporting is not enabled\n")); #endif } printf(_("Failed to get VRAM usage, kernel likely too old\n")); goto out; } bits.vram = 1; } out: pci_system_cleanup(); return device_id; }
static bool load_driver (ply_renderer_backend_t *backend) { char *driver_name; int device_fd; driver_name = find_driver_for_device (backend->device_name); ply_trace ("Attempting to load driver '%s'", driver_name); device_fd = drmOpen (driver_name, NULL); if (device_fd < 0) { ply_trace ("drmOpen failed"); free (driver_name); return false; } backend->driver_interface = NULL; /* Try intel driver first if we're supporting the legacy GDM transition * since it can map the kernel console, which gives us the ability to do * a more seamless transition when plymouth quits before X starts */ #if defined(PLY_ENABLE_DEPRECATED_GDM_TRANSITION) && defined(PLY_ENABLE_LIBDRM_INTEL) if (backend->driver_interface == NULL && strcmp (driver_name, "i915") == 0) { backend->driver_interface = ply_renderer_i915_driver_get_interface (); backend->driver_supports_mapping_console = true; } #endif if (backend->driver_interface == NULL) { backend->driver_interface = ply_renderer_generic_driver_get_interface (device_fd); backend->driver_supports_mapping_console = false; } #ifdef PLY_ENABLE_LIBDRM_INTEL if (backend->driver_interface == NULL && strcmp (driver_name, "i915") == 0) { backend->driver_interface = ply_renderer_i915_driver_get_interface (); backend->driver_supports_mapping_console = true; } #endif #ifdef PLY_ENABLE_LIBDRM_RADEON if (backend->driver_interface == NULL && strcmp (driver_name, "radeon") == 0) { backend->driver_interface = ply_renderer_radeon_driver_get_interface (); backend->driver_supports_mapping_console = false; } #endif #ifdef PLY_ENABLE_LIBDRM_NOUVEAU if (backend->driver_interface == NULL && strcmp (driver_name, "nouveau") == 0) { backend->driver_interface = ply_renderer_nouveau_driver_get_interface (); backend->driver_supports_mapping_console = false; } #endif free (driver_name); if (backend->driver_interface == NULL) { #ifdef PLY_ENABLE_LIBKMS backend->driver_interface = ply_renderer_libkms_driver_get_interface (); backend->driver_supports_mapping_console = false; #else close (device_fd); return false; #endif } backend->driver = backend->driver_interface->create_driver (device_fd); if (backend->driver == NULL) { close (device_fd); return false; } backend->device_fd = device_fd; return true; }