X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=xf86drmMode.c;h=60ce3699f3e38617a1a055dac7f7f07690309c27;hb=6737f6845cfc50596cd5f94d4080264b25168b43;hp=f330e6f2b181dcad27237d132ddbde96f50b1237;hpb=04f90a44709a48fb932ea954011cb551659bf246;p=platform%2Fupstream%2Flibdrm.git diff --git a/xf86drmMode.c b/xf86drmMode.c index f330e6f..60ce369 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -41,6 +41,10 @@ #include #include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "xf86drmMode.h" #include "xf86drm.h" #include @@ -49,9 +53,25 @@ #include #include +#ifdef HAVE_VALGRIND +#include +#include +#define VG(x) x +#else +#define VG(x) +#endif + +#define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s))) + #define U642VOID(x) ((void *)(unsigned long)(x)) #define VOID2U64(x) ((uint64_t)(unsigned long)(x)) +static inline int DRM_IOCTL(int fd, unsigned long cmd, void *arg) +{ + int ret = drmIoctl(fd, cmd, arg); + return ret < 0 ? -errno : ret; +} + /* * Util functions */ @@ -90,6 +110,10 @@ void drmModeFreeResources(drmModeResPtr ptr) if (!ptr) return; + drmFree(ptr->fbs); + drmFree(ptr->crtcs); + drmFree(ptr->connectors); + drmFree(ptr->encoders); drmFree(ptr); } @@ -235,6 +259,7 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, struct drm_mode_fb_cmd f; int ret; + VG_CLEAR(f); f.width = width; f.height = height; f.pitch = pitch; @@ -242,7 +267,30 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, f.depth = depth; f.handle = bo_handle; - if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_ADDFB, &f))) + if ((ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ADDFB, &f))) + return ret; + + *buf_id = f.fb_id; + return 0; +} + +int drmModeAddFB2(int fd, uint32_t width, uint32_t height, + uint32_t pixel_format, uint32_t bo_handles[4], + uint32_t pitches[4], uint32_t offsets[4], + uint32_t *buf_id, uint32_t flags) +{ + struct drm_mode_fb_cmd2 f; + int ret; + + f.width = width; + f.height = height; + f.pixel_format = pixel_format; + f.flags = flags; + memcpy(f.handles, bo_handles, 4 * sizeof(bo_handles[0])); + memcpy(f.pitches, pitches, 4 * sizeof(pitches[0])); + memcpy(f.offsets, offsets, 4 * sizeof(offsets[0])); + + if ((ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ADDFB2, &f))) return ret; *buf_id = f.fb_id; @@ -251,7 +299,7 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, int drmModeRmFB(int fd, uint32_t bufferId) { - return drmIoctl(fd, DRM_IOCTL_MODE_RMFB, &bufferId); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId); } @@ -289,7 +337,7 @@ int drmModeDirtyFB(int fd, uint32_t bufferId, dirty.clips_ptr = VOID2U64(clips); dirty.num_clips = num_clips; - return drmIoctl(fd, DRM_IOCTL_MODE_DIRTYFB, &dirty); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_DIRTYFB, &dirty); } @@ -302,6 +350,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId) struct drm_mode_crtc crtc; drmModeCrtcPtr r; + VG_CLEAR(crtc); crtc.crtc_id = crtcId; if (drmIoctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc)) @@ -318,8 +367,11 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId) r->x = crtc.x; r->y = crtc.y; r->mode_valid = crtc.mode_valid; - if (r->mode_valid) + if (r->mode_valid) { memcpy(&r->mode, &crtc.mode, sizeof(struct drm_mode_modeinfo)); + r->width = crtc.mode.hdisplay; + r->height = crtc.mode.vdisplay; + } r->buffer_id = crtc.fb_id; r->gamma_size = crtc.gamma_size; return r; @@ -332,6 +384,7 @@ int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, { struct drm_mode_crtc crtc; + VG_CLEAR(crtc); crtc.x = x; crtc.y = y; crtc.crtc_id = crtcId; @@ -344,7 +397,7 @@ int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, } else crtc.mode_valid = 0; - return drmIoctl(fd, DRM_IOCTL_MODE_SETCRTC, &crtc); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc); } /* @@ -361,7 +414,22 @@ int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width arg.height = height; arg.handle = bo_handle; - return drmIoctl(fd, DRM_IOCTL_MODE_CURSOR, &arg); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_CURSOR, &arg); +} + +int drmModeSetCursor2(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height, int32_t hot_x, int32_t hot_y) +{ + struct drm_mode_cursor2 arg; + + arg.flags = DRM_MODE_CURSOR_BO; + arg.crtc_id = crtcId; + arg.width = width; + arg.height = height; + arg.handle = bo_handle; + arg.hot_x = hot_x; + arg.hot_y = hot_y; + + return DRM_IOCTL(fd, DRM_IOCTL_MODE_CURSOR2, &arg); } int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y) @@ -373,7 +441,7 @@ int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y) arg.x = x; arg.y = y; - return drmIoctl(fd, DRM_IOCTL_MODE_CURSOR, &arg); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_CURSOR, &arg); } /* @@ -385,6 +453,7 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id) drmModeEncoderPtr r = NULL; enc.encoder_id = encoder_id; + enc.crtc_id = 0; enc.encoder_type = 0; enc.possible_crtcs = 0; enc.possible_clones = 0; @@ -510,7 +579,7 @@ int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_inf memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo)); res.connector_id = connector_id; - return drmIoctl(fd, DRM_IOCTL_MODE_ATTACHMODE, &res); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_ATTACHMODE, &res); } int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info) @@ -520,7 +589,7 @@ int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_inf memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo)); res.connector_id = connector_id; - return drmIoctl(fd, DRM_IOCTL_MODE_DETACHMODE, &res); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_DETACHMODE, &res); } @@ -529,6 +598,7 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id) struct drm_mode_get_property prop; drmModePropertyPtr r; + VG_CLEAR(prop); prop.prop_id = property_id; prop.count_enum_blobs = 0; prop.count_values = 0; @@ -542,7 +612,7 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id) if (prop.count_values) prop.values_ptr = VOID2U64(drmMalloc(prop.count_values * sizeof(uint64_t))); - if (prop.count_enum_blobs && (prop.flags & DRM_MODE_PROP_ENUM)) + if (prop.count_enum_blobs && (prop.flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK))) prop.enum_blob_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum))); if (prop.count_enum_blobs && (prop.flags & DRM_MODE_PROP_BLOB)) { @@ -564,7 +634,7 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id) r->flags = prop.flags; if (prop.count_values) r->values = drmAllocCpy(U642VOID(prop.values_ptr), prop.count_values, sizeof(uint64_t)); - if (prop.flags & DRM_MODE_PROP_ENUM) { + if (prop.flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { r->count_enums = prop.count_enum_blobs; r->enums = drmAllocCpy(U642VOID(prop.enum_blob_ptr), prop.count_enum_blobs, sizeof(struct drm_mode_property_enum)); } else if (prop.flags & DRM_MODE_PROP_BLOB) { @@ -613,7 +683,7 @@ drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id) } if (!(r = drmMalloc(sizeof(*r)))) - return NULL; + goto err_allocs; r->id = blob.blob_id; r->length = blob.length; @@ -637,16 +707,12 @@ int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property uint64_t value) { struct drm_mode_connector_set_property osp; - int ret; osp.connector_id = connector_id; osp.prop_id = property_id; osp.value = value; - if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp))) - return ret; - - return 0; + return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp); } /* @@ -657,7 +723,7 @@ int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property */ int drmCheckModesettingSupported(const char *busid) { -#ifdef __linux__ +#if defined (__linux__) char pci_dev_dir[1024]; int domain, bus, dev, func; DIR *sysdir; @@ -707,6 +773,41 @@ int drmCheckModesettingSupported(const char *busid) 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; #endif return -ENOSYS; @@ -715,7 +816,6 @@ int drmCheckModesettingSupported(const char *busid) int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size, uint16_t *red, uint16_t *green, uint16_t *blue) { - int ret; struct drm_mode_crtc_lut l; l.crtc_id = crtc_id; @@ -724,16 +824,12 @@ int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size, l.green = VOID2U64(green); l.blue = VOID2U64(blue); - if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_GETGAMMA, &l))) - return ret; - - return 0; + return DRM_IOCTL(fd, DRM_IOCTL_MODE_GETGAMMA, &l); } int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size, uint16_t *red, uint16_t *green, uint16_t *blue) { - int ret; struct drm_mode_crtc_lut l; l.crtc_id = crtc_id; @@ -742,10 +838,7 @@ int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size, l.green = VOID2U64(green); l.blue = VOID2U64(blue); - if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_SETGAMMA, &l))) - return ret; - - return 0; + return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETGAMMA, &l); } int drmHandleEvent(int fd, drmEventContextPtr evctx) @@ -810,5 +903,229 @@ int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id, flip.flags = flags; flip.reserved = 0; - return drmIoctl(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip); +} + +int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id, + uint32_t fb_id, uint32_t flags, + int32_t crtc_x, int32_t crtc_y, + uint32_t crtc_w, uint32_t crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h) + +{ + struct drm_mode_set_plane s; + + s.plane_id = plane_id; + s.crtc_id = crtc_id; + s.fb_id = fb_id; + s.flags = flags; + s.crtc_x = crtc_x; + s.crtc_y = crtc_y; + s.crtc_w = crtc_w; + s.crtc_h = crtc_h; + s.src_x = src_x; + s.src_y = src_y; + s.src_w = src_w; + s.src_h = src_h; + + return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s); +} + + +drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id) +{ + struct drm_mode_get_plane ovr, counts; + drmModePlanePtr r = 0; + +retry: + memset(&ovr, 0, sizeof(struct drm_mode_get_plane)); + ovr.plane_id = plane_id; + if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr)) + return 0; + + counts = ovr; + + if (ovr.count_format_types) { + ovr.format_type_ptr = VOID2U64(drmMalloc(ovr.count_format_types * + sizeof(uint32_t))); + if (!ovr.format_type_ptr) + goto err_allocs; + } + + if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr)) + goto err_allocs; + + if (counts.count_format_types < ovr.count_format_types) { + drmFree(U642VOID(ovr.format_type_ptr)); + goto retry; + } + + if (!(r = drmMalloc(sizeof(*r)))) + goto err_allocs; + + r->count_formats = ovr.count_format_types; + r->plane_id = ovr.plane_id; + r->crtc_id = ovr.crtc_id; + r->fb_id = ovr.fb_id; + r->possible_crtcs = ovr.possible_crtcs; + r->gamma_size = ovr.gamma_size; + r->formats = drmAllocCpy(U642VOID(ovr.format_type_ptr), + ovr.count_format_types, sizeof(uint32_t)); + if (ovr.count_format_types && !r->formats) { + drmFree(r->formats); + drmFree(r); + r = 0; + } + +err_allocs: + drmFree(U642VOID(ovr.format_type_ptr)); + + return r; +} + +void drmModeFreePlane(drmModePlanePtr ptr) +{ + if (!ptr) + return; + + drmFree(ptr->formats); + drmFree(ptr); +} + +drmModePlaneResPtr drmModeGetPlaneResources(int fd) +{ + struct drm_mode_get_plane_res res, counts; + drmModePlaneResPtr r = 0; + +retry: + memset(&res, 0, sizeof(struct drm_mode_get_plane_res)); + if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res)) + return 0; + + counts = res; + + if (res.count_planes) { + res.plane_id_ptr = VOID2U64(drmMalloc(res.count_planes * + sizeof(uint32_t))); + if (!res.plane_id_ptr) + goto err_allocs; + } + + if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res)) + goto err_allocs; + + if (counts.count_planes < res.count_planes) { + drmFree(U642VOID(res.plane_id_ptr)); + goto retry; + } + + if (!(r = drmMalloc(sizeof(*r)))) + goto err_allocs; + + r->count_planes = res.count_planes; + r->planes = drmAllocCpy(U642VOID(res.plane_id_ptr), + res.count_planes, sizeof(uint32_t)); + if (res.count_planes && !r->planes) { + drmFree(r->planes); + drmFree(r); + r = 0; + } + +err_allocs: + drmFree(U642VOID(res.plane_id_ptr)); + + return r; +} + +void drmModeFreePlaneResources(drmModePlaneResPtr ptr) +{ + if (!ptr) + return; + + drmFree(ptr->planes); + drmFree(ptr); +} + +drmModeObjectPropertiesPtr drmModeObjectGetProperties(int fd, + uint32_t object_id, + uint32_t object_type) +{ + struct drm_mode_obj_get_properties properties; + drmModeObjectPropertiesPtr ret = NULL; + uint32_t count; + +retry: + memset(&properties, 0, sizeof(struct drm_mode_obj_get_properties)); + properties.obj_id = object_id; + properties.obj_type = object_type; + + if (drmIoctl(fd, DRM_IOCTL_MODE_OBJ_GETPROPERTIES, &properties)) + return 0; + + count = properties.count_props; + + if (count) { + properties.props_ptr = VOID2U64(drmMalloc(count * + sizeof(uint32_t))); + if (!properties.props_ptr) + goto err_allocs; + properties.prop_values_ptr = VOID2U64(drmMalloc(count * + sizeof(uint64_t))); + if (!properties.prop_values_ptr) + goto err_allocs; + } + + if (drmIoctl(fd, DRM_IOCTL_MODE_OBJ_GETPROPERTIES, &properties)) + goto err_allocs; + + if (count < properties.count_props) { + drmFree(U642VOID(properties.props_ptr)); + drmFree(U642VOID(properties.prop_values_ptr)); + goto retry; + } + count = properties.count_props; + + ret = drmMalloc(sizeof(*ret)); + if (!ret) + goto err_allocs; + + ret->count_props = count; + ret->props = drmAllocCpy(U642VOID(properties.props_ptr), + count, sizeof(uint32_t)); + ret->prop_values = drmAllocCpy(U642VOID(properties.prop_values_ptr), + count, sizeof(uint64_t)); + if (ret->count_props && (!ret->props || !ret->prop_values)) { + drmFree(ret->props); + drmFree(ret->prop_values); + drmFree(ret); + ret = NULL; + } + +err_allocs: + drmFree(U642VOID(properties.props_ptr)); + drmFree(U642VOID(properties.prop_values_ptr)); + return ret; +} + +void drmModeFreeObjectProperties(drmModeObjectPropertiesPtr ptr) +{ + if (!ptr) + return; + drmFree(ptr->props); + drmFree(ptr->prop_values); + drmFree(ptr); +} + +int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type, + uint32_t property_id, uint64_t value) +{ + struct drm_mode_obj_set_property prop; + + prop.value = value; + prop.prop_id = property_id; + prop.obj_id = object_id; + prop.obj_type = object_type; + + return DRM_IOCTL(fd, DRM_IOCTL_MODE_OBJ_SETPROPERTY, &prop); }