コード例 #1
0
static int savage_bci_get_buffers(struct drm_device *dev,
				  struct drm_file *file_priv,
				  struct drm_dma *d)
{
	struct drm_buf *buf;
	int i;

	for (i = d->granted_count; i < d->request_count; i++) {
		buf = savage_freelist_get(dev);
		if (!buf)
			return -EAGAIN;

		buf->file_priv = file_priv;

		if (DRM_COPY_TO_USER(&d->request_indices[i],
				     &buf->idx, sizeof(buf->idx)))
			return -EFAULT;
		if (DRM_COPY_TO_USER(&d->request_sizes[i],
				     &buf->total, sizeof(buf->total)))
			return -EFAULT;

		d->granted_count++;
	}
	return 0;
}
コード例 #2
0
int i915_mem_alloc(struct drm_device *dev, void *data,
		   struct drm_file *file_priv)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	drm_i915_mem_alloc_t *alloc = data;
	struct mem_block *block, **heap;

	if (!dev_priv) {
		DRM_ERROR("called with no initialization\n");
		return -EINVAL;
	}

	heap = get_heap(dev_priv, alloc->region);
	if (!heap || !*heap)
		return -EFAULT;

	
	if (alloc->alignment < 12)
		alloc->alignment = 12;

	block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv);

	if (!block)
		return -ENOMEM;

	mark_block(dev, block, 1);

	if (DRM_COPY_TO_USER(alloc->region_offset, &block->start,
			     sizeof(int))) {
		DRM_ERROR("copy_to_user\n");
		return -EFAULT;
	}

	return 0;
}
コード例 #3
0
static int mga_getparam( DRM_IOCTL_ARGS )
{
	DRM_DEVICE;
	drm_mga_private_t *dev_priv = dev->dev_private;
	drm_mga_getparam_t param;
	int value;

	if ( !dev_priv ) {
		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
		return DRM_ERR(EINVAL);
	}

	DRM_COPY_FROM_USER_IOCTL( param, (drm_mga_getparam_t __user *)data,
			     sizeof(param) );

	DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );

	switch( param.param ) {
	case MGA_PARAM_IRQ_NR:
		value = dev->irq;
		break;
	case MGA_PARAM_CARD_TYPE:
		value = dev_priv->chipset;
		break;
	default:
		return DRM_ERR(EINVAL);
	}

	if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) {
		DRM_ERROR( "copy_to_user\n" );
		return DRM_ERR(EFAULT);
	}
	
	return 0;
}
コード例 #4
0
ファイル: radeon_irq.c プロジェクト: wan721/DragonFlyBSD
/* Needs the lock as it touches the ring.
 */
int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
	drm_radeon_private_t *dev_priv = dev->dev_private;
	drm_radeon_irq_emit_t *emit = data;
	int result;

	if (!dev_priv) {
		DRM_ERROR("called with no initialization\n");
		return -EINVAL;
	}

	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
		return -EINVAL;

	LOCK_TEST_WITH_RETURN(dev, file_priv);

	result = radeon_emit_irq(dev);

	if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
		DRM_ERROR("copy_to_user\n");
		return -EFAULT;
	}

	return 0;
}
コード例 #5
0
static int mga_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
	drm_mga_private_t *dev_priv = dev->dev_private;
	drm_mga_getparam_t *param = data;
	int value;

	if (!dev_priv) {
		DRM_ERROR("called with no initialization\n");
		return -EINVAL;
	}

	DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);

	switch (param->param) {
	case MGA_PARAM_IRQ_NR:
		value = drm_dev_to_irq(dev);
		break;
	case MGA_PARAM_CARD_TYPE:
		value = dev_priv->chipset;
		break;
	default:
		return -EINVAL;
	}

	if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) {
		DRM_ERROR("copy_to_user\n");
		return -EFAULT;
	}

	return 0;
}
コード例 #6
0
int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
{
	struct radeon_device *rdev = dev->dev_private;
	struct drm_radeon_info *info;
	struct radeon_mode_info *minfo = &rdev->mode_info;
	uint32_t *value_ptr;
	uint32_t value;
	struct drm_crtc *crtc;
	int i, found;

	info = data;
	value_ptr = (uint32_t *)((unsigned long)info->value);
	if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value)))
		return -EFAULT;

	switch (info->request) {
	case RADEON_INFO_DEVICE_ID:
		value = dev->pci_device;
		break;
	case RADEON_INFO_NUM_GB_PIPES:
		value = rdev->num_gb_pipes;
		break;
	case RADEON_INFO_NUM_Z_PIPES:
		value = rdev->num_z_pipes;
		break;
	case RADEON_INFO_ACCEL_WORKING:
		/* xf86-video-ati 6.13.0 relies on this being false for evergreen */
		if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK))
			value = false;
		else
			value = rdev->accel_working;
		break;
	case RADEON_INFO_CRTC_FROM_ID:
		for (i = 0, found = 0; i < rdev->num_crtc; i++) {
			crtc = (struct drm_crtc *)minfo->crtcs[i];
			if (crtc && crtc->base.id == value) {
				struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
				value = radeon_crtc->crtc_id;
				found = 1;
				break;
			}
		}
		if (!found) {
			DRM_DEBUG("unknown crtc id %d\n", value);
			return -EINVAL;
		}
		break;
	case RADEON_INFO_ACCEL_WORKING2:
		value = rdev->accel_working;
		break;
	default:
		DRM_DEBUG("Invalid request %d\n", info->request);
		return -EINVAL;
	}
	if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) {
		DRM_ERROR("copy_to_user\n");
		return -EFAULT;
	}
	return 0;
}
コード例 #7
0
ファイル: i915_irq.c プロジェクト: FatSunHYS/OSCourseDesign
/* Needs the lock as it touches the ring.
 */
int i915_irq_emit(DRM_IOCTL_ARGS)
{
	DRM_DEVICE;
	drm_i915_private_t *dev_priv = dev->dev_private;
	drm_i915_irq_emit_t emit;
	int result;

	LOCK_TEST_WITH_RETURN(dev, filp);

	if (!dev_priv) {
		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
		return DRM_ERR(EINVAL);
	}

	DRM_COPY_FROM_USER_IOCTL(emit, (drm_i915_irq_emit_t __user *) data,
				 sizeof(emit));

	result = i915_emit_irq(dev);

	if (DRM_COPY_TO_USER(emit.irq_seq, &result, sizeof(int))) {
		DRM_ERROR("copy_to_user\n");
		return DRM_ERR(EFAULT);
	}

	return 0;
}
コード例 #8
0
/*
 * Userspace get informations ioctl
 */
int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
{
	struct radeon_device *rdev = dev->dev_private;
	struct drm_radeon_info *info;
	uint32_t *value_ptr;
	uint32_t value;

	info = data;
	value_ptr = (uint32_t *)((unsigned long)info->value);
	switch (info->request) {
	case RADEON_INFO_DEVICE_ID:
		value = dev->pci_device;
		break;
	case RADEON_INFO_NUM_GB_PIPES:
		value = rdev->num_gb_pipes;
		break;
	case RADEON_INFO_NUM_Z_PIPES:
		value = rdev->num_z_pipes;
		break;
	case RADEON_INFO_ACCEL_WORKING:
		value = rdev->accel_working;
		break;
	default:
		DRM_DEBUG("Invalid request %d\n", info->request);
		return -EINVAL;
	}
	if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) {
		DRM_ERROR("copy_to_user\n");
		return -EFAULT;
	}
	return 0;
}
コード例 #9
0
static int mga_set_fence(DRM_IOCTL_ARGS)
{
	DRM_DEVICE;
	drm_mga_private_t *dev_priv = dev->dev_private;
	u32 temp;
	DMA_LOCALS;

	if (!dev_priv) {
		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
		return DRM_ERR(EINVAL);
	}

	DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);

	/* I would normal do this assignment in the declaration of temp,
	 * but dev_priv may be NULL.
	 */

	temp = dev_priv->next_fence_to_post;
	dev_priv->next_fence_to_post++;

	BEGIN_DMA(1);
	DMA_BLOCK(MGA_DMAPAD, 0x00000000,
		  MGA_DMAPAD, 0x00000000,
		  MGA_DMAPAD, 0x00000000,
		  MGA_SOFTRAP, 0x00000000);
	ADVANCE_DMA();

	if (DRM_COPY_TO_USER( (u32 __user *) data, & temp, sizeof(u32))) {
		DRM_ERROR("copy_to_user\n");
		return DRM_ERR(EFAULT);
	}

	return 0;
}
コード例 #10
0
ファイル: savage_bci.c プロジェクト: Ionic/nx-libs
static int savage_bci_get_buffers(DRMFILE filp, drm_device_t *dev, drm_dma_t *d)
{
	drm_buf_t *buf;
	int i;

	for (i = d->granted_count; i < d->request_count; i++) {
		buf = savage_freelist_get(dev);
		if (!buf)
			return DRM_ERR(EAGAIN);

		buf->filp = filp;

		if (DRM_COPY_TO_USER(&d->request_indices[i],
				     &buf->idx, sizeof(buf->idx)))
			return DRM_ERR(EFAULT);
		if (DRM_COPY_TO_USER(&d->request_sizes[i],
				     &buf->total, sizeof(buf->total)))
			return DRM_ERR(EFAULT);

		d->granted_count++;
	}
	return 0;
}
コード例 #11
0
ファイル: i915_gem_tiling.c プロジェクト: bahamas10/openzfs
/*ARGSUSED*/
int
i915_gem_get_tiling(DRM_IOCTL_ARGS)
{
	DRM_DEVICE;
	struct drm_i915_gem_get_tiling args;
	drm_i915_private_t *dev_priv = dev->dev_private;
	struct drm_gem_object *obj;
	struct drm_i915_gem_object *obj_priv;
	int ret;

	if (dev->driver->use_gem != 1)
		return ENODEV;

	DRM_COPYFROM_WITH_RETURN(&args,
	    (struct drm_i915_gem_get_tiling __user *) data, sizeof(args));

	obj = drm_gem_object_lookup(fpriv, args.handle);
	if (obj == NULL)
		return EINVAL;
	obj_priv = obj->driver_private;

	spin_lock(&dev->struct_mutex);

	args.tiling_mode = obj_priv->tiling_mode;
	switch (obj_priv->tiling_mode) {
	case I915_TILING_X:
		args.swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
		break;
	case I915_TILING_Y:
		args.swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
		break;
	case I915_TILING_NONE:
		args.swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
		break;
	default:
		DRM_ERROR("unknown tiling mode\n");
	}



	ret = DRM_COPY_TO_USER((struct drm_i915_gem_get_tiling __user *) data, &args, sizeof(args));
        if ( ret != 0)
                DRM_ERROR(" gem get tiling error! %d", ret);

	drm_gem_object_unreference(obj);
	spin_unlock(&dev->struct_mutex);

	return 0;
}
コード例 #12
0
ファイル: radeon_mem.c プロジェクト: gvsurenderreddy/theqvd
int radeon_mem_alloc( DRM_IOCTL_ARGS )
{
	DRM_DEVICE;
	drm_radeon_private_t *dev_priv = dev->dev_private;
	drm_radeon_mem_alloc_t alloc;
	struct mem_block *block, **heap;

	if ( !dev_priv ) {
		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
		return DRM_ERR(EINVAL);
	}

	DRM_COPY_FROM_USER_IOCTL( alloc, (drm_radeon_mem_alloc_t *)data,
				  sizeof(alloc) );

	heap = get_heap( dev_priv, alloc.region );
	if (!heap || !*heap)
		return DRM_ERR(EFAULT);
	
	/* Make things easier on ourselves: all allocations at least
	 * 4k aligned.
	 */
	if (alloc.alignment < 12)
		alloc.alignment = 12;

	block = alloc_block( *heap, alloc.size, alloc.alignment,
			     DRM_CURRENTPID );

	if (!block) 
		return DRM_ERR(ENOMEM);

	if ( DRM_COPY_TO_USER( alloc.region_offset, &block->start, 
			       sizeof(int) ) ) {
		DRM_ERROR( "copy_to_user\n" );
		return DRM_ERR(EFAULT);
	}
	
	return 0;
}
コード例 #13
0
ファイル: i915_mem.c プロジェクト: jobi/drm-psb
int i915_mem_alloc(struct drm_device *dev, void *data,
		   struct drm_file *file_priv)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_mem_alloc *alloc = data;
	struct mem_block *block, **heap;

	if (!dev_priv) {
		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
		return -EINVAL;
	}

	heap = get_heap(dev_priv, alloc->region);
	if (!heap || !*heap)
		return -EFAULT;

	/* Make things easier on ourselves: all allocations at least
	 * 4k aligned.
	 */
	if (alloc->alignment < 12)
		alloc->alignment = 12;

	block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv);

	if (!block)
		return -ENOMEM;

	mark_block(dev, block, 1);

	if (DRM_COPY_TO_USER(alloc->region_offset, &block->start,
			     sizeof(int))) {
		DRM_ERROR("copy_to_user\n");
		return -EFAULT;
	}

	return 0;
}
コード例 #14
0
static int mga_wait_fence(DRM_IOCTL_ARGS)
{
	DRM_DEVICE;
	drm_mga_private_t *dev_priv = dev->dev_private;
	u32 fence;

	if (!dev_priv) {
		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
		return DRM_ERR(EINVAL);
	}

	DRM_COPY_FROM_USER_IOCTL(fence, (u32 __user *) data, sizeof(u32));

	DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);

	mga_driver_fence_wait(dev, & fence);

	if (DRM_COPY_TO_USER( (u32 __user *) data, & fence, sizeof(u32))) {
		DRM_ERROR("copy_to_user\n");
		return DRM_ERR(EFAULT);
	}

	return 0;
}
コード例 #15
0
ファイル: radeon_kms.c プロジェクト: aywq2008/omniplay
/*
 * Userspace get information ioctl
 */
int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
{
    struct radeon_device *rdev = dev->dev_private;
    struct drm_radeon_info *info;
    struct radeon_mode_info *minfo = &rdev->mode_info;
    uint32_t *value_ptr;
    uint32_t value;
    struct drm_crtc *crtc;
    int i, found;

    info = data;
    value_ptr = (uint32_t *)((unsigned long)info->value);
    if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value)))
        return -EFAULT;

    switch (info->request) {
    case RADEON_INFO_DEVICE_ID:
        value = dev->pci_device;
        break;
    case RADEON_INFO_NUM_GB_PIPES:
        value = rdev->num_gb_pipes;
        break;
    case RADEON_INFO_NUM_Z_PIPES:
        value = rdev->num_z_pipes;
        break;
    case RADEON_INFO_ACCEL_WORKING:
        /* xf86-video-ati 6.13.0 relies on this being false for evergreen */
        if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK))
            value = false;
        else
            value = rdev->accel_working;
        break;
    case RADEON_INFO_CRTC_FROM_ID:
        for (i = 0, found = 0; i < rdev->num_crtc; i++) {
            crtc = (struct drm_crtc *)minfo->crtcs[i];
            if (crtc && crtc->base.id == value) {
                struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
                value = radeon_crtc->crtc_id;
                found = 1;
                break;
            }
        }
        if (!found) {
            DRM_DEBUG_KMS("unknown crtc id %d\n", value);
            return -EINVAL;
        }
        break;
    case RADEON_INFO_ACCEL_WORKING2:
        value = rdev->accel_working;
        break;
    case RADEON_INFO_TILING_CONFIG:
        if (rdev->family >= CHIP_TAHITI)
            value = rdev->config.si.tile_config;
        else if (rdev->family >= CHIP_CAYMAN)
            value = rdev->config.cayman.tile_config;
        else if (rdev->family >= CHIP_CEDAR)
            value = rdev->config.evergreen.tile_config;
        else if (rdev->family >= CHIP_RV770)
            value = rdev->config.rv770.tile_config;
        else if (rdev->family >= CHIP_R600)
            value = rdev->config.r600.tile_config;
        else {
            DRM_DEBUG_KMS("tiling config is r6xx+ only!\n");
            return -EINVAL;
        }
        break;
    case RADEON_INFO_WANT_HYPERZ:
        /* The "value" here is both an input and output parameter.
         * If the input value is 1, filp requests hyper-z access.
         * If the input value is 0, filp revokes its hyper-z access.
         *
         * When returning, the value is 1 if filp owns hyper-z access,
         * 0 otherwise. */
        if (value >= 2) {
            DRM_DEBUG_KMS("WANT_HYPERZ: invalid value %d\n", value);
            return -EINVAL;
        }
        radeon_set_filp_rights(dev, &rdev->hyperz_filp, filp, &value);
        break;
    case RADEON_INFO_WANT_CMASK:
        /* The same logic as Hyper-Z. */
        if (value >= 2) {
            DRM_DEBUG_KMS("WANT_CMASK: invalid value %d\n", value);
            return -EINVAL;
        }
        radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, &value);
        break;
    case RADEON_INFO_CLOCK_CRYSTAL_FREQ:
        /* return clock value in KHz */
        value = rdev->clock.spll.reference_freq * 10;
        break;
    case RADEON_INFO_NUM_BACKENDS:
        if (rdev->family >= CHIP_TAHITI)
            value = rdev->config.si.max_backends_per_se *
                    rdev->config.si.max_shader_engines;
        else if (rdev->family >= CHIP_CAYMAN)
            value = rdev->config.cayman.max_backends_per_se *
                    rdev->config.cayman.max_shader_engines;
        else if (rdev->family >= CHIP_CEDAR)
            value = rdev->config.evergreen.max_backends;
        else if (rdev->family >= CHIP_RV770)
            value = rdev->config.rv770.max_backends;
        else if (rdev->family >= CHIP_R600)
            value = rdev->config.r600.max_backends;
        else {
            return -EINVAL;
        }
        break;
    case RADEON_INFO_NUM_TILE_PIPES:
        if (rdev->family >= CHIP_TAHITI)
            value = rdev->config.si.max_tile_pipes;
        else if (rdev->family >= CHIP_CAYMAN)
            value = rdev->config.cayman.max_tile_pipes;
        else if (rdev->family >= CHIP_CEDAR)
            value = rdev->config.evergreen.max_tile_pipes;
        else if (rdev->family >= CHIP_RV770)
            value = rdev->config.rv770.max_tile_pipes;
        else if (rdev->family >= CHIP_R600)
            value = rdev->config.r600.max_tile_pipes;
        else {
            return -EINVAL;
        }
        break;
    case RADEON_INFO_FUSION_GART_WORKING:
        value = 1;
        break;
    case RADEON_INFO_BACKEND_MAP:
        if (rdev->family >= CHIP_TAHITI)
            value = rdev->config.si.backend_map;
        else if (rdev->family >= CHIP_CAYMAN)
            value = rdev->config.cayman.backend_map;
        else if (rdev->family >= CHIP_CEDAR)
            value = rdev->config.evergreen.backend_map;
        else if (rdev->family >= CHIP_RV770)
            value = rdev->config.rv770.backend_map;
        else if (rdev->family >= CHIP_R600)
            value = rdev->config.r600.backend_map;
        else {
            return -EINVAL;
        }
        break;
    case RADEON_INFO_VA_START:
        /* this is where we report if vm is supported or not */
        if (rdev->family < CHIP_CAYMAN)
            return -EINVAL;
        value = RADEON_VA_RESERVED_SIZE;
        break;
    case RADEON_INFO_IB_VM_MAX_SIZE:
        /* this is where we report if vm is supported or not */
        if (rdev->family < CHIP_CAYMAN)
            return -EINVAL;
        value = RADEON_IB_VM_MAX_SIZE;
        break;
    case RADEON_INFO_MAX_PIPES:
        if (rdev->family >= CHIP_TAHITI)
            value = rdev->config.si.max_cu_per_sh;
        else if (rdev->family >= CHIP_CAYMAN)
            value = rdev->config.cayman.max_pipes_per_simd;
        else if (rdev->family >= CHIP_CEDAR)
            value = rdev->config.evergreen.max_pipes;
        else if (rdev->family >= CHIP_RV770)
            value = rdev->config.rv770.max_pipes;
        else if (rdev->family >= CHIP_R600)
            value = rdev->config.r600.max_pipes;
        else {
            return -EINVAL;
        }
        break;
    default:
        DRM_DEBUG_KMS("Invalid request %d\n", info->request);
        return -EINVAL;
    }
    if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) {
        DRM_ERROR("copy_to_user\n");
        return -EFAULT;
    }
    return 0;
}
コード例 #16
0
/**
 * radeon_info_ioctl - answer a device specific request.
 *
 * @rdev: radeon device pointer
 * @data: request object
 * @filp: drm filp
 *
 * This function is used to pass device specific parameters to the userspace
 * drivers.  Examples include: pci device id, pipeline parms, tiling params,
 * etc. (all asics).
 * Returns 0 on success, -EINVAL on failure.
 */
int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
{
    struct radeon_device *rdev = dev->dev_private;
    struct drm_radeon_info *info = data;
    struct radeon_mode_info *minfo = &rdev->mode_info;
    uint32_t *value, value_tmp, *value_ptr, value_size;
    uint64_t value64;
    struct drm_crtc *crtc;
    int i, found;

    value_ptr = (uint32_t *)((unsigned long)info->value);
    value = &value_tmp;
    value_size = sizeof(uint32_t);

    switch (info->request) {
    case RADEON_INFO_DEVICE_ID:
        *value = dev->pdev->device;
        break;
    case RADEON_INFO_NUM_GB_PIPES:
        *value = rdev->num_gb_pipes;
        break;
    case RADEON_INFO_NUM_Z_PIPES:
        *value = rdev->num_z_pipes;
        break;
    case RADEON_INFO_ACCEL_WORKING:
        /* xf86-video-ati 6.13.0 relies on this being false for evergreen */
        if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK))
            *value = false;
        else
            *value = rdev->accel_working;
        break;
    case RADEON_INFO_CRTC_FROM_ID:
        if (DRM_COPY_FROM_USER(value, value_ptr, sizeof(uint32_t))) {
            DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
            return -EFAULT;
        }
        for (i = 0, found = 0; i < rdev->num_crtc; i++) {
            crtc = (struct drm_crtc *)minfo->crtcs[i];
            if (crtc && crtc->base.id == *value) {
                struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
                *value = radeon_crtc->crtc_id;
                found = 1;
                break;
            }
        }
        if (!found) {
            DRM_DEBUG_KMS("unknown crtc id %d\n", *value);
            return -EINVAL;
        }
        break;
    case RADEON_INFO_ACCEL_WORKING2:
        *value = rdev->accel_working;
        break;
    case RADEON_INFO_TILING_CONFIG:
        if (rdev->family >= CHIP_TAHITI)
            *value = rdev->config.si.tile_config;
        else if (rdev->family >= CHIP_CAYMAN)
            *value = rdev->config.cayman.tile_config;
        else if (rdev->family >= CHIP_CEDAR)
            *value = rdev->config.evergreen.tile_config;
        else if (rdev->family >= CHIP_RV770)
            *value = rdev->config.rv770.tile_config;
        else if (rdev->family >= CHIP_R600)
            *value = rdev->config.r600.tile_config;
        else {
            DRM_DEBUG_KMS("tiling config is r6xx+ only!\n");
            return -EINVAL;
        }
        break;
    case RADEON_INFO_WANT_HYPERZ:
        /* The "value" here is both an input and output parameter.
         * If the input value is 1, filp requests hyper-z access.
         * If the input value is 0, filp revokes its hyper-z access.
         *
         * When returning, the value is 1 if filp owns hyper-z access,
         * 0 otherwise. */
        if (DRM_COPY_FROM_USER(value, value_ptr, sizeof(uint32_t))) {
            DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
            return -EFAULT;
        }
        if (*value >= 2) {
            DRM_DEBUG_KMS("WANT_HYPERZ: invalid value %d\n", *value);
            return -EINVAL;
        }
        radeon_set_filp_rights(dev, &rdev->hyperz_filp, filp, value);
        break;
    case RADEON_INFO_WANT_CMASK:
        /* The same logic as Hyper-Z. */
        if (DRM_COPY_FROM_USER(value, value_ptr, sizeof(uint32_t))) {
            DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
            return -EFAULT;
        }
        if (*value >= 2) {
            DRM_DEBUG_KMS("WANT_CMASK: invalid value %d\n", *value);
            return -EINVAL;
        }
        radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, value);
        break;
    case RADEON_INFO_CLOCK_CRYSTAL_FREQ:
        /* return clock value in KHz */
        if (rdev->asic->get_xclk)
            *value = radeon_get_xclk(rdev) * 10;
        else
            *value = rdev->clock.spll.reference_freq * 10;
        break;
    case RADEON_INFO_NUM_BACKENDS:
        if (rdev->family >= CHIP_TAHITI)
            *value = rdev->config.si.max_backends_per_se *
                     rdev->config.si.max_shader_engines;
        else if (rdev->family >= CHIP_CAYMAN)
            *value = rdev->config.cayman.max_backends_per_se *
                     rdev->config.cayman.max_shader_engines;
        else if (rdev->family >= CHIP_CEDAR)
            *value = rdev->config.evergreen.max_backends;
        else if (rdev->family >= CHIP_RV770)
            *value = rdev->config.rv770.max_backends;
        else if (rdev->family >= CHIP_R600)
            *value = rdev->config.r600.max_backends;
        else {
            return -EINVAL;
        }
        break;
    case RADEON_INFO_NUM_TILE_PIPES:
        if (rdev->family >= CHIP_TAHITI)
            *value = rdev->config.si.max_tile_pipes;
        else if (rdev->family >= CHIP_CAYMAN)
            *value = rdev->config.cayman.max_tile_pipes;
        else if (rdev->family >= CHIP_CEDAR)
            *value = rdev->config.evergreen.max_tile_pipes;
        else if (rdev->family >= CHIP_RV770)
            *value = rdev->config.rv770.max_tile_pipes;
        else if (rdev->family >= CHIP_R600)
            *value = rdev->config.r600.max_tile_pipes;
        else {
            return -EINVAL;
        }
        break;
    case RADEON_INFO_FUSION_GART_WORKING:
        *value = 1;
        break;
    case RADEON_INFO_BACKEND_MAP:
        if (rdev->family >= CHIP_TAHITI)
            *value = rdev->config.si.backend_map;
        else if (rdev->family >= CHIP_CAYMAN)
            *value = rdev->config.cayman.backend_map;
        else if (rdev->family >= CHIP_CEDAR)
            *value = rdev->config.evergreen.backend_map;
        else if (rdev->family >= CHIP_RV770)
            *value = rdev->config.rv770.backend_map;
        else if (rdev->family >= CHIP_R600)
            *value = rdev->config.r600.backend_map;
        else {
            return -EINVAL;
        }
        break;
    case RADEON_INFO_VA_START:
        /* this is where we report if vm is supported or not */
        if (rdev->family < CHIP_CAYMAN)
            return -EINVAL;
        *value = RADEON_VA_RESERVED_SIZE;
        break;
    case RADEON_INFO_IB_VM_MAX_SIZE:
        /* this is where we report if vm is supported or not */
        if (rdev->family < CHIP_CAYMAN)
            return -EINVAL;
        *value = RADEON_IB_VM_MAX_SIZE;
        break;
    case RADEON_INFO_MAX_PIPES:
        if (rdev->family >= CHIP_TAHITI)
            *value = rdev->config.si.max_cu_per_sh;
        else if (rdev->family >= CHIP_CAYMAN)
            *value = rdev->config.cayman.max_pipes_per_simd;
        else if (rdev->family >= CHIP_CEDAR)
            *value = rdev->config.evergreen.max_pipes;
        else if (rdev->family >= CHIP_RV770)
            *value = rdev->config.rv770.max_pipes;
        else if (rdev->family >= CHIP_R600)
            *value = rdev->config.r600.max_pipes;
        else {
            return -EINVAL;
        }
        break;
    case RADEON_INFO_TIMESTAMP:
        if (rdev->family < CHIP_R600) {
            DRM_DEBUG_KMS("timestamp is r6xx+ only!\n");
            return -EINVAL;
        }
        value = (uint32_t*)&value64;
        value_size = sizeof(uint64_t);
        value64 = radeon_get_gpu_clock_counter(rdev);
        break;
    case RADEON_INFO_MAX_SE:
        if (rdev->family >= CHIP_TAHITI)
            *value = rdev->config.si.max_shader_engines;
        else if (rdev->family >= CHIP_CAYMAN)
            *value = rdev->config.cayman.max_shader_engines;
        else if (rdev->family >= CHIP_CEDAR)
            *value = rdev->config.evergreen.num_ses;
        else
            *value = 1;
        break;
    case RADEON_INFO_MAX_SH_PER_SE:
        if (rdev->family >= CHIP_TAHITI)
            *value = rdev->config.si.max_sh_per_se;
        else
            return -EINVAL;
        break;
    case RADEON_INFO_FASTFB_WORKING:
        *value = rdev->fastfb_working;
        break;
    case RADEON_INFO_RING_WORKING:
        if (DRM_COPY_FROM_USER(value, value_ptr, sizeof(uint32_t))) {
            DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
            return -EFAULT;
        }
        switch (*value) {
        case RADEON_CS_RING_GFX:
        case RADEON_CS_RING_COMPUTE:
            *value = rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready;
            break;
        case RADEON_CS_RING_DMA:
            *value = rdev->ring[R600_RING_TYPE_DMA_INDEX].ready;
            *value |= rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready;
            break;
        case RADEON_CS_RING_UVD:
            *value = rdev->ring[R600_RING_TYPE_UVD_INDEX].ready;
            break;
        default:
            return -EINVAL;
        }
        break;
    case RADEON_INFO_SI_TILE_MODE_ARRAY:
        if (rdev->family < CHIP_TAHITI) {
            DRM_DEBUG_KMS("tile mode array is si only!\n");
            return -EINVAL;
        }
        value = rdev->config.si.tile_mode_array;
        value_size = sizeof(uint32_t)*32;
        break;
    case RADEON_INFO_SI_CP_DMA_COMPUTE:
        *value = 1;
        break;
    default:
        DRM_DEBUG_KMS("Invalid request %d\n", info->request);
        return -EINVAL;
    }
    if (DRM_COPY_TO_USER(value_ptr, (char*)value, value_size)) {
        DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__);
        return -EFAULT;
    }
    return 0;
}
コード例 #17
0
/*
 * Userspace get information ioctl
 */
int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
{
	struct radeon_device *rdev = dev->dev_private;
	struct drm_radeon_info *info;
	struct radeon_mode_info *minfo = &rdev->mode_info;
	uint32_t *value_ptr;
	uint32_t value;
	struct drm_crtc *crtc;
	int i, found;

	info = data;
	value_ptr = (uint32_t *)((unsigned long)info->value);
	if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value)))
		return -EFAULT;

	switch (info->request) {
	case RADEON_INFO_DEVICE_ID:
		value = dev->pci_device;
		break;
	case RADEON_INFO_NUM_GB_PIPES:
		value = rdev->num_gb_pipes;
		break;
	case RADEON_INFO_NUM_Z_PIPES:
		value = rdev->num_z_pipes;
		break;
	case RADEON_INFO_ACCEL_WORKING:
		/* xf86-video-ati 6.13.0 relies on this being false for evergreen */
		if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK))
			value = false;
		else
			value = rdev->accel_working;
		break;
	case RADEON_INFO_CRTC_FROM_ID:
		for (i = 0, found = 0; i < rdev->num_crtc; i++) {
			crtc = (struct drm_crtc *)minfo->crtcs[i];
			if (crtc && crtc->base.id == value) {
				struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
				value = radeon_crtc->crtc_id;
				found = 1;
				break;
			}
		}
		if (!found) {
			DRM_DEBUG_KMS("unknown crtc id %d\n", value);
			return -EINVAL;
		}
		break;
	case RADEON_INFO_ACCEL_WORKING2:
		value = rdev->accel_working;
		break;
	case RADEON_INFO_TILING_CONFIG:
		if (rdev->family >= CHIP_CEDAR)
			value = rdev->config.evergreen.tile_config;
		else if (rdev->family >= CHIP_RV770)
			value = rdev->config.rv770.tile_config;
		else if (rdev->family >= CHIP_R600)
			value = rdev->config.r600.tile_config;
		else {
			DRM_DEBUG_KMS("tiling config is r6xx+ only!\n");
			return -EINVAL;
		}
		break;
	case RADEON_INFO_WANT_HYPERZ:
		/* The "value" here is both an input and output parameter.
		 * If the input value is 1, filp requests hyper-z access.
		 * If the input value is 0, filp revokes its hyper-z access.
		 *
		 * When returning, the value is 1 if filp owns hyper-z access,
		 * 0 otherwise. */
		if (value >= 2) {
			DRM_DEBUG_KMS("WANT_HYPERZ: invalid value %d\n", value);
			return -EINVAL;
		}
		radeon_set_filp_rights(dev, &rdev->hyperz_filp, filp, &value);
		break;
	case RADEON_INFO_WANT_CMASK:
		/* The same logic as Hyper-Z. */
		if (value >= 2) {
			DRM_DEBUG_KMS("WANT_CMASK: invalid value %d\n", value);
			return -EINVAL;
		}
		radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, &value);
		break;
	default:
		DRM_DEBUG_KMS("Invalid request %d\n", info->request);
		return -EINVAL;
	}
	if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) {
		DRM_ERROR("copy_to_user\n");
		return -EFAULT;
	}
	return 0;
}
コード例 #18
0
ファイル: i915_gem_tiling.c プロジェクト: bahamas10/openzfs
/*ARGSUSED*/
int
i915_gem_set_tiling(DRM_IOCTL_ARGS)
{
	DRM_DEVICE;
	struct drm_i915_gem_set_tiling args;
	drm_i915_private_t *dev_priv = dev->dev_private;
	struct drm_gem_object *obj;
	struct drm_i915_gem_object *obj_priv;
	int ret;

	if (dev->driver->use_gem != 1)
		return ENODEV;

	DRM_COPYFROM_WITH_RETURN(&args,
            (struct drm_i915_gem_set_tiling __user *) data, sizeof(args));

	obj = drm_gem_object_lookup(fpriv, args.handle);
	if (obj == NULL)
		return EINVAL;
	obj_priv = obj->driver_private;

	if (!i915_tiling_ok(dev, args.stride, obj->size, args.tiling_mode)) {
		drm_gem_object_unreference(obj);
		DRM_DEBUG("i915 tiling is not OK");
		return EINVAL;
	}

	spin_lock(&dev->struct_mutex);

	if (args.tiling_mode == I915_TILING_NONE) {
		args.swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
	} else {
		if (args.tiling_mode == I915_TILING_X)
			args.swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
		else
			args.swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
		/* If we can't handle the swizzling, make it untiled. */
		if (args.swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
			args.tiling_mode = I915_TILING_NONE;
			args.swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
		}
	}

	if (args.tiling_mode != obj_priv->tiling_mode) {
		int ret;

		/* Unbind the object, as switching tiling means we're
		 * switching the cache organization due to fencing, probably.
		 */
		ret = i915_gem_object_unbind(obj, 1);
		if (ret != 0) {
			args.tiling_mode = obj_priv->tiling_mode;
			spin_unlock(&dev->struct_mutex);
			drm_gem_object_unreference(obj);
			DRM_ERROR("tiling switch!! unbind error %d", ret);
			return ret;
		}
		obj_priv->tiling_mode = args.tiling_mode;
	}
	obj_priv->stride = args.stride;

	ret = DRM_COPY_TO_USER((struct drm_i915_gem_set_tiling __user *) data, &args, sizeof(args));
        if ( ret != 0)
                DRM_ERROR(" gem set tiling error! %d", ret);

	drm_gem_object_unreference(obj);
	spin_unlock(&dev->struct_mutex);

	return 0;
}