|
@@ -176,80 +176,65 @@ 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_ptr;
|
|
|
- uint64_t value64, *value_ptr64;
|
|
|
+ uint32_t *value, value_tmp, *value_ptr, value_size;
|
|
|
+ uint64_t value64;
|
|
|
struct drm_crtc *crtc;
|
|
|
int i, found;
|
|
|
|
|
|
- /* TIMESTAMP is a 64-bit value, needs special handling. */
|
|
|
- if (info->request == RADEON_INFO_TIMESTAMP) {
|
|
|
- if (rdev->family >= CHIP_R600) {
|
|
|
- value_ptr64 = (uint64_t*)((unsigned long)info->value);
|
|
|
- value64 = radeon_get_gpu_clock_counter(rdev);
|
|
|
-
|
|
|
- if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) {
|
|
|
- DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__);
|
|
|
- return -EFAULT;
|
|
|
- }
|
|
|
- return 0;
|
|
|
- } else {
|
|
|
- DRM_DEBUG_KMS("timestamp is r6xx+ only!\n");
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
value_ptr = (uint32_t *)((unsigned long)info->value);
|
|
|
- if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) {
|
|
|
- DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
|
|
|
- return -EFAULT;
|
|
|
- }
|
|
|
+ value = &value_tmp;
|
|
|
+ value_size = sizeof(uint32_t);
|
|
|
|
|
|
switch (info->request) {
|
|
|
case RADEON_INFO_DEVICE_ID:
|
|
|
- value = dev->pci_device;
|
|
|
+ *value = dev->pci_device;
|
|
|
break;
|
|
|
case RADEON_INFO_NUM_GB_PIPES:
|
|
|
- value = rdev->num_gb_pipes;
|
|
|
+ *value = rdev->num_gb_pipes;
|
|
|
break;
|
|
|
case RADEON_INFO_NUM_Z_PIPES:
|
|
|
- value = rdev->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;
|
|
|
+ *value = false;
|
|
|
else
|
|
|
- value = rdev->accel_working;
|
|
|
+ *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) {
|
|
|
+ if (crtc && crtc->base.id == *value) {
|
|
|
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
|
|
- value = radeon_crtc->crtc_id;
|
|
|
+ *value = radeon_crtc->crtc_id;
|
|
|
found = 1;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if (!found) {
|
|
|
- DRM_DEBUG_KMS("unknown crtc id %d\n", value);
|
|
|
+ DRM_DEBUG_KMS("unknown crtc id %d\n", *value);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
break;
|
|
|
case RADEON_INFO_ACCEL_WORKING2:
|
|
|
- value = rdev->accel_working;
|
|
|
+ *value = rdev->accel_working;
|
|
|
break;
|
|
|
case RADEON_INFO_TILING_CONFIG:
|
|
|
if (rdev->family >= CHIP_TAHITI)
|
|
|
- value = rdev->config.si.tile_config;
|
|
|
+ *value = rdev->config.si.tile_config;
|
|
|
else if (rdev->family >= CHIP_CAYMAN)
|
|
|
- value = rdev->config.cayman.tile_config;
|
|
|
+ *value = rdev->config.cayman.tile_config;
|
|
|
else if (rdev->family >= CHIP_CEDAR)
|
|
|
- value = rdev->config.evergreen.tile_config;
|
|
|
+ *value = rdev->config.evergreen.tile_config;
|
|
|
else if (rdev->family >= CHIP_RV770)
|
|
|
- value = rdev->config.rv770.tile_config;
|
|
|
+ *value = rdev->config.rv770.tile_config;
|
|
|
else if (rdev->family >= CHIP_R600)
|
|
|
- value = rdev->config.r600.tile_config;
|
|
|
+ *value = rdev->config.r600.tile_config;
|
|
|
else {
|
|
|
DRM_DEBUG_KMS("tiling config is r6xx+ only!\n");
|
|
|
return -EINVAL;
|
|
@@ -262,73 +247,81 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|
|
*
|
|
|
* 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);
|
|
|
+ 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);
|
|
|
+ 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);
|
|
|
+ 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);
|
|
|
+ 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;
|
|
|
+ *value = radeon_get_xclk(rdev) * 10;
|
|
|
else
|
|
|
- value = rdev->clock.spll.reference_freq * 10;
|
|
|
+ *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 *
|
|
|
+ *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 *
|
|
|
+ *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;
|
|
|
+ *value = rdev->config.evergreen.max_backends;
|
|
|
else if (rdev->family >= CHIP_RV770)
|
|
|
- value = rdev->config.rv770.max_backends;
|
|
|
+ *value = rdev->config.rv770.max_backends;
|
|
|
else if (rdev->family >= CHIP_R600)
|
|
|
- value = rdev->config.r600.max_backends;
|
|
|
+ *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;
|
|
|
+ *value = rdev->config.si.max_tile_pipes;
|
|
|
else if (rdev->family >= CHIP_CAYMAN)
|
|
|
- value = rdev->config.cayman.max_tile_pipes;
|
|
|
+ *value = rdev->config.cayman.max_tile_pipes;
|
|
|
else if (rdev->family >= CHIP_CEDAR)
|
|
|
- value = rdev->config.evergreen.max_tile_pipes;
|
|
|
+ *value = rdev->config.evergreen.max_tile_pipes;
|
|
|
else if (rdev->family >= CHIP_RV770)
|
|
|
- value = rdev->config.rv770.max_tile_pipes;
|
|
|
+ *value = rdev->config.rv770.max_tile_pipes;
|
|
|
else if (rdev->family >= CHIP_R600)
|
|
|
- value = rdev->config.r600.max_tile_pipes;
|
|
|
+ *value = rdev->config.r600.max_tile_pipes;
|
|
|
else {
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
break;
|
|
|
case RADEON_INFO_FUSION_GART_WORKING:
|
|
|
- value = 1;
|
|
|
+ *value = 1;
|
|
|
break;
|
|
|
case RADEON_INFO_BACKEND_MAP:
|
|
|
if (rdev->family >= CHIP_TAHITI)
|
|
|
- value = rdev->config.si.backend_map;
|
|
|
+ *value = rdev->config.si.backend_map;
|
|
|
else if (rdev->family >= CHIP_CAYMAN)
|
|
|
- value = rdev->config.cayman.backend_map;
|
|
|
+ *value = rdev->config.cayman.backend_map;
|
|
|
else if (rdev->family >= CHIP_CEDAR)
|
|
|
- value = rdev->config.evergreen.backend_map;
|
|
|
+ *value = rdev->config.evergreen.backend_map;
|
|
|
else if (rdev->family >= CHIP_RV770)
|
|
|
- value = rdev->config.rv770.backend_map;
|
|
|
+ *value = rdev->config.rv770.backend_map;
|
|
|
else if (rdev->family >= CHIP_R600)
|
|
|
- value = rdev->config.r600.backend_map;
|
|
|
+ *value = rdev->config.r600.backend_map;
|
|
|
else {
|
|
|
return -EINVAL;
|
|
|
}
|
|
@@ -337,70 +330,91 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|
|
/* this is where we report if vm is supported or not */
|
|
|
if (rdev->family < CHIP_CAYMAN)
|
|
|
return -EINVAL;
|
|
|
- value = RADEON_VA_RESERVED_SIZE;
|
|
|
+ *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;
|
|
|
+ *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;
|
|
|
+ *value = rdev->config.si.max_cu_per_sh;
|
|
|
else if (rdev->family >= CHIP_CAYMAN)
|
|
|
- value = rdev->config.cayman.max_pipes_per_simd;
|
|
|
+ *value = rdev->config.cayman.max_pipes_per_simd;
|
|
|
else if (rdev->family >= CHIP_CEDAR)
|
|
|
- value = rdev->config.evergreen.max_pipes;
|
|
|
+ *value = rdev->config.evergreen.max_pipes;
|
|
|
else if (rdev->family >= CHIP_RV770)
|
|
|
- value = rdev->config.rv770.max_pipes;
|
|
|
+ *value = rdev->config.rv770.max_pipes;
|
|
|
else if (rdev->family >= CHIP_R600)
|
|
|
- value = rdev->config.r600.max_pipes;
|
|
|
+ *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;
|
|
|
+ *value = rdev->config.si.max_shader_engines;
|
|
|
else if (rdev->family >= CHIP_CAYMAN)
|
|
|
- value = rdev->config.cayman.max_shader_engines;
|
|
|
+ *value = rdev->config.cayman.max_shader_engines;
|
|
|
else if (rdev->family >= CHIP_CEDAR)
|
|
|
- value = rdev->config.evergreen.num_ses;
|
|
|
+ *value = rdev->config.evergreen.num_ses;
|
|
|
else
|
|
|
- value = 1;
|
|
|
+ *value = 1;
|
|
|
break;
|
|
|
case RADEON_INFO_MAX_SH_PER_SE:
|
|
|
if (rdev->family >= CHIP_TAHITI)
|
|
|
- value = rdev->config.si.max_sh_per_se;
|
|
|
+ *value = rdev->config.si.max_sh_per_se;
|
|
|
else
|
|
|
return -EINVAL;
|
|
|
break;
|
|
|
case RADEON_INFO_FASTFB_WORKING:
|
|
|
- value = rdev->fastfb_working;
|
|
|
+ *value = rdev->fastfb_working;
|
|
|
break;
|
|
|
case RADEON_INFO_RING_WORKING:
|
|
|
- switch (value) {
|
|
|
+ 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;
|
|
|
+ *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;
|
|
|
+ *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;
|
|
|
+ *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;
|
|
|
default:
|
|
|
DRM_DEBUG_KMS("Invalid request %d\n", info->request);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
- if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) {
|
|
|
+ if (DRM_COPY_TO_USER(value_ptr, (char*)value, value_size)) {
|
|
|
DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__);
|
|
|
return -EFAULT;
|
|
|
}
|