aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_kms.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_kms.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c108
1 files changed, 89 insertions, 19 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 8fbbe1c6ebbd..bd58af658581 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -58,9 +58,9 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
58 dev->dev_private = (void *)rdev; 58 dev->dev_private = (void *)rdev;
59 59
60 /* update BUS flag */ 60 /* update BUS flag */
61 if (drm_device_is_agp(dev)) { 61 if (drm_pci_device_is_agp(dev)) {
62 flags |= RADEON_IS_AGP; 62 flags |= RADEON_IS_AGP;
63 } else if (drm_device_is_pcie(dev)) { 63 } else if (drm_pci_device_is_pcie(dev)) {
64 flags |= RADEON_IS_PCIE; 64 flags |= RADEON_IS_PCIE;
65 } else { 65 } else {
66 flags |= RADEON_IS_PCI; 66 flags |= RADEON_IS_PCI;
@@ -96,9 +96,27 @@ out:
96 return r; 96 return r;
97} 97}
98 98
99static void radeon_set_filp_rights(struct drm_device *dev,
100 struct drm_file **owner,
101 struct drm_file *applier,
102 uint32_t *value)
103{
104 mutex_lock(&dev->struct_mutex);
105 if (*value == 1) {
106 /* wants rights */
107 if (!*owner)
108 *owner = applier;
109 } else if (*value == 0) {
110 /* revokes rights */
111 if (*owner == applier)
112 *owner = NULL;
113 }
114 *value = *owner == applier ? 1 : 0;
115 mutex_unlock(&dev->struct_mutex);
116}
99 117
100/* 118/*
101 * Userspace get informations ioctl 119 * Userspace get information ioctl
102 */ 120 */
103int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) 121int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
104{ 122{
@@ -151,7 +169,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
151 value = rdev->accel_working; 169 value = rdev->accel_working;
152 break; 170 break;
153 case RADEON_INFO_TILING_CONFIG: 171 case RADEON_INFO_TILING_CONFIG:
154 if (rdev->family >= CHIP_CEDAR) 172 if (rdev->family >= CHIP_CAYMAN)
173 value = rdev->config.cayman.tile_config;
174 else if (rdev->family >= CHIP_CEDAR)
155 value = rdev->config.evergreen.tile_config; 175 value = rdev->config.evergreen.tile_config;
156 else if (rdev->family >= CHIP_RV770) 176 else if (rdev->family >= CHIP_RV770)
157 value = rdev->config.rv770.tile_config; 177 value = rdev->config.rv770.tile_config;
@@ -173,18 +193,49 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
173 DRM_DEBUG_KMS("WANT_HYPERZ: invalid value %d\n", value); 193 DRM_DEBUG_KMS("WANT_HYPERZ: invalid value %d\n", value);
174 return -EINVAL; 194 return -EINVAL;
175 } 195 }
176 mutex_lock(&dev->struct_mutex); 196 radeon_set_filp_rights(dev, &rdev->hyperz_filp, filp, &value);
177 if (value == 1) { 197 break;
178 /* wants hyper-z */ 198 case RADEON_INFO_WANT_CMASK:
179 if (!rdev->hyperz_filp) 199 /* The same logic as Hyper-Z. */
180 rdev->hyperz_filp = filp; 200 if (value >= 2) {
181 } else if (value == 0) { 201 DRM_DEBUG_KMS("WANT_CMASK: invalid value %d\n", value);
182 /* revokes hyper-z */ 202 return -EINVAL;
183 if (rdev->hyperz_filp == filp) 203 }
184 rdev->hyperz_filp = NULL; 204 radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, &value);
205 break;
206 case RADEON_INFO_CLOCK_CRYSTAL_FREQ:
207 /* return clock value in KHz */
208 value = rdev->clock.spll.reference_freq * 10;
209 break;
210 case RADEON_INFO_NUM_BACKENDS:
211 if (rdev->family >= CHIP_CAYMAN)
212 value = rdev->config.cayman.max_backends_per_se *
213 rdev->config.cayman.max_shader_engines;
214 else if (rdev->family >= CHIP_CEDAR)
215 value = rdev->config.evergreen.max_backends;
216 else if (rdev->family >= CHIP_RV770)
217 value = rdev->config.rv770.max_backends;
218 else if (rdev->family >= CHIP_R600)
219 value = rdev->config.r600.max_backends;
220 else {
221 return -EINVAL;
222 }
223 break;
224 case RADEON_INFO_NUM_TILE_PIPES:
225 if (rdev->family >= CHIP_CAYMAN)
226 value = rdev->config.cayman.max_tile_pipes;
227 else if (rdev->family >= CHIP_CEDAR)
228 value = rdev->config.evergreen.max_tile_pipes;
229 else if (rdev->family >= CHIP_RV770)
230 value = rdev->config.rv770.max_tile_pipes;
231 else if (rdev->family >= CHIP_R600)
232 value = rdev->config.r600.max_tile_pipes;
233 else {
234 return -EINVAL;
185 } 235 }
186 value = rdev->hyperz_filp == filp ? 1 : 0; 236 break;
187 mutex_unlock(&dev->struct_mutex); 237 case RADEON_INFO_FUSION_GART_WORKING:
238 value = 1;
188 break; 239 break;
189 default: 240 default:
190 DRM_DEBUG_KMS("Invalid request %d\n", info->request); 241 DRM_DEBUG_KMS("Invalid request %d\n", info->request);
@@ -203,10 +254,6 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
203 */ 254 */
204int radeon_driver_firstopen_kms(struct drm_device *dev) 255int radeon_driver_firstopen_kms(struct drm_device *dev)
205{ 256{
206 struct radeon_device *rdev = dev->dev_private;
207
208 if (rdev->powered_down)
209 return -EINVAL;
210 return 0; 257 return 0;
211} 258}
212 259
@@ -232,6 +279,8 @@ void radeon_driver_preclose_kms(struct drm_device *dev,
232 struct radeon_device *rdev = dev->dev_private; 279 struct radeon_device *rdev = dev->dev_private;
233 if (rdev->hyperz_filp == file_priv) 280 if (rdev->hyperz_filp == file_priv)
234 rdev->hyperz_filp = NULL; 281 rdev->hyperz_filp = NULL;
282 if (rdev->cmask_filp == file_priv)
283 rdev->cmask_filp = NULL;
235} 284}
236 285
237/* 286/*
@@ -277,6 +326,27 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)
277 radeon_irq_set(rdev); 326 radeon_irq_set(rdev);
278} 327}
279 328
329int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
330 int *max_error,
331 struct timeval *vblank_time,
332 unsigned flags)
333{
334 struct drm_crtc *drmcrtc;
335 struct radeon_device *rdev = dev->dev_private;
336
337 if (crtc < 0 || crtc >= dev->num_crtcs) {
338 DRM_ERROR("Invalid crtc %d\n", crtc);
339 return -EINVAL;
340 }
341
342 /* Get associated drm_crtc: */
343 drmcrtc = &rdev->mode_info.crtcs[crtc]->base;
344
345 /* Helper routine in DRM core does all the work: */
346 return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error,
347 vblank_time, flags,
348 drmcrtc);
349}
280 350
281/* 351/*
282 * IOCTL. 352 * IOCTL.